| author | paulson | 
| Fri, 24 Jan 2003 18:13:59 +0100 | |
| changeset 13786 | ab8f39f48a6f | 
| parent 13639 | 8ee6ea6627e1 | 
| child 13812 | 91713a1915ee | 
| permissions | -rw-r--r-- | 
| 10358 | 1 | (* Title: HOL/Relation.thy | 
| 1128 
64b30e3cc6d4
Trancl is now based on Relation which used to be in Integ.
 nipkow parents: diff
changeset | 2 | ID: $Id$ | 
| 1983 | 3 | Author: Lawrence C Paulson, Cambridge University Computer Laboratory | 
| 4 | Copyright 1996 University of Cambridge | |
| 1128 
64b30e3cc6d4
Trancl is now based on Relation which used to be in Integ.
 nipkow parents: diff
changeset | 5 | *) | 
| 
64b30e3cc6d4
Trancl is now based on Relation which used to be in Integ.
 nipkow parents: diff
changeset | 6 | |
| 12905 | 7 | header {* Relations *}
 | 
| 8 | ||
| 9 | theory Relation = Product_Type: | |
| 5978 
fa2c2dd74f8c
moved diag (diagonal relation) from Univ to Relation
 paulson parents: 
5608diff
changeset | 10 | |
| 12913 | 11 | subsection {* Definitions *}
 | 
| 12 | ||
| 5978 
fa2c2dd74f8c
moved diag (diagonal relation) from Univ to Relation
 paulson parents: 
5608diff
changeset | 13 | constdefs | 
| 10358 | 14 |   converse :: "('a * 'b) set => ('b * 'a) set"    ("(_^-1)" [1000] 999)
 | 
| 15 |   "r^-1 == {(y, x). (x, y) : r}"
 | |
| 16 | syntax (xsymbols) | |
| 12905 | 17 |   converse :: "('a * 'b) set => ('b * 'a) set"    ("(_\<inverse>)" [1000] 999)
 | 
| 7912 | 18 | |
| 10358 | 19 | constdefs | 
| 12487 | 20 |   rel_comp  :: "[('b * 'c) set, ('a * 'b) set] => ('a * 'c) set"  (infixr "O" 60)
 | 
| 12913 | 21 |   "r O s == {(x,z). EX y. (x, y) : s & (y, z) : r}"
 | 
| 22 | ||
| 11136 | 23 |   Image :: "[('a * 'b) set, 'a set] => 'b set"                (infixl "``" 90)
 | 
| 12913 | 24 |   "r `` s == {y. EX x:s. (x,y):r}"
 | 
| 7912 | 25 | |
| 12905 | 26 |   Id    :: "('a * 'a) set"  -- {* the identity relation *}
 | 
| 12913 | 27 |   "Id == {p. EX x. p = (x,x)}"
 | 
| 7912 | 28 | |
| 12905 | 29 |   diag  :: "'a set => ('a * 'a) set"  -- {* diagonal: identity over a set *}
 | 
| 12913 | 30 |   "diag A == UN x:A. {(x,x)}"
 | 
| 31 | ||
| 11136 | 32 |   Domain :: "('a * 'b) set => 'a set"
 | 
| 12913 | 33 |   "Domain r == {x. EX y. (x,y):r}"
 | 
| 5978 
fa2c2dd74f8c
moved diag (diagonal relation) from Univ to Relation
 paulson parents: 
5608diff
changeset | 34 | |
| 11136 | 35 |   Range  :: "('a * 'b) set => 'b set"
 | 
| 12913 | 36 | "Range r == Domain(r^-1)" | 
| 5978 
fa2c2dd74f8c
moved diag (diagonal relation) from Univ to Relation
 paulson parents: 
5608diff
changeset | 37 | |
| 11136 | 38 |   Field :: "('a * 'a) set => 'a set"
 | 
| 12913 | 39 | "Field r == Domain r Un Range r" | 
| 10786 | 40 | |
| 12905 | 41 |   refl   :: "['a set, ('a * 'a) set] => bool"  -- {* reflexivity over a set *}
 | 
