| author | oheimb | 
| Thu, 14 May 1998 16:50:09 +0200 | |
| changeset 4930 | 89271bc4e7ed | 
| parent 4477 | b3e5857d8d99 | 
| child 5067 | 62b6288e6005 | 
| permissions | -rw-r--r-- | 
| 1461 | 1 | (* Title: ZF/QPair.ML | 
| 0 | 2 | ID: $Id$ | 
| 1461 | 3 | Author: Lawrence C Paulson, Cambridge University Computer Laboratory | 
| 0 | 4 | Copyright 1993 University of Cambridge | 
| 5 | ||
| 744 | 6 | For QPair.thy. | 
| 0 | 7 | |
| 8 | Quine-inspired ordered pairs and disjoint sums, for non-well-founded data | |
| 9 | structures in ZF. Does not precisely follow Quine's construction. Thanks | |
| 10 | to Thomas Forster for suggesting this approach! | |
| 11 | ||
| 12 | W. V. Quine, On Ordered Pairs and Relations, in Selected Logic Papers, | |
| 13 | 1966. | |
| 14 | ||
| 15 | Many proofs are borrowed from pair.ML and sum.ML | |
| 16 | ||
| 17 | Do we EVER have rank(a) < rank(<a;b>) ? Perhaps if the latter rank | |
| 18 | is not a limit ordinal? | |
| 19 | *) | |
| 20 | ||
| 21 | open QPair; | |
| 22 | ||
| 23 | (**** Quine ordered pairing ****) | |
| 24 | ||
| 25 | (** Lemmas for showing that <a;b> uniquely determines a and b **) | |
| 26 | ||
| 2469 | 27 | qed_goalw "QPair_empty" thy [QPair_def] | 
| 28 | "<0;0> = 0" | |
| 29 | (fn _=> [Simp_tac 1]); | |
| 30 | ||
| 1096 | 31 | qed_goalw "QPair_iff" thy [QPair_def] | 
| 0 | 32 | "<a;b> = <c;d> <-> a=c & b=d" | 
| 33 | (fn _=> [rtac sum_equal_iff 1]); | |
| 34 | ||
| 782 
200a16083201
added bind_thm for theorems defined by "standard ..."
 clasohm parents: 
760diff
changeset | 35 | bind_thm ("QPair_inject", (QPair_iff RS iffD1 RS conjE));
 | 
