doc-src/IsarImplementation/Thy/Tactic.thy
author Walther Neuper <neuper@ist.tugraz.at>
Thu, 12 Aug 2010 15:03:34 +0200
branchisac-from-Isabelle2009-2
changeset 37913 20e3616b2d9c
parent 34997 f3bce1cc513c
child 40286 da8c3fc5e314
permissions -rw-r--r--
prepare reactivation of isac-update-Isa09-2
wenzelm@30081
     1
theory Tactic
wenzelm@30081
     2
imports Base
wenzelm@30081
     3
begin
wenzelm@18537
     4
wenzelm@20452
     5
chapter {* Tactical reasoning *}
wenzelm@18537
     6
wenzelm@34997
     7
text {* Tactical reasoning works by refining an initial claim in a
wenzelm@20474
     8
  backwards fashion, until a solved form is reached.  A @{text "goal"}
wenzelm@20474
     9
  consists of several subgoals that need to be solved in order to
wenzelm@20474
    10
  achieve the main statement; zero subgoals means that the proof may
wenzelm@20474
    11
  be finished.  A @{text "tactic"} is a refinement operation that maps
wenzelm@20474
    12
  a goal to a lazy sequence of potential successors.  A @{text
wenzelm@34997
    13
  "tactical"} is a combinator for composing tactics.  *}
wenzelm@18537
    14
wenzelm@18537
    15
wenzelm@18537
    16
section {* Goals \label{sec:tactical-goals} *}
wenzelm@18537
    17
wenzelm@20451
    18
