CookBook/Tactical.thy
changeset 186 371e4375c994
parent 184 c7f04a008c9c
equal deleted inserted replaced
185:043ef82000b4 186:371e4375c994
   135   hard-coded inside the tactic. For most operators that combine tactics 
   135   hard-coded inside the tactic. For most operators that combine tactics 
   136   (@{ML THEN} is only one such operator) a ``primed'' version exists.
   136   (@{ML THEN} is only one such operator) a ``primed'' version exists.
   137 
   137 
   138   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
   139   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
   140   of this form, then they return the error message:
   140   of this form, then these tactics return the error message:
   141 
   141 
   142   \begin{isabelle}
   142   \begin{isabelle}
   143   @{text "*** empty result sequence -- proof command failed"}\\
   143   @{text "*** empty result sequence -- proof command failed"}\\
   144   @{text "*** At command \"apply\"."}
   144   @{text "*** At command \"apply\"."}
   145   \end{isabelle}
   145   \end{isabelle}
   146 
   146 
   147   This means the tactics failed. The reason for this error message is that tactics 
   147   This means they failed. The reason for this error message is that tactics 
   148   are functions mapping a goal state to a (lazy) sequence of successor states. 
   148   are functions mapping a goal state to a (lazy) sequence of successor states. 
   149   Hence the type of a tactic is:
   149   Hence the type of a tactic is:
   150 *}
   150 *}
   151   
   151   
   152 ML{*type tactic = thm -> thm Seq.seq*}
   152 ML{*type tactic = thm -> thm Seq.seq*}
   421      @{subgoals [display]} 
   421      @{subgoals [display]} 
   422      \end{minipage}*}
   422      \end{minipage}*}
   423 (*<*)oops(*>*)
   423 (*<*)oops(*>*)
   424 
   424 
   425 text {* 
   425 text {* 
   426   Similarl versions taking a list of theorems exist for the tactics 
   426   Similar versions taking a list of theorems exist for the tactics 
   427   @{ML dtac} (@{ML dresolve_tac}), @{ML etac} (@{ML eresolve_tac}) and so on.
   427   @{ML dtac} (@{ML dresolve_tac}), @{ML etac} (@{ML eresolve_tac}) and so on.
   428 
   428 
   429 
   429 
   430   Another simple tactic is @{ML cut_facts_tac}. It inserts a list of theorems
   430   Another simple tactic is @{ML cut_facts_tac}. It inserts a list of theorems
   431   into the assumptions of the current goal state. For example
   431   into the assumptions of the current goal state. For example
   675    | Const (@{const_name "All"}, _) $ _ => rtac @{thm allI} i
   675    | Const (@{const_name "All"}, _) $ _ => rtac @{thm allI} i
   676    | _ => all_tac*}
   676    | _ => all_tac*}
   677 
   677 
   678 text {*
   678 text {*
   679   The input of the function is a term representing the subgoal and a number
   679   The input of the function is a term representing the subgoal and a number
   680   specifying the subgoal of interest. In line 3 you need to descend under the
   680   specifying the subgoal of interest. In Line 3 you need to descend under the
   681   outermost @{term "Trueprop"} in order to get to the connective you like to
   681   outermost @{term "Trueprop"} in order to get to the connective you like to
   682   analyse. Otherwise goals like @{prop "A \<and> B"} are not properly
   682   analyse. Otherwise goals like @{prop "A \<and> B"} are not properly
   683   analysed. Similarly with meta-implications in the next line.  While for the
   683   analysed. Similarly with meta-implications in the next line.  While for the
   684   first five patterns we can use the @{text "@term"}-antiquotation to
   684   first five patterns we can use the @{text "@term"}-antiquotation to
   685   construct the patterns, the pattern in Line 8 cannot be constructed in this
   685   construct the patterns, the pattern in Line 8 cannot be constructed in this
  1152   all printable information stored in a simpset. We are here only interested in the 
  1152   all printable information stored in a simpset. We are here only interested in the 
  1153   simplifcation rules, congruence rules and simprocs.\label{fig:printss}}
  1153   simplifcation rules, congruence rules and simprocs.\label{fig:printss}}
  1154 \end{figure} *}
  1154 \end{figure} *}
  1155 
  1155 
  1156 text {* 
  1156 text {* 
  1157   To see how they work, consider the two functions in Figure~\ref{fig:printss}, which
  1157   To see how they work, consider the function in Figure~\ref{fig:printss}, which
  1158   print out some parts of a simpset. If you use them to print out the components of the
  1158   prints out some parts of a simpset. If you use it to print out the components of the
  1159   empty simpset, in ML @{ML empty_ss} and the most primitive simpset
  1159   empty simpset, i.e.~ @{ML empty_ss}
  1160   
  1160   
  1161   @{ML_response_fake [display,gray]
  1161   @{ML_response_fake [display,gray]
  1162   "print_ss @{context} empty_ss"
  1162   "print_ss @{context} empty_ss"
  1163 "Simplification rules:
  1163 "Simplification rules:
  1164 Congruences rules:
  1164 Congruences rules:
  1212 Congruences rules:
  1212 Congruences rules:
  1213 Simproc patterns:"}
  1213 Simproc patterns:"}
  1214 
  1214 
  1215   also produces ``nothing'', the printout is misleading. In fact
  1215   also produces ``nothing'', the printout is misleading. In fact
  1216   the @{ML HOL_basic_ss} is setup so that it can solve goals of the
  1216   the @{ML HOL_basic_ss} is setup so that it can solve goals of the
  1217   form  @{thm TrueI}, @{thm refl[no_vars]}, @{term "t \<equiv> t"} and @{thm FalseE[no_vars]}; 
  1217   form  
       
  1218 
       
  1219   \begin{isabelle}
       
  1220   @{thm TrueI}, @{thm refl[no_vars]}, @{term "t \<equiv> t"} and @{thm FalseE[no_vars]}; 
       
  1221   \end{isabelle}
       
  1222 
  1218   and also resolve with assumptions. For example:
  1223   and also resolve with assumptions. For example:
  1219 *}
  1224 *}
  1220 
  1225 
  1221 lemma 
  1226 lemma 
  1222  "True" and "t = t" and "t \<equiv> t" and "False \<Longrightarrow> Foo" and "\<lbrakk>A; B; C\<rbrakk> \<Longrightarrow> A"
  1227  "True" and "t = t" and "t \<equiv> t" and "False \<Longrightarrow> Foo" and "\<lbrakk>A; B; C\<rbrakk> \<Longrightarrow> A"
  1223 apply(tactic {* ALLGOALS (simp_tac HOL_basic_ss) *})
  1228 apply(tactic {* ALLGOALS (simp_tac HOL_basic_ss) *})
  1224 done
  1229 done
  1225 
  1230 
  1226 text {*
  1231 text {*
  1227   This behaviour is not because of simplification rules, but how the subgoaler, solver 
  1232   This behaviour is not because of simplification rules, but how the subgoaler, solver 
  1228   and looper are set up. @{ML HOL_basic_ss} is usually a good start to build your 
  1233   and looper are set up in @{ML HOL_basic_ss}.
  1229   own simpsets, because of the low danger of causing loops via interacting simplifiction
       
  1230   rules.
       
  1231 
  1234 
  1232   The simpset @{ML HOL_ss} is an extention of @{ML HOL_basic_ss} containing 
  1235   The simpset @{ML HOL_ss} is an extention of @{ML HOL_basic_ss} containing 
  1233   already many useful simplification and congruence rules for the logical 
  1236   already many useful simplification and congruence rules for the logical 
  1234   connectives in HOL. 
  1237   connectives in HOL. 
  1235 
  1238 
  1253   definition
  1256   definition
  1254 *}
  1257 *}
  1255 
  1258 
  1256 definition "MyTrue \<equiv> True"
  1259 definition "MyTrue \<equiv> True"
  1257 
  1260 
       
  1261 text {*
       
  1262   then in the following proof we can unfold this constant
       
  1263 *}
       
  1264 
  1258 lemma shows "MyTrue \<Longrightarrow> True \<and> True"
  1265 lemma shows "MyTrue \<Longrightarrow> True \<and> True"
  1259 apply(rule conjI)
  1266 apply(rule conjI)
  1260 apply(tactic {* rewrite_goals_tac [@{thm MyTrue_def}] *})
  1267 apply(tactic {* rewrite_goals_tac [@{thm MyTrue_def}] *})
  1261 txt{* then the tactic produces the goal state
  1268 txt{* producing the goal state
  1262 
  1269 
  1263       \begin{minipage}{\textwidth}
  1270       \begin{minipage}{\textwidth}
  1264       @{subgoals [display]}
  1271       @{subgoals [display]}
  1265       \end{minipage} *}
  1272       \end{minipage} *}
  1266 (*<*)oops(*>*)
  1273 (*<*)oops(*>*)
  1735   act on @{ML_type cterm}s while the latter acts on @{ML_type thm}s. 
  1742   act on @{ML_type cterm}s while the latter acts on @{ML_type thm}s. 
  1736   However, we will also show in this section how conversions can be applied
  1743   However, we will also show in this section how conversions can be applied
  1737   to theorems via tactics. The type for conversions is
  1744   to theorems via tactics. The type for conversions is
  1738 *}
  1745 *}
  1739 
  1746 
  1740 ML{*type conv = Thm.cterm -> Thm.thm*}
  1747 ML{*type conv = cterm -> thm*}
  1741 
  1748 
  1742 text {*
  1749 text {*
  1743   whereby the produced theorem is always a meta-equality. A simple conversion
  1750   whereby the produced theorem is always a meta-equality. A simple conversion
  1744   is the function @{ML "Conv.all_conv"}, which maps a @{ML_type cterm} to an
  1751   is the function @{ML "Conv.all_conv"}, which maps a @{ML_type cterm} to an
  1745   instance of the (meta)reflexivity theorem. For example:
  1752   instance of the (meta)reflexivity theorem. For example:
  2007   Assume we want to apply @{ML all_true1_conv} only in the conclusion
  2014   Assume we want to apply @{ML all_true1_conv} only in the conclusion
  2008   of the goal, and @{ML if_true1_conv} should only apply to the premises.
  2015   of the goal, and @{ML if_true1_conv} should only apply to the premises.
  2009   Here is a tactic doing exactly that:
  2016   Here is a tactic doing exactly that:
  2010 *}
  2017 *}
  2011 
  2018 
  2012 ML{*val true1_tac = CSUBGOAL (fn (goal, i) =>
  2019 ML{*fun true1_tac ctxt = CSUBGOAL (fn (goal, i) =>
  2013   let 
  2020   CONVERSION 
  2014     val ctxt = ProofContext.init (Thm.theory_of_cterm goal)
  2021     (Conv.params_conv ~1 (fn ctxt =>
  2015   in
  2022        (Conv.prems_conv ~1 (if_true1_conv ctxt) then_conv
  2016     CONVERSION 
  2023           Conv.concl_conv ~1 (all_true1_conv ctxt))) ctxt) i)*}
  2017       (Conv.params_conv ~1 (fn ctxt =>
       
  2018         (Conv.prems_conv ~1 (if_true1_conv ctxt) then_conv
       
  2019           Conv.concl_conv ~1 (all_true1_conv ctxt))) ctxt) i
       
  2020   end)*}
       
  2021 
  2024 
  2022 text {* 
  2025 text {* 
  2023   We call the conversions with the argument @{ML "~1"}. This is to 
  2026   We call the conversions with the argument @{ML "~1"}. This is to 
  2024   analyse all parameters, premises and conclusions. If we call them with 
  2027   analyse all parameters, premises and conclusions. If we call them with 
  2025   a non-negative number, say @{text n}, then these conversions will 
  2028   a non-negative number, say @{text n}, then these conversions will 
  2028 *}
  2031 *}
  2029 
  2032 
  2030 lemma
  2033 lemma
  2031   "if True \<and> P then P else True \<and> False \<Longrightarrow>
  2034   "if True \<and> P then P else True \<and> False \<Longrightarrow>
  2032   (if True \<and> Q then True \<and> Q else P) \<longrightarrow> True \<and> (True \<and> Q)"
  2035   (if True \<and> Q then True \<and> Q else P) \<longrightarrow> True \<and> (True \<and> Q)"
  2033 apply(tactic {* true1_tac 1 *})
  2036 apply(tactic {* true1_tac @{context} 1 *})
  2034 txt {* where the tactic yields the goal state
  2037 txt {* where the tactic yields the goal state
  2035 
  2038 
  2036   \begin{minipage}{\textwidth}
  2039   \begin{minipage}{\textwidth}
  2037   @{subgoals [display]}
  2040   @{subgoals [display]}
  2038   \end{minipage}*}
  2041   \end{minipage}*}