support for context within morphism (for background theory);
authorwenzelm
Tue, 16 May 2023 14:30:32 +0200
changeset 78062 edb195122938
parent 78061 5ab5add88922
child 78063 7c9f290dff55
support for context within morphism (for background theory);
src/Pure/General/basics.ML
src/Pure/Isar/element.ML
src/Pure/Isar/expression.ML
src/Pure/assumption.ML
src/Pure/context.ML
src/Pure/morphism.ML
src/Pure/variable.ML
--- a/src/Pure/General/basics.ML	Mon May 15 22:46:04 2023 +0200
+++ b/src/Pure/General/basics.ML	Tue May 16 14:30:32 2023 +0200
@@ -32,6 +32,7 @@
   val the_default: 'a -> 'a option -> 'a
   val perhaps: ('a -> 'a option) -> 'a -> 'a
   val merge_options: 'a option * 'a option -> 'a option
+  val join_options: ('a * 'a -> 'a) -> 'a option * 'a option -> 'a option
   val eq_option: ('a * 'b -> bool) -> 'a option * 'b option -> bool
 
   (*partiality*)
@@ -94,6 +95,9 @@
 
 fun merge_options (x, y) = if is_some x then x else y;
 
+fun join_options f (SOME x, SOME y) = SOME (f (x, y))
+  | join_options _ args = merge_options args;
+
 fun eq_option eq (SOME x, SOME y) = eq (x, y)
   | eq_option _ (NONE, NONE) = true
   | eq_option _ _ = false;
--- a/src/Pure/Isar/element.ML	Mon May 15 22:46:04 2023 +0200
+++ b/src/Pure/Isar/element.ML	Tue May 16 14:30:32 2023 +0200
@@ -390,6 +390,7 @@
 fun eq_term_morphism _ [] = NONE
   | eq_term_morphism thy props =
       let
+        (* FIXME proper morphism context *)
         fun decomp_simp prop =
           let
             val ctxt = Proof_Context.init_global thy;
@@ -402,21 +403,21 @@
           Morphism.morphism "Element.eq_term_morphism"
            {binding = [],
             typ = [],
-            term = [Pattern.rewrite_term thy (map decomp_simp props) []],
-            fact = [fn _ => error "Illegal application of Element.eq_term_morphism"]};
+            term = [K (Pattern.rewrite_term thy (map decomp_simp props) [])],
+            fact = [fn _ => fn _ => error "Illegal application of Element.eq_term_morphism"]};
       in SOME phi end;
 
 fun eq_morphism _ [] = NONE
   | eq_morphism thy thms =
       let
-        (* FIXME proper context!? *)
+        (* FIXME proper morphism context *)
         fun rewrite th = rewrite_rule (Proof_Context.init_global (Thm.theory_of_thm th)) thms th;
         val phi =
           Morphism.morphism "Element.eq_morphism"
            {binding = [],
             typ = [],
-            term = [Raw_Simplifier.rewrite_term thy thms []],
-            fact = [map rewrite]};
+            term = [K (Raw_Simplifier.rewrite_term thy thms [])],
+            fact = [K (map rewrite)]};
       in SOME phi end;
 
 
--- a/src/Pure/Isar/expression.ML	Mon May 15 22:46:04 2023 +0200
+++ b/src/Pure/Isar/expression.ML	Tue May 16 14:30:32 2023 +0200
@@ -556,7 +556,7 @@
     val exp_typ = Logic.type_map exp_term;
     val export' =
       Morphism.morphism "Expression.prep_goal"
