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/chinese_reminder".
19 include "nat/permutation.ma".
20 include "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).
26 elim Hcut.elim H3.elim H4.
27 apply ex_intro nat ? ((a+b*m)*a1*n-b*a2*m).
30 cut a1*n = a2*m + (S O).
31 rewrite > assoc_times.
33 rewrite < sym_plus ? (a2*m).
34 rewrite > distr_times_plus.
37 rewrite < assoc_times.
38 rewrite < times_plus_l.
39 rewrite > eq_minus_plus_plus_minus.
40 rewrite < times_minus_l.
42 apply eq_times_plus_to_congruent ? ? ? ((b+(a+b*m)*a2)-b*a2).
43 assumption.reflexivity.
45 apply trans_le ? ((a+b*m)*a2).
47 apply trans_le ? (b*m).
48 rewrite > times_n_SO in \vdash (? % ?).
49 apply le_times_r.assumption.
54 change with (O + a2*m < a1*n).
55 apply lt_minus_to_plus.
56 rewrite > H5.simplify.apply le_n.
59 cut a2*m = a1*n - (S O).
60 rewrite > assoc_times b a2.
62 rewrite > distr_times_minus.
63 rewrite < assoc_times.
64 rewrite < eq_plus_minus_minus_minus.
66 rewrite < times_minus_l.
68 apply eq_times_plus_to_congruent ? ? ? ((a+b*m)*a1-b*a1).
69 assumption.reflexivity.
70 rewrite > assoc_times.
72 apply trans_le ? (a1*n - a2*m).
73 rewrite > H5.apply le_n.
74 apply le_minus_m ? (a2*m).
77 apply trans_le ? (b*m).
78 rewrite > times_n_SO in \vdash (? % ?).
79 apply le_times_r.assumption.
81 apply sym_eq. apply plus_to_minus.
85 change with (O + a2*m < a1*n).
86 apply lt_minus_to_plus.
87 rewrite > H5.simplify.apply le_n.
89 (* and now the symmetric case; the price to pay for working
90 in nat instead than Z *)
91 apply ex_intro nat ? ((b+a*n)*a2*m-a*a1*n).
94 cut a1*n = a2*m - (S O).
95 rewrite > assoc_times a a1.
97 rewrite > distr_times_minus.
98 rewrite < assoc_times.
99 rewrite < eq_plus_minus_minus_minus.
100 rewrite < times_n_SO.
101 rewrite < times_minus_l.
103 apply eq_times_plus_to_congruent ? ? ? ((b+a*n)*a2-a*a2).
104 assumption.reflexivity.
105 rewrite > assoc_times.
107 apply trans_le ? (a2*m - a1*n).
108 rewrite > H5.apply le_n.
109 apply le_minus_m ? (a1*n).
110 rewrite > assoc_times.rewrite > assoc_times.
112 apply trans_le ? (a*n).
113 rewrite > times_n_SO in \vdash (? % ?).
114 apply le_times_r.assumption.
116 apply sym_eq.apply plus_to_minus.
120 change with (O + a1*n < a2*m).
121 apply lt_minus_to_plus.
122 rewrite > H5.simplify.apply le_n.
125 cut a2*m = a1*n + (S O).
126 rewrite > assoc_times.
128 rewrite > sym_plus (a1*n).
129 rewrite > distr_times_plus.
130 rewrite < times_n_SO.
131 rewrite < assoc_times.
132 rewrite > assoc_plus.
133 rewrite < times_plus_l.
134 rewrite > eq_minus_plus_plus_minus.
135 rewrite < times_minus_l.
137 apply eq_times_plus_to_congruent ? ? ? ((a+(b+a*n)*a1)-a*a1).
138 assumption.reflexivity.
140 apply trans_le ? ((b+a*n)*a1).
142 apply trans_le ? (a*n).
143 rewrite > times_n_SO in \vdash (? % ?).
150 change with (O + a1*n < a2*m).
151 apply lt_minus_to_plus.
152 rewrite > H5.simplify.apply le_n.
154 (* proof of the cut *)
159 theorem and_congruent_congruent_lt: \forall m,n,a,b:nat. O < n \to O < m \to
161 ex nat (\lambda x. (congruent x a m \land congruent x b n) \land
163 intros.elim and_congruent_congruent m n a b.
165 apply ex_intro ? ? (a1 \mod (m*n)).
167 apply transitive_congruent m ? a1.
170 change with congruent a1 (a1 \mod (m*n)) m.
172 apply congruent_n_mod_times.
173 assumption.assumption.assumption.
174 apply transitive_congruent n ? a1.
177 change with congruent a1 (a1 \mod (m*n)) n.
178 apply congruent_n_mod_times.
179 assumption.assumption.assumption.
181 rewrite > times_n_O O.
182 apply lt_times.assumption.assumption.
183 assumption.assumption.assumption.
186 definition cr_pair : nat \to nat \to nat \to nat \to nat \def
188 min (pred (n*m)) (\lambda x. andb (eqb (x \mod n) a) (eqb (x \mod m) b)).
190 theorem cr_pair1: cr_pair (S (S O)) (S (S (S O))) O O = O.
194 theorem cr_pair2: cr_pair (S(S O)) (S(S(S O))) (S O) O = (S(S(S O))).
199 theorem cr_pair3: cr_pair (S(S O)) (S(S(S O))) (S O) (S(S O)) = (S(S(S(S(S O))))).
203 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)) =
204 (S(S(S(S(S(S(S(S(S(S(S(S(S(S(S(S(S(S(S(S(S(S(S O))))))))))))))))))))))).
208 theorem mod_cr_pair : \forall m,n,a,b. a \lt m \to b \lt n \to
210 (cr_pair m n a b) \mod m = a \land (cr_pair m n a b) \mod n = b.
212 cut andb (eqb ((cr_pair m n a b) \mod m) a)
213 (eqb ((cr_pair m n a b) \mod n) b) = true.
214 generalize in match Hcut.
216 apply eqb_elim.intro.
219 eqb ((cr_pair m n a b) \mod n) b = true
220 \to a = a \land (cr_pair m n a b) \mod n = b.
221 intro.split.reflexivity.
222 apply eqb_true_to_eq.assumption.
224 change with false = true \to
225 (cr_pair m n a b) \mod m = a \land (cr_pair m n a b) \mod n = b.
226 intro.apply False_ind.
227 apply not_eq_true_false.apply sym_eq.assumption.
229 (\lambda x. andb (eqb (x \mod m) a) (eqb (x \mod n) b)) (pred (m*n)) (pred (m*n)).
230 elim and_congruent_congruent_lt m n a b.
231 apply ex_intro ? ? a1.split.split.
232 rewrite < minus_n_n.apply le_O_n.
233 elim H3.apply le_S_S_to_le.apply trans_le ? (m*n).
234 assumption.apply nat_case (m*n).apply le_O_n.
236 rewrite < pred_Sn.apply le_n.
241 rewrite > eq_to_eqb_true ? ? Hcut.
242 rewrite > eq_to_eqb_true ? ? Hcut1.
243 simplify.reflexivity.
244 rewrite < lt_to_eq_mod b n.assumption.
246 rewrite < lt_to_eq_mod a m.assumption.
248 apply le_to_lt_to_lt ? b.apply le_O_n.assumption.
249 apply le_to_lt_to_lt ? a.apply le_O_n.assumption.