| author | paulson | 
| Tue, 01 May 2001 17:16:32 +0200 | |
| changeset 11276 | f8353c722d4e | 
| parent 10908 | a7cfffb5d7dc | 
| child 11464 | ddea204de5bc | 
| permissions | -rw-r--r-- | 
| 10213 | 1 | (* Title: HOL/Datatype_Universe.ML | 
| 2 | ID: $Id$ | |
| 3 | Author: Lawrence C Paulson, Cambridge University Computer Laboratory | |
| 4 | Copyright 1991 University of Cambridge | |
| 5 | *) | |
| 6 | ||
| 7 | (** apfst -- can be used in similar type definitions **) | |
| 8 | ||
| 9 | Goalw [apfst_def] "apfst f (a,b) = (f(a),b)"; | |
| 10908 | 10 | by (rtac split_conv 1); | 
| 10213 | 11 | qed "apfst_conv"; | 
| 12 | ||
| 13 | val [major,minor] = Goal | |
| 14 | "[| q = apfst f p; !!x y. [| p = (x,y); q = (f(x),y) |] ==> R \ | |
| 15 | \ |] ==> R"; | |
| 16 | by (rtac PairE 1); | |
| 17 | by (rtac minor 1); | |
| 18 | by (assume_tac 1); | |
| 19 | by (rtac (major RS trans) 1); | |
| 20 | by (etac ssubst 1); | |
| 21 | by (rtac apfst_conv 1); | |
| 22 | qed "apfst_convE"; | |
| 23 | ||
| 24 | (** Push -- an injection, analogous to Cons on lists **) | |
| 25 | ||
| 26 | Goalw [Push_def] "Push i f = Push j g ==> i=j"; | |
| 27 | by (etac (fun_cong RS box_equals) 1); | |
| 28 | by (rtac nat_case_0 1); | |
| 29 | by (rtac nat_case_0 1); | |
| 30 | qed "Push_inject1"; | |
| 31 | ||
| 32 | Goalw [Push_def] "Push i f = Push j g ==> f=g"; | |
| 33 | by (rtac (ext RS box_equals) 1); | |
| 34 | by (etac fun_cong 1); | |
| 35 | by (rtac (nat_case_Suc RS ext) 1); | |
| 36 | by (rtac (nat_case_Suc RS ext) 1); | |
| 37 | qed "Push_inject2"; | |
| 38 | ||
| 39 | val [major,minor] = Goal | |
| 40 | "[| Push i f =Push j g; [| i=j; f=g |] ==> P \ | |
| 41 | \ |] ==> P"; | |
| 42 | by (rtac ((major RS Push_inject2) RS ((major RS Push_inject1) RS minor)) 1); | |
| 43 | qed "Push_inject"; | |
| 44 | ||
| 45 | Goalw [Push_def] "Push (Inr (Suc k)) f = (%z. Inr 0) ==> P"; | |
| 46 | by (rtac Suc_neq_Zero 1); | |
| 47 | by (etac (fun_cong RS box_equals RS Inr_inject) 1); | |
| 48 | by (rtac nat_case_0 1); | |
| 49 | by (rtac refl 1); | |
| 50 | qed "Push_neq_K0"; | |
| 51 | ||
| 52 | (*** Isomorphisms ***) | |
| 53 | ||
| 54 | Goal "inj(Rep_Node)"; | |
| 55 | by (rtac inj_inverseI 1); (*cannot combine by RS: multiple unifiers*) | |
| 56 | by (rtac Rep_Node_inverse 1); | |
| 57 | qed "inj_Rep_Node"; | |
| 58 | ||
| 59 | Goal "inj_on Abs_Node Node"; | |
| 60 | by (rtac inj_on_inverseI 1); | |
| 61 | by (etac Abs_Node_inverse 1); | |
| 62 | qed "inj_on_Abs_Node"; | |
| 63 | ||
| 10908 | 64 | bind_thm ("Abs_Node_inj", inj_on_Abs_Node RS inj_onD);
 | 
