| 13586 |      1 | (*  Title:      HOL/Library/FuncSet.thy
 | 
|  |      2 |     ID:         $Id$
 | 
|  |      3 |     Author:     Florian Kammueller and Lawrence C Paulson
 | 
|  |      4 | *)
 | 
|  |      5 | 
 | 
| 14706 |      6 | header {* Pi and Function Sets *}
 | 
| 13586 |      7 | 
 | 
| 15131 |      8 | theory FuncSet
 | 
| 15140 |      9 | imports Main
 | 
| 15131 |     10 | begin
 | 
| 13586 |     11 | 
 | 
|  |     12 | constdefs
 | 
| 14706 |     13 |   Pi :: "['a set, 'a => 'b set] => ('a => 'b) set"
 | 
|  |     14 |   "Pi A B == {f. \<forall>x. x \<in> A --> f x \<in> B x}"
 | 
| 13586 |     15 | 
 | 
|  |     16 |   extensional :: "'a set => ('a => 'b) set"
 | 
| 14706 |     17 |   "extensional A == {f. \<forall>x. x~:A --> f x = arbitrary}"
 | 
| 13586 |     18 | 
 | 
| 14706 |     19 |   "restrict" :: "['a => 'b, 'a set] => ('a => 'b)"
 | 
|  |     20 |   "restrict f A == (%x. if x \<in> A then f x else arbitrary)"
 | 
| 13586 |     21 | 
 | 
|  |     22 | syntax
 | 
|  |     23 |   "@Pi"  :: "[pttrn, 'a set, 'b set] => ('a => 'b) set"  ("(3PI _:_./ _)" 10)
 | 
|  |     24 |   funcset :: "['a set, 'b set] => ('a => 'b) set"      (infixr "->" 60)
 | 
|  |     25 |   "@lam" :: "[pttrn, 'a set, 'a => 'b] => ('a=>'b)"  ("(3%_:_./ _)" [0,0,3] 3)
 | 
|  |     26 | 
 | 
|  |     27 | syntax (xsymbols)
 | 
|  |     28 |   "@Pi" :: "[pttrn, 'a set, 'b set] => ('a => 'b) set"  ("(3\<Pi> _\<in>_./ _)"   10)
 | 
| 14706 |     29 |   funcset :: "['a set, 'b set] => ('a => 'b) set"  (infixr "\<rightarrow>" 60)
 | 
| 13586 |     30 |   "@lam" :: "[pttrn, 'a set, 'a => 'b] => ('a=>'b)"  ("(3\<lambda>_\<in>_./ _)" [0,0,3] 3)
 | 
|  |     31 | 
 | 
| 14565 |     32 | syntax (HTML output)
 | 
|  |     33 |   "@Pi" :: "[pttrn, 'a set, 'b set] => ('a => 'b) set"  ("(3\<Pi> _\<in>_./ _)"   10)
 | 
|  |     34 |   "@lam" :: "[pttrn, 'a set, 'a => 'b] => ('a=>'b)"  ("(3\<lambda>_\<in>_./ _)" [0,0,3] 3)
 | 
|  |     35 | 
 | 
| 13586 |     36 | translations
 | 
|  |     37 |   "PI x:A. B" => "Pi A (%x. B)"
 | 
| 17781 |     38 |   "A -> B" => "Pi A (%_. B)"
 | 
| 14706 |     39 |   "%x:A. f" == "restrict (%x. f) A"
 | 
| 13586 |     40 | 
 | 
|  |     41 | constdefs
 | 
| 14706 |     42 |   "compose" :: "['a set, 'b => 'c, 'a => 'b] => ('a => 'c)"
 | 
| 13586 |     43 |   "compose A g f == \<lambda>x\<in>A. g (f x)"
 | 
|  |     44 | 
 | 
