]> matita.cs.unibo.it Git - helm.git/blob - matita/matita/lib/basics/finset.ma
graph of a function
[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/lists/listb.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   [#H1 @(absurd … (\P H1)) % #Hfalse
68    cut (∀A,P,a,a1,h,h1.mk_Sig A P a h = mk_Sig A P a1 h1 → a = a1)
69    [#A #P #a #a1 #h #h1 #H destruct (H) %] #Hcut 
70     lapply (Hcut nat (λi.i<m) i n ? ? Hfalse) #Hfalse @(absurd … ltni)
71     @le_to_not_lt >Hfalse @le_n
72   |<(notb_notb (memb …)) >Hind normalize /2/
73   ]
74 qed. 
75
76
77 lemma enumn_unique_aux: ∀n,m. ∀h:n ≤ m. uniqueb (Nat_to m) (enumnaux n m h) = true.
78 #n elim n -n // #n #Hind #m #h @true_to_andb_true // @memb_enumn //
79 qed.
80  
81 lemma enumn_unique: ∀n.uniqueb (Nat_to n) (enumn n) = true.
82 #n @enumn_unique_aux
83 qed.
84
85 (* definition ltb ≝ λn,m.leb (S n) m. *)
86 lemma enumn_complete_aux: ∀n,m,i.∀h:n ≤m.∀k:i<m.i<n → 
87   memb (Nat_to m) (mk_Sig ?? i k) (enumnaux n m h) = true.
88 #n elim n -n
89   [normalize #n #i #_ #_ #Hfalse @False_ind /2/ 
90   |#n #Hind #m #i #h #k #lein whd in ⊢ (??%?);
91    cases (le_to_or_lt_eq … (le_S_S_to_le … lein))
92     [#ltin cut (eqb (Nat_to m) (mk_Sig ?? i k) (mk_Sig ?? n h) = false)
93       [normalize @not_eq_to_eqb_false @lt_to_not_eq @ltin] 
94        #Hcut >Hcut @Hind //
95     |#eqin cut (eqb (Nat_to m) (mk_Sig ?? i k) (mk_Sig ?? n h) = true)
96      [normalize @eq_to_eqb_true //
97      |#Hcut >Hcut %
98     ]
99   ]
100 qed.
101
102 lemma enumn_complete: ∀n.∀i:Nat_to n. memb ? i (enumn n) = true.
103 #n whd in ⊢ (%→?); * #i #ltin @enumn_complete_aux //
104 qed.
105
106 definition initN ≝ λn.
107   mk_FinSet (Nat_to n) (enumn n) (enumn_unique n) (enumn_complete n).
108
109 example tipa: ∀n.∃x: initN (S n). pi1 … x = n.
110 #n @ex_intro [whd @mk_Sig [@n | @le_n] | //] qed.
111
112 (* option *)
113 definition enum_option ≝ λA:DeqSet.λl.
114   None A::(map ?? (Some A) l).
115   
116 lemma enum_option_def : ∀A:FinSet.∀l. 
117   enum_option A l = None A :: (map ?? (Some A) l).
118 // qed.
119
120 lemma enum_option_unique: ∀A:DeqSet.∀l. 
121   uniqueb A l = true → 
122     uniqueb ? (enum_option A l) = true.
123 #A #l #uA @true_to_andb_true
124   [generalize in match uA; -uA #_ elim l [%]
125    #a #tl #Hind @sym_eq @noteq_to_eqnot % #H 
126    cases (orb_true_l … (sym_eq … H))
127     [#H1 @(absurd (None A = Some A a)) [@(\P H1) | % #H2 destruct]
128     |-H #H >H in Hind; normalize /2/
129     ]
130   |@unique_map_inj // #a #a1 #H destruct %
131   ]
132 qed.
133
134 lemma enum_option_complete: ∀A:DeqSet.∀l. 
135   (∀x:A. memb A x l = true) →
136     ∀x:DeqOption A. memb ? x (enum_option A l) = true.
137 #A #l #Hl * // #a @memb_cons @memb_map @Hl
138 qed.
139     
140 definition FinOption ≝ λA:FinSet.
141   mk_FinSet (DeqOption A) 
142    (enum_option A (enum A)) 
143    (enum_option_unique … (enum_unique A))
144    (enum_option_complete … (enum_complete A)).
145
146 unification hint  0 ≔ C; 
147     T ≟ FinSetcarr C,
148     X ≟ FinOption C
149 (* ---------------------------------------- *) ⊢ 
150     option T ≡ FinSetcarr X.
151
152 (* sum *)
153 definition enum_sum ≝ λA,B:DeqSet.λl1.λl2.
154   (map ?? (inl A B) l1) @ (map ?? (inr A B) l2).
155   
156 lemma enum_sum_def : ∀A,B:FinSet.∀l1,l2. enum_sum A B l1 l2 = 
157   (map ?? (inl A B) l1) @ (map ?? (inr A B) l2).
158 // qed.
159
160 lemma enum_sum_unique: ∀A,B:DeqSet.∀l1,l2. 
161   uniqueb A l1 = true → uniqueb B l2 = true → 
162     uniqueb ? (enum_sum A B l1 l2) = true.
163 #A #B #l1 #l2 elim l1 
164   [#_ #ul2 @unique_map_inj // #b1 #b2 #Hinr destruct //
165   |#a #tl #Hind #uA #uB @true_to_andb_true 
166     [@sym_eq @noteq_to_eqnot % #H 
167      cases (memb_append … (sym_eq … H))
168       [#H1 @(absurd (memb ? a tl = true)) 
169         [@(memb_map_inj …H1) #a1 #a2 #Hinl destruct //
170         |<(andb_true_l … uA) @eqnot_to_noteq //
171         ]
172       |elim l2
173         [normalize #H destruct 
174         |#b #tlB #Hind #membH cases (orb_true_l … membH)
175           [#H lapply (\P H) #H1 destruct |@Hind]
176         ]
177       ] 
178     |@Hind // @(andb_true_r … uA)
179     ]
180   ]
181 qed.
182
183 lemma enum_sum_complete: ∀A,B:DeqSet.∀l1,l2. 
184   (∀x:A. memb A x l1 = true) →
185   (∀x:B. memb B x l2 = true) →
186     ∀x:DeqSum A B. memb ? x (enum_sum A B l1 l2) = true.
187 #A #B #l1 #l2 #Hl1 #Hl2 *
188   [#a @memb_append_l1 @memb_map @Hl1
189   |#b @memb_append_l2 @memb_map @Hl2
190   ]
191 qed.
192     
193 definition FinSum ≝ λA,B:FinSet.
194   mk_FinSet (DeqSum A B) 
195    (enum_sum A B (enum A) (enum B)) 
196    (enum_sum_unique … (enum_unique A) (enum_unique B))
197    (enum_sum_complete … (enum_complete A) (enum_complete B)).
198
199 include alias "basics/types.ma".
200
201 unification hint  0 ≔ C1,C2; 
202     T1 ≟ FinSetcarr C1,
203     T2 ≟ FinSetcarr C2,
204     X ≟ FinSum C1 C2
205 (* ---------------------------------------- *) ⊢ 
206     T1+T2 ≡ FinSetcarr X.
207
208 (* prod *)
209
210 definition enum_prod ≝ λA,B:DeqSet.λl1.λl2.
211   compose ??? (mk_Prod A B) l1 l2.
212   
213 axiom enum_prod_unique: ∀A,B,l1,l2. 
214   uniqueb A l1 = true → uniqueb B l2 = true →
215   uniqueb ? (enum_prod A B l1 l2) = true.
216
217 lemma enum_prod_complete:∀A,B:DeqSet.∀l1,l2.
218   (∀a. memb A a l1 = true) → (∀b.memb B b l2 = true) →
219     ∀p. memb ? p (enum_prod A B l1 l2) = true.
220 #A #B #l1 #l2 #Hl1 #Hl2 * #a #b @memb_compose // 
221 qed.
222
223 definition FinProd ≝ 
224 λA,B:FinSet.mk_FinSet (DeqProd A B)
225   (enum_prod A B (enum A) (enum B)) 
226   (enum_prod_unique A B … (enum_unique A) (enum_unique B)) 
227   (enum_prod_complete A B … (enum_complete A) (enum_complete B)).
228
229 unification hint  0 ≔ C1,C2; 
230     T1 ≟ FinSetcarr C1,
231     T2 ≟ FinSetcarr C2,
232     X ≟ FinProd C1 C2
233 (* ---------------------------------------- *) ⊢ 
234     T1×T2 ≡ FinSetcarr X.
235
236 (* graph of a function *)
237
238 definition graph_of ≝ λA,B.λf:A→B. 
239   Σp:A×B.f (\fst p) = \snd p.
240
241 definition graph_enum ≝ λA,B:FinSet.λf:A→B. 
242   filter ? (λp.f (\fst p) == \snd p) (enum (FinProd A B)).
243   
244 lemma graph_enum_unique : ∀A,B,f.
245   uniqueb ? (graph_enum A B f) = true.
246 #A #B #f @uniqueb_filter @(enum_unique (FinProd A B))
247 qed.
248
249 lemma graph_enum_correct: ∀A,B:FinSet.∀f:A→B. ∀a,b.
250 memb ? 〈a,b〉 (graph_enum A B f) = true → f a = b.
251 #A #B #f #a #b #membp @(\P ?) @(filter_true … membp)
252 qed.
253
254 lemma graph_enum_complete: ∀A,B:FinSet.∀f:A→B. ∀a,b.
255 f a = b → memb ? 〈a,b〉 (graph_enum A B f) = true.
256 #A #B #f #a #b #eqf @memb_filter_l [@(\b eqf)]
257 @enum_prod_complete //
258 qed.