| 12913 | 42 | "refl A r == r \<subseteq> A \<times> A & (ALL x: A. (x,x) : r)" | 
| 6806 
43c081a0858d
new preficates refl, sym [from Integ/Equiv], antisym
 paulson parents: 
5978diff
changeset | 43 | |
| 12905 | 44 |   sym    :: "('a * 'a) set => bool"  -- {* symmetry predicate *}
 | 
| 12913 | 45 | "sym r == ALL x y. (x,y): r --> (y,x): r" | 
| 6806 
43c081a0858d
new preficates refl, sym [from Integ/Equiv], antisym
 paulson parents: 
5978diff
changeset | 46 | |
| 12905 | 47 |   antisym:: "('a * 'a) set => bool"  -- {* antisymmetry predicate *}
 | 
| 12913 | 48 | "antisym r == ALL x y. (x,y):r --> (y,x):r --> x=y" | 
| 6806 
43c081a0858d
new preficates refl, sym [from Integ/Equiv], antisym
 paulson parents: 
5978diff
changeset | 49 | |
| 12905 | 50 |   trans  :: "('a * 'a) set => bool"  -- {* transitivity predicate *}
 | 
| 12913 | 51 | "trans r == (ALL x y z. (x,y):r --> (y,z):r --> (x,z):r)" | 
| 5978 
fa2c2dd74f8c
moved diag (diagonal relation) from Univ to Relation
 paulson parents: 
5608diff
changeset | 52 | |
| 11136 | 53 |   single_valued :: "('a * 'b) set => bool"
 | 
| 12913 | 54 | "single_valued r == ALL x y. (x,y):r --> (ALL z. (x,z):r --> y=z)" | 
| 7014 
11ee650edcd2
Added some definitions and theorems needed for the
 berghofe parents: 
6806diff
changeset | 55 | |
| 11136 | 56 |   inv_image :: "('b * 'b) set => ('a => 'b) => ('a * 'a) set"
 | 
| 12913 | 57 |   "inv_image r f == {(x, y). (f x, f y) : r}"
 | 
| 11136 | 58 | |
| 6806 
43c081a0858d
new preficates refl, sym [from Integ/Equiv], antisym
 paulson parents: 
5978diff
changeset | 59 | syntax | 
| 12905 | 60 |   reflexive :: "('a * 'a) set => bool"  -- {* reflexivity over a type *}
 | 
| 6806 
43c081a0858d
new preficates refl, sym [from Integ/Equiv], antisym
 paulson parents: 
5978diff
changeset | 61 | translations | 
| 
43c081a0858d
new preficates refl, sym [from Integ/Equiv], antisym
 paulson parents: 
5978diff
changeset | 62 | "reflexive" == "refl UNIV" | 
| 
43c081a0858d
new preficates refl, sym [from Integ/Equiv], antisym
 paulson parents: 
5978diff
changeset | 63 | |
| 12905 | 64 | |
| 12913 | 65 | subsection {* The identity relation *}
 | 
| 12905 | 66 | |
| 67 | lemma IdI [intro]: "(a, a) : Id" | |
| 68 | by (simp add: Id_def) | |
| 69 | ||
| 70 | lemma IdE [elim!]: "p : Id ==> (!!x. p = (x, x) ==> P) ==> P" | |
| 71 | by (unfold Id_def) (rules elim: CollectE) | |
| 72 | ||
| 73 | lemma pair_in_Id_conv [iff]: "((a, b) : Id) = (a = b)" | |
| 74 | by (unfold Id_def) blast | |
| 75 | ||
| 76 | lemma reflexive_Id: "reflexive Id" | |
| 77 | by (simp add: refl_def) | |
| 78 | ||
| 79 | lemma antisym_Id: "antisym Id" | |
| 80 |   -- {* A strange result, since @{text Id} is also symmetric. *}
 | |
| 81 | by (simp add: antisym_def) | |
| 82 | ||
| 83 | lemma trans_Id: "trans Id" | |
| 84 | by (simp add: trans_def) | |
| 85 | ||
| 86 | ||
| 12913 | 87 | subsection {* Diagonal: identity over a set *}
 | 
