--- /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