cases: formal binding of 'assumes', with position provided via invoke_case;
authorwenzelm
Tue, 03 Sep 2013 19:58:00 +0200
changeset 53380 08f3491c50bf
parent 53379 74920496ab71
child 53381 355a4cac5440
cases: formal binding of 'assumes', with position provided via invoke_case; allow literal equality on type Binding.binding;
src/HOL/Tools/Nitpick/nitpick.ML
src/HOL/Tools/Predicate_Compile/predicate_compile_core.ML
src/Pure/General/binding.ML
src/Pure/Isar/proof.ML
src/Pure/Isar/proof_context.ML
src/Pure/Isar/rule_cases.ML
--- a/src/HOL/Tools/Nitpick/nitpick.ML	Tue Sep 03 18:21:43 2013 +0200
+++ b/src/HOL/Tools/Nitpick/nitpick.ML	Tue Sep 03 19:58:00 2013 +0200
@@ -456,7 +456,7 @@
        provide a hint to the user. *)
     fun is_struct_induct_step (name, (Rule_Cases.Case {fixes, assumes, ...}, _)) =
       not (null fixes) andalso
-      exists (String.isSuffix ".hyps" o fst) assumes andalso
+      exists (String.isSuffix ".hyps" o Name_Space.full_name Name_Space.default_naming o fst) assumes andalso
       exists (exists (curry (op =) name o shortest_name o fst)
               o datatype_constrs hol_ctxt) deep_dataTs
     val likely_in_struct_induct_step =