| 12905 | 88 | |
| 89 | lemma diag_eqI: "a = b ==> a : A ==> (a, b) : diag A" | |
| 90 | by (simp add: diag_def) | |
| 91 | ||
| 92 | lemma diagI [intro!]: "a : A ==> (a, a) : diag A" | |
| 93 | by (rule diag_eqI) (rule refl) | |
| 94 | ||
| 95 | lemma diagE [elim!]: | |
| 96 | "c : diag A ==> (!!x. x : A ==> c = (x, x) ==> P) ==> P" | |
| 12913 | 97 |   -- {* The general elimination rule. *}
 | 
| 12905 | 98 | by (unfold diag_def) (rules elim!: UN_E singletonE) | 
| 99 | ||
| 100 | lemma diag_iff: "((x, y) : diag A) = (x = y & x : A)" | |
| 101 | by blast | |
| 102 | ||
| 12913 | 103 | lemma diag_subset_Times: "diag A \<subseteq> A \<times> A" | 
| 12905 | 104 | by blast | 
| 105 | ||
| 106 | ||
| 107 | subsection {* Composition of two relations *}
 | |
| 108 | ||
| 12913 | 109 | lemma rel_compI [intro]: | 
| 12905 | 110 | "(a, b) : s ==> (b, c) : r ==> (a, c) : r O s" | 
| 111 | by (unfold rel_comp_def) blast | |
| 112 | ||
| 12913 | 113 | lemma rel_compE [elim!]: "xz : r O s ==> | 
| 12905 | 114 | (!!x y z. xz = (x, z) ==> (x, y) : s ==> (y, z) : r ==> P) ==> P" | 
| 115 | by (unfold rel_comp_def) (rules elim!: CollectE splitE exE conjE) | |
| 116 | ||
| 117 | lemma rel_compEpair: | |
| 118 | "(a, c) : r O s ==> (!!y. (a, y) : s ==> (y, c) : r ==> P) ==> P" | |
| 119 | by (rules elim: rel_compE Pair_inject ssubst) | |
| 120 | ||
| 121 | lemma R_O_Id [simp]: "R O Id = R" | |
| 122 | by fast | |
| 123 | ||
| 124 | lemma Id_O_R [simp]: "Id O R = R" | |
| 125 | by fast | |
| 126 | ||
| 127 | lemma O_assoc: "(R O S) O T = R O (S O T)" | |
| 128 | by blast | |
| 129 | ||
| 12913 | 130 | lemma trans_O_subset: "trans r ==> r O r \<subseteq> r" | 
| 12905 | 131 | by (unfold trans_def) blast | 
| 132 | ||
| 12913 | 133 | lemma rel_comp_mono: "r' \<subseteq> r ==> s' \<subseteq> s ==> (r' O s') \<subseteq> (r O s)" | 
| 12905 | 134 | by blast | 
| 135 | ||
| 136 | lemma rel_comp_subset_Sigma: | |
| 12913 | 137 | "s \<subseteq> A \<times> B ==> r \<subseteq> B \<times> C ==> (r O s) \<subseteq> A \<times> C" | 
| 12905 | 138 | by blast | 
| 139 | ||
| 12913 | 140 | |
| 141 | subsection {* Reflexivity *}
 | |
| 142 | ||
| 143 | lemma reflI: "r \<subseteq> A \<times> A ==> (!!x. x : A ==> (x, x) : r) ==> refl A r" | |
| 12905 | 144 | by (unfold refl_def) (rules intro!: ballI) | 
| 145 | ||
| 146 | lemma reflD: "refl A r ==> a : A ==> (a, a) : r" | |
| 147 | by (unfold refl_def) blast | |
| 148 | ||
| 12913 | 149 | |
| 150 | subsection {* Antisymmetry *}
 | |
| 12905 | 151 | |
| 152 | lemma antisymI: | |
| 153 | "(!!x y. (x, y) : r ==> (y, x) : r ==> x=y) ==> antisym r" | |
| 154 | by (unfold antisym_def) rules | |
| 155 | ||
| 156 | lemma antisymD: "antisym r ==> (a, b) : r ==> (b, a) : r ==> a = b" | |
| 157 | by (unfold antisym_def) rules | |
| 158 | ||
| 12913 | 159 | |
| 160 | subsection {* Transitivity *}
 | |