| 0 | 36 | |
| 2469 | 37 | Addsimps [QPair_empty, QPair_iff]; | 
| 38 | AddSEs [QPair_inject]; | |
| 39 | ||
| 1096 | 40 | qed_goal "QPair_inject1" thy "<a;b> = <c;d> ==> a=c" | 
| 0 | 41 | (fn [major]=> | 
| 42 | [ (rtac (major RS QPair_inject) 1), (assume_tac 1) ]); | |
| 43 | ||
| 1096 | 44 | qed_goal "QPair_inject2" thy "<a;b> = <c;d> ==> b=d" | 
| 0 | 45 | (fn [major]=> | 
| 46 | [ (rtac (major RS QPair_inject) 1), (assume_tac 1) ]); | |
| 47 | ||
| 48 | ||
| 49 | (*** QSigma: Disjoint union of a family of sets | |
| 50 | Generalizes Cartesian product ***) | |
| 51 | ||
| 1096 | 52 | qed_goalw "QSigmaI" thy [QSigma_def] | 
| 2469 | 53 | "!!A B. [| a:A; b:B(a) |] ==> <a;b> : QSigma(A,B)" | 
| 3016 | 54 | (fn _ => [ Blast_tac 1 ]); | 
| 2469 | 55 | |
| 56 | AddSIs [QSigmaI]; | |
| 0 | 57 | |
| 58 | (*The general elimination rule*) | |
| 1096 | 59 | qed_goalw "QSigmaE" thy [QSigma_def] | 
| 0 | 60 | "[| c: QSigma(A,B); \ | 
| 61 | \ !!x y.[| x:A; y:B(x); c=<x;y> |] ==> P \ | |
| 62 | \ |] ==> P" | |
| 63 | (fn major::prems=> | |
| 64 | [ (cut_facts_tac [major] 1), | |
| 65 | (REPEAT (eresolve_tac [UN_E, singletonE] 1 ORELSE ares_tac prems 1)) ]); | |
| 66 | ||
| 67 | (** Elimination rules for <a;b>:A*B -- introducing no eigenvariables **) | |
| 68 | ||
| 69 | val QSigmaE2 = | |
| 70 | rule_by_tactic (REPEAT_FIRST (etac QPair_inject ORELSE' bound_hyp_subst_tac) | |
| 1461 | 71 | THEN prune_params_tac) | 
| 0 | 72 |       (read_instantiate [("c","<a;b>")] QSigmaE);  
 | 
| 73 | ||
| 1096 | 74 | qed_goal "QSigmaD1" thy "<a;b> : QSigma(A,B) ==> a : A" | 
| 0 | 75 | (fn [major]=> | 
| 76 | [ (rtac (major RS QSigmaE2) 1), (assume_tac 1) ]); | |
| 77 | ||
| 1096 | 78 | qed_goal "QSigmaD2" thy "<a;b> : QSigma(A,B) ==> b : B(a)" | 
| 0 | 79 | (fn [major]=> | 
| 80 | [ (rtac (major RS QSigmaE2) 1), (assume_tac 1) ]); | |
| 81 | ||
| 2469 | 82 | AddSEs [QSigmaE2, QSigmaE]; | 
| 744 | 83 | |
| 84 | ||
| 1096 | 85 | qed_goalw "QSigma_cong" thy [QSigma_def] | 
| 0 | 86 | "[| A=A'; !!x. x:A' ==> B(x)=B'(x) |] ==> \ | 
| 87 | \ QSigma(A,B) = QSigma(A',B')" | |
| 4091 | 88 | (fn prems=> [ (simp_tac (simpset() addsimps prems) 1) ]); | 
| 0 | 89 | |
| 1096 | 90 | qed_goal "QSigma_empty1" thy "QSigma(0,B) = 0" | 
| 3016 | 91 | (fn _ => [ (Blast_tac 1) ]); | 
| 1096 | 92 | |
| 93 | qed_goal "QSigma_empty2" thy "A <*> 0 = 0" | |
| 3016 | 94 | (fn _ => [ (Blast_tac 1) ]); | 
| 2469 | 95 | |
| 96 | Addsimps [QSigma_empty1, QSigma_empty2]; | |
| 0 | 97 | |
| 1096 | 98 | |
| 99 | (*** Projections: qfst, qsnd ***) | |
| 100 | ||
| 101 | qed_goalw "qfst_conv" thy [qfst_def] "qfst(<a;b>) = a" | |
| 102 | (fn _=> | |
| 4091 | 103 | [ (blast_tac (claset() addIs [the_equality]) 1) ]); | 
| 1096 | 104 | |
| 105 | qed_goalw "qsnd_conv" thy [qsnd_def] "qsnd(<a;b>) = b" | |
| 106 | (fn _=> | |
| 4091 | 107 | [ (blast_tac (claset() addIs [the_equality]) 1) ]); | 
| 1096 | 108 | |
| 2469 | 109 | Addsimps [qfst_conv, qsnd_conv]; | 
| 1096 | 110 | |
| 111 | qed_goal "qfst_type" thy | |
| 112 | "!!p. p:QSigma(A,B) ==> qfst(p) : A" | |
| 4477 
b3e5857d8d99
New Auto_tac (by Oheimb), and new syntax (without parens), and expandshort
 paulson parents: 
4091diff
changeset | 113 | (fn _=> [ Auto_tac ]); | 
| 1096 | 114 | |
| 115 | qed_goal "qsnd_type" thy | |
| 116 | "!!p. p:QSigma(A,B) ==> qsnd(p) : B(qfst(p))" | |
| 4477 
b3e5857d8d99
New Auto_tac (by Oheimb), and new syntax (without parens), and expandshort
 paulson parents: 
4091diff
changeset | 117 | (fn _=> [ Auto_tac ]); | 
| 1096 | 118 | |
| 119 | goal thy "!!a A B. a: QSigma(A,B) ==> <qfst(a); qsnd(a)> = a"; | |
| 4477 
b3e5857d8d99
New Auto_tac (by Oheimb), and new syntax (without parens), and expandshort
 paulson parents: 
4091diff
changeset | 120 | by Auto_tac; | 
| 1096 | 121 | qed "QPair_qfst_qsnd_eq"; | 
| 0 | 122 | |
| 123 | ||
| 124 | (*** Eliminator - qsplit ***) | |
| 125 | ||
| 1096 | 126 | (*A META-equality, so that it applies to higher types as well...*) | 
| 127 | qed_goalw "qsplit" thy [qsplit_def] | |
| 3840 | 128 | "qsplit(%x y. c(x,y), <a;b>) == c(a,b)" | 
| 2469 | 129 | (fn _ => [ (Simp_tac 1), | 
| 1096 | 130 | (rtac reflexive_thm 1) ]); | 
| 0 | 131 | |
| 2469 | 132 | Addsimps [qsplit]; | 
| 133 | ||
| 1096 | 134 | qed_goal "qsplit_type" thy | 
| 0 | 135 | "[| p:QSigma(A,B); \ | 
| 136 | \ !!x y.[| x:A; y:B(x) |] ==> c(x,y):C(<x;y>) \ | |
| 3840 | 137 | \ |] ==> qsplit(%x y. c(x,y), p) : C(p)" | 
| 0 | 138 | (fn major::prems=> | 
| 139 | [ (rtac (major RS QSigmaE) 1), | |
| 4091 | 140 | (asm_simp_tac (simpset() addsimps prems) 1) ]); | 
| 1096 | 141 | |
| 142 | goalw thy [qsplit_def] | |
| 143 | "!!u. u: A<*>B ==> \ | |
| 144 | \ R(qsplit(c,u)) <-> (ALL x:A. ALL y:B. u = <x;y> --> R(c(x,y)))"; | |
| 4477 
b3e5857d8d99
New Auto_tac (by Oheimb), and new syntax (without parens), and expandshort
 paulson parents: 