--- a/src/HOL/Tools/Predicate_Compile/predicate_compile_core.ML	Tue Sep 03 18:21:43 2013 +0200
+++ b/src/HOL/Tools/Predicate_Compile/predicate_compile_core.ML	Tue Sep 03 19:58:00 2013 +0200
@@ -1574,6 +1574,9 @@
   Attrib.setup @{binding code_pred_intro} (Scan.lift (Scan.option Args.name) >> attrib' add_intro)
     "adding alternative introduction rules for code generation of inductive predicates"
 
+fun qualified_binding a =
+  Binding.qualify true (Long_Name.qualifier a) (Binding.name (Long_Name.base_name a));
+
 (* TODO: make Theory_Data to Generic_Data & remove duplication of local theory and theory *)
 (* FIXME ... this is important to avoid changing the background theory below *)
 fun generic_code_pred prep_const options raw_const lthy =
@@ -1593,9 +1596,12 @@
     val cases_rules = map mk_cases preds
     val cases =
       map2 (fn pred_name => fn case_rule => Rule_Cases.Case {fixes = [],
-        assumes = ("that", tl (Logic.strip_imp_prems case_rule))
-          :: (map_filter (fn (fact_name, fact) => Option.map (rpair [fact]) fact_name)
-            ((SOME (Long_Name.base_name pred_name ^ ".prems") :: names_of ctxt' pred_name) ~~ Logic.strip_imp_prems case_rule)),
+        assumes =
+          (Binding.name "that", tl (Logic.strip_imp_prems case_rule)) ::
+          map_filter (fn (fact_name, fact) =>
+              Option.map (fn a => (qualified_binding a, [fact])) fact_name)
+            ((SOME (Long_Name.base_name pred_name ^ ".prems") :: names_of ctxt' pred_name) ~~
+              Logic.strip_imp_prems case_rule),
         binds = [], cases = []}) preds cases_rules
     val case_env = map2 (fn p => fn c => (Long_Name.base_name p, SOME c)) preds cases
     val lthy'' = lthy'
--- a/src/Pure/General/binding.ML	Tue Sep 03 18:21:43 2013 +0200
+++ b/src/Pure/General/binding.ML	Tue Sep 03 19:58:00 2013 +0200
@@ -9,10 +9,11 @@
 
 signature BINDING =
 sig
-  type binding
+  eqtype binding
   val dest: binding -> bool * (string * bool) list * bstring
   val make: bstring * Position.T -> binding
   val pos_of: binding -> Position.T
+  val set_pos: Position.T -> binding -> binding
   val name: bstring -> binding
   val name_of: binding -> bstring
   val map_name: (bstring -> bstring) -> binding -> binding
@@ -41,13 +42,12 @@
 
 (* datatype *)
 
-abstype binding = Binding of
+datatype binding = Binding of
  {conceal: bool,                    (*internal -- for foundational purposes only*)
   prefix: (string * bool) list,     (*system prefix*)
   qualifier: (string * bool) list,  (*user qualifier*)
   name: bstring,                    (*base name*)
-  pos: Position.T}                  (*source position*)
-with
+  pos: Position.T};                 (*source position*)
 
 fun make_binding (conceal, prefix, qualifier, name, pos) =
   Binding {conceal = conceal, prefix = prefix, qualifier = qualifier, name = name, pos = pos};
@@ -65,9 +65,12 @@
 (* name and position *)
 
 fun make (name, pos) = make_binding (false, [], [], name, pos);
-fun name name = make (name, Position.none);
 
 fun pos_of (Binding {pos, ...}) = pos;
+fun set_pos pos =
+  map_binding (fn (conceal, prefix, qualifier, name, _) => (conceal, prefix, qualifier, name, pos));
+
+fun name name = make (name, Position.none);
 fun name_of (Binding {name, ...}) = name;
 
 fun eq_name (b, b') = name_of b = name_of b';
@@ -140,7 +143,6 @@
   else legacy_feature (bad binding);
 
 end;
-end;
 
 type binding = Binding.binding;
 
--- a/src/Pure/Isar/proof.ML	Tue Sep 03 18:21:43 2013 +0200
+++ b/src/Pure/Isar/proof.ML	Tue Sep 03 19:58:00 2013 +0200
@@ -743,15 +743,13 @@
 
 local
 
-fun qualified_binding a =
-  Binding.qualify true (Long_Name.qualifier a) (Binding.name (Long_Name.base_name a));
-
 fun gen_invoke_case prep_att ((name, pos), xs, raw_atts) state =
   let
     val atts = map (prep_att (context_of state)) raw_atts;
     val (asms, state') = state |> map_context_result (fn ctxt =>
       ctxt |> Proof_Context.apply_case (Proof_Context.check_case ctxt (name, pos) xs));
-    val assumptions = asms |> map (fn (a, ts) => ((qualified_binding a, atts), map (rpair []) ts));
+    val assumptions =
+      asms |> map (fn (b, ts) => ((Binding.set_pos pos b, atts), map (rpair []) ts));
   in
     state'
     |> assume assumptions
--- a/src/Pure/Isar/proof_context.ML	Tue Sep 03 18:21:43 2013 +0200
+++ b/src/Pure/Isar/proof_context.ML	Tue Sep 03 19:58:00 2013 +0200
@@ -133,7 +133,7 @@
     Proof.context -> (string * thm list) list * Proof.context
   val dest_cases: Proof.context -> (string * (Rule_Cases.T * bool)) list
   val update_cases: bool -> (string * Rule_Cases.T option) list -> Proof.context -> Proof.context
-  val apply_case: Rule_Cases.T -> Proof.context -> (string * term list) list * Proof.context
+  val apply_case: Rule_Cases.T -> Proof.context -> (binding * term list) list * Proof.context
   val check_case: Proof.context -> string * Position.T -> binding option list -> Rule_Cases.T
   val type_notation: bool -> Syntax.mode -> (typ * mixfix) list -> Proof.context -> Proof.context
   val notation: bool -> Syntax.mode -> (term * mixfix) list -> Proof.context -> Proof.context
@@ -1273,8 +1273,9 @@
       [Pretty.quote (prt_term (Var (xi, Term.fastype_of t))), Pretty.str " =", Pretty.brk 1,
         Pretty.quote (prt_term t)];
 
-    fun prt_asm (a, ts) = Pretty.block (Pretty.breaks
-      ((if a = "" then [] else [Pretty.str (a ^ ":")]) @ map (Pretty.quote o prt_term) ts));
+    fun prt_asm (b, ts) = Pretty.block (Pretty.breaks
+      ((if Binding.is_empty b then []
+        else [Binding.pretty b, Pretty.str ":"]) @ map (Pretty.quote o prt_term) ts));
 
     fun prt_sect _ _ _ [] = []
       | prt_sect s sep prt xs =
--- a/src/Pure/Isar/rule_cases.ML	Tue Sep 03 18:21:43 2013 +0200
+++ b/src/Pure/Isar/rule_cases.ML	Tue Sep 03 19:58:00 2013 +0200
@@ -21,7 +21,7 @@
   include BASIC_RULE_CASES
   datatype T = Case of
    {fixes: (binding * typ) list,
-    assumes: (string * term list) list,
+    assumes: (binding * term list) list,
     binds: (indexname * term option) list,
     cases: (string * T) list}
   val case_hypsN: string
@@ -62,7 +62,7 @@
 
 datatype T = Case of
  {fixes: (binding * typ) list,
-  assumes: (string * term list) list,
+  assumes: (binding * term list) list,
   binds: (indexname * term option) list,
   cases: (string * T) list};
 
@@ -91,21 +91,22 @@
   | extract_fixes (SOME outline) prop =
       chop (length (Logic.strip_params outline)) (strip_params prop);
 
-fun extract_assumes _ _ NONE prop = ([("", Logic.strip_assums_hyp prop)], [])
-  | extract_assumes qual hnames (SOME outline) prop =
+fun extract_assumes _ _ NONE prop = ([(Binding.empty, Logic.strip_assums_hyp prop)], [])
+  | extract_assumes qualifier hyp_names (SOME outline) prop =
       let
+        val qual = Binding.qualify true qualifier o Binding.name;
         val (hyps, prems) =
           chop (length (Logic.strip_assums_hyp outline)) (Logic.strip_assums_hyp prop)
-        fun extract ((hname,h)::ps) = (qual hname, h :: map snd ps);
-        val (hyps1,hyps2) = chop (length hnames) hyps;
-        val pairs1 = if hyps1 = [] then [] else hnames ~~ hyps1;
-        val pairs = pairs1 @ (map (pair case_hypsN) hyps2);
-        val named_hyps = map extract (partition_eq (eq_fst op =) pairs)
+        fun extract ((hyp_name, hyp) :: rest) = (qual hyp_name, hyp :: map snd rest);
+        val (hyps1, hyps2) = chop (length hyp_names) hyps;
+        val pairs1 = if null hyps1 then [] else hyp_names ~~ hyps1;
+        val pairs = pairs1 @ map (pair case_hypsN) hyps2;
+        val named_hyps = map extract (partition_eq (eq_fst op =) pairs);
       in (named_hyps, [(qual case_premsN, prems)]) end;
 
 fun bindings args = map (apfst Binding.name) args;
 
-fun extract_case thy (case_outline, raw_prop) name hnames concls =
+fun extract_case thy (case_outline, raw_prop) name hyp_names concls =
   let
     val props = Logic.dest_conjunctions (Drule.norm_hhf thy raw_prop);
     val len = length props;
@@ -120,7 +121,8 @@
           else
             fold_rev Term.abs fixes1
               (app (map (Term.dummy_pattern o #2) fixes2) (fold_rev Term.abs fixes2 t));
-        val (assumes1, assumes2) = extract_assumes (Long_Name.qualify name) hnames case_outline prop
+        val (assumes1, assumes2) =
+          extract_assumes name hyp_names case_outline prop
           |> pairself (map (apsnd (maps Logic.dest_conjunctions)));
 
         val concl = Object_Logic.drop_judgment thy (Logic.strip_assums_concl prop);
@@ -153,11 +155,11 @@
   let
     val n = length cases;
     val nprems = Logic.count_prems prop;
-    fun add_case ((name, hnames), concls) (cs, i) =
+    fun add_case ((name, hyp_names), concls) (cs, i) =
       ((case try (fn () =>
           (Option.map (curry Logic.nth_prem i) rule_struct, Logic.nth_prem (i, prop))) () of
         NONE => (name, NONE)
-      | SOME p => (name, extract_case thy p name hnames concls)) :: cs, i - 1);
+      | SOME p => (name, extract_case thy p name hyp_names concls)) :: cs, i - 1);
   in fold_rev add_case (drop (Int.max (n - nprems, 0)) cases) ([], n) |> #1 end;
 
 in