text {*
wenzelm@30084
    19
  Isabelle/Pure represents a goal as a theorem stating that the
wenzelm@30084
    20
  subgoals imply the main goal: @{text "A\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^sub>n \<Longrightarrow>
wenzelm@30084
    21
  C"}.  The outermost goal structure is that of a Horn Clause: i.e.\
wenzelm@30084
    22
  an iterated implication without any quantifiers\footnote{Recall that
wenzelm@30084
    23
  outermost @{text "\<And>x. \<phi>[x]"} is always represented via schematic
wenzelm@30084
    24
  variables in the body: @{text "\<phi>[?x]"}.  These variables may get
wenzelm@30084
    25
  instantiated during the course of reasoning.}.  For @{text "n = 0"}
wenzelm@30084
    26
  a goal is called ``solved''.
wenzelm@18537
    27
wenzelm@30087
    28
  The structure of each subgoal @{text "A\<^sub>i"} is that of a
wenzelm@30087
    29
  general Hereditary Harrop Formula @{text "\<And>x\<^sub>1 \<dots>
wenzelm@30087
    30
  \<And>x\<^sub>k. H\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> H\<^sub>m \<Longrightarrow> B"}.  Here @{text
wenzelm@30087
    31
  "x\<^sub>1, \<dots>, x\<^sub>k"} are goal parameters, i.e.\
wenzelm@30087
    32
  arbitrary-but-fixed entities of certain types, and @{text
wenzelm@30087
    33
  "H\<^sub>1, \<dots>, H\<^sub>m"} are goal hypotheses, i.e.\ facts that may
wenzelm@30087
    34
  be assumed locally.  Together, this forms the goal context of the
wenzelm@30087
    35
  conclusion @{text B} to be established.  The goal hypotheses may be
wenzelm@30087
    36
  again arbitrary Hereditary Harrop Formulas, although the level of
wenzelm@30087
    37
  nesting rarely exceeds 1--2 in practice.
wenzelm@18537
    38
wenzelm@20451
    39
  The main conclusion @{text C} is internally marked as a protected
wenzelm@30084
    40
  proposition, which is represented explicitly by the notation @{text
wenzelm@34997
    41
  "#C"} here.  This ensures that the decomposition into subgoals and
wenzelm@34997
    42
  main conclusion is well-defined for arbitrarily structured claims.
wenzelm@18537
    43
wenzelm@20451
    44
  \medskip Basic goal management is performed via the following
wenzelm@20451
    45
  Isabelle/Pure rules:
wenzelm@18537
    46
wenzelm@18537
    47
  \[
wenzelm@18537
    48
  \infer[@{text "(init)"}]{@{text "C \<Longrightarrow> #C"}}{} \qquad
wenzelm@20547
    49
  \infer[@{text "(finish)"}]{@{text "C"}}{@{text "#C"}}
wenzelm@18537
    50
  \]
wenzelm@18537
    51
wenzelm@18537
    52
  \medskip The following low-level variants admit general reasoning
wenzelm@18537
    53
  with protected propositions:
wenzelm@18537
    54
wenzelm@18537
    55
  \[
wenzelm@18537
    56
  \infer[@{text "(protect)"}]{@{text "#C"}}{@{text "C"}} \qquad
wenzelm@18537
    57
  \infer[@{text "(conclude)"}]{@{text "A\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^sub>n \<Longrightarrow> C"}}{@{text "A\<^sub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^sub>n \<Longrightarrow> #C"}}
wenzelm@18537
    58
  \]
wenzelm@18537
    59
*}
wenzelm@18537
    60
wenzelm@18537
    61
text %mlref {*
wenzelm@18537
    62
  \begin{mldecls}
wenzelm@18537
    63
  @{index_ML Goal.init: "cterm -> thm"} \\
wenzelm@32207
    64
  @{index_ML Goal.finish: "Proof.context -> thm -> thm"} \\
wenzelm@18537
    65
  @{index_ML Goal.protect: "thm -> thm"} \\
wenzelm@18537
    66
  @{index_ML Goal.conclude: "thm -> thm"} \\
wenzelm@18537
    67
  \end{mldecls}
wenzelm@18537
    68
wenzelm@18537
    69
  \begin{description}
wenzelm@18537
    70
wenzelm@20474
    71
  \item @{ML "Goal.init"}~@{text C} initializes a tactical goal from
wenzelm@20474
    72
  the well-formed proposition @{text C}.
wenzelm@18537
    73
wenzelm@32207
    74
  \item @{ML "Goal.finish"}~@{text "ctxt thm"} checks whether theorem
wenzelm@20474
    75
  @{text "thm"} is a solved goal (no subgoals), and concludes the
wenzelm@32207
    76
  result by removing the goal protection.  The context is only
wenzelm@32207
    77
  required for printing error messages.
wenzelm@18537
    78
wenzelm@20474
    79
  \item @{ML "Goal.protect"}~@{text "thm"} protects the full statement
wenzelm@20474
    80
  of theorem @{text "thm"}.
wenzelm@18537
    81
wenzelm@20474
    82
  \item @{ML "Goal.conclude"}~@{text "thm"} removes the goal
wenzelm@20474
    83
  protection, even if there are pending subgoals.
wenzelm@18537
    84
wenzelm@18537
    85
  \end{description}
wenzelm@18537
    86
*}
wenzelm@18537
    87
wenzelm@18537
    88
wenzelm@18537
    89
section {* Tactics *}
wenzelm@18537
    90
wenzelm@28781
    91
text {* A @{text "tactic"} is a function @{text "goal \<rightarrow> goal\<^sup>*\<^sup>*"} that
wenzelm@28781
    92
  maps a given goal state (represented as a theorem, cf.\
wenzelm@28781
    93
  \secref{sec:tactical-goals}) to a lazy sequence of potential
wenzelm@28781
    94
  successor states.  The underlying sequence implementation is lazy
wenzelm@28781
    95
  both in head and tail, and is purely functional in \emph{not}
wenzelm@28781
    96
  supporting memoing.\footnote{The lack of memoing and the strict
wenzelm@28781
    97
  nature of SML requires some care when working with low-level
wenzelm@28781
    98
  sequence operations, to avoid duplicate or premature evaluation of
wenzelm@34997
    99
  results.  It also means that modified runtime behavior, such as
wenzelm@34997
   100
  timeout, is very hard to achieve for general tactics.}
wenzelm@18537
   101
wenzelm@28781
   102
  An \emph{empty result sequence} means that the tactic has failed: in
wenzelm@34997
   103
  a compound tactic expression other tactics might be tried instead,
wenzelm@28781
   104
  or the whole refinement step might fail outright, producing a
wenzelm@34997
   105
  toplevel error message in the end.  When implementing tactics from
wenzelm@34997
   106
  scratch, one should take care to observe the basic protocol of
wenzelm@34997
   107
  mapping regular error conditions to an empty result; only serious
wenzelm@34997
   108
  faults should emerge as exceptions.
wenzelm@18537
   109
wenzelm@28781
   110
  By enumerating \emph{multiple results}, a tactic can easily express
wenzelm@28781
   111
  the potential outcome of an internal search process.  There are also
wenzelm@28781
   112
  combinators for building proof tools that involve search
wenzelm@28781
   113
  systematically, see also \secref{sec:tacticals}.
wenzelm@18537
   114
wenzelm@34997
   115
  \medskip As explained before, a goal state essentially consists of a
wenzelm@34997
   116
  list of subgoals that imply the main goal (conclusion).  Tactics may
wenzelm@34997
   117
  operate on all subgoals or on a particularly specified subgoal, but
wenzelm@34997
   118
  must not change the main conclusion (apart from instantiating
wenzelm@34997
   119
  schematic goal variables).
wenzelm@18537
   120
wenzelm@28781
   121
  Tactics with explicit \emph{subgoal addressing} are of the form
wenzelm@28781
   122
  @{text "int \<rightarrow> tactic"} and may be applied to a particular subgoal
wenzelm@28781
   123
  (counting from 1).  If the subgoal number is out of range, the
wenzelm@28781
   124
  tactic should fail with an empty result sequence, but must not raise
wenzelm@28781
   125
  an exception!
wenzelm@28781
   126
wenzelm@28781
   127
  Operating on a particular subgoal means to replace it by an interval
wenzelm@28781
   128
  of zero or more subgoals in the same place; other subgoals must not
wenzelm@28781
   129
  be affected, apart from instantiating schematic variables ranging
wenzelm@28781
   130
  over the whole goal state.
wenzelm@28781
   131
wenzelm@28781
   132
  A common pattern of composing tactics with subgoal addressing is to
wenzelm@28781
   133
  try the first one, and then the second one only if the subgoal has
wenzelm@28781
   134
  not been solved yet.  Special care is required here to avoid bumping
wenzelm@28782
   135
  into unrelated subgoals that happen to come after the original
wenzelm@28782
   136
  subgoal.  Assuming that there is only a single initial subgoal is a
wenzelm@28782
   137
  very common error when implementing tactics!
wenzelm@28782
   138
wenzelm@28782
   139
  Tactics with internal subgoal addressing should expose the subgoal
wenzelm@28782
   140
  index as @{text "int"} argument in full generality; a hardwired
wenzelm@34997
   141
  subgoal 1 is not acceptable.
wenzelm@28781
   142
  
wenzelm@28781
   143
  \medskip The main well-formedness conditions for proper tactics are
wenzelm@28781
   144
  summarized as follows.
wenzelm@28781
   145
wenzelm@28781
   146
  \begin{itemize}
wenzelm@28781
   147
wenzelm@28781
   148
  \item General tactic failure is indicated by an empty result, only
wenzelm@28781
   149
  serious faults may produce an exception.
wenzelm@28781
   150
wenzelm@28781
   151
  \item The main conclusion must not be changed, apart from
wenzelm@28781
   152
  instantiating schematic variables.
wenzelm@28781
   153
wenzelm@28781
   154
  \item A tactic operates either uniformly on all subgoals, or
wenzelm@28781
   155
  specifically on a selected subgoal (without bumping into unrelated
wenzelm@28781
   156
  subgoals).
wenzelm@28781
   157
wenzelm@28781
   158
  \item Range errors in subgoal addressing produce an empty result.
wenzelm@28781
   159
wenzelm@28781
   160
  \end{itemize}
wenzelm@28782
   161
wenzelm@28782
   162
  Some of these conditions are checked by higher-level goal
wenzelm@34997
   163
  infrastructure (\secref{sec:struct-goals}); others are not checked
wenzelm@28782
   164
  explicitly, and violating them merely results in ill-behaved tactics
wenzelm@28782
   165
  experienced by the user (e.g.\ tactics that insist in being
wenzelm@34997
   166
  applicable only to singleton goals, or prevent composition via
wenzelm@34997
   167
  standard tacticals).
wenzelm@28782
   168
*}
wenzelm@28782
   169
wenzelm@28782
   170
text %mlref {*
wenzelm@28782
   171
  \begin{mldecls}
wenzelm@28782
   172
  @{index_ML_type tactic: "thm -> thm Seq.seq"} \\
wenzelm@28783
   173
  @{index_ML no_tac: tactic} \\
wenzelm@28783
   174
  @{index_ML all_tac: tactic} \\
wenzelm@28783
   175
  @{index_ML print_tac: "string -> tactic"} \\[1ex]
wenzelm@28783
   176
  @{index_ML PRIMITIVE: "(thm -> thm) -> tactic"} \\[1ex]
wenzelm@28782
   177
  @{index_ML SUBGOAL: "(term * int -> tactic) -> int -> tactic"} \\
wenzelm@28782
   178
  @{index_ML CSUBGOAL: "(cterm * int -> tactic) -> int -> tactic"} \\
wenzelm@28782
   179
  \end{mldecls}
wenzelm@28782
   180
wenzelm@28782
   181
  \begin{description}
wenzelm@28782
   182
wenzelm@28782
   183
  \item @{ML_type tactic} represents tactics.  The well-formedness
wenzelm@28782
   184
  conditions described above need to be observed.  See also @{"file"
wenzelm@28782
   185
  "~~/src/Pure/General/seq.ML"} for the underlying implementation of
wenzelm@28782
   186
  lazy sequences.
wenzelm@28782
   187
wenzelm@28782
   188
  \item @{ML_type "int -> tactic"} represents tactics with explicit
wenzelm@28782
   189
  subgoal addressing, with well-formedness conditions as described
wenzelm@28782
   190
  above.
wenzelm@28782
   191
wenzelm@28783
   192
  \item @{ML no_tac} is a tactic that always fails, returning the
wenzelm@28783
   193
  empty sequence.
wenzelm@28783
   194
wenzelm@28783
   195
  \item @{ML all_tac} is a tactic that always succeeds, returning a
wenzelm@28783
   196
  singleton sequence with unchanged goal state.
wenzelm@28783
   197
wenzelm@28783
   198
  \item @{ML print_tac}~@{text "message"} is like @{ML all_tac}, but
wenzelm@28783
   199
  prints a message together with the goal state on the tracing
wenzelm@28783
   200
  channel.
wenzelm@28783
   201
wenzelm@28782
   202
  \item @{ML PRIMITIVE}~@{text rule} turns a primitive inference rule
wenzelm@28782
   203
  into a tactic with unique result.  Exception @{ML THM} is considered
wenzelm@28782
   204
  a regular tactic failure and produces an empty result; other
wenzelm@28782
   205
  exceptions are passed through.
wenzelm@28782
   206
wenzelm@28782
   207
  \item @{ML SUBGOAL}~@{text "(fn (subgoal, i) => tactic)"} is the
wenzelm@28783
   208
  most basic form to produce a tactic with subgoal addressing.  The
wenzelm@28782
   209
  given abstraction over the subgoal term and subgoal number allows to
wenzelm@28782
   210
  peek at the relevant information of the full goal state.  The
wenzelm@28782
   211
  subgoal range is checked as required above.
wenzelm@28782
   212
wenzelm@28782
   213
  \item @{ML CSUBGOAL} is similar to @{ML SUBGOAL}, but passes the
wenzelm@28783
   214
  subgoal as @{ML_type cterm} instead of raw @{ML_type term}.  This
wenzelm@28782
   215
  avoids expensive re-certification in situations where the subgoal is
wenzelm@28782
   216
  used directly for primitive inferences.
wenzelm@28782
   217
wenzelm@28782
   218
  \end{description}
wenzelm@18537
   219
*}
wenzelm@18537
   220
wenzelm@28781
   221
wenzelm@28785
   222
subsection {* Resolution and assumption tactics \label{sec:resolve-assume-tac} *}
wenzelm@28783
   223
wenzelm@28783
   224
text {* \emph{Resolution} is the most basic mechanism for refining a
wenzelm@28783
   225
  subgoal using a theorem as object-level rule.
wenzelm@28783
   226
  \emph{Elim-resolution} is particularly suited for elimination rules:
wenzelm@28783
   227
  it resolves with a rule, proves its first premise by assumption, and
wenzelm@28783
   228
  finally deletes that assumption from any new subgoals.
wenzelm@28783
   229
  \emph{Destruct-resolution} is like elim-resolution, but the given
wenzelm@28783
   230
  destruction rules are first turned into canonical elimination
wenzelm@28783
   231
  format.  \emph{Forward-resolution} is like destruct-resolution, but
wenzelm@28785
   232
  without deleting the selected assumption.  The @{text "r/e/d/f"}
wenzelm@28785
   233
  naming convention is maintained for several different kinds of
wenzelm@28785
   234
  resolution rules and tactics.
wenzelm@28783
   235
wenzelm@28783
   236
  Assumption tactics close a subgoal by unifying some of its premises
wenzelm@28783
   237
  against its conclusion.
wenzelm@28783
   238
wenzelm@28783
   239
  \medskip All the tactics in this section operate on a subgoal
wenzelm@28783
   240
  designated by a positive integer.  Other subgoals might be affected
wenzelm@28783
   241
  indirectly, due to instantiation of schematic variables.
wenzelm@28783
   242
wenzelm@28783
   243
  There are various sources of non-determinism, the tactic result
wenzelm@28783
   244
  sequence enumerates all possibilities of the following choices (if
wenzelm@28783
   245
  applicable):
wenzelm@28783
   246
wenzelm@28783
   247
  \begin{enumerate}
wenzelm@28783
   248
wenzelm@28783
   249
  \item selecting one of the rules given as argument to the tactic;
wenzelm@28783
   250
wenzelm@28783
   251
  \item selecting a subgoal premise to eliminate, unifying it against
wenzelm@28783
   252
  the first premise of the rule;
wenzelm@28783
   253
wenzelm@28783
   254
  \item unifying the conclusion of the subgoal to the conclusion of
wenzelm@28783
   255
  the rule.
wenzelm@28783
   256
wenzelm@28783
   257
  \end{enumerate}
wenzelm@28783
   258
wenzelm@28783
   259
  Recall that higher-order unification may produce multiple results
wenzelm@28783
   260
  that are enumerated here.
wenzelm@28783
   261
*}
wenzelm@28783
   262
wenzelm@28783
   263
text %mlref {*
wenzelm@28783
   264
  \begin{mldecls}
wenzelm@28783
   265
  @{index_ML resolve_tac: "thm list -> int -> tactic"} \\
wenzelm@28783
   266
  @{index_ML eresolve_tac: "thm list -> int -> tactic"} \\
wenzelm@28783
   267
  @{index_ML dresolve_tac: "thm list -> int -> tactic"} \\
wenzelm@28783
   268
  @{index_ML forward_tac: "thm list -> int -> tactic"} \\[1ex]
wenzelm@28783
   269
  @{index_ML assume_tac: "int -> tactic"} \\
wenzelm@28783
   270
  @{index_ML eq_assume_tac: "int -> tactic"} \\[1ex]
wenzelm@28783
   271
  @{index_ML match_tac: "thm list -> int -> tactic"} \\
wenzelm@28783
   272
  @{index_ML ematch_tac: "thm list -> int -> tactic"} \\
wenzelm@28783
   273
  @{index_ML dmatch_tac: "thm list -> int -> tactic"} \\
wenzelm@28783
   274
  \end{mldecls}
wenzelm@28783
   275
wenzelm@28783
   276
  \begin{description}
wenzelm@28783
   277
wenzelm@28783
   278
  \item @{ML resolve_tac}~@{text "thms i"} refines the goal state
wenzelm@28783
   279
  using the given theorems, which should normally be introduction
wenzelm@28783
   280
  rules.  The tactic resolves a rule's conclusion with subgoal @{text
wenzelm@28783
   281
  i}, replacing it by the corresponding versions of the rule's
wenzelm@28783
   282
  premises.
wenzelm@28783
   283
wenzelm@28783
   284
  \item @{ML eresolve_tac}~@{text "thms i"} performs elim-resolution
wenzelm@28783
   285
  with the given theorems, which should normally be elimination rules.
wenzelm@28783
   286
wenzelm@28783
   287
  \item @{ML dresolve_tac}~@{text "thms i"} performs
wenzelm@28783
   288
  destruct-resolution with the given theorems, which should normally
wenzelm@28783
   289
  be destruction rules.  This replaces an assumption by the result of
wenzelm@28783
   290
  applying one of the rules.
wenzelm@28783
   291
wenzelm@28783
   292
  \item @{ML forward_tac} is like @{ML dresolve_tac} except that the
wenzelm@28783
   293
  selected assumption is not deleted.  It applies a rule to an
wenzelm@28783
   294
  assumption, adding the result as a new assumption.
wenzelm@28783
   295
wenzelm@28783
   296
  \item @{ML assume_tac}~@{text i} attempts to solve subgoal @{text i}
wenzelm@28783
   297
  by assumption (modulo higher-order unification).
wenzelm@28783
   298
wenzelm@28783
   299
  \item @{ML eq_assume_tac} is similar to @{ML assume_tac}, but checks
wenzelm@28783
   300
  only for immediate @{text "\<alpha>"}-convertibility instead of using
wenzelm@28783
   301
  unification.  It succeeds (with a unique next state) if one of the
wenzelm@28783
   302
  assumptions is equal to the subgoal's conclusion.  Since it does not
wenzelm@28783
   303
  instantiate variables, it cannot make other subgoals unprovable.
wenzelm@28783
   304
wenzelm@28783
   305
  \item @{ML match_tac}, @{ML ematch_tac}, and @{ML dmatch_tac} are
wenzelm@28783
   306
  similar to @{ML resolve_tac}, @{ML eresolve_tac}, and @{ML
wenzelm@28783
   307
  dresolve_tac}, respectively, but do not instantiate schematic
wenzelm@28783
   308
  variables in the goal state.
wenzelm@28783
   309
wenzelm@28783
   310
  Flexible subgoals are not updated at will, but are left alone.
wenzelm@28783
   311
  Strictly speaking, matching means to treat the unknowns in the goal
wenzelm@28783
   312
  state as constants; these tactics merely discard unifiers that would
wenzelm@28783
   313
  update the goal state.
wenzelm@28783
   314
wenzelm@28783
   315
  \end{description}
wenzelm@28783
   316
*}
wenzelm@28783
   317
