doc-src/Ref/tctical.tex
author lcp
Wed, 10 Nov 1993 05:00:57 +0100
changeset 104 d8205bb279a7
child 286 e7efbf03562b
permissions -rw-r--r--
Initial revision
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
104
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     1
%% $Id$
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     2
\chapter{Tacticals}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     3
\index{tacticals|(}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     4
\index{tactics!combining|see{tacticals}}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     5
Tacticals are operations on tactics.  Their implementation makes use of
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     6
functional programming techniques, especially for sequences.  Most of the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     7
time, you may forget about this and regard tacticals as high-level control
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     8
structures.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     9
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    10
\section{The basic tacticals}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    11
\subsection{Joining two tactics}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    12
\index{tacticals!joining two tactics|bold}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    13
The tacticals {\tt THEN} and {\tt ORELSE}, which provide sequencing and
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    14
alternation, underlie most of the other control structures in Isabelle.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    15
{\tt APPEND} and {\tt INTLEAVE} provide more sophisticated forms of
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    16
alternation.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    17
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    18
THEN     : tactic * tactic -> tactic                 \hfill{\bf infix 1}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    19
ORELSE   : tactic * tactic -> tactic                 \hfill{\bf infix}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    20
APPEND   : tactic * tactic -> tactic                 \hfill{\bf infix}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    21
INTLEAVE : tactic * tactic -> tactic                 \hfill{\bf infix}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    22
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    23
\begin{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    24
\item[\tt $tac@1$ \ttindexbold{THEN} $tac@2$] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    25
is the sequential composition of the two tactics.  Applied to a proof
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    26
state, it returns all states reachable in two steps by applying $tac@1$
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    27
followed by~$tac@2$.  First, it applies $tac@1$ to the proof state, getting a
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    28
sequence of next states; then, it applies $tac@2$ to each of these and
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    29
concatenates the results.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    30
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    31
\item[\tt $tac@1$ \ttindexbold{ORELSE} $tac@2$] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    32
makes a choice between the two tactics.  Applied to a state, it
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    33
tries~$tac@1$ and returns the result if non-empty; if $tac@1$ fails then it
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    34
uses~$tac@2$.  This is a deterministic choice: if $tac@1$ succeeds then
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    35
$tac@2$ is excluded.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    36
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    37
\item[\tt $tac@1$ \ttindexbold{APPEND} $tac@2$] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    38
concatenates the results of $tac@1$ and~$tac@2$.  By not making a commitment
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    39
to either tactic, {\tt APPEND} helps avoid incompleteness during search.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    40
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    41
\item[\tt $tac@1$ \ttindexbold{INTLEAVE} $tac@2$] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    42
interleaves the results of $tac@1$ and~$tac@2$.  Thus, it includes all
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    43
possible next states, even if one of the tactics returns an infinite
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    44
sequence.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    45
\end{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    46
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    47
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    48
\subsection{Joining a list of tactics}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    49
\index{tacticals!joining a list of tactics|bold}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    50
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    51
EVERY : tactic list -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    52
FIRST : tactic list -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    53
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    54
{\tt EVERY} and {\tt FIRST} are block structured versions of {\tt THEN} and
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    55
{\tt ORELSE}\@.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    56
\begin{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    57
\item[\ttindexbold{EVERY} {$[tac@1,\ldots,tac@n]$}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    58
abbreviates \hbox{\tt$tac@1$ THEN \ldots{} THEN $tac@n$}.  It is useful for
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    59
writing a series of tactics to be executed in sequence.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    60
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    61
\item[\ttindexbold{FIRST} {$[tac@1,\ldots,tac@n]$}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    62
abbreviates \hbox{\tt$tac@1$ ORELSE \ldots{} ORELSE $tac@n$}.  It is useful for
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    63
writing a series of tactics to be attempted one after another.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    64
\end{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    65
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    66
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    67
\subsection{Repetition tacticals}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    68
\index{tacticals!repetition|bold}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    69
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    70
TRY           : tactic -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    71
REPEAT_DETERM : tactic -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    72
REPEAT        : tactic -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    73
REPEAT1       : tactic -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    74
trace_REPEAT  : bool ref \hfill{\bf initially false}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    75
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    76
\begin{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    77
\item[\ttindexbold{TRY} {\it tac}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    78
applies {\it tac\/} to the proof state and returns the resulting sequence,
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    79
if non-empty; otherwise it returns the original state.  Thus, it applies
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    80
{\it tac\/} at most once.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    81
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    82
\item[\ttindexbold{REPEAT_DETERM} {\it tac}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    83
applies {\it tac\/} to the proof state and, recursively, to the head of the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    84
resulting sequence.  It returns the first state to make {\it tac\/} fail.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    85
It is deterministic, discarding alternative outcomes.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    86
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    87
\item[\ttindexbold{REPEAT} {\it tac}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    88
applies {\it tac\/} to the proof state and, recursively, to each element of
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    89
the resulting sequence.  The resulting sequence consists of those states
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    90
that make {\it tac\/} fail.  Thus, it applies {\it tac\/} as many times as
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    91
possible (including zero times), and allows backtracking over each
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    92
invocation of {\it tac}.  It is more general than {\tt REPEAT_DETERM}, but
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    93
requires more space.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    94
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    95
\item[\ttindexbold{REPEAT1} {\it tac}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    96
is like \hbox{\tt REPEAT {\it tac}} but it always applies {\it tac\/} at
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    97
least once, failing if this is impossible.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    98
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    99
\item[\ttindexbold{trace_REPEAT} \tt:= true;] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   100
enables an interactive tracing mode for {\tt REPEAT_DETERM} and {\tt
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   101
REPEAT}.  To view the tracing options, type {\tt h} at the prompt.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   102
\end{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   103
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   104
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   105
\subsection{Identities for tacticals}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   106
\index{tacticals!identities for|bold}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   107
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   108
all_tac : tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   109
no_tac  : tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   110
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   111
\begin{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   112
\item[\ttindexbold{all_tac}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   113
maps any proof state to the one-element sequence containing that state.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   114
Thus, it succeeds for all states.  It is the identity element of the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   115
tactical \ttindex{THEN}\@.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   116
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   117
\item[\ttindexbold{no_tac}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   118
maps any proof state to the empty sequence.  Thus it succeeds for no state.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   119
It is the identity element of \ttindex{ORELSE}, \ttindex{APPEND}, and 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   120
\ttindex{INTLEAVE}\@.  Also, it is a zero element for \ttindex{THEN}, which means that
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   121
\hbox{\tt$tac$ THEN no_tac} is equivalent to {\tt no_tac}.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   122
\end{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   123
These primitive tactics are useful when writing tacticals.  For example,
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   124
\ttindexbold{TRY} and \ttindexbold{REPEAT} (ignoring tracing) can be coded
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   125
as follows: 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   126
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   127
fun TRY tac = tac ORELSE all_tac;
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   128
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   129
fun REPEAT tac = Tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   130
     (fn state => tapply((tac THEN REPEAT tac) ORELSE all_tac,
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   131
                         state));
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   132
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   133
If $tac$ can return multiple outcomes then so can \hbox{\tt REPEAT $tac$}.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   134
Since {\tt REPEAT} uses \ttindex{ORELSE} and not {\tt APPEND} or {\tt
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   135
INTLEAVE}, it applies $tac$ as many times as possible in each
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   136
outcome.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   137
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   138
\begin{warn}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   139
Note {\tt REPEAT}'s explicit abstraction over the proof state.  Recursive
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   140
tacticals must be coded in this awkward fashion to avoid infinite
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   141
recursion.  With the following definition, \hbox{\tt REPEAT $tac$} would
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   142
loop:
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   143
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   144
fun REPEAT tac = (tac THEN REPEAT tac) ORELSE all_tac;
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   145
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   146
\par\noindent
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   147
The built-in {\tt REPEAT} avoids~{\tt THEN}, handling sequences explicitly
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   148
and using tail recursion.  This sacrifices clarity, but saves much space by
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   149
discarding intermediate proof states.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   150
\end{warn}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   151
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   152
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   153
\section{Control and search tacticals}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   154
A predicate on theorems, namely a function of type \hbox{\tt thm->bool},
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   155
can test whether a proof state enjoys some desirable property --- such as
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   156
having no subgoals.  Tactics that search for satisfactory states are easy
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   157
to express.  The main search procedures, depth-first, breadth-first and
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   158
best-first, are provided as tacticals.  They generate the search tree by
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   159
repeatedly applying a given tactic.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   160
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   161
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   162
\subsection{Filtering a tactic's results}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   163
\index{tacticals!for filtering|bold}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   164
\index{tactics!filtering results of|bold}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   165
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   166
FILTER  : (thm -> bool) -> tactic -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   167
CHANGED : tactic -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   168
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   169
\begin{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   170
\item[\tt \tt FILTER {\it p} $tac$] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   171
applies $tac$ to the proof state and returns a sequence consisting of those
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   172
result states that satisfy~$p$.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   173
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   174
\item[\ttindexbold{CHANGED} {\it tac}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   175
applies {\it tac\/} to the proof state and returns precisely those states
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   176
that differ from the original state.  Thus, \hbox{\tt CHANGED {\it tac}}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   177
always has some effect on the state.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   178
\end{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   179
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   180
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   181
\subsection{Depth-first search}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   182
\index{tacticals!searching|bold}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   183
\index{tracing!of searching tacticals}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   184
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   185
DEPTH_FIRST   : (thm->bool) -> tactic -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   186
DEPTH_SOLVE   : tactic -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   187
DEPTH_SOLVE_1 : tactic -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   188
trace_DEPTH_FIRST: bool ref \hfill{\bf initially false}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   189
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   190
\begin{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   191
\item[\ttindexbold{DEPTH_FIRST} {\it satp} {\it tac}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   192
returns the proof state if {\it satp} returns true.  Otherwise it applies
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   193
{\it tac}, then recursively searches from each element of the resulting
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   194
sequence.  The code uses a stack for efficiency, in effect applying
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   195
\hbox{\tt {\it tac} THEN DEPTH_FIRST {\it satp} {\it tac}} to the state.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   196
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   197
\item[\ttindexbold{DEPTH_SOLVE} {\it tac}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   198
uses {\tt DEPTH_FIRST} to search for states having no subgoals.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   199
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   200
\item[\ttindexbold{DEPTH_SOLVE_1} {\it tac}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   201
uses {\tt DEPTH_FIRST} to search for states having fewer subgoals than the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   202
given state.  Thus, it insists upon solving at least one subgoal.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   203
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   204
\item[\ttindexbold{trace_DEPTH_FIRST} \tt:= true;] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   205
enables interactive tracing for {\tt DEPTH_FIRST}.  To view the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   206
tracing options, type {\tt h} at the prompt.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   207
\end{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   208
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   209
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   210
\subsection{Other search strategies}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   211
\index{tacticals!searching|bold}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   212
\index{tracing!of searching tacticals}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   213
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   214
BREADTH_FIRST   : (thm->bool) -> tactic -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   215
BEST_FIRST      : (thm->bool)*(thm->int) -> tactic -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   216
THEN_BEST_FIRST : tactic * ((thm->bool) * (thm->int) * tactic)
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   217
                  -> tactic                    \hfill{\bf infix 1}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   218
trace_BEST_FIRST: bool ref \hfill{\bf initially false}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   219
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   220
These search strategies will find a solution if one exists.  However, they
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   221
do not enumerate all solutions; they terminate after the first satisfactory
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   222
result from {\it tac}.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   223
\begin{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   224
\item[\ttindexbold{BREADTH_FIRST} {\it satp} {\it tac}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   225
uses breadth-first search to find states for which {\it satp\/} is true.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   226
For most applications, it is too slow.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   227
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   228
\item[\ttindexbold{BEST_FIRST} $(satp,distf)$ {\it tac}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   229
does a heuristic search, using {\it distf\/} to estimate the distance from
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   230
a satisfactory state.  It maintains a list of states ordered by distance.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   231
It applies $tac$ to the head of this list; if the result contains any
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   232
satisfactory states, then it returns them.  Otherwise, {\tt BEST_FIRST}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   233
adds the new states to the list, and continues.  
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   234
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   235
The distance function is typically \ttindex{size_of_thm}, which computes
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   236
the size of the state.  The smaller the state, the fewer and simpler
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   237
subgoals it has.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   238
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   239
\item[$tac@0$ \ttindexbold{THEN_BEST_FIRST} $(satp,distf,tac)$] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   240
is like {\tt BEST_FIRST}, except that the priority queue initially
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   241
contains the result of applying $tac@0$ to the proof state.  This tactical
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   242
permits separate tactics for starting the search and continuing the search.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   243
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   244
\item[\ttindexbold{trace_BEST_FIRST} \tt:= true;] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   245
enables an interactive tracing mode for {\tt BEST_FIRST}.  To view the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   246
tracing options, type {\tt h} at the prompt.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   247
\end{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   248
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   249
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   250
\subsection{Auxiliary tacticals for searching}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   251
\index{tacticals!conditional}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   252
\index{tacticals!deterministic}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   253
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   254
COND        : (thm->bool) -> tactic -> tactic -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   255
IF_UNSOLVED : tactic -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   256
DETERM      : tactic -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   257
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   258
\begin{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   259
\item[\tt \tt COND {\it p} $tac@1$ $tac@2$] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   260
applies $tac@1$ to the proof state if it satisfies~$p$, and applies $tac@2$
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   261
otherwise.  It is a conditional tactical in that only one of $tac@1$ and
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   262
$tac@2$ is applied to a proof state.  However, both $tac@1$ and $tac@2$ are
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   263
evaluated because \ML{} uses eager evaluation.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   264
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   265
\item[\ttindexbold{IF_UNSOLVED} {\it tac}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   266
applies {\it tac\/} to the proof state if it has any subgoals, and simply
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   267
returns the proof state otherwise.  Many common tactics, such as {\tt
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   268
resolve_tac}, fail if applied to a proof state that has no subgoals.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   269
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   270
\item[\ttindexbold{DETERM} {\it tac}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   271
applies {\it tac\/} to the proof state and returns the head of the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   272
resulting sequence.  {\tt DETERM} limits the search space by making its
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   273
argument deterministic.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   274
\end{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   275
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   276
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   277
\subsection{Predicates and functions useful for searching}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   278
\index{theorems!size of}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   279
\index{theorems!equality of}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   280
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   281
has_fewer_prems : int -> thm -> bool
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   282
eq_thm          : thm * thm -> bool
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   283
size_of_thm     : thm -> int
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   284
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   285
\begin{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   286
\item[\ttindexbold{has_fewer_prems} $n$ $thm$] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   287
reports whether $thm$ has fewer than~$n$ premises.  By currying,
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   288
\hbox{\tt has_fewer_prems $n$} is a predicate on theorems; it may 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   289
be given to the searching tacticals.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   290
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   291
\item[\ttindexbold{eq_thm}($thm1$,$thm2$)] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   292
reports whether $thm1$ and $thm2$ are equal.  Both theorems must have
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   293
identical signatures.  Both theorems must have the same conclusions, and
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   294
the same hypotheses, in the same order.  Names of bound variables are
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   295
ignored.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   296
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   297
\item[\ttindexbold{size_of_thm} $thm$] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   298
computes the size of $thm$, namely the number of variables, constants and
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   299
abstractions in its conclusion.  It may serve as a distance function for 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   300
\ttindex{BEST_FIRST}. 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   301
\end{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   302
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   303
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   304
\section{Tacticals for subgoal numbering}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   305
When conducting a backward proof, we normally consider one goal at a time.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   306
A tactic can affect the entire proof state, but many tactics --- such as
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   307
{\tt resolve_tac} and {\tt assume_tac} --- work on a single subgoal.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   308
Subgoals are designated by a positive integer, so Isabelle provides
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   309
tacticals for combining values of type {\tt int->tactic}.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   310
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   311
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   312
\subsection{Restricting a tactic to one subgoal}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   313
\index{tactics!restricting to a subgoal}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   314
\index{tacticals!for restriction to a subgoal}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   315
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   316
SELECT_GOAL : tactic -> int -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   317
METAHYPS    : (thm list -> tactic) -> int -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   318
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   319
\begin{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   320
\item[\ttindexbold{SELECT_GOAL} {\it tac} $i$] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   321
restricts the effect of {\it tac\/} to subgoal~$i$ of the proof state.  It
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   322
fails if there is no subgoal~$i$, or if {\it tac\/} changes the main goal
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   323
(do not use {\tt rewrite_tac}).  It applies {\it tac\/} to a dummy proof
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   324
state and uses the result to refine the original proof state at
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   325
subgoal~$i$.  If {\it tac\/} returns multiple results then so does 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   326
\hbox{\tt SELECT_GOAL {\it tac} $i$}.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   327
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   328
Its workings are devious.  {\tt SELECT_GOAL} creates a state of the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   329
form $\phi\Imp\phi$, with one subgoal.  If subgoal~$i$ has the form say
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   330
$\psi\Imp\theta$, then {\tt SELECT_GOAL} creates the state 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   331
\[ (\Forall x.\psi\Imp\theta)\Imp(\Forall x.\psi\Imp\theta) \]
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   332
rather than $\List{\psi\Imp\theta;\; \psi}\Imp\theta$, which has two
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   333
subgoals.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   334
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   335
\item[\ttindexbold{METAHYPS} {\it tacf} $i$] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   336
takes subgoal~$i$, of the form 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   337
\[ \Forall x@1 \ldots x@l. \List{\theta@1; \ldots; \theta@k}\Imp\theta, \]
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   338
and creates the list $\theta'@1$, \ldots, $\theta'@k$ of meta-level
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   339
assumptions.  In these theorems, the subgoal's parameters ($x@1$,
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   340
\ldots,~$x@l$) become free variables.  It supplies the assumptions to
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   341
$tacf$ and applies the resulting tactic to the proof state
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   342
$\theta\Imp\theta$.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   343
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   344
If the resulting proof state is $\List{\phi@1; \ldots; \phi@n} \Imp \phi$,
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   345
possibly containing $\theta'@1,\ldots,\theta'@k$ as assumptions, then it is
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   346
lifted back into the original context, yielding $n$ subgoals.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   347
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   348
Meta-level assumptions may not contain unknowns.  Unknowns in
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   349
$\theta@1,\ldots,\theta@k$ become free variables in $\theta'@1$, \ldots,
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   350
$\theta'@k$, and are restored afterwards; the {\tt METAHYPS} call cannot
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   351
instantiate them.  Unknowns in $\theta$ may be instantiated.  New unknowns
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   352
in $\phi@1$, \ldots; $\phi@n$ are lifted over the parameters.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   353
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   354
Here is a typical application.  Calling {\tt hyp_res_tac}~$i$ resolves
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   355
subgoal~$i$ with one of its own assumptions, which may itself have the form
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   356
of an inference rule (these are called {\bf higher-level assumptions}).  
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   357
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   358
val hyp_res_tac = METAHYPS (fn prems => resolve_tac prems 1);
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   359
\end{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   360
\end{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   361
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   362
\begin{warn}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   363
{\tt METAHYPS} fails if the context or new subgoals contain type unknowns.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   364
In principle, the tactical could treat these like ordinary unknowns.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   365
\end{warn}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   366
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   367
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   368
\subsection{Scanning for a subgoal by number}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   369
\index{tacticals!scanning for subgoals|bold}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   370
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   371
ALLGOALS         : (int -> tactic) -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   372
TRYALL           : (int -> tactic) -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   373
SOMEGOAL         : (int -> tactic) -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   374
FIRSTGOAL        : (int -> tactic) -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   375
REPEAT_SOME      : (int -> tactic) -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   376
REPEAT_FIRST     : (int -> tactic) -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   377
trace_goalno_tac : (int -> tactic) -> int -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   378
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   379
These apply a tactic function of type {\tt int -> tactic} to all the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   380
subgoal numbers of a proof state, and join the resulting tactics using
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   381
\ttindex{THEN} or \ttindex{ORELSE}\@.  Thus, they apply the tactic to all the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   382
subgoals, or to one subgoal.  
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   383
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   384
Suppose that the original proof state has $n$ subgoals.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   385
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   386
\begin{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   387
\item[\ttindexbold{ALLGOALS} {\it tacf}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   388
is equivalent to
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   389
\hbox{\tt$tacf(n)$ THEN \ldots{} THEN $tacf(1)$}.  
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   390
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   391
It applies {\it tacf} to all the subgoals, counting {\bf downwards} (to
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   392
avoid problems when subgoals are added or deleted).
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   393
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   394
\item[\ttindexbold{TRYALL} {\it tacf}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   395
is equivalent to
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   396
\hbox{\tt TRY($tacf(n)$) THEN \ldots{} THEN TRY($tacf(1)$)}.  
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   397
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   398
It attempts to apply {\it tacf} to all the subgoals.  For instance,
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   399
\hbox{\tt TRYALL assume_tac} attempts to solve all the subgoals by
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   400
assumption.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   401
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   402
\item[\ttindexbold{SOMEGOAL} {\it tacf}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   403
is equivalent to
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   404
\hbox{\tt$tacf(n)$ ORELSE \ldots{} ORELSE $tacf(1)$}.  
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   405
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   406
It applies {\it tacf} to one subgoal, counting {\bf downwards}.  
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   407
\hbox{\tt SOMEGOAL assume_tac} solves one subgoal by assumption, failing if
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   408
this is impossible.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   409
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   410
\item[\ttindexbold{FIRSTGOAL} {\it tacf}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   411
is equivalent to
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   412
\hbox{\tt$tacf(1)$ ORELSE \ldots{} ORELSE $tacf(n)$}.  
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   413
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   414
It applies {\it tacf} to one subgoal, counting {\bf upwards}.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   415
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   416
\item[\ttindexbold{REPEAT_SOME} {\it tacf}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   417
applies {\it tacf} once or more to a subgoal, counting {\bf downwards}.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   418
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   419
\item[\ttindexbold{REPEAT_FIRST} {\it tacf}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   420
applies {\it tacf} once or more to a subgoal, counting {\bf upwards}.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   421
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   422
\item[\ttindexbold{trace_goalno_tac} {\it tac} {\it i}] 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   423
applies \hbox{\it tac i\/} to the proof state.  If the resulting sequence
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   424
is non-empty, then it is returned, with the side-effect of printing {\tt
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   425
Subgoal~$i$ selected}.  Otherwise, {\tt trace_goalno_tac} returns the empty
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   426
sequence and prints nothing.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   427
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   428
It indicates that ``the tactic worked for subgoal~$i$'' and is mainly used
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   429
with {\tt SOMEGOAL} and {\tt FIRSTGOAL}.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   430
\end{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   431
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   432
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   433
\subsection{Joining tactic functions}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   434
\index{tacticals!joining tactic functions|bold}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   435
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   436
THEN'     : ('a -> tactic) * ('a -> tactic) -> 'a -> tactic \hfill{\bf infix 1}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   437
ORELSE'   : ('a -> tactic) * ('a -> tactic) -> 'a -> tactic \hfill{\bf infix}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   438
APPEND'   : ('a -> tactic) * ('a -> tactic) -> 'a -> tactic \hfill{\bf infix}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   439
INTLEAVE' : ('a -> tactic) * ('a -> tactic) -> 'a -> tactic \hfill{\bf infix}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   440
EVERY'    : ('a -> tactic) list -> 'a -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   441
FIRST'    : ('a -> tactic) list -> 'a -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   442
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   443
These help to express tactics that specify subgoal numbers.  The tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   444
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   445
SOMEGOAL (fn i => resolve_tac rls i  ORELSE  eresolve_tac erls i)
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   446
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   447
can be simplified to
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   448
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   449
SOMEGOAL (resolve_tac rls  ORELSE'  eresolve_tac erls)
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   450
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   451
Note that {\tt TRY'}, {\tt REPEAT'}, {\tt DEPTH_FIRST'}, etc.\ are not
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   452
provided, because function composition accomplishes the same purpose.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   453
The tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   454
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   455
ALLGOALS (fn i => REPEAT (etac exE i  ORELSE  atac i))
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   456
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   457
can be simplified to
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   458
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   459
ALLGOALS (REPEAT o (etac exE  ORELSE'  atac))
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   460
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   461
These tacticals are polymorphic; $x$ need not be an integer.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   462
\begin{center} \tt
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   463
\begin{tabular}{r@{\rm\ \ yields\ \ }l}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   464
    ($tacf@1$~~THEN'~~$tacf@2$)$(x)$ \index{*THEN'} &
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   465
    $tacf@1(x)$~~THEN~~$tacf@2(x)$ \\
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   466
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   467
    ($tacf@1$ ORELSE' $tacf@2$)$(x)$ \index{*ORELSE'} &
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   468
    $tacf@1(x)$ ORELSE $tacf@2(x)$ \\
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   469
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   470
    ($tacf@1$ APPEND' $tacf@2$)$(x)$ \index{*APPEND'} &
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   471
    $tacf@1(x)$ APPEND $tacf@2(x)$ \\
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   472
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   473
    ($tacf@1$ INTLEAVE' $tacf@2$)$(x)$ \index{*INTLEAVE'} &
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   474
    $tacf@1(x)$ INTLEAVE $tacf@2(x)$ \\
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   475
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   476
    EVERY' $[tacf@1,\ldots,tacf@n] \; (x)$ \index{*EVERY'} &
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   477
    EVERY $[tacf@1(x),\ldots,tacf@n(x)]$ \\
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   478
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   479
    FIRST' $[tacf@1,\ldots,tacf@n] \; (x)$ \index{*FIRST'} &
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   480
    FIRST $[tacf@1(x),\ldots,tacf@n(x)]$
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   481
\end{tabular}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   482
\end{center}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   483
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   484
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   485
\subsection{Applying a list of tactics to 1}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   486
\index{tacticals!joining tactic functions|bold}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   487
\begin{ttbox} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   488
EVERY1: (int -> tactic) list -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   489
FIRST1: (int -> tactic) list -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   490
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   491
A common proof style is to treat the subgoals as a stack, always
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   492
restricting attention to the first subgoal.  Such proofs contain long lists
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   493
of tactics, each applied to~1.  These can be simplified using {\tt EVERY1}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   494
and {\tt FIRST1}:
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   495
\begin{center} \tt
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   496
\begin{tabular}{r@{\rm\ \ abbreviates\ \ }l}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   497
    EVERY1 $[tacf@1,\ldots,tacf@n]$ \indexbold{*EVERY1} &
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   498
    EVERY $[tacf@1(1),\ldots,tacf@n(1)]$ \\
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   499
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   500
    FIRST1 $[tacf@1,\ldots,tacf@n]$ \indexbold{*FIRST1} &
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   501
    FIRST $[tacf@1(1),\ldots,tacf@n(1)]$
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   502
\end{tabular}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   503
\end{center}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   504
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   505
\index{tacticals|)}