382 |
382 |
383 text {* |
383 text {* |
384 Similarly, @{ML [index] rtac}, @{ML [index] dtac}, @{ML [index] etac} and |
384 Similarly, @{ML [index] rtac}, @{ML [index] dtac}, @{ML [index] etac} and |
385 @{ML [index] ftac} correspond (roughly) |
385 @{ML [index] ftac} correspond (roughly) |
386 to @{text rule}, @{text drule}, @{text erule} and @{text frule}, |
386 to @{text rule}, @{text drule}, @{text erule} and @{text frule}, |
387 respectively. Each of them take a theorem as argument and attempt to |
387 respectively. Each of them takes a theorem as argument and attempts to |
388 apply it to a goal. Below are three self-explanatory examples. |
388 apply it to a goal. Below are three self-explanatory examples. |
389 *} |
389 *} |
390 |
390 |
391 lemma shows "P \<and> Q" |
391 lemma shows "P \<and> Q" |
392 apply(tactic {* rtac @{thm conjI} 1 *}) |
392 apply(tactic {* rtac @{thm conjI} 1 *}) |
455 procedure might become too fragile, if it just applies inference rules as |
455 procedure might become too fragile, if it just applies inference rules as |
456 shown above. The reason is that a number of rules introduce meta-variables |
456 shown above. The reason is that a number of rules introduce meta-variables |
457 into the goal state. Consider for example the proof |
457 into the goal state. Consider for example the proof |
458 *} |
458 *} |
459 |
459 |
460 lemma shows "\<forall>x\<in>A. P x \<Longrightarrow> Q x" |
460 lemma shows "\<forall>x \<in> A. P x \<Longrightarrow> Q x" |
461 apply(tactic {* dtac @{thm bspec} 1 *}) |
461 apply(tactic {* dtac @{thm bspec} 1 *}) |
462 txt{*\begin{minipage}{\textwidth} |
462 txt{*\begin{minipage}{\textwidth} |
463 @{subgoals [display]} |
463 @{subgoals [display]} |
464 \end{minipage}*} |
464 \end{minipage}*} |
465 (*<*)oops(*>*) |
465 (*<*)oops(*>*) |
523 \end{readmore} |
523 \end{readmore} |
524 |
524 |
525 Often proofs on the ML-level involve elaborate operations on assumptions and |
525 Often proofs on the ML-level involve elaborate operations on assumptions and |
526 @{text "\<And>"}-quantified variables. To do such operations using the basic tactics |
526 @{text "\<And>"}-quantified variables. To do such operations using the basic tactics |
527 shown so far is very unwieldy and brittle. Some convenience and |
527 shown so far is very unwieldy and brittle. Some convenience and |
528 safety is provided by @{ML [index] SUBPROOF}. This tactic fixes the parameters |
528 safety is provided by the functions @{ML [index] FOCUS} and @{ML [index] SUBPROOF}. |
529 and binds the various components of a goal state to a record. |
529 These tactics fix the parameters |
|
530 and bind the various components of a goal state to a record. |
530 To see what happens, assume the function defined in Figure~\ref{fig:sptac}, which |
531 To see what happens, assume the function defined in Figure~\ref{fig:sptac}, which |
531 takes a record and just prints out the content of this record (using the |
532 takes a record and just prints out the content of this record (using the |
532 string transformation functions from in Section~\ref{sec:printing}). Consider |
533 string transformation functions from in Section~\ref{sec:printing}). Consider |
533 now the proof: |
534 now the proof: |
534 *} |
535 *} |
538 \begin{minipage}{\textwidth} |
539 \begin{minipage}{\textwidth} |
539 \begin{isabelle} |
540 \begin{isabelle} |
540 *} |
541 *} |
541 |
542 |
542 |
543 |
543 ML{*fun sp_tac {prems, params, asms, concl, context, schematics} = |
544 ML{*fun foc_tac {prems, params, asms, concl, context, schematics} = |
544 let |
545 let |
545 val string_of_params = string_of_cterms context (map snd params) |
546 val string_of_params = string_of_cterms context (map snd params) |
546 val test = commas (map fst params) |
|
547 val string_of_asms = string_of_cterms context asms |
547 val string_of_asms = string_of_cterms context asms |
548 val string_of_concl = string_of_cterm context concl |
548 val string_of_concl = string_of_cterm context concl |
549 val string_of_prems = string_of_thms_no_vars context prems |
549 val string_of_prems = string_of_thms_no_vars context prems |
550 val string_of_schms = string_of_cterms context (snd schematics) |
550 val string_of_schms = string_of_cterms context (snd schematics) |
551 |
551 |
552 val _ = (writeln ("params: " ^ string_of_params); |
552 val _ = (writeln ("params: " ^ string_of_params); |
553 writeln ("param names: " ^ test); |
|
554 writeln ("schematics: " ^ string_of_schms); |
553 writeln ("schematics: " ^ string_of_schms); |
555 writeln ("assumptions: " ^ string_of_asms); |
554 writeln ("assumptions: " ^ string_of_asms); |
556 writeln ("conclusion: " ^ string_of_concl); |
555 writeln ("conclusion: " ^ string_of_concl); |
557 writeln ("premises: " ^ string_of_prems)) |
556 writeln ("premises: " ^ string_of_prems)) |
558 in |
557 in |
559 no_tac |
558 all_tac |
560 end*} |
559 end*} |
561 text_raw{* |
560 text_raw{* |
562 \end{isabelle} |
561 \end{isabelle} |
563 \end{minipage} |
562 \end{minipage} |
564 \caption{A function that prints out the various parameters provided by the tactic |
563 \caption{A function that prints out the various parameters provided by |
565 @{ML SUBPROOF}. It uses the functions defined in Section~\ref{sec:printing} for |
564 @{ML FOCUS} and @{ML SUBPROOF}. It uses the functions defined in Section~\ref{sec:printing} for |
566 extracting strings from @{ML_type cterm}s and @{ML_type thm}s.\label{fig:sptac}} |
565 extracting strings from @{ML_type cterm}s and @{ML_type thm}s.\label{fig:sptac}} |
567 \end{figure} |
566 \end{figure} |
568 *} |
567 *} |
569 |
568 |
570 lemma shows "\<And>x y. A x y \<Longrightarrow> B y x \<longrightarrow> C (?z y) x" |
569 lemma shows "\<And>x y. A x y \<Longrightarrow> B y x \<longrightarrow> C (?z y) x" |
571 apply(tactic {* SUBPROOF sp_tac @{context} 1 *})? |
570 apply(tactic {* FOCUS foc_tac @{context} 1 *}) |
572 |
571 |
573 txt {* |
572 txt {* |
574 The tactic produces the following printout: |
573 The tactic produces the following printout: |
575 |
574 |
576 \begin{quote}\small |
575 \begin{quote}\small |
588 the subproof. By convention these fixed variables are printed in brown colour. |
587 the subproof. By convention these fixed variables are printed in brown colour. |
589 Similarly the schematic variable @{term z}. The assumption, or premise, |
588 Similarly the schematic variable @{term z}. The assumption, or premise, |
590 @{prop "A x y"} is bound as @{ML_type cterm} to the record-variable |
589 @{prop "A x y"} is bound as @{ML_type cterm} to the record-variable |
591 @{text asms}, but also as @{ML_type thm} to @{text prems}. |
590 @{text asms}, but also as @{ML_type thm} to @{text prems}. |
592 |
591 |
593 Notice also that we had to append @{text [quotes] "?"} to the |
|
594 \isacommand{apply}-command. The reason is that @{ML [index] SUBPROOF} normally |
|
595 expects that the subgoal is solved completely. Since in the function @{ML |
|
596 sp_tac} we returned the tactic @{ML no_tac}, the subproof obviously |
|
597 fails. The question-mark allows us to recover from this failure in a |
|
598 graceful manner so that the output messages are not overwritten by an |
|
599 ``empty sequence'' error message. |
|
600 |
|
601 If we continue the proof script by applying the @{text impI}-rule |
592 If we continue the proof script by applying the @{text impI}-rule |
602 *} |
593 *} |
603 |
594 |
604 apply(rule impI) |
595 apply(rule impI) |
605 apply(tactic {* SUBPROOF sp_tac @{context} 1 *})? |
596 apply(tactic {* FOCUS foc_tac @{context} 1 *}) |
606 |
597 |
607 txt {* |
598 txt {* |
608 then the tactic prints out: |
599 then the tactic prints out: |
609 |
600 |
610 \begin{quote}\small |
601 \begin{quote}\small |
620 (*<*)oops(*>*) |
611 (*<*)oops(*>*) |
621 |
612 |
622 text {* |
613 text {* |
623 Now also @{term "B y x"} is an assumption bound to @{text asms} and @{text prems}. |
614 Now also @{term "B y x"} is an assumption bound to @{text asms} and @{text prems}. |
624 |
615 |
625 One convenience of @{ML SUBPROOF} is that we can apply the assumptions |
616 The difference between @{ML SUBPROOF} and @{ML FOCUS} is that the former |
626 using the usual tactics, because the parameter @{text prems} |
617 expects that the goal is solved completely, which the latter does not. One |
627 contains them as theorems. With this you can easily |
618 convenience of both @{ML FOCUS} and @{ML SUBPROOF} is that we can apply the |
628 implement a tactic that behaves almost like @{ML atac}: |
619 assumptions using the usual tactics, because the parameter @{text prems} |
|
620 contains them as theorems. With this you can easily implement a tactic that |
|
621 behaves almost like @{ML atac}: |
629 *} |
622 *} |
630 |
623 |
631 ML{*val atac' = SUBPROOF (fn {prems, ...} => resolve_tac prems 1)*} |
624 ML{*val atac' = SUBPROOF (fn {prems, ...} => resolve_tac prems 1)*} |
632 |
625 |
633 text {* |
626 text {* |
662 done |
655 done |
663 |
656 |
664 |
657 |
665 text {* |
658 text {* |
666 \begin{readmore} |
659 \begin{readmore} |
667 The function @{ML SUBPROOF} is defined in @{ML_file "Pure/subgoal.ML"} and |
660 The functions @{ML FOCUS} and @{ML SUBPROOF} are defined in |
668 also described in \isccite{sec:results}. |
661 @{ML_file "Pure/subgoal.ML"} and also described in |
|
662 \isccite{sec:results}. |
669 \end{readmore} |
663 \end{readmore} |
670 |
664 |
671 Similar but less powerful functions than @{ML SUBPROOF} are @{ML [index] SUBGOAL} |
665 Similar but less powerful functions than @{ML FOCUS} are @{ML [index] SUBGOAL} |
672 and @{ML [index] CSUBGOAL}. They allow you to inspect a given subgoal (the former |
666 and @{ML [index] CSUBGOAL}. They allow you to inspect a given subgoal (the former |
673 presents the subgoal as a @{ML_type term}, while the latter as a @{ML_type |
667 presents the subgoal as a @{ML_type term}, while the latter as a @{ML_type |
674 cterm}). With this you can implement a tactic that applies a rule according |
668 cterm}). With this you can implement a tactic that applies a rule according |
675 to the topmost logic connective in the subgoal (to illustrate this we only |
669 to the topmost logic connective in the subgoal (to illustrate this we only |
676 analyse a few connectives). The code of the tactic is as |
670 analyse a few connectives). The code of the tactic is as |
697 construct the patterns, the pattern in Line 8 cannot be constructed in this |
691 construct the patterns, the pattern in Line 8 cannot be constructed in this |
698 way. The reason is that an antiquotation would fix the type of the |
692 way. The reason is that an antiquotation would fix the type of the |
699 quantified variable. So you really have to construct the pattern using the |
693 quantified variable. So you really have to construct the pattern using the |
700 basic term-constructors. This is not necessary in other cases, because their |
694 basic term-constructors. This is not necessary in other cases, because their |
701 type is always fixed to function types involving only the type @{typ |
695 type is always fixed to function types involving only the type @{typ |
702 bool}. (See Section \ref{sec:terms_manually} about constructing terms |
696 bool}. (See Section \ref{sec:terms_types_manually} about constructing terms |
703 manually.) For the catch-all pattern, we chose to just return @{ML all_tac}. |
697 manually.) For the catch-all pattern, we chose to just return @{ML all_tac}. |
704 Consequently, @{ML select_tac} never fails. |
698 Consequently, @{ML select_tac} never fails. |
705 |
699 |
706 |
700 |
707 Let us now see how to apply this tactic. Consider the four goals: |
701 Let us now see how to apply this tactic. Consider the four goals: |
874 list. The same can be achieved with the tactic combinator @{ML [index] TRY}. |
868 list. The same can be achieved with the tactic combinator @{ML [index] TRY}. |
875 For example: |
869 For example: |
876 *} |
870 *} |
877 |
871 |
878 ML{*val select_tac'' = TRY o FIRST' [rtac @{thm conjI}, rtac @{thm impI}, |
872 ML{*val select_tac'' = TRY o FIRST' [rtac @{thm conjI}, rtac @{thm impI}, |
879 rtac @{thm notI}, rtac @{thm allI}]*} |
873 rtac @{thm notI}, rtac @{thm allI}]*} |
880 text_raw{*\label{tac:selectprimeprime}*} |
874 text_raw{*\label{tac:selectprimeprime}*} |
881 |
875 |
882 text {* |
876 text {* |
883 This tactic behaves in the same way as @{ML select_tac'}: it tries out |
877 This tactic behaves in the same way as @{ML select_tac'}: it tries out |
884 one of the given tactics and if none applies leaves the goal state |
878 one of the given tactics and if none applies leaves the goal state |