]> matita.cs.unibo.it Git - helm.git/blobdiff - 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
index df8d0a87c66ae6783735f95a0c1b4791cd3f76f0..24a5e16ce55a900d168a73965698f9ea576393b4 100644 (file)
@@ -9,7 +9,7 @@
      \ /   GNU General Public License Version 2   
       V_______________________________________________________________ *)
 
-include "basics/lists/listb.ma".
+include "basics/deqlist.ma".
 
 (****** DeqSet: a set with a decidable equality ******)
 
@@ -270,3 +270,184 @@ 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.
+
+(* FinFun *)
+   
+definition enum_fun_raw: ∀A,B:DeqSet.list A → list B → list (list (DeqProd A B)) ≝
+  λA,B,lA,lB.foldr A (list (list (DeqProd A B))) 
+   (λa.compose ??? (λb. cons ? 〈a,b〉) lB) [[]] lA.
+   
+lemma enum_fun_raw_cons: ∀A,B,a,lA,lB. 
+  enum_fun_raw A B (a::lA) lB = 
+    compose ??? (λb. cons ? 〈a,b〉) lB (enum_fun_raw A B lA lB).
+//
+qed.  
+
+definition is_functional ≝ λA,B:DeqSet.λlA:list A.λl: list (DeqProd A B).
+  map ?? (fst A B) l = lA.
+
+definition carr_fun ≝ λA,B:FinSet.
+  DeqSig (DeqList (DeqProd A B)) (is_functional A B (enum A)).
+
+definition carr_fun_l ≝ λA,B:DeqSet.λl.
+  DeqSig (DeqList (DeqProd A B)) (is_functional A B l).
+
+lemma compose_spec1 : ∀A,B,C:DeqSet.∀f:A→B→C.∀a:A.∀b:B.∀lA:list A.∀lB:list B.  
+  a ∈ lA = true → b ∈ lB = true → ((f a b) ∈ (compose A B C f lA lB)) = true.
+#A #B #C #f #a #b #lA elim lA
+  [normalize #lB #H destruct
+  |#a1 #tl #Hind #lB #Ha #Hb cases (orb_true_l ?? Ha) #Hcase
+    [>(\P Hcase) normalize @memb_append_l1 @memb_map //
+    |@memb_append_l2 @Hind //
+    ]
+  ]
+qed.
+
+lemma compose_cons: ∀A,B,C.∀f:A→B→C.∀l1,l2,a.
+  compose A B C f (a::l1) l2 =
+    (map ?? (f a) l2)@(compose A B C f l1 l2). 
+// qed.
+
+lemma compose_spec2 : ∀A,B,C:DeqSet.∀f:A→B→C.∀c:C.∀lA:list A.∀lB:list B.  
+  c ∈ (compose A B C f lA lB) = true → 
+    ∃a,b.a ∈ lA = true ∧ b ∈ lB = true ∧ c = f a b.
+#A #B #C #f #c #lA elim lA
+  [normalize #lB #H destruct
+  |#a1 #tl #Hind #lB >compose_cons #Hc cases (memb_append … Hc) #Hcase
+    [lapply(memb_map_to_exists … Hcase) * #b * #Hb #Hf
+     %{a1} %{b} /3/
+    |lapply(Hind ? Hcase) * #a2 * #b * * #Ha #Hb #Hf %{a2} %{b} % // % //
+     @orb_true_r2 //
+    ]
+  ]
+qed.
+
+definition compose2 ≝ 
+  λA,B:DeqSet.λa:A.λl. compose B (carr_fun_l A B l) (carr_fun_l A B (a::l)) 
+   (λb,tl. mk_Sig ?? (〈a,b〉::(pi1 … tl)) ?).
+normalize @eq_f @(pi2 … tl) 
+qed.
+
+let rec Dfoldr (A:Type[0]) (B:list A → Type[0]) 
+ (f:∀a:A.∀l.B l → B (a::l)) (b:B [ ]) (l:list A) on l : B l ≝  
+ match l with [ nil ⇒ b | cons a l ⇒ f a l (Dfoldr A B f b l)].
+
+definition empty_graph: ∀A,B:DeqSet. carr_fun_l A B []. 
+#A #B %{[]} // qed.
+
+definition enum_fun: ∀A,B:DeqSet.∀lA:list A.list B → list (carr_fun_l A B lA) ≝
+  λA,B,lA,lB.Dfoldr A (λl.list (carr_fun_l A B l)) 
+   (λa,l.compose2 ?? a l lB) [empty_graph A B] lA.
+
+lemma mem_enum_fun: ∀A,B:DeqSet.∀lA,lB.∀x:carr_fun_l A B lA. 
+  pi1 … x ∈ map ?? (pi1 … ) (enum_fun A B lA lB) = true → 
+  x ∈ enum_fun A B lA lB = true .
+#A #B #lA #lB #x @(memb_map_inj  
+  (DeqSig (DeqList (DeqProd A B))
+   (λx0:DeqList (DeqProd A B).is_functional A B lA x0))
+  (DeqList (DeqProd A B)) (pi1 …))
+* #l1 #H1 * #l2 #H2 #Heq lapply H1 lapply H2 >Heq // 
+qed.
+  
+lemma enum_fun_cons: ∀A,B,a,lA,lB. 
+  enum_fun A B (a::lA) lB = 
+    compose ??? (λb,tl. mk_Sig ?? (〈a,b〉::(pi1 … tl)) ?) lB (enum_fun A B lA lB).
+//
+qed.
+
+lemma map_map: ∀A,B,C.∀f:A→B.∀g:B→C.∀l.
+  map ?? g (map ?? f l) =  map ?? (g ∘ f) l.
+#A #B #C #f #g #l elim l [//]
+#a #tl #Hind normalize @eq_f @Hind
+qed.
+
+lemma map_compose: ∀A,B,C,D.∀f:A→B→C.∀g:C→D.∀l1,l2.
+  map ?? g (compose A B C f l1 l2) = compose A B D (λa,b. g (f a b)) l1 l2.
+#A #B #C #D #f #g #l1 elim l1 [//]
+#a #tl #Hind #l2 >compose_cons >compose_cons <map_append @eq_f2
+  [@map_map |@Hind]
+qed.
+   
+definition enum_fun_graphs: ∀A,B,lA,lB.
+  map ?? (pi1 … ) (enum_fun A B lA lB) = enum_fun_raw A B lA lB.
+#A #B #lA elim lA [normalize //]
+#a #tl #Hind #lB >(enum_fun_cons A B a tl lB) >enum_fun_raw_cons >map_compose 
+cut (∀lB2. compose B (Σx:DeqList (DeqProd A B).is_functional A B tl x)
+  (DeqList (DeqProd A B))
+  (λa0:B
+   .λb:Σx:DeqList (DeqProd A B).is_functional A B tl x
+    .〈a,a0〉
+     ::pi1 (list (A×B)) (λx:DeqList (DeqProd A B).is_functional A B tl x) b) lB
+  (enum_fun A B tl lB2)
+  =compose B (list (A×B)) (list (A×B)) (λb:B.cons (A×B) 〈a,b〉) lB
+   (enum_fun_raw A B tl lB2))
+  [#lB2 elim lB
+    [normalize //
+    |#b #tlb #Hindb >compose_cons in ⊢ (???%); >compose_cons 
+     @eq_f2 [<Hind >map_map // |@Hindb]]] 
+#Hcut @Hcut
+qed.    
+
+lemma uniqueb_compose: ∀A,B,C:DeqSet.∀f,l1,l2. 
+  (∀a1,a2,b1,b2. f a1 b1 = f a2 b2 → a1 = a2 ∧ b1 = b2) →
+  uniqueb ? l1 = true → uniqueb ? l2 = true → 
+    uniqueb ? (compose A B C f l1 l2) = true.
+#A #B #C #f #l1 #l2 #Hinj elim l1 //
+#a #tl #Hind #HuA #HuB >compose_cons @uniqueb_append
+  [@(unique_map_inj … HuB) #b1 #b2 #Hb1b2 @(proj2 … (Hinj … Hb1b2))
+  |@Hind // @(andb_true_r … HuA)
+  |#c #Hc lapply(memb_map_to_exists … Hc) * #b * #Hb2 #Hfab % #Hc
+   lapply(compose_spec2 … Hc) * #a1 * #b1 * * #Ha1 #Hb1 <Hfab #H
+   @(absurd (a=a1)) 
+    [@(proj1 … (Hinj … H))
+    |% #eqa @(absurd … Ha1) % <eqa #H lapply(andb_true_l … HuA) >H 
+     normalize #H1 destruct (H1) 
+    ]
+  ]
+qed.
+
+lemma enum_fun_unique: ∀A,B:DeqSet.∀lA,lB.
+    uniqueb ? lA = true → uniqueb ? lB = true →
+    uniqueb ? (enum_fun A B lA lB) = true.
+#A #B #lA elim lA
+  [#lB #_ #ulB //
+  |#a #tlA #Hind #lB #uA #uB lapply (enum_fun_cons A B a tlA lB) #H >H
+   @(uniqueb_compose B (carr_fun_l A B tlA) (carr_fun_l A B (a::tlA))) 
+    [#b1 #b2 * #l1 #funl1 * #l2 #funl2 #H1 destruct (H1) /2/
+    |//
+    |@(Hind … uB) @(andb_true_r … uA)
+    ]
+  ]
+qed.
+
+lemma enum_fun_complete: ∀A,B:FinSet.∀l1,l2. 
+  (∀x:A. memb A x l1 = true) →
+  (∀x:B. memb B x l2 = true) →
+    ∀x:carr_fun_l A B l1. memb ? x (enum_fun A B l1 l2) = true.
+#A #B #l1 #l2 #H1 #H2 * #g #H @mem_enum_fun >enum_fun_graphs 
+lapply H -H lapply g -g elim l1  
+  [* // #p #tlg normalize #H destruct (H)
+  |#a #tl #Hind #g cases g
+    [normalize in ⊢ (%→?); #H destruct (H)
+    |* #a1 #b #tl1 normalize in ⊢ (%→?); #H
+     cut (is_functional A B tl tl1) [destruct (H) //] #Hfun 
+     >(cons_injective_l ????? H)
+     >(enum_fun_raw_cons … ) @(compose_spec1 … (λb. cons ? 〈a,b〉))
+      [@H2 |@Hind @Hfun]
+    ]
+  ]
+qed.
+    
+definition FinFun ≝ 
+λA,B:FinSet.mk_FinSet (carr_fun A B)
+  (enum_fun A B (enum A) (enum B)) 
+  (enum_fun_unique A B … (enum_unique A) (enum_unique B))
+  (enum_fun_complete A B … (enum_complete A) (enum_complete B)).
+
+(*
+unification hint  0 ≔ C1,C2; 
+    T1 ≟ FinSetcarr C1,
+    T2 ≟ FinSetcarr C2,
+    X ≟ FinProd C1 C2
+(* ---------------------------------------- *) ⊢ 
+    T1×T2 ≡ FinSetcarr X. *)
\ No newline at end of file