59 \] |
59 \] |
60 \<close> |
60 \<close> |
61 |
61 |
62 text %mlref \<open> |
62 text %mlref \<open> |
63 \begin{mldecls} |
63 \begin{mldecls} |
64 @{index_ML Goal.init: "cterm -> thm"} \\ |
64 @{define_ML Goal.init: "cterm -> thm"} \\ |
65 @{index_ML Goal.finish: "Proof.context -> thm -> thm"} \\ |
65 @{define_ML Goal.finish: "Proof.context -> thm -> thm"} \\ |
66 @{index_ML Goal.protect: "int -> thm -> thm"} \\ |
66 @{define_ML Goal.protect: "int -> thm -> thm"} \\ |
67 @{index_ML Goal.conclude: "thm -> thm"} \\ |
67 @{define_ML Goal.conclude: "thm -> thm"} \\ |
68 \end{mldecls} |
68 \end{mldecls} |
69 |
69 |
70 \<^descr> \<^ML>\<open>Goal.init\<close>~\<open>C\<close> initializes a tactical goal from the well-formed |
70 \<^descr> \<^ML>\<open>Goal.init\<close>~\<open>C\<close> initializes a tactical goal from the well-formed |
71 proposition \<open>C\<close>. |
71 proposition \<open>C\<close>. |
72 |
72 |
154 prevent composition via standard tacticals such as \<^ML>\<open>REPEAT\<close>). |
154 prevent composition via standard tacticals such as \<^ML>\<open>REPEAT\<close>). |
155 \<close> |
155 \<close> |
156 |
156 |
157 text %mlref \<open> |
157 text %mlref \<open> |
158 \begin{mldecls} |
158 \begin{mldecls} |
159 @{index_ML_type tactic = "thm -> thm Seq.seq"} \\ |
159 @{define_ML_type tactic = "thm -> thm Seq.seq"} \\ |
160 @{index_ML no_tac: tactic} \\ |
160 @{define_ML no_tac: tactic} \\ |
161 @{index_ML all_tac: tactic} \\ |
161 @{define_ML all_tac: tactic} \\ |
162 @{index_ML print_tac: "Proof.context -> string -> tactic"} \\[1ex] |
162 @{define_ML print_tac: "Proof.context -> string -> tactic"} \\[1ex] |
163 @{index_ML PRIMITIVE: "(thm -> thm) -> tactic"} \\[1ex] |
163 @{define_ML PRIMITIVE: "(thm -> thm) -> tactic"} \\[1ex] |
164 @{index_ML SUBGOAL: "(term * int -> tactic) -> int -> tactic"} \\ |
164 @{define_ML SUBGOAL: "(term * int -> tactic) -> int -> tactic"} \\ |
165 @{index_ML CSUBGOAL: "(cterm * int -> tactic) -> int -> tactic"} \\ |
165 @{define_ML CSUBGOAL: "(cterm * int -> tactic) -> int -> tactic"} \\ |
166 @{index_ML SELECT_GOAL: "tactic -> int -> tactic"} \\ |
166 @{define_ML SELECT_GOAL: "tactic -> int -> tactic"} \\ |
167 @{index_ML PREFER_GOAL: "tactic -> int -> tactic"} \\ |
167 @{define_ML PREFER_GOAL: "tactic -> int -> tactic"} \\ |
168 \end{mldecls} |
168 \end{mldecls} |
169 |
169 |
170 \<^descr> Type \<^ML_type>\<open>tactic\<close> represents tactics. The well-formedness conditions |
170 \<^descr> Type \<^ML_type>\<open>tactic\<close> represents tactics. The well-formedness conditions |
171 described above need to be observed. See also \<^file>\<open>~~/src/Pure/General/seq.ML\<close> |
171 described above need to be observed. See also \<^file>\<open>~~/src/Pure/General/seq.ML\<close> |
172 for the underlying implementation of lazy sequences. |
172 for the underlying implementation of lazy sequences. |
241 enumerated here. |
241 enumerated here. |
242 \<close> |
242 \<close> |
243 |
243 |
244 text %mlref \<open> |
244 text %mlref \<open> |
245 \begin{mldecls} |
245 \begin{mldecls} |
246 @{index_ML resolve_tac: "Proof.context -> thm list -> int -> tactic"} \\ |
246 @{define_ML resolve_tac: "Proof.context -> thm list -> int -> tactic"} \\ |
247 @{index_ML eresolve_tac: "Proof.context -> thm list -> int -> tactic"} \\ |
247 @{define_ML eresolve_tac: "Proof.context -> thm list -> int -> tactic"} \\ |
248 @{index_ML dresolve_tac: "Proof.context -> thm list -> int -> tactic"} \\ |
248 @{define_ML dresolve_tac: "Proof.context -> thm list -> int -> tactic"} \\ |
249 @{index_ML forward_tac: "Proof.context -> thm list -> int -> tactic"} \\ |
249 @{define_ML forward_tac: "Proof.context -> thm list -> int -> tactic"} \\ |
250 @{index_ML biresolve_tac: "Proof.context -> (bool * thm) list -> int -> tactic"} \\[1ex] |
250 @{define_ML biresolve_tac: "Proof.context -> (bool * thm) list -> int -> tactic"} \\[1ex] |
251 @{index_ML assume_tac: "Proof.context -> int -> tactic"} \\ |
251 @{define_ML assume_tac: "Proof.context -> int -> tactic"} \\ |
252 @{index_ML eq_assume_tac: "int -> tactic"} \\[1ex] |
252 @{define_ML eq_assume_tac: "int -> tactic"} \\[1ex] |
253 @{index_ML match_tac: "Proof.context -> thm list -> int -> tactic"} \\ |
253 @{define_ML match_tac: "Proof.context -> thm list -> int -> tactic"} \\ |
254 @{index_ML ematch_tac: "Proof.context -> thm list -> int -> tactic"} \\ |
254 @{define_ML ematch_tac: "Proof.context -> thm list -> int -> tactic"} \\ |
255 @{index_ML dmatch_tac: "Proof.context -> thm list -> int -> tactic"} \\ |
255 @{define_ML dmatch_tac: "Proof.context -> thm list -> int -> tactic"} \\ |
256 @{index_ML bimatch_tac: "Proof.context -> (bool * thm) list -> int -> tactic"} \\ |
256 @{define_ML bimatch_tac: "Proof.context -> (bool * thm) list -> int -> tactic"} \\ |
257 \end{mldecls} |
257 \end{mldecls} |
258 |
258 |
259 \<^descr> \<^ML>\<open>resolve_tac\<close>~\<open>ctxt thms i\<close> refines the goal state using the given |
259 \<^descr> \<^ML>\<open>resolve_tac\<close>~\<open>ctxt thms i\<close> refines the goal state using the given |
260 theorems, which should normally be introduction rules. The tactic resolves a |
260 theorems, which should normally be introduction rules. The tactic resolves a |
261 rule's conclusion with subgoal \<open>i\<close>, replacing it by the corresponding |
261 rule's conclusion with subgoal \<open>i\<close>, replacing it by the corresponding |
349 type instantiations are seldom necessary. |
349 type instantiations are seldom necessary. |
350 \<close> |
350 \<close> |
351 |
351 |
352 text %mlref \<open> |
352 text %mlref \<open> |
353 \begin{mldecls} |
353 \begin{mldecls} |
354 @{index_ML Rule_Insts.res_inst_tac: "Proof.context -> |
354 @{define_ML Rule_Insts.res_inst_tac: "Proof.context -> |
355 ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> |
355 ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> |
356 thm -> int -> tactic"} \\ |
356 thm -> int -> tactic"} \\ |
357 @{index_ML Rule_Insts.eres_inst_tac: "Proof.context -> |
357 @{define_ML Rule_Insts.eres_inst_tac: "Proof.context -> |
358 ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> |
358 ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> |
359 thm -> int -> tactic"} \\ |
359 thm -> int -> tactic"} \\ |
360 @{index_ML Rule_Insts.dres_inst_tac: "Proof.context -> |
360 @{define_ML Rule_Insts.dres_inst_tac: "Proof.context -> |
361 ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> |
361 ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> |
362 thm -> int -> tactic"} \\ |
362 thm -> int -> tactic"} \\ |
363 @{index_ML Rule_Insts.forw_inst_tac: "Proof.context -> |
363 @{define_ML Rule_Insts.forw_inst_tac: "Proof.context -> |
364 ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> |
364 ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> |
365 thm -> int -> tactic"} \\ |
365 thm -> int -> tactic"} \\ |
366 @{index_ML Rule_Insts.subgoal_tac: "Proof.context -> string -> |
366 @{define_ML Rule_Insts.subgoal_tac: "Proof.context -> string -> |
367 (binding * string option * mixfix) list -> int -> tactic"} \\ |
367 (binding * string option * mixfix) list -> int -> tactic"} \\ |
368 @{index_ML Rule_Insts.thin_tac: "Proof.context -> string -> |
368 @{define_ML Rule_Insts.thin_tac: "Proof.context -> string -> |
369 (binding * string option * mixfix) list -> int -> tactic"} \\ |
369 (binding * string option * mixfix) list -> int -> tactic"} \\ |
370 @{index_ML rename_tac: "string list -> int -> tactic"} \\ |
370 @{define_ML rename_tac: "string list -> int -> tactic"} \\ |
371 \end{mldecls} |
371 \end{mldecls} |
372 |
372 |
373 \<^descr> \<^ML>\<open>Rule_Insts.res_inst_tac\<close>~\<open>ctxt insts thm i\<close> instantiates the rule |
373 \<^descr> \<^ML>\<open>Rule_Insts.res_inst_tac\<close>~\<open>ctxt insts thm i\<close> instantiates the rule |
374 \<open>thm\<close> with the instantiations \<open>insts\<close>, as described above, and then performs |
374 \<open>thm\<close> with the instantiations \<open>insts\<close>, as described above, and then performs |
375 resolution on subgoal \<open>i\<close>. |
375 resolution on subgoal \<open>i\<close>. |
413 conceptual sets of formulae. |
413 conceptual sets of formulae. |
414 \<close> |
414 \<close> |
415 |
415 |
416 text %mlref \<open> |
416 text %mlref \<open> |
417 \begin{mldecls} |
417 \begin{mldecls} |
418 @{index_ML rotate_tac: "int -> int -> tactic"} \\ |
418 @{define_ML rotate_tac: "int -> int -> tactic"} \\ |
419 @{index_ML distinct_subgoals_tac: tactic} \\ |
419 @{define_ML distinct_subgoals_tac: tactic} \\ |
420 @{index_ML flexflex_tac: "Proof.context -> tactic"} \\ |
420 @{define_ML flexflex_tac: "Proof.context -> tactic"} \\ |
421 \end{mldecls} |
421 \end{mldecls} |
422 |
422 |
423 \<^descr> \<^ML>\<open>rotate_tac\<close>~\<open>n i\<close> rotates the premises of subgoal \<open>i\<close> by \<open>n\<close> |
423 \<^descr> \<^ML>\<open>rotate_tac\<close>~\<open>n i\<close> rotates the premises of subgoal \<open>i\<close> by \<open>n\<close> |
424 positions: from right to left if \<open>n\<close> is positive, and from left to right if |
424 positions: from right to left if \<open>n\<close> is positive, and from left to right if |
425 \<open>n\<close> is negative. |
425 \<open>n\<close> is negative. |
448 Schematic variables are not renamed by default, so beware of clashes! |
448 Schematic variables are not renamed by default, so beware of clashes! |
449 \<close> |
449 \<close> |
450 |
450 |
451 text %mlref \<open> |
451 text %mlref \<open> |
452 \begin{mldecls} |
452 \begin{mldecls} |
453 @{index_ML compose_tac: "Proof.context -> (bool * thm * int) -> int -> tactic"} \\ |
453 @{define_ML compose_tac: "Proof.context -> (bool * thm * int) -> int -> tactic"} \\ |
454 @{index_ML Drule.compose: "thm * int * thm -> thm"} \\ |
454 @{define_ML Drule.compose: "thm * int * thm -> thm"} \\ |
455 @{index_ML_infix COMP: "thm * thm -> thm"} \\ |
455 @{define_ML_infix COMP: "thm * thm -> thm"} \\ |
456 \end{mldecls} |
456 \end{mldecls} |
457 |
457 |
458 \<^descr> \<^ML>\<open>compose_tac\<close>~\<open>ctxt (flag, rule, m) i\<close> refines subgoal \<open>i\<close> using |
458 \<^descr> \<^ML>\<open>compose_tac\<close>~\<open>ctxt (flag, rule, m) i\<close> refines subgoal \<open>i\<close> using |
459 \<open>rule\<close>, without lifting. The \<open>rule\<close> is taken to have the form \<open>\<psi>\<^sub>1 \<Longrightarrow> \<dots> \<psi>\<^sub>m \<Longrightarrow> |
459 \<open>rule\<close>, without lifting. The \<open>rule\<close> is taken to have the form \<open>\<psi>\<^sub>1 \<Longrightarrow> \<dots> \<psi>\<^sub>m \<Longrightarrow> |
460 \<psi>\<close>, where \<open>\<psi>\<close> need not be atomic; thus \<open>m\<close> determines the number of new |
460 \<psi>\<close>, where \<open>\<psi>\<close> need not be atomic; thus \<open>m\<close> determines the number of new |
500 subgoal addressing. |
500 subgoal addressing. |
501 \<close> |
501 \<close> |
502 |
502 |
503 text %mlref \<open> |
503 text %mlref \<open> |
504 \begin{mldecls} |
504 \begin{mldecls} |
505 @{index_ML_infix "THEN": "tactic * tactic -> tactic"} \\ |
505 @{define_ML_infix "THEN": "tactic * tactic -> tactic"} \\ |
506 @{index_ML_infix "ORELSE": "tactic * tactic -> tactic"} \\ |
506 @{define_ML_infix "ORELSE": "tactic * tactic -> tactic"} \\ |
507 @{index_ML_infix "APPEND": "tactic * tactic -> tactic"} \\ |
507 @{define_ML_infix "APPEND": "tactic * tactic -> tactic"} \\ |
508 @{index_ML "EVERY": "tactic list -> tactic"} \\ |
508 @{define_ML "EVERY": "tactic list -> tactic"} \\ |
509 @{index_ML "FIRST": "tactic list -> tactic"} \\[0.5ex] |
509 @{define_ML "FIRST": "tactic list -> tactic"} \\[0.5ex] |
510 |
510 |
511 @{index_ML_infix "THEN'": "('a -> tactic) * ('a -> tactic) -> 'a -> tactic"} \\ |
511 @{define_ML_infix "THEN'": "('a -> tactic) * ('a -> tactic) -> 'a -> tactic"} \\ |
512 @{index_ML_infix "ORELSE'": "('a -> tactic) * ('a -> tactic) -> 'a -> tactic"} \\ |
512 @{define_ML_infix "ORELSE'": "('a -> tactic) * ('a -> tactic) -> 'a -> tactic"} \\ |
513 @{index_ML_infix "APPEND'": "('a -> tactic) * ('a -> tactic) -> 'a -> tactic"} \\ |
513 @{define_ML_infix "APPEND'": "('a -> tactic) * ('a -> tactic) -> 'a -> tactic"} \\ |
514 @{index_ML "EVERY'": "('a -> tactic) list -> 'a -> tactic"} \\ |
514 @{define_ML "EVERY'": "('a -> tactic) list -> 'a -> tactic"} \\ |
515 @{index_ML "FIRST'": "('a -> tactic) list -> 'a -> tactic"} \\ |
515 @{define_ML "FIRST'": "('a -> tactic) list -> 'a -> tactic"} \\ |
516 \end{mldecls} |
516 \end{mldecls} |
517 |
517 |
518 \<^descr> \<open>tac\<^sub>1\<close>~\<^ML_op>\<open>THEN\<close>~\<open>tac\<^sub>2\<close> is the sequential composition of \<open>tac\<^sub>1\<close> and |
518 \<^descr> \<open>tac\<^sub>1\<close>~\<^ML_op>\<open>THEN\<close>~\<open>tac\<^sub>2\<close> is the sequential composition of \<open>tac\<^sub>1\<close> and |
519 \<open>tac\<^sub>2\<close>. Applied to a goal state, it returns all states reachable in two |
519 \<open>tac\<^sub>2\<close>. Applied to a goal state, it returns all states reachable in two |
520 steps by applying \<open>tac\<^sub>1\<close> followed by \<open>tac\<^sub>2\<close>. First, it applies \<open>tac\<^sub>1\<close> to |
520 steps by applying \<open>tac\<^sub>1\<close> followed by \<open>tac\<^sub>2\<close>. First, it applies \<open>tac\<^sub>1\<close> to |
553 the stylized forms of ``\<^verbatim>\<open>?\<close>'' and ``\<^verbatim>\<open>+\<close>'' in Isar method expressions. |
553 the stylized forms of ``\<^verbatim>\<open>?\<close>'' and ``\<^verbatim>\<open>+\<close>'' in Isar method expressions. |
554 \<close> |
554 \<close> |
555 |
555 |
556 text %mlref \<open> |
556 text %mlref \<open> |
557 \begin{mldecls} |
557 \begin{mldecls} |
558 @{index_ML "TRY": "tactic -> tactic"} \\ |
558 @{define_ML "TRY": "tactic -> tactic"} \\ |
559 @{index_ML "REPEAT": "tactic -> tactic"} \\ |
559 @{define_ML "REPEAT": "tactic -> tactic"} \\ |
560 @{index_ML "REPEAT1": "tactic -> tactic"} \\ |
560 @{define_ML "REPEAT1": "tactic -> tactic"} \\ |
561 @{index_ML "REPEAT_DETERM": "tactic -> tactic"} \\ |
561 @{define_ML "REPEAT_DETERM": "tactic -> tactic"} \\ |
562 @{index_ML "REPEAT_DETERM_N": "int -> tactic -> tactic"} \\ |
562 @{define_ML "REPEAT_DETERM_N": "int -> tactic -> tactic"} \\ |
563 \end{mldecls} |
563 \end{mldecls} |
564 |
564 |
565 \<^descr> \<^ML>\<open>TRY\<close>~\<open>tac\<close> applies \<open>tac\<close> to the goal state and returns the resulting |
565 \<^descr> \<^ML>\<open>TRY\<close>~\<open>tac\<close> applies \<open>tac\<close> to the goal state and returns the resulting |
566 sequence, if non-empty; otherwise it returns the original state. Thus, it |
566 sequence, if non-empty; otherwise it returns the original state. Thus, it |
567 applies \<open>tac\<close> at most once. |
567 applies \<open>tac\<close> at most once. |
639 situations where a different order is desired. |
639 situations where a different order is desired. |
640 \<close> |
640 \<close> |
641 |
641 |
642 text %mlref \<open> |
642 text %mlref \<open> |
643 \begin{mldecls} |
643 \begin{mldecls} |
644 @{index_ML ALLGOALS: "(int -> tactic) -> tactic"} \\ |
644 @{define_ML ALLGOALS: "(int -> tactic) -> tactic"} \\ |
645 @{index_ML SOMEGOAL: "(int -> tactic) -> tactic"} \\ |
645 @{define_ML SOMEGOAL: "(int -> tactic) -> tactic"} \\ |
646 @{index_ML FIRSTGOAL: "(int -> tactic) -> tactic"} \\ |
646 @{define_ML FIRSTGOAL: "(int -> tactic) -> tactic"} \\ |
647 @{index_ML HEADGOAL: "(int -> tactic) -> tactic"} \\ |
647 @{define_ML HEADGOAL: "(int -> tactic) -> tactic"} \\ |
648 @{index_ML REPEAT_SOME: "(int -> tactic) -> tactic"} \\ |
648 @{define_ML REPEAT_SOME: "(int -> tactic) -> tactic"} \\ |
649 @{index_ML REPEAT_FIRST: "(int -> tactic) -> tactic"} \\ |
649 @{define_ML REPEAT_FIRST: "(int -> tactic) -> tactic"} \\ |
650 @{index_ML RANGE: "(int -> tactic) list -> int -> tactic"} \\ |
650 @{define_ML RANGE: "(int -> tactic) list -> int -> tactic"} \\ |
651 \end{mldecls} |
651 \end{mldecls} |
652 |
652 |
653 \<^descr> \<^ML>\<open>ALLGOALS\<close>~\<open>tac\<close> is equivalent to \<open>tac n\<close>~\<^ML_op>\<open>THEN\<close>~\<open>\<dots>\<close>~\<^ML_op>\<open>THEN\<close>~\<open>tac 1\<close>. It applies the \<open>tac\<close> to all the subgoals, counting downwards. |
653 \<^descr> \<^ML>\<open>ALLGOALS\<close>~\<open>tac\<close> is equivalent to \<open>tac n\<close>~\<^ML_op>\<open>THEN\<close>~\<open>\<dots>\<close>~\<^ML_op>\<open>THEN\<close>~\<open>tac 1\<close>. It applies the \<open>tac\<close> to all the subgoals, counting downwards. |
654 |
654 |
655 \<^descr> \<^ML>\<open>SOMEGOAL\<close>~\<open>tac\<close> is equivalent to \<open>tac n\<close>~\<^ML_op>\<open>ORELSE\<close>~\<open>\<dots>\<close>~\<^ML_op>\<open>ORELSE\<close>~\<open>tac 1\<close>. It applies \<open>tac\<close> to one subgoal, counting downwards. |
655 \<^descr> \<^ML>\<open>SOMEGOAL\<close>~\<open>tac\<close> is equivalent to \<open>tac n\<close>~\<^ML_op>\<open>ORELSE\<close>~\<open>\<dots>\<close>~\<^ML_op>\<open>ORELSE\<close>~\<open>tac 1\<close>. It applies \<open>tac\<close> to one subgoal, counting downwards. |
687 |
687 |
688 subsubsection \<open>Filtering a tactic's results\<close> |
688 subsubsection \<open>Filtering a tactic's results\<close> |
689 |
689 |
690 text \<open> |
690 text \<open> |
691 \begin{mldecls} |
691 \begin{mldecls} |
692 @{index_ML FILTER: "(thm -> bool) -> tactic -> tactic"} \\ |
692 @{define_ML FILTER: "(thm -> bool) -> tactic -> tactic"} \\ |
693 @{index_ML CHANGED: "tactic -> tactic"} \\ |
693 @{define_ML CHANGED: "tactic -> tactic"} \\ |
694 \end{mldecls} |
694 \end{mldecls} |
695 |
695 |
696 \<^descr> \<^ML>\<open>FILTER\<close>~\<open>sat tac\<close> applies \<open>tac\<close> to the goal state and returns a |
696 \<^descr> \<^ML>\<open>FILTER\<close>~\<open>sat tac\<close> applies \<open>tac\<close> to the goal state and returns a |
697 sequence consisting of those result goal states that are satisfactory in the |
697 sequence consisting of those result goal states that are satisfactory in the |
698 sense of \<open>sat\<close>. |
698 sense of \<open>sat\<close>. |
704 |
704 |
705 subsubsection \<open>Depth-first search\<close> |
705 subsubsection \<open>Depth-first search\<close> |
706 |
706 |
707 text \<open> |
707 text \<open> |
708 \begin{mldecls} |
708 \begin{mldecls} |
709 @{index_ML DEPTH_FIRST: "(thm -> bool) -> tactic -> tactic"} \\ |
709 @{define_ML DEPTH_FIRST: "(thm -> bool) -> tactic -> tactic"} \\ |
710 @{index_ML DEPTH_SOLVE: "tactic -> tactic"} \\ |
710 @{define_ML DEPTH_SOLVE: "tactic -> tactic"} \\ |
711 @{index_ML DEPTH_SOLVE_1: "tactic -> tactic"} \\ |
711 @{define_ML DEPTH_SOLVE_1: "tactic -> tactic"} \\ |
712 \end{mldecls} |
712 \end{mldecls} |
713 |
713 |
714 \<^descr> \<^ML>\<open>DEPTH_FIRST\<close>~\<open>sat tac\<close> returns the goal state if \<open>sat\<close> returns true. |
714 \<^descr> \<^ML>\<open>DEPTH_FIRST\<close>~\<open>sat tac\<close> returns the goal state if \<open>sat\<close> returns true. |
715 Otherwise it applies \<open>tac\<close>, then recursively searches from each element of |
715 Otherwise it applies \<open>tac\<close>, then recursively searches from each element of |
716 the resulting sequence. The code uses a stack for efficiency, in effect |
716 the resulting sequence. The code uses a stack for efficiency, in effect |
727 |
727 |
728 subsubsection \<open>Other search strategies\<close> |
728 subsubsection \<open>Other search strategies\<close> |
729 |
729 |
730 text \<open> |
730 text \<open> |
731 \begin{mldecls} |
731 \begin{mldecls} |
732 @{index_ML BREADTH_FIRST: "(thm -> bool) -> tactic -> tactic"} \\ |
732 @{define_ML BREADTH_FIRST: "(thm -> bool) -> tactic -> tactic"} \\ |
733 @{index_ML BEST_FIRST: "(thm -> bool) * (thm -> int) -> tactic -> tactic"} \\ |
733 @{define_ML BEST_FIRST: "(thm -> bool) * (thm -> int) -> tactic -> tactic"} \\ |
734 @{index_ML THEN_BEST_FIRST: "tactic -> (thm -> bool) * (thm -> int) -> tactic -> tactic"} \\ |
734 @{define_ML THEN_BEST_FIRST: "tactic -> (thm -> bool) * (thm -> int) -> tactic -> tactic"} \\ |
735 \end{mldecls} |
735 \end{mldecls} |
736 |
736 |
737 These search strategies will find a solution if one exists. However, they do |
737 These search strategies will find a solution if one exists. However, they do |
738 not enumerate all solutions; they terminate after the first satisfactory |
738 not enumerate all solutions; they terminate after the first satisfactory |
739 result from \<open>tac\<close>. |
739 result from \<open>tac\<close>. |
761 |
761 |
762 subsubsection \<open>Auxiliary tacticals for searching\<close> |
762 subsubsection \<open>Auxiliary tacticals for searching\<close> |
763 |
763 |
764 text \<open> |
764 text \<open> |
765 \begin{mldecls} |
765 \begin{mldecls} |
766 @{index_ML COND: "(thm -> bool) -> tactic -> tactic -> tactic"} \\ |
766 @{define_ML COND: "(thm -> bool) -> tactic -> tactic -> tactic"} \\ |
767 @{index_ML IF_UNSOLVED: "tactic -> tactic"} \\ |
767 @{define_ML IF_UNSOLVED: "tactic -> tactic"} \\ |
768 @{index_ML SOLVE: "tactic -> tactic"} \\ |
768 @{define_ML SOLVE: "tactic -> tactic"} \\ |
769 @{index_ML DETERM: "tactic -> tactic"} \\ |
769 @{define_ML DETERM: "tactic -> tactic"} \\ |
770 \end{mldecls} |
770 \end{mldecls} |
771 |
771 |
772 \<^descr> \<^ML>\<open>COND\<close>~\<open>sat tac\<^sub>1 tac\<^sub>2\<close> applies \<open>tac\<^sub>1\<close> to the goal state if it |
772 \<^descr> \<^ML>\<open>COND\<close>~\<open>sat tac\<^sub>1 tac\<^sub>2\<close> applies \<open>tac\<^sub>1\<close> to the goal state if it |
773 satisfies predicate \<open>sat\<close>, and applies \<open>tac\<^sub>2\<close>. It is a conditional tactical |
773 satisfies predicate \<open>sat\<close>, and applies \<open>tac\<^sub>2\<close>. It is a conditional tactical |
774 in that only one of \<open>tac\<^sub>1\<close> and \<open>tac\<^sub>2\<close> is applied to a goal state. However, |
774 in that only one of \<open>tac\<^sub>1\<close> and \<open>tac\<^sub>2\<close> is applied to a goal state. However, |
790 |
790 |
791 subsubsection \<open>Predicates and functions useful for searching\<close> |
791 subsubsection \<open>Predicates and functions useful for searching\<close> |
792 |
792 |
793 text \<open> |
793 text \<open> |
794 \begin{mldecls} |
794 \begin{mldecls} |
795 @{index_ML has_fewer_prems: "int -> thm -> bool"} \\ |
795 @{define_ML has_fewer_prems: "int -> thm -> bool"} \\ |
796 @{index_ML Thm.eq_thm: "thm * thm -> bool"} \\ |
796 @{define_ML Thm.eq_thm: "thm * thm -> bool"} \\ |
797 @{index_ML Thm.eq_thm_prop: "thm * thm -> bool"} \\ |
797 @{define_ML Thm.eq_thm_prop: "thm * thm -> bool"} \\ |
798 @{index_ML size_of_thm: "thm -> int"} \\ |
798 @{define_ML size_of_thm: "thm -> int"} \\ |
799 \end{mldecls} |
799 \end{mldecls} |
800 |
800 |
801 \<^descr> \<^ML>\<open>has_fewer_prems\<close>~\<open>n thm\<close> reports whether \<open>thm\<close> has fewer than \<open>n\<close> |
801 \<^descr> \<^ML>\<open>has_fewer_prems\<close>~\<open>n thm\<close> reports whether \<open>thm\<close> has fewer than \<open>n\<close> |
802 premises. |
802 premises. |
803 |
803 |