| author | paulson |
| Fri, 04 Dec 1998 10:45:20 +0100 | |
| changeset 6017 | dbb33359a7ab |
| parent 5983 | 79e301a6a51b |
| child 6079 | 4f7975c74cdf |
| permissions | -rw-r--r-- |
| 1269 | 1 |
(* Title: HOL/Lambda/Eta.ML |
2 |
ID: $Id$ |
|
3 |
Author: Tobias Nipkow |
|
4 |
Copyright 1995 TU Muenchen |
|
5 |
||
6 |
Eta reduction, |
|
| 1302 | 7 |
confluence of eta, |
| 1269 | 8 |
commutation of beta/eta, |
9 |
confluence of beta+eta |
|
10 |
*) |
|
11 |
||
| 1302 | 12 |
Addsimps eta.intrs; |
|
5261
ce3c25c8a694
First steps towards termination of simply typed terms.
nipkow
parents:
5184
diff
changeset
|
13 |
AddIs eta.intrs; |
| 1269 | 14 |
|
|
2159
e650a3f6f600
Used nat_trans_tac. New Eta. various smaller changes.
nipkow
parents:
2116
diff
changeset
|
15 |
val eta_cases = map (eta.mk_cases dB.simps) |
| 5146 | 16 |
["Abs s -e> z","s $ t -e> u","Var i -e> t"]; |
|
5261
ce3c25c8a694
First steps towards termination of simply typed terms.
nipkow
parents:
5184
diff
changeset
|
17 |
AddSEs eta_cases; |
| 1269 | 18 |
|
|
2159
e650a3f6f600
Used nat_trans_tac. New Eta. various smaller changes.
nipkow
parents:
2116
diff
changeset
|
19 |
section "eta, subst and free"; |
|
e650a3f6f600
Used nat_trans_tac. New Eta. various smaller changes.
nipkow
parents:
2116
diff
changeset
|
20 |
|
| 5069 | 21 |
Goal "!i t u. ~free s i --> s[t/i] = s[u/i]"; |
| 5184 | 22 |
by (induct_tac "s" 1); |
| 4089 | 23 |
by (ALLGOALS(simp_tac (addsplit (simpset())))); |
| 2891 | 24 |
by (Blast_tac 1); |
25 |
by (Blast_tac 1); |
|
|
2159
e650a3f6f600
Used nat_trans_tac. New Eta. various smaller changes.
nipkow
parents:
2116
diff
changeset
|
26 |
qed_spec_mp "subst_not_free"; |
|
e650a3f6f600
Used nat_trans_tac. New Eta. various smaller changes.
nipkow
parents:
2116
diff
changeset
|
27 |
Addsimps [subst_not_free RS eqTrueI]; |
| 1269 | 28 |
|
| 5117 | 29 |
Goal "!i k. free (lift t k) i = (i < k & free t i | k < i & free t (i-1))"; |
| 5184 | 30 |
by (induct_tac "t" 1); |
| 4089 | 31 |
by (ALLGOALS(asm_full_simp_tac (addsplit (simpset()) addcongs [conj_cong]))); |
| 5983 | 32 |
by(Auto_tac); |
| 5184 | 33 |
by (simp_tac (simpset() addsimps [diff_Suc] addsplits [nat.split]) 1); |
| 5983 | 34 |
by(Auto_tac); |
| 1269 | 35 |
qed "free_lift"; |
36 |
Addsimps [free_lift]; |
|
37 |
||
| 5069 | 38 |
Goal "!i k t. free (s[t/k]) i = \ |
| 1269 | 39 |
\ (free s k & free t i | free s (if i<k then i else Suc i))"; |
| 5184 | 40 |
by (induct_tac "s" 1); |
|
2116
73bbf2cc7651
Used trans_tac (see Provers/nat_transitive.ML) to automate arithmetic.
nipkow
parents:
2083
diff
changeset
|
41 |
by (Asm_simp_tac 2); |
| 2891 | 42 |
by (Blast_tac 2); |
| 4089 | 43 |
by (asm_full_simp_tac (addsplit (simpset())) 2); |
| 4360 | 44 |
by (simp_tac (simpset() addsimps [diff_Suc,subst_Var] |
| 5184 | 45 |
addsplits [nat.split]) 1); |
| 5625 | 46 |
by (safe_tac (HOL_cs addSEs [linorder_neqE])); |
| 5983 | 47 |
by (ALLGOALS Simp_tac); |
| 1269 | 48 |
qed "free_subst"; |
49 |
Addsimps [free_subst]; |
|
50 |
||
| 5117 | 51 |
Goal "s -e> t ==> !i. free t i = free s i"; |
| 1730 | 52 |
by (etac eta.induct 1); |
| 4089 | 53 |
by (ALLGOALS(asm_simp_tac (simpset() addcongs [conj_cong]))); |
| 1486 | 54 |
qed_spec_mp "free_eta"; |
| 1269 | 55 |
|
| 5117 | 56 |
Goal "[| s -e> t; ~free s i |] ==> ~free t i"; |
| 4089 | 57 |
by (asm_simp_tac (simpset() addsimps [free_eta]) 1); |
| 1269 | 58 |
qed "not_free_eta"; |
59 |
||
| 5117 | 60 |
Goal "s -e> t ==> !u i. s[u/i] -e> t[u/i]"; |
| 1730 | 61 |
by (etac eta.induct 1); |
| 4089 | 62 |
by (ALLGOALS(asm_simp_tac (simpset() addsimps [subst_subst RS sym]))); |
| 1486 | 63 |
qed_spec_mp "eta_subst"; |
| 1269 | 64 |
Addsimps [eta_subst]; |
65 |
||
|
1759
a42d6c537f4a
Added comparison with implicit rule Fun(lift s 0 @ Var 0) -e> s
nipkow
parents:
1730
diff
changeset
|
66 |
section "Confluence of -e>"; |
| 1269 | 67 |
|
| 5069 | 68 |
Goalw [square_def,id_def] "square eta eta (eta^=) (eta^=)"; |
| 1730 | 69 |
by (rtac (impI RS allI RS allI) 1); |
| 2057 | 70 |
by (Simp_tac 1); |
| 1730 | 71 |
by (etac eta.induct 1); |
| 4089 | 72 |
by (slow_tac (claset() addIs [subst_not_free,eta_subst] |
73 |
addIs [free_eta RS iffD1] addss simpset()) 1); |
|
| 4162 | 74 |
by Safe_tac; |
| 4089 | 75 |
by (blast_tac (claset() addSIs [eta_subst] addIs [free_eta RS iffD1]) 5); |
| 2922 | 76 |
by (ALLGOALS Blast_tac); |
|
2159
e650a3f6f600
Used nat_trans_tac. New Eta. various smaller changes.
nipkow
parents:
2116
diff
changeset
|
77 |
qed "square_eta"; |
| 1269 | 78 |
|
| 5069 | 79 |
Goal "confluent(eta)"; |
|
2159
e650a3f6f600
Used nat_trans_tac. New Eta. various smaller changes.
nipkow
parents:
2116
diff
changeset
|
80 |
by (rtac (square_eta RS square_reflcl_confluent) 1); |
| 1269 | 81 |
qed "eta_confluent"; |
82 |
||
|
1759
a42d6c537f4a
Added comparison with implicit rule Fun(lift s 0 @ Var 0) -e> s
nipkow
parents:
1730
diff
changeset
|
83 |
section "Congruence rules for -e>>"; |
| 1269 | 84 |
|
| 5117 | 85 |
Goal "s -e>> s' ==> Abs s -e>> Abs s'"; |
| 1465 | 86 |
by (etac rtrancl_induct 1); |
| 4089 | 87 |
by (ALLGOALS(blast_tac (claset() addIs [rtrancl_refl,rtrancl_into_rtrancl]))); |
|
2159
e650a3f6f600
Used nat_trans_tac. New Eta. various smaller changes.
nipkow
parents:
2116
diff
changeset
|
88 |
qed "rtrancl_eta_Abs"; |
| 1269 | 89 |
|
| 5146 | 90 |
Goal "s -e>> s' ==> s $ t -e>> s' $ t"; |
| 1465 | 91 |
by (etac rtrancl_induct 1); |
| 4089 | 92 |
by (ALLGOALS(blast_tac (claset() addIs [rtrancl_refl,rtrancl_into_rtrancl]))); |
| 1269 | 93 |
qed "rtrancl_eta_AppL"; |
94 |
||
| 5146 | 95 |
Goal "t -e>> t' ==> s $ t -e>> s $ t'"; |
| 1465 | 96 |
by (etac rtrancl_induct 1); |
| 4089 | 97 |
by (ALLGOALS(blast_tac (claset() addIs [rtrancl_refl,rtrancl_into_rtrancl]))); |
| 1269 | 98 |
qed "rtrancl_eta_AppR"; |
99 |
||
| 5146 | 100 |
Goal "[| s -e>> s'; t -e>> t' |] ==> s $ t -e>> s' $ t'"; |
| 4089 | 101 |
by (blast_tac (claset() addSIs [rtrancl_eta_AppL, rtrancl_eta_AppR] |
| 2922 | 102 |
addIs [rtrancl_trans]) 1); |
| 1269 | 103 |
qed "rtrancl_eta_App"; |
104 |
||
|
1759
a42d6c537f4a
Added comparison with implicit rule Fun(lift s 0 @ Var 0) -e> s
nipkow
parents:
1730
diff
changeset
|
105 |
section "Commutation of -> and -e>"; |
| 1269 | 106 |
|
| 5117 | 107 |
Goal "s -> t ==> (!i. free t i --> free s i)"; |
| 1730 | 108 |
by (etac beta.induct 1); |
| 2031 | 109 |
by (ALLGOALS(Asm_full_simp_tac)); |
| 1486 | 110 |
qed_spec_mp "free_beta"; |
| 1269 | 111 |
|
| 5117 | 112 |
Goal "s -> t ==> !u i. s[u/i] -> t[u/i]"; |
| 1730 | 113 |
by (etac beta.induct 1); |
| 4089 | 114 |
by (ALLGOALS(asm_full_simp_tac (simpset() addsimps [subst_subst RS sym]))); |
|
2159
e650a3f6f600
Used nat_trans_tac. New Eta. various smaller changes.
nipkow
parents:
2116
diff
changeset
|
115 |
qed_spec_mp "beta_subst"; |
|
e650a3f6f600
Used nat_trans_tac. New Eta. various smaller changes.
nipkow
parents:
2116
diff
changeset
|
116 |
AddIs [beta_subst]; |
| 1269 | 117 |
|
| 5069 | 118 |
Goal "!i. t[Var i/i] = t[Var(i)/Suc i]"; |
| 5184 | 119 |
by (induct_tac "t" 1); |
| 5983 | 120 |
by(auto_tac (claset() addSEs [linorder_neqE], addsplit (simpset()))); |
|
2159
e650a3f6f600
Used nat_trans_tac. New Eta. various smaller changes.
nipkow
parents:
2116
diff
changeset
|
121 |
qed_spec_mp "subst_Var_Suc"; |
|
e650a3f6f600
Used nat_trans_tac. New Eta. various smaller changes.
nipkow
parents:
2116
diff
changeset
|
122 |
Addsimps [subst_Var_Suc]; |
| 1269 | 123 |
|
| 5117 | 124 |
Goal "s -e> t ==> (!i. lift s i -e> lift t i)"; |
| 1730 | 125 |
by (etac eta.induct 1); |
| 4089 | 126 |
by (ALLGOALS(asm_simp_tac (addsplit (simpset())))); |
| 1486 | 127 |
qed_spec_mp "eta_lift"; |
| 1269 | 128 |
Addsimps [eta_lift]; |
129 |
||
| 5069 | 130 |
Goal "!s t i. s -e> t --> u[s/i] -e>> u[t/i]"; |
| 5184 | 131 |
by (induct_tac "u" 1); |
| 4089 | 132 |
by (ALLGOALS(asm_simp_tac (addsplit (simpset())))); |
133 |
by (blast_tac (claset() addIs [r_into_rtrancl]) 1); |
|
134 |
by (blast_tac (claset() addSIs [rtrancl_eta_App]) 1); |
|
135 |
by (blast_tac (claset() addSIs [rtrancl_eta_Abs,eta_lift]) 1); |
|
| 1486 | 136 |
qed_spec_mp "rtrancl_eta_subst"; |
| 1269 | 137 |
|
| 5069 | 138 |
Goalw [square_def] "square beta eta (eta^*) (beta^=)"; |
| 1730 | 139 |
by (rtac (impI RS allI RS allI) 1); |
140 |
by (etac beta.induct 1); |
|
| 4089 | 141 |
by (slow_tac (claset() addIs [r_into_rtrancl,rtrancl_eta_subst,eta_subst] |
142 |
addss simpset()) 1); |
|
143 |
by (blast_tac (claset() addIs [r_into_rtrancl,rtrancl_eta_AppL]) 1); |
|
144 |
by (blast_tac (claset() addIs [r_into_rtrancl,rtrancl_eta_AppR]) 1); |
|
| 2922 | 145 |
(*23 seconds?*) |
|
2931
8658bf6c1a5b
Mod because of "Turned Addsimps into AddIffs for datatype laws."
nipkow
parents:
2922
diff
changeset
|
146 |
DelIffs dB.distinct; |
|
8658bf6c1a5b
Mod because of "Turned Addsimps into AddIffs for datatype laws."
nipkow
parents:
2922
diff
changeset
|
147 |
Addsimps dB.distinct; |
| 4089 | 148 |
by (slow_tac (claset() addIs [r_into_rtrancl,rtrancl_eta_Abs,free_beta] |
149 |
addss simpset()) 1); |
|
| 1269 | 150 |
qed "square_beta_eta"; |
151 |
||
| 5069 | 152 |
Goal "confluent(beta Un eta)"; |
| 2031 | 153 |
by (REPEAT(ares_tac [square_rtrancl_reflcl_commute,confluent_Un, |
| 1269 | 154 |
beta_confluent,eta_confluent,square_beta_eta] 1)); |
155 |
qed "confluent_beta_eta"; |
|
|
1759
a42d6c537f4a
Added comparison with implicit rule Fun(lift s 0 @ Var 0) -e> s
nipkow
parents:
1730
diff
changeset
|
156 |
|
| 5146 | 157 |
section "Implicit definition of -e>: Abs(lift s 0 $ Var 0) -e> s"; |
|
1759
a42d6c537f4a
Added comparison with implicit rule Fun(lift s 0 @ Var 0) -e> s
nipkow
parents:
1730
diff
changeset
|
158 |
|
| 5069 | 159 |
Goal "!i. (~free s i) = (? t. s = lift t i)"; |
| 5184 | 160 |
by (induct_tac "s" 1); |
| 4686 | 161 |
by (Simp_tac 1); |
| 2057 | 162 |
by (SELECT_GOAL(safe_tac HOL_cs)1); |
| 5625 | 163 |
by (etac linorder_neqE 1); |
|
2159
e650a3f6f600
Used nat_trans_tac. New Eta. various smaller changes.
nipkow
parents:
2116
diff
changeset
|
164 |
by (res_inst_tac [("x","Var nat")] exI 1);
|
|
e650a3f6f600
Used nat_trans_tac. New Eta. various smaller changes.
nipkow
parents:
2116
diff
changeset
|
165 |
by (Asm_simp_tac 1); |
| 4360 | 166 |
by (res_inst_tac [("x","Var(nat-1)")] exI 1);
|
| 2057 | 167 |
by (Asm_simp_tac 1); |
168 |
by (rtac notE 1); |
|
169 |
by (assume_tac 2); |
|
170 |
by (etac thin_rl 1); |
|
|
5261
ce3c25c8a694
First steps towards termination of simply typed terms.
nipkow
parents:
5184
diff
changeset
|
171 |
by (exhaust_tac "t" 1); |
|
ce3c25c8a694
First steps towards termination of simply typed terms.
nipkow
parents:
5184
diff
changeset
|
172 |
by (Asm_simp_tac 1); |
| 2891 | 173 |
by (blast_tac (HOL_cs addDs [less_not_refl2]) 1); |
|
5261
ce3c25c8a694
First steps towards termination of simply typed terms.
nipkow
parents:
5184
diff
changeset
|
174 |
by (Asm_simp_tac 1); |
|
ce3c25c8a694
First steps towards termination of simply typed terms.
nipkow
parents:
5184
diff
changeset
|
175 |
by (Asm_simp_tac 1); |
|
2116
73bbf2cc7651
Used trans_tac (see Provers/nat_transitive.ML) to automate arithmetic.
nipkow
parents:
2083
diff
changeset
|
176 |
by (Asm_simp_tac 1); |
| 2057 | 177 |
by (etac thin_rl 1); |
178 |
by (etac thin_rl 1); |
|
179 |
by (rtac allI 1); |
|
180 |
by (rtac iffI 1); |
|
181 |
by (REPEAT(eresolve_tac [conjE,exE] 1)); |
|
182 |
by (rename_tac "u1 u2" 1); |
|
| 5146 | 183 |
by (res_inst_tac [("x","u1$u2")] exI 1);
|
| 2057 | 184 |
by (Asm_simp_tac 1); |
185 |
by (etac exE 1); |
|
186 |
by (etac rev_mp 1); |
|
|
5261
ce3c25c8a694
First steps towards termination of simply typed terms.
nipkow
parents:
5184
diff
changeset
|
187 |
by (exhaust_tac "t" 1); |
|
ce3c25c8a694
First steps towards termination of simply typed terms.
nipkow
parents:
5184
diff
changeset
|
188 |
by (Asm_simp_tac 1); |
|
ce3c25c8a694
First steps towards termination of simply typed terms.
nipkow
parents:
5184
diff
changeset
|
189 |
by (Asm_simp_tac 1); |
| 2891 | 190 |
by (Blast_tac 1); |
|
5261
ce3c25c8a694
First steps towards termination of simply typed terms.
nipkow
parents:
5184
diff
changeset
|
191 |
by (Asm_simp_tac 1); |
| 2031 | 192 |
by (Asm_simp_tac 1); |
193 |
by (etac thin_rl 1); |
|
194 |
by (rtac allI 1); |
|
195 |
by (rtac iffI 1); |
|
| 2057 | 196 |
by (etac exE 1); |
|
2159
e650a3f6f600
Used nat_trans_tac. New Eta. various smaller changes.
nipkow
parents:
2116
diff
changeset
|
197 |
by (res_inst_tac [("x","Abs t")] exI 1);
|
| 2057 | 198 |
by (Asm_simp_tac 1); |
| 2031 | 199 |
by (etac exE 1); |
200 |
by (etac rev_mp 1); |
|
|
5261
ce3c25c8a694
First steps towards termination of simply typed terms.
nipkow
parents:
5184
diff
changeset
|
201 |
by (exhaust_tac "t" 1); |
|
ce3c25c8a694
First steps towards termination of simply typed terms.
nipkow
parents:
5184
diff
changeset
|
202 |
by (Asm_simp_tac 1); |
|
ce3c25c8a694
First steps towards termination of simply typed terms.
nipkow
parents:
5184
diff
changeset
|
203 |
by (Asm_simp_tac 1); |
|
ce3c25c8a694
First steps towards termination of simply typed terms.
nipkow
parents:
5184
diff
changeset
|
204 |
by (Asm_simp_tac 1); |
| 2891 | 205 |
by (Blast_tac 1); |
|
1759
a42d6c537f4a
Added comparison with implicit rule Fun(lift s 0 @ Var 0) -e> s
nipkow
parents:
1730
diff
changeset
|
206 |
qed_spec_mp "not_free_iff_lifted"; |
|
a42d6c537f4a
Added comparison with implicit rule Fun(lift s 0 @ Var 0) -e> s
nipkow
parents:
1730
diff
changeset
|
207 |
|
| 5146 | 208 |
Goal "(!s u. (~free s 0) --> R(Abs(s $ Var 0))(s[u/0])) = \ |
209 |
\ (!s. R(Abs(lift s 0 $ Var 0))(s))"; |
|
| 4089 | 210 |
by (fast_tac (HOL_cs addss (simpset() addsimps [not_free_iff_lifted])) 1); |
|
1759
a42d6c537f4a
Added comparison with implicit rule Fun(lift s 0 @ Var 0) -e> s
nipkow
parents:
1730
diff
changeset
|
211 |
qed "explicit_is_implicit"; |