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