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_iter_p".
17 include "nat/primes.ma".
20 (*a generic definition of summatory indexed over natural numbers:
21 * n:N is the advanced end in the range of the sommatory
22 * p: N -> bool is a predicate. if (p i) = true, then (g i) is summed, else it isn't
23 * A is the type of the elements of the sum.
24 * g:nat -> A, is the function which associates the nth element of the sum to the nth natural numbers
25 * baseA (of type A) is the neutral element of A for plusA operation
26 * plusA: A -> A -> A is the sum over elements in A.
29 let rec iter_p_gen (n:nat) (p: nat \to bool) (A:Type) (g: nat \to A)
30 (baseA: A) (plusA: A \to A \to A) \def
35 [true \Rightarrow (plusA (g k) (iter_p_gen k p A g baseA plusA))
36 |false \Rightarrow iter_p_gen k p A g baseA plusA]
39 theorem true_to_iter_p_gen_Sn:
40 \forall n:nat. \forall p:nat \to bool. \forall A:Type. \forall g:nat \to A.
41 \forall baseA:A. \forall plusA: A \to A \to A.
42 p n = true \to iter_p_gen (S n) p A g baseA plusA =
43 (plusA (g n) (iter_p_gen n p A g baseA plusA)).
52 theorem false_to_iter_p_gen_Sn:
53 \forall n:nat. \forall p:nat \to bool. \forall A:Type. \forall g:nat \to A.
54 \forall baseA:A. \forall plusA: A \to A \to A.
55 p n = false \to iter_p_gen (S n) p A g baseA plusA = iter_p_gen n p A g baseA plusA.
63 theorem eq_iter_p_gen: \forall p1,p2:nat \to bool. \forall A:Type.
64 \forall g1,g2: nat \to A. \forall baseA: A.
65 \forall plusA: A \to A \to A. \forall n:nat.
66 (\forall x. x < n \to p1 x = p2 x) \to
67 (\forall x. x < n \to g1 x = g2 x) \to
68 iter_p_gen n p1 A g1 baseA plusA = iter_p_gen n p2 A g2 baseA plusA.
72 | apply (bool_elim ? (p1 n1))
74 rewrite > (true_to_iter_p_gen_Sn ? ? ? ? ? ? H3).
75 rewrite > true_to_iter_p_gen_Sn
77 [ apply H2.apply le_n.
79 [ intros.apply H1.apply le_S.assumption
80 | intros.apply H2.apply le_S.assumption
83 | rewrite < H3.apply sym_eq.apply H1.apply le_n
86 rewrite > (false_to_iter_p_gen_Sn ? ? ? ? ? ? H3).
87 rewrite > false_to_iter_p_gen_Sn
89 [ intros.apply H1.apply le_S.assumption
90 | intros.apply H2.apply le_S.assumption
92 | rewrite < H3.apply sym_eq.apply H1.apply le_n
98 theorem eq_iter_p_gen1: \forall p1,p2:nat \to bool. \forall A:Type.
99 \forall g1,g2: nat \to A. \forall baseA: A.
100 \forall plusA: A \to A \to A.\forall n:nat.
101 (\forall x. x < n \to p1 x = p2 x) \to
102 (\forall x. x < n \to p1 x = true \to g1 x = g2 x) \to
103 iter_p_gen n p1 A g1 baseA plusA = iter_p_gen n p2 A g2 baseA plusA.
107 | apply (bool_elim ? (p1 n1))
109 rewrite > (true_to_iter_p_gen_Sn ? ? ? ? ? ? H3).
110 rewrite > true_to_iter_p_gen_Sn
117 [ intros.apply H1.apply le_S.assumption
119 [ apply le_S.assumption
125 apply sym_eq.apply H1.apply le_n
128 rewrite > (false_to_iter_p_gen_Sn ? ? ? ? ? ? H3).
129 rewrite > false_to_iter_p_gen_Sn
131 [ intros.apply H1.apply le_S.assumption
133 [ apply le_S.assumption
137 | rewrite < H3.apply sym_eq.
144 theorem iter_p_gen_false: \forall A:Type. \forall g: nat \to A. \forall baseA:A.
145 \forall plusA: A \to A \to A. \forall n.
146 iter_p_gen n (\lambda x.false) A g baseA plusA = baseA.
155 theorem iter_p_gen_plusA: \forall A:Type. \forall n,k:nat.\forall p:nat \to bool.
156 \forall g: nat \to A. \forall baseA:A. \forall plusA: A \to A \to A.
157 (symmetric A plusA) \to (\forall a:A. (plusA a baseA) = a) \to (associative A plusA)
159 iter_p_gen (k + n) p A g baseA plusA
160 = (plusA (iter_p_gen k (\lambda x.p (x+n)) A (\lambda x.g (x+n)) baseA plusA)
161 (iter_p_gen n p A g baseA plusA)).
165 [ rewrite < (plus_n_O n).
167 rewrite > H in \vdash (? ? ? %).
170 | apply (bool_elim ? (p (n1+n)))
172 rewrite > (true_to_iter_p_gen_Sn ? ? ? ? ? ? H4).
173 rewrite > (true_to_iter_p_gen_Sn n1 (\lambda x.p (x+n)) ? ? ? ? H4).
174 rewrite > (H2 (g (n1 + n)) ? ?).
178 rewrite > (false_to_iter_p_gen_Sn ? ? ? ? ? ? H4).
179 rewrite > (false_to_iter_p_gen_Sn n1 (\lambda x.p (x+n)) ? ? ? ? H4).
185 theorem false_to_eq_iter_p_gen: \forall A:Type. \forall n,m:nat.\forall p:nat \to bool.
186 \forall g: nat \to A. \forall baseA:A. \forall plusA: A \to A \to A.
187 n \le m \to (\forall i:nat. n \le i \to i < m \to p i = false)
188 \to iter_p_gen m p A g baseA plusA = iter_p_gen n p A g baseA plusA.
208 theorem iter_p_gen2 :
210 \forall p1,p2:nat \to bool.
212 \forall g: nat \to nat \to A.
214 \forall plusA: A \to A \to A.
215 (symmetric A plusA) \to (associative A plusA) \to (\forall a:A.(plusA a baseA) = a)
218 (\lambda x.andb (p1 (div x m)) (p2 (mod x m)))
220 (\lambda x.g (div x m) (mod x m))
224 (\lambda x.iter_p_gen m p2 A (g x) baseA plusA)
230 | apply (bool_elim ? (p1 n1))
232 rewrite > (true_to_iter_p_gen_Sn ? ? ? ? ? ? H4).
233 simplify in \vdash (? ? (? % ? ? ? ? ?) ?).
234 rewrite > iter_p_gen_plusA
237 [ apply eq_iter_p_gen
240 rewrite > (div_plus_times ? ? ? H5).
241 rewrite > (mod_plus_times ? ? ? H5).
247 rewrite > (div_plus_times ? ? ? H5).
248 rewrite > (mod_plus_times ? ? ? H5).
250 simplify.reflexivity.
259 rewrite > (false_to_iter_p_gen_Sn ? ? ? ? ? ? H4).
260 simplify in \vdash (? ? (? % ? ? ? ? ?) ?).
261 rewrite > iter_p_gen_plusA
263 apply (trans_eq ? ? (plusA baseA
264 (iter_p_gen n1 p1 A (\lambda x:nat.iter_p_gen m p2 A (g x) baseA plusA) baseA plusA )))
266 [ rewrite > (eq_iter_p_gen ? (\lambda x.false) A ? (\lambda x:nat.g ((x+n1*m)/m) ((x+n1*m)\mod m)))
267 [ apply iter_p_gen_false
270 rewrite > (div_plus_times ? ? ? H5).
271 rewrite > (mod_plus_times ? ? ? H5).
274 | intros.reflexivity.
290 theorem iter_p_gen2':
292 \forall p1: nat \to bool.
293 \forall p2: nat \to nat \to bool.
295 \forall g: nat \to nat \to A.
297 \forall plusA: A \to A \to A.
298 (symmetric A plusA) \to (associative A plusA) \to (\forall a:A.(plusA a baseA) = a)
301 (\lambda x.andb (p1 (div x m)) (p2 (div x m)(mod x m)))
303 (\lambda x.g (div x m) (mod x m))
307 (\lambda x.iter_p_gen m (p2 x) A (g x) baseA plusA)
313 | apply (bool_elim ? (p1 n1))
315 rewrite > (true_to_iter_p_gen_Sn ? ? ? ? ? ? H4).
316 simplify in \vdash (? ? (? % ? ? ? ? ?) ?).
317 rewrite > iter_p_gen_plusA
320 [ apply eq_iter_p_gen
323 rewrite > (div_plus_times ? ? ? H5).
324 rewrite > (mod_plus_times ? ? ? H5).
330 rewrite > (div_plus_times ? ? ? H5).
331 rewrite > (mod_plus_times ? ? ? H5).
333 simplify.reflexivity.
342 rewrite > (false_to_iter_p_gen_Sn ? ? ? ? ? ? H4).
343 simplify in \vdash (? ? (? % ? ? ? ? ?) ?).
344 rewrite > iter_p_gen_plusA
346 apply (trans_eq ? ? (plusA baseA
347 (iter_p_gen n1 p1 A (\lambda x:nat.iter_p_gen m (p2 x) A (g x) baseA plusA) baseA plusA )))
349 [ rewrite > (eq_iter_p_gen ? (\lambda x.false) A ? (\lambda x:nat.g ((x+n1*m)/m) ((x+n1*m)\mod m)))
350 [ apply iter_p_gen_false
353 rewrite > (div_plus_times ? ? ? H5).
354 rewrite > (mod_plus_times ? ? ? H5).
357 | intros.reflexivity.
375 \forall g: nat \to A.
377 \forall plusA: A \to A \to A.
379 \forall p:nat \to bool.
380 (symmetric A plusA) \to (associative A plusA) \to (\forall a:A.(plusA a baseA) = a)
383 i < n \to p i = true \to
384 (iter_p_gen n p A g baseA plusA) =
385 (plusA (g i) (iter_p_gen n (\lambda x:nat. andb (p x) (notb (eqb x i))) A g baseA plusA)).
389 apply (not_le_Sn_O i).
391 | apply (bool_elim ? (p n1));intro
392 [ elim (le_to_or_lt_eq i n1)
393 [ rewrite > true_to_iter_p_gen_Sn
394 [ rewrite > true_to_iter_p_gen_Sn
395 [ rewrite < (H2 (g i) ? ?).
396 rewrite > (H1 (g i) (g n1)).
397 rewrite > (H2 (g n1) ? ?).
408 | rewrite > H6.simplify.
409 change with (notb (eqb n1 i) = notb false).
411 apply not_eq_to_eqb_false.
413 apply (lt_to_not_eq ? ? H7).
414 apply sym_eq.assumption
418 | rewrite > true_to_iter_p_gen_Sn
422 | rewrite > false_to_iter_p_gen_Sn
423 [ apply eq_iter_p_gen
427 change with (notb false = notb (eqb x n1)).
430 apply not_eq_to_eqb_false.
431 apply (lt_to_not_eq ? ? H8)
438 rewrite > (eq_to_eqb_true ? ? (refl_eq ? n1)).
444 | apply le_S_S_to_le.
447 | rewrite > false_to_iter_p_gen_Sn
448 [ elim (le_to_or_lt_eq i n1)
449 [ rewrite > false_to_iter_p_gen_Sn
457 | rewrite > H6.reflexivity
460 apply not_eq_true_false.
464 | apply le_S_S_to_le.
473 (* invariance under permutation; single sum *)
474 theorem eq_iter_p_gen_gh:
477 \forall plusA: A \to A \to A.
478 (symmetric A plusA) \to (associative A plusA) \to (\forall a:A.(plusA a baseA) = a) \to
479 \forall g: nat \to A.
480 \forall h,h1: nat \to nat.
482 \forall p1,p2:nat \to bool.
483 (\forall i. i < n \to p1 i = true \to p2 (h i) = true) \to
484 (\forall i. i < n \to p1 i = true \to h1 (h i) = i) \to
485 (\forall i. i < n \to p1 i = true \to h i < n1) \to
486 (\forall j. j < n1 \to p2 j = true \to p1 (h1 j) = true) \to
487 (\forall j. j < n1 \to p2 j = true \to h (h1 j) = j) \to
488 (\forall j. j < n1 \to p2 j = true \to h1 j < n) \to
490 iter_p_gen n p1 A (\lambda x.g(h x)) baseA plusA =
491 iter_p_gen n1 p2 A g baseA plusA.
494 [ generalize in match H8.
497 | apply (bool_elim ? (p2 n2));intro
499 apply (not_le_Sn_O (h1 n2)).
504 | rewrite > false_to_iter_p_gen_Sn
516 | apply (bool_elim ? (p1 n1));intro
517 [ rewrite > true_to_iter_p_gen_Sn
518 [ rewrite > (iter_p_gen_gi A g baseA plusA n2 (h n1))
525 change with ((\not eqb (h i) (h n1))= \not false).
527 apply not_eq_to_eqb_false.
530 apply (lt_to_not_eq ? ? H11).
542 | apply le_S.assumption
553 [ apply le_S.assumption
559 | generalize in match H12.
568 | generalize in match H12.
575 elim (le_to_or_lt_eq (h1 j) n1)
577 | generalize in match H12.
587 | apply eqb_false_to_not_eq.
588 generalize in match H14.
590 [ apply sym_eq.assumption
596 apply not_eq_true_false.
597 apply sym_eq.assumption
599 | apply le_S_S_to_le.
602 | generalize in match H12.
625 | rewrite > false_to_iter_p_gen_Sn
628 apply H4[apply le_S.assumption|assumption]
630 apply H5[apply le_S.assumption|assumption]
632 apply H6[apply le_S.assumption|assumption]
634 apply H7[assumption|assumption]
636 apply H8[assumption|assumption]
638 elim (le_to_or_lt_eq (h1 j) n1)
640 | absurd (j = (h n1))
648 apply not_eq_true_false.
657 | apply le_S_S_to_le.
673 definition p_ord_times \def
676 [pair q r \Rightarrow r*m+q].
678 theorem eq_p_ord_times: \forall p,m,x.
679 p_ord_times p m x = (ord_rem x p)*m+(ord x p).
680 intros.unfold p_ord_times. unfold ord_rem.
686 theorem div_p_ord_times:
687 \forall p,m,x. ord x p < m \to p_ord_times p m x / m = ord_rem x p.
688 intros.rewrite > eq_p_ord_times.
689 apply div_plus_times.
693 theorem mod_p_ord_times:
694 \forall p,m,x. ord x p < m \to p_ord_times p m x \mod m = ord x p.
695 intros.rewrite > eq_p_ord_times.
696 apply mod_plus_times.
700 lemma lt_times_to_lt_O: \forall i,n,m:nat. i < n*m \to O < m.
702 elim (le_to_or_lt_eq O ? (le_O_n m))
706 rewrite < times_n_O in H.
707 apply (not_le_Sn_O ? H)
711 (* lemmino da postare *)
712 theorem lt_times_to_lt_div: \forall i,n,m. i < n*m \to i/m < n.
715 [apply (lt_times_n_to_lt m)
717 |apply (le_to_lt_to_lt ? i)
718 [rewrite > (div_mod i m) in \vdash (? ? %).
724 |apply (lt_times_to_lt_O ? ? ? H)
728 theorem iter_p_gen_knm:
731 \forall plusA: A \to A \to A.
732 (symmetric A plusA) \to
733 (associative A plusA) \to
734 (\forall a:A.(plusA a baseA) = a)\to
735 \forall g: nat \to A.
736 \forall h2:nat \to nat \to nat.
737 \forall h11,h12:nat \to nat.
739 \forall p1,p21:nat \to bool.
740 \forall p22:nat \to nat \to bool.
741 (\forall x. x < k \to p1 x = true \to
742 p21 (h11 x) = true \land p22 (h11 x) (h12 x) = true
743 \land h2 (h11 x) (h12 x) = x
744 \land (h11 x) < n \land (h12 x) < m) \to
745 (\forall i,j. i < n \to j < m \to p21 i = true \to p22 i j = true \to
746 p1 (h2 i j) = true \land
747 h11 (h2 i j) = i \land h12 (h2 i j) = j
748 \land h2 i j < k) \to
749 iter_p_gen k p1 A g baseA plusA =
750 iter_p_gen n p21 A (\lambda x:nat.iter_p_gen m (p22 x) A (\lambda y. g (h2 x y)) baseA plusA) baseA plusA.
752 rewrite < (iter_p_gen2' n m p21 p22 ? ? ? ? H H1 H2).
754 apply (eq_iter_p_gen_gh A baseA plusA H H1 H2 g ? (\lambda x.(h11 x)*m+(h12 x)))
756 elim (H4 (i/m) (i \mod m));clear H4
760 |apply (lt_times_to_lt_div ? ? ? H5)
762 apply (lt_times_to_lt_O ? ? ? H5)
763 |apply (andb_true_true ? ? H6)
764 |apply (andb_true_true_r ? ? H6)
767 elim (H4 (i/m) (i \mod m));clear H4
774 apply (lt_times_to_lt_O ? ? ? H5)
775 |apply (lt_times_to_lt_div ? ? ? H5)
777 apply (lt_times_to_lt_O ? ? ? H5)
778 |apply (andb_true_true ? ? H6)
779 |apply (andb_true_true_r ? ? H6)
782 elim (H4 (i/m) (i \mod m));clear H4
786 |apply (lt_times_to_lt_div ? ? ? H5)
788 apply (lt_times_to_lt_O ? ? ? H5)
789 |apply (andb_true_true ? ? H6)
790 |apply (andb_true_true_r ? ? H6)
797 rewrite > div_plus_times
798 [rewrite > mod_plus_times
811 rewrite > div_plus_times
812 [rewrite > mod_plus_times
823 apply (lt_to_le_to_lt ? ((h11 j)*m+m))
824 [apply monotonic_lt_plus_r.
827 change with ((S (h11 j)*m) \le n*m).
828 apply monotonic_le_times_l.
834 theorem iter_p_gen_divides:
837 \forall plusA: A \to A \to A.
838 \forall n,m,p:nat.O < n \to prime p \to Not (divides p n) \to
839 \forall g: nat \to A.
840 (symmetric A plusA) \to (associative A plusA) \to (\forall a:A.(plusA a baseA) = a)
844 iter_p_gen (S (n*(exp p m))) (\lambda x.divides_b x (n*(exp p m))) A g baseA plusA =
845 iter_p_gen (S n) (\lambda x.divides_b x n) A
846 (\lambda x.iter_p_gen (S m) (\lambda y.true) A (\lambda y.g (x*(exp p y))) baseA plusA) baseA plusA.
849 [rewrite < (iter_p_gen2 ? ? ? ? ? ? ? ? H3 H4 H5).
851 (iter_p_gen (S n*S m) (\lambda x:nat.divides_b (x/S m) n) A
852 (\lambda x:nat.g (x/S m*(p)\sup(x\mod S m))) baseA plusA) )
854 apply (eq_iter_p_gen_gh ? ? ? ? ? ? g ? (p_ord_times p (S m)))
859 lapply (divides_b_true_to_lt_O ? ? H H7).
860 apply divides_to_divides_b_true
861 [rewrite > (times_n_O O).
864 |apply lt_O_exp.assumption
867 [apply divides_b_true_to_divides.assumption
868 |apply (witness ? ? (p \sup (m-i \mod (S m)))).
869 rewrite < exp_plus_times.
872 apply plus_minus_m_m.
877 lapply (divides_b_true_to_lt_O ? ? H H7).
879 rewrite > (p_ord_exp1 p ? (i \mod (S m)) (i/S m))
880 [change with ((i/S m)*S m+i \mod S m=i).
887 apply (trans_divides ? (i/ S m))
889 apply divides_b_true_to_divides;assumption]
896 change with ((i/S m) < S n).
897 apply (lt_times_to_lt_l m).
898 apply (le_to_lt_to_lt ? i)
899 [autobatch|assumption]
909 [rewrite > div_p_ord_times
910 [apply divides_to_divides_b_true
913 |apply (divides_b_true_to_lt_O ? ? ? H7).
914 rewrite > (times_n_O O).
916 [assumption|apply lt_O_exp.assumption]
918 |cut (n = ord_rem (n*(exp p m)) p)
920 apply divides_to_divides_ord_rem
921 [apply (divides_b_true_to_lt_O ? ? ? H7).
922 rewrite > (times_n_O O).
924 [assumption|apply lt_O_exp.assumption]
925 |rewrite > (times_n_O O).
927 [assumption|apply lt_O_exp.assumption]
929 |apply divides_b_true_to_divides.
933 rewrite > (p_ord_exp1 p ? m n)
943 |cut (m = ord (n*(exp p m)) p)
946 apply divides_to_le_ord
947 [apply (divides_b_true_to_lt_O ? ? ? H7).
948 rewrite > (times_n_O O).
950 [assumption|apply lt_O_exp.assumption]
951 |rewrite > (times_n_O O).
953 [assumption|apply lt_O_exp.assumption]
955 |apply divides_b_true_to_divides.
959 rewrite > (p_ord_exp1 p ? m n)
969 [rewrite > div_p_ord_times
970 [rewrite > mod_p_ord_times
971 [rewrite > sym_times.
975 |apply (divides_b_true_to_lt_O ? ? ? H7).
976 rewrite > (times_n_O O).
978 [assumption|apply lt_O_exp.assumption]
980 |cut (m = ord (n*(exp p m)) p)
983 apply divides_to_le_ord
984 [apply (divides_b_true_to_lt_O ? ? ? H7).
985 rewrite > (times_n_O O).
987 [assumption|apply lt_O_exp.assumption]
988 |rewrite > (times_n_O O).
990 [assumption|apply lt_O_exp.assumption]
992 |apply divides_b_true_to_divides.
996 rewrite > (p_ord_exp1 p ? m n)
1006 |cut (m = ord (n*(exp p m)) p)
1009 apply divides_to_le_ord
1010 [apply (divides_b_true_to_lt_O ? ? ? H7).
1011 rewrite > (times_n_O O).
1013 [assumption|apply lt_O_exp.assumption]
1014 |rewrite > (times_n_O O).
1016 [assumption|apply lt_O_exp.assumption]
1018 |apply divides_b_true_to_divides.
1022 rewrite > (p_ord_exp1 p ? m n)
1031 rewrite > eq_p_ord_times.
1033 apply (lt_to_le_to_lt ? (S m +ord_rem j p*S m))
1036 cut (m = ord (n*(p \sup m)) p)
1038 apply divides_to_le_ord
1039 [apply (divides_b_true_to_lt_O ? ? ? H7).
1040 rewrite > (times_n_O O).
1042 [assumption|apply lt_O_exp.assumption]
1043 |rewrite > (times_n_O O).
1045 [assumption|apply lt_O_exp.assumption]
1047 |apply divides_b_true_to_divides.
1051 rewrite > sym_times.
1052 rewrite > (p_ord_exp1 p ? m n)
1059 |change with (S (ord_rem j p)*S m \le S n*S m).
1062 cut (n = ord_rem (n*(p \sup m)) p)
1067 |rewrite > (times_n_O O).
1069 [assumption|apply lt_O_exp.assumption]
1071 |apply divides_to_divides_ord_rem
1072 [apply (divides_b_true_to_lt_O ? ? ? H7).
1073 rewrite > (times_n_O O).
1075 [assumption|apply lt_O_exp.assumption]
1076 |rewrite > (times_n_O O).
1078 [assumption|apply lt_O_exp.assumption]
1080 |apply divides_b_true_to_divides.
1085 rewrite > sym_times.
1086 rewrite > (p_ord_exp1 p ? m n)
1095 |apply eq_iter_p_gen
1098 elim (divides_b (x/S m) n);reflexivity
1102 |elim H1.apply lt_to_le.assumption
1106 (*distributive property for iter_p_gen*)
1107 theorem distributive_times_plus_iter_p_gen: \forall A:Type.
1108 \forall plusA: A \to A \to A. \forall basePlusA: A.
1109 \forall timesA: A \to A \to A.
1110 \forall n:nat. \forall k:A. \forall p:nat \to bool. \forall g:nat \to A.
1111 (symmetric A plusA) \to (associative A plusA) \to (\forall a:A.(plusA a basePlusA) = a) \to
1112 (symmetric A timesA) \to (distributive A timesA plusA) \to
1113 (\forall a:A. (timesA a basePlusA) = basePlusA)
1117 ((timesA k (iter_p_gen n p A g basePlusA plusA)) =
1118 (iter_p_gen n p A (\lambda i:nat.(timesA k (g i))) basePlusA plusA)).
1123 | cut( (p n1) = true \lor (p n1) = false)
1125 [ rewrite > (true_to_iter_p_gen_Sn ? ? ? ? ? ? H7).
1126 rewrite > (true_to_iter_p_gen_Sn ? ? ? ? ? ? H7) in \vdash (? ? ? %).
1128 rewrite > (H3 k (g n1)).
1131 | rewrite > (false_to_iter_p_gen_Sn ? ? ? ? ? ? H7).
1132 rewrite > (false_to_iter_p_gen_Sn ? ? ? ? ? ? H7) in \vdash (? ? ? %).
1145 (* old version - proved without theorem iter_p_gen_knm
1146 theorem iter_p_gen_2_eq:
1149 \forall plusA: A \to A \to A.
1150 (symmetric A plusA) \to
1151 (associative A plusA) \to
1152 (\forall a:A.(plusA a baseA) = a)\to
1153 \forall g: nat \to nat \to A.
1154 \forall h11,h12,h21,h22: nat \to nat \to nat.
1155 \forall n1,m1,n2,m2.
1156 \forall p11,p21:nat \to bool.
1157 \forall p12,p22:nat \to nat \to bool.
1158 (\forall i,j. i < n2 \to j < m2 \to p21 i = true \to p22 i j = true \to
1159 p11 (h11 i j) = true \land p12 (h11 i j) (h12 i j) = true
1160 \land h21 (h11 i j) (h12 i j) = i \land h22 (h11 i j) (h12 i j) = j
1161 \land h11 i j < n1 \land h12 i j < m1) \to
1162 (\forall i,j. i < n1 \to j < m1 \to p11 i = true \to p12 i j = true \to
1163 p21 (h21 i j) = true \land p22 (h21 i j) (h22 i j) = true
1164 \land h11 (h21 i j) (h22 i j) = i \land h12 (h21 i j) (h22 i j) = j
1165 \land (h21 i j) < n2 \land (h22 i j) < m2) \to
1167 (\lambda x:nat .iter_p_gen m1 (p12 x) A (\lambda y. g x y) baseA plusA)
1170 (\lambda x:nat .iter_p_gen m2 (p22 x) A (\lambda y. g (h11 x y) (h12 x y)) baseA plusA )
1173 rewrite < (iter_p_gen2' ? ? ? ? ? ? ? ? H H1 H2).
1174 rewrite < (iter_p_gen2' ? ? ? ? ? ? ? ? H H1 H2).
1176 letin h := (\lambda x.(h11 (x/m2) (x\mod m2))*m1 + (h12 (x/m2) (x\mod m2))).
1177 letin h1 := (\lambda x.(h21 (x/m1) (x\mod m1))*m2 + (h22 (x/m1) (x\mod m1))).
1179 (iter_p_gen (n2*m2) (\lambda x:nat.p21 (x/m2)\land p22 (x/m2) (x\mod m2)) A
1180 (\lambda x:nat.g ((h x)/m1) ((h x)\mod m1)) baseA plusA ))
1182 apply eq_iter_p_gen1
1187 [cut (x \mod m2 < m2)
1188 [elim (and_true ? ? H6).
1189 elim (H3 ? ? Hcut1 Hcut2 H7 H8).
1196 apply div_plus_times.
1199 apply mod_plus_times.
1205 |apply (lt_times_n_to_lt m2)
1207 |apply (le_to_lt_to_lt ? x)
1208 [apply (eq_plus_to_le ? ? (x \mod m2)).
1215 |apply not_le_to_lt.unfold.intro.
1216 generalize in match H5.
1217 apply (le_n_O_elim ? H7).
1218 rewrite < times_n_O.
1223 |apply (eq_iter_p_gen_gh ? ? ? H H1 H2 ? h h1);intros
1226 [cut (i \mod m2 < m2)
1227 [elim (and_true ? ? H6).
1228 elim (H3 ? ? Hcut1 Hcut2 H7 H8).
1233 cut ((h11 (i/m2) (i\mod m2)*m1+h12 (i/m2) (i\mod m2))/m1 =
1234 h11 (i/m2) (i\mod m2))
1235 [cut ((h11 (i/m2) (i\mod m2)*m1+h12 (i/m2) (i\mod m2))\mod m1 =
1236 h12 (i/m2) (i\mod m2))
1242 |apply mod_plus_times.
1245 |apply div_plus_times.
1251 |apply (lt_times_n_to_lt m2)
1253 |apply (le_to_lt_to_lt ? i)
1254 [apply (eq_plus_to_le ? ? (i \mod m2)).
1261 |apply not_le_to_lt.unfold.intro.
1262 generalize in match H5.
1263 apply (le_n_O_elim ? H7).
1264 rewrite < times_n_O.
1270 [cut (i \mod m2 < m2)
1271 [elim (and_true ? ? H6).
1272 elim (H3 ? ? Hcut1 Hcut2 H7 H8).
1277 cut ((h11 (i/m2) (i\mod m2)*m1+h12 (i/m2) (i\mod m2))/m1 =
1278 h11 (i/m2) (i\mod m2))
1279 [cut ((h11 (i/m2) (i\mod m2)*m1+h12 (i/m2) (i\mod m2))\mod m1 =
1280 h12 (i/m2) (i\mod m2))
1288 |apply mod_plus_times.
1291 |apply div_plus_times.
1297 |apply (lt_times_n_to_lt m2)
1299 |apply (le_to_lt_to_lt ? i)
1300 [apply (eq_plus_to_le ? ? (i \mod m2)).
1307 |apply not_le_to_lt.unfold.intro.
1308 generalize in match H5.
1309 apply (le_n_O_elim ? H7).
1310 rewrite < times_n_O.
1316 [cut (i \mod m2 < m2)
1317 [elim (and_true ? ? H6).
1318 elim (H3 ? ? Hcut1 Hcut2 H7 H8).
1323 apply lt_times_plus_times
1324 [assumption|assumption]
1328 |apply (lt_times_n_to_lt m2)
1330 |apply (le_to_lt_to_lt ? i)
1331 [apply (eq_plus_to_le ? ? (i \mod m2)).
1338 |apply not_le_to_lt.unfold.intro.
1339 generalize in match H5.
1340 apply (le_n_O_elim ? H7).
1341 rewrite < times_n_O.
1347 [cut (j \mod m1 < m1)
1348 [elim (and_true ? ? H6).
1349 elim (H4 ? ? Hcut1 Hcut2 H7 H8).
1354 cut ((h21 (j/m1) (j\mod m1)*m2+h22 (j/m1) (j\mod m1))/m2 =
1355 h21 (j/m1) (j\mod m1))
1356 [cut ((h21 (j/m1) (j\mod m1)*m2+h22 (j/m1) (j\mod m1))\mod m2 =
1357 h22 (j/m1) (j\mod m1))
1363 |apply mod_plus_times.
1366 |apply div_plus_times.
1372 |apply (lt_times_n_to_lt m1)
1374 |apply (le_to_lt_to_lt ? j)
1375 [apply (eq_plus_to_le ? ? (j \mod m1)).
1382 |apply not_le_to_lt.unfold.intro.
1383 generalize in match H5.
1384 apply (le_n_O_elim ? H7).
1385 rewrite < times_n_O.
1391 [cut (j \mod m1 < m1)
1392 [elim (and_true ? ? H6).
1393 elim (H4 ? ? Hcut1 Hcut2 H7 H8).
1398 cut ((h21 (j/m1) (j\mod m1)*m2+h22 (j/m1) (j\mod m1))/m2 =
1399 h21 (j/m1) (j\mod m1))
1400 [cut ((h21 (j/m1) (j\mod m1)*m2+h22 (j/m1) (j\mod m1))\mod m2 =
1401 h22 (j/m1) (j\mod m1))
1409 |apply mod_plus_times.
1412 |apply div_plus_times.
1418 |apply (lt_times_n_to_lt m1)
1420 |apply (le_to_lt_to_lt ? j)
1421 [apply (eq_plus_to_le ? ? (j \mod m1)).
1428 |apply not_le_to_lt.unfold.intro.
1429 generalize in match H5.
1430 apply (le_n_O_elim ? H7).
1431 rewrite < times_n_O.
1437 [cut (j \mod m1 < m1)
1438 [elim (and_true ? ? H6).
1439 elim (H4 ? ? Hcut1 Hcut2 H7 H8).
1444 apply (lt_times_plus_times ? ? ? m2)
1445 [assumption|assumption]
1449 |apply (lt_times_n_to_lt m1)
1451 |apply (le_to_lt_to_lt ? j)
1452 [apply (eq_plus_to_le ? ? (j \mod m1)).
1459 |apply not_le_to_lt.unfold.intro.
1460 generalize in match H5.
1461 apply (le_n_O_elim ? H7).
1462 rewrite < times_n_O.
1471 theorem iter_p_gen_2_eq:
1474 \forall plusA: A \to A \to A.
1475 (symmetric A plusA) \to
1476 (associative A plusA) \to
1477 (\forall a:A.(plusA a baseA) = a)\to
1478 \forall g: nat \to nat \to A.
1479 \forall h11,h12,h21,h22: nat \to nat \to nat.
1480 \forall n1,m1,n2,m2.
1481 \forall p11,p21:nat \to bool.
1482 \forall p12,p22:nat \to nat \to bool.
1483 (\forall i,j. i < n2 \to j < m2 \to p21 i = true \to p22 i j = true \to
1484 p11 (h11 i j) = true \land p12 (h11 i j) (h12 i j) = true
1485 \land h21 (h11 i j) (h12 i j) = i \land h22 (h11 i j) (h12 i j) = j
1486 \land h11 i j < n1 \land h12 i j < m1) \to
1487 (\forall i,j. i < n1 \to j < m1 \to p11 i = true \to p12 i j = true \to
1488 p21 (h21 i j) = true \land p22 (h21 i j) (h22 i j) = true
1489 \land h11 (h21 i j) (h22 i j) = i \land h12 (h21 i j) (h22 i j) = j
1490 \land (h21 i j) < n2 \land (h22 i j) < m2) \to
1492 (\lambda x:nat .iter_p_gen m1 (p12 x) A (\lambda y. g x y) baseA plusA)
1495 (\lambda x:nat .iter_p_gen m2 (p22 x) A (\lambda y. g (h11 x y) (h12 x y)) baseA plusA )
1499 rewrite < (iter_p_gen2' ? ? ? ? ? ? ? ? H H1 H2).
1500 letin ha:= (\lambda x,y.(((h11 x y)*m1) + (h12 x y))).
1501 letin ha12:= (\lambda x.(h21 (x/m1) (x \mod m1))).
1502 letin ha22:= (\lambda x.(h22 (x/m1) (x \mod m1))).
1505 (iter_p_gen n2 p21 A (\lambda x:nat. iter_p_gen m2 (p22 x) A
1506 (\lambda y:nat.(g (((h11 x y)*m1+(h12 x y))/m1) (((h11 x y)*m1+(h12 x y))\mod m1))) baseA plusA ) baseA plusA))
1508 apply (iter_p_gen_knm A baseA plusA H H1 H2 (\lambda e. (g (e/m1) (e \mod m1))) ha ha12 ha22);intros
1509 [ elim (and_true ? ? H6).
1512 [ cut((x \mod m1) < m1)
1513 [ elim (H4 ? ? Hcut1 Hcut2 H7 H8).
1538 | apply (lt_times_n_to_lt m1)
1540 | apply (le_to_lt_to_lt ? x)
1541 [ apply (eq_plus_to_le ? ? (x \mod m1)).
1548 | apply not_le_to_lt.unfold.intro.
1549 generalize in match H5.
1550 apply (le_n_O_elim ? H9).
1551 rewrite < times_n_O.
1555 | elim (H3 ? ? H5 H6 H7 H8).
1560 cut(((h11 i j)*m1 + (h12 i j))/m1 = (h11 i j))
1561 [ cut(((h11 i j)*m1 + (h12 i j)) \mod m1 = (h12 i j))
1565 [ apply true_to_true_to_andb_true
1582 [ apply (lt_to_le_to_lt ? ((h11 i j)*m1 + m1) )
1583 [ apply (lt_plus_r).
1585 | rewrite > sym_plus.
1586 rewrite > (sym_times (h11 i j) m1).
1587 rewrite > times_n_Sm.
1588 rewrite > sym_times.
1592 | apply not_le_to_lt.unfold.intro.
1593 generalize in match H12.
1594 apply (le_n_O_elim ? H11).
1598 | apply not_le_to_lt.unfold.intro.
1599 generalize in match H10.
1600 apply (le_n_O_elim ? H11).
1605 | rewrite > (mod_plus_times m1 (h11 i j) (h12 i j)).
1609 | rewrite > (div_plus_times m1 (h11 i j) (h12 i j)).
1614 | apply (eq_iter_p_gen1)
1615 [ intros. reflexivity
1617 apply (eq_iter_p_gen1)
1618 [ intros. reflexivity
1620 rewrite > (div_plus_times)
1621 [ rewrite > (mod_plus_times)
1623 | elim (H3 x x1 H5 H7 H6 H8).
1626 | elim (H3 x x1 H5 H7 H6 H8).