Quot/Examples/FSet3.thy
changeset 768 e9e205b904e2
parent 767 37285ec4387d
child 784 da75568e7f12
equal deleted inserted replaced
767:37285ec4387d 768:e9e205b904e2
     1 theory FSet3
     1 theory FSet3
     2 imports "../QuotMain" List
     2 imports "../QuotMain" "../QuotList" List
     3 begin
     3 begin
     4 
     4 
     5 fun
     5 fun
     6   list_eq :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" (infix "\<approx>" 50)
     6   list_eq :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" (infix "\<approx>" 50)
     7 where
     7 where
     8   "list_eq xs ys = (\<forall>e. (e \<in> set xs) = (e \<in> set ys))"
     8   "list_eq xs ys = (\<forall>x. x \<in> set xs \<longleftrightarrow> x \<in> set ys)"
     9 
     9 
    10 lemma list_eq_equivp:
    10 lemma list_eq_equivp:
    11   shows "equivp list_eq"
    11   shows "equivp list_eq"
    12 unfolding equivp_reflp_symp_transp reflp_def symp_def transp_def
    12 unfolding equivp_reflp_symp_transp reflp_def symp_def transp_def
    13 by auto
    13 by auto
    14 
    14 
    15 quotient_type fset = "'a list" / "list_eq"
    15 quotient_type 
    16   by (rule list_eq_equivp)
    16   fset = "'a list" / "list_eq"
    17 
    17 by (rule list_eq_equivp)
    18 lemma not_nil_equiv_cons: 
    18 
    19   "\<not>[] \<approx> a # A" 
    19 
    20 by auto
    20 section {* empty fset, finsert and membership *} 
       
    21 
       
    22 quotient_definition
       
    23   "fempty :: 'a fset" ("{||}")
       
    24 as "[]::'a list"
       
    25 
       
    26 quotient_definition
       
    27   "finsert :: 'a \<Rightarrow> 'a fset \<Rightarrow> 'a fset" 
       
    28 as "op #"
       
    29 
       
    30 syntax
       
    31   "@Finset"     :: "args => 'a fset"  ("{|(_)|}")
       
    32 
       
    33 translations
       
    34   "{|x, xs|}" == "CONST finsert x {|xs|}"
       
    35   "{|x|}"     == "CONST finsert x {||}"
       
    36 
       
    37 definition 
       
    38   memb :: "'a \<Rightarrow> 'a list \<Rightarrow> bool"
       
    39 where
       
    40   "memb x xs \<equiv> x \<in> set xs"
       
    41 
       
    42 quotient_definition
       
    43   "fin :: 'a \<Rightarrow> 'a fset \<Rightarrow> bool" ("_ |\<in>| _" [50, 51] 50)
       
    44 as "memb"
       
    45 
       
    46 abbreviation
       
    47   fnotin :: "'a \<Rightarrow> 'a fset \<Rightarrow> bool" ("_ |\<notin>| _" [50, 51] 50)
       
    48 where
       
    49   "a |\<notin>| S \<equiv> \<not>(a |\<in>| S)"
       
    50 
       
    51 lemma memb_rsp[quot_respect]: 
       
    52   shows "(op = ===> op \<approx> ===> op =) memb memb"
       
    53 by (auto simp add: memb_def)
    21 
    54 
    22 lemma nil_rsp[quot_respect]:
    55 lemma nil_rsp[quot_respect]:
    23   shows "[] \<approx> []"
    56   shows "[] \<approx> []"
    24   by simp
    57 by simp
    25 
    58 
    26 lemma cons_rsp[quot_respect]: 
    59 lemma cons_rsp[quot_respect]: 
    27   shows "(op = ===> op \<approx> ===> op \<approx>) op # op #"
    60   shows "(op = ===> op \<approx> ===> op \<approx>) op # op #"
    28   by simp
    61 by simp
    29 
    62 
    30 (*
    63 
    31 lemma mem_rsp[quot_respect]:
    64 section {* Augmenting a set -- @{const finsert} *}
    32   "(op = ===> op \<approx> ===> op =) (op mem) (op mem)"
    65 
       
    66 text {* raw section *}
       
    67 
       
    68 lemma nil_not_cons: 
       
    69   shows "\<not>[] \<approx> x # xs" 
       
    70 by auto
       
    71 
       
    72 lemma memb_cons_iff:
       
    73   shows "memb x (y # xs) = (x = y \<or> memb x xs)"
       
    74 by (induct xs) (auto simp add: memb_def)
       
    75 
       
    76 lemma memb_consI1:
       
    77   shows "memb x (x # xs)"
       
    78 by (simp add: memb_def)
       
    79 
       
    80 lemma memb_consI2: 
       
    81   shows "memb x xs \<Longrightarrow> memb x (y # xs)"
       
    82   by (simp add: memb_def)
       
    83 
       
    84 lemma memb_absorb:
       
    85   shows "memb x xs \<Longrightarrow> (x # xs) \<approx> xs"
       
    86 by (induct xs) (auto simp add: memb_def)
       
    87 
       
    88 text {* lifted section *}
       
    89 
       
    90 lemma fempty_not_finsert[simp]:
       
    91   shows "{||} \<noteq> finsert x S"
       
    92 by (lifting nil_not_cons)
       
    93 
       
    94 lemma fin_finsert_iff[simp]:
       
    95   "x |\<in>| finsert y S = (x = y \<or> x |\<in>| S)"
       
    96 by (lifting memb_cons_iff) 
       
    97 
       
    98 lemma
       
    99   shows finsertI1: "x |\<in>| finsert x S"
       
   100   and   finsertI2: "x |\<in>| S \<Longrightarrow> x |\<in>| finsert y S"
       
   101   by (lifting memb_consI1, lifting memb_consI2)
       
   102 
       
   103 lemma finsert_absorb [simp]: 
       
   104   shows "x |\<in>| S \<Longrightarrow> finsert x S = S"
       
   105 by (lifting memb_absorb)
       
   106 
       
   107 
       
   108 section {* Singletons *}
       
   109 
       
   110 text {* raw section *}
       
   111 
       
   112 lemma singleton_list_eq:
       
   113   shows "[x] \<approx> [y] \<longleftrightarrow> x = y"
       
   114 by auto
       
   115 
       
   116 text {* lifted section *}
       
   117 
       
   118 lemma fsingleton_eq[simp]:
       
   119   shows "{|x|} = {|y|} \<longleftrightarrow> x = y"
       
   120 by (lifting singleton_list_eq)
       
   121 
       
   122 
       
   123 section {* Cardinality of finite sets *}
       
   124 
       
   125 fun
       
   126   fcard_raw :: "'a list \<Rightarrow> nat"
       
   127 where
       
   128   fcard_raw_nil:  "fcard_raw [] = 0"
       
   129 | fcard_raw_cons: "fcard_raw (x # xs) = (if memb x xs then fcard_raw xs else Suc (fcard_raw xs))"
       
   130 
       
   131 quotient_definition
       
   132   "fcard :: 'a fset \<Rightarrow> nat" 
       
   133 as "fcard_raw"
       
   134 
       
   135 text {* raw section *}
       
   136 
       
   137 lemma fcard_raw_ge_0:
       
   138   assumes a: "x \<in> set xs"
       
   139   shows "0 < fcard_raw xs"
       
   140 using a
       
   141 by (induct xs) (auto simp add: memb_def)
       
   142 
       
   143 lemma fcard_raw_delete_one:
       
   144   "fcard_raw ([x \<leftarrow> xs. x \<noteq> y]) = (if memb y xs then fcard_raw xs - 1 else fcard_raw xs)"
       
   145 by (induct xs) (auto dest: fcard_raw_ge_0 simp add: memb_def)
       
   146 
       
   147 lemma fcard_raw_rsp_aux:
       
   148   assumes a: "a \<approx> b"
       
   149   shows "fcard_raw a = fcard_raw b"
       
   150 using a
       
   151 apply(induct a arbitrary: b)
       
   152 apply(auto simp add: memb_def)
       
   153 apply(metis)
       
   154 apply(drule_tac x="[x \<leftarrow> b. x \<noteq> a1]" in meta_spec)
       
   155 apply(simp add: fcard_raw_delete_one)
       
   156 apply(metis Suc_pred' fcard_raw_ge_0 fcard_raw_delete_one memb_def)
       
   157 done
       
   158 
       
   159 lemma fcard_raw_rsp[quot_respect]:
       
   160   "(op \<approx> ===> op =) fcard_raw fcard_raw"
       
   161   by (simp add: fcard_raw_rsp_aux)
       
   162 
       
   163 text {* lifted section *}
       
   164 
       
   165 lemma fcard_fempty [simp]:
       
   166   shows "fcard {||} = 0"
       
   167 by (lifting fcard_raw_nil)
       
   168 
       
   169 lemma fcard_finsert_if [simp]:
       
   170   shows "fcard (finsert x S) = (if x |\<in>| S then fcard S else Suc (fcard S))"
       
   171 by (lifting fcard_raw_cons)
       
   172 
       
   173 
       
   174 section {* Induction and Cases rules for finite sets *}
       
   175 
       
   176 lemma fset_exhaust[case_names fempty finsert, cases type: fset]:
       
   177   shows "\<lbrakk>S = {||} \<Longrightarrow> P; \<And>x S'. S = finsert x S' \<Longrightarrow> P\<rbrakk> \<Longrightarrow> P"
       
   178 by (lifting list.exhaust)
       
   179 
       
   180 lemma fset_induct[case_names fempty finsert]:
       
   181   shows "\<lbrakk>P {||}; \<And>x S. P S \<Longrightarrow> P (finsert x S)\<rbrakk> \<Longrightarrow> P S"
       
   182 by (lifting list.induct)
       
   183 
       
   184 lemma fset_induct2[case_names fempty finsert, induct type: fset]:
       
   185   assumes prem1: "P {||}" 
       
   186   and     prem2: "\<And>x S. \<lbrakk>x |\<notin>| S; P S\<rbrakk> \<Longrightarrow> P (finsert x S)"
       
   187   shows "P S"
       
   188 proof(induct S rule: fset_induct)
       
   189   case fempty
       
   190   show "P {||}" by (rule prem1)
       
   191 next
       
   192   case (finsert x S)
       
   193   have asm: "P S" by fact
       
   194   show "P (finsert x S)"
       
   195   proof(cases "x |\<in>| S")
       
   196     case True
       
   197     have "x |\<in>| S" by fact
       
   198     then show "P (finsert x S)" using asm by simp
       
   199   next
       
   200     case False
       
   201     have "x |\<notin>| S" by fact
       
   202     then show "P (finsert x S)" using prem2 asm by simp
       
   203   qed
       
   204 qed
       
   205 
       
   206 
       
   207 section {* fmap and fset comprehension *}
       
   208 
       
   209 quotient_definition
       
   210   "fmap :: ('a \<Rightarrow> 'b) \<Rightarrow> 'a fset \<Rightarrow> 'b fset"
       
   211 as
       
   212  "map"
       
   213 
       
   214 (* PROPBLEM
       
   215 quotient_definition
       
   216   "fconcat :: ('a fset) fset => 'a fset"
       
   217 as
       
   218  "concat"
       
   219 
       
   220 term concat
       
   221 term fconcat
    33 *)
   222 *)
       
   223 
       
   224 consts
       
   225   fconcat :: "('a fset) fset => 'a fset"
       
   226 
       
   227 text {* raw section *}
       
   228 
       
   229 lemma map_rsp_aux:
       
   230   assumes a: "a \<approx> b"
       
   231   shows "map f a \<approx> map f b"
       
   232   using a
       
   233 apply(induct a arbitrary: b)
       
   234 apply(auto)
       
   235 apply(metis rev_image_eqI)
       
   236 done
       
   237 
       
   238 lemma map_rsp[quot_respect]:
       
   239   shows "(op = ===> op \<approx> ===> op \<approx>) map map"
       
   240 by (auto simp add: map_rsp_aux)
       
   241 
       
   242 
       
   243 text {* lifted section *}
       
   244 
       
   245 (* TBD *)
       
   246 
       
   247 text {* syntax for fset comprehensions (adapted from lists) *}
       
   248 
       
   249 nonterminals fsc_qual fsc_quals
       
   250 
       
   251 syntax
       
   252 "_fsetcompr" :: "'a \<Rightarrow> fsc_qual \<Rightarrow> fsc_quals \<Rightarrow> 'a fset"  ("{|_ . __")
       
   253 "_fsc_gen" :: "'a \<Rightarrow> 'a fset \<Rightarrow> fsc_qual" ("_ <- _")
       
   254 "_fsc_test" :: "bool \<Rightarrow> fsc_qual" ("_")
       
   255 "_fsc_end" :: "fsc_quals" ("|}")
       
   256 "_fsc_quals" :: "fsc_qual \<Rightarrow> fsc_quals \<Rightarrow> fsc_quals" (", __")
       
   257 "_fsc_abs" :: "'a => 'b fset => 'b fset"
       
   258 
       
   259 syntax (xsymbols)
       
   260 "_fsc_gen" :: "'a \<Rightarrow> 'a fset \<Rightarrow> fsc_qual" ("_ \<leftarrow> _")
       
   261 syntax (HTML output)
       
   262 "_fsc_gen" :: "'a \<Rightarrow> 'a fset \<Rightarrow> fsc_qual" ("_ \<leftarrow> _")
       
   263 
       
   264 parse_translation (advanced) {*
       
   265 let
       
   266   val femptyC = Syntax.const @{const_name fempty};
       
   267   val finsertC = Syntax.const @{const_name finsert};
       
   268   val fmapC = Syntax.const @{const_name fmap};
       
   269   val fconcatC = Syntax.const @{const_name fconcat};
       
   270   val IfC = Syntax.const @{const_name If};
       
   271   fun fsingl x = finsertC $ x $ femptyC;
       
   272 
       
   273   fun pat_tr ctxt p e opti = (* %x. case x of p => e | _ => [] *)
       
   274     let
       
   275       val x = Free (Name.variant (fold Term.add_free_names [p, e] []) "x", dummyT);
       
   276       val e = if opti then fsingl e else e;
       
   277       val case1 = Syntax.const "_case1" $ p $ e;
       
   278       val case2 = Syntax.const "_case1" $ Syntax.const Term.dummy_patternN
       
   279                                         $ femptyC;
       
   280       val cs = Syntax.const "_case2" $ case1 $ case2
       
   281       val ft = Datatype_Case.case_tr false Datatype.info_of_constr
       
   282                  ctxt [x, cs]
       
   283     in lambda x ft end;
       
   284 
       
   285   fun abs_tr ctxt (p as Free(s,T)) e opti =
       
   286         let val thy = ProofContext.theory_of ctxt;
       
   287             val s' = Sign.intern_const thy s
       
   288         in if Sign.declared_const thy s'
       
   289            then (pat_tr ctxt p e opti, false)
       
   290            else (lambda p e, true)
       
   291         end
       
   292     | abs_tr ctxt p e opti = (pat_tr ctxt p e opti, false);
       
   293 
       
   294   fun fsc_tr ctxt [e, Const("_fsc_test",_) $ b, qs] =
       
   295         let 
       
   296           val res = case qs of 
       
   297                       Const("_fsc_end",_) => fsingl e
       
   298                     | Const("_fsc_quals",_)$ q $ qs => fsc_tr ctxt [e, q, qs];
       
   299         in 
       
   300           IfC $ b $ res $ femptyC 
       
   301         end
       
   302 
       
   303     | fsc_tr ctxt [e, Const("_fsc_gen",_) $ p $ es, Const("_fsc_end",_)] =
       
   304          (case abs_tr ctxt p e true of
       
   305             (f,true) => fmapC $ f $ es
       
   306           | (f, false) => fconcatC $ (fmapC $ f $ es))
       
   307        
       
   308     | fsc_tr ctxt [e, Const("_fsc_gen",_) $ p $ es, Const("_fsc_quals",_) $ q $ qs] =
       
   309         let
       
   310           val e' = fsc_tr ctxt [e, q, qs];
       
   311         in 
       
   312           fconcatC $ (fmapC $ (fst (abs_tr ctxt p e' false)) $ es) 
       
   313         end
       
   314 
       
   315 in [("_fsetcompr", fsc_tr)] end
       
   316 *}
       
   317 
       
   318 (* examles *)
       
   319 term "{|(x,y,z). b|}"
       
   320 term "{|x. x \<leftarrow> xs|}"
       
   321 term "{|(x,y,z). x\<leftarrow>xs|}"
       
   322 term "{|e x y. x\<leftarrow>xs, y\<leftarrow>ys|}"
       
   323 term "{|(x,y,z). x<a, x>b|}"
       
   324 term "{|(x,y,z). x\<leftarrow>xs, x>b|}"
       
   325 term "{|(x,y,z). x<a, x\<leftarrow>xs|}"
       
   326 term "{|(x,y). Cons True x \<leftarrow> xs|}"
       
   327 term "{|(x,y,z). Cons x [] \<leftarrow> xs|}"
       
   328 term "{|(x,y,z). x<a, x>b, x=d|}"
       
   329 term "{|(x,y,z). x<a, x>b, y\<leftarrow>ys|}"
       
   330 term "{|(x,y,z). x<a, x\<leftarrow>xs,y>b|}"
       
   331 term "{|(x,y,z). x<a, x\<leftarrow>xs, y\<leftarrow>ys|}"
       
   332 term "{|(x,y,z). x\<leftarrow>xs, x>b, y<a|}"
       
   333 term "{|(x,y,z). x\<leftarrow>xs, x>b, y\<leftarrow>ys|}"
       
   334 term "{|(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys,y>x|}"
       
   335 term "{|(x,y,z). x\<leftarrow>xs, y\<leftarrow>ys,z\<leftarrow>zs|}"
       
   336 
       
   337 
       
   338 (* BELOW CONSTRUCTION SITE *)
    34 
   339 
    35 
   340 
    36 lemma no_mem_nil: 
   341 lemma no_mem_nil: 
    37   "(\<forall>a. a \<notin> set A) = (A = [])"
   342   "(\<forall>a. a \<notin> set A) = (A = [])"
    38 by (induct A) (auto)
   343 by (induct A) (auto)
   106 
   411 
   107 lemma finite_set_raw_delete_raw_cases:
   412 lemma finite_set_raw_delete_raw_cases:
   108     "X = [] \<or> (\<exists>a. a mem X \<and> X \<approx> a # delete_raw X a)"
   413     "X = [] \<or> (\<exists>a. a mem X \<and> X \<approx> a # delete_raw X a)"
   109   by (induct X) (auto)
   414   by (induct X) (auto)
   110 
   415 
   111 fun
   416 
   112   card_raw :: "'a list \<Rightarrow> nat"
   417 
   113 where
   418 
   114   card_raw_nil: "card_raw [] = 0"
       
   115 | card_raw_cons: "card_raw (x # xs) = (if x \<in> set xs then card_raw xs else Suc (card_raw xs))"
       
   116 
       
   117 lemma not_mem_card_raw:
       
   118   fixes x :: "'a"
       
   119   fixes xs :: "'a list"
       
   120   shows "(\<not>(x mem xs)) = (card_raw (x # xs) = Suc (card_raw xs))"
       
   121   sorry
       
   122 
       
   123 lemma card_raw_suc:
       
   124   assumes c: "card_raw xs = Suc n"
       
   125   shows "\<exists>a ys. (a \<notin> set ys) \<and> xs \<approx> (a # ys)"
       
   126   using c apply(induct xs)
       
   127   apply(simp)
       
   128   sorry
       
   129 
       
   130 lemma mem_card_raw_gt_0:
       
   131   "a \<in> set A \<Longrightarrow> 0 < card_raw A"
       
   132   by (induct A) (auto)
       
   133 
       
   134 lemma card_raw_cons_gt_0:
       
   135   "0 < card_raw (a # A)"
       
   136   by (induct A) (auto)
       
   137 
       
   138 lemma card_raw_delete_raw:
       
   139   "card_raw (delete_raw A a) = (if a \<in> set A then card_raw A - 1 else card_raw A)"
       
   140 sorry
       
   141 
       
   142 lemma card_raw_rsp_aux:
       
   143   assumes e: "a \<approx> b"
       
   144   shows "card_raw a = card_raw b"
       
   145   using e sorry
       
   146 
       
   147 lemma card_raw_rsp[quot_respect]:
       
   148   "(op \<approx> ===> op =) card_raw card_raw"
       
   149   by (simp add: card_raw_rsp_aux)
       
   150 
       
   151 lemma card_raw_0:
       
   152   "(card_raw A = 0) = (A = [])"
       
   153   by (induct A) (auto)
       
   154 
   419 
   155 lemma list2set_thm:
   420 lemma list2set_thm:
   156   shows "set [] = {}"
   421   shows "set [] = {}"
   157   and "set (h # t) = insert h (set t)"
   422   and "set (h # t) = insert h (set t)"
   158   by (auto)
   423   by (auto)
   207 (* LIFTING DEFS *)
   472 (* LIFTING DEFS *)
   208 
   473 
   209 
   474 
   210 section {* Constants on the Quotient Type *} 
   475 section {* Constants on the Quotient Type *} 
   211 
   476 
   212 quotient_definition
       
   213   "fempty :: 'a fset" 
       
   214   as "[]::'a list"
       
   215 
       
   216 quotient_definition
       
   217   "finsert :: 'a \<Rightarrow> 'a fset \<Rightarrow> 'a fset" 
       
   218   as "op #"
       
   219 
       
   220 quotient_definition
       
   221   "fin :: 'a \<Rightarrow> 'a fset \<Rightarrow> bool" ("_ \<in>f _" [50, 51] 50)
       
   222   as "\<lambda>x X. x \<in> set X"
       
   223 
       
   224 abbreviation
       
   225   fnotin :: "'a \<Rightarrow> 'a fset \<Rightarrow> bool" ("_ \<notin>f _" [50, 51] 50)
       
   226 where
       
   227   "a \<notin>f S \<equiv> \<not>(a \<in>f S)"
       
   228 
       
   229 quotient_definition
       
   230   "fcard :: 'a fset \<Rightarrow> nat" 
       
   231   as "card_raw"
       
   232 
   477 
   233 quotient_definition
   478 quotient_definition
   234   "fdelete :: 'a fset \<Rightarrow> 'a \<Rightarrow> 'a fset" 
   479   "fdelete :: 'a fset \<Rightarrow> 'a \<Rightarrow> 'a fset" 
   235   as "delete_raw"
   480   as "delete_raw"
   236 
   481 
   269 thm none_mem_nil
   514 thm none_mem_nil
   270 (*lemma "(\<forall>a. a \<notin>f A) = (A = fempty)"*)
   515 (*lemma "(\<forall>a. a \<notin>f A) = (A = fempty)"*)
   271 
   516 
   272 thm mem_cons
   517 thm mem_cons
   273 thm finite_set_raw_strong_cases
   518 thm finite_set_raw_strong_cases
   274 thm card_raw.simps
   519 (*thm card_raw.simps*)
   275 thm not_mem_card_raw
   520 (*thm not_mem_card_raw*)
   276 thm card_raw_suc
   521 (*thm card_raw_suc*)
   277 
   522 
   278 lemma "fcard X = Suc n \<Longrightarrow> (\<exists>a S. a \<notin>f S & X = finsert a S)"
   523 lemma "fcard X = Suc n \<Longrightarrow> (\<exists>a S. a \<notin>f S & X = finsert a S)"
   279 (*by (lifting card_raw_suc)*)
   524 (*by (lifting card_raw_suc)*)
   280 sorry
   525 sorry
   281 
   526 
   282 thm card_raw_cons_gt_0
   527 (*thm card_raw_cons_gt_0
   283 thm mem_card_raw_gt_0
   528 thm mem_card_raw_gt_0
   284 thm not_nil_equiv_cons
   529 thm not_nil_equiv_cons
       
   530 *)
   285 thm delete_raw.simps
   531 thm delete_raw.simps
   286 (*thm mem_delete_raw*)
   532 (*thm mem_delete_raw*)
   287 thm card_raw_delete_raw
   533 (*thm card_raw_delete_raw*)
   288 thm cons_delete_raw
   534 thm cons_delete_raw
   289 thm mem_cons_delete_raw
   535 thm mem_cons_delete_raw
   290 thm finite_set_raw_delete_raw_cases
   536 thm finite_set_raw_delete_raw_cases
   291 thm append.simps
   537 thm append.simps
   292 (* MEM_APPEND: MEM e (APPEND l1 l2) = MEM e l1 \/ MEM e l2 *)
   538 (* MEM_APPEND: MEM e (APPEND l1 l2) = MEM e l1 \/ MEM e l2 *)