ProgTutorial/Tactical.thy
changeset 301 2728e8daebc0
parent 299 d0b81d6e1b28
child 302 0cbd34857b9e
equal deleted inserted replaced
300:f286dfa9f173 301:2728e8daebc0
   143   \begin{isabelle}
   143   \begin{isabelle}
   144   @{text "*** empty result sequence -- proof command failed"}\\
   144   @{text "*** empty result sequence -- proof command failed"}\\
   145   @{text "*** At command \"apply\"."}
   145   @{text "*** At command \"apply\"."}
   146   \end{isabelle}
   146   \end{isabelle}
   147 
   147 
   148   This means they failed.\footnote{To be precise tactics do not produce this error
   148   This means they failed.\footnote{To be precise, tactics do not produce this error
   149   message, it originates from the \isacommand{apply} wrapper.} The reason for this 
   149   message, it originates from the \isacommand{apply} wrapper.} The reason for this 
   150   error message is that tactics 
   150   error message is that tactics 
   151   are functions mapping a goal state to a (lazy) sequence of successor states. 
   151   are functions mapping a goal state to a (lazy) sequence of successor states. 
   152   Hence the type of a tactic is:
   152   Hence the type of a tactic is:
   153 *}
   153 *}
   210   tactic
   210   tactic
   211 *}
   211 *}
   212 
   212 
   213 ML{*fun my_print_tac ctxt thm =
   213 ML{*fun my_print_tac ctxt thm =
   214 let
   214 let
   215   val _ = writeln (string_of_thm_no_vars ctxt thm)
   215   val _ = tracing (string_of_thm_no_vars ctxt thm)
   216 in 
   216 in 
   217   Seq.single thm
   217   Seq.single thm
   218 end*}
   218 end*}
   219 
   219 
   220 text_raw {*
   220 text_raw {*
   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 the functions @{ML [index] FOCUS in Subgoal} and 
   528   safety is provided by the functions @{ML [index] FOCUS in Subgoal} and 
   529   @{ML [index] SUBPROOF}. These tactics fix the parameters 
   529   @{ML [index] SUBPROOF}. These tactics fix the parameters 
   530   and bind the various components of a goal state to a record. 
   530   and bind the various components of a goal state to a record. 
   531   To see what happens, assume the function defined in Figure~\ref{fig:sptac}, which
   531   To see what happens, use the function defined in Figure~\ref{fig:sptac}, which
   532   takes a record and just prints out the content of this record (using the 
   532   takes a record and just prints out the contents of this record. Consider
   533   string transformation functions from in Section~\ref{sec:printing}). Consider
       
   534   now the proof:
   533   now the proof:
   535 *}
   534 *}
   536 
   535 
   537 text_raw{*
   536 text_raw{*
   538 \begin{figure}[t]
   537 \begin{figure}[t]
   547   val string_of_asms = string_of_cterms context asms
   546   val string_of_asms = string_of_cterms context asms
   548   val string_of_concl = string_of_cterm context concl
   547   val string_of_concl = string_of_cterm context concl
   549   val string_of_prems = string_of_thms_no_vars context prems   
   548   val string_of_prems = string_of_thms_no_vars context prems   
   550   val string_of_schms = string_of_cterms context (map fst (snd schematics))    
   549   val string_of_schms = string_of_cterms context (map fst (snd schematics))    
   551  
   550  
   552   val _ = (writeln ("params: " ^ string_of_params);
   551   val _ = (tracing ("params: " ^ string_of_params);
   553            writeln ("schematics: " ^ string_of_schms);
   552            tracing ("schematics: " ^ string_of_schms);
   554            writeln ("assumptions: " ^ string_of_asms);
   553            tracing ("assumptions: " ^ string_of_asms);
   555            writeln ("conclusion: " ^ string_of_concl);
   554            tracing ("conclusion: " ^ string_of_concl);
   556            writeln ("premises: " ^ string_of_prems))
   555            tracing ("premises: " ^ string_of_prems))
   557 in
   556 in
   558   all_tac 
   557   all_tac 
   559 end*}
   558 end*}
   560 
   559 
   561 text_raw{*
   560 text_raw{*
   575   The tactic produces the following printout:
   574   The tactic produces the following printout:
   576 
   575 
   577   \begin{quote}\small
   576   \begin{quote}\small
   578   \begin{tabular}{ll}
   577   \begin{tabular}{ll}
   579   params:      & @{term x}, @{term y}\\
   578   params:      & @{term x}, @{term y}\\
   580   schematics:  & @{term z}\\
   579   schematics:  & @{text ?z}\\
   581   assumptions: & @{term "A x y"}\\
   580   assumptions: & @{term "A x y"}\\
   582   conclusion:  & @{term "B y x \<longrightarrow> C (z y) x"}\\
   581   conclusion:  & @{term "B y x \<longrightarrow> C (z y) x"}\\
   583   premises:    & @{term "A x y"}
   582   premises:    & @{term "A x y"}
   584   \end{tabular}
   583   \end{tabular}
   585   \end{quote}
   584   \end{quote}
   586 
   585 
   587   (FIXME: find out how nowadays the schmetics are handled)
   586   (FIXME: Find out how nowadays the schematics are handled)
   588 
   587 
   589   Notice in the actual output the brown colour of the variables @{term x} and 
   588   Notice in the actual output the brown colour of the variables @{term x}, 
   590   @{term y}. Although they are parameters in the original goal, they are fixed inside
   589   and @{term y}. Although they are parameters in the original goal, they are fixed inside
   591   the subproof. By convention these fixed variables are printed in brown colour.
   590   the tactic. By convention these fixed variables are printed in brown colour.
   592   Similarly the schematic variable @{term z}. The assumption, or premise, 
   591   Similarly the schematic variable @{text ?z}. The assumption, or premise, 
   593   @{prop "A x y"} is bound as @{ML_type cterm} to the record-variable 
   592   @{prop "A x y"} is bound as @{ML_type cterm} to the record-variable 
   594   @{text asms}, but also as @{ML_type thm} to @{text prems}.
   593   @{text asms}, but also as @{ML_type thm} to @{text prems}.
   595 
   594 
   596   If we continue the proof script by applying the @{text impI}-rule
   595   If we continue the proof script by applying the @{text impI}-rule
   597 *}
   596 *}
   603   then the tactic prints out: 
   602   then the tactic prints out: 
   604 
   603 
   605   \begin{quote}\small
   604   \begin{quote}\small
   606   \begin{tabular}{ll}
   605   \begin{tabular}{ll}
   607   params:      & @{term x}, @{term y}\\
   606   params:      & @{term x}, @{term y}\\
   608   schematics:  & @{term z}\\
   607   schematics:  & @{text ?z}\\
   609   assumptions: & @{term "A x y"}, @{term "B y x"}\\
   608   assumptions: & @{term "A x y"}, @{term "B y x"}\\
   610   conclusion:  & @{term "C (z y) x"}\\
   609   conclusion:  & @{term "C (z y) x"}\\
   611   premises:    & @{term "A x y"}, @{term "B y x"}
   610   premises:    & @{term "A x y"}, @{term "B y x"}
   612   \end{tabular}
   611   \end{tabular}
   613   \end{quote}
   612   \end{quote}
   615 (*<*)oops(*>*)
   614 (*<*)oops(*>*)
   616 
   615 
   617 text {*
   616 text {*
   618   Now also @{term "B y x"} is an assumption bound to @{text asms} and @{text prems}.
   617   Now also @{term "B y x"} is an assumption bound to @{text asms} and @{text prems}.
   619 
   618 
   620   The difference between @{ML SUBPROOF} and @{ML FOCUS in Subgoal} is that the former
   619   The difference between the tactics @{ML SUBPROOF} and @{ML FOCUS in Subgoal}
   621   expects that the goal is solved completely, which the latter does not.  One
   620   is that the former expects that the goal is solved completely, which the
   622   convenience of both @{ML FOCUS in Subgoal} and @{ML SUBPROOF} is that we can apply the
   621   latter does not. @{ML SUBPROOF} can also not instantiate an schematic
   623   assumptions using the usual tactics, because the parameter @{text prems}
   622   variables.
   624   contains them as theorems. With this you can easily implement a tactic that
   623 
   625   behaves almost like @{ML atac}:
   624   One convenience of both @{ML FOCUS in Subgoal} and @{ML SUBPROOF} is that we
   626 *}
   625   can apply the assumptions using the usual tactics, because the parameter
   627 
   626   @{text prems} contains them as theorems. With this you can easily implement
   628 ML{*val atac' = SUBPROOF (fn {prems, ...} => resolve_tac prems 1)*}
   627   a tactic that behaves almost like @{ML atac}:
       
   628 *}
       
   629 
       
   630 ML{*val atac' = Subgoal.FOCUS (fn {prems, ...} => resolve_tac prems 1)*}
   629 
   631 
   630 text {*
   632 text {*
   631   If you apply @{ML atac'} to the next lemma
   633   If you apply @{ML atac'} to the next lemma
   632 *}
   634 *}
   633 
   635 
   636 txt{* it will produce
   638 txt{* it will produce
   637       @{subgoals [display]} *}
   639       @{subgoals [display]} *}
   638 (*<*)oops(*>*)
   640 (*<*)oops(*>*)
   639 
   641 
   640 text {*
   642 text {*
   641   The restriction in this tactic which is not present in @{ML atac} is that it
   643   Notice that @{ML atac'} inside @{ML FOCUS in Subgoal} calls @{ML
   642   cannot instantiate any schematic variables. This might be seen as a defect,
   644   resolve_tac} with the subgoal number @{text "1"} and also the outer call to
   643   but it is actually an advantage in the situations for which @{ML SUBPROOF}
   645   @{ML FOCUS in Subgoal} in the \isacommand{apply}-step uses @{text "1"}. This
   644   was designed: the reason is that, as mentioned before, instantiation of
   646   is another advantage of @{ML FOCUS in Subgoal} and @{ML SUBPROOF}: the
   645   schematic variables can affect several goals and can render them
   647   addressing inside it is completely local to the tactic inside the
   646   unprovable. @{ML SUBPROOF} is meant to avoid this.
   648   subproof. It is therefore possible to also apply @{ML atac'} to the second
   647 
   649   goal by just writing:
   648   Notice that @{ML atac'} inside @{ML SUBPROOF} calls @{ML resolve_tac} with
   650 
   649   the subgoal number @{text "1"} and also the outer call to @{ML SUBPROOF} in
       
   650   the \isacommand{apply}-step uses @{text "1"}. This is another advantage of
       
   651   @{ML SUBPROOF}: the addressing inside it is completely local to the tactic
       
   652   inside the subproof. It is therefore possible to also apply @{ML atac'} to
       
   653   the second goal by just writing:
       
   654 *}
   651 *}
   655 
   652 
   656 lemma shows "True" and "\<lbrakk>B x y; A x y; C x y\<rbrakk> \<Longrightarrow> A x y"
   653 lemma shows "True" and "\<lbrakk>B x y; A x y; C x y\<rbrakk> \<Longrightarrow> A x y"
   657 apply(tactic {* atac' @{context} 2 *})
   654 apply(tactic {* atac' @{context} 2 *})
   658 apply(rule TrueI)
   655 apply(rule TrueI)
   664   The functions @{ML FOCUS in Subgoal} and @{ML SUBPROOF} are defined in 
   661   The functions @{ML FOCUS in Subgoal} and @{ML SUBPROOF} are defined in 
   665   @{ML_file "Pure/subgoal.ML"} and also described in 
   662   @{ML_file "Pure/subgoal.ML"} and also described in 
   666   \isccite{sec:results}. 
   663   \isccite{sec:results}. 
   667   \end{readmore}
   664   \end{readmore}
   668 
   665 
   669   Similar but less powerful functions than @{ML FOCUS in Subgoal} are 
   666   Similar but less powerful functions than @{ML FOCUS in Subgoal}, respectively
       
   667   @{ML SUBPROOF}, are 
   670   @{ML [index] SUBGOAL} and @{ML [index] CSUBGOAL}. They allow you to 
   668   @{ML [index] SUBGOAL} and @{ML [index] CSUBGOAL}. They allow you to 
   671   inspect a given subgoal (the former
   669   inspect a given subgoal (the former
   672   presents the subgoal as a @{ML_type term}, while the latter as a @{ML_type
   670   presents the subgoal as a @{ML_type term}, while the latter as a @{ML_type
   673   cterm}). With this you can implement a tactic that applies a rule according
   671   cterm}). With this you can implement a tactic that applies a rule according
   674   to the topmost logic connective in the subgoal (to illustrate this we only
   672   to the topmost logic connective in the subgoal (to illustrate this we only
  1194   val s = ["Simplification rules:"] @ map name_thm simps @
  1192   val s = ["Simplification rules:"] @ map name_thm simps @
  1195           ["Congruences rules:"] @ map name_thm congs @
  1193           ["Congruences rules:"] @ map name_thm congs @
  1196           ["Simproc patterns:"] @ map name_ctrm procs
  1194           ["Simproc patterns:"] @ map name_ctrm procs
  1197 in
  1195 in
  1198   s |> cat_lines
  1196   s |> cat_lines
  1199     |> writeln
  1197     |> tracing
  1200 end*}
  1198 end*}
  1201 text_raw {* 
  1199 text_raw {* 
  1202 \end{isabelle}
  1200 \end{isabelle}
  1203 \end{minipage}
  1201 \end{minipage}
  1204 \caption{The function @{ML [index] dest_ss in Simplifier} returns a record containing
  1202 \caption{The function @{ML [index] dest_ss in Simplifier} returns a record containing
  1521 *}
  1519 *}
  1522 
  1520 
  1523 ML %linenosgray{*fun fail_simproc simpset redex = 
  1521 ML %linenosgray{*fun fail_simproc simpset redex = 
  1524 let
  1522 let
  1525   val ctxt = Simplifier.the_context simpset
  1523   val ctxt = Simplifier.the_context simpset
  1526   val _ = writeln ("The redex: " ^ (string_of_cterm ctxt redex))
  1524   val _ = tracing ("The redex: " ^ (string_of_cterm ctxt redex))
  1527 in
  1525 in
  1528   NONE
  1526   NONE
  1529 end*}
  1527 end*}
  1530 
  1528 
  1531 text {*
  1529 text {*
  1592 *}
  1590 *}
  1593 
  1591 
  1594 ML{*fun fail_simproc' simpset redex = 
  1592 ML{*fun fail_simproc' simpset redex = 
  1595 let
  1593 let
  1596   val ctxt = Simplifier.the_context simpset
  1594   val ctxt = Simplifier.the_context simpset
  1597   val _ = writeln ("The redex: " ^ (Syntax.string_of_term ctxt redex))
  1595   val _ = tracing ("The redex: " ^ (Syntax.string_of_term ctxt redex))
  1598 in
  1596 in
  1599   NONE
  1597   NONE
  1600 end*}
  1598 end*}
  1601 
  1599 
  1602 text {*
  1600 text {*