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)" |
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 |