src/HOL/Quotient_Examples/FSet.thy
changeset 40953 d13bcb42e479
parent 40952 580b1a30994c
child 40954 ecca598474dd
equal deleted inserted replaced
40952:580b1a30994c 40953:d13bcb42e479
     4 
     4 
     5     Type of finite sets.
     5     Type of finite sets.
     6 *)
     6 *)
     7 
     7 
     8 theory FSet
     8 theory FSet
     9 imports Quotient_List
     9 imports Quotient_List More_List
    10 begin
    10 begin
    11 
    11 
    12 text {* 
    12 text {* 
    13   The type of finite sets is created by a quotient construction
    13   The type of finite sets is created by a quotient construction
    14   over lists. The definition of the equivalence:
    14   over lists. The definition of the equivalence:
    40 quotient_type
    40 quotient_type
    41   'a fset = "'a list" / "list_eq"
    41   'a fset = "'a list" / "list_eq"
    42   by (rule list_eq_equivp)
    42   by (rule list_eq_equivp)
    43 
    43 
    44 text {* 
    44 text {* 
    45   Definitions for membership, sublist, cardinality, 
    45   Definitions for sublist, cardinality, 
    46   intersection, difference and respectful fold over 
    46   intersection, difference and respectful fold over 
    47   lists.
    47   lists.
    48 *}
    48 *}
    49 
    49 
    50 definition
    50 declare List.member_def [simp]
    51   memb :: "'a \<Rightarrow> 'a list \<Rightarrow> bool"
       
    52 where
       
    53   [simp]: "memb x xs \<longleftrightarrow> x \<in> set xs"
       
    54 
    51 
    55 definition
    52 definition
    56   sub_list :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool"
    53   sub_list :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool"
    57 where 
    54 where 
    58   [simp]: "sub_list xs ys \<longleftrightarrow> set xs \<subseteq> set ys"
    55   [simp]: "sub_list xs ys \<longleftrightarrow> set xs \<subseteq> set ys"
   184 
   181 
   185 lemma sub_list_rsp [quot_respect]:
   182 lemma sub_list_rsp [quot_respect]:
   186   shows "(op \<approx> ===> op \<approx> ===> op =) sub_list sub_list"
   183   shows "(op \<approx> ===> op \<approx> ===> op =) sub_list sub_list"
   187   by (auto intro!: fun_relI)
   184   by (auto intro!: fun_relI)
   188 
   185 
   189 lemma memb_rsp [quot_respect]:
   186 lemma member_rsp [quot_respect]:
   190   shows "(op = ===> op \<approx> ===> op =) memb memb"
   187   shows "(op \<approx> ===> op =) List.member List.member"
   191   by (auto intro!: fun_relI)
   188   by (auto intro!: fun_relI simp add: mem_def)
   192 
   189 
   193 lemma nil_rsp [quot_respect]:
   190 lemma nil_rsp [quot_respect]:
   194   shows "(op \<approx>) Nil Nil"
   191   shows "(op \<approx>) Nil Nil"
   195   by simp
   192   by simp
   196 
   193 
   224 
   221 
   225 lemma filter_rsp [quot_respect]:
   222 lemma filter_rsp [quot_respect]:
   226   shows "(op = ===> op \<approx> ===> op \<approx>) filter filter"
   223   shows "(op = ===> op \<approx> ===> op \<approx>) filter filter"
   227   by (auto intro!: fun_relI)
   224   by (auto intro!: fun_relI)
   228 
   225 
   229 lemma memb_commute_fold_list:
   226 lemma member_commute_fold_list:
   230   assumes a: "rsp_fold f"
   227   assumes a: "rsp_fold f"
   231   and     b: "x \<in> set xs"
   228   and     b: "x \<in> set xs"
   232   shows "fold_list f y xs = f x (fold_list f y (removeAll x xs))"
   229   shows "fold_list f y xs = f x (fold_list f y (removeAll x xs))"
   233   using a b by (induct xs) (auto simp add: rsp_fold_def)
   230   using a b by (induct xs) (auto simp add: rsp_fold_def)
   234 
   231 
   243   apply (rule_tac [!] impI)
   240   apply (rule_tac [!] impI)
   244   apply (rule_tac [!] conjI)
   241   apply (rule_tac [!] conjI)
   245   apply (rule_tac [!] impI)
   242   apply (rule_tac [!] impI)
   246   apply (metis insert_absorb)
   243   apply (metis insert_absorb)
   247   apply (metis List.insert_def List.set.simps(2) List.set_insert fold_list.simps(2))
   244   apply (metis List.insert_def List.set.simps(2) List.set_insert fold_list.simps(2))
   248   apply (metis Diff_insert_absorb insertI1 memb_commute_fold_list set_removeAll)
   245   apply (metis Diff_insert_absorb insertI1 member_commute_fold_list set_removeAll)
   249   apply(drule_tac x="removeAll a ys" in meta_spec)
   246   apply(drule_tac x="removeAll a ys" in meta_spec)
   250   apply(auto)
   247   apply(auto)
   251   apply(drule meta_mp)
   248   apply(drule meta_mp)
   252   apply(blast)
   249   apply(blast)
   253   by (metis List.set.simps(2) emptyE fold_list.simps(2) in_listsp_conv_set listsp.simps mem_def)
   250   by (metis List.set.simps(2) emptyE fold_list.simps(2) in_listsp_conv_set listsp.simps mem_def)
   406 translations
   403 translations
   407   "{|x, xs|}" == "CONST insert_fset x {|xs|}"
   404   "{|x, xs|}" == "CONST insert_fset x {|xs|}"
   408   "{|x|}"     == "CONST insert_fset x {||}"
   405   "{|x|}"     == "CONST insert_fset x {||}"
   409 
   406 
   410 quotient_definition
   407 quotient_definition
   411   in_fset (infix "|\<in>|" 50)
   408   fset_member
   412 where
   409 where
   413   "in_fset :: 'a \<Rightarrow> 'a fset \<Rightarrow> bool" is "memb"
   410   "fset_member :: 'a fset \<Rightarrow> 'a \<Rightarrow> bool" is "List.member"
       
   411 
       
   412 abbreviation
       
   413   in_fset :: "'a \<Rightarrow> 'a fset \<Rightarrow> bool" (infix "|\<in>|" 50)
       
   414 where
       
   415   "x |\<in>| S \<equiv> fset_member S x"
   414 
   416 
   415 abbreviation
   417 abbreviation
   416   notin_fset :: "'a \<Rightarrow> 'a fset \<Rightarrow> bool" (infix "|\<notin>|" 50)
   418   notin_fset :: "'a \<Rightarrow> 'a fset \<Rightarrow> bool" (infix "|\<notin>|" 50)
   417 where
   419 where
   418   "x |\<notin>| S \<equiv> \<not> (x |\<in>| S)"
   420   "x |\<notin>| S \<equiv> \<not> (x |\<in>| S)"
   568 
   570 
   569 subsection {* in_fset *}
   571 subsection {* in_fset *}
   570 
   572 
   571 lemma in_fset: 
   573 lemma in_fset: 
   572   shows "x |\<in>| S \<longleftrightarrow> x \<in> fset S"
   574   shows "x |\<in>| S \<longleftrightarrow> x \<in> fset S"
   573   by (descending) (simp)
   575   by descending simp
   574 
   576 
   575 lemma notin_fset: 
   577 lemma notin_fset: 
   576   shows "x |\<notin>| S \<longleftrightarrow> x \<notin> fset S"
   578   shows "x |\<notin>| S \<longleftrightarrow> x \<notin> fset S"
   577   by (simp add: in_fset)
   579   by (simp add: in_fset)
   578 
   580 
   580   shows "x |\<notin>| {||}"
   582   shows "x |\<notin>| {||}"
   581   by (simp add: in_fset)
   583   by (simp add: in_fset)
   582 
   584 
   583 lemma fset_eq_iff:
   585 lemma fset_eq_iff:
   584   shows "S = T \<longleftrightarrow> (\<forall>x. (x |\<in>| S) = (x |\<in>| T))"
   586   shows "S = T \<longleftrightarrow> (\<forall>x. (x |\<in>| S) = (x |\<in>| T))"
   585   by (descending) (auto)
   587   by descending auto
   586 
   588 
   587 lemma none_in_empty_fset:
   589 lemma none_in_empty_fset:
   588   shows "(\<forall>x. x |\<notin>| S) \<longleftrightarrow> S = {||}"
   590   shows "(\<forall>x. x |\<notin>| S) \<longleftrightarrow> S = {||}"
   589   by (descending) (simp)
   591   by descending simp
   590 
   592 
   591 
   593 
   592 subsection {* insert_fset *}
   594 subsection {* insert_fset *}
   593 
   595 
   594 lemma in_insert_fset_iff [simp]:
   596 lemma in_insert_fset_iff [simp]:
   595   shows "x |\<in>| insert_fset y S \<longleftrightarrow> x = y \<or> x |\<in>| S"
   597   shows "x |\<in>| insert_fset y S \<longleftrightarrow> x = y \<or> x |\<in>| S"
   596   by (descending) (simp)
   598   by descending simp
   597 
   599 
   598 lemma
   600 lemma
   599   shows insert_fsetI1: "x |\<in>| insert_fset x S"
   601   shows insert_fsetI1: "x |\<in>| insert_fset x S"
   600   and   insert_fsetI2: "x |\<in>| S \<Longrightarrow> x |\<in>| insert_fset y S"
   602   and   insert_fsetI2: "x |\<in>| S \<Longrightarrow> x |\<in>| insert_fset y S"
   601   by simp_all
   603   by simp_all
   924   (if rsp_fold f then if a |\<in>| A then fold_fset f z A else f a (fold_fset f z A) else z)"
   926   (if rsp_fold f then if a |\<in>| A then fold_fset f z A else f a (fold_fset f z A) else z)"
   925   by (descending) (simp)
   927   by (descending) (simp)
   926 
   928 
   927 lemma in_commute_fold_fset:
   929 lemma in_commute_fold_fset:
   928   "\<lbrakk>rsp_fold f; h |\<in>| b\<rbrakk> \<Longrightarrow> fold_fset f z b = f h (fold_fset f z (remove_fset h b))"
   930   "\<lbrakk>rsp_fold f; h |\<in>| b\<rbrakk> \<Longrightarrow> fold_fset f z b = f h (fold_fset f z (remove_fset h b))"
   929   by (descending) (simp add: memb_commute_fold_list)
   931   by (descending) (simp add: member_commute_fold_list)
   930 
   932 
   931 
   933 
   932 subsection {* Choice in fsets *}
   934 subsection {* Choice in fsets *}
   933 
   935 
   934 lemma fset_choice: 
   936 lemma fset_choice: 
   986     using h card_fset_Suc_case by simp
   988     using h card_fset_Suc_case by simp
   987 qed
   989 qed
   988 
   990 
   989 lemma fset_raw_strong_cases:
   991 lemma fset_raw_strong_cases:
   990   obtains "xs = []"
   992   obtains "xs = []"
   991     | x ys where "\<not> memb x ys" and "xs \<approx> x # ys"
   993     | ys x where "\<not> List.member ys x" and "xs \<approx> x # ys"
   992 proof (induct xs arbitrary: x ys)
   994 proof (induct xs arbitrary: x ys)
   993   case Nil
   995   case Nil
   994   then show thesis by simp
   996   then show thesis by simp
   995 next
   997 next
   996   case (Cons a xs)
   998   case (Cons a xs)
   997   have a: "\<lbrakk>xs = [] \<Longrightarrow> thesis; \<And>x ys. \<lbrakk>\<not> memb x ys; xs \<approx> x # ys\<rbrakk> \<Longrightarrow> thesis\<rbrakk> \<Longrightarrow> thesis" by fact
   999   have a: "\<lbrakk>xs = [] \<Longrightarrow> thesis; \<And>x ys. \<lbrakk>\<not> List.member ys x; xs \<approx> x # ys\<rbrakk> \<Longrightarrow> thesis\<rbrakk> \<Longrightarrow> thesis"
   998   have b: "\<And>x' ys'. \<lbrakk>\<not> memb x' ys'; a # xs \<approx> x' # ys'\<rbrakk> \<Longrightarrow> thesis" by fact
  1000     by (rule Cons(1))
       
  1001   have b: "\<And>x' ys'. \<lbrakk>\<not> List.member ys' x'; a # xs \<approx> x' # ys'\<rbrakk> \<Longrightarrow> thesis" by fact
   999   have c: "xs = [] \<Longrightarrow> thesis" using b 
  1002   have c: "xs = [] \<Longrightarrow> thesis" using b 
  1000     apply(simp)
  1003     apply(simp)
  1001     by (metis List.set.simps(1) emptyE empty_subsetI)
  1004     by (metis List.set.simps(1) emptyE empty_subsetI)
  1002   have "\<And>x ys. \<lbrakk>\<not> memb x ys; xs \<approx> x # ys\<rbrakk> \<Longrightarrow> thesis"
  1005   have "\<And>x ys. \<lbrakk>\<not> List.member ys x; xs \<approx> x # ys\<rbrakk> \<Longrightarrow> thesis"
  1003   proof -
  1006   proof -
  1004     fix x :: 'a
  1007     fix x :: 'a
  1005     fix ys :: "'a list"
  1008     fix ys :: "'a list"
  1006     assume d:"\<not> memb x ys"
  1009     assume d:"\<not> List.member ys x"
  1007     assume e:"xs \<approx> x # ys"
  1010     assume e:"xs \<approx> x # ys"
  1008     show thesis
  1011     show thesis
  1009     proof (cases "x = a")
  1012     proof (cases "x = a")
  1010       assume h: "x = a"
  1013       assume h: "x = a"
  1011       then have f: "\<not> memb a ys" using d by simp
  1014       then have f: "\<not> List.member ys a" using d by simp
  1012       have g: "a # xs \<approx> a # ys" using e h by auto
  1015       have g: "a # xs \<approx> a # ys" using e h by auto
  1013       show thesis using b f g by simp
  1016       show thesis using b f g by simp
  1014     next
  1017     next
  1015       assume h: "x \<noteq> a"
  1018       assume h: "x \<noteq> a"
  1016       then have f: "\<not> memb x (a # ys)" using d by auto
  1019       then have f: "\<not> List.member (a # ys) x" using d by auto
  1017       have g: "a # xs \<approx> x # (a # ys)" using e h by auto
  1020       have g: "a # xs \<approx> x # (a # ys)" using e h by auto
  1018       show thesis using b f g by (simp del: memb_def) 
  1021       show thesis using b f g by (simp del: List.member_def) 
  1019     qed
  1022     qed
  1020   qed
  1023   qed
  1021   then show thesis using a c by blast
  1024   then show thesis using a c by blast
  1022 qed
  1025 qed
  1023 
  1026 
  1024 
  1027 
  1025 lemma fset_strong_cases:
  1028 lemma fset_strong_cases:
  1026   obtains "xs = {||}"
  1029   obtains "xs = {||}"
  1027     | x ys where "x |\<notin>| ys" and "xs = insert_fset x ys"
  1030     | ys x where "x |\<notin>| ys" and "xs = insert_fset x ys"
  1028   by (lifting fset_raw_strong_cases)
  1031   by (lifting fset_raw_strong_cases)
  1029 
  1032 
  1030 
  1033 
  1031 lemma fset_induct2:
  1034 lemma fset_induct2:
  1032   "P {||} {||} \<Longrightarrow>
  1035   "P {||} {||} \<Longrightarrow>
  1059 lemma list_eq2_refl:
  1062 lemma list_eq2_refl:
  1060   shows "xs \<approx>2 xs"
  1063   shows "xs \<approx>2 xs"
  1061   by (induct xs) (auto intro: list_eq2.intros)
  1064   by (induct xs) (auto intro: list_eq2.intros)
  1062 
  1065 
  1063 lemma cons_delete_list_eq2:
  1066 lemma cons_delete_list_eq2:
  1064   shows "(a # (removeAll a A)) \<approx>2 (if memb a A then A else a # A)"
  1067   shows "(a # (removeAll a A)) \<approx>2 (if List.member A a then A else a # A)"
  1065   apply (induct A)
  1068   apply (induct A)
  1066   apply (simp add: list_eq2_refl)
  1069   apply (simp add: list_eq2_refl)
  1067   apply (case_tac "memb a (aa # A)")
  1070   apply (case_tac "List.member (aa # A) a")
  1068   apply (simp_all)
  1071   apply (simp_all)
  1069   apply (case_tac [!] "a = aa")
  1072   apply (case_tac [!] "a = aa")
  1070   apply (simp_all)
  1073   apply (simp_all)
  1071   apply (case_tac "memb a A")
  1074   apply (case_tac "List.member A a")
  1072   apply (auto)[2]
  1075   apply (auto)[2]
  1073   apply (metis list_eq2.intros(3) list_eq2.intros(4) list_eq2.intros(5) list_eq2.intros(6))
  1076   apply (metis list_eq2.intros(3) list_eq2.intros(4) list_eq2.intros(5) list_eq2.intros(6))
  1074   apply (metis list_eq2.intros(1) list_eq2.intros(5) list_eq2.intros(6))
  1077   apply (metis list_eq2.intros(1) list_eq2.intros(5) list_eq2.intros(6))
  1075   apply (auto simp add: list_eq2_refl memb_def)
  1078   apply (auto simp add: list_eq2_refl)
  1076   done
  1079   done
  1077 
  1080 
  1078 lemma memb_delete_list_eq2:
  1081 lemma member_delete_list_eq2:
  1079   assumes a: "memb e r"
  1082   assumes a: "List.member r e"
  1080   shows "(e # removeAll e r) \<approx>2 r"
  1083   shows "(e # removeAll e r) \<approx>2 r"
  1081   using a cons_delete_list_eq2[of e r]
  1084   using a cons_delete_list_eq2[of e r]
  1082   by simp
  1085   by simp
  1083 
  1086 
  1084 lemma list_eq2_equiv:
  1087 lemma list_eq2_equiv:
  1092     have "l \<approx>2 r"
  1095     have "l \<approx>2 r"
  1093       using a b
  1096       using a b
  1094     proof (induct n arbitrary: l r)
  1097     proof (induct n arbitrary: l r)
  1095       case 0
  1098       case 0
  1096       have "card_list l = 0" by fact
  1099       have "card_list l = 0" by fact
  1097       then have "\<forall>x. \<not> memb x l" by auto
  1100       then have "\<forall>x. \<not> List.member l x" by auto
  1098       then have z: "l = []" by auto
  1101       then have z: "l = []" by auto
  1099       then have "r = []" using `l \<approx> r` by simp
  1102       then have "r = []" using `l \<approx> r` by simp
  1100       then show ?case using z list_eq2_refl by simp
  1103       then show ?case using z list_eq2_refl by simp
  1101     next
  1104     next
  1102       case (Suc m)
  1105       case (Suc m)
  1103       have b: "l \<approx> r" by fact
  1106       have b: "l \<approx> r" by fact
  1104       have d: "card_list l = Suc m" by fact
  1107       have d: "card_list l = Suc m" by fact
  1105       then have "\<exists>a. memb a l" 
  1108       then have "\<exists>a. List.member l a" 
  1106 	apply(simp)
  1109 	apply(simp)
  1107 	apply(drule card_eq_SucD)
  1110 	apply(drule card_eq_SucD)
  1108 	apply(blast)
  1111 	apply(blast)
  1109 	done
  1112 	done
  1110       then obtain a where e: "memb a l" by auto
  1113       then obtain a where e: "List.member l a" by auto
  1111       then have e': "memb a r" using list_eq_def [simplified memb_def [symmetric], of l r] b 
  1114       then have e': "List.member r a" using list_eq_def [simplified List.member_def [symmetric], of l r] b 
  1112 	by auto
  1115 	by auto
  1113       have f: "card_list (removeAll a l) = m" using e d by (simp)
  1116       have f: "card_list (removeAll a l) = m" using e d by (simp)
  1114       have g: "removeAll a l \<approx> removeAll a r" using removeAll_rsp b by simp
  1117       have g: "removeAll a l \<approx> removeAll a r" using removeAll_rsp b by simp
  1115       have "(removeAll a l) \<approx>2 (removeAll a r)" by (rule Suc.hyps[OF f g])
  1118       have "(removeAll a l) \<approx>2 (removeAll a r)" by (rule Suc.hyps[OF f g])
  1116       then have h: "(a # removeAll a l) \<approx>2 (a # removeAll a r)" by (rule list_eq2.intros(5))
  1119       then have h: "(a # removeAll a l) \<approx>2 (a # removeAll a r)" by (rule list_eq2.intros(5))
  1117       have i: "l \<approx>2 (a # removeAll a l)"	
  1120       have i: "l \<approx>2 (a # removeAll a l)"	
  1118         by (rule list_eq2.intros(3)[OF memb_delete_list_eq2[OF e]])
  1121         by (rule list_eq2.intros(3)[OF member_delete_list_eq2[OF e]])
  1119       have "l \<approx>2 (a # removeAll a r)" by (rule list_eq2.intros(6)[OF i h])
  1122       have "l \<approx>2 (a # removeAll a r)" by (rule list_eq2.intros(6)[OF i h])
  1120       then show ?case using list_eq2.intros(6)[OF _ memb_delete_list_eq2[OF e']] by simp
  1123       then show ?case using list_eq2.intros(6)[OF _ member_delete_list_eq2[OF e']] by simp
  1121     qed
  1124     qed
  1122     }
  1125     }
  1123   then show "l \<approx> r \<Longrightarrow> l \<approx>2 r" by blast
  1126   then show "l \<approx> r \<Longrightarrow> l \<approx>2 r" by blast
  1124 qed
  1127 qed
  1125 
  1128