CookBook/Tactical.thy
changeset 108 8bea3f74889d
parent 107 258ce361ba1b
child 109 b4234e8a0202
equal deleted inserted replaced
107:258ce361ba1b 108:8bea3f74889d
    19 
    19 
    20 section {* Basics of Reasoning with Tactics*}
    20 section {* Basics of Reasoning with Tactics*}
    21 
    21 
    22 text {*
    22 text {*
    23   To see how tactics work, let us first transcribe a simple \isacommand{apply}-style proof 
    23   To see how tactics work, let us first transcribe a simple \isacommand{apply}-style proof 
    24   into ML. Consider the following proof.
    24   into ML. Suppose the following proof.
    25 *}
    25 *}
    26 
    26 
    27 lemma disj_swap: "P \<or> Q \<Longrightarrow> Q \<or> P"
    27 lemma disj_swap: "P \<or> Q \<Longrightarrow> Q \<or> P"
    28 apply(erule disjE)
    28 apply(erule disjE)
    29 apply(rule disjI2)
    29 apply(rule disjI2)
    60   @{text erule}, @{text rule} and @{text assumption}, respectively. 
    60   @{text erule}, @{text rule} and @{text assumption}, respectively. 
    61   The operator @{ML THEN} strings the tactics together. 
    61   The operator @{ML THEN} strings the tactics together. 
    62 
    62 
    63   \begin{readmore}
    63   \begin{readmore}
    64   To learn more about the function @{ML Goal.prove} see \isccite{sec:results}
    64   To learn more about the function @{ML Goal.prove} see \isccite{sec:results}
    65   and the file @{ML_file "Pure/goal.ML"}. For more information about the
    65   and the file @{ML_file "Pure/goal.ML"}.  See @{ML_file
    66   internals of goals see \isccite{sec:tactical-goals}.  See @{ML_file
       
    67   "Pure/tactic.ML"} and @{ML_file "Pure/tctical.ML"} for the code of basic
    66   "Pure/tactic.ML"} and @{ML_file "Pure/tctical.ML"} for the code of basic
    68   tactics and tactic combinators; see also Chapters 3 and 4 in the old
    67   tactics and tactic combinators; see also Chapters 3 and 4 in the old
    69   Isabelle Reference Manual.
    68   Isabelle Reference Manual.
    70   \end{readmore}
    69   \end{readmore}
    71 
    70 
    72   Note that we used antiquotations for referencing the theorems. Many theorems
    71   Note that in the code above we used antiquotations for referencing the theorems. Many theorems
    73   also have ML-bindings with the same name. Therefore, we could also just have
    72   also have ML-bindings with the same name. Therefore, we could also just have
    74   written @{ML "etac disjE 1"}, or in case there are no ML-binding obtained
    73   written @{ML "etac disjE 1"}, or in case there are no ML-binding obtained
    75   the theorem dynamically using the function @{ML thm}; for example 
    74   the theorem dynamically using the function @{ML thm}; for example 
    76   @{ML "etac (thm \"disjE\") 1"}. Both ways however are considered bad style. 
    75   @{ML "etac (thm \"disjE\") 1"}. Both ways however are considered bad style! 
    77   The reason
    76   The reason
    78   is that the binding for @{ML disjE} can be re-assigned by the user and thus
    77   is that the binding for @{ML disjE} can be re-assigned by the user and thus
    79   one does not have complete control over which theorem is actually
    78   one does not have complete control over which theorem is actually
    80   applied. This problem is nicely prevented by using antiquotations, because
    79   applied. This problem is nicely prevented by using antiquotations, because
    81   then the theorems are fixed statically at compile-time.
    80   then the theorems are fixed statically at compile-time.
   131 apply(tactic {* foo_tac' 1 *})
   130 apply(tactic {* foo_tac' 1 *})
   132 done
   131 done
   133 
   132 
   134 text {*
   133 text {*
   135   This kind of addressing is more difficult to achieve when the goal is 
   134   This kind of addressing is more difficult to achieve when the goal is 
   136   hard-coded inside the tactic. For every operator that combines tactics 
   135   hard-coded inside the tactic. For most operators that combine tactics 
   137   (@{ML THEN} is only one such operator) a ``primed'' version exists.
   136   (@{ML THEN} is only one such operator) a ``primed'' version exists.
   138 
   137 
   139   The tactics @{ML foo_tac} and @{ML foo_tac'} are very specific for
   138   The tactics @{ML foo_tac} and @{ML foo_tac'} are very specific for
   140   analysing goals being only of the form @{prop "P \<or> Q \<Longrightarrow> Q \<or> P"}. If the goal is not
   139   analysing goals being only of the form @{prop "P \<or> Q \<Longrightarrow> Q \<or> P"}. If the goal is not
   141   of this form, then they throw the error message:
   140   of this form, then they throw the error message:
   173   which means it always succeeds (but also does not make any progress 
   172   which means it always succeeds (but also does not make any progress 
   174   with the proof).
   173   with the proof).
   175 
   174 
   176   The lazy list of possible successor states shows through at the user-level 
   175   The lazy list of possible successor states shows through at the user-level 
   177   of Isabelle when using the command \isacommand{back}. For instance in the 
   176   of Isabelle when using the command \isacommand{back}. For instance in the 
   178   following proof, there are two possibilities for how to apply 
   177   following proof there are two possibilities for how to apply 
   179   @{ML foo_tac'}: either using the first assumption or the second.
   178   @{ML foo_tac'}: either using the first assumption or the second.
   180 *}
   179 *}
   181 
   180 
   182 lemma "\<lbrakk>P \<or> Q; P \<or> Q\<rbrakk> \<Longrightarrow> Q \<or> P"
   181 lemma "\<lbrakk>P \<or> Q; P \<or> Q\<rbrakk> \<Longrightarrow> Q \<or> P"
   183 apply(tactic {* foo_tac' 1 *})
   182 apply(tactic {* foo_tac' 1 *})
   213  end*}
   212  end*}
   214 
   213 
   215 text {*
   214 text {*
   216   which prints out the given theorem (using the string-function defined 
   215   which prints out the given theorem (using the string-function defined 
   217   in Section~\ref{sec:printing}) and then behaves like @{ML all_tac}. We
   216   in Section~\ref{sec:printing}) and then behaves like @{ML all_tac}. We
   218   are now in the position to inspect every proof state in a proof. Consider 
   217   are now in the position to inspect every goal state in a proof. Consider 
   219   the proof below: on the left-hand side we show the goal state as shown 
   218   the proof below: on the left-hand side we show the goal state as shown 
   220   by Isabelle, on the right-hand side the print out from @{ML my_print_tac}.
   219   by Isabelle, on the right-hand side the print out from @{ML my_print_tac}.
   221 *}
   220 *}
   222 
   221 
   223 lemma shows "\<lbrakk>A; B\<rbrakk> \<Longrightarrow> A \<and> B" 
   222 lemma shows "\<lbrakk>A; B\<rbrakk> \<Longrightarrow> A \<and> B" 
   224 apply(tactic {* my_print_tac @{context} *})
   223 apply(tactic {* my_print_tac @{context} *})
   225 
   224 
   226 txt{* \small 
   225 txt{* \small 
   227       \begin{tabular}{@ {}l@ {}p{0.7\textwidth}@ {}}
   226       \begin{tabularstar}{\textwidth}{@ {}l@ {\extracolsep{\fill}}l@ {}}
   228       \begin{minipage}[t]{0.3\textwidth}
   227       \begin{minipage}[t]{0.3\textwidth}
   229       @{subgoals [display]} 
   228       @{subgoals [display]} 
   230       \end{minipage} &
   229       \end{minipage} &
   231       \hfill@{text "(\<lbrakk>A; B\<rbrakk> \<Longrightarrow> A \<and> B) \<Longrightarrow> (\<lbrakk>A; B\<rbrakk> \<Longrightarrow> A \<and> B)"}
   230       @{text "(\<lbrakk>A; B\<rbrakk> \<Longrightarrow> A \<and> B) \<Longrightarrow> (\<lbrakk>A; B\<rbrakk> \<Longrightarrow> A \<and> B)"}
   232       \end{tabular}
   231       \end{tabularstar}
   233 *}
   232 *}
   234 
   233 
   235 apply(rule conjI)
   234 apply(rule conjI)
   236 apply(tactic {* my_print_tac @{context} *})
   235 apply(tactic {* my_print_tac @{context} *})
   237 
   236 
   238 txt{* \small 
   237 txt{* \small 
   239       \begin{tabular}{@ {}l@ {}p{0.76\textwidth}@ {}}
   238       \begin{tabularstar}{\textwidth}{@ {}l@ {\extracolsep{\fill}}l@ {}}
   240       \begin{minipage}[t]{0.26\textwidth}
   239       \begin{minipage}[t]{0.26\textwidth}
   241       @{subgoals [display]} 
   240       @{subgoals [display]} 
   242       \end{minipage} &
   241       \end{minipage} &
   243       \hfill@{text "(\<lbrakk>A; B\<rbrakk> \<Longrightarrow> A) \<Longrightarrow> (\<lbrakk>A; B\<rbrakk> \<Longrightarrow> B) \<Longrightarrow> (\<lbrakk>A; B\<rbrakk> \<Longrightarrow> A \<and> B)"}
   242       @{text "(\<lbrakk>A; B\<rbrakk> \<Longrightarrow> A) \<Longrightarrow> (\<lbrakk>A; B\<rbrakk> \<Longrightarrow> B) \<Longrightarrow> (\<lbrakk>A; B\<rbrakk> \<Longrightarrow> A \<and> B)"}
   244       \end{tabular}
   243       \end{tabularstar}
   245 *}
   244 *}
   246 
   245 
   247 apply(assumption)
   246 apply(assumption)
   248 apply(tactic {* my_print_tac @{context} *})
   247 apply(tactic {* my_print_tac @{context} *})
   249 
   248 
   250 txt{* \small 
   249 txt{* \small 
   251       \begin{tabular}{@ {}l@ {}p{0.7\textwidth}@ {}}
   250       \begin{tabularstar}{\textwidth}{@ {}l@ {\extracolsep{\fill}}l@ {}}
   252       \begin{minipage}[t]{0.3\textwidth}
   251       \begin{minipage}[t]{0.3\textwidth}
   253       @{subgoals [display]} 
   252       @{subgoals [display]} 
   254       \end{minipage} &
   253       \end{minipage} &
   255       \hfill@{text "(\<lbrakk>A; B\<rbrakk> \<Longrightarrow> B) \<Longrightarrow> (\<lbrakk>A; B\<rbrakk> \<Longrightarrow> A \<and> B)"}
   254       @{text "(\<lbrakk>A; B\<rbrakk> \<Longrightarrow> B) \<Longrightarrow> (\<lbrakk>A; B\<rbrakk> \<Longrightarrow> A \<and> B)"}
   256       \end{tabular}
   255       \end{tabularstar}
   257 *}
   256 *}
   258 
   257 
   259 apply(assumption)
   258 apply(assumption)
   260 apply(tactic {* my_print_tac @{context} *})
   259 apply(tactic {* my_print_tac @{context} *})
   261 
   260 
   262 txt{* \small 
   261 txt{* \small 
   263       \begin{tabular}{@ {}l@ {}p{0.7\textwidth}@ {}}
   262       \begin{tabularstar}{\textwidth}{@ {}l@ {\extracolsep{\fill}}l@ {}}
   264       \begin{minipage}[t]{0.3\textwidth}
   263       \begin{minipage}[t]{0.3\textwidth}
   265       @{subgoals [display]} 
   264       @{subgoals [display]} 
   266       \end{minipage} &
   265       \end{minipage} &
   267       \hfill@{text "\<lbrakk>A; B\<rbrakk> \<Longrightarrow> A \<and> B"}
   266       @{text "\<lbrakk>A; B\<rbrakk> \<Longrightarrow> A \<and> B"}
   268       \end{tabular}
   267       \end{tabularstar}
   269 *}
   268 *}
   270 
   269 
   271 done
   270 done
   272 
   271 
   273 text {*
   272 text {*
   275 
   274 
   276   @{text[display] "A\<^isub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^isub>n \<Longrightarrow> (C)"}
   275   @{text[display] "A\<^isub>1 \<Longrightarrow> \<dots> \<Longrightarrow> A\<^isub>n \<Longrightarrow> (C)"}
   277 
   276 
   278   where @{term C} is the goal to be proved and the @{term "A\<^isub>i"} are the  
   277   where @{term C} is the goal to be proved and the @{term "A\<^isub>i"} are the  
   279   subgoals. So after setting up the lemma, the goal state is always of the form
   278   subgoals. So after setting up the lemma, the goal state is always of the form
   280   @{text "C \<Longrightarrow> (C)"}, and when the proof is finished we are left with @{text "(C)"}. 
   279   @{text "C \<Longrightarrow> (C)"}; when the proof is finished we are left with @{text "(C)"}. 
   281   Since the goal @{term C} can potentially be an implication, 
   280   Since the goal @{term C} can potentially be an implication, 
   282   there is a ``protector'' wrapped around it (in from of an outermost constant 
   281   there is a ``protector'' wrapped around it (in from of an outermost constant 
   283   @{text "Const (\"prop\", bool \<Rightarrow> bool)"} applied to each goal;
   282   @{text "Const (\"prop\", bool \<Rightarrow> bool)"} applied to each goal;
   284   however this constant is invisible in the print out above). This 
   283   however this constant is invisible in the print out above). This 
   285   prevents that premises of @{text C} are mis-interpreted as open subgoals. 
   284   prevents that premises of @{text C} are mis-interpreted as open subgoals. 
   286   While tactics can operate on the subgoals (the @{text "A\<^isub>i"} above), they 
   285   While tactics can operate on the subgoals (the @{text "A\<^isub>i"} above), they 
   287   are expected to leave the conclusion @{term C} intact, with the 
   286   are expected to leave the conclusion @{term C} intact, with the 
   288   exception of possibly instantiating schematic variables. 
   287   exception of possibly instantiating schematic variables. If you use
       
   288   the predefined tactics, this will always be the case. 
   289  
   289  
       
   290   \begin{readmore}
       
   291   For more information about the internals of goals see \isccite{sec:tactical-goals}.
       
   292   \end{readmore}
       
   293 
   290 *}
   294 *}
   291 
   295 
   292 section {* Simple Tactics *}
   296 section {* Simple Tactics *}
   293 
   297 
   294 text {*
   298 text {*
   394      \end{minipage}*}
   398      \end{minipage}*}
   395 (*<*)oops(*>*)
   399 (*<*)oops(*>*)
   396 
   400 
   397 text {*
   401 text {*
   398   Since rules are applied using higher-order unification, an automatic proof
   402   Since rules are applied using higher-order unification, an automatic proof
   399   procedure might become too fragile, if it just applies inference rules shown
   403   procedure might become too fragile, if it just applies inference rules as 
   400   in the fashion above.  More constraints can be introduced by
   404   shown above. The reason is that a number of rules introduce meta-variables 
   401   pre-instantiating theorems with other theorems. You can do this using the
   405   into the goal state. Consider for example the proof
   402   function @{ML RS}. For example
   406 *}
       
   407 
       
   408 lemma shows "\<forall>x\<in>A. P x \<Longrightarrow> Q x"
       
   409 apply(drule bspec)
       
   410 txt{*\begin{minipage}{\textwidth}
       
   411      @{subgoals [display]} 
       
   412      \end{minipage}*}
       
   413 (*<*)oops(*>*)
       
   414 
       
   415 text {*
       
   416   where the application of @{text bspec} results into two subgoals involving the
       
   417   meta-variable @{text "?x"}. The point is that if you are not careful, tactics 
       
   418   applied to the first subgoal might instantiate this meta-variable in such a 
       
   419   way that the second subgoal becomes unprovable. If it is clear what the @{text "?x"}
       
   420   should be, then this situation can be avoided by introducing a more
       
   421   constraint version of the @{text bspec}-rule. Such constraints can be enforced by
       
   422   pre-instantiating theorems with other theorems, for example by using the
       
   423   function @{ML RS}
   403   
   424   
   404   @{ML_response_fake [display,gray]
   425   @{ML_response_fake [display,gray]
   405   "@{thm disjI1} RS @{thm conjI}" "\<lbrakk>?P1; ?Q\<rbrakk> \<Longrightarrow> (?P1 \<or> ?Q1) \<and> ?Q"}
   426   "@{thm disjI1} RS @{thm conjI}" "\<lbrakk>?P1; ?Q\<rbrakk> \<Longrightarrow> (?P1 \<or> ?Q1) \<and> ?Q"}
   406 
   427 
   407   instantiates the first premise of the @{text conjI}-rule with the
   428   which, for instance, instantiates the first premise of the @{text conjI}-rule 
   408   rule @{text disjI1}. If this is impossible, as in the case of
   429   with the rule @{text disjI1}. If this is impossible, as in the case of
   409 
   430 
   410   @{ML_response_fake_both [display,gray]
   431   @{ML_response_fake_both [display,gray]
   411   "@{thm conjI} RS @{thm mp}" 
   432   "@{thm conjI} RS @{thm mp}" 
   412 "*** Exception- THM (\"RSN: no unifiers\", 1, 
   433 "*** Exception- THM (\"RSN: no unifiers\", 1, 
   413 [\"\<lbrakk>?P; ?Q\<rbrakk> \<Longrightarrow> ?P \<and> ?Q\", \"\<lbrakk>?P \<longrightarrow> ?Q; ?P\<rbrakk> \<Longrightarrow> ?Q\"]) raised"}
   434 [\"\<lbrakk>?P; ?Q\<rbrakk> \<Longrightarrow> ?P \<and> ?Q\", \"\<lbrakk>?P \<longrightarrow> ?Q; ?P\<rbrakk> \<Longrightarrow> ?Q\"]) raised"}
   611    | @{term "Not"} $ _ => rtac @{thm notI} i
   632    | @{term "Not"} $ _ => rtac @{thm notI} i
   612    | Const (@{const_name "All"}, _) $ _ => rtac @{thm allI} i
   633    | Const (@{const_name "All"}, _) $ _ => rtac @{thm allI} i
   613    | _ => all_tac*}
   634    | _ => all_tac*}
   614 
   635 
   615 text {*
   636 text {*
   616   In line 3 you need to decend under the outermost @{term "Trueprop"} in order
   637   In line 3 you need to descend under the outermost @{term "Trueprop"} in order
   617   to get to the connective you like to analyse. Otherwise goals like @{prop "A \<and> B"} 
   638   to get to the connective you like to analyse. Otherwise goals like @{prop "A \<and> B"} 
   618   are not properly analysed. While for the first four pattern we can use the 
   639   are not properly analysed. While for the first four pattern we can use the 
   619   @{text "@term"}-antiquotation, the pattern in Line 7 cannot be constructed
   640   @{text "@term"}-antiquotation, the pattern in Line 7 cannot be constructed
   620   in this way. The reason is that an antiquotation would fix the type of the 
   641   in this way. The reason is that an antiquotation would fix the type of the 
   621   quantified variable. So you really have to construct the pattern
   642   quantified variable. So you really have to construct the pattern
   622   using the term-constructors. This is not necessary in  other cases, because 
   643   using the term-constructors. This is not necessary in  other cases, because 
   623   their type is always something involving @{typ bool}. The final patter is 
   644   their type is always something involving @{typ bool}. The final patter is 
   624   for the case where the goal does not fall into any of the categorories before.
   645   for the case where the goal does not fall into any of the categories before.
   625   In this case we chose to just return @{ML all_tac} (i.e., @{ML select_tac} 
   646   In this case we chose to just return @{ML all_tac} (i.e., @{ML select_tac} 
   626   never fails). 
   647   never fails). 
   627 
   648 
   628   Let us now see how to apply this tactic. Consider the four goals:
   649   Let us now see how to apply this tactic. Consider the four goals:
   629 *}
   650 *}
   641 
   662 
   642 text {*
   663 text {*
   643   where in all but the last the tactic applied an introduction rule. 
   664   where in all but the last the tactic applied an introduction rule. 
   644   Note that we applied the tactic to subgoals in ``reverse'' order. 
   665   Note that we applied the tactic to subgoals in ``reverse'' order. 
   645   This is a trick in order to be independent from what subgoals are 
   666   This is a trick in order to be independent from what subgoals are 
   646   that are produced by the rule. If we had it applied in the other order 
   667   that are produced by the rule. If we had applied it in the other order 
   647 *}
   668 *}
   648 
   669 
   649 lemma shows "A \<and> B" and "A \<longrightarrow> B \<longrightarrow>C" and "\<forall>x. D x" and "E \<Longrightarrow> F"
   670 lemma shows "A \<and> B" and "A \<longrightarrow> B \<longrightarrow>C" and "\<forall>x. D x" and "E \<Longrightarrow> F"
   650 apply(tactic {* SUBGOAL select_tac 1 *})
   671 apply(tactic {* SUBGOAL select_tac 1 *})
   651 apply(tactic {* SUBGOAL select_tac 3 *})
   672 apply(tactic {* SUBGOAL select_tac 3 *})
   657   then we have to be careful to not apply the tactic to the two subgoals the
   678   then we have to be careful to not apply the tactic to the two subgoals the
   658   first goal produced. To do this can result in quite messy code. In contrast, 
   679   first goal produced. To do this can result in quite messy code. In contrast, 
   659   the ``reverse application'' is easy to implement.
   680   the ``reverse application'' is easy to implement.
   660 
   681 
   661   However, this example is very contrived: there are much simpler methods to implement
   682   However, this example is very contrived: there are much simpler methods to implement
   662   such a proof procedure analying a goal according to its topmost
   683   such a proof procedure analysing a goal according to its topmost
   663   connective. These simpler methods use tactic combinators which will be explained 
   684   connective. These simpler methods use tactic combinators which will be explained 
   664   in the next section.
   685   in the next section.
   665 *}
   686 *}
   666 
   687 
   667 section {* Tactic Combinators *}
   688 section {* Tactic Combinators *}
   668 
   689 
   669 text {* 
   690 text {* 
   670   The purpose of tactic combinators is to build powerful tactics out of
   691   The purpose of tactic combinators is to build powerful tactics out of
   671   smaller components. In the previous section we already used @{ML THEN} which
   692   smaller components. In the previous section we already used @{ML THEN}, which
   672   strings two tactics together in sequence. For example:
   693   strings two tactics together in sequence. For example:
   673 *}
   694 *}
   674 
   695 
   675 lemma shows "(Foo \<and> Bar) \<and> False"
   696 lemma shows "(Foo \<and> Bar) \<and> False"
   676 apply(tactic {* rtac @{thm conjI} 1 THEN rtac @{thm conjI} 1 *})
   697 apply(tactic {* rtac @{thm conjI} 1 THEN rtac @{thm conjI} 1 *})
   679        \end{minipage} *}
   700        \end{minipage} *}
   680 (*<*)oops(*>*)
   701 (*<*)oops(*>*)
   681 
   702 
   682 text {*
   703 text {*
   683   If you want to avoid the hard-coded subgoal addressing, then you can use
   704   If you want to avoid the hard-coded subgoal addressing, then you can use
   684   the ``primed'' version of @{ML THEN}, namely @{ML THEN'}. For example:
   705   the ``primed'' version of @{ML THEN}. For example:
   685 *}
   706 *}
   686 
   707 
   687 lemma shows "(Foo \<and> Bar) \<and> False"
   708 lemma shows "(Foo \<and> Bar) \<and> False"
   688 apply(tactic {* (rtac @{thm conjI} THEN' rtac @{thm conjI}) 1 *})
   709 apply(tactic {* (rtac @{thm conjI} THEN' rtac @{thm conjI}) 1 *})
   689 txt {* \begin{minipage}{\textwidth}
   710 txt {* \begin{minipage}{\textwidth}
   696   in what follows we will usually prefer it over the ``unprimed'' one. 
   717   in what follows we will usually prefer it over the ``unprimed'' one. 
   697 
   718 
   698   If there is a list of tactics that should all be tried out in 
   719   If there is a list of tactics that should all be tried out in 
   699   sequence, you can use the combinator @{ML EVERY'}. For example
   720   sequence, you can use the combinator @{ML EVERY'}. For example
   700   the function @{ML foo_tac'} from page~\ref{tac:footacprime} can also 
   721   the function @{ML foo_tac'} from page~\ref{tac:footacprime} can also 
   701   be written as
   722   be written as:
   702 *}
   723 *}
   703 
   724 
   704 ML{*val foo_tac'' = EVERY' [etac @{thm disjE}, rtac @{thm disjI2}, 
   725 ML{*val foo_tac'' = EVERY' [etac @{thm disjE}, rtac @{thm disjI2}, 
   705                         atac, rtac @{thm disjI1}, atac]*}
   726                         atac, rtac @{thm disjI1}, atac]*}
   706 
   727 
   707 text {*
   728 text {*
   708   There is even another variant for @{ML foo_tac''}: in automatic proof
   729   There is even another way: in automatic proof procedures (in contrast to
   709   procedures (in contrast to tactics that might be called by the user) 
   730   tactics that might be called by the user) there are often long lists of
   710   there are often long lists of tactics that are applied to the first
   731   tactics that are applied to the first subgoal. Instead of writing the code
   711   subgoal. Instead of writing the code above and then calling 
   732   above and then calling @{ML "foo_tac'' 1"}, you can also just write
   712   @{ML "foo_tac'' 1"}, you can also just write
       
   713 *}
   733 *}
   714 
   734 
   715 ML{*val foo_tac1 = EVERY1 [etac @{thm disjE}, rtac @{thm disjI2}, 
   735 ML{*val foo_tac1 = EVERY1 [etac @{thm disjE}, rtac @{thm disjI2}, 
   716                          atac, rtac @{thm disjI1}, atac]*}
   736                        atac, rtac @{thm disjI1}, atac]*}
   717 
   737 
   718 text {*
   738 text {*
   719   With the combinators @{ML THEN'}, @{ML EVERY'} and @{ML EVERY1} it must be 
   739   With the combinators @{ML THEN'}, @{ML EVERY'} and @{ML EVERY1} it must be 
   720   guaranteed that  all component tactics sucessfully apply; otherwise the 
   740   guaranteed that  all component tactics successfully apply; otherwise the 
   721   whole tactic will fail. If you rather want to try out a number of tactics, 
   741   whole tactic will fail. If you rather want to try out a number of tactics, 
   722   then you can use the combinator @{ML ORELSE'} for two tactics and @{ML FIRST'} 
   742   then you can use the combinator @{ML ORELSE'} for two tactics, and @{ML FIRST'} 
   723   (or @{ML FIRST1}) for a list of tactics. For example, the tactic
   743   (or @{ML FIRST1}) for a list of tactics. For example, the tactic
   724 *}
   744 *}
   725 
   745 
   726 ML{*val orelse_xmp = (rtac @{thm disjI1} ORELSE' rtac @{thm conjI})*}
   746 ML{*val orelse_xmp = (rtac @{thm disjI1} ORELSE' rtac @{thm conjI})*}
   727 
   747 
   729   will first try out whether rule @{text disjI} applies and after that 
   749   will first try out whether rule @{text disjI} applies and after that 
   730   whether @{text conjI}. To see this consider the proof:
   750   whether @{text conjI}. To see this consider the proof:
   731 *}
   751 *}
   732 
   752 
   733 lemma shows "True \<and> False" and "Foo \<or> Bar"
   753 lemma shows "True \<and> False" and "Foo \<or> Bar"
       
   754 apply(tactic {* orelse_xmp 2 *})
   734 apply(tactic {* orelse_xmp 1 *})
   755 apply(tactic {* orelse_xmp 1 *})
   735 apply(tactic {* orelse_xmp 3 *})
       
   736 txt {* which results in the goal state
   756 txt {* which results in the goal state
   737 
   757 
   738        \begin{minipage}{\textwidth}
   758        \begin{minipage}{\textwidth}
   739        @{subgoals [display]} 
   759        @{subgoals [display]} 
   740        \end{minipage}
   760        \end{minipage}
   749 
   769 
   750 ML{*val select_tac' = FIRST' [rtac @{thm conjI}, rtac @{thm impI}, 
   770 ML{*val select_tac' = FIRST' [rtac @{thm conjI}, rtac @{thm impI}, 
   751                           rtac @{thm notI}, rtac @{thm allI}, K all_tac]*}
   771                           rtac @{thm notI}, rtac @{thm allI}, K all_tac]*}
   752 
   772 
   753 text {*
   773 text {*
   754   Since we like to mimic the bahaviour of @{ML select_tac}, we must include
   774   Since we like to mimic the behaviour of @{ML select_tac} as closely as possible, 
   755   @{ML all_tac} at the end (@{ML all_tac} must also be ``wrapped up'' using
   775   we must include @{ML all_tac} at the end of the list (@{ML all_tac} must also 
   756   the @{ML K}-combinator as it does not take a subgoal number as argument). 
   776   be ``wrapped up'' using the @{ML K}-combinator, as it does not take a subgoal 
   757   We can test the tactic on the same proof:
   777   number as argument). We can test the tactic on the same proof:
   758 *}
   778 *}
   759 
   779 
   760 lemma shows "A \<and> B" and "A \<longrightarrow> B \<longrightarrow>C" and "\<forall>x. D x" and "E \<Longrightarrow> F"
   780 lemma shows "A \<and> B" and "A \<longrightarrow> B \<longrightarrow>C" and "\<forall>x. D x" and "E \<Longrightarrow> F"
   761 apply(tactic {* select_tac' 4 *})
   781 apply(tactic {* select_tac' 4 *})
   762 apply(tactic {* select_tac' 3 *})
   782 apply(tactic {* select_tac' 3 *})
   766       @{subgoals [display]}
   786       @{subgoals [display]}
   767       \end{minipage} *}
   787       \end{minipage} *}
   768 (*<*)oops(*>*)
   788 (*<*)oops(*>*)
   769 
   789 
   770 text {* 
   790 text {* 
   771   and obtain the same subgoals. Since this repeated application of a tactic
   791   Because such repeated applications of a tactic to the reverse order of 
   772   to the reverse order of \emph{all} subgoals is quite common, there is 
   792   \emph{all} subgoals is quite common, there is the tactics combinator 
   773   the tactics combinator @{ML ALLGOALS} that simplifies this. Using this 
   793   @{ML ALLGOALS} that simplifies this. Using this combinator we can simply 
   774   combinator we can simply write: *}
   794   write: *}
   775 
   795 
   776 lemma shows "A \<and> B" and "A \<longrightarrow> B \<longrightarrow>C" and "\<forall>x. D x" and "E \<Longrightarrow> F"
   796 lemma shows "A \<and> B" and "A \<longrightarrow> B \<longrightarrow>C" and "\<forall>x. D x" and "E \<Longrightarrow> F"
   777 apply(tactic {* ALLGOALS select_tac' *})
   797 apply(tactic {* ALLGOALS select_tac' *})
   778 txt{* \begin{minipage}{\textwidth}
   798 txt{* \begin{minipage}{\textwidth}
   779       @{subgoals [display]}
   799       @{subgoals [display]}
   780       \end{minipage} *}
   800       \end{minipage} *}
   781 (*<*)oops(*>*)
   801 (*<*)oops(*>*)
   782 
   802 
   783 text {*
   803 text {*
   784   We chose to write @{ML select_tac'} in such a way that it always succeeds.
   804   Remember that we chose to write @{ML select_tac'} in such a way that it always 
   785   This can be potetially very  confusing for the user in cases of goals 
   805   succeeds. This can be potentially very confusing for the user, for example,  
   786   of the form
   806   in cases the goals is the form
   787 *}
   807 *}
   788 
   808 
   789 lemma shows "E \<Longrightarrow> F"
   809 lemma shows "E \<Longrightarrow> F"
   790 apply(tactic {* select_tac' 1 *})
   810 apply(tactic {* select_tac' 1 *})
   791 txt{* \begin{minipage}{\textwidth}
   811 txt{* \begin{minipage}{\textwidth}
   794 (*<*)oops(*>*)
   814 (*<*)oops(*>*)
   795 
   815 
   796 text {*
   816 text {*
   797   where no rule applies. The reason is that the user has little chance 
   817   where no rule applies. The reason is that the user has little chance 
   798   to see whether progress in the proof has been made or not. We could simply
   818   to see whether progress in the proof has been made or not. We could simply
   799   remove @{ML "K all_tac"} from the end of the list. Then the tactic would
   819   delete th @{ML "K all_tac"} from the end of the list. Then @{ML select_tac'} 
   800   only apply in cases where it can make some progress. But for the sake of
   820   would only succeed on goals where it can make progress. But for the sake of
   801   argument, let us assume that this is not an option. In such cases, you 
   821   argument, let us suppose that this deletion is not an option. In such cases, you 
   802   can use the combinator @{ML CHANGED} to make sure the subgoal has been
   822   can use the combinator @{ML CHANGED} to make sure the subgoal has been
   803   changed by the tactic. Because now
   823   changed by the tactic. Because now
   804 *}
   824 *}
   805 
   825 
   806 lemma shows "E \<Longrightarrow> F"
   826 lemma shows "E \<Longrightarrow> F"
   807 apply(tactic {* CHANGED (select_tac' 1) *})(*<*)?(*>*)
   827 apply(tactic {* CHANGED (select_tac' 1) *})(*<*)?(*>*)
   808 txt{* results in the usual error message for empty result sequences. *}
   828 txt{* results in the error message:
   809 (*<*)oops(*>*)
   829   \begin{isabelle}
   810 
   830   @{text "*** empty result sequence -- proof command failed"}\\
   811 
   831   @{text "*** At command \"apply\"."}
   812 text {*
   832   \end{isabelle} 
   813 
   833 *}(*<*)oops(*>*)
   814   @{ML REPEAT} @{ML DETERM}
   834 
   815 
   835 
   816   @{ML CHANGED}
   836 text {*
       
   837   Meaning the tactic failed. 
       
   838 
       
   839   We can extend @{ML select_tac'} so that it not just applies to the top-most
       
   840   connective, but also to the ones immediately ``underneath''. For this you can use the
       
   841   tactic combinator @{ML REPEAT}. For example suppose the following tactic
       
   842 *}
       
   843 
       
   844 ML{*val repeat_xmp = REPEAT (CHANGED (select_tac' 1)) *}
       
   845 
       
   846 text {* and the proof *}
       
   847 
       
   848 lemma shows "((\<not>A) \<and> (\<forall>x. B x)) \<and> (C \<longrightarrow> D)"
       
   849 apply(tactic {* repeat_xmp *})
       
   850 txt{* \begin{minipage}{\textwidth}
       
   851       @{subgoals [display]}
       
   852       \end{minipage} *}
       
   853 (*<*)oops(*>*)
       
   854 
       
   855 text {*
       
   856   Here it is crucial that @{ML select_tac'} is prefixed with @{ML CHANGED}, 
       
   857   because otherwise @{ML REPEAT} runs into an infinite loop. The function
       
   858   @{ML REPEAT1} is similar, but runs the tactic at least once (failing if 
       
   859   this is not possible).
       
   860 
       
   861   If you are after the ``primed'' version of @{ML repeat_xmp} then it 
       
   862   needs to be coded as
       
   863 *}
       
   864 
       
   865 ML{*val repeat_xmp' = REPEAT o CHANGED o select_tac'*}
       
   866 
       
   867 text {*
       
   868   since there are no ``primed'' versions of @{ML REPEAT} and @{ML CHANGED}.
       
   869 
       
   870   If you look closely at the goal state above, the tactics @{ML repeat_xmp}
       
   871   and @{ML repeat_xmp'} are not yet quite what we are after: the problem is
       
   872   that goals 2 and 3 are not yet analysed. This is because both tactics
       
   873   apply repeatedly only to the first subgoal. To analyse also all
       
   874   resulting subgoals, you can use the function @{ML REPEAT_ALL_NEW}. 
       
   875   Suppose the tactic
       
   876 *}
       
   877 
       
   878 ML{*val repeat_all_new_xmp = REPEAT_ALL_NEW (CHANGED o select_tac')*}
       
   879 
       
   880 text {* 
       
   881   which analyses the topmost connectives also in all resulting 
       
   882   subgoals.
       
   883 *}
       
   884 
       
   885 lemma shows "((\<not>A) \<and> (\<forall>x. B x)) \<and> (C \<longrightarrow> D)"
       
   886 apply(tactic {* repeat_all_new_xmp 1 *})
       
   887 txt{* \begin{minipage}{\textwidth}
       
   888       @{subgoals [display]}
       
   889       \end{minipage} *}
       
   890 (*<*)oops(*>*)
       
   891 
       
   892 text {*
       
   893   The last tactic combinator we describe here is @{ML DETERM}. Recall 
       
   894   that tactics produce a lazy sequence of successor goal states. These
       
   895   states can be explored using the command \isacommand{back}. For example
       
   896 
       
   897 *}
       
   898 
       
   899 lemma "\<lbrakk>P1 \<or> Q1; P2 \<or> Q2\<rbrakk> \<Longrightarrow> R"
       
   900 apply(tactic {* etac @{thm disjE} 1 *})
       
   901 txt{* applies the rule to the first assumption
       
   902       
       
   903       \begin{minipage}{\textwidth}
       
   904       @{subgoals [display]}
       
   905       \end{minipage} *}
       
   906 (*<*)
       
   907 oops
       
   908 lemma "\<lbrakk>P1 \<or> Q1; P2 \<or> Q2\<rbrakk> \<Longrightarrow> R"
       
   909 apply(tactic {* etac @{thm disjE} 1 *})
       
   910 (*>*)
       
   911 back
       
   912 txt{* whereas it is now applied to the second
       
   913 
       
   914       \begin{minipage}{\textwidth}
       
   915       @{subgoals [display]}
       
   916       \end{minipage} *}
       
   917 (*<*)oops(*>*)
       
   918 
       
   919 text {*
       
   920   Sometimes this leads to confusing behaviour of tactics and also has
       
   921   the potential to explode the search space for tactics build on top.
       
   922   This can be avoided by prefixing the tactic with @{ML DETERM}.
       
   923 *}
       
   924 
       
   925 lemma "\<lbrakk>P1 \<or> Q1; P2 \<or> Q2\<rbrakk> \<Longrightarrow> R"
       
   926 apply(tactic {* DETERM (etac @{thm disjE} 1) *})
       
   927 txt {*\begin{minipage}{\textwidth}
       
   928       @{subgoals [display]}
       
   929       \end{minipage} *}
       
   930 (*<*)oops(*>*)
       
   931 text {*
       
   932   This will prune the search space to just the first possibility.
       
   933   Attempting to apply \isacommand{back} in this goal states gives the
       
   934   error message:
       
   935 
       
   936   \begin{isabelle}
       
   937   @{text "*** back: no alternatives"}\\
       
   938   @{text "*** At command \"back\"."}
       
   939   \end{isabelle}
       
   940 
       
   941   \begin{readmore}
       
   942   Most tactic combinators are defined in @{ML_file "Pure/tctical.ML"}.
       
   943   \end{readmore}
   817 
   944 
   818 *}
   945 *}
   819 
   946 
   820 section {* Rewriting and Simplifier Tactics *}
   947 section {* Rewriting and Simplifier Tactics *}
   821 
   948