3 begin |
3 begin |
4 |
4 |
5 chapter {* Tactical Reasoning\label{chp:tactical} *} |
5 chapter {* Tactical Reasoning\label{chp:tactical} *} |
6 |
6 |
7 text {* |
7 text {* |
8 The main reason for descending to the ML-level of Isabelle is to be able to |
8 One of the main reason for descending to the ML-level of Isabelle is to be able to |
9 implement automatic proof procedures. Such proof procedures usually lessen |
9 implement automatic proof procedures. Such proof procedures usually lessen |
10 considerably the burden of manual reasoning, for example, when introducing |
10 considerably the burden of manual reasoning, for example, when introducing |
11 new definitions. These proof procedures are centred around refining a goal |
11 new definitions. These proof procedures are centred around refining a goal |
12 state using tactics. This is similar to the \isacommand{apply}-style |
12 state using tactics. This is similar to the \isacommand{apply}-style |
13 reasoning at the user-level, where goals are modified in a sequence of proof |
13 reasoning at the user-level, where goals are modified in a sequence of proof |
117 THEN' atac |
117 THEN' atac |
118 THEN' rtac @{thm disjI1} |
118 THEN' rtac @{thm disjI1} |
119 THEN' atac)*} |
119 THEN' atac)*} |
120 |
120 |
121 text {* |
121 text {* |
122 and then give the number for the subgoal explicitly when the tactic is |
122 where @{ML THEN'} is used instead of @{ML THEN}. With @{ML foo_tac'} you can give |
|
123 the number for the subgoal explicitly when the tactic is |
123 called. So in the next proof you can first discharge the second subgoal, and |
124 called. So in the next proof you can first discharge the second subgoal, and |
124 subsequently the first. |
125 subsequently the first. |
125 *} |
126 *} |
126 |
127 |
127 lemma "P1 \<or> Q1 \<Longrightarrow> Q1 \<or> P1" |
128 lemma "P1 \<or> Q1 \<Longrightarrow> Q1 \<or> P1" |
308 |
309 |
309 where @{term C} is the goal to be proved and the @{term "A\<^isub>i"} are |
310 where @{term C} is the goal to be proved and the @{term "A\<^isub>i"} are |
310 the subgoals. So after setting up the lemma, the goal state is always of the |
311 the subgoals. So after setting up the lemma, the goal state is always of the |
311 form @{text "C \<Longrightarrow> (C)"}; when the proof is finished we are left with @{text |
312 form @{text "C \<Longrightarrow> (C)"}; when the proof is finished we are left with @{text |
312 "(C)"}. Since the goal @{term C} can potentially be an implication, there is |
313 "(C)"}. Since the goal @{term C} can potentially be an implication, there is |
313 a ``protector'' wrapped around it (in from of an outermost constant @{text |
314 a ``protector'' wrapped around it (the wrapper is the outermost constant @{text |
314 "Const (\"prop\", bool \<Rightarrow> bool)"}; however this constant |
315 "Const (\"prop\", bool \<Rightarrow> bool)"}; however this constant |
315 is invisible in the figure). This wrapper prevents that premises of @{text C} are |
316 is invisible in the figure). This wrapper prevents that premises of @{text C} are |
316 mis-interpreted as open subgoals. While tactics can operate on the subgoals |
317 mis-interpreted as open subgoals. While tactics can operate on the subgoals |
317 (the @{text "A\<^isub>i"} above), they are expected to leave the conclusion |
318 (the @{text "A\<^isub>i"} above), they are expected to leave the conclusion |
318 @{term C} intact, with the exception of possibly instantiating schematic |
319 @{term C} intact, with the exception of possibly instantiating schematic |
345 \end{minipage} |
346 \end{minipage} |
346 *} |
347 *} |
347 (*<*)oops(*>*) |
348 (*<*)oops(*>*) |
348 |
349 |
349 text {* |
350 text {* |
350 A simple tactic for ``easily'' discharging proof obligations is |
351 A simple tactic for easy discharge of any proof obligations is |
351 @{ML SkipProof.cheat_tac}. This tactic corresponds to |
352 @{ML SkipProof.cheat_tac}. This tactic corresponds to |
352 the Isabelle command \isacommand{sorry} and is sometimes useful |
353 the Isabelle command \isacommand{sorry} and is sometimes useful |
353 during the development of tactics. |
354 during the development of tactics. |
354 *} |
355 *} |
355 |
356 |
356 lemma shows "False" and "something_else_obviously_false" |
357 lemma shows "False" and "Goldbach_conjecture" |
357 apply(tactic {* SkipProof.cheat_tac @{theory} *}) |
358 apply(tactic {* SkipProof.cheat_tac @{theory} *}) |
358 txt{*\begin{minipage}{\textwidth} |
359 txt{*\begin{minipage}{\textwidth} |
359 @{subgoals [display]} |
360 @{subgoals [display]} |
360 \end{minipage}*} |
361 \end{minipage}*} |
361 (*<*)oops(*>*) |
362 (*<*)oops(*>*) |
373 (*<*)oops(*>*) |
374 (*<*)oops(*>*) |
374 |
375 |
375 text {* |
376 text {* |
376 Similarly, @{ML rtac}, @{ML dtac}, @{ML etac} and @{ML ftac} correspond |
377 Similarly, @{ML rtac}, @{ML dtac}, @{ML etac} and @{ML ftac} correspond |
377 to @{text rule}, @{text drule}, @{text erule} and @{text frule}, |
378 to @{text rule}, @{text drule}, @{text erule} and @{text frule}, |
378 respectively. Each of them takes a theorem as argument and attempts to |
379 respectively. Each of them take a theorem as argument and attempt to |
379 apply it to a goal. Below are three self-explanatory examples. |
380 apply it to a goal. Below are three self-explanatory examples. |
380 *} |
381 *} |
381 |
382 |
382 lemma shows "P \<and> Q" |
383 lemma shows "P \<and> Q" |
383 apply(tactic {* rtac @{thm conjI} 1 *}) |
384 apply(tactic {* rtac @{thm conjI} 1 *}) |
396 lemma shows "False \<and> True \<Longrightarrow> False" |
397 lemma shows "False \<and> True \<Longrightarrow> False" |
397 apply(tactic {* dtac @{thm conjunct2} 1 *}) |
398 apply(tactic {* dtac @{thm conjunct2} 1 *}) |
398 txt{*\begin{minipage}{\textwidth} |
399 txt{*\begin{minipage}{\textwidth} |
399 @{subgoals [display]} |
400 @{subgoals [display]} |
400 \end{minipage}*} |
401 \end{minipage}*} |
401 (*<*)oops(*>*) |
|
402 |
|
403 text {* |
|
404 Note the number in each tactic call. Also as mentioned in the previous section, most |
|
405 basic tactics take such a number as argument: this argument addresses the subgoal |
|
406 the tacics are analysing. In the proof below, we first split up the conjunction in |
|
407 the second subgoal by focusing on this subgoal first. |
|
408 *} |
|
409 |
|
410 lemma shows "Foo" and "P \<and> Q" |
|
411 apply(tactic {* rtac @{thm conjI} 2 *}) |
|
412 txt {*\begin{minipage}{\textwidth} |
|
413 @{subgoals [display]} |
|
414 \end{minipage}*} |
|
415 (*<*)oops(*>*) |
402 (*<*)oops(*>*) |
416 |
403 |
417 text {* |
404 text {* |
418 The function @{ML resolve_tac} is similar to @{ML rtac}, except that it |
405 The function @{ML resolve_tac} is similar to @{ML rtac}, except that it |
419 expects a list of theorems as arguments. From this list it will apply the |
406 expects a list of theorems as arguments. From this list it will apply the |
492 |
479 |
493 then the function raises an exception. The function @{ML RSN} is similar to @{ML RS}, but |
480 then the function raises an exception. The function @{ML RSN} is similar to @{ML RS}, but |
494 takes an additional number as argument that makes explicit which premise |
481 takes an additional number as argument that makes explicit which premise |
495 should be instantiated. |
482 should be instantiated. |
496 |
483 |
497 To improve readability of the theorems we produce below, we shall use the |
484 To improve readability of the theorems we shall produce below, we will use the |
498 function @{ML no_vars} from Section~\ref{sec:printing}, which transforms |
485 function @{ML no_vars} from Section~\ref{sec:printing}, which transforms |
499 schematic variables into free ones. Using this function for the first @{ML |
486 schematic variables into free ones. Using this function for the first @{ML |
500 RS}-expression above produces the more readable result: |
487 RS}-expression above produces the more readable result: |
501 |
488 |
502 @{ML_response_fake [display,gray] |
489 @{ML_response_fake [display,gray] |
762 @{subgoals [display]} |
749 @{subgoals [display]} |
763 \end{minipage} *} |
750 \end{minipage} *} |
764 (*<*)oops(*>*) |
751 (*<*)oops(*>*) |
765 |
752 |
766 text {* |
753 text {* |
767 If you want to avoid the hard-coded subgoal addressing, then you can use |
754 If you want to avoid the hard-coded subgoal addressing, then, as |
|
755 seen earlier, you can use |
768 the ``primed'' version of @{ML THEN}. For example: |
756 the ``primed'' version of @{ML THEN}. For example: |
769 *} |
757 *} |
770 |
758 |
771 lemma shows "(Foo \<and> Bar) \<and> False" |
759 lemma shows "(Foo \<and> Bar) \<and> False" |
772 apply(tactic {* (rtac @{thm conjI} THEN' rtac @{thm conjI}) 1 *}) |
760 apply(tactic {* (rtac @{thm conjI} THEN' rtac @{thm conjI}) 1 *}) |
774 @{subgoals [display]} |
762 @{subgoals [display]} |
775 \end{minipage} *} |
763 \end{minipage} *} |
776 (*<*)oops(*>*) |
764 (*<*)oops(*>*) |
777 |
765 |
778 text {* |
766 text {* |
779 Here you only have to specify the subgoal of interest only once and |
767 Here you have to specify the subgoal of interest only once and |
780 it is consistently applied to the component tactics. |
768 it is consistently applied to the component tactics. |
781 For most tactic combinators such a ``primed'' version exists and |
769 For most tactic combinators such a ``primed'' version exists and |
782 in what follows we will usually prefer it over the ``unprimed'' one. |
770 in what follows we will usually prefer it over the ``unprimed'' one. |
783 |
771 |
784 If there is a list of tactics that should all be tried out in |
772 If there is a list of tactics that should all be tried out in |
1273 then in the following proof we can unfold this constant |
1261 then in the following proof we can unfold this constant |
1274 *} |
1262 *} |
1275 |
1263 |
1276 lemma shows "MyTrue \<Longrightarrow> True \<and> True" |
1264 lemma shows "MyTrue \<Longrightarrow> True \<and> True" |
1277 apply(rule conjI) |
1265 apply(rule conjI) |
1278 apply(tactic {* rewrite_goals_tac [@{thm MyTrue_def}] *}) |
1266 apply(tactic {* rewrite_goals_tac @{thms MyTrue_def} *}) |
1279 txt{* producing the goal state |
1267 txt{* producing the goal state |
1280 |
1268 |
1281 \begin{minipage}{\textwidth} |
1269 \begin{minipage}{\textwidth} |
1282 @{subgoals [display]} |
1270 @{subgoals [display]} |
1283 \end{minipage} *} |
1271 \end{minipage} *} |
1389 are simple consequence of the definition and @{thm [source] perm_compose}. |
1377 are simple consequence of the definition and @{thm [source] perm_compose}. |
1390 More importantly, the lemma @{thm [source] perm_compose_aux} can be safely |
1378 More importantly, the lemma @{thm [source] perm_compose_aux} can be safely |
1391 added to the simplifier, because now the right-hand side is not anymore an instance |
1379 added to the simplifier, because now the right-hand side is not anymore an instance |
1392 of the left-hand side. In a sense it freezes all redexes of permutation compositions |
1380 of the left-hand side. In a sense it freezes all redexes of permutation compositions |
1393 after one step. In this way, we can split simplification of permutations |
1381 after one step. In this way, we can split simplification of permutations |
1394 into three phases without the user not noticing anything about the auxiliary |
1382 into three phases without the user noticing anything about the auxiliary |
1395 contant. We first freeze any instance of permutation compositions in the term using |
1383 contant. We first freeze any instance of permutation compositions in the term using |
1396 lemma @{thm [source] "perm_aux_expand"} (Line 9); |
1384 lemma @{thm [source] "perm_aux_expand"} (Line 9); |
1397 then simplifiy all other permutations including pusing permutations over |
1385 then simplifiy all other permutations including pushing permutations over |
1398 other permutations by rule @{thm [source] perm_compose_aux} (Line 10); and |
1386 other permutations by rule @{thm [source] perm_compose_aux} (Line 10); and |
1399 finally ``unfreeze'' all instances of permutation compositions by unfolding |
1387 finally ``unfreeze'' all instances of permutation compositions by unfolding |
1400 the definition of the auxiliary constant. |
1388 the definition of the auxiliary constant. |
1401 *} |
1389 *} |
1402 |
1390 |
1490 lemma shows "Suc 0 = 1" |
1478 lemma shows "Suc 0 = 1" |
1491 apply(simp) |
1479 apply(simp) |
1492 (*<*)oops(*>*) |
1480 (*<*)oops(*>*) |
1493 |
1481 |
1494 text {* |
1482 text {* |
|
1483 \begin{isabelle} |
|
1484 @{text "> The redex: Suc 0"}\\ |
|
1485 @{text "> The redex: Suc 0"}\\ |
|
1486 \end{isabelle} |
|
1487 |
1495 This will print out the message twice: once for the left-hand side and |
1488 This will print out the message twice: once for the left-hand side and |
1496 once for the right-hand side. The reason is that during simplification the |
1489 once for the right-hand side. The reason is that during simplification the |
1497 simplifier will at some point reduce the term @{term "1::nat"} to @{term "Suc |
1490 simplifier will at some point reduce the term @{term "1::nat"} to @{term "Suc |
1498 0"}, and then the simproc ``fires'' also on that term. |
1491 0"}, and then the simproc ``fires'' also on that term. |
1499 |
1492 |