wenzelm@28783
   318
wenzelm@28785
   319
subsection {* Explicit instantiation within a subgoal context *}
wenzelm@28785
   320
wenzelm@28785
   321
text {* The main resolution tactics (\secref{sec:resolve-assume-tac})
wenzelm@28785
   322
  use higher-order unification, which works well in many practical
wenzelm@28785
   323
  situations despite its daunting theoretical properties.
wenzelm@28785
   324
  Nonetheless, there are important problem classes where unguided
wenzelm@28785
   325
  higher-order unification is not so useful.  This typically involves
wenzelm@28785
   326
  rules like universal elimination, existential introduction, or
wenzelm@28785
   327
  equational substitution.  Here the unification problem involves
wenzelm@28785
   328
  fully flexible @{text "?P ?x"} schemes, which are hard to manage
wenzelm@28785
   329
  without further hints.
wenzelm@28785
   330
wenzelm@28785
   331
  By providing a (small) rigid term for @{text "?x"} explicitly, the
wenzelm@28785
   332
  remaining unification problem is to assign a (large) term to @{text
wenzelm@28785
   333
  "?P"}, according to the shape of the given subgoal.  This is
wenzelm@28785
   334
  sufficiently well-behaved in most practical situations.
wenzelm@28785
   335
wenzelm@28785
   336
  \medskip Isabelle provides separate versions of the standard @{text
wenzelm@28785
   337
  "r/e/d/f"} resolution tactics that allow to provide explicit
wenzelm@28785
   338
  instantiations of unknowns of the given rule, wrt.\ terms that refer
wenzelm@28785
   339
  to the implicit context of the selected subgoal.
wenzelm@28785
   340
wenzelm@28785
   341
  An instantiation consists of a list of pairs of the form @{text
wenzelm@28785
   342
  "(?x, t)"}, where @{text ?x} is a schematic variable occurring in
wenzelm@28785
   343
  the given rule, and @{text t} is a term from the current proof
wenzelm@28785
   344
  context, augmented by the local goal parameters of the selected
wenzelm@28785
   345
  subgoal; cf.\ the @{text "focus"} operation described in
wenzelm@28785
   346
  \secref{sec:variables}.
wenzelm@28785
   347
wenzelm@28785
   348
  Entering the syntactic context of a subgoal is a brittle operation,
wenzelm@28785
   349
  because its exact form is somewhat accidental, and the choice of
wenzelm@28785
   350
  bound variable names depends on the presence of other local and
wenzelm@28785
   351
  global names.  Explicit renaming of subgoal parameters prior to
wenzelm@28785
   352
  explicit instantiation might help to achieve a bit more robustness.
wenzelm@28785
   353
wenzelm@28785
   354
  Type instantiations may be given as well, via pairs like @{text
wenzelm@28785
   355
  "(?'a, \<tau>)"}.  Type instantiations are distinguished from term
wenzelm@28785
   356
  instantiations by the syntactic form of the schematic variable.
wenzelm@28785
   357
  Types are instantiated before terms are.  Since term instantiation
wenzelm@34997
   358
  already performs simple type-inference, so explicit type
wenzelm@28785
   359
  instantiations are seldom necessary.
wenzelm@28785
   360
*}
wenzelm@28785
   361
