143 \begin{isabelle} |
143 \begin{isabelle} |
144 @{text "*** empty result sequence -- proof command failed"}\\ |
144 @{text "*** empty result sequence -- proof command failed"}\\ |
145 @{text "*** At command \"apply\"."} |
145 @{text "*** At command \"apply\"."} |
146 \end{isabelle} |
146 \end{isabelle} |
147 |
147 |
148 This means they failed.\footnote{To be precise tactics do not produce this error |
148 This means they failed.\footnote{To be precise, tactics do not produce this error |
149 message, it originates from the \isacommand{apply} wrapper.} The reason for this |
149 message, it originates from the \isacommand{apply} wrapper.} The reason for this |
150 error message is that tactics |
150 error message is that tactics |
151 are functions mapping a goal state to a (lazy) sequence of successor states. |
151 are functions mapping a goal state to a (lazy) sequence of successor states. |
152 Hence the type of a tactic is: |
152 Hence the type of a tactic is: |
153 *} |
153 *} |
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 the functions @{ML [index] FOCUS in Subgoal} and |
528 safety is provided by the functions @{ML [index] FOCUS in Subgoal} and |
529 @{ML [index] SUBPROOF}. These tactics fix the parameters |
529 @{ML [index] SUBPROOF}. These tactics fix the parameters |
530 and bind the various components of a goal state to a record. |
530 and bind the various components of a goal state to a record. |
531 To see what happens, assume the function defined in Figure~\ref{fig:sptac}, which |
531 To see what happens, use the function defined in Figure~\ref{fig:sptac}, which |
532 takes a record and just prints out the content of this record (using the |
532 takes a record and just prints out the contents of this record. Consider |
533 string transformation functions from in Section~\ref{sec:printing}). Consider |
|
534 now the proof: |
533 now the proof: |
535 *} |
534 *} |
536 |
535 |
537 text_raw{* |
536 text_raw{* |
538 \begin{figure}[t] |
537 \begin{figure}[t] |
547 val string_of_asms = string_of_cterms context asms |
546 val string_of_asms = string_of_cterms context asms |
548 val string_of_concl = string_of_cterm context concl |
547 val string_of_concl = string_of_cterm context concl |
549 val string_of_prems = string_of_thms_no_vars context prems |
548 val string_of_prems = string_of_thms_no_vars context prems |
550 val string_of_schms = string_of_cterms context (map fst (snd schematics)) |
549 val string_of_schms = string_of_cterms context (map fst (snd schematics)) |
551 |
550 |
552 val _ = (writeln ("params: " ^ string_of_params); |
551 val _ = (tracing ("params: " ^ string_of_params); |
553 writeln ("schematics: " ^ string_of_schms); |
552 tracing ("schematics: " ^ string_of_schms); |
554 writeln ("assumptions: " ^ string_of_asms); |
553 tracing ("assumptions: " ^ string_of_asms); |
555 writeln ("conclusion: " ^ string_of_concl); |
554 tracing ("conclusion: " ^ string_of_concl); |
556 writeln ("premises: " ^ string_of_prems)) |
555 tracing ("premises: " ^ string_of_prems)) |
557 in |
556 in |
558 all_tac |
557 all_tac |
559 end*} |
558 end*} |
560 |
559 |
561 text_raw{* |
560 text_raw{* |
575 The tactic produces the following printout: |
574 The tactic produces the following printout: |
576 |
575 |
577 \begin{quote}\small |
576 \begin{quote}\small |
578 \begin{tabular}{ll} |
577 \begin{tabular}{ll} |
579 params: & @{term x}, @{term y}\\ |
578 params: & @{term x}, @{term y}\\ |
580 schematics: & @{term z}\\ |
579 schematics: & @{text ?z}\\ |
581 assumptions: & @{term "A x y"}\\ |
580 assumptions: & @{term "A x y"}\\ |
582 conclusion: & @{term "B y x \<longrightarrow> C (z y) x"}\\ |
581 conclusion: & @{term "B y x \<longrightarrow> C (z y) x"}\\ |
583 premises: & @{term "A x y"} |
582 premises: & @{term "A x y"} |
584 \end{tabular} |
583 \end{tabular} |
585 \end{quote} |
584 \end{quote} |
586 |
585 |
587 (FIXME: find out how nowadays the schmetics are handled) |
586 (FIXME: Find out how nowadays the schematics are handled) |
588 |
587 |
589 Notice in the actual output the brown colour of the variables @{term x} and |
588 Notice in the actual output the brown colour of the variables @{term x}, |
590 @{term y}. Although they are parameters in the original goal, they are fixed inside |
589 and @{term y}. Although they are parameters in the original goal, they are fixed inside |
591 the subproof. By convention these fixed variables are printed in brown colour. |
590 the tactic. By convention these fixed variables are printed in brown colour. |
592 Similarly the schematic variable @{term z}. The assumption, or premise, |
591 Similarly the schematic variable @{text ?z}. The assumption, or premise, |
593 @{prop "A x y"} is bound as @{ML_type cterm} to the record-variable |
592 @{prop "A x y"} is bound as @{ML_type cterm} to the record-variable |
594 @{text asms}, but also as @{ML_type thm} to @{text prems}. |
593 @{text asms}, but also as @{ML_type thm} to @{text prems}. |
595 |
594 |
596 If we continue the proof script by applying the @{text impI}-rule |
595 If we continue the proof script by applying the @{text impI}-rule |
597 *} |
596 *} |
603 then the tactic prints out: |
602 then the tactic prints out: |
604 |
603 |
605 \begin{quote}\small |
604 \begin{quote}\small |
606 \begin{tabular}{ll} |
605 \begin{tabular}{ll} |
607 params: & @{term x}, @{term y}\\ |
606 params: & @{term x}, @{term y}\\ |
608 schematics: & @{term z}\\ |
607 schematics: & @{text ?z}\\ |
609 assumptions: & @{term "A x y"}, @{term "B y x"}\\ |
608 assumptions: & @{term "A x y"}, @{term "B y x"}\\ |
610 conclusion: & @{term "C (z y) x"}\\ |
609 conclusion: & @{term "C (z y) x"}\\ |
611 premises: & @{term "A x y"}, @{term "B y x"} |
610 premises: & @{term "A x y"}, @{term "B y x"} |
612 \end{tabular} |
611 \end{tabular} |
613 \end{quote} |
612 \end{quote} |
615 (*<*)oops(*>*) |
614 (*<*)oops(*>*) |
616 |
615 |
617 text {* |
616 text {* |
618 Now also @{term "B y x"} is an assumption bound to @{text asms} and @{text prems}. |
617 Now also @{term "B y x"} is an assumption bound to @{text asms} and @{text prems}. |
619 |
618 |
620 The difference between @{ML SUBPROOF} and @{ML FOCUS in Subgoal} is that the former |
619 The difference between the tactics @{ML SUBPROOF} and @{ML FOCUS in Subgoal} |
621 expects that the goal is solved completely, which the latter does not. One |
620 is that the former expects that the goal is solved completely, which the |
622 convenience of both @{ML FOCUS in Subgoal} and @{ML SUBPROOF} is that we can apply the |
621 latter does not. @{ML SUBPROOF} can also not instantiate an schematic |
623 assumptions using the usual tactics, because the parameter @{text prems} |
622 variables. |
624 contains them as theorems. With this you can easily implement a tactic that |
623 |
625 behaves almost like @{ML atac}: |
624 One convenience of both @{ML FOCUS in Subgoal} and @{ML SUBPROOF} is that we |
626 *} |
625 can apply the assumptions using the usual tactics, because the parameter |
627 |
626 @{text prems} contains them as theorems. With this you can easily implement |
628 ML{*val atac' = SUBPROOF (fn {prems, ...} => resolve_tac prems 1)*} |
627 a tactic that behaves almost like @{ML atac}: |
|
628 *} |
|
629 |
|
630 ML{*val atac' = Subgoal.FOCUS (fn {prems, ...} => resolve_tac prems 1)*} |
629 |
631 |
630 text {* |
632 text {* |
631 If you apply @{ML atac'} to the next lemma |
633 If you apply @{ML atac'} to the next lemma |
632 *} |
634 *} |
633 |
635 |
636 txt{* it will produce |
638 txt{* it will produce |
637 @{subgoals [display]} *} |
639 @{subgoals [display]} *} |
638 (*<*)oops(*>*) |
640 (*<*)oops(*>*) |
639 |
641 |
640 text {* |
642 text {* |
641 The restriction in this tactic which is not present in @{ML atac} is that it |
643 Notice that @{ML atac'} inside @{ML FOCUS in Subgoal} calls @{ML |
642 cannot instantiate any schematic variables. This might be seen as a defect, |
644 resolve_tac} with the subgoal number @{text "1"} and also the outer call to |
643 but it is actually an advantage in the situations for which @{ML SUBPROOF} |
645 @{ML FOCUS in Subgoal} in the \isacommand{apply}-step uses @{text "1"}. This |
644 was designed: the reason is that, as mentioned before, instantiation of |
646 is another advantage of @{ML FOCUS in Subgoal} and @{ML SUBPROOF}: the |
645 schematic variables can affect several goals and can render them |
647 addressing inside it is completely local to the tactic inside the |
646 unprovable. @{ML SUBPROOF} is meant to avoid this. |
648 subproof. It is therefore possible to also apply @{ML atac'} to the second |
647 |
649 goal by just writing: |
648 Notice that @{ML atac'} inside @{ML SUBPROOF} calls @{ML resolve_tac} with |
650 |
649 the subgoal number @{text "1"} and also the outer call to @{ML SUBPROOF} in |
|
650 the \isacommand{apply}-step uses @{text "1"}. This is another advantage of |
|
651 @{ML SUBPROOF}: the addressing inside it is completely local to the tactic |
|
652 inside the subproof. It is therefore possible to also apply @{ML atac'} to |
|
653 the second goal by just writing: |
|
654 *} |
651 *} |
655 |
652 |
656 lemma shows "True" and "\<lbrakk>B x y; A x y; C x y\<rbrakk> \<Longrightarrow> A x y" |
653 lemma shows "True" and "\<lbrakk>B x y; A x y; C x y\<rbrakk> \<Longrightarrow> A x y" |
657 apply(tactic {* atac' @{context} 2 *}) |
654 apply(tactic {* atac' @{context} 2 *}) |
658 apply(rule TrueI) |
655 apply(rule TrueI) |
664 The functions @{ML FOCUS in Subgoal} and @{ML SUBPROOF} are defined in |
661 The functions @{ML FOCUS in Subgoal} and @{ML SUBPROOF} are defined in |
665 @{ML_file "Pure/subgoal.ML"} and also described in |
662 @{ML_file "Pure/subgoal.ML"} and also described in |
666 \isccite{sec:results}. |
663 \isccite{sec:results}. |
667 \end{readmore} |
664 \end{readmore} |
668 |
665 |
669 Similar but less powerful functions than @{ML FOCUS in Subgoal} are |
666 Similar but less powerful functions than @{ML FOCUS in Subgoal}, respectively |
|
667 @{ML SUBPROOF}, are |
670 @{ML [index] SUBGOAL} and @{ML [index] CSUBGOAL}. They allow you to |
668 @{ML [index] SUBGOAL} and @{ML [index] CSUBGOAL}. They allow you to |
671 inspect a given subgoal (the former |
669 inspect a given subgoal (the former |
672 presents the subgoal as a @{ML_type term}, while the latter as a @{ML_type |
670 presents the subgoal as a @{ML_type term}, while the latter as a @{ML_type |
673 cterm}). With this you can implement a tactic that applies a rule according |
671 cterm}). With this you can implement a tactic that applies a rule according |
674 to the topmost logic connective in the subgoal (to illustrate this we only |
672 to the topmost logic connective in the subgoal (to illustrate this we only |