wenzelm@30056: wenzelm@30056: header {* Example: First-Order Logic *} wenzelm@30056: wenzelm@30056: theory %visible First_Order_Logic wenzelm@43522: imports Base (* FIXME Pure!? *) wenzelm@30056: begin wenzelm@30056: wenzelm@30056: text {* wenzelm@30058: \noindent In order to commence a new object-logic within wenzelm@30058: Isabelle/Pure we introduce abstract syntactic categories @{text "i"} wenzelm@30058: for individuals and @{text "o"} for object-propositions. The latter wenzelm@30058: is embedded into the language of Pure propositions by means of a wenzelm@30058: separate judgment. wenzelm@30056: *} wenzelm@30056: wenzelm@30056: typedecl i wenzelm@30056: typedecl o wenzelm@30056: wenzelm@30056: judgment wenzelm@30056: Trueprop :: "o \ prop" ("_" 5) wenzelm@30056: wenzelm@30056: text {* wenzelm@30056: \noindent Note that the object-logic judgement is implicit in the wenzelm@30056: syntax: writing @{prop A} produces @{term "Trueprop A"} internally. wenzelm@30056: From the Pure perspective this means ``@{prop A} is derivable in the wenzelm@30056: object-logic''. wenzelm@30056: *} wenzelm@30056: wenzelm@30056: wenzelm@30056: subsection {* Equational reasoning \label{sec:framework-ex-equal} *} wenzelm@30056: wenzelm@30056: text {* wenzelm@30056: Equality is axiomatized as a binary predicate on individuals, with wenzelm@30056: reflexivity as introduction, and substitution as elimination wenzelm@30056: principle. Note that the latter is particularly convenient in a wenzelm@30056: framework like Isabelle, because syntactic congruences are wenzelm@30056: implicitly produced by unification of @{term "B x"} against wenzelm@30056: expressions containing occurrences of @{term x}. wenzelm@30056: *} wenzelm@30056: wenzelm@30056: axiomatization wenzelm@30056: equal :: "i \ i \ o" (infix "=" 50) wenzelm@30056: where wenzelm@30056: refl [intro]: "x = x" and wenzelm@30056: subst [elim]: "x = y \ B x \ B y" wenzelm@30056: wenzelm@30056: text {* wenzelm@30056: \noindent Substitution is very powerful, but also hard to control in wenzelm@30056: full generality. We derive some common symmetry~/ transitivity wenzelm@45988: schemes of @{term equal} as particular consequences. wenzelm@30056: *} wenzelm@30056: wenzelm@30056: theorem sym [sym]: wenzelm@30056: assumes "x = y" wenzelm@30056: shows "y = x" wenzelm@30056: proof - wenzelm@30056: have "x = x" .. wenzelm@30056: with `x = y` show "y = x" .. wenzelm@30056: qed wenzelm@30056: wenzelm@30056: theorem forw_subst [trans]: wenzelm@30056: assumes "y = x" and "B x" wenzelm@30056: shows "B y" wenzelm@30056: proof - wenzelm@30056: from `y = x` have "x = y" .. wenzelm@30056: from this and `B x` show "B y" .. wenzelm@30056: qed wenzelm@30056: wenzelm@30056: theorem back_subst [trans]: wenzelm@30056: assumes "B x" and "x = y" wenzelm@30056: shows "B y" wenzelm@30056: proof - wenzelm@30056: from `x = y` and `B x` wenzelm@30056: show "B y" .. wenzelm@30056: qed wenzelm@30056: wenzelm@30056: theorem trans [trans]: wenzelm@30056: assumes "x = y" and "y = z" wenzelm@30056: shows "x = z" wenzelm@30056: proof - wenzelm@30056: from `y = z` and `x = y` wenzelm@30056: show "x = z" .. wenzelm@30056: qed wenzelm@30056: wenzelm@30056: wenzelm@30056: subsection {* Basic group theory *} wenzelm@30056: wenzelm@30056: text {* wenzelm@30056: As an example for equational reasoning we consider some bits of wenzelm@30056: group theory. The subsequent locale definition postulates group wenzelm@30056: operations and axioms; we also derive some consequences of this wenzelm@30056: specification. wenzelm@30056: *} wenzelm@30056: wenzelm@30056: locale group = wenzelm@30056: fixes prod :: "i \ i \ i" (infix "\" 70) wenzelm@30056: and inv :: "i \ i" ("(_\)" [1000] 999) wenzelm@30056: and unit :: i ("1") wenzelm@30056: assumes assoc: "(x \ y) \ z = x \ (y \ z)" wenzelm@30056: and left_unit: "1 \ x = x" wenzelm@30056: and left_inv: "x\ \ x = 1" wenzelm@30056: begin wenzelm@30056: wenzelm@30056: theorem right_inv: "x \ x\ = 1" wenzelm@30056: proof - wenzelm@30056: have "x \ x\ = 1 \ (x \ x\)" by (rule left_unit [symmetric]) wenzelm@30056: also have "\ = (1 \ x) \ x\" by (rule assoc [symmetric]) wenzelm@30056: also have "1 = (x\)\ \ x\" by (rule left_inv [symmetric]) wenzelm@30056: also have "\ \ x = (x\)\ \ (x\ \ x)" by (rule assoc) wenzelm@30056: also have "x\ \ x = 1" by (rule left_inv) wenzelm@30056: also have "((x\)\ \ \) \ x\ = (x\)\ \ (1 \ x\)" by (rule assoc) wenzelm@30056: also have "1 \ x\ = x\" by (rule left_unit) wenzelm@30056: also have "(x\)\ \ \ = 1" by (rule left_inv) wenzelm@30056: finally show "x \ x\ = 1" . wenzelm@30056: qed wenzelm@30056: wenzelm@30056: theorem right_unit: "x \ 1 = x" wenzelm@30056: proof - wenzelm@30056: have "1 = x\ \ x" by (rule left_inv [symmetric]) wenzelm@30056: also have "x \ \ = (x \ x\) \ x" by (rule assoc [symmetric]) wenzelm@30056: also have "x \ x\ = 1" by (rule right_inv) wenzelm@30056: also have "\ \ x = x" by (rule left_unit) wenzelm@30056: finally show "x \ 1 = x" . wenzelm@30056: qed wenzelm@30056: wenzelm@30056: text {* wenzelm@30058: \noindent Reasoning from basic axioms is often tedious. Our proofs wenzelm@30058: work by producing various instances of the given rules (potentially wenzelm@30058: the symmetric form) using the pattern ``@{command have}~@{text wenzelm@30056: eq}~@{command "by"}~@{text "(rule r)"}'' and composing the chain of wenzelm@30056: results via @{command also}/@{command finally}. These steps may wenzelm@30056: involve any of the transitivity rules declared in wenzelm@30056: \secref{sec:framework-ex-equal}, namely @{thm trans} in combining wenzelm@30056: the first two results in @{thm right_inv} and in the final steps of wenzelm@30056: both proofs, @{thm forw_subst} in the first combination of @{thm wenzelm@30056: right_unit}, and @{thm back_subst} in all other calculational steps. wenzelm@30056: wenzelm@30056: Occasional substitutions in calculations are adequate, but should wenzelm@30056: not be over-emphasized. The other extreme is to compose a chain by wenzelm@30056: plain transitivity only, with replacements occurring always in wenzelm@30056: topmost position. For example: wenzelm@30056: *} wenzelm@30056: wenzelm@30056: (*<*) wenzelm@30056: theorem "\A. PROP A \ PROP A" wenzelm@30056: proof - wenzelm@30056: assume [symmetric, defn]: "\x y. (x \ y) \ Trueprop (x = y)" wenzelm@30056: (*>*) wenzelm@30056: have "x \ 1 = x \ (x\ \ x)" unfolding left_inv .. wenzelm@30056: also have "\ = (x \ x\) \ x" unfolding assoc .. wenzelm@30056: also have "\ = 1 \ x" unfolding right_inv .. wenzelm@30056: also have "\ = x" unfolding left_unit .. wenzelm@30056: finally have "x \ 1 = x" . wenzelm@30056: (*<*) wenzelm@30056: qed wenzelm@30056: (*>*) wenzelm@30056: wenzelm@30056: text {* wenzelm@30056: \noindent Here we have re-used the built-in mechanism for unfolding wenzelm@30056: definitions in order to normalize each equational problem. A more wenzelm@30056: realistic object-logic would include proper setup for the Simplifier wenzelm@30056: (\secref{sec:simplifier}), the main automated tool for equational wenzelm@30058: reasoning in Isabelle. Then ``@{command unfolding}~@{thm wenzelm@30056: left_inv}~@{command ".."}'' would become ``@{command "by"}~@{text wenzelm@30061: "(simp only: left_inv)"}'' etc. wenzelm@30056: *} wenzelm@30056: wenzelm@30056: end wenzelm@30056: wenzelm@30056: wenzelm@30060: subsection {* Propositional logic \label{sec:framework-ex-prop} *} wenzelm@30056: wenzelm@30056: text {* wenzelm@30056: We axiomatize basic connectives of propositional logic: implication, wenzelm@30056: disjunction, and conjunction. The associated rules are modeled wenzelm@30058: after Gentzen's system of Natural Deduction \cite{Gentzen:1935}. wenzelm@30056: *} wenzelm@30056: wenzelm@30056: axiomatization wenzelm@30056: imp :: "o \ o \ o" (infixr "\" 25) where wenzelm@30056: impI [intro]: "(A \ B) \ A \ B" and wenzelm@30056: impD [dest]: "(A \ B) \ A \ B" wenzelm@30056: wenzelm@30056: axiomatization wenzelm@30056: disj :: "o \ o \ o" (infixr "\" 30) where wenzelm@30056: disjI\<^isub>1 [intro]: "A \ A \ B" and wenzelm@30060: disjI\<^isub>2 [intro]: "B \ A \ B" and wenzelm@30060: disjE [elim]: "A \ B \ (A \ C) \ (B \ C) \ C" wenzelm@30056: wenzelm@30056: axiomatization wenzelm@30056: conj :: "o \ o \ o" (infixr "\" 35) where wenzelm@30056: conjI [intro]: "A \ B \ A \ B" and wenzelm@30060: conjD\<^isub>1: "A \ B \ A" and wenzelm@30060: conjD\<^isub>2: "A \ B \ B" wenzelm@30056: wenzelm@30056: text {* wenzelm@30056: \noindent The conjunctive destructions have the disadvantage that wenzelm@30056: decomposing @{prop "A \ B"} involves an immediate decision which wenzelm@30056: component should be projected. The more convenient simultaneous wenzelm@30056: elimination @{prop "A \ B \ (A \ B \ C) \ C"} can be derived as wenzelm@30056: follows: wenzelm@30056: *} wenzelm@30056: wenzelm@30056: theorem conjE [elim]: wenzelm@30056: assumes "A \ B" wenzelm@30056: obtains A and B wenzelm@30056: proof wenzelm@30060: from `A \ B` show A by (rule conjD\<^isub>1) wenzelm@30060: from `A \ B` show B by (rule conjD\<^isub>2) wenzelm@30056: qed wenzelm@30056: wenzelm@30056: text {* wenzelm@30056: \noindent Here is an example of swapping conjuncts with a single wenzelm@30056: intermediate elimination step: wenzelm@30056: *} wenzelm@30056: wenzelm@30056: (*<*) wenzelm@30056: lemma "\A. PROP A \ PROP A" wenzelm@30056: proof - wenzelm@30056: (*>*) wenzelm@30056: assume "A \ B" wenzelm@30056: then obtain B and A .. wenzelm@30056: then have "B \ A" .. wenzelm@30056: (*<*) wenzelm@30056: qed wenzelm@30056: (*>*) wenzelm@30056: wenzelm@30056: text {* wenzelm@30058: \noindent Note that the analogous elimination rule for disjunction wenzelm@30058: ``@{text "\ A \ B \ A \ B"}'' coincides with wenzelm@30058: the original axiomatization of @{thm disjE}. wenzelm@30056: wenzelm@30056: \medskip We continue propositional logic by introducing absurdity wenzelm@30056: with its characteristic elimination. Plain truth may then be wenzelm@30056: defined as a proposition that is trivially true. wenzelm@30056: *} wenzelm@30056: wenzelm@30056: axiomatization wenzelm@30056: false :: o ("\") where wenzelm@30056: falseE [elim]: "\ \ A" wenzelm@30056: wenzelm@30056: definition wenzelm@30056: true :: o ("\") where wenzelm@30056: "\ \ \ \ \" wenzelm@30056: wenzelm@30056: theorem trueI [intro]: \ wenzelm@30056: unfolding true_def .. wenzelm@30056: wenzelm@30056: text {* wenzelm@30058: \medskip\noindent Now negation represents an implication towards wenzelm@30058: absurdity: wenzelm@30056: *} wenzelm@30056: wenzelm@30056: definition wenzelm@30056: not :: "o \ o" ("\ _" [40] 40) where wenzelm@30056: "\ A \ A \ \" wenzelm@30056: wenzelm@30056: theorem notI [intro]: wenzelm@30056: assumes "A \ \" wenzelm@30056: shows "\ A" wenzelm@30056: unfolding not_def wenzelm@30056: proof wenzelm@30056: assume A wenzelm@30056: then show \ by (rule `A \ \`) wenzelm@30056: qed wenzelm@30056: wenzelm@30056: theorem notE [elim]: wenzelm@30056: assumes "\ A" and A wenzelm@30056: shows B wenzelm@30056: proof - wenzelm@30056: from `\ A` have "A \ \" unfolding not_def . wenzelm@30056: from `A \ \` and `A` have \ .. wenzelm@30056: then show B .. wenzelm@30056: qed wenzelm@30056: wenzelm@30056: wenzelm@30056: subsection {* Classical logic *} wenzelm@30056: wenzelm@30056: text {* wenzelm@30056: Subsequently we state the principle of classical contradiction as a wenzelm@30056: local assumption. Thus we refrain from forcing the object-logic wenzelm@30056: into the classical perspective. Within that context, we may derive wenzelm@30056: well-known consequences of the classical principle. wenzelm@30056: *} wenzelm@30056: wenzelm@30056: locale classical = wenzelm@30056: assumes classical: "(\ C \ C) \ C" wenzelm@30056: begin wenzelm@30056: wenzelm@30056: theorem double_negation: wenzelm@30056: assumes "\ \ C" wenzelm@30056: shows C wenzelm@30056: proof (rule classical) wenzelm@30056: assume "\ C" wenzelm@30056: with `\ \ C` show C .. wenzelm@30056: qed wenzelm@30056: wenzelm@30056: theorem tertium_non_datur: "C \ \ C" wenzelm@30056: proof (rule double_negation) wenzelm@30056: show "\ \ (C \ \ C)" wenzelm@30056: proof wenzelm@30056: assume "\ (C \ \ C)" wenzelm@30056: have "\ C" wenzelm@30056: proof wenzelm@30056: assume C then have "C \ \ C" .. wenzelm@30056: with `\ (C \ \ C)` show \ .. wenzelm@30056: qed wenzelm@30056: then have "C \ \ C" .. wenzelm@30056: with `\ (C \ \ C)` show \ .. wenzelm@30056: qed wenzelm@30056: qed wenzelm@30056: wenzelm@30056: text {* wenzelm@30061: \noindent These examples illustrate both classical reasoning and wenzelm@30061: non-trivial propositional proofs in general. All three rules wenzelm@30061: characterize classical logic independently, but the original rule is wenzelm@30061: already the most convenient to use, because it leaves the conclusion wenzelm@30061: unchanged. Note that @{prop "(\ C \ C) \ C"} fits again into our wenzelm@30061: format for eliminations, despite the additional twist that the wenzelm@30061: context refers to the main conclusion. So we may write @{thm wenzelm@30061: classical} as the Isar statement ``@{text "\ \ thesis"}''. wenzelm@30061: This also explains nicely how classical reasoning really works: wenzelm@30061: whatever the main @{text thesis} might be, we may always assume its wenzelm@30061: negation! wenzelm@30056: *} wenzelm@30056: wenzelm@30056: end wenzelm@30056: wenzelm@30056: wenzelm@30060: subsection {* Quantifiers \label{sec:framework-ex-quant} *} wenzelm@30056: wenzelm@30056: text {* wenzelm@30056: Representing quantifiers is easy, thanks to the higher-order nature wenzelm@30056: of the underlying framework. According to the well-known technique wenzelm@30056: introduced by Church \cite{church40}, quantifiers are operators on wenzelm@30056: predicates, which are syntactically represented as @{text "\"}-terms wenzelm@30058: of type @{typ "i \ o"}. Binder notation turns @{text "All (\x. B wenzelm@30058: x)"} into @{text "\x. B x"} etc. wenzelm@30056: *} wenzelm@30056: wenzelm@30056: axiomatization wenzelm@30056: All :: "(i \ o) \ o" (binder "\" 10) where wenzelm@30056: allI [intro]: "(\x. B x) \ \x. B x" and wenzelm@30056: allD [dest]: "(\x. B x) \ B a" wenzelm@30056: wenzelm@30056: axiomatization wenzelm@30056: Ex :: "(i \ o) \ o" (binder "\" 10) where wenzelm@30056: exI [intro]: "B a \ (\x. B x)" and wenzelm@30056: exE [elim]: "(\x. B x) \ (\x. B x \ C) \ C" wenzelm@30056: wenzelm@30056: text {* wenzelm@30061: \noindent The statement of @{thm exE} corresponds to ``@{text wenzelm@30061: "\ \x. B x \ x \ B x"}'' in Isar. In the wenzelm@30061: subsequent example we illustrate quantifier reasoning involving all wenzelm@30061: four rules: wenzelm@30056: *} wenzelm@30056: wenzelm@30056: theorem wenzelm@30056: assumes "\x. \y. R x y" wenzelm@30056: shows "\y. \x. R x y" wenzelm@30056: proof -- {* @{text "\"} introduction *} wenzelm@30056: obtain x where "\y. R x y" using `\x. \y. R x y` .. -- {* @{text "\"} elimination *} wenzelm@30056: fix y have "R x y" using `\y. R x y` .. -- {* @{text "\"} destruction *} wenzelm@30056: then show "\x. R x y" .. -- {* @{text "\"} introduction *} wenzelm@30056: qed wenzelm@30056: wenzelm@30060: wenzelm@30060: subsection {* Canonical reasoning patterns *} wenzelm@30060: wenzelm@30060: text {* wenzelm@30060: The main rules of first-order predicate logic from wenzelm@30060: \secref{sec:framework-ex-prop} and \secref{sec:framework-ex-quant} wenzelm@30060: can now be summarized as follows, using the native Isar statement wenzelm@30060: format of \secref{sec:framework-stmt}. wenzelm@30060: wenzelm@30060: \medskip wenzelm@30060: \begin{tabular}{l} wenzelm@30060: @{text "impI: \ A \ B \ A \ B"} \\ wenzelm@30060: @{text "impD: \ A \ B \ A \ B"} \\[1ex] wenzelm@30060: wenzelm@30060: @{text "disjI\<^isub>1: \ A \ A \ B"} \\ wenzelm@30060: @{text "disjI\<^isub>2: \ B \ A \ B"} \\ wenzelm@30060: @{text "disjE: \ A \ B \ A \ B"} \\[1ex] wenzelm@30060: wenzelm@30060: @{text "conjI: \ A \ B \ A \ B"} \\ wenzelm@30060: @{text "conjE: \ A \ B \ A \ B"} \\[1ex] wenzelm@30060: wenzelm@30060: @{text "falseE: \ \ \ A"} \\ wenzelm@30060: @{text "trueI: \ \"} \\[1ex] wenzelm@30060: wenzelm@30060: @{text "notI: \ A \ \ \ \ A"} \\ wenzelm@30060: @{text "notE: \ \ A \ A \ B"} \\[1ex] wenzelm@30060: wenzelm@30060: @{text "allI: \ \x. B x \ \x. B x"} \\ wenzelm@30060: @{text "allE: \ \x. B x \ B a"} \\[1ex] wenzelm@30060: wenzelm@30060: @{text "exI: \ B a \ \x. B x"} \\ wenzelm@30060: @{text "exE: \ \x. B x \ a \ B a"} wenzelm@30060: \end{tabular} wenzelm@30060: \medskip wenzelm@30060: wenzelm@30060: \noindent This essentially provides a declarative reading of Pure wenzelm@30060: rules as Isar reasoning patterns: the rule statements tells how a wenzelm@30060: canonical proof outline shall look like. Since the above rules have wenzelm@30061: already been declared as @{attribute (Pure) intro}, @{attribute wenzelm@30061: (Pure) elim}, @{attribute (Pure) dest} --- each according to its wenzelm@30061: particular shape --- we can immediately write Isar proof texts as wenzelm@30061: follows: wenzelm@30060: *} wenzelm@30060: wenzelm@30060: (*<*) wenzelm@30060: theorem "\A. PROP A \ PROP A" wenzelm@30060: proof - wenzelm@30060: (*>*) wenzelm@30060: wenzelm@30060: txt_raw {*\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*) wenzelm@30060: wenzelm@30060: have "A \ B" wenzelm@30060: proof wenzelm@30060: assume A wenzelm@30060: show B sorry %noproof wenzelm@30060: qed wenzelm@30060: wenzelm@30060: txt_raw {*\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*) wenzelm@30060: wenzelm@30060: have "A \ B" and A sorry %noproof wenzelm@30060: then have B .. wenzelm@30060: wenzelm@30060: txt_raw {*\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*) wenzelm@30060: wenzelm@30060: have A sorry %noproof wenzelm@30060: then have "A \ B" .. wenzelm@30060: wenzelm@30060: have B sorry %noproof wenzelm@30060: then have "A \ B" .. wenzelm@30060: wenzelm@30060: txt_raw {*\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*) wenzelm@30060: wenzelm@30060: have "A \ B" sorry %noproof wenzelm@30060: then have C wenzelm@30060: proof wenzelm@30060: assume A wenzelm@30060: then show C sorry %noproof wenzelm@30060: next wenzelm@30060: assume B wenzelm@30060: then show C sorry %noproof wenzelm@30060: qed wenzelm@30060: wenzelm@30060: txt_raw {*\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*) wenzelm@30060: wenzelm@30060: have A and B sorry %noproof wenzelm@30060: then have "A \ B" .. wenzelm@30060: wenzelm@30060: txt_raw {*\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*) wenzelm@30060: wenzelm@30060: have "A \ B" sorry %noproof wenzelm@30060: then obtain A and B .. wenzelm@30060: wenzelm@30060: txt_raw {*\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*) wenzelm@30060: wenzelm@30060: have "\" sorry %noproof wenzelm@30060: then have A .. wenzelm@30060: wenzelm@30060: txt_raw {*\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*) wenzelm@30060: wenzelm@30060: have "\" .. wenzelm@30060: wenzelm@30060: txt_raw {*\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*) wenzelm@30060: wenzelm@30060: have "\ A" wenzelm@30060: proof wenzelm@30060: assume A wenzelm@30060: then show "\" sorry %noproof wenzelm@30060: qed wenzelm@30060: wenzelm@30060: txt_raw {*\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*) wenzelm@30060: wenzelm@30060: have "\ A" and A sorry %noproof wenzelm@30060: then have B .. wenzelm@30060: wenzelm@30060: txt_raw {*\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*) wenzelm@30060: wenzelm@30060: have "\x. B x" wenzelm@30060: proof wenzelm@30060: fix x wenzelm@30060: show "B x" sorry %noproof wenzelm@30060: qed wenzelm@30060: wenzelm@30060: txt_raw {*\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*) wenzelm@30060: wenzelm@30060: have "\x. B x" sorry %noproof wenzelm@30060: then have "B a" .. wenzelm@30060: wenzelm@30060: txt_raw {*\end{minipage}\\[3ex]\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*) wenzelm@30060: wenzelm@30060: have "\x. B x" wenzelm@30060: proof wenzelm@30060: show "B a" sorry %noproof wenzelm@30060: qed wenzelm@30060: wenzelm@30060: txt_raw {*\end{minipage}\qquad\begin{minipage}[t]{0.4\textwidth}*}(*<*)next(*>*) wenzelm@30060: wenzelm@30060: have "\x. B x" sorry %noproof wenzelm@30060: then obtain a where "B a" .. wenzelm@30060: wenzelm@30060: txt_raw {*\end{minipage}*} wenzelm@30060: wenzelm@30060: (*<*) wenzelm@30060: qed wenzelm@30060: (*>*) wenzelm@30060: wenzelm@30060: text {* wenzelm@30060: \bigskip\noindent Of course, these proofs are merely examples. As wenzelm@30060: sketched in \secref{sec:framework-subproof}, there is a fair amount wenzelm@30060: of flexibility in expressing Pure deductions in Isar. Here the user wenzelm@30060: is asked to express himself adequately, aiming at proof texts of wenzelm@30060: literary quality. wenzelm@30060: *} wenzelm@30060: wenzelm@30056: end %visible