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/library_auto/nat/chinese_reminder".
17 include "auto/nat/exp.ma".
18 include "auto/nat/gcd.ma".
19 include "auto/nat/permutation.ma".
20 include "auto/nat/congruence.ma".
22 theorem and_congruent_congruent: \forall m,n,a,b:nat. O < n \to O < m \to
23 gcd n m = (S O) \to ex nat (\lambda x. congruent x a m \land congruent x b n).
25 cut (\exists c,d.c*n - d*m = (S O) \lor d*m - c*n = (S O))
30 apply (ex_intro nat ? ((a+b*m)*a1*n-b*a2*m)).
32 [ (* congruent to a *)
33 cut (a1*n = a2*m + (S O))
34 [ rewrite > assoc_times.
36 rewrite < (sym_plus ? (a2*m)).
37 rewrite > distr_times_plus.
40 rewrite < assoc_times.
41 rewrite < times_plus_l.
42 rewrite > eq_minus_plus_plus_minus
44 (*rewrite < times_minus_l.
46 apply (eq_times_plus_to_congruent ? ? ? ((b+(a+b*m)*a2)-b*a2))
51 apply (trans_le ? ((a+b*m)*a2))
53 apply (trans_le ? (b*m));auto
54 (*[ rewrite > times_n_SO in \vdash (? % ?).
64 change with (O + a2*m < a1*n).
65 apply lt_minus_to_plus.
73 | (* congruent to b *)
74 cut (a2*m = a1*n - (S O))
75 [ rewrite > (assoc_times b a2).
77 rewrite > distr_times_minus.
78 rewrite < assoc_times.
79 rewrite < eq_plus_minus_minus_minus
81 (*rewrite < times_n_SO.
82 rewrite < times_minus_l.
84 apply (eq_times_plus_to_congruent ? ? ? ((a+b*m)*a1-b*a1))
88 | rewrite > assoc_times.
90 (*auto genera un'esecuzione troppo lunga*)
91 apply (trans_le ? (a1*n - a2*m));auto
94 | apply (le_minus_m ? (a2*m))
99 (*apply (trans_le ? (b*m))
100 [ rewrite > times_n_SO in \vdash (? % ?).
111 change with (O + a2*m < a1*n).
112 apply lt_minus_to_plus.
121 | (* and now the symmetric case; the price to pay for working
122 in nat instead than Z *)
123 apply (ex_intro nat ? ((b+a*n)*a2*m-a*a1*n)).
125 [(* congruent to a *)
126 cut (a1*n = a2*m - (S O))
127 [ rewrite > (assoc_times a a1).
129 rewrite > distr_times_minus.
130 rewrite < assoc_times.
131 rewrite < eq_plus_minus_minus_minus
133 (*rewrite < times_n_SO.
134 rewrite < times_minus_l.
136 apply (eq_times_plus_to_congruent ? ? ? ((b+a*n)*a2-a*a2))
140 | rewrite > assoc_times.
142 apply (trans_le ? (a2*m - a1*n));auto
145 | apply (le_minus_m ? (a1*n))
147 | rewrite > assoc_times.
148 rewrite > assoc_times.
151 (*apply (trans_le ? (a*n))
152 [ rewrite > times_n_SO in \vdash (? % ?).
163 change with (O + a1*n < a2*m).
164 apply lt_minus_to_plus.
172 | (* congruent to b *)
173 cut (a2*m = a1*n + (S O))
174 [ rewrite > assoc_times.
176 rewrite > (sym_plus (a1*n)).
177 rewrite > distr_times_plus.
178 rewrite < times_n_SO.
179 rewrite < assoc_times.
180 rewrite > assoc_plus.
181 rewrite < times_plus_l.
182 rewrite > eq_minus_plus_plus_minus
184 (*rewrite < times_minus_l.
186 apply (eq_times_plus_to_congruent ? ? ? ((a+(b+a*n)*a1)-a*a1))
191 apply (trans_le ? ((b+a*n)*a1))
194 (*apply (trans_le ? (a*n))
195 [ rewrite > times_n_SO in \vdash (? % ?).
203 | apply minus_to_plus
205 change with (O + a1*n < a2*m).
206 apply lt_minus_to_plus.
216 (* proof of the cut *)
217 | (* qui auto non conclude il goal *)
223 theorem and_congruent_congruent_lt: \forall m,n,a,b:nat. O < n \to O < m \to
225 ex nat (\lambda x. (congruent x a m \land congruent x b n) \land
228 elim (and_congruent_congruent m n a b)
230 apply (ex_intro ? ? (a1 \mod (m*n))).
233 [ apply (transitive_congruent m ? a1)
236 change with (congruent a1 (a1 \mod (m*n)) m).
239 (*apply congruent_n_mod_times;assumption*)
242 | apply (transitive_congruent n ? a1)
245 change with (congruent a1 (a1 \mod (m*n)) n).
247 (*apply congruent_n_mod_times;assumption*)
253 (*rewrite > (times_n_O O).
254 apply lt_times;assumption*)
262 definition cr_pair : nat \to nat \to nat \to nat \to nat \def
264 min (pred (n*m)) (\lambda x. andb (eqb (x \mod n) a) (eqb (x \mod m) b)).
266 theorem cr_pair1: cr_pair (S (S O)) (S (S (S O))) O O = O.
270 theorem cr_pair2: cr_pair (S(S O)) (S(S(S O))) (S O) O = (S(S(S O))).
276 theorem cr_pair3: cr_pair (S(S O)) (S(S(S O))) (S O) (S(S O)) = (S(S(S(S(S O))))).
280 theorem cr_pair4: cr_pair (S(S(S(S(S O))))) (S(S(S(S(S(S(S O))))))) (S(S(S O))) (S(S O)) =
281 (S(S(S(S(S(S(S(S(S(S(S(S(S(S(S(S(S(S(S(S(S(S(S O))))))))))))))))))))))).
285 theorem mod_cr_pair : \forall m,n,a,b. a \lt m \to b \lt n \to
287 (cr_pair m n a b) \mod m = a \land (cr_pair m n a b) \mod n = b.
289 cut (andb (eqb ((cr_pair m n a b) \mod m) a)
290 (eqb ((cr_pair m n a b) \mod n) b) = true)
291 [ generalize in match Hcut.
300 | apply eqb_true_to_eq.
305 (* l'invocazione di auto qui genera segmentation fault *)
307 (* l'invocazione di auto qui genera segmentation fault *)
308 apply not_eq_true_false.
309 (* l'invocazione di auto qui genera segmentation fault *)
313 | apply (f_min_aux_true
314 (\lambda x. andb (eqb (x \mod m) a) (eqb (x \mod n) b)) (pred (m*n)) (pred (m*n))).
315 elim (and_congruent_congruent_lt m n a b)
316 [ apply (ex_intro ? ? a1).
320 (*rewrite < minus_n_n.
324 apply (trans_le ? (m*n))
326 | apply (nat_case (m*n))
339 [ cut (a1 \mod n = b)
340 [ rewrite > (eq_to_eqb_true ? ? Hcut).
341 rewrite > (eq_to_eqb_true ? ? Hcut1).
342 (* l'invocazione di auto qui non chiude il goal *)
345 | rewrite < (lt_to_eq_mod b n);
348 | rewrite < (lt_to_eq_mod a m);assumption
352 (*apply (le_to_lt_to_lt ? b)
357 (*apply (le_to_lt_to_lt ? a)