1 (**************************************************************************)
4 (* ||A|| A project by Andrea Asperti *)
6 (* ||I|| Developers: *)
7 (* ||T|| A.Asperti, C.Sacerdoti Coen, *)
8 (* ||A|| E.Tassi, S.Zacchiroli *)
10 (* \ / This file is distributed under the terms of the *)
11 (* v GNU Lesser General Public License Version 2.1 *)
13 (**************************************************************************)
15 set "baseuri" "cic:/matita/nat/iteration2".
17 include "nat/primes.ma".
19 include "nat/generic_iter_p.ma".
20 include "nat/count.ma".(*necessary just to use bool_to_nat and bool_to_nat_andb*)
23 (* sigma_p on nautral numbers is a specialization of sigma_p_gen *)
24 definition sigma_p: nat \to (nat \to bool) \to (nat \to nat) \to nat \def
25 \lambda n, p, g. (iter_p_gen n p nat g O plus).
27 theorem symmetricIntPlus: symmetric nat plus.
28 change with (\forall a,b:nat. (plus a b) = (plus b a)).
34 (*the following theorems on sigma_p in N are obtained by the more general ones
37 theorem true_to_sigma_p_Sn:
38 \forall n:nat. \forall p:nat \to bool. \forall g:nat \to nat.
39 p n = true \to sigma_p (S n) p g =
40 (g n)+(sigma_p n p g).
43 apply true_to_iter_p_gen_Sn.
47 theorem false_to_sigma_p_Sn:
48 \forall n:nat. \forall p:nat \to bool. \forall g:nat \to nat.
49 p n = false \to sigma_p (S n) p g = sigma_p n p g.
52 apply false_to_iter_p_gen_Sn.
56 theorem eq_sigma_p: \forall p1,p2:nat \to bool.
57 \forall g1,g2: nat \to nat.\forall n.
58 (\forall x. x < n \to p1 x = p2 x) \to
59 (\forall x. x < n \to g1 x = g2 x) \to
60 sigma_p n p1 g1 = sigma_p n p2 g2.
67 theorem eq_sigma_p1: \forall p1,p2:nat \to bool.
68 \forall g1,g2: nat \to nat.\forall n.
69 (\forall x. x < n \to p1 x = p2 x) \to
70 (\forall x. x < n \to p1 x = true \to g1 x = g2 x) \to
71 sigma_p n p1 g1 = sigma_p n p2 g2.
78 theorem sigma_p_false:
79 \forall g: nat \to nat.\forall n.sigma_p n (\lambda x.false) g = O.
82 apply iter_p_gen_false.
85 theorem sigma_p_plus: \forall n,k:nat.\forall p:nat \to bool.
86 \forall g: nat \to nat.
88 = sigma_p k (\lambda x.p (x+n)) (\lambda x.g (x+n)) + sigma_p n p g.
91 apply (iter_p_gen_plusA nat n k p g O plus)
92 [ apply symmetricIntPlus.
96 | apply associative_plus
100 theorem false_to_eq_sigma_p: \forall n,m:nat.n \le m \to
101 \forall p:nat \to bool.
102 \forall g: nat \to nat. (\forall i:nat. n \le i \to i < m \to
103 p i = false) \to sigma_p m p g = sigma_p n p g.
106 apply (false_to_eq_iter_p_gen);
112 \forall p1,p2:nat \to bool.
113 \forall g: nat \to nat \to nat.
115 (\lambda x.andb (p1 (div x m)) (p2 (mod x m)))
116 (\lambda x.g (div x m) (mod x m)) =
118 (\lambda x.sigma_p m p2 (g x)).
121 apply (iter_p_gen2 n m p1 p2 nat g O plus)
122 [ apply symmetricIntPlus
123 | apply associative_plus
132 \forall p1:nat \to bool.
133 \forall p2:nat \to nat \to bool.
134 \forall g: nat \to nat \to nat.
136 (\lambda x.andb (p1 (div x m)) (p2 (div x m) (mod x m)))
137 (\lambda x.g (div x m) (mod x m)) =
139 (\lambda x.sigma_p m (p2 x) (g x)).
142 apply (iter_p_gen2' n m p1 p2 nat g O plus)
143 [ apply symmetricIntPlus
144 | apply associative_plus
151 lemma sigma_p_gi: \forall g: nat \to nat.
152 \forall n,i.\forall p:nat \to bool.i < n \to p i = true \to
153 sigma_p n p g = g i + sigma_p n (\lambda x. andb (p x) (notb (eqb x i))) g.
156 apply (iter_p_gen_gi)
157 [ apply symmetricIntPlus
158 | apply associative_plus
167 theorem eq_sigma_p_gh:
168 \forall g,h,h1: nat \to nat.\forall n,n1.
169 \forall p1,p2:nat \to bool.
170 (\forall i. i < n \to p1 i = true \to p2 (h i) = true) \to
171 (\forall i. i < n \to p1 i = true \to h1 (h i) = i) \to
172 (\forall i. i < n \to p1 i = true \to h i < n1) \to
173 (\forall j. j < n1 \to p2 j = true \to p1 (h1 j) = true) \to
174 (\forall j. j < n1 \to p2 j = true \to h (h1 j) = j) \to
175 (\forall j. j < n1 \to p2 j = true \to h1 j < n) \to
176 sigma_p n p1 (\lambda x.g(h x)) = sigma_p n1 p2 g.
179 apply (eq_iter_p_gen_gh nat O plus ? ? ? g h h1 n n1 p1 p2)
180 [ apply symmetricIntPlus
181 | apply associative_plus
196 \forall n:nat. \forall p:nat \to bool. \forall g1,g2:nat \to nat.
197 (\forall i. i < n \to p i = true \to g1 i \le g2 i ) \to
198 sigma_p n p g1 \le sigma_p n p g2.
200 generalize in match H.
203 |apply (bool_elim ? (p n1));intros
204 [rewrite > true_to_sigma_p_Sn
205 [rewrite > true_to_sigma_p_Sn in ⊢ (? ? %)
207 [apply H2[apply le_n|assumption]
210 apply H2[apply le_S.assumption|assumption]
216 |rewrite > false_to_sigma_p_Sn
217 [rewrite > false_to_sigma_p_Sn in ⊢ (? ? %)
220 apply H2[apply le_S.assumption|assumption]
230 \forall n:nat. \forall p:nat \to bool. \forall g1,g2:nat \to nat.
231 (\forall i. i < n \to p i = true \to g1 i \le g2 i ) \to
232 (\exists i. i < n \and (p i = true) \and (g1 i < g2 i)) \to
233 sigma_p n p g1 < sigma_p n p g2.
240 apply (lt_to_not_le ? ? H2).
242 |apply (bool_elim ? (p n1));intros
243 [apply (bool_elim ? (leb (S (g1 n1)) (g2 n1)));intros
244 [rewrite > true_to_sigma_p_Sn
245 [rewrite > true_to_sigma_p_Sn in ⊢ (? ? %)
247 (S (g1 n1)+sigma_p n1 p g1 \le g2 n1+sigma_p n1 p g2).
249 [apply leb_true_to_le.assumption
250 |apply le_sigma_p.intros.
252 [apply lt_to_le.apply le_S_S.assumption
260 |rewrite > true_to_sigma_p_Sn
261 [rewrite > true_to_sigma_p_Sn in ⊢ (? ? %)
271 [apply lt_to_le.apply le_S_S.assumption
277 apply (ex_intro ? ? a).
280 [elim (le_to_or_lt_eq a n1)
282 |absurd (g1 a < g2 a)
284 |apply leb_false_to_not_le.
302 |rewrite > false_to_sigma_p_Sn
303 [rewrite > false_to_sigma_p_Sn in ⊢ (? ? %)
306 [apply lt_to_le.apply le_S_S.assumption
312 apply (ex_intro ? ? a).
315 [elim (le_to_or_lt_eq a n1)
318 apply not_eq_true_false.
339 theorem sigma_p_divides:
340 \forall n,m,p:nat.O < n \to prime p \to Not (divides p n) \to
341 \forall g: nat \to nat.
342 sigma_p (S (n*(exp p m))) (\lambda x.divides_b x (n*(exp p m))) g =
343 sigma_p (S n) (\lambda x.divides_b x n)
344 (\lambda x.sigma_p (S m) (\lambda y.true) (\lambda y.g (x*(exp p y)))).
347 apply (iter_p_gen_divides nat O plus n m p ? ? ? g)
351 | apply symmetricIntPlus
352 | apply associative_plus
359 theorem distributive_times_plus_sigma_p: \forall n,k:nat. \forall p:nat \to bool. \forall g:nat \to nat.
360 k*(sigma_p n p g) = sigma_p n p (\lambda i:nat.k * (g i)).
362 apply (distributive_times_plus_iter_p_gen nat plus O times n k p g)
363 [ apply symmetricIntPlus
364 | apply associative_plus
368 | apply symmetric_times
369 | apply distributive_times_plus
371 rewrite < (times_n_O a).
376 (*some properties of sigma_p invoked with an "always true" predicate (in this
377 way sigma_p just counts the elements, without doing any control) or with
378 the nat \to nat function which always returns (S O).
379 It 's not easily possible proving these theorems in a general form
380 in generic_sigma_p.ma
383 theorem sigma_p_true: \forall n:nat.
384 (sigma_p n (\lambda x.true) (\lambda x.S O)) = n.
389 | rewrite > (true_to_sigma_p_Sn n1 (\lambda x:nat.true) (\lambda x:nat.S O))
398 theorem sigma_P_SO_to_sigma_p_true: \forall n:nat. \forall g:nat \to bool.
399 sigma_p n g (\lambda n:nat. (S O)) =
400 sigma_p n (\lambda x:nat.true) (\lambda i:nat.bool_to_nat (g i)).
405 | cut ((g n1) = true \lor (g n1) = false)
406 [ rewrite > true_to_sigma_p_Sn in \vdash (? ? ? %)
409 rewrite > true_to_sigma_p_Sn in \vdash (? ? % ?)
416 rewrite > false_to_sigma_p_Sn in \vdash (? ? % ?)
434 (* I introduce an equivalence in the form map_iter_i in order to use
435 * the existing result about permutation in that part of the library.
438 theorem eq_map_iter_i_sigma_p_alwaysTrue: \forall n:nat.\forall g:nat \to nat.
439 map_iter_i n g plus O = sigma_p (S n) (\lambda c:nat.true) g.
445 | rewrite > true_to_sigma_p_Sn
446 [ simplify in \vdash (? ? % ?).
455 theorem sigma_p_plus_1: \forall n:nat. \forall f,g:nat \to nat.
456 sigma_p n (\lambda b:nat. true) (\lambda a:nat.(f a) + (g a)) =
457 sigma_p n (\lambda b:nat. true) f + sigma_p n (\lambda b:nat. true) g.
462 | rewrite > true_to_sigma_p_Sn
463 [ rewrite > (true_to_sigma_p_Sn n1 (\lambda c:nat.true) f)
464 [ rewrite > (true_to_sigma_p_Sn n1 (\lambda c:nat.true) g)
465 [ rewrite > assoc_plus in \vdash (? ? ? %).
466 rewrite < assoc_plus in \vdash (? ? ? (? ? %)).
467 rewrite < sym_plus in \vdash (? ? ? (? ? (? % ?))).
468 rewrite > assoc_plus in \vdash (? ? ? (? ? %)).
469 rewrite < assoc_plus in \vdash (? ? ? %).
482 theorem eq_sigma_p_sigma_p_times1 : \forall n,m:nat.\forall f:nat \to nat.
483 sigma_p (n*m) (\lambda x:nat.true) f =
484 sigma_p m (\lambda x:nat.true)
485 (\lambda a.(sigma_p n (\lambda x:nat.true) (\lambda b.f (b*m + a)))).
492 | rewrite > true_to_sigma_p_Sn
498 | change in \vdash (? ? ? (? ? ? (\lambda a:?.%))) with ((f ((n1*m)+a)) +
499 (sigma_p n1 (\lambda x:nat.true) (\lambda b:nat.f (b*m +a)))).
500 rewrite > sigma_p_plus_1 in \vdash (? ? ? %).
501 rewrite > (sym_times (S n1) m).
502 rewrite < (times_n_Sm m n1).
503 rewrite > sigma_p_plus in \vdash (? ? % ?).
505 [ rewrite < (sym_times m n1).
510 rewrite < (sym_plus ? (m * n1)).
513 | rewrite > (sym_times m n1).
519 theorem eq_sigma_p_sigma_p_times2 : \forall n,m:nat.\forall f:nat \to nat.
520 sigma_p (n *m) (\lambda c:nat.true) f =
521 sigma_p n (\lambda c:nat.true)
522 (\lambda a.(sigma_p m (\lambda c:nat.true) (\lambda b:nat.f (b* n + a)))).
525 apply eq_sigma_p_sigma_p_times1.
529 theorem sigma_p_times:\forall n,m:nat.
530 \forall f,f1,f2:nat \to bool.
531 \forall g:nat \to nat \to nat.
532 \forall g1,g2: nat \to nat.
533 (\forall a,b:nat. a < (S n) \to b < (S m) \to (g b a) < (S n)*(S m)) \to
534 (\forall a,b:nat. a < (S n) \to b < (S m) \to (g1 (g b a)) = a) \to
535 (\forall a,b:nat. a < (S n) \to b < (S m) \to (g2 (g b a)) = b) \to
536 (\forall a,b:nat. a < (S n) \to b < (S m) \to f (g b a) = andb (f2 b) (f1 a)) \to
537 (sigma_p ((S n) * (S m)) f (\lambda c:nat.(S O))) =
538 sigma_p (S n) f1 (\lambda c:nat.(S O)) * sigma_p (S m) f2 (\lambda c:nat.(S O)).
541 rewrite > (sigma_P_SO_to_sigma_p_true ).
542 rewrite > (S_pred ((S n)*(S m))) in \vdash (? ? (? % ? ?) ?)
543 [ rewrite < (eq_map_iter_i_sigma_p_alwaysTrue (pred ((S n)* (S m)))).
544 rewrite > (permut_to_eq_map_iter_i plus assoc_plus sym_plus ? ? ?
545 (\lambda i.g (div i (S n)) (mod i (S n))))
546 [ rewrite > eq_map_iter_i_sigma_p_alwaysTrue.
548 [ rewrite > eq_sigma_p_sigma_p_times2.
549 apply (trans_eq ? ? (sigma_p (S n) (\lambda c:nat.true)
550 (\lambda a. sigma_p (S m) (\lambda c:nat.true)
551 (\lambda b.(bool_to_nat (f2 b))*(bool_to_nat (f1 a))))))
552 [ apply eq_sigma_p;intros
554 | apply eq_sigma_p;intros
557 rewrite > (div_mod_spec_to_eq (x1*(S n) + x) (S n) ((x1*(S n) + x)/(S n))
558 ((x1*(S n) + x) \mod (S n)) x1 x)
559 [ rewrite > (div_mod_spec_to_eq2 (x1*(S n) + x) (S n) ((x1*(S n) + x)/(S n))
560 ((x1*(S n) + x) \mod (S n)) x1 x)
562 [ apply bool_to_nat_andb
566 | apply div_mod_spec_div_mod.
573 | apply div_mod_spec_div_mod.
582 | apply (trans_eq ? ?
583 (sigma_p (S n) (\lambda c:nat.true) (\lambda n.((bool_to_nat (f1 n)) *
584 (sigma_p (S m) (\lambda c:nat.true) (\lambda n.bool_to_nat (f2 n)))))))
585 [ apply eq_sigma_p;intros
587 | rewrite > distributive_times_plus_sigma_p.
588 apply eq_sigma_p;intros
590 | rewrite > sym_times.
595 rewrite > sigma_P_SO_to_sigma_p_true.
596 rewrite > sigma_P_SO_to_sigma_p_true in \vdash (? ? (? ? %) ?).
598 rewrite > distributive_times_plus_sigma_p.
599 apply eq_sigma_p;intros
601 | rewrite > distributive_times_plus_sigma_p.
603 rewrite > distributive_times_plus_sigma_p.
609 | apply lt_O_times_S_S
617 rewrite < S_pred in \vdash (? ? %)
618 [ change with ((g (i/(S n)) (i \mod (S n))) \lt (S n)*(S m)).
624 | apply (lt_times_to_lt_l n).
625 apply (le_to_lt_to_lt ? i)
626 [ rewrite > (div_mod i (S n)) in \vdash (? ? %)
627 [ rewrite > sym_plus.
634 rewrite > S_pred in \vdash (? ? %)
636 rewrite > plus_n_O in \vdash (? ? %).
639 | apply lt_O_times_S_S
643 | apply lt_O_times_S_S
645 | rewrite < plus_n_O.
648 cut (i < (S n)*(S m))
649 [ cut (j < (S n)*(S m))
650 [ cut ((i \mod (S n)) < (S n))
651 [ cut ((i/(S n)) < (S m))
652 [ cut ((j \mod (S n)) < (S n))
653 [ cut ((j/(S n)) < (S m))
654 [ rewrite > (div_mod i (S n))
655 [ rewrite > (div_mod j (S n))
656 [ rewrite < (H1 (i \mod (S n)) (i/(S n)) Hcut2 Hcut3).
657 rewrite < (H2 (i \mod (S n)) (i/(S n)) Hcut2 Hcut3) in \vdash (? ? (? % ?) ?).
658 rewrite < (H1 (j \mod (S n)) (j/(S n)) Hcut4 Hcut5).
659 rewrite < (H2 (j \mod (S n)) (j/(S n)) Hcut4 Hcut5) in \vdash (? ? ? (? % ?)).
670 | apply (lt_times_to_lt_l n).
671 apply (le_to_lt_to_lt ? j)
672 [ rewrite > (div_mod j (S n)) in \vdash (? ? %)
673 [ rewrite > sym_plus.
675 | unfold lt. apply le_S_S.
678 | rewrite < sym_times.
687 | apply (lt_times_to_lt_l n).
688 apply (le_to_lt_to_lt ? i)
689 [ rewrite > (div_mod i (S n)) in \vdash (? ? %)
690 [ rewrite > sym_plus.
696 | rewrite < sym_times.
706 rewrite > S_pred in \vdash (? ? %)
709 | apply lt_O_times_S_S
713 rewrite > S_pred in \vdash (? ? %)
716 | apply lt_O_times_S_S
722 apply (not_le_Sn_O m1 H4)
724 | apply lt_O_times_S_S
729 \forall g: nat \to nat.
730 \forall h2:nat \to nat \to nat.
731 \forall h11,h12:nat \to nat.
733 \forall p1,p21:nat \to bool.
734 \forall p22:nat \to nat \to bool.
735 (\forall x. x < k \to p1 x = true \to
736 p21 (h11 x) = true \land p22 (h11 x) (h12 x) = true
737 \land h2 (h11 x) (h12 x) = x
738 \land (h11 x) < n \land (h12 x) < m) \to
739 (\forall i,j. i < n \to j < m \to p21 i = true \to p22 i j = true \to
740 p1 (h2 i j) = true \land
741 h11 (h2 i j) = i \land h12 (h2 i j) = j
742 \land h2 i j < k) \to
744 sigma_p n p21 (\lambda x:nat.sigma_p m (p22 x) (\lambda y. g (h2 x y))).
747 unfold sigma_p in \vdash (? ? ? (? ? ? ? (\lambda x:?.%) ? ?)).
749 [apply symmetricIntPlus
750 |apply associative_plus
751 |intro.rewrite < plus_n_O.reflexivity
761 \forall g: nat \to nat \to nat.
762 \forall h11,h12,h21,h22: nat \to nat \to nat.
764 \forall p11,p21:nat \to bool.
765 \forall p12,p22:nat \to nat \to bool.
766 (\forall i,j. i < n2 \to j < m2 \to p21 i = true \to p22 i j = true \to
767 p11 (h11 i j) = true \land p12 (h11 i j) (h12 i j) = true
768 \land h21 (h11 i j) (h12 i j) = i \land h22 (h11 i j) (h12 i j) = j
769 \land h11 i j < n1 \land h12 i j < m1) \to
770 (\forall i,j. i < n1 \to j < m1 \to p11 i = true \to p12 i j = true \to
771 p21 (h21 i j) = true \land p22 (h21 i j) (h22 i j) = true
772 \land h11 (h21 i j) (h22 i j) = i \land h12 (h21 i j) (h22 i j) = j
773 \land (h21 i j) < n2 \land (h22 i j) < m2) \to
774 sigma_p n1 p11 (\lambda x:nat .sigma_p m1 (p12 x) (\lambda y. g x y)) =
775 sigma_p n2 p21 (\lambda x:nat .sigma_p m2 (p22 x) (\lambda y. g (h11 x y) (h12 x y))).
778 unfold sigma_p in \vdash (? ? (? ? ? ? (\lambda x:?.%) ? ?) ?).
779 unfold sigma_p in \vdash (? ? ? (? ? ? ? (\lambda x:?.%) ? ?)).
781 apply(iter_p_gen_2_eq nat O plus ? ? ? g h11 h12 h21 h22 n1 m1 n2 m2 p11 p21 p12 p22)
782 [ apply symmetricIntPlus
783 | apply associative_plus
785 rewrite < (plus_n_O).