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.
8 \ / This file is distributed under the terms of the
9 \ / GNU General Public License Version 2
10 V_______________________________________________________________ *)
12 include "basics/lists/listb.ma".
14 (****** DeqSet: a set with a decidable equality ******)
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
23 notation < "𝐅" non associative with precedence 90
25 interpretation "FinSet" 'bigF = (mk_FinSet ???).
28 lemma bool_enum_unique: uniqueb ? [true;false] = true.
31 lemma bool_enum_complete: ∀x:bool. memb ? x [true;false] = true.
35 mk_FinSet DeqBool [true;false] bool_enum_unique bool_enum_complete.
37 unification hint 0 ≔ ;
39 (* ---------------------------------------- *) ⊢
44 lemma eqbnat_true : ∀n,m. eqb n m = true ↔ n = m.
45 #n #m % [@eqb_true_to_eq | @eq_to_eqb_true]
48 definition DeqNat ≝ mk_DeqSet nat eqb eqbnat_true.
50 lemma lt_to_le : ∀n,m. n < m → n ≤ m.
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)].
57 definition enumn ≝ λn.enumnaux n n (le_n n).
59 definition Nat_to ≝ λn. DeqSig DeqNat (λi.i<n).
61 (* lemma prova : ∀n. carr (Nat_to n) = (Σx.x<n). // *)
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/
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 //
77 lemma enumn_unique: ∀n.uniqueb (Nat_to n) (enumn n) = true.
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.
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]
91 |#eqin cut (eqb (Nat_to m) (mk_Sig ?? i k) (mk_Sig ?? n h) = true)
92 [normalize @eq_to_eqb_true //
98 lemma enumn_complete: ∀n.∀i:Nat_to n. memb ? i (enumn n) = true.
99 #n whd in ⊢ (%→?); * #i #ltin @enumn_complete_aux //
102 definition initN ≝ λn.
103 mk_FinSet (Nat_to n) (enumn n) (enumn_unique n) (enumn_complete n).
105 example tipa: ∀n.∃x: initN (S n). pi1 … x = n.
106 #n @ex_intro [whd @mk_Sig [@n | @le_n] | //] qed.
109 definition enum_option ≝ λA:DeqSet.λl.
110 None A::(map ?? (Some A) l).
112 lemma enum_option_def : ∀A:FinSet.∀l.
113 enum_option A l = None A :: (map ?? (Some A) l).
116 lemma enum_option_unique: ∀A:DeqSet.∀l.
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/
126 |@unique_map_inj // #a #a1 #H destruct %
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
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)).
142 unification hint 0 ≔ C;
145 (* ---------------------------------------- *) ⊢
146 option T ≡ FinSetcarr X.
149 definition enum_sum ≝ λA,B:DeqSet.λl1.λl2.
150 (map ?? (inl A B) l1) @ (map ?? (inr A B) l2).
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).
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 //
169 [normalize #H destruct
170 |#b #tlB #Hind #membH cases (orb_true_l … membH)
171 [#H lapply (\P H) #H1 destruct |@Hind]
174 |@Hind // @(andb_true_r … uA)
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
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)).
195 include alias "basics/types.ma".
197 unification hint 0 ≔ C1,C2;
201 (* ---------------------------------------- *) ⊢
202 T1+T2 ≡ FinSetcarr X.
206 definition enum_prod ≝ λA,B:DeqSet.λl1.λl2.
207 compose ??? (mk_Prod A B) l1 l2.
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.
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)
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
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 //
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)).
243 unification hint 0 ≔ C1,C2;
247 (* ---------------------------------------- *) ⊢
248 T1×T2 ≡ FinSetcarr X.
250 (* graph of a function *)
252 definition graph_of ≝ λA,B.λf:A→B.
253 Σp:A×B.f (\fst p) = \snd p.
255 definition graph_enum ≝ λA,B:FinSet.λf:A→B.
256 filter ? (λp.f (\fst p) == \snd p) (enum (FinProd A B)).
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))
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)
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 //