4091diff
changeset | 145 | by Auto_tac; | 
| 1096 | 146 | qed "expand_qsplit"; | 
| 147 | ||
| 148 | ||
| 149 | (*** qsplit for predicates: result type o ***) | |
| 150 | ||
| 151 | goalw thy [qsplit_def] "!!R a b. R(a,b) ==> qsplit(R, <a;b>)"; | |
| 2469 | 152 | by (Asm_simp_tac 1); | 
| 1096 | 153 | qed "qsplitI"; | 
| 154 | ||
| 155 | val major::sigma::prems = goalw thy [qsplit_def] | |
| 1461 | 156 | "[| qsplit(R,z); z:QSigma(A,B); \ | 
| 157 | \ !!x y. [| z = <x;y>; R(x,y) |] ==> P \ | |
| 1096 | 158 | \ |] ==> P"; | 
| 159 | by (rtac (sigma RS QSigmaE) 1); | |
| 160 | by (cut_facts_tac [major] 1); | |
| 2469 | 161 | by (REPEAT (ares_tac prems 1)); | 
| 162 | by (Asm_full_simp_tac 1); | |
| 1096 | 163 | qed "qsplitE"; | 
| 164 | ||
| 165 | goalw thy [qsplit_def] "!!R a b. qsplit(R,<a;b>) ==> R(a,b)"; | |
| 2469 | 166 | by (Asm_full_simp_tac 1); | 
| 1096 | 167 | qed "qsplitD"; | 
| 0 | 168 | |
| 169 | ||
| 170 | (*** qconverse ***) | |
| 171 | ||
| 1096 | 172 | qed_goalw "qconverseI" thy [qconverse_def] | 
| 0 | 173 | "!!a b r. <a;b>:r ==> <b;a>:qconverse(r)" | 
| 3016 | 174 | (fn _ => [ (Blast_tac 1) ]); | 
| 0 | 175 | |
| 1096 | 176 | qed_goalw "qconverseD" thy [qconverse_def] | 
| 0 | 177 | "!!a b r. <a;b> : qconverse(r) ==> <b;a> : r" | 
| 3016 | 178 | (fn _ => [ (Blast_tac 1) ]); | 
| 0 | 179 | |
| 1096 | 180 | qed_goalw "qconverseE" thy [qconverse_def] | 
| 0 | 181 | "[| yx : qconverse(r); \ | 
| 182 | \ !!x y. [| yx=<y;x>; <x;y>:r |] ==> P \ | |
| 183 | \ |] ==> P" | |
| 184 | (fn [major,minor]=> | |
| 185 | [ (rtac (major RS ReplaceE) 1), | |
| 186 | (REPEAT (eresolve_tac [exE, conjE, minor] 1)), | |
| 187 | (hyp_subst_tac 1), | |
| 188 | (assume_tac 1) ]); | |
| 189 | ||
| 2469 | 190 | AddSIs [qconverseI]; | 
| 191 | AddSEs [qconverseD, qconverseE]; | |
| 0 | 192 | |
| 1096 | 193 | qed_goal "qconverse_qconverse" thy | 
| 0 | 194 | "!!A B r. r<=QSigma(A,B) ==> qconverse(qconverse(r)) = r" | 
| 3016 | 195 | (fn _ => [ (Blast_tac 1) ]); | 
| 0 | 196 | |
| 1096 | 197 | qed_goal "qconverse_type" thy | 
| 0 | 198 | "!!A B r. r <= A <*> B ==> qconverse(r) <= B <*> A" | 
| 3016 | 199 | (fn _ => [ (Blast_tac 1) ]); | 
| 0 | 200 | |
| 1096 | 201 | qed_goal "qconverse_prod" thy "qconverse(A <*> B) = B <*> A" | 
| 3016 | 202 | (fn _ => [ (Blast_tac 1) ]); | 
| 0 | 203 | |
| 1096 | 204 | qed_goal "qconverse_empty" thy "qconverse(0) = 0" | 
| 3016 | 205 | (fn _ => [ (Blast_tac 1) ]); | 
| 0 | 206 | |
| 207 | ||
| 208 | (**** The Quine-inspired notion of disjoint sum ****) | |
| 209 | ||
| 210 | val qsum_defs = [qsum_def,QInl_def,QInr_def,qcase_def]; | |
| 211 | ||
| 212 | (** Introduction rules for the injections **) | |
| 213 | ||
| 1096 | 214 | goalw thy qsum_defs "!!a A B. a : A ==> QInl(a) : A <+> B"; | 
| 3016 | 215 | by (Blast_tac 1); | 
| 760 | 216 | qed "QInlI"; | 
| 0 | 217 | |
| 1096 | 218 | goalw thy qsum_defs "!!b A B. b : B ==> QInr(b) : A <+> B"; | 
| 3016 | 219 | by (Blast_tac 1); | 
| 760 | 220 | qed "QInrI"; | 
| 0 | 221 | |
| 222 | (** Elimination rules **) | |
| 223 | ||
| 1096 | 224 | val major::prems = goalw thy qsum_defs | 
| 0 | 225 | "[| u: A <+> B; \ | 
| 226 | \ !!x. [| x:A; u=QInl(x) |] ==> P; \ | |
| 227 | \ !!y. [| y:B; u=QInr(y) |] ==> P \ | |
| 228 | \ |] ==> P"; | |
| 229 | by (rtac (major RS UnE) 1); | |
| 230 | by (REPEAT (rtac refl 1 | |
| 231 | ORELSE eresolve_tac (prems@[QSigmaE,singletonE,ssubst]) 1)); | |
| 760 | 232 | qed "qsumE"; | 
| 0 | 233 | |
| 2469 | 234 | AddSIs [QInlI, QInrI]; | 
| 235 | ||
| 0 | 236 | (** Injection and freeness equivalences, for rewriting **) | 
| 237 | ||
| 1096 | 238 | goalw thy qsum_defs "QInl(a)=QInl(b) <-> a=b"; | 
| 2469 | 239 | by (Simp_tac 1); | 
| 760 | 240 | qed "QInl_iff"; | 
| 0 | 241 | |
| 1096 | 242 | goalw thy qsum_defs "QInr(a)=QInr(b) <-> a=b"; | 
| 2469 | 243 | by (Simp_tac 1); | 
| 760 | 244 | qed "QInr_iff"; | 
| 0 | 245 | |
| 1096 | 246 | goalw thy qsum_defs "QInl(a)=QInr(b) <-> False"; | 
| 2469 | 247 | by (Simp_tac 1); | 
| 760 | 248 | qed "QInl_QInr_iff"; | 
| 0 | 249 | |
| 1096 | 250 | goalw thy qsum_defs "QInr(b)=QInl(a) <-> False"; | 
| 2469 | 251 | by (Simp_tac 1); | 
| 760 | 252 | qed "QInr_QInl_iff"; | 
| 0 | 253 | |
| 2469 | 254 | goalw thy qsum_defs "0<+>0 = 0"; | 
| 255 | by (Simp_tac 1); | |
| 256 | qed "qsum_empty"; | |
| 257 | ||
| 55 | 258 | (*Injection and freeness rules*) | 
| 259 | ||
| 782 
200a16083201
added bind_thm for theorems defined by "standard ..."
 clasohm parents: 
