1 (**************************************************************************)
4 (* ||A|| A project by Andrea Asperti *)
6 (* ||I|| Developers: *)
7 (* ||T|| The HELM team. *)
8 (* ||A|| http://helm.cs.unibo.it *)
10 (* \ / This file is distributed under the terms of the *)
11 (* v GNU General Public License Version 2 *)
13 (**************************************************************************)
15 (* ********************************************************************** *)
16 (* Progetto FreeScale *)
18 (* Sviluppato da: Cosimo Oliboni, oliboni@cs.unibo.it *)
19 (* Cosimo Oliboni, oliboni@cs.unibo.it *)
21 (* ********************************************************************** *)
23 include "freescale/bool_lemmas.ma".
24 include "freescale/prod.ma".
30 nlemma pair_destruct_1 :
31 ∀T1,T2.∀x1,x2:T1.∀y1,y2:T2.
32 pair T1 T2 x1 y1 = pair T1 T2 x2 y2 → x1 = x2.
33 #T1; #T2; #x1; #x2; #y1; #y2; #H;
34 nchange with (match pair T1 T2 x2 y2 with [ pair a _ ⇒ x1 = a ]);
40 nlemma pair_destruct_2 :
41 ∀T1,T2.∀x1,x2:T1.∀y1,y2:T2.
42 pair T1 T2 x1 y1 = pair T1 T2 x2 y2 → y1 = y2.
43 #T1; #T2; #x1; #x2; #y1; #y2; #H;
44 nchange with (match pair T1 T2 x2 y2 with [ pair _ b ⇒ y1 = b ]);
50 nlemma symmetric_eqpair :
51 ∀T1,T2:Type.∀p1,p2:ProdT T1 T2.
52 ∀f1:T1 → T1 → bool.∀f2:T2 → T2 → bool.
53 (symmetricT T1 bool f1) →
54 (symmetricT T2 bool f2) →
55 (eq_pair T1 T2 p1 p2 f1 f2 = eq_pair T1 T2 p2 p1 f1 f2).
56 #T1; #T2; #p1; #p2; #f1; #f2; #H; #H1;
65 ##[ ##1: nrewrite > (H1 y1 y2); napply refl_eq
66 ##| ##2: napply refl_eq
71 ∀T1,T2.∀p1,p2:ProdT T1 T2.
72 ∀f1:T1 → T1 → bool.∀f2:T2 → T2 → bool.
73 (∀x1,x2:T1.x1 = x2 → f1 x1 x2 = true) →
74 (∀y1,y2:T2.y1 = y2 → f2 y1 y2 = true) →
75 (p1 = p2 → eq_pair T1 T2 p1 p2 f1 f2 = true).
76 #T1; #T2; #p1; #p2; #f1; #f2; #H1; #H2;
82 nrewrite > (H1 … (pair_destruct_1 … H));
84 nrewrite > (H2 … (pair_destruct_2 … H));
89 ∀T1,T2.∀p1,p2:ProdT T1 T2.
90 ∀f1:T1 → T1 → bool.∀f2:T2 → T2 → bool.
91 (∀x1,x2:T1.f1 x1 x2 = true → x1 = x2) →
92 (∀y1,y2:T2.f2 y1 y2 = true → y1 = y2) →
93 (eq_pair T1 T2 p1 p2 f1 f2 = true → p1 = p2).
94 #T1; #T2; #p1; #p2; #f1; #f2; #H1; #H2;
100 nletin K ≝ (H1 x1 x2);
101 ncases (f1 x1 x2) in H:(%) K:(%);
104 ##[ ##2: napply (bool_destruct … H3) ##]
106 nrewrite > (H4 (refl_eq …));
107 nrewrite > (H2 y1 y2 H3);
111 nlemma triple_destruct_1 :
112 ∀T1,T2,T3.∀x1,x2:T1.∀y1,y2:T2.∀z1,z2:T3.
113 triple T1 T2 T3 x1 y1 z1 = triple T1 T2 T3 x2 y2 z2 → x1 = x2.
114 #T1; #T2; #T3; #x1; #x2; #y1; #y2; #z1; #z2; #H;
115 nchange with (match triple T1 T2 T3 x2 y2 z2 with [ triple a _ _ ⇒ x1 = a ]);
121 nlemma triple_destruct_2 :
122 ∀T1,T2,T3.∀x1,x2:T1.∀y1,y2:T2.∀z1,z2:T3.
123 triple T1 T2 T3 x1 y1 z1 = triple T1 T2 T3 x2 y2 z2 → y1 = y2.
124 #T1; #T2; #T3; #x1; #x2; #y1; #y2; #z1; #z2; #H;
125 nchange with (match triple T1 T2 T3 x2 y2 z2 with [ triple _ b _ ⇒ y1 = b ]);
131 nlemma triple_destruct_3 :
132 ∀T1,T2,T3.∀x1,x2:T1.∀y1,y2:T2.∀z1,z2:T3.
133 triple T1 T2 T3 x1 y1 z1 = triple T1 T2 T3 x2 y2 z2 → z1 = z2.
134 #T1; #T2; #T3; #x1; #x2; #y1; #y2; #z1; #z2; #H;
135 nchange with (match triple T1 T2 T3 x2 y2 z2 with [ triple _ _ c ⇒ z1 = c ]);
141 nlemma symmetric_eqtriple :
142 ∀T1,T2,T3:Type.∀p1,p2:Prod3T T1 T2 T3.
143 ∀f1:T1 → T1 → bool.∀f2:T2 → T2 → bool.∀f3:T3 → T3 → bool.
144 (symmetricT T1 bool f1) →
145 (symmetricT T2 bool f2) →
146 (symmetricT T3 bool f3) →
147 (eq_triple T1 T2 T3 p1 p2 f1 f2 f3 = eq_triple T1 T2 T3 p2 p1 f1 f2 f3).
148 #T1; #T2; #T3; #p1; #p2; #f1; #f2; #f3; #H; #H1; #H2;
154 nrewrite > (H x1 x2);
157 ##[ ##1: nrewrite > (H1 y1 y2);
160 ##[ ##1: nrewrite > (H2 z1 z2); napply refl_eq
161 ##| ##2: napply refl_eq
163 ##| ##2: napply refl_eq
167 nlemma eq_to_eqtriple :
168 ∀T1,T2,T3.∀p1,p2:Prod3T T1 T2 T3.
169 ∀f1:T1 → T1 → bool.∀f2:T2 → T2 → bool.∀f3:T3 → T3 → bool.
170 (∀x1,x2:T1.x1 = x2 → f1 x1 x2 = true) →
171 (∀y1,y2:T2.y1 = y2 → f2 y1 y2 = true) →
172 (∀z1,z2:T3.z1 = z2 → f3 z1 z2 = true) →
173 (p1 = p2 → eq_triple T1 T2 T3 p1 p2 f1 f2 f3 = true).
174 #T1; #T2; #T3; #p1; #p2; #f1; #f2; #f3; #H1; #H2; #H3;
180 nrewrite > (H1 … (triple_destruct_1 … H));
182 nrewrite > (H2 … (triple_destruct_2 … H));
184 nrewrite > (H3 … (triple_destruct_3 … H));
188 nlemma eqtriple_to_eq :
189 ∀T1,T2,T3.∀p1,p2:Prod3T T1 T2 T3.
190 ∀f1:T1 → T1 → bool.∀f2:T2 → T2 → bool.∀f3:T3 → T3 → bool.
191 (∀x1,x2:T1.f1 x1 x2 = true → x1 = x2) →
192 (∀y1,y2:T2.f2 y1 y2 = true → y1 = y2) →
193 (∀z1,z2:T3.f3 z1 z2 = true → z1 = z2) →
194 (eq_triple T1 T2 T3 p1 p2 f1 f2 f3 = true → p1 = p2).
195 #T1; #T2; #T3; #p1; #p2; #f1; #f2; #f3; #H1; #H2; #H3;
201 nletin K ≝ (H1 x1 x2);
202 ncases (f1 x1 x2) in H:(%) K:(%);
204 ##[ ##2: #H4; napply (bool_destruct … H4) ##]
205 nletin K1 ≝ (H2 y1 y2);
206 ncases (f2 y1 y2) in K1:(%) ⊢ %;
208 ##[ ##2: #H4; #H5; napply (bool_destruct … H5) ##]
210 nrewrite > (H4 (refl_eq …));
211 nrewrite > (H6 (refl_eq …));
212 nrewrite > (H3 z1 z2 H5);
216 nlemma quadruple_destruct_1 :
217 ∀T1,T2,T3,T4.∀x1,x2:T1.∀y1,y2:T2.∀z1,z2:T3.∀v1,v2:T4.
218 quadruple T1 T2 T3 T4 x1 y1 z1 v1 = quadruple T1 T2 T3 T4 x2 y2 z2 v2 → x1 = x2.
219 #T1; #T2; #T3; #T4; #x1; #x2; #y1; #y2; #z1; #z2; #v1; #v2; #H;
220 nchange with (match quadruple T1 T2 T3 T4 x2 y2 z2 v2 with [ quadruple a _ _ _ ⇒ x1 = a ]);
226 nlemma quadruple_destruct_2 :
227 ∀T1,T2,T3,T4.∀x1,x2:T1.∀y1,y2:T2.∀z1,z2:T3.∀v1,v2:T4.
228 quadruple T1 T2 T3 T4 x1 y1 z1 v1 = quadruple T1 T2 T3 T4 x2 y2 z2 v2 → y1 = y2.
229 #T1; #T2; #T3; #T4; #x1; #x2; #y1; #y2; #z1; #z2; #v1; #v2; #H;
230 nchange with (match quadruple T1 T2 T3 T4 x2 y2 z2 v2 with [ quadruple _ b _ _ ⇒ y1 = b ]);
236 nlemma quadruple_destruct_3 :
237 ∀T1,T2,T3,T4.∀x1,x2:T1.∀y1,y2:T2.∀z1,z2:T3.∀v1,v2:T4.
238 quadruple T1 T2 T3 T4 x1 y1 z1 v1 = quadruple T1 T2 T3 T4 x2 y2 z2 v2 → z1 = z2.
239 #T1; #T2; #T3; #T4; #x1; #x2; #y1; #y2; #z1; #z2; #v1; #v2; #H;
240 nchange with (match quadruple T1 T2 T3 T4 x2 y2 z2 v2 with [ quadruple _ _ c _ ⇒ z1 = c ]);
246 nlemma quadruple_destruct_4 :
247 ∀T1,T2,T3,T4.∀x1,x2:T1.∀y1,y2:T2.∀z1,z2:T3.∀v1,v2:T4.
248 quadruple T1 T2 T3 T4 x1 y1 z1 v1 = quadruple T1 T2 T3 T4 x2 y2 z2 v2 → v1 = v2.
249 #T1; #T2; #T3; #T4; #x1; #x2; #y1; #y2; #z1; #z2; #v1; #v2; #H;
250 nchange with (match quadruple T1 T2 T3 T4 x2 y2 z2 v2 with [ quadruple _ _ _ d ⇒ v1 = d ]);
256 nlemma symmetric_eqquadruple :
257 ∀T1,T2,T3,T4:Type.∀p1,p2:Prod4T T1 T2 T3 T4.
258 ∀f1:T1 → T1 → bool.∀f2:T2 → T2 → bool.∀f3:T3 → T3 → bool.∀f4:T4 → T4 → bool.
259 (symmetricT T1 bool f1) →
260 (symmetricT T2 bool f2) →
261 (symmetricT T3 bool f3) →
262 (symmetricT T4 bool f4) →
263 (eq_quadruple T1 T2 T3 T4 p1 p2 f1 f2 f3 f4 = eq_quadruple T1 T2 T3 T4 p2 p1 f1 f2 f3 f4).
264 #T1; #T2; #T3; #T4; #p1; #p2; #f1; #f2; #f3; #f4; #H; #H1; #H2; #H3;
270 nrewrite > (H x1 x2);
273 ##[ ##1: nrewrite > (H1 y1 y2);
276 ##[ ##1: nrewrite > (H2 z1 z2);
279 ##[ ##1: nrewrite > (H3 v1 v2); napply refl_eq
280 ##| ##2: napply refl_eq
282 ##| ##2: napply refl_eq
284 ##| ##2: napply refl_eq
288 nlemma eq_to_eqquadruple :
289 ∀T1,T2,T3,T4.∀p1,p2:Prod4T T1 T2 T3 T4.
290 ∀f1:T1 → T1 → bool.∀f2:T2 → T2 → bool.∀f3:T3 → T3 → bool.∀f4:T4 → T4 → bool.
291 (∀x1,x2:T1.x1 = x2 → f1 x1 x2 = true) →
292 (∀y1,y2:T2.y1 = y2 → f2 y1 y2 = true) →
293 (∀z1,z2:T3.z1 = z2 → f3 z1 z2 = true) →
294 (∀v1,v2:T4.v1 = v2 → f4 v1 v2 = true) →
295 (p1 = p2 → eq_quadruple T1 T2 T3 T4 p1 p2 f1 f2 f3 f4 = true).
296 #T1; #T2; #T3; #T4; #p1; #p2; #f1; #f2; #f3; #f4; #H1; #H2; #H3; #H4;
300 #x2; #y2; #z2; #v2; #H;
302 nrewrite > (H1 … (quadruple_destruct_1 … H));
304 nrewrite > (H2 … (quadruple_destruct_2 … H));
306 nrewrite > (H3 … (quadruple_destruct_3 … H));
308 nrewrite > (H4 … (quadruple_destruct_4 … H));
312 nlemma eqquadruple_to_eq :
313 ∀T1,T2,T3,T4.∀p1,p2:Prod4T T1 T2 T3 T4.
314 ∀f1:T1 → T1 → bool.∀f2:T2 → T2 → bool.∀f3:T3 → T3 → bool.∀f4:T4 → T4 → bool.
315 (∀x1,x2:T1.f1 x1 x2 = true → x1 = x2) →
316 (∀y1,y2:T2.f2 y1 y2 = true → y1 = y2) →
317 (∀z1,z2:T3.f3 z1 z2 = true → z1 = z2) →
318 (∀v1,v2:T4.f4 v1 v2 = true → v1 = v2) →
319 (eq_quadruple T1 T2 T3 T4 p1 p2 f1 f2 f3 f4 = true → p1 = p2).
320 #T1; #T2; #T3; #T4; #p1; #p2; #f1; #f2; #f3; #f4; #H1; #H2; #H3; #H4;
324 #x2; #y2; #z2; #v2; #H;
326 nletin K ≝ (H1 x1 x2);
327 ncases (f1 x1 x2) in H:(%) K:(%);
329 ##[ ##2: #H5; napply (bool_destruct … H5) ##]
330 nletin K1 ≝ (H2 y1 y2);
331 ncases (f2 y1 y2) in K1:(%) ⊢ %;
333 ##[ ##2: #H5; #H6; napply (bool_destruct … H6) ##]
334 nletin K2 ≝ (H3 z1 z2);
335 ncases (f3 z1 z2) in K2:(%) ⊢ %;
337 ##[ ##2: #H5; #H6; #H7; napply (bool_destruct … H7) ##]
339 nrewrite > (H5 (refl_eq …));
340 nrewrite > (H6 (refl_eq …));
341 nrewrite > (H8 (refl_eq …));
342 nrewrite > (H4 v1 v2 H7);
346 nlemma quintuple_destruct_1 :
347 ∀T1,T2,T3,T4,T5.∀x1,x2:T1.∀y1,y2:T2.∀z1,z2:T3.∀v1,v2:T4.∀w1,w2:T5.
348 quintuple T1 T2 T3 T4 T5 x1 y1 z1 v1 w1 = quintuple T1 T2 T3 T4 T5 x2 y2 z2 v2 w2 → x1 = x2.
349 #T1; #T2; #T3; #T4; #T5; #x1; #x2; #y1; #y2; #z1; #z2; #v1; #v2; #w1; #w2; #H;
350 nchange with (match quintuple T1 T2 T3 T4 T5 x2 y2 z2 v2 w2 with [ quintuple a _ _ _ _ ⇒ x1 = a ]);
356 nlemma quintuple_destruct_2 :
357 ∀T1,T2,T3,T4,T5.∀x1,x2:T1.∀y1,y2:T2.∀z1,z2:T3.∀v1,v2:T4.∀w1,w2:T5.
358 quintuple T1 T2 T3 T4 T5 x1 y1 z1 v1 w1 = quintuple T1 T2 T3 T4 T5 x2 y2 z2 v2 w2 → y1 = y2.
359 #T1; #T2; #T3; #T4; #T5; #x1; #x2; #y1; #y2; #z1; #z2; #v1; #v2; #w1; #w2; #H;
360 nchange with (match quintuple T1 T2 T3 T4 T5 x2 y2 z2 v2 w2 with [ quintuple _ b _ _ _ ⇒ y1 = b ]);
366 nlemma quintuple_destruct_3 :
367 ∀T1,T2,T3,T4,T5.∀x1,x2:T1.∀y1,y2:T2.∀z1,z2:T3.∀v1,v2:T4.∀w1,w2:T5.
368 quintuple T1 T2 T3 T4 T5 x1 y1 z1 v1 w1 = quintuple T1 T2 T3 T4 T5 x2 y2 z2 v2 w2 → z1 = z2.
369 #T1; #T2; #T3; #T4; #T5; #x1; #x2; #y1; #y2; #z1; #z2; #v1; #v2; #w1; #w2; #H;
370 nchange with (match quintuple T1 T2 T3 T4 T5 x2 y2 z2 v2 w2 with [ quintuple _ _ c _ _ ⇒ z1 = c ]);
376 nlemma quintuple_destruct_4 :
377 ∀T1,T2,T3,T4,T5.∀x1,x2:T1.∀y1,y2:T2.∀z1,z2:T3.∀v1,v2:T4.∀w1,w2:T5.
378 quintuple T1 T2 T3 T4 T5 x1 y1 z1 v1 w1 = quintuple T1 T2 T3 T4 T5 x2 y2 z2 v2 w2 → v1 = v2.
379 #T1; #T2; #T3; #T4; #T5; #x1; #x2; #y1; #y2; #z1; #z2; #v1; #v2; #w1; #w2; #H;
380 nchange with (match quintuple T1 T2 T3 T4 T5 x2 y2 z2 v2 w2 with [ quintuple _ _ _ d _ ⇒ v1 = d ]);
386 nlemma quintuple_destruct_5 :
387 ∀T1,T2,T3,T4,T5.∀x1,x2:T1.∀y1,y2:T2.∀z1,z2:T3.∀v1,v2:T4.∀w1,w2:T5.
388 quintuple T1 T2 T3 T4 T5 x1 y1 z1 v1 w1 = quintuple T1 T2 T3 T4 T5 x2 y2 z2 v2 w2 → w1 = w2.
389 #T1; #T2; #T3; #T4; #T5; #x1; #x2; #y1; #y2; #z1; #z2; #v1; #v2; #w1; #w2; #H;
390 nchange with (match quintuple T1 T2 T3 T4 T5 x2 y2 z2 v2 w2 with [ quintuple _ _ _ _ e ⇒ w1 = e ]);
396 nlemma symmetric_eqquintuple :
397 ∀T1,T2,T3,T4,T5:Type.∀p1,p2:Prod5T T1 T2 T3 T4 T5.
398 ∀f1:T1 → T1 → bool.∀f2:T2 → T2 → bool.∀f3:T3 → T3 → bool.∀f4:T4 → T4 → bool.∀f5:T5 → T5 → bool.
399 (symmetricT T1 bool f1) →
400 (symmetricT T2 bool f2) →
401 (symmetricT T3 bool f3) →
402 (symmetricT T4 bool f4) →
403 (symmetricT T5 bool f5) →
404 (eq_quintuple T1 T2 T3 T4 T5 p1 p2 f1 f2 f3 f4 f5 = eq_quintuple T1 T2 T3 T4 T5 p2 p1 f1 f2 f3 f4 f5).
405 #T1; #T2; #T3; #T4; #T5; #p1; #p2; #f1; #f2; #f3; #f4; #f5; #H; #H1; #H2; #H3; #H4;
407 #x1; #y1; #z1; #v1; #w1;
409 #x2; #y2; #z2; #v2; #w2;
411 nrewrite > (H x1 x2);
414 ##[ ##1: nrewrite > (H1 y1 y2);
417 ##[ ##1: nrewrite > (H2 z1 z2);
420 ##[ ##1: nrewrite > (H3 v1 v2);
423 ##[ ##1: nrewrite > (H4 w1 w2); napply refl_eq
424 ##| ##2: napply refl_eq
426 ##| ##2: napply refl_eq
428 ##| ##2: napply refl_eq
430 ##| ##2: napply refl_eq
434 nlemma eq_to_eqquintuple :
435 ∀T1,T2,T3,T4,T5.∀p1,p2:Prod5T T1 T2 T3 T4 T5.
436 ∀f1:T1 → T1 → bool.∀f2:T2 → T2 → bool.∀f3:T3 → T3 → bool.∀f4:T4 → T4 → bool.∀f5:T5 → T5 → bool.
437 (∀x1,x2:T1.x1 = x2 → f1 x1 x2 = true) →
438 (∀y1,y2:T2.y1 = y2 → f2 y1 y2 = true) →
439 (∀z1,z2:T3.z1 = z2 → f3 z1 z2 = true) →
440 (∀v1,v2:T4.v1 = v2 → f4 v1 v2 = true) →
441 (∀w1,w2:T5.w1 = w2 → f5 w1 w2 = true) →
442 (p1 = p2 → eq_quintuple T1 T2 T3 T4 T5 p1 p2 f1 f2 f3 f4 f5 = true).
443 #T1; #T2; #T3; #T4; #T5; #p1; #p2; #f1; #f2; #f3; #f4; #f5; #H1; #H2; #H3; #H4; #H5;
445 #x1; #y1; #z1; #v1; #w1;
447 #x2; #y2; #z2; #v2; #w2; #H;
449 nrewrite > (H1 … (quintuple_destruct_1 … H));
451 nrewrite > (H2 … (quintuple_destruct_2 … H));
453 nrewrite > (H3 … (quintuple_destruct_3 … H));
455 nrewrite > (H4 … (quintuple_destruct_4 … H));
457 nrewrite > (H5 … (quintuple_destruct_5 … H));
461 nlemma eqquintuple_to_eq :
462 ∀T1,T2,T3,T4,T5.∀p1,p2:Prod5T T1 T2 T3 T4 T5.
463 ∀f1:T1 → T1 → bool.∀f2:T2 → T2 → bool.∀f3:T3 → T3 → bool.∀f4:T4 → T4 → bool.∀f5:T5 → T5 → bool.
464 (∀x1,x2:T1.f1 x1 x2 = true → x1 = x2) →
465 (∀y1,y2:T2.f2 y1 y2 = true → y1 = y2) →
466 (∀z1,z2:T3.f3 z1 z2 = true → z1 = z2) →
467 (∀v1,v2:T4.f4 v1 v2 = true → v1 = v2) →
468 (∀w1,w2:T5.f5 w1 w2 = true → w1 = w2) →
469 (eq_quintuple T1 T2 T3 T4 T5 p1 p2 f1 f2 f3 f4 f5 = true → p1 = p2).
470 #T1; #T2; #T3; #T4; #T5; #p1; #p2; #f1; #f2; #f3; #f4; #f5; #H1; #H2; #H3; #H4; #H5;
472 #x1; #y1; #z1; #v1; #w1;
474 #x2; #y2; #z2; #v2; #w2; #H;
476 nletin K ≝ (H1 x1 x2);
477 ncases (f1 x1 x2) in H:(%) K:(%);
479 ##[ ##2: #H6; napply (bool_destruct … H6) ##]
480 nletin K1 ≝ (H2 y1 y2);
481 ncases (f2 y1 y2) in K1:(%) ⊢ %;
483 ##[ ##2: #H6; #H7; napply (bool_destruct … H7) ##]
484 nletin K2 ≝ (H3 z1 z2);
485 ncases (f3 z1 z2) in K2:(%) ⊢ %;
487 ##[ ##2: #H6; #H7; #H8; napply (bool_destruct … H8) ##]
488 nletin K3 ≝ (H4 v1 v2);
489 ncases (f4 v1 v2) in K3:(%) ⊢ %;
491 ##[ ##2: #H6; #H7; #H8; #H9; napply (bool_destruct … H9) ##]
492 #H6; #H7; #H8; #H9; #H10;
493 nrewrite > (H6 (refl_eq …));
494 nrewrite > (H7 (refl_eq …));
495 nrewrite > (H8 (refl_eq …));
496 nrewrite > (H10 (refl_eq …));
497 nrewrite > (H5 w1 w2 H9);