| 10213 | 65 | |
| 66 | ||
| 67 | (*** Introduction rules for Node ***) | |
| 68 | ||
| 69 | Goalw [Node_def] "(%k. Inr 0, a) : Node"; | |
| 70 | by (Blast_tac 1); | |
| 71 | qed "Node_K0_I"; | |
| 72 | ||
| 73 | Goalw [Node_def,Push_def] | |
| 74 | "p: Node ==> apfst (Push i) p : Node"; | |
| 75 | by (fast_tac (claset() addSIs [apfst_conv, nat_case_Suc RS trans]) 1); | |
| 76 | qed "Node_Push_I"; | |
| 77 | ||
| 78 | ||
| 79 | (*** Distinctness of constructors ***) | |
| 80 | ||
| 81 | (** Scons vs Atom **) | |
| 82 | ||
| 83 | Goalw [Atom_def,Scons_def,Push_Node_def] "Scons M N ~= Atom(a)"; | |
| 84 | by (rtac notI 1); | |
| 85 | by (etac (equalityD2 RS subsetD RS UnE) 1); | |
| 86 | by (rtac singletonI 1); | |
| 10908 | 87 | by (REPEAT (eresolve_tac [imageE, Abs_Node_inj RS apfst_convE, | 
| 10213 | 88 | Pair_inject, sym RS Push_neq_K0] 1 | 
| 89 | ORELSE resolve_tac [Node_K0_I, Rep_Node RS Node_Push_I] 1)); | |
| 90 | qed "Scons_not_Atom"; | |
| 91 | bind_thm ("Atom_not_Scons", Scons_not_Atom RS not_sym);
 | |
| 92 | ||
| 93 | ||
| 94 | (*** Injectiveness ***) | |
| 95 | ||
| 96 | (** Atomic nodes **) | |
| 97 | ||
| 98 | Goalw [Atom_def] "inj(Atom)"; | |
| 10908 | 99 | by (blast_tac (claset() addSIs [injI, Node_K0_I] addSDs [Abs_Node_inj]) 1); | 
| 10213 | 100 | qed "inj_Atom"; | 
| 101 | bind_thm ("Atom_inject", inj_Atom RS injD);
 | |
| 102 | ||
| 103 | Goal "(Atom(a)=Atom(b)) = (a=b)"; | |
| 104 | by (blast_tac (claset() addSDs [Atom_inject]) 1); | |
| 105 | qed "Atom_Atom_eq"; | |
| 106 | AddIffs [Atom_Atom_eq]; | |
| 107 | ||
| 108 | Goalw [Leaf_def,o_def] "inj(Leaf)"; | |
| 109 | by (rtac injI 1); | |
| 110 | by (etac (Atom_inject RS Inl_inject) 1); | |
| 111 | qed "inj_Leaf"; | |
| 112 | ||
| 113 | bind_thm ("Leaf_inject", inj_Leaf RS injD);
 | |
| 114 | AddSDs [Leaf_inject]; | |
| 115 | ||
| 116 | Goalw [Numb_def,o_def] "inj(Numb)"; | |
| 117 | by (rtac injI 1); | |
| 118 | by (etac (Atom_inject RS Inr_inject) 1); | |
| 119 | qed "inj_Numb"; | |
| 120 | ||
| 121 | bind_thm ("Numb_inject", inj_Numb RS injD);
 | |