760diff
changeset | 260 | bind_thm ("QInl_inject", (QInl_iff RS iffD1));
 | 
| 
200a16083201
added bind_thm for theorems defined by "standard ..."
 clasohm parents: 
760diff
changeset | 261 | bind_thm ("QInr_inject", (QInr_iff RS iffD1));
 | 
| 
200a16083201
added bind_thm for theorems defined by "standard ..."
 clasohm parents: 
760diff
changeset | 262 | bind_thm ("QInl_neq_QInr", (QInl_QInr_iff RS iffD1 RS FalseE));
 | 
| 
200a16083201
added bind_thm for theorems defined by "standard ..."
 clasohm parents: 
760diff
changeset | 263 | bind_thm ("QInr_neq_QInl", (QInr_QInl_iff RS iffD1 RS FalseE));
 | 
| 55 | 264 | |
| 2469 | 265 | AddSEs [qsumE, QInl_neq_QInr, QInr_neq_QInl]; | 
| 266 | AddSDs [QInl_inject, QInr_inject]; | |
| 267 | Addsimps [QInl_iff, QInr_iff, QInl_QInr_iff, QInr_QInl_iff, qsum_empty]; | |
| 0 | 268 | |
| 1096 | 269 | goal thy "!!A B. QInl(a): A<+>B ==> a: A"; | 
| 3016 | 270 | by (Blast_tac 1); | 
| 760 | 271 | qed "QInlD"; | 
| 55 | 272 | |
| 1096 | 273 | goal thy "!!A B. QInr(b): A<+>B ==> b: B"; | 
| 3016 | 274 | by (Blast_tac 1); | 
| 760 | 275 | qed "QInrD"; | 
| 55 | 276 | |
| 0 | 277 | (** <+> is itself injective... who cares?? **) | 
| 278 | ||
| 1096 | 279 | goal thy | 
| 0 | 280 | "u: A <+> B <-> (EX x. x:A & u=QInl(x)) | (EX y. y:B & u=QInr(y))"; | 
| 3016 | 281 | by (Blast_tac 1); | 
| 760 | 282 | qed "qsum_iff"; | 
| 0 | 283 | |
| 1096 | 284 | goal thy "A <+> B <= C <+> D <-> A<=C & B<=D"; | 
| 3016 | 285 | by (Blast_tac 1); | 
| 760 | 286 | qed "qsum_subset_iff"; | 
| 0 | 287 | |
| 1096 | 288 | goal thy "A <+> B = C <+> D <-> A=C & B=D"; | 
| 4091 | 289 | by (simp_tac (simpset() addsimps [extension,qsum_subset_iff]) 1); | 
| 3016 | 290 | by (Blast_tac 1); | 
| 760 | 291 | qed "qsum_equal_iff"; | 
| 0 | 292 | |
| 293 | (*** Eliminator -- qcase ***) | |
| 294 | ||
| 1096 | 295 | goalw thy qsum_defs "qcase(c, d, QInl(a)) = c(a)"; | 
| 2469 | 296 | by (Simp_tac 1); | 
| 760 | 297 | qed "qcase_QInl"; | 
| 0 | 298 | |
| 1096 | 299 | goalw thy qsum_defs "qcase(c, d, QInr(b)) = d(b)"; | 
| 2469 | 300 | by (Simp_tac 1); | 
| 760 | 301 | qed "qcase_QInr"; | 
| 0 | 302 | |
| 2469 | 303 | Addsimps [qcase_QInl, qcase_QInr]; | 
| 304 | ||
| 1096 | 305 | val major::prems = goal thy | 
| 0 | 306 | "[| u: A <+> B; \ | 
| 307 | \ !!x. x: A ==> c(x): C(QInl(x)); \ | |
| 308 | \ !!y. y: B ==> d(y): C(QInr(y)) \ | |
| 309 | \ |] ==> qcase(c,d,u) : C(u)"; | |
| 310 | by (rtac (major RS qsumE) 1); | |
| 311 | by (ALLGOALS (etac ssubst)); | |
| 4091 | 312 | by (ALLGOALS (asm_simp_tac (simpset() addsimps prems))); | 
| 760 | 313 | qed "qcase_type"; | 
| 0 | 314 | |
| 315 | (** Rules for the Part primitive **) | |
| 316 | ||
| 1096 | 317 | goal thy "Part(A <+> B,QInl) = {QInl(x). x: A}";
 | 
| 3016 | 318 | by (Blast_tac 1); | 
| 760 | 319 | qed "Part_QInl"; | 
| 0 | 320 | |
| 1096 | 321 | goal thy "Part(A <+> B,QInr) = {QInr(y). y: B}";
 | 
| 3016 | 322 | by (Blast_tac 1); | 
| 760 | 323 | qed "Part_QInr"; | 
| 0 | 324 | |
| 3840 | 325 | goal thy "Part(A <+> B, %x. QInr(h(x))) = {QInr(y). y: Part(B,h)}";
 | 
| 3016 | 326 | by (Blast_tac 1); | 
| 760 | 327 | qed "Part_QInr2"; | 
| 0 | 328 | |
| 1096 | 329 | goal thy "!!A B C. C <= A <+> B ==> Part(C,QInl) Un Part(C,QInr) = C"; | 
| 3016 | 330 | by (Blast_tac 1); | 
| 760 | 331 | qed "Part_qsum_equality"; |