focus: more precise treatment of schematic variables, only the "visible" part of the text is fixed;
authorwenzelm
Thu, 30 Jul 2009 11:23:17 +0200
changeset 32281 750101435f60
parent 32280 4fb3f426052a
child 32282 853ef99c04cc
focus: more precise treatment of schematic variables, only the "visible" part of the text is fixed; added FOCUS_PREMS, which may serve as full replacement for OldGoals.METAHYPS;
src/Pure/subgoal.ML
--- a/src/Pure/subgoal.ML	Thu Jul 30 01:14:40 2009 +0200
+++ b/src/Pure/subgoal.ML	Thu Jul 30 11:23:17 2009 +0200
@@ -1,20 +1,23 @@
 (*  Title:      Pure/subgoal.ML
     Author:     Makarius
 
-Tactical operations with explicit subgoal focus, based on
-canonical proof decomposition (similar to fix/assume/show).
+Tactical operations with explicit subgoal focus, based on canonical
+proof decomposition.  The "visible" part of the text within the
+context is fixed, the remaining goal may be schematic.
 *)
 
 signature SUBGOAL =
 sig
   type focus = {context: Proof.context, params: (string * cterm) list, prems: thm list,
-    asms: cterm list, concl: cterm, schematics: ctyp list * cterm list}
+    asms: cterm list, concl: cterm, schematics: (ctyp * ctyp) list * (cterm * cterm) list}
+  val focus_params: Proof.context -> int -> thm -> focus * thm
+  val focus_prems: Proof.context -> int -> thm -> focus * thm
   val focus: Proof.context -> int -> thm -> focus * thm
-  val focus_params: Proof.context -> int -> thm -> focus * thm
   val retrofit: Proof.context -> Proof.context -> (string * cterm) list -> cterm list ->
     int -> thm -> thm -> thm Seq.seq
+  val FOCUS_PARAMS: (focus -> tactic) -> Proof.context -> int -> tactic
+  val FOCUS_PREMS: (focus -> tactic) -> Proof.context -> int -> tactic
   val FOCUS: (focus -> tactic) -> Proof.context -> int -> tactic
-  val FOCUS_PARAMS: (focus -> tactic) -> Proof.context -> int -> tactic
   val SUBPROOF: (focus -> tactic) -> Proof.context -> int -> tactic
 end;
 
@@ -24,24 +27,35 @@
 (* focus *)
 
 type focus = {context: Proof.context, params: (string * cterm) list, prems: thm list,
-  asms: cterm list, concl: cterm, schematics: ctyp list * cterm list};
+  asms: cterm list, concl: cterm, schematics: (ctyp * ctyp) list * (cterm * cterm) list};
 
-fun gen_focus params_only ctxt i st =
+fun gen_focus (do_prems, do_concl) ctxt i raw_st =
   let
-    val ((schematics, [st']), ctxt') =
-      Variable.import true [Simplifier.norm_hhf_protect st] ctxt;
-    val ((params, goal), ctxt'') = Variable.focus_subgoal i st' ctxt';
+    val st = Simplifier.norm_hhf_protect raw_st;
+    val ((schematic_types, [st']), ctxt1) = Variable.importT [st] ctxt;
+    val ((params, goal), ctxt2) = Variable.focus (Thm.cprem_of st' i) ctxt1;
+
     val (asms, concl) =
-      if params_only then ([], goal)
-      else (Drule.strip_imp_prems goal, Drule.strip_imp_concl goal);
-    val (prems, context) = Assumption.add_assumes asms ctxt'';
+      if do_prems then (Drule.strip_imp_prems goal, Drule.strip_imp_concl goal)
+      else ([], goal);
+    val text = asms @ (if do_concl then [concl] else []);
+
+    val ((_, schematic_terms), ctxt3) =
+      Variable.import_inst true (map Thm.term_of text) ctxt2
+      |>> Thm.certify_inst (Thm.theory_of_thm raw_st);
+
+    val schematics = (schematic_types, schematic_terms);
+    val asms' = map (Thm.instantiate_cterm schematics) asms;
+    val concl' = Thm.instantiate_cterm schematics concl;
+    val (prems, context) = Assumption.add_assumes asms' ctxt3;
   in
     ({context = context, params = params, prems = prems,
-      asms = asms, concl = concl, schematics = schematics}, Goal.init concl)
+      asms = asms', concl = concl', schematics = schematics}, Goal.init concl')
   end;
 
-val focus = gen_focus false;
-val focus_params = gen_focus true;
+val focus_params = gen_focus (false, false);
+val focus_prems = gen_focus (true, false);
+val focus = gen_focus (true, true);
 
 
 (* lift and retrofit *)
@@ -53,27 +67,29 @@
 *)
 fun lift_import params th ctxt =
   let
-    val cert = Thm.cterm_of (Thm.theory_of_thm th);
     val ((_, [th']), ctxt') = Variable.importT [th] ctxt;
 
     val Ts = map (#T o Thm.rep_cterm) params;
     val ts = map Thm.term_of params;
 
-    val vars = rev (Term.add_vars (Thm.full_prop_of th') []);
+    val prop = Thm.full_prop_of th';
+    val concl_vars = Term.add_vars (Logic.strip_imp_concl prop) [];
+    val vars = rev (Term.add_vars prop []);
     val (ys, ctxt'') = Variable.variant_fixes (map (Name.clean o #1 o #1) vars) ctxt';
     fun var_inst (v as (_, T)) y =
-      (cert (Var v), cert (list_comb (Free (y, Ts ---> T), ts)));
-    val th'' = Thm.instantiate ([], map2 var_inst vars ys) th';
+      if member (op =) concl_vars v then (v, Free (y, T))
+      else (v, list_comb (Free (y, Ts ---> T), ts));
+    val th'' = Thm.certify_instantiate ([], map2 var_inst vars ys) th';
   in (th'', ctxt'') end;
 
 (*
-      [x, A x]
+       [x, A x]
           :
-      B x ==> C
+       B x ==> C
   ------------------
   [!!x. A x ==> B x]
-         :
-         C
+          :
+          C
 *)
 fun lift_subgoals params asms th =
   let
@@ -103,20 +119,22 @@
 
 (* tacticals *)
 
-fun GEN_FOCUS params_only tac ctxt i st =
+fun GEN_FOCUS flags tac ctxt i st =
   if Thm.nprems_of st < i then Seq.empty
   else
-    let val (args as {context, params, asms, ...}, st') = gen_focus params_only ctxt i st;
+    let val (args as {context, params, asms, ...}, st') = gen_focus flags ctxt i st;
     in Seq.lifts (retrofit context ctxt params asms i) (tac args st') st end;
 
-val FOCUS = GEN_FOCUS false;
-val FOCUS_PARAMS = GEN_FOCUS true;
+val FOCUS_PARAMS = GEN_FOCUS (false, false);
+val FOCUS_PREMS = GEN_FOCUS (true, false);
+val FOCUS = GEN_FOCUS (true, true);
 
 fun SUBPROOF tac = FOCUS (FILTER Thm.no_prems o tac);
 
 end;
 
+val FOCUS_PARAMS = Subgoal.FOCUS_PARAMS;
+val FOCUS_PREMS = Subgoal.FOCUS_PREMS;
 val FOCUS = Subgoal.FOCUS;
-val FOCUS_PARAMS = Subgoal.FOCUS_PARAMS;
 val SUBPROOF = Subgoal.SUBPROOF;