460 |
460 |
461 lemma subsetD [elim, intro?]: "A \<subseteq> B ==> c \<in> A ==> c \<in> B" |
461 lemma subsetD [elim, intro?]: "A \<subseteq> B ==> c \<in> A ==> c \<in> B" |
462 unfolding mem_def by (erule le_funE, erule le_boolE) |
462 unfolding mem_def by (erule le_funE, erule le_boolE) |
463 -- {* Rule in Modus Ponens style. *} |
463 -- {* Rule in Modus Ponens style. *} |
464 |
464 |
465 lemma rev_subsetD [noatp,intro?]: "c \<in> A ==> A \<subseteq> B ==> c \<in> B" |
465 lemma rev_subsetD [no_atp,intro?]: "c \<in> A ==> A \<subseteq> B ==> c \<in> B" |
466 -- {* The same, with reversed premises for use with @{text erule} -- |
466 -- {* The same, with reversed premises for use with @{text erule} -- |
467 cf @{text rev_mp}. *} |
467 cf @{text rev_mp}. *} |
468 by (rule subsetD) |
468 by (rule subsetD) |
469 |
469 |
470 text {* |
470 text {* |
471 \medskip Converts @{prop "A \<subseteq> B"} to @{prop "x \<in> A ==> x \<in> B"}. |
471 \medskip Converts @{prop "A \<subseteq> B"} to @{prop "x \<in> A ==> x \<in> B"}. |
472 *} |
472 *} |
473 |
473 |
474 lemma subsetCE [noatp,elim]: "A \<subseteq> B ==> (c \<notin> A ==> P) ==> (c \<in> B ==> P) ==> P" |
474 lemma subsetCE [no_atp,elim]: "A \<subseteq> B ==> (c \<notin> A ==> P) ==> (c \<in> B ==> P) ==> P" |
475 -- {* Classical elimination rule. *} |
475 -- {* Classical elimination rule. *} |
476 unfolding mem_def by (blast dest: le_funE le_boolE) |
476 unfolding mem_def by (blast dest: le_funE le_boolE) |
477 |
477 |
478 lemma subset_eq [noatp]: "A \<le> B = (\<forall>x\<in>A. x \<in> B)" by blast |
478 lemma subset_eq [no_atp]: "A \<le> B = (\<forall>x\<in>A. x \<in> B)" by blast |
479 |
479 |
480 lemma contra_subsetD [noatp]: "A \<subseteq> B ==> c \<notin> B ==> c \<notin> A" |
480 lemma contra_subsetD [no_atp]: "A \<subseteq> B ==> c \<notin> B ==> c \<notin> A" |
481 by blast |
481 by blast |
482 |
482 |
483 lemma subset_refl [simp]: "A \<subseteq> A" |
483 lemma subset_refl [simp]: "A \<subseteq> A" |
484 by (fact order_refl) |
484 by (fact order_refl) |
485 |
485 |
789 lemma insert_ident: "x ~: A ==> x ~: B ==> (insert x A = insert x B) = (A = B)" |
789 lemma insert_ident: "x ~: A ==> x ~: B ==> (insert x A = insert x B) = (A = B)" |
790 by auto |
790 by auto |
791 |
791 |
792 subsubsection {* Singletons, using insert *} |
792 subsubsection {* Singletons, using insert *} |
793 |
793 |
794 lemma singletonI [intro!,noatp]: "a : {a}" |
794 lemma singletonI [intro!,no_atp]: "a : {a}" |
795 -- {* Redundant? But unlike @{text insertCI}, it proves the subgoal immediately! *} |
795 -- {* Redundant? But unlike @{text insertCI}, it proves the subgoal immediately! *} |
796 by (rule insertI1) |
796 by (rule insertI1) |
797 |
797 |
798 lemma singletonD [dest!,noatp]: "b : {a} ==> b = a" |
798 lemma singletonD [dest!,no_atp]: "b : {a} ==> b = a" |
799 by blast |
799 by blast |
800 |
800 |
801 lemmas singletonE = singletonD [elim_format] |
801 lemmas singletonE = singletonD [elim_format] |
802 |
802 |
803 lemma singleton_iff: "(b : {a}) = (b = a)" |
803 lemma singleton_iff: "(b : {a}) = (b = a)" |
804 by blast |
804 by blast |
805 |
805 |
806 lemma singleton_inject [dest!]: "{a} = {b} ==> a = b" |
806 lemma singleton_inject [dest!]: "{a} = {b} ==> a = b" |
807 by blast |
807 by blast |
808 |
808 |
809 lemma singleton_insert_inj_eq [iff,noatp]: |
809 lemma singleton_insert_inj_eq [iff,no_atp]: |
810 "({b} = insert a A) = (a = b & A \<subseteq> {b})" |
810 "({b} = insert a A) = (a = b & A \<subseteq> {b})" |
811 by blast |
811 by blast |
812 |
812 |
813 lemma singleton_insert_inj_eq' [iff,noatp]: |
813 lemma singleton_insert_inj_eq' [iff,no_atp]: |
814 "(insert a A = {b}) = (a = b & A \<subseteq> {b})" |
814 "(insert a A = {b}) = (a = b & A \<subseteq> {b})" |
815 by blast |
815 by blast |
816 |
816 |
817 lemma subset_singletonD: "A \<subseteq> {x} ==> A = {} | A = {x}" |
817 lemma subset_singletonD: "A \<subseteq> {x} ==> A = {} | A = {x}" |
818 by fast |
818 by fast |
835 text {* |
835 text {* |
836 Frequently @{term b} does not have the syntactic form of @{term "f x"}. |
836 Frequently @{term b} does not have the syntactic form of @{term "f x"}. |
837 *} |
837 *} |
838 |
838 |
839 definition image :: "('a => 'b) => 'a set => 'b set" (infixr "`" 90) where |
839 definition image :: "('a => 'b) => 'a set => 'b set" (infixr "`" 90) where |
840 image_def [noatp]: "f ` A = {y. EX x:A. y = f(x)}" |
840 image_def [no_atp]: "f ` A = {y. EX x:A. y = f(x)}" |
841 |
841 |
842 abbreviation |
842 abbreviation |
843 range :: "('a => 'b) => 'b set" where -- "of function" |
843 range :: "('a => 'b) => 'b set" where -- "of function" |
844 "range f == f ` UNIV" |
844 "range f == f ` UNIV" |
845 |
845 |
940 |
940 |
941 subsection {* Further operations and lemmas *} |
941 subsection {* Further operations and lemmas *} |
942 |
942 |
943 subsubsection {* The ``proper subset'' relation *} |
943 subsubsection {* The ``proper subset'' relation *} |
944 |
944 |
945 lemma psubsetI [intro!,noatp]: "A \<subseteq> B ==> A \<noteq> B ==> A \<subset> B" |
945 lemma psubsetI [intro!,no_atp]: "A \<subseteq> B ==> A \<noteq> B ==> A \<subset> B" |
946 by (unfold less_le) blast |
946 by (unfold less_le) blast |
947 |
947 |
948 lemma psubsetE [elim!,noatp]: |
948 lemma psubsetE [elim!,no_atp]: |
949 "[|A \<subset> B; [|A \<subseteq> B; ~ (B\<subseteq>A)|] ==> R|] ==> R" |
949 "[|A \<subset> B; [|A \<subseteq> B; ~ (B\<subseteq>A)|] ==> R|] ==> R" |
950 by (unfold less_le) blast |
950 by (unfold less_le) blast |
951 |
951 |
952 lemma psubset_insert_iff: |
952 lemma psubset_insert_iff: |
953 "(A \<subset> insert x B) = (if x \<in> B then A \<subset> B else if x \<in> A then A - {x} \<subset> B else A \<subseteq> B)" |
953 "(A \<subset> insert x B) = (if x \<in> B then A \<subset> B else if x \<in> A then A - {x} \<subset> B else A \<subseteq> B)" |
1100 by auto |
1100 by auto |
1101 |
1101 |
1102 lemma insert_inter_insert[simp]: "insert a A \<inter> insert a B = insert a (A \<inter> B)" |
1102 lemma insert_inter_insert[simp]: "insert a A \<inter> insert a B = insert a (A \<inter> B)" |
1103 by blast |
1103 by blast |
1104 |
1104 |
1105 lemma insert_disjoint [simp,noatp]: |
1105 lemma insert_disjoint [simp,no_atp]: |
1106 "(insert a A \<inter> B = {}) = (a \<notin> B \<and> A \<inter> B = {})" |
1106 "(insert a A \<inter> B = {}) = (a \<notin> B \<and> A \<inter> B = {})" |
1107 "({} = insert a A \<inter> B) = (a \<notin> B \<and> {} = A \<inter> B)" |
1107 "({} = insert a A \<inter> B) = (a \<notin> B \<and> {} = A \<inter> B)" |
1108 by auto |
1108 by auto |
1109 |
1109 |
1110 lemma disjoint_insert [simp,noatp]: |
1110 lemma disjoint_insert [simp,no_atp]: |
1111 "(B \<inter> insert a A = {}) = (a \<notin> B \<and> B \<inter> A = {})" |
1111 "(B \<inter> insert a A = {}) = (a \<notin> B \<and> B \<inter> A = {})" |
1112 "({} = A \<inter> insert b B) = (b \<notin> A \<and> {} = A \<inter> B)" |
1112 "({} = A \<inter> insert b B) = (b \<notin> A \<and> {} = A \<inter> B)" |
1113 by auto |
1113 by auto |
1114 |
1114 |
1115 text {* \medskip @{text image}. *} |
1115 text {* \medskip @{text image}. *} |
1137 |
1137 |
1138 lemma empty_is_image[iff]: "({} = f ` A) = (A = {})" |
1138 lemma empty_is_image[iff]: "({} = f ` A) = (A = {})" |
1139 by blast |
1139 by blast |
1140 |
1140 |
1141 |
1141 |
1142 lemma image_Collect [noatp]: "f ` {x. P x} = {f x | x. P x}" |
1142 lemma image_Collect [no_atp]: "f ` {x. P x} = {f x | x. P x}" |
1143 -- {* NOT suitable as a default simprule: the RHS isn't simpler than the LHS, |
1143 -- {* NOT suitable as a default simprule: the RHS isn't simpler than the LHS, |
1144 with its implicit quantifier and conjunction. Also image enjoys better |
1144 with its implicit quantifier and conjunction. Also image enjoys better |
1145 equational properties than does the RHS. *} |
1145 equational properties than does the RHS. *} |
1146 by blast |
1146 by blast |
1147 |
1147 |
1154 by (simp add: image_def) |
1154 by (simp add: image_def) |
1155 |
1155 |
1156 |
1156 |
1157 text {* \medskip @{text range}. *} |
1157 text {* \medskip @{text range}. *} |
1158 |
1158 |
1159 lemma full_SetCompr_eq [noatp]: "{u. \<exists>x. u = f x} = range f" |
1159 lemma full_SetCompr_eq [no_atp]: "{u. \<exists>x. u = f x} = range f" |
1160 by auto |
1160 by auto |
1161 |
1161 |
1162 lemma range_composition: "range (\<lambda>x. f (g x)) = f`range g" |
1162 lemma range_composition: "range (\<lambda>x. f (g x)) = f`range g" |
1163 by (subst image_image, simp) |
1163 by (subst image_image, simp) |
1164 |
1164 |
1637 |
1637 |
1638 lemma vimage_mono: "A \<subseteq> B ==> f -` A \<subseteq> f -` B" |
1638 lemma vimage_mono: "A \<subseteq> B ==> f -` A \<subseteq> f -` B" |
1639 -- {* monotonicity *} |
1639 -- {* monotonicity *} |
1640 by blast |
1640 by blast |
1641 |
1641 |
1642 lemma vimage_image_eq [noatp]: "f -` (f ` A) = {y. EX x:A. f x = f y}" |
1642 lemma vimage_image_eq [no_atp]: "f -` (f ` A) = {y. EX x:A. f x = f y}" |
1643 by (blast intro: sym) |
1643 by (blast intro: sym) |
1644 |
1644 |
1645 lemma image_vimage_subset: "f ` (f -` A) <= A" |
1645 lemma image_vimage_subset: "f ` (f -` A) <= A" |
1646 by blast |
1646 by blast |
1647 |
1647 |