1269
|
1 |
(* Title: HOL/Lambda/Lambda.ML
|
1120
|
2 |
ID: $Id$
|
|
3 |
Author: Tobias Nipkow
|
|
4 |
Copyright 1995 TU Muenchen
|
|
5 |
|
|
6 |
Substitution-lemmas. Most of the proofs, esp. those about natural numbers,
|
|
7 |
are ported from Ole Rasmussen's ZF development. In ZF, m<=n is syntactic
|
|
8 |
sugar for m<Suc(n). In HOL <= is a separate operator. Hence we have to prove
|
|
9 |
some compatibility lemmas.
|
|
10 |
*)
|
|
11 |
|
|
12 |
(*** Nat ***)
|
|
13 |
|
|
14 |
goal Nat.thy "!!i. [| i < Suc j; j < k |] ==> i < k";
|
|
15 |
br le_less_trans 1;
|
|
16 |
ba 2;
|
1266
|
17 |
by(asm_full_simp_tac (!simpset addsimps [le_def]) 1);
|
1120
|
18 |
by(fast_tac (HOL_cs addEs [less_asym,less_anti_refl]) 1);
|
|
19 |
qed "lt_trans1";
|
|
20 |
|
|
21 |
goal Nat.thy "!!i. [| i < j; j < Suc(k) |] ==> i < k";
|
|
22 |
be less_le_trans 1;
|
1266
|
23 |
by(asm_full_simp_tac (!simpset addsimps [le_def]) 1);
|
1120
|
24 |
by(fast_tac (HOL_cs addEs [less_asym,less_anti_refl]) 1);
|
|
25 |
qed "lt_trans2";
|
|
26 |
|
|
27 |
val major::prems = goal Nat.thy
|
|
28 |
"[| i < Suc j; i < j ==> P; i = j ==> P |] ==> P";
|
|
29 |
br (major RS lessE) 1;
|
1266
|
30 |
by(ALLGOALS Asm_full_simp_tac);
|
1120
|
31 |
by(resolve_tac prems 1 THEN etac sym 1);
|
|
32 |
by(fast_tac (HOL_cs addIs prems) 1);
|
|
33 |
qed "leqE";
|
|
34 |
|
|
35 |
goal Arith.thy "!!i. Suc i < j ==> i < pred j ";
|
|
36 |
by (resolve_tac [Suc_less_SucD] 1);
|
1302
|
37 |
by (Asm_simp_tac 1);
|
1120
|
38 |
qed "lt_pred";
|
|
39 |
|
|
40 |
goal Arith.thy "!!i. [| i < Suc j; k < i |] ==> pred i < j ";
|
|
41 |
by (resolve_tac [Suc_less_SucD] 1);
|
1302
|
42 |
by (Asm_simp_tac 1);
|
1120
|
43 |
qed "gt_pred";
|
|
44 |
|
1153
|
45 |
|
1120
|
46 |
(*** Lambda ***)
|
|
47 |
|
|
48 |
open Lambda;
|
|
49 |
|
1269
|
50 |
Delsimps [less_Suc_eq, subst_Var];
|
|
51 |
Addsimps ([if_not_P, not_less_eq] @ beta.intrs);
|
1120
|
52 |
|
1302
|
53 |
(* don't add r_into_rtrancl! *)
|
|
54 |
val lambda_cs = trancl_cs addSIs beta.intrs;
|
1120
|
55 |
|
|
56 |
(*** Congruence rules for ->> ***)
|
|
57 |
|
|
58 |
goal Lambda.thy "!!s. s ->> s' ==> Fun s ->> Fun s'";
|
|
59 |
be rtrancl_induct 1;
|
|
60 |
by (ALLGOALS(fast_tac (lambda_cs addIs [rtrancl_refl,rtrancl_into_rtrancl])));
|
|
61 |
qed "rtrancl_beta_Fun";
|
|
62 |
|
|
63 |
goal Lambda.thy "!!s. s ->> s' ==> s @ t ->> s' @ t";
|
|
64 |
be rtrancl_induct 1;
|
|
65 |
by (ALLGOALS(fast_tac (lambda_cs addIs [rtrancl_refl,rtrancl_into_rtrancl])));
|
|
66 |
qed "rtrancl_beta_AppL";
|
|
67 |
|
|
68 |
goal Lambda.thy "!!s. t ->> t' ==> s @ t ->> s @ t'";
|
|
69 |
be rtrancl_induct 1;
|
|
70 |
by (ALLGOALS(fast_tac (lambda_cs addIs [rtrancl_refl,rtrancl_into_rtrancl])));
|
|
71 |
qed "rtrancl_beta_AppR";
|
|
72 |
|
|
73 |
goal Lambda.thy "!!s. [| s ->> s'; t ->> t' |] ==> s @ t ->> s' @ t'";
|
1302
|
74 |
by (fast_tac (lambda_cs addSIs [rtrancl_beta_AppL,rtrancl_beta_AppR]
|
|
75 |
addIs [rtrancl_trans]) 1);
|
1120
|
76 |
qed "rtrancl_beta_App";
|
|
77 |
|
|
78 |
(*** subst and lift ***)
|
|
79 |
|
1269
|
80 |
fun addsplit ss = ss addsimps [subst_Var] setloop (split_tac [expand_if]);
|
1120
|
81 |
|
1153
|
82 |
goal Lambda.thy "(Var k)[u/k] = u";
|
1269
|
83 |
by (asm_full_simp_tac(addsplit(!simpset)) 1);
|
1120
|
84 |
qed "subst_eq";
|
|
85 |
|
1153
|
86 |
goal Lambda.thy "!!s. i<j ==> (Var j)[u/i] = Var(pred j)";
|
1269
|
87 |
by (asm_full_simp_tac(addsplit(!simpset)) 1);
|
1120
|
88 |
qed "subst_gt";
|
|
89 |
|
1153
|
90 |
goal Lambda.thy "!!s. j<i ==> (Var j)[u/i] = Var(j)";
|
1269
|
91 |
by (asm_full_simp_tac (addsplit(!simpset) addsimps
|
1120
|
92 |
[less_not_refl2 RS not_sym,less_SucI]) 1);
|
|
93 |
qed "subst_lt";
|
|
94 |
|
1266
|
95 |
Addsimps [subst_eq,subst_gt,subst_lt];
|
1120
|
96 |
|
|
97 |
goal Lambda.thy
|
1172
|
98 |
"!i k. i < Suc k --> lift (lift t i) (Suc k) = lift (lift t k) i";
|
|
99 |
by(db.induct_tac "t" 1);
|
1269
|
100 |
by(ALLGOALS Asm_simp_tac);
|
1120
|
101 |
by(strip_tac 1);
|
|
102 |
by (excluded_middle_tac "nat < i" 1);
|
|
103 |
by ((forward_tac [lt_trans2] 2) THEN (assume_tac 2));
|
1269
|
104 |
by (ALLGOALS(asm_full_simp_tac (addsplit(!simpset) addsimps [less_SucI])));
|
1288
|
105 |
bind_thm("lift_lift", result() RS spec RS spec RS mp);
|
1120
|
106 |
|
1153
|
107 |
goal Lambda.thy "!i j s. j < Suc i --> \
|
|
108 |
\ lift (t[s/j]) i = (lift t (Suc i)) [lift s i / j]";
|
1120
|
109 |
by(db.induct_tac "t" 1);
|
1269
|
110 |
by(ALLGOALS(asm_simp_tac (!simpset addsimps [lift_lift])));
|
1120
|
111 |
by(strip_tac 1);
|
1153
|
112 |
by (excluded_middle_tac "nat < j" 1);
|
1269
|
113 |
by (Asm_full_simp_tac 1);
|
1120
|
114 |
by (eres_inst_tac [("j","nat")] leqE 1);
|
1269
|
115 |
by (asm_full_simp_tac (addsplit(!simpset)
|
1302
|
116 |
addsimps [less_SucI,gt_pred]) 1);
|
1120
|
117 |
by (hyp_subst_tac 1);
|
1266
|
118 |
by (Asm_simp_tac 1);
|
1153
|
119 |
by (forw_inst_tac [("j","j")] lt_trans2 1);
|
1120
|
120 |
by (assume_tac 1);
|
1269
|
121 |
by (asm_full_simp_tac (addsplit(!simpset) addsimps [less_SucI]) 1);
|
1120
|
122 |
qed "lift_subst";
|
1266
|
123 |
Addsimps [lift_subst];
|
1120
|
124 |
|
|
125 |
goal Lambda.thy
|
1172
|
126 |
"!i j s. i < Suc j -->\
|
|
127 |
\ lift (t[s/j]) i = (lift t i) [lift s i / Suc j]";
|
|
128 |
by(db.induct_tac "t" 1);
|
1269
|
129 |
by(ALLGOALS(asm_simp_tac (!simpset addsimps [lift_lift])));
|
1120
|
130 |
by(strip_tac 1);
|
1153
|
131 |
by (excluded_middle_tac "nat < j" 1);
|
1269
|
132 |
by (Asm_full_simp_tac 1);
|
1153
|
133 |
by (eres_inst_tac [("i","j")] leqE 1);
|
1120
|
134 |
by (forward_tac [lt_trans1] 1 THEN assume_tac 1);
|
1269
|
135 |
by (ALLGOALS(asm_full_simp_tac
|
1302
|
136 |
(!simpset addsimps [less_SucI,gt_pred])));
|
1120
|
137 |
by (hyp_subst_tac 1);
|
1269
|
138 |
by (asm_full_simp_tac (!simpset addsimps [less_SucI]) 1);
|
1120
|
139 |
by(split_tac [expand_if] 1);
|
1266
|
140 |
by (asm_full_simp_tac (!simpset addsimps [less_SucI]) 1);
|
1120
|
141 |
qed "lift_subst_lt";
|
|
142 |
|
1172
|
143 |
goal Lambda.thy "!k s. (lift t k)[s/k] = t";
|
|
144 |
by(db.induct_tac "t" 1);
|
1266
|
145 |
by(ALLGOALS Asm_simp_tac);
|
1120
|
146 |
by(split_tac [expand_if] 1);
|
1266
|
147 |
by(ALLGOALS Asm_full_simp_tac);
|
1120
|
148 |
qed "subst_lift";
|
1266
|
149 |
Addsimps [subst_lift];
|
1120
|
150 |
|
|
151 |
|
1172
|
152 |
goal Lambda.thy "!i j u v. i < Suc j --> \
|
|
153 |
\ t[lift v i / Suc j][u[v/j]/i] = t[u/i][v/j]";
|
|
154 |
by(db.induct_tac "t" 1);
|
1288
|
155 |
by(ALLGOALS(asm_simp_tac(!simpset addsimps [lift_lift RS sym,lift_subst_lt])));
|
1120
|
156 |
by(strip_tac 1);
|
1153
|
157 |
by (excluded_middle_tac "nat < Suc(Suc j)" 1);
|
1269
|
158 |
by(Asm_full_simp_tac 1);
|
1120
|
159 |
by (forward_tac [lessI RS less_trans] 1);
|
|
160 |
by (eresolve_tac [leqE] 1);
|
1302
|
161 |
by (asm_simp_tac (!simpset addsimps [lt_pred]) 2);
|
1120
|
162 |
by (forward_tac [Suc_mono RS less_trans] 1 THEN assume_tac 1);
|
1153
|
163 |
by (forw_inst_tac [("i","i")] (lessI RS less_trans) 1);
|
1302
|
164 |
by (asm_simp_tac (!simpset addsimps [lt_pred]) 1);
|
1120
|
165 |
by (eres_inst_tac [("i","nat")] leqE 1);
|
1302
|
166 |
by (asm_full_simp_tac (!simpset addsimps [less_SucI]) 2);
|
1153
|
167 |
by (excluded_middle_tac "nat < i" 1);
|
1269
|
168 |
by (Asm_full_simp_tac 1);
|
1120
|
169 |
by (eres_inst_tac [("j","nat")] leqE 1);
|
1266
|
170 |
by (asm_simp_tac (!simpset addsimps [gt_pred]) 1);
|
|
171 |
by (Asm_simp_tac 1);
|
1120
|
172 |
by (forward_tac [lt_trans2] 1 THEN assume_tac 1);
|
1266
|
173 |
by (asm_simp_tac (!simpset addsimps [gt_pred]) 1);
|
1120
|
174 |
bind_thm("subst_subst", result() RS spec RS spec RS spec RS spec RS mp);
|
1153
|
175 |
|
|
176 |
|
|
177 |
(*** Equivalence proof for optimized substitution ***)
|
|
178 |
|
|
179 |
goal Lambda.thy "!k. liftn 0 t k = t";
|
|
180 |
by(db.induct_tac "t" 1);
|
1269
|
181 |
by(ALLGOALS(asm_simp_tac(addsplit(!simpset))));
|
1153
|
182 |
qed "liftn_0";
|
1266
|
183 |
Addsimps [liftn_0];
|
1153
|
184 |
|
|
185 |
goal Lambda.thy "!k. liftn (Suc n) t k = lift (liftn n t k) k";
|
|
186 |
by(db.induct_tac "t" 1);
|
1269
|
187 |
by(ALLGOALS(asm_simp_tac(addsplit(!simpset))));
|
1153
|
188 |
by(fast_tac (HOL_cs addDs [add_lessD1]) 1);
|
|
189 |
qed "liftn_lift";
|
1266
|
190 |
Addsimps [liftn_lift];
|
1153
|
191 |
|
|
192 |
goal Lambda.thy "!n. substn t s n = t[liftn n s 0 / n]";
|
|
193 |
by(db.induct_tac "t" 1);
|
1269
|
194 |
by(ALLGOALS(asm_simp_tac(addsplit(!simpset))));
|
1153
|
195 |
qed "substn_subst_n";
|
1266
|
196 |
Addsimps [substn_subst_n];
|
1153
|
197 |
|
|
198 |
goal Lambda.thy "substn t s 0 = t[s/0]";
|
1266
|
199 |
by(Simp_tac 1);
|
1153
|
200 |
qed "substn_subst_0";
|