]> matita.cs.unibo.it Git - helm.git/blob - matita/matita/lib/basics/finset.ma
backport of WIP on \lambda\delta to matita 0.99.3
[helm.git] / matita / matita / lib / basics / finset.ma
1 (*
2     ||M||  This file is part of HELM, an Hypertextual, Electronic        
3     ||A||  Library of Mathematics, developed at the Computer Science     
4     ||T||  Department of the University of Bologna, Italy.                     
5     ||I||                                                                 
6     ||T||  
7     ||A||  
8     \   /  This file is distributed under the terms of the       
9      \ /   GNU General Public License Version 2   
10       V_______________________________________________________________ *)
11
12 include "basics/deqlist.ma".
13
14 (****** DeqSet: a set with a decidable equality ******)
15
16 record FinSet : Type[1] ≝ 
17 { FinSetcarr:> DeqSet;
18   enum: list FinSetcarr;
19   enum_unique: uniqueb FinSetcarr enum = true;
20   enum_complete : ∀x:FinSetcarr. memb ? x enum = true
21 }.
22
23 notation < "𝐅" non associative with precedence 90 
24  for @{'bigF}.
25 interpretation "FinSet" 'bigF = (mk_FinSet ???).
26
27 (* bool *)
28 lemma bool_enum_unique: uniqueb ? [true;false] = true.
29 // qed.
30
31 lemma bool_enum_complete: ∀x:bool. memb ? x [true;false] = true.
32 * // qed.
33
34 definition FinBool ≝ 
35   mk_FinSet DeqBool [true;false] bool_enum_unique bool_enum_complete.
36
37 unification hint  0 ≔ ; 
38     X ≟ FinBool
39 (* ---------------------------------------- *) ⊢ 
40     bool ≡ FinSetcarr X.
41
42 (* nat segment *)
43
44 lemma eqbnat_true : ∀n,m. eqb n m = true ↔ n = m.
45 #n #m % [@eqb_true_to_eq | @eq_to_eqb_true]
46 qed.
47
48 definition DeqNat ≝ mk_DeqSet nat eqb eqbnat_true.
49
50 lemma lt_to_le : ∀n,m. n < m → n ≤ m.
51 /2/ qed-.
52  
53 let rec enumnaux n m ≝ 
54   match n return (λn.n ≤ m → list (Σx.x < m)) with 
55     [ O ⇒ λh.[ ] | S p ⇒ λh:p < m.(mk_Sig ?? p h)::enumnaux p m (lt_to_le p m h)].
56     
57 definition enumn ≝ λn.enumnaux n n (le_n n).
58
59 definition Nat_to ≝ λn. DeqSig DeqNat (λi.i<n).
60
61 (* lemma prova : ∀n. carr (Nat_to n) = (Σx.x<n). // *)
62
63 lemma memb_enumn: ∀m,n,i:DeqNat. ∀h:n ≤ m. ∀k: i < m. n ≤ i →
64   (¬ (memb (Nat_to m) (mk_Sig ?? i k) (enumnaux n m h))) = true.
65 #m #n elim n -n // #n #Hind #i #ltm #k #ltni @sym_eq @noteq_to_eqnot @sym_not_eq
66 % #H cases (orb_true_l … H)
67   [whd in ⊢ (??%?→?); #H1 @(absurd  … ltni) @le_to_not_lt 
68    >(eqb_true_to_eq … H1) @le_n
69   |<(notb_notb (memb …)) >Hind normalize /2 by lt_to_le, absurd/
70   ]
71 qed. 
72
73 lemma enumn_unique_aux: ∀n,m. ∀h:n ≤ m. uniqueb (Nat_to m) (enumnaux n m h) = true.
74 #n elim n -n // #n #Hind #m #h @true_to_andb_true // @memb_enumn //
75 qed.
76  
77 lemma enumn_unique: ∀n.uniqueb (Nat_to n) (enumn n) = true.
78 #n @enumn_unique_aux
79 qed.
80
81 (* definition ltb ≝ λn,m.leb (S n) m. *)
82 lemma enumn_complete_aux: ∀n,m,i.∀h:n ≤m.∀k:i<m.i<n → 
83   memb (Nat_to m) (mk_Sig ?? i k) (enumnaux n m h) = true.
84 #n elim n -n
85   [normalize #n #i #_ #_ #Hfalse @False_ind /2/ 
86   |#n #Hind #m #i #h #k #lein whd in ⊢ (??%?);
87    cases (le_to_or_lt_eq … (le_S_S_to_le … lein))
88     [#ltin cut (eqb (Nat_to m) (mk_Sig ?? i k) (mk_Sig ?? n h) = false)
89       [normalize @not_eq_to_eqb_false @lt_to_not_eq @ltin] 
90        #Hcut >Hcut @Hind //
91     |#eqin cut (eqb (Nat_to m) (mk_Sig ?? i k) (mk_Sig ?? n h) = true)
92      [normalize @eq_to_eqb_true //
93      |#Hcut >Hcut %
94     ]
95   ]
96 qed.
97
98 lemma enumn_complete: ∀n.∀i:Nat_to n. memb ? i (enumn n) = true.
99 #n whd in ⊢ (%→?); * #i #ltin @enumn_complete_aux //
100 qed.
101
102 definition initN ≝ λn.
103   mk_FinSet (Nat_to n) (enumn n) (enumn_unique n) (enumn_complete n).
104
105 example tipa: ∀n.∃x: initN (S n). pi1 … x = n.
106 #n @ex_intro [whd @mk_Sig [@n | @le_n] | //] qed.
107
108 (* option *)
109 definition enum_option ≝ λA:DeqSet.λl.
110   None A::(map ?? (Some A) l).
111   
112 lemma enum_option_def : ∀A:FinSet.∀l. 
113   enum_option A l = None A :: (map ?? (Some A) l).
114 // qed.
115
116 lemma enum_option_unique: ∀A:DeqSet.∀l. 
117   uniqueb A l = true → 
118     uniqueb ? (enum_option A l) = true.
119 #A #l #uA @true_to_andb_true
120   [generalize in match uA; -uA #_ elim l [%]
121    #a #tl #Hind @sym_eq @noteq_to_eqnot % #H 
122    cases (orb_true_l … (sym_eq … H))
123     [#H1 @(absurd (None A = Some A a)) [@(\P H1) | % #H2 destruct]
124     |-H #H >H in Hind; normalize /2/
125     ]
126   |@unique_map_inj // #a #a1 #H destruct %
127   ]
128 qed.
129
130 lemma enum_option_complete: ∀A:DeqSet.∀l. 
131   (∀x:A. memb A x l = true) →
132     ∀x:DeqOption A. memb ? x (enum_option A l) = true.
133 #A #l #Hl * // #a @memb_cons @memb_map @Hl
134 qed.
135     
136 definition FinOption ≝ λA:FinSet.
137   mk_FinSet (DeqOption A) 
138    (enum_option A (enum A)) 
139    (enum_option_unique … (enum_unique A))
140    (enum_option_complete … (enum_complete A)).
141
142 unification hint  0 ≔ C; 
143     T ≟ FinSetcarr C,
144     X ≟ FinOption C
145 (* ---------------------------------------- *) ⊢ 
146     option T ≡ FinSetcarr X.
147
148 (* sum *)
149 definition enum_sum ≝ λA,B:DeqSet.λl1.λl2.
150   (map ?? (inl A B) l1) @ (map ?? (inr A B) l2).
151   
152 lemma enum_sum_def : ∀A,B:FinSet.∀l1,l2. enum_sum A B l1 l2 = 
153   (map ?? (inl A B) l1) @ (map ?? (inr A B) l2).
154 // qed.
155
156 lemma enum_sum_unique: ∀A,B:DeqSet.∀l1,l2. 
157   uniqueb A l1 = true → uniqueb B l2 = true → 
158     uniqueb ? (enum_sum A B l1 l2) = true.
159 #A #B #l1 #l2 elim l1 
160   [#_ #ul2 @unique_map_inj // #b1 #b2 #Hinr destruct //
161   |#a #tl #Hind #uA #uB @true_to_andb_true 
162     [@sym_eq @noteq_to_eqnot % #H 
163      cases (memb_append … (sym_eq … H))
164       [#H1 @(absurd (memb ? a tl = true)) 
165         [@(memb_map_inj …H1) #a1 #a2 #Hinl destruct //
166         |<(andb_true_l … uA) @eqnot_to_noteq //
167         ]
168       |elim l2
169         [normalize #H destruct 
170         |#b #tlB #Hind #membH cases (orb_true_l … membH)
171           [#H lapply (\P H) #H1 destruct |@Hind]
172         ]
173       ] 
174     |@Hind // @(andb_true_r … uA)
175     ]
176   ]
177 qed.
178
179 lemma enum_sum_complete: ∀A,B:DeqSet.∀l1,l2. 
180   (∀x:A. memb A x l1 = true) →
181   (∀x:B. memb B x l2 = true) →
182     ∀x:DeqSum A B. memb ? x (enum_sum A B l1 l2) = true.
183 #A #B #l1 #l2 #Hl1 #Hl2 *
184   [#a @memb_append_l1 @memb_map @Hl1
185   |#b @memb_append_l2 @memb_map @Hl2
186   ]
187 qed.
188     
189 definition FinSum ≝ λA,B:FinSet.
190   mk_FinSet (DeqSum A B) 
191    (enum_sum A B (enum A) (enum B)) 
192    (enum_sum_unique … (enum_unique A) (enum_unique B))
193    (enum_sum_complete … (enum_complete A) (enum_complete B)).
194
195 include alias "basics/types.ma".
196
197 unification hint  0 ≔ C1,C2; 
198     T1 ≟ FinSetcarr C1,
199     T2 ≟ FinSetcarr C2,
200     X ≟ FinSum C1 C2
201 (* ---------------------------------------- *) ⊢ 
202     T1+T2 ≡ FinSetcarr X.
203
204 (* prod *)
205
206 definition enum_prod ≝ λA,B:DeqSet.λl1.λl2.
207   compose ??? (mk_Prod A B) l1 l2.
208
209 lemma enum_prod_unique: ∀A,B,l1,l2. 
210   uniqueb A l1 = true → uniqueb B l2 = true →
211   uniqueb ? (enum_prod A B l1 l2) = true.
212 #A #B #l1 elim l1 //
213   #a #tl #Hind #l2 #H1 #H2 @uniqueb_append 
214   [@unique_map_inj [#x #y #Heq @(eq_f … \snd … Heq) | //]
215   |@Hind // @(andb_true_r … H1)
216   |#p #H3 cases (memb_map_to_exists … H3) #b * 
217    #Hmemb #eqp <eqp @(not_to_not ? (memb ? a tl = true))
218     [2: @sym_not_eq @eqnot_to_noteq @sym_eq @(andb_true_l … H1)
219     |elim tl 
220       [normalize //
221       |#a1 #tl1 #Hind2 #H4 cases (memb_append … H4) -H4 #H4
222         [cases (memb_map_to_exists … H4) #b1 * #memb1 #H destruct (H)
223          normalize >(\b (refl ? a)) //
224         |@orb_true_r2 @Hind2 @H4
225         ]
226       ]
227     ]
228   ]
229 qed.
230
231 lemma enum_prod_complete:∀A,B:DeqSet.∀l1,l2.
232   (∀a. memb A a l1 = true) → (∀b.memb B b l2 = true) →
233     ∀p. memb ? p (enum_prod A B l1 l2) = true.
234 #A #B #l1 #l2 #Hl1 #Hl2 * #a #b @memb_compose // 
235 qed.
236
237 definition FinProd ≝ 
238 λA,B:FinSet.mk_FinSet (DeqProd A B)
239   (enum_prod A B (enum A) (enum B)) 
240   (enum_prod_unique A B … (enum_unique A) (enum_unique B)) 
241   (enum_prod_complete A B … (enum_complete A) (enum_complete B)).
242
243 unification hint  0 ≔ C1,C2; 
244     T1 ≟ FinSetcarr C1,
245     T2 ≟ FinSetcarr C2,
246     X ≟ FinProd C1 C2
247 (* ---------------------------------------- *) ⊢ 
248     T1×T2 ≡ FinSetcarr X.
249
250 (* graph of a function *)
251
252 definition graph_of ≝ λA,B.λf:A→B. 
253   Σp:A×B.f (\fst p) = \snd p.
254
255 definition graph_enum ≝ λA,B:FinSet.λf:A→B. 
256   filter ? (λp.f (\fst p) == \snd p) (enum (FinProd A B)).
257   
258 lemma graph_enum_unique : ∀A,B,f.
259   uniqueb ? (graph_enum A B f) = true.
260 #A #B #f @uniqueb_filter @(enum_unique (FinProd A B))
261 qed.
262
263 lemma graph_enum_correct: ∀A,B:FinSet.∀f:A→B. ∀a,b.
264 memb ? 〈a,b〉 (graph_enum A B f) = true → f a = b.
265 #A #B #f #a #b #membp @(\P ?) @(filter_true … membp)
266 qed.
267
268 lemma graph_enum_complete: ∀A,B:FinSet.∀f:A→B. ∀a,b.
269 f a = b → memb ? 〈a,b〉 (graph_enum A B f) = true.
270 #A #B #f #a #b #eqf @memb_filter_l [@(\b eqf)]
271 @enum_prod_complete //
272 qed.
273
274 (* FinFun *)
275    
276 definition enum_fun_raw: ∀A,B:DeqSet.list A → list B → list (list (DeqProd A B)) ≝
277   λA,B,lA,lB.foldr A (list (list (DeqProd A B))) 
278    (λa.compose ??? (λb. cons ? 〈a,b〉) lB) [[]] lA.
279    
280 lemma enum_fun_raw_cons: ∀A,B,a,lA,lB. 
281   enum_fun_raw A B (a::lA) lB = 
282     compose ??? (λb. cons ? 〈a,b〉) lB (enum_fun_raw A B lA lB).
283 //
284 qed.  
285
286 definition is_functional ≝ λA,B:DeqSet.λlA:list A.λl: list (DeqProd A B).
287   map ?? (fst A B) l = lA.
288
289 definition carr_fun ≝ λA,B:FinSet.
290   DeqSig (DeqList (DeqProd A B)) (is_functional A B (enum A)).
291
292 definition carr_fun_l ≝ λA,B:DeqSet.λl.
293   DeqSig (DeqList (DeqProd A B)) (is_functional A B l).
294
295 lemma compose_spec1 : ∀A,B,C:DeqSet.∀f:A→B→C.∀a:A.∀b:B.∀lA:list A.∀lB:list B.  
296   a ∈ lA = true → b ∈ lB = true → ((f a b) ∈ (compose A B C f lA lB)) = true.
297 #A #B #C #f #a #b #lA elim lA
298   [normalize #lB #H destruct
299   |#a1 #tl #Hind #lB #Ha #Hb cases (orb_true_l ?? Ha) #Hcase
300     [>(\P Hcase) normalize @memb_append_l1 @memb_map //
301     |@memb_append_l2 @Hind //
302     ]
303   ]
304 qed.
305
306 lemma compose_cons: ∀A,B,C.∀f:A→B→C.∀l1,l2,a.
307   compose A B C f (a::l1) l2 =
308     (map ?? (f a) l2)@(compose A B C f l1 l2). 
309 // qed.
310
311 lemma compose_spec2 : ∀A,B,C:DeqSet.∀f:A→B→C.∀c:C.∀lA:list A.∀lB:list B.  
312   c ∈ (compose A B C f lA lB) = true → 
313     ∃a,b.a ∈ lA = true ∧ b ∈ lB = true ∧ c = f a b.
314 #A #B #C #f #c #lA elim lA
315   [normalize #lB #H destruct
316   |#a1 #tl #Hind #lB >compose_cons #Hc cases (memb_append … Hc) #Hcase
317     [lapply(memb_map_to_exists … Hcase) * #b * #Hb #Hf
318      %{a1} %{b} /3/
319     |lapply(Hind ? Hcase) * #a2 * #b * * #Ha #Hb #Hf %{a2} %{b} % // % //
320      @orb_true_r2 //
321     ]
322   ]
323 qed.
324
325 definition compose2 ≝ 
326   λA,B:DeqSet.λa:A.λl. compose B (carr_fun_l A B l) (carr_fun_l A B (a::l)) 
327    (λb,tl. mk_Sig ?? (〈a,b〉::(pi1 … tl)) ?).
328 normalize @eq_f @(pi2 … tl) 
329 qed.
330
331 let rec Dfoldr (A:Type[0]) (B:list A → Type[0]) 
332  (f:∀a:A.∀l.B l → B (a::l)) (b:B [ ]) (l:list A) on l : B l ≝  
333  match l with [ nil ⇒ b | cons a l ⇒ f a l (Dfoldr A B f b l)].
334
335 definition empty_graph: ∀A,B:DeqSet. carr_fun_l A B []. 
336 #A #B %{[]} // qed.
337
338 definition enum_fun: ∀A,B:DeqSet.∀lA:list A.list B → list (carr_fun_l A B lA) ≝
339   λA,B,lA,lB.Dfoldr A (λl.list (carr_fun_l A B l)) 
340    (λa,l.compose2 ?? a l lB) [empty_graph A B] lA.
341
342 lemma mem_enum_fun: ∀A,B:DeqSet.∀lA,lB.∀x:carr_fun_l A B lA. 
343   pi1 … x ∈ map ?? (pi1 … ) (enum_fun A B lA lB) = true → 
344   x ∈ enum_fun A B lA lB = true .
345 #A #B #lA #lB #x @(memb_map_inj  
346   (DeqSig (DeqList (DeqProd A B))
347    (λx0:DeqList (DeqProd A B).is_functional A B lA x0))
348   (DeqList (DeqProd A B)) (pi1 …))
349 * #l1 #H1 * #l2 #H2 #Heq lapply H1 lapply H2 >Heq // 
350 qed.
351   
352 lemma enum_fun_cons: ∀A,B,a,lA,lB. 
353   enum_fun A B (a::lA) lB = 
354     compose ??? (λb,tl. mk_Sig ?? (〈a,b〉::(pi1 … tl)) ?) lB (enum_fun A B lA lB).
355 //
356 qed.
357
358 lemma map_map: ∀A,B,C.∀f:A→B.∀g:B→C.∀l.
359   map ?? g (map ?? f l) =  map ?? (g ∘ f) l.
360 #A #B #C #f #g #l elim l [//]
361 #a #tl #Hind normalize @eq_f @Hind
362 qed.
363
364 lemma map_compose: ∀A,B,C,D.∀f:A→B→C.∀g:C→D.∀l1,l2.
365   map ?? g (compose A B C f l1 l2) = compose A B D (λa,b. g (f a b)) l1 l2.
366 #A #B #C #D #f #g #l1 elim l1 [//]
367 #a #tl #Hind #l2 >compose_cons >compose_cons <map_append @eq_f2
368   [@map_map |@Hind]
369 qed.
370    
371 definition enum_fun_graphs: ∀A,B,lA,lB.
372   map ?? (pi1 … ) (enum_fun A B lA lB) = enum_fun_raw A B lA lB.
373 #A #B #lA elim lA [normalize //]
374 #a #tl #Hind #lB >(enum_fun_cons A B a tl lB) >enum_fun_raw_cons >map_compose 
375 cut (∀lB2. compose B (Σx:DeqList (DeqProd A B).is_functional A B tl x)
376   (DeqList (DeqProd A B))
377   (λa0:B
378    .λb:Σx:DeqList (DeqProd A B).is_functional A B tl x
379     .〈a,a0〉
380      ::pi1 (list (A×B)) (λx:DeqList (DeqProd A B).is_functional A B tl x) b) lB
381   (enum_fun A B tl lB2)
382   =compose B (list (A×B)) (list (A×B)) (λb:B.cons (A×B) 〈a,b〉) lB
383    (enum_fun_raw A B tl lB2))
384   [#lB2 elim lB
385     [normalize //
386     |#b #tlb #Hindb >compose_cons in ⊢ (???%); >compose_cons 
387      @eq_f2 [<Hind >map_map // |@Hindb]]] 
388 #Hcut @Hcut
389 qed.    
390
391 lemma uniqueb_compose: ∀A,B,C:DeqSet.∀f,l1,l2. 
392   (∀a1,a2,b1,b2. f a1 b1 = f a2 b2 → a1 = a2 ∧ b1 = b2) →
393   uniqueb ? l1 = true → uniqueb ? l2 = true → 
394     uniqueb ? (compose A B C f l1 l2) = true.
395 #A #B #C #f #l1 #l2 #Hinj elim l1 //
396 #a #tl #Hind #HuA #HuB >compose_cons @uniqueb_append
397   [@(unique_map_inj … HuB) #b1 #b2 #Hb1b2 @(proj2 … (Hinj … Hb1b2))
398   |@Hind // @(andb_true_r … HuA)
399   |#c #Hc lapply(memb_map_to_exists … Hc) * #b * #Hb2 #Hfab % #Hc
400    lapply(compose_spec2 … Hc) * #a1 * #b1 * * #Ha1 #Hb1 <Hfab #H
401    @(absurd (a=a1)) 
402     [@(proj1 … (Hinj … H))
403     |% #eqa @(absurd … Ha1) % <eqa #H lapply(andb_true_l … HuA) >H 
404      normalize #H1 destruct (H1) 
405     ]
406   ]
407 qed.
408
409 lemma enum_fun_unique: ∀A,B:DeqSet.∀lA,lB.
410     uniqueb ? lA = true → uniqueb ? lB = true →
411     uniqueb ? (enum_fun A B lA lB) = true.
412 #A #B #lA elim lA
413   [#lB #_ #ulB //
414   |#a #tlA #Hind #lB #uA #uB lapply (enum_fun_cons A B a tlA lB) #H >H
415    @(uniqueb_compose B (carr_fun_l A B tlA) (carr_fun_l A B (a::tlA))) 
416     [#b1 #b2 * #l1 #funl1 * #l2 #funl2 #H1 destruct (H1) /2/
417     |//
418     |@(Hind … uB) @(andb_true_r … uA)
419     ]
420   ]
421 qed.
422
423 lemma enum_fun_complete: ∀A,B:FinSet.∀l1,l2. 
424   (∀x:A. memb A x l1 = true) →
425   (∀x:B. memb B x l2 = true) →
426     ∀x:carr_fun_l A B l1. memb ? x (enum_fun A B l1 l2) = true.
427 #A #B #l1 #l2 #H1 #H2 * #g #H @mem_enum_fun >enum_fun_graphs 
428 lapply H -H lapply g -g elim l1  
429   [* // #p #tlg normalize #H destruct (H)
430   |#a #tl #Hind #g cases g
431     [normalize in ⊢ (%→?); #H destruct (H)
432     |* #a1 #b #tl1 normalize in ⊢ (%→?); #H
433      cut (is_functional A B tl tl1) [destruct (H) //] #Hfun 
434      >(cons_injective_l ????? H)
435      >(enum_fun_raw_cons … ) @(compose_spec1 … (λb. cons ? 〈a,b〉))
436       [@H2 |@Hind @Hfun]
437     ]
438   ]
439 qed.
440     
441 definition FinFun ≝ 
442 λA,B:FinSet.mk_FinSet (carr_fun A B)
443   (enum_fun A B (enum A) (enum B)) 
444   (enum_fun_unique A B … (enum_unique A) (enum_unique B))
445   (enum_fun_complete A B … (enum_complete A) (enum_complete B)).
446
447 (*
448 unification hint  0 ≔ C1,C2; 
449     T1 ≟ FinSetcarr C1,
450     T2 ≟ FinSetcarr C2,
451     X ≟ FinProd C1 C2
452 (* ---------------------------------------- *) ⊢ 
453     T1×T2 ≡ FinSetcarr X. *)