diff -r 3480725c71d2 -r 0debd22f0c0e src/Doc/Implementation/Tactic.thy --- a/src/Doc/Implementation/Tactic.thy Tue Oct 20 23:03:46 2015 +0200 +++ b/src/Doc/Implementation/Tactic.thy Tue Oct 20 23:53:40 2015 +0200 @@ -5,40 +5,36 @@ chapter \Tactical reasoning\ text \Tactical reasoning works by refining an initial claim in a - backwards fashion, until a solved form is reached. A @{text "goal"} + backwards fashion, until a solved form is reached. A \goal\ consists of several subgoals that need to be solved in order to achieve the main statement; zero subgoals means that the proof may - be finished. A @{text "tactic"} is a refinement operation that maps - a goal to a lazy sequence of potential successors. A @{text - "tactical"} is a combinator for composing tactics.\ + be finished. A \tactic\ is a refinement operation that maps + a goal to a lazy sequence of potential successors. A \tactical\ is a combinator for composing tactics.\ section \Goals \label{sec:tactical-goals}\ text \ Isabelle/Pure represents a goal as a theorem stating that the - subgoals imply the main goal: @{text "A\<^sub>1 \ \ \ A\<^sub>n \ - C"}. The outermost goal structure is that of a Horn Clause: i.e.\ + subgoals imply the main goal: \A\<^sub>1 \ \ \ A\<^sub>n \ + C\. The outermost goal structure is that of a Horn Clause: i.e.\ an iterated implication without any quantifiers\footnote{Recall that - outermost @{text "\x. \[x]"} is always represented via schematic - variables in the body: @{text "\[?x]"}. These variables may get - instantiated during the course of reasoning.}. For @{text "n = 0"} + outermost \\x. \[x]\ is always represented via schematic + variables in the body: \\[?x]\. These variables may get + instantiated during the course of reasoning.}. For \n = 0\ a goal is called ``solved''. - The structure of each subgoal @{text "A\<^sub>i"} is that of a - general Hereditary Harrop Formula @{text "\x\<^sub>1 \ - \x\<^sub>k. H\<^sub>1 \ \ \ H\<^sub>m \ B"}. Here @{text - "x\<^sub>1, \, x\<^sub>k"} are goal parameters, i.e.\ - arbitrary-but-fixed entities of certain types, and @{text - "H\<^sub>1, \, H\<^sub>m"} are goal hypotheses, i.e.\ facts that may + The structure of each subgoal \A\<^sub>i\ is that of a + general Hereditary Harrop Formula \\x\<^sub>1 \ + \x\<^sub>k. H\<^sub>1 \ \ \ H\<^sub>m \ B\. Here \x\<^sub>1, \, x\<^sub>k\ are goal parameters, i.e.\ + arbitrary-but-fixed entities of certain types, and \H\<^sub>1, \, H\<^sub>m\ are goal hypotheses, i.e.\ facts that may be assumed locally. Together, this forms the goal context of the - conclusion @{text B} to be established. The goal hypotheses may be + conclusion \B\ to be established. The goal hypotheses may be again arbitrary Hereditary Harrop Formulas, although the level of nesting rarely exceeds 1--2 in practice. - The main conclusion @{text C} is internally marked as a protected - proposition, which is represented explicitly by the notation @{text - "#C"} here. This ensures that the decomposition into subgoals and + The main conclusion \C\ is internally marked as a protected + proposition, which is represented explicitly by the notation \#C\ here. This ensures that the decomposition into subgoals and main conclusion is well-defined for arbitrarily structured claims. \<^medskip> @@ -46,8 +42,8 @@ Isabelle/Pure rules: \[ - \infer[@{text "(init)"}]{@{text "C \ #C"}}{} \qquad - \infer[@{text "(finish)"}]{@{text "C"}}{@{text "#C"}} + \infer[\(init)\]{\C \ #C\}{} \qquad + \infer[\(finish)\]{\C\}{\#C\} \] \<^medskip> @@ -55,10 +51,10 @@ with protected propositions: \[ - \infer[@{text "(protect n)"}]{@{text "A\<^sub>1 \ \ \ A\<^sub>n \ #C"}}{@{text "A\<^sub>1 \ \ \ A\<^sub>n \ C"}} + \infer[\(protect n)\]{\A\<^sub>1 \ \ \ A\<^sub>n \ #C\}{\A\<^sub>1 \ \ \ A\<^sub>n \ C\} \] \[ - \infer[@{text "(conclude)"}]{@{text "A \ \ \ C"}}{@{text "A \ \ \ #C"}} + \infer[\(conclude)\]{\A \ \ \ C\}{\A \ \ \ #C\} \] \ @@ -70,26 +66,26 @@ @{index_ML Goal.conclude: "thm -> thm"} \\ \end{mldecls} - \<^descr> @{ML "Goal.init"}~@{text C} initializes a tactical goal from - the well-formed proposition @{text C}. + \<^descr> @{ML "Goal.init"}~\C\ initializes a tactical goal from + the well-formed proposition \C\. - \<^descr> @{ML "Goal.finish"}~@{text "ctxt thm"} checks whether theorem - @{text "thm"} is a solved goal (no subgoals), and concludes the + \<^descr> @{ML "Goal.finish"}~\ctxt thm\ checks whether theorem + \thm\ is a solved goal (no subgoals), and concludes the result by removing the goal protection. The context is only required for printing error messages. - \<^descr> @{ML "Goal.protect"}~@{text "n thm"} protects the statement - of theorem @{text "thm"}. The parameter @{text n} indicates the + \<^descr> @{ML "Goal.protect"}~\n thm\ protects the statement + of theorem \thm\. The parameter \n\ indicates the number of premises to be retained. - \<^descr> @{ML "Goal.conclude"}~@{text "thm"} removes the goal + \<^descr> @{ML "Goal.conclude"}~\thm\ removes the goal protection, even if there are pending subgoals. \ section \Tactics\label{sec:tactics}\ -text \A @{text "tactic"} is a function @{text "goal \ goal\<^sup>*\<^sup>*"} that +text \A \tactic\ is a function \goal \ goal\<^sup>*\<^sup>*\ that maps a given goal state (represented as a theorem, cf.\ \secref{sec:tactical-goals}) to a lazy sequence of potential successor states. The underlying sequence implementation is lazy @@ -121,7 +117,7 @@ schematic goal variables). Tactics with explicit \<^emph>\subgoal addressing\ are of the form - @{text "int \ tactic"} and may be applied to a particular subgoal + \int \ tactic\ and may be applied to a particular subgoal (counting from 1). If the subgoal number is out of range, the tactic should fail with an empty result sequence, but must not raise an exception! @@ -139,7 +135,7 @@ very common error when implementing tactics! Tactics with internal subgoal addressing should expose the subgoal - index as @{text "int"} argument in full generality; a hardwired + index as \int\ argument in full generality; a hardwired subgoal 1 is not acceptable. \<^medskip> @@ -195,16 +191,16 @@ \<^descr> @{ML all_tac} is a tactic that always succeeds, returning a singleton sequence with unchanged goal state. - \<^descr> @{ML print_tac}~@{text "ctxt message"} is like @{ML all_tac}, but + \<^descr> @{ML print_tac}~\ctxt message\ is like @{ML all_tac}, but prints a message together with the goal state on the tracing channel. - \<^descr> @{ML PRIMITIVE}~@{text rule} turns a primitive inference rule + \<^descr> @{ML PRIMITIVE}~\rule\ turns a primitive inference rule into a tactic with unique result. Exception @{ML THM} is considered a regular tactic failure and produces an empty result; other exceptions are passed through. - \<^descr> @{ML SUBGOAL}~@{text "(fn (subgoal, i) => tactic)"} is the + \<^descr> @{ML SUBGOAL}~\(fn (subgoal, i) => tactic)\ is the most basic form to produce a tactic with subgoal addressing. The given abstraction over the subgoal term and subgoal number allows to peek at the relevant information of the full goal state. The @@ -215,14 +211,14 @@ avoids expensive re-certification in situations where the subgoal is used directly for primitive inferences. - \<^descr> @{ML SELECT_GOAL}~@{text "tac i"} confines a tactic to the - specified subgoal @{text "i"}. This rearranges subgoals and the + \<^descr> @{ML SELECT_GOAL}~\tac i\ confines a tactic to the + specified subgoal \i\. This rearranges subgoals and the main goal protection (\secref{sec:tactical-goals}), while retaining the syntactic context of the overall goal state (concerning schematic variables etc.). - \<^descr> @{ML PREFER_GOAL}~@{text "tac i"} rearranges subgoals to put - @{text "i"} in front. This is similar to @{ML SELECT_GOAL}, but + \<^descr> @{ML PREFER_GOAL}~\tac i\ rearranges subgoals to put + \i\ in front. This is similar to @{ML SELECT_GOAL}, but without changing the main goal protection. \ @@ -237,7 +233,7 @@ \<^emph>\Destruct-resolution\ is like elim-resolution, but the given destruction rules are first turned into canonical elimination format. \<^emph>\Forward-resolution\ is like destruct-resolution, but - without deleting the selected assumption. The @{text "r/e/d/f"} + without deleting the selected assumption. The \r/e/d/f\ naming convention is maintained for several different kinds of resolution rules and tactics. @@ -281,20 +277,19 @@ @{index_ML bimatch_tac: "Proof.context -> (bool * thm) list -> int -> tactic"} \\ \end{mldecls} - \<^descr> @{ML resolve_tac}~@{text "ctxt thms i"} refines the goal state + \<^descr> @{ML resolve_tac}~\ctxt thms i\ refines the goal state using the given theorems, which should normally be introduction - rules. The tactic resolves a rule's conclusion with subgoal @{text - i}, replacing it by the corresponding versions of the rule's + rules. The tactic resolves a rule's conclusion with subgoal \i\, replacing it by the corresponding versions of the rule's premises. - \<^descr> @{ML eresolve_tac}~@{text "ctxt thms i"} performs elim-resolution + \<^descr> @{ML eresolve_tac}~\ctxt thms i\ performs elim-resolution with the given theorems, which are normally be elimination rules. Note that @{ML_text "eresolve_tac ctxt [asm_rl]"} is equivalent to @{ML_text "assume_tac ctxt"}, which facilitates mixing of assumption steps with genuine eliminations. - \<^descr> @{ML dresolve_tac}~@{text "ctxt thms i"} performs + \<^descr> @{ML dresolve_tac}~\ctxt thms i\ performs destruct-resolution with the given theorems, which should normally be destruction rules. This replaces an assumption by the result of applying one of the rules. @@ -303,21 +298,20 @@ selected assumption is not deleted. It applies a rule to an assumption, adding the result as a new assumption. - \<^descr> @{ML biresolve_tac}~@{text "ctxt brls i"} refines the proof state + \<^descr> @{ML biresolve_tac}~\ctxt brls i\ refines the proof state by resolution or elim-resolution on each rule, as indicated by its - flag. It affects subgoal @{text "i"} of the proof state. + flag. It affects subgoal \i\ of the proof state. - For each pair @{text "(flag, rule)"}, it applies resolution if the - flag is @{text "false"} and elim-resolution if the flag is @{text - "true"}. A single tactic call handles a mixture of introduction and + For each pair \(flag, rule)\, it applies resolution if the + flag is \false\ and elim-resolution if the flag is \true\. A single tactic call handles a mixture of introduction and elimination rules, which is useful to organize the search process systematically in proof tools. - \<^descr> @{ML assume_tac}~@{text "ctxt i"} attempts to solve subgoal @{text i} + \<^descr> @{ML assume_tac}~\ctxt i\ attempts to solve subgoal \i\ by assumption (modulo higher-order unification). \<^descr> @{ML eq_assume_tac} is similar to @{ML assume_tac}, but checks - only for immediate @{text "\"}-convertibility instead of using + only for immediate \\\-convertibility instead of using unification. It succeeds (with a unique next state) if one of the assumptions is equal to the subgoal's conclusion. Since it does not instantiate variables, it cannot make other subgoals unprovable. @@ -346,25 +340,22 @@ higher-order unification is not so useful. This typically involves rules like universal elimination, existential introduction, or equational substitution. Here the unification problem involves - fully flexible @{text "?P ?x"} schemes, which are hard to manage + fully flexible \?P ?x\ schemes, which are hard to manage without further hints. - By providing a (small) rigid term for @{text "?x"} explicitly, the - remaining unification problem is to assign a (large) term to @{text - "?P"}, according to the shape of the given subgoal. This is + By providing a (small) rigid term for \?x\ explicitly, the + remaining unification problem is to assign a (large) term to \?P\, according to the shape of the given subgoal. This is sufficiently well-behaved in most practical situations. \<^medskip> - Isabelle provides separate versions of the standard @{text - "r/e/d/f"} resolution tactics that allow to provide explicit + Isabelle provides separate versions of the standard \r/e/d/f\ resolution tactics that allow to provide explicit instantiations of unknowns of the given rule, wrt.\ terms that refer to the implicit context of the selected subgoal. - An instantiation consists of a list of pairs of the form @{text - "(?x, t)"}, where @{text ?x} is a schematic variable occurring in - the given rule, and @{text t} is a term from the current proof + An instantiation consists of a list of pairs of the form \(?x, t)\, where \?x\ is a schematic variable occurring in + the given rule, and \t\ is a term from the current proof context, augmented by the local goal parameters of the selected - subgoal; cf.\ the @{text "focus"} operation described in + subgoal; cf.\ the \focus\ operation described in \secref{sec:variables}. Entering the syntactic context of a subgoal is a brittle operation, @@ -373,8 +364,7 @@ global names. Explicit renaming of subgoal parameters prior to explicit instantiation might help to achieve a bit more robustness. - Type instantiations may be given as well, via pairs like @{text - "(?'a, \)"}. Type instantiations are distinguished from term + Type instantiations may be given as well, via pairs like \(?'a, \)\. Type instantiations are distinguished from term instantiations by the syntactic form of the schematic variable. Types are instantiated before terms are. Since term instantiation already performs simple type-inference, so explicit type @@ -402,9 +392,9 @@ @{index_ML rename_tac: "string list -> int -> tactic"} \\ \end{mldecls} - \<^descr> @{ML Rule_Insts.res_inst_tac}~@{text "ctxt insts thm i"} instantiates the - rule @{text thm} with the instantiations @{text insts}, as described - above, and then performs resolution on subgoal @{text i}. + \<^descr> @{ML Rule_Insts.res_inst_tac}~\ctxt insts thm i\ instantiates the + rule \thm\ with the instantiations \insts\, as described + above, and then performs resolution on subgoal \i\. \<^descr> @{ML Rule_Insts.eres_inst_tac} is like @{ML Rule_Insts.res_inst_tac}, but performs elim-resolution. @@ -415,20 +405,19 @@ \<^descr> @{ML Rule_Insts.forw_inst_tac} is like @{ML Rule_Insts.dres_inst_tac} except that the selected assumption is not deleted. - \<^descr> @{ML Rule_Insts.subgoal_tac}~@{text "ctxt \ i"} adds the proposition - @{text "\"} as local premise to subgoal @{text "i"}, and poses the - same as a new subgoal @{text "i + 1"} (in the original context). + \<^descr> @{ML Rule_Insts.subgoal_tac}~\ctxt \ i\ adds the proposition + \\\ as local premise to subgoal \i\, and poses the + same as a new subgoal \i + 1\ (in the original context). - \<^descr> @{ML Rule_Insts.thin_tac}~@{text "ctxt \ i"} deletes the specified - premise from subgoal @{text i}. Note that @{text \} may contain + \<^descr> @{ML Rule_Insts.thin_tac}~\ctxt \ i\ deletes the specified + premise from subgoal \i\. Note that \\\ may contain schematic variables, to abbreviate the intended proposition; the first matching subgoal premise will be deleted. Removing useless premises from a subgoal increases its readability and can make search tactics run faster. - \<^descr> @{ML rename_tac}~@{text "names i"} renames the innermost - parameters of subgoal @{text i} according to the provided @{text - names} (which need to be distinct identifiers). + \<^descr> @{ML rename_tac}~\names i\ renames the innermost + parameters of subgoal \i\ according to the provided \names\ (which need to be distinct identifiers). For historical reasons, the above instantiation tactics take @@ -453,9 +442,9 @@ @{index_ML flexflex_tac: "Proof.context -> tactic"} \\ \end{mldecls} - \<^descr> @{ML rotate_tac}~@{text "n i"} rotates the premises of subgoal - @{text i} by @{text n} positions: from right to left if @{text n} is - positive, and from left to right if @{text n} is negative. + \<^descr> @{ML rotate_tac}~\n i\ rotates the premises of subgoal + \i\ by \n\ positions: from right to left if \n\ is + positive, and from left to right if \n\ is negative. \<^descr> @{ML distinct_subgoals_tac} removes duplicate subgoals from a proof state. This is potentially inefficient. @@ -489,24 +478,21 @@ @{index_ML_op COMP: "thm * thm -> thm"} \\ \end{mldecls} - \<^descr> @{ML compose_tac}~@{text "ctxt (flag, rule, m) i"} refines subgoal - @{text "i"} using @{text "rule"}, without lifting. The @{text - "rule"} is taken to have the form @{text "\\<^sub>1 \ \ \\<^sub>m \ \"}, where - @{text "\"} need not be atomic; thus @{text "m"} determines the - number of new subgoals. If @{text "flag"} is @{text "true"} then it - performs elim-resolution --- it solves the first premise of @{text - "rule"} by assumption and deletes that assumption. + \<^descr> @{ML compose_tac}~\ctxt (flag, rule, m) i\ refines subgoal + \i\ using \rule\, without lifting. The \rule\ is taken to have the form \\\<^sub>1 \ \ \\<^sub>m \ \\, where + \\\ need not be atomic; thus \m\ determines the + number of new subgoals. If \flag\ is \true\ then it + performs elim-resolution --- it solves the first premise of \rule\ by assumption and deletes that assumption. - \<^descr> @{ML Drule.compose}~@{text "(thm\<^sub>1, i, thm\<^sub>2)"} uses @{text "thm\<^sub>1"}, - regarded as an atomic formula, to solve premise @{text "i"} of - @{text "thm\<^sub>2"}. Let @{text "thm\<^sub>1"} and @{text "thm\<^sub>2"} be @{text - "\"} and @{text "\\<^sub>1 \ \ \\<^sub>n \ \"}. The unique @{text "s"} that - unifies @{text "\"} and @{text "\\<^sub>i"} yields the theorem @{text "(\\<^sub>1 \ - \ \\<^sub>i\<^sub>-\<^sub>1 \ \\<^sub>i\<^sub>+\<^sub>1 \ \ \\<^sub>n \ \)s"}. Multiple results are considered as + \<^descr> @{ML Drule.compose}~\(thm\<^sub>1, i, thm\<^sub>2)\ uses \thm\<^sub>1\, + regarded as an atomic formula, to solve premise \i\ of + \thm\<^sub>2\. Let \thm\<^sub>1\ and \thm\<^sub>2\ be \\\ and \\\<^sub>1 \ \ \\<^sub>n \ \\. The unique \s\ that + unifies \\\ and \\\<^sub>i\ yields the theorem \(\\<^sub>1 \ + \ \\<^sub>i\<^sub>-\<^sub>1 \ \\<^sub>i\<^sub>+\<^sub>1 \ \ \\<^sub>n \ \)s\. Multiple results are considered as error (exception @{ML THM}). - \<^descr> @{text "thm\<^sub>1 COMP thm\<^sub>2"} is the same as @{text "Drule.compose - (thm\<^sub>1, 1, thm\<^sub>2)"}. + \<^descr> \thm\<^sub>1 COMP thm\<^sub>2\ is the same as \Drule.compose + (thm\<^sub>1, 1, thm\<^sub>2)\. \begin{warn} @@ -554,42 +540,35 @@ @{index_ML "FIRST'": "('a -> tactic) list -> 'a -> tactic"} \\ \end{mldecls} - \<^descr> @{text "tac\<^sub>1"}~@{ML_op THEN}~@{text "tac\<^sub>2"} is the sequential - composition of @{text "tac\<^sub>1"} and @{text "tac\<^sub>2"}. Applied to a goal + \<^descr> \tac\<^sub>1\~@{ML_op THEN}~\tac\<^sub>2\ is the sequential + composition of \tac\<^sub>1\ and \tac\<^sub>2\. Applied to a goal state, it returns all states reachable in two steps by applying - @{text "tac\<^sub>1"} followed by @{text "tac\<^sub>2"}. First, it applies @{text - "tac\<^sub>1"} to the goal state, getting a sequence of possible next - states; then, it applies @{text "tac\<^sub>2"} to each of these and + \tac\<^sub>1\ followed by \tac\<^sub>2\. First, it applies \tac\<^sub>1\ to the goal state, getting a sequence of possible next + states; then, it applies \tac\<^sub>2\ to each of these and concatenates the results to produce again one flat sequence of states. - \<^descr> @{text "tac\<^sub>1"}~@{ML_op ORELSE}~@{text "tac\<^sub>2"} makes a choice - between @{text "tac\<^sub>1"} and @{text "tac\<^sub>2"}. Applied to a state, it - tries @{text "tac\<^sub>1"} and returns the result if non-empty; if @{text - "tac\<^sub>1"} fails then it uses @{text "tac\<^sub>2"}. This is a deterministic - choice: if @{text "tac\<^sub>1"} succeeds then @{text "tac\<^sub>2"} is excluded + \<^descr> \tac\<^sub>1\~@{ML_op ORELSE}~\tac\<^sub>2\ makes a choice + between \tac\<^sub>1\ and \tac\<^sub>2\. Applied to a state, it + tries \tac\<^sub>1\ and returns the result if non-empty; if \tac\<^sub>1\ fails then it uses \tac\<^sub>2\. This is a deterministic + choice: if \tac\<^sub>1\ succeeds then \tac\<^sub>2\ is excluded from the result. - \<^descr> @{text "tac\<^sub>1"}~@{ML_op APPEND}~@{text "tac\<^sub>2"} concatenates the - possible results of @{text "tac\<^sub>1"} and @{text "tac\<^sub>2"}. Unlike + \<^descr> \tac\<^sub>1\~@{ML_op APPEND}~\tac\<^sub>2\ concatenates the + possible results of \tac\<^sub>1\ and \tac\<^sub>2\. Unlike @{ML_op "ORELSE"} there is \<^emph>\no commitment\ to either tactic, so @{ML_op "APPEND"} helps to avoid incompleteness during search, at the cost of potential inefficiencies. - \<^descr> @{ML EVERY}~@{text "[tac\<^sub>1, \, tac\<^sub>n]"} abbreviates @{text - "tac\<^sub>1"}~@{ML_op THEN}~@{text "\"}~@{ML_op THEN}~@{text "tac\<^sub>n"}. + \<^descr> @{ML EVERY}~\[tac\<^sub>1, \, tac\<^sub>n]\ abbreviates \tac\<^sub>1\~@{ML_op THEN}~\\\~@{ML_op THEN}~\tac\<^sub>n\. Note that @{ML "EVERY []"} is the same as @{ML all_tac}: it always succeeds. - \<^descr> @{ML FIRST}~@{text "[tac\<^sub>1, \, tac\<^sub>n]"} abbreviates @{text - "tac\<^sub>1"}~@{ML_op ORELSE}~@{text "\"}~@{ML_op "ORELSE"}~@{text - "tac\<^sub>n"}. Note that @{ML "FIRST []"} is the same as @{ML no_tac}: it + \<^descr> @{ML FIRST}~\[tac\<^sub>1, \, tac\<^sub>n]\ abbreviates \tac\<^sub>1\~@{ML_op ORELSE}~\\\~@{ML_op "ORELSE"}~\tac\<^sub>n\. Note that @{ML "FIRST []"} is the same as @{ML no_tac}: it always fails. \<^descr> @{ML_op "THEN'"} is the lifted version of @{ML_op "THEN"}, for - tactics with explicit subgoal addressing. So @{text - "(tac\<^sub>1"}~@{ML_op THEN'}~@{text "tac\<^sub>2) i"} is the same as @{text - "(tac\<^sub>1 i"}~@{ML_op THEN}~@{text "tac\<^sub>2 i)"}. + tactics with explicit subgoal addressing. So \(tac\<^sub>1\~@{ML_op THEN'}~\tac\<^sub>2) i\ is the same as \(tac\<^sub>1 i\~@{ML_op THEN}~\tac\<^sub>2 i)\. The other primed tacticals work analogously. \ @@ -610,35 +589,33 @@ @{index_ML "REPEAT_DETERM_N": "int -> tactic -> tactic"} \\ \end{mldecls} - \<^descr> @{ML TRY}~@{text "tac"} applies @{text "tac"} to the goal + \<^descr> @{ML TRY}~\tac\ applies \tac\ to the goal state and returns the resulting sequence, if non-empty; otherwise it - returns the original state. Thus, it applies @{text "tac"} at most + returns the original state. Thus, it applies \tac\ at most once. Note that for tactics with subgoal addressing, the combinator can be - applied via functional composition: @{ML "TRY"}~@{ML_op o}~@{text - "tac"}. There is no need for @{verbatim TRY'}. + applied via functional composition: @{ML "TRY"}~@{ML_op o}~\tac\. There is no need for @{verbatim TRY'}. - \<^descr> @{ML REPEAT}~@{text "tac"} applies @{text "tac"} to the goal + \<^descr> @{ML REPEAT}~\tac\ applies \tac\ to the goal state and, recursively, to each element of the resulting sequence. - The resulting sequence consists of those states that make @{text - "tac"} fail. Thus, it applies @{text "tac"} as many times as + The resulting sequence consists of those states that make \tac\ fail. Thus, it applies \tac\ as many times as possible (including zero times), and allows backtracking over each - invocation of @{text "tac"}. @{ML REPEAT} is more general than @{ML + invocation of \tac\. @{ML REPEAT} is more general than @{ML REPEAT_DETERM}, but requires more space. - \<^descr> @{ML REPEAT1}~@{text "tac"} is like @{ML REPEAT}~@{text "tac"} - but it always applies @{text "tac"} at least once, failing if this + \<^descr> @{ML REPEAT1}~\tac\ is like @{ML REPEAT}~\tac\ + but it always applies \tac\ at least once, failing if this is impossible. - \<^descr> @{ML REPEAT_DETERM}~@{text "tac"} applies @{text "tac"} to the + \<^descr> @{ML REPEAT_DETERM}~\tac\ applies \tac\ to the goal state and, recursively, to the head of the resulting sequence. - It returns the first state to make @{text "tac"} fail. It is + It returns the first state to make \tac\ fail. It is deterministic, discarding alternative outcomes. - \<^descr> @{ML REPEAT_DETERM_N}~@{text "n tac"} is like @{ML - REPEAT_DETERM}~@{text "tac"} but the number of repetitions is bound - by @{text "n"} (where @{ML "~1"} means @{text "\"}). + \<^descr> @{ML REPEAT_DETERM_N}~\n tac\ is like @{ML + REPEAT_DETERM}~\tac\ but the number of repetitions is bound + by \n\ (where @{ML "~1"} means \\\). \ text %mlex \The basic tactics and tacticals considered above follow @@ -649,7 +626,7 @@ \<^item> @{ML no_tac} is the identity element of @{ML_op "ORELSE"} and @{ML_op "APPEND"}. Also, it is a zero element for @{ML_op "THEN"}, - which means that @{text "tac"}~@{ML_op THEN}~@{ML no_tac} is + which means that \tac\~@{ML_op THEN}~@{ML no_tac} is equivalent to @{ML no_tac}. \<^item> @{ML TRY} and @{ML REPEAT} can be expressed as (recursive) @@ -662,9 +639,9 @@ fun REPEAT tac st = ((tac THEN REPEAT tac) ORELSE all_tac) st; \ -text \If @{text "tac"} can return multiple outcomes then so can @{ML - REPEAT}~@{text "tac"}. @{ML REPEAT} uses @{ML_op "ORELSE"} and not - @{ML_op "APPEND"}, it applies @{text "tac"} as many times as +text \If \tac\ can return multiple outcomes then so can @{ML + REPEAT}~\tac\. @{ML REPEAT} uses @{ML_op "ORELSE"} and not + @{ML_op "APPEND"}, it applies \tac\ as many times as possible in each outcome. \begin{warn} @@ -672,7 +649,7 @@ definition of @{ML REPEAT}. Recursive tacticals must be coded in this awkward fashion to avoid infinite recursion of eager functional evaluation in Standard ML. The following attempt would make @{ML - REPEAT}~@{text "tac"} loop: + REPEAT}~\tac\ loop: \end{warn} \ @@ -690,9 +667,9 @@ tactic a certain range of subgoals is covered. Thus the body tactic is applied to \<^emph>\all\ subgoals, \<^emph>\some\ subgoal etc. - Suppose that the goal state has @{text "n \ 0"} subgoals. Many of + Suppose that the goal state has \n \ 0\ subgoals. Many of these tacticals address subgoal ranges counting downwards from - @{text "n"} towards @{text "1"}. This has the fortunate effect that + \n\ towards \1\. This has the fortunate effect that newly emerging subgoals are concatenated in the result, without interfering each other. Nonetheless, there might be situations where a different order is desired.\ @@ -708,30 +685,30 @@ @{index_ML RANGE: "(int -> tactic) list -> int -> tactic"} \\ \end{mldecls} - \<^descr> @{ML ALLGOALS}~@{text "tac"} is equivalent to @{text "tac - n"}~@{ML_op THEN}~@{text "\"}~@{ML_op THEN}~@{text "tac 1"}. It - applies the @{text tac} to all the subgoals, counting downwards. + \<^descr> @{ML ALLGOALS}~\tac\ is equivalent to \tac + n\~@{ML_op THEN}~\\\~@{ML_op THEN}~\tac 1\. It + applies the \tac\ to all the subgoals, counting downwards. - \<^descr> @{ML SOMEGOAL}~@{text "tac"} is equivalent to @{text "tac - n"}~@{ML_op ORELSE}~@{text "\"}~@{ML_op ORELSE}~@{text "tac 1"}. It - applies @{text "tac"} to one subgoal, counting downwards. + \<^descr> @{ML SOMEGOAL}~\tac\ is equivalent to \tac + n\~@{ML_op ORELSE}~\\\~@{ML_op ORELSE}~\tac 1\. It + applies \tac\ to one subgoal, counting downwards. - \<^descr> @{ML FIRSTGOAL}~@{text "tac"} is equivalent to @{text "tac - 1"}~@{ML_op ORELSE}~@{text "\"}~@{ML_op ORELSE}~@{text "tac n"}. It - applies @{text "tac"} to one subgoal, counting upwards. + \<^descr> @{ML FIRSTGOAL}~\tac\ is equivalent to \tac + 1\~@{ML_op ORELSE}~\\\~@{ML_op ORELSE}~\tac n\. It + applies \tac\ to one subgoal, counting upwards. - \<^descr> @{ML HEADGOAL}~@{text "tac"} is equivalent to @{text "tac 1"}. - It applies @{text "tac"} unconditionally to the first subgoal. + \<^descr> @{ML HEADGOAL}~\tac\ is equivalent to \tac 1\. + It applies \tac\ unconditionally to the first subgoal. - \<^descr> @{ML REPEAT_SOME}~@{text "tac"} applies @{text "tac"} once or + \<^descr> @{ML REPEAT_SOME}~\tac\ applies \tac\ once or more to a subgoal, counting downwards. - \<^descr> @{ML REPEAT_FIRST}~@{text "tac"} applies @{text "tac"} once or + \<^descr> @{ML REPEAT_FIRST}~\tac\ applies \tac\ once or more to a subgoal, counting upwards. - \<^descr> @{ML RANGE}~@{text "[tac\<^sub>1, \, tac\<^sub>k] i"} is equivalent to - @{text "tac\<^sub>k (i + k - 1)"}~@{ML_op THEN}~@{text "\"}~@{ML_op - THEN}~@{text "tac\<^sub>1 i"}. It applies the given list of tactics to the + \<^descr> @{ML RANGE}~\[tac\<^sub>1, \, tac\<^sub>k] i\ is equivalent to + \tac\<^sub>k (i + k - 1)\~@{ML_op THEN}~\\\~@{ML_op + THEN}~\tac\<^sub>1 i\. It applies the given list of tactics to the corresponding range of subgoals, counting downwards. \ @@ -757,14 +734,14 @@ @{index_ML CHANGED: "tactic -> tactic"} \\ \end{mldecls} - \<^descr> @{ML FILTER}~@{text "sat tac"} applies @{text "tac"} to the + \<^descr> @{ML FILTER}~\sat tac\ applies \tac\ to the goal state and returns a sequence consisting of those result goal - states that are satisfactory in the sense of @{text "sat"}. + states that are satisfactory in the sense of \sat\. - \<^descr> @{ML CHANGED}~@{text "tac"} applies @{text "tac"} to the goal + \<^descr> @{ML CHANGED}~\tac\ applies \tac\ to the goal state and returns precisely those states that differ from the original state (according to @{ML Thm.eq_thm}). Thus @{ML - CHANGED}~@{text "tac"} always has some effect on the state. + CHANGED}~\tac\ always has some effect on the state. \ @@ -777,17 +754,17 @@ @{index_ML DEPTH_SOLVE_1: "tactic -> tactic"} \\ \end{mldecls} - \<^descr> @{ML DEPTH_FIRST}~@{text "sat tac"} returns the goal state if - @{text "sat"} returns true. Otherwise it applies @{text "tac"}, + \<^descr> @{ML DEPTH_FIRST}~\sat tac\ returns the goal state if + \sat\ returns true. Otherwise it applies \tac\, then recursively searches from each element of the resulting sequence. The code uses a stack for efficiency, in effect applying - @{text "tac"}~@{ML_op THEN}~@{ML DEPTH_FIRST}~@{text "sat tac"} to + \tac\~@{ML_op THEN}~@{ML DEPTH_FIRST}~\sat tac\ to the state. - \<^descr> @{ML DEPTH_SOLVE}@{text "tac"} uses @{ML DEPTH_FIRST} to + \<^descr> @{ML DEPTH_SOLVE}\tac\ uses @{ML DEPTH_FIRST} to search for states having no subgoals. - \<^descr> @{ML DEPTH_SOLVE_1}~@{text "tac"} uses @{ML DEPTH_FIRST} to + \<^descr> @{ML DEPTH_SOLVE_1}~\tac\ uses @{ML DEPTH_FIRST} to search for states having fewer subgoals than the given state. Thus, it insists upon solving at least one subgoal. \ @@ -804,16 +781,16 @@ These search strategies will find a solution if one exists. However, they do not enumerate all solutions; they terminate after - the first satisfactory result from @{text "tac"}. + the first satisfactory result from \tac\. - \<^descr> @{ML BREADTH_FIRST}~@{text "sat tac"} uses breadth-first - search to find states for which @{text "sat"} is true. For most + \<^descr> @{ML BREADTH_FIRST}~\sat tac\ uses breadth-first + search to find states for which \sat\ is true. For most applications, it is too slow. - \<^descr> @{ML BEST_FIRST}~@{text "(sat, dist) tac"} does a heuristic - search, using @{text "dist"} to estimate the distance from a - satisfactory state (in the sense of @{text "sat"}). It maintains a - list of states ordered by distance. It applies @{text "tac"} to the + \<^descr> @{ML BEST_FIRST}~\(sat, dist) tac\ does a heuristic + search, using \dist\ to estimate the distance from a + satisfactory state (in the sense of \sat\). It maintains a + list of states ordered by distance. It applies \tac\ to the head of this list; if the result contains any satisfactory states, then it returns them. Otherwise, @{ML BEST_FIRST} adds the new states to the list, and continues. @@ -822,9 +799,9 @@ the size of the state. The smaller the state, the fewer and simpler subgoals it has. - \<^descr> @{ML THEN_BEST_FIRST}~@{text "tac\<^sub>0 (sat, dist) tac"} is like + \<^descr> @{ML THEN_BEST_FIRST}~\tac\<^sub>0 (sat, dist) tac\ is like @{ML BEST_FIRST}, except that the priority queue initially contains - the result of applying @{text "tac\<^sub>0"} to the goal state. This + the result of applying \tac\<^sub>0\ to the goal state. This tactical permits separate tactics for starting the search and continuing the search. \ @@ -840,22 +817,22 @@ @{index_ML DETERM: "tactic -> tactic"} \\ \end{mldecls} - \<^descr> @{ML COND}~@{text "sat tac\<^sub>1 tac\<^sub>2"} applies @{text "tac\<^sub>1"} to - the goal state if it satisfies predicate @{text "sat"}, and applies - @{text "tac\<^sub>2"}. It is a conditional tactical in that only one of - @{text "tac\<^sub>1"} and @{text "tac\<^sub>2"} is applied to a goal state. - However, both @{text "tac\<^sub>1"} and @{text "tac\<^sub>2"} are evaluated + \<^descr> @{ML COND}~\sat tac\<^sub>1 tac\<^sub>2\ applies \tac\<^sub>1\ to + the goal state if it satisfies predicate \sat\, and applies + \tac\<^sub>2\. It is a conditional tactical in that only one of + \tac\<^sub>1\ and \tac\<^sub>2\ is applied to a goal state. + However, both \tac\<^sub>1\ and \tac\<^sub>2\ are evaluated because ML uses eager evaluation. - \<^descr> @{ML IF_UNSOLVED}~@{text "tac"} applies @{text "tac"} to the + \<^descr> @{ML IF_UNSOLVED}~\tac\ applies \tac\ to the goal state if it has any subgoals, and simply returns the goal state otherwise. Many common tactics, such as @{ML resolve_tac}, fail if applied to a goal state that has no subgoals. - \<^descr> @{ML SOLVE}~@{text "tac"} applies @{text "tac"} to the goal + \<^descr> @{ML SOLVE}~\tac\ applies \tac\ to the goal state and then fails iff there are subgoals left. - \<^descr> @{ML DETERM}~@{text "tac"} applies @{text "tac"} to the goal + \<^descr> @{ML DETERM}~\tac\ applies \tac\ to the goal state and returns the head of the resulting sequence. @{ML DETERM} limits the search space by making its argument deterministic. \ @@ -871,20 +848,17 @@ @{index_ML size_of_thm: "thm -> int"} \\ \end{mldecls} - \<^descr> @{ML has_fewer_prems}~@{text "n thm"} reports whether @{text - "thm"} has fewer than @{text "n"} premises. + \<^descr> @{ML has_fewer_prems}~\n thm\ reports whether \thm\ has fewer than \n\ premises. - \<^descr> @{ML Thm.eq_thm}~@{text "(thm\<^sub>1, thm\<^sub>2)"} reports whether @{text - "thm\<^sub>1"} and @{text "thm\<^sub>2"} are equal. Both theorems must have the + \<^descr> @{ML Thm.eq_thm}~\(thm\<^sub>1, thm\<^sub>2)\ reports whether \thm\<^sub>1\ and \thm\<^sub>2\ are equal. Both theorems must have the same conclusions, the same set of hypotheses, and the same set of sort hypotheses. Names of bound variables are ignored as usual. - \<^descr> @{ML Thm.eq_thm_prop}~@{text "(thm\<^sub>1, thm\<^sub>2)"} reports whether - the propositions of @{text "thm\<^sub>1"} and @{text "thm\<^sub>2"} are equal. + \<^descr> @{ML Thm.eq_thm_prop}~\(thm\<^sub>1, thm\<^sub>2)\ reports whether + the propositions of \thm\<^sub>1\ and \thm\<^sub>2\ are equal. Names of bound variables are ignored. - \<^descr> @{ML size_of_thm}~@{text "thm"} computes the size of @{text - "thm"}, namely the number of variables, constants and abstractions + \<^descr> @{ML size_of_thm}~\thm\ computes the size of \thm\, namely the number of variables, constants and abstractions in its conclusion. It may serve as a distance function for @{ML BEST_FIRST}. \