doc-src/Ref/tactic.tex
author lcp
Mon, 11 Jul 1994 17:38:10 +0200
changeset 457 8577bc1c4e1b
parent 332 01b87a921967
child 1212 7059356e18e0
permissions -rw-r--r--
documented subgoals_tac
lcp@104
     1
%% $Id$
lcp@104
     2
\chapter{Tactics} \label{tactics}
lcp@104
     3
\index{tactics|(}
lcp@323
     4
Tactics have type \mltydx{tactic}.  They are essentially
lcp@104
     5
functions from theorems to theorem sequences, where the theorems represent
lcp@104
     6
states of a backward proof.  Tactics seldom need to be coded from scratch,
lcp@323
     7
as functions; instead they are expressed using basic tactics and tacticals.
lcp@104
     8
lcp@104
     9
\section{Resolution and assumption tactics}
lcp@104
    10
{\bf Resolution} is Isabelle's basic mechanism for refining a subgoal using
lcp@104
    11
a rule.  {\bf Elim-resolution} is particularly suited for elimination
lcp@104
    12
rules, while {\bf destruct-resolution} is particularly suited for
lcp@104
    13
destruction rules.  The {\tt r}, {\tt e}, {\tt d} naming convention is
lcp@104
    14
maintained for several different kinds of resolution tactics, as well as
lcp@104
    15
the shortcuts in the subgoal module.
lcp@104
    16
lcp@104
    17
All the tactics in this section act on a subgoal designated by a positive
lcp@104
    18
integer~$i$.  They fail (by returning the empty sequence) if~$i$ is out of
lcp@104
    19
range.
lcp@104
    20
lcp@104
    21
\subsection{Resolution tactics}
lcp@323
    22
\index{resolution!tactics}
lcp@104
    23
\index{tactics!resolution|bold}
lcp@104
    24
\begin{ttbox} 
lcp@104
    25
resolve_tac  : thm list -> int -> tactic
lcp@104
    26
eresolve_tac : thm list -> int -> tactic
lcp@104
    27
dresolve_tac : thm list -> int -> tactic
lcp@104
    28
forward_tac  : thm list -> int -> tactic 
lcp@104
    29
\end{ttbox}
lcp@104
    30
These perform resolution on a list of theorems, $thms$, representing a list
lcp@104
    31
of object-rules.  When generating next states, they take each of the rules
lcp@104
    32
in the order given.  Each rule may yield several next states, or none:
lcp@104
    33
higher-order resolution may yield multiple resolvents.
lcp@323
    34
\begin{ttdescription}
lcp@104
    35
\item[\ttindexbold{resolve_tac} {\it thms} {\it i}] 
lcp@323
    36
  refines the proof state using the rules, which should normally be
lcp@323
    37
  introduction rules.  It resolves a rule's conclusion with
lcp@323
    38
  subgoal~$i$ of the proof state.
lcp@104
    39
lcp@104
    40
\item[\ttindexbold{eresolve_tac} {\it thms} {\it i}] 
lcp@323
    41
  \index{elim-resolution}
lcp@323
    42
  performs elim-resolution with the rules, which should normally be
lcp@323
    43
  elimination rules.  It resolves with a rule, solves its first premise by
lcp@323
    44
  assumption, and finally {\em deletes\/} that assumption from any new
lcp@323
    45
  subgoals.
lcp@104
    46
lcp@104
    47
\item[\ttindexbold{dresolve_tac} {\it thms} {\it i}] 
lcp@323
    48
  \index{forward proof}\index{destruct-resolution}
lcp@323
    49
  performs destruct-resolution with the rules, which normally should
lcp@323
    50
  be destruction rules.  This replaces an assumption by the result of
lcp@323
    51
  applying one of the rules.
lcp@104
    52
lcp@323
    53
\item[\ttindexbold{forward_tac}]\index{forward proof}
lcp@323
    54
  is like {\tt dresolve_tac} except that the selected assumption is not
lcp@323
    55
  deleted.  It applies a rule to an assumption, adding the result as a new
lcp@323
    56
  assumption.
lcp@323
    57
\end{ttdescription}
lcp@104
    58
lcp@104
    59
\subsection{Assumption tactics}
lcp@323
    60
\index{tactics!assumption|bold}\index{assumptions!tactics for}
lcp@104
    61
\begin{ttbox} 
lcp@104
    62
assume_tac    : int -> tactic
lcp@104
    63
eq_assume_tac : int -> tactic
lcp@104
    64
\end{ttbox} 
lcp@323
    65
\begin{ttdescription}
lcp@104
    66
\item[\ttindexbold{assume_tac} {\it i}] 
lcp@104
    67
attempts to solve subgoal~$i$ by assumption.
lcp@104
    68
lcp@104
    69
\item[\ttindexbold{eq_assume_tac}] 
lcp@104
    70
is like {\tt assume_tac} but does not use unification.  It succeeds (with a
lcp@323
    71
{\em unique\/} next state) if one of the assumptions is identical to the
lcp@104
    72
subgoal's conclusion.  Since it does not instantiate variables, it cannot
lcp@104
    73
make other subgoals unprovable.  It is intended to be called from proof
lcp@104
    74
strategies, not interactively.
lcp@323
    75
\end{ttdescription}
lcp@104
    76
lcp@104
    77
\subsection{Matching tactics} \label{match_tac}
lcp@323
    78
\index{tactics!matching}
lcp@104
    79
\begin{ttbox} 
lcp@104
    80
match_tac  : thm list -> int -> tactic
lcp@104
    81
ematch_tac : thm list -> int -> tactic
lcp@104
    82
dmatch_tac : thm list -> int -> tactic
lcp@104
    83
\end{ttbox}
lcp@104
    84
These are just like the resolution tactics except that they never
lcp@104
    85
instantiate unknowns in the proof state.  Flexible subgoals are not updated
lcp@104
    86
willy-nilly, but are left alone.  Matching --- strictly speaking --- means
lcp@104
    87
treating the unknowns in the proof state as constants; these tactics merely
lcp@104
    88
discard unifiers that would update the proof state.
lcp@323
    89
\begin{ttdescription}
lcp@104
    90
\item[\ttindexbold{match_tac} {\it thms} {\it i}] 
lcp@323
    91
refines the proof state using the rules, matching a rule's
lcp@104
    92
conclusion with subgoal~$i$ of the proof state.
lcp@104
    93
lcp@104
    94
\item[\ttindexbold{ematch_tac}] 
lcp@104
    95
is like {\tt match_tac}, but performs elim-resolution.
lcp@104
    96
lcp@104
    97
\item[\ttindexbold{dmatch_tac}] 
lcp@104
    98
is like {\tt match_tac}, but performs destruct-resolution.
lcp@323
    99
\end{ttdescription}
lcp@104
   100
lcp@104
   101
lcp@104
   102
\subsection{Resolution with instantiation} \label{res_inst_tac}
lcp@323
   103
\index{tactics!instantiation}\index{instantiation}
lcp@104
   104
\begin{ttbox} 
lcp@104
   105
res_inst_tac  : (string*string)list -> thm -> int -> tactic
lcp@104
   106
eres_inst_tac : (string*string)list -> thm -> int -> tactic
lcp@104
   107
dres_inst_tac : (string*string)list -> thm -> int -> tactic
lcp@104
   108
forw_inst_tac : (string*string)list -> thm -> int -> tactic
lcp@104
   109
\end{ttbox}
lcp@104
   110
These tactics are designed for applying rules such as substitution and
lcp@104
   111
induction, which cause difficulties for higher-order unification.  The
lcp@332
   112
tactics accept explicit instantiations for unknowns in the rule ---
lcp@332
   113
typically, in the rule's conclusion.  Each instantiation is a pair
lcp@332
   114
{\tt($v$,$e$)}, where $v$ is an unknown {\em without\/} its leading
lcp@332
   115
question mark!
lcp@104
   116
\begin{itemize}
lcp@332
   117
\item If $v$ is the type unknown {\tt'a}, then
lcp@332
   118
the rule must contain a type unknown \verb$?'a$ of some
lcp@104
   119
sort~$s$, and $e$ should be a type of sort $s$.
lcp@104
   120
lcp@332
   121
\item If $v$ is the unknown {\tt P}, then
lcp@332
   122
the rule must contain an unknown \verb$?P$ of some type~$\tau$,
lcp@104
   123
and $e$ should be a term of some type~$\sigma$ such that $\tau$ and
lcp@104
   124
$\sigma$ are unifiable.  If the unification of $\tau$ and $\sigma$
lcp@332
   125
instantiates any type unknowns in $\tau$, these instantiations
lcp@104
   126
are recorded for application to the rule.
lcp@104
   127
\end{itemize}
lcp@104
   128
Types are instantiated before terms.  Because type instantiations are
lcp@104
   129
inferred from term instantiations, explicit type instantiations are seldom
lcp@104
   130
necessary --- if \verb$?t$ has type \verb$?'a$, then the instantiation list
lcp@104
   131
\verb$[("'a","bool"),("t","True")]$ may be simplified to
lcp@104
   132
\verb$[("t","True")]$.  Type unknowns in the proof state may cause
lcp@104
   133
failure because the tactics cannot instantiate them.
lcp@104
   134
lcp@104
   135
The instantiation tactics act on a given subgoal.  Terms in the
lcp@104
   136
instantiations are type-checked in the context of that subgoal --- in
lcp@104
   137
particular, they may refer to that subgoal's parameters.  Any unknowns in
lcp@104
   138
the terms receive subscripts and are lifted over the parameters; thus, you
lcp@104
   139
may not refer to unknowns in the subgoal.
lcp@104
   140
lcp@323
   141
\begin{ttdescription}
lcp@104
   142
\item[\ttindexbold{res_inst_tac} {\it insts} {\it thm} {\it i}]
lcp@104
   143
instantiates the rule {\it thm} with the instantiations {\it insts}, as
lcp@104
   144
described above, and then performs resolution on subgoal~$i$.  Resolution
lcp@104
   145
typically causes further instantiations; you need not give explicit
lcp@332
   146
instantiations for every unknown in the rule.
lcp@104
   147
lcp@104
   148
\item[\ttindexbold{eres_inst_tac}] 
lcp@104
   149
is like {\tt res_inst_tac}, but performs elim-resolution.
lcp@104
   150
lcp@104
   151
\item[\ttindexbold{dres_inst_tac}] 
lcp@104
   152
is like {\tt res_inst_tac}, but performs destruct-resolution.
lcp@104
   153
lcp@104
   154
\item[\ttindexbold{forw_inst_tac}] 
lcp@104
   155
is like {\tt dres_inst_tac} except that the selected assumption is not
lcp@104
   156
deleted.  It applies the instantiated rule to an assumption, adding the
lcp@104
   157
result as a new assumption.
lcp@323
   158
\end{ttdescription}
lcp@104
   159
lcp@104
   160
lcp@104
   161
\section{Other basic tactics}
lcp@104
   162
\subsection{Definitions and meta-level rewriting}
lcp@323
   163
\index{tactics!meta-rewriting|bold}\index{meta-rewriting|bold}
lcp@323
   164
\index{definitions}
lcp@323
   165
lcp@332
   166
Definitions in Isabelle have the form $t\equiv u$, where $t$ is typically a
lcp@104
   167
constant or a constant applied to a list of variables, for example $\it
lcp@104
   168
sqr(n)\equiv n\times n$.  (Conditional definitions, $\phi\Imp t\equiv u$,
lcp@332
   169
are not supported.)  {\bf Unfolding} the definition ${t\equiv u}$ means using
lcp@104
   170
it as a rewrite rule, replacing~$t$ by~$u$ throughout a theorem.  {\bf
lcp@104
   171
Folding} $t\equiv u$ means replacing~$u$ by~$t$.  Rewriting continues until
lcp@104
   172
no rewrites are applicable to any subterm.
lcp@104
   173
lcp@104
   174
There are rules for unfolding and folding definitions; Isabelle does not do
lcp@104
   175
this automatically.  The corresponding tactics rewrite the proof state,
lcp@332
   176
yielding a single next state.  See also the {\tt goalw} command, which is the
lcp@104
   177
easiest way of handling definitions.
lcp@104
   178
\begin{ttbox} 
lcp@104
   179
rewrite_goals_tac : thm list -> tactic
lcp@104
   180
rewrite_tac       : thm list -> tactic
lcp@104
   181
fold_goals_tac    : thm list -> tactic
lcp@104
   182
fold_tac          : thm list -> tactic
lcp@104
   183
\end{ttbox}
lcp@323
   184
\begin{ttdescription}
lcp@104
   185
\item[\ttindexbold{rewrite_goals_tac} {\it defs}]  
lcp@104
   186
unfolds the {\it defs} throughout the subgoals of the proof state, while
lcp@104
   187
leaving the main goal unchanged.  Use \ttindex{SELECT_GOAL} to restrict it to a
lcp@104
   188
particular subgoal.
lcp@104
   189
lcp@104
   190
\item[\ttindexbold{rewrite_tac} {\it defs}]  
lcp@104
   191
unfolds the {\it defs} throughout the proof state, including the main goal
lcp@104
   192
--- not normally desirable!
lcp@104
   193
lcp@104
   194
\item[\ttindexbold{fold_goals_tac} {\it defs}]  
lcp@104
   195
folds the {\it defs} throughout the subgoals of the proof state, while
lcp@104
   196
leaving the main goal unchanged.
lcp@104
   197
lcp@104
   198
\item[\ttindexbold{fold_tac} {\it defs}]  
lcp@104
   199
folds the {\it defs} throughout the proof state.
lcp@323
   200
\end{ttdescription}
lcp@104
   201
lcp@104
   202
lcp@104
   203
\subsection{Tactic shortcuts}
lcp@323
   204
\index{shortcuts!for tactics}
lcp@104
   205
\index{tactics!resolution}\index{tactics!assumption}
lcp@104
   206
\index{tactics!meta-rewriting}
lcp@104
   207
\begin{ttbox} 
lcp@332
   208
rtac     :      thm -> int -> tactic
lcp@332
   209
etac     :      thm -> int -> tactic
lcp@332
   210
dtac     :      thm -> int -> tactic
lcp@332
   211
atac     :             int -> tactic
lcp@104
   212
ares_tac : thm list -> int -> tactic
lcp@332
   213
rewtac   :      thm ->        tactic
lcp@104
   214
\end{ttbox}
lcp@104
   215
These abbreviate common uses of tactics.
lcp@323
   216
\begin{ttdescription}
lcp@104
   217
\item[\ttindexbold{rtac} {\it thm} {\it i}] 
lcp@104
   218
abbreviates \hbox{\tt resolve_tac [{\it thm}] {\it i}}, doing resolution.
lcp@104
   219
lcp@104
   220
\item[\ttindexbold{etac} {\it thm} {\it i}] 
lcp@104
   221
abbreviates \hbox{\tt eresolve_tac [{\it thm}] {\it i}}, doing elim-resolution.
lcp@104
   222
lcp@104
   223
\item[\ttindexbold{dtac} {\it thm} {\it i}] 
lcp@104
   224
abbreviates \hbox{\tt dresolve_tac [{\it thm}] {\it i}}, doing
lcp@104
   225
destruct-resolution.
lcp@104
   226
lcp@104
   227
\item[\ttindexbold{atac} {\it i}] 
lcp@332
   228
abbreviates \hbox{\tt assume_tac {\it i}}, doing proof by assumption.
lcp@104
   229
lcp@104
   230
\item[\ttindexbold{ares_tac} {\it thms} {\it i}] 
lcp@104
   231
tries proof by assumption and resolution; it abbreviates
lcp@104
   232
\begin{ttbox}
lcp@104
   233
assume_tac {\it i} ORELSE resolve_tac {\it thms} {\it i}
lcp@104
   234
\end{ttbox}
lcp@104
   235
lcp@104
   236
\item[\ttindexbold{rewtac} {\it def}] 
lcp@104
   237
abbreviates \hbox{\tt rewrite_goals_tac [{\it def}]}, unfolding a definition.
lcp@323
   238
\end{ttdescription}
lcp@104
   239
lcp@104
   240
lcp@104
   241
\subsection{Inserting premises and facts}\label{cut_facts_tac}
lcp@323
   242
\index{tactics!for inserting facts}\index{assumptions!inserting}
lcp@104
   243
\begin{ttbox} 
lcp@104
   244
cut_facts_tac : thm list -> int -> tactic
lcp@286
   245
cut_inst_tac  : (string*string)list -> thm -> int -> tactic
lcp@286
   246
subgoal_tac   : string -> int -> tactic
lcp@457
   247
subgoal_tacs  : string list -> int -> tactic
lcp@104
   248
\end{ttbox}
lcp@332
   249
These tactics add assumptions to a given subgoal.
lcp@323
   250
\begin{ttdescription}
lcp@104
   251
\item[\ttindexbold{cut_facts_tac} {\it thms} {\it i}] 
lcp@104
   252
  adds the {\it thms} as new assumptions to subgoal~$i$.  Once they have
lcp@286
   253
  been inserted as assumptions, they become subject to tactics such as {\tt
lcp@286
   254
    eresolve_tac} and {\tt rewrite_goals_tac}.  Only rules with no premises
lcp@286
   255
  are inserted: Isabelle cannot use assumptions that contain $\Imp$
lcp@286
   256
  or~$\Forall$.  Sometimes the theorems are premises of a rule being
lcp@286
   257
  derived, returned by~{\tt goal}; instead of calling this tactic, you
lcp@286
   258
  could state the goal with an outermost meta-quantifier.
lcp@286
   259
lcp@286
   260
\item[\ttindexbold{cut_inst_tac} {\it insts} {\it thm} {\it i}]
lcp@286
   261
  instantiates the {\it thm} with the instantiations {\it insts}, as
lcp@286
   262
  described in \S\ref{res_inst_tac}.  It adds the resulting theorem as a
lcp@286
   263
  new assumption to subgoal~$i$. 
lcp@104
   264
lcp@104
   265
\item[\ttindexbold{subgoal_tac} {\it formula} {\it i}] 
lcp@104
   266
adds the {\it formula} as a assumption to subgoal~$i$, and inserts the same
lcp@104
   267
{\it formula} as a new subgoal, $i+1$.
lcp@457
   268
lcp@457
   269
\item[\ttindexbold{subgoals_tac} {\it formulae} {\it i}] 
lcp@457
   270
  uses {\tt subgoal_tac} to add the members of the list of {\it
lcp@457
   271
    formulae} as assumptions to subgoal~$i$. 
lcp@323
   272
\end{ttdescription}
lcp@104
   273
lcp@104
   274
lcp@104
   275
\subsection{Theorems useful with tactics}
lcp@323
   276
\index{theorems!of pure theory}
lcp@104
   277
\begin{ttbox} 
lcp@104
   278
asm_rl: thm 
lcp@104
   279
cut_rl: thm 
lcp@104
   280
\end{ttbox}
lcp@323
   281
\begin{ttdescription}
lcp@323
   282
\item[\tdx{asm_rl}] 
lcp@104
   283
is $\psi\Imp\psi$.  Under elim-resolution it does proof by assumption, and
lcp@104
   284
\hbox{\tt eresolve_tac (asm_rl::{\it thms}) {\it i}} is equivalent to
lcp@104
   285
\begin{ttbox} 
lcp@104
   286
assume_tac {\it i}  ORELSE  eresolve_tac {\it thms} {\it i}
lcp@104
   287
\end{ttbox}
lcp@104
   288
lcp@323
   289
\item[\tdx{cut_rl}] 
lcp@104
   290
is $\List{\psi\Imp\theta,\psi}\Imp\theta$.  It is useful for inserting
lcp@323
   291
assumptions; it underlies {\tt forward_tac}, {\tt cut_facts_tac}
lcp@323
   292
and {\tt subgoal_tac}.
lcp@323
   293
\end{ttdescription}
lcp@104
   294
lcp@104
   295
lcp@104
   296
\section{Obscure tactics}
lcp@104
   297
\subsection{Tidying the proof state}
lcp@323
   298
\index{parameters!removing unused}
lcp@104
   299
\index{flex-flex constraints}
lcp@104
   300
\begin{ttbox} 
lcp@104
   301
prune_params_tac : tactic
lcp@104
   302
flexflex_tac     : tactic
lcp@104
   303
\end{ttbox}
lcp@323
   304
\begin{ttdescription}
lcp@104
   305
\item[\ttindexbold{prune_params_tac}]  
lcp@104
   306
  removes unused parameters from all subgoals of the proof state.  It works
lcp@104
   307
  by rewriting with the theorem $(\Forall x. V)\equiv V$.  This tactic can
lcp@104
   308
  make the proof state more readable.  It is used with
lcp@104
   309
  \ttindex{rule_by_tactic} to simplify the resulting theorem.
lcp@104
   310
lcp@104
   311
\item[\ttindexbold{flexflex_tac}]  
lcp@104
   312
  removes all flex-flex pairs from the proof state by applying the trivial
lcp@104
   313
  unifier.  This drastic step loses information, and should only be done as
lcp@104
   314
  the last step of a proof.
lcp@104
   315
lcp@104
   316
  Flex-flex constraints arise from difficult cases of higher-order
lcp@104
   317
  unification.  To prevent this, use \ttindex{res_inst_tac} to instantiate
lcp@104
   318
  some variables in a rule~(\S\ref{res_inst_tac}).  Normally flex-flex
lcp@104
   319
  constraints can be ignored; they often disappear as unknowns get
lcp@104
   320
  instantiated.
lcp@323
   321
\end{ttdescription}
lcp@104
   322
lcp@104
   323
lcp@323
   324
\subsection{Renaming parameters in a goal} \index{parameters!renaming}
lcp@104
   325
\begin{ttbox} 
lcp@104
   326
rename_tac        : string -> int -> tactic
lcp@104
   327
rename_last_tac   : string -> string list -> int -> tactic
lcp@104
   328
Logic.set_rename_prefix : string -> unit
lcp@104
   329
Logic.auto_rename       : bool ref      \hfill{\bf initially false}
lcp@104
   330
\end{ttbox}
lcp@104
   331
When creating a parameter, Isabelle chooses its name by matching variable
lcp@104
   332
names via the object-rule.  Given the rule $(\forall I)$ formalized as
lcp@104
   333
$\left(\Forall x. P(x)\right) \Imp \forall x.P(x)$, Isabelle will note that
lcp@104
   334
the $\Forall$-bound variable in the premise has the same name as the
lcp@104
   335
$\forall$-bound variable in the conclusion.  
lcp@104
   336
lcp@104
   337
Sometimes there is insufficient information and Isabelle chooses an
lcp@104
   338
arbitrary name.  The renaming tactics let you override Isabelle's choice.
lcp@104
   339
Because renaming parameters has no logical effect on the proof state, the
lcp@323
   340
{\tt by} command prints the message {\tt Warning:\ same as previous
lcp@104
   341
level}.
lcp@104
   342
lcp@104
   343
Alternatively, you can suppress the naming mechanism described above and
lcp@104
   344
have Isabelle generate uniform names for parameters.  These names have the
lcp@104
   345
form $p${\tt a}, $p${\tt b}, $p${\tt c},~\ldots, where $p$ is any desired
lcp@104
   346
prefix.  They are ugly but predictable.
lcp@104
   347
lcp@323
   348
\begin{ttdescription}
lcp@104
   349
\item[\ttindexbold{rename_tac} {\it str} {\it i}] 
lcp@104
   350
interprets the string {\it str} as a series of blank-separated variable
lcp@104
   351
names, and uses them to rename the parameters of subgoal~$i$.  The names
lcp@104
   352
must be distinct.  If there are fewer names than parameters, then the
lcp@104
   353
tactic renames the innermost parameters and may modify the remaining ones
lcp@104
   354
to ensure that all the parameters are distinct.
lcp@104
   355
lcp@104
   356
\item[\ttindexbold{rename_last_tac} {\it prefix} {\it suffixes} {\it i}] 
lcp@104
   357
generates a list of names by attaching each of the {\it suffixes\/} to the 
lcp@104
   358
{\it prefix}.  It is intended for coding structural induction tactics,
lcp@104
   359
where several of the new parameters should have related names.
lcp@104
   360
lcp@104
   361
\item[\ttindexbold{Logic.set_rename_prefix} {\it prefix};] 
lcp@104
   362
sets the prefix for uniform renaming to~{\it prefix}.  The default prefix
lcp@104
   363
is {\tt"k"}.
lcp@104
   364
lcp@323
   365
\item[\ttindexbold{Logic.auto_rename} := true;] 
lcp@104
   366
makes Isabelle generate uniform names for parameters. 
lcp@323
   367
\end{ttdescription}
lcp@104
   368
lcp@104
   369
lcp@104
   370
\subsection{Composition: resolution without lifting}
lcp@323
   371
\index{tactics!for composition}
lcp@104
   372
\begin{ttbox}
lcp@104
   373
compose_tac: (bool * thm * int) -> int -> tactic
lcp@104
   374
\end{ttbox}
lcp@332
   375
{\bf Composing} two rules means resolving them without prior lifting or
lcp@104
   376
renaming of unknowns.  This low-level operation, which underlies the
lcp@104
   377
resolution tactics, may occasionally be useful for special effects.
lcp@104
   378
A typical application is \ttindex{res_inst_tac}, which lifts and instantiates a
lcp@104
   379
rule, then passes the result to {\tt compose_tac}.
lcp@323
   380
\begin{ttdescription}
lcp@104
   381
\item[\ttindexbold{compose_tac} ($flag$, $rule$, $m$) $i$] 
lcp@104
   382
refines subgoal~$i$ using $rule$, without lifting.  The $rule$ is taken to
lcp@104
   383
have the form $\List{\psi@1; \ldots; \psi@m} \Imp \psi$, where $\psi$ need
lcp@323
   384
not be atomic; thus $m$ determines the number of new subgoals.  If
lcp@104
   385
$flag$ is {\tt true} then it performs elim-resolution --- it solves the
lcp@104
   386
first premise of~$rule$ by assumption and deletes that assumption.
lcp@323
   387
\end{ttdescription}
lcp@104
   388
lcp@104
   389
lcp@104
   390
\section{Managing lots of rules}
lcp@104
   391
These operations are not intended for interactive use.  They are concerned
lcp@104
   392
with the processing of large numbers of rules in automatic proof
lcp@104
   393
strategies.  Higher-order resolution involving a long list of rules is
lcp@104
   394
slow.  Filtering techniques can shorten the list of rules given to
lcp@104
   395
resolution, and can also detect whether a given subgoal is too flexible,
lcp@104
   396
with too many rules applicable.
lcp@104
   397
lcp@104
   398
\subsection{Combined resolution and elim-resolution} \label{biresolve_tac}
lcp@104
   399
\index{tactics!resolution}
lcp@104
   400
\begin{ttbox} 
lcp@104
   401
biresolve_tac   : (bool*thm)list -> int -> tactic
lcp@104
   402
bimatch_tac     : (bool*thm)list -> int -> tactic
lcp@104
   403
subgoals_of_brl : bool*thm -> int
lcp@104
   404
lessb           : (bool*thm) * (bool*thm) -> bool
lcp@104
   405
\end{ttbox}
lcp@104
   406
{\bf Bi-resolution} takes a list of $\it (flag,rule)$ pairs.  For each
lcp@104
   407
pair, it applies resolution if the flag is~{\tt false} and
lcp@104
   408
elim-resolution if the flag is~{\tt true}.  A single tactic call handles a
lcp@104
   409
mixture of introduction and elimination rules.
lcp@104
   410
lcp@323
   411
\begin{ttdescription}
lcp@104
   412
\item[\ttindexbold{biresolve_tac} {\it brls} {\it i}] 
lcp@104
   413
refines the proof state by resolution or elim-resolution on each rule, as
lcp@104
   414
indicated by its flag.  It affects subgoal~$i$ of the proof state.
lcp@104
   415
lcp@104
   416
\item[\ttindexbold{bimatch_tac}] 
lcp@104
   417
is like {\tt biresolve_tac}, but performs matching: unknowns in the
lcp@104
   418
proof state are never updated (see~\S\ref{match_tac}).
lcp@104
   419
lcp@104
   420
\item[\ttindexbold{subgoals_of_brl}({\it flag},{\it rule})] 
lcp@104
   421
returns the number of new subgoals that bi-resolution would yield for the
lcp@104
   422
pair (if applied to a suitable subgoal).  This is $n$ if the flag is
lcp@104
   423
{\tt false} and $n-1$ if the flag is {\tt true}, where $n$ is the number
lcp@104
   424
of premises of the rule.  Elim-resolution yields one fewer subgoal than
lcp@104
   425
ordinary resolution because it solves the major premise by assumption.
lcp@104
   426
lcp@104
   427
\item[\ttindexbold{lessb} ({\it brl1},{\it brl2})] 
lcp@104
   428
returns the result of 
lcp@104
   429
\begin{ttbox}
lcp@332
   430
subgoals_of_brl{\it brl1} < subgoals_of_brl{\it brl2}
lcp@104
   431
\end{ttbox}
lcp@323
   432
\end{ttdescription}
lcp@104
   433
Note that \hbox{\tt sort lessb {\it brls}} sorts a list of $\it
lcp@104
   434
(flag,rule)$ pairs by the number of new subgoals they will yield.  Thus,
lcp@104
   435
those that yield the fewest subgoals should be tried first.
lcp@104
   436
lcp@104
   437
lcp@323
   438
\subsection{Discrimination nets for fast resolution}\label{filt_resolve_tac}
lcp@104
   439
\index{discrimination nets|bold}
lcp@104
   440
\index{tactics!resolution}
lcp@104
   441
\begin{ttbox} 
lcp@104
   442
net_resolve_tac  : thm list -> int -> tactic
lcp@104
   443
net_match_tac    : thm list -> int -> tactic
lcp@104
   444
net_biresolve_tac: (bool*thm) list -> int -> tactic
lcp@104
   445
net_bimatch_tac  : (bool*thm) list -> int -> tactic
lcp@104
   446
filt_resolve_tac : thm list -> int -> int -> tactic
lcp@104
   447
could_unify      : term*term->bool
lcp@104
   448
filter_thms      : (term*term->bool) -> int*term*thm list -> thm list
lcp@104
   449
\end{ttbox}
lcp@323
   450
The module {\tt Net} implements a discrimination net data structure for
lcp@104
   451
fast selection of rules \cite[Chapter 14]{charniak80}.  A term is
lcp@104
   452
classified by the symbol list obtained by flattening it in preorder.
lcp@104
   453
The flattening takes account of function applications, constants, and free
lcp@104
   454
and bound variables; it identifies all unknowns and also regards
lcp@323
   455
\index{lambda abs@$\lambda$-abstractions}
lcp@104
   456
$\lambda$-abstractions as unknowns, since they could $\eta$-contract to
lcp@104
   457
anything.  
lcp@104
   458
lcp@104
   459
A discrimination net serves as a polymorphic dictionary indexed by terms.
lcp@104
   460
The module provides various functions for inserting and removing items from
lcp@104
   461
nets.  It provides functions for returning all items whose term could match
lcp@104
   462
or unify with a target term.  The matching and unification tests are
lcp@104
   463
overly lax (due to the identifications mentioned above) but they serve as
lcp@104
   464
useful filters.
lcp@104
   465
lcp@104
   466
A net can store introduction rules indexed by their conclusion, and
lcp@104
   467
elimination rules indexed by their major premise.  Isabelle provides
lcp@323
   468
several functions for `compiling' long lists of rules into fast
lcp@104
   469
resolution tactics.  When supplied with a list of theorems, these functions
lcp@104
   470
build a discrimination net; the net is used when the tactic is applied to a
lcp@332
   471
goal.  To avoid repeatedly constructing the nets, use currying: bind the
lcp@104
   472
resulting tactics to \ML{} identifiers.
lcp@104
   473
lcp@323
   474
\begin{ttdescription}
lcp@104
   475
\item[\ttindexbold{net_resolve_tac} {\it thms}] 
lcp@104
   476
builds a discrimination net to obtain the effect of a similar call to {\tt
lcp@104
   477
resolve_tac}.
lcp@104
   478
lcp@104
   479
\item[\ttindexbold{net_match_tac} {\it thms}] 
lcp@104
   480
builds a discrimination net to obtain the effect of a similar call to {\tt
lcp@104
   481
match_tac}.
lcp@104
   482
lcp@104
   483
\item[\ttindexbold{net_biresolve_tac} {\it brls}] 
lcp@104
   484
builds a discrimination net to obtain the effect of a similar call to {\tt
lcp@104
   485
biresolve_tac}.
lcp@104
   486
lcp@104
   487
\item[\ttindexbold{net_bimatch_tac} {\it brls}] 
lcp@104
   488
builds a discrimination net to obtain the effect of a similar call to {\tt
lcp@104
   489
bimatch_tac}.
lcp@104
   490
lcp@104
   491
\item[\ttindexbold{filt_resolve_tac} {\it thms} {\it maxr} {\it i}] 
lcp@104
   492
uses discrimination nets to extract the {\it thms} that are applicable to
lcp@104
   493
subgoal~$i$.  If more than {\it maxr\/} theorems are applicable then the
lcp@104
   494
tactic fails.  Otherwise it calls {\tt resolve_tac}.  
lcp@104
   495
lcp@104
   496
This tactic helps avoid runaway instantiation of unknowns, for example in
lcp@104
   497
type inference.
lcp@104
   498
lcp@104
   499
\item[\ttindexbold{could_unify} ({\it t},{\it u})] 
lcp@323
   500
returns {\tt false} if~$t$ and~$u$ are `obviously' non-unifiable, and
lcp@104
   501
otherwise returns~{\tt true}.  It assumes all variables are distinct,
lcp@104
   502
reporting that {\tt ?a=?a} may unify with {\tt 0=1}.
lcp@104
   503
lcp@104
   504
\item[\ttindexbold{filter_thms} $could\; (limit,prem,thms)$] 
lcp@104
   505
returns the list of potentially resolvable rules (in {\it thms\/}) for the
lcp@104
   506
subgoal {\it prem}, using the predicate {\it could\/} to compare the
lcp@104
   507
conclusion of the subgoal with the conclusion of each rule.  The resulting list
lcp@104
   508
is no longer than {\it limit}.
lcp@323
   509
\end{ttdescription}
lcp@104
   510
lcp@104
   511
lcp@104
   512
\section{Programming tools for proof strategies}
lcp@104
   513
Do not consider using the primitives discussed in this section unless you
lcp@323
   514
really need to code tactics from scratch.
lcp@104
   515
lcp@104
   516
\subsection{Operations on type {\tt tactic}}
lcp@323
   517
\index{tactics!primitives for coding}
lcp@104
   518
A tactic maps theorems to theorem sequences (lazy lists).  The type
lcp@323
   519
constructor for sequences is called \mltydx{Sequence.seq}.  To simplify the
lcp@104
   520
types of tactics and tacticals, Isabelle defines a type of tactics:
lcp@104
   521
\begin{ttbox} 
lcp@104
   522
datatype tactic = Tactic of thm -> thm Sequence.seq
lcp@104
   523
\end{ttbox} 
lcp@104
   524
{\tt Tactic} and {\tt tapply} convert between tactics and functions.  The
lcp@104
   525
other operations provide means for coding tactics in a clean style.
lcp@104
   526
\begin{ttbox} 
lcp@104
   527
tapply    : tactic * thm -> thm Sequence.seq
lcp@104
   528
Tactic    :     (thm -> thm Sequence.seq) -> tactic
lcp@104
   529
PRIMITIVE :                  (thm -> thm) -> tactic  
lcp@104
   530
STATE     :               (thm -> tactic) -> tactic
lcp@104
   531
SUBGOAL   : ((term*int) -> tactic) -> int -> tactic
lcp@104
   532
\end{ttbox} 
lcp@323
   533
\begin{ttdescription}
lcp@323
   534
\item[\ttindexbold{tapply}({\it tac}, {\it thm})]  
lcp@104
   535
returns the result of applying the tactic, as a function, to {\it thm}.
lcp@104
   536
lcp@104
   537
\item[\ttindexbold{Tactic} {\it f}]  
lcp@104
   538
packages {\it f} as a tactic.
lcp@104
   539
lcp@104
   540
\item[\ttindexbold{PRIMITIVE} $f$] 
lcp@104
   541
applies $f$ to the proof state and returns the result as a
lcp@104
   542
one-element sequence.  This packages the meta-rule~$f$ as a tactic.
lcp@104
   543
lcp@104
   544
\item[\ttindexbold{STATE} $f$] 
lcp@104
   545
applies $f$ to the proof state and then applies the resulting tactic to the
lcp@104
   546
same state.  It supports the following style, where the tactic body is
lcp@323
   547
expressed using tactics and tacticals, but may peek at the proof state:
lcp@104
   548
\begin{ttbox} 
lcp@323
   549
STATE (fn state => {\it tactic-valued expression})
lcp@104
   550
\end{ttbox} 
lcp@104
   551
lcp@104
   552
\item[\ttindexbold{SUBGOAL} $f$ $i$] 
lcp@104
   553
extracts subgoal~$i$ from the proof state as a term~$t$, and computes a
lcp@104
   554
tactic by calling~$f(t,i)$.  It applies the resulting tactic to the same
lcp@323
   555
state.  The tactic body is expressed using tactics and tacticals, but may
lcp@323
   556
peek at a particular subgoal:
lcp@104
   557
\begin{ttbox} 
lcp@323
   558
SUBGOAL (fn (t,i) => {\it tactic-valued expression})
lcp@104
   559
\end{ttbox} 
lcp@323
   560
\end{ttdescription}
lcp@104
   561
lcp@104
   562
lcp@104
   563
\subsection{Tracing}
lcp@323
   564
\index{tactics!tracing}
lcp@104
   565
\index{tracing!of tactics}
lcp@104
   566
\begin{ttbox} 
lcp@104
   567
pause_tac: tactic
lcp@104
   568
print_tac: tactic
lcp@104
   569
\end{ttbox}
lcp@332
   570
These tactics print tracing information when they are applied to a proof
lcp@332
   571
state.  Their output may be difficult to interpret.  Note that certain of
lcp@332
   572
the searching tacticals, such as {\tt REPEAT}, have built-in tracing
lcp@332
   573
options.
lcp@323
   574
\begin{ttdescription}
lcp@104
   575
\item[\ttindexbold{pause_tac}] 
lcp@332
   576
prints {\footnotesize\tt** Press RETURN to continue:} and then reads a line
lcp@332
   577
from the terminal.  If this line is blank then it returns the proof state
lcp@332
   578
unchanged; otherwise it fails (which may terminate a repetition).
lcp@104
   579
lcp@104
   580
\item[\ttindexbold{print_tac}] 
lcp@104
   581
returns the proof state unchanged, with the side effect of printing it at
lcp@104
   582
the terminal.
lcp@323
   583
\end{ttdescription}
lcp@104
   584
lcp@104
   585
lcp@323
   586
\section{Sequences}
lcp@104
   587
\index{sequences (lazy lists)|bold}
lcp@323
   588
The module {\tt Sequence} declares a type of lazy lists.  It uses
lcp@323
   589
Isabelle's type \mltydx{option} to represent the possible presence
lcp@104
   590
(\ttindexbold{Some}) or absence (\ttindexbold{None}) of
lcp@104
   591
a value:
lcp@104
   592
\begin{ttbox}
lcp@104
   593
datatype 'a option = None  |  Some of 'a;
lcp@104
   594
\end{ttbox}
lcp@286
   595
For clarity, the module name {\tt Sequence} is omitted from the signature
lcp@286
   596
specifications below; for instance, {\tt null} appears instead of {\tt
lcp@286
   597
  Sequence.null}.
lcp@104
   598
lcp@323
   599
\subsection{Basic operations on sequences}
lcp@104
   600
\begin{ttbox} 
lcp@286
   601
null   : 'a seq
lcp@286
   602
seqof  : (unit -> ('a * 'a seq) option) -> 'a seq
lcp@286
   603
single : 'a -> 'a seq
lcp@286
   604
pull   : 'a seq -> ('a * 'a seq) option
lcp@104
   605
\end{ttbox}
lcp@323
   606
\begin{ttdescription}
lcp@323
   607
\item[Sequence.null] 
lcp@104
   608
is the empty sequence.
lcp@104
   609
lcp@104
   610
\item[\tt Sequence.seqof (fn()=> Some($x$,$s$))] 
lcp@104
   611
constructs the sequence with head~$x$ and tail~$s$, neither of which is
lcp@104
   612
evaluated.
lcp@104
   613
lcp@323
   614
\item[Sequence.single $x$] 
lcp@104
   615
constructs the sequence containing the single element~$x$.
lcp@104
   616
lcp@323
   617
\item[Sequence.pull $s$] 
lcp@104
   618
returns {\tt None} if the sequence is empty and {\tt Some($x$,$s'$)} if the
lcp@104
   619
sequence has head~$x$ and tail~$s'$.  Warning: calling \hbox{Sequence.pull
lcp@332
   620
$s$} again will {\it recompute\/} the value of~$x$; it is not stored!
lcp@323
   621
\end{ttdescription}
lcp@104
   622
lcp@104
   623
lcp@323
   624
\subsection{Converting between sequences and lists}
lcp@104
   625
\begin{ttbox} 
lcp@286
   626
chop      : int * 'a seq -> 'a list * 'a seq
lcp@286
   627
list_of_s : 'a seq -> 'a list
lcp@286
   628
s_of_list : 'a list -> 'a seq
lcp@104
   629
\end{ttbox}
lcp@323
   630
\begin{ttdescription}
lcp@332
   631
\item[Sequence.chop($n$,$s$)] 
lcp@104
   632
returns the first~$n$ elements of~$s$ as a list, paired with the remaining
lcp@104
   633
elements of~$s$.  If $s$ has fewer than~$n$ elements, then so will the
lcp@104
   634
list.
lcp@104
   635
lcp@323
   636
\item[Sequence.list_of_s $s$] 
lcp@104
   637
returns the elements of~$s$, which must be finite, as a list.
lcp@104
   638
lcp@323
   639
\item[Sequence.s_of_list $l$] 
lcp@104
   640
creates a sequence containing the elements of~$l$.
lcp@323
   641
\end{ttdescription}
lcp@104
   642
lcp@104
   643
lcp@323
   644
\subsection{Combining sequences}
lcp@104
   645
\begin{ttbox} 
lcp@286
   646
append     : 'a seq * 'a seq -> 'a seq
lcp@286
   647
interleave : 'a seq * 'a seq -> 'a seq
lcp@286
   648
flats      : 'a seq seq -> 'a seq
lcp@286
   649
maps       : ('a -> 'b) -> 'a seq -> 'b seq
lcp@286
   650
filters    : ('a -> bool) -> 'a seq -> 'a seq
lcp@104
   651
\end{ttbox} 
lcp@323
   652
\begin{ttdescription}
lcp@332
   653
\item[Sequence.append($s@1$,$s@2$)] 
lcp@104
   654
concatenates $s@1$ to $s@2$.
lcp@104
   655
lcp@332
   656
\item[Sequence.interleave($s@1$,$s@2$)] 
lcp@104
   657
joins $s@1$ with $s@2$ by interleaving their elements.  The result contains
lcp@104
   658
all the elements of the sequences, even if both are infinite.
lcp@104
   659
lcp@323
   660
\item[Sequence.flats $ss$] 
lcp@104
   661
concatenates a sequence of sequences.
lcp@104
   662
lcp@323
   663
\item[Sequence.maps $f$ $s$] 
lcp@104
   664
applies $f$ to every element of~$s=x@1,x@2,\ldots$, yielding the sequence
lcp@104
   665
$f(x@1),f(x@2),\ldots$.
lcp@104
   666
lcp@323
   667
\item[Sequence.filters $p$ $s$] 
lcp@104
   668
returns the sequence consisting of all elements~$x$ of~$s$ such that $p(x)$
lcp@104
   669
is {\tt true}.
lcp@323
   670
\end{ttdescription}
lcp@104
   671
lcp@104
   672
\index{tactics|)}