| 12905 | 161 | |
| 162 | lemma transI: | |
| 163 | "(!!x y z. (x, y) : r ==> (y, z) : r ==> (x, z) : r) ==> trans r" | |
| 164 | by (unfold trans_def) rules | |
| 165 | ||
| 166 | lemma transD: "trans r ==> (a, b) : r ==> (b, c) : r ==> (a, c) : r" | |
| 167 | by (unfold trans_def) rules | |
| 168 | ||
| 169 | ||
| 12913 | 170 | subsection {* Converse *}
 | 
| 171 | ||
| 172 | lemma converse_iff [iff]: "((a,b): r^-1) = ((b,a) : r)" | |
| 12905 | 173 | by (simp add: converse_def) | 
| 174 | ||
| 13343 | 175 | lemma converseI[sym]: "(a, b) : r ==> (b, a) : r^-1" | 
| 12905 | 176 | by (simp add: converse_def) | 
| 177 | ||
| 13343 | 178 | lemma converseD[sym]: "(a,b) : r^-1 ==> (b, a) : r" | 
| 12905 | 179 | by (simp add: converse_def) | 
| 180 | ||
| 181 | lemma converseE [elim!]: | |
| 182 | "yx : r^-1 ==> (!!x y. yx = (y, x) ==> (x, y) : r ==> P) ==> P" | |
| 12913 | 183 |     -- {* More general than @{text converseD}, as it ``splits'' the member of the relation. *}
 | 
| 12905 | 184 | by (unfold converse_def) (rules elim!: CollectE splitE bexE) | 
| 185 | ||
| 186 | lemma converse_converse [simp]: "(r^-1)^-1 = r" | |
| 187 | by (unfold converse_def) blast | |
| 188 | ||
| 189 | lemma converse_rel_comp: "(r O s)^-1 = s^-1 O r^-1" | |
| 190 | by blast | |
| 191 | ||
| 192 | lemma converse_Id [simp]: "Id^-1 = Id" | |
| 193 | by blast | |
| 194 | ||
| 12913 | 195 | lemma converse_diag [simp]: "(diag A)^-1 = diag A" | 
| 12905 | 196 | by blast | 
| 197 | ||
| 198 | lemma refl_converse: "refl A r ==> refl A (converse r)" | |
| 199 | by (unfold refl_def) blast | |
| 200 | ||
| 201 | lemma antisym_converse: "antisym (converse r) = antisym r" | |
| 202 | by (unfold antisym_def) blast | |
| 203 | ||
| 204 | lemma trans_converse: "trans (converse r) = trans r" | |
| 205 | by (unfold trans_def) blast | |
| 206 | ||
| 12913 | 207 | |
| 12905 | 208 | subsection {* Domain *}
 | 
| 209 | ||
| 210 | lemma Domain_iff: "(a : Domain r) = (EX y. (a, y) : r)" | |
| 211 | by (unfold Domain_def) blast | |
| 212 | ||
| 213 | lemma DomainI [intro]: "(a, b) : r ==> a : Domain r" | |
| 214 | by (rules intro!: iffD2 [OF Domain_iff]) | |
| 215 | ||
| 216 | lemma DomainE [elim!]: | |
| 217 | "a : Domain r ==> (!!y. (a, y) : r ==> P) ==> P" | |
| 218 | by (rules dest!: iffD1 [OF Domain_iff]) | |
| 219 | ||
| 220 | lemma Domain_empty [simp]: "Domain {} = {}"
 | |
