src/Doc/Implementation/Tactic.thy
changeset 73764 35d8132633c6
parent 73763 eccc4a13216d
child 73765 ebaed09ce06e
equal deleted inserted replaced
73763:eccc4a13216d 73764:35d8132633c6
    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