(* $Id: CSums.v,v 1.13 2000/11/10 11:27:31 freek Exp $ *)

Require Export CGroups.
Require Export PolyList.
Require Export Peano_dec.

(* Tex_Prose
\section{Sums}

\begin{convention}
Let \verb!G! be a group.
\end{convention}
*)

Section Sums.

Variable G : CGroup. (* sum1 and sum use subtraction *)

(* Begin_Tex_Verb *)
Fixpoint sumlist [l:(list G)] : G :=
  Cases l of
    nil => Zero::G
  | (cons x k) => x[+](sumlist k)
  end.
(* End_Tex_Verb *)

(* Begin_Tex_Verb *)
Fixpoint sumx [n:nat] : ((i:nat)(lt i n)->G)->G :=
  <[n:nat](((i:nat)(lt i n)->G)->G)>
  Cases n of
    O => [_:(i:nat)(lt i O)->G]Zero::G
  | (S m) => [f:(i:nat)(lt i (S m))->G]
      (sumx m [i:nat][l:(lt i m)](f i (lt_S ?? l)))
        [+](f m (lt_n_Sn m))
  end.
(* End_Tex_Verb *)

(* Begin_Tex_Verb *)
Fixpoint sum0 [n:nat] : (nat->G)->G := [f:nat->G]
(* sum i=0..(n-1) *)
  Cases n of
    O => Zero::G
  | (S m) => (sum0 m f)[+](f m)
  end.
(* End_Tex_Verb *)

(* Begin_Tex_Verb *)
Definition sum1 : nat->nat->(nat->G)->G :=
(* sum i=m..(n-1) *)
  [m,n:nat][f:nat->G]((sum0 n f)[-](sum0 m f)).
(* End_Tex_Verb *)

(* Begin_Tex_Verb *)
Definition sum : nat->nat->(nat->G)->G :=
(* sum i=m..n *)
  [m,n:nat](sum1 m (S n)).
(* End_Tex_Verb *)

(* Begin_Tex_Verb *)
Lemma sum_one : (n:nat)(f:nat->G)(sum n n f)[=](f n).
(* End_Tex_Verb *)
Intros.
Unfold sum.
Unfold sum1.
Simpl.
Step_final ((f n)[+](sum0 n f))[-](sum0 n f).
Qed.

Hints Resolve sum_one : algebra.

(* Begin_Tex_Verb *)
Lemma sum_sum : (l,m,n:nat)(f:nat->G)
  (sum l m f)[+](sum (S m) n f)[=](sum l n f).
(* End_Tex_Verb *)
Intros.
Unfold sum.
Unfold sum1.
Step ((sum0 (S n) f)[-](sum0 (S m) f))[+]((sum0 (S m) f)[-](sum0 l f)).
Step (((sum0 (S n) f)[-](sum0 (S m) f))[+](sum0 (S m) f))[-](sum0 l f).
Step ((sum0 (S n) f)[-]((sum0 (S m) f)[-](sum0 (S m) f)))[-](sum0 l f).
Step ((sum0 (S n) f)[-]Zero)[-](sum0 l f).
Step ((sum0 (S n) f)[+][--]Zero)[-](sum0 l f).
Step_final ((sum0 (S n) f)[+]Zero)[-](sum0 l f).
(* this calculation is fairly ridiculous, but:
- we can't use Rational, because this is only a CGroup and not a CField
- we don't use the full power of Step, because it would need _many_ more
  algebra Lemmas and I don't feel like adding them systematically right now
*)
Qed.

Hints Resolve sum_sum : algebra.

(* Begin_Tex_Verb *)
Lemma sum_first : (m,n:nat)(f:nat->G)
  (sum m n f) [=] (f m)[+](sum (S m) n f).
(* End_Tex_Verb *)
Intros.
Unfold sum.
Unfold sum1.
Step_rht ((f m)[+](sum0 (S n) f))[-](sum0 (S m) f).
Step_rht ((sum0 (S n) f)[+](f m))[-](sum0 (S m) f).
Step_rht (sum0 (S n) f)[+]((f m)[-](sum0 (S m) f)).
Unfold cg_minus.
Apply bin_op_wd_unfolded.
Algebra.
Simpl.
Step_rht (f m)[+][--]((f m)[+](sum0 m f)).
Step_rht (f m)[+]([--](f m)[+][--](sum0 m f)).
Step_rht ((f m)[+][--](f m))[+][--](sum0 m f).
Step_rht Zero[+][--](sum0 m f).
Algebra.
Qed.

(* Begin_Tex_Verb *)
Lemma sum_last : (m,n:nat)(f:nat->G)
  (sum m (S n) f) [=] (sum m n f)[+](f (S n)).