| 122 | AddSDs [Numb_inject]; | |
| 123 | ||
| 124 | (** Injectiveness of Push_Node **) | |
| 125 | ||
| 126 | val [major,minor] = Goalw [Push_Node_def] | |
| 127 | "[| Push_Node i m =Push_Node j n; [| i=j; m=n |] ==> P \ | |
| 128 | \ |] ==> P"; | |
| 10908 | 129 | by (rtac (major RS Abs_Node_inj RS apfst_convE) 1); | 
| 10213 | 130 | by (REPEAT (resolve_tac [Rep_Node RS Node_Push_I] 1)); | 
| 131 | by (etac (sym RS apfst_convE) 1); | |
| 132 | by (rtac minor 1); | |
| 133 | by (etac Pair_inject 1); | |
| 134 | by (etac (Push_inject1 RS sym) 1); | |
| 135 | by (rtac (inj_Rep_Node RS injD) 1); | |
| 136 | by (etac trans 1); | |
| 137 | by (safe_tac (claset() addSEs [Push_inject,sym])); | |
| 138 | qed "Push_Node_inject"; | |
| 139 | ||
| 140 | ||
| 141 | (** Injectiveness of Scons **) | |
| 142 | ||
| 143 | Goalw [Scons_def] "Scons M N <= Scons M' N' ==> M<=M'"; | |
| 144 | by (blast_tac (claset() addSDs [Push_Node_inject]) 1); | |
| 145 | qed "Scons_inject_lemma1"; | |
| 146 | ||
| 147 | Goalw [Scons_def] "Scons M N <= Scons M' N' ==> N<=N'"; | |
| 148 | by (blast_tac (claset() addSDs [Push_Node_inject]) 1); | |
| 149 | qed "Scons_inject_lemma2"; | |
| 150 | ||
| 151 | Goal "Scons M N = Scons M' N' ==> M=M'"; | |
| 152 | by (etac equalityE 1); | |
| 153 | by (REPEAT (ares_tac [equalityI, Scons_inject_lemma1] 1)); | |
| 154 | qed "Scons_inject1"; | |
| 155 | ||
| 156 | Goal "Scons M N = Scons M' N' ==> N=N'"; | |
| 157 | by (etac equalityE 1); | |
| 158 | by (REPEAT (ares_tac [equalityI, Scons_inject_lemma2] 1)); | |
| 159 | qed "Scons_inject2"; | |
| 160 | ||
| 161 | val [major,minor] = Goal | |
| 162 | "[| Scons M N = Scons M' N'; [| M=M'; N=N' |] ==> P \ | |
| 163 | \ |] ==> P"; | |
| 164 | by (rtac ((major RS Scons_inject2) RS ((major RS Scons_inject1) RS minor)) 1); | |
| 165 | qed "Scons_inject"; | |
| 166 | ||
| 167 | Goal "(Scons M N = Scons M' N') = (M=M' & N=N')"; | |
| 168 | by (blast_tac (claset() addSEs [Scons_inject]) 1); | |
| 169 | qed "Scons_Scons_eq"; | |
| 170 | ||
| 171 | (*** Distinctness involving Leaf and Numb ***) | |
| 172 | ||
| 173 | (** Scons vs Leaf **) | |
| 174 | ||
| 175 | Goalw [Leaf_def,o_def] "Scons M N ~= Leaf(a)"; | |
| 176 | by (rtac Scons_not_Atom 1); | |
| 177 | qed "Scons_not_Leaf"; | |
| 178 | bind_thm ("Leaf_not_Scons", Scons_not_Leaf RS not_sym);
 | |
| 179 | ||
| 180 | AddIffs [Scons_not_Leaf, Leaf_not_Scons]; | |
| 181 | ||
| 182 | ||
| 183 | (** Scons vs Numb **) | |
| 184 | ||
| 185 | Goalw [Numb_def,o_def] "Scons M N ~= Numb(k)"; | |
| 186 | by (rtac Scons_not_Atom 1); | |
| 187 | qed "Scons_not_Numb"; | |
| 188 | bind_thm ("Numb_not_Scons", Scons_not_Numb RS not_sym);
 | |
| 189 | ||
| 190 | AddIffs [Scons_not_Numb, Numb_not_Scons]; | |
| 191 | ||
| 192 | ||
| 193 | (** Leaf vs Numb **) | |
| 194 | ||
| 195 | Goalw [Leaf_def,Numb_def] "Leaf(a) ~= Numb(k)"; | |
| 196 | by (simp_tac (simpset() addsimps [Inl_not_Inr]) 1); | |
| 197 | qed "Leaf_not_Numb"; | |
| 198 | bind_thm ("Numb_not_Leaf", Leaf_not_Numb RS not_sym);
 | |
| 199 | ||
| 200 | AddIffs [Leaf_not_Numb, Numb_not_Leaf]; | |
| 201 | ||
| 202 | ||
| 203 | (*** ndepth -- the depth of a node ***) | |
| 204 | ||
| 205 | Addsimps [apfst_conv]; | |
| 206 | AddIffs [Scons_not_Atom, Atom_not_Scons, Scons_Scons_eq]; | |
| 207 | ||
| 208 | ||
| 209 | Goalw [ndepth_def] "ndepth (Abs_Node(%k. Inr 0, x)) = 0"; | |
| 10908 | 210 | by (EVERY1[stac (Node_K0_I RS Abs_Node_inverse), stac split_conv]); | 
| 10213 | 211 | by (rtac Least_equality 1); | 
| 10850 
e1a793957a8f
generalizing the LEAST theorems from "nat" to linear
 paulson parents: 
10213diff
changeset | 212 | by Auto_tac; | 
| 10213 | 213 | qed "ndepth_K0"; | 
| 214 | ||
| 10850 
e1a793957a8f
generalizing the LEAST theorems from "nat" to linear
 paulson parents: 
10213diff
changeset | 215 | Goal "nat_case (Inr (Suc i)) f k = Inr 0 --> Suc(LEAST x. f x = Inr 0) <= k"; | 
| 10213 | 216 | by (induct_tac "k" 1); | 
| 217 | by (ALLGOALS Simp_tac); | |
| 10850 
e1a793957a8f
generalizing the LEAST theorems from "nat" to linear
 paulson parents: 
