src/Doc/Implementation/Tactic.thy
changeset 61493 0debd22f0c0e
parent 61477 e467ae7aa808
child 61503 28e788ca2c5d
equal deleted inserted replaced
61492:3480725c71d2 61493:0debd22f0c0e
     3 begin
     3 begin
     4 
     4 
     5 chapter \<open>Tactical reasoning\<close>
     5 chapter \<open>Tactical reasoning\<close>
     6 
     6 
     7 text \<open>Tactical reasoning works by refining an initial claim in a
     7 text \<open>Tactical reasoning works by refining an initial claim in a
     8   backwards fashion, until a solved form is reached.  A @{text "goal"}
     8   backwards fashion, until a solved form is reached.  A \<open>goal\<close>
     9   consists of several subgoals that need to be solved in order to
     9   consists of several subgoals that need to be solved in order to
    10   achieve the main statement; zero subgoals means that the proof may
    10   achieve the main statement; zero subgoals means that the proof may
    11   be finished.  A @{text "tactic"} is a refinement operation that maps
    11   be finished.  A \<open>tactic\<close> is a refinement operation that maps
    12   a goal to a lazy sequence of potential successors.  A @{text
    12   a goal to a lazy sequence of potential successors.  A \<open>tactical\<close> is a combinator for composing tactics.\<close>
    13   "tactical"} is a combinator for composing tactics.\<close>
       
    14 
    13 
    15 
    14 
    16 section \<open>Goals \label{sec:tactical-goals}\<close>
    15 section \<open>Goals \label{sec:tactical-goals}\<close>
    17 
    16 
    18 text \<open>
    17 text \<open>
    19   Isabelle/Pure represents a goal as a theorem stating that the
    18   Isabelle/Pure represents a goal as a theorem stating that the
    20   subgoals imply the main goal: @{text "A\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^sub>n \<Longrightarrow>
    19   subgoals imply the main goal: \<open>A\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^sub>n \<Longrightarrow>
    21   C"}.  The outermost goal structure is that of a Horn Clause: i.e.\
    20   C\<close>.  The outermost goal structure is that of a Horn Clause: i.e.\
    22   an iterated implication without any quantifiers\footnote{Recall that
    21   an iterated implication without any quantifiers\footnote{Recall that
    23   outermost @{text "\<And>x. \<phi>[x]"} is always represented via schematic
    22   outermost \<open>\<And>x. \<phi>[x]\<close> is always represented via schematic
    24   variables in the body: @{text "\<phi>[?x]"}.  These variables may get
    23   variables in the body: \<open>\<phi>[?x]\<close>.  These variables may get
    25   instantiated during the course of reasoning.}.  For @{text "n = 0"}
    24   instantiated during the course of reasoning.}.  For \<open>n = 0\<close>
    26   a goal is called ``solved''.
    25   a goal is called ``solved''.
    27 
    26 
    28   The structure of each subgoal @{text "A\<^sub>i"} is that of a
    27   The structure of each subgoal \<open>A\<^sub>i\<close> is that of a
    29   general Hereditary Harrop Formula @{text "\<And>x\<^sub>1 \<dots>
    28   general Hereditary Harrop Formula \<open>\<And>x\<^sub>1 \<dots>
    30   \<And>x\<^sub>k. H\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> H\<^sub>m \<Longrightarrow> B"}.  Here @{text
    29   \<And>x\<^sub>k. H\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> H\<^sub>m \<Longrightarrow> B\<close>.  Here \<open>x\<^sub>1, \<dots>, x\<^sub>k\<close> are goal parameters, i.e.\
    31   "x\<^sub>1, \<dots>, x\<^sub>k"} are goal parameters, i.e.\
    30   arbitrary-but-fixed entities of certain types, and \<open>H\<^sub>1, \<dots>, H\<^sub>m\<close> are goal hypotheses, i.e.\ facts that may
    32   arbitrary-but-fixed entities of certain types, and @{text
       
    33   "H\<^sub>1, \<dots>, H\<^sub>m"} are goal hypotheses, i.e.\ facts that may
       
    34   be assumed locally.  Together, this forms the goal context of the
    31   be assumed locally.  Together, this forms the goal context of the
    35   conclusion @{text B} to be established.  The goal hypotheses may be
    32   conclusion \<open>B\<close> to be established.  The goal hypotheses may be
    36   again arbitrary Hereditary Harrop Formulas, although the level of
    33   again arbitrary Hereditary Harrop Formulas, although the level of
    37   nesting rarely exceeds 1--2 in practice.
    34   nesting rarely exceeds 1--2 in practice.
    38 
    35 
    39   The main conclusion @{text C} is internally marked as a protected
    36   The main conclusion \<open>C\<close> is internally marked as a protected
    40   proposition, which is represented explicitly by the notation @{text
    37   proposition, which is represented explicitly by the notation \<open>#C\<close> here.  This ensures that the decomposition into subgoals and
    41   "#C"} here.  This ensures that the decomposition into subgoals and
       
    42   main conclusion is well-defined for arbitrarily structured claims.
    38   main conclusion is well-defined for arbitrarily structured claims.
    43 
    39 
    44   \<^medskip>
    40   \<^medskip>
    45   Basic goal management is performed via the following
    41   Basic goal management is performed via the following
    46   Isabelle/Pure rules:
    42   Isabelle/Pure rules:
    47 
    43 
    48   \[
    44   \[
    49   \infer[@{text "(init)"}]{@{text "C \<Longrightarrow> #C"}}{} \qquad
    45   \infer[\<open>(init)\<close>]{\<open>C \<Longrightarrow> #C\<close>}{} \qquad
    50   \infer[@{text "(finish)"}]{@{text "C"}}{@{text "#C"}}
    46   \infer[\<open>(finish)\<close>]{\<open>C\<close>}{\<open>#C\<close>}
    51   \]
    47   \]
    52 
    48 
    53   \<^medskip>
    49   \<^medskip>
    54   The following low-level variants admit general reasoning
    50   The following low-level variants admit general reasoning
    55   with protected propositions:
    51   with protected propositions:
    56 
    52 
    57   \[
    53   \[
    58   \infer[@{text "(protect n)"}]{@{text "A\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^sub>n \<Longrightarrow> #C"}}{@{text "A\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^sub>n \<Longrightarrow> C"}}
    54   \infer[\<open>(protect n)\<close>]{\<open>A\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^sub>n \<Longrightarrow> #C\<close>}{\<open>A\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^sub>n \<Longrightarrow> C\<close>}
    59   \]
    55   \]
    60   \[
    56   \[
    61   \infer[@{text "(conclude)"}]{@{text "A \<Longrightarrow> \<dots> \<Longrightarrow> C"}}{@{text "A \<Longrightarrow> \<dots> \<Longrightarrow> #C"}}
    57   \infer[\<open>(conclude)\<close>]{\<open>A \<Longrightarrow> \<dots> \<Longrightarrow> C\<close>}{\<open>A \<Longrightarrow> \<dots> \<Longrightarrow> #C\<close>}
    62   \]
    58   \]
    63 \<close>
    59 \<close>
    64 
    60 
    65 text %mlref \<open>
    61 text %mlref \<open>
    66   \begin{mldecls}
    62   \begin{mldecls}
    68   @{index_ML Goal.finish: "Proof.context -> thm -> thm"} \\
    64   @{index_ML Goal.finish: "Proof.context -> thm -> thm"} \\
    69   @{index_ML Goal.protect: "int -> thm -> thm"} \\
    65   @{index_ML Goal.protect: "int -> thm -> thm"} \\
    70   @{index_ML Goal.conclude: "thm -> thm"} \\
    66   @{index_ML Goal.conclude: "thm -> thm"} \\
    71   \end{mldecls}
    67   \end{mldecls}
    72 
    68 
    73   \<^descr> @{ML "Goal.init"}~@{text C} initializes a tactical goal from
    69   \<^descr> @{ML "Goal.init"}~\<open>C\<close> initializes a tactical goal from
    74   the well-formed proposition @{text C}.
    70   the well-formed proposition \<open>C\<close>.
    75 
    71 
    76   \<^descr> @{ML "Goal.finish"}~@{text "ctxt thm"} checks whether theorem
    72   \<^descr> @{ML "Goal.finish"}~\<open>ctxt thm\<close> checks whether theorem
    77   @{text "thm"} is a solved goal (no subgoals), and concludes the
    73   \<open>thm\<close> is a solved goal (no subgoals), and concludes the
    78   result by removing the goal protection.  The context is only
    74   result by removing the goal protection.  The context is only
    79   required for printing error messages.
    75   required for printing error messages.
    80 
    76 
    81   \<^descr> @{ML "Goal.protect"}~@{text "n thm"} protects the statement
    77   \<^descr> @{ML "Goal.protect"}~\<open>n thm\<close> protects the statement
    82   of theorem @{text "thm"}.  The parameter @{text n} indicates the
    78   of theorem \<open>thm\<close>.  The parameter \<open>n\<close> indicates the
    83   number of premises to be retained.
    79   number of premises to be retained.
    84 
    80 
    85   \<^descr> @{ML "Goal.conclude"}~@{text "thm"} removes the goal
    81   \<^descr> @{ML "Goal.conclude"}~\<open>thm\<close> removes the goal
    86   protection, even if there are pending subgoals.
    82   protection, even if there are pending subgoals.
    87 \<close>
    83 \<close>
    88 
    84 
    89 
    85 
    90 section \<open>Tactics\label{sec:tactics}\<close>
    86 section \<open>Tactics\label{sec:tactics}\<close>
    91 
    87 
    92 text \<open>A @{text "tactic"} is a function @{text "goal \<rightarrow> goal\<^sup>*\<^sup>*"} that
    88 text \<open>A \<open>tactic\<close> is a function \<open>goal \<rightarrow> goal\<^sup>*\<^sup>*\<close> that
    93   maps a given goal state (represented as a theorem, cf.\
    89   maps a given goal state (represented as a theorem, cf.\
    94   \secref{sec:tactical-goals}) to a lazy sequence of potential
    90   \secref{sec:tactical-goals}) to a lazy sequence of potential
    95   successor states.  The underlying sequence implementation is lazy
    91   successor states.  The underlying sequence implementation is lazy
    96   both in head and tail, and is purely functional in \<^emph>\<open>not\<close>
    92   both in head and tail, and is purely functional in \<^emph>\<open>not\<close>
    97   supporting memoing.\footnote{The lack of memoing and the strict
    93   supporting memoing.\footnote{The lack of memoing and the strict
   119   operate on all subgoals or on a particularly specified subgoal, but
   115   operate on all subgoals or on a particularly specified subgoal, but
   120   must not change the main conclusion (apart from instantiating
   116   must not change the main conclusion (apart from instantiating
   121   schematic goal variables).
   117   schematic goal variables).
   122 
   118 
   123   Tactics with explicit \<^emph>\<open>subgoal addressing\<close> are of the form
   119   Tactics with explicit \<^emph>\<open>subgoal addressing\<close> are of the form
   124   @{text "int \<rightarrow> tactic"} and may be applied to a particular subgoal
   120   \<open>int \<rightarrow> tactic\<close> and may be applied to a particular subgoal
   125   (counting from 1).  If the subgoal number is out of range, the
   121   (counting from 1).  If the subgoal number is out of range, the
   126   tactic should fail with an empty result sequence, but must not raise
   122   tactic should fail with an empty result sequence, but must not raise
   127   an exception!
   123   an exception!
   128 
   124 
   129   Operating on a particular subgoal means to replace it by an interval
   125   Operating on a particular subgoal means to replace it by an interval
   137   into unrelated subgoals that happen to come after the original
   133   into unrelated subgoals that happen to come after the original
   138   subgoal.  Assuming that there is only a single initial subgoal is a
   134   subgoal.  Assuming that there is only a single initial subgoal is a
   139   very common error when implementing tactics!
   135   very common error when implementing tactics!
   140 
   136 
   141   Tactics with internal subgoal addressing should expose the subgoal
   137   Tactics with internal subgoal addressing should expose the subgoal
   142   index as @{text "int"} argument in full generality; a hardwired
   138   index as \<open>int\<close> argument in full generality; a hardwired
   143   subgoal 1 is not acceptable.
   139   subgoal 1 is not acceptable.
   144   
   140   
   145   \<^medskip>
   141   \<^medskip>
   146   The main well-formedness conditions for proper tactics are
   142   The main well-formedness conditions for proper tactics are
   147   summarized as follows.
   143   summarized as follows.
   193   empty sequence.
   189   empty sequence.
   194 
   190 
   195   \<^descr> @{ML all_tac} is a tactic that always succeeds, returning a
   191   \<^descr> @{ML all_tac} is a tactic that always succeeds, returning a
   196   singleton sequence with unchanged goal state.
   192   singleton sequence with unchanged goal state.
   197 
   193 
   198   \<^descr> @{ML print_tac}~@{text "ctxt message"} is like @{ML all_tac}, but
   194   \<^descr> @{ML print_tac}~\<open>ctxt message\<close> is like @{ML all_tac}, but
   199   prints a message together with the goal state on the tracing
   195   prints a message together with the goal state on the tracing
   200   channel.
   196   channel.
   201 
   197 
   202   \<^descr> @{ML PRIMITIVE}~@{text rule} turns a primitive inference rule
   198   \<^descr> @{ML PRIMITIVE}~\<open>rule\<close> turns a primitive inference rule
   203   into a tactic with unique result.  Exception @{ML THM} is considered
   199   into a tactic with unique result.  Exception @{ML THM} is considered
   204   a regular tactic failure and produces an empty result; other
   200   a regular tactic failure and produces an empty result; other
   205   exceptions are passed through.
   201   exceptions are passed through.
   206 
   202 
   207   \<^descr> @{ML SUBGOAL}~@{text "(fn (subgoal, i) => tactic)"} is the
   203   \<^descr> @{ML SUBGOAL}~\<open>(fn (subgoal, i) => tactic)\<close> is the
   208   most basic form to produce a tactic with subgoal addressing.  The
   204   most basic form to produce a tactic with subgoal addressing.  The
   209   given abstraction over the subgoal term and subgoal number allows to
   205   given abstraction over the subgoal term and subgoal number allows to
   210   peek at the relevant information of the full goal state.  The
   206   peek at the relevant information of the full goal state.  The
   211   subgoal range is checked as required above.
   207   subgoal range is checked as required above.
   212 
   208 
   213   \<^descr> @{ML CSUBGOAL} is similar to @{ML SUBGOAL}, but passes the
   209   \<^descr> @{ML CSUBGOAL} is similar to @{ML SUBGOAL}, but passes the
   214   subgoal as @{ML_type cterm} instead of raw @{ML_type term}.  This
   210   subgoal as @{ML_type cterm} instead of raw @{ML_type term}.  This
   215   avoids expensive re-certification in situations where the subgoal is
   211   avoids expensive re-certification in situations where the subgoal is
   216   used directly for primitive inferences.
   212   used directly for primitive inferences.
   217 
   213 
   218   \<^descr> @{ML SELECT_GOAL}~@{text "tac i"} confines a tactic to the
   214   \<^descr> @{ML SELECT_GOAL}~\<open>tac i\<close> confines a tactic to the
   219   specified subgoal @{text "i"}.  This rearranges subgoals and the
   215   specified subgoal \<open>i\<close>.  This rearranges subgoals and the
   220   main goal protection (\secref{sec:tactical-goals}), while retaining
   216   main goal protection (\secref{sec:tactical-goals}), while retaining
   221   the syntactic context of the overall goal state (concerning
   217   the syntactic context of the overall goal state (concerning
   222   schematic variables etc.).
   218   schematic variables etc.).
   223 
   219 
   224   \<^descr> @{ML PREFER_GOAL}~@{text "tac i"} rearranges subgoals to put
   220   \<^descr> @{ML PREFER_GOAL}~\<open>tac i\<close> rearranges subgoals to put
   225   @{text "i"} in front.  This is similar to @{ML SELECT_GOAL}, but
   221   \<open>i\<close> in front.  This is similar to @{ML SELECT_GOAL}, but
   226   without changing the main goal protection.
   222   without changing the main goal protection.
   227 \<close>
   223 \<close>
   228 
   224 
   229 
   225 
   230 subsection \<open>Resolution and assumption tactics \label{sec:resolve-assume-tac}\<close>
   226 subsection \<open>Resolution and assumption tactics \label{sec:resolve-assume-tac}\<close>
   235   it resolves with a rule, proves its first premise by assumption, and
   231   it resolves with a rule, proves its first premise by assumption, and
   236   finally deletes that assumption from any new subgoals.
   232   finally deletes that assumption from any new subgoals.
   237   \<^emph>\<open>Destruct-resolution\<close> is like elim-resolution, but the given
   233   \<^emph>\<open>Destruct-resolution\<close> is like elim-resolution, but the given
   238   destruction rules are first turned into canonical elimination
   234   destruction rules are first turned into canonical elimination
   239   format.  \<^emph>\<open>Forward-resolution\<close> is like destruct-resolution, but
   235   format.  \<^emph>\<open>Forward-resolution\<close> is like destruct-resolution, but
   240   without deleting the selected assumption.  The @{text "r/e/d/f"}
   236   without deleting the selected assumption.  The \<open>r/e/d/f\<close>
   241   naming convention is maintained for several different kinds of
   237   naming convention is maintained for several different kinds of
   242   resolution rules and tactics.
   238   resolution rules and tactics.
   243 
   239 
   244   Assumption tactics close a subgoal by unifying some of its premises
   240   Assumption tactics close a subgoal by unifying some of its premises
   245   against its conclusion.
   241   against its conclusion.
   279   @{index_ML ematch_tac: "Proof.context -> thm list -> int -> tactic"} \\
   275   @{index_ML ematch_tac: "Proof.context -> thm list -> int -> tactic"} \\
   280   @{index_ML dmatch_tac: "Proof.context -> thm list -> int -> tactic"} \\
   276   @{index_ML dmatch_tac: "Proof.context -> thm list -> int -> tactic"} \\
   281   @{index_ML bimatch_tac: "Proof.context -> (bool * thm) list -> int -> tactic"} \\
   277   @{index_ML bimatch_tac: "Proof.context -> (bool * thm) list -> int -> tactic"} \\
   282   \end{mldecls}
   278   \end{mldecls}
   283 
   279 
   284   \<^descr> @{ML resolve_tac}~@{text "ctxt thms i"} refines the goal state
   280   \<^descr> @{ML resolve_tac}~\<open>ctxt thms i\<close> refines the goal state
   285   using the given theorems, which should normally be introduction
   281   using the given theorems, which should normally be introduction
   286   rules.  The tactic resolves a rule's conclusion with subgoal @{text
   282   rules.  The tactic resolves a rule's conclusion with subgoal \<open>i\<close>, replacing it by the corresponding versions of the rule's
   287   i}, replacing it by the corresponding versions of the rule's
       
   288   premises.
   283   premises.
   289 
   284 
   290   \<^descr> @{ML eresolve_tac}~@{text "ctxt thms i"} performs elim-resolution
   285   \<^descr> @{ML eresolve_tac}~\<open>ctxt thms i\<close> performs elim-resolution
   291   with the given theorems, which are normally be elimination rules.
   286   with the given theorems, which are normally be elimination rules.
   292 
   287 
   293   Note that @{ML_text "eresolve_tac ctxt [asm_rl]"} is equivalent to @{ML_text
   288   Note that @{ML_text "eresolve_tac ctxt [asm_rl]"} is equivalent to @{ML_text
   294   "assume_tac ctxt"}, which facilitates mixing of assumption steps with
   289   "assume_tac ctxt"}, which facilitates mixing of assumption steps with
   295   genuine eliminations.
   290   genuine eliminations.
   296 
   291 
   297   \<^descr> @{ML dresolve_tac}~@{text "ctxt thms i"} performs
   292   \<^descr> @{ML dresolve_tac}~\<open>ctxt thms i\<close> performs
   298   destruct-resolution with the given theorems, which should normally
   293   destruct-resolution with the given theorems, which should normally
   299   be destruction rules.  This replaces an assumption by the result of
   294   be destruction rules.  This replaces an assumption by the result of
   300   applying one of the rules.
   295   applying one of the rules.
   301 
   296 
   302   \<^descr> @{ML forward_tac} is like @{ML dresolve_tac} except that the
   297   \<^descr> @{ML forward_tac} is like @{ML dresolve_tac} except that the
   303   selected assumption is not deleted.  It applies a rule to an
   298   selected assumption is not deleted.  It applies a rule to an
   304   assumption, adding the result as a new assumption.
   299   assumption, adding the result as a new assumption.
   305 
   300 
   306   \<^descr> @{ML biresolve_tac}~@{text "ctxt brls i"} refines the proof state
   301   \<^descr> @{ML biresolve_tac}~\<open>ctxt brls i\<close> refines the proof state
   307   by resolution or elim-resolution on each rule, as indicated by its
   302   by resolution or elim-resolution on each rule, as indicated by its
   308   flag.  It affects subgoal @{text "i"} of the proof state.
   303   flag.  It affects subgoal \<open>i\<close> of the proof state.
   309 
   304 
   310   For each pair @{text "(flag, rule)"}, it applies resolution if the
   305   For each pair \<open>(flag, rule)\<close>, it applies resolution if the
   311   flag is @{text "false"} and elim-resolution if the flag is @{text
   306   flag is \<open>false\<close> and elim-resolution if the flag is \<open>true\<close>.  A single tactic call handles a mixture of introduction and
   312   "true"}.  A single tactic call handles a mixture of introduction and
       
   313   elimination rules, which is useful to organize the search process
   307   elimination rules, which is useful to organize the search process
   314   systematically in proof tools.
   308   systematically in proof tools.
   315 
   309 
   316   \<^descr> @{ML assume_tac}~@{text "ctxt i"} attempts to solve subgoal @{text i}
   310   \<^descr> @{ML assume_tac}~\<open>ctxt i\<close> attempts to solve subgoal \<open>i\<close>
   317   by assumption (modulo higher-order unification).
   311   by assumption (modulo higher-order unification).
   318 
   312 
   319   \<^descr> @{ML eq_assume_tac} is similar to @{ML assume_tac}, but checks
   313   \<^descr> @{ML eq_assume_tac} is similar to @{ML assume_tac}, but checks
   320   only for immediate @{text "\<alpha>"}-convertibility instead of using
   314   only for immediate \<open>\<alpha>\<close>-convertibility instead of using
   321   unification.  It succeeds (with a unique next state) if one of the
   315   unification.  It succeeds (with a unique next state) if one of the
   322   assumptions is equal to the subgoal's conclusion.  Since it does not
   316   assumptions is equal to the subgoal's conclusion.  Since it does not
   323   instantiate variables, it cannot make other subgoals unprovable.
   317   instantiate variables, it cannot make other subgoals unprovable.
   324 
   318 
   325   \<^descr> @{ML match_tac}, @{ML ematch_tac}, @{ML dmatch_tac}, and @{ML
   319   \<^descr> @{ML match_tac}, @{ML ematch_tac}, @{ML dmatch_tac}, and @{ML
   344   situations despite its daunting theoretical properties.
   338   situations despite its daunting theoretical properties.
   345   Nonetheless, there are important problem classes where unguided
   339   Nonetheless, there are important problem classes where unguided
   346   higher-order unification is not so useful.  This typically involves
   340   higher-order unification is not so useful.  This typically involves
   347   rules like universal elimination, existential introduction, or
   341   rules like universal elimination, existential introduction, or
   348   equational substitution.  Here the unification problem involves
   342   equational substitution.  Here the unification problem involves
   349   fully flexible @{text "?P ?x"} schemes, which are hard to manage
   343   fully flexible \<open>?P ?x\<close> schemes, which are hard to manage
   350   without further hints.
   344   without further hints.
   351 
   345 
   352   By providing a (small) rigid term for @{text "?x"} explicitly, the
   346   By providing a (small) rigid term for \<open>?x\<close> explicitly, the
   353   remaining unification problem is to assign a (large) term to @{text
   347   remaining unification problem is to assign a (large) term to \<open>?P\<close>, according to the shape of the given subgoal.  This is
   354   "?P"}, according to the shape of the given subgoal.  This is
       
   355   sufficiently well-behaved in most practical situations.
   348   sufficiently well-behaved in most practical situations.
   356 
   349 
   357   \<^medskip>
   350   \<^medskip>
   358   Isabelle provides separate versions of the standard @{text
   351   Isabelle provides separate versions of the standard \<open>r/e/d/f\<close> resolution tactics that allow to provide explicit
   359   "r/e/d/f"} resolution tactics that allow to provide explicit
       
   360   instantiations of unknowns of the given rule, wrt.\ terms that refer
   352   instantiations of unknowns of the given rule, wrt.\ terms that refer
   361   to the implicit context of the selected subgoal.
   353   to the implicit context of the selected subgoal.
   362 
   354 
   363   An instantiation consists of a list of pairs of the form @{text
   355   An instantiation consists of a list of pairs of the form \<open>(?x, t)\<close>, where \<open>?x\<close> is a schematic variable occurring in
   364   "(?x, t)"}, where @{text ?x} is a schematic variable occurring in
   356   the given rule, and \<open>t\<close> is a term from the current proof
   365   the given rule, and @{text t} is a term from the current proof
       
   366   context, augmented by the local goal parameters of the selected
   357   context, augmented by the local goal parameters of the selected
   367   subgoal; cf.\ the @{text "focus"} operation described in
   358   subgoal; cf.\ the \<open>focus\<close> operation described in
   368   \secref{sec:variables}.
   359   \secref{sec:variables}.
   369 
   360 
   370   Entering the syntactic context of a subgoal is a brittle operation,
   361   Entering the syntactic context of a subgoal is a brittle operation,
   371   because its exact form is somewhat accidental, and the choice of
   362   because its exact form is somewhat accidental, and the choice of
   372   bound variable names depends on the presence of other local and
   363   bound variable names depends on the presence of other local and
   373   global names.  Explicit renaming of subgoal parameters prior to
   364   global names.  Explicit renaming of subgoal parameters prior to
   374   explicit instantiation might help to achieve a bit more robustness.
   365   explicit instantiation might help to achieve a bit more robustness.
   375 
   366 
   376   Type instantiations may be given as well, via pairs like @{text
   367   Type instantiations may be given as well, via pairs like \<open>(?'a, \<tau>)\<close>.  Type instantiations are distinguished from term
   377   "(?'a, \<tau>)"}.  Type instantiations are distinguished from term
       
   378   instantiations by the syntactic form of the schematic variable.
   368   instantiations by the syntactic form of the schematic variable.
   379   Types are instantiated before terms are.  Since term instantiation
   369   Types are instantiated before terms are.  Since term instantiation
   380   already performs simple type-inference, so explicit type
   370   already performs simple type-inference, so explicit type
   381   instantiations are seldom necessary.
   371   instantiations are seldom necessary.
   382 \<close>
   372 \<close>
   400   @{index_ML Rule_Insts.thin_tac: "Proof.context -> string ->
   390   @{index_ML Rule_Insts.thin_tac: "Proof.context -> string ->
   401     (binding * string option * mixfix) list -> int -> tactic"} \\
   391     (binding * string option * mixfix) list -> int -> tactic"} \\
   402   @{index_ML rename_tac: "string list -> int -> tactic"} \\
   392   @{index_ML rename_tac: "string list -> int -> tactic"} \\
   403   \end{mldecls}
   393   \end{mldecls}
   404 
   394 
   405   \<^descr> @{ML Rule_Insts.res_inst_tac}~@{text "ctxt insts thm i"} instantiates the
   395   \<^descr> @{ML Rule_Insts.res_inst_tac}~\<open>ctxt insts thm i\<close> instantiates the
   406   rule @{text thm} with the instantiations @{text insts}, as described
   396   rule \<open>thm\<close> with the instantiations \<open>insts\<close>, as described
   407   above, and then performs resolution on subgoal @{text i}.
   397   above, and then performs resolution on subgoal \<open>i\<close>.
   408   
   398   
   409   \<^descr> @{ML Rule_Insts.eres_inst_tac} is like @{ML Rule_Insts.res_inst_tac},
   399   \<^descr> @{ML Rule_Insts.eres_inst_tac} is like @{ML Rule_Insts.res_inst_tac},
   410   but performs elim-resolution.
   400   but performs elim-resolution.
   411 
   401 
   412   \<^descr> @{ML Rule_Insts.dres_inst_tac} is like @{ML Rule_Insts.res_inst_tac},
   402   \<^descr> @{ML Rule_Insts.dres_inst_tac} is like @{ML Rule_Insts.res_inst_tac},
   413   but performs destruct-resolution.
   403   but performs destruct-resolution.
   414 
   404 
   415   \<^descr> @{ML Rule_Insts.forw_inst_tac} is like @{ML Rule_Insts.dres_inst_tac}
   405   \<^descr> @{ML Rule_Insts.forw_inst_tac} is like @{ML Rule_Insts.dres_inst_tac}
   416   except that the selected assumption is not deleted.
   406   except that the selected assumption is not deleted.
   417 
   407 
   418   \<^descr> @{ML Rule_Insts.subgoal_tac}~@{text "ctxt \<phi> i"} adds the proposition
   408   \<^descr> @{ML Rule_Insts.subgoal_tac}~\<open>ctxt \<phi> i\<close> adds the proposition
   419   @{text "\<phi>"} as local premise to subgoal @{text "i"}, and poses the
   409   \<open>\<phi>\<close> as local premise to subgoal \<open>i\<close>, and poses the
   420   same as a new subgoal @{text "i + 1"} (in the original context).
   410   same as a new subgoal \<open>i + 1\<close> (in the original context).
   421 
   411 
   422   \<^descr> @{ML Rule_Insts.thin_tac}~@{text "ctxt \<phi> i"} deletes the specified
   412   \<^descr> @{ML Rule_Insts.thin_tac}~\<open>ctxt \<phi> i\<close> deletes the specified
   423   premise from subgoal @{text i}.  Note that @{text \<phi>} may contain
   413   premise from subgoal \<open>i\<close>.  Note that \<open>\<phi>\<close> may contain
   424   schematic variables, to abbreviate the intended proposition; the
   414   schematic variables, to abbreviate the intended proposition; the
   425   first matching subgoal premise will be deleted.  Removing useless
   415   first matching subgoal premise will be deleted.  Removing useless
   426   premises from a subgoal increases its readability and can make
   416   premises from a subgoal increases its readability and can make
   427   search tactics run faster.
   417   search tactics run faster.
   428 
   418 
   429   \<^descr> @{ML rename_tac}~@{text "names i"} renames the innermost
   419   \<^descr> @{ML rename_tac}~\<open>names i\<close> renames the innermost
   430   parameters of subgoal @{text i} according to the provided @{text
   420   parameters of subgoal \<open>i\<close> according to the provided \<open>names\<close> (which need to be distinct identifiers).
   431   names} (which need to be distinct identifiers).
       
   432 
   421 
   433 
   422 
   434   For historical reasons, the above instantiation tactics take
   423   For historical reasons, the above instantiation tactics take
   435   unparsed string arguments, which makes them hard to use in general
   424   unparsed string arguments, which makes them hard to use in general
   436   ML code.  The slightly more advanced @{ML Subgoal.FOCUS} combinator
   425   ML code.  The slightly more advanced @{ML Subgoal.FOCUS} combinator
   451   @{index_ML rotate_tac: "int -> int -> tactic"} \\
   440   @{index_ML rotate_tac: "int -> int -> tactic"} \\
   452   @{index_ML distinct_subgoals_tac: tactic} \\
   441   @{index_ML distinct_subgoals_tac: tactic} \\
   453   @{index_ML flexflex_tac: "Proof.context -> tactic"} \\
   442   @{index_ML flexflex_tac: "Proof.context -> tactic"} \\
   454   \end{mldecls}
   443   \end{mldecls}
   455 
   444 
   456   \<^descr> @{ML rotate_tac}~@{text "n i"} rotates the premises of subgoal
   445   \<^descr> @{ML rotate_tac}~\<open>n i\<close> rotates the premises of subgoal
   457   @{text i} by @{text n} positions: from right to left if @{text n} is
   446   \<open>i\<close> by \<open>n\<close> positions: from right to left if \<open>n\<close> is
   458   positive, and from left to right if @{text n} is negative.
   447   positive, and from left to right if \<open>n\<close> is negative.
   459 
   448 
   460   \<^descr> @{ML distinct_subgoals_tac} removes duplicate subgoals from a
   449   \<^descr> @{ML distinct_subgoals_tac} removes duplicate subgoals from a
   461   proof state.  This is potentially inefficient.
   450   proof state.  This is potentially inefficient.
   462 
   451 
   463   \<^descr> @{ML flexflex_tac} removes all flex-flex pairs from the proof
   452   \<^descr> @{ML flexflex_tac} removes all flex-flex pairs from the proof
   487   @{index_ML compose_tac: "Proof.context -> (bool * thm * int) -> int -> tactic"} \\
   476   @{index_ML compose_tac: "Proof.context -> (bool * thm * int) -> int -> tactic"} \\
   488   @{index_ML Drule.compose: "thm * int * thm -> thm"} \\
   477   @{index_ML Drule.compose: "thm * int * thm -> thm"} \\
   489   @{index_ML_op COMP: "thm * thm -> thm"} \\
   478   @{index_ML_op COMP: "thm * thm -> thm"} \\
   490   \end{mldecls}
   479   \end{mldecls}
   491 
   480 
   492   \<^descr> @{ML compose_tac}~@{text "ctxt (flag, rule, m) i"} refines subgoal
   481   \<^descr> @{ML compose_tac}~\<open>ctxt (flag, rule, m) i\<close> refines subgoal
   493   @{text "i"} using @{text "rule"}, without lifting.  The @{text
   482   \<open>i\<close> using \<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> \<psi>\<close>, where
   494   "rule"} is taken to have the form @{text "\<psi>\<^sub>1 \<Longrightarrow> \<dots> \<psi>\<^sub>m \<Longrightarrow> \<psi>"}, where
   483   \<open>\<psi>\<close> need not be atomic; thus \<open>m\<close> determines the
   495   @{text "\<psi>"} need not be atomic; thus @{text "m"} determines the
   484   number of new subgoals.  If \<open>flag\<close> is \<open>true\<close> then it
   496   number of new subgoals.  If @{text "flag"} is @{text "true"} then it
   485   performs elim-resolution --- it solves the first premise of \<open>rule\<close> by assumption and deletes that assumption.
   497   performs elim-resolution --- it solves the first premise of @{text
   486 
   498   "rule"} by assumption and deletes that assumption.
   487   \<^descr> @{ML Drule.compose}~\<open>(thm\<^sub>1, i, thm\<^sub>2)\<close> uses \<open>thm\<^sub>1\<close>,
   499 
   488   regarded as an atomic formula, to solve premise \<open>i\<close> of
   500   \<^descr> @{ML Drule.compose}~@{text "(thm\<^sub>1, i, thm\<^sub>2)"} uses @{text "thm\<^sub>1"},
   489   \<open>thm\<^sub>2\<close>.  Let \<open>thm\<^sub>1\<close> and \<open>thm\<^sub>2\<close> be \<open>\<psi>\<close> and \<open>\<phi>\<^sub>1 \<Longrightarrow> \<dots> \<phi>\<^sub>n \<Longrightarrow> \<phi>\<close>.  The unique \<open>s\<close> that
   501   regarded as an atomic formula, to solve premise @{text "i"} of
   490   unifies \<open>\<psi>\<close> and \<open>\<phi>\<^sub>i\<close> yields the theorem \<open>(\<phi>\<^sub>1 \<Longrightarrow>
   502   @{text "thm\<^sub>2"}.  Let @{text "thm\<^sub>1"} and @{text "thm\<^sub>2"} be @{text
   491   \<dots> \<phi>\<^sub>i\<^sub>-\<^sub>1 \<Longrightarrow> \<phi>\<^sub>i\<^sub>+\<^sub>1 \<Longrightarrow> \<dots> \<phi>\<^sub>n \<Longrightarrow> \<phi>)s\<close>.  Multiple results are considered as
   503   "\<psi>"} and @{text "\<phi>\<^sub>1 \<Longrightarrow> \<dots> \<phi>\<^sub>n \<Longrightarrow> \<phi>"}.  The unique @{text "s"} that
       
   504   unifies @{text "\<psi>"} and @{text "\<phi>\<^sub>i"} yields the theorem @{text "(\<phi>\<^sub>1 \<Longrightarrow>
       
   505   \<dots> \<phi>\<^sub>i\<^sub>-\<^sub>1 \<Longrightarrow> \<phi>\<^sub>i\<^sub>+\<^sub>1 \<Longrightarrow> \<dots> \<phi>\<^sub>n \<Longrightarrow> \<phi>)s"}.  Multiple results are considered as
       
   506   error (exception @{ML THM}).
   492   error (exception @{ML THM}).
   507 
   493 
   508   \<^descr> @{text "thm\<^sub>1 COMP thm\<^sub>2"} is the same as @{text "Drule.compose
   494   \<^descr> \<open>thm\<^sub>1 COMP thm\<^sub>2\<close> is the same as \<open>Drule.compose
   509   (thm\<^sub>1, 1, thm\<^sub>2)"}.
   495   (thm\<^sub>1, 1, thm\<^sub>2)\<close>.
   510 
   496 
   511 
   497 
   512   \begin{warn}
   498   \begin{warn}
   513   These low-level operations are stepping outside the structure
   499   These low-level operations are stepping outside the structure
   514   imposed by regular rule resolution.  Used without understanding of
   500   imposed by regular rule resolution.  Used without understanding of
   552   @{index_ML_op "APPEND'": "('a -> tactic) * ('a -> tactic) -> 'a -> tactic"} \\
   538   @{index_ML_op "APPEND'": "('a -> tactic) * ('a -> tactic) -> 'a -> tactic"} \\
   553   @{index_ML "EVERY'": "('a -> tactic) list -> 'a -> tactic"} \\
   539   @{index_ML "EVERY'": "('a -> tactic) list -> 'a -> tactic"} \\
   554   @{index_ML "FIRST'": "('a -> tactic) list -> 'a -> tactic"} \\
   540   @{index_ML "FIRST'": "('a -> tactic) list -> 'a -> tactic"} \\
   555   \end{mldecls}
   541   \end{mldecls}
   556 
   542 
   557   \<^descr> @{text "tac\<^sub>1"}~@{ML_op THEN}~@{text "tac\<^sub>2"} is the sequential
   543   \<^descr> \<open>tac\<^sub>1\<close>~@{ML_op THEN}~\<open>tac\<^sub>2\<close> is the sequential
   558   composition of @{text "tac\<^sub>1"} and @{text "tac\<^sub>2"}.  Applied to a goal
   544   composition of \<open>tac\<^sub>1\<close> and \<open>tac\<^sub>2\<close>.  Applied to a goal
   559   state, it returns all states reachable in two steps by applying
   545   state, it returns all states reachable in two steps by applying
   560   @{text "tac\<^sub>1"} followed by @{text "tac\<^sub>2"}.  First, it applies @{text
   546   \<open>tac\<^sub>1\<close> followed by \<open>tac\<^sub>2\<close>.  First, it applies \<open>tac\<^sub>1\<close> to the goal state, getting a sequence of possible next
   561   "tac\<^sub>1"} to the goal state, getting a sequence of possible next
   547   states; then, it applies \<open>tac\<^sub>2\<close> to each of these and
   562   states; then, it applies @{text "tac\<^sub>2"} to each of these and
       
   563   concatenates the results to produce again one flat sequence of
   548   concatenates the results to produce again one flat sequence of
   564   states.
   549   states.
   565 
   550 
   566   \<^descr> @{text "tac\<^sub>1"}~@{ML_op ORELSE}~@{text "tac\<^sub>2"} makes a choice
   551   \<^descr> \<open>tac\<^sub>1\<close>~@{ML_op ORELSE}~\<open>tac\<^sub>2\<close> makes a choice
   567   between @{text "tac\<^sub>1"} and @{text "tac\<^sub>2"}.  Applied to a state, it
   552   between \<open>tac\<^sub>1\<close> and \<open>tac\<^sub>2\<close>.  Applied to a state, it
   568   tries @{text "tac\<^sub>1"} and returns the result if non-empty; if @{text
   553   tries \<open>tac\<^sub>1\<close> and returns the result if non-empty; if \<open>tac\<^sub>1\<close> fails then it uses \<open>tac\<^sub>2\<close>.  This is a deterministic
   569   "tac\<^sub>1"} fails then it uses @{text "tac\<^sub>2"}.  This is a deterministic
   554   choice: if \<open>tac\<^sub>1\<close> succeeds then \<open>tac\<^sub>2\<close> is excluded
   570   choice: if @{text "tac\<^sub>1"} succeeds then @{text "tac\<^sub>2"} is excluded
       
   571   from the result.
   555   from the result.
   572 
   556 
   573   \<^descr> @{text "tac\<^sub>1"}~@{ML_op APPEND}~@{text "tac\<^sub>2"} concatenates the
   557   \<^descr> \<open>tac\<^sub>1\<close>~@{ML_op APPEND}~\<open>tac\<^sub>2\<close> concatenates the
   574   possible results of @{text "tac\<^sub>1"} and @{text "tac\<^sub>2"}.  Unlike
   558   possible results of \<open>tac\<^sub>1\<close> and \<open>tac\<^sub>2\<close>.  Unlike
   575   @{ML_op "ORELSE"} there is \<^emph>\<open>no commitment\<close> to either tactic, so
   559   @{ML_op "ORELSE"} there is \<^emph>\<open>no commitment\<close> to either tactic, so
   576   @{ML_op "APPEND"} helps to avoid incompleteness during search, at
   560   @{ML_op "APPEND"} helps to avoid incompleteness during search, at
   577   the cost of potential inefficiencies.
   561   the cost of potential inefficiencies.
   578 
   562 
   579   \<^descr> @{ML EVERY}~@{text "[tac\<^sub>1, \<dots>, tac\<^sub>n]"} abbreviates @{text
   563   \<^descr> @{ML EVERY}~\<open>[tac\<^sub>1, \<dots>, tac\<^sub>n]\<close> abbreviates \<open>tac\<^sub>1\<close>~@{ML_op THEN}~\<open>\<dots>\<close>~@{ML_op THEN}~\<open>tac\<^sub>n\<close>.
   580   "tac\<^sub>1"}~@{ML_op THEN}~@{text "\<dots>"}~@{ML_op THEN}~@{text "tac\<^sub>n"}.
       
   581   Note that @{ML "EVERY []"} is the same as @{ML all_tac}: it always
   564   Note that @{ML "EVERY []"} is the same as @{ML all_tac}: it always
   582   succeeds.
   565   succeeds.
   583 
   566 
   584   \<^descr> @{ML FIRST}~@{text "[tac\<^sub>1, \<dots>, tac\<^sub>n]"} abbreviates @{text
   567   \<^descr> @{ML FIRST}~\<open>[tac\<^sub>1, \<dots>, tac\<^sub>n]\<close> abbreviates \<open>tac\<^sub>1\<close>~@{ML_op ORELSE}~\<open>\<dots>\<close>~@{ML_op "ORELSE"}~\<open>tac\<^sub>n\<close>.  Note that @{ML "FIRST []"} is the same as @{ML no_tac}: it
   585   "tac\<^sub>1"}~@{ML_op ORELSE}~@{text "\<dots>"}~@{ML_op "ORELSE"}~@{text
       
   586   "tac\<^sub>n"}.  Note that @{ML "FIRST []"} is the same as @{ML no_tac}: it
       
   587   always fails.
   568   always fails.
   588 
   569 
   589   \<^descr> @{ML_op "THEN'"} is the lifted version of @{ML_op "THEN"}, for
   570   \<^descr> @{ML_op "THEN'"} is the lifted version of @{ML_op "THEN"}, for
   590   tactics with explicit subgoal addressing.  So @{text
   571   tactics with explicit subgoal addressing.  So \<open>(tac\<^sub>1\<close>~@{ML_op THEN'}~\<open>tac\<^sub>2) i\<close> is the same as \<open>(tac\<^sub>1 i\<close>~@{ML_op THEN}~\<open>tac\<^sub>2 i)\<close>.
   591   "(tac\<^sub>1"}~@{ML_op THEN'}~@{text "tac\<^sub>2) i"} is the same as @{text
       
   592   "(tac\<^sub>1 i"}~@{ML_op THEN}~@{text "tac\<^sub>2 i)"}.
       
   593 
   572 
   594   The other primed tacticals work analogously.
   573   The other primed tacticals work analogously.
   595 \<close>
   574 \<close>
   596 
   575 
   597 
   576 
   608   @{index_ML "REPEAT1": "tactic -> tactic"} \\
   587   @{index_ML "REPEAT1": "tactic -> tactic"} \\
   609   @{index_ML "REPEAT_DETERM": "tactic -> tactic"} \\
   588   @{index_ML "REPEAT_DETERM": "tactic -> tactic"} \\
   610   @{index_ML "REPEAT_DETERM_N": "int -> tactic -> tactic"} \\
   589   @{index_ML "REPEAT_DETERM_N": "int -> tactic -> tactic"} \\
   611   \end{mldecls}
   590   \end{mldecls}
   612 
   591 
   613   \<^descr> @{ML TRY}~@{text "tac"} applies @{text "tac"} to the goal
   592   \<^descr> @{ML TRY}~\<open>tac\<close> applies \<open>tac\<close> to the goal
   614   state and returns the resulting sequence, if non-empty; otherwise it
   593   state and returns the resulting sequence, if non-empty; otherwise it
   615   returns the original state.  Thus, it applies @{text "tac"} at most
   594   returns the original state.  Thus, it applies \<open>tac\<close> at most
   616   once.
   595   once.
   617 
   596 
   618   Note that for tactics with subgoal addressing, the combinator can be
   597   Note that for tactics with subgoal addressing, the combinator can be
   619   applied via functional composition: @{ML "TRY"}~@{ML_op o}~@{text
   598   applied via functional composition: @{ML "TRY"}~@{ML_op o}~\<open>tac\<close>.  There is no need for @{verbatim TRY'}.
   620   "tac"}.  There is no need for @{verbatim TRY'}.
   599 
   621 
   600   \<^descr> @{ML REPEAT}~\<open>tac\<close> applies \<open>tac\<close> to the goal
   622   \<^descr> @{ML REPEAT}~@{text "tac"} applies @{text "tac"} to the goal
       
   623   state and, recursively, to each element of the resulting sequence.
   601   state and, recursively, to each element of the resulting sequence.
   624   The resulting sequence consists of those states that make @{text
   602   The resulting sequence consists of those states that make \<open>tac\<close> fail.  Thus, it applies \<open>tac\<close> as many times as
   625   "tac"} fail.  Thus, it applies @{text "tac"} as many times as
       
   626   possible (including zero times), and allows backtracking over each
   603   possible (including zero times), and allows backtracking over each
   627   invocation of @{text "tac"}.  @{ML REPEAT} is more general than @{ML
   604   invocation of \<open>tac\<close>.  @{ML REPEAT} is more general than @{ML
   628   REPEAT_DETERM}, but requires more space.
   605   REPEAT_DETERM}, but requires more space.
   629 
   606 
   630   \<^descr> @{ML REPEAT1}~@{text "tac"} is like @{ML REPEAT}~@{text "tac"}
   607   \<^descr> @{ML REPEAT1}~\<open>tac\<close> is like @{ML REPEAT}~\<open>tac\<close>
   631   but it always applies @{text "tac"} at least once, failing if this
   608   but it always applies \<open>tac\<close> at least once, failing if this
   632   is impossible.
   609   is impossible.
   633 
   610 
   634   \<^descr> @{ML REPEAT_DETERM}~@{text "tac"} applies @{text "tac"} to the
   611   \<^descr> @{ML REPEAT_DETERM}~\<open>tac\<close> applies \<open>tac\<close> to the
   635   goal state and, recursively, to the head of the resulting sequence.
   612   goal state and, recursively, to the head of the resulting sequence.
   636   It returns the first state to make @{text "tac"} fail.  It is
   613   It returns the first state to make \<open>tac\<close> fail.  It is
   637   deterministic, discarding alternative outcomes.
   614   deterministic, discarding alternative outcomes.
   638 
   615 
   639   \<^descr> @{ML REPEAT_DETERM_N}~@{text "n tac"} is like @{ML
   616   \<^descr> @{ML REPEAT_DETERM_N}~\<open>n tac\<close> is like @{ML
   640   REPEAT_DETERM}~@{text "tac"} but the number of repetitions is bound
   617   REPEAT_DETERM}~\<open>tac\<close> but the number of repetitions is bound
   641   by @{text "n"} (where @{ML "~1"} means @{text "\<infinity>"}).
   618   by \<open>n\<close> (where @{ML "~1"} means \<open>\<infinity>\<close>).
   642 \<close>
   619 \<close>
   643 
   620 
   644 text %mlex \<open>The basic tactics and tacticals considered above follow
   621 text %mlex \<open>The basic tactics and tacticals considered above follow
   645   some algebraic laws:
   622   some algebraic laws:
   646 
   623 
   647   \<^item> @{ML all_tac} is the identity element of the tactical @{ML_op
   624   \<^item> @{ML all_tac} is the identity element of the tactical @{ML_op
   648   "THEN"}.
   625   "THEN"}.
   649 
   626 
   650   \<^item> @{ML no_tac} is the identity element of @{ML_op "ORELSE"} and
   627   \<^item> @{ML no_tac} is the identity element of @{ML_op "ORELSE"} and
   651   @{ML_op "APPEND"}.  Also, it is a zero element for @{ML_op "THEN"},
   628   @{ML_op "APPEND"}.  Also, it is a zero element for @{ML_op "THEN"},
   652   which means that @{text "tac"}~@{ML_op THEN}~@{ML no_tac} is
   629   which means that \<open>tac\<close>~@{ML_op THEN}~@{ML no_tac} is
   653   equivalent to @{ML no_tac}.
   630   equivalent to @{ML no_tac}.
   654 
   631 
   655   \<^item> @{ML TRY} and @{ML REPEAT} can be expressed as (recursive)
   632   \<^item> @{ML TRY} and @{ML REPEAT} can be expressed as (recursive)
   656   functions over more basic combinators (ignoring some internal
   633   functions over more basic combinators (ignoring some internal
   657   implementation tricks):
   634   implementation tricks):
   660 ML \<open>
   637 ML \<open>
   661   fun TRY tac = tac ORELSE all_tac;
   638   fun TRY tac = tac ORELSE all_tac;
   662   fun REPEAT tac st = ((tac THEN REPEAT tac) ORELSE all_tac) st;
   639   fun REPEAT tac st = ((tac THEN REPEAT tac) ORELSE all_tac) st;
   663 \<close>
   640 \<close>
   664 
   641 
   665 text \<open>If @{text "tac"} can return multiple outcomes then so can @{ML
   642 text \<open>If \<open>tac\<close> can return multiple outcomes then so can @{ML
   666   REPEAT}~@{text "tac"}.  @{ML REPEAT} uses @{ML_op "ORELSE"} and not
   643   REPEAT}~\<open>tac\<close>.  @{ML REPEAT} uses @{ML_op "ORELSE"} and not
   667   @{ML_op "APPEND"}, it applies @{text "tac"} as many times as
   644   @{ML_op "APPEND"}, it applies \<open>tac\<close> as many times as
   668   possible in each outcome.
   645   possible in each outcome.
   669 
   646 
   670   \begin{warn}
   647   \begin{warn}
   671   Note the explicit abstraction over the goal state in the ML
   648   Note the explicit abstraction over the goal state in the ML
   672   definition of @{ML REPEAT}.  Recursive tacticals must be coded in
   649   definition of @{ML REPEAT}.  Recursive tacticals must be coded in
   673   this awkward fashion to avoid infinite recursion of eager functional
   650   this awkward fashion to avoid infinite recursion of eager functional
   674   evaluation in Standard ML.  The following attempt would make @{ML
   651   evaluation in Standard ML.  The following attempt would make @{ML
   675   REPEAT}~@{text "tac"} loop:
   652   REPEAT}~\<open>tac\<close> loop:
   676   \end{warn}
   653   \end{warn}
   677 \<close>
   654 \<close>
   678 
   655 
   679 ML_val \<open>
   656 ML_val \<open>
   680   (*BAD -- does not terminate!*)
   657   (*BAD -- does not terminate!*)
   688   @{ML_type "int -> tactic"} can be used together with tacticals that
   665   @{ML_type "int -> tactic"} can be used together with tacticals that
   689   act like ``subgoal quantifiers'': guided by success of the body
   666   act like ``subgoal quantifiers'': guided by success of the body
   690   tactic a certain range of subgoals is covered.  Thus the body tactic
   667   tactic a certain range of subgoals is covered.  Thus the body tactic
   691   is applied to \<^emph>\<open>all\<close> subgoals, \<^emph>\<open>some\<close> subgoal etc.
   668   is applied to \<^emph>\<open>all\<close> subgoals, \<^emph>\<open>some\<close> subgoal etc.
   692 
   669 
   693   Suppose that the goal state has @{text "n \<ge> 0"} subgoals.  Many of
   670   Suppose that the goal state has \<open>n \<ge> 0\<close> subgoals.  Many of
   694   these tacticals address subgoal ranges counting downwards from
   671   these tacticals address subgoal ranges counting downwards from
   695   @{text "n"} towards @{text "1"}.  This has the fortunate effect that
   672   \<open>n\<close> towards \<open>1\<close>.  This has the fortunate effect that
   696   newly emerging subgoals are concatenated in the result, without
   673   newly emerging subgoals are concatenated in the result, without
   697   interfering each other.  Nonetheless, there might be situations
   674   interfering each other.  Nonetheless, there might be situations
   698   where a different order is desired.\<close>
   675   where a different order is desired.\<close>
   699 
   676 
   700 text %mlref \<open>
   677 text %mlref \<open>
   706   @{index_ML REPEAT_SOME: "(int -> tactic) -> tactic"} \\
   683   @{index_ML REPEAT_SOME: "(int -> tactic) -> tactic"} \\
   707   @{index_ML REPEAT_FIRST: "(int -> tactic) -> tactic"} \\
   684   @{index_ML REPEAT_FIRST: "(int -> tactic) -> tactic"} \\
   708   @{index_ML RANGE: "(int -> tactic) list -> int -> tactic"} \\
   685   @{index_ML RANGE: "(int -> tactic) list -> int -> tactic"} \\
   709   \end{mldecls}
   686   \end{mldecls}
   710 
   687 
   711   \<^descr> @{ML ALLGOALS}~@{text "tac"} is equivalent to @{text "tac
   688   \<^descr> @{ML ALLGOALS}~\<open>tac\<close> is equivalent to \<open>tac
   712   n"}~@{ML_op THEN}~@{text "\<dots>"}~@{ML_op THEN}~@{text "tac 1"}.  It
   689   n\<close>~@{ML_op THEN}~\<open>\<dots>\<close>~@{ML_op THEN}~\<open>tac 1\<close>.  It
   713   applies the @{text tac} to all the subgoals, counting downwards.
   690   applies the \<open>tac\<close> to all the subgoals, counting downwards.
   714 
   691 
   715   \<^descr> @{ML SOMEGOAL}~@{text "tac"} is equivalent to @{text "tac
   692   \<^descr> @{ML SOMEGOAL}~\<open>tac\<close> is equivalent to \<open>tac
   716   n"}~@{ML_op ORELSE}~@{text "\<dots>"}~@{ML_op ORELSE}~@{text "tac 1"}.  It
   693   n\<close>~@{ML_op ORELSE}~\<open>\<dots>\<close>~@{ML_op ORELSE}~\<open>tac 1\<close>.  It
   717   applies @{text "tac"} to one subgoal, counting downwards.
   694   applies \<open>tac\<close> to one subgoal, counting downwards.
   718 
   695 
   719   \<^descr> @{ML FIRSTGOAL}~@{text "tac"} is equivalent to @{text "tac
   696   \<^descr> @{ML FIRSTGOAL}~\<open>tac\<close> is equivalent to \<open>tac
   720   1"}~@{ML_op ORELSE}~@{text "\<dots>"}~@{ML_op ORELSE}~@{text "tac n"}.  It
   697   1\<close>~@{ML_op ORELSE}~\<open>\<dots>\<close>~@{ML_op ORELSE}~\<open>tac n\<close>.  It
   721   applies @{text "tac"} to one subgoal, counting upwards.
   698   applies \<open>tac\<close> to one subgoal, counting upwards.
   722 
   699 
   723   \<^descr> @{ML HEADGOAL}~@{text "tac"} is equivalent to @{text "tac 1"}.
   700   \<^descr> @{ML HEADGOAL}~\<open>tac\<close> is equivalent to \<open>tac 1\<close>.
   724   It applies @{text "tac"} unconditionally to the first subgoal.
   701   It applies \<open>tac\<close> unconditionally to the first subgoal.
   725 
   702 
   726   \<^descr> @{ML REPEAT_SOME}~@{text "tac"} applies @{text "tac"} once or
   703   \<^descr> @{ML REPEAT_SOME}~\<open>tac\<close> applies \<open>tac\<close> once or
   727   more to a subgoal, counting downwards.
   704   more to a subgoal, counting downwards.
   728 
   705 
   729   \<^descr> @{ML REPEAT_FIRST}~@{text "tac"} applies @{text "tac"} once or
   706   \<^descr> @{ML REPEAT_FIRST}~\<open>tac\<close> applies \<open>tac\<close> once or
   730   more to a subgoal, counting upwards.
   707   more to a subgoal, counting upwards.
   731 
   708 
   732   \<^descr> @{ML RANGE}~@{text "[tac\<^sub>1, \<dots>, tac\<^sub>k] i"} is equivalent to
   709   \<^descr> @{ML RANGE}~\<open>[tac\<^sub>1, \<dots>, tac\<^sub>k] i\<close> is equivalent to
   733   @{text "tac\<^sub>k (i + k - 1)"}~@{ML_op THEN}~@{text "\<dots>"}~@{ML_op
   710   \<open>tac\<^sub>k (i + k - 1)\<close>~@{ML_op THEN}~\<open>\<dots>\<close>~@{ML_op
   734   THEN}~@{text "tac\<^sub>1 i"}.  It applies the given list of tactics to the
   711   THEN}~\<open>tac\<^sub>1 i\<close>.  It applies the given list of tactics to the
   735   corresponding range of subgoals, counting downwards.
   712   corresponding range of subgoals, counting downwards.
   736 \<close>
   713 \<close>
   737 
   714 
   738 
   715 
   739 subsection \<open>Control and search tacticals\<close>
   716 subsection \<open>Control and search tacticals\<close>
   755   \begin{mldecls}
   732   \begin{mldecls}
   756   @{index_ML FILTER: "(thm -> bool) -> tactic -> tactic"} \\
   733   @{index_ML FILTER: "(thm -> bool) -> tactic -> tactic"} \\
   757   @{index_ML CHANGED: "tactic -> tactic"} \\
   734   @{index_ML CHANGED: "tactic -> tactic"} \\
   758   \end{mldecls}
   735   \end{mldecls}
   759 
   736 
   760   \<^descr> @{ML FILTER}~@{text "sat tac"} applies @{text "tac"} to the
   737   \<^descr> @{ML FILTER}~\<open>sat tac\<close> applies \<open>tac\<close> to the
   761   goal state and returns a sequence consisting of those result goal
   738   goal state and returns a sequence consisting of those result goal
   762   states that are satisfactory in the sense of @{text "sat"}.
   739   states that are satisfactory in the sense of \<open>sat\<close>.
   763 
   740 
   764   \<^descr> @{ML CHANGED}~@{text "tac"} applies @{text "tac"} to the goal
   741   \<^descr> @{ML CHANGED}~\<open>tac\<close> applies \<open>tac\<close> to the goal
   765   state and returns precisely those states that differ from the
   742   state and returns precisely those states that differ from the
   766   original state (according to @{ML Thm.eq_thm}).  Thus @{ML
   743   original state (according to @{ML Thm.eq_thm}).  Thus @{ML
   767   CHANGED}~@{text "tac"} always has some effect on the state.
   744   CHANGED}~\<open>tac\<close> always has some effect on the state.
   768 \<close>
   745 \<close>
   769 
   746 
   770 
   747 
   771 subsubsection \<open>Depth-first search\<close>
   748 subsubsection \<open>Depth-first search\<close>
   772 
   749 
   775   @{index_ML DEPTH_FIRST: "(thm -> bool) -> tactic -> tactic"} \\
   752   @{index_ML DEPTH_FIRST: "(thm -> bool) -> tactic -> tactic"} \\
   776   @{index_ML DEPTH_SOLVE: "tactic -> tactic"} \\
   753   @{index_ML DEPTH_SOLVE: "tactic -> tactic"} \\
   777   @{index_ML DEPTH_SOLVE_1: "tactic -> tactic"} \\
   754   @{index_ML DEPTH_SOLVE_1: "tactic -> tactic"} \\
   778   \end{mldecls}
   755   \end{mldecls}
   779 
   756 
   780   \<^descr> @{ML DEPTH_FIRST}~@{text "sat tac"} returns the goal state if
   757   \<^descr> @{ML DEPTH_FIRST}~\<open>sat tac\<close> returns the goal state if
   781   @{text "sat"} returns true.  Otherwise it applies @{text "tac"},
   758   \<open>sat\<close> returns true.  Otherwise it applies \<open>tac\<close>,
   782   then recursively searches from each element of the resulting
   759   then recursively searches from each element of the resulting
   783   sequence.  The code uses a stack for efficiency, in effect applying
   760   sequence.  The code uses a stack for efficiency, in effect applying
   784   @{text "tac"}~@{ML_op THEN}~@{ML DEPTH_FIRST}~@{text "sat tac"} to
   761   \<open>tac\<close>~@{ML_op THEN}~@{ML DEPTH_FIRST}~\<open>sat tac\<close> to
   785   the state.
   762   the state.
   786 
   763 
   787   \<^descr> @{ML DEPTH_SOLVE}@{text "tac"} uses @{ML DEPTH_FIRST} to
   764   \<^descr> @{ML DEPTH_SOLVE}\<open>tac\<close> uses @{ML DEPTH_FIRST} to
   788   search for states having no subgoals.
   765   search for states having no subgoals.
   789 
   766 
   790   \<^descr> @{ML DEPTH_SOLVE_1}~@{text "tac"} uses @{ML DEPTH_FIRST} to
   767   \<^descr> @{ML DEPTH_SOLVE_1}~\<open>tac\<close> uses @{ML DEPTH_FIRST} to
   791   search for states having fewer subgoals than the given state.  Thus,
   768   search for states having fewer subgoals than the given state.  Thus,
   792   it insists upon solving at least one subgoal.
   769   it insists upon solving at least one subgoal.
   793 \<close>
   770 \<close>
   794 
   771 
   795 
   772 
   802   @{index_ML THEN_BEST_FIRST: "tactic -> (thm -> bool) * (thm -> int) -> tactic -> tactic"} \\
   779   @{index_ML THEN_BEST_FIRST: "tactic -> (thm -> bool) * (thm -> int) -> tactic -> tactic"} \\
   803   \end{mldecls}
   780   \end{mldecls}
   804 
   781 
   805   These search strategies will find a solution if one exists.
   782   These search strategies will find a solution if one exists.
   806   However, they do not enumerate all solutions; they terminate after
   783   However, they do not enumerate all solutions; they terminate after
   807   the first satisfactory result from @{text "tac"}.
   784   the first satisfactory result from \<open>tac\<close>.
   808 
   785 
   809   \<^descr> @{ML BREADTH_FIRST}~@{text "sat tac"} uses breadth-first
   786   \<^descr> @{ML BREADTH_FIRST}~\<open>sat tac\<close> uses breadth-first
   810   search to find states for which @{text "sat"} is true.  For most
   787   search to find states for which \<open>sat\<close> is true.  For most
   811   applications, it is too slow.
   788   applications, it is too slow.
   812 
   789 
   813   \<^descr> @{ML BEST_FIRST}~@{text "(sat, dist) tac"} does a heuristic
   790   \<^descr> @{ML BEST_FIRST}~\<open>(sat, dist) tac\<close> does a heuristic
   814   search, using @{text "dist"} to estimate the distance from a
   791   search, using \<open>dist\<close> to estimate the distance from a
   815   satisfactory state (in the sense of @{text "sat"}).  It maintains a
   792   satisfactory state (in the sense of \<open>sat\<close>).  It maintains a
   816   list of states ordered by distance.  It applies @{text "tac"} to the
   793   list of states ordered by distance.  It applies \<open>tac\<close> to the
   817   head of this list; if the result contains any satisfactory states,
   794   head of this list; if the result contains any satisfactory states,
   818   then it returns them.  Otherwise, @{ML BEST_FIRST} adds the new
   795   then it returns them.  Otherwise, @{ML BEST_FIRST} adds the new
   819   states to the list, and continues.
   796   states to the list, and continues.
   820 
   797 
   821   The distance function is typically @{ML size_of_thm}, which computes
   798   The distance function is typically @{ML size_of_thm}, which computes
   822   the size of the state.  The smaller the state, the fewer and simpler
   799   the size of the state.  The smaller the state, the fewer and simpler
   823   subgoals it has.
   800   subgoals it has.
   824 
   801 
   825   \<^descr> @{ML THEN_BEST_FIRST}~@{text "tac\<^sub>0 (sat, dist) tac"} is like
   802   \<^descr> @{ML THEN_BEST_FIRST}~\<open>tac\<^sub>0 (sat, dist) tac\<close> is like
   826   @{ML BEST_FIRST}, except that the priority queue initially contains
   803   @{ML BEST_FIRST}, except that the priority queue initially contains
   827   the result of applying @{text "tac\<^sub>0"} to the goal state.  This
   804   the result of applying \<open>tac\<^sub>0\<close> to the goal state.  This
   828   tactical permits separate tactics for starting the search and
   805   tactical permits separate tactics for starting the search and
   829   continuing the search.
   806   continuing the search.
   830 \<close>
   807 \<close>
   831 
   808 
   832 
   809 
   838   @{index_ML IF_UNSOLVED: "tactic -> tactic"} \\
   815   @{index_ML IF_UNSOLVED: "tactic -> tactic"} \\
   839   @{index_ML SOLVE: "tactic -> tactic"} \\
   816   @{index_ML SOLVE: "tactic -> tactic"} \\
   840   @{index_ML DETERM: "tactic -> tactic"} \\
   817   @{index_ML DETERM: "tactic -> tactic"} \\
   841   \end{mldecls}
   818   \end{mldecls}
   842 
   819 
   843   \<^descr> @{ML COND}~@{text "sat tac\<^sub>1 tac\<^sub>2"} applies @{text "tac\<^sub>1"} to
   820   \<^descr> @{ML COND}~\<open>sat tac\<^sub>1 tac\<^sub>2\<close> applies \<open>tac\<^sub>1\<close> to
   844   the goal state if it satisfies predicate @{text "sat"}, and applies
   821   the goal state if it satisfies predicate \<open>sat\<close>, and applies
   845   @{text "tac\<^sub>2"}.  It is a conditional tactical in that only one of
   822   \<open>tac\<^sub>2\<close>.  It is a conditional tactical in that only one of
   846   @{text "tac\<^sub>1"} and @{text "tac\<^sub>2"} is applied to a goal state.
   823   \<open>tac\<^sub>1\<close> and \<open>tac\<^sub>2\<close> is applied to a goal state.
   847   However, both @{text "tac\<^sub>1"} and @{text "tac\<^sub>2"} are evaluated
   824   However, both \<open>tac\<^sub>1\<close> and \<open>tac\<^sub>2\<close> are evaluated
   848   because ML uses eager evaluation.
   825   because ML uses eager evaluation.
   849 
   826 
   850   \<^descr> @{ML IF_UNSOLVED}~@{text "tac"} applies @{text "tac"} to the
   827   \<^descr> @{ML IF_UNSOLVED}~\<open>tac\<close> applies \<open>tac\<close> to the
   851   goal state if it has any subgoals, and simply returns the goal state
   828   goal state if it has any subgoals, and simply returns the goal state
   852   otherwise.  Many common tactics, such as @{ML resolve_tac}, fail if
   829   otherwise.  Many common tactics, such as @{ML resolve_tac}, fail if
   853   applied to a goal state that has no subgoals.
   830   applied to a goal state that has no subgoals.
   854 
   831 
   855   \<^descr> @{ML SOLVE}~@{text "tac"} applies @{text "tac"} to the goal
   832   \<^descr> @{ML SOLVE}~\<open>tac\<close> applies \<open>tac\<close> to the goal
   856   state and then fails iff there are subgoals left.
   833   state and then fails iff there are subgoals left.
   857 
   834 
   858   \<^descr> @{ML DETERM}~@{text "tac"} applies @{text "tac"} to the goal
   835   \<^descr> @{ML DETERM}~\<open>tac\<close> applies \<open>tac\<close> to the goal
   859   state and returns the head of the resulting sequence.  @{ML DETERM}
   836   state and returns the head of the resulting sequence.  @{ML DETERM}
   860   limits the search space by making its argument deterministic.
   837   limits the search space by making its argument deterministic.
   861 \<close>
   838 \<close>
   862 
   839 
   863 
   840 
   869   @{index_ML Thm.eq_thm: "thm * thm -> bool"} \\
   846   @{index_ML Thm.eq_thm: "thm * thm -> bool"} \\
   870   @{index_ML Thm.eq_thm_prop: "thm * thm -> bool"} \\
   847   @{index_ML Thm.eq_thm_prop: "thm * thm -> bool"} \\
   871   @{index_ML size_of_thm: "thm -> int"} \\
   848   @{index_ML size_of_thm: "thm -> int"} \\
   872   \end{mldecls}
   849   \end{mldecls}
   873 
   850 
   874   \<^descr> @{ML has_fewer_prems}~@{text "n thm"} reports whether @{text
   851   \<^descr> @{ML has_fewer_prems}~\<open>n thm\<close> reports whether \<open>thm\<close> has fewer than \<open>n\<close> premises.
   875   "thm"} has fewer than @{text "n"} premises.
   852 
   876 
   853   \<^descr> @{ML Thm.eq_thm}~\<open>(thm\<^sub>1, thm\<^sub>2)\<close> reports whether \<open>thm\<^sub>1\<close> and \<open>thm\<^sub>2\<close> are equal.  Both theorems must have the
   877   \<^descr> @{ML Thm.eq_thm}~@{text "(thm\<^sub>1, thm\<^sub>2)"} reports whether @{text
       
   878   "thm\<^sub>1"} and @{text "thm\<^sub>2"} are equal.  Both theorems must have the
       
   879   same conclusions, the same set of hypotheses, and the same set of sort
   854   same conclusions, the same set of hypotheses, and the same set of sort
   880   hypotheses.  Names of bound variables are ignored as usual.
   855   hypotheses.  Names of bound variables are ignored as usual.
   881 
   856 
   882   \<^descr> @{ML Thm.eq_thm_prop}~@{text "(thm\<^sub>1, thm\<^sub>2)"} reports whether
   857   \<^descr> @{ML Thm.eq_thm_prop}~\<open>(thm\<^sub>1, thm\<^sub>2)\<close> reports whether
   883   the propositions of @{text "thm\<^sub>1"} and @{text "thm\<^sub>2"} are equal.
   858   the propositions of \<open>thm\<^sub>1\<close> and \<open>thm\<^sub>2\<close> are equal.
   884   Names of bound variables are ignored.
   859   Names of bound variables are ignored.
   885 
   860 
   886   \<^descr> @{ML size_of_thm}~@{text "thm"} computes the size of @{text
   861   \<^descr> @{ML size_of_thm}~\<open>thm\<close> computes the size of \<open>thm\<close>, namely the number of variables, constants and abstractions
   887   "thm"}, namely the number of variables, constants and abstractions
       
   888   in its conclusion.  It may serve as a distance function for
   862   in its conclusion.  It may serve as a distance function for
   889   @{ML BEST_FIRST}.
   863   @{ML BEST_FIRST}.
   890 \<close>
   864 \<close>
   891 
   865 
   892 end
   866 end