Attic/Quot/Examples/FSet3.thy
changeset 1260 9df6144e281b
parent 1144 538daee762e6
child 1850 05b2dd2b0e8a
equal deleted inserted replaced
1259:db158e995bfc 1260:9df6144e281b
       
     1 theory FSet3
       
     2 imports "../Quotient" "../Quotient_List" List
       
     3 begin
       
     4 
       
     5 ML {*
       
     6 structure QuotientRules = Named_Thms
       
     7   (val name = "quot_thm"
       
     8    val description = "Quotient theorems.")
       
     9 *}
       
    10 
       
    11 ML {*
       
    12 open QuotientRules
       
    13 *}
       
    14 
       
    15 fun
       
    16   list_eq :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" (infix "\<approx>" 50)
       
    17 where
       
    18   "list_eq xs ys = (\<forall>x. x \<in> set xs \<longleftrightarrow> x \<in> set ys)"
       
    19 
       
    20 lemma list_eq_equivp:
       
    21   shows "equivp list_eq"
       
    22 unfolding equivp_reflp_symp_transp reflp_def symp_def transp_def
       
    23 by auto
       
    24 
       
    25 (* FIXME-TODO: because of beta-reduction, one cannot give the *)
       
    26 (* FIXME-TODO: relation as a term or abbreviation             *) 
       
    27 quotient_type 
       
    28   'a fset = "'a list" / "list_eq"
       
    29 by (rule list_eq_equivp)
       
    30 
       
    31 
       
    32 section {* empty fset, finsert and membership *} 
       
    33 
       
    34 quotient_definition
       
    35   fempty  ("{||}")
       
    36 where
       
    37   "fempty :: 'a fset"
       
    38 is "[]::'a list"
       
    39 
       
    40 quotient_definition
       
    41   "finsert :: 'a \<Rightarrow> 'a fset \<Rightarrow> 'a fset" 
       
    42 is "op #"
       
    43 
       
    44 syntax
       
    45   "@Finset"     :: "args => 'a fset"  ("{|(_)|}")
       
    46 
       
    47 translations
       
    48   "{|x, xs|}" == "CONST finsert x {|xs|}"
       
    49   "{|x|}"     == "CONST finsert x {||}"
       
    50 
       
    51 definition 
       
    52   memb :: "'a \<Rightarrow> 'a list \<Rightarrow> bool"
       
    53 where
       
    54   "memb x xs \<equiv> x \<in> set xs"
       
    55 
       
    56 quotient_definition
       
    57   fin ("_ |\<in>| _" [50, 51] 50)
       
    58 where
       
    59   "fin :: 'a \<Rightarrow> 'a fset \<Rightarrow> bool"
       
    60 is "memb"
       
    61 
       
    62 abbreviation
       
    63   fnotin :: "'a \<Rightarrow> 'a fset \<Rightarrow> bool" ("_ |\<notin>| _" [50, 51] 50)
       
    64 where
       
    65   "a |\<notin>| S \<equiv> \<not>(a |\<in>| S)"
       
    66 
       
    67 lemma memb_rsp[quot_respect]: 
       
    68   shows "(op = ===> op \<approx> ===> op =) memb memb"
       
    69 by (auto simp add: memb_def)
       
    70 
       
    71 lemma nil_rsp[quot_respect]:
       
    72   shows "[] \<approx> []"
       
    73 by simp
       
    74 
       
    75 lemma cons_rsp[quot_respect]: 
       
    76   shows "(op = ===> op \<approx> ===> op \<approx>) op # op #"
       
    77 by simp
       
    78 
       
    79 
       
    80 section {* Augmenting a set -- @{const finsert} *}
       
    81 
       
    82 text {* raw section *}
       
    83 
       
    84 lemma nil_not_cons:
       
    85   shows "\<not>[] \<approx> x # xs"
       
    86   by auto
       
    87 
       
    88 lemma memb_cons_iff:
       
    89   shows "memb x (y # xs) = (x = y \<or> memb x xs)"
       
    90   by (induct xs) (auto simp add: memb_def)
       
    91 
       
    92 lemma memb_consI1:
       
    93   shows "memb x (x # xs)"
       
    94   by (simp add: memb_def)
       
    95 
       
    96 lemma memb_consI2:
       
    97   shows "memb x xs \<Longrightarrow> memb x (y # xs)"
       
    98   by (simp add: memb_def)
       
    99 
       
   100 lemma memb_absorb:
       
   101   shows "memb x xs \<Longrightarrow> x # xs \<approx> xs"
       
   102   by (induct xs) (auto simp add: memb_def id_simps)
       
   103 
       
   104 text {* lifted section *}
       
   105 
       
   106 lemma fin_finsert_iff[simp]:
       
   107   "x |\<in>| finsert y S = (x = y \<or> x |\<in>| S)"
       
   108 by (lifting memb_cons_iff) 
       
   109 
       
   110 lemma
       
   111   shows finsertI1: "x |\<in>| finsert x S"
       
   112   and   finsertI2: "x |\<in>| S \<Longrightarrow> x |\<in>| finsert y S"
       
   113   by (lifting memb_consI1, lifting memb_consI2)
       
   114 
       
   115 
       
   116 lemma finsert_absorb [simp]: 
       
   117   shows "x |\<in>| S \<Longrightarrow> finsert x S = S"
       
   118   by (lifting memb_absorb)
       
   119 
       
   120 
       
   121 section {* Singletons *}
       
   122 
       
   123 text {* raw section *}
       
   124 
       
   125 lemma singleton_list_eq:
       
   126   shows "[x] \<approx> [y] \<longleftrightarrow> x = y"
       
   127   by (simp add: id_simps) auto
       
   128 
       
   129 text {* lifted section *}
       
   130 
       
   131 lemma fempty_not_finsert[simp]:
       
   132   shows "{||} \<noteq> finsert x S"
       
   133   by (lifting nil_not_cons)
       
   134 
       
   135 lemma fsingleton_eq[simp]:
       
   136   shows "{|x|} = {|y|} \<longleftrightarrow> x = y"
       
   137   by (lifting singleton_list_eq)
       
   138 
       
   139 section {* Union *}
       
   140 
       
   141 quotient_definition
       
   142   funion  (infixl "|\<union>|" 65)
       
   143 where
       
   144   "funion :: 'a fset \<Rightarrow> 'a fset \<Rightarrow> 'a fset"
       
   145 is
       
   146   "op @"
       
   147 
       
   148 section {* Cardinality of finite sets *}
       
   149 
       
   150 fun
       
   151   fcard_raw :: "'a list \<Rightarrow> nat"
       
   152 where
       
   153   fcard_raw_nil:  "fcard_raw [] = 0"
       
   154 | fcard_raw_cons: "fcard_raw (x # xs) = (if memb x xs then fcard_raw xs else Suc (fcard_raw xs))"
       
   155 
       
   156 quotient_definition
       
   157   "fcard :: 'a fset \<Rightarrow> nat" 
       
   158 is "fcard_raw"
       
   159 
       
   160 text {* raw section *}
       
   161 
       
   162 lemma fcard_raw_ge_0:
       
   163   assumes a: "x \<in> set xs"
       
   164   shows "0 < fcard_raw xs"
       
   165 using a
       
   166 by (induct xs) (auto simp add: memb_def)
       
   167 
       
   168 lemma fcard_raw_delete_one:
       
   169   "fcard_raw ([x \<leftarrow> xs. x \<noteq> y]) = (if memb y xs then fcard_raw xs - 1 else fcard_raw xs)"
       
   170 by (induct xs) (auto dest: fcard_raw_ge_0 simp add: memb_def)
       
   171 
       
   172 lemma fcard_raw_rsp_aux:
       
   173   assumes a: "a \<approx> b"
       
   174   shows "fcard_raw a = fcard_raw b"
       
   175 using a
       
   176 apply(induct a arbitrary: b)
       
   177 apply(auto simp add: memb_def)
       
   178 apply(metis)
       
   179 apply(drule_tac x="[x \<leftarrow> b. x \<noteq> a1]" in meta_spec)
       
   180 apply(simp add: fcard_raw_delete_one)
       
   181 apply(metis Suc_pred' fcard_raw_ge_0 fcard_raw_delete_one memb_def)
       
   182 done
       
   183 
       
   184 lemma fcard_raw_rsp[quot_respect]:
       
   185   "(op \<approx> ===> op =) fcard_raw fcard_raw"
       
   186   by (simp add: fcard_raw_rsp_aux)
       
   187 
       
   188 text {* lifted section *}
       
   189 
       
   190 lemma fcard_fempty [simp]:
       
   191   shows "fcard {||} = 0"
       
   192 by (lifting fcard_raw_nil)
       
   193 
       
   194 lemma fcard_finsert_if [simp]:
       
   195   shows "fcard (finsert x S) = (if x |\<in>| S then fcard S else Suc (fcard S))"
       
   196 by (lifting fcard_raw_cons)
       
   197 
       
   198 
       
   199 section {* Induction and Cases rules for finite sets *}
       
   200 
       
   201 lemma fset_exhaust[case_names fempty finsert, cases type: fset]:
       
   202   shows "\<lbrakk>S = {||} \<Longrightarrow> P; \<And>x S'. S = finsert x S' \<Longrightarrow> P\<rbrakk> \<Longrightarrow> P"
       
   203 by (lifting list.exhaust)
       
   204 
       
   205 lemma fset_induct[case_names fempty finsert]:
       
   206   shows "\<lbrakk>P {||}; \<And>x S. P S \<Longrightarrow> P (finsert x S)\<rbrakk> \<Longrightarrow> P S"
       
   207 by (lifting list.induct)
       
   208 
       
   209 lemma fset_induct2[case_names fempty finsert, induct type: fset]:
       
   210   assumes prem1: "P {||}" 
       
   211   and     prem2: "\<And>x S. \<lbrakk>x |\<notin>| S; P S\<rbrakk> \<Longrightarrow> P (finsert x S)"
       
   212   shows "P S"
       
   213 proof(induct S rule: fset_induct)
       
   214   case fempty
       
   215   show "P {||}" by (rule prem1)
       
   216 next
       
   217   case (finsert x S)
       
   218   have asm: "P S" by fact
       
   219   show "P (finsert x S)"
       
   220   proof(cases "x |\<in>| S")
       
   221     case True
       
   222     have "x |\<in>| S" by fact
       
   223     then show "P (finsert x S)" using asm by simp
       
   224   next
       
   225     case False
       
   226     have "x |\<notin>| S" by fact
       
   227     then show "P (finsert x S)" using prem2 asm by simp
       
   228   qed
       
   229 qed
       
   230 
       
   231 
       
   232 section {* fmap and fset comprehension *}
       
   233 
       
   234 quotient_definition
       
   235   "fmap :: ('a \<Rightarrow> 'b) \<Rightarrow> 'a fset \<Rightarrow> 'b fset"
       
   236 is
       
   237  "map"
       
   238 
       
   239 quotient_definition
       
   240   "fconcat :: ('a fset) fset => 'a fset"
       
   241 is
       
   242  "concat"
       
   243 
       
   244 (*lemma fconcat_rsp[quot_respect]:
       
   245   shows "((list_rel op \<approx>) ===> op \<approx>) concat concat"
       
   246 apply(auto)
       
   247 sorry
       
   248 *)
       
   249 
       
   250 (* PROBLEM: these lemmas needs to be restated, since  *)
       
   251 (* concat.simps(1) and concat.simps(2) contain the    *)
       
   252 (* type variables ?'a1.0 (which are turned into frees *)
       
   253 (* 'a_1                                               *)
       
   254 lemma concat1:
       
   255   shows "concat [] \<approx> []"
       
   256 by (simp add: id_simps)
       
   257 
       
   258 lemma concat2:
       
   259   shows "concat (x # xs) \<approx> x @ concat xs"
       
   260 by (simp add: id_simps)
       
   261 
       
   262 lemma concat_rsp[quot_respect]:
       
   263   shows "(list_rel op \<approx> OOO op \<approx> ===> op \<approx>) concat concat"
       
   264 sorry
       
   265 
       
   266 lemma nil_rsp2[quot_respect]: "(list_rel op \<approx> OOO op \<approx>) [] []"
       
   267   apply (metis FSet3.nil_rsp list_rel.simps(1) pred_comp.intros)
       
   268   done
       
   269 
       
   270 lemma set_in_eq: "(\<forall>e. ((e \<in> A) \<longleftrightarrow> (e \<in> B))) \<equiv> A = B"
       
   271   apply (rule eq_reflection)
       
   272   apply auto
       
   273   done
       
   274 
       
   275 lemma map_rel_cong: "b \<approx> ba \<Longrightarrow> map f b \<approx> map f ba"
       
   276   unfolding list_eq.simps
       
   277   apply(simp only: set_map set_in_eq)
       
   278   done
       
   279 
       
   280 lemma quotient_compose_list_pre:
       
   281   "(list_rel op \<approx> OOO op \<approx>) r s =
       
   282   ((list_rel op \<approx> OOO op \<approx>) r r \<and> (list_rel op \<approx> OOO op \<approx>) s s \<and>
       
   283   abs_fset (map abs_fset r) = abs_fset (map abs_fset s))"
       
   284   apply rule
       
   285   apply rule
       
   286   apply rule
       
   287   apply (rule list_rel_refl)
       
   288   apply (metis equivp_def fset_equivp)
       
   289   apply rule
       
   290   apply (rule equivp_reflp[OF fset_equivp])
       
   291   apply (rule list_rel_refl)
       
   292   apply (metis equivp_def fset_equivp)
       
   293   apply(rule)
       
   294   apply rule
       
   295   apply (rule list_rel_refl)
       
   296   apply (metis equivp_def fset_equivp)
       
   297   apply rule
       
   298   apply (rule equivp_reflp[OF fset_equivp])
       
   299   apply (rule list_rel_refl)
       
   300   apply (metis equivp_def fset_equivp)
       
   301   apply (subgoal_tac "map abs_fset r \<approx> map abs_fset s")
       
   302   apply (metis Quotient_rel[OF Quotient_fset])
       
   303   apply (auto simp only:)[1]
       
   304   apply (subgoal_tac "map abs_fset r = map abs_fset b")
       
   305   prefer 2
       
   306   apply (metis Quotient_rel[OF list_quotient[OF Quotient_fset]])
       
   307   apply (subgoal_tac "map abs_fset s = map abs_fset ba")
       
   308   prefer 2
       
   309   apply (metis Quotient_rel[OF list_quotient[OF Quotient_fset]])
       
   310   apply (simp only: map_rel_cong)
       
   311   apply rule
       
   312   apply (rule rep_abs_rsp[of "list_rel op \<approx>" "map abs_fset"])
       
   313   apply (tactic {* Quotient_Tacs.quotient_tac @{context} 1 *})
       
   314   apply (rule list_rel_refl)
       
   315   apply (metis equivp_def fset_equivp)
       
   316   apply rule
       
   317   prefer 2
       
   318   apply (rule rep_abs_rsp_left[of "list_rel op \<approx>" "map abs_fset"])
       
   319   apply (tactic {* Quotient_Tacs.quotient_tac @{context} 1 *})
       
   320   apply (rule list_rel_refl)
       
   321   apply (metis equivp_def fset_equivp)
       
   322   apply (erule conjE)+
       
   323   apply (subgoal_tac "map abs_fset r \<approx> map abs_fset s")
       
   324   prefer 2
       
   325   apply (metis Quotient_def Quotient_fset equivp_reflp fset_equivp)
       
   326   apply (rule map_rel_cong)
       
   327   apply (assumption)
       
   328   done
       
   329 
       
   330 lemma quotient_compose_list[quot_thm]:
       
   331   shows  "Quotient ((list_rel op \<approx>) OOO (op \<approx>))
       
   332     (abs_fset \<circ> (map abs_fset)) ((map rep_fset) \<circ> rep_fset)"
       
   333   unfolding Quotient_def comp_def
       
   334   apply (rule)+
       
   335   apply (simp add: abs_o_rep[OF Quotient_fset] id_simps Quotient_abs_rep[OF Quotient_fset])
       
   336   apply (rule)
       
   337   apply (rule)
       
   338   apply (rule)
       
   339   apply (rule list_rel_refl)
       
   340   apply (metis equivp_def fset_equivp)
       
   341   apply (rule)
       
   342   apply (rule equivp_reflp[OF fset_equivp])
       
   343   apply (rule list_rel_refl)
       
   344   apply (metis equivp_def fset_equivp)
       
   345   apply rule
       
   346   apply rule
       
   347   apply(rule quotient_compose_list_pre)
       
   348   done
       
   349 
       
   350 lemma fconcat_empty:
       
   351   shows "fconcat {||} = {||}"
       
   352 apply(lifting concat1)
       
   353 apply(cleaning)
       
   354 apply(simp add: comp_def)
       
   355 apply(fold fempty_def[simplified id_simps])
       
   356 apply(rule refl)
       
   357 done
       
   358 
       
   359 (* Should be true *)
       
   360 
       
   361 lemma insert_rsp2[quot_respect]:
       
   362   "(op \<approx> ===> list_rel op \<approx> OOO op \<approx> ===> list_rel op \<approx> OOO op \<approx>) op # op #"
       
   363 apply auto
       
   364 apply (simp add: set_in_eq)
       
   365 sorry
       
   366 
       
   367 lemma append_rsp[quot_respect]:
       
   368   "(op \<approx> ===> op \<approx> ===> op \<approx>) op @ op @"
       
   369   by (auto)
       
   370 
       
   371 lemma fconcat_insert:
       
   372   shows "fconcat (finsert x S) = x |\<union>| fconcat S"
       
   373 apply(lifting concat2)
       
   374 apply(cleaning)
       
   375 apply (simp add: finsert_def fconcat_def comp_def)
       
   376 apply cleaning
       
   377 done
       
   378 
       
   379 text {* raw section *}
       
   380 
       
   381 lemma map_rsp_aux:
       
   382   assumes a: "a \<approx> b"
       
   383   shows "map f a \<approx> map f b"
       
   384   using a
       
   385 apply(induct a arbitrary: b)
       
   386 apply(auto)
       
   387 apply(metis rev_image_eqI)
       
   388 done
       
   389 
       
   390 lemma map_rsp[quot_respect]:
       
   391   shows "(op = ===> op \<approx> ===> op \<approx>) map map"
       
   392 by (auto simp add: map_rsp_aux)
       
   393 
       
   394 
       
   395 text {* lifted section *}
       
   396 
       
   397 (* TBD *)
       
   398 
       
   399 text {* syntax for fset comprehensions (adapted from lists) *}
       
   400 
       
   401 nonterminals fsc_qual fsc_quals
       
   402 
       
   403 syntax
       
   404 "_fsetcompr" :: "'a \<Rightarrow> fsc_qual \<Rightarrow> fsc_quals \<Rightarrow> 'a fset"  ("{|_ . __")
       
   405 "_fsc_gen" :: "'a \<Rightarrow> 'a fset \<Rightarrow> fsc_qual" ("_ <- _")
       
   406 "_fsc_test" :: "bool \<Rightarrow> fsc_qual" ("_")
       
   407 "_fsc_end" :: "fsc_quals" ("|}")
       
   408 "_fsc_quals" :: "fsc_qual \<Rightarrow> fsc_quals \<Rightarrow> fsc_quals" (", __")
       
   409 "_fsc_abs" :: "'a => 'b fset => 'b fset"
       
   410 
       
   411 syntax (xsymbols)
       
   412 "_fsc_gen" :: "'a \<Rightarrow> 'a fset \<Rightarrow> fsc_qual" ("_ \<leftarrow> _")
       
   413 syntax (HTML output)
       
   414 "_fsc_gen" :: "'a \<Rightarrow> 'a fset \<Rightarrow> fsc_qual" ("_ \<leftarrow> _")
       
   415 
       
   416 parse_translation (advanced) {*
       
   417 let
       
   418   val femptyC = Syntax.const @{const_name fempty};
       
   419   val finsertC = Syntax.const @{const_name finsert};
       
   420   val fmapC = Syntax.const @{const_name fmap};
       
   421   val fconcatC = Syntax.const @{const_name fconcat};
       
   422   val IfC = Syntax.const @{const_name If};
       
   423   fun fsingl x = finsertC $ x $ femptyC;
       
   424 
       
   425   fun pat_tr ctxt p e opti = (* %x. case x of p => e | _ => [] *)
       
   426     let
       
   427       val x = Free (Name.variant (fold Term.add_free_names [p, e] []) "x", dummyT);
       
   428       val e = if opti then fsingl e else e;
       
   429       val case1 = Syntax.const "_case1" $ p $ e;
       
   430       val case2 = Syntax.const "_case1" $ Syntax.const Term.dummy_patternN
       
   431                                         $ femptyC;
       
   432       val cs = Syntax.const "_case2" $ case1 $ case2
       
   433       val ft = Datatype_Case.case_tr false Datatype.info_of_constr
       
   434                  ctxt [x, cs]
       
   435     in lambda x ft end;
       
   436 
       
   437   fun abs_tr ctxt (p as Free(s,T)) e opti =
       
   438         let val thy = ProofContext.theory_of ctxt;
       
   439             val s' = Sign.intern_const thy s
       
   440         in if Sign.declared_const thy s'
       
   441            then (pat_tr ctxt p e opti, false)
       
   442            else (lambda p e, true)
       
   443         end
       
   444     | abs_tr ctxt p e opti = (pat_tr ctxt p e opti, false);
       
   445 
       
   446   fun fsc_tr ctxt [e, Const("_fsc_test",_) $ b, qs] =
       
   447         let 
       
   448           val res = case qs of 
       
   449                       Const("_fsc_end",_) => fsingl e
       
   450                     | Const("_fsc_quals",_)$ q $ qs => fsc_tr ctxt [e, q, qs];
       
   451         in 
       
   452           IfC $ b $ res $ femptyC 
       
   453         end
       
   454 
       
   455     | fsc_tr ctxt [e, Const("_fsc_gen",_) $ p $ es, Const("_fsc_end",_)] =
       
   456          (case abs_tr ctxt p e true of
       
   457             (f,true) => fmapC $ f $ es
       
   458           | (f, false) => fconcatC $ (fmapC $ f $ es))
       
   459        
       
   460     | fsc_tr ctxt [e, Const("_fsc_gen",_) $ p $ es, Const("_fsc_quals",_) $ q $ qs] =
       
   461         let
       
   462           val e' = fsc_tr ctxt [e, q, qs];
       
   463         in 
       
   464           fconcatC $ (fmapC $ (fst (abs_tr ctxt p e' false)) $ es) 
       
   465         end
       
   466 
       
   467 in [("_fsetcompr", fsc_tr)] end
       
   468 *}
       
   469 
       
   470 
       
   471 (* NEEDS FIXING *)
       
   472 (* examles *)
       
   473 (*
       
   474 term "{|(x,y,z). b|}"
       
   475 term "{|x. x \<leftarrow> xs|}"
       
   476 term "{|(x,y,z). x\<leftarrow>xs|}"
       
   477 term "{|e x y. x\<leftarrow>xs, y\<leftarrow>ys|}"
       
   478 term "{|(x,y,z). x<a, x>b|}"
       
   479 term "{|(x,y,z). x\<leftarrow>xs, x>b|}"
       
   480 term "{|(x,y,z). x<a, x\<leftarrow>xs|}"
       
   481 term "{|(x,y). Cons True x \<leftarrow> xs|}"
       
   482 term "{|(x,y,z). Cons x [] \<leftarrow> xs|}"
       
   483 term "{|(x,y,z). x<a, x>b, x=d|}"
       
   484 term "{|(x,y,z). x<a, x>b, y\<leftarrow>ys|}"
       
   485 term "{|(x,y,z). x<a, x\<leftarrow>xs,y>b|}"
       
   486 term "{|(x,y,z). x<a, x\<leftarrow>xs, y\<leftarrow>ys|}"
       
   487 term "{|(x,y,z). x\<leftarrow>xs, x>b, y<a|}"
       
   488 term "{|(x,y,z). x\<leftarrow>xs, x>b, y\<leftarrow>ys|}"
       
   489 term "{|(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys,y>x|}"
       
   490 term "{|(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys,z\<leftarrow>zs|}"
       
   491 *)
       
   492 
       
   493 (* BELOW CONSTRUCTION SITE *)
       
   494 
       
   495 
       
   496 lemma no_mem_nil: 
       
   497   "(\<forall>a. a \<notin> set A) = (A = [])"
       
   498 by (induct A) (auto)
       
   499 
       
   500 lemma none_mem_nil: 
       
   501   "(\<forall>a. a \<notin> set A) = (A \<approx> [])"
       
   502 by simp
       
   503 
       
   504 lemma mem_cons: 
       
   505   "a \<in> set A \<Longrightarrow> a # A \<approx> A"
       
   506 by auto
       
   507 
       
   508 lemma cons_left_comm:
       
   509   "x # y # A \<approx> y # x # A"
       
   510 by (auto simp add: id_simps)
       
   511 
       
   512 lemma cons_left_idem:
       
   513   "x # x # A \<approx> x # A"
       
   514 by (auto simp add: id_simps)
       
   515 
       
   516 lemma finite_set_raw_strong_cases:
       
   517   "(X = []) \<or> (\<exists>a Y. ((a \<notin> set Y) \<and> (X \<approx> a # Y)))"
       
   518   apply (induct X)
       
   519   apply (simp)
       
   520   apply (rule disjI2)
       
   521   apply (erule disjE)
       
   522   apply (rule_tac x="a" in exI)
       
   523   apply (rule_tac x="[]" in exI)
       
   524   apply (simp)
       
   525   apply (erule exE)+
       
   526   apply (case_tac "a = aa")
       
   527   apply (rule_tac x="a" in exI)
       
   528   apply (rule_tac x="Y" in exI)
       
   529   apply (simp)
       
   530   apply (rule_tac x="aa" in exI)
       
   531   apply (rule_tac x="a # Y" in exI)
       
   532   apply (auto)
       
   533   done
       
   534 
       
   535 fun
       
   536   delete_raw :: "'a list \<Rightarrow> 'a \<Rightarrow> 'a list"
       
   537 where
       
   538   "delete_raw [] x = []"
       
   539 | "delete_raw (a # A) x = (if (a = x) then delete_raw A x else a # (delete_raw A x))"
       
   540 
       
   541 lemma mem_delete_raw:
       
   542   "x \<in> set (delete_raw A a) = (x \<in> set A \<and> \<not>(x = a))"
       
   543   by (induct A arbitrary: x a) (auto)
       
   544 
       
   545 lemma mem_delete_raw_ident:
       
   546   "\<not>(a \<in> set (delete_raw A a))"
       
   547 by (induct A) (auto)
       
   548 
       
   549 lemma not_mem_delete_raw_ident:
       
   550   "b \<notin> set A \<Longrightarrow> (delete_raw A b = A)"
       
   551 by (induct A) (auto)
       
   552 
       
   553 lemma delete_raw_RSP:
       
   554   "A \<approx> B \<Longrightarrow> delete_raw A a \<approx> delete_raw B a"
       
   555 apply(induct A arbitrary: B a)
       
   556 apply(auto)
       
   557 sorry
       
   558 
       
   559 lemma cons_delete_raw:
       
   560   "a # (delete_raw A a) \<approx> (if a \<in> set A then A else (a # A))"
       
   561 sorry
       
   562 
       
   563 lemma mem_cons_delete_raw:
       
   564     "a \<in> set A \<Longrightarrow> a # (delete_raw A a) \<approx> A"
       
   565 sorry
       
   566 
       
   567 lemma finite_set_raw_delete_raw_cases:
       
   568     "X = [] \<or> (\<exists>a. a mem X \<and> X \<approx> a # delete_raw X a)"
       
   569   by (induct X) (auto)
       
   570 
       
   571 
       
   572 
       
   573 
       
   574 
       
   575 lemma list2set_thm:
       
   576   shows "set [] = {}"
       
   577   and "set (h # t) = insert h (set t)"
       
   578   by (auto)
       
   579 
       
   580 lemma list2set_RSP:
       
   581   "A \<approx> B \<Longrightarrow> set A = set B"
       
   582   by auto
       
   583 
       
   584 definition
       
   585   rsp_fold
       
   586 where
       
   587   "rsp_fold f = (\<forall>u v w. (f u (f v w) = f v (f u w)))"
       
   588 
       
   589 primrec
       
   590   fold_raw :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a list \<Rightarrow> 'b"
       
   591 where
       
   592   "fold_raw f z [] = z"
       
   593 | "fold_raw f z (a # A) =
       
   594      (if (rsp_fold f) then
       
   595        if a mem A then fold_raw f z A
       
   596        else f a (fold_raw f z A)
       
   597      else z)"
       
   598 
       
   599 lemma mem_lcommuting_fold_raw:
       
   600   "rsp_fold f \<Longrightarrow> h mem B \<Longrightarrow> fold_raw f z B = f h (fold_raw f z (delete_raw B h))"
       
   601 sorry
       
   602 
       
   603 lemma fold_rsp[quot_respect]:
       
   604   "(op = ===> op = ===> op \<approx> ===> op =) fold_raw fold_raw"
       
   605 apply(auto)
       
   606 sorry
       
   607 
       
   608 primrec
       
   609   inter_raw
       
   610 where
       
   611   "inter_raw [] B = []"
       
   612 | "inter_raw (a # A) B = (if a mem B then a # inter_raw A B else inter_raw A B)"
       
   613 
       
   614 lemma mem_inter_raw:
       
   615   "x mem (inter_raw A B) = x mem A \<and> x mem B"
       
   616 sorry
       
   617 
       
   618 lemma inter_raw_RSP:
       
   619   "A1 \<approx> A2 \<and> B1 \<approx> B2 \<Longrightarrow> (inter_raw A1 B1) \<approx> (inter_raw A2 B2)"
       
   620 sorry
       
   621 
       
   622 
       
   623 (* LIFTING DEFS *)
       
   624 
       
   625 
       
   626 section {* Constants on the Quotient Type *} 
       
   627 
       
   628 
       
   629 quotient_definition
       
   630   "fdelete :: 'a fset \<Rightarrow> 'a \<Rightarrow> 'a fset" 
       
   631   is "delete_raw"
       
   632 
       
   633 quotient_definition
       
   634   finter ("_ \<inter>f _" [70, 71] 70)
       
   635 where
       
   636   "finter :: 'a fset \<Rightarrow> 'a fset \<Rightarrow> 'a fset"
       
   637   is "inter_raw"
       
   638 
       
   639 quotient_definition
       
   640   "ffold :: ('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a fset \<Rightarrow> 'b" 
       
   641   is "fold_raw"
       
   642 
       
   643 quotient_definition
       
   644   "fset_to_set :: 'a fset \<Rightarrow> 'a set" 
       
   645   is "set"
       
   646 
       
   647 
       
   648 section {* Lifted Theorems *}
       
   649 
       
   650 thm list.cases (* ??? *)
       
   651 
       
   652 thm cons_left_comm
       
   653 lemma "finsert a (finsert b S) = finsert b (finsert a S)"
       
   654 by (lifting cons_left_comm)
       
   655 
       
   656 thm cons_left_idem
       
   657 lemma "finsert a (finsert a S) = finsert a S"
       
   658 by (lifting cons_left_idem)
       
   659 
       
   660 (* thm MEM:
       
   661   MEM x [] = F
       
   662   MEM x (h::t) = (x=h) \/ MEM x t *)
       
   663 thm none_mem_nil
       
   664 (*lemma "(\<forall>a. a \<notin>f A) = (A = fempty)"*)
       
   665 
       
   666 thm mem_cons
       
   667 thm finite_set_raw_strong_cases
       
   668 (*thm card_raw.simps*)
       
   669 (*thm not_mem_card_raw*)
       
   670 (*thm card_raw_suc*)
       
   671 
       
   672 lemma "fcard X = Suc n \<Longrightarrow> (\<exists>a S. a \<notin>f S & X = finsert a S)"
       
   673 (*by (lifting card_raw_suc)*)
       
   674 sorry
       
   675 
       
   676 (*thm card_raw_cons_gt_0
       
   677 thm mem_card_raw_gt_0
       
   678 thm not_nil_equiv_cons
       
   679 *)
       
   680 thm delete_raw.simps
       
   681 (*thm mem_delete_raw*)
       
   682 (*thm card_raw_delete_raw*)
       
   683 thm cons_delete_raw
       
   684 thm mem_cons_delete_raw
       
   685 thm finite_set_raw_delete_raw_cases
       
   686 thm append.simps
       
   687 (* MEM_APPEND: MEM e (APPEND l1 l2) = MEM e l1 \/ MEM e l2 *)
       
   688 thm inter_raw.simps
       
   689 thm mem_inter_raw
       
   690 thm fold_raw.simps
       
   691 thm list2set_thm
       
   692 thm list_eq_def
       
   693 thm list.induct
       
   694 lemma "\<lbrakk>P fempty; \<And>a x. P x \<Longrightarrow> P (finsert a x)\<rbrakk> \<Longrightarrow> P l"
       
   695 by (lifting list.induct)
       
   696 
       
   697 (* We also have map and some properties of it in FSet *)
       
   698 (* and the following which still lifts ok *)
       
   699 lemma "funion (funion x xa) xb = funion x (funion xa xb)"
       
   700 by (lifting append_assoc)
       
   701 
       
   702 quotient_definition
       
   703   "fset_case :: 'a \<Rightarrow> ('b \<Rightarrow> 'b fset \<Rightarrow> 'a) \<Rightarrow> 'b fset \<Rightarrow> 'a"
       
   704 is
       
   705   "list_case"
       
   706 
       
   707 (* NOT SURE IF TRUE *)
       
   708 lemma list_case_rsp[quot_respect]:
       
   709   "(op = ===> (op = ===> op \<approx> ===> op =) ===> op \<approx> ===> op =) list_case list_case"
       
   710   apply (auto)
       
   711   sorry
       
   712 
       
   713 lemma "fset_case (f1::'t) f2 (finsert a xa) = f2 a xa"
       
   714 apply (lifting list.cases(2))
       
   715 done
       
   716 
       
   717 end