13 (*** Nat ***) |
13 (*** Nat ***) |
14 |
14 |
15 goal Nat.thy "!!i. [| i < Suc j; j < k |] ==> i < k"; |
15 goal Nat.thy "!!i. [| i < Suc j; j < k |] ==> i < k"; |
16 br le_less_trans 1; |
16 br le_less_trans 1; |
17 ba 2; |
17 ba 2; |
18 by(asm_full_simp_tac (nat_ss addsimps [le_def]) 1); |
18 by(asm_full_simp_tac (!simpset addsimps [le_def]) 1); |
19 by(fast_tac (HOL_cs addEs [less_asym,less_anti_refl]) 1); |
19 by(fast_tac (HOL_cs addEs [less_asym,less_anti_refl]) 1); |
20 qed "lt_trans1"; |
20 qed "lt_trans1"; |
21 |
21 |
22 goal Nat.thy "!!i. [| i < j; j < Suc(k) |] ==> i < k"; |
22 goal Nat.thy "!!i. [| i < j; j < Suc(k) |] ==> i < k"; |
23 be less_le_trans 1; |
23 be less_le_trans 1; |
24 by(asm_full_simp_tac (nat_ss addsimps [le_def]) 1); |
24 by(asm_full_simp_tac (!simpset addsimps [le_def]) 1); |
25 by(fast_tac (HOL_cs addEs [less_asym,less_anti_refl]) 1); |
25 by(fast_tac (HOL_cs addEs [less_asym,less_anti_refl]) 1); |
26 qed "lt_trans2"; |
26 qed "lt_trans2"; |
27 |
27 |
28 val major::prems = goal Nat.thy |
28 val major::prems = goal Nat.thy |
29 "[| i < Suc j; i < j ==> P; i = j ==> P |] ==> P"; |
29 "[| i < Suc j; i < j ==> P; i = j ==> P |] ==> P"; |
30 br (major RS lessE) 1; |
30 br (major RS lessE) 1; |
31 by(ALLGOALS(asm_full_simp_tac nat_ss)); |
31 by(ALLGOALS Asm_full_simp_tac); |
32 by(resolve_tac prems 1 THEN etac sym 1); |
32 by(resolve_tac prems 1 THEN etac sym 1); |
33 by(fast_tac (HOL_cs addIs prems) 1); |
33 by(fast_tac (HOL_cs addIs prems) 1); |
34 qed "leqE"; |
34 qed "leqE"; |
35 |
35 |
36 goal Arith.thy "!!i. i < j ==> Suc(pred j) = j"; |
36 goal Arith.thy "!!i. i < j ==> Suc(pred j) = j"; |
37 by(fast_tac (HOL_cs addEs [lessE] addss arith_ss) 1); |
37 by(fast_tac (HOL_cs addEs [lessE] addss !simpset) 1); |
38 qed "Suc_pred"; |
38 qed "Suc_pred"; |
39 |
39 |
40 goal Arith.thy "!!i. Suc i < j ==> i < pred j "; |
40 goal Arith.thy "!!i. Suc i < j ==> i < pred j "; |
41 by (resolve_tac [Suc_less_SucD] 1); |
41 by (resolve_tac [Suc_less_SucD] 1); |
42 by (asm_simp_tac (arith_ss addsimps [Suc_pred]) 1); |
42 by (asm_simp_tac (!simpset addsimps [Suc_pred]) 1); |
43 qed "lt_pred"; |
43 qed "lt_pred"; |
44 |
44 |
45 goal Arith.thy "!!i. [| i < Suc j; k < i |] ==> pred i < j "; |
45 goal Arith.thy "!!i. [| i < Suc j; k < i |] ==> pred i < j "; |
46 by (resolve_tac [Suc_less_SucD] 1); |
46 by (resolve_tac [Suc_less_SucD] 1); |
47 by (asm_simp_tac (arith_ss addsimps [Suc_pred]) 1); |
47 by (asm_simp_tac (!simpset addsimps [Suc_pred]) 1); |
48 qed "gt_pred"; |
48 qed "gt_pred"; |
49 |
49 |
50 |
50 |
51 (*** Lambda ***) |
51 (*** Lambda ***) |
52 |
52 |
53 open Lambda; |
53 open Lambda; |
54 |
54 |
55 val lambda_ss = arith_ss delsimps [less_Suc_eq] addsimps |
55 Addsimps [if_not_P, not_less_eq]; |
56 db.simps @ beta.intrs @ |
|
57 [if_not_P, not_less_eq, |
|
58 subst_App,subst_Fun, |
|
59 lift_Var,lift_App,lift_Fun]; |
|
60 |
56 |
61 val lambda_cs = HOL_cs addSIs beta.intrs; |
57 val lambda_cs = HOL_cs addSIs beta.intrs; |
62 |
58 |
63 (*** Congruence rules for ->> ***) |
59 (*** Congruence rules for ->> ***) |
64 |
60 |
82 [rtrancl_beta_AppL,rtrancl_beta_AppR,rtrancl_trans]) 1); |
78 [rtrancl_beta_AppL,rtrancl_beta_AppR,rtrancl_trans]) 1); |
83 qed "rtrancl_beta_App"; |
79 qed "rtrancl_beta_App"; |
84 |
80 |
85 (*** subst and lift ***) |
81 (*** subst and lift ***) |
86 |
82 |
87 fun addsplit ss = ss addsimps [subst_Var] setloop (split_tac [expand_if]); |
83 val split_ss = !simpset delsimps [less_Suc_eq,subst_Var] |
|
84 addsimps [subst_Var] |
|
85 setloop (split_tac [expand_if]); |
88 |
86 |
89 goal Lambda.thy "(Var k)[u/k] = u"; |
87 goal Lambda.thy "(Var k)[u/k] = u"; |
90 by (asm_full_simp_tac (addsplit lambda_ss) 1); |
88 by (asm_full_simp_tac split_ss 1); |
91 qed "subst_eq"; |
89 qed "subst_eq"; |
92 |
90 |
93 goal Lambda.thy "!!s. i<j ==> (Var j)[u/i] = Var(pred j)"; |
91 goal Lambda.thy "!!s. i<j ==> (Var j)[u/i] = Var(pred j)"; |
94 by (asm_full_simp_tac (addsplit lambda_ss) 1); |
92 by (asm_full_simp_tac split_ss 1); |
95 qed "subst_gt"; |
93 qed "subst_gt"; |
96 |
94 |
97 goal Lambda.thy "!!s. j<i ==> (Var j)[u/i] = Var(j)"; |
95 goal Lambda.thy "!!s. j<i ==> (Var j)[u/i] = Var(j)"; |
98 by (asm_full_simp_tac (addsplit lambda_ss addsimps |
96 by (asm_full_simp_tac (split_ss addsimps |
99 [less_not_refl2 RS not_sym,less_SucI]) 1); |
97 [less_not_refl2 RS not_sym,less_SucI]) 1); |
100 qed "subst_lt"; |
98 qed "subst_lt"; |
101 |
99 |
102 val lambda_ss = lambda_ss addsimps [subst_eq,subst_gt,subst_lt]; |
100 Addsimps [subst_eq,subst_gt,subst_lt]; |
|
101 val ss = !simpset delsimps [less_Suc_eq, subst_Var]; |
103 |
102 |
104 goal Lambda.thy |
103 goal Lambda.thy |
105 "!i k. i < Suc k --> lift (lift t i) (Suc k) = lift (lift t k) i"; |
104 "!i k. i < Suc k --> lift (lift t i) (Suc k) = lift (lift t k) i"; |
106 by(db.induct_tac "t" 1); |
105 by(db.induct_tac "t" 1); |
107 by(ALLGOALS(asm_simp_tac lambda_ss)); |
106 by(ALLGOALS (asm_simp_tac ss)); |
108 by(strip_tac 1); |
107 by(strip_tac 1); |
109 by (excluded_middle_tac "nat < i" 1); |
108 by (excluded_middle_tac "nat < i" 1); |
110 by ((forward_tac [lt_trans2] 2) THEN (assume_tac 2)); |
109 by ((forward_tac [lt_trans2] 2) THEN (assume_tac 2)); |
111 by (ALLGOALS(asm_full_simp_tac ((addsplit lambda_ss) addsimps [less_SucI]))); |
110 by (ALLGOALS(asm_full_simp_tac (split_ss addsimps [less_SucI]))); |
112 qed"lift_lift"; |
111 qed"lift_lift"; |
113 |
112 |
114 goal Lambda.thy "!i j s. j < Suc i --> \ |
113 goal Lambda.thy "!i j s. j < Suc i --> \ |
115 \ lift (t[s/j]) i = (lift t (Suc i)) [lift s i / j]"; |
114 \ lift (t[s/j]) i = (lift t (Suc i)) [lift s i / j]"; |
116 by(db.induct_tac "t" 1); |
115 by(db.induct_tac "t" 1); |
117 by(ALLGOALS(asm_simp_tac (lambda_ss addsimps [lift_lift]))); |
116 by(ALLGOALS(asm_simp_tac (ss addsimps [lift_lift]))); |
118 by(strip_tac 1); |
117 by(strip_tac 1); |
119 by (excluded_middle_tac "nat < j" 1); |
118 by (excluded_middle_tac "nat < j" 1); |
120 by (asm_full_simp_tac lambda_ss 1); |
119 by (asm_full_simp_tac ss 1); |
121 by (eres_inst_tac [("j","nat")] leqE 1); |
120 by (eres_inst_tac [("j","nat")] leqE 1); |
122 by (asm_full_simp_tac ((addsplit lambda_ss) |
121 by (asm_full_simp_tac (split_ss addsimps [less_SucI,gt_pred,Suc_pred]) 1); |
123 addsimps [less_SucI,gt_pred,Suc_pred]) 1); |
|
124 by (hyp_subst_tac 1); |
122 by (hyp_subst_tac 1); |
125 by (asm_simp_tac lambda_ss 1); |
123 by (Asm_simp_tac 1); |
126 by (forw_inst_tac [("j","j")] lt_trans2 1); |
124 by (forw_inst_tac [("j","j")] lt_trans2 1); |
127 by (assume_tac 1); |
125 by (assume_tac 1); |
128 by (asm_full_simp_tac (addsplit lambda_ss addsimps [less_SucI]) 1); |
126 by (asm_full_simp_tac (split_ss addsimps [less_SucI]) 1); |
129 qed "lift_subst"; |
127 qed "lift_subst"; |
130 val lambda_ss = lambda_ss addsimps [lift_subst]; |
128 Addsimps [lift_subst]; |
131 |
129 |
132 goal Lambda.thy |
130 goal Lambda.thy |
133 "!i j s. i < Suc j -->\ |
131 "!i j s. i < Suc j -->\ |
134 \ lift (t[s/j]) i = (lift t i) [lift s i / Suc j]"; |
132 \ lift (t[s/j]) i = (lift t i) [lift s i / Suc j]"; |
135 by(db.induct_tac "t" 1); |
133 by(db.induct_tac "t" 1); |
136 by(ALLGOALS(asm_simp_tac (lambda_ss addsimps [lift_lift]))); |
134 by(ALLGOALS(asm_simp_tac (ss addsimps [lift_lift]))); |
137 by(strip_tac 1); |
135 by(strip_tac 1); |
138 by (excluded_middle_tac "nat < j" 1); |
136 by (excluded_middle_tac "nat < j" 1); |
139 by (asm_full_simp_tac lambda_ss 1); |
137 by (asm_full_simp_tac ss 1); |
140 by (eres_inst_tac [("i","j")] leqE 1); |
138 by (eres_inst_tac [("i","j")] leqE 1); |
141 by (forward_tac [lt_trans1] 1 THEN assume_tac 1); |
139 by (forward_tac [lt_trans1] 1 THEN assume_tac 1); |
142 by (ALLGOALS(asm_full_simp_tac |
140 by (ALLGOALS(asm_full_simp_tac (ss addsimps [Suc_pred,less_SucI,gt_pred]))); |
143 (lambda_ss addsimps [Suc_pred,less_SucI,gt_pred]))); |
|
144 by (hyp_subst_tac 1); |
141 by (hyp_subst_tac 1); |
145 by (asm_full_simp_tac (lambda_ss addsimps [less_SucI]) 1); |
142 by (asm_full_simp_tac (ss addsimps [less_SucI]) 1); |
146 by(split_tac [expand_if] 1); |
143 by(split_tac [expand_if] 1); |
147 by (asm_full_simp_tac (lambda_ss addsimps [less_SucI]) 1); |
144 by (asm_full_simp_tac (!simpset addsimps [less_SucI]) 1); |
148 qed "lift_subst_lt"; |
145 qed "lift_subst_lt"; |
149 |
146 |
150 goal Lambda.thy "!k s. (lift t k)[s/k] = t"; |
147 goal Lambda.thy "!k s. (lift t k)[s/k] = t"; |
151 by(db.induct_tac "t" 1); |
148 by(db.induct_tac "t" 1); |
152 by(ALLGOALS(asm_simp_tac lambda_ss)); |
149 by(ALLGOALS Asm_simp_tac); |
153 by(split_tac [expand_if] 1); |
150 by(split_tac [expand_if] 1); |
154 by(ALLGOALS(asm_full_simp_tac lambda_ss)); |
151 by(ALLGOALS Asm_full_simp_tac); |
155 qed "subst_lift"; |
152 qed "subst_lift"; |
156 val lambda_ss = lambda_ss addsimps [subst_lift]; |
153 Addsimps [subst_lift]; |
157 |
154 |
158 |
155 |
159 goal Lambda.thy "!i j u v. i < Suc j --> \ |
156 goal Lambda.thy "!i j u v. i < Suc j --> \ |
160 \ t[lift v i / Suc j][u[v/j]/i] = t[u/i][v/j]"; |
157 \ t[lift v i / Suc j][u[v/j]/i] = t[u/i][v/j]"; |
161 by(db.induct_tac "t" 1); |
158 by(db.induct_tac "t" 1); |
162 by (ALLGOALS(asm_simp_tac (lambda_ss addsimps |
159 by (ALLGOALS(asm_simp_tac (ss addsimps |
163 [lift_lift RS spec RS spec RS mp RS sym,lift_subst_lt]))); |
160 [lift_lift RS spec RS spec RS mp RS sym,lift_subst_lt]))); |
164 by(strip_tac 1); |
161 by(strip_tac 1); |
165 by (excluded_middle_tac "nat < Suc(Suc j)" 1); |
162 by (excluded_middle_tac "nat < Suc(Suc j)" 1); |
166 by(asm_full_simp_tac lambda_ss 1); |
163 by(asm_full_simp_tac ss 1); |
167 by (forward_tac [lessI RS less_trans] 1); |
164 by (forward_tac [lessI RS less_trans] 1); |
168 by (eresolve_tac [leqE] 1); |
165 by (eresolve_tac [leqE] 1); |
169 by (asm_simp_tac (lambda_ss addsimps [Suc_pred,lt_pred]) 2); |
166 by (asm_simp_tac (ss addsimps [Suc_pred,lt_pred]) 2); |
170 by (forward_tac [Suc_mono RS less_trans] 1 THEN assume_tac 1); |
167 by (forward_tac [Suc_mono RS less_trans] 1 THEN assume_tac 1); |
171 by (forw_inst_tac [("i","i")] (lessI RS less_trans) 1); |
168 by (forw_inst_tac [("i","i")] (lessI RS less_trans) 1); |
172 by (asm_simp_tac (lambda_ss addsimps [Suc_pred,lt_pred]) 1); |
169 by (asm_simp_tac (ss addsimps [Suc_pred,lt_pred]) 1); |
173 by (eres_inst_tac [("i","nat")] leqE 1); |
170 by (eres_inst_tac [("i","nat")] leqE 1); |
174 by (asm_full_simp_tac (lambda_ss addsimps [Suc_pred,less_SucI]) 2); |
171 by (asm_full_simp_tac (!simpset delsimps [less_Suc_eq] |
|
172 addsimps [Suc_pred,less_SucI]) 2); |
175 by (excluded_middle_tac "nat < i" 1); |
173 by (excluded_middle_tac "nat < i" 1); |
176 by (asm_full_simp_tac lambda_ss 1); |
174 by (asm_full_simp_tac ss 1); |
177 by (eres_inst_tac [("j","nat")] leqE 1); |
175 by (eres_inst_tac [("j","nat")] leqE 1); |
178 by (asm_simp_tac (lambda_ss addsimps [gt_pred]) 1); |
176 by (asm_simp_tac (!simpset addsimps [gt_pred]) 1); |
179 by (asm_simp_tac lambda_ss 1); |
177 by (Asm_simp_tac 1); |
180 by (forward_tac [lt_trans2] 1 THEN assume_tac 1); |
178 by (forward_tac [lt_trans2] 1 THEN assume_tac 1); |
181 by (asm_simp_tac (lambda_ss addsimps [gt_pred]) 1); |
179 by (asm_simp_tac (!simpset addsimps [gt_pred]) 1); |
182 bind_thm("subst_subst", result() RS spec RS spec RS spec RS spec RS mp); |
180 bind_thm("subst_subst", result() RS spec RS spec RS spec RS spec RS mp); |
183 |
181 |
184 val lambda_ss = lambda_ss addsimps |
|
185 [liftn_Var,liftn_App,liftn_Fun,substn_Var,substn_App,substn_Fun]; |
|
186 |
182 |
187 (*** Equivalence proof for optimized substitution ***) |
183 (*** Equivalence proof for optimized substitution ***) |
188 |
184 |
189 goal Lambda.thy "!k. liftn 0 t k = t"; |
185 goal Lambda.thy "!k. liftn 0 t k = t"; |
190 by(db.induct_tac "t" 1); |
186 by(db.induct_tac "t" 1); |
191 by(ALLGOALS(asm_simp_tac (addsplit lambda_ss))); |
187 by(ALLGOALS(asm_simp_tac split_ss)); |
192 qed "liftn_0"; |
188 qed "liftn_0"; |
193 val lambda_ss = lambda_ss addsimps [liftn_0]; |
189 Addsimps [liftn_0]; |
194 |
190 |
195 goal Lambda.thy "!k. liftn (Suc n) t k = lift (liftn n t k) k"; |
191 goal Lambda.thy "!k. liftn (Suc n) t k = lift (liftn n t k) k"; |
196 by(db.induct_tac "t" 1); |
192 by(db.induct_tac "t" 1); |
197 by(ALLGOALS(asm_simp_tac (addsplit lambda_ss))); |
193 by(ALLGOALS(asm_simp_tac split_ss)); |
198 by(fast_tac (HOL_cs addDs [add_lessD1]) 1); |
194 by(fast_tac (HOL_cs addDs [add_lessD1]) 1); |
199 qed "liftn_lift"; |
195 qed "liftn_lift"; |
200 val lambda_ss = lambda_ss addsimps [liftn_lift]; |
196 Addsimps [liftn_lift]; |
201 |
197 |
202 goal Lambda.thy "!n. substn t s n = t[liftn n s 0 / n]"; |
198 goal Lambda.thy "!n. substn t s n = t[liftn n s 0 / n]"; |
203 by(db.induct_tac "t" 1); |
199 by(db.induct_tac "t" 1); |
204 by(ALLGOALS(asm_simp_tac (addsplit lambda_ss))); |
200 by(ALLGOALS(asm_simp_tac (!simpset setloop (split_tac [expand_if])))); |
205 qed "substn_subst_n"; |
201 qed "substn_subst_n"; |
206 val lambda_ss = lambda_ss addsimps [substn_subst_n]; |
202 Addsimps [substn_subst_n]; |
207 |
203 |
208 goal Lambda.thy "substn t s 0 = t[s/0]"; |
204 goal Lambda.thy "substn t s 0 = t[s/0]"; |
209 by(simp_tac lambda_ss 1); |
205 by(Simp_tac 1); |
210 qed "substn_subst_0"; |
206 qed "substn_subst_0"; |