Attic/Quot/Examples/FSet3.thy
changeset 1260 9df6144e281b
parent 1144 538daee762e6
child 1850 05b2dd2b0e8a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Attic/Quot/Examples/FSet3.thy	Thu Feb 25 07:57:17 2010 +0100
@@ -0,0 +1,717 @@
+theory FSet3
+imports "../Quotient" "../Quotient_List" List
+begin
+
+ML {*
+structure QuotientRules = Named_Thms
+  (val name = "quot_thm"
+   val description = "Quotient theorems.")
+*}
+
+ML {*
+open QuotientRules
+*}
+
+fun
+  list_eq :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" (infix "\<approx>" 50)
+where
+  "list_eq xs ys = (\<forall>x. x \<in> set xs \<longleftrightarrow> x \<in> set ys)"
+
+lemma list_eq_equivp:
+  shows "equivp list_eq"
+unfolding equivp_reflp_symp_transp reflp_def symp_def transp_def
+by auto
+
+(* FIXME-TODO: because of beta-reduction, one cannot give the *)
+(* FIXME-TODO: relation as a term or abbreviation             *) 
+quotient_type 
+  'a fset = "'a list" / "list_eq"
+by (rule list_eq_equivp)
+
+
+section {* empty fset, finsert and membership *} 
+
+quotient_definition
+  fempty  ("{||}")
+where
+  "fempty :: 'a fset"
+is "[]::'a list"
+
+quotient_definition
+  "finsert :: 'a \<Rightarrow> 'a fset \<Rightarrow> 'a fset" 
+is "op #"
+
+syntax
+  "@Finset"     :: "args => 'a fset"  ("{|(_)|}")
+
+translations
+  "{|x, xs|}" == "CONST finsert x {|xs|}"
+  "{|x|}"     == "CONST finsert x {||}"
+
+definition 
+  memb :: "'a \<Rightarrow> 'a list \<Rightarrow> bool"
+where
+  "memb x xs \<equiv> x \<in> set xs"
+
+quotient_definition
+  fin ("_ |\<in>| _" [50, 51] 50)
+where
+  "fin :: 'a \<Rightarrow> 'a fset \<Rightarrow> bool"
+is "memb"
+
+abbreviation
+  fnotin :: "'a \<Rightarrow> 'a fset \<Rightarrow> bool" ("_ |\<notin>| _" [50, 51] 50)
+where
+  "a |\<notin>| S \<equiv> \<not>(a |\<in>| S)"
+
+lemma memb_rsp[quot_respect]: 
+  shows "(op = ===> op \<approx> ===> op =) memb memb"
+by (auto simp add: memb_def)
+
+lemma nil_rsp[quot_respect]:
+  shows "[] \<approx> []"
+by simp
+
+lemma cons_rsp[quot_respect]: 
+  shows "(op = ===> op \<approx> ===> op \<approx>) op # op #"
+by simp
+
+
+section {* Augmenting a set -- @{const finsert} *}
+
+text {* raw section *}
+
+lemma nil_not_cons:
+  shows "\<not>[] \<approx> x # xs"
+  by auto
+
+lemma memb_cons_iff:
+  shows "memb x (y # xs) = (x = y \<or> memb x xs)"
+  by (induct xs) (auto simp add: memb_def)
+
+lemma memb_consI1:
+  shows "memb x (x # xs)"
+  by (simp add: memb_def)
+
+lemma memb_consI2:
+  shows "memb x xs \<Longrightarrow> memb x (y # xs)"
+  by (simp add: memb_def)
+
+lemma memb_absorb:
+  shows "memb x xs \<Longrightarrow> x # xs \<approx> xs"
+  by (induct xs) (auto simp add: memb_def id_simps)
+
+text {* lifted section *}
+
+lemma fin_finsert_iff[simp]:
+  "x |\<in>| finsert y S = (x = y \<or> x |\<in>| S)"
+by (lifting memb_cons_iff) 
+
+lemma
+  shows finsertI1: "x |\<in>| finsert x S"
+  and   finsertI2: "x |\<in>| S \<Longrightarrow> x |\<in>| finsert y S"
+  by (lifting memb_consI1, lifting memb_consI2)
+
+
+lemma finsert_absorb [simp]: 
+  shows "x |\<in>| S \<Longrightarrow> finsert x S = S"
+  by (lifting memb_absorb)
+
+
+section {* Singletons *}
+
+text {* raw section *}
+
+lemma singleton_list_eq:
+  shows "[x] \<approx> [y] \<longleftrightarrow> x = y"
+  by (simp add: id_simps) auto
+
+text {* lifted section *}
+
+lemma fempty_not_finsert[simp]:
+  shows "{||} \<noteq> finsert x S"
+  by (lifting nil_not_cons)
+
+lemma fsingleton_eq[simp]:
+  shows "{|x|} = {|y|} \<longleftrightarrow> x = y"
+  by (lifting singleton_list_eq)
+
+section {* Union *}
+
+quotient_definition
+  funion  (infixl "|\<union>|" 65)
+where
+  "funion :: 'a fset \<Rightarrow> 'a fset \<Rightarrow> 'a fset"
+is
+  "op @"
+
+section {* Cardinality of finite sets *}
+
+fun
+  fcard_raw :: "'a list \<Rightarrow> nat"
+where
+  fcard_raw_nil:  "fcard_raw [] = 0"
+| fcard_raw_cons: "fcard_raw (x # xs) = (if memb x xs then fcard_raw xs else Suc (fcard_raw xs))"
+
+quotient_definition
+  "fcard :: 'a fset \<Rightarrow> nat" 
+is "fcard_raw"
+
+text {* raw section *}
+
+lemma fcard_raw_ge_0:
+  assumes a: "x \<in> set xs"
+  shows "0 < fcard_raw xs"
+using a
+by (induct xs) (auto simp add: memb_def)
+
+lemma fcard_raw_delete_one:
+  "fcard_raw ([x \<leftarrow> xs. x \<noteq> y]) = (if memb y xs then fcard_raw xs - 1 else fcard_raw xs)"
+by (induct xs) (auto dest: fcard_raw_ge_0 simp add: memb_def)
+
+lemma fcard_raw_rsp_aux:
+  assumes a: "a \<approx> b"
+  shows "fcard_raw a = fcard_raw b"
+using a
+apply(induct a arbitrary: b)
+apply(auto simp add: memb_def)
+apply(metis)
+apply(drule_tac x="[x \<leftarrow> b. x \<noteq> a1]" in meta_spec)
+apply(simp add: fcard_raw_delete_one)
+apply(metis Suc_pred' fcard_raw_ge_0 fcard_raw_delete_one memb_def)
+done
+
+lemma fcard_raw_rsp[quot_respect]:
+  "(op \<approx> ===> op =) fcard_raw fcard_raw"
+  by (simp add: fcard_raw_rsp_aux)
+
+text {* lifted section *}
+
+lemma fcard_fempty [simp]:
+  shows "fcard {||} = 0"
+by (lifting fcard_raw_nil)
+
+lemma fcard_finsert_if [simp]:
+  shows "fcard (finsert x S) = (if x |\<in>| S then fcard S else Suc (fcard S))"
+by (lifting fcard_raw_cons)
+
+
+section {* Induction and Cases rules for finite sets *}
+
+lemma fset_exhaust[case_names fempty finsert, cases type: fset]:
+  shows "\<lbrakk>S = {||} \<Longrightarrow> P; \<And>x S'. S = finsert x S' \<Longrightarrow> P\<rbrakk> \<Longrightarrow> P"
+by (lifting list.exhaust)
+
+lemma fset_induct[case_names fempty finsert]:
+  shows "\<lbrakk>P {||}; \<And>x S. P S \<Longrightarrow> P (finsert x S)\<rbrakk> \<Longrightarrow> P S"
+by (lifting list.induct)
+
+lemma fset_induct2[case_names fempty finsert, induct type: fset]:
+  assumes prem1: "P {||}" 
+  and     prem2: "\<And>x S. \<lbrakk>x |\<notin>| S; P S\<rbrakk> \<Longrightarrow> P (finsert x S)"
+  shows "P S"
+proof(induct S rule: fset_induct)
+  case fempty
+  show "P {||}" by (rule prem1)
+next
+  case (finsert x S)
+  have asm: "P S" by fact
+  show "P (finsert x S)"
+  proof(cases "x |\<in>| S")
+    case True
+    have "x |\<in>| S" by fact
+    then show "P (finsert x S)" using asm by simp
+  next
+    case False
+    have "x |\<notin>| S" by fact
+    then show "P (finsert x S)" using prem2 asm by simp
+  qed
+qed
+
+
+section {* fmap and fset comprehension *}
+
+quotient_definition
+  "fmap :: ('a \<Rightarrow> 'b) \<Rightarrow> 'a fset \<Rightarrow> 'b fset"
+is
+ "map"
+
+quotient_definition
+  "fconcat :: ('a fset) fset => 'a fset"
+is
+ "concat"
+
+(*lemma fconcat_rsp[quot_respect]:
+  shows "((list_rel op \<approx>) ===> op \<approx>) concat concat"
+apply(auto)
+sorry
+*)
+
+(* PROBLEM: these lemmas needs to be restated, since  *)
+(* concat.simps(1) and concat.simps(2) contain the    *)
+(* type variables ?'a1.0 (which are turned into frees *)
+(* 'a_1                                               *)
+lemma concat1:
+  shows "concat [] \<approx> []"
+by (simp add: id_simps)
+
+lemma concat2:
+  shows "concat (x # xs) \<approx> x @ concat xs"
+by (simp add: id_simps)
+
+lemma concat_rsp[quot_respect]:
+  shows "(list_rel op \<approx> OOO op \<approx> ===> op \<approx>) concat concat"
+sorry
+
+lemma nil_rsp2[quot_respect]: "(list_rel op \<approx> OOO op \<approx>) [] []"
+  apply (metis FSet3.nil_rsp list_rel.simps(1) pred_comp.intros)
+  done
+
+lemma set_in_eq: "(\<forall>e. ((e \<in> A) \<longleftrightarrow> (e \<in> B))) \<equiv> A = B"
+  apply (rule eq_reflection)
+  apply auto
+  done
+
+lemma map_rel_cong: "b \<approx> ba \<Longrightarrow> map f b \<approx> map f ba"
+  unfolding list_eq.simps
+  apply(simp only: set_map set_in_eq)
+  done
+
+lemma quotient_compose_list_pre:
+  "(list_rel op \<approx> OOO op \<approx>) r s =
+  ((list_rel op \<approx> OOO op \<approx>) r r \<and> (list_rel op \<approx> OOO op \<approx>) s s \<and>
+  abs_fset (map abs_fset r) = abs_fset (map abs_fset s))"
+  apply rule
+  apply rule
+  apply rule
+  apply (rule list_rel_refl)
+  apply (metis equivp_def fset_equivp)
+  apply rule
+  apply (rule equivp_reflp[OF fset_equivp])
+  apply (rule list_rel_refl)
+  apply (metis equivp_def fset_equivp)
+  apply(rule)
+  apply rule
+  apply (rule list_rel_refl)
+  apply (metis equivp_def fset_equivp)
+  apply rule
+  apply (rule equivp_reflp[OF fset_equivp])
+  apply (rule list_rel_refl)
+  apply (metis equivp_def fset_equivp)
+  apply (subgoal_tac "map abs_fset r \<approx> map abs_fset s")
+  apply (metis Quotient_rel[OF Quotient_fset])
+  apply (auto simp only:)[1]
+  apply (subgoal_tac "map abs_fset r = map abs_fset b")
+  prefer 2
+  apply (metis Quotient_rel[OF list_quotient[OF Quotient_fset]])
+  apply (subgoal_tac "map abs_fset s = map abs_fset ba")
+  prefer 2
+  apply (metis Quotient_rel[OF list_quotient[OF Quotient_fset]])
+  apply (simp only: map_rel_cong)
+  apply rule
+  apply (rule rep_abs_rsp[of "list_rel op \<approx>" "map abs_fset"])
+  apply (tactic {* Quotient_Tacs.quotient_tac @{context} 1 *})
+  apply (rule list_rel_refl)
+  apply (metis equivp_def fset_equivp)
+  apply rule
+  prefer 2
+  apply (rule rep_abs_rsp_left[of "list_rel op \<approx>" "map abs_fset"])
+  apply (tactic {* Quotient_Tacs.quotient_tac @{context} 1 *})
+  apply (rule list_rel_refl)
+  apply (metis equivp_def fset_equivp)
+  apply (erule conjE)+
+  apply (subgoal_tac "map abs_fset r \<approx> map abs_fset s")
+  prefer 2
+  apply (metis Quotient_def Quotient_fset equivp_reflp fset_equivp)
+  apply (rule map_rel_cong)
+  apply (assumption)
+  done
+
+lemma quotient_compose_list[quot_thm]:
+  shows  "Quotient ((list_rel op \<approx>) OOO (op \<approx>))
+    (abs_fset \<circ> (map abs_fset)) ((map rep_fset) \<circ> rep_fset)"
+  unfolding Quotient_def comp_def
+  apply (rule)+
+  apply (simp add: abs_o_rep[OF Quotient_fset] id_simps Quotient_abs_rep[OF Quotient_fset])
+  apply (rule)
+  apply (rule)
+  apply (rule)
+  apply (rule list_rel_refl)
+  apply (metis equivp_def fset_equivp)
+  apply (rule)
+  apply (rule equivp_reflp[OF fset_equivp])
+  apply (rule list_rel_refl)
+  apply (metis equivp_def fset_equivp)
+  apply rule
+  apply rule
+  apply(rule quotient_compose_list_pre)
+  done
+
+lemma fconcat_empty:
+  shows "fconcat {||} = {||}"
+apply(lifting concat1)
+apply(cleaning)
+apply(simp add: comp_def)
+apply(fold fempty_def[simplified id_simps])
+apply(rule refl)
+done
+
+(* Should be true *)
+
+lemma insert_rsp2[quot_respect]:
+  "(op \<approx> ===> list_rel op \<approx> OOO op \<approx> ===> list_rel op \<approx> OOO op \<approx>) op # op #"
+apply auto
+apply (simp add: set_in_eq)
+sorry
+
+lemma append_rsp[quot_respect]:
+  "(op \<approx> ===> op \<approx> ===> op \<approx>) op @ op @"
+  by (auto)
+
+lemma fconcat_insert:
+  shows "fconcat (finsert x S) = x |\<union>| fconcat S"
+apply(lifting concat2)
+apply(cleaning)
+apply (simp add: finsert_def fconcat_def comp_def)
+apply cleaning
+done
+
+text {* raw section *}
+
+lemma map_rsp_aux:
+  assumes a: "a \<approx> b"
+  shows "map f a \<approx> map f b"
+  using a
+apply(induct a arbitrary: b)
+apply(auto)
+apply(metis rev_image_eqI)
+done
+
+lemma map_rsp[quot_respect]:
+  shows "(op = ===> op \<approx> ===> op \<approx>) map map"
+by (auto simp add: map_rsp_aux)
+
+
+text {* lifted section *}
+
+(* TBD *)
+
+text {* syntax for fset comprehensions (adapted from lists) *}
+
+nonterminals fsc_qual fsc_quals
+
+syntax
+"_fsetcompr" :: "'a \<Rightarrow> fsc_qual \<Rightarrow> fsc_quals \<Rightarrow> 'a fset"  ("{|_ . __")
+"_fsc_gen" :: "'a \<Rightarrow> 'a fset \<Rightarrow> fsc_qual" ("_ <- _")
+"_fsc_test" :: "bool \<Rightarrow> fsc_qual" ("_")
+"_fsc_end" :: "fsc_quals" ("|}")
+"_fsc_quals" :: "fsc_qual \<Rightarrow> fsc_quals \<Rightarrow> fsc_quals" (", __")
+"_fsc_abs" :: "'a => 'b fset => 'b fset"
+
+syntax (xsymbols)
+"_fsc_gen" :: "'a \<Rightarrow> 'a fset \<Rightarrow> fsc_qual" ("_ \<leftarrow> _")
+syntax (HTML output)
+"_fsc_gen" :: "'a \<Rightarrow> 'a fset \<Rightarrow> fsc_qual" ("_ \<leftarrow> _")
+
+parse_translation (advanced) {*
+let
+  val femptyC = Syntax.const @{const_name fempty};
+  val finsertC = Syntax.const @{const_name finsert};
+  val fmapC = Syntax.const @{const_name fmap};
+  val fconcatC = Syntax.const @{const_name fconcat};
+  val IfC = Syntax.const @{const_name If};
+  fun fsingl x = finsertC $ x $ femptyC;
+
+  fun pat_tr ctxt p e opti = (* %x. case x of p => e | _ => [] *)
+    let
+      val x = Free (Name.variant (fold Term.add_free_names [p, e] []) "x", dummyT);
+      val e = if opti then fsingl e else e;
+      val case1 = Syntax.const "_case1" $ p $ e;
+      val case2 = Syntax.const "_case1" $ Syntax.const Term.dummy_patternN
+                                        $ femptyC;
+      val cs = Syntax.const "_case2" $ case1 $ case2
+      val ft = Datatype_Case.case_tr false Datatype.info_of_constr
+                 ctxt [x, cs]
+    in lambda x ft end;
+
+  fun abs_tr ctxt (p as Free(s,T)) e opti =
+        let val thy = ProofContext.theory_of ctxt;
+            val s' = Sign.intern_const thy s
+        in if Sign.declared_const thy s'
+           then (pat_tr ctxt p e opti, false)
+           else (lambda p e, true)
+        end
+    | abs_tr ctxt p e opti = (pat_tr ctxt p e opti, false);
+
+  fun fsc_tr ctxt [e, Const("_fsc_test",_) $ b, qs] =
+        let 
+          val res = case qs of 
+                      Const("_fsc_end",_) => fsingl e
+                    | Const("_fsc_quals",_)$ q $ qs => fsc_tr ctxt [e, q, qs];
+        in 
+          IfC $ b $ res $ femptyC 
+        end
+
+    | fsc_tr ctxt [e, Const("_fsc_gen",_) $ p $ es, Const("_fsc_end",_)] =
+         (case abs_tr ctxt p e true of
+            (f,true) => fmapC $ f $ es
+          | (f, false) => fconcatC $ (fmapC $ f $ es))
+       
+    | fsc_tr ctxt [e, Const("_fsc_gen",_) $ p $ es, Const("_fsc_quals",_) $ q $ qs] =
+        let
+          val e' = fsc_tr ctxt [e, q, qs];
+        in 
+          fconcatC $ (fmapC $ (fst (abs_tr ctxt p e' false)) $ es) 
+        end
+
+in [("_fsetcompr", fsc_tr)] end
+*}
+
+
+(* NEEDS FIXING *)
+(* examles *)
+(*
+term "{|(x,y,z). b|}"
+term "{|x. x \<leftarrow> xs|}"
+term "{|(x,y,z). x\<leftarrow>xs|}"
+term "{|e x y. x\<leftarrow>xs, y\<leftarrow>ys|}"
+term "{|(x,y,z). x<a, x>b|}"
+term "{|(x,y,z). x\<leftarrow>xs, x>b|}"
+term "{|(x,y,z). x<a, x\<leftarrow>xs|}"
+term "{|(x,y). Cons True x \<leftarrow> xs|}"
+term "{|(x,y,z). Cons x [] \<leftarrow> xs|}"
+term "{|(x,y,z). x<a, x>b, x=d|}"
+term "{|(x,y,z). x<a, x>b, y\<leftarrow>ys|}"
+term "{|(x,y,z). x<a, x\<leftarrow>xs,y>b|}"
+term "{|(x,y,z). x<a, x\<leftarrow>xs, y\<leftarrow>ys|}"
+term "{|(x,y,z). x\<leftarrow>xs, x>b, y<a|}"
+term "{|(x,y,z). x\<leftarrow>xs, x>b, y\<leftarrow>ys|}"
+term "{|(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys,y>x|}"
+term "{|(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys,z\<leftarrow>zs|}"
+*)
+
+(* BELOW CONSTRUCTION SITE *)
+
+
+lemma no_mem_nil: 
+  "(\<forall>a. a \<notin> set A) = (A = [])"
+by (induct A) (auto)
+
+lemma none_mem_nil: 
+  "(\<forall>a. a \<notin> set A) = (A \<approx> [])"
+by simp
+
+lemma mem_cons: 
+  "a \<in> set A \<Longrightarrow> a # A \<approx> A"
+by auto
+
+lemma cons_left_comm:
+  "x # y # A \<approx> y # x # A"
+by (auto simp add: id_simps)
+
+lemma cons_left_idem:
+  "x # x # A \<approx> x # A"
+by (auto simp add: id_simps)
+
+lemma finite_set_raw_strong_cases:
+  "(X = []) \<or> (\<exists>a Y. ((a \<notin> set Y) \<and> (X \<approx> a # Y)))"
+  apply (induct X)
+  apply (simp)
+  apply (rule disjI2)
+  apply (erule disjE)
+  apply (rule_tac x="a" in exI)
+  apply (rule_tac x="[]" in exI)
+  apply (simp)
+  apply (erule exE)+
+  apply (case_tac "a = aa")
+  apply (rule_tac x="a" in exI)
+  apply (rule_tac x="Y" in exI)
+  apply (simp)
+  apply (rule_tac x="aa" in exI)
+  apply (rule_tac x="a # Y" in exI)
+  apply (auto)
+  done
+
+fun
+  delete_raw :: "'a list \<Rightarrow> 'a \<Rightarrow> 'a list"
+where
+  "delete_raw [] x = []"
+| "delete_raw (a # A) x = (if (a = x) then delete_raw A x else a # (delete_raw A x))"
+
+lemma mem_delete_raw:
+  "x \<in> set (delete_raw A a) = (x \<in> set A \<and> \<not>(x = a))"
+  by (induct A arbitrary: x a) (auto)
+
+lemma mem_delete_raw_ident:
+  "\<not>(a \<in> set (delete_raw A a))"
+by (induct A) (auto)
+
+lemma not_mem_delete_raw_ident:
+  "b \<notin> set A \<Longrightarrow> (delete_raw A b = A)"
+by (induct A) (auto)
+
+lemma delete_raw_RSP:
+  "A \<approx> B \<Longrightarrow> delete_raw A a \<approx> delete_raw B a"
+apply(induct A arbitrary: B a)
+apply(auto)
+sorry
+
+lemma cons_delete_raw:
+  "a # (delete_raw A a) \<approx> (if a \<in> set A then A else (a # A))"
+sorry
+
+lemma mem_cons_delete_raw:
+    "a \<in> set A \<Longrightarrow> a # (delete_raw A a) \<approx> A"
+sorry
+
+lemma finite_set_raw_delete_raw_cases:
+    "X = [] \<or> (\<exists>a. a mem X \<and> X \<approx> a # delete_raw X a)"
+  by (induct X) (auto)
+
+
+
+
+
+lemma list2set_thm:
+  shows "set [] = {}"
+  and "set (h # t) = insert h (set t)"
+  by (auto)
+
+lemma list2set_RSP:
+  "A \<approx> B \<Longrightarrow> set A = set B"
+  by auto
+
+definition
+  rsp_fold
+where
+  "rsp_fold f = (\<forall>u v w. (f u (f v w) = f v (f u w)))"
+
+primrec
+  fold_raw :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a list \<Rightarrow> 'b"
+where
+  "fold_raw f z [] = z"
+| "fold_raw f z (a # A) =
+     (if (rsp_fold f) then
+       if a mem A then fold_raw f z A
+       else f a (fold_raw f z A)
+     else z)"
+
+lemma mem_lcommuting_fold_raw:
+  "rsp_fold f \<Longrightarrow> h mem B \<Longrightarrow> fold_raw f z B = f h (fold_raw f z (delete_raw B h))"
+sorry
+
+lemma fold_rsp[quot_respect]:
+  "(op = ===> op = ===> op \<approx> ===> op =) fold_raw fold_raw"
+apply(auto)
+sorry
+
+primrec
+  inter_raw
+where
+  "inter_raw [] B = []"
+| "inter_raw (a # A) B = (if a mem B then a # inter_raw A B else inter_raw A B)"
+
+lemma mem_inter_raw:
+  "x mem (inter_raw A B) = x mem A \<and> x mem B"
+sorry
+
+lemma inter_raw_RSP:
+  "A1 \<approx> A2 \<and> B1 \<approx> B2 \<Longrightarrow> (inter_raw A1 B1) \<approx> (inter_raw A2 B2)"
+sorry
+
+
+(* LIFTING DEFS *)
+
+
+section {* Constants on the Quotient Type *} 
+
+
+quotient_definition
+  "fdelete :: 'a fset \<Rightarrow> 'a \<Rightarrow> 'a fset" 
+  is "delete_raw"
+
+quotient_definition
+  finter ("_ \<inter>f _" [70, 71] 70)
+where
+  "finter :: 'a fset \<Rightarrow> 'a fset \<Rightarrow> 'a fset"
+  is "inter_raw"
+
+quotient_definition
+  "ffold :: ('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a fset \<Rightarrow> 'b" 
+  is "fold_raw"
+
+quotient_definition
+  "fset_to_set :: 'a fset \<Rightarrow> 'a set" 
+  is "set"
+
+
+section {* Lifted Theorems *}
+
+thm list.cases (* ??? *)
+
+thm cons_left_comm
+lemma "finsert a (finsert b S) = finsert b (finsert a S)"
+by (lifting cons_left_comm)
+
+thm cons_left_idem
+lemma "finsert a (finsert a S) = finsert a S"
+by (lifting cons_left_idem)
+
+(* thm MEM:
+  MEM x [] = F
+  MEM x (h::t) = (x=h) \/ MEM x t *)
+thm none_mem_nil
+(*lemma "(\<forall>a. a \<notin>f A) = (A = fempty)"*)
+
+thm mem_cons
+thm finite_set_raw_strong_cases
+(*thm card_raw.simps*)
+(*thm not_mem_card_raw*)
+(*thm card_raw_suc*)
+
+lemma "fcard X = Suc n \<Longrightarrow> (\<exists>a S. a \<notin>f S & X = finsert a S)"
+(*by (lifting card_raw_suc)*)
+sorry
+
+(*thm card_raw_cons_gt_0
+thm mem_card_raw_gt_0
+thm not_nil_equiv_cons
+*)
+thm delete_raw.simps
+(*thm mem_delete_raw*)
+(*thm card_raw_delete_raw*)
+thm cons_delete_raw
+thm mem_cons_delete_raw
+thm finite_set_raw_delete_raw_cases
+thm append.simps
+(* MEM_APPEND: MEM e (APPEND l1 l2) = MEM e l1 \/ MEM e l2 *)
+thm inter_raw.simps
+thm mem_inter_raw
+thm fold_raw.simps
+thm list2set_thm
+thm list_eq_def
+thm list.induct
+lemma "\<lbrakk>P fempty; \<And>a x. P x \<Longrightarrow> P (finsert a x)\<rbrakk> \<Longrightarrow> P l"
+by (lifting list.induct)
+
+(* We also have map and some properties of it in FSet *)
+(* and the following which still lifts ok *)
+lemma "funion (funion x xa) xb = funion x (funion xa xb)"
+by (lifting append_assoc)
+
+quotient_definition
+  "fset_case :: 'a \<Rightarrow> ('b \<Rightarrow> 'b fset \<Rightarrow> 'a) \<Rightarrow> 'b fset \<Rightarrow> 'a"
+is
+  "list_case"
+
+(* NOT SURE IF TRUE *)
+lemma list_case_rsp[quot_respect]:
+  "(op = ===> (op = ===> op \<approx> ===> op =) ===> op \<approx> ===> op =) list_case list_case"
+  apply (auto)
+  sorry
+
+lemma "fset_case (f1::'t) f2 (finsert a xa) = f2 a xa"
+apply (lifting list.cases(2))
+done
+
+end