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 set "baseuri" "cic:/matita/nat/gcd".
17 include "nat/primes.ma".
18 include "higher_order_defs/functions.ma".
20 let rec gcd_aux p m n: nat \def
21 match divides_b n m with
26 |(S q) \Rightarrow gcd_aux q n (mod m n)]].
28 definition gcd : nat \to nat \to nat \def
34 | (S p) \Rightarrow gcd_aux (S p) m (S p) ]
38 | (S p) \Rightarrow gcd_aux (S p) n (S p) ]].
40 theorem divides_mod: \forall p,m,n:nat. O < n \to divides p m \to divides p n \to
42 intros.elim H1.elim H2.
43 apply witness ? ? (n2 - n1*(div m n)).
44 rewrite > distr_times_minus.
46 rewrite < assoc_times.
50 rewrite > div_mod m n in \vdash (? ? %).
52 apply eq_plus_to_le ? ? (mod m n).
56 apply div_mod.assumption.
59 theorem divides_mod_to_divides: \forall p,m,n:nat. O < n \to
60 divides p (mod m n) \to divides p n \to divides p m.
61 intros.elim H1.elim H2.
62 apply witness p m ((n1*(div m n))+n2).
63 rewrite > distr_times_plus.
65 rewrite < assoc_times.
66 rewrite < H4.rewrite < sym_times.
67 apply div_mod.assumption.
70 theorem divides_gcd_aux_mn: \forall p,m,n. O < n \to n \le m \to n \le p \to
71 divides (gcd_aux p m n) m \land divides (gcd_aux p m n) n.
73 absurd O < n.assumption.apply le_to_not_lt.assumption.
74 cut (divides n1 m) \lor \not (divides n1 m).
77 (match divides_b n1 m with
79 | false \Rightarrow gcd_aux n n1 (mod m n1)]) m) \land
81 (match divides_b n1 m with
83 | false \Rightarrow gcd_aux n n1 (mod m n1)]) n1).
84 elim Hcut.rewrite > divides_to_divides_b_true.
86 split.assumption.apply witness n1 n1 (S O).apply times_n_SO.
87 assumption.assumption.
88 rewrite > not_divides_to_divides_b_false.
90 (divides (gcd_aux n n1 (mod m n1)) m) \land
91 (divides (gcd_aux n n1 (mod m n1)) n1).
92 cut (divides (gcd_aux n n1 (mod m n1)) n1) \land
93 (divides (gcd_aux n n1 (mod m n1)) (mod m n1)).
95 split.apply divides_mod_to_divides ? ? n1.
96 assumption.assumption.assumption.assumption.
98 cut O \lt mod m n1 \lor O = mod m n1.
99 elim Hcut1.assumption.
100 apply False_ind.apply H4.apply mod_O_to_divides.
101 assumption.apply sym_eq.assumption.
102 apply le_to_or_lt_eq.apply le_O_n.
104 apply lt_mod_m_m.assumption.
107 change with mod m n1 < n1.
108 apply lt_mod_m_m.assumption.assumption.
109 assumption.assumption.
110 apply decidable_divides n1 m.assumption.
113 theorem divides_gcd_nm: \forall n,m.
114 divides (gcd n m) m \land divides (gcd n m) n.
122 | (S p) \Rightarrow gcd_aux (S p) m (S p) ]
126 | (S p) \Rightarrow gcd_aux (S p) n (S p) ]]) m
133 | (S p) \Rightarrow gcd_aux (S p) m (S p) ]
137 | (S p) \Rightarrow gcd_aux (S p) n (S p) ]]) n.
140 simplify.intros.split.
141 apply witness m m (S O).apply times_n_SO.
142 apply witness m O O.apply times_n_O.
144 divides (gcd_aux (S m1) m (S m1)) m
146 divides (gcd_aux (S m1) m (S m1)) (S m1).
147 apply divides_gcd_aux_mn.
148 simplify.apply le_S_S.apply le_O_n.
149 assumption.apply le_n.
152 simplify.intros.split.
153 apply witness n O O.apply times_n_O.
154 apply witness n n (S O).apply times_n_SO.
156 divides (gcd_aux (S m1) n (S m1)) (S m1)
158 divides (gcd_aux (S m1) n (S m1)) n.
159 cut divides (gcd_aux (S m1) n (S m1)) n
161 divides (gcd_aux (S m1) n (S m1)) (S m1).
162 elim Hcut.split.assumption.assumption.
163 apply divides_gcd_aux_mn.
164 simplify.apply le_S_S.apply le_O_n.
165 apply not_lt_to_le.simplify.intro.apply H.
166 rewrite > H1.apply trans_le ? (S n).
167 apply le_n_Sn.assumption.apply le_n.
170 theorem divides_gcd_n: \forall n,m.
173 exact proj2 ? ? (divides_gcd_nm n m).
176 theorem divides_gcd_m: \forall n,m.
179 exact proj1 ? ? (divides_gcd_nm n m).
182 theorem divides_gcd_aux: \forall p,m,n,d. O < n \to n \le m \to n \le p \to
183 divides d m \to divides d n \to divides d (gcd_aux p m n).
185 absurd O < n.assumption.apply le_to_not_lt.assumption.
188 (match divides_b n1 m with
189 [ true \Rightarrow n1
190 | false \Rightarrow gcd_aux n n1 (mod m n1)]).
191 cut divides n1 m \lor \not (divides n1 m).
193 rewrite > divides_to_divides_b_true.
195 assumption.assumption.
196 rewrite > not_divides_to_divides_b_false.
197 change with divides d (gcd_aux n n1 (mod m n1)).
199 cut O \lt mod m n1 \lor O = mod m n1.
200 elim Hcut1.assumption.
201 absurd divides n1 m.apply mod_O_to_divides.
202 assumption.apply sym_eq.assumption.assumption.
203 apply le_to_or_lt_eq.apply le_O_n.
205 apply lt_mod_m_m.assumption.
208 change with mod m n1 < n1.
209 apply lt_mod_m_m.assumption.assumption.
211 apply divides_mod.assumption.assumption.assumption.
212 assumption.assumption.
213 apply decidable_divides n1 m.assumption.
216 theorem divides_d_gcd: \forall m,n,d.
217 divides d m \to divides d n \to divides d (gcd n m).
225 | (S p) \Rightarrow gcd_aux (S p) m (S p) ]
229 | (S p) \Rightarrow gcd_aux (S p) n (S p) ]]).
231 apply nat_case1 n.simplify.intros.assumption.
233 change with divides d (gcd_aux (S m1) m (S m1)).
234 apply divides_gcd_aux.
235 simplify.apply le_S_S.apply le_O_n.assumption.apply le_n.assumption.
236 rewrite < H2.assumption.
237 apply nat_case1 m.simplify.intros.assumption.
239 change with divides d (gcd_aux (S m1) n (S m1)).
240 apply divides_gcd_aux.
241 simplify.apply le_S_S.apply le_O_n.
242 apply lt_to_le.apply not_le_to_lt.assumption.apply le_n.assumption.
243 rewrite < H2.assumption.
246 theorem eq_minus_gcd_aux: \forall p,m,n.O < n \to n \le m \to n \le p \to
247 ex nat (\lambda a. ex nat (\lambda b.
248 a*n - b*m = (gcd_aux p m n) \lor b*m - a*n = (gcd_aux p m n))).
251 absurd O < n.assumption.apply le_to_not_lt.assumption.
253 cut (divides n1 m) \lor \not (divides n1 m).
255 ex nat (\lambda a. ex nat (\lambda b.
256 a*n1 - b*m = match divides_b n1 m with
257 [ true \Rightarrow n1
258 | false \Rightarrow gcd_aux n n1 (mod m n1)]
260 b*m - a*n1 = match divides_b n1 m with
261 [ true \Rightarrow n1
262 | false \Rightarrow gcd_aux n n1 (mod m n1)])).
264 rewrite > divides_to_divides_b_true.
266 apply ex_intro ? ? (S O).
267 apply ex_intro ? ? O.
268 left.simplify.rewrite < plus_n_O.
269 apply sym_eq.apply minus_n_O.
270 assumption.assumption.
271 rewrite > not_divides_to_divides_b_false.
273 ex nat (\lambda a. ex nat (\lambda b.
274 a*n1 - b*m = gcd_aux n n1 (mod m n1)
276 b*m - a*n1 = gcd_aux n n1 (mod m n1))).
278 ex nat (\lambda a. ex nat (\lambda b.
279 a*(mod m n1) - b*n1= gcd_aux n n1 (mod m n1)
281 b*n1 - a*(mod m n1) = gcd_aux n n1 (mod m n1))).
282 elim Hcut2.elim H5.elim H6.
285 apply ex_intro ? ? (a1+a*(div m n1)).
286 apply ex_intro ? ? a.
289 rewrite < sym_times n1.
290 rewrite > distr_times_plus.
291 rewrite > sym_times n1.
292 rewrite > sym_times n1.
293 rewrite > div_mod m n1 in \vdash (? ? (? % ?) ?).
294 rewrite > assoc_times.
296 rewrite > distr_times_plus.
297 rewrite < eq_minus_minus_minus_plus.
299 rewrite < plus_minus.
300 rewrite < minus_n_n.reflexivity.
305 apply ex_intro ? ? (a1+a*(div m n1)).
306 apply ex_intro ? ? a.
309 rewrite > distr_times_plus.
311 rewrite > sym_times n1.
312 rewrite > div_mod m n1 in \vdash (? ? (? ? %) ?).
313 rewrite > distr_times_plus.
314 rewrite > assoc_times.
315 rewrite < eq_minus_minus_minus_plus.
317 rewrite < plus_minus.
318 rewrite < minus_n_n.reflexivity.
321 apply H n1 (mod m n1).
322 cut O \lt mod m n1 \lor O = mod m n1.
323 elim Hcut2.assumption.
324 absurd divides n1 m.apply mod_O_to_divides.
326 symmetry.assumption.assumption.
327 apply le_to_or_lt_eq.apply le_O_n.
329 apply lt_mod_m_m.assumption.
332 change with mod m n1 < n1.
334 assumption.assumption.assumption.assumption.
335 apply decidable_divides n1 m.assumption.
336 apply lt_to_le_to_lt ? n1.assumption.assumption.
339 theorem eq_minus_gcd: \forall m,n.
340 ex nat (\lambda a. ex nat (\lambda b.
341 a*n - b*m = (gcd n m) \lor b*m - a*n = (gcd n m))).
344 ex nat (\lambda a. ex nat (\lambda b.
350 | (S p) \Rightarrow gcd_aux (S p) m (S p) ]
354 | (S p) \Rightarrow gcd_aux (S p) n (S p) ]]
360 | (S p) \Rightarrow gcd_aux (S p) m (S p) ]
364 | (S p) \Rightarrow gcd_aux (S p) n (S p) ]]
369 apply ex_intro ? ? O.
370 apply ex_intro ? ? (S O).
373 apply sym_eq.apply minus_n_O.
376 ex nat (\lambda a. ex nat (\lambda b.
377 a*(S m1) - b*m = (gcd_aux (S m1) m (S m1))
378 \lor b*m - a*(S m1) = (gcd_aux (S m1) m (S m1)))).
379 apply eq_minus_gcd_aux.
380 simplify. apply le_S_S.apply le_O_n.
381 assumption.apply le_n.
384 apply ex_intro ? ? (S O).
385 apply ex_intro ? ? O.
388 apply sym_eq.apply minus_n_O.
391 ex nat (\lambda a. ex nat (\lambda b.
392 a*n - b*(S m1) = (gcd_aux (S m1) n (S m1))
393 \lor b*(S m1) - a*n = (gcd_aux (S m1) n (S m1)))).
395 ex nat (\lambda a. ex nat (\lambda b.
396 a*(S m1) - b*n = (gcd_aux (S m1) n (S m1))
398 b*n - a*(S m1) = (gcd_aux (S m1) n (S m1)))).
399 elim Hcut.elim H2.elim H3.
400 apply ex_intro ? ? a1.
401 apply ex_intro ? ? a.
403 apply ex_intro ? ? a1.
404 apply ex_intro ? ? a.
406 apply eq_minus_gcd_aux.
407 simplify. apply le_S_S.apply le_O_n.
408 apply lt_to_le.apply not_le_to_lt.assumption.
412 (* some properties of gcd *)
414 theorem gcd_O_n: \forall n:nat. gcd O n = n.
415 intro.simplify.reflexivity.
418 theorem gcd_O_to_eq_O:\forall m,n:nat. (gcd m n) = O \to
420 intros.cut divides O n \land divides O m.
421 elim Hcut.elim H2.split.
422 assumption.elim H1.assumption.
424 apply divides_gcd_nm.
427 theorem symmetric_gcd: symmetric nat gcd.
429 \forall n,m:nat. gcd n m = gcd m n.
431 cut O < (gcd n m) \lor O = (gcd n m).
433 cut O < (gcd m n) \lor O = (gcd m n).
436 apply divides_to_le.assumption.
437 apply divides_d_gcd.apply divides_gcd_n.apply divides_gcd_m.
438 apply divides_to_le.assumption.
439 apply divides_d_gcd.apply divides_gcd_n.apply divides_gcd_m.
442 elim Hcut2.rewrite > H2.rewrite > H3.reflexivity.
443 apply gcd_O_to_eq_O.apply sym_eq.assumption.
444 apply le_to_or_lt_eq.apply le_O_n.
447 elim Hcut1.rewrite > H1.rewrite > H2.reflexivity.
448 apply gcd_O_to_eq_O.apply sym_eq.assumption.
449 apply le_to_or_lt_eq.apply le_O_n.
452 variant sym_gcd: \forall n,m:nat. gcd n m = gcd m n \def
455 theorem gcd_SO_n: \forall n:nat. gcd (S O) n = (S O).
457 apply antisym_le.apply divides_to_le.simplify.apply le_n.
459 cut O < gcd (S O) n \lor O = gcd (S O) n.
460 elim Hcut.assumption.
463 cut (S O)=O \land n=O.
464 elim Hcut1.apply sym_eq.assumption.
465 apply gcd_O_to_eq_O.apply sym_eq.assumption.
466 apply le_to_or_lt_eq.apply le_O_n.
469 theorem prime_to_gcd_SO: \forall n,m:nat. prime n \to \not (divides n m) \to
471 intros.simplify in H.change with gcd n m = (S O).
475 change with (S (S O)) \le gcd n m \to False.intro.
476 apply H1.rewrite < H3 (gcd n m).
478 apply divides_gcd_n.assumption.
479 cut O < gcd n m \lor O = gcd n m.
480 elim Hcut.assumption.
482 apply not_le_Sn_O (S O).
484 elim Hcut1.rewrite < H5 in \vdash (? ? %).assumption.
485 apply gcd_O_to_eq_O.apply sym_eq.assumption.
486 apply le_to_or_lt_eq.apply le_O_n.
489 (* esempio di sfarfallalmento !!! *)
491 theorem bad: \forall n,p,q:nat.prime n \to divides n (p*q) \to
492 divides n p \lor divides n q.
494 cut divides n p \lor \not (divides n p).
495 elim Hcut.left.assumption.
497 cut ex nat (\lambda a. ex nat (\lambda b.
498 a*n - b*p = (S O) \lor b*p - a*n = (S O))).
499 elim Hcut1.elim H3.*)
501 theorem divides_times_to_divides: \forall n,p,q:nat.prime n \to divides n (p*q) \to
502 divides n p \lor divides n q.
504 cut divides n p \lor \not (divides n p).
508 cut ex nat (\lambda a. ex nat (\lambda b.
509 a*n - b*p = (S O) \lor b*p - a*n = (S O))).
510 elim Hcut1.elim H3.elim H4.
512 rewrite > times_n_SO q.rewrite < H5.
513 rewrite > distr_times_minus.
514 rewrite > sym_times q (a1*p).
515 rewrite > assoc_times a1.
516 elim H1.rewrite > H6.
517 rewrite < sym_times n.rewrite < assoc_times.
518 rewrite > sym_times q.rewrite > assoc_times.
519 rewrite < assoc_times a1.rewrite < sym_times n.
520 rewrite > assoc_times n.
521 rewrite < distr_times_minus.
522 apply witness ? ? (q*a-a1*n2).reflexivity.
524 rewrite > times_n_SO q.rewrite < H5.
525 rewrite > distr_times_minus.
526 rewrite > sym_times q (a1*p).
527 rewrite > assoc_times a1.
528 elim H1.rewrite > H6.
529 rewrite < sym_times.rewrite > assoc_times.
530 rewrite < assoc_times q.
531 rewrite < sym_times n.
532 rewrite < distr_times_minus.
533 apply witness ? ? (n2*a1-q*a).reflexivity.
534 (* end second case *)
535 rewrite < prime_to_gcd_SO n p.
537 assumption.assumption.
538 apply decidable_divides n p.
539 apply trans_lt ? (S O).simplify.apply le_n.
540 simplify in H.elim H. assumption.