added promise_result, prove_promise;
authorwenzelm
Tue, 23 Sep 2008 22:04:30 +0200
changeset 28340 e8597242f649
parent 28339 6f6fa16543f5
child 28341 383f512314b9
added promise_result, prove_promise;
src/Pure/goal.ML
--- a/src/Pure/goal.ML	Tue Sep 23 18:31:33 2008 +0200
+++ b/src/Pure/goal.ML	Tue Sep 23 22:04:30 2008 +0200
@@ -20,9 +20,12 @@
   val conclude: thm -> thm
   val finish: thm -> thm
   val norm_result: thm -> thm
+  val promise_result: Proof.context -> (unit -> thm) -> term -> thm
   val prove_internal: cterm list -> cterm -> (thm list -> tactic) -> thm
   val prove_multi: Proof.context -> string list -> term list -> term list ->
     ({prems: thm list, context: Proof.context} -> tactic) -> thm list
+  val prove_promise: Proof.context -> string list -> term list -> term ->
+    ({prems: thm list, context: Proof.context} -> tactic) -> thm
   val prove: Proof.context -> string list -> term list -> term ->
     ({prems: thm list, context: Proof.context} -> tactic) -> thm
   val prove_global: theory -> string list -> term list -> term ->
@@ -84,6 +87,8 @@
 
 (** results **)
 
+(* normal form *)
+
 val norm_result =
   Drule.flexflex_unique
   #> MetaSimplifier.norm_hhf_protect
@@ -91,6 +96,39 @@
   #> Drule.zero_var_indexes;
 
 
+(* promise *)
+
+fun promise_result ctxt result prop =
+  let
+    val thy = ProofContext.theory_of ctxt;
+    val _ = Context.reject_draft thy;
+    val cert = Thm.cterm_of thy;
+    val certT = Thm.ctyp_of thy;
+
+    val assms = Assumption.assms_of ctxt;
+    val As = map Thm.term_of assms;
+
+    val xs = map Free (fold Term.add_frees (prop :: As) []);
+    val fixes = map cert xs;
+
+    val tfrees = fold Term.add_tfrees (prop :: As) [];
+    val instT = map (fn (a, S) => (certT (TVar ((a, 0), S)), certT (TFree (a, S)))) tfrees;
+
+    val global_prop =
+      Term.map_types Logic.varifyT (fold_rev Logic.all xs (Logic.list_implies (As, prop)));
+    val global_result =
+      Thm.generalize (map #1 tfrees, []) 0 o
+      Drule.forall_intr_list fixes o
+      Drule.implies_intr_list assms o
+      Thm.adjust_maxidx_thm ~1 o result;
+    val local_result =
+      Thm.promise (Future.fork_irrelevant global_result) (cert global_prop)
+      |> Thm.instantiate (instT, [])
+      |> Drule.forall_elim_list fixes
+      |> fold (Thm.elim_implies o Thm.assume) assms;
+  in local_result end;
+
+
 
 (** tactical theorem proving **)
 
@@ -102,9 +140,9 @@
   | NONE => error "Tactic failed.");
 
 
-(* prove_multi *)
+(* prove_common etc. *)
 
-fun prove_multi ctxt xs asms props tac =
+fun prove_common immediate ctxt xs asms props tac =
   let
     val thy = ProofContext.theory_of ctxt;
     val string_of_term = Syntax.string_of_term ctxt;
@@ -124,26 +162,30 @@
       |> Assumption.add_assumes casms
       ||> Variable.set_body true;
 
-    val goal = init (Conjunction.mk_conjunction_balanced cprops);
-    val res =
-      (case SINGLE (tac {prems = prems, context = ctxt'}) goal of
+    val stmt = Conjunction.mk_conjunction_balanced cprops;
+
+    fun result () =
+      (case SINGLE (tac {prems = prems, context = ctxt'}) (init stmt) of
         NONE => err "Tactic failed."
-      | SOME res => res);
-    val results = Conjunction.elim_balanced (length props) (finish res)
-      handle THM (msg, _, _) => err msg;
-    val _ = Unify.matches_list thy (map Thm.term_of cprops) (map Thm.prop_of results)
-      orelse err ("Proved a different theorem: " ^ string_of_term (Thm.prop_of res));
+      | SOME st =>
+          let val res = finish st handle THM (msg, _, _) => err msg in
+            if Unify.matches_list thy [Thm.term_of stmt] [Thm.prop_of res] then res
+            else err ("Proved a different theorem: " ^ string_of_term (Thm.prop_of res))
+          end);
+    val res =
+      if immediate orelse #maxidx (Thm.rep_cterm stmt) >= 0 then result ()
+      else promise_result ctxt result (Thm.term_of stmt);
   in
-    results
+    Conjunction.elim_balanced (length props) res
     |> map (Assumption.export false ctxt' ctxt)
     |> Variable.export ctxt' ctxt
     |> map Drule.zero_var_indexes
   end;
 
+val prove_multi = prove_common false;
 
-(* prove *)
-
-fun prove ctxt xs asms prop tac = hd (prove_multi ctxt xs asms [prop] tac);
+fun prove_promise ctxt xs asms prop tac = hd (prove_common false ctxt xs asms [prop] tac);
+fun prove ctxt xs asms prop tac = hd (prove_common true ctxt xs asms [prop] tac);
 
 fun prove_global thy xs asms prop tac =
   Drule.standard (prove (ProofContext.init thy) xs asms prop tac);