wenzelm@29716: theory Framework wenzelm@42651: imports Base Main wenzelm@29716: begin wenzelm@29716: wenzelm@58618: chapter \The Isabelle/Isar Framework \label{ch:isar-framework}\ wenzelm@29716: wenzelm@58618: text \ wenzelm@58552: Isabelle/Isar @{cite "Wenzel:1999:TPHOL" and "Wenzel-PhD" and wenzelm@58552: "Nipkow-TYPES02" and "Wenzel-Paulson:2006" and "Wenzel:2006:Festschrift"} wenzelm@29716: is intended as a generic framework for developing formal wenzelm@29716: mathematical documents with full proof checking. Definitions and wenzelm@29735: proofs are organized as theories. An assembly of theory sources may wenzelm@29716: be presented as a printed document; see also wenzelm@29716: \chref{ch:document-prep}. wenzelm@29716: wenzelm@29716: The main objective of Isar is the design of a human-readable wenzelm@29716: structured proof language, which is called the ``primary proof wenzelm@29716: format'' in Isar terminology. Such a primary proof language is wenzelm@29716: somewhere in the middle between the extremes of primitive proof wenzelm@29716: objects and actual natural language. In this respect, Isar is a bit wenzelm@58552: more formalistic than Mizar @{cite "Trybulec:1993:MizarFeatures" and wenzelm@58552: "Rudnicki:1992:MizarOverview" and "Wiedijk:1999:Mizar"}, wenzelm@29716: using logical symbols for certain reasoning schemes where Mizar wenzelm@58552: would prefer English words; see @{cite "Wenzel-Wiedijk:2002"} for wenzelm@29716: further comparisons of these systems. wenzelm@29716: wenzelm@29716: So Isar challenges the traditional way of recording informal proofs wenzelm@29716: in mathematical prose, as well as the common tendency to see fully wenzelm@29716: formal proofs directly as objects of some logical calculus (e.g.\ wenzelm@29716: @{text "\"}-terms in a version of type theory). In fact, Isar is wenzelm@29716: better understood as an interpreter of a simple block-structured wenzelm@29735: language for describing the data flow of local facts and goals, wenzelm@29716: interspersed with occasional invocations of proof methods. wenzelm@29716: Everything is reduced to logical inferences internally, but these wenzelm@29716: steps are somewhat marginal compared to the overall bookkeeping of wenzelm@29716: the interpretation process. Thanks to careful design of the syntax wenzelm@29716: and semantics of Isar language elements, a formal record of Isar wenzelm@29716: instructions may later appear as an intelligible text to the wenzelm@29716: attentive reader. wenzelm@29716: wenzelm@29716: The Isar proof language has emerged from careful analysis of some wenzelm@29716: inherent virtues of the existing logical framework of Isabelle/Pure wenzelm@58552: @{cite "paulson-found" and "paulson700"}, notably composition of higher-order wenzelm@29716: natural deduction rules, which is a generalization of Gentzen's wenzelm@58552: original calculus @{cite "Gentzen:1935"}. The approach of generic wenzelm@29716: inference systems in Pure is continued by Isar towards actual proof wenzelm@29716: texts. wenzelm@29716: wenzelm@29716: Concrete applications require another intermediate layer: an wenzelm@58552: object-logic. Isabelle/HOL @{cite "isa-tutorial"} (simply-typed wenzelm@29716: set-theory) is being used most of the time; Isabelle/ZF wenzelm@58552: @{cite "isabelle-ZF"} is less extensively developed, although it would wenzelm@29716: probably fit better for classical mathematics. wenzelm@29721: wenzelm@29735: \medskip In order to illustrate natural deduction in Isar, we shall wenzelm@29735: refer to the background theory and library of Isabelle/HOL. This wenzelm@29735: includes common notions of predicate logic, naive set-theory etc.\ wenzelm@29735: using fairly standard mathematical notation. From the perspective wenzelm@29735: of generic natural deduction there is nothing special about the wenzelm@29735: logical connectives of HOL (@{text "\"}, @{text "\"}, @{text "\"}, wenzelm@29735: @{text "\"}, etc.), only the resulting reasoning principles are wenzelm@29735: relevant to the user. There are similar rules available for wenzelm@29735: set-theory operators (@{text "\"}, @{text "\"}, @{text "\"}, @{text wenzelm@29735: "\"}, etc.), or any other theory developed in the library (lattice wenzelm@29735: theory, topology etc.). wenzelm@29721: wenzelm@29721: Subsequently we briefly review fragments of Isar proof texts wenzelm@29735: corresponding directly to such general deduction schemes. The wenzelm@29735: examples shall refer to set-theory, to minimize the danger of wenzelm@29721: understanding connectives of predicate logic as something special. wenzelm@29721: wenzelm@29721: \medskip The following deduction performs @{text "\"}-introduction, wenzelm@29721: working forwards from assumptions towards the conclusion. We give wenzelm@29721: both the Isar text, and depict the primitive rule involved, as wenzelm@29735: determined by unification of the problem against rules that are wenzelm@29735: declared in the library context. wenzelm@58618: \ wenzelm@29721: wenzelm@58618: text_raw \\medskip\begin{minipage}{0.6\textwidth}\ wenzelm@29721: wenzelm@29721: (*<*) wenzelm@40964: notepad wenzelm@40964: begin wenzelm@29721: (*>*) wenzelm@29721: assume "x \ A" and "x \ B" wenzelm@29721: then have "x \ A \ B" .. wenzelm@29721: (*<*) wenzelm@40964: end wenzelm@29721: (*>*) wenzelm@29721: wenzelm@58618: text_raw \\end{minipage}\begin{minipage}{0.4\textwidth}\ wenzelm@29721: wenzelm@58618: text \ wenzelm@29721: \infer{@{prop "x \ A \ B"}}{@{prop "x \ A"} & @{prop "x \ B"}} wenzelm@58618: \ wenzelm@29721: wenzelm@58618: text_raw \\end{minipage}\ wenzelm@29721: wenzelm@58618: text \ wenzelm@29737: \medskip\noindent Note that @{command assume} augments the proof wenzelm@29737: context, @{command then} indicates that the current fact shall be wenzelm@29737: used in the next step, and @{command have} states an intermediate wenzelm@29735: goal. The two dots ``@{command ".."}'' refer to a complete proof of wenzelm@29735: this claim, using the indicated facts and a canonical rule from the wenzelm@29721: context. We could have been more explicit here by spelling out the wenzelm@29721: final proof step via the @{command "by"} command: wenzelm@58618: \ wenzelm@29721: wenzelm@29721: (*<*) wenzelm@40964: notepad wenzelm@40964: begin wenzelm@29721: (*>*) wenzelm@29721: assume "x \ A" and "x \ B" wenzelm@29721: then have "x \ A \ B" by (rule IntI) wenzelm@29721: (*<*) wenzelm@40964: end wenzelm@29721: (*>*) wenzelm@29721: wenzelm@58618: text \ wenzelm@29721: \noindent The format of the @{text "\"}-introduction rule represents wenzelm@29721: the most basic inference, which proceeds from given premises to a wenzelm@29735: conclusion, without any nested proof context involved. wenzelm@29721: wenzelm@29735: The next example performs backwards introduction on @{term "\\"}, wenzelm@29735: the intersection of all sets within a given set. This requires a wenzelm@29735: nested proof of set membership within a local context, where @{term wenzelm@29735: A} is an arbitrary-but-fixed member of the collection: wenzelm@58618: \ wenzelm@29721: wenzelm@58618: text_raw \\medskip\begin{minipage}{0.6\textwidth}\ wenzelm@29721: wenzelm@29721: (*<*) wenzelm@40964: notepad wenzelm@40964: begin wenzelm@29721: (*>*) wenzelm@29721: have "x \ \\" wenzelm@29721: proof wenzelm@29721: fix A wenzelm@29721: assume "A \ \" wenzelm@29733: show "x \ A" sorry %noproof wenzelm@29721: qed wenzelm@29721: (*<*) wenzelm@40964: end wenzelm@29721: (*>*) wenzelm@29721: wenzelm@58618: text_raw \\end{minipage}\begin{minipage}{0.4\textwidth}\ wenzelm@29721: wenzelm@58618: text \ wenzelm@29721: \infer{@{prop "x \ \\"}}{\infer*{@{prop "x \ A"}}{@{text "[A][A \ \]"}}} wenzelm@58618: \ wenzelm@29721: wenzelm@58618: text_raw \\end{minipage}\ wenzelm@29721: wenzelm@58618: text \ wenzelm@29721: \medskip\noindent This Isar reasoning pattern again refers to the wenzelm@29721: primitive rule depicted above. The system determines it in the wenzelm@56594: ``@{command proof}'' step, which could have been spelled out more wenzelm@29737: explicitly as ``@{command proof}~@{text "(rule InterI)"}''. Note wenzelm@29735: that the rule involves both a local parameter @{term "A"} and an wenzelm@29729: assumption @{prop "A \ \"} in the nested reasoning. This kind of wenzelm@29729: compound rule typically demands a genuine sub-proof in Isar, working wenzelm@29729: backwards rather than forwards as seen before. In the proof body we wenzelm@29737: encounter the @{command fix}-@{command assume}-@{command show} wenzelm@29737: outline of nested sub-proofs that is typical for Isar. The final wenzelm@29737: @{command show} is like @{command have} followed by an additional wenzelm@29737: refinement of the enclosing claim, using the rule derived from the wenzelm@29737: proof body. wenzelm@29721: wenzelm@29721: \medskip The next example involves @{term "\\"}, which can be wenzelm@29721: characterized as the set of all @{term "x"} such that @{prop "\A. x wenzelm@29721: \ A \ A \ \"}. The elimination rule for @{prop "x \ \\"} does wenzelm@29721: not mention @{text "\"} and @{text "\"} at all, but admits to obtain wenzelm@29721: directly a local @{term "A"} such that @{prop "x \ A"} and @{prop "A wenzelm@29721: \ \"} hold. This corresponds to the following Isar proof and wenzelm@29721: inference rule, respectively: wenzelm@58618: \ wenzelm@29721: wenzelm@58618: text_raw \\medskip\begin{minipage}{0.6\textwidth}\ wenzelm@29721: wenzelm@29721: (*<*) wenzelm@40964: notepad wenzelm@40964: begin wenzelm@29721: (*>*) wenzelm@29721: assume "x \ \\" wenzelm@29721: then have C wenzelm@29721: proof wenzelm@29721: fix A wenzelm@29721: assume "x \ A" and "A \ \" wenzelm@29733: show C sorry %noproof wenzelm@29721: qed wenzelm@29721: (*<*) wenzelm@40964: end wenzelm@29721: (*>*) wenzelm@29721: wenzelm@58618: text_raw \\end{minipage}\begin{minipage}{0.4\textwidth}\ wenzelm@29721: wenzelm@58618: text \ wenzelm@29721: \infer{@{prop "C"}}{@{prop "x \ \\"} & \infer*{@{prop "C"}~}{@{text "[A][x \ A, A \ \]"}}} wenzelm@58618: \ wenzelm@29721: wenzelm@58618: text_raw \\end{minipage}\ wenzelm@29721: wenzelm@58618: text \ wenzelm@29721: \medskip\noindent Although the Isar proof follows the natural wenzelm@29721: deduction rule closely, the text reads not as natural as wenzelm@29721: anticipated. There is a double occurrence of an arbitrary wenzelm@29721: conclusion @{prop "C"}, which represents the final result, but is wenzelm@29721: irrelevant for now. This issue arises for any elimination rule wenzelm@29721: involving local parameters. Isar provides the derived language wenzelm@29737: element @{command obtain}, which is able to perform the same wenzelm@29721: elimination proof more conveniently: wenzelm@58618: \ wenzelm@29721: wenzelm@29721: (*<*) wenzelm@40964: notepad wenzelm@40964: begin wenzelm@29721: (*>*) wenzelm@29721: assume "x \ \\" wenzelm@29721: then obtain A where "x \ A" and "A \ \" .. wenzelm@29721: (*<*) wenzelm@40964: end wenzelm@29721: (*>*) wenzelm@29721: wenzelm@58618: text \ wenzelm@29721: \noindent Here we avoid to mention the final conclusion @{prop "C"} wenzelm@29721: and return to plain forward reasoning. The rule involved in the wenzelm@29721: ``@{command ".."}'' proof is the same as before. wenzelm@58618: \ wenzelm@29716: wenzelm@29729: wenzelm@58618: section \The Pure framework \label{sec:framework-pure}\ wenzelm@29729: wenzelm@58618: text \ wenzelm@58552: The Pure logic @{cite "paulson-found" and "paulson700"} is an intuitionistic wenzelm@58552: fragment of higher-order logic @{cite "church40"}. In type-theoretic wenzelm@29729: parlance, there are three levels of @{text "\"}-calculus with wenzelm@29735: corresponding arrows @{text "\"}/@{text "\"}/@{text "\"}: wenzelm@29735: wenzelm@29735: \medskip wenzelm@29735: \begin{tabular}{ll} wenzelm@29735: @{text "\ \ \"} & syntactic function space (terms depending on terms) \\ wenzelm@29735: @{text "\x. B(x)"} & universal quantification (proofs depending on terms) \\ wenzelm@29735: @{text "A \ B"} & implication (proofs depending on proofs) \\ wenzelm@29735: \end{tabular} wenzelm@29735: \medskip wenzelm@29729: wenzelm@29735: \noindent Here only the types of syntactic terms, and the wenzelm@29735: propositions of proof terms have been shown. The @{text wenzelm@29735: "\"}-structure of proofs can be recorded as an optional feature of wenzelm@58552: the Pure inference kernel @{cite "Berghofer-Nipkow:2000:TPHOL"}, but wenzelm@29735: the formal system can never depend on them due to \emph{proof wenzelm@29735: irrelevance}. wenzelm@29735: wenzelm@29735: On top of this most primitive layer of proofs, Pure implements a wenzelm@29735: generic calculus for nested natural deduction rules, similar to wenzelm@58552: @{cite "Schroeder-Heister:1984"}. Here object-logic inferences are wenzelm@29735: internalized as formulae over @{text "\"} and @{text "\"}. wenzelm@29735: Combining such rule statements may involve higher-order unification wenzelm@58552: @{cite "paulson-natural"}. wenzelm@58618: \ wenzelm@29729: wenzelm@29729: wenzelm@58618: subsection \Primitive inferences\ wenzelm@29729: wenzelm@58618: text \ wenzelm@29729: Term syntax provides explicit notation for abstraction @{text "\x :: wenzelm@29729: \. b(x)"} and application @{text "b a"}, while types are usually wenzelm@29729: implicit thanks to type-inference; terms of type @{text "prop"} are wenzelm@29729: called propositions. Logical statements are composed via @{text "\x wenzelm@29729: :: \. B(x)"} and @{text "A \ B"}. Primitive reasoning operates on wenzelm@29729: judgments of the form @{text "\ \ \"}, with standard introduction wenzelm@29729: and elimination rules for @{text "\"} and @{text "\"} that refer to wenzelm@53015: fixed parameters @{text "x\<^sub>1, \, x\<^sub>m"} and hypotheses wenzelm@53015: @{text "A\<^sub>1, \, A\<^sub>n"} from the context @{text "\"}; wenzelm@29729: the corresponding proof terms are left implicit. The subsequent wenzelm@29729: inference rules define @{text "\ \ \"} inductively, relative to a wenzelm@29729: collection of axioms: wenzelm@29729: wenzelm@29729: \[ wenzelm@29729: \infer{@{text "\ A"}}{(@{text "A"} \text{~axiom})} wenzelm@29729: \qquad wenzelm@29729: \infer{@{text "A \ A"}}{} wenzelm@29729: \] wenzelm@29729: wenzelm@29729: \[ wenzelm@29729: \infer{@{text "\ \ \x. B(x)"}}{@{text "\ \ B(x)"} & @{text "x \ \"}} wenzelm@29729: \qquad wenzelm@29729: \infer{@{text "\ \ B(a)"}}{@{text "\ \ \x. B(x)"}} wenzelm@29729: \] wenzelm@29729: wenzelm@29729: \[ wenzelm@29729: \infer{@{text "\ - A \ A \ B"}}{@{text "\ \ B"}} wenzelm@29729: \qquad wenzelm@29729: \infer{@{text "\\<^sub>1 \ \\<^sub>2 \ B"}}{@{text "\\<^sub>1 \ A \ B"} & @{text "\\<^sub>2 \ A"}} wenzelm@29729: \] wenzelm@29729: wenzelm@29729: Furthermore, Pure provides a built-in equality @{text "\ :: \ \ \ \ wenzelm@29729: prop"} with axioms for reflexivity, substitution, extensionality, wenzelm@29729: and @{text "\\\"}-conversion on @{text "\"}-terms. wenzelm@29729: wenzelm@29729: \medskip An object-logic introduces another layer on top of Pure, wenzelm@29729: e.g.\ with types @{text "i"} for individuals and @{text "o"} for wenzelm@29729: propositions, term constants @{text "Trueprop :: o \ prop"} as wenzelm@29729: (implicit) derivability judgment and connectives like @{text "\ :: o wenzelm@29729: \ o \ o"} or @{text "\ :: (i \ o) \ o"}, and axioms for object-level wenzelm@29729: rules such as @{text "conjI: A \ B \ A \ B"} or @{text "allI: (\x. B wenzelm@29729: x) \ \x. B x"}. Derived object rules are represented as theorems of wenzelm@29729: Pure. After the initial object-logic setup, further axiomatizations wenzelm@29729: are usually avoided; plain definitions and derived principles are wenzelm@29729: used exclusively. wenzelm@58618: \ wenzelm@29729: wenzelm@29729: wenzelm@58618: subsection \Reasoning with rules \label{sec:framework-resolution}\ wenzelm@29729: wenzelm@58618: text \ wenzelm@29729: Primitive inferences mostly serve foundational purposes. The main wenzelm@29729: reasoning mechanisms of Pure operate on nested natural deduction wenzelm@29729: rules expressed as formulae, using @{text "\"} to bind local wenzelm@29729: parameters and @{text "\"} to express entailment. Multiple wenzelm@29729: parameters and premises are represented by repeating these wenzelm@29735: connectives in a right-associative manner. wenzelm@29729: wenzelm@29729: Since @{text "\"} and @{text "\"} commute thanks to the theorem wenzelm@29729: @{prop "(A \ (\x. B x)) \ (\x. A \ B x)"}, we may assume w.l.o.g.\ wenzelm@29729: that rule statements always observe the normal form where wenzelm@29729: quantifiers are pulled in front of implications at each level of wenzelm@29729: nesting. This means that any Pure proposition may be presented as a wenzelm@58552: \emph{Hereditary Harrop Formula} @{cite "Miller:1991"} which is of the wenzelm@53015: form @{text "\x\<^sub>1 \ x\<^sub>m. H\<^sub>1 \ \ H\<^sub>n \ wenzelm@29735: A"} for @{text "m, n \ 0"}, and @{text "A"} atomic, and @{text wenzelm@53015: "H\<^sub>1, \, H\<^sub>n"} being recursively of the same format. wenzelm@29729: Following the convention that outermost quantifiers are implicit, wenzelm@53015: Horn clauses @{text "A\<^sub>1 \ \ A\<^sub>n \ A"} are a special wenzelm@29729: case of this. wenzelm@29729: wenzelm@29735: For example, @{text "\"}-introduction rule encountered before is wenzelm@29735: represented as a Pure theorem as follows: wenzelm@29735: \[ wenzelm@29735: @{text "IntI:"}~@{prop "x \ A \ x \ B \ x \ A \ B"} wenzelm@29735: \] wenzelm@29735: wenzelm@29735: \noindent This is a plain Horn clause, since no further nesting on wenzelm@29735: the left is involved. The general @{text "\"}-introduction wenzelm@29735: corresponds to a Hereditary Harrop Formula with one additional level wenzelm@29735: of nesting: wenzelm@29735: \[ wenzelm@29735: @{text "InterI:"}~@{prop "(\A. A \ \ \ x \ A) \ x \ \\"} wenzelm@29735: \] wenzelm@29735: wenzelm@53015: \medskip Goals are also represented as rules: @{text "A\<^sub>1 \ wenzelm@53015: \ A\<^sub>n \ C"} states that the sub-goals @{text "A\<^sub>1, \, wenzelm@53015: A\<^sub>n"} entail the result @{text "C"}; for @{text "n = 0"} the wenzelm@29729: goal is finished. To allow @{text "C"} being a rule statement wenzelm@29729: itself, we introduce the protective marker @{text "# :: prop \ wenzelm@29729: prop"}, which is defined as identity and hidden from the user. We wenzelm@29729: initialize and finish goal states as follows: wenzelm@29729: wenzelm@29729: \[ wenzelm@29729: \begin{array}{c@ {\qquad}c} wenzelm@29729: \infer[(@{inference_def init})]{@{text "C \ #C"}}{} & wenzelm@29729: \infer[(@{inference_def finish})]{@{text C}}{@{text "#C"}} wenzelm@29729: \end{array} wenzelm@29729: \] wenzelm@29729: wenzelm@29735: \noindent Goal states are refined in intermediate proof steps until wenzelm@29735: a finished form is achieved. Here the two main reasoning principles wenzelm@29735: are @{inference resolution}, for back-chaining a rule against a wenzelm@29735: sub-goal (replacing it by zero or more sub-goals), and @{inference wenzelm@29729: assumption}, for solving a sub-goal (finding a short-circuit with wenzelm@29729: local assumptions). Below @{text "\<^vec>x"} stands for @{text wenzelm@53015: "x\<^sub>1, \, x\<^sub>n"} (@{text "n \ 0"}). wenzelm@29729: wenzelm@29729: \[ wenzelm@29729: \infer[(@{inference_def resolution})] wenzelm@29729: {@{text "(\\<^vec>x. \<^vec>H \<^vec>x \ \<^vec>A (\<^vec>a \<^vec>x))\ \ C\"}} wenzelm@29729: {\begin{tabular}{rl} wenzelm@29729: @{text "rule:"} & wenzelm@29729: @{text "\<^vec>A \<^vec>a \ B \<^vec>a"} \\ wenzelm@29729: @{text "goal:"} & wenzelm@29729: @{text "(\\<^vec>x. \<^vec>H \<^vec>x \ B' \<^vec>x) \ C"} \\ wenzelm@29729: @{text "goal unifier:"} & wenzelm@29729: @{text "(\\<^vec>x. B (\<^vec>a \<^vec>x))\ = B'\"} \\ wenzelm@29729: \end{tabular}} wenzelm@29729: \] wenzelm@29729: wenzelm@29729: \medskip wenzelm@29729: wenzelm@29729: \[ wenzelm@29729: \infer[(@{inference_def assumption})]{@{text "C\"}} wenzelm@29729: {\begin{tabular}{rl} wenzelm@29729: @{text "goal:"} & wenzelm@29729: @{text "(\\<^vec>x. \<^vec>H \<^vec>x \ A \<^vec>x) \ C"} \\ wenzelm@29729: @{text "assm unifier:"} & @{text "A\ = H\<^sub>i\"}~~\text{(for some~@{text "H\<^sub>i"})} \\ wenzelm@29729: \end{tabular}} wenzelm@29729: \] wenzelm@29729: wenzelm@29729: The following trace illustrates goal-oriented reasoning in wenzelm@29729: Isabelle/Pure: wenzelm@29729: wenzelm@29735: {\footnotesize wenzelm@29729: \medskip wenzelm@29735: \begin{tabular}{r@ {\quad}l} wenzelm@29729: @{text "(A \ B \ B \ A) \ #(A \ B \ B \ A)"} & @{text "(init)"} \\ wenzelm@29729: @{text "(A \ B \ B) \ (A \ B \ A) \ #\"} & @{text "(resolution B \ A \ B \ A)"} \\ wenzelm@29729: @{text "(A \ B \ A \ B) \ (A \ B \ A) \ #\"} & @{text "(resolution A \ B \ B)"} \\ wenzelm@29729: @{text "(A \ B \ A) \ #\"} & @{text "(assumption)"} \\ wenzelm@48279: @{text "(A \ B \ A \ B) \ #\"} & @{text "(resolution A \ B \ A)"} \\ wenzelm@29729: @{text "#\"} & @{text "(assumption)"} \\ wenzelm@29729: @{text "A \ B \ B \ A"} & @{text "(finish)"} \\ wenzelm@29729: \end{tabular} wenzelm@29729: \medskip wenzelm@29735: } wenzelm@29729: wenzelm@29729: Compositions of @{inference assumption} after @{inference wenzelm@29729: resolution} occurs quite often, typically in elimination steps. wenzelm@29729: Traditional Isabelle tactics accommodate this by a combined wenzelm@29729: @{inference_def elim_resolution} principle. In contrast, Isar uses wenzelm@29729: a slightly more refined combination, where the assumptions to be wenzelm@29729: closed are marked explicitly, using again the protective marker wenzelm@29729: @{text "#"}: wenzelm@29729: wenzelm@29729: \[ wenzelm@29729: \infer[(@{inference refinement})] wenzelm@29729: {@{text "(\\<^vec>x. \<^vec>H \<^vec>x \ \<^vec>G' (\<^vec>a \<^vec>x))\ \ C\"}} wenzelm@29729: {\begin{tabular}{rl} wenzelm@42666: @{text "sub\proof:"} & wenzelm@29729: @{text "\<^vec>G \<^vec>a \ B \<^vec>a"} \\ wenzelm@29729: @{text "goal:"} & wenzelm@29729: @{text "(\\<^vec>x. \<^vec>H \<^vec>x \ B' \<^vec>x) \ C"} \\ wenzelm@29729: @{text "goal unifier:"} & wenzelm@29729: @{text "(\\<^vec>x. B (\<^vec>a \<^vec>x))\ = B'\"} \\ wenzelm@29729: @{text "assm unifiers:"} & wenzelm@29729: @{text "(\\<^vec>x. G\<^sub>j (\<^vec>a \<^vec>x))\ = #H\<^sub>i\"} \\ wenzelm@29729: & \quad (for each marked @{text "G\<^sub>j"} some @{text "#H\<^sub>i"}) \\ wenzelm@29729: \end{tabular}} wenzelm@29729: \] wenzelm@29729: wenzelm@42666: \noindent Here the @{text "sub\proof"} rule stems from the wenzelm@29737: main @{command fix}-@{command assume}-@{command show} outline of wenzelm@29737: Isar (cf.\ \secref{sec:framework-subproof}): each assumption wenzelm@29729: indicated in the text results in a marked premise @{text "G"} above. wenzelm@29735: The marking enforces resolution against one of the sub-goal's wenzelm@29737: premises. Consequently, @{command fix}-@{command assume}-@{command wenzelm@29737: show} enables to fit the result of a sub-proof quite robustly into a wenzelm@29737: pending sub-goal, while maintaining a good measure of flexibility. wenzelm@58618: \ wenzelm@29729: wenzelm@29729: wenzelm@58618: section \The Isar proof language \label{sec:framework-isar}\ wenzelm@29729: wenzelm@58618: text \ wenzelm@29729: Structured proofs are presented as high-level expressions for wenzelm@29729: composing entities of Pure (propositions, facts, and goals). The wenzelm@29729: Isar proof language allows to organize reasoning within the wenzelm@29729: underlying rule calculus of Pure, but Isar is not another logical wenzelm@29729: calculus! wenzelm@29729: wenzelm@29729: Isar is an exercise in sound minimalism. Approximately half of the wenzelm@29729: language is introduced as primitive, the rest defined as derived wenzelm@29729: concepts. The following grammar describes the core language wenzelm@29729: (category @{text "proof"}), which is embedded into theory wenzelm@29729: specification elements such as @{command theorem}; see also wenzelm@29729: \secref{sec:framework-stmt} for the separate category @{text wenzelm@29729: "statement"}. wenzelm@29729: wenzelm@29729: \medskip wenzelm@29729: \begin{tabular}{rcl} wenzelm@42666: @{text "theory\stmt"} & = & @{command "theorem"}~@{text "statement proof |"}~~@{command "definition"}~@{text "\ | \"} \\[1ex] wenzelm@29729: wenzelm@29729: @{text "proof"} & = & @{text "prfx\<^sup>*"}~@{command "proof"}~@{text "method\<^sup>? stmt\<^sup>*"}~@{command "qed"}~@{text "method\<^sup>?"} \\[1ex] wenzelm@29729: wenzelm@29729: @{text prfx} & = & @{command "using"}~@{text "facts"} \\ wenzelm@29729: & @{text "|"} & @{command "unfolding"}~@{text "facts"} \\ wenzelm@29729: wenzelm@29729: @{text stmt} & = & @{command "{"}~@{text "stmt\<^sup>*"}~@{command "}"} \\ wenzelm@29729: & @{text "|"} & @{command "next"} \\ wenzelm@29729: & @{text "|"} & @{command "note"}~@{text "name = facts"} \\ wenzelm@29729: & @{text "|"} & @{command "let"}~@{text "term = term"} \\ wenzelm@29729: & @{text "|"} & @{command "fix"}~@{text "var\<^sup>+"} \\ wenzelm@29737: & @{text "|"} & @{command assume}~@{text "\inference\ name: props"} \\ wenzelm@29729: & @{text "|"} & @{command "then"}@{text "\<^sup>?"}~@{text goal} \\ wenzelm@29729: @{text goal} & = & @{command "have"}~@{text "name: props proof"} \\ wenzelm@29729: & @{text "|"} & @{command "show"}~@{text "name: props proof"} \\ wenzelm@29729: \end{tabular} wenzelm@29729: wenzelm@29729: \medskip Simultaneous propositions or facts may be separated by the wenzelm@29729: @{keyword "and"} keyword. wenzelm@29729: wenzelm@29729: \medskip The syntax for terms and propositions is inherited from wenzelm@29729: Pure (and the object-logic). A @{text "pattern"} is a @{text wenzelm@29729: "term"} with schematic variables, to be bound by higher-order wenzelm@29729: matching. wenzelm@29729: wenzelm@29735: \medskip Facts may be referenced by name or proposition. For wenzelm@29737: example, the result of ``@{command have}~@{text "a: A \proof\"}'' wenzelm@29735: becomes available both as @{text "a"} and wenzelm@29735: \isacharbackquoteopen@{text "A"}\isacharbackquoteclose. Moreover, wenzelm@29735: fact expressions may involve attributes that modify either the wenzelm@29735: theorem or the background context. For example, the expression wenzelm@29735: ``@{text "a [OF b]"}'' refers to the composition of two facts wenzelm@29735: according to the @{inference resolution} inference of wenzelm@29735: \secref{sec:framework-resolution}, while ``@{text "a [intro]"}'' wenzelm@29735: declares a fact as introduction rule in the context. wenzelm@29729: wenzelm@29735: The special fact called ``@{fact this}'' always refers to the last wenzelm@29737: result, as produced by @{command note}, @{command assume}, @{command wenzelm@29737: have}, or @{command show}. Since @{command note} occurs wenzelm@29737: frequently together with @{command then} we provide some wenzelm@29737: abbreviations: wenzelm@29729: wenzelm@29737: \medskip wenzelm@29737: \begin{tabular}{rcl} wenzelm@29737: @{command from}~@{text a} & @{text "\"} & @{command note}~@{text a}~@{command then} \\ wenzelm@29737: @{command with}~@{text a} & @{text "\"} & @{command from}~@{text "a \ this"} \\ wenzelm@29737: \end{tabular} wenzelm@29737: \medskip wenzelm@29737: wenzelm@29737: The @{text "method"} category is essentially a parameter and may be wenzelm@29737: populated later. Methods use the facts indicated by @{command wenzelm@29737: "then"} or @{command using}, and then operate on the goal state. wenzelm@29737: Some basic methods are predefined: ``@{method "-"}'' leaves the goal wenzelm@29737: unchanged, ``@{method this}'' applies the facts as rules to the wenzelm@42626: goal, ``@{method (Pure) "rule"}'' applies the facts to another rule and the wenzelm@42626: result to the goal (both ``@{method this}'' and ``@{method (Pure) rule}'' wenzelm@29737: refer to @{inference resolution} of wenzelm@29729: \secref{sec:framework-resolution}). The secondary arguments to wenzelm@42626: ``@{method (Pure) rule}'' may be specified explicitly as in ``@{text "(rule wenzelm@29729: a)"}'', or picked from the context. In the latter case, the system wenzelm@29729: first tries rules declared as @{attribute (Pure) elim} or wenzelm@29729: @{attribute (Pure) dest}, followed by those declared as @{attribute wenzelm@29729: (Pure) intro}. wenzelm@29729: wenzelm@42626: The default method for @{command proof} is ``@{method (Pure) rule}'' wenzelm@29737: (arguments picked from the context), for @{command qed} it is wenzelm@29729: ``@{method "-"}''. Further abbreviations for terminal proof steps wenzelm@29729: are ``@{command "by"}~@{text "method\<^sub>1 method\<^sub>2"}'' for wenzelm@29737: ``@{command proof}~@{text "method\<^sub>1"}~@{command qed}~@{text wenzelm@29737: "method\<^sub>2"}'', and ``@{command ".."}'' for ``@{command wenzelm@42626: "by"}~@{method (Pure) rule}, and ``@{command "."}'' for ``@{command wenzelm@29737: "by"}~@{method this}''. The @{command unfolding} element operates wenzelm@29737: directly on the current facts and goal by applying equalities. wenzelm@29729: wenzelm@29737: \medskip Block structure can be indicated explicitly by ``@{command wenzelm@29737: "{"}~@{text "\"}~@{command "}"}'', although the body of a sub-proof wenzelm@29737: already involves implicit nesting. In any case, @{command next} wenzelm@29737: jumps into the next section of a block, i.e.\ it acts like closing wenzelm@29737: an implicit block scope and opening another one; there is no direct wenzelm@29737: correspondence to subgoals here. wenzelm@29729: wenzelm@29737: The remaining elements @{command fix} and @{command assume} build up wenzelm@29737: a local context (see \secref{sec:framework-context}), while wenzelm@29737: @{command show} refines a pending sub-goal by the rule resulting wenzelm@29729: from a nested sub-proof (see \secref{sec:framework-subproof}). wenzelm@29729: Further derived concepts will support calculational reasoning (see wenzelm@29729: \secref{sec:framework-calc}). wenzelm@58618: \ wenzelm@29729: wenzelm@29729: wenzelm@58618: subsection \Context elements \label{sec:framework-context}\ wenzelm@29729: wenzelm@58618: text \ wenzelm@29729: In judgments @{text "\ \ \"} of the primitive framework, @{text "\"} wenzelm@29729: essentially acts like a proof context. Isar elaborates this idea wenzelm@29735: towards a higher-level notion, with additional information for wenzelm@29729: type-inference, term abbreviations, local facts, hypotheses etc. wenzelm@29729: wenzelm@29737: The element @{command fix}~@{text "x :: \"} declares a local wenzelm@29729: parameter, i.e.\ an arbitrary-but-fixed entity of a given type; in wenzelm@29729: results exported from the context, @{text "x"} may become anything. wenzelm@29737: The @{command assume}~@{text "\inference\"} element provides a wenzelm@29737: general interface to hypotheses: ``@{command assume}~@{text wenzelm@29737: "\inference\ A"}'' produces @{text "A \ A"} locally, while the wenzelm@29737: included inference tells how to discharge @{text A} from results wenzelm@29737: @{text "A \ B"} later on. There is no user-syntax for @{text wenzelm@29737: "\inference\"}, i.e.\ it may only occur internally when derived wenzelm@29737: commands are defined in ML. wenzelm@29737: wenzelm@29737: At the user-level, the default inference for @{command assume} is wenzelm@29737: @{inference discharge} as given below. The additional variants wenzelm@29737: @{command presume} and @{command def} are defined as follows: wenzelm@29737: wenzelm@29737: \medskip wenzelm@29737: \begin{tabular}{rcl} wenzelm@42666: @{command presume}~@{text A} & @{text "\"} & @{command assume}~@{text "\weak\discharge\ A"} \\ wenzelm@29737: @{command def}~@{text "x \ a"} & @{text "\"} & @{command fix}~@{text x}~@{command assume}~@{text "\expansion\ x \ a"} \\ wenzelm@29737: \end{tabular} wenzelm@29737: \medskip wenzelm@29729: wenzelm@29729: \[ wenzelm@29737: \infer[(@{inference_def discharge})]{@{text "\\ - A \ #A \ B"}}{@{text "\\ \ B"}} wenzelm@29737: \] wenzelm@29737: \[ wenzelm@42666: \infer[(@{inference_def "weak\discharge"})]{@{text "\\ - A \ A \ B"}}{@{text "\\ \ B"}} wenzelm@29737: \] wenzelm@29737: \[ wenzelm@29729: \infer[(@{inference_def expansion})]{@{text "\\ - (x \ a) \ B a"}}{@{text "\\ \ B x"}} wenzelm@29729: \] wenzelm@29729: wenzelm@29737: \medskip Note that @{inference discharge} and @{inference wenzelm@42666: "weak\discharge"} differ in the marker for @{prop A}, which is wenzelm@29737: relevant when the result of a @{command fix}-@{command wenzelm@29737: assume}-@{command show} outline is composed with a pending goal, wenzelm@29737: cf.\ \secref{sec:framework-subproof}. wenzelm@29729: wenzelm@29737: The most interesting derived context element in Isar is @{command wenzelm@58552: obtain} @{cite \\S5.3\ "Wenzel-PhD"}, which supports generalized wenzelm@29737: elimination steps in a purely forward manner. The @{command obtain} wenzelm@29739: command takes a specification of parameters @{text "\<^vec>x"} and wenzelm@29737: assumptions @{text "\<^vec>A"} to be added to the context, together wenzelm@29737: with a proof of a case rule stating that this extension is wenzelm@29737: conservative (i.e.\ may be removed from closed results later on): wenzelm@29729: wenzelm@29729: \medskip wenzelm@29729: \begin{tabular}{l} wenzelm@29729: @{text "\facts\"}~~@{command obtain}~@{text "\<^vec>x \ \<^vec>A \<^vec>x \proof\ \"} \\[0.5ex] wenzelm@29729: \quad @{command have}~@{text "case: \thesis. (\\<^vec>x. \<^vec>A \<^vec>x \ thesis) \ thesis\"} \\ wenzelm@29729: \quad @{command proof}~@{method "-"} \\ wenzelm@29729: \qquad @{command fix}~@{text thesis} \\ wenzelm@29729: \qquad @{command assume}~@{text "[intro]: \\<^vec>x. \<^vec>A \<^vec>x \ thesis"} \\ wenzelm@29733: \qquad @{command show}~@{text thesis}~@{command using}~@{text "\facts\ \proof\"} \\ wenzelm@29729: \quad @{command qed} \\ wenzelm@29737: \quad @{command fix}~@{text "\<^vec>x"}~@{command assume}~@{text "\elimination case\ \<^vec>A \<^vec>x"} \\ wenzelm@29729: \end{tabular} wenzelm@29729: \medskip wenzelm@29729: wenzelm@29729: \[ wenzelm@29729: \infer[(@{inference elimination})]{@{text "\ \ B"}}{ wenzelm@29729: \begin{tabular}{rl} wenzelm@29729: @{text "case:"} & wenzelm@29729: @{text "\ \ \thesis. (\\<^vec>x. \<^vec>A \<^vec>x \ thesis) \ thesis"} \\[0.2ex] wenzelm@29729: @{text "result:"} & wenzelm@29729: @{text "\ \ \<^vec>A \<^vec>y \ B"} \\[0.2ex] wenzelm@29729: \end{tabular}} wenzelm@29729: \] wenzelm@29729: wenzelm@29729: \noindent Here the name ``@{text thesis}'' is a specific convention wenzelm@29729: for an arbitrary-but-fixed proposition; in the primitive natural wenzelm@29729: deduction rules shown before we have occasionally used @{text C}. wenzelm@29737: The whole statement of ``@{command obtain}~@{text x}~@{keyword wenzelm@29729: "where"}~@{text "A x"}'' may be read as a claim that @{text "A x"} wenzelm@29729: may be assumed for some arbitrary-but-fixed @{text "x"}. Also note wenzelm@29737: that ``@{command obtain}~@{text "A \ B"}'' without parameters wenzelm@29737: is similar to ``@{command have}~@{text "A \ B"}'', but the wenzelm@29737: latter involves multiple sub-goals. wenzelm@29729: wenzelm@29729: \medskip The subsequent Isar proof texts explain all context wenzelm@29729: elements introduced above using the formal proof language itself. wenzelm@29729: After finishing a local proof within a block, we indicate the wenzelm@29739: exported result via @{command note}. wenzelm@58618: \ wenzelm@29729: wenzelm@29729: (*<*) wenzelm@29729: theorem True wenzelm@29729: proof wenzelm@29729: (*>*) wenzelm@58999: text_raw \\begin{minipage}[t]{0.45\textwidth}\ wenzelm@29729: { wenzelm@29729: fix x wenzelm@29735: have "B x" sorry %noproof wenzelm@29729: } wenzelm@58618: note \\x. B x\ wenzelm@58999: text_raw \\end{minipage}\quad\begin{minipage}[t]{0.45\textwidth}\(*<*)next(*>*) wenzelm@29735: { wenzelm@29735: assume A wenzelm@29735: have B sorry %noproof wenzelm@29735: } wenzelm@58618: note \A \ B\ wenzelm@58999: text_raw \\end{minipage}\\[3ex]\begin{minipage}[t]{0.45\textwidth}\(*<*)next(*>*) wenzelm@29729: { wenzelm@29729: def x \ a wenzelm@29735: have "B x" sorry %noproof wenzelm@29729: } wenzelm@58618: note \B a\ wenzelm@58999: text_raw \\end{minipage}\quad\begin{minipage}[t]{0.45\textwidth}\(*<*)next(*>*) wenzelm@29729: { wenzelm@29735: obtain x where "A x" sorry %noproof wenzelm@29733: have B sorry %noproof wenzelm@29729: } wenzelm@58618: note \B\ wenzelm@58999: text_raw \\end{minipage}\ wenzelm@29729: (*<*) wenzelm@29729: qed wenzelm@29729: (*>*) wenzelm@29729: wenzelm@58618: text \ wenzelm@29739: \bigskip\noindent This illustrates the meaning of Isar context wenzelm@29739: elements without goals getting in between. wenzelm@58618: \ wenzelm@29729: wenzelm@58618: subsection \Structured statements \label{sec:framework-stmt}\ wenzelm@29729: wenzelm@58618: text \ wenzelm@29729: The category @{text "statement"} of top-level theorem specifications wenzelm@29729: is defined as follows: wenzelm@29729: wenzelm@29729: \medskip wenzelm@29729: \begin{tabular}{rcl} wenzelm@29729: @{text "statement"} & @{text "\"} & @{text "name: props \ \"} \\ wenzelm@29729: & @{text "|"} & @{text "context\<^sup>* conclusion"} \\[0.5ex] wenzelm@29729: wenzelm@29729: @{text "context"} & @{text "\"} & @{text "\ vars \ \"} \\ wenzelm@29729: & @{text "|"} & @{text "\ name: props \ \"} \\ wenzelm@29729: wenzelm@29729: @{text "conclusion"} & @{text "\"} & @{text "\ name: props \ \"} \\ wenzelm@29735: & @{text "|"} & @{text "\ vars \ \ \ name: props \ \"} \\ wenzelm@29735: & & \quad @{text "\ \"} \\ wenzelm@29729: \end{tabular} wenzelm@29729: wenzelm@29729: \medskip\noindent A simple @{text "statement"} consists of named wenzelm@29729: propositions. The full form admits local context elements followed wenzelm@29729: by the actual conclusions, such as ``@{keyword "fixes"}~@{text wenzelm@29729: x}~@{keyword "assumes"}~@{text "A x"}~@{keyword "shows"}~@{text "B wenzelm@29729: x"}''. The final result emerges as a Pure rule after discharging wenzelm@29729: the context: @{prop "\x. A x \ B x"}. wenzelm@29729: wenzelm@29729: The @{keyword "obtains"} variant is another abbreviation defined wenzelm@29729: below; unlike @{command obtain} (cf.\ wenzelm@29729: \secref{sec:framework-context}) there may be several ``cases'' wenzelm@29729: separated by ``@{text "\"}'', each consisting of several wenzelm@29729: parameters (@{text "vars"}) and several premises (@{text "props"}). wenzelm@29729: This specifies multi-branch elimination rules. wenzelm@29729: wenzelm@29729: \medskip wenzelm@29729: \begin{tabular}{l} wenzelm@29729: @{text "\ \<^vec>x \ \<^vec>A \<^vec>x \ \ \"} \\[0.5ex] wenzelm@29729: \quad @{text "\ thesis"} \\ wenzelm@29729: \quad @{text "\ [intro]: \\<^vec>x. \<^vec>A \<^vec>x \ thesis \ \"} \\ wenzelm@29729: \quad @{text "\ thesis"} \\ wenzelm@29729: \end{tabular} wenzelm@29729: \medskip wenzelm@29729: wenzelm@29729: Presenting structured statements in such an ``open'' format usually wenzelm@29729: simplifies the subsequent proof, because the outer structure of the wenzelm@29729: problem is already laid out directly. E.g.\ consider the following wenzelm@29729: canonical patterns for @{text "\"} and @{text "\"}, wenzelm@29729: respectively: wenzelm@58618: \ wenzelm@29729: wenzelm@58618: text_raw \\begin{minipage}{0.5\textwidth}\ wenzelm@29729: wenzelm@29729: theorem wenzelm@29729: fixes x and y wenzelm@29729: assumes "A x" and "B y" wenzelm@29729: shows "C x y" wenzelm@29729: proof - wenzelm@58618: from \A x\ and \B y\ wenzelm@29733: show "C x y" sorry %noproof wenzelm@29729: qed wenzelm@29729: wenzelm@58618: text_raw \\end{minipage}\begin{minipage}{0.5\textwidth}\ wenzelm@29729: wenzelm@29729: theorem wenzelm@29729: obtains x and y wenzelm@29729: where "A x" and "B y" wenzelm@29729: proof - wenzelm@29733: have "A a" and "B b" sorry %noproof wenzelm@29729: then show thesis .. wenzelm@29729: qed wenzelm@29729: wenzelm@58618: text_raw \\end{minipage}\ wenzelm@29729: wenzelm@58618: text \ wenzelm@29729: \medskip\noindent Here local facts \isacharbackquoteopen@{text "A wenzelm@29729: x"}\isacharbackquoteclose\ and \isacharbackquoteopen@{text "B wenzelm@29729: y"}\isacharbackquoteclose\ are referenced immediately; there is no wenzelm@29729: need to decompose the logical rule structure again. In the second wenzelm@29729: proof the final ``@{command then}~@{command show}~@{text wenzelm@29729: thesis}~@{command ".."}'' involves the local rule case @{text "\x wenzelm@29729: y. A x \ B y \ thesis"} for the particular instance of terms @{text wenzelm@29729: "a"} and @{text "b"} produced in the body. wenzelm@58618: \ wenzelm@29729: wenzelm@29729: wenzelm@58618: subsection \Structured proof refinement \label{sec:framework-subproof}\ wenzelm@29729: wenzelm@58618: text \ wenzelm@29729: By breaking up the grammar for the Isar proof language, we may wenzelm@29729: understand a proof text as a linear sequence of individual proof wenzelm@29729: commands. These are interpreted as transitions of the Isar virtual wenzelm@29729: machine (Isar/VM), which operates on a block-structured wenzelm@29729: configuration in single steps. This allows users to write proof wenzelm@29729: texts in an incremental manner, and inspect intermediate wenzelm@29729: configurations for debugging. wenzelm@29729: wenzelm@29729: The basic idea is analogous to evaluating algebraic expressions on a wenzelm@29729: stack machine: @{text "(a + b) \ c"} then corresponds to a sequence wenzelm@29729: of single transitions for each symbol @{text "(, a, +, b, ), \, c"}. wenzelm@29729: In Isar the algebraic values are facts or goals, and the operations wenzelm@29729: are inferences. wenzelm@29729: wenzelm@29729: \medskip The Isar/VM state maintains a stack of nodes, each node wenzelm@29729: contains the local proof context, the linguistic mode, and a pending wenzelm@29729: goal (optional). The mode determines the type of transition that wenzelm@29729: may be performed next, it essentially alternates between forward and wenzelm@29738: backward reasoning, with an intermediate stage for chained facts wenzelm@29738: (see \figref{fig:isar-vm}). wenzelm@29738: wenzelm@29738: \begin{figure}[htb] wenzelm@29738: \begin{center} wenzelm@48958: \includegraphics[width=0.8\textwidth]{isar-vm} wenzelm@29738: \end{center} wenzelm@29738: \caption{Isar/VM modes}\label{fig:isar-vm} wenzelm@29738: \end{figure} wenzelm@29738: wenzelm@29738: For example, in @{text "state"} mode Isar acts like a mathematical wenzelm@29738: scratch-pad, accepting declarations like @{command fix}, @{command wenzelm@29738: assume}, and claims like @{command have}, @{command show}. A goal wenzelm@29738: statement changes the mode to @{text "prove"}, which means that we wenzelm@29738: may now refine the problem via @{command unfolding} or @{command wenzelm@29738: proof}. Then we are again in @{text "state"} mode of a proof body, wenzelm@29738: which may issue @{command show} statements to solve pending wenzelm@29738: sub-goals. A concluding @{command qed} will return to the original wenzelm@29738: @{text "state"} mode one level upwards. The subsequent Isar/VM wenzelm@29738: trace indicates block structure, linguistic mode, goal state, and wenzelm@29738: inferences: wenzelm@58618: \ wenzelm@29729: wenzelm@58618: text_raw \\begingroup\footnotesize\ wenzelm@40964: (*<*)notepad begin wenzelm@29729: (*>*) wenzelm@58999: text_raw \\begin{minipage}[t]{0.18\textwidth}\ wenzelm@29729: have "A \ B" wenzelm@29729: proof wenzelm@29729: assume A wenzelm@29729: show B wenzelm@29733: sorry %noproof wenzelm@29729: qed wenzelm@58999: text_raw \\end{minipage}\quad wenzelm@29735: \begin{minipage}[t]{0.06\textwidth} wenzelm@29729: @{text "begin"} \\ wenzelm@29729: \\ wenzelm@29729: \\ wenzelm@29729: @{text "begin"} \\ wenzelm@29729: @{text "end"} \\ wenzelm@29729: @{text "end"} \\ wenzelm@29729: \end{minipage} wenzelm@29729: \begin{minipage}[t]{0.08\textwidth} wenzelm@29729: @{text "prove"} \\ wenzelm@29729: @{text "state"} \\ wenzelm@29729: @{text "state"} \\ wenzelm@29729: @{text "prove"} \\ wenzelm@29729: @{text "state"} \\ wenzelm@29729: @{text "state"} \\ wenzelm@29735: \end{minipage}\begin{minipage}[t]{0.35\textwidth} wenzelm@29729: @{text "(A \ B) \ #(A \ B)"} \\ wenzelm@29729: @{text "(A \ B) \ #(A \ B)"} \\ wenzelm@29729: \\ wenzelm@29729: \\ wenzelm@29729: @{text "#(A \ B)"} \\ wenzelm@29729: @{text "A \ B"} \\ wenzelm@29735: \end{minipage}\begin{minipage}[t]{0.4\textwidth} wenzelm@29729: @{text "(init)"} \\ wenzelm@29735: @{text "(resolution impI)"} \\ wenzelm@29729: \\ wenzelm@29729: \\ wenzelm@29729: @{text "(refinement #A \ B)"} \\ wenzelm@29729: @{text "(finish)"} \\ wenzelm@58618: \end{minipage}\ wenzelm@29729: (*<*) wenzelm@40964: end wenzelm@29729: (*>*) wenzelm@58618: text_raw \\endgroup\ wenzelm@29729: wenzelm@58618: text \ wenzelm@29735: \noindent Here the @{inference refinement} inference from wenzelm@29729: \secref{sec:framework-resolution} mediates composition of Isar wenzelm@29729: sub-proofs nicely. Observe that this principle incorporates some wenzelm@29729: degree of freedom in proof composition. In particular, the proof wenzelm@29729: body allows parameters and assumptions to be re-ordered, or commuted wenzelm@29729: according to Hereditary Harrop Form. Moreover, context elements wenzelm@29729: that are not used in a sub-proof may be omitted altogether. For wenzelm@29729: example: wenzelm@58618: \ wenzelm@29729: wenzelm@58618: text_raw \\begin{minipage}{0.5\textwidth}\ wenzelm@29729: wenzelm@29729: (*<*) wenzelm@40964: notepad wenzelm@40964: begin wenzelm@29729: (*>*) wenzelm@29729: have "\x y. A x \ B y \ C x y" wenzelm@29729: proof - wenzelm@29729: fix x and y wenzelm@29729: assume "A x" and "B y" wenzelm@29733: show "C x y" sorry %noproof wenzelm@29729: qed wenzelm@29729: wenzelm@58999: text_raw \\end{minipage}\begin{minipage}{0.5\textwidth}\ wenzelm@29729: wenzelm@29729: (*<*) wenzelm@29729: next wenzelm@29729: (*>*) wenzelm@29729: have "\x y. A x \ B y \ C x y" wenzelm@29729: proof - wenzelm@29729: fix x assume "A x" wenzelm@29729: fix y assume "B y" wenzelm@29733: show "C x y" sorry %noproof wenzelm@29729: qed wenzelm@29729: wenzelm@58999: text_raw \\end{minipage}\\[3ex]\begin{minipage}{0.5\textwidth}\ wenzelm@29729: wenzelm@29729: (*<*) wenzelm@29729: next wenzelm@29729: (*>*) wenzelm@29729: have "\x y. A x \ B y \ C x y" wenzelm@29729: proof - wenzelm@29729: fix y assume "B y" wenzelm@29729: fix x assume "A x" wenzelm@29729: show "C x y" sorry wenzelm@29729: qed wenzelm@29729: wenzelm@58999: text_raw \\end{minipage}\begin{minipage}{0.5\textwidth}\ wenzelm@29729: (*<*) wenzelm@29729: next wenzelm@29729: (*>*) wenzelm@29729: have "\x y. A x \ B y \ C x y" wenzelm@29729: proof - wenzelm@29729: fix y assume "B y" wenzelm@29729: fix x wenzelm@29729: show "C x y" sorry wenzelm@29729: qed wenzelm@29729: (*<*) wenzelm@40964: end wenzelm@29729: (*>*) wenzelm@29729: wenzelm@58618: text_raw \\end{minipage}\ wenzelm@29729: wenzelm@58618: text \ wenzelm@29735: \medskip\noindent Such ``peephole optimizations'' of Isar texts are wenzelm@29729: practically important to improve readability, by rearranging wenzelm@29729: contexts elements according to the natural flow of reasoning in the wenzelm@29729: body, while still observing the overall scoping rules. wenzelm@29729: wenzelm@29729: \medskip This illustrates the basic idea of structured proof wenzelm@29729: processing in Isar. The main mechanisms are based on natural wenzelm@29729: deduction rule composition within the Pure framework. In wenzelm@29729: particular, there are no direct operations on goal states within the wenzelm@29729: proof body. Moreover, there is no hidden automated reasoning wenzelm@29729: involved, just plain unification. wenzelm@58618: \ wenzelm@29729: wenzelm@29729: wenzelm@58618: subsection \Calculational reasoning \label{sec:framework-calc}\ wenzelm@29729: wenzelm@58618: text \ wenzelm@29735: The existing Isar infrastructure is sufficiently flexible to support wenzelm@29729: calculational reasoning (chains of transitivity steps) as derived wenzelm@29729: concept. The generic proof elements introduced below depend on wenzelm@29732: rules declared as @{attribute trans} in the context. It is left to wenzelm@29729: the object-logic to provide a suitable rule collection for mixed wenzelm@29732: relations of @{text "="}, @{text "<"}, @{text "\"}, @{text "\"}, wenzelm@29732: @{text "\"} etc. Due to the flexibility of rule composition wenzelm@29729: (\secref{sec:framework-resolution}), substitution of equals by wenzelm@29729: equals is covered as well, even substitution of inequalities wenzelm@58552: involving monotonicity conditions; see also @{cite \\S6\ "Wenzel-PhD"} wenzelm@58552: and @{cite "Bauer-Wenzel:2001"}. wenzelm@29729: wenzelm@29729: The generic calculational mechanism is based on the observation that wenzelm@29735: rules such as @{text "trans:"}~@{prop "x = y \ y = z \ x = z"} wenzelm@29735: proceed from the premises towards the conclusion in a deterministic wenzelm@29735: fashion. Thus we may reason in forward mode, feeding intermediate wenzelm@29735: results into rules selected from the context. The course of wenzelm@29735: reasoning is organized by maintaining a secondary fact called wenzelm@29735: ``@{fact calculation}'', apart from the primary ``@{fact this}'' wenzelm@29735: already provided by the Isar primitives. In the definitions below, wenzelm@29735: @{attribute OF} refers to @{inference resolution} wenzelm@29735: (\secref{sec:framework-resolution}) with multiple rule arguments, wenzelm@29735: and @{text "trans"} represents to a suitable rule from the context: wenzelm@29729: wenzelm@29729: \begin{matharray}{rcl} wenzelm@29729: @{command "also"}@{text "\<^sub>0"} & \equiv & @{command "note"}~@{text "calculation = this"} \\ wenzelm@29729: @{command "also"}@{text "\<^sub>n\<^sub>+\<^sub>1"} & \equiv & @{command "note"}~@{text "calculation = trans [OF calculation this]"} \\[0.5ex] wenzelm@29729: @{command "finally"} & \equiv & @{command "also"}~@{command "from"}~@{text calculation} \\ wenzelm@29729: \end{matharray} wenzelm@29729: wenzelm@29729: \noindent The start of a calculation is determined implicitly in the wenzelm@29729: text: here @{command also} sets @{fact calculation} to the current wenzelm@29729: result; any subsequent occurrence will update @{fact calculation} by wenzelm@29729: combination with the next result and a transitivity rule. The wenzelm@29729: calculational sequence is concluded via @{command finally}, where wenzelm@29729: the final result is exposed for use in a concluding claim. wenzelm@29729: wenzelm@29729: Here is a canonical proof pattern, using @{command have} to wenzelm@29729: establish the intermediate results: wenzelm@58618: \ wenzelm@29729: wenzelm@29729: (*<*) wenzelm@40964: notepad wenzelm@40964: begin wenzelm@29729: (*>*) wenzelm@29729: have "a = b" sorry wenzelm@29729: also have "\ = c" sorry wenzelm@29729: also have "\ = d" sorry wenzelm@29729: finally have "a = d" . wenzelm@29729: (*<*) wenzelm@40964: end wenzelm@29729: (*>*) wenzelm@29729: wenzelm@58618: text \ wenzelm@29729: \noindent The term ``@{text "\"}'' above is a special abbreviation wenzelm@29729: provided by the Isabelle/Isar syntax layer: it statically refers to wenzelm@29729: the right-hand side argument of the previous statement given in the wenzelm@29729: text. Thus it happens to coincide with relevant sub-expressions in wenzelm@29729: the calculational chain, but the exact correspondence is dependent wenzelm@29729: on the transitivity rules being involved. wenzelm@29729: wenzelm@29729: \medskip Symmetry rules such as @{prop "x = y \ y = x"} are like wenzelm@29729: transitivities with only one premise. Isar maintains a separate wenzelm@29729: rule collection declared via the @{attribute sym} attribute, to be wenzelm@29729: used in fact expressions ``@{text "a [symmetric]"}'', or single-step wenzelm@29729: proofs ``@{command assume}~@{text "x = y"}~@{command then}~@{command wenzelm@29729: have}~@{text "y = x"}~@{command ".."}''. wenzelm@58618: \ wenzelm@29729: wenzelm@29742: end