| 221 | by blast | |
| 222 | ||
| 223 | lemma Domain_insert: "Domain (insert (a, b) r) = insert a (Domain r)" | |
| 224 | by blast | |
| 225 | ||
| 226 | lemma Domain_Id [simp]: "Domain Id = UNIV" | |
| 227 | by blast | |
| 228 | ||
| 229 | lemma Domain_diag [simp]: "Domain (diag A) = A" | |
| 230 | by blast | |
| 231 | ||
| 232 | lemma Domain_Un_eq: "Domain(A Un B) = Domain(A) Un Domain(B)" | |
| 233 | by blast | |
| 234 | ||
| 12913 | 235 | lemma Domain_Int_subset: "Domain(A Int B) \<subseteq> Domain(A) Int Domain(B)" | 
| 12905 | 236 | by blast | 
| 237 | ||
| 12913 | 238 | lemma Domain_Diff_subset: "Domain(A) - Domain(B) \<subseteq> Domain(A - B)" | 
| 12905 | 239 | by blast | 
| 240 | ||
| 241 | lemma Domain_Union: "Domain (Union S) = (UN A:S. Domain A)" | |
| 242 | by blast | |
| 243 | ||
| 12913 | 244 | lemma Domain_mono: "r \<subseteq> s ==> Domain r \<subseteq> Domain s" | 
| 12905 | 245 | by blast | 
| 246 | ||
| 247 | ||
| 248 | subsection {* Range *}
 | |
| 249 | ||
| 250 | lemma Range_iff: "(a : Range r) = (EX y. (y, a) : r)" | |
| 251 | by (simp add: Domain_def Range_def) | |
| 252 | ||
| 253 | lemma RangeI [intro]: "(a, b) : r ==> b : Range r" | |
| 254 | by (unfold Range_def) (rules intro!: converseI DomainI) | |
| 255 | ||
| 256 | lemma RangeE [elim!]: "b : Range r ==> (!!x. (x, b) : r ==> P) ==> P" | |
| 257 | by (unfold Range_def) (rules elim!: DomainE dest!: converseD) | |
| 258 | ||
| 259 | lemma Range_empty [simp]: "Range {} = {}"
 | |
| 260 | by blast | |
| 261 | ||
| 262 | lemma Range_insert: "Range (insert (a, b) r) = insert b (Range r)" | |
| 263 | by blast | |
| 264 | ||
| 265 | lemma Range_Id [simp]: "Range Id = UNIV" | |
| 266 | by blast | |
| 267 | ||
| 268 | lemma Range_diag [simp]: "Range (diag A) = A" | |
| 269 | by auto | |
| 270 | ||
| 271 | lemma Range_Un_eq: "Range(A Un B) = Range(A) Un Range(B)" | |
| 272 | by blast | |
| 273 | ||
| 12913 | 274 | lemma Range_Int_subset: "Range(A Int B) \<subseteq> Range(A) Int Range(B)" | 
| 12905 | 275 | by blast | 
| 276 | ||
| 12913 | 277 | lemma Range_Diff_subset: "Range(A) - Range(B) \<subseteq> Range(A - B)" | 
| 12905 | 278 | by blast | 
| 279 | ||
| 280 | lemma Range_Union: "Range (Union S) = (UN A:S. Range A)" | |
| 281 | by blast | |
| 282 | ||
| 283 | ||
| 284 | subsection {* Image of a set under a relation *}
 | |
| 285 | ||
| 12913 | 286 | lemma Image_iff: "(b : r``A) = (EX x:A. (x, b) : r)" | 
| 12905 | 287 | by (simp add: Image_def) | 
| 288 | ||
| 12913 | 289 | lemma Image_singleton: "r``{a} = {b. (a, b) : r}"
 | 
| 12905 | 290 | by (simp add: Image_def) | 
| 291 | ||
| 12913 | 292 | lemma Image_singleton_iff [iff]: "(b : r``{a}) = ((a, b) : r)"
 | 
