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 |