10213diff
changeset | 218 | by (rtac impI 1); | 
| 
e1a793957a8f
generalizing the LEAST theorems from "nat" to linear
 paulson parents: 
10213diff
changeset | 219 | by (etac Least_le 1); | 
| 10213 | 220 | val lemma = result(); | 
| 221 | ||
| 222 | Goalw [ndepth_def,Push_Node_def] | |
| 223 | "ndepth (Push_Node (Inr (Suc i)) n) = Suc(ndepth(n))"; | |
| 224 | by (stac (Rep_Node RS Node_Push_I RS Abs_Node_inverse) 1); | |
| 225 | by (cut_facts_tac [rewrite_rule [Node_def] Rep_Node] 1); | |
| 226 | by Safe_tac; | |
| 227 | by (etac ssubst 1); (*instantiates type variables!*) | |
| 228 | by (Simp_tac 1); | |
| 229 | by (rtac Least_equality 1); | |
| 230 | by (rewtac Push_def); | |
| 10850 
e1a793957a8f
generalizing the LEAST theorems from "nat" to linear
 paulson parents: 
10213diff
changeset | 231 | by (auto_tac (claset(), simpset() addsimps [lemma])); | 
| 10213 | 232 | by (etac LeastI 1); | 
| 233 | qed "ndepth_Push_Node"; | |
| 234 | ||
| 235 | ||
| 236 | (*** ntrunc applied to the various node sets ***) | |
| 237 | ||
| 238 | Goalw [ntrunc_def] "ntrunc 0 M = {}";
 | |
| 239 | by (Blast_tac 1); | |
| 240 | qed "ntrunc_0"; | |
| 241 | ||
| 242 | Goalw [Atom_def,ntrunc_def] "ntrunc (Suc k) (Atom a) = Atom(a)"; | |
| 243 | by (fast_tac (claset() addss (simpset() addsimps [ndepth_K0])) 1); | |
| 244 | qed "ntrunc_Atom"; | |
| 245 | ||
| 246 | Goalw [Leaf_def,o_def] "ntrunc (Suc k) (Leaf a) = Leaf(a)"; | |
| 247 | by (rtac ntrunc_Atom 1); | |
| 248 | qed "ntrunc_Leaf"; | |
| 249 | ||
| 250 | Goalw [Numb_def,o_def] "ntrunc (Suc k) (Numb i) = Numb(i)"; | |
| 251 | by (rtac ntrunc_Atom 1); | |
| 252 | qed "ntrunc_Numb"; | |
| 253 | ||
| 254 | Goalw [Scons_def,ntrunc_def] | |
| 255 | "ntrunc (Suc k) (Scons M N) = Scons (ntrunc k M) (ntrunc k N)"; | |
| 256 | by (safe_tac (claset() addSIs [imageI])); | |
| 257 | by (REPEAT (stac ndepth_Push_Node 3 THEN etac Suc_mono 3)); | |
| 258 | by (REPEAT (rtac Suc_less_SucD 1 THEN | |
| 259 | rtac (ndepth_Push_Node RS subst) 1 THEN | |
| 260 | assume_tac 1)); | |
| 261 | qed "ntrunc_Scons"; | |
| 262 | ||
| 263 | Addsimps [ntrunc_0, ntrunc_Atom, ntrunc_Leaf, ntrunc_Numb, ntrunc_Scons]; | |
| 264 | ||
| 265 | ||
| 266 | (** Injection nodes **) | |
| 267 | ||
| 268 | Goalw [In0_def] "ntrunc 1 (In0 M) = {}";
 | |
| 269 | by (Simp_tac 1); | |
| 270 | by (rewtac Scons_def); | |
| 271 | by (Blast_tac 1); | |
| 272 | qed "ntrunc_one_In0"; | |
| 273 | ||
| 274 | Goalw [In0_def] | |
| 275 | "ntrunc (Suc (Suc k)) (In0 M) = In0 (ntrunc (Suc k) M)"; | |
| 276 | by (Simp_tac 1); | |
| 277 | qed "ntrunc_In0"; | |
| 278 | ||
| 279 | Goalw [In1_def] "ntrunc 1 (In1 M) = {}";
 | |
