ProgTutorial/Tactical.thy
changeset 298 8057d65607eb
parent 294 ee9d53fbb56b
child 299 d0b81d6e1b28
equal deleted inserted replaced
297:2565c87f8db7 298:8057d65607eb
   382 
   382 
   383 text {*
   383 text {*
   384   Similarly, @{ML [index] rtac}, @{ML [index] dtac}, @{ML [index] etac} and 
   384   Similarly, @{ML [index] rtac}, @{ML [index] dtac}, @{ML [index] etac} and 
   385   @{ML [index] ftac} correspond (roughly)
   385   @{ML [index] ftac} correspond (roughly)
   386   to @{text rule}, @{text drule}, @{text erule} and @{text frule}, 
   386   to @{text rule}, @{text drule}, @{text erule} and @{text frule}, 
   387   respectively. Each of them take a theorem as argument and attempt to 
   387   respectively. Each of them takes a theorem as argument and attempts to 
   388   apply it to a goal. Below are three self-explanatory examples.
   388   apply it to a goal. Below are three self-explanatory examples.
   389 *}
   389 *}
   390 
   390 
   391 lemma shows "P \<and> Q"
   391 lemma shows "P \<and> Q"
   392 apply(tactic {* rtac @{thm conjI} 1 *})
   392 apply(tactic {* rtac @{thm conjI} 1 *})
   455   procedure might become too fragile, if it just applies inference rules as 
   455   procedure might become too fragile, if it just applies inference rules as 
   456   shown above. The reason is that a number of rules introduce meta-variables 
   456   shown above. The reason is that a number of rules introduce meta-variables 
   457   into the goal state. Consider for example the proof
   457   into the goal state. Consider for example the proof
   458 *}
   458 *}
   459 
   459 
   460 lemma shows "\<forall>x\<in>A. P x \<Longrightarrow> Q x"
   460 lemma shows "\<forall>x \<in> A. P x \<Longrightarrow> Q x"
   461 apply(tactic {* dtac @{thm bspec} 1 *})
   461 apply(tactic {* dtac @{thm bspec} 1 *})
   462 txt{*\begin{minipage}{\textwidth}
   462 txt{*\begin{minipage}{\textwidth}
   463      @{subgoals [display]} 
   463      @{subgoals [display]} 
   464      \end{minipage}*}
   464      \end{minipage}*}
   465 (*<*)oops(*>*)
   465 (*<*)oops(*>*)
   523   \end{readmore}
   523   \end{readmore}
   524 
   524 
   525   Often proofs on the ML-level involve elaborate operations on assumptions and 
   525   Often proofs on the ML-level involve elaborate operations on assumptions and 
   526   @{text "\<And>"}-quantified variables. To do such operations using the basic tactics 
   526   @{text "\<And>"}-quantified variables. To do such operations using the basic tactics 
   527   shown so far is very unwieldy and brittle. Some convenience and
   527   shown so far is very unwieldy and brittle. Some convenience and
   528   safety is provided by @{ML [index] SUBPROOF}. This tactic fixes the parameters 
   528   safety is provided by the functions @{ML [index] FOCUS} and @{ML [index] SUBPROOF}. 
   529   and binds the various components of a goal state to a record. 
   529   These tactics fix the parameters 
       
   530   and bind the various components of a goal state to a record. 
   530   To see what happens, assume the function defined in Figure~\ref{fig:sptac}, which
   531   To see what happens, assume the function defined in Figure~\ref{fig:sptac}, which
   531   takes a record and just prints out the content of this record (using the 
   532   takes a record and just prints out the content of this record (using the 
   532   string transformation functions from in Section~\ref{sec:printing}). Consider
   533   string transformation functions from in Section~\ref{sec:printing}). Consider
   533   now the proof:
   534   now the proof:
   534 *}
   535 *}
   538 \begin{minipage}{\textwidth}
   539 \begin{minipage}{\textwidth}
   539 \begin{isabelle}
   540 \begin{isabelle}
   540 *}
   541 *}
   541 
   542 
   542 
   543 
   543 ML{*fun sp_tac {prems, params, asms, concl, context, schematics} = 
   544 ML{*fun foc_tac {prems, params, asms, concl, context, schematics} = 
   544 let 
   545 let 
   545   val string_of_params = string_of_cterms context (map snd params)
   546   val string_of_params = string_of_cterms context (map snd params)
   546   val test = commas (map fst params)
       
   547   val string_of_asms = string_of_cterms context asms
   547   val string_of_asms = string_of_cterms context asms
   548   val string_of_concl = string_of_cterm context concl
   548   val string_of_concl = string_of_cterm context concl
   549   val string_of_prems = string_of_thms_no_vars context prems   
   549   val string_of_prems = string_of_thms_no_vars context prems   
   550   val string_of_schms = string_of_cterms context (snd schematics)    
   550   val string_of_schms = string_of_cterms context (snd schematics)    
   551  
   551  
   552   val _ = (writeln ("params: " ^ string_of_params);
   552   val _ = (writeln ("params: " ^ string_of_params);
   553            writeln ("param names: " ^ test);
       
   554            writeln ("schematics: " ^ string_of_schms);
   553            writeln ("schematics: " ^ string_of_schms);
   555            writeln ("assumptions: " ^ string_of_asms);
   554            writeln ("assumptions: " ^ string_of_asms);
   556            writeln ("conclusion: " ^ string_of_concl);
   555            writeln ("conclusion: " ^ string_of_concl);
   557            writeln ("premises: " ^ string_of_prems))
   556            writeln ("premises: " ^ string_of_prems))
   558 in
   557 in
   559   no_tac 
   558   all_tac 
   560 end*}
   559 end*}
   561 text_raw{*
   560 text_raw{*
   562 \end{isabelle}
   561 \end{isabelle}
   563 \end{minipage}
   562 \end{minipage}
   564 \caption{A function that prints out the various parameters provided by the tactic
   563 \caption{A function that prints out the various parameters provided by 
   565  @{ML SUBPROOF}. It uses the functions defined in Section~\ref{sec:printing} for
   564  @{ML FOCUS} and @{ML SUBPROOF}. It uses the functions defined in Section~\ref{sec:printing} for
   566   extracting strings from @{ML_type cterm}s and @{ML_type thm}s.\label{fig:sptac}}
   565   extracting strings from @{ML_type cterm}s and @{ML_type thm}s.\label{fig:sptac}}
   567 \end{figure}
   566 \end{figure}
   568 *}
   567 *}
   569 
   568 
   570 lemma shows "\<And>x y. A x y \<Longrightarrow> B y x \<longrightarrow> C (?z y) x"
   569 lemma shows "\<And>x y. A x y \<Longrightarrow> B y x \<longrightarrow> C (?z y) x"
   571 apply(tactic {* SUBPROOF sp_tac @{context} 1 *})?
   570 apply(tactic {* FOCUS foc_tac @{context} 1 *})
   572 
   571 
   573 txt {*
   572 txt {*
   574   The tactic produces the following printout:
   573   The tactic produces the following printout:
   575 
   574 
   576   \begin{quote}\small
   575   \begin{quote}\small
   588   the subproof. By convention these fixed variables are printed in brown colour.
   587   the subproof. By convention these fixed variables are printed in brown colour.
   589   Similarly the schematic variable @{term z}. The assumption, or premise, 
   588   Similarly the schematic variable @{term z}. The assumption, or premise, 
   590   @{prop "A x y"} is bound as @{ML_type cterm} to the record-variable 
   589   @{prop "A x y"} is bound as @{ML_type cterm} to the record-variable 
   591   @{text asms}, but also as @{ML_type thm} to @{text prems}.
   590   @{text asms}, but also as @{ML_type thm} to @{text prems}.
   592 
   591 
   593   Notice also that we had to append @{text [quotes] "?"} to the
       
   594   \isacommand{apply}-command. The reason is that @{ML [index] SUBPROOF} normally
       
   595   expects that the subgoal is solved completely.  Since in the function @{ML
       
   596   sp_tac} we returned the tactic @{ML no_tac}, the subproof obviously
       
   597   fails. The question-mark allows us to recover from this failure in a
       
   598   graceful manner so that the output messages are not overwritten by an 
       
   599   ``empty sequence'' error message.
       
   600 
       
   601   If we continue the proof script by applying the @{text impI}-rule
   592   If we continue the proof script by applying the @{text impI}-rule
   602 *}
   593 *}
   603 
   594 
   604 apply(rule impI)
   595 apply(rule impI)
   605 apply(tactic {* SUBPROOF sp_tac @{context} 1 *})?
   596 apply(tactic {* FOCUS foc_tac @{context} 1 *})
   606 
   597 
   607 txt {*
   598 txt {*
   608   then the tactic prints out: 
   599   then the tactic prints out: 
   609 
   600 
   610   \begin{quote}\small
   601   \begin{quote}\small
   620 (*<*)oops(*>*)
   611 (*<*)oops(*>*)
   621 
   612 
   622 text {*
   613 text {*
   623   Now also @{term "B y x"} is an assumption bound to @{text asms} and @{text prems}.
   614   Now also @{term "B y x"} is an assumption bound to @{text asms} and @{text prems}.
   624 
   615 
   625   One convenience of @{ML SUBPROOF} is that we can apply the assumptions
   616   The difference between @{ML SUBPROOF} and @{ML FOCUS} is that the former
   626   using the usual tactics, because the parameter @{text prems} 
   617   expects that the goal is solved completely, which the latter does not.  One
   627   contains them as theorems. With this you can easily 
   618   convenience of both @{ML FOCUS} and @{ML SUBPROOF} is that we can apply the
   628   implement a tactic that behaves almost like @{ML atac}:
   619   assumptions using the usual tactics, because the parameter @{text prems}
       
   620   contains them as theorems. With this you can easily implement a tactic that
       
   621   behaves almost like @{ML atac}:
   629 *}
   622 *}
   630 
   623 
   631 ML{*val atac' = SUBPROOF (fn {prems, ...} => resolve_tac prems 1)*}
   624 ML{*val atac' = SUBPROOF (fn {prems, ...} => resolve_tac prems 1)*}
   632 
   625 
   633 text {*
   626 text {*
   662 done
   655 done
   663 
   656 
   664 
   657 
   665 text {*
   658 text {*
   666   \begin{readmore}
   659   \begin{readmore}
   667   The function @{ML SUBPROOF} is defined in @{ML_file "Pure/subgoal.ML"} and
   660   The functions @{ML FOCUS} and @{ML SUBPROOF} are defined in 
   668   also described in \isccite{sec:results}. 
   661   @{ML_file "Pure/subgoal.ML"} and also described in 
       
   662   \isccite{sec:results}. 
   669   \end{readmore}
   663   \end{readmore}
   670 
   664 
   671   Similar but less powerful functions than @{ML SUBPROOF} are @{ML [index] SUBGOAL}
   665   Similar but less powerful functions than @{ML FOCUS} are @{ML [index] SUBGOAL}
   672   and @{ML [index] CSUBGOAL}. They allow you to inspect a given subgoal (the former
   666   and @{ML [index] CSUBGOAL}. They allow you to inspect a given subgoal (the former
   673   presents the subgoal as a @{ML_type term}, while the latter as a @{ML_type
   667   presents the subgoal as a @{ML_type term}, while the latter as a @{ML_type
   674   cterm}). With this you can implement a tactic that applies a rule according
   668   cterm}). With this you can implement a tactic that applies a rule according
   675   to the topmost logic connective in the subgoal (to illustrate this we only
   669   to the topmost logic connective in the subgoal (to illustrate this we only
   676   analyse a few connectives). The code of the tactic is as
   670   analyse a few connectives). The code of the tactic is as
   697   construct the patterns, the pattern in Line 8 cannot be constructed in this
   691   construct the patterns, the pattern in Line 8 cannot be constructed in this
   698   way. The reason is that an antiquotation would fix the type of the
   692   way. The reason is that an antiquotation would fix the type of the
   699   quantified variable. So you really have to construct the pattern using the
   693   quantified variable. So you really have to construct the pattern using the
   700   basic term-constructors. This is not necessary in other cases, because their
   694   basic term-constructors. This is not necessary in other cases, because their
   701   type is always fixed to function types involving only the type @{typ
   695   type is always fixed to function types involving only the type @{typ
   702   bool}. (See Section \ref{sec:terms_manually} about constructing terms
   696   bool}. (See Section \ref{sec:terms_types_manually} about constructing terms
   703   manually.) For the catch-all pattern, we chose to just return @{ML all_tac}. 
   697   manually.) For the catch-all pattern, we chose to just return @{ML all_tac}. 
   704   Consequently, @{ML select_tac} never fails.
   698   Consequently, @{ML select_tac} never fails.
   705 
   699 
   706 
   700 
   707   Let us now see how to apply this tactic. Consider the four goals:
   701   Let us now see how to apply this tactic. Consider the four goals:
   874   list. The same can be achieved with the tactic combinator @{ML [index] TRY}.
   868   list. The same can be achieved with the tactic combinator @{ML [index] TRY}.
   875   For example:
   869   For example:
   876 *}
   870 *}
   877 
   871 
   878 ML{*val select_tac'' = TRY o FIRST' [rtac @{thm conjI}, rtac @{thm impI}, 
   872 ML{*val select_tac'' = TRY o FIRST' [rtac @{thm conjI}, rtac @{thm impI}, 
   879                           rtac @{thm notI}, rtac @{thm allI}]*}
   873                                  rtac @{thm notI}, rtac @{thm allI}]*}
   880 text_raw{*\label{tac:selectprimeprime}*}
   874 text_raw{*\label{tac:selectprimeprime}*}
   881 
   875 
   882 text {*
   876 text {*
   883   This tactic behaves in the same way as @{ML select_tac'}: it tries out
   877   This tactic behaves in the same way as @{ML select_tac'}: it tries out
   884   one of the given tactics and if none applies leaves the goal state 
   878   one of the given tactics and if none applies leaves the goal state