author | nipkow |
Tue, 30 Dec 1997 11:14:09 +0100 | |
changeset 4502 | 337c073de95e |
parent 4153 | e534c4c32d54 |
child 4686 | 74a12e86b20b |
permissions | -rw-r--r-- |
2525 | 1 |
(* Title: HOL/MiniML/Type.thy |
2 |
ID: $Id$ |
|
3 |
Author: Wolfgang Naraschewski and Tobias Nipkow |
|
4 |
Copyright 1996 TU Muenchen |
|
5 |
*) |
|
1300 | 6 |
|
7 |
Addsimps [mgu_eq,mgu_mg,mgu_free]; |
|
8 |
||
2525 | 9 |
|
10 |
(* lemmata for make scheme *) |
|
11 |
||
12 |
goal thy "mk_scheme t = sch1 =-> sch2 --> (? t1 t2. sch1 = mk_scheme t1 & sch2 = mk_scheme t2)"; |
|
13 |
by (typ.induct_tac "t" 1); |
|
14 |
by (Simp_tac 1); |
|
15 |
by (Asm_full_simp_tac 1); |
|
16 |
by (Fast_tac 1); |
|
17 |
qed_spec_mp "mk_scheme_Fun"; |
|
1300 | 18 |
|
3842 | 19 |
goal thy "!t'. mk_scheme t = mk_scheme t' --> t=t'"; |
2525 | 20 |
by (typ.induct_tac "t" 1); |
3018 | 21 |
by (rtac allI 1); |
2525 | 22 |
by (typ.induct_tac "t'" 1); |
3018 | 23 |
by (Simp_tac 1); |
24 |
by (Asm_full_simp_tac 1); |
|
25 |
by (rtac allI 1); |
|
2525 | 26 |
by (typ.induct_tac "t'" 1); |
3018 | 27 |
by (Simp_tac 1); |
28 |
by (Asm_full_simp_tac 1); |
|
2525 | 29 |
qed_spec_mp "mk_scheme_injective"; |
30 |
||
31 |
goal thy "!!t. free_tv (mk_scheme t) = free_tv t"; |
|
32 |
by (typ.induct_tac "t" 1); |
|
33 |
by (ALLGOALS Asm_simp_tac); |
|
34 |
qed "free_tv_mk_scheme"; |
|
35 |
||
36 |
Addsimps [free_tv_mk_scheme]; |
|
37 |
||
38 |
goal thy "!!t. $ S (mk_scheme t) = mk_scheme ($ S t)"; |
|
1400 | 39 |
by (typ.induct_tac "t" 1); |
1300 | 40 |
by (ALLGOALS Asm_simp_tac); |
2525 | 41 |
qed "subst_mk_scheme"; |
42 |
||
43 |
Addsimps [subst_mk_scheme]; |
|
44 |
||
1300 | 45 |
|
2525 | 46 |
(* constructor laws for app_subst *) |
47 |
||
48 |
goalw thy [app_subst_list] |
|
49 |
"$ S [] = []"; |
|
50 |
by (Simp_tac 1); |
|
51 |
qed "app_subst_Nil"; |
|
52 |
||
1300 | 53 |
goalw thy [app_subst_list] |
2525 | 54 |
"$ S (x#l) = ($ S x)#($ S l)"; |
55 |
by (Simp_tac 1); |
|
56 |
qed "app_subst_Cons"; |
|
57 |
||
58 |
Addsimps [app_subst_Nil,app_subst_Cons]; |
|
59 |
||
60 |
||
61 |
(* constructor laws for new_tv *) |
|
62 |
||
63 |
goalw thy [new_tv_def] |
|
64 |
"new_tv n (TVar m) = (m<n)"; |
|
4089 | 65 |
by (fast_tac (HOL_cs addss simpset()) 1); |
2525 | 66 |
qed "new_tv_TVar"; |
67 |
||
68 |
goalw thy [new_tv_def] |
|
69 |
"new_tv n (FVar m) = (m<n)"; |
|
4089 | 70 |
by (fast_tac (HOL_cs addss simpset()) 1); |
2525 | 71 |
qed "new_tv_FVar"; |
72 |
||
73 |
goalw thy [new_tv_def] |
|
74 |
"new_tv n (BVar m) = True"; |
|
75 |
by (Simp_tac 1); |
|
76 |
qed "new_tv_BVar"; |
|
77 |
||
78 |
goalw thy [new_tv_def] |
|
79 |
"new_tv n (t1 -> t2) = (new_tv n t1 & new_tv n t2)"; |
|
4089 | 80 |
by (fast_tac (HOL_cs addss simpset()) 1); |
2525 | 81 |
qed "new_tv_Fun"; |
1300 | 82 |
|
2525 | 83 |
goalw thy [new_tv_def] |
84 |
"new_tv n (t1 =-> t2) = (new_tv n t1 & new_tv n t2)"; |
|
4089 | 85 |
by (fast_tac (HOL_cs addss simpset()) 1); |
2525 | 86 |
qed "new_tv_Fun2"; |
87 |
||
88 |
goalw thy [new_tv_def] |
|
89 |
"new_tv n []"; |
|
2031 | 90 |
by (Simp_tac 1); |
2525 | 91 |
qed "new_tv_Nil"; |
92 |
||
93 |
goalw thy [new_tv_def] |
|
94 |
"new_tv n (x#l) = (new_tv n x & new_tv n l)"; |
|
4089 | 95 |
by (fast_tac (HOL_cs addss simpset()) 1); |
2525 | 96 |
qed "new_tv_Cons"; |
97 |
||
2625 | 98 |
goalw thy [new_tv_def] "!!n. new_tv n TVar"; |
2525 | 99 |
by (strip_tac 1); |
4089 | 100 |
by (asm_full_simp_tac (simpset() addsimps [free_tv_subst,dom_def,cod_def]) 1); |
2525 | 101 |
qed "new_tv_TVar_subst"; |
102 |
||
103 |
Addsimps [new_tv_TVar,new_tv_FVar,new_tv_BVar,new_tv_Fun,new_tv_Fun2,new_tv_Nil,new_tv_Cons,new_tv_TVar_subst]; |
|
104 |
||
2625 | 105 |
goalw thy [id_subst_def,new_tv_def,free_tv_subst,dom_def,cod_def] |
2525 | 106 |
"new_tv n id_subst"; |
3018 | 107 |
by (Simp_tac 1); |
2525 | 108 |
qed "new_tv_id_subst"; |
109 |
Addsimps[new_tv_id_subst]; |
|
110 |
||
2625 | 111 |
goal thy "new_tv n (sch::type_scheme) --> \ |
3842 | 112 |
\ $(%k. if k<n then S k else S' k) sch = $S sch"; |
2625 | 113 |
by (type_scheme.induct_tac "sch" 1); |
3018 | 114 |
by (ALLGOALS Asm_simp_tac); |
2625 | 115 |
qed "new_if_subst_type_scheme"; |
116 |
Addsimps [new_if_subst_type_scheme]; |
|
117 |
||
118 |
goal thy "new_tv n (A::type_scheme list) --> \ |
|
3842 | 119 |
\ $(%k. if k<n then S k else S' k) A = $S A"; |
2625 | 120 |
by (list.induct_tac "A" 1); |
3018 | 121 |
by (ALLGOALS Asm_simp_tac); |
2625 | 122 |
qed "new_if_subst_type_scheme_list"; |
123 |
Addsimps [new_if_subst_type_scheme_list]; |
|
124 |
||
2525 | 125 |
|
126 |
(* constructor laws for dom and cod *) |
|
1751 | 127 |
|
1300 | 128 |
goalw thy [dom_def,id_subst_def,empty_def] |
129 |
"dom id_subst = {}"; |
|
130 |
by (Simp_tac 1); |
|
131 |
qed "dom_id_subst"; |
|
132 |
Addsimps [dom_id_subst]; |
|
133 |
||
134 |
goalw thy [cod_def] |
|
135 |
"cod id_subst = {}"; |
|
136 |
by (Simp_tac 1); |
|
137 |
qed "cod_id_subst"; |
|
138 |
Addsimps [cod_id_subst]; |
|
139 |
||
2525 | 140 |
|
141 |
(* lemmata for free_tv *) |
|
142 |
||
1300 | 143 |
goalw thy [free_tv_subst] |
144 |
"free_tv id_subst = {}"; |
|
145 |
by (Simp_tac 1); |
|
146 |
qed "free_tv_id_subst"; |
|
147 |
Addsimps [free_tv_id_subst]; |
|
148 |
||
4502 | 149 |
goal thy "!!A. !n. n < length A --> x : free_tv (A!n) --> x : free_tv A"; |
2525 | 150 |
by (list.induct_tac "A" 1); |
151 |
by (Asm_full_simp_tac 1); |
|
152 |
by (rtac allI 1); |
|
153 |
by (res_inst_tac [("n","n")] nat_induct 1); |
|
154 |
by (Asm_full_simp_tac 1); |
|
155 |
by (Asm_full_simp_tac 1); |
|
156 |
qed_spec_mp "free_tv_nth_A_impl_free_tv_A"; |
|
157 |
||
158 |
Addsimps [free_tv_nth_A_impl_free_tv_A]; |
|
159 |
||
4502 | 160 |
goal thy "!!A. !nat. nat < length A --> x : free_tv (A!nat) --> x : free_tv A"; |
2525 | 161 |
by (list.induct_tac "A" 1); |
162 |
by (Asm_full_simp_tac 1); |
|
163 |
by (rtac allI 1); |
|
164 |
by (res_inst_tac [("n","nat")] nat_induct 1); |
|
165 |
by (strip_tac 1); |
|
166 |
by (Asm_full_simp_tac 1); |
|
167 |
by (Simp_tac 1); |
|
168 |
qed_spec_mp "free_tv_nth_nat_A"; |
|
169 |
||
170 |
||
171 |
(* if two substitutions yield the same result if applied to a type |
|
172 |
structure the substitutions coincide on the free type variables |
|
173 |
occurring in the type structure *) |
|
174 |
||
175 |
goal thy "!!S S'. (!x:free_tv t. (S x) = (S' x)) --> $ S (t::typ) = $ S' t"; |
|
176 |
by (typ.induct_tac "t" 1); |
|
177 |
by (Simp_tac 1); |
|
178 |
by (Asm_full_simp_tac 1); |
|
179 |
qed_spec_mp "typ_substitutions_only_on_free_variables"; |
|
180 |
||
181 |
goal thy |
|
182 |
"!!t. (!n. n:(free_tv t) --> S1 n = S2 n) ==> $ S1 (t::typ) = $ S2 t"; |
|
183 |
by (rtac typ_substitutions_only_on_free_variables 1); |
|
4089 | 184 |
by (simp_tac (simpset() addsimps [Ball_def]) 1); |
2525 | 185 |
qed "eq_free_eq_subst_te"; |
186 |
||
187 |
goal thy "!!S S'. (!x:free_tv sch. (S x) = (S' x)) --> $ S (sch::type_scheme) = $ S' sch"; |
|
188 |
by (type_scheme.induct_tac "sch" 1); |
|
189 |
by (Simp_tac 1); |
|
190 |
by (Simp_tac 1); |
|
191 |
by (Asm_full_simp_tac 1); |
|
192 |
qed_spec_mp "scheme_substitutions_only_on_free_variables"; |
|
193 |
||
194 |
goal thy |
|
195 |
"!!sch. (!n. n:(free_tv sch) --> S1 n = S2 n) ==> $ S1 (sch::type_scheme) = $ S2 sch"; |
|
196 |
by (rtac scheme_substitutions_only_on_free_variables 1); |
|
4089 | 197 |
by (simp_tac (simpset() addsimps [Ball_def]) 1); |
2525 | 198 |
qed "eq_free_eq_subst_type_scheme"; |
199 |
||
200 |
goal thy |
|
201 |
"(!n. n:(free_tv A) --> S1 n = S2 n) --> $S1 (A::type_scheme list) = $S2 A"; |
|
202 |
by (list.induct_tac "A" 1); |
|
203 |
(* case [] *) |
|
4089 | 204 |
by (fast_tac (HOL_cs addss simpset()) 1); |
2525 | 205 |
(* case x#xl *) |
4089 | 206 |
by (fast_tac (HOL_cs addIs [eq_free_eq_subst_type_scheme] addss (simpset())) 1); |
2525 | 207 |
qed_spec_mp "eq_free_eq_subst_scheme_list"; |
208 |
||
209 |
goal thy "!!P Q. ((!x:A. (P x)) --> Q) ==> ((!x:A Un B. (P x)) --> Q)"; |
|
210 |
by (Fast_tac 1); |
|
211 |
val weaken_asm_Un = result (); |
|
212 |
||
213 |
goal thy "!!S S'. (!x:free_tv A. (S x) = (S' x)) --> $ S (A::type_scheme list) = $ S' A"; |
|
214 |
by (list.induct_tac "A" 1); |
|
215 |
by (Simp_tac 1); |
|
216 |
by (Asm_full_simp_tac 1); |
|
217 |
by (rtac weaken_asm_Un 1); |
|
218 |
by (strip_tac 1); |
|
219 |
by (etac scheme_substitutions_only_on_free_variables 1); |
|
220 |
qed_spec_mp "scheme_list_substitutions_only_on_free_variables"; |
|
221 |
||
222 |
goal thy |
|
223 |
"$ S1 (t::typ) = $ S2 t --> n:(free_tv t) --> S1 n = S2 n"; |
|
224 |
by (typ.induct_tac "t" 1); |
|
225 |
(* case TVar n *) |
|
4089 | 226 |
by (fast_tac (HOL_cs addss simpset()) 1); |
2525 | 227 |
(* case Fun t1 t2 *) |
4089 | 228 |
by (fast_tac (HOL_cs addss simpset()) 1); |
2525 | 229 |
qed_spec_mp "eq_subst_te_eq_free"; |
230 |
||
231 |
goal thy |
|
232 |
"$ S1 (sch::type_scheme) = $ S2 sch --> n:(free_tv sch) --> S1 n = S2 n"; |
|
233 |
by (type_scheme.induct_tac "sch" 1); |
|
234 |
(* case TVar n *) |
|
235 |
by (Asm_simp_tac 1); |
|
236 |
(* case BVar n *) |
|
237 |
by (strip_tac 1); |
|
238 |
by (etac mk_scheme_injective 1); |
|
239 |
by (Asm_simp_tac 1); |
|
240 |
(* case Fun t1 t2 *) |
|
241 |
by (Asm_full_simp_tac 1); |
|
242 |
qed_spec_mp "eq_subst_type_scheme_eq_free"; |
|
243 |
||
244 |
goal thy |
|
245 |
"$S1 (A::type_scheme list) = $S2 A --> n:(free_tv A) --> S1 n = S2 n"; |
|
246 |
by (list.induct_tac "A" 1); |
|
247 |
(* case [] *) |
|
4089 | 248 |
by (fast_tac (HOL_cs addss simpset()) 1); |
2525 | 249 |
(* case x#xl *) |
4089 | 250 |
by (fast_tac (HOL_cs addIs [eq_subst_type_scheme_eq_free] addss (simpset())) 1); |
2525 | 251 |
qed_spec_mp "eq_subst_scheme_list_eq_free"; |
252 |
||
253 |
goalw thy [free_tv_subst] |
|
254 |
"!!v. v : cod S ==> v : free_tv S"; |
|
3385
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
255 |
by (fast_tac set_cs 1); |
2525 | 256 |
qed "codD"; |
257 |
||
258 |
goalw thy [free_tv_subst,dom_def] |
|
259 |
"!! x. x ~: free_tv S ==> S x = TVar x"; |
|
3385
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
260 |
by (fast_tac set_cs 1); |
2525 | 261 |
qed "not_free_impl_id"; |
262 |
||
263 |
goalw thy [new_tv_def] |
|
264 |
"!! n. [| new_tv n t; m:free_tv t |] ==> m<n"; |
|
3385
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
265 |
by (fast_tac HOL_cs 1 ); |
2525 | 266 |
qed "free_tv_le_new_tv"; |
267 |
||
1300 | 268 |
goalw thy [dom_def,cod_def,UNION_def,Bex_def] |
2525 | 269 |
"!!v. [| v : free_tv(S n); v~=n |] ==> v : cod S"; |
1300 | 270 |
by (Simp_tac 1); |
271 |
by (safe_tac (empty_cs addSIs [exI,conjI,notI])); |
|
1465 | 272 |
by (assume_tac 2); |
1300 | 273 |
by (rotate_tac 1 1); |
274 |
by (Asm_full_simp_tac 1); |
|
275 |
qed "cod_app_subst"; |
|
276 |
Addsimps [cod_app_subst]; |
|
277 |
||
278 |
goal thy |
|
3385
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
279 |
"free_tv (S (v::nat)) <= insert v (cod S)"; |
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
280 |
by (expand_case_tac "v:dom S" 1); |
4089 | 281 |
by (fast_tac (set_cs addss (simpset() addsimps [cod_def])) 1); |
282 |
by (fast_tac (set_cs addss (simpset() addsimps [dom_def])) 1); |
|
1300 | 283 |
qed "free_tv_subst_var"; |
284 |
||
285 |
goal thy |
|
2525 | 286 |
"free_tv ($ S (t::typ)) <= cod S Un free_tv t"; |
3385
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
287 |
by (typ.induct_tac "t" 1); |
1300 | 288 |
(* case TVar n *) |
4089 | 289 |
by (simp_tac (simpset() addsimps [free_tv_subst_var]) 1); |
1300 | 290 |
(* case Fun t1 t2 *) |
4089 | 291 |
by (fast_tac (set_cs addss simpset()) 1); |
1300 | 292 |
qed "free_tv_app_subst_te"; |
293 |
||
294 |
goal thy |
|
2525 | 295 |
"free_tv ($ S (sch::type_scheme)) <= cod S Un free_tv sch"; |
3385
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
296 |
by (type_scheme.induct_tac "sch" 1); |
2525 | 297 |
(* case FVar n *) |
4089 | 298 |
by (simp_tac (simpset() addsimps [free_tv_subst_var]) 1); |
2525 | 299 |
(* case BVar n *) |
300 |
by (Simp_tac 1); |
|
301 |
(* case Fun t1 t2 *) |
|
4089 | 302 |
by (fast_tac (set_cs addss simpset()) 1); |
2525 | 303 |
qed "free_tv_app_subst_type_scheme"; |
304 |
||
305 |
goal thy |
|
306 |
"free_tv ($ S (A::type_scheme list)) <= cod S Un free_tv A"; |
|
3385
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
307 |
by (list.induct_tac "A" 1); |
1300 | 308 |
(* case [] *) |
309 |
by (Simp_tac 1); |
|
310 |
(* case a#al *) |
|
3385
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
311 |
by (cut_facts_tac [free_tv_app_subst_type_scheme] 1); |
4089 | 312 |
by (fast_tac (set_cs addss simpset()) 1); |
2525 | 313 |
qed "free_tv_app_subst_scheme_list"; |
1300 | 314 |
|
1521 | 315 |
goalw thy [free_tv_subst,dom_def] |
316 |
"free_tv (%u::nat. $ s1 (s2 u) :: typ) <= \ |
|
317 |
\ free_tv s1 Un free_tv s2"; |
|
2513
d708d8cdc8e8
New miniscoping rules for the bounded quantifiers and UN/INT operators
paulson
parents:
2031
diff
changeset
|
318 |
by (fast_tac (set_cs addSDs [free_tv_app_subst_te RS subsetD, |
3008 | 319 |
free_tv_subst_var RS subsetD] |
4089 | 320 |
addss (simpset() delsimps bex_simps |
3008 | 321 |
addsimps [cod_def,dom_def])) 1); |
1521 | 322 |
qed "free_tv_comp_subst"; |
323 |
||
2525 | 324 |
goalw thy [o_def] |
325 |
"free_tv ($ S1 o S2) <= free_tv S1 Un free_tv (S2 :: nat => typ)"; |
|
326 |
by (rtac free_tv_comp_subst 1); |
|
327 |
qed "free_tv_o_subst"; |
|
328 |
||
329 |
goal thy "!!n. n : free_tv t --> free_tv (S n) <= free_tv ($ S t::typ)"; |
|
330 |
by (typ.induct_tac "t" 1); |
|
331 |
by (Simp_tac 1); |
|
332 |
by (Simp_tac 1); |
|
333 |
by (Fast_tac 1); |
|
334 |
qed_spec_mp "free_tv_of_substitutions_extend_to_types"; |
|
335 |
||
336 |
goal thy "!!n. n : free_tv sch --> free_tv (S n) <= free_tv ($ S sch::type_scheme)"; |
|
337 |
by (type_scheme.induct_tac "sch" 1); |
|
338 |
by (Simp_tac 1); |
|
339 |
by (Simp_tac 1); |
|
340 |
by (Simp_tac 1); |
|
341 |
by (Fast_tac 1); |
|
342 |
qed_spec_mp "free_tv_of_substitutions_extend_to_schemes"; |
|
343 |
||
344 |
goal thy "!!n. n : free_tv A --> free_tv (S n) <= free_tv ($ S A::type_scheme list)"; |
|
345 |
by (list.induct_tac "A" 1); |
|
346 |
by (Simp_tac 1); |
|
347 |
by (Simp_tac 1); |
|
4089 | 348 |
by (fast_tac (claset() addDs [free_tv_of_substitutions_extend_to_schemes]) 1); |
2525 | 349 |
qed_spec_mp "free_tv_of_substitutions_extend_to_scheme_lists"; |
350 |
||
351 |
Addsimps [free_tv_of_substitutions_extend_to_scheme_lists]; |
|
352 |
||
353 |
goal thy "!!sch::type_scheme. (n : free_tv sch) = (n mem free_tv_ML sch)"; |
|
354 |
by (type_scheme.induct_tac "sch" 1); |
|
4089 | 355 |
by (ALLGOALS (asm_simp_tac (simpset() addsplits [expand_if]))); |
2525 | 356 |
by (strip_tac 1); |
357 |
by (Fast_tac 1); |
|
358 |
qed "free_tv_ML_scheme"; |
|
359 |
||
360 |
goal thy "!!A::type_scheme list. (n : free_tv A) = (n mem free_tv_ML A)"; |
|
361 |
by (list.induct_tac "A" 1); |
|
362 |
by (Simp_tac 1); |
|
4089 | 363 |
by (asm_simp_tac (simpset() addsimps [free_tv_ML_scheme]) 1); |
2525 | 364 |
qed "free_tv_ML_scheme_list"; |
365 |
||
366 |
||
367 |
(* lemmata for bound_tv *) |
|
368 |
||
369 |
goal thy "!!t. bound_tv (mk_scheme t) = {}"; |
|
370 |
by (typ.induct_tac "t" 1); |
|
371 |
by (ALLGOALS Asm_simp_tac); |
|
372 |
qed "bound_tv_mk_scheme"; |
|
373 |
||
374 |
Addsimps [bound_tv_mk_scheme]; |
|
375 |
||
376 |
goal thy "!!sch::type_scheme. bound_tv ($ S sch) = bound_tv sch"; |
|
377 |
by (type_scheme.induct_tac "sch" 1); |
|
378 |
by (ALLGOALS Asm_simp_tac); |
|
379 |
qed "bound_tv_subst_scheme"; |
|
380 |
||
381 |
Addsimps [bound_tv_subst_scheme]; |
|
382 |
||
383 |
goal thy "!!A::type_scheme list. bound_tv ($ S A) = bound_tv A"; |
|
384 |
by (rtac list.induct 1); |
|
385 |
by (Simp_tac 1); |
|
386 |
by (Asm_simp_tac 1); |
|
387 |
qed "bound_tv_subst_scheme_list"; |
|
388 |
||
389 |
Addsimps [bound_tv_subst_scheme_list]; |
|
390 |
||
391 |
||
392 |
(* lemmata for new_tv *) |
|
393 |
||
394 |
goalw thy [new_tv_def] |
|
395 |
"new_tv n S = ((!m. n <= m --> (S m = TVar m)) & \ |
|
396 |
\ (! l. l < n --> new_tv n (S l) ))"; |
|
3385
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
397 |
by (safe_tac HOL_cs ); |
2525 | 398 |
(* ==> *) |
4089 | 399 |
by (fast_tac (HOL_cs addDs [leD] addss (simpset() addsimps [free_tv_subst,dom_def])) 1); |
3385
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
400 |
by (subgoal_tac "m:cod S | S l = TVar l" 1); |
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
401 |
by (safe_tac HOL_cs ); |
4089 | 402 |
by (fast_tac (HOL_cs addDs [UnI2] addss (simpset() addsimps [free_tv_subst])) 1); |
3018 | 403 |
by (dres_inst_tac [("P","%x. m:free_tv x")] subst 1 THEN atac 1); |
404 |
by (Asm_full_simp_tac 1); |
|
4089 | 405 |
by (fast_tac (set_cs addss (simpset() addsimps [free_tv_subst,cod_def,dom_def])) 1); |
2525 | 406 |
(* <== *) |
3385
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
407 |
by (rewrite_goals_tac [free_tv_subst,cod_def,dom_def] ); |
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
408 |
by (safe_tac set_cs ); |
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
409 |
by (cut_inst_tac [("m","m"),("n","n")] less_linear 1); |
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
410 |
by (fast_tac (HOL_cs addSIs [less_or_eq_imp_le]) 1); |
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
411 |
by (cut_inst_tac [("m","ma"),("n","n")] less_linear 1); |
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
412 |
by (fast_tac (HOL_cs addSIs [less_or_eq_imp_le]) 1); |
2525 | 413 |
qed "new_tv_subst"; |
414 |
||
415 |
goal thy |
|
416 |
"new_tv n = list_all (new_tv n)"; |
|
417 |
by (rtac ext 1); |
|
3018 | 418 |
by (list.induct_tac "x" 1); |
419 |
by (ALLGOALS Asm_simp_tac); |
|
2525 | 420 |
qed "new_tv_list"; |
421 |
||
422 |
(* substitution affects only variables occurring freely *) |
|
423 |
goal thy |
|
424 |
"new_tv n (t::typ) --> $(%x. if x=n then t' else S x) t = $S t"; |
|
425 |
by (typ.induct_tac "t" 1); |
|
4089 | 426 |
by (ALLGOALS(asm_simp_tac (simpset() addsplits [expand_if]))); |
2525 | 427 |
qed "subst_te_new_tv"; |
428 |
Addsimps [subst_te_new_tv]; |
|
429 |
||
430 |
goal thy |
|
431 |
"new_tv n (sch::type_scheme) --> $(%x. if x=n then sch' else S x) sch = $S sch"; |
|
432 |
by (type_scheme.induct_tac "sch" 1); |
|
4089 | 433 |
by (ALLGOALS(asm_simp_tac (simpset() addsplits [expand_if]))); |
2525 | 434 |
qed_spec_mp "subst_te_new_type_scheme"; |
435 |
Addsimps [subst_te_new_type_scheme]; |
|
436 |
||
437 |
goal thy |
|
438 |
"new_tv n (A::type_scheme list) --> $(%x. if x=n then t else S x) A = $S A"; |
|
439 |
by (list.induct_tac "A" 1); |
|
440 |
by (ALLGOALS Asm_full_simp_tac); |
|
441 |
qed_spec_mp "subst_tel_new_scheme_list"; |
|
442 |
Addsimps [subst_tel_new_scheme_list]; |
|
443 |
||
444 |
(* all greater variables are also new *) |
|
445 |
goalw thy [new_tv_def] |
|
446 |
"!!n m. n<=m ==> new_tv n t ==> new_tv m t"; |
|
4153 | 447 |
by Safe_tac; |
2525 | 448 |
by (dtac spec 1); |
449 |
by (mp_tac 1); |
|
450 |
by (trans_tac 1); |
|
451 |
qed "new_tv_le"; |
|
452 |
Addsimps [lessI RS less_imp_le RS new_tv_le]; |
|
453 |
||
454 |
goal thy "!!n m. n<=m ==> new_tv n (t::typ) ==> new_tv m t"; |
|
4089 | 455 |
by (asm_simp_tac (simpset() addsimps [new_tv_le]) 1); |
2525 | 456 |
qed "new_tv_typ_le"; |
457 |
||
458 |
goal thy "!!n m. n<=m ==> new_tv n (A::type_scheme list) ==> new_tv m A"; |
|
4089 | 459 |
by (asm_simp_tac (simpset() addsimps [new_tv_le]) 1); |
2525 | 460 |
qed "new_scheme_list_le"; |
461 |
||
462 |
goal thy "!!n m. n<=m ==> new_tv n (S::subst) ==> new_tv m S"; |
|
4089 | 463 |
by (asm_simp_tac (simpset() addsimps [new_tv_le]) 1); |
2525 | 464 |
qed "new_tv_subst_le"; |
465 |
||
466 |
(* new_tv property remains if a substitution is applied *) |
|
467 |
goal thy |
|
468 |
"!!n. [| n<m; new_tv m (S::subst) |] ==> new_tv m (S n)"; |
|
4089 | 469 |
by (asm_full_simp_tac (simpset() addsimps [new_tv_subst]) 1); |
2525 | 470 |
qed "new_tv_subst_var"; |
471 |
||
472 |
goal thy |
|
473 |
"new_tv n S --> new_tv n (t::typ) --> new_tv n ($ S t)"; |
|
474 |
by (typ.induct_tac "t" 1); |
|
4089 | 475 |
by (ALLGOALS(fast_tac (HOL_cs addss (simpset() addsimps [new_tv_subst])))); |
2525 | 476 |
qed_spec_mp "new_tv_subst_te"; |
477 |
Addsimps [new_tv_subst_te]; |
|
478 |
||
479 |
goal thy "new_tv n S --> new_tv n (sch::type_scheme) --> new_tv n ($ S sch)"; |
|
480 |
by (type_scheme.induct_tac "sch" 1); |
|
481 |
by (ALLGOALS (Asm_full_simp_tac)); |
|
3008 | 482 |
by (rewtac new_tv_def); |
4089 | 483 |
by (simp_tac (simpset() addsimps [free_tv_subst,dom_def,cod_def]) 1); |
2525 | 484 |
by (strip_tac 1); |
485 |
by (case_tac "S nat = TVar nat" 1); |
|
486 |
by (rotate_tac 3 1); |
|
487 |
by (Asm_full_simp_tac 1); |
|
488 |
by (dres_inst_tac [("x","m")] spec 1); |
|
489 |
by (Fast_tac 1); |
|
490 |
qed_spec_mp "new_tv_subst_type_scheme"; |
|
491 |
Addsimps [new_tv_subst_type_scheme]; |
|
492 |
||
493 |
goal thy |
|
494 |
"new_tv n S --> new_tv n (A::type_scheme list) --> new_tv n ($ S A)"; |
|
495 |
by (list.induct_tac "A" 1); |
|
4089 | 496 |
by (ALLGOALS(fast_tac (HOL_cs addss (simpset())))); |
2525 | 497 |
qed_spec_mp "new_tv_subst_scheme_list"; |
498 |
Addsimps [new_tv_subst_scheme_list]; |
|
499 |
||
500 |
goal thy |
|
501 |
"new_tv n A --> new_tv (Suc n) ((TVar n)#A)"; |
|
4089 | 502 |
by (simp_tac (simpset() addsimps [new_tv_list]) 1); |
2525 | 503 |
by (list.induct_tac "A" 1); |
504 |
by (ALLGOALS Asm_full_simp_tac); |
|
505 |
qed "new_tv_Suc_list"; |
|
506 |
||
507 |
goalw thy [new_tv_def] "!!sch::type_scheme. (free_tv sch) = (free_tv sch') --> (new_tv n sch --> new_tv n sch')"; |
|
508 |
by (Asm_simp_tac 1); |
|
509 |
qed_spec_mp "new_tv_only_depends_on_free_tv_type_scheme"; |
|
510 |
||
511 |
goalw thy [new_tv_def] "!!A::type_scheme list. (free_tv A) = (free_tv A') --> (new_tv n A --> new_tv n A')"; |
|
512 |
by (Asm_simp_tac 1); |
|
513 |
qed_spec_mp "new_tv_only_depends_on_free_tv_scheme_list"; |
|
514 |
||
4502 | 515 |
goalw thy [new_tv_def] |
516 |
"!!A. !nat. nat < length A --> new_tv n A --> (new_tv n (A!nat))"; |
|
2525 | 517 |
by (list.induct_tac "A" 1); |
518 |
by (Asm_full_simp_tac 1); |
|
519 |
by (rtac allI 1); |
|
520 |
by (res_inst_tac [("n","nat")] nat_induct 1); |
|
521 |
by (strip_tac 1); |
|
522 |
by (Asm_full_simp_tac 1); |
|
523 |
by (Simp_tac 1); |
|
524 |
qed_spec_mp "new_tv_nth_nat_A"; |
|
525 |
||
526 |
||
527 |
(* composition of substitutions preserves new_tv proposition *) |
|
528 |
goal thy |
|
529 |
"!! n. [| new_tv n (S::subst); new_tv n R |] ==> \ |
|
530 |
\ new_tv n (($ R) o S)"; |
|
4089 | 531 |
by (asm_full_simp_tac (simpset() addsimps [new_tv_subst]) 1); |
2525 | 532 |
qed "new_tv_subst_comp_1"; |
533 |
||
534 |
goal thy |
|
535 |
"!! n. [| new_tv n (S::subst); new_tv n R |] ==> \ |
|
536 |
\ new_tv n (%v.$ R (S v))"; |
|
4089 | 537 |
by (asm_full_simp_tac (simpset() addsimps [new_tv_subst]) 1); |
2525 | 538 |
qed "new_tv_subst_comp_2"; |
539 |
||
540 |
Addsimps [new_tv_subst_comp_1,new_tv_subst_comp_2]; |
|
541 |
||
542 |
(* new type variables do not occur freely in a type structure *) |
|
543 |
goalw thy [new_tv_def] |
|
544 |
"!!n. new_tv n A ==> n~:(free_tv A)"; |
|
545 |
by (fast_tac (HOL_cs addEs [less_irrefl]) 1); |
|
546 |
qed "new_tv_not_free_tv"; |
|
547 |
Addsimps [new_tv_not_free_tv]; |
|
548 |
||
549 |
goalw thy [max_def] "!!n::nat. m < n ==> m < max n n'"; |
|
4089 | 550 |
by (simp_tac (simpset() addsplits [expand_if]) 1); |
4153 | 551 |
by Safe_tac; |
2525 | 552 |
by (trans_tac 1); |
553 |
qed "less_maxL"; |
|
554 |
||
555 |
goalw thy [max_def] "!!n::nat. m < n' ==> m < max n n'"; |
|
4089 | 556 |
by (simp_tac (simpset() addsplits [expand_if]) 1); |
557 |
by (fast_tac (claset() addDs [not_leE] addIs [less_trans]) 1); |
|
2625 | 558 |
val less_maxR = result(); |
2525 | 559 |
|
560 |
goalw thy [new_tv_def] "!!t::typ. ? n. (new_tv n t)"; |
|
561 |
by (typ.induct_tac "t" 1); |
|
562 |
by (res_inst_tac [("x","Suc nat")] exI 1); |
|
563 |
by (Asm_simp_tac 1); |
|
564 |
by (REPEAT (etac exE 1)); |
|
565 |
by (rename_tac "n'" 1); |
|
566 |
by (res_inst_tac [("x","max n n'")] exI 1); |
|
567 |
by (Simp_tac 1); |
|
4089 | 568 |
by (fast_tac (claset() addIs [less_maxR,less_maxL]) 1); |
2525 | 569 |
qed "fresh_variable_types"; |
570 |
||
571 |
Addsimps [fresh_variable_types]; |
|
572 |
||
573 |
goalw thy [new_tv_def] "!!sch::type_scheme. ? n. (new_tv n sch)"; |
|
574 |
by (type_scheme.induct_tac "sch" 1); |
|
575 |
by (res_inst_tac [("x","Suc nat")] exI 1); |
|
576 |
by (Simp_tac 1); |
|
577 |
by (res_inst_tac [("x","Suc nat")] exI 1); |
|
578 |
by (Simp_tac 1); |
|
579 |
by (REPEAT (etac exE 1)); |
|
580 |
by (rename_tac "n'" 1); |
|
581 |
by (res_inst_tac [("x","max n n'")] exI 1); |
|
582 |
by (Simp_tac 1); |
|
4089 | 583 |
by (fast_tac (claset() addIs [less_maxR,less_maxL]) 1); |
2525 | 584 |
qed "fresh_variable_type_schemes"; |
585 |
||
586 |
Addsimps [fresh_variable_type_schemes]; |
|
587 |
||
588 |
goalw thy [max_def] "!!n::nat. n <= (max n n')"; |
|
4089 | 589 |
by (simp_tac (simpset() addsplits [expand_if]) 1); |
2625 | 590 |
val le_maxL = result(); |
2525 | 591 |
|
592 |
goalw thy [max_def] "!!n'::nat. n' <= (max n n')"; |
|
4089 | 593 |
by (simp_tac (simpset() addsplits [expand_if]) 1); |
594 |
by (fast_tac (claset() addDs [not_leE] addIs [less_or_eq_imp_le]) 1); |
|
2625 | 595 |
val le_maxR = result(); |
2525 | 596 |
|
597 |
goal thy "!!A::type_scheme list. ? n. (new_tv n A)"; |
|
598 |
by (list.induct_tac "A" 1); |
|
599 |
by (Simp_tac 1); |
|
600 |
by (Simp_tac 1); |
|
601 |
by (etac exE 1); |
|
602 |
by (cut_inst_tac [("sch","a")] fresh_variable_type_schemes 1); |
|
603 |
by (etac exE 1); |
|
604 |
by (rename_tac "n'" 1); |
|
605 |
by (res_inst_tac [("x","(max n n')")] exI 1); |
|
606 |
by (subgoal_tac "n <= (max n n')" 1); |
|
607 |
by (subgoal_tac "n' <= (max n n')" 1); |
|
4089 | 608 |
by (fast_tac (claset() addDs [new_tv_le]) 1); |
609 |
by (ALLGOALS (simp_tac (simpset() addsimps [le_maxR,le_maxL]))); |
|
2525 | 610 |
qed "fresh_variable_type_scheme_lists"; |
611 |
||
612 |
Addsimps [fresh_variable_type_scheme_lists]; |
|
613 |
||
614 |
goal thy "!!x y. [| ? n1. (new_tv n1 x); ? n2. (new_tv n2 y)|] ==> ? n. (new_tv n x) & (new_tv n y)"; |
|
615 |
by (REPEAT (etac exE 1)); |
|
616 |
by (rename_tac "n1 n2" 1); |
|
617 |
by (res_inst_tac [("x","(max n1 n2)")] exI 1); |
|
618 |
by (subgoal_tac "n1 <= max n1 n2" 1); |
|
619 |
by (subgoal_tac "n2 <= max n1 n2" 1); |
|
4089 | 620 |
by (fast_tac (claset() addDs [new_tv_le]) 1); |
621 |
by (ALLGOALS (simp_tac (simpset() addsimps [le_maxL,le_maxR]))); |
|
2525 | 622 |
qed "make_one_new_out_of_two"; |
623 |
||
624 |
goal thy "!!(A::type_scheme list) (A'::type_scheme list) (t::typ) (t'::typ). \ |
|
625 |
\ ? n. (new_tv n A) & (new_tv n A') & (new_tv n t) & (new_tv n t')" ; |
|
626 |
by (cut_inst_tac [("t","t")] fresh_variable_types 1); |
|
627 |
by (cut_inst_tac [("t","t'")] fresh_variable_types 1); |
|
628 |
by (dtac make_one_new_out_of_two 1); |
|
3018 | 629 |
by (assume_tac 1); |
2525 | 630 |
by (thin_tac "? n. new_tv n t'" 1); |
631 |
by (cut_inst_tac [("A","A")] fresh_variable_type_scheme_lists 1); |
|
632 |
by (cut_inst_tac [("A","A'")] fresh_variable_type_scheme_lists 1); |
|
633 |
by (rotate_tac 1 1); |
|
634 |
by (dtac make_one_new_out_of_two 1); |
|
3018 | 635 |
by (assume_tac 1); |
2525 | 636 |
by (thin_tac "? n. new_tv n A'" 1); |
637 |
by (REPEAT (etac exE 1)); |
|
638 |
by (rename_tac "n2 n1" 1); |
|
639 |
by (res_inst_tac [("x","(max n1 n2)")] exI 1); |
|
3008 | 640 |
by (rewtac new_tv_def); |
4089 | 641 |
by (fast_tac (claset() addIs [less_maxL,less_maxR]) 1); |
2525 | 642 |
qed "ex_fresh_variable"; |
643 |
||
644 |
(* mgu does not introduce new type variables *) |
|
645 |
goalw thy [new_tv_def] |
|
646 |
"!! n. [|mgu t1 t2 = Some u; new_tv n t1; new_tv n t2|] ==> \ |
|
647 |
\ new_tv n u"; |
|
3385
f59e64fe4058
New statement and proof of free_tv_subst_var in order to cope with new
paulson
parents:
3018
diff
changeset
|
648 |
by (fast_tac (set_cs addDs [mgu_free]) 1); |
2525 | 649 |
qed "mgu_new"; |
650 |
||
651 |
||
652 |
(* lemmata for substitutions *) |
|
653 |
||
3438
8d63ff01d37e
Type constraint added to ensure that "length" refers to lists. Maybe should
paulson
parents:
3385
diff
changeset
|
654 |
goalw Type.thy [app_subst_list] |
8d63ff01d37e
Type constraint added to ensure that "length" refers to lists. Maybe should
paulson
parents:
3385
diff
changeset
|
655 |
"!!A:: ('a::type_struct) list. length ($ S A) = length A"; |
3018 | 656 |
by (Simp_tac 1); |
2525 | 657 |
qed "length_app_subst_list"; |
658 |
Addsimps [length_app_subst_list]; |
|
659 |
||
660 |
goal thy "!!sch::type_scheme. $ TVar sch = sch"; |
|
661 |
by (type_scheme.induct_tac "sch" 1); |
|
662 |
by (ALLGOALS Asm_simp_tac); |
|
663 |
qed "subst_TVar_scheme"; |
|
664 |
||
665 |
Addsimps [subst_TVar_scheme]; |
|
666 |
||
667 |
goal thy "!!A::type_scheme list. $ TVar A = A"; |
|
668 |
by (rtac list.induct 1); |
|
4089 | 669 |
by (ALLGOALS (asm_full_simp_tac (simpset() addsimps [app_subst_list]))); |
2525 | 670 |
qed "subst_TVar_scheme_list"; |
671 |
||
672 |
Addsimps [subst_TVar_scheme_list]; |
|
673 |
||
674 |
(* application of id_subst does not change type expression *) |
|
675 |
goalw thy [id_subst_def] |
|
3842 | 676 |
"$ id_subst = (%t::typ. t)"; |
2525 | 677 |
by (rtac ext 1); |
678 |
by (typ.induct_tac "t" 1); |
|
679 |
by (ALLGOALS Asm_simp_tac); |
|
680 |
qed "app_subst_id_te"; |
|
681 |
Addsimps [app_subst_id_te]; |
|
682 |
||
683 |
goalw thy [id_subst_def] |
|
3842 | 684 |
"$ id_subst = (%sch::type_scheme. sch)"; |
2525 | 685 |
by (rtac ext 1); |
686 |
by (type_scheme.induct_tac "t" 1); |
|
687 |
by (ALLGOALS Asm_simp_tac); |
|
688 |
qed "app_subst_id_type_scheme"; |
|
689 |
Addsimps [app_subst_id_type_scheme]; |
|
690 |
||
691 |
(* application of id_subst does not change list of type expressions *) |
|
692 |
goalw thy [app_subst_list] |
|
3842 | 693 |
"$ id_subst = (%A::type_scheme list. A)"; |
2525 | 694 |
by (rtac ext 1); |
695 |
by (list.induct_tac "A" 1); |
|
696 |
by (ALLGOALS Asm_simp_tac); |
|
697 |
qed "app_subst_id_tel"; |
|
698 |
Addsimps [app_subst_id_tel]; |
|
699 |
||
700 |
goal thy "!!sch::type_scheme. $ id_subst sch = sch"; |
|
701 |
by (type_scheme.induct_tac "sch" 1); |
|
4089 | 702 |
by (ALLGOALS (asm_full_simp_tac (simpset() addsimps [id_subst_def]))); |
2525 | 703 |
qed "id_subst_sch"; |
704 |
||
705 |
Addsimps [id_subst_sch]; |
|
706 |
||
707 |
goal thy "!!A::type_scheme list. $ id_subst A = A"; |
|
708 |
by (list.induct_tac "A" 1); |
|
709 |
by (Asm_full_simp_tac 1); |
|
710 |
by (Asm_full_simp_tac 1); |
|
711 |
qed "id_subst_A"; |
|
712 |
||
713 |
Addsimps [id_subst_A]; |
|
714 |
||
715 |
(* composition of substitutions *) |
|
716 |
goalw Type.thy [id_subst_def,o_def] "$S o id_subst = S"; |
|
3018 | 717 |
by (rtac ext 1); |
718 |
by (Simp_tac 1); |
|
2525 | 719 |
qed "o_id_subst"; |
720 |
Addsimps[o_id_subst]; |
|
721 |
||
722 |
goal thy |
|
723 |
"$ R ($ S t::typ) = $ (%x. $ R (S x) ) t"; |
|
724 |
by (typ.induct_tac "t" 1); |
|
725 |
by (ALLGOALS Asm_simp_tac); |
|
726 |
qed "subst_comp_te"; |
|
727 |
||
728 |
goal thy |
|
729 |
"$ R ($ S sch::type_scheme) = $ (%x. $ R (S x) ) sch"; |
|
730 |
by (type_scheme.induct_tac "sch" 1); |
|
731 |
by (ALLGOALS Asm_full_simp_tac); |
|
732 |
qed "subst_comp_type_scheme"; |
|
733 |
||
734 |
goalw thy [app_subst_list] |
|
735 |
"$ R ($ S A::type_scheme list) = $ (%x. $ R (S x)) A"; |
|
736 |
by (list.induct_tac "A" 1); |
|
737 |
(* case [] *) |
|
738 |
by (Simp_tac 1); |
|
739 |
(* case x#xl *) |
|
4089 | 740 |
by (asm_full_simp_tac (simpset() addsimps [subst_comp_type_scheme]) 1); |
2525 | 741 |
qed "subst_comp_scheme_list"; |
742 |
||
743 |
goal thy "!!A::type_scheme list. !x : free_tv A. S x = (TVar x) ==> $ S A = $ id_subst A"; |
|
744 |
by (rtac scheme_list_substitutions_only_on_free_variables 1); |
|
4089 | 745 |
by (asm_full_simp_tac (simpset() addsimps [id_subst_def]) 1); |
2525 | 746 |
qed "subst_id_on_type_scheme_list'"; |
747 |
||
748 |
goal thy "!!A::type_scheme list. !x : free_tv A. S x = (TVar x) ==> $ S A = A"; |
|
749 |
by (stac subst_id_on_type_scheme_list' 1); |
|
3018 | 750 |
by (assume_tac 1); |
2525 | 751 |
by (Simp_tac 1); |
752 |
qed "subst_id_on_type_scheme_list"; |
|
753 |
||
4502 | 754 |
goal thy "!n. n < length A --> ($ S A)!n = $S (A!n)"; |
2525 | 755 |
by (list.induct_tac "A" 1); |
756 |
by (Asm_full_simp_tac 1); |
|
757 |
by (rtac allI 1); |
|
758 |
by (rename_tac "n1" 1); |
|
759 |
by (res_inst_tac[("n","n1")] nat_induct 1); |
|
760 |
by (Asm_full_simp_tac 1); |
|
761 |
by (Asm_full_simp_tac 1); |
|
762 |
qed_spec_mp "nth_subst"; |