# HG changeset patch # User wenzelm # Date 1432311211 -7200 # Node ID 7c278b692aae516cf376bf8ad52ce2eeb1955fa5 # Parent 1f9e08394d465fd1d208be83ac27127ef3b13a53 updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository; diff -r 1f9e08394d46 -r 7c278b692aae src/Doc/Eisbach/Manual.thy --- a/src/Doc/Eisbach/Manual.thy Fri May 22 15:13:49 2015 +0200 +++ b/src/Doc/Eisbach/Manual.thy Fri May 22 18:13:31 2015 +0200 @@ -102,9 +102,8 @@ A @{text "named theorem"} is a fact whose contents are produced dynamically within the current proof context. The Isar command @{command_ref "named_theorems"} provides simple access to this concept: it declares a - dynamic fact with corresponding \emph{attribute} - (see \autoref{s:attributes}) for managing this particular data slot in the - context. + dynamic fact with corresponding \emph{attribute} for managing + this particular data slot in the context. \ named_theorems intros @@ -178,7 +177,7 @@ @{text method\<^sub>1}. This is useful to handle cases where the number of subgoals produced by a method is determined dynamically at run-time. \ - +text_raw\\vbox{\ method conj_with uses rule = (intro conjI ; intro rule) @@ -186,7 +185,7 @@ assumes A: "P" shows "P \ P \ P" by (conj_with rule: A) - +text_raw\}\ text \ Method definitions may take other methods as arguments, and thus implement method combinators with prefix syntax. For example, to more usefully exploit @@ -254,7 +253,7 @@ disjCI -- \@{thm disjCI}\ iffI -- \@{thm iffI}\ notI -- \@{thm notI}\ - (*<*)TrueI(*>*) + lemmas [elims] = impCE -- \@{thm impCE}\ conjE -- \@{thm conjE}\ @@ -327,7 +326,7 @@ the Isar proof state. In general, however, proof subgoals can be \emph{unstructured}, with goal parameters and premises arising from rule application. To address this, @{method match} uses \emph{subgoal focusing} - (see also \autoref{s:design}) to produce structured goals out of + to produce structured goals out of unstructured ones. In place of fact or term, we may give the keyword @{keyword_def "premises"} as the match target. This causes a subgoal focus on the first subgoal, lifting local goal parameters to fixed term @@ -394,7 +393,7 @@ by solve_ex -subsubsection \Operating within a focus\ +subsection \Operating within a focus\ text \ Subgoal focusing provides a structured form of a subgoal, allowing for more @@ -461,8 +460,42 @@ lemma "\x. P x \ \x. Q x \ P y \ Q y" by (my_allE y)+ (rule conjI) +subsubsection \Inner focusing\ -subsection \Attributes\ +text \ + Premises are \emph{accumulated} for the purposes of subgoal focusing. + In contrast to using standard methods like @{method frule} within + focused match, another @{method match} will have access to all the premises + of the outer focus. + \ + + lemma "A \ B \ A \ B" + by (match premises in H: A \ \intro conjI, rule H, + match premises in H': B \ \rule H'\\) + +text \ + In this example, the inner @{method match} can find the focused premise + @{term B}. In contrast, the @{method assumption} method would fail here + due to @{term B} not being logically accessible. +\ + + lemma + "A \ A \ (B \ B)" + by (match premises in H: A \ \intro conjI, rule H, rule impI, + match premises (local) in A \ \fail\ + \ H': B \ \rule H'\\) + +text \ + In this example, the only premise that exists in the first focus is + @{term "A"}. Prior to the inner match, the rule @{text impI} changes + the goal @{term "B \ B"} into @{term "B \ B"}. A standard premise + match would also include @{term A} as an original premise of the outer + match. The @{text local} argument limits the match to + newly focused premises. + +\ + +section \Attributes\ text \ Attributes may throw errors when applied to a given fact. For example, rule @@ -474,7 +507,7 @@ \ method my_compose uses rule1 rule2 = - (rule rule1[OF rule2]) + (rule rule1 [OF rule2]) text \ Some attributes (like @{attribute OF}) have been made partially @@ -493,13 +526,13 @@ forming a static closure, allowing the @{attribute "where"} attribute to perform an instantiation at run-time. \ - +text_raw\\vbox{\ lemma assumes A: "Q \ False" shows "\ Q" by (match intros in X: "\P. (P \ False) \ \ P" \ \rule X [where P = Q, OF A]\) - +text_raw\}\ text \ Subgoal focusing converts the outermost quantifiers of premises into schematics when lifting them to hypothetical facts. This allows us to @@ -551,7 +584,7 @@ \ lemma "(\x :: 'a. A x \ B x) \ A y \ B y" - by (match premises in I[of y, intros]: "\x :: 'a. ?P x \ ?Q x" \ + by (match premises in I [of y, intros]: "\x :: 'a. ?P x \ ?Q x" \ \prop_solver\) text \ @@ -574,10 +607,11 @@ \ lemma - assumes asms: "A \ B" "A \ D" + assumes asms: "A \ B" "A \ D" shows "(A \ B) \ (A \ D)" - apply (match asms in I[intros]: "?P \ ?Q" \ \solves \prop_solver\\)? - by (match asms in I[intros]: "?P \ ?Q" (multi) \ \prop_solver\) + apply (match asms in I [intros]: "?P \ ?Q" \ \solves \prop_solver\\)? + apply (match asms in I [intros]: "?P \ ?Q" (multi) \ \prop_solver\) + done text \ In the first @{method match}, without the @{text "(multi)"} argument, @{term @@ -598,12 +632,13 @@ \ lemma - assumes asms: "A \ B" "A \ D" "D \ B" + assumes asms: "A \ B" "A \ D" "D \ B" shows "(A \ B) \ (A \ D)" - apply (match asms in I[intros]: "?P \ Q" (multi) for Q \ + apply (match asms in I [intros]: "?P \ Q" (multi) for Q \ \solves \prop_solver\\)? - by (match asms in I[intros]: "P \ ?Q" (multi) for P \ + apply (match asms in I [intros]: "P \ ?Q" (multi) for P \ \prop_solver\) + done text \ Here we have two seemingly-equivalent applications of @{method match}, @@ -631,7 +666,7 @@ lemma assumes asms: "A &&& B \ D" shows "(A \ B \ D)" - by (match asms in I:_ \ \prop_solver intros: I conjunctionI\) + by (match asms in I: _ \ \prop_solver intros: I conjunctionI\) section \Backtracking\ @@ -649,22 +684,17 @@ The method @{text foo} below fails for all goals that are conjunctions. Any such goal will match the first pattern, causing the second pattern (that - would otherwise match all goals) to never be considered. If multiple - unifiers exist for the pattern @{text "?P \ ?Q"} against the current goal, - then the failing method @{method fail} will be (uselessly) tried for all of - them. + would otherwise match all goals) to never be considered. \ method foo = (match conclusion in "?P \ ?Q" \ \fail\ \ "?R" \ \prop_solver\) text \ - This behaviour is in direct contrast to the backtracking done by Coq's Ltac, - which will attempt all patterns in a match before failing. This means that - the failure of an inner method that is executed after a successful match - does not, in Ltac, cause the entire match to fail, whereas it does in - Eisbach. In Eisbach the distinction is important due to the pervasive use of - backtracking. When a method is used in a combinator chain, its failure + The failure of an inner method that is executed after a successful match + will cause the entire match to fail. This distinction is important + due to the pervasive use of backtracking. When a method is used in a + combinator chain, its failure becomes significant because it signals previously applied methods to move to the next result. Therefore, it is necessary for @{method match} to not mask such failure. One can always rewrite a match using the combinators ``@{text @@ -713,6 +743,11 @@ succeeding after picking @{term "A \ C"}. In the second lemma, however, @{term "C \ D"} is matched first, the second pattern in the match cannot be found and so the method fails, falling through to @{method prop_solver}. + + More precise control is also possible by giving a positive + number @{text n} as an argument to @{text cut}. This will limit the number + of backtracking results of that match to be at most @{text n}. + The match argument @{text "(cut 1)"} is the same as simply @{text "(cut)"}. \ @@ -728,7 +763,7 @@ \ lemma - assumes asms: "\x. A x \ B x" "\y. A y \ C y" "\z. B z \ C z" + assumes asms: "\x. A x \ B x" "\y. A y \ C y" "\z. B z \ C z" shows "A x \ C x" by (match asms in I: "\x. P x \ ?Q x" (multi) for P \ \match (P) in "A" \ \fail\ @@ -771,21 +806,23 @@ via meta-implication @{text "_ \ _"}. \ +text_raw \\vbox{\ lemma - assumes asms: "D \ B \ C" "D \ A" + assumes asms: "D \ B \ C" "D \ A" shows "D \ B \ C \ A" - by (match asms in H:"D \ _" (multi) \ \prop_solver elims: H\) - + by (match asms in H: "D \ _" (multi) \ \prop_solver elims: H\) +text_raw \}\ text \ For the first member of @{text asms} the dummy pattern successfully matches against @{term "B \ C"} and so the proof is successful. \ lemma - assumes asms: "A \ B \ C" "D \ C" + assumes asms: "A \ B \ C" "D \ C" shows "D \ (A \ B) \ C" - apply (match asms in H:"_ \ C" (multi) \ \prop_solver elims: H\)(*<*)? - by (prop_solver elims: asms)(*>*) + apply (match asms in H: "_ \ C" (multi) \ \prop_solver elims: H\)(*<*)? + apply (prop_solver elims: asms) + done(*>*) text \ This proof will fail to solve the goal. Our match pattern will only match @@ -804,9 +841,9 @@ \ lemma - assumes asms: "A \ B \ C" "D \ C" + assumes asms: "A \ B \ C" "D \ C" shows "D \ (A \ B) \ C" - by (match asms[uncurry] in H[curry]:"_ \ C" (multi) \ + by (match asms [uncurry] in H [curry]: "_ \ C" (multi) \ \prop_solver elims: H\) @@ -821,9 +858,10 @@ lemma assumes asms: "\x :: 'a. A x" shows "A y" - apply (match asms in H:"A y" \ \rule H\)? - by (match asms in H:"P" for P \ - \match ("A y") in "P" \ \rule H\\) + apply (match asms in H: "A y" \ \rule H\)? + apply (match asms in H: P for P \ + \match ("A y") in P \ \rule H\\) + done text \ In the first @{method match} we attempt to find a member of @{text asms} @@ -847,8 +885,8 @@ lemma assumes asms: "\x :: 'a. A x" shows "A y" - by (match asms in H:"\z :: 'b. P z" for P \ - \match (y) in "y :: 'b" for y \ \rule H[where z=y]\\) + by (match asms in H: "\z :: 'b. P z" for P \ + \match (y) in "y :: 'b" for y \ \rule H [where z = y]\\) text \ In this example the type @{text 'b} is matched to @{text 'a}, however @@ -875,8 +913,9 @@ lemma assumes asms: A B C D shows D - apply (match asms in H:_ \ \print_fact H, fail\)(*<*)? - by (simp add: asms)(*>*) + apply (match asms in H: _ \ \print_fact H, fail\)(*<*)? + apply (simp add: asms) + done(*>*) text \ This proof will fail, but the tracing output will show the order that the @@ -886,7 +925,7 @@ section \Integrating with Isabelle/ML\ -subsection \Attributes\ +subsubsection \Attributes\ text \ A custom rule attribute is a simple way to extend the functionality of @@ -905,19 +944,28 @@ text \ In this example, the new attribute @{attribute get_split_rule} lifts the ML - function of the same name into an attribute. When applied to a cast + function of the same name into an attribute. When applied to a case distinction over a datatype, it retrieves its corresponding split rule. - We can then integrate this intro a method that applies the split rule, fist + We can then integrate this intro a method that applies the split rule, first matching to ensure that fetching the rule was successful. \ - +(*<*)declare TrueI [intros](*>*) method splits = (match conclusion in "?P f" for f \ \match [[get_split_rule f]] in U: "(_ :: bool) = _" \ - \rule U[THEN iffD2]\\) + \rule U [THEN iffD2]\\) lemma "L \ [] \ case L of [] \ False | _ \ True" - by (splits, prop_solver intros: allI) + apply splits + apply (prop_solver intros: allI) + done + +text \ + Here the new @{method splits} method transforms the goal to use only logical + connectives: @{term "L = [] \ False \ (\x y. L = x # y \ True)"}. This goal + is then in a form solvable by @{method prop_solver} when given the universal + quantifier introduction rule @{text allI}. +\ end diff -r 1f9e08394d46 -r 7c278b692aae src/Doc/Eisbach/Preface.thy --- a/src/Doc/Eisbach/Preface.thy Fri May 22 15:13:49 2015 +0200 +++ b/src/Doc/Eisbach/Preface.thy Fri May 22 18:13:31 2015 +0200 @@ -12,7 +12,7 @@ The core functionality of Eisbach is provided by the Isar @{command method} command. Here users may define new methods by combining existing ones with - the usual Isar syntax These methods can be abstracted over terms, facts and + the usual Isar syntax. These methods can be abstracted over terms, facts and other methods, as one might expect in any higher-order functional language. Additional functionality is provided by extending the space of methods and