956 by (auto simp add: Ball_def) |
956 by (auto simp add: Ball_def) |
957 |
957 |
958 |
958 |
959 section {* Induction and Cases rules for fsets *} |
959 section {* Induction and Cases rules for fsets *} |
960 |
960 |
961 lemma fset_exhaust [case_names empty_fset insert_fset, cases type: fset]: |
961 lemma fset_exhaust [case_names empty insert, cases type: fset]: |
962 assumes empty_fset_case: "S = {||} \<Longrightarrow> P" |
962 assumes empty_fset_case: "S = {||} \<Longrightarrow> P" |
963 and insert_fset_case: "\<And>x S'. S = insert_fset x S' \<Longrightarrow> P" |
963 and insert_fset_case: "\<And>x S'. S = insert_fset x S' \<Longrightarrow> P" |
964 shows "P" |
964 shows "P" |
965 using assms by (lifting list.exhaust) |
965 using assms by (lifting list.exhaust) |
966 |
966 |
967 lemma fset_induct [case_names empty_fset insert_fset]: |
967 lemma fset_induct [case_names empty insert]: |
968 assumes empty_fset_case: "P {||}" |
968 assumes empty_fset_case: "P {||}" |
969 and insert_fset_case: "\<And>x S. P S \<Longrightarrow> P (insert_fset x S)" |
969 and insert_fset_case: "\<And>x S. P S \<Longrightarrow> P (insert_fset x S)" |
970 shows "P S" |
970 shows "P S" |
971 using assms |
971 using assms |
972 by (descending) (blast intro: list.induct) |
972 by (descending) (blast intro: list.induct) |
973 |
973 |
974 lemma fset_induct_stronger [case_names empty_fset insert_fset, induct type: fset]: |
974 lemma fset_induct_stronger [case_names empty insert, induct type: fset]: |
975 assumes empty_fset_case: "P {||}" |
975 assumes empty_fset_case: "P {||}" |
976 and insert_fset_case: "\<And>x S. \<lbrakk>x |\<notin>| S; P S\<rbrakk> \<Longrightarrow> P (insert_fset x S)" |
976 and insert_fset_case: "\<And>x S. \<lbrakk>x |\<notin>| S; P S\<rbrakk> \<Longrightarrow> P (insert_fset x S)" |
977 shows "P S" |
977 shows "P S" |
978 proof(induct S rule: fset_induct) |
978 proof(induct S rule: fset_induct) |
979 case empty_fset |
979 case empty |
980 show "P {||}" using empty_fset_case by simp |
980 show "P {||}" using empty_fset_case by simp |
981 next |
981 next |
982 case (insert_fset x S) |
982 case (insert x S) |
983 have "P S" by fact |
983 have "P S" by fact |
984 then show "P (insert_fset x S)" using insert_fset_case |
984 then show "P (insert_fset x S)" using insert_fset_case |
985 by (cases "x |\<in>| S") (simp_all) |
985 by (cases "x |\<in>| S") (simp_all) |
986 qed |
986 qed |
987 |
987 |
988 lemma fset_card_induct: |
988 lemma fset_card_induct: |
989 assumes empty_fset_case: "P {||}" |
989 assumes empty_fset_case: "P {||}" |
990 and card_fset_Suc_case: "\<And>S T. Suc (card_fset S) = (card_fset T) \<Longrightarrow> P S \<Longrightarrow> P T" |
990 and card_fset_Suc_case: "\<And>S T. Suc (card_fset S) = (card_fset T) \<Longrightarrow> P S \<Longrightarrow> P T" |
991 shows "P S" |
991 shows "P S" |
992 proof (induct S) |
992 proof (induct S) |
993 case empty_fset |
993 case empty |
994 show "P {||}" by (rule empty_fset_case) |
994 show "P {||}" by (rule empty_fset_case) |
995 next |
995 next |
996 case (insert_fset x S) |
996 case (insert x S) |
997 have h: "P S" by fact |
997 have h: "P S" by fact |
998 have "x |\<notin>| S" by fact |
998 have "x |\<notin>| S" by fact |
999 then have "Suc (card_fset S) = card_fset (insert_fset x S)" |
999 then have "Suc (card_fset S) = card_fset (insert_fset x S)" |
1000 using card_fset_Suc by auto |
1000 using card_fset_Suc by auto |
1001 then show "P (insert_fset x S)" |
1001 then show "P (insert_fset x S)" |
1056 apply simp_all |
1056 apply simp_all |
1057 apply (induct_tac xa rule: fset_induct_stronger) |
1057 apply (induct_tac xa rule: fset_induct_stronger) |
1058 apply simp_all |
1058 apply simp_all |
1059 done |
1059 done |
1060 |
1060 |
1061 |
1061 text {* Extensionality *} |
|
1062 |
|
1063 lemma fset_eqI: |
|
1064 assumes "\<And>x. x \<in> fset A \<longleftrightarrow> x \<in> fset B" |
|
1065 shows "A = B" |
|
1066 using assms proof (induct A arbitrary: B) |
|
1067 case empty then show ?case |
|
1068 by (auto simp add: in_fset none_in_empty_fset [symmetric] sym) |
|
1069 next |
|
1070 case (insert x A) |
|
1071 from insert.prems insert.hyps(1) have "\<And>z. z \<in> fset A \<longleftrightarrow> z \<in> fset (B - {|x|})" |
|
1072 by (auto simp add: in_fset) |
|
1073 then have "A = B - {|x|}" by (rule insert.hyps(2)) |
|
1074 moreover with insert.prems [symmetric, of x] have "x |\<in>| B" by (simp add: in_fset) |
|
1075 ultimately show ?case by (metis in_fset_mdef) |
|
1076 qed |
1062 |
1077 |
1063 subsection {* alternate formulation with a different decomposition principle |
1078 subsection {* alternate formulation with a different decomposition principle |
1064 and a proof of equivalence *} |
1079 and a proof of equivalence *} |
1065 |
1080 |
1066 inductive |
1081 inductive |