233 \] |
233 \] |
234 Only the first argument is simplified; the others remain unchanged. |
234 Only the first argument is simplified; the others remain unchanged. |
235 This can make simplification much faster, but may require an extra case split |
235 This can make simplification much faster, but may require an extra case split |
236 to prove the goal. |
236 to prove the goal. |
237 |
237 |
238 Congruence rules are added using \ttindexbold{addeqcongs}. Their conclusion |
238 Congruence rules are added/deleted using |
239 must be a meta-equality, as in the examples above. It is more |
239 \ttindexbold{addeqcongs}/\ttindex{deleqcongs}. |
|
240 Their conclusion must be a meta-equality, as in the examples above. It is more |
240 natural to derive the rules with object-logic equality, for example |
241 natural to derive the rules with object-logic equality, for example |
241 \[ \List{\Var{P@1} \bimp \Var{Q@1};\; \Var{Q@1} \Imp \Var{P@2} \bimp \Var{Q@2}} |
242 \[ \List{\Var{P@1} \bimp \Var{Q@1};\; \Var{Q@1} \Imp \Var{P@2} \bimp \Var{Q@2}} |
242 \Imp (\Var{P@1} \imp \Var{P@2}) \bimp (\Var{Q@1} \imp \Var{Q@2}), |
243 \Imp (\Var{P@1} \imp \Var{P@2}) \bimp (\Var{Q@1} \imp \Var{Q@2}), |
243 \] |
244 \] |
244 Each object-logic should define an operator called \ttindex{addcongs} that |
245 Each object-logic should define operators called \ttindex{addcongs} and |
245 expects object-equalities and translates them into meta-equalities. |
246 \ttindex{delcongs} that expects object-equalities and translates them into |
|
247 meta-equalities. |
246 |
248 |
247 \subsection{*The subgoaler} |
249 \subsection{*The subgoaler} |
248 The subgoaler is the tactic used to solve subgoals arising out of |
250 The subgoaler is the tactic used to solve subgoals arising out of |
249 conditional rewrite rules or congruence rules. The default should be |
251 conditional rewrite rules or congruence rules. The default should be |
250 simplification itself. Occasionally this strategy needs to be changed. For |
252 simplification itself. Occasionally this strategy needs to be changed. For |
262 tries to solve the subgoal by assumption or with one of the premises, calling |
264 tries to solve the subgoal by assumption or with one of the premises, calling |
263 simplification only if that fails; here {\tt prems_of_ss} extracts the |
265 simplification only if that fails; here {\tt prems_of_ss} extracts the |
264 current premises from a simpset. |
266 current premises from a simpset. |
265 |
267 |
266 \subsection{*The solver}\label{sec:simp-solver} |
268 \subsection{*The solver}\label{sec:simp-solver} |
267 The solver is a tactic that attempts to solve a subgoal after |
269 The solver is a pair of tactics that attempt to solve a subgoal after |
268 simplification. Typically it just proves trivial subgoals such as {\tt |
270 simplification. Typically it just proves trivial subgoals such as {\tt |
269 True} and $t=t$. It could use sophisticated means such as {\tt |
271 True} and $t=t$. It could use sophisticated means such as {\tt |
270 fast_tac}, though that could make simplification expensive. The solver |
272 fast_tac}, though that could make simplification expensive. |
271 is set using \ttindex{setsolver}. Additional solvers, which are tried after |
|
272 the already set solver, may be added with \ttindex{addsolver}. |
|
273 |
273 |
274 Rewriting does not instantiate unknowns. For example, rewriting cannot |
274 Rewriting does not instantiate unknowns. For example, rewriting cannot |
275 prove $a\in \Var{A}$ since this requires instantiating~$\Var{A}$. The |
275 prove $a\in \Var{A}$ since this requires instantiating~$\Var{A}$. The |
276 solver, however, is an arbitrary tactic and may instantiate unknowns as it |
276 solver, however, is an arbitrary tactic and may instantiate unknowns as it |
277 pleases. This is the only way the simplifier can handle a conditional |
277 pleases. This is the only way the simplifier can handle a conditional |
278 rewrite rule whose condition contains extra variables. |
278 rewrite rule whose condition contains extra variables. When a simplification |
|
279 tactic is to be combined with other provers, especially with the classical |
|
280 reasoner, it is important whether it can be considered safe or not. Therefore, |
|
281 solver is split into a safe and anunsafe part. Both parts of the solver, |
|
282 which are stored within the simpset, can be set independently using |
|
283 \ttindex{setSSolver} (with a safe tactic as argument) and \ttindex{setSolver} |
|
284 (with an unsafe tactic) . Additional solvers, which are tried after the already |
|
285 set solvers, may be added using \ttindex{addSSolver} and \ttindex{addSolver}. |
|
286 |
|
287 The standard simplification procedures uses solely the unsafe solver, which is |
|
288 appropriate in most cases. But for special applications, where the simplification |
|
289 process is not allowed to instantiate unknowns within the goal, the tactic |
|
290 \ttindexbold{safe_asm_full_simp_tac} is provided. Like {\tt asm_full_simp_tac}, |
|
291 it uses the unsafe solver for any embedded simplification steps |
|
292 (i.e. for solving subgoals created by the subgoaler), |
|
293 but for the current subgoal, it applies the safe solver. |
279 |
294 |
280 \index{assumptions!in simplification} |
295 \index{assumptions!in simplification} |
281 The tactic is presented with the full goal, including the asssumptions. |
296 The tactic is presented with the full goal, including the asssumptions. |
282 Hence it can use those assumptions (say by calling {\tt assume_tac}) even |
297 Hence it can use those assumptions (say by calling {\tt assume_tac}) even |
283 inside {\tt simp_tac}, which otherwise does not use assumptions. The |
298 inside {\tt simp_tac}, which otherwise does not use assumptions. The |
322 \index{*empty_ss} |
337 \index{*empty_ss} |
323 \index{*rep_ss} |
338 \index{*rep_ss} |
324 \index{*prems_of_ss} |
339 \index{*prems_of_ss} |
325 \index{*setloop} |
340 \index{*setloop} |
326 \index{*addloop} |
341 \index{*addloop} |
327 \index{*setsolver} |
342 \index{*setSSolver} |
328 \index{*addsolver} |
343 \index{*addSSolver} |
|
344 \index{*setSolver} |
|
345 \index{*addSolver} |
329 \index{*setsubgoaler} |
346 \index{*setsubgoaler} |
330 \index{*setmksimps} |
347 \index{*setmksimps} |
331 \index{*addsimps} |
348 \index{*addsimps} |
332 \index{*delsimps} |
349 \index{*delsimps} |
333 \index{*addeqcongs} |
350 \index{*addeqcongs} |
|
351 \index{*deleqcongs} |
334 \index{*merge_ss} |
352 \index{*merge_ss} |
335 \index{*simpset} |
353 \index{*simpset} |
336 \index{*Addsimps} |
354 \index{*Addsimps} |
337 \index{*Delsimps} |
355 \index{*Delsimps} |
338 \index{*simp_tac} |
356 \index{*simp_tac} |
339 \index{*asm_simp_tac} |
357 \index{*asm_simp_tac} |
340 \index{*full_simp_tac} |
358 \index{*full_simp_tac} |
341 \index{*asm_full_simp_tac} |
359 \index{*asm_full_simp_tac} |
|
360 \index{*safe_asm_full_simp_tac} |
342 \index{*Simp_tac} |
361 \index{*Simp_tac} |
343 \index{*Asm_simp_tac} |
362 \index{*Asm_simp_tac} |
344 \index{*Full_simp_tac} |
363 \index{*Full_simp_tac} |
345 \index{*Asm_full_simp_tac} |
364 \index{*Asm_full_simp_tac} |
346 |
365 |
347 \begin{ttbox} |
366 \begin{ttbox} |
348 infix 4 setloop addloop setsolver addsolver |
367 infix 4 setsubgoaler setloop addloop setSSolver addSSolver setSolver addSolver |
349 setsubgoaler setmksimps |
368 setmksimps addsimps delsimps addeqcongs deleqcongs; |
350 addsimps addeqcongs delsimps; |
|
351 |
369 |
352 signature SIMPLIFIER = |
370 signature SIMPLIFIER = |
353 sig |
371 sig |
|
372 type simproc |
|
373 val mk_simproc: string -> cterm list -> (Sign.sg -> term -> thm option) -> simproc |
|
374 val name_of_simproc: simproc -> string |
|
375 val conv_prover: (term * term -> term) -> thm -> (thm -> thm) |
|
376 -> tactic -> (int -> tactic) -> Sign.sg -> term -> term -> thm (* FIXME move?, rename? *) |
354 type simpset |
377 type simpset |
355 val empty_ss: simpset |
378 val empty_ss: simpset |
356 val rep_ss: simpset -> {simps: thm list, congs: thm list} |
379 val rep_ss: simpset -> {simps: thm list, procs: string list, congs: thm list, |
|
380 subgoal_tac: simpset -> int -> tactic, |
|
381 loop_tac: int -> tactic, |
|
382 finish_tac: thm list -> int -> tactic, |
|
383 unsafe_finish_tac: thm list -> int -> tactic} |
|
384 val setsubgoaler: simpset * (simpset -> int -> tactic) -> simpset |
|
385 val setloop: simpset * (int -> tactic) -> simpset |
|
386 val addloop: simpset * (int -> tactic) -> simpset |
|
387 val setSSolver: simpset * (thm list -> int -> tactic) -> simpset |
|
388 val addSSolver: simpset * (thm list -> int -> tactic) -> simpset |
|
389 val setSolver: simpset * (thm list -> int -> tactic) -> simpset |
|
390 val addSolver: simpset * (thm list -> int -> tactic) -> simpset |
|
391 val setmksimps: simpset * (thm -> thm list) -> simpset |
|
392 val addsimps: simpset * thm list -> simpset |
|
393 val delsimps: simpset * thm list -> simpset |
|
394 val addeqcongs: simpset * thm list -> simpset |
|
395 val deleqcongs: simpset * thm list -> simpset |
|
396 val merge_ss: simpset * simpset -> simpset |
357 val prems_of_ss: simpset -> thm list |
397 val prems_of_ss: simpset -> thm list |
358 val setloop: simpset * (int -> tactic) -> simpset |
398 val simpset: simpset ref |
359 val addloop: simpset * (int -> tactic) -> simpset |
|
360 val setsolver: simpset * (thm list -> int -> tactic) -> simpset |
|
361 val addsolver: simpset * (thm list -> int -> tactic) -> simpset |
|
362 val setsubgoaler: simpset * (simpset -> int -> tactic) -> simpset |
|
363 val setmksimps: simpset * (thm -> thm list) -> simpset |
|
364 val addsimps: simpset * thm list -> simpset |
|
365 val delsimps: simpset * thm list -> simpset |
|
366 val addeqcongs: simpset * thm list -> simpset |
|
367 val merge_ss: simpset * simpset -> simpset |
|
368 val simpset: simpset ref |
|
369 val Addsimps: thm list -> unit |
399 val Addsimps: thm list -> unit |
370 val Delsimps: thm list -> unit |
400 val Delsimps: thm list -> unit |
371 val simp_tac: simpset -> int -> tactic |
401 val simp_tac: simpset -> int -> tactic |
372 val asm_simp_tac: simpset -> int -> tactic |
402 val asm_simp_tac: simpset -> int -> tactic |
373 val full_simp_tac: simpset -> int -> tactic |
403 val full_simp_tac: simpset -> int -> tactic |
374 val asm_full_simp_tac: simpset -> int -> tactic |
404 val asm_full_simp_tac: simpset -> int -> tactic |
375 val Simp_tac: int -> tactic |
405 val safe_asm_full_simp_tac: simpset -> int -> tactic |
376 val Asm_simp_tac: int -> tactic |
406 val Simp_tac: int -> tactic |
377 val Full_simp_tac: int -> tactic |
407 val Asm_simp_tac: int -> tactic |
378 val Asm_full_simp_tac: int -> tactic |
408 val Full_simp_tac: int -> tactic |
|
409 val Asm_full_simp_tac: int -> tactic |
379 end; |
410 end; |
380 \end{ttbox} |
411 \end{ttbox} |
381 \caption{The simplifier primitives} \label{SIMPLIFIER} |
412 \caption{The simplifier primitives} \label{SIMPLIFIER} |
382 \end{figure} |
413 \end{figure} |
383 |
414 |
941 It uses \ttindex{asm_simp_tac} to tackle subgoals of |
972 It uses \ttindex{asm_simp_tac} to tackle subgoals of |
942 conditional rewrites. It takes {\tt IFOL_rews} as rewrite rules. |
973 conditional rewrites. It takes {\tt IFOL_rews} as rewrite rules. |
943 Other simpsets built from {\tt IFOL_ss} will inherit these items. |
974 Other simpsets built from {\tt IFOL_ss} will inherit these items. |
944 In particular, {\tt FOL_ss} extends {\tt IFOL_ss} with classical rewrite |
975 In particular, {\tt FOL_ss} extends {\tt IFOL_ss} with classical rewrite |
945 rules such as $\neg\neg P\bimp P$. |
976 rules such as $\neg\neg P\bimp P$. |
946 \index{*setmksimps}\index{*setsolver}\index{*setsubgoaler} |
977 \index{*setmksimps}\index{*setSSolver}\index{*setSolver}\index{*setsubgoaler} |
947 \index{*addsimps}\index{*addcongs} |
978 \index{*addsimps}\index{*addcongs} |
948 \begin{ttbox} |
979 \begin{ttbox} |
949 val IFOL_ss = |
980 fun unsafe_solver prems = FIRST'[resolve_tac (triv_rls@prems), |
950 empty_ss |
981 atac, etac FalseE]; |
951 setmksimps (map mk_meta_eq o atomize o gen_all) |
982 fun safe_solver prems = FIRST'[match_tac (triv_rls@prems), |
952 setsolver (fn prems => resolve_tac (triv_rls \at prems) |
983 eq_assume_tac, ematch_tac [FalseE]]; |
953 ORELSE' assume_tac |
984 val IFOL_ss = empty_ss setsubgoaler asm_simp_tac |
954 ORELSE' etac FalseE) |
985 setSSolver safe_solver |
955 setsubgoaler asm_simp_tac |
986 setSolver unsafe_solver |
956 addsimps IFOL_rews |
987 setmksimps (map mk_meta_eq o atomize o gen_all) |
957 addcongs [imp_cong]; |
988 addsimps IFOL_simps |
|
989 addcongs [imp_cong]; |
958 \end{ttbox} |
990 \end{ttbox} |
959 This simpset takes {\tt imp_cong} as a congruence rule in order to use |
991 This simpset takes {\tt imp_cong} as a congruence rule in order to use |
960 contextual information to simplify the conclusions of implications: |
992 contextual information to simplify the conclusions of implications: |
961 \[ \List{\Var{P}\bimp\Var{P'};\; \Var{P'} \Imp \Var{Q}\bimp\Var{Q'}} \Imp |
993 \[ \List{\Var{P}\bimp\Var{P'};\; \Var{P'} \Imp \Var{Q}\bimp\Var{Q'}} \Imp |
962 (\Var{P}\imp\Var{Q}) \bimp (\Var{P'}\imp\Var{Q'}) |
994 (\Var{P}\imp\Var{Q}) \bimp (\Var{P'}\imp\Var{Q'}) |