(* End_Tex_Verb *)
Intros.
Unfold sum.
Unfold sum1.
Simpl.
Unfold cg_minus.
Step_lft (sum0 n f)[+](f n)[+] ((f (S n))[+][--](sum0 m f)).
Step_rht (sum0 n f)[+](f n)[+] ([--](sum0 m f)[+](f (S n))).
Algebra.
Qed.

(* Begin_Tex_Verb *)
Lemma sum_last' : (m,n:nat)(f:nat->G)(lt O n) ->
  (sum m n f) [=] (sum m (pred n) f)[+](f n).
(* End_Tex_Verb *)
Intros. Induction n; Intros.
Elim (lt_n_n (0) H).
Apply sum_last.
Qed.

(* Begin_Tex_Verb *)
Lemma sum0_wd : (m:nat)(f,f':nat->G)((i:nat)(f i)[=](f' i)) ->
                (sum0 m f)[=](sum0 m f').
(* End_Tex_Verb *)
Intros.Elim m.
Simpl.
Algebra.
Intros.
Simpl.
Apply bin_op_wd_unfolded.
Assumption.
Apply H.
Qed.

(* Begin_Tex_Verb *)
Lemma sum_wd : (m,n:nat)(f,f':nat->G)((i:nat)(f i)[=](f' i)) ->
               (sum m n f)[=](sum m n f').
(* End_Tex_Verb *)
Intros.
Unfold sum.
Unfold sum1.
Unfold cg_minus.
Apply bin_op_wd_unfolded.
Apply sum0_wd.
Exact H.
Apply un_op_wd_unfolded.
Apply sum0_wd.
Exact H.
Qed.

(* Begin_Tex_Verb *)
Lemma sum0_plus_sum0 : (f,g:nat->G)(m:nat)
                     (sum0 m [i:nat]((f i)[+](g i))) [=]
                     ((sum0 m f) [+] (sum0 m g)).
(* End_Tex_Verb *)
Intros.
Elim m.
Simpl.
Algebra.
Intros.
Simpl.
Step_lft (sum0 n f)[+](sum0 n g) [+] ((f n)[+](g n)).
Step_lft (sum0 n f)[+]((sum0 n g) [+] ((f n)[+](g n))).
Step_lft (sum0 n f)[+]((sum0 n g) [+] (f n)[+](g n)).
Step_lft (sum0 n f)[+]((f n) [+] (sum0 n g)[+](g n)).
Step_lft (sum0 n f)[+]((f n) [+] (sum0 n g))[+](g n).
Step_lft (sum0 n f)[+](f n) [+] (sum0 n g)[+](g n).
Algebra.
Qed.
Hints Resolve sum0_plus_sum0 : algebra.

(* Begin_Tex_Verb *)
Lemma sum_plus_sum : (f,g:nat->G)(a,b:nat)
                     (sum a b [i:nat]((f i)[+](g i))) [=]
                     ((sum a b f) [+] (sum a b g)).
(* End_Tex_Verb *)
Intros.
Unfold sum.
Unfold sum1.
Step_lft ((sum0 (S b) f) [+] (sum0 (S b) g))[-] ((sum0 a f) [+](sum0 a g)).
Step_lft ((((sum0 (S b) f) [+] (sum0 (S b) g)) [-] (sum0 a f)) [-] (sum0 a g)).
Unfold cg_minus.
Step_rht ((sum0 (S b) f)[+][--](sum0 a f)
            [+](sum0 (S b) g))[+][--](sum0 a g).
Apply bin_op_wd_unfolded.
Step_lft (sum0 (S b) f)[+]((sum0 (S b) g)[+][--](sum0 a f)).
Step_lft (sum0 (S b) f)[+]([--](sum0 a f)[+](sum0 (S b) g)).
Algebra.
Algebra.
Qed.

(* Begin_Tex_Verb *)
Lemma sum_apzero : (a:nat->G)(k,l:nat)(le k l) ->
  ((sum k l a) [#] Zero) ->
    (EX i | (le k i) /\ (le i l) /\ ((a i) [#] Zero)).
(* End_Tex_Verb *)
Intros. Induction l; Intros.
Exists (0). Split. Auto. Split. Auto.
Inversion H. Rewrite H1 in H0.
Step_ap_lft (sum (0) (0) a).
Elim (le_lt_eq_dec k (S l) H); Intros.
Cut ((sum k l a) [#] Zero) \/ ((a (S l)) [#] Zero). Intro.
Elim H1; Clear H1; Intros.
Elim Hrecl. Intro i. Intros. Exists i.
Elim H2. Clear H2. Intros. Elim H3. Clear H3. Intros.
Auto. Auto with arith. Auto.
Exists (S l). Auto.
Apply cg_add_ap_zero.
Apply ap_well_def_lft_unfolded with (sum k (S l) a). Auto.
Apply sum_last.
Exists (S l). Rewrite y in H0.
Split. Auto. Split. Auto.
Step_ap_lft (sum (S l) (S l) a).
Qed.

(* Begin_Tex_Verb *)
Lemma sum_zero : (a:nat->G)(k,l:nat)(le k (S l)) ->
  ((i:nat)(le k i) -> (le i l) -> (a i) [=] Zero) ->
    (sum k l a) [=] Zero.
(* End_Tex_Verb *)
Intros. Induction l; Intros.
Inversion H.
Unfold sum. Unfold sum1. Algebra.
Inversion H2.
Step (a (0)). Apply H0; Auto.
Elim (le_lt_eq_dec k (S (S l)) H); Intros.
Apply eq_transitive_unfolded with (sum k l a)[+](a (S l)).
Apply sum_last.
Step_rht Zero[+]Zero::G.
Apply bin_op_wd_unfolded.
Apply Hrecl. Auto with arith.
Auto.
Apply H0. Auto with arith.
Auto.
Rewrite y.
Unfold sum. Unfold sum1. Algebra.
Qed.

(* Begin_Tex_Verb *)
Lemma sum_wd' :
  (k,l:nat)(le k (S l)) -> (a,a':nat->G)
    ((i:nat)(le k i) -> (le i l) -> ((a i)[=](a' i))) ->
      (sum k l a)[=](sum k l a').
(* End_Tex_Verb *)
Intros. Induction l; Intros.
Inversion H.
Unfold sum. Unfold sum1. Step_final Zero::G.
Inversion H2.
Step (a (0)). Step_rht (a' (0)). Apply H0; Auto.
Elim (le_lt_eq_dec k (S (S l)) H); Intros.
Apply eq_transitive_unfolded with (sum k l a)[+](a (S l)).
Apply sum_last.
Apply eq_transitive_unfolded with (sum k l a')[+](a' (S l)).
Apply bin_op_wd_unfolded.
Apply Hrecl. Auto with arith.
Auto.
Apply H0. Auto with arith.
Auto.
Apply eq_symmetric_unfolded.
Apply sum_last.
Rewrite y.
Unfold sum. Unfold sum1. Step_final Zero::G.
Qed.

(* Begin_Tex_Verb *)
Lemma sum_term : (a:nat->G)(k,i0,l:nat)(le k i0) -> (le i0 l) ->
  ((i:nat)(le k i) -> (~i=i0) -> (le i l) -> (a i) [=] Zero) ->
    (sum k l a) [=] (a i0).
(* End_Tex_Verb *)
Intros.
Step (sum k i0 a)[+](sum (S i0) l a).
Step_rht (a i0)[+]Zero.
Apply bin_op_wd_unfolded.
Elim (O_or_S i0); Intros.
Elim y. Intros.
Rewrite <- y0.
Apply eq_transitive_unfolded with (sum k x a)[+](a (S x)).
Apply sum_last.
Step_rht Zero[+](a (S x)).
Apply bin_op_wd_unfolded.
Apply sum_zero. Omega.
Intros. Apply H1. Auto. Omega. Omega.
Algebra.
Rewrite <- y in H. Rewrite <- y. Inversion H. Algebra.
Apply sum_zero. Auto with arith.
Intros. Apply H1. Omega. Omega. Auto.
Qed.

(* Begin_Tex_Verb *)
Lemma sum0_shift : (a,b:nat->G)(l:nat)
  ((i:nat)((a i) [=] (b (S i)))) ->
    (b (0))[+](sum0 l a) [=] (sum0 (S l) b).
(* End_Tex_Verb *)
Intros. Induction l; Intros.
Simpl. Algebra.
Simpl.
Step (b (0))[+](sum0 l a)[+](a l).
Step_final (sum0 (S l) b)[+](a l).
Qed.

Hints Resolve sum0_shift : algebra.

(* Begin_Tex_Verb *)
Lemma sum_shift : (a,b:nat->G)(k,l:nat)
  ((i:nat)((a i) [=] (b (S i)))) ->
    (sum k l a) [=] (sum (S k) (S l) b).
(* End_Tex_Verb *)
Unfold sum. Unfold sum1. Intros.
Step (((sum0 (S l) a)[+](b (0)))[-](b (0)))[-](sum0 k a).
Step ((sum0 (S l) a)[+](b (0)))[-]((b (0))[+](sum0 k a)).
Step_final ((b (0))[+](sum0 (S l) a))[-]((b (0))[+](sum0 k a)).
Qed.

End Sums.

Hints Resolve sum_one sum_sum sum_first sum_last sum_last' sum_wd
  sum_plus_sum: algebra.

Syntactic Definition Sum := (sum ?).
Syntactic Definition Sum0 := (sum0 ?).