| 280 | by (Simp_tac 1); | |
| 281 | by (rewtac Scons_def); | |
| 282 | by (Blast_tac 1); | |
| 283 | qed "ntrunc_one_In1"; | |
| 284 | ||
| 285 | Goalw [In1_def] | |
| 286 | "ntrunc (Suc (Suc k)) (In1 M) = In1 (ntrunc (Suc k) M)"; | |
| 287 | by (Simp_tac 1); | |
| 288 | qed "ntrunc_In1"; | |
| 289 | ||
| 290 | Addsimps [ntrunc_one_In0, ntrunc_In0, ntrunc_one_In1, ntrunc_In1]; | |
| 291 | ||
| 292 | ||
| 293 | (*** Cartesian Product ***) | |
| 294 | ||
| 295 | Goalw [uprod_def] "[| M:A; N:B |] ==> Scons M N : uprod A B"; | |
| 296 | by (REPEAT (ares_tac [singletonI,UN_I] 1)); | |
| 297 | qed "uprodI"; | |
| 298 | ||
| 299 | (*The general elimination rule*) | |
| 300 | val major::prems = Goalw [uprod_def] | |
| 301 | "[| c : uprod A B; \ | |
| 302 | \ !!x y. [| x:A; y:B; c = Scons x y |] ==> P \ | |
| 303 | \ |] ==> P"; | |
| 304 | by (cut_facts_tac [major] 1); | |
| 305 | by (REPEAT (eresolve_tac [asm_rl,singletonE,UN_E] 1 | |
| 306 | ORELSE resolve_tac prems 1)); | |
| 307 | qed "uprodE"; | |
| 308 | ||
| 309 | (*Elimination of a pair -- introduces no eigenvariables*) | |
| 310 | val prems = Goal | |
| 311 | "[| Scons M N : uprod A B; [| M:A; N:B |] ==> P \ | |
| 312 | \ |] ==> P"; | |
| 313 | by (rtac uprodE 1); | |
| 314 | by (REPEAT (ares_tac prems 1 ORELSE eresolve_tac [Scons_inject,ssubst] 1)); | |
| 315 | qed "uprodE2"; | |
| 316 | ||
| 317 | ||
| 318 | (*** Disjoint Sum ***) | |
| 319 | ||
| 320 | Goalw [usum_def] "M:A ==> In0(M) : usum A B"; | |
| 321 | by (Blast_tac 1); | |
| 322 | qed "usum_In0I"; | |
| 323 | ||
| 324 | Goalw [usum_def] "N:B ==> In1(N) : usum A B"; | |
| 325 | by (Blast_tac 1); | |
| 326 | qed "usum_In1I"; | |
| 327 | ||
| 328 | val major::prems = Goalw [usum_def] | |
| 329 | "[| u : usum A B; \ | |
| 330 | \ !!x. [| x:A; u=In0(x) |] ==> P; \ | |
| 331 | \ !!y. [| y:B; u=In1(y) |] ==> P \ | |
| 332 | \ |] ==> P"; | |
| 333 | by (rtac (major RS UnE) 1); | |
| 334 | by (REPEAT (rtac refl 1 | |
| 335 | ORELSE eresolve_tac (prems@[imageE,ssubst]) 1)); | |
| 336 | qed "usumE"; | |
| 337 | ||
| 338 | ||
| 339 | (** Injection **) | |
| 340 | ||
| 341 | Goalw [In0_def,In1_def] "In0(M) ~= In1(N)"; | |
| 342 | by (rtac notI 1); | |
| 343 | by (etac (Scons_inject1 RS Numb_inject RS Zero_neq_Suc) 1); | |
| 344 | qed "In0_not_In1"; | |
| 345 | ||
| 346 | bind_thm ("In1_not_In0", In0_not_In1 RS not_sym);
 | |
