src/HOL/Set.thy
changeset 36096 abc6a2ea4b88
parent 36009 9cdbc5ffc15c
child 37387 3581483cca6c
equal deleted inserted replaced
36095:059c3568fdc8 36096:abc6a2ea4b88
    46   not_mem  ("(_/ \<notin> _)" [50, 51] 50)
    46   not_mem  ("(_/ \<notin> _)" [50, 51] 50)
    47 
    47 
    48 text {* Set comprehensions *}
    48 text {* Set comprehensions *}
    49 
    49 
    50 syntax
    50 syntax
    51   "@Coll"       :: "pttrn => bool => 'a set"              ("(1{_./ _})")
    51   "_Coll" :: "pttrn => bool => 'a set"    ("(1{_./ _})")
    52 
       
    53 translations
    52 translations
    54   "{x. P}"      == "Collect (%x. P)"
    53   "{x. P}" == "CONST Collect (%x. P)"
    55 
    54 
    56 syntax
    55 syntax
    57   "@SetCompr"   :: "'a => idts => bool => 'a set"         ("(1{_ |/_./ _})")
    56   "_Collect" :: "idt => 'a set => bool => 'a set"    ("(1{_ :/ _./ _})")
    58   "@Collect"    :: "idt => 'a set => bool => 'a set"      ("(1{_ :/ _./ _})")
       
    59 
       
    60 syntax (xsymbols)
    57 syntax (xsymbols)
    61   "@Collect"    :: "idt => 'a set => bool => 'a set"      ("(1{_ \<in>/ _./ _})")
    58   "_Collect" :: "idt => 'a set => bool => 'a set"    ("(1{_ \<in>/ _./ _})")
    62 
       
    63 translations
    59 translations
    64   "{x:A. P}"    => "{x. x:A & P}"
    60   "{x:A. P}" => "{x. x:A & P}"
    65 
    61 
    66 lemma mem_Collect_eq [iff]: "(a : {x. P(x)}) = P(a)"
    62 lemma mem_Collect_eq [iff]: "(a : {x. P(x)}) = P(a)"
    67   by (simp add: Collect_def mem_def)
    63   by (simp add: Collect_def mem_def)
    68 
    64 
    69 lemma Collect_mem_eq [simp]: "{x. x:A} = A"
    65 lemma Collect_mem_eq [simp]: "{x. x:A} = A"
   105 
   101 
   106 definition insert :: "'a \<Rightarrow> 'a set \<Rightarrow> 'a set" where
   102 definition insert :: "'a \<Rightarrow> 'a set \<Rightarrow> 'a set" where
   107   insert_compr: "insert a B = {x. x = a \<or> x \<in> B}"
   103   insert_compr: "insert a B = {x. x = a \<or> x \<in> B}"
   108 
   104 
   109 syntax
   105 syntax
   110   "@Finset"     :: "args => 'a set"                       ("{(_)}")
   106   "_Finset" :: "args => 'a set"    ("{(_)}")
   111 
       
   112 translations
   107 translations
   113   "{x, xs}"     == "CONST insert x {xs}"
   108   "{x, xs}" == "CONST insert x {xs}"
   114   "{x}"         == "CONST insert x {}"
   109   "{x}" == "CONST insert x {}"
   115 
   110 
   116 
   111 
   117 subsection {* Subsets and bounded quantifiers *}
   112 subsection {* Subsets and bounded quantifiers *}
   118 
   113 
   119 abbreviation
   114 abbreviation
   159 global
   154 global
   160 
   155 
   161 consts
   156 consts
   162   Ball          :: "'a set => ('a => bool) => bool"      -- "bounded universal quantifiers"
   157   Ball          :: "'a set => ('a => bool) => bool"      -- "bounded universal quantifiers"
   163   Bex           :: "'a set => ('a => bool) => bool"      -- "bounded existential quantifiers"
   158   Bex           :: "'a set => ('a => bool) => bool"      -- "bounded existential quantifiers"
   164   Bex1          :: "'a set => ('a => bool) => bool"      -- "bounded unique existential quantifiers"
       
   165 
   159 
   166 local
   160 local
   167 
   161 
   168 defs
   162 defs
   169   Ball_def:     "Ball A P       == ALL x. x:A --> P(x)"
   163   Ball_def:     "Ball A P       == ALL x. x:A --> P(x)"
   170   Bex_def:      "Bex A P        == EX x. x:A & P(x)"
   164   Bex_def:      "Bex A P        == EX x. x:A & P(x)"
   171   Bex1_def:     "Bex1 A P       == EX! x. x:A & P(x)"
       
   172 
   165 
   173 syntax
   166 syntax
   174   "_Ball"       :: "pttrn => 'a set => bool => bool"      ("(3ALL _:_./ _)" [0, 0, 10] 10)
   167   "_Ball"       :: "pttrn => 'a set => bool => bool"      ("(3ALL _:_./ _)" [0, 0, 10] 10)
   175   "_Bex"        :: "pttrn => 'a set => bool => bool"      ("(3EX _:_./ _)" [0, 0, 10] 10)
   168   "_Bex"        :: "pttrn => 'a set => bool => bool"      ("(3EX _:_./ _)" [0, 0, 10] 10)
   176   "_Bex1"       :: "pttrn => 'a set => bool => bool"      ("(3EX! _:_./ _)" [0, 0, 10] 10)
   169   "_Bex1"       :: "pttrn => 'a set => bool => bool"      ("(3EX! _:_./ _)" [0, 0, 10] 10)
   191   "_Ball"       :: "pttrn => 'a set => bool => bool"      ("(3\<forall>_\<in>_./ _)" [0, 0, 10] 10)
   184   "_Ball"       :: "pttrn => 'a set => bool => bool"      ("(3\<forall>_\<in>_./ _)" [0, 0, 10] 10)
   192   "_Bex"        :: "pttrn => 'a set => bool => bool"      ("(3\<exists>_\<in>_./ _)" [0, 0, 10] 10)
   185   "_Bex"        :: "pttrn => 'a set => bool => bool"      ("(3\<exists>_\<in>_./ _)" [0, 0, 10] 10)
   193   "_Bex1"       :: "pttrn => 'a set => bool => bool"      ("(3\<exists>!_\<in>_./ _)" [0, 0, 10] 10)
   186   "_Bex1"       :: "pttrn => 'a set => bool => bool"      ("(3\<exists>!_\<in>_./ _)" [0, 0, 10] 10)
   194 
   187 
   195 translations
   188 translations
   196   "ALL x:A. P"  == "Ball A (%x. P)"
   189   "ALL x:A. P" == "CONST Ball A (%x. P)"
   197   "EX x:A. P"   == "Bex A (%x. P)"
   190   "EX x:A. P" == "CONST Bex A (%x. P)"
   198   "EX! x:A. P"  == "Bex1 A (%x. P)"
   191   "EX! x:A. P" => "EX! x. x:A & P"
   199   "LEAST x:A. P" => "LEAST x. x:A & P"
   192   "LEAST x:A. P" => "LEAST x. x:A & P"
   200 
   193 
   201 syntax (output)
   194 syntax (output)
   202   "_setlessAll" :: "[idt, 'a, bool] => bool"  ("(3ALL _<_./ _)"  [0, 0, 10] 10)
   195   "_setlessAll" :: "[idt, 'a, bool] => bool"  ("(3ALL _<_./ _)"  [0, 0, 10] 10)
   203   "_setlessEx"  :: "[idt, 'a, bool] => bool"  ("(3EX _<_./ _)"  [0, 0, 10] 10)
   196   "_setlessEx"  :: "[idt, 'a, bool] => bool"  ("(3EX _<_./ _)"  [0, 0, 10] 10)
   233  "\<exists>A\<subseteq>B. P"   =>  "EX A. A \<subseteq> B & P"
   226  "\<exists>A\<subseteq>B. P"   =>  "EX A. A \<subseteq> B & P"
   234  "\<exists>!A\<subseteq>B. P"  =>  "EX! A. A \<subseteq> B & P"
   227  "\<exists>!A\<subseteq>B. P"  =>  "EX! A. A \<subseteq> B & P"
   235 
   228 
   236 print_translation {*
   229 print_translation {*
   237 let
   230 let
   238   val Type (set_type, _) = @{typ "'a set"};
   231   val Type (set_type, _) = @{typ "'a set"};   (* FIXME 'a => bool (!?!) *)
   239   val All_binder = Syntax.binder_name @{const_syntax "All"};
   232   val All_binder = Syntax.binder_name @{const_syntax All};
   240   val Ex_binder = Syntax.binder_name @{const_syntax "Ex"};
   233   val Ex_binder = Syntax.binder_name @{const_syntax Ex};
   241   val impl = @{const_syntax "op -->"};
   234   val impl = @{const_syntax "op -->"};
   242   val conj = @{const_syntax "op &"};
   235   val conj = @{const_syntax "op &"};
   243   val sbset = @{const_syntax "subset"};
   236   val sbset = @{const_syntax subset};
   244   val sbset_eq = @{const_syntax "subset_eq"};
   237   val sbset_eq = @{const_syntax subset_eq};
   245 
   238 
   246   val trans =
   239   val trans =
   247    [((All_binder, impl, sbset), "_setlessAll"),
   240    [((All_binder, impl, sbset), @{syntax_const "_setlessAll"}),
   248     ((All_binder, impl, sbset_eq), "_setleAll"),
   241     ((All_binder, impl, sbset_eq), @{syntax_const "_setleAll"}),
   249     ((Ex_binder, conj, sbset), "_setlessEx"),
   242     ((Ex_binder, conj, sbset), @{syntax_const "_setlessEx"}),
   250     ((Ex_binder, conj, sbset_eq), "_setleEx")];
   243     ((Ex_binder, conj, sbset_eq), @{syntax_const "_setleEx"})];
   251 
   244 
   252   fun mk v v' c n P =
   245   fun mk v v' c n P =
   253     if v = v' andalso not (Term.exists_subterm (fn Free (x, _) => x = v | _ => false) n)
   246     if v = v' andalso not (Term.exists_subterm (fn Free (x, _) => x = v | _ => false) n)
   254     then Syntax.const c $ Syntax.mark_bound v' $ n $ P else raise Match;
   247     then Syntax.const c $ Syntax.mark_bound v' $ n $ P else raise Match;
   255 
   248 
   256   fun tr' q = (q,
   249   fun tr' q = (q,
   257     fn [Const ("_bound", _) $ Free (v, Type (T, _)), Const (c, _) $ (Const (d, _) $ (Const ("_bound", _) $ Free (v', _)) $ n) $ P] =>
   250         fn [Const (@{syntax_const "_bound"}, _) $ Free (v, Type (T, _)),
   258          if T = (set_type) then case AList.lookup (op =) trans (q, c, d)
   251             Const (c, _) $
   259           of NONE => raise Match
   252               (Const (d, _) $ (Const (@{syntax_const "_bound"}, _) $ Free (v', _)) $ n) $ P] =>
   260            | SOME l => mk v v' l n P
   253             if T = set_type then
   261          else raise Match
   254               (case AList.lookup (op =) trans (q, c, d) of
   262      | _ => raise Match);
   255                 NONE => raise Match
       
   256               | SOME l => mk v v' l n P)
       
   257             else raise Match
       
   258          | _ => raise Match);
   263 in
   259 in
   264   [tr' All_binder, tr' Ex_binder]
   260   [tr' All_binder, tr' Ex_binder]
   265 end
   261 end
   266 *}
   262 *}
   267 
   263 
   270   \medskip Translate between @{text "{e | x1...xn. P}"} and @{text
   266   \medskip Translate between @{text "{e | x1...xn. P}"} and @{text
   271   "{u. EX x1..xn. u = e & P}"}; @{text "{y. EX x1..xn. y = e & P}"} is
   267   "{u. EX x1..xn. u = e & P}"}; @{text "{y. EX x1..xn. y = e & P}"} is
   272   only translated if @{text "[0..n] subset bvs(e)"}.
   268   only translated if @{text "[0..n] subset bvs(e)"}.
   273 *}
   269 *}
   274 
   270 
       
   271 syntax
       
   272   "_Setcompr" :: "'a => idts => bool => 'a set"    ("(1{_ |/_./ _})")
       
   273 
   275 parse_translation {*
   274 parse_translation {*
   276   let
   275   let
   277     val ex_tr = snd (mk_binder_tr ("EX ", "Ex"));
   276     val ex_tr = snd (mk_binder_tr ("EX ", @{const_syntax Ex}));
   278 
   277 
   279     fun nvars (Const ("_idts", _) $ _ $ idts) = nvars idts + 1
   278     fun nvars (Const (@{syntax_const "_idts"}, _) $ _ $ idts) = nvars idts + 1
   280       | nvars _ = 1;
   279       | nvars _ = 1;
   281 
   280 
   282     fun setcompr_tr [e, idts, b] =
   281     fun setcompr_tr [e, idts, b] =
   283       let
   282       let
   284         val eq = Syntax.const "op =" $ Bound (nvars idts) $ e;
   283         val eq = Syntax.const @{const_syntax "op ="} $ Bound (nvars idts) $ e;
   285         val P = Syntax.const "op &" $ eq $ b;
   284         val P = Syntax.const @{const_syntax "op &"} $ eq $ b;
   286         val exP = ex_tr [idts, P];
   285         val exP = ex_tr [idts, P];
   287       in Syntax.const "Collect" $ Term.absdummy (dummyT, exP) end;
   286       in Syntax.const @{const_syntax Collect} $ Term.absdummy (dummyT, exP) end;
   288 
   287 
   289   in [("@SetCompr", setcompr_tr)] end;
   288   in [(@{syntax_const "_Setcompr"}, setcompr_tr)] end;
   290 *}
   289 *}
   291 
   290 
   292 print_translation {* [
   291 print_translation {*
   293 Syntax.preserve_binder_abs2_tr' @{const_syntax Ball} "_Ball",
   292  [Syntax.preserve_binder_abs2_tr' @{const_syntax Ball} @{syntax_const "_Ball"},
   294 Syntax.preserve_binder_abs2_tr' @{const_syntax Bex} "_Bex"
   293   Syntax.preserve_binder_abs2_tr' @{const_syntax Bex} @{syntax_const "_Bex"}]
   295 ] *} -- {* to avoid eta-contraction of body *}
   294 *} -- {* to avoid eta-contraction of body *}
   296 
   295 
   297 print_translation {*
   296 print_translation {*
   298 let
   297 let
   299   val ex_tr' = snd (mk_binder_tr' ("Ex", "DUMMY"));
   298   val ex_tr' = snd (mk_binder_tr' (@{const_syntax Ex}, "DUMMY"));
   300 
   299 
   301   fun setcompr_tr' [Abs (abs as (_, _, P))] =
   300   fun setcompr_tr' [Abs (abs as (_, _, P))] =
   302     let
   301     let
   303       fun check (Const ("Ex", _) $ Abs (_, _, P), n) = check (P, n + 1)
   302       fun check (Const (@{const_syntax Ex}, _) $ Abs (_, _, P), n) = check (P, n + 1)
   304         | check (Const ("op &", _) $ (Const ("op =", _) $ Bound m $ e) $ P, n) =
   303         | check (Const (@{const_syntax "op &"}, _) $
       
   304               (Const (@{const_syntax "op ="}, _) $ Bound m $ e) $ P, n) =
   305             n > 0 andalso m = n andalso not (loose_bvar1 (P, n)) andalso
   305             n > 0 andalso m = n andalso not (loose_bvar1 (P, n)) andalso
   306             subset (op =) (0 upto (n - 1), add_loose_bnos (e, 0, []))
   306             subset (op =) (0 upto (n - 1), add_loose_bnos (e, 0, []))
   307         | check _ = false
   307         | check _ = false;
   308 
   308 
   309         fun tr' (_ $ abs) =
   309         fun tr' (_ $ abs) =
   310           let val _ $ idts $ (_ $ (_ $ _ $ e) $ Q) = ex_tr' [abs]
   310           let val _ $ idts $ (_ $ (_ $ _ $ e) $ Q) = ex_tr' [abs]
   311           in Syntax.const "@SetCompr" $ e $ idts $ Q end;
   311           in Syntax.const @{syntax_const "_Setcompr"} $ e $ idts $ Q end;
   312     in if check (P, 0) then tr' P
   312     in
   313        else let val (x as _ $ Free(xN,_), t) = atomic_abs_tr' abs
   313       if check (P, 0) then tr' P
   314                 val M = Syntax.const "@Coll" $ x $ t
   314       else
   315             in case t of
   315         let
   316                  Const("op &",_)
   316           val (x as _ $ Free(xN, _), t) = atomic_abs_tr' abs;
   317                    $ (Const("op :",_) $ (Const("_bound",_) $ Free(yN,_)) $ A)
   317           val M = Syntax.const @{syntax_const "_Coll"} $ x $ t;
   318                    $ P =>
   318         in
   319                    if xN=yN then Syntax.const "@Collect" $ x $ A $ P else M
   319           case t of
   320                | _ => M
   320             Const (@{const_syntax "op &"}, _) $
   321             end
   321               (Const (@{const_syntax "op :"}, _) $
       
   322                 (Const (@{syntax_const "_bound"}, _) $ Free (yN, _)) $ A) $ P =>
       
   323             if xN = yN then Syntax.const @{syntax_const "_Collect"} $ x $ A $ P else M
       
   324           | _ => M
       
   325         end
   322     end;
   326     end;
   323   in [("Collect", setcompr_tr')] end;
   327   in [(@{const_syntax Collect}, setcompr_tr')] end;
   324 *}
   328 *}
   325 
   329 
   326 setup {*
   330 setup {*
   327 let
   331 let
   328   val unfold_bex_tac = unfold_tac @{thms "Bex_def"};
   332   val unfold_bex_tac = unfold_tac @{thms "Bex_def"};
   456 
   460 
   457 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"
   458   unfolding mem_def by (erule le_funE, erule le_boolE)
   462   unfolding mem_def by (erule le_funE, erule le_boolE)
   459   -- {* Rule in Modus Ponens style. *}
   463   -- {* Rule in Modus Ponens style. *}
   460 
   464 
   461 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"
   462   -- {* The same, with reversed premises for use with @{text erule} --
   466   -- {* The same, with reversed premises for use with @{text erule} --
   463       cf @{text rev_mp}. *}
   467       cf @{text rev_mp}. *}
   464   by (rule subsetD)
   468   by (rule subsetD)
   465 
   469 
   466 text {*
   470 text {*
   467   \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"}.
   468 *}
   472 *}
   469 
   473 
   470 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"
   471   -- {* Classical elimination rule. *}
   475   -- {* Classical elimination rule. *}
   472   unfolding mem_def by (blast dest: le_funE le_boolE)
   476   unfolding mem_def by (blast dest: le_funE le_boolE)
   473 
   477 
   474 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
   475 
   479 
   476 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"
   477   by blast
   481   by blast
   478 
   482 
   479 lemma subset_refl [simp]: "A \<subseteq> A"
   483 lemma subset_refl [simp]: "A \<subseteq> A"
   480   by (fact order_refl)
   484   by (fact order_refl)
   481 
   485 
   501   apply (rule prem [THEN ext, THEN arg_cong, THEN box_equals])
   505   apply (rule prem [THEN ext, THEN arg_cong, THEN box_equals])
   502    apply (rule Collect_mem_eq)
   506    apply (rule Collect_mem_eq)
   503   apply (rule Collect_mem_eq)
   507   apply (rule Collect_mem_eq)
   504   done
   508   done
   505 
   509 
   506 (* Due to Brian Huffman *)
       
   507 lemma expand_set_eq: "(A = B) = (ALL x. (x:A) = (x:B))"
   510 lemma expand_set_eq: "(A = B) = (ALL x. (x:A) = (x:B))"
   508 by(auto intro:set_ext)
   511 by(auto intro:set_ext)
   509 
   512 
   510 lemma subset_antisym [intro!]: "A \<subseteq> B ==> B \<subseteq> A ==> A = B"
   513 lemma subset_antisym [intro!]: "A \<subseteq> B ==> B \<subseteq> A ==> A = B"
   511   -- {* Anti-symmetry of the subset relation. *}
   514   -- {* Anti-symmetry of the subset relation. *}
   785 lemma insert_ident: "x ~: A ==> x ~: B ==> (insert x A = insert x B) = (A = B)"
   788 lemma insert_ident: "x ~: A ==> x ~: B ==> (insert x A = insert x B) = (A = B)"
   786 by auto
   789 by auto
   787 
   790 
   788 subsubsection {* Singletons, using insert *}
   791 subsubsection {* Singletons, using insert *}
   789 
   792 
   790 lemma singletonI [intro!,noatp]: "a : {a}"
   793 lemma singletonI [intro!,no_atp]: "a : {a}"
   791     -- {* Redundant? But unlike @{text insertCI}, it proves the subgoal immediately! *}
   794     -- {* Redundant? But unlike @{text insertCI}, it proves the subgoal immediately! *}
   792   by (rule insertI1)
   795   by (rule insertI1)
   793 
   796 
   794 lemma singletonD [dest!,noatp]: "b : {a} ==> b = a"
   797 lemma singletonD [dest!,no_atp]: "b : {a} ==> b = a"
   795   by blast
   798   by blast
   796 
   799 
   797 lemmas singletonE = singletonD [elim_format]
   800 lemmas singletonE = singletonD [elim_format]
   798 
   801 
   799 lemma singleton_iff: "(b : {a}) = (b = a)"
   802 lemma singleton_iff: "(b : {a}) = (b = a)"
   800   by blast
   803   by blast
   801 
   804 
   802 lemma singleton_inject [dest!]: "{a} = {b} ==> a = b"
   805 lemma singleton_inject [dest!]: "{a} = {b} ==> a = b"
   803   by blast
   806   by blast
   804 
   807 
   805 lemma singleton_insert_inj_eq [iff,noatp]:
   808 lemma singleton_insert_inj_eq [iff,no_atp]:
   806      "({b} = insert a A) = (a = b & A \<subseteq> {b})"
   809      "({b} = insert a A) = (a = b & A \<subseteq> {b})"
   807   by blast
   810   by blast
   808 
   811 
   809 lemma singleton_insert_inj_eq' [iff,noatp]:
   812 lemma singleton_insert_inj_eq' [iff,no_atp]:
   810      "(insert a A = {b}) = (a = b & A \<subseteq> {b})"
   813      "(insert a A = {b}) = (a = b & A \<subseteq> {b})"
   811   by blast
   814   by blast
   812 
   815 
   813 lemma subset_singletonD: "A \<subseteq> {x} ==> A = {} | A = {x}"
   816 lemma subset_singletonD: "A \<subseteq> {x} ==> A = {} | A = {x}"
   814   by fast
   817   by fast
   831 text {*
   834 text {*
   832   Frequently @{term b} does not have the syntactic form of @{term "f x"}.
   835   Frequently @{term b} does not have the syntactic form of @{term "f x"}.
   833 *}
   836 *}
   834 
   837 
   835 definition image :: "('a => 'b) => 'a set => 'b set" (infixr "`" 90) where
   838 definition image :: "('a => 'b) => 'a set => 'b set" (infixr "`" 90) where
   836   image_def [noatp]: "f ` A = {y. EX x:A. y = f(x)}"
   839   image_def [no_atp]: "f ` A = {y. EX x:A. y = f(x)}"
   837 
   840 
   838 abbreviation
   841 abbreviation
   839   range :: "('a => 'b) => 'b set" where -- "of function"
   842   range :: "('a => 'b) => 'b set" where -- "of function"
   840   "range f == f ` UNIV"
   843   "range f == f ` UNIV"
   841 
   844 
   926 
   929 
   927 (*Would like to add these, but the existing code only searches for the
   930 (*Would like to add these, but the existing code only searches for the
   928   outer-level constant, which in this case is just "op :"; we instead need
   931   outer-level constant, which in this case is just "op :"; we instead need
   929   to use term-nets to associate patterns with rules.  Also, if a rule fails to
   932   to use term-nets to associate patterns with rules.  Also, if a rule fails to
   930   apply, then the formula should be kept.
   933   apply, then the formula should be kept.
   931   [("HOL.uminus", Compl_iff RS iffD1), ("HOL.minus", [Diff_iff RS iffD1]),
   934   [("uminus", Compl_iff RS iffD1), ("minus", [Diff_iff RS iffD1]),
   932    ("Int", [IntD1,IntD2]),
   935    ("Int", [IntD1,IntD2]),
   933    ("Collect", [CollectD]), ("Inter", [InterD]), ("INTER", [INT_D])]
   936    ("Collect", [CollectD]), ("Inter", [InterD]), ("INTER", [INT_D])]
   934  *)
   937  *)
   935 
   938 
   936 
   939 
   937 subsection {* Further operations and lemmas *}
   940 subsection {* Further operations and lemmas *}
   938 
   941 
   939 subsubsection {* The ``proper subset'' relation *}
   942 subsubsection {* The ``proper subset'' relation *}
   940 
   943 
   941 lemma psubsetI [intro!,noatp]: "A \<subseteq> B ==> A \<noteq> B ==> A \<subset> B"
   944 lemma psubsetI [intro!,no_atp]: "A \<subseteq> B ==> A \<noteq> B ==> A \<subset> B"
   942   by (unfold less_le) blast
   945   by (unfold less_le) blast
   943 
   946 
   944 lemma psubsetE [elim!,noatp]: 
   947 lemma psubsetE [elim!,no_atp]: 
   945     "[|A \<subset> B;  [|A \<subseteq> B; ~ (B\<subseteq>A)|] ==> R|] ==> R"
   948     "[|A \<subset> B;  [|A \<subseteq> B; ~ (B\<subseteq>A)|] ==> R|] ==> R"
   946   by (unfold less_le) blast
   949   by (unfold less_le) blast
   947 
   950 
   948 lemma psubset_insert_iff:
   951 lemma psubset_insert_iff:
   949   "(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)"
   952   "(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)"
   996 
   999 
   997 
  1000 
   998 text {* \medskip Finite Union -- the least upper bound of two sets. *}
  1001 text {* \medskip Finite Union -- the least upper bound of two sets. *}
   999 
  1002 
  1000 lemma Un_upper1: "A \<subseteq> A \<union> B"
  1003 lemma Un_upper1: "A \<subseteq> A \<union> B"
  1001   by blast
  1004   by (fact sup_ge1)
  1002 
  1005 
  1003 lemma Un_upper2: "B \<subseteq> A \<union> B"
  1006 lemma Un_upper2: "B \<subseteq> A \<union> B"
  1004   by blast
  1007   by (fact sup_ge2)
  1005 
  1008 
  1006 lemma Un_least: "A \<subseteq> C ==> B \<subseteq> C ==> A \<union> B \<subseteq> C"
  1009 lemma Un_least: "A \<subseteq> C ==> B \<subseteq> C ==> A \<union> B \<subseteq> C"
  1007   by blast
  1010   by (fact sup_least)
  1008 
  1011 
  1009 
  1012 
  1010 text {* \medskip Finite Intersection -- the greatest lower bound of two sets. *}
  1013 text {* \medskip Finite Intersection -- the greatest lower bound of two sets. *}
  1011 
  1014 
  1012 lemma Int_lower1: "A \<inter> B \<subseteq> A"
  1015 lemma Int_lower1: "A \<inter> B \<subseteq> A"
  1013   by blast
  1016   by (fact inf_le1)
  1014 
  1017 
  1015 lemma Int_lower2: "A \<inter> B \<subseteq> B"
  1018 lemma Int_lower2: "A \<inter> B \<subseteq> B"
  1016   by blast
  1019   by (fact inf_le2)
  1017 
  1020 
  1018 lemma Int_greatest: "C \<subseteq> A ==> C \<subseteq> B ==> C \<subseteq> A \<inter> B"
  1021 lemma Int_greatest: "C \<subseteq> A ==> C \<subseteq> B ==> C \<subseteq> A \<inter> B"
  1019   by blast
  1022   by (fact inf_greatest)
  1020 
  1023 
  1021 
  1024 
  1022 text {* \medskip Set difference. *}
  1025 text {* \medskip Set difference. *}
  1023 
  1026 
  1024 lemma Diff_subset: "A - B \<subseteq> A"
  1027 lemma Diff_subset: "A - B \<subseteq> A"
  1096   by auto
  1099   by auto
  1097 
  1100 
  1098 lemma insert_inter_insert[simp]: "insert a A \<inter> insert a B = insert a (A \<inter> B)"
  1101 lemma insert_inter_insert[simp]: "insert a A \<inter> insert a B = insert a (A \<inter> B)"
  1099   by blast
  1102   by blast
  1100 
  1103 
  1101 lemma insert_disjoint [simp,noatp]:
  1104 lemma insert_disjoint [simp,no_atp]:
  1102  "(insert a A \<inter> B = {}) = (a \<notin> B \<and> A \<inter> B = {})"
  1105  "(insert a A \<inter> B = {}) = (a \<notin> B \<and> A \<inter> B = {})"
  1103  "({} = 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)"
  1104   by auto
  1107   by auto
  1105 
  1108 
  1106 lemma disjoint_insert [simp,noatp]:
  1109 lemma disjoint_insert [simp,no_atp]:
  1107  "(B \<inter> insert a A = {}) = (a \<notin> B \<and> B \<inter> A = {})"
  1110  "(B \<inter> insert a A = {}) = (a \<notin> B \<and> B \<inter> A = {})"
  1108  "({} = A \<inter> insert b B) = (b \<notin> A \<and> {} = A \<inter> B)"
  1111  "({} = A \<inter> insert b B) = (b \<notin> A \<and> {} = A \<inter> B)"
  1109   by auto
  1112   by auto
  1110 
  1113 
  1111 text {* \medskip @{text image}. *}
  1114 text {* \medskip @{text image}. *}
  1133 
  1136 
  1134 lemma empty_is_image[iff]: "({} = f ` A) = (A = {})"
  1137 lemma empty_is_image[iff]: "({} = f ` A) = (A = {})"
  1135 by blast
  1138 by blast
  1136 
  1139 
  1137 
  1140 
  1138 lemma image_Collect [noatp]: "f ` {x. P x} = {f x | x. P x}"
  1141 lemma image_Collect [no_atp]: "f ` {x. P x} = {f x | x. P x}"
  1139   -- {* NOT suitable as a default simprule: the RHS isn't simpler than the LHS,
  1142   -- {* NOT suitable as a default simprule: the RHS isn't simpler than the LHS,
  1140       with its implicit quantifier and conjunction.  Also image enjoys better
  1143       with its implicit quantifier and conjunction.  Also image enjoys better
  1141       equational properties than does the RHS. *}
  1144       equational properties than does the RHS. *}
  1142   by blast
  1145   by blast
  1143 
  1146 
  1150   by (simp add: image_def)
  1153   by (simp add: image_def)
  1151 
  1154 
  1152 
  1155 
  1153 text {* \medskip @{text range}. *}
  1156 text {* \medskip @{text range}. *}
  1154 
  1157 
  1155 lemma full_SetCompr_eq [noatp]: "{u. \<exists>x. u = f x} = range f"
  1158 lemma full_SetCompr_eq [no_atp]: "{u. \<exists>x. u = f x} = range f"
  1156   by auto
  1159   by auto
  1157 
  1160 
  1158 lemma range_composition: "range (\<lambda>x. f (g x)) = f`range g"
  1161 lemma range_composition: "range (\<lambda>x. f (g x)) = f`range g"
  1159 by (subst image_image, simp)
  1162 by (subst image_image, simp)
  1160 
  1163 
  1161 
  1164 
  1162 text {* \medskip @{text Int} *}
  1165 text {* \medskip @{text Int} *}
  1163 
  1166 
  1164 lemma Int_absorb [simp]: "A \<inter> A = A"
  1167 lemma Int_absorb [simp]: "A \<inter> A = A"
  1165   by blast
  1168   by (fact inf_idem)
  1166 
  1169 
  1167 lemma Int_left_absorb: "A \<inter> (A \<inter> B) = A \<inter> B"
  1170 lemma Int_left_absorb: "A \<inter> (A \<inter> B) = A \<inter> B"
  1168   by blast
  1171   by (fact inf_left_idem)
  1169 
  1172 
  1170 lemma Int_commute: "A \<inter> B = B \<inter> A"
  1173 lemma Int_commute: "A \<inter> B = B \<inter> A"
  1171   by blast
  1174   by (fact inf_commute)
  1172 
  1175 
  1173 lemma Int_left_commute: "A \<inter> (B \<inter> C) = B \<inter> (A \<inter> C)"
  1176 lemma Int_left_commute: "A \<inter> (B \<inter> C) = B \<inter> (A \<inter> C)"
  1174   by blast
  1177   by (fact inf_left_commute)
  1175 
  1178 
  1176 lemma Int_assoc: "(A \<inter> B) \<inter> C = A \<inter> (B \<inter> C)"
  1179 lemma Int_assoc: "(A \<inter> B) \<inter> C = A \<inter> (B \<inter> C)"
  1177   by blast
  1180   by (fact inf_assoc)
  1178 
  1181 
  1179 lemmas Int_ac = Int_assoc Int_left_absorb Int_commute Int_left_commute
  1182 lemmas Int_ac = Int_assoc Int_left_absorb Int_commute Int_left_commute
  1180   -- {* Intersection is an AC-operator *}
  1183   -- {* Intersection is an AC-operator *}
  1181 
  1184 
  1182 lemma Int_absorb1: "B \<subseteq> A ==> A \<inter> B = B"
  1185 lemma Int_absorb1: "B \<subseteq> A ==> A \<inter> B = B"
  1183   by blast
  1186   by (fact inf_absorb2)
  1184 
  1187 
  1185 lemma Int_absorb2: "A \<subseteq> B ==> A \<inter> B = A"
  1188 lemma Int_absorb2: "A \<subseteq> B ==> A \<inter> B = A"
  1186   by blast
  1189   by (fact inf_absorb1)
  1187 
  1190 
  1188 lemma Int_empty_left [simp]: "{} \<inter> B = {}"
  1191 lemma Int_empty_left [simp]: "{} \<inter> B = {}"
  1189   by blast
  1192   by (fact inf_bot_left)
  1190 
  1193 
  1191 lemma Int_empty_right [simp]: "A \<inter> {} = {}"
  1194 lemma Int_empty_right [simp]: "A \<inter> {} = {}"
  1192   by blast
  1195   by (fact inf_bot_right)
  1193 
  1196 
  1194 lemma disjoint_eq_subset_Compl: "(A \<inter> B = {}) = (A \<subseteq> -B)"
  1197 lemma disjoint_eq_subset_Compl: "(A \<inter> B = {}) = (A \<subseteq> -B)"
  1195   by blast
  1198   by blast
  1196 
  1199 
  1197 lemma disjoint_iff_not_equal: "(A \<inter> B = {}) = (\<forall>x\<in>A. \<forall>y\<in>B. x \<noteq> y)"
  1200 lemma disjoint_iff_not_equal: "(A \<inter> B = {}) = (\<forall>x\<in>A. \<forall>y\<in>B. x \<noteq> y)"
  1198   by blast
  1201   by blast
  1199 
  1202 
  1200 lemma Int_UNIV_left [simp]: "UNIV \<inter> B = B"
  1203 lemma Int_UNIV_left [simp]: "UNIV \<inter> B = B"
  1201   by blast
  1204   by (fact inf_top_left)
  1202 
  1205 
  1203 lemma Int_UNIV_right [simp]: "A \<inter> UNIV = A"
  1206 lemma Int_UNIV_right [simp]: "A \<inter> UNIV = A"
  1204   by blast
  1207   by (fact inf_top_right)
  1205 
  1208 
  1206 lemma Int_Un_distrib: "A \<inter> (B \<union> C) = (A \<inter> B) \<union> (A \<inter> C)"
  1209 lemma Int_Un_distrib: "A \<inter> (B \<union> C) = (A \<inter> B) \<union> (A \<inter> C)"
  1207   by blast
  1210   by (fact inf_sup_distrib1)
  1208 
  1211 
  1209 lemma Int_Un_distrib2: "(B \<union> C) \<inter> A = (B \<inter> A) \<union> (C \<inter> A)"
  1212 lemma Int_Un_distrib2: "(B \<union> C) \<inter> A = (B \<inter> A) \<union> (C \<inter> A)"
  1210   by blast
  1213   by (fact inf_sup_distrib2)
  1211 
  1214 
  1212 lemma Int_UNIV [simp,noatp]: "(A \<inter> B = UNIV) = (A = UNIV & B = UNIV)"
  1215 lemma Int_UNIV [simp,no_atp]: "(A \<inter> B = UNIV) = (A = UNIV & B = UNIV)"
  1213   by blast
  1216   by (fact inf_eq_top_iff)
  1214 
  1217 
  1215 lemma Int_subset_iff [simp]: "(C \<subseteq> A \<inter> B) = (C \<subseteq> A & C \<subseteq> B)"
  1218 lemma Int_subset_iff [simp]: "(C \<subseteq> A \<inter> B) = (C \<subseteq> A & C \<subseteq> B)"
  1216   by blast
  1219   by (fact le_inf_iff)
  1217 
  1220 
  1218 lemma Int_Collect: "(x \<in> A \<inter> {x. P x}) = (x \<in> A & P x)"
  1221 lemma Int_Collect: "(x \<in> A \<inter> {x. P x}) = (x \<in> A & P x)"
  1219   by blast
  1222   by blast
  1220 
  1223 
  1221 
  1224 
  1222 text {* \medskip @{text Un}. *}
  1225 text {* \medskip @{text Un}. *}
  1223 
  1226 
  1224 lemma Un_absorb [simp]: "A \<union> A = A"
  1227 lemma Un_absorb [simp]: "A \<union> A = A"
  1225   by blast
  1228   by (fact sup_idem)
  1226 
  1229 
  1227 lemma Un_left_absorb: "A \<union> (A \<union> B) = A \<union> B"
  1230 lemma Un_left_absorb: "A \<union> (A \<union> B) = A \<union> B"
  1228   by blast
  1231   by (fact sup_left_idem)
  1229 
  1232 
  1230 lemma Un_commute: "A \<union> B = B \<union> A"
  1233 lemma Un_commute: "A \<union> B = B \<union> A"
  1231   by blast
  1234   by (fact sup_commute)
  1232 
  1235 
  1233 lemma Un_left_commute: "A \<union> (B \<union> C) = B \<union> (A \<union> C)"
  1236 lemma Un_left_commute: "A \<union> (B \<union> C) = B \<union> (A \<union> C)"
  1234   by blast
  1237   by (fact sup_left_commute)
  1235 
  1238 
  1236 lemma Un_assoc: "(A \<union> B) \<union> C = A \<union> (B \<union> C)"
  1239 lemma Un_assoc: "(A \<union> B) \<union> C = A \<union> (B \<union> C)"
  1237   by blast
  1240   by (fact sup_assoc)
  1238 
  1241 
  1239 lemmas Un_ac = Un_assoc Un_left_absorb Un_commute Un_left_commute
  1242 lemmas Un_ac = Un_assoc Un_left_absorb Un_commute Un_left_commute
  1240   -- {* Union is an AC-operator *}
  1243   -- {* Union is an AC-operator *}
  1241 
  1244 
  1242 lemma Un_absorb1: "A \<subseteq> B ==> A \<union> B = B"
  1245 lemma Un_absorb1: "A \<subseteq> B ==> A \<union> B = B"
  1243   by blast
  1246   by (fact sup_absorb2)
  1244 
  1247 
  1245 lemma Un_absorb2: "B \<subseteq> A ==> A \<union> B = A"
  1248 lemma Un_absorb2: "B \<subseteq> A ==> A \<union> B = A"
  1246   by blast
  1249   by (fact sup_absorb1)
  1247 
  1250 
  1248 lemma Un_empty_left [simp]: "{} \<union> B = B"
  1251 lemma Un_empty_left [simp]: "{} \<union> B = B"
  1249   by blast
  1252   by (fact sup_bot_left)
  1250 
  1253 
  1251 lemma Un_empty_right [simp]: "A \<union> {} = A"
  1254 lemma Un_empty_right [simp]: "A \<union> {} = A"
  1252   by blast
  1255   by (fact sup_bot_right)
  1253 
  1256 
  1254 lemma Un_UNIV_left [simp]: "UNIV \<union> B = UNIV"
  1257 lemma Un_UNIV_left [simp]: "UNIV \<union> B = UNIV"
  1255   by blast
  1258   by (fact sup_top_left)
  1256 
  1259 
  1257 lemma Un_UNIV_right [simp]: "A \<union> UNIV = UNIV"
  1260 lemma Un_UNIV_right [simp]: "A \<union> UNIV = UNIV"
  1258   by blast
  1261   by (fact sup_top_right)
  1259 
  1262 
  1260 lemma Un_insert_left [simp]: "(insert a B) \<union> C = insert a (B \<union> C)"
  1263 lemma Un_insert_left [simp]: "(insert a B) \<union> C = insert a (B \<union> C)"
  1261   by blast
  1264   by blast
  1262 
  1265 
  1263 lemma Un_insert_right [simp]: "A \<union> (insert a B) = insert a (A \<union> B)"
  1266 lemma Un_insert_right [simp]: "A \<union> (insert a B) = insert a (A \<union> B)"
  1286 lemma Int_insert_right_if1[simp]:
  1289 lemma Int_insert_right_if1[simp]:
  1287     "a \<in> A \<Longrightarrow> A Int (insert a B) = insert a (A Int B)"
  1290     "a \<in> A \<Longrightarrow> A Int (insert a B) = insert a (A Int B)"
  1288   by auto
  1291   by auto
  1289 
  1292 
  1290 lemma Un_Int_distrib: "A \<union> (B \<inter> C) = (A \<union> B) \<inter> (A \<union> C)"
  1293 lemma Un_Int_distrib: "A \<union> (B \<inter> C) = (A \<union> B) \<inter> (A \<union> C)"
  1291   by blast
  1294   by (fact sup_inf_distrib1)
  1292 
  1295 
  1293 lemma Un_Int_distrib2: "(B \<inter> C) \<union> A = (B \<union> A) \<inter> (C \<union> A)"
  1296 lemma Un_Int_distrib2: "(B \<inter> C) \<union> A = (B \<union> A) \<inter> (C \<union> A)"
  1294   by blast
  1297   by (fact sup_inf_distrib2)
  1295 
  1298 
  1296 lemma Un_Int_crazy:
  1299 lemma Un_Int_crazy:
  1297     "(A \<inter> B) \<union> (B \<inter> C) \<union> (C \<inter> A) = (A \<union> B) \<inter> (B \<union> C) \<inter> (C \<union> A)"
  1300     "(A \<inter> B) \<union> (B \<inter> C) \<union> (C \<inter> A) = (A \<union> B) \<inter> (B \<union> C) \<inter> (C \<union> A)"
  1298   by blast
  1301   by blast
  1299 
  1302 
  1300 lemma subset_Un_eq: "(A \<subseteq> B) = (A \<union> B = B)"
  1303 lemma subset_Un_eq: "(A \<subseteq> B) = (A \<union> B = B)"
  1301   by blast
  1304   by (fact le_iff_sup)
  1302 
  1305 
  1303 lemma Un_empty [iff]: "(A \<union> B = {}) = (A = {} & B = {})"
  1306 lemma Un_empty [iff]: "(A \<union> B = {}) = (A = {} & B = {})"
  1304   by blast
  1307   by (fact sup_eq_bot_iff)
  1305 
  1308 
  1306 lemma Un_subset_iff [simp]: "(A \<union> B \<subseteq> C) = (A \<subseteq> C & B \<subseteq> C)"
  1309 lemma Un_subset_iff [simp]: "(A \<union> B \<subseteq> C) = (A \<subseteq> C & B \<subseteq> C)"
  1307   by blast
  1310   by (fact le_sup_iff)
  1308 
  1311 
  1309 lemma Un_Diff_Int: "(A - B) \<union> (A \<inter> B) = A"
  1312 lemma Un_Diff_Int: "(A - B) \<union> (A \<inter> B) = A"
  1310   by blast
  1313   by blast
  1311 
  1314 
  1312 lemma Diff_Int2: "A \<inter> C - B \<inter> C = A \<inter> C - B"
  1315 lemma Diff_Int2: "A \<inter> C - B \<inter> C = A \<inter> C - B"
  1314 
  1317 
  1315 
  1318 
  1316 text {* \medskip Set complement *}
  1319 text {* \medskip Set complement *}
  1317 
  1320 
  1318 lemma Compl_disjoint [simp]: "A \<inter> -A = {}"
  1321 lemma Compl_disjoint [simp]: "A \<inter> -A = {}"
  1319   by blast
  1322   by (fact inf_compl_bot)
  1320 
  1323 
  1321 lemma Compl_disjoint2 [simp]: "-A \<inter> A = {}"
  1324 lemma Compl_disjoint2 [simp]: "-A \<inter> A = {}"
  1322   by blast
  1325   by (fact compl_inf_bot)
  1323 
  1326 
  1324 lemma Compl_partition: "A \<union> -A = UNIV"
  1327 lemma Compl_partition: "A \<union> -A = UNIV"
  1325   by blast
  1328   by (fact sup_compl_top)
  1326 
  1329 
  1327 lemma Compl_partition2: "-A \<union> A = UNIV"
  1330 lemma Compl_partition2: "-A \<union> A = UNIV"
  1328   by blast
  1331   by (fact compl_sup_top)
  1329 
  1332 
  1330 lemma double_complement [simp]: "- (-A) = (A::'a set)"
  1333 lemma double_complement [simp]: "- (-A) = (A::'a set)"
  1331   by blast
  1334   by (fact double_compl)
  1332 
  1335 
  1333 lemma Compl_Un [simp]: "-(A \<union> B) = (-A) \<inter> (-B)"
  1336 lemma Compl_Un [simp]: "-(A \<union> B) = (-A) \<inter> (-B)"
  1334   by blast
  1337   by (fact compl_sup)
  1335 
  1338 
  1336 lemma Compl_Int [simp]: "-(A \<inter> B) = (-A) \<union> (-B)"
  1339 lemma Compl_Int [simp]: "-(A \<inter> B) = (-A) \<union> (-B)"
  1337   by blast
  1340   by (fact compl_inf)
  1338 
  1341 
  1339 lemma subset_Compl_self_eq: "(A \<subseteq> -A) = (A = {})"
  1342 lemma subset_Compl_self_eq: "(A \<subseteq> -A) = (A = {})"
  1340   by blast
  1343   by blast
  1341 
  1344 
  1342 lemma Un_Int_assoc_eq: "((A \<inter> B) \<union> C = A \<inter> (B \<union> C)) = (C \<subseteq> A)"
  1345 lemma Un_Int_assoc_eq: "((A \<inter> B) \<union> C = A \<inter> (B \<union> C)) = (C \<subseteq> A)"
  1343   -- {* Halmos, Naive Set Theory, page 16. *}
  1346   -- {* Halmos, Naive Set Theory, page 16. *}
  1344   by blast
  1347   by blast
  1345 
  1348 
  1346 lemma Compl_UNIV_eq [simp]: "-UNIV = {}"
  1349 lemma Compl_UNIV_eq [simp]: "-UNIV = {}"
  1347   by blast
  1350   by (fact compl_top_eq)
  1348 
  1351 
  1349 lemma Compl_empty_eq [simp]: "-{} = UNIV"
  1352 lemma Compl_empty_eq [simp]: "-{} = UNIV"
  1350   by blast
  1353   by (fact compl_bot_eq)
  1351 
  1354 
  1352 lemma Compl_subset_Compl_iff [iff]: "(-A \<subseteq> -B) = (B \<subseteq> A)"
  1355 lemma Compl_subset_Compl_iff [iff]: "(-A \<subseteq> -B) = (B \<subseteq> A)"
  1353   by blast
  1356   by (fact compl_le_compl_iff)
  1354 
  1357 
  1355 lemma Compl_eq_Compl_iff [iff]: "(-A = -B) = (A = (B::'a set))"
  1358 lemma Compl_eq_Compl_iff [iff]: "(-A = -B) = (A = (B::'a set))"
  1356   by blast
  1359   by (fact compl_eq_compl_iff)
  1357 
  1360 
  1358 text {* \medskip Bounded quantifiers.
  1361 text {* \medskip Bounded quantifiers.
  1359 
  1362 
  1360   The following are not added to the default simpset because
  1363   The following are not added to the default simpset because
  1361   (a) they duplicate the body and (b) there are no similar rules for @{text Int}. *}
  1364   (a) they duplicate the body and (b) there are no similar rules for @{text Int}. *}
  1370 text {* \medskip Set difference. *}
  1373 text {* \medskip Set difference. *}
  1371 
  1374 
  1372 lemma Diff_eq: "A - B = A \<inter> (-B)"
  1375 lemma Diff_eq: "A - B = A \<inter> (-B)"
  1373   by blast
  1376   by blast
  1374 
  1377 
  1375 lemma Diff_eq_empty_iff [simp,noatp]: "(A - B = {}) = (A \<subseteq> B)"
  1378 lemma Diff_eq_empty_iff [simp,no_atp]: "(A - B = {}) = (A \<subseteq> B)"
  1376   by blast
  1379   by blast
  1377 
  1380 
  1378 lemma Diff_cancel [simp]: "A - A = {}"
  1381 lemma Diff_cancel [simp]: "A - A = {}"
  1379   by blast
  1382   by blast
  1380 
  1383 
  1391   by blast
  1394   by blast
  1392 
  1395 
  1393 lemma Diff_UNIV [simp]: "A - UNIV = {}"
  1396 lemma Diff_UNIV [simp]: "A - UNIV = {}"
  1394   by blast
  1397   by blast
  1395 
  1398 
  1396 lemma Diff_insert0 [simp,noatp]: "x \<notin> A ==> A - insert x B = A - B"
  1399 lemma Diff_insert0 [simp,no_atp]: "x \<notin> A ==> A - insert x B = A - B"
  1397   by blast
  1400   by blast
  1398 
  1401 
  1399 lemma Diff_insert: "A - insert a B = A - B - {a}"
  1402 lemma Diff_insert: "A - insert a B = A - B - {a}"
  1400   -- {* NOT SUITABLE FOR REWRITING since @{text "{a} == insert a 0"} *}
  1403   -- {* NOT SUITABLE FOR REWRITING since @{text "{a} == insert a 0"} *}
  1401   by blast
  1404   by blast
  1525 
  1528 
  1526 lemma insert_mono: "C \<subseteq> D ==> insert a C \<subseteq> insert a D"
  1529 lemma insert_mono: "C \<subseteq> D ==> insert a C \<subseteq> insert a D"
  1527   by blast
  1530   by blast
  1528 
  1531 
  1529 lemma Un_mono: "A \<subseteq> C ==> B \<subseteq> D ==> A \<union> B \<subseteq> C \<union> D"
  1532 lemma Un_mono: "A \<subseteq> C ==> B \<subseteq> D ==> A \<union> B \<subseteq> C \<union> D"
  1530   by blast
  1533   by (fact sup_mono)
  1531 
  1534 
  1532 lemma Int_mono: "A \<subseteq> C ==> B \<subseteq> D ==> A \<inter> B \<subseteq> C \<inter> D"
  1535 lemma Int_mono: "A \<subseteq> C ==> B \<subseteq> D ==> A \<inter> B \<subseteq> C \<inter> D"
  1533   by blast
  1536   by (fact inf_mono)
  1534 
  1537 
  1535 lemma Diff_mono: "A \<subseteq> C ==> D \<subseteq> B ==> A - B \<subseteq> C - D"
  1538 lemma Diff_mono: "A \<subseteq> C ==> D \<subseteq> B ==> A - B \<subseteq> C - D"
  1536   by blast
  1539   by blast
  1537 
  1540 
  1538 lemma Compl_anti_mono: "A \<subseteq> B ==> -B \<subseteq> -A"
  1541 lemma Compl_anti_mono: "A \<subseteq> B ==> -B \<subseteq> -A"
  1539   by blast
  1542   by (fact compl_mono)
  1540 
  1543 
  1541 text {* \medskip Monotonicity of implications. *}
  1544 text {* \medskip Monotonicity of implications. *}
  1542 
  1545 
  1543 lemma in_mono: "A \<subseteq> B ==> x \<in> A --> x \<in> B"
  1546 lemma in_mono: "A \<subseteq> B ==> x \<in> A --> x \<in> B"
  1544   apply (rule impI)
  1547   apply (rule impI)
  1580   by iprover
  1583   by iprover
  1581 
  1584 
  1582 
  1585 
  1583 subsubsection {* Inverse image of a function *}
  1586 subsubsection {* Inverse image of a function *}
  1584 
  1587 
  1585 constdefs
  1588 definition vimage :: "('a => 'b) => 'b set => 'a set" (infixr "-`" 90) where
  1586   vimage :: "('a => 'b) => 'b set => 'a set"    (infixr "-`" 90)
       
  1587   [code del]: "f -` B == {x. f x : B}"
  1589   [code del]: "f -` B == {x. f x : B}"
  1588 
  1590 
  1589 lemma vimage_eq [simp]: "(a : f -` B) = (f a : B)"
  1591 lemma vimage_eq [simp]: "(a : f -` B) = (f a : B)"
  1590   by (unfold vimage_def) blast
  1592   by (unfold vimage_def) blast
  1591 
  1593 
  1634 
  1636 
  1635 lemma vimage_mono: "A \<subseteq> B ==> f -` A \<subseteq> f -` B"
  1637 lemma vimage_mono: "A \<subseteq> B ==> f -` A \<subseteq> f -` B"
  1636   -- {* monotonicity *}
  1638   -- {* monotonicity *}
  1637   by blast
  1639   by blast
  1638 
  1640 
  1639 lemma vimage_image_eq [noatp]: "f -` (f ` A) = {y. EX x:A. f x = f y}"
  1641 lemma vimage_image_eq [no_atp]: "f -` (f ` A) = {y. EX x:A. f x = f y}"
  1640 by (blast intro: sym)
  1642 by (blast intro: sym)
  1641 
  1643 
  1642 lemma image_vimage_subset: "f ` (f -` A) <= A"
  1644 lemma image_vimage_subset: "f ` (f -` A) <= A"
  1643 by blast
  1645 by blast
  1644 
  1646 
  1650 
  1652 
  1651 lemma vimage_if [simp]: "((\<lambda>x. if x \<in> B then c else d) -` A) = 
  1653 lemma vimage_if [simp]: "((\<lambda>x. if x \<in> B then c else d) -` A) = 
  1652    (if c \<in> A then (if d \<in> A then UNIV else B)
  1654    (if c \<in> A then (if d \<in> A then UNIV else B)
  1653     else if d \<in> A then -B else {})"  
  1655     else if d \<in> A then -B else {})"  
  1654   by (auto simp add: vimage_def) 
  1656   by (auto simp add: vimage_def) 
       
  1657 
       
  1658 lemma vimage_inter_cong:
       
  1659   "(\<And> w. w \<in> S \<Longrightarrow> f w = g w) \<Longrightarrow> f -` y \<inter> S = g -` y \<inter> S"
       
  1660   by auto
  1655 
  1661 
  1656 lemma image_Int_subset: "f`(A Int B) <= f`A Int f`B"
  1662 lemma image_Int_subset: "f`(A Int B) <= f`A Int f`B"
  1657 by blast
  1663 by blast
  1658 
  1664 
  1659 lemma image_diff_subset: "f`A - f`B <= f`(A - B)"
  1665 lemma image_diff_subset: "f`A - f`B <= f`(A - B)"