ProgTutorial/Tactical.thy
changeset 412 73f716b9201a
parent 411 24fc00319c4a
child 413 95461cf6fd07
equal deleted inserted replaced
411:24fc00319c4a 412:73f716b9201a
  1408   definition for a constant and this constant is not present in the goal state, 
  1408   definition for a constant and this constant is not present in the goal state, 
  1409   you can still safely apply the simplifier.
  1409   you can still safely apply the simplifier.
  1410 
  1410 
  1411   \footnote{\bf FIXME: show rewriting of cterms}
  1411   \footnote{\bf FIXME: show rewriting of cterms}
  1412 
  1412 
       
  1413   There is one restriction you have to keep in mind when using the simplifier:
       
  1414   it can only deal with rewriting rules that are higher order pattern 
       
  1415   (see Section \ref{sec:univ} on unification). If a rule is not a pattern,
       
  1416   then you have to use simprocs or conversions, which we shall describe in
       
  1417   the next section.
       
  1418 
  1413   When using the simplifier, the crucial information you have to provide is
  1419   When using the simplifier, the crucial information you have to provide is
  1414   the simpset. If this information is not handled with care, then, as
  1420   the simpset. If this information is not handled with care, then, as
  1415   mentioned above, the simplifier can easily run into a loop. Therefore a good
  1421   mentioned above, the simplifier can easily run into a loop. Therefore a good
  1416   rule of thumb is to use simpsets that are as minimal as possible. It might
  1422   rule of thumb is to use simpsets that are as minimal as possible. It might
  1417   be surprising that a simpset is more complex than just a simple collection
  1423   be surprising that a simpset is more complex than just a simple collection
  2112 section {* Conversions\label{sec:conversion} *}
  2118 section {* Conversions\label{sec:conversion} *}
  2113 
  2119 
  2114 text {*
  2120 text {*
  2115   Conversions are a thin layer on top of Isabelle's inference kernel, and can
  2121   Conversions are a thin layer on top of Isabelle's inference kernel, and can
  2116   be viewed as a controllable, bare-bone version of Isabelle's simplifier.
  2122   be viewed as a controllable, bare-bone version of Isabelle's simplifier.
  2117   The purpose of conversions is to manipulate on @{ML_type cterm}s. However,
  2123   The purpose of conversions is to manipulate @{ML_type cterm}s. However,
  2118   we will also show in this section how conversions can be applied to theorems
  2124   we will also show in this section how conversions can be applied to theorems
  2119   and used as tactics. The type of conversions is
  2125   and to goal states. The type of conversions is
  2120 *}
  2126 *}
  2121 
  2127 
  2122 ML{*type conv = cterm -> thm*}
  2128 ML{*type conv = cterm -> thm*}
  2123 
  2129 
  2124 text {*
  2130 text {*
  2350 text {*
  2356 text {*
  2351   If we regard terms as trees with variables and constants on the top, then 
  2357   If we regard terms as trees with variables and constants on the top, then 
  2352   @{ML bottom_conv in More_Conv} traverses first the the term and
  2358   @{ML bottom_conv in More_Conv} traverses first the the term and
  2353   on the ``way down'' applies the conversion, whereas @{ML top_conv in
  2359   on the ``way down'' applies the conversion, whereas @{ML top_conv in
  2354   More_Conv} applies the conversion on the ``way up''. To see the difference, 
  2360   More_Conv} applies the conversion on the ``way up''. To see the difference, 
  2355   assume the following two meta-equations.
  2361   assume the following two meta-equations
  2356 *}
  2362 *}
  2357 
  2363 
  2358 lemma conj_assoc:
  2364 lemma conj_assoc:
  2359   fixes A B C::bool
  2365   fixes A B C::bool
  2360   shows "A \<and> (B \<and> C) \<equiv> (A \<and> B) \<and> C"
  2366   shows "A \<and> (B \<and> C) \<equiv> (A \<and> B) \<and> C"
  2361   and   "(A \<and> B) \<and> C \<equiv> A \<and> (B \<and> C)"
  2367   and   "(A \<and> B) \<and> C \<equiv> A \<and> (B \<and> C)"
  2362 by simp_all
  2368 by simp_all
  2363 
  2369 
  2364 text {*
  2370 text {*
  2365   and the @{ML_type cterm} @{text "(a \<and> (b \<and> c)) \<and> d"}. The reader should
  2371   and the @{ML_type cterm} @{text "(a \<and> (b \<and> c)) \<and> d"}. Here you should
  2366   pause for a moment to be convinced that rewriting top-down and bottom-up 
  2372   pause for a moment to be convinced that rewriting top-down and bottom-up 
  2367   according to the two meta-equations produces two results. 
  2373   according to the two meta-equations produces two results. Below these
       
  2374   two results are calculated. 
  2368 
  2375 
  2369   @{ML_response_fake [display, gray]
  2376   @{ML_response_fake [display, gray]
  2370   "let
  2377   "let
  2371   val ctxt = @{context}
  2378   val ctxt = @{context}
  2372   val conv = Conv.try_conv (More_Conv.rewrs_conv @{thms conj_assoc})
  2379   val conv = Conv.try_conv (More_Conv.rewrs_conv @{thms conj_assoc})
  2377   (conv_top ctrm, conv_bot ctrm)
  2384   (conv_top ctrm, conv_bot ctrm)
  2378 end"
  2385 end"
  2379   "(\"(a \<and> (b \<and> c)) \<and> d \<equiv> a \<and> (b \<and> (c \<and> d))\",
  2386   "(\"(a \<and> (b \<and> c)) \<and> d \<equiv> a \<and> (b \<and> (c \<and> d))\",
  2380  \"(a \<and> (b \<and> c)) \<and> d \<equiv> (a \<and> b) \<and> (c \<and> d)\")"}
  2387  \"(a \<and> (b \<and> c)) \<and> d \<equiv> (a \<and> b) \<and> (c \<and> d)\")"}
  2381 
  2388 
  2382   To see how much control you have about rewriting by using conversions, let us 
  2389   To see how much control you have over rewriting with conversions, let us 
  2383   make the task a bit more complicated by rewriting according to the rule
  2390   make the task a bit more complicated by rewriting according to the rule
  2384   @{text true_conj1}, but only in the first arguments of @{term If}s. Then 
  2391   @{text true_conj1}, but only in the first arguments of @{term If}s. Then 
  2385   the conversion should be as follows.
  2392   the conversion should be as follows.
  2386 *}
  2393 *}
  2387 
  2394 
  2393 
  2400 
  2394 val if_true1_conv = More_Conv.top_sweep_conv if_true1_simple_conv*}
  2401 val if_true1_conv = More_Conv.top_sweep_conv if_true1_simple_conv*}
  2395 
  2402 
  2396 text {*
  2403 text {*
  2397   In the first function we only treat the top-most redex and also only the
  2404   In the first function we only treat the top-most redex and also only the
  2398   success case and otherwise return @{ML no_conv in Conv}.  To apply this
  2405   success case. As default we return @{ML no_conv in Conv}.  To apply this
  2399   conversion inside a term, we use in the last line the combinator @{ML_ind
  2406   ``simple'' conversion inside a term, we use in the last line the combinator @{ML_ind
  2400   top_sweep_conv in More_Conv}, which traverses the term starting from the
  2407   top_sweep_conv in More_Conv}, which traverses the term starting from the
  2401   root and applies it to all the redexes on the way, but stops in each branch as
  2408   root and applies it to all the redexes on the way, but stops in each branch as
  2402   soon as it found one redex. Here is an example for this conversion:
  2409   soon as it found one redex. Here is an example for this conversion:
  2403 
  2410 
  2404 
  2411 
  2414 *}
  2421 *}
  2415 
  2422 
  2416 text {*
  2423 text {*
  2417   So far we only applied conversions to @{ML_type cterm}s. Conversions can, however, 
  2424   So far we only applied conversions to @{ML_type cterm}s. Conversions can, however, 
  2418   also work on theorems using the function @{ML_ind  fconv_rule in Conv}. As an example, 
  2425   also work on theorems using the function @{ML_ind  fconv_rule in Conv}. As an example, 
  2419   consider the conversion @{ML true_conj1_conv} and the lemma:
  2426   consider again the conversion @{ML true_conj1_conv} and the lemma:
  2420 *}
  2427 *}
  2421 
  2428 
  2422 lemma foo_test: 
  2429 lemma foo_test: 
  2423   shows "P \<or> (True \<and> \<not>P)" by simp
  2430   shows "P \<or> (True \<and> \<not>P)" by simp
  2424 
  2431 
  2425 text {*
  2432 text {*
  2426   Using the conversion @{ML true_conj1_conv} you can transform this theorem into a 
  2433   Using the conversion you can transform this theorem into a 
  2427   new theorem as follows
  2434   new theorem as follows
  2428 
  2435 
  2429   @{ML_response_fake [display,gray]
  2436   @{ML_response_fake [display,gray]
  2430 "let
  2437 "let
  2431   val conv = Conv.fconv_rule (true_conj1_conv @{context}) 
  2438   val conv = Conv.fconv_rule (true_conj1_conv @{context}) 
  2433 in
  2440 in
  2434   conv thm
  2441   conv thm
  2435 end" 
  2442 end" 
  2436   "?P \<or> \<not> ?P"}
  2443   "?P \<or> \<not> ?P"}
  2437 
  2444 
  2438   Finally, conversions can also be turned into tactics and then applied to
  2445   Finally, Isabelle provides function @{ML_ind CONVERSION in Tactical} 
  2439   goal states. This can be done with the help of the function 
  2446   for turning conversions into tactics. This needs some predefined conversion 
  2440   @{ML_ind CONVERSION in Tactical},
  2447   combinators that traverse a goal
  2441   and also some predefined conversion combinators that traverse a goal
       
  2442   state and can selectively apply the conversion. The combinators for 
  2448   state and can selectively apply the conversion. The combinators for 
  2443   the goal state are: 
  2449   the goal state are: 
  2444 
  2450 
  2445   \begin{itemize}
  2451   \begin{itemize}
  2446   \item @{ML_ind params_conv in Conv} for converting under parameters
  2452   \item @{ML_ind params_conv in Conv} for converting under parameters
  2447   (i.e.~where goals are of the form @{text "\<And>x. P x \<Longrightarrow> Q x"})
  2453   (i.e.~where a goal state is of the form @{text "\<And>x. P x \<Longrightarrow> Q x"})
  2448 
  2454 
  2449   \item @{ML_ind prems_conv in Conv} for applying a conversion to all
  2455   \item @{ML_ind prems_conv in Conv} for applying a conversion to 
  2450   premises of a goal, and
  2456   premises of a goal state, and
  2451 
  2457 
  2452   \item @{ML_ind concl_conv in Conv} for applying a conversion to the
  2458   \item @{ML_ind concl_conv in Conv} for applying a conversion to the
  2453   conclusion of a goal.
  2459   conclusion of a goal state.
  2454   \end{itemize}
  2460   \end{itemize}
  2455 
  2461 
  2456   Assume we want to apply @{ML true_conj1_conv} only in the conclusion
  2462   Assume we want to apply @{ML true_conj1_conv} only in the conclusion
  2457   of the goal, and @{ML if_true1_conv} should only apply to the premises.
  2463   of the goal, and @{ML if_true1_conv} should only apply to the premises.
  2458   Here is a tactic doing exactly that:
  2464   Here is a tactic doing exactly that:
  2486 
  2492 
  2487 text {*
  2493 text {*
  2488   As you can see, the premises are rewritten according to @{ML if_true1_conv}, while
  2494   As you can see, the premises are rewritten according to @{ML if_true1_conv}, while
  2489   the conclusion according to @{ML true_conj1_conv}. If we only have one
  2495   the conclusion according to @{ML true_conj1_conv}. If we only have one
  2490   conversion that should be uniformly applied to the whole goal state, we
  2496   conversion that should be uniformly applied to the whole goal state, we
  2491   can also use @{ML_ind top_conv in More_Conv}.
  2497   can simplify @{ML true1_tac} using @{ML_ind top_conv in More_Conv}.
  2492 
  2498 
  2493   Conversions can also be helpful for constructing meta-equality theorems.
  2499   Conversions are also be helpful for constructing meta-equality theorems.
  2494   Such theorems are often definitions. As an example consider the following
  2500   Such theorems are often definitions. As an example consider the following
  2495   two ways of defining the identity function in Isabelle. 
  2501   two ways of defining the identity function in Isabelle. 
  2496 *}
  2502 *}
  2497 
  2503 
  2498 definition id1::"'a \<Rightarrow> 'a" 
  2504 definition id1::"'a \<Rightarrow> 'a" 
  2501 definition id2::"'a \<Rightarrow> 'a"
  2507 definition id2::"'a \<Rightarrow> 'a"
  2502 where "id2 \<equiv> \<lambda>x. x"
  2508 where "id2 \<equiv> \<lambda>x. x"
  2503 
  2509 
  2504 text {*
  2510 text {*
  2505   Although both definitions define the same function, the theorems @{thm
  2511   Although both definitions define the same function, the theorems @{thm
  2506   [source] id1_def} and @{thm [source] id2_def} are different. However it is
  2512   [source] id1_def} and @{thm [source] id2_def} are different meta-equations. However it is
  2507   easy to transform one theorem into the other. The function @{ML_ind abs_def
  2513   easy to transform one into the other. The function @{ML_ind abs_def
  2508   in Drule} can automatically transform theorem @{thm [source] id1_def}
  2514   in Drule} from the structure @{ML_struct Drule} can automatically transform 
       
  2515   theorem @{thm [source] id1_def}
  2509   into @{thm [source] id2_def} by abstracting all variables on the 
  2516   into @{thm [source] id2_def} by abstracting all variables on the 
  2510   left-hand side in the right-hand side.
  2517   left-hand side in the right-hand side.
  2511 
  2518 
  2512   @{ML_response_fake [display,gray]
  2519   @{ML_response_fake [display,gray]
  2513   "Drule.abs_def @{thm id1_def}"
  2520   "Drule.abs_def @{thm id1_def}"
  2542   In Line 3 we destruct the meta-equality into the @{ML_type cterm}s
  2549   In Line 3 we destruct the meta-equality into the @{ML_type cterm}s
  2543   corresponding to the left-hand and right-hand side of the meta-equality. The
  2550   corresponding to the left-hand and right-hand side of the meta-equality. The
  2544   assumption in @{ML unabs_def} is that the right-hand side is an
  2551   assumption in @{ML unabs_def} is that the right-hand side is an
  2545   abstraction. We compute the possibly empty list of abstracted variables in
  2552   abstraction. We compute the possibly empty list of abstracted variables in
  2546   Line 4 using the function @{ML_ind strip_abs_vars in Term}. For this we have to
  2553   Line 4 using the function @{ML_ind strip_abs_vars in Term}. For this we have to
  2547   transform the @{ML_type cterm} into a @{ML_type term}. In Line 5 we
  2554   first transform the @{ML_type cterm} into a @{ML_type term}. In Line 5 we
  2548   import these variables into the context @{text "ctxt'"}, in order to
  2555   import these variables into the context @{text "ctxt'"}, in order to
  2549   export them again in Line 15.  In Line 8 we certify the list of variables,
  2556   export them again in Line 15.  In Line 8 we certify the list of variables,
  2550   which in turn we apply to the @{ML_text lhs} of the definition using the
  2557   which in turn we apply to the @{ML_text lhs} of the definition using the
  2551   function @{ML_ind list_comb in Drule}. In Line 11 and 12 we generate the
  2558   function @{ML_ind list_comb in Drule}. In Line 11 and 12 we generate the
  2552   conversion according to the length of the list of (abstracted) variables. If
  2559   conversion according to the length of the list of (abstracted) variables. If