| 13595 |     45 | print_translation {* [("Pi", dependent_tr' ("@Pi", "funcset"))] *}
 | 
| 13586 |     46 | 
 | 
|  |     47 | 
 | 
|  |     48 | subsection{*Basic Properties of @{term Pi}*}
 | 
|  |     49 | 
 | 
|  |     50 | lemma Pi_I: "(!!x. x \<in> A ==> f x \<in> B x) ==> f \<in> Pi A B"
 | 
| 14706 |     51 |   by (simp add: Pi_def)
 | 
| 13586 |     52 | 
 | 
|  |     53 | lemma funcsetI: "(!!x. x \<in> A ==> f x \<in> B) ==> f \<in> A -> B"
 | 
| 14706 |     54 |   by (simp add: Pi_def)
 | 
| 13586 |     55 | 
 | 
|  |     56 | lemma Pi_mem: "[|f: Pi A B; x \<in> A|] ==> f x \<in> B x"
 | 
| 14706 |     57 |   by (simp add: Pi_def)
 | 
| 13586 |     58 | 
 | 
|  |     59 | lemma funcset_mem: "[|f \<in> A -> B; x \<in> A|] ==> f x \<in> B"
 | 
| 14706 |     60 |   by (simp add: Pi_def)
 | 
| 13586 |     61 | 
 | 
| 14762 |     62 | lemma funcset_image: "f \<in> A\<rightarrow>B ==> f ` A \<subseteq> B"
 | 
|  |     63 | by (auto simp add: Pi_def)
 | 
|  |     64 | 
 | 
| 13586 |     65 | lemma Pi_eq_empty: "((PI x: A. B x) = {}) = (\<exists>x\<in>A. B(x) = {})"
 | 
| 13593 |     66 | apply (simp add: Pi_def, auto)
 | 
| 13586 |     67 | txt{*Converse direction requires Axiom of Choice to exhibit a function
 | 
|  |     68 | picking an element from each non-empty @{term "B x"}*}
 | 
| 13593 |     69 | apply (drule_tac x = "%u. SOME y. y \<in> B u" in spec, auto)
 | 
| 14706 |     70 | apply (cut_tac P= "%y. y \<in> B x" in some_eq_ex, auto)
 | 
| 13586 |     71 | done
 | 
|  |     72 | 
 | 
| 13593 |     73 | lemma Pi_empty [simp]: "Pi {} B = UNIV"
 | 
| 14706 |     74 |   by (simp add: Pi_def)
 | 
| 13593 |     75 | 
 | 
|  |     76 | lemma Pi_UNIV [simp]: "A -> UNIV = UNIV"
 | 
| 14706 |     77 |   by (simp add: Pi_def)
 | 
| 13586 |     78 | 
 | 
|  |     79 | text{*Covariance of Pi-sets in their second argument*}
 | 
|  |     80 | lemma Pi_mono: "(!!x. x \<in> A ==> B x <= C x) ==> Pi A B <= Pi A C"
 | 
| 14706 |     81 |   by (simp add: Pi_def, blast)
 | 
| 13586 |     82 | 
 | 
|  |     83 | text{*Contravariance of Pi-sets in their first argument*}
 | 
|  |     84 | lemma Pi_anti_mono: "A' <= A ==> Pi A B <= Pi A' B"
 | 
| 14706 |     85 |   by (simp add: Pi_def, blast)
 | 
| 13586 |     86 | 
 | 
|  |     87 | 
 | 
|  |     88 | subsection{*Composition With a Restricted Domain: @{term compose}*}
 | 
|  |     89 | 
 | 
| 14706 |     90 | lemma funcset_compose:
 | 
|  |     91 |     "[| f \<in> A -> B; g \<in> B -> C |]==> compose A g f \<in> A -> C"
 | 
|  |     92 |   by (simp add: Pi_def compose_def restrict_def)
 | 
| 13586 |     93 | 
 | 
|  |     94 | lemma compose_assoc:
 | 
| 14706 |     95 |     "[| f \<in> A -> B; g \<in> B -> C; h \<in> C -> D |]
 | 
| 13586 |     96 |       ==> compose A h (compose A g f) = compose A (compose B h g) f"
 | 
| 14706 |     97 |   by (simp add: expand_fun_eq Pi_def compose_def restrict_def)
 | 
| 13586 |     98 | 
 | 
|  |     99 | lemma compose_eq: "x \<in> A ==> compose A g f x = g(f(x))"
 | 
| 14706 |    100 |   by (simp add: compose_def restrict_def)
 | 
| 13586 |    101 | 
 | 
|  |    102 | lemma surj_compose: "[| f ` A = B; g ` B = C |] ==> compose A g f ` A = C"
 | 
| 14706 |    103 |   by (auto simp add: image_def compose_eq)
 | 
| 13586 |    104 | 
 | 
|  |    105 | 
 | 
|  |    106 | subsection{*Bounded Abstraction: @{term restrict}*}
 | 
|  |    107 | 
 | 
|  |    108 | lemma restrict_in_funcset: "(!!x. x \<in> A ==> f x \<in> B) ==> (\<lambda>x\<in>A. f x) \<in> A -> B"
 | 
| 14706 |    109 |   by (simp add: Pi_def restrict_def)
 | 
| 13586 |    110 | 
 | 
|  |    111 | lemma restrictI: "(!!x. x \<in> A ==> f x \<in> B x) ==> (\<lambda>x\<in>A. f x) \<in> Pi A B"
 | 
| 14706 |    112 |   by (simp add: Pi_def restrict_def)
 | 
| 13586 |    113 | 
 | 
|  |    114 | lemma restrict_apply [simp]:
 | 
| 14706 |    115 |     "(\<lambda>y\<in>A. f y) x = (if x \<in> A then f x else arbitrary)"
 | 
|  |    116 |   by (simp add: restrict_def)
 | 
| 13586 |    117 | 
 | 
| 14706 |    118 | lemma restrict_ext:
 | 
| 13586 |    119 |     "(!!x. x \<in> A ==> f x = g x) ==> (\<lambda>x\<in>A. f x) = (\<lambda>x\<in>A. g x)"
 | 
| 14706 |    120 |   by (simp add: expand_fun_eq Pi_def Pi_def restrict_def)
 | 
| 13586 |    121 | 
 | 
| 14853 |    122 | lemma inj_on_restrict_eq [simp]: "inj_on (restrict f A) A = inj_on f A"
 | 
| 14706 |    123 |   by (simp add: inj_on_def restrict_def)
 | 
| 13586 |    124 | 
 | 
|  |    125 | lemma Id_compose:
 | 
| 14706 |    126 |     "[|f \<in> A -> B;  f \<in> extensional A|] ==> compose A (\<lambda>y\<in>B. y) f = f"
 | 
|  |    127 |   by (auto simp add: expand_fun_eq compose_def extensional_def Pi_def)
 | 
| 13586 |    128 | 
 | 
|  |    129 | lemma compose_Id:
 | 
| 14706 |    130 |     "[|g \<in> A -> B;  g \<in> extensional A|] ==> compose A g (\<lambda>x\<in>A. x) = g"
 | 
|  |    131 |   by (auto simp add: expand_fun_eq compose_def extensional_def Pi_def)
 | 
| 13586 |    132 | 
 | 
| 14853 |    133 | lemma image_restrict_eq [simp]: "(restrict f A) ` A = f ` A"
 | 
|  |    134 |   by (auto simp add: restrict_def) 
 | 
| 13586 |    135 | 
 | 
| 14745 |    136 | 
 | 
| 14762 |    137 | subsection{*Bijections Between Sets*}
 | 
|  |    138 | 
 | 
|  |    139 | text{*The basic definition could be moved to @{text "Fun.thy"}, but most of
 | 
|  |    140 | the theorems belong here, or need at least @{term Hilbert_Choice}.*}
 | 
|  |    141 | 
 | 
|  |    142 | constdefs
 | 
|  |    143 |   bij_betw :: "['a => 'b, 'a set, 'b set] => bool"         (*bijective*)
 | 
|  |    144 |     "bij_betw f A B == inj_on f A & f ` A = B"
 | 
|  |    145 | 
 | 
|  |    146 | lemma bij_betw_imp_inj_on: "bij_betw f A B \<Longrightarrow> inj_on f A"
 | 
|  |    147 | by (simp add: bij_betw_def)
 | 
|  |    148 | 
 | 
|  |    149 | lemma bij_betw_imp_funcset: "bij_betw f A B \<Longrightarrow> f \<in> A \<rightarrow> B"
 | 
|  |    150 | by (auto simp add: bij_betw_def inj_on_Inv Pi_def)
 | 
|  |    151 | 
 | 
|  |    152 | lemma bij_betw_Inv: "bij_betw f A B \<Longrightarrow> bij_betw (Inv A f) B A"
 | 
|  |    153 | apply (auto simp add: bij_betw_def inj_on_Inv Inv_mem) 
 | 
|  |    154 | apply (simp add: image_compose [symmetric] o_def) 
 | 
|  |    155 | apply (simp add: image_def Inv_f_f) 
 | 
|  |    156 | done
 | 
|  |    157 | 
 | 
| 14853 |    158 | lemma inj_on_compose:
 | 
|  |    159 |     "[| bij_betw f A B; inj_on g B |] ==> inj_on (compose A g f) A"
 | 
|  |    160 |   by (auto simp add: bij_betw_def inj_on_def compose_eq)
 | 
|  |    161 | 
 | 
| 14762 |    162 | lemma bij_betw_compose:
 | 
|  |    163 |     "[| bij_betw f A B; bij_betw g B C |] ==> bij_betw (compose A g f) A C"
 | 
|  |    164 | apply (simp add: bij_betw_def compose_eq inj_on_compose)
 | 
|  |    165 | apply (auto simp add: compose_def image_def)
 | 
|  |    166 | done
 | 
|  |    167 | 
 | 
| 14853 |    168 | lemma bij_betw_restrict_eq [simp]:
 | 
|  |    169 |      "bij_betw (restrict f A) A B = bij_betw f A B"
 | 
|  |    170 |   by (simp add: bij_betw_def)
 | 
|  |    171 | 
 | 
|  |    172 | 
 | 
|  |    173 | subsection{*Extensionality*}
 | 
|  |    174 | 
 | 
|  |    175 | lemma extensional_arb: "[|f \<in> extensional A; x\<notin> A|] ==> f x = arbitrary"
 | 
|  |    176 |   by (simp add: extensional_def)
 | 
|  |    177 | 
 | 
|  |    178 | lemma restrict_extensional [simp]: "restrict f A \<in> extensional A"
 | 
|  |    179 |   by (simp add: restrict_def extensional_def)
 | 
|  |    180 | 
 | 
|  |    181 | lemma compose_extensional [simp]: "compose A f g \<in> extensional A"
 | 
|  |    182 |   by (simp add: compose_def)
 | 
|  |    183 | 
 | 
|  |    184 | lemma extensionalityI:
 | 
|  |    185 |     "[| f \<in> extensional A; g \<in> extensional A;
 | 
|  |    186 |       !!x. x\<in>A ==> f x = g x |] ==> f = g"
 | 
|  |    187 |   by (force simp add: expand_fun_eq extensional_def)
 | 
|  |    188 | 
 | 
|  |    189 | lemma Inv_funcset: "f ` A = B ==> (\<lambda>x\<in>B. Inv A f x) : B -> A"
 | 
|  |    190 |   by (unfold Inv_def) (fast intro: restrict_in_funcset someI2)
 | 
|  |    191 | 
 | 
|  |    192 | lemma compose_Inv_id:
 | 
|  |    193 |     "bij_betw f A B ==> compose A (\<lambda>y\<in>B. Inv A f y) f = (\<lambda>x\<in>A. x)"
 | 
|  |    194 |   apply (simp add: bij_betw_def compose_def)
 | 
|  |    195 |   apply (rule restrict_ext, auto)
 | 
|  |    196 |   apply (erule subst)
 | 
|  |    197 |   apply (simp add: Inv_f_f)
 | 
|  |    198 |   done
 | 
|  |    199 | 
 | 
|  |    200 | lemma compose_id_Inv:
 | 
|  |    201 |     "f ` A = B ==> compose B f (\<lambda>y\<in>B. Inv A f y) = (\<lambda>x\<in>B. x)"
 | 
|  |    202 |   apply (simp add: compose_def)
 | 
|  |    203 |   apply (rule restrict_ext)
 | 
|  |    204 |   apply (simp add: f_Inv_f)
 | 
|  |    205 |   done
 | 
|  |    206 | 
 | 
| 14762 |    207 | 
 | 
| 14745 |    208 | subsection{*Cardinality*}
 | 
|  |    209 | 
 | 
|  |    210 | lemma card_inj: "[|f \<in> A\<rightarrow>B; inj_on f A; finite B|] ==> card(A) \<le> card(B)"
 | 
|  |    211 | apply (rule card_inj_on_le)
 | 
|  |    212 | apply (auto simp add: Pi_def)
 | 
|  |    213 | done
 | 
|  |    214 | 
 | 
|  |    215 | lemma card_bij:
 | 
|  |    216 |      "[|f \<in> A\<rightarrow>B; inj_on f A;
 | 
|  |    217 |         g \<in> B\<rightarrow>A; inj_on g B; finite A; finite B|] ==> card(A) = card(B)"
 | 
|  |    218 | by (blast intro: card_inj order_antisym)
 | 
|  |    219 | 
 | 
| 13586 |    220 | end
 |