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 (* \ / Matita is distributed under the terms of the *)
11 (* v GNU Lesser General Public License Version 2.1 *)
13 (**************************************************************************)
15 include "datatypes/constructors.ma".
17 include "nat/nth_prime.ma".
18 include "nat/gcd.ma". (* for some properties of divides *)
19 include "nat/relevant_equations.ma". (* required by autobatch paramod *)
21 let rec p_ord_aux p n m \def
25 [ O \Rightarrow pair nat nat O n
27 match (p_ord_aux p (n / m) m) with
28 [ (pair q r) \Rightarrow pair nat nat (S q) r] ]
29 | (S a) \Rightarrow pair nat nat O n].
31 (* p_ord n m = <q,r> if m divides n q times, with remainder r *)
32 definition p_ord \def \lambda n,m:nat.p_ord_aux n n m.
34 theorem p_ord_aux_to_Prop: \forall p,n,m. O < m \to
35 match p_ord_aux p n m with
36 [ (pair q r) \Rightarrow n = m \sup q *r ].
39 apply (nat_case (n \mod m)).
40 simplify.apply plus_n_O.
42 simplify.apply plus_n_O.
44 apply (nat_case1 (n1 \mod m)).intro.
46 generalize in match (H (n1 / m) m).
47 elim (p_ord_aux n (n1 / m) m).
49 rewrite > assoc_times.
50 rewrite < H3.rewrite > (plus_n_O (m*(n1 / m))).
53 rewrite < div_mod.reflexivity.
54 assumption.assumption.
55 intros.simplify.apply plus_n_O.
58 theorem p_ord_aux_to_exp: \forall p,n,m,q,r. O < m \to
59 (pair nat nat q r) = p_ord_aux p n m \to n = m \sup q * r.
62 match (pair nat nat q r) with
63 [ (pair q r) \Rightarrow n = m \sup q * r ].
65 apply p_ord_aux_to_Prop.
69 (* questo va spostato in primes1.ma *)
70 theorem p_ord_exp: \forall n,m,i. O < m \to n \mod m \neq O \to
71 \forall p. i \le p \to p_ord_aux p (m \sup i * n) m = pair nat nat i n.
78 elim (n \mod m).simplify.reflexivity.simplify.reflexivity.
81 cut (O < n \mod m \lor O = n \mod m).
82 elim Hcut.apply (lt_O_n_elim (n \mod m) H3).
83 intros. simplify.reflexivity.
85 apply H1.apply sym_eq.assumption.
86 apply le_to_or_lt_eq.apply le_O_n.
87 generalize in match H3.
88 apply (nat_case p).intro.apply False_ind.apply (not_le_Sn_O n1 H4).
90 simplify. fold simplify (m \sup (S n1)).
91 cut (((m \sup (S n1)*n) \mod m) = O).
93 simplify.fold simplify (m \sup (S n1)).
94 cut ((m \sup (S n1) *n) / m = m \sup n1 *n).
96 rewrite > (H2 m1). simplify.reflexivity.
97 apply le_S_S_to_le.assumption.
100 rewrite > assoc_times.
101 apply (lt_O_n_elim m H).
102 intro.apply div_times.
104 apply divides_to_mod_O.
106 simplify.rewrite > assoc_times.
107 apply (witness ? ? (m \sup n1 *n)).reflexivity.
110 theorem p_ord_aux_to_Prop1: \forall p,n,m. (S O) < m \to O < n \to n \le p \to
111 match p_ord_aux p n m with
112 [ (pair q r) \Rightarrow r \mod m \neq O].
113 intro.elim p.absurd (O < n).assumption.
114 apply le_to_not_lt.assumption.
116 apply (nat_case1 (n1 \mod m)).intro.
117 generalize in match (H (n1 / m) m).
118 elim (p_ord_aux n (n1 / m) m).
120 apply eq_mod_O_to_lt_O_div.
121 apply (trans_lt ? (S O)).unfold lt.apply le_n.
122 assumption.assumption.assumption.
124 apply (trans_le ? n1).change with (n1 / m < n1).
125 apply lt_div_n_m_n.assumption.assumption.assumption.
129 apply (not_eq_O_S m1).
130 rewrite > H5.reflexivity.
133 theorem p_ord_aux_to_not_mod_O: \forall p,n,m,q,r. (S O) < m \to O < n \to n \le p \to
134 pair nat nat q r = p_ord_aux p n m \to r \mod m \neq O.
137 match (pair nat nat q r) with
138 [ (pair q r) \Rightarrow r \mod m \neq O].
140 apply p_ord_aux_to_Prop1.
141 assumption.assumption.assumption.
144 theorem p_ord_exp1: \forall p,n,q,r. O < p \to \lnot p \divides r \to
145 n = p \sup q * r \to p_ord n p = pair nat nat q r.
150 |unfold.intro.apply H1.
151 apply mod_O_to_divides[assumption|assumption]
152 |apply (trans_le ? (p \sup q)).
154 elim q.simplify.apply le_n_Sn.
156 generalize in match H3.
157 apply (nat_case n1).simplify.
158 rewrite < times_n_SO.intro.assumption.
160 apply (trans_le ? (p*(S m))).
161 apply (trans_le ? ((S (S O))*(S m))).
162 simplify.rewrite > plus_n_Sm.
167 apply le_times_r.assumption.
168 apply not_eq_to_le_to_lt.
169 unfold.intro.apply H1.
171 apply (witness ? r r ?).simplify.apply plus_n_O.
173 rewrite > times_n_SO in \vdash (? % ?).
175 change with (O \lt r).
176 apply not_eq_to_le_to_lt.
178 apply H1.rewrite < H3.
179 apply (witness ? ? O ?).rewrite < times_n_O.reflexivity.
184 theorem p_ord_to_exp1: \forall p,n,q,r. (S O) \lt p \to O \lt n \to p_ord n p = pair nat nat q r\to
185 \lnot p \divides r \land n = p \sup q * r.
189 apply (p_ord_aux_to_not_mod_O n n p q r).assumption.assumption.
190 apply le_n.symmetry.assumption.
191 apply divides_to_mod_O.apply (trans_lt ? (S O)).
192 unfold.apply le_n.assumption.assumption.
193 apply (p_ord_aux_to_exp n).apply (trans_lt ? (S O)).
194 unfold.apply le_n.assumption.symmetry.assumption.
197 theorem p_ord_times: \forall p,a,b,qa,ra,qb,rb. prime p
198 \to O \lt a \to O \lt b
199 \to p_ord a p = pair nat nat qa ra
200 \to p_ord b p = pair nat nat qb rb
201 \to p_ord (a*b) p = pair nat nat (qa + qb) (ra*rb).
204 elim (p_ord_to_exp1 ? ? ? ? Hcut H1 H3).
205 elim (p_ord_to_exp1 ? ? ? ? Hcut H2 H4).
207 apply (trans_lt ? (S O)).unfold.apply le_n.assumption.
209 elim (divides_times_to_divides ? ? ? H H9).
210 apply (absurd ? ? H10 H5).
211 apply (absurd ? ? H10 H7).
214 autobatch paramodulation.
215 unfold prime in H. elim H. assumption.
218 theorem fst_p_ord_times: \forall p,a,b. prime p
219 \to O \lt a \to O \lt b
220 \to fst ? ? (p_ord (a*b) p) = (fst ? ? (p_ord a p)) + (fst ? ? (p_ord b p)).
222 rewrite > (p_ord_times p a b (fst ? ? (p_ord a p)) (snd ? ? (p_ord a p))
223 (fst ? ? (p_ord b p)) (snd ? ? (p_ord b p)) H H1 H2).
224 simplify.reflexivity.
225 apply eq_pair_fst_snd.
226 apply eq_pair_fst_snd.
229 theorem p_ord_p : \forall p:nat. (S O) \lt p \to p_ord p p = pair ? ? (S O) (S O).
232 apply (trans_lt ? (S O)). unfold.apply le_n.assumption.
234 apply (absurd ? ? H).
236 apply divides_to_le.unfold.apply le_n.assumption.
237 rewrite < times_n_SO.
241 (* p_ord and divides *)
242 theorem divides_to_p_ord: \forall p,a,b,c,d,n,m:nat.
243 O < n \to O < m \to prime p
244 \to divides n m \to p_ord n p = pair ? ? a b \to
245 p_ord m p = pair ? ? c d \to divides b d \land a \le c.
248 [lapply (p_ord_to_exp1 ? ? ? ? Hcut H H4).
249 lapply (p_ord_to_exp1 ? ? ? ? Hcut H1 H5).
250 elim Hletin. clear Hletin.
251 elim Hletin1. clear Hletin1.
254 [apply (gcd_SO_to_divides_times_to_divides (exp p c))
255 [elim (le_to_or_lt_eq ? ? (le_O_n b))
258 apply (lt_to_not_eq O ? H).
267 apply eq_gcd_times_SO
268 [apply lt_to_le.assumption
269 |apply lt_O_exp.apply lt_to_le.assumption
271 (* hint non trova prime_to_gcd_SO e
272 autobatch non chiude il goal *)
273 apply prime_to_gcd_SO
274 [assumption|assumption]
278 |apply (trans_divides ? n)
279 [apply (witness ? ? (exp p a)).
285 |apply (le_exp_to_le p)
288 [apply lt_O_exp.apply lt_to_le.assumption
289 |apply (gcd_SO_to_divides_times_to_divides d)
290 [apply lt_O_exp.apply lt_to_le.assumption
293 |simplify.rewrite < sym_gcd.
294 apply eq_gcd_times_SO
295 [apply lt_to_le.assumption
296 |apply lt_O_exp.apply lt_to_le.assumption
298 (* hint non trova prime_to_gcd_SO e
299 autobatch non chiude il goal *)
300 apply prime_to_gcd_SO
301 [assumption|assumption]
302 |rewrite > sym_gcd. assumption
305 |apply (trans_divides ? n)
306 [apply (witness ? ? b).assumption
307 |rewrite > sym_times.assumption
317 (* p_ord and primes *)
318 theorem not_divides_to_p_ord_O: \forall n,i.
319 Not (divides (nth_prime i) n) \to p_ord n (nth_prime i) =
323 [apply lt_O_nth_prime_n
329 theorem p_ord_O_to_not_divides: \forall n,i,r.
331 p_ord n (nth_prime i) = pair nat nat O r
332 \to Not (divides (nth_prime i) n).
334 lapply (p_ord_to_exp1 ? ? ? ? ? ? H1)
335 [apply lt_SO_nth_prime_n
345 theorem p_ord_to_not_eq_O : \forall n,p,q,r.
347 p_ord n (nth_prime p) = pair nat nat q r \to
352 [lapply (p_ord_to_exp1 ? ? ? ? ? ? H1)
353 [apply lt_SO_nth_prime_n.
356 apply (lt_to_not_eq ? ? Hcut).
361 |apply (trans_lt ? (S O))[apply lt_O_S|assumption]
365 definition ord :nat \to nat \to nat \def
366 \lambda n,p. fst ? ? (p_ord n p).
368 definition ord_rem :nat \to nat \to nat \def
369 \lambda n,p. snd ? ? (p_ord n p).
371 theorem divides_to_ord: \forall p,n,m:nat.
372 O < n \to O < m \to prime p
374 \to divides (ord_rem n p) (ord_rem m p) \land (ord n p) \le (ord m p).
376 apply (divides_to_p_ord p ? ? ? ? n m H H1 H2 H3)
377 [unfold ord.unfold ord_rem.apply eq_pair_fst_snd
378 |unfold ord.unfold ord_rem.apply eq_pair_fst_snd
382 theorem divides_to_divides_ord_rem: \forall p,n,m:nat.
383 O < n \to O < m \to prime p \to divides n m \to
384 divides (ord_rem n p) (ord_rem m p).
386 elim (divides_to_ord p n m H H1 H2 H3).assumption.
389 theorem divides_to_le_ord: \forall p,n,m:nat.
390 O < n \to O < m \to prime p \to divides n m \to
391 (ord n p) \le (ord m p).
393 elim (divides_to_ord p n m H H1 H2 H3).assumption.
396 theorem exp_ord: \forall p,n. (S O) \lt p
397 \to O \lt n \to n = p \sup (ord n p) * (ord_rem n p).
399 elim (p_ord_to_exp1 p n (ord n p) (ord_rem n p))
403 |unfold ord.unfold ord_rem.
404 apply eq_pair_fst_snd
408 theorem divides_ord_rem: \forall p,n. (S O) < p \to O < n
409 \to divides (ord_rem n p) n.
411 apply (witness ? ? (p \sup (ord n p))).
413 apply exp_ord[assumption|assumption]
416 theorem lt_O_ord_rem: \forall p,n. (S O) < p \to O < n \to O < ord_rem n p.
418 elim (le_to_or_lt_eq O (ord_rem n p))
421 apply (lt_to_not_eq ? ? H1).
422 lapply (divides_ord_rem ? ? H H1).
423 rewrite < H2 in Hletin.
431 (* properties of ord e ord_rem *)
433 theorem ord_times: \forall p,m,n.O<m \to O<n \to prime p \to
434 ord (m*n) p = ord m p+ord n p.
436 rewrite > (p_ord_times ? ? ? (ord m p) (ord_rem m p) (ord n p) (ord_rem n p))
441 |unfold ord.unfold ord_rem.apply eq_pair_fst_snd
442 |unfold ord.unfold ord_rem.apply eq_pair_fst_snd
446 theorem ord_exp: \forall p,m.S O < p \to
450 rewrite > (p_ord_exp1 p (exp p m) m (S O))
452 |apply lt_to_le.assumption
453 |intro.apply (lt_to_not_le ? ? H).
462 theorem not_divides_to_ord_O:
463 \forall p,m. prime p \to \lnot (divides p m) \to
466 rewrite > (p_ord_exp1 p m O m)
468 |apply prime_to_lt_O.assumption
470 |simplify.apply plus_n_O
474 theorem ord_O_to_not_divides:
475 \forall p,m. O < m \to prime p \to ord m p = O \to
478 lapply (p_ord_to_exp1 p m (ord m p) (ord_rem m p))
483 rewrite < times_n_SO.
485 |apply prime_to_lt_SO.assumption
487 |unfold ord.unfold ord_rem.apply eq_pair_fst_snd
491 theorem divides_to_not_ord_O:
492 \forall p,m. O < m \to prime p \to divides p m \to
495 apply (ord_O_to_not_divides ? ? H H1 H3).
499 theorem not_ord_O_to_divides:
500 \forall p,m. O < m \to prime p \to \lnot (ord m p = O) \to
503 rewrite > (exp_ord p) in ⊢ (? ? %)
504 [apply (trans_divides ? (exp p (ord m p)))
505 [generalize in match H2.
506 cases (ord m p);intro
507 [apply False_ind.apply H3.reflexivity
512 |apply prime_to_lt_SO.
518 theorem not_divides_ord_rem: \forall m,p.O< m \to S O < p \to
519 \lnot (divides p (ord_rem m p)).
521 elim (p_ord_to_exp1 p m (ord m p) (ord_rem m p))
525 |unfold ord.unfold ord_rem.apply eq_pair_fst_snd
529 theorem ord_ord_rem: \forall p,q,m. O < m \to
530 prime p \to prime q \to
531 q < p \to ord (ord_rem m p) q = ord m q.
533 rewrite > (exp_ord p) in ⊢ (? ? ? (? % ?))
535 [rewrite > not_divides_to_ord_O in ⊢ (? ? ? (? % ?))
539 apply (lt_to_not_eq ? ? H3).
540 apply (divides_exp_to_eq ? ? ? H2 H1 H4)
543 apply (ltn_to_ltO ? ? H3)
556 theorem lt_ord_rem: \forall n,m. prime n \to O < m \to
557 divides n m \to ord_rem m n < m.
559 elim (le_to_or_lt_eq (ord_rem m n) m)
562 apply (ord_O_to_not_divides ? ? H1 H ? H2).
564 [apply prime_to_lt_SO.assumption
565 |apply (inj_times_l1 m)
567 |rewrite > sym_times in ⊢ (? ? ? %).
568 rewrite < times_n_SO.
569 rewrite < H3 in ⊢ (? ? (? ? %) ?).
572 [apply prime_to_lt_SO.assumption
579 |apply divides_ord_rem
580 [apply prime_to_lt_SO.assumption
587 (* p_ord_inv is used to encode the pair ord and rem into
588 a single natural number. *)
590 definition p_ord_inv \def
593 [pair q r \Rightarrow r*m+q].
595 theorem eq_p_ord_inv: \forall p,m,x.
596 p_ord_inv p m x = (ord_rem x p)*m+(ord x p).
597 intros.unfold p_ord_inv. unfold ord_rem.
603 theorem div_p_ord_inv:
604 \forall p,m,x. ord x p < m \to p_ord_inv p m x / m = ord_rem x p.
605 intros.rewrite > eq_p_ord_inv.
606 apply div_plus_times.
610 theorem mod_p_ord_inv:
611 \forall p,m,x. ord x p < m \to p_ord_inv p m x \mod m = ord x p.
612 intros.rewrite > eq_p_ord_inv.
613 apply mod_plus_times.