ProgTutorial/Tactical.thy
changeset 562 daf404920ab9
parent 559 ffa5c4ec9611
child 565 cecd7a941885
equal deleted inserted replaced
561:aec7073d4645 562:daf404920ab9
    42 apply(assumption)
    42 apply(assumption)
    43 apply(rule disjI1)
    43 apply(rule disjI1)
    44 apply(assumption)
    44 apply(assumption)
    45 done
    45 done
    46 
    46 
    47 
       
    48 
       
    49 text {*
    47 text {*
    50   This proof translates to the following ML-code.
    48   This proof translates to the following ML-code.
    51   
    49   
    52 @{ML_response_fake [display,gray]
    50 @{ML_response_fake [display,gray]
    53 "let
    51 "let
    54   val ctxt = @{context}
    52   val ctxt = @{context}
    55   val goal = @{prop \"P \<or> Q \<Longrightarrow> Q \<or> P\"}
    53   val goal = @{prop \"P \<or> Q \<Longrightarrow> Q \<or> P\"}
    56 in
    54 in
    57   Goal.prove ctxt [\"P\", \"Q\"] [] goal 
    55   Goal.prove ctxt [\"P\", \"Q\"] [] goal 
    58    (fn _ =>  etac @{thm disjE} 1
    56    (fn _ =>  eresolve_tac @{context} [@{thm disjE}] 1
    59              THEN rtac @{thm disjI2} 1
    57              THEN resolve_tac @{context} [@{thm disjI2}] 1
    60              THEN atac 1
    58              THEN assume_tac @{context} 1
    61              THEN rtac @{thm disjI1} 1
    59              THEN resolve_tac @{context} [@{thm disjI1}] 1
    62              THEN atac 1)
    60              THEN assume_tac @{context} 1)
    63 end" "?P \<or> ?Q \<Longrightarrow> ?Q \<or> ?P"}
    61 end" "?P \<or> ?Q \<Longrightarrow> ?Q \<or> ?P"}
    64   
    62   
    65   To start the proof, the function @{ML_ind prove in Goal} sets up a goal
    63   To start the proof, the function @{ML_ind prove in Goal} sets up a goal
    66   state for proving the goal @{prop "P \<or> Q \<Longrightarrow> Q \<or> P"}. We can give this
    64   state for proving the goal @{prop "P \<or> Q \<Longrightarrow> Q \<or> P"}. We can give this
    67   function some assumptions in the third argument (there are no assumption in
    65   function some assumptions in the third argument (there are no assumption in
    68   the proof at hand). The second argument stands for a list of variables
    66   the proof at hand). The second argument stands for a list of variables
    69   (given as strings). This list contains the variables that will be turned
    67   (given as strings). This list contains the variables that will be turned
    70   into schematic variables once the goal is proved (in our case @{text P} and
    68   into schematic variables once the goal is proved (in our case @{text P} and
    71   @{text Q}). The last argument is the tactic that proves the goal. This
    69   @{text Q}). The last argument is the tactic that proves the goal. This
    72   tactic can make use of the local assumptions (there are none in this
    70   tactic can make use of the local assumptions (there are none in this
    73   example). The tactics @{ML_ind etac in Tactic}, @{ML_ind rtac in Tactic} and
    71   example). The tactics @{ML_ind eresolve_tac in Tactic}, @{ML_ind resolve_tac in Tactic} and
    74   @{ML_ind atac in Tactic} in the code above correspond roughly to @{text
    72   @{ML_ind assume_tac in Tactic} in the code above correspond roughly to @{text
    75   erule}, @{text rule} and @{text assumption}, respectively. The combinator
    73   erule}, @{text rule} and @{text assumption}, respectively. The combinator
    76   @{ML THEN} strings the tactics together.
    74   @{ML THEN} strings the tactics together.
    77 
    75 
    78   TBD: Write something about @{ML_ind prove_multi in Goal}.
    76   TBD: Write something about @{ML_ind prove_common in Goal}.
    79 
    77 
    80   \begin{readmore}
    78   \begin{readmore}
    81   To learn more about the function @{ML_ind prove in Goal} see
    79   To learn more about the function @{ML_ind prove in Goal} see
    82   \isccite{sec:results} and the file @{ML_file "Pure/goal.ML"}.  See @{ML_file
    80   \isccite{sec:results} and the file @{ML_file "Pure/goal.ML"}.  See @{ML_file
    83   "Pure/tactic.ML"} and @{ML_file "Pure/tactical.ML"} for the code of basic
    81   "Pure/tactic.ML"} and @{ML_file "Pure/tactical.ML"} for the code of basic
    94   the command \isacommand{apply}@{text "(tactic \<verbopen> \<dots> \<verbclose>)"}. 
    92   the command \isacommand{apply}@{text "(tactic \<verbopen> \<dots> \<verbclose>)"}. 
    95   Consider the following sequence of tactics
    93   Consider the following sequence of tactics
    96 
    94 
    97 *}
    95 *}
    98 
    96 
    99 ML %grayML{*val foo_tac = 
    97 ML %grayML{*fun foo_tac ctxt = 
   100       (etac @{thm disjE} 1
    98       (eresolve_tac ctxt [@{thm disjE}] 1
   101        THEN rtac @{thm disjI2} 1
    99        THEN resolve_tac  ctxt [@{thm disjI2}] 1
   102        THEN atac 1
   100        THEN assume_tac  ctxt 1
   103        THEN rtac @{thm disjI1} 1
   101        THEN resolve_tac ctxt [@{thm disjI1}] 1
   104        THEN atac 1)*}
   102        THEN assume_tac  ctxt 1)*}
   105 
   103 
   106 text {* and the Isabelle proof: *}
   104 text {* and the Isabelle proof: *}
   107 
   105 
   108 lemma 
   106 lemma 
   109   shows "P \<or> Q \<Longrightarrow> Q \<or> P"
   107   shows "P \<or> Q \<Longrightarrow> Q \<or> P"
   110 apply(tactic {* foo_tac *})
   108 apply(tactic {* foo_tac @{context} *})
   111 done
   109 done
   112 
   110 
   113 text {*
   111 text {*
   114   By using @{text "tactic \<verbopen> \<dots> \<verbclose>"} you can call from the 
   112   By using @{text "tactic \<verbopen> \<dots> \<verbclose>"} you can call from the 
   115   user-level of Isabelle the tactic @{ML foo_tac} or 
   113   user-level of Isabelle the tactic @{ML foo_tac} or 
   123   tactic (@{text "1"} stands for the first, or top-most, subgoal). This hard-coding
   121   tactic (@{text "1"} stands for the first, or top-most, subgoal). This hard-coding
   124   of goals is sometimes wanted, but usually it is not. To avoid the explicit numbering, 
   122   of goals is sometimes wanted, but usually it is not. To avoid the explicit numbering, 
   125   you can write
   123   you can write
   126 *}
   124 *}
   127 
   125 
   128 ML %grayML{*val foo_tac' = 
   126 ML %grayML{*fun foo_tac' ctxt = 
   129       (etac @{thm disjE} 
   127       (eresolve_tac ctxt [@{thm disjE}] 
   130        THEN' rtac @{thm disjI2} 
   128        THEN' resolve_tac ctxt [@{thm disjI2}] 
   131        THEN' atac 
   129        THEN' assume_tac ctxt 
   132        THEN' rtac @{thm disjI1} 
   130        THEN' resolve_tac ctxt [@{thm disjI1}] 
   133        THEN' atac)*}text_raw{*\label{tac:footacprime}*}
   131        THEN' assume_tac ctxt)*}text_raw{*\label{tac:footacprime}*}
   134 
   132 
   135 text {* 
   133 text {* 
   136   where @{ML_ind THEN' in Tactical} is used instead of @{ML THEN in
   134   where @{ML_ind THEN' in Tactical} is used instead of @{ML THEN in
   137   Tactical}. (For most combinators that combine tactics---@{ML THEN} is only
   135   Tactical}. (For most combinators that combine tactics---@{ML THEN} is only
   138   one such combinator---a ``primed'' version exists.)  With @{ML foo_tac'} you
   136   one such combinator---a ``primed'' version exists.)  With @{ML foo_tac'} you
   142 *}
   140 *}
   143 
   141 
   144 lemma 
   142 lemma 
   145   shows "P1 \<or> Q1 \<Longrightarrow> Q1 \<or> P1"
   143   shows "P1 \<or> Q1 \<Longrightarrow> Q1 \<or> P1"
   146   and   "P2 \<or> Q2 \<Longrightarrow> Q2 \<or> P2"
   144   and   "P2 \<or> Q2 \<Longrightarrow> Q2 \<or> P2"
   147 apply(tactic {* foo_tac' 2 *})
   145 apply(tactic {* foo_tac' @{context} 2 *})
   148 apply(tactic {* foo_tac' 1 *})
   146 apply(tactic {* foo_tac' @{context} 1 *})
   149 done
   147 done
   150 
   148 
   151 text {*
   149 text {*
   152   This kind of addressing is more difficult to achieve when the goal is 
   150   This kind of addressing is more difficult to achieve when the goal is 
   153   hard-coded inside the tactic. 
   151   hard-coded inside the tactic. 
   201   @{ML foo_tac'}: either using the first assumption or the second.
   199   @{ML foo_tac'}: either using the first assumption or the second.
   202 *}
   200 *}
   203 
   201 
   204 lemma 
   202 lemma 
   205   shows "\<lbrakk>P \<or> Q; P \<or> Q\<rbrakk> \<Longrightarrow> Q \<or> P"
   203   shows "\<lbrakk>P \<or> Q; P \<or> Q\<rbrakk> \<Longrightarrow> Q \<or> P"
   206 apply(tactic {* foo_tac' 1 *})
   204 apply(tactic {* foo_tac' @{context} 1 *})
   207 back
   205 back
   208 done
   206 done
   209 
   207 
   210 
   208 
   211 text {*
   209 text {*
   348 definition 
   346 definition 
   349   EQ_TRUE 
   347   EQ_TRUE 
   350 where
   348 where
   351   "EQ_TRUE X \<equiv> (X = True)"
   349   "EQ_TRUE X \<equiv> (X = True)"
   352 
   350 
   353 schematic_lemma test: 
   351 schematic_goal test: 
   354   shows "EQ_TRUE ?X"
   352   shows "EQ_TRUE ?X"
   355 unfolding EQ_TRUE_def
   353 unfolding EQ_TRUE_def
   356 by (rule refl)
   354 by (rule refl)
   357 
   355 
   358 text {*
   356 text {*
   405   sometimes useful during the development of tactics.
   403   sometimes useful during the development of tactics.
   406 *}
   404 *}
   407 
   405 
   408 lemma 
   406 lemma 
   409   shows "False" and "Goldbach_conjecture"  
   407   shows "False" and "Goldbach_conjecture"  
   410 apply(tactic {* Skip_Proof.cheat_tac 1 *})
   408 apply(tactic {* Skip_Proof.cheat_tac @{context} 1 *})
   411 txt{*\begin{minipage}{\textwidth}
   409 txt{*\begin{minipage}{\textwidth}
   412      @{subgoals [display]}
   410      @{subgoals [display]}
   413      \end{minipage}*}
   411      \end{minipage}*}
   414 (*<*)oops(*>*)
   412 (*<*)oops(*>*)
   415 
   413 
   416 text {*
   414 text {*
   417   Another simple tactic is the function @{ML_ind atac in Tactic}, which, as shown 
   415   Another simple tactic is the function @{ML_ind assume_tac in Tactic}, which, as shown 
   418   earlier, corresponds to the assumption method.
   416   earlier, corresponds to the assumption method.
   419 *}
   417 *}
   420 
   418 
   421 lemma 
   419 lemma 
   422   shows "P \<Longrightarrow> P"
   420   shows "P \<Longrightarrow> P"
   423 apply(tactic {* atac 1 *})
   421 apply(tactic {* assume_tac @{context} 1 *})
   424 txt{*\begin{minipage}{\textwidth}
   422 txt{*\begin{minipage}{\textwidth}
   425      @{subgoals [display]}
   423      @{subgoals [display]}
   426      \end{minipage}*}
   424      \end{minipage}*}
   427 (*<*)oops(*>*)
   425 (*<*)oops(*>*)
   428 
   426 
   429 text {*
   427 text {*
   430   Similarly, @{ML_ind rtac in Tactic}, @{ML_ind dtac in Tactic}, @{ML_ind etac
   428   Similarly, @{ML_ind resolve_tac in Tactic}, @{ML_ind dresolve_tac in Tactic}, @{ML_ind eresolve_tac
   431   in Tactic} and @{ML_ind ftac in Tactic} correspond (roughly) to @{text
   429   in Tactic} and @{ML_ind forward_tac in Tactic} correspond (roughly) to @{text
   432   rule}, @{text drule}, @{text erule} and @{text frule}, respectively. Each of
   430   rule}, @{text drule}, @{text erule} and @{text frule}, respectively. Each of
   433   them takes a theorem as argument and attempts to apply it to a goal. Below
   431   them takes a theorem as argument and attempts to apply it to a goal. Below
   434   are three self-explanatory examples.
   432   are three self-explanatory examples.
   435 *}
   433 *}
   436 
   434 
   437 lemma 
   435 lemma 
   438   shows "P \<and> Q"
   436   shows "P \<and> Q"
   439 apply(tactic {* rtac @{thm conjI} 1 *})
   437 apply(tactic {* resolve_tac @{context} [@{thm conjI}] 1 *})
   440 txt{*\begin{minipage}{\textwidth}
   438 txt{*\begin{minipage}{\textwidth}
   441      @{subgoals [display]}
   439      @{subgoals [display]}
   442      \end{minipage}*}
   440      \end{minipage}*}
   443 (*<*)oops(*>*)
   441 (*<*)oops(*>*)
   444 
   442 
   445 lemma 
   443 lemma 
   446   shows "P \<and> Q \<Longrightarrow> False"
   444   shows "P \<and> Q \<Longrightarrow> False"
   447 apply(tactic {* etac @{thm conjE} 1 *})
   445 apply(tactic {* eresolve_tac @{context} [@{thm conjE}] 1 *})
   448 txt{*\begin{minipage}{\textwidth}
   446 txt{*\begin{minipage}{\textwidth}
   449      @{subgoals [display]}
   447      @{subgoals [display]}
   450      \end{minipage}*}
   448      \end{minipage}*}
   451 (*<*)oops(*>*)
   449 (*<*)oops(*>*)
   452 
   450 
   453 lemma 
   451 lemma 
   454   shows "False \<and> True \<Longrightarrow> False"
   452   shows "False \<and> True \<Longrightarrow> False"
   455 apply(tactic {* dtac @{thm conjunct2} 1 *})
   453 apply(tactic {* dresolve_tac @{context} [@{thm conjunct2}] 1 *})
   456 txt{*\begin{minipage}{\textwidth}
   454 txt{*\begin{minipage}{\textwidth}
   457      @{subgoals [display]}
   455      @{subgoals [display]}
   458      \end{minipage}*}
   456      \end{minipage}*}
   459 (*<*)oops(*>*)
   457 (*<*)oops(*>*)
   460 
   458 
   461 text {*
   459 text {*
   462   The function @{ML_ind resolve_tac in Tactic} is similar to @{ML rtac}, except that it
   460   The function @{ML_ind resolve_tac in Tactic} 
   463   expects a list of theorems as argument. From this list it will apply the
   461   expects a list of theorems as argument. From this list it will apply the
   464   first applicable theorem (later theorems that are also applicable can be
   462   first applicable theorem (later theorems that are also applicable can be
   465   explored via the lazy sequences mechanism). Given the code
   463   explored via the lazy sequences mechanism). Given the code
   466 *}
   464 *}
   467 
   465 
   468 ML %grayML{*val resolve_xmp_tac = resolve_tac [@{thm impI}, @{thm conjI}]*}
   466 ML %grayML{*fun resolve_xmp_tac ctxt = resolve_tac ctxt [@{thm impI}, @{thm conjI}]*}
   469 
   467 
   470 text {*
   468 text {*
   471   an example for @{ML resolve_tac} is the following proof where first an outermost 
   469   an example for @{ML resolve_tac} is the following proof where first an outermost 
   472   implication is analysed and then an outermost conjunction.
   470   implication is analysed and then an outermost conjunction.
   473 *}
   471 *}
   474 
   472 
   475 lemma 
   473 lemma 
   476   shows "C \<longrightarrow> (A \<and> B)" 
   474   shows "C \<longrightarrow> (A \<and> B)" 
   477   and   "(A \<longrightarrow> B) \<and> C"
   475   and   "(A \<longrightarrow> B) \<and> C"
   478 apply(tactic {* resolve_xmp_tac 1 *})
   476 apply(tactic {* resolve_xmp_tac @{context} 1 *})
   479 apply(tactic {* resolve_xmp_tac 2 *})
   477 apply(tactic {* resolve_xmp_tac @{context} 2 *})
   480 txt{*\begin{minipage}{\textwidth}
   478 txt{*\begin{minipage}{\textwidth}
   481      @{subgoals [display]} 
   479      @{subgoals [display]} 
   482      \end{minipage}*}
   480      \end{minipage}*}
   483 (*<*)oops(*>*)
   481 (*<*)oops(*>*)
   484 
   482 
   485 text {* 
   483 text {* 
   486   Similar versions taking a list of theorems exist for the tactics 
   484   Similar versions taking a list of theorems exist for the tactics 
   487   @{ML dtac} (@{ML_ind dresolve_tac in Tactic}), @{ML etac} 
   485    @{ML_ind dresolve_tac in Tactic},  
   488   (@{ML_ind eresolve_tac in Tactic}) and so on.
   486   @{ML_ind eresolve_tac in Tactic} and so on.
   489 
   487 
   490   Another simple tactic is @{ML_ind cut_facts_tac in Tactic}. It inserts a
   488   Another simple tactic is @{ML_ind cut_facts_tac in Tactic}. It inserts a
   491   list of theorems into the assumptions of the current goal state. Below we
   489   list of theorems into the assumptions of the current goal state. Below we
   492   will insert the definitions for the constants @{term True} and @{term
   490   will insert the definitions for the constants @{term True} and @{term
   493   False}. So
   491   False}. So
   519 \begin{figure}[t]
   517 \begin{figure}[t]
   520 \begin{minipage}{\textwidth}
   518 \begin{minipage}{\textwidth}
   521 \begin{isabelle}
   519 \begin{isabelle}
   522 *}
   520 *}
   523 
   521 
   524 ML %grayML{*fun foc_tac {prems, params, asms, concl, context, schematics} = 
   522 ML %grayML{*fun foc_tac {context, params, prems, asms, concl, schematics} = 
   525 let 
   523 let 
   526   fun assgn1 f1 f2 xs =
   524   fun assgn1 f1 f2 xs =
   527     let
   525     let
   528       val out = map (fn (x, y) => Pretty.enum ":=" "" "" [f1 x, f2 y]) xs
   526       val out = map (fn (x, y) => Pretty.enum ":=" "" "" [f1 x, f2 y]) xs
   529     in
   527     in
   530       Pretty.list "" "" out
   528       Pretty.list "" "" out
   531     end 
   529     end 
   532 
   530 
   533   fun assgn2 f xs = assgn1 f f xs 
   531   fun assgn2 f xs = assgn1 (fn (n,T) => pretty_term context (Var (n,T))) f  xs 
   534  
   532  
   535   val pps = map (fn (s, pp) => Pretty.block [Pretty.str s, pp])
   533   val pps = map (fn (s, pp) => Pretty.block [Pretty.str s, pp])
   536     [("params: ", assgn1 Pretty.str (pretty_cterm context) params),
   534     [("params: ", assgn1 Pretty.str (pretty_cterm context) params),
   537      ("assumptions: ", pretty_cterms context asms),
   535      ("assumptions: ", pretty_cterms context asms),
   538      ("conclusion: ", pretty_cterm context concl),
   536      ("conclusion: ", pretty_cterm context concl),
   550   in Section~\ref{sec:printing} for extracting strings from @{ML_type cterm}s 
   548   in Section~\ref{sec:printing} for extracting strings from @{ML_type cterm}s 
   551   and @{ML_type thm}s.\label{fig:sptac}}
   549   and @{ML_type thm}s.\label{fig:sptac}}
   552 \end{figure}
   550 \end{figure}
   553 *}
   551 *}
   554 
   552 
   555 schematic_lemma 
   553 schematic_goal
   556   shows "\<And>x y. A x y \<Longrightarrow> B y x \<longrightarrow> C (?z y) x"
   554   shows "\<And>x y. A x y \<Longrightarrow> B y x \<longrightarrow> C (?z y) x"
   557 apply(tactic {* Subgoal.FOCUS foc_tac @{context} 1 *})
   555 apply(tactic {* Subgoal.FOCUS foc_tac @{context} 1 *})
   558 
   556 
   559 txt {*
   557 txt {*
   560   The tactic produces the following printout:
   558   The tactic produces the following printout:
   606   is that the former expects that the goal is solved completely, which the
   604   is that the former expects that the goal is solved completely, which the
   607   latter does not. Another is that @{ML SUBPROOF} cannot instantiate any schematic
   605   latter does not. Another is that @{ML SUBPROOF} cannot instantiate any schematic
   608   variables.
   606   variables.
   609 
   607 
   610   Observe that inside @{ML FOCUS in Subgoal} and @{ML SUBPROOF}, we are in a goal
   608   Observe that inside @{ML FOCUS in Subgoal} and @{ML SUBPROOF}, we are in a goal
   611   state where there is only a conclusion. This means the tactics @{ML dtac} and 
   609   state where there is only a conclusion. This means the tactics @{ML dresolve_tac} and 
   612   the like are of no use for manipulating the goal state. The assumptions inside 
   610   the like are of no use for manipulating the goal state. The assumptions inside 
   613   @{ML FOCUS in Subgoal} and @{ML SUBPROOF} are given as cterms and theorems in 
   611   @{ML FOCUS in Subgoal} and @{ML SUBPROOF} are given as cterms and theorems in 
   614   the arguments @{text "asms"} and @{text "prems"}, respectively. This 
   612   the arguments @{text "asms"} and @{text "prems"}, respectively. This 
   615   means we can apply them using the usual assumption tactics. With this you can 
   613   means we can apply them using the usual assumption tactics. With this you can 
   616   for example easily implement a tactic that behaves almost like @{ML atac}:
   614   for example easily implement a tactic that behaves almost like @{ML assume_tac}:
   617 *}
   615 *}
   618 
   616 
   619 ML %grayML{*val atac' = Subgoal.FOCUS (fn {prems, ...} => resolve_tac prems 1)*}
   617 ML %grayML{*val atac' = Subgoal.FOCUS (fn {prems, context, ...} => resolve_tac context prems 1)*}
   620 
   618 
   621 text {*
   619 text {*
   622   If you apply @{ML atac'} to the next lemma
   620   If you apply @{ML atac'} to the next lemma
   623 *}
   621 *}
   624 
   622 
   654   described next are more appropriate.
   652   described next are more appropriate.
   655 
   653 
   656 
   654 
   657   \begin{readmore}
   655   \begin{readmore}
   658   The functions @{ML FOCUS in Subgoal} and @{ML SUBPROOF} are defined in 
   656   The functions @{ML FOCUS in Subgoal} and @{ML SUBPROOF} are defined in 
   659   @{ML_file "Pure/subgoal.ML"} and also described in 
   657   @{ML_file "Pure/Isar/subgoal.ML"} and also described in 
   660   \isccite{sec:results}. 
   658   \isccite{sec:results}. 
   661   \end{readmore}
   659   \end{readmore}
   662 
   660 
   663   Similar but less powerful functions than @{ML FOCUS in Subgoal},
   661   Similar but less powerful functions than @{ML FOCUS in Subgoal},
   664   respectively @{ML SUBPROOF}, are @{ML_ind SUBGOAL in Tactical} and @{ML_ind
   662   respectively @{ML SUBPROOF}, are @{ML_ind SUBGOAL in Tactical} and @{ML_ind
   667   cterm}). With them you can implement a tactic that applies a rule according
   665   cterm}). With them you can implement a tactic that applies a rule according
   668   to the topmost logic connective in the subgoal (to illustrate this we only
   666   to the topmost logic connective in the subgoal (to illustrate this we only
   669   analyse a few connectives). The code of the tactic is as follows.
   667   analyse a few connectives). The code of the tactic is as follows.
   670 *}
   668 *}
   671 
   669 
   672 ML %linenosgray{*fun select_tac (t, i) =
   670 ML %linenosgray{*fun select_tac ctxt (t, i) =
   673   case t of
   671   case t of
   674      @{term "Trueprop"} $ t' => select_tac (t', i)
   672      @{term "Trueprop"} $ t' => select_tac ctxt (t', i)
   675    | @{term "op \<Longrightarrow>"} $ _ $ t' => select_tac (t', i)
   673    | @{term "(\<Longrightarrow>)"} $ _ $ t' => select_tac ctxt (t', i)
   676    | @{term "op \<and>"} $ _ $ _ => rtac @{thm conjI} i
   674    | @{term "(\<and>)"} $ _ $ _ => resolve_tac ctxt [@{thm conjI}] i
   677    | @{term "op \<longrightarrow>"} $ _ $ _ => rtac @{thm impI} i
   675    | @{term "(\<longrightarrow>)"} $ _ $ _ => resolve_tac ctxt [@{thm impI}] i
   678    | @{term "Not"} $ _ => rtac @{thm notI} i
   676    | @{term "Not"} $ _ => resolve_tac ctxt [@{thm notI}] i
   679    | Const (@{const_name "All"}, _) $ _ => rtac @{thm allI} i
   677    | Const (@{const_name "All"}, _) $ _ => resolve_tac ctxt [@{thm allI}] i
   680    | _ => all_tac*}text_raw{*\label{tac:selecttac}*}
   678    | _ => all_tac*}text_raw{*\label{tac:selecttac}*}
   681 
   679 
   682 text {*
   680 text {*
   683   The input of the function is a term representing the subgoal and a number
   681   The input of the function is a term representing the subgoal and a number
   684   specifying the subgoal of interest. In Line 3 you need to descend under the
   682   specifying the subgoal of interest. In Line 3 you need to descend under the
   700 *}
   698 *}
   701 
   699 
   702 
   700 
   703 lemma 
   701 lemma 
   704   shows "A \<and> B" and "A \<longrightarrow> B \<longrightarrow>C" and "\<forall>x. D x" and "E \<Longrightarrow> F"
   702   shows "A \<and> B" and "A \<longrightarrow> B \<longrightarrow>C" and "\<forall>x. D x" and "E \<Longrightarrow> F"
   705 apply(tactic {* SUBGOAL select_tac 4 *})
   703 apply(tactic {* SUBGOAL (select_tac @{context}) 4 *})
   706 apply(tactic {* SUBGOAL select_tac 3 *})
   704 apply(tactic {* SUBGOAL (select_tac @{context}) 3 *})
   707 apply(tactic {* SUBGOAL select_tac 2 *})
   705 apply(tactic {* SUBGOAL (select_tac @{context}) 2 *})
   708 apply(tactic {* SUBGOAL select_tac 1 *})
   706 apply(tactic {* SUBGOAL (select_tac @{context}) 1 *})
   709 txt{* \begin{minipage}{\textwidth}
   707 txt{* \begin{minipage}{\textwidth}
   710       @{subgoals [display]}
   708       @{subgoals [display]}
   711       \end{minipage} *}
   709       \end{minipage} *}
   712 (*<*)oops(*>*)
   710 (*<*)oops(*>*)
   713 
   711 
   718   produced by the rule. If we had applied it in the other order 
   716   produced by the rule. If we had applied it in the other order 
   719 *}
   717 *}
   720 
   718 
   721 lemma 
   719 lemma 
   722   shows "A \<and> B" and "A \<longrightarrow> B \<longrightarrow>C" and "\<forall>x. D x" and "E \<Longrightarrow> F"
   720   shows "A \<and> B" and "A \<longrightarrow> B \<longrightarrow>C" and "\<forall>x. D x" and "E \<Longrightarrow> F"
   723 apply(tactic {* SUBGOAL select_tac 1 *})
   721 apply(tactic {* SUBGOAL (select_tac @{context}) 1 *})
   724 apply(tactic {* SUBGOAL select_tac 3 *})
   722 apply(tactic {* SUBGOAL (select_tac @{context}) 3 *})
   725 apply(tactic {* SUBGOAL select_tac 4 *})
   723 apply(tactic {* SUBGOAL (select_tac @{context}) 4 *})
   726 apply(tactic {* SUBGOAL select_tac 5 *})
   724 apply(tactic {* SUBGOAL (select_tac @{context}) 5 *})
   727 (*<*)oops(*>*)
   725 (*<*)oops(*>*)
   728 
   726 
   729 text {*
   727 text {*
   730   then we have to be careful to not apply the tactic to the two subgoals produced by 
   728   then we have to be careful to not apply the tactic to the two subgoals produced by 
   731   the first goal. To do this can result in quite messy code. In contrast, 
   729   the first goal. To do this can result in quite messy code. In contrast, 
   741   \begin{readmore}
   739   \begin{readmore}
   742   The functions @{ML SUBGOAL} and @{ML CSUBGOAL} are defined in @{ML_file "Pure/tactical.ML"}.
   740   The functions @{ML SUBGOAL} and @{ML CSUBGOAL} are defined in @{ML_file "Pure/tactical.ML"}.
   743   \end{readmore}
   741   \end{readmore}
   744 
   742 
   745 
   743 
   746   Since @{ML_ind rtac in Tactic} and the like use higher-order unification, an
   744   Since @{ML_ind resolve_tac in Tactic} and the like use higher-order unification, an
   747   automatic proof procedure based on them might become too fragile, if it just
   745   automatic proof procedure based on them might become too fragile, if it just
   748   applies theorems as shown above. The reason is that a number of theorems
   746   applies theorems as shown above. The reason is that a number of theorems
   749   introduce schematic variables into the goal state. Consider for example the
   747   introduce schematic variables into the goal state. Consider for example the
   750   proof
   748   proof
   751 *}
   749 *}
   752 
   750 
   753 lemma 
   751 lemma 
   754   shows "\<forall>x \<in> A. P x \<Longrightarrow> Q x"
   752   shows "\<forall>x \<in> A. P x \<Longrightarrow> Q x"
   755 apply(tactic {* dtac @{thm bspec} 1 *})
   753 apply(tactic {* dresolve_tac @{context} [@{thm bspec}] 1 *})
   756 txt{*\begin{minipage}{\textwidth}
   754 txt{*\begin{minipage}{\textwidth}
   757      @{subgoals [display]} 
   755      @{subgoals [display]} 
   758      \end{minipage}*}
   756      \end{minipage}*}
   759 (*<*)oops(*>*)
   757 (*<*)oops(*>*)
   760 
   758 
   847 *}
   845 *}
   848 
   846 
   849 lemma 
   847 lemma 
   850   fixes x y u w::"'a"
   848   fixes x y u w::"'a"
   851   shows "t x y = s u w"
   849   shows "t x y = s u w"
   852 apply(tactic {* Cong_Tac.cong_tac @{thm cong} 1 *})
   850 apply(tactic {* Cong_Tac.cong_tac @{context} @{thm cong} 1 *})
   853 txt{*\begin{minipage}{\textwidth}
   851 txt{*\begin{minipage}{\textwidth}
   854      @{subgoals [display]}
   852      @{subgoals [display]}
   855      \end{minipage}*}
   853      \end{minipage}*}
   856 (*<*)oops(*>*)
   854 (*<*)oops(*>*)
   857 
   855 
   879   that can be used to instantiate the theorem. The instantiation 
   877   that can be used to instantiate the theorem. The instantiation 
   880   can be done with the function @{ML_ind instantiate_normalize in Drule}. To automate 
   878   can be done with the function @{ML_ind instantiate_normalize in Drule}. To automate 
   881   this we implement the following function.
   879   this we implement the following function.
   882 *}
   880 *}
   883 
   881 
   884 ML %linenosgray{*fun fo_rtac thm = Subgoal.FOCUS (fn {concl, ...} =>
   882 ML %linenosgray{*fun fo_rtac thm = Subgoal.FOCUS (fn {context, concl, ...} =>
   885   let 
   883   let 
   886     val concl_pat = Drule.strip_imp_concl (cprop_of thm)
   884     val concl_pat = Drule.strip_imp_concl (Thm.cprop_of thm)
   887     val insts = Thm.first_order_match (concl_pat, concl)
   885     val insts = Thm.first_order_match (concl_pat, concl)
   888   in
   886   in
   889     rtac (Drule.instantiate_normalize insts thm) 1
   887     resolve_tac context [(Drule.instantiate_normalize insts thm)] 1
   890   end)*}
   888   end)*}
   891 
   889 
   892 text {*
   890 text {*
   893   Note that we use @{ML FOCUS in Subgoal} because it gives us directly access
   891   Note that we use @{ML FOCUS in Subgoal} because it gives us directly access
   894   to the conclusion of the goal state, but also because this function 
   892   to the conclusion of the goal state, but also because this function 
   928   which just strings together two tactics in a sequence. For example:
   926   which just strings together two tactics in a sequence. For example:
   929 *}
   927 *}
   930 
   928 
   931 lemma 
   929 lemma 
   932   shows "(Foo \<and> Bar) \<and> False"
   930   shows "(Foo \<and> Bar) \<and> False"
   933 apply(tactic {* rtac @{thm conjI} 1 THEN rtac @{thm conjI} 1 *})
   931 apply(tactic {* resolve_tac @{context} [@{thm conjI}] 1 THEN resolve_tac @{context} [@{thm conjI}] 1 *})
   934 txt {* \begin{minipage}{\textwidth}
   932 txt {* \begin{minipage}{\textwidth}
   935        @{subgoals [display]} 
   933        @{subgoals [display]} 
   936        \end{minipage} *}
   934        \end{minipage} *}
   937 (*<*)oops(*>*)
   935 (*<*)oops(*>*)
   938 
   936 
   942   For example:
   940   For example:
   943 *}
   941 *}
   944 
   942 
   945 lemma 
   943 lemma 
   946   shows "(Foo \<and> Bar) \<and> False"
   944   shows "(Foo \<and> Bar) \<and> False"
   947 apply(tactic {* (rtac @{thm conjI} THEN' rtac @{thm conjI}) 1 *})
   945 apply(tactic {* (resolve_tac @{context} [@{thm conjI}] THEN' resolve_tac @{context} [@{thm conjI}]) 1 *})
   948 txt {* \begin{minipage}{\textwidth}
   946 txt {* \begin{minipage}{\textwidth}
   949        @{subgoals [display]} 
   947        @{subgoals [display]} 
   950        \end{minipage} *}
   948        \end{minipage} *}
   951 (*<*)oops(*>*)
   949 (*<*)oops(*>*)
   952 
   950 
   962   and then apply a tactic to each of the two subgoals. 
   960   and then apply a tactic to each of the two subgoals. 
   963 *}
   961 *}
   964 
   962 
   965 lemma 
   963 lemma 
   966   shows "A \<Longrightarrow> True \<and> A"
   964   shows "A \<Longrightarrow> True \<and> A"
   967 apply(tactic {* (rtac @{thm conjI} 
   965 apply(tactic {* (resolve_tac @{context} [@{thm conjI}] 
   968                  THEN' RANGE [rtac @{thm TrueI}, atac]) 1 *})
   966                  THEN' RANGE [resolve_tac @{context} [@{thm TrueI}], assume_tac @{context}]) 1 *})
   969 txt {* \begin{minipage}{\textwidth}
   967 txt {* \begin{minipage}{\textwidth}
   970        @{subgoals [display]} 
   968        @{subgoals [display]} 
   971        \end{minipage} *}
   969        \end{minipage} *}
   972 (*<*)oops(*>*)
   970 (*<*)oops(*>*)
   973 
   971 
   976   one specified subgoal, you can use the combinator @{ML_ind EVERY' in
   974   one specified subgoal, you can use the combinator @{ML_ind EVERY' in
   977   Tactical}. For example the function @{ML foo_tac'} from
   975   Tactical}. For example the function @{ML foo_tac'} from
   978   page~\pageref{tac:footacprime} can also be written as:
   976   page~\pageref{tac:footacprime} can also be written as:
   979 *}
   977 *}
   980 
   978 
   981 ML %grayML{*val foo_tac'' = EVERY' [etac @{thm disjE}, rtac @{thm disjI2}, 
   979 ML %grayML{*fun foo_tac'' ctxt = 
   982                         atac, rtac @{thm disjI1}, atac]*}
   980   EVERY' [eresolve_tac ctxt [@{thm disjE}], resolve_tac ctxt [@{thm disjI2}], 
       
   981           assume_tac ctxt, resolve_tac ctxt [@{thm disjI1}], assume_tac ctxt]*}
   983 
   982 
   984 text {*
   983 text {*
   985   There is even another way of implementing this tactic: in automatic proof
   984   There is even another way of implementing this tactic: in automatic proof
   986   procedures (in contrast to tactics that might be called by the user) there
   985   procedures (in contrast to tactics that might be called by the user) there
   987   are often long lists of tactics that are applied to the first
   986   are often long lists of tactics that are applied to the first
   988   subgoal. Instead of writing the code above and then calling @{ML "foo_tac'' 1"}, 
   987   subgoal. Instead of writing the code above and then calling @{ML "foo_tac'' @{context} 1"}, 
   989   you can also just write
   988   you can also just write
   990 *}
   989 *}
   991 
   990 
   992 ML %grayML{*val foo_tac1 = EVERY1 [etac @{thm disjE}, rtac @{thm disjI2}, 
   991 ML %grayML{*fun foo_tac1 ctxt = 
   993                        atac, rtac @{thm disjI1}, atac]*}
   992   EVERY1 [eresolve_tac ctxt [@{thm disjE}], resolve_tac ctxt [@{thm disjI2}], 
       
   993           assume_tac ctxt, resolve_tac ctxt [@{thm disjI1}], assume_tac ctxt]*}
   994 
   994 
   995 text {*
   995 text {*
   996   and call @{ML foo_tac1}.  
   996   and call @{ML foo_tac1}.  
   997 
   997 
   998   With the combinators @{ML THEN'}, @{ML EVERY'} and @{ML_ind  EVERY1 in Tactical} it must be
   998   With the combinators @{ML THEN'}, @{ML EVERY'} and @{ML_ind  EVERY1 in Tactical} it must be
  1001   then you can use the combinator @{ML_ind  ORELSE' in Tactical} for two tactics, and @{ML_ind
  1001   then you can use the combinator @{ML_ind  ORELSE' in Tactical} for two tactics, and @{ML_ind
  1002    FIRST' in Tactical} (or @{ML_ind  FIRST1 in Tactical}) for a list of tactics. For example, the tactic
  1002    FIRST' in Tactical} (or @{ML_ind  FIRST1 in Tactical}) for a list of tactics. For example, the tactic
  1003 
  1003 
  1004 *}
  1004 *}
  1005 
  1005 
  1006 ML %grayML{*val orelse_xmp_tac = rtac @{thm disjI1} ORELSE' rtac @{thm conjI}*}
  1006 ML %grayML{*fun orelse_xmp_tac ctxt = 
       
  1007   resolve_tac ctxt [@{thm disjI1}] ORELSE' resolve_tac ctxt [@{thm conjI}]*}
  1007 
  1008 
  1008 text {*
  1009 text {*
  1009   will first try out whether theorem @{text disjI} applies and in case of failure 
  1010   will first try out whether theorem @{text disjI} applies and in case of failure 
  1010   will try @{text conjI}. To see this consider the proof
  1011   will try @{text conjI}. To see this consider the proof
  1011 *}
  1012 *}
  1012 
  1013 
  1013 lemma 
  1014 lemma 
  1014   shows "True \<and> False" and "Foo \<or> Bar"
  1015   shows "True \<and> False" and "Foo \<or> Bar"
  1015 apply(tactic {* orelse_xmp_tac 2 *})
  1016 apply(tactic {* orelse_xmp_tac @{context} 2 *})
  1016 apply(tactic {* orelse_xmp_tac 1 *})
  1017 apply(tactic {* orelse_xmp_tac @{context} 1 *})
  1017 txt {* which results in the goal state
  1018 txt {* which results in the goal state
  1018        \begin{isabelle}
  1019        \begin{isabelle}
  1019        @{subgoals [display]} 
  1020        @{subgoals [display]} 
  1020        \end{isabelle}
  1021        \end{isabelle}
  1021 *}
  1022 *}
  1025 text {*
  1026 text {*
  1026   Using @{ML FIRST'} we can simplify our @{ML select_tac} from Page~\pageref{tac:selecttac} 
  1027   Using @{ML FIRST'} we can simplify our @{ML select_tac} from Page~\pageref{tac:selecttac} 
  1027   as follows:
  1028   as follows:
  1028 *}
  1029 *}
  1029 
  1030 
  1030 ML %grayML{*val select_tac' = FIRST' [rtac @{thm conjI}, rtac @{thm impI}, 
  1031 ML %grayML{*fun select_tac' ctxt = 
  1031                           rtac @{thm notI}, rtac @{thm allI}, K all_tac]*}text_raw{*\label{tac:selectprime}*}
  1032   FIRST' [resolve_tac ctxt [@{thm conjI}], resolve_tac ctxt [@{thm impI}], 
       
  1033           resolve_tac ctxt [@{thm notI}], resolve_tac ctxt [@{thm allI}], K all_tac]*}text_raw{*\label{tac:selectprime}*}
  1032 
  1034 
  1033 text {*
  1035 text {*
  1034   Since we like to mimic the behaviour of @{ML select_tac} as closely as possible, 
  1036   Since we like to mimic the behaviour of @{ML select_tac} as closely as possible, 
  1035   we must include @{ML all_tac} at the end of the list, otherwise the tactic will
  1037   we must include @{ML all_tac} at the end of the list, otherwise the tactic will
  1036   fail if no theorem applies (we also have to wrap @{ML all_tac} using the 
  1038   fail if no theorem applies (we also have to wrap @{ML all_tac} using the 
  1038   test the tactic on the same goals:
  1040   test the tactic on the same goals:
  1039 *}
  1041 *}
  1040 
  1042 
  1041 lemma 
  1043 lemma 
  1042   shows "A \<and> B" and "A \<longrightarrow> B \<longrightarrow>C" and "\<forall>x. D x" and "E \<Longrightarrow> F"
  1044   shows "A \<and> B" and "A \<longrightarrow> B \<longrightarrow>C" and "\<forall>x. D x" and "E \<Longrightarrow> F"
  1043 apply(tactic {* select_tac' 4 *})
  1045 apply(tactic {* select_tac' @{context} 4 *})
  1044 apply(tactic {* select_tac' 3 *})
  1046 apply(tactic {* select_tac' @{context} 3 *})
  1045 apply(tactic {* select_tac' 2 *})
  1047 apply(tactic {* select_tac' @{context} 2 *})
  1046 apply(tactic {* select_tac' 1 *})
  1048 apply(tactic {* select_tac' @{context} 1 *})
  1047 txt{* \begin{minipage}{\textwidth}
  1049 txt{* \begin{minipage}{\textwidth}
  1048       @{subgoals [display]}
  1050       @{subgoals [display]}
  1049       \end{minipage} *}
  1051       \end{minipage} *}
  1050 (*<*)oops(*>*)
  1052 (*<*)oops(*>*)
  1051 
  1053 
  1055   @{ML_ind  ALLGOALS in Tactical} that simplifies this. Using this combinator you can simply 
  1057   @{ML_ind  ALLGOALS in Tactical} that simplifies this. Using this combinator you can simply 
  1056   write: *}
  1058   write: *}
  1057 
  1059 
  1058 lemma 
  1060 lemma 
  1059   shows "A \<and> B" and "A \<longrightarrow> B \<longrightarrow>C" and "\<forall>x. D x" and "E \<Longrightarrow> F"
  1061   shows "A \<and> B" and "A \<longrightarrow> B \<longrightarrow>C" and "\<forall>x. D x" and "E \<Longrightarrow> F"
  1060 apply(tactic {* ALLGOALS select_tac' *})
  1062 apply(tactic {* ALLGOALS (select_tac' @{context}) *})
  1061 txt{* \begin{minipage}{\textwidth}
  1063 txt{* \begin{minipage}{\textwidth}
  1062       @{subgoals [display]}
  1064       @{subgoals [display]}
  1063       \end{minipage} *}
  1065       \end{minipage} *}
  1064 (*<*)oops(*>*)
  1066 (*<*)oops(*>*)
  1065 
  1067 
  1068   always  succeeds by fact of having @{ML all_tac} at the end of the tactic
  1070   always  succeeds by fact of having @{ML all_tac} at the end of the tactic
  1069   list. The same can be achieved with the tactic combinator @{ML_ind  TRY in Tactical}.
  1071   list. The same can be achieved with the tactic combinator @{ML_ind  TRY in Tactical}.
  1070   For example:
  1072   For example:
  1071 *}
  1073 *}
  1072 
  1074 
  1073 ML %grayML{*val select_tac'' = TRY o FIRST' [rtac @{thm conjI}, rtac @{thm impI}, 
  1075 ML %grayML{*fun select_tac'' ctxt = 
  1074                                  rtac @{thm notI}, rtac @{thm allI}]*}
  1076  TRY o FIRST' [resolve_tac ctxt [@{thm conjI}], resolve_tac ctxt [@{thm impI}], 
       
  1077                resolve_tac ctxt [@{thm notI}], resolve_tac ctxt [@{thm allI}]]*}
  1075 text_raw{*\label{tac:selectprimeprime}*}
  1078 text_raw{*\label{tac:selectprimeprime}*}
  1076 
  1079 
  1077 text {*
  1080 text {*
  1078   This tactic behaves in the same way as @{ML select_tac'}: it tries out
  1081   This tactic behaves in the same way as @{ML select_tac'}: it tries out
  1079   one of the given tactics and if none applies leaves the goal state 
  1082   one of the given tactics and if none applies leaves the goal state 
  1082 
  1085 
  1083 *}
  1086 *}
  1084 
  1087 
  1085 lemma 
  1088 lemma 
  1086   shows "E \<Longrightarrow> F"
  1089   shows "E \<Longrightarrow> F"
  1087 apply(tactic {* select_tac' 1 *})
  1090 apply(tactic {* select_tac' @{context} 1 *})
  1088 txt{* \begin{minipage}{\textwidth}
  1091 txt{* \begin{minipage}{\textwidth}
  1089       @{subgoals [display]}
  1092       @{subgoals [display]}
  1090       \end{minipage} *}
  1093       \end{minipage} *}
  1091 (*<*)oops(*>*)
  1094 (*<*)oops(*>*)
  1092 
  1095 
  1105   now
  1108   now
  1106 *}
  1109 *}
  1107 
  1110 
  1108 lemma 
  1111 lemma 
  1109   shows "E \<Longrightarrow> F"
  1112   shows "E \<Longrightarrow> F"
  1110 apply(tactic {* CHANGED (select_tac' 1) *})(*<*)?(*>*)
  1113 apply(tactic {* CHANGED (select_tac' @{context} 1) *})(*<*)?(*>*)
  1111 txt{* gives the error message:
  1114 txt{* gives the error message:
  1112   \begin{isabelle}
  1115   \begin{isabelle}
  1113   @{text "*** empty result sequence -- proof command failed"}\\
  1116   @{text "*** empty result sequence -- proof command failed"}\\
  1114   @{text "*** At command \"apply\"."}
  1117   @{text "*** At command \"apply\"."}
  1115   \end{isabelle} 
  1118   \end{isabelle} 
  1121   connective, but also to the ones immediately ``underneath'', i.e.~analyse the goal 
  1124   connective, but also to the ones immediately ``underneath'', i.e.~analyse the goal 
  1122   completely. For this you can use the tactic combinator @{ML_ind REPEAT in Tactical}. As an example 
  1125   completely. For this you can use the tactic combinator @{ML_ind REPEAT in Tactical}. As an example 
  1123   suppose the following tactic
  1126   suppose the following tactic
  1124 *}
  1127 *}
  1125 
  1128 
  1126 ML %grayML{*val repeat_xmp_tac = REPEAT (CHANGED (select_tac' 1)) *}
  1129 ML %grayML{*fun repeat_xmp_tac ctxt = REPEAT (CHANGED (select_tac' ctxt 1)) *}
  1127 
  1130 
  1128 text {* which applied to the proof *}
  1131 text {* which applied to the proof *}
  1129 
  1132 
  1130 lemma 
  1133 lemma 
  1131   shows "((\<not>A) \<and> (\<forall>x. B x)) \<and> (C \<longrightarrow> D)"
  1134   shows "((\<not>A) \<and> (\<forall>x. B x)) \<and> (C \<longrightarrow> D)"
  1132 apply(tactic {* repeat_xmp_tac *})
  1135 apply(tactic {* repeat_xmp_tac @{context} *})
  1133 txt{* produces
  1136 txt{* produces
  1134       \begin{isabelle}
  1137       \begin{isabelle}
  1135       @{subgoals [display]}
  1138       @{subgoals [display]}
  1136       \end{isabelle} *}
  1139       \end{isabelle} *}
  1137 (*<*)oops(*>*)
  1140 (*<*)oops(*>*)
  1145 
  1148 
  1146   If you are after the ``primed'' version of @{ML repeat_xmp_tac}, then you 
  1149   If you are after the ``primed'' version of @{ML repeat_xmp_tac}, then you 
  1147   can implement it as
  1150   can implement it as
  1148 *}
  1151 *}
  1149 
  1152 
  1150 ML %grayML{*val repeat_xmp_tac' = REPEAT o CHANGED o select_tac'*}
  1153 ML %grayML{*fun repeat_xmp_tac' ctxt = REPEAT o CHANGED o select_tac' ctxt*}
  1151 
  1154 
  1152 text {*
  1155 text {*
  1153   since there are no ``primed'' versions of @{ML REPEAT} and @{ML CHANGED}.
  1156   since there are no ``primed'' versions of @{ML REPEAT} and @{ML CHANGED}.
  1154 
  1157 
  1155   If you look closely at the goal state above, then you see the tactics @{ML repeat_xmp_tac}
  1158   If you look closely at the goal state above, then you see the tactics @{ML repeat_xmp_tac}
  1158   is applied repeatedly only to the first subgoal. To analyse also all
  1161   is applied repeatedly only to the first subgoal. To analyse also all
  1159   resulting subgoals, you can use the tactic combinator @{ML_ind  REPEAT_ALL_NEW in Tactical}. 
  1162   resulting subgoals, you can use the tactic combinator @{ML_ind  REPEAT_ALL_NEW in Tactical}. 
  1160   Supposing the tactic
  1163   Supposing the tactic
  1161 *}
  1164 *}
  1162 
  1165 
  1163 ML %grayML{*val repeat_all_new_xmp_tac = REPEAT_ALL_NEW (CHANGED o select_tac')*}
  1166 ML %grayML{*fun repeat_all_new_xmp_tac ctxt = REPEAT_ALL_NEW (CHANGED o select_tac' ctxt)*}
  1164 
  1167 
  1165 text {* 
  1168 text {* 
  1166   you can see that the following goal
  1169   you can see that the following goal
  1167 *}
  1170 *}
  1168 
  1171 
  1169 lemma 
  1172 lemma 
  1170   shows "((\<not>A) \<and> (\<forall>x. B x)) \<and> (C \<longrightarrow> D)"
  1173   shows "((\<not>A) \<and> (\<forall>x. B x)) \<and> (C \<longrightarrow> D)"
  1171 apply(tactic {* repeat_all_new_xmp_tac 1 *})
  1174 apply(tactic {* repeat_all_new_xmp_tac @{context} 1 *})
  1172 txt{* \begin{minipage}{\textwidth}
  1175 txt{* \begin{minipage}{\textwidth}
  1173       @{subgoals [display]}
  1176       @{subgoals [display]}
  1174       \end{minipage} *}
  1177       \end{minipage} *}
  1175 (*<*)oops(*>*)
  1178 (*<*)oops(*>*)
  1176 
  1179 
  1183 
  1186 
  1184 *}
  1187 *}
  1185 
  1188 
  1186 lemma 
  1189 lemma 
  1187   shows "\<lbrakk>P1 \<or> Q1; P2 \<or> Q2\<rbrakk> \<Longrightarrow> R"
  1190   shows "\<lbrakk>P1 \<or> Q1; P2 \<or> Q2\<rbrakk> \<Longrightarrow> R"
  1188 apply(tactic {* etac @{thm disjE} 1 *})
  1191 apply(tactic {* eresolve_tac @{context} [@{thm disjE}] 1 *})
  1189 txt{* applies the rule to the first assumption yielding the goal state:
  1192 txt{* applies the rule to the first assumption yielding the goal state:
  1190       \begin{isabelle}
  1193       \begin{isabelle}
  1191       @{subgoals [display]}
  1194       @{subgoals [display]}
  1192       \end{isabelle}
  1195       \end{isabelle}
  1193 
  1196 
  1195   *}
  1198   *}
  1196 (*<*)
  1199 (*<*)
  1197 oops
  1200 oops
  1198 lemma 
  1201 lemma 
  1199   shows "\<lbrakk>P1 \<or> Q1; P2 \<or> Q2\<rbrakk> \<Longrightarrow> R"
  1202   shows "\<lbrakk>P1 \<or> Q1; P2 \<or> Q2\<rbrakk> \<Longrightarrow> R"
  1200 apply(tactic {* etac @{thm disjE} 1 *})
  1203 apply(tactic {* eresolve_tac @{context} [@{thm disjE}] 1 *})
  1201 (*>*)
  1204 (*>*)
  1202 back
  1205 back
  1203 txt{* the rule now applies to the second assumption.
  1206 txt{* the rule now applies to the second assumption.
  1204       \begin{isabelle}
  1207       \begin{isabelle}
  1205       @{subgoals [display]}
  1208       @{subgoals [display]}
  1213   combinator @{ML_ind  DETERM in Tactical}.
  1216   combinator @{ML_ind  DETERM in Tactical}.
  1214 *}
  1217 *}
  1215 
  1218 
  1216 lemma 
  1219 lemma 
  1217   shows "\<lbrakk>P1 \<or> Q1; P2 \<or> Q2\<rbrakk> \<Longrightarrow> R"
  1220   shows "\<lbrakk>P1 \<or> Q1; P2 \<or> Q2\<rbrakk> \<Longrightarrow> R"
  1218 apply(tactic {* DETERM (etac @{thm disjE} 1) *})
  1221 apply(tactic {* DETERM (eresolve_tac @{context} [@{thm disjE}] 1) *})
  1219 txt {*\begin{minipage}{\textwidth}
  1222 txt {*\begin{minipage}{\textwidth}
  1220       @{subgoals [display]}
  1223       @{subgoals [display]}
  1221       \end{minipage} *}
  1224       \end{minipage} *}
  1222 (*<*)oops(*>*)
  1225 (*<*)oops(*>*)
  1223 text {*
  1226 text {*
  1432 
  1435 
  1433   fun name_sthm (nm, thm) =
  1436   fun name_sthm (nm, thm) =
  1434     Pretty.enclose (nm ^ ": ") "" [pretty_thm_no_vars ctxt thm]
  1437     Pretty.enclose (nm ^ ": ") "" [pretty_thm_no_vars ctxt thm]
  1435   fun name_cthm ((_, nm), thm) =
  1438   fun name_cthm ((_, nm), thm) =
  1436     Pretty.enclose (nm ^ ": ") "" [pretty_thm_no_vars ctxt thm]
  1439     Pretty.enclose (nm ^ ": ") "" [pretty_thm_no_vars ctxt thm]
  1437   fun name_ctrm (nm, ctrm) =
  1440   fun name_trm (nm, trm) =
  1438     Pretty.enclose (nm ^ ": ") "" [pretty_cterms ctxt ctrm]
  1441     Pretty.enclose (nm ^ ": ") "" [pretty_terms ctxt trm]
  1439 
  1442 
  1440   val pps = [Pretty.big_list "Simplification rules:" (map name_sthm simps),
  1443   val pps = [Pretty.big_list "Simplification rules:" (map name_sthm simps),
  1441              Pretty.big_list "Congruences rules:" (map name_cthm congs),
  1444              Pretty.big_list "Congruences rules:" (map name_cthm congs),
  1442              Pretty.big_list "Simproc patterns:" (map name_ctrm procs)]
  1445              Pretty.big_list "Simproc patterns:" (map name_trm procs)]
  1443 in
  1446 in
  1444   pps |> Pretty.chunks
  1447   pps |> Pretty.chunks
  1445       |> pwriteln
  1448       |> pwriteln
  1446 end*}
  1449 end*}
  1447 text_raw {* 
  1450 text_raw {* 
  1746   In order to solve all cases we have to deal with corner-cases such as the
  1749   In order to solve all cases we have to deal with corner-cases such as the
  1747   lemma being an exact instance of the permutation composition lemma. This can
  1750   lemma being an exact instance of the permutation composition lemma. This can
  1748   often be done easier by implementing a simproc or a conversion. Both will be 
  1751   often be done easier by implementing a simproc or a conversion. Both will be 
  1749   explained in the next two chapters.
  1752   explained in the next two chapters.
  1750 
  1753 
  1751   (FIXME: Is it interesting to say something about @{term "op =simp=>"}?)
  1754   (FIXME: Is it interesting to say something about @{term "(=simp=>)"}?)
  1752 
  1755 
  1753   (FIXME: What are the second components of the congruence rules---something to
  1756   (FIXME: What are the second components of the congruence rules---something to
  1754   do with weak congruence constants?)
  1757   do with weak congruence constants?)
  1755 
  1758 
  1756   (FIXME: what are @{ML mksimps_pairs}; used in Nominal.thy)
  1759   (FIXME: what are @{ML mksimps_pairs}; used in Nominal.thy)
  1844   want this, then you have to use a slightly different method for setting 
  1847   want this, then you have to use a slightly different method for setting 
  1845   up the simproc. First the function @{ML fail_simproc} needs to be modified
  1848   up the simproc. First the function @{ML fail_simproc} needs to be modified
  1846   to
  1849   to
  1847 *}
  1850 *}
  1848 
  1851 
  1849 ML %grayML{*fun fail_simproc' ctxt redex = 
  1852 ML %grayML{*fun fail_simproc' _ ctxt redex = 
  1850 let
  1853 let
  1851   val _ = pwriteln (Pretty.block 
  1854   val _ = pwriteln (Pretty.block 
  1852     [Pretty.str "The redex:", pretty_term ctxt redex])
  1855     [Pretty.str "The redex:", pretty_cterm ctxt redex])
  1853 in
  1856 in
  1854   NONE
  1857   NONE
  1855 end*}
  1858 end*}
  1856 
  1859 
  1857 text {*
  1860 text {*
  1858   Here the redex is given as a @{ML_type term}, instead of a @{ML_type cterm}
  1861   Here the redex is given as a @{ML_type term}, instead of a @{ML_type cterm}
  1859   (therefore we printing it out using the function @{ML pretty_term in Pretty}).
  1862   (therefore we printing it out using the function @{ML pretty_term in Pretty}).
  1860   We can turn this function into a proper simproc using the function 
  1863   We can turn this function into a proper simproc using the function 
  1861   @{ML Simplifier.simproc_global_i}:
  1864   @{ML Simplifier.make_simproc}:
  1862 *}
  1865 *}
  1863 
  1866 
  1864 
  1867 ML %grayML{*val fail' = 
  1865 ML %grayML{*fun fail' ctxt = 
  1868   Simplifier.make_simproc @{context} "fail_simproc'"
  1866 let 
  1869     {lhss = [@{term "Suc n"}], proc = fail_simproc'}*}
  1867   val thy = @{theory}
       
  1868   val pat = [@{term "Suc n"}]
       
  1869 in
       
  1870   Simplifier.simproc_global_i thy "fail_simproc'" pat (K fail_simproc' ctxt)
       
  1871 end*}
       
  1872 
  1870 
  1873 text {*
  1871 text {*
  1874   Here the pattern is given as @{ML_type term} (instead of @{ML_type cterm}).
  1872   Here the pattern is given as @{ML_type term} (instead of @{ML_type cterm}).
  1875   The function also takes a list of patterns that can trigger the simproc.
  1873   The function also takes a list of patterns that can trigger the simproc.
  1876   Now the simproc is set up and can be explicitly added using
  1874   Now the simproc is set up and can be explicitly added using
  1881   see this in the proof
  1879   see this in the proof
  1882 *}
  1880 *}
  1883 
  1881 
  1884 lemma 
  1882 lemma 
  1885   shows "Suc (Suc 0) = (Suc 1)"
  1883   shows "Suc (Suc 0) = (Suc 1)"
  1886 apply(tactic {* simp_tac ((put_simpset HOL_basic_ss @{context}) addsimprocs [fail' @{context}]) 1*})
  1884 apply(tactic {* simp_tac ((put_simpset HOL_basic_ss @{context}) addsimprocs [fail']) 1*})
  1887 (*<*)oops(*>*)
  1885 (*<*)oops(*>*)
  1888 
  1886 
  1889 text {*
  1887 text {*
  1890   The simproc @{ML fail'} prints out the sequence 
  1888   The simproc @{ML fail'} prints out the sequence 
  1891 
  1889 
  1908   the rewriting with simprocs, let us further assume we want that the simproc
  1906   the rewriting with simprocs, let us further assume we want that the simproc
  1909   only rewrites terms ``greater'' than @{term "Suc 0"}. For this we can write 
  1907   only rewrites terms ``greater'' than @{term "Suc 0"}. For this we can write 
  1910 *}
  1908 *}
  1911 
  1909 
  1912 
  1910 
  1913 ML %grayML{*fun plus_one_simproc ctxt redex =
  1911 ML %grayML{*fun plus_one_simproc _ ctxt redex =
  1914   case redex of
  1912   case Thm.term_of redex of
  1915     @{term "Suc 0"} => NONE
  1913     @{term "Suc 0"} => NONE
  1916   | _ => SOME @{thm plus_one}*}
  1914   | _ => SOME @{thm plus_one}*}
  1917 
  1915 
  1918 text {*
  1916 text {*
  1919   and set up the simproc as follows.
  1917   and set up the simproc as follows.
  1920 *}
  1918 *}
  1921 
  1919 
  1922 ML %grayML{*fun plus_one ctxt =
  1920 ML %grayML{*val plus_one =
  1923 let
  1921   Simplifier.make_simproc @{context} "sproc +1"
  1924   val thy = @{theory}
  1922     {lhss = [@{term "Suc n"}], proc = plus_one_simproc}*}
  1925   val pat = [@{term "Suc n"}] 
       
  1926 in
       
  1927   Simplifier.simproc_global_i thy "sproc +1" pat (K plus_one_simproc ctxt)
       
  1928 end*}
       
  1929 
  1923 
  1930 text {*
  1924 text {*
  1931   Now the simproc is set up so that it is triggered by terms
  1925   Now the simproc is set up so that it is triggered by terms
  1932   of the form @{term "Suc n"}, but inside the simproc we only produce
  1926   of the form @{term "Suc n"}, but inside the simproc we only produce
  1933   a theorem if the term is not @{term "Suc 0"}. The result you can see
  1927   a theorem if the term is not @{term "Suc 0"}. The result you can see
  1934   in the following proof
  1928   in the following proof
  1935 *}
  1929 *}
  1936 
  1930 
  1937 lemma 
  1931 lemma 
  1938   shows "P (Suc (Suc (Suc 0))) (Suc 0)"
  1932   shows "P (Suc (Suc (Suc 0))) (Suc 0)"
  1939 apply(tactic {* simp_tac (put_simpset HOL_basic_ss @{context} addsimprocs [plus_one @{context}]) 1*})
  1933 apply(tactic {* simp_tac (put_simpset HOL_basic_ss @{context} addsimprocs [plus_one]) 1*})
  1940 txt{*
  1934 txt{*
  1941   where the simproc produces the goal state
  1935   where the simproc produces the goal state
  1942   \begin{isabelle}
  1936   \begin{isabelle}
  1943   @{subgoals[display]}
  1937   @{subgoals[display]}
  1944   \end{isabelle}
  1938   \end{isabelle}
  2009 
  2003 
  2010   Anyway, either version can be used in the function that produces the actual 
  2004   Anyway, either version can be used in the function that produces the actual 
  2011   theorem for the simproc.
  2005   theorem for the simproc.
  2012 *}
  2006 *}
  2013 
  2007 
  2014 ML %grayML{*fun nat_number_simproc ctxt t =
  2008 ML %grayML{*fun nat_number_simproc _ ctxt ct =
  2015   SOME (get_thm_alt ctxt (t, dest_suc_trm t))
  2009   SOME (get_thm_alt ctxt (Thm.term_of ct, dest_suc_trm (Thm.term_of ct)))
  2016   handle TERM _ => NONE *}
  2010   handle TERM _ => NONE *}
  2017 
  2011 
  2018 text {*
  2012 text {*
  2019   This function uses the fact that @{ML dest_suc_trm} might raise an exception 
  2013   This function uses the fact that @{ML dest_suc_trm} might raise an exception 
  2020   @{ML TERM}. In this case there is nothing that can be rewritten and therefore no
  2014   @{ML TERM}. In this case there is nothing that can be rewritten and therefore no
  2021   theorem is produced (i.e.~the function returns @{ML NONE}). To try out the simproc 
  2015   theorem is produced (i.e.~the function returns @{ML NONE}). To try out the simproc 
  2022   on an example, you can set it up as follows:
  2016   on an example, you can set it up as follows:
  2023 *}
  2017 *}
  2024 
  2018 
  2025 ML %grayML{*fun nat_number ctxt =
  2019 ML %grayML{*val nat_number =
  2026 let
  2020   Simplifier.make_simproc @{context} "nat_number"
  2027   val thy = @{theory}
  2021     {lhss = [@{term "Suc n"}], proc = nat_number_simproc}*}
  2028   val pat = [@{term "Suc n"}]
  2022 
  2029 in 
       
  2030   Simplifier.simproc_global_i thy "nat_number" pat (K nat_number_simproc ctxt) 
       
  2031 end*}
       
  2032 
  2023 
  2033 text {* 
  2024 text {* 
  2034   Now in the lemma
  2025   Now in the lemma
  2035   *}
  2026   *}
  2036 
  2027 
  2037 lemma 
  2028 lemma 
  2038   shows "P (Suc (Suc 2)) (Suc 99) (0::nat) (Suc 4 + Suc 0) (Suc (0 + 0))"
  2029   shows "P (Suc (Suc 2)) (Suc 99) (0::nat) (Suc 4 + Suc 0) (Suc (0 + 0))"
  2039 apply(tactic {* simp_tac (put_simpset HOL_ss @{context} addsimprocs [nat_number @{context}]) 1*})
  2030 apply(tactic {* simp_tac (put_simpset HOL_ss @{context} addsimprocs [nat_number]) 1*})
  2040 txt {* 
  2031 txt {* 
  2041   you obtain the more legible goal state
  2032   you obtain the more legible goal state
  2042   \begin{isabelle}
  2033   \begin{isabelle}
  2043   @{subgoals [display]}
  2034   @{subgoals [display]}
  2044   \end{isabelle}*}
  2035   \end{isabelle}*}
  2274   in all possible positions.
  2265   in all possible positions.
  2275 *}
  2266 *}
  2276 
  2267 
  2277 ML %linenosgray{*fun true_conj1_conv ctxt ctrm =
  2268 ML %linenosgray{*fun true_conj1_conv ctxt ctrm =
  2278   case (Thm.term_of ctrm) of
  2269   case (Thm.term_of ctrm) of
  2279     @{term "op \<and>"} $ @{term True} $ _ => 
  2270     @{term "(\<and>)"} $ @{term True} $ _ => 
  2280       (Conv.arg_conv (true_conj1_conv ctxt) then_conv
  2271       (Conv.arg_conv (true_conj1_conv ctxt) then_conv
  2281          Conv.rewr_conv @{thm true_conj1}) ctrm
  2272          Conv.rewr_conv @{thm true_conj1}) ctrm
  2282   | _ $ _ => Conv.comb_conv (true_conj1_conv ctxt) ctrm
  2273   | _ $ _ => Conv.comb_conv (true_conj1_conv ctxt) ctrm
  2283   | Abs _ => Conv.abs_conv (fn (_, ctxt) => true_conj1_conv ctxt) ctxt ctrm
  2274   | Abs _ => Conv.abs_conv (fn (_, ctxt) => true_conj1_conv ctxt) ctxt ctrm
  2284   | _ => Conv.all_conv ctrm*}
  2275   | _ => Conv.all_conv ctrm*}
  2489   @{ML_type "cterm -> thm"}). The code of the transformation is below.
  2480   @{ML_type "cterm -> thm"}). The code of the transformation is below.
  2490 *}
  2481 *}
  2491 
  2482 
  2492 ML %linenosgray{*fun unabs_def ctxt def =
  2483 ML %linenosgray{*fun unabs_def ctxt def =
  2493 let
  2484 let
  2494   val (lhs, rhs) = Thm.dest_equals (cprop_of def)
  2485   val (lhs, rhs) = Thm.dest_equals (Thm.cprop_of def)
  2495   val xs = strip_abs_vars (term_of rhs)
  2486   val xs = strip_abs_vars (Thm.term_of rhs)
  2496   val (_, ctxt') = Variable.add_fixes (map fst xs) ctxt
  2487   val (_, ctxt') = Variable.add_fixes (map fst xs) ctxt
  2497   
  2488   
  2498   val thy = Proof_Context.theory_of ctxt'
  2489   val cxs = map (Thm.cterm_of ctxt' o Free) xs
  2499   val cxs = map (cterm_of thy o Free) xs
       
  2500   val new_lhs = Drule.list_comb (lhs, cxs)
  2490   val new_lhs = Drule.list_comb (lhs, cxs)
  2501 
  2491 
  2502   fun get_conv [] = Conv.rewr_conv def
  2492   fun get_conv [] = Conv.rewr_conv def
  2503     | get_conv (_::xs) = Conv.fun_conv (get_conv xs)
  2493     | get_conv (_::xs) = Conv.fun_conv (get_conv xs)
  2504 in
  2494 in