| 347 | ||
| 348 | AddIffs [In0_not_In1, In1_not_In0]; | |
| 349 | ||
| 350 | Goalw [In0_def] "In0(M) = In0(N) ==> M=N"; | |
| 351 | by (etac (Scons_inject2) 1); | |
| 352 | qed "In0_inject"; | |
| 353 | ||
| 354 | Goalw [In1_def] "In1(M) = In1(N) ==> M=N"; | |
| 355 | by (etac (Scons_inject2) 1); | |
| 356 | qed "In1_inject"; | |
| 357 | ||
| 358 | Goal "(In0 M = In0 N) = (M=N)"; | |
| 359 | by (blast_tac (claset() addSDs [In0_inject]) 1); | |
| 360 | qed "In0_eq"; | |
| 361 | ||
| 362 | Goal "(In1 M = In1 N) = (M=N)"; | |
| 363 | by (blast_tac (claset() addSDs [In1_inject]) 1); | |
| 364 | qed "In1_eq"; | |
| 365 | ||
| 366 | AddIffs [In0_eq, In1_eq]; | |
| 367 | ||
| 368 | Goal "inj In0"; | |
| 369 | by (blast_tac (claset() addSIs [injI]) 1); | |
| 370 | qed "inj_In0"; | |
| 371 | ||
| 372 | Goal "inj In1"; | |
| 373 | by (blast_tac (claset() addSIs [injI]) 1); | |
| 374 | qed "inj_In1"; | |
| 375 | ||
| 376 | ||
| 377 | (*** Function spaces ***) | |
| 378 | ||
| 379 | Goalw [Lim_def] "Lim f = Lim g ==> f = g"; | |
| 380 | by (rtac ext 1); | |
| 381 | by (blast_tac (claset() addSEs [Push_Node_inject]) 1); | |
| 382 | qed "Lim_inject"; | |
| 383 | ||
| 384 | Goalw [Funs_def] "S <= T ==> Funs S <= Funs T"; | |
| 385 | by (Blast_tac 1); | |
| 386 | qed "Funs_mono"; | |
| 387 | ||
| 388 | val [prem] = Goalw [Funs_def] "(!!x. f x : S) ==> f : Funs S"; | |
| 389 | by (blast_tac (claset() addIs [prem]) 1); | |
| 390 | qed "FunsI"; | |
| 391 | ||
| 392 | Goalw [Funs_def] "f : Funs S ==> f x : S"; | |
| 393 | by (etac CollectE 1); | |
| 394 | by (etac subsetD 1); | |
| 395 | by (rtac rangeI 1); | |
| 396 | qed "FunsD"; | |
| 397 | ||
| 398 | val [p1, p2] = Goalw [o_def] | |
| 399 | "[| f : Funs R; !!x. x : R ==> r (a x) = x |] ==> r o (a o f) = f"; | |
| 400 | by (rtac (p2 RS ext) 1); | |
| 401 | by (rtac (p1 RS FunsD) 1); | |
| 402 | qed "Funs_inv"; | |
| 403 | ||
| 404 | val [p1, p2] = Goalw [o_def] | |
| 405 | "[| f : Funs (range g); !!h. f = g o h ==> P |] ==> P"; | |
| 406 | by (res_inst_tac [("h", "%x. @y. (f::'a=>'b) x = g y")] p2 1);
 | |