wenzelm@28785
   362
text %mlref {*
wenzelm@28785
   363
  \begin{mldecls}
wenzelm@28785
   364
  @{index_ML res_inst_tac: "Proof.context -> (indexname * string) list -> thm -> int -> tactic"} \\
wenzelm@28785
   365
  @{index_ML eres_inst_tac: "Proof.context -> (indexname * string) list -> thm -> int -> tactic"} \\
wenzelm@28785
   366
  @{index_ML dres_inst_tac: "Proof.context -> (indexname * string) list -> thm -> int -> tactic"} \\
wenzelm@28785
   367
  @{index_ML forw_inst_tac: "Proof.context -> (indexname * string) list -> thm -> int -> tactic"} \\[1ex]
wenzelm@28785
   368
  @{index_ML rename_tac: "string list -> int -> tactic"} \\
wenzelm@28785
   369
  \end{mldecls}
wenzelm@28785
   370
wenzelm@28785
   371
  \begin{description}
wenzelm@28785
   372
wenzelm@28785
   373
  \item @{ML res_inst_tac}~@{text "ctxt insts thm i"} instantiates the
wenzelm@28785
   374
  rule @{text thm} with the instantiations @{text insts}, as described
wenzelm@28785
   375
  above, and then performs resolution on subgoal @{text i}.
wenzelm@28785
   376
  
wenzelm@28785
   377
  \item @{ML eres_inst_tac} is like @{ML res_inst_tac}, but performs
wenzelm@28785
   378
  elim-resolution.
wenzelm@28785
   379
wenzelm@28785
   380
  \item @{ML dres_inst_tac} is like @{ML res_inst_tac}, but performs
wenzelm@28785
   381
  destruct-resolution.
wenzelm@28785
   382
wenzelm@28785
   383
  \item @{ML forw_inst_tac} is like @{ML dres_inst_tac} except that
wenzelm@28785
   384
  the selected assumption is not deleted.
wenzelm@28785
   385
wenzelm@28785
   386
  \item @{ML rename_tac}~@{text "names i"} renames the innermost
wenzelm@28785
   387
  parameters of subgoal @{text i} according to the provided @{text
wenzelm@28785
   388
  names} (which need to be distinct indentifiers).
wenzelm@28785
   389
wenzelm@28785
   390
  \end{description}
wenzelm@34997
   391
wenzelm@34997
   392
  For historical reasons, the above instantiation tactics take
wenzelm@34997
   393
  unparsed string arguments, which makes them hard to use in general
wenzelm@34997
   394
  ML code.  The slightly more advanced @{ML Subgoal.FOCUS} combinator
wenzelm@34997
   395
  of \secref{sec:struct-goals} allows to refer to internal goal
wenzelm@34997
   396
  structure with explicit context management.
wenzelm@28785
   397
*}
wenzelm@28785
   398
wenzelm@28785
   399
wenzelm@28781
   400
section {* Tacticals \label{sec:tacticals} *}
wenzelm@18537
   401
wenzelm@18537
   402
text {*
wenzelm@30084
   403
  A \emph{tactical} is a functional combinator for building up complex
wenzelm@30084
   404
  tactics from simpler ones.  Typical tactical perform sequential
wenzelm@30084
   405
  composition, disjunction (choice), iteration, or goal addressing.
wenzelm@30084
   406
  Various search strategies may be expressed via tacticals.
wenzelm@18537
   407
wenzelm@30084
   408
  \medskip FIXME
wenzelm@18537
   409
*}
wenzelm@30273
   410
wenzelm@18537
   411
end