1 (**************************************************************************)
4 (* ||A|| A project by Andrea Asperti *)
6 (* ||I|| Developers: *)
7 (* ||T|| The HELM team. *)
8 (* ||A|| http://helm.cs.unibo.it *)
10 (* \ / This file is distributed under the terms of the *)
11 (* v GNU General Public License Version 2 *)
13 (**************************************************************************)
15 set "baseuri" "cic:/matita/nat/generic_sigma_p.ma".
17 include "nat/primes.ma".
22 (*a generic definition of summatory indexed over natural numbers:
23 * n:N is the advanced end in the range of the sommatory
24 * p: N -> bool is a predicate. if (p i) = true, then (g i) is summed, else it isn't
25 * A is the type of the elements of the sum.
26 * g:nat -> A, is the function which associates the nth element of the sum to the nth natural numbers
27 * baseA (of type A) is the neutral element of A for plusA operation
28 * plusA: A -> A -> A is the sum over elements in A.
30 let rec sigma_p_gen (n:nat) (p: nat \to bool) (A:Type) (g: nat \to A)
31 (baseA: A) (plusA: A \to A \to A) \def
36 [true \Rightarrow (plusA (g k) (sigma_p_gen k p A g baseA plusA))
37 |false \Rightarrow sigma_p_gen k p A g baseA plusA]
40 theorem true_to_sigma_p_Sn_gen:
41 \forall n:nat. \forall p:nat \to bool. \forall A:Type. \forall g:nat \to A.
42 \forall baseA:A. \forall plusA: A \to A \to A.
43 p n = true \to sigma_p_gen (S n) p A g baseA plusA =
44 (plusA (g n) (sigma_p_gen n p A g baseA plusA)).
53 theorem false_to_sigma_p_Sn_gen:
54 \forall n:nat. \forall p:nat \to bool. \forall A:Type. \forall g:nat \to A.
55 \forall baseA:A. \forall plusA: A \to A \to A.
56 p n = false \to sigma_p_gen (S n) p A g baseA plusA = sigma_p_gen n p A g baseA plusA.
64 theorem eq_sigma_p_gen: \forall p1,p2:nat \to bool. \forall A:Type.
65 \forall g1,g2: nat \to A. \forall baseA: A.
66 \forall plusA: A \to A \to A. \forall n:nat.
67 (\forall x. x < n \to p1 x = p2 x) \to
68 (\forall x. x < n \to g1 x = g2 x) \to
69 sigma_p_gen n p1 A g1 baseA plusA = sigma_p_gen n p2 A g2 baseA plusA.
73 | apply (bool_elim ? (p1 n1))
75 rewrite > (true_to_sigma_p_Sn_gen ? ? ? ? ? ? H3).
76 rewrite > true_to_sigma_p_Sn_gen
78 [ apply H2.apply le_n.
80 [ intros.apply H1.apply le_S.assumption
81 | intros.apply H2.apply le_S.assumption
84 | rewrite < H3.apply sym_eq.apply H1.apply le_n
87 rewrite > (false_to_sigma_p_Sn_gen ? ? ? ? ? ? H3).
88 rewrite > false_to_sigma_p_Sn_gen
90 [ intros.apply H1.apply le_S.assumption
91 | intros.apply H2.apply le_S.assumption
93 | rewrite < H3.apply sym_eq.apply H1.apply le_n
99 theorem eq_sigma_p1_gen: \forall p1,p2:nat \to bool. \forall A:Type.
100 \forall g1,g2: nat \to A. \forall baseA: A.
101 \forall plusA: A \to A \to A.\forall n:nat.
102 (\forall x. x < n \to p1 x = p2 x) \to
103 (\forall x. x < n \to p1 x = true \to g1 x = g2 x) \to
104 sigma_p_gen n p1 A g1 baseA plusA = sigma_p_gen n p2 A g2 baseA plusA.
108 | apply (bool_elim ? (p1 n1))
110 rewrite > (true_to_sigma_p_Sn_gen ? ? ? ? ? ? H3).
111 rewrite > true_to_sigma_p_Sn_gen
118 [ intros.apply H1.apply le_S.assumption
120 [ apply le_S.assumption
126 apply sym_eq.apply H1.apply le_n
129 rewrite > (false_to_sigma_p_Sn_gen ? ? ? ? ? ? H3).
130 rewrite > false_to_sigma_p_Sn_gen
132 [ intros.apply H1.apply le_S.assumption
134 [ apply le_S.assumption
138 | rewrite < H3.apply sym_eq.
145 theorem sigma_p_false_gen: \forall A:Type. \forall g: nat \to A. \forall baseA:A.
146 \forall plusA: A \to A \to A. \forall n.
147 sigma_p_gen n (\lambda x.false) A g baseA plusA = baseA.
156 theorem sigma_p_plusA_gen: \forall A:Type. \forall n,k:nat.\forall p:nat \to bool.
157 \forall g: nat \to A. \forall baseA:A. \forall plusA: A \to A \to A.
158 (symmetric A plusA) \to (\forall a:A. (plusA a baseA) = a) \to (associative A plusA)
160 sigma_p_gen (k + n) p A g baseA plusA
161 = (plusA (sigma_p_gen k (\lambda x.p (x+n)) A (\lambda x.g (x+n)) baseA plusA)
162 (sigma_p_gen n p A g baseA plusA)).
166 [ rewrite < (plus_n_O n).
168 rewrite > H in \vdash (? ? ? %).
171 | apply (bool_elim ? (p (n1+n)))
173 rewrite > (true_to_sigma_p_Sn_gen ? ? ? ? ? ? H4).
174 rewrite > (true_to_sigma_p_Sn_gen n1 (\lambda x.p (x+n)) ? ? ? ? H4).
175 rewrite > (H2 (g (n1 + n)) ? ?).
179 rewrite > (false_to_sigma_p_Sn_gen ? ? ? ? ? ? H4).
180 rewrite > (false_to_sigma_p_Sn_gen n1 (\lambda x.p (x+n)) ? ? ? ? H4).
186 theorem false_to_eq_sigma_p_gen: \forall A:Type. \forall n,m:nat.\forall p:nat \to bool.
187 \forall g: nat \to A. \forall baseA:A. \forall plusA: A \to A \to A.
188 n \le m \to (\forall i:nat. n \le i \to i < m \to p i = false)
189 \to sigma_p_gen m p A g baseA plusA = sigma_p_gen n p A g baseA plusA.
209 theorem sigma_p2_gen :
211 \forall p1,p2:nat \to bool.
213 \forall g: nat \to nat \to A.
215 \forall plusA: A \to A \to A.
216 (symmetric A plusA) \to (associative A plusA) \to (\forall a:A.(plusA a baseA) = a)
219 (\lambda x.andb (p1 (div x m)) (p2 (mod x m)))
221 (\lambda x.g (div x m) (mod x m))
225 (\lambda x.sigma_p_gen m p2 A (g x) baseA plusA)
231 | apply (bool_elim ? (p1 n1))
233 rewrite > (true_to_sigma_p_Sn_gen ? ? ? ? ? ? H4).
234 simplify in \vdash (? ? (? % ? ? ? ? ?) ?).
235 rewrite > sigma_p_plusA_gen
238 [ apply eq_sigma_p_gen
241 rewrite > (div_plus_times ? ? ? H5).
242 rewrite > (mod_plus_times ? ? ? H5).
248 rewrite > (div_plus_times ? ? ? H5).
249 rewrite > (mod_plus_times ? ? ? H5).
251 simplify.reflexivity.
260 rewrite > (false_to_sigma_p_Sn_gen ? ? ? ? ? ? H4).
261 simplify in \vdash (? ? (? % ? ? ? ? ?) ?).
262 rewrite > sigma_p_plusA_gen
264 apply (trans_eq ? ? (plusA baseA
265 (sigma_p_gen n1 p1 A (\lambda x:nat.sigma_p_gen m p2 A (g x) baseA plusA) baseA plusA )))
267 [ rewrite > (eq_sigma_p_gen ? (\lambda x.false) A ? (\lambda x:nat.g ((x+n1*m)/m) ((x+n1*m)\mod m)))
268 [ apply sigma_p_false_gen
271 rewrite > (div_plus_times ? ? ? H5).
272 rewrite > (mod_plus_times ? ? ? H5).
275 | intros.reflexivity.
292 theorem sigma_p2_gen':
294 \forall p1: nat \to bool.
295 \forall p2: nat \to nat \to bool.
297 \forall g: nat \to nat \to A.
299 \forall plusA: A \to A \to A.
300 (symmetric A plusA) \to (associative A plusA) \to (\forall a:A.(plusA a baseA) = a)
303 (\lambda x.andb (p1 (div x m)) (p2 (div x m)(mod x m)))
305 (\lambda x.g (div x m) (mod x m))
309 (\lambda x.sigma_p_gen m (p2 x) A (g x) baseA plusA)
315 | apply (bool_elim ? (p1 n1))
317 rewrite > (true_to_sigma_p_Sn_gen ? ? ? ? ? ? H4).
318 simplify in \vdash (? ? (? % ? ? ? ? ?) ?).
319 rewrite > sigma_p_plusA_gen
322 [ apply eq_sigma_p_gen
325 rewrite > (div_plus_times ? ? ? H5).
326 rewrite > (mod_plus_times ? ? ? H5).
332 rewrite > (div_plus_times ? ? ? H5).
333 rewrite > (mod_plus_times ? ? ? H5).
335 simplify.reflexivity.
344 rewrite > (false_to_sigma_p_Sn_gen ? ? ? ? ? ? H4).
345 simplify in \vdash (? ? (? % ? ? ? ? ?) ?).
346 rewrite > sigma_p_plusA_gen
348 apply (trans_eq ? ? (plusA baseA
349 (sigma_p_gen n1 p1 A (\lambda x:nat.sigma_p_gen m (p2 x) A (g x) baseA plusA) baseA plusA )))
351 [ rewrite > (eq_sigma_p_gen ? (\lambda x.false) A ? (\lambda x:nat.g ((x+n1*m)/m) ((x+n1*m)\mod m)))
352 [ apply sigma_p_false_gen
355 rewrite > (div_plus_times ? ? ? H5).
356 rewrite > (mod_plus_times ? ? ? H5).
359 | intros.reflexivity.
375 lemma sigma_p_gi_gen:
377 \forall g: nat \to A.
379 \forall plusA: A \to A \to A.
381 \forall p:nat \to bool.
382 (symmetric A plusA) \to (associative A plusA) \to (\forall a:A.(plusA a baseA) = a)
385 i < n \to p i = true \to
386 (sigma_p_gen n p A g baseA plusA) =
387 (plusA (g i) (sigma_p_gen n (\lambda x:nat. andb (p x) (notb (eqb x i))) A g baseA plusA)).
391 apply (not_le_Sn_O i).
393 | apply (bool_elim ? (p n1));intro
394 [ elim (le_to_or_lt_eq i n1)
395 [ rewrite > true_to_sigma_p_Sn_gen
396 [ rewrite > true_to_sigma_p_Sn_gen
397 [ rewrite < (H2 (g i) ? ?).
398 rewrite > (H1 (g i) (g n1)).
399 rewrite > (H2 (g n1) ? ?).
410 | rewrite > H6.simplify.
411 change with (notb (eqb n1 i) = notb false).
413 apply not_eq_to_eqb_false.
415 apply (lt_to_not_eq ? ? H7).
416 apply sym_eq.assumption
420 | rewrite > true_to_sigma_p_Sn_gen
424 | rewrite > false_to_sigma_p_Sn_gen
425 [ apply eq_sigma_p_gen
429 change with (notb false = notb (eqb x n1)).
432 apply not_eq_to_eqb_false.
433 apply (lt_to_not_eq ? ? H8)
440 rewrite > (eq_to_eqb_true ? ? (refl_eq ? n1)).
446 | apply le_S_S_to_le.
449 | rewrite > false_to_sigma_p_Sn_gen
450 [ elim (le_to_or_lt_eq i n1)
451 [ rewrite > false_to_sigma_p_Sn_gen
459 | rewrite > H6.reflexivity
462 apply not_eq_true_false.
466 | apply le_S_S_to_le.
476 theorem eq_sigma_p_gh_gen:
479 \forall plusA: A \to A \to A.
480 (symmetric A plusA) \to (associative A plusA) \to (\forall a:A.(plusA a baseA) = a) \to
481 \forall g: nat \to A.
482 \forall h,h1: nat \to nat.
484 \forall p1,p2:nat \to bool.
485 (\forall i. i < n \to p1 i = true \to p2 (h i) = true) \to
486 (\forall i. i < n \to p1 i = true \to h1 (h i) = i) \to
487 (\forall i. i < n \to p1 i = true \to h i < n1) \to
488 (\forall j. j < n1 \to p2 j = true \to p1 (h1 j) = true) \to
489 (\forall j. j < n1 \to p2 j = true \to h (h1 j) = j) \to
490 (\forall j. j < n1 \to p2 j = true \to h1 j < n) \to
492 sigma_p_gen n p1 A (\lambda x.g(h x)) baseA plusA =
493 sigma_p_gen n1 (\lambda x.p2 x) A g baseA plusA.
496 [ generalize in match H8.
499 | apply (bool_elim ? (p2 n2));intro
501 apply (not_le_Sn_O (h1 n2)).
506 | rewrite > false_to_sigma_p_Sn_gen
518 | apply (bool_elim ? (p1 n1));intro
519 [ rewrite > true_to_sigma_p_Sn_gen
520 [ rewrite > (sigma_p_gi_gen A g baseA plusA n2 (h n1))
527 change with ((\not eqb (h i) (h n1))= \not false).
529 apply not_eq_to_eqb_false.
532 apply (lt_to_not_eq ? ? H11).
544 | apply le_S.assumption
555 [ apply le_S.assumption
561 | generalize in match H12.
570 | generalize in match H12.
577 elim (le_to_or_lt_eq (h1 j) n1)
579 | generalize in match H12.
589 | apply eqb_false_to_not_eq.
590 generalize in match H14.
592 [ apply sym_eq.assumption
598 apply not_eq_true_false.
599 apply sym_eq.assumption
601 | apply le_S_S_to_le.
604 | generalize in match H12.
627 | rewrite > false_to_sigma_p_Sn_gen
630 apply H4[apply le_S.assumption|assumption]
632 apply H5[apply le_S.assumption|assumption]
634 apply H6[apply le_S.assumption|assumption]
636 apply H7[assumption|assumption]
638 apply H8[assumption|assumption]
640 elim (le_to_or_lt_eq (h1 j) n1)
642 | absurd (j = (h n1))
650 apply not_eq_true_false.
659 | apply le_S_S_to_le.
674 definition p_ord_times \def
677 [pair q r \Rightarrow r*m+q].
679 theorem eq_p_ord_times: \forall p,m,x.
680 p_ord_times p m x = (ord_rem x p)*m+(ord x p).
681 intros.unfold p_ord_times. unfold ord_rem.
687 theorem div_p_ord_times:
688 \forall p,m,x. ord x p < m \to p_ord_times p m x / m = ord_rem x p.
689 intros.rewrite > eq_p_ord_times.
690 apply div_plus_times.
694 theorem mod_p_ord_times:
695 \forall p,m,x. ord x p < m \to p_ord_times p m x \mod m = ord x p.
696 intros.rewrite > eq_p_ord_times.
697 apply mod_plus_times.
701 theorem sigma_p_divides_gen:
704 \forall plusA: A \to A \to A.
705 \forall n,m,p:nat.O < n \to prime p \to Not (divides p n) \to
706 \forall g: nat \to A.
707 (symmetric A plusA) \to (associative A plusA) \to (\forall a:A.(plusA a baseA) = a)
711 sigma_p_gen (S (n*(exp p m))) (\lambda x.divides_b x (n*(exp p m))) A g baseA plusA =
712 sigma_p_gen (S n) (\lambda x.divides_b x n) A
713 (\lambda x.sigma_p_gen (S m) (\lambda y.true) A (\lambda y.g (x*(exp p y))) baseA plusA) baseA plusA.
716 [rewrite < (sigma_p2_gen ? ? ? ? ? ? ? ? H3 H4 H5).
718 (sigma_p_gen (S n*S m) (\lambda x:nat.divides_b (x/S m) n) A
719 (\lambda x:nat.g (x/S m*(p)\sup(x\mod S m))) baseA plusA) )
721 apply (eq_sigma_p_gh_gen ? ? ? ? ? ? g ? (p_ord_times p (S m)))
726 lapply (divides_b_true_to_lt_O ? ? H H7).
727 apply divides_to_divides_b_true
728 [rewrite > (times_n_O O).
731 |apply lt_O_exp.assumption
734 [apply divides_b_true_to_divides.assumption
735 |apply (witness ? ? (p \sup (m-i \mod (S m)))).
736 rewrite < exp_plus_times.
739 apply plus_minus_m_m.
744 lapply (divides_b_true_to_lt_O ? ? H H7).
746 rewrite > (p_ord_exp1 p ? (i \mod (S m)) (i/S m))
747 [change with ((i/S m)*S m+i \mod S m=i).
754 apply (trans_divides ? (i/ S m))
756 apply divides_b_true_to_divides;assumption]
763 change with ((i/S m) < S n).
764 apply (lt_times_to_lt_l m).
765 apply (le_to_lt_to_lt ? i)
766 [autobatch|assumption]
776 [rewrite > div_p_ord_times
777 [apply divides_to_divides_b_true
780 |apply (divides_b_true_to_lt_O ? ? ? H7).
781 rewrite > (times_n_O O).
783 [assumption|apply lt_O_exp.assumption]
785 |cut (n = ord_rem (n*(exp p m)) p)
787 apply divides_to_divides_ord_rem
788 [apply (divides_b_true_to_lt_O ? ? ? H7).
789 rewrite > (times_n_O O).
791 [assumption|apply lt_O_exp.assumption]
792 |rewrite > (times_n_O O).
794 [assumption|apply lt_O_exp.assumption]
796 |apply divides_b_true_to_divides.
800 rewrite > (p_ord_exp1 p ? m n)
810 |cut (m = ord (n*(exp p m)) p)
813 apply divides_to_le_ord
814 [apply (divides_b_true_to_lt_O ? ? ? H7).
815 rewrite > (times_n_O O).
817 [assumption|apply lt_O_exp.assumption]
818 |rewrite > (times_n_O O).
820 [assumption|apply lt_O_exp.assumption]
822 |apply divides_b_true_to_divides.
826 rewrite > (p_ord_exp1 p ? m n)
836 [rewrite > div_p_ord_times
837 [rewrite > mod_p_ord_times
838 [rewrite > sym_times.
842 |apply (divides_b_true_to_lt_O ? ? ? H7).
843 rewrite > (times_n_O O).
845 [assumption|apply lt_O_exp.assumption]
847 |cut (m = ord (n*(exp p m)) p)
850 apply divides_to_le_ord
851 [apply (divides_b_true_to_lt_O ? ? ? H7).
852 rewrite > (times_n_O O).
854 [assumption|apply lt_O_exp.assumption]
855 |rewrite > (times_n_O O).
857 [assumption|apply lt_O_exp.assumption]
859 |apply divides_b_true_to_divides.
863 rewrite > (p_ord_exp1 p ? m n)
873 |cut (m = ord (n*(exp p m)) p)
876 apply divides_to_le_ord
877 [apply (divides_b_true_to_lt_O ? ? ? H7).
878 rewrite > (times_n_O O).
880 [assumption|apply lt_O_exp.assumption]
881 |rewrite > (times_n_O O).
883 [assumption|apply lt_O_exp.assumption]
885 |apply divides_b_true_to_divides.
889 rewrite > (p_ord_exp1 p ? m n)
898 rewrite > eq_p_ord_times.
900 apply (lt_to_le_to_lt ? (S m +ord_rem j p*S m))
903 cut (m = ord (n*(p \sup m)) p)
905 apply divides_to_le_ord
906 [apply (divides_b_true_to_lt_O ? ? ? H7).
907 rewrite > (times_n_O O).
909 [assumption|apply lt_O_exp.assumption]
910 |rewrite > (times_n_O O).
912 [assumption|apply lt_O_exp.assumption]
914 |apply divides_b_true_to_divides.
919 rewrite > (p_ord_exp1 p ? m n)
926 |change with (S (ord_rem j p)*S m \le S n*S m).
929 cut (n = ord_rem (n*(p \sup m)) p)
934 |rewrite > (times_n_O O).
936 [assumption|apply lt_O_exp.assumption]
938 |apply divides_to_divides_ord_rem
939 [apply (divides_b_true_to_lt_O ? ? ? H7).
940 rewrite > (times_n_O O).
942 [assumption|apply lt_O_exp.assumption]
943 |rewrite > (times_n_O O).
945 [assumption|apply lt_O_exp.assumption]
947 |apply divides_b_true_to_divides.
953 rewrite > (p_ord_exp1 p ? m n)
962 |apply eq_sigma_p_gen
965 elim (divides_b (x/S m) n);reflexivity
969 |elim H1.apply lt_to_le.assumption
973 (*distributive property for sigma_p_gen*)
974 theorem distributive_times_plus_sigma_p_generic: \forall A:Type.
975 \forall plusA: A \to A \to A. \forall basePlusA: A.
976 \forall timesA: A \to A \to A.
977 \forall n:nat. \forall k:A. \forall p:nat \to bool. \forall g:nat \to A.
978 (symmetric A plusA) \to (associative A plusA) \to (\forall a:A.(plusA a basePlusA) = a) \to
979 (symmetric A timesA) \to (distributive A timesA plusA) \to
980 (\forall a:A. (timesA a basePlusA) = basePlusA)
984 ((timesA k (sigma_p_gen n p A g basePlusA plusA)) =
985 (sigma_p_gen n p A (\lambda i:nat.(timesA (g i) k)) basePlusA plusA)).
990 | cut( (p n1) = true \lor (p n1) = false)
992 [ rewrite > (true_to_sigma_p_Sn_gen ? ? ? ? ? ? H7).
993 rewrite > (true_to_sigma_p_Sn_gen ? ? ? ? ? ? H7) in \vdash (? ? ? %).
995 rewrite > (H3 k (g n1)).
998 | rewrite > (false_to_sigma_p_Sn_gen ? ? ? ? ? ? H7).
999 rewrite > (false_to_sigma_p_Sn_gen ? ? ? ? ? ? H7) in \vdash (? ? ? %).