author | wenzelm |
Fri, 28 Feb 1997 16:55:35 +0100 | |
changeset 2703 | 5ce1310560ff |
parent 2645 | 9d3a3e62bf34 |
child 3520 | 5b5807645a1a |
permissions | -rw-r--r-- |
1243 | 1 |
(* Title: Provers/simplifier.ML |
1 | 2 |
ID: $Id$ |
3 |
Author: Tobias Nipkow |
|
4 |
Copyright 1993 TU Munich |
|
5 |
||
6 |
Generic simplifier, suitable for most logics. |
|
2503 | 7 |
|
8 |
TODO: |
|
9 |
- stamps to identify funs / tacs |
|
10 |
- merge: fail if incompatible funs |
|
2509 | 11 |
- improve merge |
1 | 12 |
*) |
1260 | 13 |
|
2629 | 14 |
infix 4 setsubgoaler setloop addloop setSSolver addSSolver setSolver addSolver |
15 |
setmksimps addsimps delsimps addeqcongs deleqcongs |
|
2567 | 16 |
settermless addsimprocs delsimprocs; |
17 |
||
0 | 18 |
|
19 |
signature SIMPLIFIER = |
|
20 |
sig |
|
2509 | 21 |
type simproc |
22 |
val mk_simproc: string -> cterm list -> (Sign.sg -> term -> thm option) -> simproc |
|
23 |
val name_of_simproc: simproc -> string |
|
24 |
val conv_prover: (term * term -> term) -> thm -> (thm -> thm) |
|
25 |
-> tactic -> (int -> tactic) -> Sign.sg -> term -> term -> thm (* FIXME move?, rename? *) |
|
0 | 26 |
type simpset |
2503 | 27 |
val empty_ss: simpset |
2629 | 28 |
val rep_ss: simpset -> {simps: thm list, procs: string list, congs: thm list, |
29 |
subgoal_tac: simpset -> int -> tactic, |
|
30 |
loop_tac: int -> tactic, |
|
31 |
finish_tac: thm list -> int -> tactic, |
|
32 |
unsafe_finish_tac: thm list -> int -> tactic} |
|
33 |
val setsubgoaler: simpset * (simpset -> int -> tactic) -> simpset |
|
34 |
val setloop: simpset * (int -> tactic) -> simpset |
|
35 |
val addloop: simpset * (int -> tactic) -> simpset |
|
36 |
val setSSolver: simpset * (thm list -> int -> tactic) -> simpset |
|
37 |
val addSSolver: simpset * (thm list -> int -> tactic) -> simpset |
|
38 |
val setSolver: simpset * (thm list -> int -> tactic) -> simpset |
|
39 |
val addSolver: simpset * (thm list -> int -> tactic) -> simpset |
|
40 |
val setmksimps: simpset * (thm -> thm list) -> simpset |
|
2509 | 41 |
val settermless: simpset * (term * term -> bool) -> simpset |
2629 | 42 |
val addsimps: simpset * thm list -> simpset |
43 |
val delsimps: simpset * thm list -> simpset |
|
44 |
val addeqcongs: simpset * thm list -> simpset |
|
45 |
val deleqcongs: simpset * thm list -> simpset |
|
2509 | 46 |
val addsimprocs: simpset * simproc list -> simpset |
47 |
val delsimprocs: simpset * simproc list -> simpset |
|
2629 | 48 |
val merge_ss: simpset * simpset -> simpset |
49 |
val prems_of_ss: simpset -> thm list |
|
50 |
val simpset: simpset ref |
|
1243 | 51 |
val Addsimps: thm list -> unit |
52 |
val Delsimps: thm list -> unit |
|
2509 | 53 |
val Addsimprocs: simproc list -> unit |
54 |
val Delsimprocs: simproc list -> unit |
|
2629 | 55 |
val simp_tac: simpset -> int -> tactic |
56 |
val asm_simp_tac: simpset -> int -> tactic |
|
57 |
val full_simp_tac: simpset -> int -> tactic |
|
58 |
val asm_full_simp_tac: simpset -> int -> tactic |
|
59 |
val safe_asm_full_simp_tac: simpset -> int -> tactic |
|
60 |
val Simp_tac: int -> tactic |
|
61 |
val Asm_simp_tac: int -> tactic |
|
62 |
val Full_simp_tac: int -> tactic |
|
63 |
val Asm_full_simp_tac: int -> tactic |
|
0 | 64 |
end; |
65 |
||
2503 | 66 |
|
67 |
structure Simplifier: SIMPLIFIER = |
|
0 | 68 |
struct |
69 |
||
2509 | 70 |
|
71 |
(** simplification procedures **) |
|
72 |
||
73 |
(* datatype simproc *) |
|
74 |
||
75 |
datatype simproc = |
|
76 |
Simproc of { |
|
77 |
name: string, |
|
78 |
procs: (Sign.sg * term * (Sign.sg -> term -> thm option) * stamp) list} |
|
79 |
||
80 |
(* FIXME stamps!? *) |
|
81 |
fun eq_simproc (Simproc {name = name1, ...}, Simproc {name = name2, ...}) = |
|
82 |
(name1 = name2); |
|
83 |
||
84 |
fun mk_simproc name lhss proc = |
|
85 |
let |
|
86 |
fun mk_proc lhs = |
|
87 |
(#sign (Thm.rep_cterm lhs), Logic.varify (term_of lhs), proc, stamp ()); |
|
88 |
in |
|
89 |
Simproc {name = name, procs = map mk_proc lhss} |
|
90 |
end; |
|
91 |
||
92 |
fun name_of_simproc (Simproc {name, ...}) = name; |
|
93 |
||
94 |
||
95 |
(* generic conversion prover *) (* FIXME move?, rename? *) |
|
96 |
||
97 |
fun conv_prover mk_eqv eqv_refl mk_meta_eq expand_tac norm_tac sg t u = |
|
98 |
let |
|
99 |
val X = Free (gensym "X.", fastype_of t); |
|
100 |
val goal = Logic.mk_implies (mk_eqv (X, t), mk_eqv (X, u)); |
|
101 |
val pre_result = |
|
102 |
prove_goalw_cterm [] (cterm_of sg goal) (*goal: X=t ==> X=u*) |
|
103 |
(fn prems => [ |
|
104 |
expand_tac, (*expand u*) |
|
105 |
ALLGOALS (cut_facts_tac prems), |
|
106 |
ALLGOALS norm_tac]); (*normalize both t and u*) |
|
107 |
in |
|
108 |
mk_meta_eq (eqv_refl RS pre_result) (*final result: t==u*) |
|
109 |
end |
|
110 |
handle ERROR => error ("The error(s) above occurred while trying to prove " ^ |
|
111 |
(string_of_cterm (cterm_of sg (mk_eqv (t, u))))); |
|
112 |
||
113 |
||
114 |
||
2503 | 115 |
(** simplification sets **) |
116 |
||
117 |
(* type simpset *) |
|
118 |
||
0 | 119 |
datatype simpset = |
2503 | 120 |
Simpset of { |
121 |
mss: meta_simpset, |
|
122 |
simps: thm list, |
|
2509 | 123 |
procs: simproc list, |
2503 | 124 |
congs: thm list, |
2629 | 125 |
subgoal_tac: simpset -> int -> tactic, |
126 |
loop_tac: int -> tactic, |
|
127 |
finish_tac: thm list -> int -> tactic, |
|
128 |
unsafe_finish_tac: thm list -> int -> tactic}; |
|
2503 | 129 |
|
2629 | 130 |
fun make_ss (mss, simps, procs, congs, |
131 |
subgoal_tac, loop_tac, finish_tac, unsafe_finish_tac) = |
|
2509 | 132 |
Simpset {mss = mss, simps = simps, procs = procs, congs = congs, |
2629 | 133 |
subgoal_tac = subgoal_tac, loop_tac = loop_tac, |
134 |
finish_tac = finish_tac, unsafe_finish_tac = unsafe_finish_tac}; |
|
0 | 135 |
|
136 |
val empty_ss = |
|
2629 | 137 |
make_ss (Thm.empty_mss, [], [], [], |
138 |
K (K no_tac), K no_tac, K (K no_tac), K (K no_tac)); |
|
2503 | 139 |
|
2629 | 140 |
fun rep_ss (Simpset {simps, procs, congs, subgoal_tac, loop_tac, |
141 |
finish_tac, unsafe_finish_tac, ...}) = |
|
142 |
{simps = simps, procs = map name_of_simproc procs, congs = congs, |
|
143 |
subgoal_tac = subgoal_tac, loop_tac = loop_tac, |
|
144 |
finish_tac = finish_tac, unsafe_finish_tac = unsafe_finish_tac}; |
|
2503 | 145 |
|
146 |
fun prems_of_ss (Simpset {mss, ...}) = Thm.prems_of_mss mss; |
|
147 |
||
148 |
||
149 |
(* extend simpsets *) |
|
150 |
||
2629 | 151 |
fun (Simpset {mss, simps, procs, congs, subgoal_tac = _, loop_tac, |
152 |
finish_tac, unsafe_finish_tac}) setsubgoaler subgoal_tac = |
|
153 |
make_ss (mss, simps, procs, congs, subgoal_tac, loop_tac, |
|
154 |
finish_tac, unsafe_finish_tac); |
|
155 |
||
156 |
fun (Simpset {mss, simps, procs, congs, subgoal_tac, loop_tac = _, |
|
157 |
finish_tac, unsafe_finish_tac}) setloop loop_tac = |
|
158 |
make_ss (mss, simps, procs, congs, subgoal_tac, DETERM o loop_tac, |
|
159 |
finish_tac, unsafe_finish_tac); |
|
2503 | 160 |
|
2629 | 161 |
fun (Simpset {mss, simps, procs, congs, subgoal_tac, loop_tac, |
162 |
finish_tac, unsafe_finish_tac}) addloop tac = |
|
163 |
make_ss (mss, simps, procs, congs, subgoal_tac, loop_tac ORELSE'(DETERM o tac), |
|
164 |
finish_tac, unsafe_finish_tac); |
|
2567 | 165 |
|
2629 | 166 |
fun (Simpset {mss, simps, procs, congs, subgoal_tac, loop_tac, |
167 |
finish_tac = _, unsafe_finish_tac}) setSSolver finish_tac = |
|
168 |
make_ss (mss, simps, procs, congs, subgoal_tac, loop_tac, |
|
169 |
finish_tac, unsafe_finish_tac); |
|
2503 | 170 |
|
2629 | 171 |
fun (Simpset {mss, simps, procs, congs, subgoal_tac, loop_tac, |
172 |
finish_tac, unsafe_finish_tac}) addSSolver tac = |
|
173 |
make_ss (mss, simps, procs, congs, subgoal_tac, loop_tac, |
|
174 |
fn hyps => finish_tac hyps ORELSE' tac hyps, unsafe_finish_tac); |
|
2503 | 175 |
|
2629 | 176 |
fun (Simpset {mss, simps, procs, congs, subgoal_tac, loop_tac, |
177 |
finish_tac, unsafe_finish_tac = _}) setSolver unsafe_finish_tac = |
|
178 |
make_ss (mss, simps, procs, congs, subgoal_tac, loop_tac, |
|
179 |
finish_tac, unsafe_finish_tac); |
|
2503 | 180 |
|
2629 | 181 |
fun (Simpset {mss, simps, procs, congs, subgoal_tac, loop_tac, |
182 |
finish_tac, unsafe_finish_tac}) addSolver tac = |
|
183 |
make_ss (mss, simps, procs, congs, subgoal_tac, loop_tac, |
|
184 |
finish_tac, fn hyps => unsafe_finish_tac hyps ORELSE' tac hyps); |
|
2503 | 185 |
|
2629 | 186 |
fun (Simpset {mss, simps, procs, congs, subgoal_tac, loop_tac, |
187 |
finish_tac, unsafe_finish_tac}) setmksimps mk_simps = |
|
2645
9d3a3e62bf34
mk_rews: automatically includes strip_shyps, zero_var_indexes;
wenzelm
parents:
2629
diff
changeset
|
188 |
make_ss (Thm.set_mk_rews (mss, map (Thm.strip_shyps o Drule.zero_var_indexes) o mk_simps), |
9d3a3e62bf34
mk_rews: automatically includes strip_shyps, zero_var_indexes;
wenzelm
parents:
2629
diff
changeset
|
189 |
simps, procs, congs, subgoal_tac, loop_tac, finish_tac, unsafe_finish_tac); |
2629 | 190 |
|
191 |
fun (Simpset {mss, simps, procs, congs, subgoal_tac, loop_tac, |
|
192 |
finish_tac, unsafe_finish_tac}) settermless termless = |
|
2509 | 193 |
make_ss (Thm.set_termless (mss, termless), simps, procs, congs, |
2629 | 194 |
subgoal_tac, loop_tac, finish_tac, unsafe_finish_tac); |
2509 | 195 |
|
2629 | 196 |
fun (Simpset {mss, simps, procs, congs, subgoal_tac, loop_tac, |
197 |
finish_tac, unsafe_finish_tac}) addsimps rews = |
|
2503 | 198 |
let val rews' = flat (map (Thm.mk_rews_of_mss mss) rews) in |
2521 | 199 |
make_ss (Thm.add_simps (mss, rews'), gen_union eq_thm (rews', simps), |
2629 | 200 |
procs, congs, subgoal_tac, loop_tac, finish_tac, unsafe_finish_tac) |
2503 | 201 |
end; |
202 |
||
2629 | 203 |
fun (Simpset {mss, simps, procs, congs, subgoal_tac, loop_tac, |
204 |
finish_tac, unsafe_finish_tac}) delsimps rews = |
|
2503 | 205 |
let val rews' = flat (map (Thm.mk_rews_of_mss mss) rews) in |
2629 | 206 |
make_ss (Thm.del_simps (mss, rews'), foldl (gen_rem eq_thm) (simps, rews'), |
207 |
procs, congs, subgoal_tac, loop_tac, finish_tac, unsafe_finish_tac) |
|
2503 | 208 |
end; |
209 |
||
2629 | 210 |
fun (Simpset {mss, simps, procs, congs, subgoal_tac, loop_tac, |
211 |
finish_tac, unsafe_finish_tac}) addeqcongs newcongs = |
|
212 |
make_ss (Thm.add_congs (mss, newcongs), simps, procs, |
|
213 |
gen_union eq_thm (congs, newcongs), subgoal_tac, loop_tac, |
|
214 |
finish_tac, unsafe_finish_tac); |
|
2509 | 215 |
|
2629 | 216 |
fun (Simpset {mss, simps, procs, congs, subgoal_tac, loop_tac, |
217 |
finish_tac, unsafe_finish_tac}) deleqcongs oldcongs = |
|
218 |
make_ss (Thm.del_congs (mss, oldcongs), simps, procs, |
|
219 |
foldl (gen_rem eq_thm) (congs, oldcongs), subgoal_tac, loop_tac, |
|
220 |
finish_tac, unsafe_finish_tac); |
|
221 |
||
222 |
fun addsimproc ((Simpset {mss, simps, procs, congs, subgoal_tac, loop_tac, |
|
223 |
finish_tac, unsafe_finish_tac}), |
|
224 |
simproc as Simproc {name = _, procs = procs'}) = |
|
2509 | 225 |
make_ss (Thm.add_simprocs (mss, procs'), |
226 |
simps, gen_ins eq_simproc (simproc, procs), |
|
2629 | 227 |
congs, subgoal_tac, loop_tac, finish_tac, unsafe_finish_tac); |
2509 | 228 |
|
229 |
val op addsimprocs = foldl addsimproc; |
|
230 |
||
2629 | 231 |
fun delsimproc ((Simpset {mss, simps, procs, congs, subgoal_tac, loop_tac, |
232 |
finish_tac, unsafe_finish_tac}), |
|
233 |
simproc as Simproc {name = _, procs = procs'}) = |
|
2509 | 234 |
make_ss (Thm.del_simprocs (mss, procs'), |
235 |
simps, gen_rem eq_simproc (procs, simproc), |
|
2629 | 236 |
congs, subgoal_tac, loop_tac, finish_tac, unsafe_finish_tac); |
2509 | 237 |
|
238 |
val op delsimprocs = foldl delsimproc; |
|
2503 | 239 |
|
240 |
||
241 |
(* merge simpsets *) |
|
242 |
||
2509 | 243 |
(*prefers first simpset (FIXME improve?)*) |
2629 | 244 |
fun merge_ss (Simpset {mss, simps, procs, congs, subgoal_tac, loop_tac, |
245 |
finish_tac, unsafe_finish_tac}, |
|
2509 | 246 |
Simpset {simps = simps2, procs = procs2, congs = congs2, ...}) = |
2503 | 247 |
let |
248 |
val simps' = gen_union eq_thm (simps, simps2); |
|
2509 | 249 |
val procs' = gen_union eq_simproc (procs, procs2); |
2503 | 250 |
val congs' = gen_union eq_thm (congs, congs2); |
251 |
val mss' = Thm.set_mk_rews (empty_mss, Thm.mk_rews_of_mss mss); |
|
252 |
val mss' = Thm.add_simps (mss', simps'); |
|
253 |
val mss' = Thm.add_congs (mss', congs'); |
|
254 |
in |
|
2629 | 255 |
make_ss (mss', simps', procs', congs', subgoal_tac, loop_tac, |
256 |
finish_tac, unsafe_finish_tac) |
|
2503 | 257 |
end; |
258 |
||
259 |
||
260 |
(* the current simpset *) |
|
0 | 261 |
|
1243 | 262 |
val simpset = ref empty_ss; |
0 | 263 |
|
2503 | 264 |
fun Addsimps rews = (simpset := ! simpset addsimps rews); |
265 |
fun Delsimps rews = (simpset := ! simpset delsimps rews); |
|
0 | 266 |
|
2509 | 267 |
fun Addsimprocs procs = (simpset := ! simpset addsimprocs procs); |
268 |
fun Delsimprocs procs = (simpset := ! simpset delsimprocs procs); |
|
269 |
||
0 | 270 |
|
2503 | 271 |
(** simplification tactics **) |
0 | 272 |
|
1 | 273 |
fun NEWSUBGOALS tac tacf = |
2503 | 274 |
STATE (fn state0 => |
275 |
tac THEN STATE (fn state1 => tacf (nprems_of state1 - nprems_of state0))); |
|
1 | 276 |
|
2629 | 277 |
(*not totally safe: may instantiate unknowns that appear also in other subgoals*) |
278 |
fun basic_gen_simp_tac mode = |
|
279 |
fn (Simpset {mss, simps, procs, congs, subgoal_tac, loop_tac, |
|
280 |
finish_tac, unsafe_finish_tac}) => |
|
0 | 281 |
let fun solve_all_tac mss = |
2509 | 282 |
let val ss = |
2629 | 283 |
make_ss (mss, simps, procs, congs, subgoal_tac, loop_tac, |
284 |
unsafe_finish_tac, unsafe_finish_tac); |
|
1 | 285 |
val solve1_tac = |
286 |
NEWSUBGOALS (subgoal_tac ss 1) |
|
287 |
(fn n => if n<0 then all_tac else no_tac) |
|
288 |
in DEPTH_SOLVE(solve1_tac) end |
|
1512 | 289 |
fun simp_loop_tac i thm = |
2503 | 290 |
(asm_rewrite_goal_tac mode solve_all_tac mss i THEN |
291 |
(finish_tac (prems_of_mss mss) i ORELSE looper i)) thm |
|
1 | 292 |
and allsimp i n = EVERY(map (fn j => simp_loop_tac (i+j)) (n downto 0)) |
293 |
and looper i = TRY(NEWSUBGOALS (loop_tac i) (allsimp i)) |
|
217
c972c57e7762
got rid of METAHYPS due to the change of the basic simplification routines
nipkow
parents:
146
diff
changeset
|
294 |
in simp_loop_tac end; |
0 | 295 |
|
2629 | 296 |
fun gen_simp_tac mode ss = basic_gen_simp_tac mode |
297 |
(ss setSSolver #unsafe_finish_tac (rep_ss ss)); |
|
298 |
||
2503 | 299 |
val simp_tac = gen_simp_tac (false, false); |
300 |
val asm_simp_tac = gen_simp_tac (false, true); |
|
301 |
val full_simp_tac = gen_simp_tac (true, false); |
|
302 |
val asm_full_simp_tac = gen_simp_tac (true, true); |
|
0 | 303 |
|
2629 | 304 |
(*not totally safe: may instantiate unknowns that appear also in other subgoals*) |
305 |
val safe_asm_full_simp_tac = basic_gen_simp_tac (true, true); |
|
306 |
||
2503 | 307 |
fun Simp_tac i = simp_tac (! simpset) i; |
308 |
fun Asm_simp_tac i = asm_simp_tac (! simpset) i; |
|
309 |
fun Full_simp_tac i = full_simp_tac (! simpset) i; |
|
310 |
fun Asm_full_simp_tac i = asm_full_simp_tac (! simpset) i; |
|
406 | 311 |
|
1243 | 312 |
end; |