| author | wenzelm | 
| Fri, 03 Dec 2010 16:39:07 +0100 | |
| changeset 40895 | c3f68ea97495 | 
| parent 40153 | b6fe3b189725 | 
| child 40964 | 482a8334ee9e | 
| permissions | -rw-r--r-- | 
| 29755 | 1 | theory Proof | 
| 2 | imports Base | |
| 3 | begin | |
| 18537 | 4 | |
| 20451 | 5 | chapter {* Structured proofs *}
 | 
| 18537 | 6 | |
| 20474 | 7 | section {* Variables \label{sec:variables} *}
 | 
| 20026 | 8 | |
| 20470 | 9 | text {*
 | 
| 10 |   Any variable that is not explicitly bound by @{text "\<lambda>"}-abstraction
 | |
| 11 | is considered as ``free''. Logically, free variables act like | |
| 20474 | 12 |   outermost universal quantification at the sequent level: @{text
 | 
| 20470 | 13 | "A\<^isub>1(x), \<dots>, A\<^isub>n(x) \<turnstile> B(x)"} means that the result | 
| 14 |   holds \emph{for all} values of @{text "x"}.  Free variables for
 | |
| 15 |   terms (not types) can be fully internalized into the logic: @{text
 | |
| 20474 | 16 |   "\<turnstile> B(x)"} and @{text "\<turnstile> \<And>x. B(x)"} are interchangeable, provided
 | 
| 17 |   that @{text "x"} does not occur elsewhere in the context.
 | |
| 18 |   Inspecting @{text "\<turnstile> \<And>x. B(x)"} more closely, we see that inside the
 | |
| 20470 | 19 |   quantifier, @{text "x"} is essentially ``arbitrary, but fixed'',
 | 
| 20 | while from outside it appears as a place-holder for instantiation | |
| 20474 | 21 |   (thanks to @{text "\<And>"} elimination).
 | 
| 20470 | 22 | |
| 20474 | 23 | The Pure logic represents the idea of variables being either inside | 
| 24 | or outside the current scope by providing separate syntactic | |
| 20470 | 25 |   categories for \emph{fixed variables} (e.g.\ @{text "x"}) vs.\
 | 
| 26 |   \emph{schematic variables} (e.g.\ @{text "?x"}).  Incidently, a
 | |
| 20474 | 27 |   universal result @{text "\<turnstile> \<And>x. B(x)"} has the HHF normal form @{text
 | 
| 34930 | 28 | "\<turnstile> B(?x)"}, which represents its generality without requiring an | 
| 29 | explicit quantifier. The same principle works for type variables: | |
| 30 |   @{text "\<turnstile> B(?\<alpha>)"} represents the idea of ``@{text "\<turnstile> \<forall>\<alpha>. B(\<alpha>)"}''
 | |
| 31 | without demanding a truly polymorphic framework. | |
| 20470 | 32 | |
| 33 | \medskip Additional care is required to treat type variables in a | |
| 34 | way that facilitates type-inference. In principle, term variables | |
| 35 | depend on type variables, which means that type variables would have | |
| 36 | to be declared first. For example, a raw type-theoretic framework | |
| 37 | would demand the context to be constructed in stages as follows: | |
| 38 |   @{text "\<Gamma> = \<alpha>: type, x: \<alpha>, a: A(x\<^isub>\<alpha>)"}.
 | |
| 39 | ||
| 40 | We allow a slightly less formalistic mode of operation: term | |
| 41 |   variables @{text "x"} are fixed without specifying a type yet
 | |
| 42 |   (essentially \emph{all} potential occurrences of some instance
 | |
| 20474 | 43 |   @{text "x\<^isub>\<tau>"} are fixed); the first occurrence of @{text "x"}
 | 
| 44 | within a specific term assigns its most general type, which is then | |
| 45 | maintained consistently in the context. The above example becomes | |
| 46 |   @{text "\<Gamma> = x: term, \<alpha>: type, A(x\<^isub>\<alpha>)"}, where type @{text
 | |
| 47 |   "\<alpha>"} is fixed \emph{after} term @{text "x"}, and the constraint
 | |
| 48 |   @{text "x :: \<alpha>"} is an implicit consequence of the occurrence of
 | |
| 49 |   @{text "x\<^isub>\<alpha>"} in the subsequent proposition.
 | |
| 20470 | 50 | |
| 51 | This twist of dependencies is also accommodated by the reverse | |
| 52 | operation of exporting results from a context: a type variable | |
| 53 |   @{text "\<alpha>"} is considered fixed as long as it occurs in some fixed
 | |
| 54 |   term variable of the context.  For example, exporting @{text "x:
 | |
| 39841 | 55 |   term, \<alpha>: type \<turnstile> x\<^isub>\<alpha> \<equiv> x\<^isub>\<alpha>"} produces in the first step @{text "x: term
 | 
| 56 |   \<turnstile> x\<^isub>\<alpha> \<equiv> x\<^isub>\<alpha>"} for fixed @{text "\<alpha>"}, and only in the second step
 | |
| 57 |   @{text "\<turnstile> ?x\<^isub>?\<^isub>\<alpha> \<equiv> ?x\<^isub>?\<^isub>\<alpha>"} for schematic @{text "?x"} and @{text "?\<alpha>"}.
 | |
| 58 | The following Isar source text illustrates this scenario. | |
| 59 | *} | |
| 20470 | 60 | |
| 39841 | 61 | example_proof | 
| 62 |   {
 | |
| 63 |     fix x  -- {* all potential occurrences of some @{text "x::\<tau>"} are fixed *}
 | |
| 64 |     {
 | |
| 65 |       have "x::'a \<equiv> x"  -- {* implicit type assigment by concrete occurrence *}
 | |
| 66 | by (rule reflexive) | |
| 67 | } | |
| 68 |     thm this  -- {* result still with fixed type @{text "'a"} *}
 | |
| 69 | } | |
| 70 |   thm this  -- {* fully general result for arbitrary @{text "?x::?'a"} *}
 | |
| 71 | qed | |
| 72 | ||
| 39861 
b8d89db3e238
use continental paragraph style, which works better with mixture of (in)formal text;
 wenzelm parents: 
39853diff
changeset | 73 | text {* The Isabelle/Isar proof context manages the details of term
 | 
| 
b8d89db3e238
use continental paragraph style, which works better with mixture of (in)formal text;
 wenzelm parents: 
39853diff
changeset | 74 | vs.\ type variables, with high-level principles for moving the | 
| 20474 | 75 | frontier between fixed and schematic variables. | 
| 76 | ||
| 77 |   The @{text "add_fixes"} operation explictly declares fixed
 | |
| 78 |   variables; the @{text "declare_term"} operation absorbs a term into
 | |
| 79 | a context by fixing new type variables and adding syntactic | |
| 80 | constraints. | |
| 20470 | 81 | |
| 20474 | 82 |   The @{text "export"} operation is able to perform the main work of
 | 
| 83 | generalizing term and type variables as sketched above, assuming | |
| 84 | that fixing variables and terms have been declared properly. | |
| 85 | ||
| 86 |   There @{text "import"} operation makes a generalized fact a genuine
 | |
| 87 | part of the context, by inventing fixed variables for the schematic | |
| 88 |   ones.  The effect can be reversed by using @{text "export"} later,
 | |
| 89 | potentially with an extended context; the result is equivalent to | |
| 90 | the original modulo renaming of schematic variables. | |
| 20470 | 91 | |
| 92 |   The @{text "focus"} operation provides a variant of @{text "import"}
 | |
| 93 |   for nested propositions (with explicit quantification): @{text
 | |
| 20474 | 94 | "\<And>x\<^isub>1 \<dots> x\<^isub>n. B(x\<^isub>1, \<dots>, x\<^isub>n)"} is | 
| 95 |   decomposed by inventing fixed variables @{text "x\<^isub>1, \<dots>,
 | |
| 96 | x\<^isub>n"} for the body. | |
| 20470 | 97 | *} | 
| 20064 | 98 | |
| 20026 | 99 | text %mlref {*
 | 
| 100 |   \begin{mldecls}
 | |
| 20474 | 101 |   @{index_ML Variable.add_fixes: "
 | 
| 102 | string list -> Proof.context -> string list * Proof.context"} \\ | |
| 20797 
c1f0bc7e7d80
renamed Variable.invent_fixes to Variable.variant_fixes;
 wenzelm parents: 
20547diff
changeset | 103 |   @{index_ML Variable.variant_fixes: "
 | 
| 20474 | 104 | string list -> Proof.context -> string list * Proof.context"} \\ | 
| 20026 | 105 |   @{index_ML Variable.declare_term: "term -> Proof.context -> Proof.context"} \\
 | 
| 20470 | 106 |   @{index_ML Variable.declare_constraints: "term -> Proof.context -> Proof.context"} \\
 | 
| 107 |   @{index_ML Variable.export: "Proof.context -> Proof.context -> thm list -> thm list"} \\
 | |
| 108 |   @{index_ML Variable.polymorphic: "Proof.context -> term list -> term list"} \\
 | |
| 31794 
71af1fd6a5e4
renamed Variable.import_thms to Variable.import (back again cf. ed7aa5a350ef -- Alice is no longer supported);
 wenzelm parents: 
30272diff
changeset | 109 |   @{index_ML Variable.import: "bool -> thm list -> Proof.context ->
 | 
| 32302 | 110 | (((ctyp * ctyp) list * (cterm * cterm) list) * thm list) * Proof.context"} \\ | 
| 34930 | 111 |   @{index_ML Variable.focus: "cterm -> Proof.context ->
 | 
| 112 | ((string * cterm) list * cterm) * Proof.context"} \\ | |
| 20026 | 113 |   \end{mldecls}
 | 
| 114 | ||
| 115 |   \begin{description}
 | |
| 116 | ||
| 20064 | 117 |   \item @{ML Variable.add_fixes}~@{text "xs ctxt"} fixes term
 | 
| 20470 | 118 |   variables @{text "xs"}, returning the resulting internal names.  By
 | 
| 119 | default, the internal representation coincides with the external | |
| 20474 | 120 | one, which also means that the given variables must not be fixed | 
| 121 | already. There is a different policy within a local proof body: the | |
| 122 | given names are just hints for newly invented Skolem variables. | |
| 20064 | 123 | |
| 20797 
c1f0bc7e7d80
renamed Variable.invent_fixes to Variable.variant_fixes;
 wenzelm parents: 
20547diff
changeset | 124 |   \item @{ML Variable.variant_fixes} is similar to @{ML
 | 
| 20470 | 125 | Variable.add_fixes}, but always produces fresh variants of the given | 
| 20474 | 126 | names. | 
| 20470 | 127 | |
| 128 |   \item @{ML Variable.declare_term}~@{text "t ctxt"} declares term
 | |
| 129 |   @{text "t"} to belong to the context.  This automatically fixes new
 | |
| 130 | type variables, but not term variables. Syntactic constraints for | |
| 20474 | 131 | type and term variables are declared uniformly, though. | 
| 20470 | 132 | |
| 20474 | 133 |   \item @{ML Variable.declare_constraints}~@{text "t ctxt"} declares
 | 
| 134 |   syntactic constraints from term @{text "t"}, without making it part
 | |
| 135 | of the context yet. | |
| 20026 | 136 | |
| 20470 | 137 |   \item @{ML Variable.export}~@{text "inner outer thms"} generalizes
 | 
| 138 |   fixed type and term variables in @{text "thms"} according to the
 | |
| 139 |   difference of the @{text "inner"} and @{text "outer"} context,
 | |
| 140 | following the principles sketched above. | |
| 141 | ||
| 142 |   \item @{ML Variable.polymorphic}~@{text "ctxt ts"} generalizes type
 | |
| 143 |   variables in @{text "ts"} as far as possible, even those occurring
 | |
| 144 | in fixed term variables. The default policy of type-inference is to | |
| 20474 | 145 | fix newly introduced type variables, which is essentially reversed | 
| 146 |   with @{ML Variable.polymorphic}: here the given terms are detached
 | |
| 147 | from the context as far as possible. | |
| 20470 | 148 | |
| 31794 
71af1fd6a5e4
renamed Variable.import_thms to Variable.import (back again cf. ed7aa5a350ef -- Alice is no longer supported);
 wenzelm parents: 
30272diff
changeset | 149 |   \item @{ML Variable.import}~@{text "open thms ctxt"} invents fixed
 | 
| 20474 | 150 |   type and term variables for the schematic ones occurring in @{text
 | 
| 151 |   "thms"}.  The @{text "open"} flag indicates whether the fixed names
 | |
| 152 | should be accessible to the user, otherwise newly introduced names | |
| 153 |   are marked as ``internal'' (\secref{sec:names}).
 | |
| 20026 | 154 | |
| 20474 | 155 |   \item @{ML Variable.focus}~@{text B} decomposes the outermost @{text
 | 
| 156 |   "\<And>"} prefix of proposition @{text "B"}.
 | |
| 20026 | 157 | |
| 158 |   \end{description}
 | |
| 159 | *} | |
| 160 | ||
| 39846 | 161 | text %mlex {* The following example shows how to work with fixed term
 | 
| 162 | and type parameters and with type-inference. *} | |
| 34932 | 163 | |
| 164 | ML {*
 | |
| 165 | (*static compile-time context -- for testing only*) | |
| 166 |   val ctxt0 = @{context};
 | |
| 167 | ||
| 168 | (*locally fixed parameters -- no type assignment yet*) | |
| 169 | val ([x, y], ctxt1) = ctxt0 |> Variable.add_fixes ["x", "y"]; | |
| 170 | ||
| 171 | (*t1: most general fixed type; t1': most general arbitrary type*) | |
| 172 | val t1 = Syntax.read_term ctxt1 "x"; | |
| 173 | val t1' = singleton (Variable.polymorphic ctxt1) t1; | |
| 174 | ||
| 175 | (*term u enforces specific type assignment*) | |
| 39846 | 176 | val u = Syntax.read_term ctxt1 "(x::nat) \<equiv> y"; | 
| 34932 | 177 | |
| 178 | (*official declaration of u -- propagates constraints etc.*) | |
| 179 | val ctxt2 = ctxt1 |> Variable.declare_term u; | |
| 39846 | 180 | val t2 = Syntax.read_term ctxt2 "x"; (*x::nat is enforced*) | 
| 34932 | 181 | *} | 
| 182 | ||
| 40126 | 183 | text {* In the above example, the starting context is derived from the
 | 
| 184 | toplevel theory, which means that fixed variables are internalized | |
| 40153 | 185 |   literally: @{text "x"} is mapped again to @{text "x"}, and
 | 
| 40126 | 186 | attempting to fix it again in the subsequent context is an error. | 
| 187 | Alternatively, fixed parameters can be renamed explicitly as | |
| 188 | follows: *} | |
| 34932 | 189 | |
| 190 | ML {*
 | |
| 191 |   val ctxt0 = @{context};
 | |
| 192 | val ([x1, x2, x3], ctxt1) = | |
| 193 | ctxt0 |> Variable.variant_fixes ["x", "x", "x"]; | |
| 194 | *} | |
| 195 | ||
| 39861 
b8d89db3e238
use continental paragraph style, which works better with mixture of (in)formal text;
 wenzelm parents: 
39853diff
changeset | 196 | text {* The following ML code can now work with the invented names of
 | 
| 40153 | 197 |   @{text x1}, @{text x2}, @{text x3}, without depending on
 | 
| 39861 
b8d89db3e238
use continental paragraph style, which works better with mixture of (in)formal text;
 wenzelm parents: 
39853diff
changeset | 198 | the details on the system policy for introducing these variants. | 
| 
b8d89db3e238
use continental paragraph style, which works better with mixture of (in)formal text;
 wenzelm parents: 
39853diff
changeset | 199 | Recall that within a proof body the system always invents fresh | 
| 
b8d89db3e238
use continental paragraph style, which works better with mixture of (in)formal text;
 wenzelm parents: 
39853diff
changeset | 200 | ``skolem constants'', e.g.\ as follows: *} | 
| 34932 | 201 | |
| 39821 | 202 | example_proof | 
| 34932 | 203 |   ML_prf %"ML" {*
 | 
| 204 |     val ctxt0 = @{context};
 | |
| 205 | ||
| 206 | val ([x1], ctxt1) = ctxt0 |> Variable.add_fixes ["x"]; | |
| 207 | val ([x2], ctxt2) = ctxt1 |> Variable.add_fixes ["x"]; | |
| 208 | val ([x3], ctxt3) = ctxt2 |> Variable.add_fixes ["x"]; | |
| 209 | ||
| 210 | val ([y1, y2], ctxt4) = | |
| 211 | ctxt3 |> Variable.variant_fixes ["y", "y"]; | |
| 212 | *} | |
| 213 | oops | |
| 214 | ||
| 39861 
b8d89db3e238
use continental paragraph style, which works better with mixture of (in)formal text;
 wenzelm parents: 
39853diff
changeset | 215 | text {* In this situation @{ML Variable.add_fixes} and @{ML
 | 
| 34932 | 216 | Variable.variant_fixes} are very similar, but identical name | 
| 217 | proposals given in a row are only accepted by the second version. | |
| 39861 
b8d89db3e238
use continental paragraph style, which works better with mixture of (in)formal text;
 wenzelm parents: 
39853diff
changeset | 218 | *} | 
| 34932 | 219 | |
| 18537 | 220 | |
| 20474 | 221 | section {* Assumptions \label{sec:assumptions} *}
 | 
| 20451 | 222 | |
| 20458 | 223 | text {*
 | 
| 224 |   An \emph{assumption} is a proposition that it is postulated in the
 | |
| 225 | current context. Local conclusions may use assumptions as | |
| 226 | additional facts, but this imposes implicit hypotheses that weaken | |
| 227 | the overall statement. | |
| 228 | ||
| 20474 | 229 | Assumptions are restricted to fixed non-schematic statements, i.e.\ | 
| 230 | all generality needs to be expressed by explicit quantifiers. | |
| 20458 | 231 | Nevertheless, the result will be in HHF normal form with outermost | 
| 232 |   quantifiers stripped.  For example, by assuming @{text "\<And>x :: \<alpha>. P
 | |
| 20474 | 233 |   x"} we get @{text "\<And>x :: \<alpha>. P x \<turnstile> P ?x"} for schematic @{text "?x"}
 | 
| 234 |   of fixed type @{text "\<alpha>"}.  Local derivations accumulate more and
 | |
| 235 |   more explicit references to hypotheses: @{text "A\<^isub>1, \<dots>,
 | |
| 20458 | 236 |   A\<^isub>n \<turnstile> B"} where @{text "A\<^isub>1, \<dots>, A\<^isub>n"} needs to
 | 
| 237 | be covered by the assumptions of the current context. | |
| 238 | ||
| 20459 | 239 |   \medskip The @{text "add_assms"} operation augments the context by
 | 
| 240 |   local assumptions, which are parameterized by an arbitrary @{text
 | |
| 241 | "export"} rule (see below). | |
| 20458 | 242 | |
| 243 |   The @{text "export"} operation moves facts from a (larger) inner
 | |
| 244 | context into a (smaller) outer context, by discharging the | |
| 245 | difference of the assumptions as specified by the associated export | |
| 246 | rules. Note that the discharged portion is determined by the | |
| 34930 | 247 | difference of contexts, not the facts being exported! There is a | 
| 20459 | 248 | separate flag to indicate a goal context, where the result is meant | 
| 29760 | 249 | to refine an enclosing sub-goal of a structured proof state. | 
| 20458 | 250 | |
| 251 | \medskip The most basic export rule discharges assumptions directly | |
| 252 |   by means of the @{text "\<Longrightarrow>"} introduction rule:
 | |
| 253 | \[ | |
| 34930 | 254 |   \infer[(@{text "\<Longrightarrow>\<dash>intro"})]{@{text "\<Gamma> - A \<turnstile> A \<Longrightarrow> B"}}{@{text "\<Gamma> \<turnstile> B"}}
 | 
| 20458 | 255 | \] | 
| 256 | ||
| 257 | The variant for goal refinements marks the newly introduced | |
| 20474 | 258 | premises, which causes the canonical Isar goal refinement scheme to | 
| 20458 | 259 | enforce unification with local premises within the goal: | 
| 260 | \[ | |
| 34930 | 261 |   \infer[(@{text "#\<Longrightarrow>\<dash>intro"})]{@{text "\<Gamma> - A \<turnstile> #A \<Longrightarrow> B"}}{@{text "\<Gamma> \<turnstile> B"}}
 | 
| 20458 | 262 | \] | 
| 263 | ||
| 20474 | 264 | \medskip Alternative versions of assumptions may perform arbitrary | 
| 265 | transformations on export, as long as the corresponding portion of | |
| 20459 | 266 | hypotheses is removed from the given facts. For example, a local | 
| 267 |   definition works by fixing @{text "x"} and assuming @{text "x \<equiv> t"},
 | |
| 268 | with the following export rule to reverse the effect: | |
| 20458 | 269 | \[ | 
| 34930 | 270 |   \infer[(@{text "\<equiv>\<dash>expand"})]{@{text "\<Gamma> - (x \<equiv> t) \<turnstile> B t"}}{@{text "\<Gamma> \<turnstile> B x"}}
 | 
| 20458 | 271 | \] | 
| 20474 | 272 |   This works, because the assumption @{text "x \<equiv> t"} was introduced in
 | 
| 273 |   a context with @{text "x"} being fresh, so @{text "x"} does not
 | |
| 274 |   occur in @{text "\<Gamma>"} here.
 | |
| 20458 | 275 | *} | 
| 276 | ||
| 277 | text %mlref {*
 | |
| 278 |   \begin{mldecls}
 | |
| 279 |   @{index_ML_type Assumption.export} \\
 | |
| 280 |   @{index_ML Assumption.assume: "cterm -> thm"} \\
 | |
| 281 |   @{index_ML Assumption.add_assms:
 | |
| 20459 | 282 | "Assumption.export -> | 
| 283 | cterm list -> Proof.context -> thm list * Proof.context"} \\ | |
| 284 |   @{index_ML Assumption.add_assumes: "
 | |
| 285 | cterm list -> Proof.context -> thm list * Proof.context"} \\ | |
| 20458 | 286 |   @{index_ML Assumption.export: "bool -> Proof.context -> Proof.context -> thm -> thm"} \\
 | 
| 287 |   \end{mldecls}
 | |
| 288 | ||
| 289 |   \begin{description}
 | |
| 290 | ||
| 39864 | 291 |   \item Type @{ML_type Assumption.export} represents arbitrary export
 | 
| 292 |   rules, which is any function of type @{ML_type "bool -> cterm list
 | |
| 293 |   -> thm -> thm"}, where the @{ML_type "bool"} indicates goal mode,
 | |
| 294 |   and the @{ML_type "cterm list"} the collection of assumptions to be
 | |
| 295 | discharged simultaneously. | |
| 20458 | 296 | |
| 20459 | 297 |   \item @{ML Assumption.assume}~@{text "A"} turns proposition @{text
 | 
| 34930 | 298 |   "A"} into a primitive assumption @{text "A \<turnstile> A'"}, where the
 | 
| 299 |   conclusion @{text "A'"} is in HHF normal form.
 | |
| 20458 | 300 | |
| 20474 | 301 |   \item @{ML Assumption.add_assms}~@{text "r As"} augments the context
 | 
| 302 |   by assumptions @{text "As"} with export rule @{text "r"}.  The
 | |
| 303 | resulting facts are hypothetical theorems as produced by the raw | |
| 304 |   @{ML Assumption.assume}.
 | |
| 20459 | 305 | |
| 306 |   \item @{ML Assumption.add_assumes}~@{text "As"} is a special case of
 | |
| 307 |   @{ML Assumption.add_assms} where the export rule performs @{text
 | |
| 34930 | 308 |   "\<Longrightarrow>\<dash>intro"} or @{text "#\<Longrightarrow>\<dash>intro"}, depending on goal
 | 
| 309 | mode. | |
| 20458 | 310 | |
| 20474 | 311 |   \item @{ML Assumption.export}~@{text "is_goal inner outer thm"}
 | 
| 312 |   exports result @{text "thm"} from the the @{text "inner"} context
 | |
| 20459 | 313 |   back into the @{text "outer"} one; @{text "is_goal = true"} means
 | 
| 314 | this is a goal context. The result is in HHF normal form. Note | |
| 315 |   that @{ML "ProofContext.export"} combines @{ML "Variable.export"}
 | |
| 316 |   and @{ML "Assumption.export"} in the canonical way.
 | |
| 20458 | 317 | |
| 318 |   \end{description}
 | |
| 319 | *} | |
| 20451 | 320 | |
| 34932 | 321 | text %mlex {* The following example demonstrates how rules can be
 | 
| 322 | derived by building up a context of assumptions first, and exporting | |
| 323 |   some local fact afterwards.  We refer to @{theory Pure} equality
 | |
| 324 | here for testing purposes. | |
| 325 | *} | |
| 326 | ||
| 327 | ML {*
 | |
| 328 | (*static compile-time context -- for testing only*) | |
| 329 |   val ctxt0 = @{context};
 | |
| 330 | ||
| 331 | val ([eq], ctxt1) = | |
| 332 |     ctxt0 |> Assumption.add_assumes [@{cprop "x \<equiv> y"}];
 | |
| 333 | val eq' = Thm.symmetric eq; | |
| 334 | ||
| 335 | (*back to original context -- discharges assumption*) | |
| 336 | val r = Assumption.export false ctxt1 ctxt0 eq'; | |
| 337 | *} | |
| 338 | ||
| 39861 
b8d89db3e238
use continental paragraph style, which works better with mixture of (in)formal text;
 wenzelm parents: 
39853diff
changeset | 339 | text {* Note that the variables of the resulting rule are not
 | 
| 
b8d89db3e238
use continental paragraph style, which works better with mixture of (in)formal text;
 wenzelm parents: 
39853diff
changeset | 340 | generalized. This would have required to fix them properly in the | 
| 
b8d89db3e238
use continental paragraph style, which works better with mixture of (in)formal text;
 wenzelm parents: 
39853diff
changeset | 341 |   context beforehand, and export wrt.\ variables afterwards (cf.\ @{ML
 | 
| 
b8d89db3e238
use continental paragraph style, which works better with mixture of (in)formal text;
 wenzelm parents: 
39853diff
changeset | 342 |   Variable.export} or the combined @{ML "ProofContext.export"}).  *}
 | 
| 34932 | 343 | |
| 20451 | 344 | |
| 34930 | 345 | section {* Structured goals and results \label{sec:struct-goals} *}
 | 
| 20451 | 346 | |
| 18537 | 347 | text {*
 | 
| 20472 | 348 | Local results are established by monotonic reasoning from facts | 
| 20474 | 349 | within a context. This allows common combinations of theorems, | 
| 350 |   e.g.\ via @{text "\<And>/\<Longrightarrow>"} elimination, resolution rules, or equational
 | |
| 351 |   reasoning, see \secref{sec:thms}.  Unaccounted context manipulations
 | |
| 352 |   should be avoided, notably raw @{text "\<And>/\<Longrightarrow>"} introduction or ad-hoc
 | |
| 20472 | 353 | references to free variables or assumptions not present in the proof | 
| 354 | context. | |
| 18537 | 355 | |
| 20491 | 356 |   \medskip The @{text "SUBPROOF"} combinator allows to structure a
 | 
| 357 | tactical proof recursively by decomposing a selected sub-goal: | |
| 358 |   @{text "(\<And>x. A(x) \<Longrightarrow> B(x)) \<Longrightarrow> \<dots>"} is turned into @{text "B(x) \<Longrightarrow> \<dots>"}
 | |
| 359 |   after fixing @{text "x"} and assuming @{text "A(x)"}.  This means
 | |
| 360 | the tactic needs to solve the conclusion, but may use the premise as | |
| 361 | a local fact, for locally fixed variables. | |
| 18537 | 362 | |
| 34930 | 363 |   The family of @{text "FOCUS"} combinators is similar to @{text
 | 
| 364 | "SUBPROOF"}, but allows to retain schematic variables and pending | |
| 365 | subgoals in the resulting goal state. | |
| 366 | ||
| 20491 | 367 |   The @{text "prove"} operation provides an interface for structured
 | 
| 368 | backwards reasoning under program control, with some explicit sanity | |
| 369 | checks of the result. The goal context can be augmented by | |
| 370 |   additional fixed variables (cf.\ \secref{sec:variables}) and
 | |
| 371 |   assumptions (cf.\ \secref{sec:assumptions}), which will be available
 | |
| 372 | as local facts during the proof and discharged into implications in | |
| 373 | the result. Type and term variables are generalized as usual, | |
| 374 | according to the context. | |
| 18537 | 375 | |
| 20491 | 376 |   The @{text "obtain"} operation produces results by eliminating
 | 
| 377 | existing facts by means of a given tactic. This acts like a dual | |
| 378 | conclusion: the proof demonstrates that the context may be augmented | |
| 34930 | 379 | by parameters and assumptions, without affecting any conclusions | 
| 380 | that do not mention these parameters. See also | |
| 39851 | 381 |   \cite{isabelle-isar-ref} for the user-level @{command obtain} and
 | 
| 382 |   @{command guess} elements.  Final results, which may not refer to
 | |
| 20491 | 383 | the parameters in the conclusion, need to exported explicitly into | 
| 39851 | 384 | the original context. *} | 
| 18537 | 385 | |
| 20472 | 386 | text %mlref {*
 | 
| 387 |   \begin{mldecls}
 | |
| 39821 | 388 |   @{index_ML SUBPROOF: "(Subgoal.focus -> tactic) ->
 | 
| 389 | Proof.context -> int -> tactic"} \\ | |
| 390 |   @{index_ML Subgoal.FOCUS: "(Subgoal.focus -> tactic) ->
 | |
| 391 | Proof.context -> int -> tactic"} \\ | |
| 392 |   @{index_ML Subgoal.FOCUS_PREMS: "(Subgoal.focus -> tactic) ->
 | |
| 393 | Proof.context -> int -> tactic"} \\ | |
| 394 |   @{index_ML Subgoal.FOCUS_PARAMS: "(Subgoal.focus -> tactic) ->
 | |
| 395 | Proof.context -> int -> tactic"} \\ | |
| 39853 | 396 |   @{index_ML Subgoal.focus: "Proof.context -> int -> thm -> Subgoal.focus * thm"} \\
 | 
| 397 |   @{index_ML Subgoal.focus_prems: "Proof.context -> int -> thm -> Subgoal.focus * thm"} \\
 | |
| 398 |   @{index_ML Subgoal.focus_params: "Proof.context -> int -> thm -> Subgoal.focus * thm"} \\
 | |
| 20547 | 399 |   \end{mldecls}
 | 
| 34930 | 400 | |
| 20547 | 401 |   \begin{mldecls}
 | 
| 20472 | 402 |   @{index_ML Goal.prove: "Proof.context -> string list -> term list -> term ->
 | 
| 403 |   ({prems: thm list, context: Proof.context} -> tactic) -> thm"} \\
 | |
| 404 |   @{index_ML Goal.prove_multi: "Proof.context -> string list -> term list -> term list ->
 | |
| 405 |   ({prems: thm list, context: Proof.context} -> tactic) -> thm list"} \\
 | |
| 20547 | 406 |   \end{mldecls}
 | 
| 407 |   \begin{mldecls}
 | |
| 39821 | 408 |   @{index_ML Obtain.result: "(Proof.context -> tactic) -> thm list ->
 | 
| 409 | Proof.context -> ((string * cterm) list * thm list) * Proof.context"} \\ | |
| 20472 | 410 |   \end{mldecls}
 | 
| 18537 | 411 | |
| 20472 | 412 |   \begin{description}
 | 
| 18537 | 413 | |
| 29761 | 414 |   \item @{ML SUBPROOF}~@{text "tac ctxt i"} decomposes the structure
 | 
| 415 | of the specified sub-goal, producing an extended context and a | |
| 416 | reduced goal, which needs to be solved by the given tactic. All | |
| 417 | schematic parameters of the goal are imported into the context as | |
| 418 | fixed ones, which may not be instantiated in the sub-proof. | |
| 20491 | 419 | |
| 34930 | 420 |   \item @{ML Subgoal.FOCUS}, @{ML Subgoal.FOCUS_PREMS}, and @{ML
 | 
| 421 |   Subgoal.FOCUS_PARAMS} are similar to @{ML SUBPROOF}, but are
 | |
| 422 | slightly more flexible: only the specified parts of the subgoal are | |
| 423 | imported into the context, and the body tactic may introduce new | |
| 424 | subgoals and schematic variables. | |
| 425 | ||
| 39853 | 426 |   \item @{ML Subgoal.focus}, @{ML Subgoal.focus_prems}, @{ML
 | 
| 427 | Subgoal.focus_params} extract the focus information from a goal | |
| 428 | state in the same way as the corresponding tacticals above. This is | |
| 429 | occasionally useful to experiment without writing actual tactics | |
| 430 | yet. | |
| 431 | ||
| 20472 | 432 |   \item @{ML Goal.prove}~@{text "ctxt xs As C tac"} states goal @{text
 | 
| 20474 | 433 |   "C"} in the context augmented by fixed variables @{text "xs"} and
 | 
| 434 |   assumptions @{text "As"}, and applies tactic @{text "tac"} to solve
 | |
| 435 | it. The latter may depend on the local assumptions being presented | |
| 436 | as facts. The result is in HHF normal form. | |
| 18537 | 437 | |
| 20472 | 438 |   \item @{ML Goal.prove_multi} is simular to @{ML Goal.prove}, but
 | 
| 20491 | 439 | states several conclusions simultaneously. The goal is encoded by | 
| 21827 | 440 |   means of Pure conjunction; @{ML Goal.conjunction_tac} will turn this
 | 
| 441 | into a collection of individual subgoals. | |
| 20472 | 442 | |
| 20491 | 443 |   \item @{ML Obtain.result}~@{text "tac thms ctxt"} eliminates the
 | 
| 444 | given facts using a tactic, which results in additional fixed | |
| 445 | variables and assumptions in the context. Final results need to be | |
| 446 | exported explicitly. | |
| 20472 | 447 | |
| 448 |   \end{description}
 | |
| 449 | *} | |
| 30272 | 450 | |
| 39853 | 451 | text %mlex {* The following minimal example illustrates how to access
 | 
| 452 | the focus information of a structured goal state. *} | |
| 453 | ||
| 454 | example_proof | |
| 455 | fix A B C :: "'a \<Rightarrow> bool" | |
| 456 | ||
| 457 | have "\<And>x. A x \<Longrightarrow> B x \<Longrightarrow> C x" | |
| 458 | ML_val | |
| 459 |     {*
 | |
| 460 |       val {goal, context = goal_ctxt, ...} = @{Isar.goal};
 | |
| 461 |       val (focus as {params, asms, concl, ...}, goal') =
 | |
| 462 | Subgoal.focus goal_ctxt 1 goal; | |
| 463 | val [A, B] = #prems focus; | |
| 464 | val [(_, x)] = #params focus; | |
| 465 | *} | |
| 466 | oops | |
| 467 | ||
| 468 | text {* \medskip The next example demonstrates forward-elimination in
 | |
| 469 |   a local context, using @{ML Obtain.result}.  *}
 | |
| 39851 | 470 | |
| 471 | example_proof | |
| 472 | assume ex: "\<exists>x. B x" | |
| 473 | ||
| 474 |   ML_prf %"ML" {*
 | |
| 475 |     val ctxt0 = @{context};
 | |
| 476 | val (([(_, x)], [B]), ctxt1) = ctxt0 | |
| 477 |       |> Obtain.result (fn _ => etac @{thm exE} 1) [@{thm ex}];
 | |
| 478 | *} | |
| 479 |   ML_prf %"ML" {*
 | |
| 480 |     singleton (ProofContext.export ctxt1 ctxt0) @{thm refl};
 | |
| 481 | *} | |
| 482 |   ML_prf %"ML" {*
 | |
| 483 | ProofContext.export ctxt1 ctxt0 [Thm.reflexive x] | |
| 484 | handle ERROR msg => (warning msg; []); | |
| 485 | *} | |
| 486 | qed | |
| 487 | ||
| 18537 | 488 | end |