| 12905 | 293 | by (rule Image_iff [THEN trans]) simp | 
| 294 | ||
| 12913 | 295 | lemma ImageI [intro]: "(a, b) : r ==> a : A ==> b : r``A" | 
| 12905 | 296 | by (unfold Image_def) blast | 
| 297 | ||
| 298 | lemma ImageE [elim!]: | |
| 12913 | 299 | "b : r `` A ==> (!!x. (x, b) : r ==> x : A ==> P) ==> P" | 
| 12905 | 300 | by (unfold Image_def) (rules elim!: CollectE bexE) | 
| 301 | ||
| 302 | lemma rev_ImageI: "a : A ==> (a, b) : r ==> b : r `` A" | |
| 303 |   -- {* This version's more effective when we already have the required @{text a} *}
 | |
| 304 | by blast | |
| 305 | ||
| 306 | lemma Image_empty [simp]: "R``{} = {}"
 | |
| 307 | by blast | |
| 308 | ||
| 309 | lemma Image_Id [simp]: "Id `` A = A" | |
| 310 | by blast | |
| 311 | ||
| 312 | lemma Image_diag [simp]: "diag A `` B = A Int B" | |
| 313 | by blast | |
| 314 | ||
| 12913 | 315 | lemma Image_Int_subset: "R `` (A Int B) \<subseteq> R `` A Int R `` B" | 
| 12905 | 316 | by blast | 
| 317 | ||
| 318 | lemma Image_Un: "R `` (A Un B) = R `` A Un R `` B" | |
| 319 | by blast | |
| 320 | ||
| 12913 | 321 | lemma Image_subset: "r \<subseteq> A \<times> B ==> r``C \<subseteq> B" | 
| 12905 | 322 | by (rules intro!: subsetI elim!: ImageE dest!: subsetD SigmaD2) | 
| 323 | ||
| 324 | lemma Image_eq_UN: "r``B = (UN y: B. r``{y})"
 | |
| 325 |   -- {* NOT suitable for rewriting *}
 | |
| 326 | by blast | |
| 327 | ||
| 12913 | 328 | lemma Image_mono: "r' \<subseteq> r ==> A' \<subseteq> A ==> (r' `` A') \<subseteq> (r `` A)" | 
| 12905 | 329 | by blast | 
| 330 | ||
| 331 | lemma Image_UN: "(r `` (UNION A B)) = (UN x:A.(r `` (B x)))" | |
| 332 | by blast | |
| 333 | ||
| 12913 | 334 | lemma Image_INT_subset: "(r `` (INTER A B)) \<subseteq> (INT x:A.(r `` (B x)))" | 
| 12905 | 335 |   -- {* Converse inclusion fails *}
 | 
| 336 | by blast | |
| 337 | ||
| 12913 | 338 | lemma Image_subset_eq: "(r``A \<subseteq> B) = (A \<subseteq> - ((r^-1) `` (-B)))" | 
| 12905 | 339 | by blast | 
| 340 | ||
| 341 | ||
| 12913 | 342 | subsection {* Single valued relations *}
 | 
| 343 | ||
| 344 | lemma single_valuedI: | |
| 12905 | 345 | "ALL x y. (x,y):r --> (ALL z. (x,z):r --> y=z) ==> single_valued r" | 
| 346 | by (unfold single_valued_def) | |
| 347 | ||
| 348 | lemma single_valuedD: | |
| 349 | "single_valued r ==> (x, y) : r ==> (x, z) : r ==> y = z" | |
| 350 | by (simp add: single_valued_def) | |
| 351 | ||
| 352 | ||
| 353 | subsection {* Graphs given by @{text Collect} *}
 | |
| 354 | ||
| 355 | lemma Domain_Collect_split [simp]: "Domain{(x,y). P x y} = {x. EX y. P x y}"
 | |
| 356 | by auto | |
| 357 | ||
| 358 | lemma Range_Collect_split [simp]: "Range{(x,y). P x y} = {y. EX x. P x y}"
 | |
| 359 | by auto | |
| 360 | ||
| 361 | lemma Image_Collect_split [simp]: "{(x,y). P x y} `` A = {y. EX x:A. P x y}"
 | |
| 362 | by auto | |
| 363 | ||
| 364 | ||
| 12913 | 365 | subsection {* Inverse image *}
 | 
| 12905 | 366 | |
| 12913 | 367 | lemma trans_inv_image: "trans r ==> trans (inv_image r f)" | 
| 12905 | 368 | apply (unfold trans_def inv_image_def) | 
| 369 | apply (simp (no_asm)) | |
| 370 | apply blast | |
| 371 | done | |
| 372 | ||
| 1128 
64b30e3cc6d4
Trancl is now based on Relation which used to be in Integ.
 nipkow parents: diff
changeset | 373 | end |