X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=matita%2Fmatita%2Flib%2Fbasics%2Ffinset.ma;h=d72388dfb19953c525c6f43256f0796e44c8eec4;hb=723514507b1e2e58c0a8c7bcc39c5d1301b910bc;hp=1b972ec06c7cdb8db859838572c93bef7813fcd6;hpb=65a3b93b01f2d00960c56df3563b879f36f3cbfd;p=helm.git diff --git a/matita/matita/lib/basics/finset.ma b/matita/matita/lib/basics/finset.ma index 1b972ec06..d72388dfb 100644 --- a/matita/matita/lib/basics/finset.ma +++ b/matita/matita/lib/basics/finset.ma @@ -11,60 +11,248 @@ include "basics/lists/listb.ma". -(****** DeqSet: a set with a decidbale equality ******) +(****** DeqSet: a set with a decidable equality ******) record FinSet : Type[1] ≝ -{ carr:> DeqSet; - enum: list carr; - enum_complete: ∀x.memb carr x enum = true; - enum_unique: uniqueb carr enum = true +{ FinSetcarr:> DeqSet; + enum: list FinSetcarr; + enum_unique: uniqueb FinSetcarr enum = true; + enum_complete : ∀x:FinSetcarr. memb ? x enum = true }. -(* -definition DeqBool ≝ mk_DeqSet bool beqb beqb_true. +notation < "𝐅" non associative with precedence 90 + for @{'bigF}. +interpretation "FinSet" 'bigF = (mk_FinSet ???). + +(* bool *) +lemma bool_enum_unique: uniqueb ? [true;false] = true. +// qed. + +lemma bool_enum_complete: ∀x:bool. memb ? x [true;false] = true. +* // qed. + +definition FinBool ≝ + mk_FinSet DeqBool [true;false] bool_enum_unique bool_enum_complete. unification hint 0 ≔ ; - X ≟ mk_DeqSet bool beqb beqb_true + X ≟ FinBool (* ---------------------------------------- *) ⊢ - bool ≡ carr X. - -unification hint 0 ≔ b1,b2:bool; - X ≟ mk_DeqSet bool beqb beqb_true -(* ---------------------------------------- *) ⊢ - beqb b1 b2 ≡ eqb X b1 b2. + bool ≡ FinSetcarr X. + +(* nat segment *) + +lemma eqbnat_true : ∀n,m. eqb n m = true ↔ n = m. +#n #m % [@eqb_true_to_eq | @eq_to_eqb_true] +qed. + +definition DeqNat ≝ mk_DeqSet nat eqb eqbnat_true. + +lemma lt_to_le : ∀n,m. n < m → n ≤ m. +/2/ qed-. + +let rec enumnaux n m ≝ + match n return (λn.n ≤ m → list (Σx.x < m)) with + [ O ⇒ λh.[ ] | S p ⇒ λh:p < m.(mk_Sig ?? p h)::enumnaux p m (lt_to_le p m h)]. -example exhint: ∀b:bool. (b == false) = true → b = false. -#b #H @(\P H). +definition enumn ≝ λn.enumnaux n n (le_n n). + +definition Nat_to ≝ λn. DeqSig DeqNat (λi.iHfalse @le_n + |<(notb_notb (memb …)) >Hind normalize /2/ + ] +qed. + + +lemma enumn_unique_aux: ∀n,m. ∀h:n ≤ m. uniqueb (Nat_to m) (enumnaux n m h) = true. +#n elim n -n // #n #Hind #m #h @true_to_andb_true // @memb_enumn // +qed. + +lemma enumn_unique: ∀n.uniqueb (Nat_to n) (enumn n) = true. +#n @enumn_unique_aux +qed. + +(* definition ltb ≝ λn,m.leb (S n) m. *) +lemma enumn_complete_aux: ∀n,m,i.∀h:n ≤m.∀k:iHcut @Hind // + |#eqin cut (eqb (Nat_to m) (mk_Sig ?? i k) (mk_Sig ?? n h) = true) + [normalize @eq_to_eqb_true // + |#Hcut >Hcut % + ] + ] qed. -(* pairs *) -definition eq_pairs ≝ - λA,B:DeqSet.λp1,p2:A×B.(\fst p1 == \fst p2) ∧ (\snd p1 == \snd p2). +lemma enumn_complete: ∀n.∀i:Nat_to n. memb ? i (enumn n) = true. +#n whd in ⊢ (%→?); * #i #ltin @enumn_complete_aux // +qed. + +definition initN ≝ λn. + mk_FinSet (Nat_to n) (enumn n) (enumn_unique n) (enumn_complete n). -lemma eq_pairs_true: ∀A,B:DeqSet.∀p1,p2:A×B. - eq_pairs A B p1 p2 = true ↔ p1 = p2. -#A #B * #a1 #b1 * #a2 #b2 % - [#H cases (andb_true …H) #eqa #eqb >(\P eqa) >(\P eqb) // - |#H destruct normalize >(\b (refl … a2)) >(\b (refl … b2)) // +example tipa: ∀n.∃x: initN (S n). pi1 … x = n. +#n @ex_intro [whd @mk_Sig [@n | @le_n] | //] qed. + +(* option *) +definition enum_option ≝ λA:DeqSet.λl. + None A::(map ?? (Some A) l). + +lemma enum_option_def : ∀A:FinSet.∀l. + enum_option A l = None A :: (map ?? (Some A) l). +// qed. + +lemma enum_option_unique: ∀A:DeqSet.∀l. + uniqueb A l = true → + uniqueb ? (enum_option A l) = true. +#A #l #uA @true_to_andb_true + [generalize in match uA; -uA #_ elim l [%] + #a #tl #Hind @sym_eq @noteq_to_eqnot % #H + cases (orb_true_l … (sym_eq … H)) + [#H1 @(absurd (None A = Some A a)) [@(\P H1) | % #H2 destruct] + |-H #H >H in Hind; normalize /2/ + ] + |@unique_map_inj // #a #a1 #H destruct % ] qed. -definition DeqProd ≝ λA,B:DeqSet. - mk_DeqSet (A×B) (eq_pairs A B) (eq_pairs_true A B). +lemma enum_option_complete: ∀A:DeqSet.∀l. + (∀x:A. memb A x l = true) → + ∀x:DeqOption A. memb ? x (enum_option A l) = true. +#A #l #Hl * // #a @memb_cons @memb_map @Hl +qed. + +definition FinOption ≝ λA:FinSet. + mk_FinSet (DeqOption A) + (enum_option A (enum A)) + (enum_option_unique … (enum_unique A)) + (enum_option_complete … (enum_complete A)). + +unification hint 0 ≔ C; + T ≟ FinSetcarr C, + X ≟ FinOption C +(* ---------------------------------------- *) ⊢ + option T ≡ FinSetcarr X. + +(* sum *) +definition enum_sum ≝ λA,B:DeqSet.λl1.λl2. + (map ?? (inl A B) l1) @ (map ?? (inr A B) l2). +lemma enum_sum_def : ∀A,B:FinSet.∀l1,l2. enum_sum A B l1 l2 = + (map ?? (inl A B) l1) @ (map ?? (inr A B) l2). +// qed. + +lemma enum_sum_unique: ∀A,B:DeqSet.∀l1,l2. + uniqueb A l1 = true → uniqueb B l2 = true → + uniqueb ? (enum_sum A B l1 l2) = true. +#A #B #l1 #l2 elim l1 + [#_ #ul2 @unique_map_inj // #b1 #b2 #Hinr destruct // + |#a #tl #Hind #uA #uB @true_to_andb_true + [@sym_eq @noteq_to_eqnot % #H + cases (memb_append … (sym_eq … H)) + [#H1 @(absurd (memb ? a tl = true)) + [@(memb_map_inj …H1) #a1 #a2 #Hinl destruct // + |<(andb_true_l … uA) @eqnot_to_noteq // + ] + |elim l2 + [normalize #H destruct + |#b #tlB #Hind #membH cases (orb_true_l … membH) + [#H lapply (\P H) #H1 destruct |@Hind] + ] + ] + |@Hind // @(andb_true_r … uA) + ] + ] +qed. + +lemma enum_sum_complete: ∀A,B:DeqSet.∀l1,l2. + (∀x:A. memb A x l1 = true) → + (∀x:B. memb B x l2 = true) → + ∀x:DeqSum A B. memb ? x (enum_sum A B l1 l2) = true. +#A #B #l1 #l2 #Hl1 #Hl2 * + [#a @memb_append_l1 @memb_map @Hl1 + |#b @memb_append_l2 @memb_map @Hl2 + ] +qed. + +definition FinSum ≝ λA,B:FinSet. + mk_FinSet (DeqSum A B) + (enum_sum A B (enum A) (enum B)) + (enum_sum_unique … (enum_unique A) (enum_unique B)) + (enum_sum_complete … (enum_complete A) (enum_complete B)). + +include alias "basics/types.ma". + unification hint 0 ≔ C1,C2; - T1 ≟ carr C1, - T2 ≟ carr C2, - X ≟ DeqProd C1 C2 + T1 ≟ FinSetcarr C1, + T2 ≟ FinSetcarr C2, + X ≟ FinSum C1 C2 (* ---------------------------------------- *) ⊢ - T1×T2 ≡ carr X. + T1+T2 ≡ FinSetcarr X. + +(* prod *) -unification hint 0 ≔ T1,T2,p1,p2; - X ≟ DeqProd T1 T2 +definition enum_prod ≝ λA,B:DeqSet.λl1.λl2. + compose ??? (mk_Prod A B) l1 l2. + +axiom enum_prod_unique: ∀A,B,l1,l2. + uniqueb A l1 = true → uniqueb B l2 = true → + uniqueb ? (enum_prod A B l1 l2) = true. + +lemma enum_prod_complete:∀A,B:DeqSet.∀l1,l2. + (∀a. memb A a l1 = true) → (∀b.memb B b l2 = true) → + ∀p. memb ? p (enum_prod A B l1 l2) = true. +#A #B #l1 #l2 #Hl1 #Hl2 * #a #b @memb_compose // +qed. + +definition FinProd ≝ +λA,B:FinSet.mk_FinSet (DeqProd A B) + (enum_prod A B (enum A) (enum B)) + (enum_prod_unique A B … (enum_unique A) (enum_unique B)) + (enum_prod_complete A B … (enum_complete A) (enum_complete B)). + +unification hint 0 ≔ C1,C2; + T1 ≟ FinSetcarr C1, + T2 ≟ FinSetcarr C2, + X ≟ FinProd C1 C2 (* ---------------------------------------- *) ⊢ - eq_pairs T1 T2 p1 p2 ≡ eqb X p1 p2. + T1×T2 ≡ FinSetcarr X. + +(* graph of a function *) + +definition graph_of ≝ λA,B.λf:A→B. + Σp:A×B.f (\fst p) = \snd p. -example hint2: ∀b1,b2. - 〈b1,true〉==〈false,b2〉=true → 〈b1,true〉=〈false,b2〉. -#b1 #b2 #H @(\P H). -*) \ No newline at end of file +definition graph_enum ≝ λA,B:FinSet.λf:A→B. + filter ? (λp.f (\fst p) == \snd p) (enum (FinProd A B)). + +lemma graph_enum_unique : ∀A,B,f. + uniqueb ? (graph_enum A B f) = true. +#A #B #f @uniqueb_filter @(enum_unique (FinProd A B)) +qed. + +lemma graph_enum_correct: ∀A,B:FinSet.∀f:A→B. ∀a,b. +memb ? 〈a,b〉 (graph_enum A B f) = true → f a = b. +#A #B #f #a #b #membp @(\P ?) @(filter_true … membp) +qed. + +lemma graph_enum_complete: ∀A,B:FinSet.∀f:A→B. ∀a,b. +f a = b → memb ? 〈a,b〉 (graph_enum A B f) = true. +#A #B #f #a #b #eqf @memb_filter_l [@(\b eqf)] +@enum_prod_complete // +qed.