| 407 | by (rtac ext 1); | |
| 408 | by (rtac (p1 RS FunsD RS rangeE) 1); | |
| 409 | by (etac (exI RS (some_eq_ex RS iffD2)) 1); | |
| 410 | qed "Funs_rangeE"; | |
| 411 | ||
| 412 | Goal "a : S ==> (%x. a) : Funs S"; | |
| 413 | by (rtac FunsI 1); | |
| 414 | by (assume_tac 1); | |
| 415 | qed "Funs_nonempty"; | |
| 416 | ||
| 417 | ||
| 418 | (*** proving equality of sets and functions using ntrunc ***) | |
| 419 | ||
| 420 | Goalw [ntrunc_def] "ntrunc k M <= M"; | |
| 421 | by (Blast_tac 1); | |
| 422 | qed "ntrunc_subsetI"; | |
| 423 | ||
| 424 | val [major] = Goalw [ntrunc_def] "(!!k. ntrunc k M <= N) ==> M<=N"; | |
| 425 | by (blast_tac (claset() addIs [less_add_Suc1, less_add_Suc2, | |
| 426 | major RS subsetD]) 1); | |
| 427 | qed "ntrunc_subsetD"; | |
| 428 | ||
| 429 | (*A generalized form of the take-lemma*) | |
| 430 | val [major] = Goal "(!!k. ntrunc k M = ntrunc k N) ==> M=N"; | |
| 431 | by (rtac equalityI 1); | |
| 432 | by (ALLGOALS (rtac ntrunc_subsetD)); | |
| 433 | by (ALLGOALS (rtac (ntrunc_subsetI RSN (2, subset_trans)))); | |
| 434 | by (rtac (major RS equalityD1) 1); | |
| 435 | by (rtac (major RS equalityD2) 1); | |
| 436 | qed "ntrunc_equality"; | |
| 437 | ||
| 438 | val [major] = Goalw [o_def] | |
| 439 | "[| !!k. (ntrunc(k) o h1) = (ntrunc(k) o h2) |] ==> h1=h2"; | |
| 440 | by (rtac (ntrunc_equality RS ext) 1); | |
| 441 | by (rtac (major RS fun_cong) 1); | |
| 442 | qed "ntrunc_o_equality"; | |
| 443 | ||
| 444 | (*** Monotonicity ***) | |
| 445 | ||
| 446 | Goalw [uprod_def] "[| A<=A'; B<=B' |] ==> uprod A B <= uprod A' B'"; | |
| 447 | by (Blast_tac 1); | |
| 448 | qed "uprod_mono"; | |
| 449 | ||
| 450 | Goalw [usum_def] "[| A<=A'; B<=B' |] ==> usum A B <= usum A' B'"; | |
| 451 | by (Blast_tac 1); | |
| 452 | qed "usum_mono"; | |
| 453 | ||
| 454 | Goalw [Scons_def] "[| M<=M'; N<=N' |] ==> Scons M N <= Scons M' N'"; | |
| 455 | by (Blast_tac 1); | |
| 456 | qed "Scons_mono"; | |
| 457 | ||
| 458 | Goalw [In0_def] "M<=N ==> In0(M) <= In0(N)"; | |
| 459 | by (REPEAT (ares_tac [subset_refl,Scons_mono] 1)); | |
| 460 | qed "In0_mono"; | |
| 461 | ||
| 462 | Goalw [In1_def] "M<=N ==> In1(M) <= In1(N)"; | |
| 463 | by (REPEAT (ares_tac [subset_refl,Scons_mono] 1)); | |
| 464 | qed "In1_mono"; | |
| 465 | ||
| 466 | ||
| 467 | (*** Split and Case ***) | |
| 468 | ||
| 469 | Goalw [Split_def] "Split c (Scons M N) = c M N"; | |
| 470 | by (Blast_tac 1); | |
| 471 | qed "Split"; | |
| 472 | ||
| 473 | Goalw [Case_def] "Case c d (In0 M) = c(M)"; | |
| 474 | by (Blast_tac 1); | |
| 475 | qed "Case_In0"; | |
| 476 | ||
| 477 | Goalw [Case_def] "Case c d (In1 N) = d(N)"; | |
| 478 | by (Blast_tac 1); | |
| 479 | qed "Case_In1"; | |
| 480 | ||
| 481 | Addsimps [Split, Case_In0, Case_In1]; | |
| 482 | ||
| 483 | ||
| 484 | (**** UN x. B(x) rules ****) | |
| 485 | ||
| 486 | Goalw [ntrunc_def] "ntrunc k (UN x. f(x)) = (UN x. ntrunc k (f x))"; | |
| 487 | by (Blast_tac 1); | |
| 488 | qed "ntrunc_UN1"; | |
| 489 | ||
| 490 | Goalw [Scons_def] "Scons (UN x. f x) M = (UN x. Scons (f x) M)"; | |
| 491 | by (Blast_tac 1); | |
| 492 | qed "Scons_UN1_x"; | |
| 493 | ||
| 494 | Goalw [Scons_def] "Scons M (UN x. f x) = (UN x. Scons M (f x))"; | |
| 495 | by (Blast_tac 1); | |
| 496 | qed "Scons_UN1_y"; | |
| 497 | ||
| 498 | Goalw [In0_def] "In0(UN x. f(x)) = (UN x. In0(f(x)))"; | |
| 499 | by (rtac Scons_UN1_y 1); | |
| 500 | qed "In0_UN1"; | |
| 501 | ||
| 502 | Goalw [In1_def] "In1(UN x. f(x)) = (UN x. In1(f(x)))"; | |
| 503 | by (rtac Scons_UN1_y 1); | |
| 504 | qed "In1_UN1"; | |
| 505 | ||
| 506 | ||
| 507 | (*** Equality for Cartesian Product ***) | |
| 508 | ||
| 509 | Goalw [dprod_def] | |
| 510 | "[| (M,M'):r; (N,N'):s |] ==> (Scons M N, Scons M' N') : dprod r s"; | |
| 511 | by (Blast_tac 1); | |
| 512 | qed "dprodI"; | |
| 513 | ||
| 514 | (*The general elimination rule*) | |
| 515 | val major::prems = Goalw [dprod_def] | |
| 516 | "[| c : dprod r s; \ | |
| 517 | \ !!x y x' y'. [| (x,x') : r; (y,y') : s; c = (Scons x y, Scons x' y') |] ==> P \ | |
| 518 | \ |] ==> P"; | |
| 519 | by (cut_facts_tac [major] 1); | |
| 520 | by (REPEAT_FIRST (eresolve_tac [asm_rl, UN_E, mem_splitE, singletonE])); | |
| 521 | by (REPEAT (ares_tac prems 1 ORELSE hyp_subst_tac 1)); | |
| 522 | qed "dprodE"; | |
| 523 | ||
| 524 | ||
| 525 | (*** Equality for Disjoint Sum ***) | |
| 526 | ||
| 527 | Goalw [dsum_def] "(M,M'):r ==> (In0(M), In0(M')) : dsum r s"; | |
| 528 | by (Blast_tac 1); | |
| 529 | qed "dsum_In0I"; | |
| 530 | ||
| 531 | Goalw [dsum_def] "(N,N'):s ==> (In1(N), In1(N')) : dsum r s"; | |
| 532 | by (Blast_tac 1); | |
| 533 | qed "dsum_In1I"; | |
| 534 | ||
| 535 | val major::prems = Goalw [dsum_def] | |
| 536 | "[| w : dsum r s; \ | |
| 537 | \ !!x x'. [| (x,x') : r; w = (In0(x), In0(x')) |] ==> P; \ | |
| 538 | \ !!y y'. [| (y,y') : s; w = (In1(y), In1(y')) |] ==> P \ | |
| 539 | \ |] ==> P"; | |
| 540 | by (cut_facts_tac [major] 1); | |
| 541 | by (REPEAT_FIRST (eresolve_tac [asm_rl, UN_E, UnE, mem_splitE, singletonE])); | |
| 542 | by (DEPTH_SOLVE (ares_tac prems 1 ORELSE hyp_subst_tac 1)); | |
| 543 | qed "dsumE"; | |
| 544 | ||
| 545 | AddSIs [uprodI, dprodI]; | |
| 546 | AddIs [usum_In0I, usum_In1I, dsum_In0I, dsum_In1I]; | |
| 547 | AddSEs [uprodE, dprodE, usumE, dsumE]; | |
| 548 | ||
| 549 | ||
| 550 | (*** Monotonicity ***) | |
| 551 | ||
| 552 | Goal "[| r<=r'; s<=s' |] ==> dprod r s <= dprod r' s'"; | |
| 553 | by (Blast_tac 1); | |
| 554 | qed "dprod_mono"; | |
| 555 | ||
| 556 | Goal "[| r<=r'; s<=s' |] ==> dsum r s <= dsum r' s'"; | |
| 557 | by (Blast_tac 1); | |
| 558 | qed "dsum_mono"; | |
| 559 | ||
| 560 | ||
| 561 | (*** Bounding theorems ***) | |
| 562 | ||
| 563 | Goal "(dprod (A <*> B) (C <*> D)) <= (uprod A C) <*> (uprod B D)"; | |
| 564 | by (Blast_tac 1); | |
| 565 | qed "dprod_Sigma"; | |
| 566 | ||
| 567 | bind_thm ("dprod_subset_Sigma", [dprod_mono, dprod_Sigma] MRS subset_trans |> standard);
 | |
| 568 | ||
| 569 | (*Dependent version*) | |
| 570 | Goal "(dprod (Sigma A B) (Sigma C D)) <= Sigma (uprod A C) (Split (%x y. uprod (B x) (D y)))"; | |
| 571 | by Safe_tac; | |
| 572 | by (stac Split 1); | |
| 573 | by (Blast_tac 1); | |
| 574 | qed "dprod_subset_Sigma2"; | |
| 575 | ||
| 576 | Goal "(dsum (A <*> B) (C <*> D)) <= (usum A C) <*> (usum B D)"; | |
| 577 | by (Blast_tac 1); | |
| 578 | qed "dsum_Sigma"; | |
| 579 | ||
| 580 | bind_thm ("dsum_subset_Sigma", [dsum_mono, dsum_Sigma] MRS subset_trans |> standard);
 | |
| 581 | ||
| 582 | ||
| 583 | (*** Domain ***) | |
| 584 | ||
| 585 | Goal "Domain (dprod r s) = uprod (Domain r) (Domain s)"; | |
| 586 | by Auto_tac; | |
| 587 | qed "Domain_dprod"; | |
| 588 | ||
| 589 | Goal "Domain (dsum r s) = usum (Domain r) (Domain s)"; | |
| 590 | by Auto_tac; | |
| 591 | qed "Domain_dsum"; | |
| 592 | ||
| 593 | Addsimps [Domain_dprod, Domain_dsum]; |