-        {binding = [], typ = [exp_typ], term = [exp_term], fact = [exp_fact]};
+        {binding = [], typ = [K exp_typ], term = [K exp_term], fact = [K exp_fact]};
   in ((propss, eq_propss, deps, eqnss, export'), goal_ctxt) end;
 
 in
--- a/src/Pure/assumption.ML	Mon May 15 22:46:04 2023 +0200
+++ b/src/Pure/assumption.ML	Tue May 16 14:30:32 2023 +0200
@@ -143,7 +143,7 @@
     val typ = Logic.type_map term;
   in
     Morphism.morphism "Assumption.export"
-      {binding = [], typ = [typ], term = [term], fact = [map thm]}
+      {binding = [], typ = [K typ], term = [K term], fact = [K (map thm)]}
   end;
 
 end;
--- a/src/Pure/context.ML	Mon May 15 22:46:04 2023 +0200
+++ b/src/Pure/context.ML	Tue May 16 14:30:32 2023 +0200
@@ -65,6 +65,7 @@
   val certificate_theory_id: certificate -> theory_id
   val eq_certificate: certificate * certificate -> bool
   val join_certificate: certificate * certificate -> certificate
+  val join_certificate_theory: theory * theory -> theory
   (*generic context*)
   datatype generic = Theory of theory | Proof of Proof.context
   val theory_tracing: bool Unsynchronized.ref
@@ -627,16 +628,24 @@
   | eq_certificate (Certificate_Id thy_id1, Certificate_Id thy_id2) = eq_thy_id (thy_id1, thy_id2)
   | eq_certificate _ = false;
 
+fun err_join (thy_id1, thy_id2) =
+  error ("Cannot join unrelated theory certificates " ^
+    display_name thy_id1 ^ " and " ^ display_name thy_id2);
+
 fun join_certificate (cert1, cert2) =
   let val (thy_id1, thy_id2) = apply2 certificate_theory_id (cert1, cert2) in
     if eq_thy_id (thy_id1, thy_id2) then (case cert1 of Certificate _ => cert1 | _ => cert2)
     else if proper_subthy_id (thy_id2, thy_id1) then cert1
     else if proper_subthy_id (thy_id1, thy_id2) then cert2
-    else
-      error ("Cannot join unrelated theory certificates " ^
-        display_name thy_id1 ^ " and " ^ display_name thy_id2)
+    else err_join (thy_id1, thy_id2)
   end;
 
+fun join_certificate_theory (thy1, thy2) =
+  let val (thy_id1, thy_id2) = apply2 theory_id (thy1, thy2) in
+    if subthy_id (thy_id2, thy_id1) then thy1
+    else if proper_subthy_id (thy_id1, thy_id2) then thy2
+    else err_join (thy_id1, thy_id2)
+  end;
 
 
 (*** generic context ***)
--- a/src/Pure/morphism.ML	Mon May 15 22:46:04 2023 +0200
+++ b/src/Pure/morphism.ML	Tue May 16 14:30:32 2023 +0200
@@ -17,12 +17,16 @@
 sig
   include BASIC_MORPHISM
   exception MORPHISM of string * exn
+  val the_theory: theory option -> theory
+  val set_context: theory -> morphism -> morphism
+  val reset_context: morphism -> morphism
   val morphism: string ->
-   {binding: (binding -> binding) list,
-    typ: (typ -> typ) list,
-    term: (term -> term) list,
-    fact: (thm list -> thm list) list} -> morphism
+   {binding: (theory option -> binding -> binding) list,
+    typ: (theory option -> typ -> typ) list,
+    term: (theory option -> term -> term) list,
+    fact: (theory option -> thm list -> thm list) list} -> morphism
   val is_identity: morphism -> bool
+  val is_empty: morphism -> bool
   val pretty: morphism -> Pretty.T
   val binding: morphism -> binding -> binding
   val binding_prefix: morphism -> (string * bool) list
@@ -37,7 +41,9 @@
   val transform: morphism -> (morphism -> 'a) -> morphism -> 'a
   val form: (morphism -> 'a) -> 'a
   val binding_morphism: string -> (binding -> binding) -> morphism
+  val typ_morphism': string -> (theory -> typ -> typ) -> morphism
   val typ_morphism: string -> (typ -> typ) -> morphism
+  val term_morphism': string -> (theory -> term -> term) -> morphism
   val term_morphism: string -> (term -> term) -> morphism
   val fact_morphism: string -> (thm list -> thm list) -> morphism
   val thm_morphism: string -> (thm -> thm) -> morphism
@@ -54,32 +60,53 @@
 
 (* named functions *)
 
-type 'a funs = (string * ('a -> 'a)) list;
+type 'a funs = (string * (theory option -> 'a -> 'a)) list;
 
 exception MORPHISM of string * exn;
 
-fun app (name, f) x = f x
+fun app context (name, f) x = f context x
   handle exn =>
     if Exn.is_interrupt exn then Exn.reraise exn else raise MORPHISM (name, exn);
 
-fun apply fs = fold_rev app fs;
+
+(* optional context *)
+
+fun the_theory (SOME thy) = thy
+  | the_theory NONE = raise Fail "Morphism lacks theory context";
+
+fun join_transfer (SOME thy) = Thm.join_transfer thy
+  | join_transfer NONE = I;
+
+val join_context = join_options Context.join_certificate_theory;
 
 
 (* type morphism *)
 
 datatype morphism = Morphism of
- {names: string list,
+ {context: theory option,
+  names: string list,
   binding: binding funs,
   typ: typ funs,
   term: term funs,
   fact: thm list funs};
 
+type declaration = morphism -> Context.generic -> Context.generic;
+
 fun rep (Morphism args) = args;
 
-type declaration = morphism -> Context.generic -> Context.generic;
+fun apply which phi =
+  let val args = rep phi
+  in fold_rev (app (#context args)) (which args) end;
+
+fun put_context context (Morphism {context = _, names, binding, typ, term, fact}) =
+  Morphism {context = context, names = names, binding = binding, typ = typ, term = term, fact = fact};
+
+val set_context = put_context o SOME;
+val reset_context = put_context NONE;
 
 fun morphism a {binding, typ, term, fact} =
   Morphism {
+    context = NONE,
     names = if a = "" then [] else [a],
     binding = map (pair a) binding,
     typ = map (pair a) typ,
@@ -87,18 +114,20 @@
     fact = map (pair a) fact};
 
 (*syntactic test only!*)
-fun is_identity (Morphism {names, binding, typ, term, fact}) =
+fun is_identity (Morphism {context = _, names, binding, typ, term, fact}) =
   null names andalso null binding andalso null typ andalso null term andalso null fact;
 
+fun is_empty phi = is_none (#context (rep phi)) andalso is_identity phi;
+
 fun pretty phi = Pretty.enum ";" "{" "}" (map Pretty.str (rev (#names (rep phi))));
 
 val _ = ML_system_pp (fn _ => fn _ => Pretty.to_polyml o pretty);
 
-val binding = apply o #binding o rep;
+val binding = apply #binding;
 fun binding_prefix morph = Binding.name "x" |> binding morph |> Binding.prefix_of;
-val typ = apply o #typ o rep;
-val term = apply o #term o rep;
-val fact = apply o #fact o rep;
+val typ = apply #typ;
+val term = apply #term;
+fun fact phi = map (join_transfer (#context (rep phi))) #> apply #fact phi;
 val thm = singleton o fact;
 val cterm = Drule.cterm_rule o thm;
 
@@ -110,14 +139,17 @@
 val default = the_default identity;
 
 fun compose phi1 phi2 =
-  if is_identity phi1 then phi2
-  else if is_identity phi2 then phi1
+  if is_empty phi1 then phi2
+  else if is_empty phi2 then phi1
   else
     let
-      val {names = names1, binding = binding1, typ = typ1, term = term1, fact = fact1} = rep phi1;
-      val {names = names2, binding = binding2, typ = typ2, term = term2, fact = fact2} = rep phi2;
+      val {context = context1, names = names1, binding = binding1,
+        typ = typ1, term = term1, fact = fact1} = rep phi1;
+      val {context = context2, names = names2, binding = binding2,
+        typ = typ2, term = term2, fact = fact2} = rep phi2;
     in
       Morphism {
+        context = join_context (context1, context2),
         names = names1 @ names2,
         binding = binding1 @ binding2,
         typ = typ1 @ typ2,
@@ -133,11 +165,13 @@
 
 (* concrete morphisms *)
 
-fun binding_morphism a binding = morphism a {binding = [binding], typ = [], term = [], fact = []};
-fun typ_morphism a typ = morphism a {binding = [], typ = [typ], term = [], fact = []};
-fun term_morphism a term = morphism a {binding = [], typ = [], term = [term], fact = []};
-fun fact_morphism a fact = morphism a {binding = [], typ = [], term = [], fact = [fact]};
-fun thm_morphism a thm = morphism a {binding = [], typ = [], term = [], fact = [map thm]};
+fun binding_morphism a binding = morphism a {binding = [K binding], typ = [], term = [], fact = []};
+fun typ_morphism' a typ = morphism a {binding = [], typ = [typ o the_theory], term = [], fact = []};
+fun typ_morphism a typ = morphism a {binding = [], typ = [K typ], term = [], fact = []};
+fun term_morphism' a term = morphism a {binding = [], typ = [], term = [term o the_theory], fact = []};
+fun term_morphism a term = morphism a {binding = [], typ = [], term = [K term], fact = []};
+fun fact_morphism a fact = morphism a {binding = [], typ = [], term = [], fact = [K fact]};
+fun thm_morphism a thm = morphism a {binding = [], typ = [], term = [], fact = [K (map thm)]};
 
 val transfer_morphism = thm_morphism "transfer" o Thm.join_transfer;
 val transfer_morphism' = transfer_morphism o Proof_Context.theory_of;
@@ -159,9 +193,9 @@
         {binding = [],
          typ =
           if TFrees.is_empty instT then []
-          else [Term_Subst.instantiateT_frees instT],
-         term = [Term_Subst.instantiate_frees (instT, inst)],
-         fact = [map (Thm.instantiate_frees (cinstT, cinst))]}
+          else [K (Term_Subst.instantiateT_frees instT)],
+         term = [K (Term_Subst.instantiate_frees (instT, inst))],
+         fact = [K (map (Thm.instantiate_frees (cinstT, cinst)))]}
     end;
 
 fun instantiate_morphism (cinstT, cinst) =
@@ -175,9 +209,9 @@
         {binding = [],
          typ =
           if TVars.is_empty instT then []
-          else [Term_Subst.instantiateT instT],
-         term = [Term_Subst.instantiate (instT, inst)],
-         fact = [map (Thm.instantiate (cinstT, cinst))]}
+          else [K (Term_Subst.instantiateT instT)],
+         term = [K (Term_Subst.instantiate (instT, inst))],
+         fact = [K (map (Thm.instantiate (cinstT, cinst)))]}
     end;
 
 end;
--- a/src/Pure/variable.ML	Mon May 15 22:46:04 2023 +0200
+++ b/src/Pure/variable.ML	Tue May 16 14:30:32 2023 +0200
@@ -583,7 +583,8 @@
     val term = singleton (export_terms inner outer);
     val typ = Logic.type_map term;
   in
-    Morphism.morphism "Variable.export" {binding = [], typ = [typ], term = [term], fact = [fact]}
+    Morphism.morphism "Variable.export"
+      {binding = [], typ = [K typ], term = [K term], fact = [K fact]}
   end;