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/Z/sigma_p.ma".
18 include "nat/primes.ma".
21 let rec sigma_p n p (g:nat \to Z) \def
26 [true \Rightarrow (g k)+(sigma_p k p g)
27 |false \Rightarrow sigma_p k p g]
30 theorem true_to_sigma_p_Sn:
31 \forall n:nat. \forall p:nat \to bool. \forall g:nat \to Z.
32 p n = true \to sigma_p (S n) p g =
33 (g n)+(sigma_p n p g).
35 rewrite > H.reflexivity.
38 theorem false_to_sigma_p_Sn:
39 \forall n:nat. \forall p:nat \to bool. \forall g:nat \to Z.
40 p n = false \to sigma_p (S n) p g = sigma_p n p g.
42 rewrite > H.reflexivity.
45 theorem eq_sigma_p: \forall p1,p2:nat \to bool.
46 \forall g1,g2: nat \to Z.\forall n.
47 (\forall x. x < n \to p1 x = p2 x) \to
48 (\forall x. x < n \to g1 x = g2 x) \to
49 sigma_p n p1 g1 = sigma_p n p2 g2.
52 |apply (bool_elim ? (p1 n1))
54 rewrite > (true_to_sigma_p_Sn ? ? ? H3).
55 rewrite > true_to_sigma_p_Sn
59 [intros.apply H1.apply le_S.assumption
60 |intros.apply H2.apply le_S.assumption
63 |rewrite < H3.apply sym_eq.apply H1.apply le_n
66 rewrite > (false_to_sigma_p_Sn ? ? ? H3).
67 rewrite > false_to_sigma_p_Sn
69 [intros.apply H1.apply le_S.assumption
70 |intros.apply H2.apply le_S.assumption
72 |rewrite < H3.apply sym_eq.apply H1.apply le_n
78 theorem eq_sigma_p1: \forall p1,p2:nat \to bool.
79 \forall g1,g2: nat \to Z.\forall n.
80 (\forall x. x < n \to p1 x = p2 x) \to
81 (\forall x. x < n \to p1 x = true \to g1 x = g2 x) \to
82 sigma_p n p1 g1 = sigma_p n p2 g2.
86 |apply (bool_elim ? (p1 n1))
88 rewrite > (true_to_sigma_p_Sn ? ? ? H3).
89 rewrite > true_to_sigma_p_Sn
92 [apply le_n|assumption]
94 [intros.apply H1.apply le_S.assumption
96 [apply le_S.assumption|assumption]
99 |rewrite < H3.apply sym_eq.apply H1.apply le_n
102 rewrite > (false_to_sigma_p_Sn ? ? ? H3).
103 rewrite > false_to_sigma_p_Sn
105 [intros.apply H1.apply le_S.assumption
107 [apply le_S.assumption|assumption]
109 |rewrite < H3.apply sym_eq.apply H1.apply le_n
115 theorem sigma_p_false:
116 \forall g: nat \to Z.\forall n.sigma_p n (\lambda x.false) g = O.
118 elim n[reflexivity|simplify.assumption]
121 theorem sigma_p_plus: \forall n,k:nat.\forall p:nat \to bool.
122 \forall g: nat \to Z.
124 = sigma_p k (\lambda x.p (x+n)) (\lambda x.g (x+n)) + sigma_p n p g.
128 |apply (bool_elim ? (p (n1+n)))
130 simplify in \vdash (? ? (? % ? ?) ?).
131 rewrite > (true_to_sigma_p_Sn ? ? ? H1).
132 rewrite > (true_to_sigma_p_Sn n1 (\lambda x.p (x+n)) ? H1).
133 rewrite > assoc_Zplus.
134 rewrite < H.reflexivity
136 simplify in \vdash (? ? (? % ? ?) ?).
137 rewrite > (false_to_sigma_p_Sn ? ? ? H1).
138 rewrite > (false_to_sigma_p_Sn n1 (\lambda x.p (x+n)) ? H1).
144 theorem false_to_eq_sigma_p: \forall n,m:nat.n \le m \to
145 \forall p:nat \to bool.
146 \forall g: nat \to Z. (\forall i:nat. n \le i \to i < m \to
147 p i = false) \to sigma_p m p g = sigma_p n p g.
156 apply H3[apply H4|apply le_S.assumption]
165 \forall p1,p2:nat \to bool.
166 \forall g: nat \to nat \to Z.
168 (\lambda x.andb (p1 (div x m)) (p2 (mod x m)))
169 (\lambda x.g (div x m) (mod x m)) =
171 (\lambda x.sigma_p m p2 (g x)).
174 [simplify.reflexivity
175 |apply (bool_elim ? (p1 n1))
177 rewrite > (true_to_sigma_p_Sn ? ? ? H1).
178 simplify in \vdash (? ? (? % ? ?) ?);
179 rewrite > sigma_p_plus.
185 rewrite > (div_plus_times ? ? ? H2).
186 rewrite > (mod_plus_times ? ? ? H2).
191 rewrite > (div_plus_times ? ? ? H2).
192 rewrite > (mod_plus_times ? ? ? H2).
194 simplify.reflexivity.
199 rewrite > (false_to_sigma_p_Sn ? ? ? H1).
200 simplify in \vdash (? ? (? % ? ?) ?);
201 rewrite > sigma_p_plus.
203 apply (trans_eq ? ? (O+(sigma_p n1 p1 (\lambda x:nat.sigma_p m p2 (g x)))))
205 [rewrite > (eq_sigma_p ? (\lambda x.false) ? (\lambda x:nat.g ((x+n1*m)/m) ((x+n1*m)\mod m)))
209 rewrite > (div_plus_times ? ? ? H2).
210 rewrite > (mod_plus_times ? ? ? H2).
223 (* a stronger, dependent version, required e.g. for dirichlet product *)
226 \forall p1:nat \to bool.
227 \forall p2:nat \to nat \to bool.
228 \forall g: nat \to nat \to Z.
230 (\lambda x.andb (p1 (div x m)) (p2 (div x m) (mod x m)))
231 (\lambda x.g (div x m) (mod x m)) =
233 (\lambda x.sigma_p m (p2 x) (g x)).
236 [simplify.reflexivity
237 |apply (bool_elim ? (p1 n1))
239 rewrite > (true_to_sigma_p_Sn ? ? ? H1).
240 simplify in \vdash (? ? (? % ? ?) ?);
241 rewrite > sigma_p_plus.
247 rewrite > (div_plus_times ? ? ? H2).
248 rewrite > (mod_plus_times ? ? ? H2).
253 rewrite > (div_plus_times ? ? ? H2).
254 rewrite > (mod_plus_times ? ? ? H2).
256 simplify.reflexivity.
261 rewrite > (false_to_sigma_p_Sn ? ? ? H1).
262 simplify in \vdash (? ? (? % ? ?) ?);
263 rewrite > sigma_p_plus.
265 apply (trans_eq ? ? (O+(sigma_p n1 p1 (\lambda x:nat.sigma_p m (p2 x) (g x)))))
267 [rewrite > (eq_sigma_p ? (\lambda x.false) ? (\lambda x:nat.g ((x+n1*m)/m) ((x+n1*m)\mod m)))
271 rewrite > (div_plus_times ? ? ? H2).
272 rewrite > (mod_plus_times ? ? ? H2).
285 lemma sigma_p_gi: \forall g: nat \to Z.
286 \forall n,i.\forall p:nat \to bool.i < n \to p i = true \to
287 sigma_p n p g = g i + sigma_p n (\lambda x. andb (p x) (notb (eqb x i))) g.
291 apply (not_le_Sn_O i).
293 |apply (bool_elim ? (p n1));intro
294 [elim (le_to_or_lt_eq i n1)
295 [rewrite > true_to_sigma_p_Sn
296 [rewrite > true_to_sigma_p_Sn
297 [rewrite < assoc_Zplus.
298 rewrite < sym_Zplus in \vdash (? ? ? (? % ?)).
299 rewrite > assoc_Zplus.
302 |apply H[assumption|assumption]
304 |rewrite > H3.simplify.
305 change with (notb (eqb n1 i) = notb false).
307 apply not_eq_to_eqb_false.
309 apply (lt_to_not_eq ? ? H4).
310 apply sym_eq.assumption
314 |rewrite > true_to_sigma_p_Sn
318 |rewrite > false_to_sigma_p_Sn
323 change with (notb false = notb (eqb x n1)).
326 apply not_eq_to_eqb_false.
327 apply (lt_to_not_eq ? ? H5)
333 rewrite > (eq_to_eqb_true ? ? (refl_eq ? n1)).
339 |apply le_S_S_to_le.assumption
341 |rewrite > false_to_sigma_p_Sn
342 [elim (le_to_or_lt_eq i n1)
343 [rewrite > false_to_sigma_p_Sn
344 [apply H[assumption|assumption]
345 |rewrite > H3.reflexivity
348 apply not_eq_true_false.
352 |apply le_S_S_to_le.assumption
360 theorem eq_sigma_p_gh:
361 \forall g: nat \to Z.
362 \forall h,h1: nat \to nat.\forall n,n1.
363 \forall p1,p2:nat \to bool.
364 (\forall i. i < n \to p1 i = true \to p2 (h i) = true) \to
365 (\forall i. i < n \to p1 i = true \to h1 (h i) = i) \to
366 (\forall i. i < n \to p1 i = true \to h i < n1) \to
367 (\forall j. j < n1 \to p2 j = true \to p1 (h1 j) = true) \to
368 (\forall j. j < n1 \to p2 j = true \to h (h1 j) = j) \to
369 (\forall j. j < n1 \to p2 j = true \to h1 j < n) \to
370 sigma_p n p1 (\lambda x.g(h x)) = sigma_p n1 (\lambda x.p2 x) g.
373 [generalize in match H5.
376 |apply (bool_elim ? (p2 n2));intro
378 apply (not_le_Sn_O (h1 n2)).
380 [apply le_n|assumption]
381 |rewrite > false_to_sigma_p_Sn
384 apply H7[apply le_S.apply H9|assumption]
389 |apply (bool_elim ? (p1 n1));intro
390 [rewrite > true_to_sigma_p_Sn
391 [rewrite > (sigma_p_gi g n2 (h n1))
398 change with ((\not eqb (h i) (h n1))= \not false).
400 apply not_eq_to_eqb_false.
402 apply (lt_to_not_eq ? ? H8).
405 [apply eq_f.assumption|apply le_n|assumption]
406 |apply le_S.assumption
409 |apply le_S.assumption
413 apply H2[apply le_S.assumption|assumption]
415 apply H3[apply le_S.assumption|assumption]
419 |generalize in match H9.
421 [reflexivity|assumption]
426 |generalize in match H9.
428 [reflexivity|assumption]
431 elim (le_to_or_lt_eq (h1 j) n1)
433 |generalize in match H9.
439 [reflexivity|assumption|auto]
440 |apply eqb_false_to_not_eq.
441 generalize in match H11.
443 [apply sym_eq.assumption|reflexivity]
447 apply not_eq_true_false.
448 apply sym_eq.assumption
453 |generalize in match H9.
455 [reflexivity|assumption]
460 |apply H3[apply le_n|assumption]
461 |apply H1[apply le_n|assumption]
465 |rewrite > false_to_sigma_p_Sn
467 [intros.apply H1[apply le_S.assumption|assumption]
468 |intros.apply H2[apply le_S.assumption|assumption]
469 |intros.apply H3[apply le_S.assumption|assumption]
470 |intros.apply H4[assumption|assumption]
471 |intros.apply H5[assumption|assumption]
473 elim (le_to_or_lt_eq (h1 j) n1)
478 [reflexivity|assumption|assumption]
480 apply not_eq_true_false.
484 [reflexivity|assumption|assumption]
487 apply H6[assumption|assumption]
496 (* sigma_p and Ztimes *)
497 lemma Ztimes_sigma_pl: \forall z:Z.\forall n:nat.\forall p. \forall f.
498 z * (sigma_p n p f) = sigma_p n p (\lambda i.z*(f i)).
501 [rewrite > Ztimes_z_OZ.reflexivity
502 |apply (bool_elim ? (p n1)); intro
503 [rewrite > true_to_sigma_p_Sn
504 [rewrite > true_to_sigma_p_Sn
506 apply distr_Ztimes_Zplus
511 |rewrite > false_to_sigma_p_Sn
512 [rewrite > false_to_sigma_p_Sn
522 lemma Ztimes_sigma_pr: \forall z:Z.\forall n:nat.\forall p. \forall f.
523 (sigma_p n p f) * z = sigma_p n p (\lambda i.(f i)*z).
525 rewrite < sym_Ztimes.
526 rewrite > Ztimes_sigma_pl.
529 |intros.apply sym_Ztimes
533 theorem divides_exp_to_lt_ord:\forall n,m,j,p. O < n \to prime p \to
534 p \ndivides n \to j \divides n*(exp p m) \to ord j p < S m.
536 cut (m = ord (n*(exp p m)) p)
539 apply divides_to_le_ord
540 [elim (le_to_or_lt_eq ? ? (le_O_n j))
543 apply (lt_to_not_eq ? ? H).
545 rewrite < H4 in H5.simplify in H5.
546 elim (times_O_to_O ? ? H5)
547 [apply sym_eq.assumption
549 apply (not_le_Sn_n O).
550 rewrite < H6 in \vdash (? ? %).
552 elim H1.apply lt_to_le.assumption
555 |rewrite > (times_n_O O).
557 [assumption|apply lt_O_exp.apply (prime_to_lt_O ? H1)]
562 rewrite > (p_ord_exp1 p ? m n)
564 |apply (prime_to_lt_O ? H1)
571 theorem divides_exp_to_divides_ord_rem:\forall n,m,j,p. O < n \to prime p \to
572 p \ndivides n \to j \divides n*(exp p m) \to ord_rem j p \divides n.
575 [cut (n = ord_rem (n*(exp p m)) p)
577 apply divides_to_divides_ord_rem
579 |rewrite > (times_n_O O).
581 [assumption|apply lt_O_exp.apply (prime_to_lt_O ? H1)]
586 rewrite > (p_ord_exp1 p ? m n)
588 |apply (prime_to_lt_O ? H1)
593 |elim (le_to_or_lt_eq ? ? (le_O_n j))
596 apply (lt_to_not_eq ? ? H).
598 rewrite < H4 in H5.simplify in H5.
599 elim (times_O_to_O ? ? H5)
600 [apply sym_eq.assumption
602 apply (not_le_Sn_n O).
603 rewrite < H6 in \vdash (? ? %).
605 elim H1.apply lt_to_le.assumption
611 theorem sigma_p_divides_b:
612 \forall n,m,p:nat.O < n \to prime p \to Not (divides p n) \to
613 \forall g: nat \to Z.
614 sigma_p (S (n*(exp p m))) (\lambda x.divides_b x (n*(exp p m))) g =
615 sigma_p (S n) (\lambda x.divides_b x n)
616 (\lambda x.sigma_p (S m) (\lambda y.true) (\lambda y.g (x*(exp p y)))).
621 (sigma_p (S n*S m) (\lambda x:nat.divides_b (x/S m) n)
622 (\lambda x:nat.g (x/S m*(p)\sup(x\mod S m)))))
624 apply (eq_sigma_p_gh g ? (p_ord_inv p (S m)))
626 lapply (divides_b_true_to_lt_O ? ? H H4).
627 apply divides_to_divides_b_true
628 [rewrite > (times_n_O O).
631 |apply lt_O_exp.assumption
634 [apply divides_b_true_to_divides.assumption
635 |apply (witness ? ? (p \sup (m-i \mod (S m)))).
636 rewrite < exp_plus_times.
639 apply plus_minus_m_m.
644 lapply (divides_b_true_to_lt_O ? ? H H4).
646 rewrite > (p_ord_exp1 p ? (i \mod (S m)) (i/S m))
647 [change with ((i/S m)*S m+i \mod S m=i).
654 apply (trans_divides ? (i/ S m))
656 apply divides_b_true_to_divides;assumption]
663 change with ((i/S m) < S n).
664 apply (lt_times_to_lt_l m).
665 apply (le_to_lt_to_lt ? i)
676 [rewrite > div_p_ord_inv
677 [apply divides_to_divides_b_true
680 |apply (divides_b_true_to_lt_O ? ? ? H4).
681 rewrite > (times_n_O O).
683 [assumption|apply lt_O_exp.assumption]
685 |apply (divides_exp_to_divides_ord_rem ? m ? ? H H1 H2).
686 apply divides_b_true_to_divides.
691 |apply (divides_exp_to_lt_ord ? ? ? ? H H1 H2).
692 apply (divides_b_true_to_divides ? ? H4).
693 apply (divides_b_true_to_lt_O ? ? H4)
697 [rewrite > div_p_ord_inv
698 [rewrite > mod_p_ord_inv
699 [rewrite > sym_times.
703 |apply (divides_b_true_to_lt_O ? ? ? H4).
704 rewrite > (times_n_O O).
706 [assumption|apply lt_O_exp.assumption]
708 |apply (divides_exp_to_lt_ord ? ? ? ? H H1 H2).
709 apply (divides_b_true_to_divides ? ? H4).
710 apply (divides_b_true_to_lt_O ? ? H4)
714 |apply (divides_exp_to_lt_ord ? ? ? ? H H1 H2).
715 apply (divides_b_true_to_divides ? ? H4).
716 apply (divides_b_true_to_lt_O ? ? H4).
719 rewrite > eq_p_ord_inv.
721 apply (lt_to_le_to_lt ? (S m +ord_rem j p*S m))
724 cut (m = ord (n*(p \sup m)) p)
726 apply divides_to_le_ord
727 [apply (divides_b_true_to_lt_O ? ? ? H4).
728 rewrite > (times_n_O O).
730 [assumption|apply lt_O_exp.assumption]
731 |rewrite > (times_n_O O).
733 [assumption|apply lt_O_exp.assumption]
735 |apply divides_b_true_to_divides.
740 rewrite > (p_ord_exp1 p ? m n)
747 |change with (S (ord_rem j p)*S m \le S n*S m).
752 |apply (divides_exp_to_divides_ord_rem ? m ? ? H H1 H2).
753 apply divides_b_true_to_divides.
760 elim (divides_b (x/S m) n);reflexivity
764 |elim H1.apply lt_to_le.assumption