# HG changeset patch # User boehmes # Date 1235556463 -3600 # Node ID c06885c3657527a93c250b365cc0813335990f57 # Parent 5aa3140ad52e624123769d5494bf00c94f6553be Polished conversion section. diff -r 5aa3140ad52e -r c06885c36575 CookBook/Tactical.thy --- a/CookBook/Tactical.thy Wed Feb 25 10:14:42 2009 +0100 +++ b/CookBook/Tactical.thy Wed Feb 25 11:07:43 2009 +0100 @@ -1,5 +1,6 @@ theory Tactical imports Base FirstSteps +uses "infix_conv.ML" begin chapter {* Tactical Reasoning\label{chp:tactical} *} @@ -1317,40 +1318,55 @@ section {* Conversions\label{sec:conversion} *} text {* -Conversions are meta-equalities depending on some input term. There type is +Conversions are meta-equalities depending on some input term. Their type is as follows: *} ML {*type conv = Thm.cterm -> Thm.thm*} text {* -The simplest two conversions are @{ML "Conv.all_conv"} and @{ML "Conv.no_conv"}: +The simplest two conversions are @{ML "Conv.all_conv"}, which maps a term to an instance of the reflexivity theorem, and @{ML "Conv.no_conv"}, which always fails: @{ML_response_fake "Conv.all_conv @{cterm True}" "True \ True"} @{ML_response_fake "Conv.no_conv @{cterm True}" "*** Exception- CTERM (\"no conversion\", []) raised"} -Further basic conversions are, for example, @{ML "Thm.beta_conversion"} and - @{ML "Conv.rewr_conv"}: +A further basic conversion is, for example, @{ML "Thm.beta_conversion"}: + +@{ML_response_fake "Thm.beta_conversion true @{cterm \"(\x. x \ False) True\"}" +"(\x. x \ False) True \ True \ False"} + +User-defined rewrite rules can be applied by the conversion +@{ML "Conv.rewr_conv"}. Consider, for example, the following rule: *} lemma true_conj1: "True \ P \ P" by simp text {* -@{ML_response_fake "Thm.beta_conversion true @{cterm \"(\x. x \ False) True\"}" -"(\x. x \ False) True \ True \ False"} +Here is how this rule can be used for rewriting: @{ML_response_fake "Conv.rewr_conv @{thm true_conj1} @{cterm \"True \ False\"}" "True \ False \ False"} +*} +text {* Basic conversions can be combined with a number of conversionals, i.e. conversion combinators: -@{ML_response_fake "Conv.then_conv (Thm.beta_conversion true, Conv.rewr_conv @{thm true_conj1}) @{cterm \"(\x. x \ False) True\"}" "(\x. x \ False) True \ False"} +@{ML_response_fake +"(Thm.beta_conversion true then_conv Conv.rewr_conv @{thm true_conj1}) + @{cterm \"(\x. x \ False) True\"}" +"(\x. x \ False) True \ False"} -@{ML_response_fake "Conv.else_conv (Conv.rewr_conv @{thm true_conj1}, Conv.all_conv) @{cterm \"P \ (True \ Q)\"}" "P \ (True \ Q) \ P \ (True \ Q)"} +@{ML_response_fake +"(Conv.rewr_conv @{thm true_conj1} else_conv Conv.all_conv) + @{cterm \"P \ (True \ Q)\"}" +"P \ (True \ Q) \ P \ (True \ Q)"} -@{ML_response_fake "Conv.arg_conv (Conv.rewr_conv @{thm true_conj1}) @{cterm \"P \ (True \ Q)\"}" "P \ (True \ Q) \ P \ Q"} +@{ML_response_fake +"Conv.arg_conv (Conv.rewr_conv @{thm true_conj1}) + @{cterm \"P \ (True \ Q)\"}" +"P \ (True \ Q) \ P \ Q"} \begin{readmore} See @{ML_file "Pure/conv.ML"} for more conversionals. Further basic conversions @@ -1362,70 +1378,86 @@ be seen as a controllable, bare-bone version of Isabelle's simplifier. We will demonstrate this feature in the following example. -For the moment, let's assumes we want to simplify according to the rewrite rule -@{thm true_conj1}. As a conversion, this may look as follows: +To begin with, let's assumes we want to simplify with the rewrite rule +@{text true_conj1}. As a conversion, this may look as follows: *} ML {*fun all_true1_conv ctxt ct = (case Thm.term_of ct of - @{term "op \"} $ @{term True} $ _ => Conv.rewr_conv @{thm true_conj1} ct - | _ $ _ => Conv.combination_conv (all_true1_conv ctxt) (all_true1_conv ctxt) ct + @{term "op \"} $ @{term True} $ _ => + (Conv.arg_conv (all_true1_conv ctxt) then_conv + Conv.rewr_conv @{thm true_conj1}) ct + | _ $ _ => Conv.combination_conv (all_true1_conv ctxt) + (all_true1_conv ctxt) ct | Abs _ => Conv.abs_conv (fn (_, cx) => all_true1_conv cx) ctxt ct | _ => Conv.all_conv ct)*} text {* -Here is the new conversion in action: +Here is this conversion in action: -@{ML_response_fake "all_true1_conv @{context} @{cterm \"distinct [1, x] \ True \ 1 \ x\"}" - "distinct [1, x] \ True \ 1 \ x \ distinct [1, x] \ 1 \ x"} +@{ML_response_fake +"all_true1_conv @{context} + @{cterm \"distinct [1, x] \ True \ 1 \ x\"}" +"distinct [1, x] \ True \ 1 \ x \ distinct [1, x] \ 1 \ x"} -Now, let's complicate the task: Rewrite according to the rule -@{thm true_conj1}, but only in the first arguments of @{term If}: +Now, let's complicate the task a bit: Rewrite according to the rule +@{text true_conj1}, but only in the first arguments of @{term If}: *} ML {*fun if_true1_conv ctxt ct = (case Thm.term_of ct of - Const (@{const_name If}, _) $ _ => Conv.arg_conv (all_true1_conv ctxt) ct - | _ $ _ => Conv.combination_conv (if_true1_conv ctxt) (if_true1_conv ctxt) ct + Const (@{const_name If}, _) $ _ => + Conv.arg_conv (all_true1_conv ctxt) ct + | _ $ _ => Conv.combination_conv (if_true1_conv ctxt) + (if_true1_conv ctxt) ct | Abs _ => Conv.abs_conv (fn (_, cx) => if_true1_conv cx) ctxt ct | _ => Conv.all_conv ct)*} text {* -Here is an application of this new conversion: +Here is an application of this conversion: -@{ML_response_fake "if_true1_conv @{context} @{cterm \"if P (True \ 1 \ 2) then True \ True else True \ False\"}" "if P (True \ 1 \ 2) then True \ True else True \ False \ if P (1 \ 2) then True \ True else True \ False"} +@{ML_response_fake +"if_true1_conv @{context} + @{cterm \"if P (True \ 1 \ 2) then True \ True else True \ False\"}" +"if P (True \ 1 \ 2) then True \ True else True \ False \ if P (1 \ 2) then True \ True else True \ False"} *} text {* Conversions can also be turned into a tactic with the @{ML CONVERSION} -tactical, and there are predefined conversionals to traverse a goal state - -@{term "\x. P \ Q"}: - -The conversional -@{ML Conv.params_conv} applies a conversion to @{term "P \ Q"}, -@{ML Conv.prems_conv} applies a conversion to all premises in @{term "P \ Q"}, and -@{ML Conv.concl_conv} applies a conversion to the conclusion @{term Q} in @{term "P \ Q"}. +tactical, and there are predefined conversionals to traverse a goal state. +Given a state @{term "\x. P \ Q"}, the conversional +@{ML Conv.params_conv} applies a conversion to @{term "P \ Q"}; +given a state @{term "\ P1; P2 \ \ Q"}, +the conversional @{ML Conv.prems_conv} applies a conversion to the premises +@{term P1} and @{term P2}, and @{ML Conv.concl_conv} applies a conversion to +the conclusion @{term Q}. Assume we want to apply @{ML all_true1_conv} only in the conclusion of the goal, and @{ML if_true1_conv} should only be applied in the premises. Here is a tactic doing exactly that: *} -ML {*local open Conv -in -val true1_tac = CSUBGOAL (fn (goal, i) => +ML {*val true1_tac = CSUBGOAL (fn (goal, i) => let val ctxt = ProofContext.init (Thm.theory_of_cterm goal) in CONVERSION ( Conv.params_conv ~1 (fn cx => (Conv.prems_conv ~1 (if_true1_conv cx)) then_conv - (Conv.concl_conv ~1 (all_true1_conv cx))) ctxt) i - end) -end*} + Conv.concl_conv ~1 (all_true1_conv cx)) ctxt) i + end)*} + +text {* +To demonstrate this tactic, consider the following example: +*} -text {* FIXME: give example, show that the conditional rewriting works *} - +lemma + "if True \ P then P else True \ False \ + (if True \ Q then Q else P) \ True \ (True \ Q)" +apply(tactic {* true1_tac 1 *}) +txt {* \begin{minipage}{\textwidth} + @{subgoals [display]} + \end{minipage} *} +(*<*)oops(*>*) text {* Conversions are not restricted to work on certified terms only, they can also @@ -1433,7 +1465,9 @@ theorem, by the help of @{ML Conv.fconv_rule}. As an example, consider the conversion @{ML all_true1_conv} again: -@{ML_response_fake "Conv.fconv_rule (all_true1_conv @{context}) @{lemma \"P \ (True \ \P)\" by simp}" "P \ \P"} +@{ML_response_fake +"Conv.fconv_rule (all_true1_conv @{context}) + @{lemma \"P \ (True \ \P)\" by simp}" "P \ \P"} *} diff -r 5aa3140ad52e -r c06885c36575 CookBook/infix_conv.ML --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CookBook/infix_conv.ML Wed Feb 25 11:07:43 2009 +0100 @@ -0,0 +1,9 @@ +signature INFIX_CONV = +sig + val then_conv : Thm.conv * Thm.conv -> Thm.conv + val else_conv : Thm.conv * Thm.conv -> Thm.conv +end + +structure InfixConv : INFIX_CONV = Conv + +open InfixConv diff -r 5aa3140ad52e -r c06885c36575 cookbook.pdf Binary file cookbook.pdf has changed