1 |
1 |
2 \chapter{Tacticals} |
2 \chapter{Tacticals} |
3 \index{tacticals|(} |
|
4 Tacticals are operations on tactics. Their implementation makes use of |
|
5 functional programming techniques, especially for sequences. Most of the |
|
6 time, you may forget about this and regard tacticals as high-level control |
|
7 structures. |
|
8 |
3 |
9 \section{The basic tacticals} |
4 \section{The basic tacticals} |
10 \subsection{Joining two tactics} |
|
11 \index{tacticals!joining two tactics} |
|
12 The tacticals {\tt THEN} and {\tt ORELSE}, which provide sequencing and |
|
13 alternation, underlie most of the other control structures in Isabelle. |
|
14 {\tt APPEND} and {\tt INTLEAVE} provide more sophisticated forms of |
|
15 alternation. |
|
16 \begin{ttbox} |
|
17 THEN : tactic * tactic -> tactic \hfill{\bf infix 1} |
|
18 ORELSE : tactic * tactic -> tactic \hfill{\bf infix} |
|
19 APPEND : tactic * tactic -> tactic \hfill{\bf infix} |
|
20 INTLEAVE : tactic * tactic -> tactic \hfill{\bf infix} |
|
21 \end{ttbox} |
|
22 \begin{ttdescription} |
|
23 \item[$tac@1$ \ttindexbold{THEN} $tac@2$] |
|
24 is the sequential composition of the two tactics. Applied to a proof |
|
25 state, it returns all states reachable in two steps by applying $tac@1$ |
|
26 followed by~$tac@2$. First, it applies $tac@1$ to the proof state, getting a |
|
27 sequence of next states; then, it applies $tac@2$ to each of these and |
|
28 concatenates the results. |
|
29 |
|
30 \item[$tac@1$ \ttindexbold{ORELSE} $tac@2$] |
|
31 makes a choice between the two tactics. Applied to a state, it |
|
32 tries~$tac@1$ and returns the result if non-empty; if $tac@1$ fails then it |
|
33 uses~$tac@2$. This is a deterministic choice: if $tac@1$ succeeds then |
|
34 $tac@2$ is excluded. |
|
35 |
|
36 \item[$tac@1$ \ttindexbold{APPEND} $tac@2$] |
|
37 concatenates the results of $tac@1$ and~$tac@2$. By not making a commitment |
|
38 to either tactic, {\tt APPEND} helps avoid incompleteness during |
|
39 search.\index{search} |
|
40 |
|
41 \item[$tac@1$ \ttindexbold{INTLEAVE} $tac@2$] |
|
42 interleaves the results of $tac@1$ and~$tac@2$. Thus, it includes all |
|
43 possible next states, even if one of the tactics returns an infinite |
|
44 sequence. |
|
45 \end{ttdescription} |
|
46 |
|
47 |
|
48 \subsection{Joining a list of tactics} |
|
49 \index{tacticals!joining a list of tactics} |
|
50 \begin{ttbox} |
|
51 EVERY : tactic list -> tactic |
|
52 FIRST : tactic list -> tactic |
|
53 \end{ttbox} |
|
54 {\tt EVERY} and {\tt FIRST} are block structured versions of {\tt THEN} and |
|
55 {\tt ORELSE}\@. |
|
56 \begin{ttdescription} |
|
57 \item[\ttindexbold{EVERY} {$[tac@1,\ldots,tac@n]$}] |
|
58 abbreviates \hbox{\tt$tac@1$ THEN \ldots{} THEN $tac@n$}. It is useful for |
|
59 writing a series of tactics to be executed in sequence. |
|
60 |
|
61 \item[\ttindexbold{FIRST} {$[tac@1,\ldots,tac@n]$}] |
|
62 abbreviates \hbox{\tt$tac@1$ ORELSE \ldots{} ORELSE $tac@n$}. It is useful for |
|
63 writing a series of tactics to be attempted one after another. |
|
64 \end{ttdescription} |
|
65 |
|
66 |
5 |
67 \subsection{Repetition tacticals} |
6 \subsection{Repetition tacticals} |
68 \index{tacticals!repetition} |
7 \index{tacticals!repetition} |
69 \begin{ttbox} |
8 \begin{ttbox} |
70 TRY : tactic -> tactic |
9 TRY : tactic -> tactic |
126 Thus, it succeeds for all states. It is the identity element of the |
65 Thus, it succeeds for all states. It is the identity element of the |
127 tactical \ttindex{THEN}\@. |
66 tactical \ttindex{THEN}\@. |
128 |
67 |
129 \item[\ttindexbold{no_tac}] |
68 \item[\ttindexbold{no_tac}] |
130 maps any proof state to the empty sequence. Thus it succeeds for no state. |
69 maps any proof state to the empty sequence. Thus it succeeds for no state. |
131 It is the identity element of \ttindex{ORELSE}, \ttindex{APPEND}, and |
70 It is the identity element of \ttindex{ORELSE}, and |
132 \ttindex{INTLEAVE}\@. Also, it is a zero element for \ttindex{THEN}, which means that |
71 \ttindex{APPEND}\@. Also, it is a zero element for \ttindex{THEN}, |
|
72 which means that |
|
73 |
133 \hbox{\tt$tac$ THEN no_tac} is equivalent to {\tt no_tac}. |
74 \hbox{\tt$tac$ THEN no_tac} is equivalent to {\tt no_tac}. |
134 \end{ttdescription} |
75 \end{ttdescription} |
135 These primitive tactics are useful when writing tacticals. For example, |
76 These primitive tactics are useful when writing tacticals. For example, |
136 \ttindexbold{TRY} and \ttindexbold{REPEAT} (ignoring tracing) can be coded |
77 \ttindexbold{TRY} and \ttindexbold{REPEAT} (ignoring tracing) can be coded |
137 as follows: |
78 as follows: |
140 |
81 |
141 fun REPEAT tac = |
82 fun REPEAT tac = |
142 (fn state => ((tac THEN REPEAT tac) ORELSE all_tac) state); |
83 (fn state => ((tac THEN REPEAT tac) ORELSE all_tac) state); |
143 \end{ttbox} |
84 \end{ttbox} |
144 If $tac$ can return multiple outcomes then so can \hbox{\tt REPEAT $tac$}. |
85 If $tac$ can return multiple outcomes then so can \hbox{\tt REPEAT $tac$}. |
145 Since {\tt REPEAT} uses \ttindex{ORELSE} and not {\tt APPEND} or {\tt |
86 Since {\tt REPEAT} uses \ttindex{ORELSE} and not {\tt APPEND}, it |
146 INTLEAVE}, it applies $tac$ as many times as possible in each |
87 applies $tac$ as many times as possible in each outcome. |
147 outcome. |
|
148 |
88 |
149 \begin{warn} |
89 \begin{warn} |
150 Note {\tt REPEAT}'s explicit abstraction over the proof state. Recursive |
90 Note {\tt REPEAT}'s explicit abstraction over the proof state. Recursive |
151 tacticals must be coded in this awkward fashion to avoid infinite |
91 tacticals must be coded in this awkward fashion to avoid infinite |
152 recursion. With the following definition, \hbox{\tt REPEAT $tac$} would |
92 recursion. With the following definition, \hbox{\tt REPEAT $tac$} would |
427 |
367 |
428 It indicates that `the tactic worked for subgoal~$i$' and is mainly used |
368 It indicates that `the tactic worked for subgoal~$i$' and is mainly used |
429 with {\tt SOMEGOAL} and {\tt FIRSTGOAL}. |
369 with {\tt SOMEGOAL} and {\tt FIRSTGOAL}. |
430 \end{ttdescription} |
370 \end{ttdescription} |
431 |
371 |
432 |
|
433 \subsection{Joining tactic functions} |
|
434 \index{tacticals!joining tactic functions} |
|
435 \begin{ttbox} |
|
436 THEN' : ('a -> tactic) * ('a -> tactic) -> 'a -> tactic \hfill{\bf infix 1} |
|
437 ORELSE' : ('a -> tactic) * ('a -> tactic) -> 'a -> tactic \hfill{\bf infix} |
|
438 APPEND' : ('a -> tactic) * ('a -> tactic) -> 'a -> tactic \hfill{\bf infix} |
|
439 INTLEAVE' : ('a -> tactic) * ('a -> tactic) -> 'a -> tactic \hfill{\bf infix} |
|
440 EVERY' : ('a -> tactic) list -> 'a -> tactic |
|
441 FIRST' : ('a -> tactic) list -> 'a -> tactic |
|
442 \end{ttbox} |
|
443 These help to express tactics that specify subgoal numbers. The tactic |
|
444 \begin{ttbox} |
|
445 SOMEGOAL (fn i => resolve_tac rls i ORELSE eresolve_tac erls i) |
|
446 \end{ttbox} |
|
447 can be simplified to |
|
448 \begin{ttbox} |
|
449 SOMEGOAL (resolve_tac rls ORELSE' eresolve_tac erls) |
|
450 \end{ttbox} |
|
451 Note that {\tt TRY'}, {\tt REPEAT'}, {\tt DEPTH_FIRST'}, etc.\ are not |
|
452 provided, because function composition accomplishes the same purpose. |
|
453 The tactic |
|
454 \begin{ttbox} |
|
455 ALLGOALS (fn i => REPEAT (etac exE i ORELSE atac i)) |
|
456 \end{ttbox} |
|
457 can be simplified to |
|
458 \begin{ttbox} |
|
459 ALLGOALS (REPEAT o (etac exE ORELSE' atac)) |
|
460 \end{ttbox} |
|
461 These tacticals are polymorphic; $x$ need not be an integer. |
|
462 \begin{center} \tt |
|
463 \begin{tabular}{r@{\rm\ \ yields\ \ }l} |
|
464 $(tacf@1$~~THEN'~~$tacf@2)(x)$ \index{*THEN'} & |
|
465 $tacf@1(x)$~~THEN~~$tacf@2(x)$ \\ |
|
466 |
|
467 $(tacf@1$ ORELSE' $tacf@2)(x)$ \index{*ORELSE'} & |
|
468 $tacf@1(x)$ ORELSE $tacf@2(x)$ \\ |
|
469 |
|
470 $(tacf@1$ APPEND' $tacf@2)(x)$ \index{*APPEND'} & |
|
471 $tacf@1(x)$ APPEND $tacf@2(x)$ \\ |
|
472 |
|
473 $(tacf@1$ INTLEAVE' $tacf@2)(x)$ \index{*INTLEAVE'} & |
|
474 $tacf@1(x)$ INTLEAVE $tacf@2(x)$ \\ |
|
475 |
|
476 EVERY' $[tacf@1,\ldots,tacf@n] \; (x)$ \index{*EVERY'} & |
|
477 EVERY $[tacf@1(x),\ldots,tacf@n(x)]$ \\ |
|
478 |
|
479 FIRST' $[tacf@1,\ldots,tacf@n] \; (x)$ \index{*FIRST'} & |
|
480 FIRST $[tacf@1(x),\ldots,tacf@n(x)]$ |
|
481 \end{tabular} |
|
482 \end{center} |
|
483 |
|
484 |
|
485 \subsection{Applying a list of tactics to 1} |
|
486 \index{tacticals!joining tactic functions} |
|
487 \begin{ttbox} |
|
488 EVERY1: (int -> tactic) list -> tactic |
|
489 FIRST1: (int -> tactic) list -> tactic |
|
490 \end{ttbox} |
|
491 A common proof style is to treat the subgoals as a stack, always |
|
492 restricting attention to the first subgoal. Such proofs contain long lists |
|
493 of tactics, each applied to~1. These can be simplified using {\tt EVERY1} |
|
494 and {\tt FIRST1}: |
|
495 \begin{center} \tt |
|
496 \begin{tabular}{r@{\rm\ \ abbreviates\ \ }l} |
|
497 EVERY1 $[tacf@1,\ldots,tacf@n]$ \indexbold{*EVERY1} & |
|
498 EVERY $[tacf@1(1),\ldots,tacf@n(1)]$ \\ |
|
499 |
|
500 FIRST1 $[tacf@1,\ldots,tacf@n]$ \indexbold{*FIRST1} & |
|
501 FIRST $[tacf@1(1),\ldots,tacf@n(1)]$ |
|
502 \end{tabular} |
|
503 \end{center} |
|
504 |
|
505 \index{tacticals|)} |
372 \index{tacticals|)} |
506 |
373 |
507 |
374 |
508 %%% Local Variables: |
375 %%% Local Variables: |
509 %%% mode: latex |
376 %%% mode: latex |