merged
authorwenzelm
Tue, 09 May 2023 09:49:41 +0200
changeset 78000 f589c50e54a0
parent 77991 bdb5de00379a (current diff)
parent 77999 ec850750db87 (diff)
child 78001 e5c146904c90
child 78014 24f0cd70790b
merged
--- a/src/Pure/Concurrent/synchronized.ML	Mon May 08 17:26:33 2023 +0200
+++ b/src/Pure/Concurrent/synchronized.ML	Tue May 09 09:49:41 2023 +0200
@@ -14,6 +14,9 @@
   val guarded_access: 'a var -> ('a -> ('b * 'a) option) -> 'b
   val change_result: 'a var -> ('a -> 'b * 'a) -> 'b
   val change: 'a var -> ('a -> 'a) -> unit
+  type 'a cache
+  val cache: (unit -> 'a) -> 'a cache
+  val cache_eval: 'a cache -> 'a
 end;
 
 structure Synchronized: SYNCHRONIZED =
@@ -92,4 +95,24 @@
 
 end;
 
+
+(* cached evaluation via weak_ref *)
+
+abstype 'a cache =
+  Cache of {expr: unit -> 'a, var: 'a Unsynchronized.weak_ref option var}
+with
+
+fun cache expr =
+  Cache {expr = expr, var = var "Synchronized.cache" NONE};
+
+fun cache_eval (Cache {expr, var}) =
+  change_result var (fn state =>
+    (case state of
+      SOME (Unsynchronized.ref (SOME (Unsynchronized.ref result))) => (result, state)
+    | _ =>
+      let val result = expr ()
+      in (result, SOME (Unsynchronized.weak_ref result)) end));
+
 end;
+
+end;
--- a/src/Pure/Concurrent/unsynchronized.ML	Mon May 08 17:26:33 2023 +0200
+++ b/src/Pure/Concurrent/unsynchronized.ML	Tue May 09 09:49:41 2023 +0200
@@ -15,6 +15,8 @@
   val dec: int ref -> int
   val add: int ref -> int -> int
   val setmp: 'a ref -> 'a -> ('b -> 'c) -> 'b -> 'c
+  type 'a weak_ref = 'a ref option ref
+  val weak_ref: 'a -> 'a weak_ref
 end;
 
 structure Unsynchronized: UNSYNCHRONIZED =
@@ -41,6 +43,9 @@
       val _ = flag := orig_value;
     in Exn.release result end) ();
 
+type 'a weak_ref = 'a ref option ref;
+fun weak_ref a = Weak.weak (SOME (ref a));
+
 end;
 
 ML_Name_Space.forget_val "ref";
--- a/src/Pure/General/long_name.ML	Mon May 08 17:26:33 2023 +0200
+++ b/src/Pure/General/long_name.ML	Tue May 09 09:49:41 2023 +0200
@@ -108,18 +108,15 @@
 fun range_length r = r mod range_limit;
 fun range_string s r = String.substring (s, range_index r, range_length r);
 
-val range_empty = 0;
-val ranges_empty: int vector = Vector.fromList [];
-
 in
 
 abstype chunks = Chunks of {range0: int, ranges: int list (*reverse*), string: string}
 with
 
-val empty_chunks = Chunks {range0 = range_empty, ranges = [], string = ""};
+val empty_chunks = Chunks {range0 = 0, ranges = [], string = ""};
 
 fun is_empty_chunks (Chunks {range0, ranges, ...}) =
-  range0 = range_empty andalso null ranges;
+  range0 = 0 andalso null ranges;
 
 fun count_chunks (chunks as Chunks {ranges, ...}) =
   if is_empty_chunks chunks then 0
--- a/src/Pure/General/name_space.ML	Mon May 08 17:26:33 2023 +0200
+++ b/src/Pure/General/name_space.ML	Tue May 09 09:49:41 2023 +0200
@@ -134,7 +134,8 @@
 
 type internals = string list Long_Name.Chunks.T;  (*external name -> internal names*)
 
-val merge_internals : internals * internals -> internals = Long_Name.Chunks.merge_list (op =);
+val merge_internals : internals * internals -> internals =
+  Long_Name.Chunks.merge_list (op =);
 
 fun add_internals name xname : internals -> internals =
   Long_Name.Chunks.update_list (op =) (xname, name);
--- a/src/Pure/Syntax/parser.ML	Mon May 08 17:26:33 2023 +0200
+++ b/src/Pure/Syntax/parser.ML	Tue May 09 09:49:41 2023 +0200
@@ -7,6 +7,7 @@
 
 signature PARSER =
 sig
+  val timing: bool Unsynchronized.ref
   type gram
   val empty_gram: gram
   val extend_gram: Syntax_Ext.xprod list -> gram -> gram
@@ -415,6 +416,8 @@
 
 (** operations on grammars **)
 
+val timing = Unsynchronized.ref true;
+
 val empty_gram =
   Gram
    {nt_count = 0,
@@ -426,8 +429,8 @@
 
 
 (*Add productions to a grammar*)
-fun extend_gram [] gram = gram
-  | extend_gram xprods (Gram {nt_count, prod_count, tags, chains, lambdas, prods}) =
+fun extend_gram0 [] gram = gram
+  | extend_gram0 xprods (Gram {nt_count, prod_count, tags, chains, lambdas, prods}) =
       let
         (*Get tag for existing nonterminal or create a new one*)
         fun get_tag nt_count tags nt =
@@ -490,6 +493,12 @@
           prods = Array.vector prods'}
       end;
 
+fun extend_gram xprods gram =
+  if ! timing then
+    Timing.cond_timeit true ("Parser.extend_gram" ^ Position.here (Position.thread_data ()))
+      (fn () => extend_gram0 xprods gram)
+  else extend_gram0 xprods gram;
+
 fun make_gram xprods = extend_gram xprods empty_gram;
 
 
--- a/src/Pure/Syntax/syntax_ext.ML	Mon May 08 17:26:33 2023 +0200
+++ b/src/Pure/Syntax/syntax_ext.ML	Tue May 09 09:49:41 2023 +0200
@@ -19,7 +19,7 @@
     En
   datatype xprod = XProd of string * xsymb list * string * int
   val chain_pri: int
-  val delims_of: xprod list -> string list list
+  val delims_of: xprod list -> Symbol.symbol list list
   datatype syn_ext =
     Syn_Ext of {
       xprods: xprod list,
--- a/src/Pure/Tools/find_theorems.ML	Mon May 08 17:26:33 2023 +0200
+++ b/src/Pure/Tools/find_theorems.ML	Tue May 09 09:49:41 2023 +0200
@@ -236,7 +236,7 @@
     val thy = Proof_Context.theory_of ctxt;
     fun matches obj ctxt' = Pattern.matches thy (pat, obj) orelse
       (case obj of
-        Abs (_, T, t) =>
+        Abs _ =>
           let val ((_, t'), ctxt'') = Variable.dest_abs obj ctxt'
           in matches t' ctxt'' end
       | t $ u => matches t ctxt' orelse matches u ctxt'
--- a/src/Pure/context.ML	Mon May 08 17:26:33 2023 +0200
+++ b/src/Pure/context.ML	Tue May 09 09:49:41 2023 +0200
@@ -53,8 +53,6 @@
   val proper_subthy: theory * theory -> bool
   val subthy_id: theory_id * theory_id -> bool
   val subthy: theory * theory -> bool
-  val trace_theories: bool Unsynchronized.ref
-  val theories_trace: unit -> {active_positions: Position.T list, active: int, total: int}
   val join_thys: theory list -> theory
   val begin_thy: string -> theory list -> theory
   val finish_thy: theory -> theory
@@ -69,6 +67,16 @@
   val join_certificate: certificate * certificate -> certificate
   (*generic context*)
   datatype generic = Theory of theory | Proof of Proof.context
+  val trace_theories: bool Unsynchronized.ref
+  val trace_proofs: bool Unsynchronized.ref
+  val allocations_trace: unit ->
+   {contexts: generic list,
+    active_contexts: int,
+    active_theories: int,
+    active_proofs: int,
+    total_contexts: int,
+    total_theories: int,
+    total_proofs: int}
   val cases: (theory -> 'a) -> (Proof.context -> 'a) -> generic -> 'a
   val mapping: (theory -> theory) -> (Proof.context -> Proof.context) -> generic -> generic
   val mapping_result: (theory -> 'a * theory) -> (Proof.context -> 'a * Proof.context) ->
@@ -114,9 +122,9 @@
 structure Context: PRIVATE_CONTEXT =
 struct
 
-(*** theory context ***)
+(*** type definitions ***)
 
-(* theory data *)
+(* context data *)
 
 (*private copy avoids potential conflict of table exceptions*)
 structure Datatab = Table(type key = int val ord = int_ord);
@@ -125,9 +133,24 @@
 val data_kind = Counter.make ();
 
 
-(** datatype theory **)
+(* theory identity *)
+
+type id = int;
+val new_id = Counter.make ();
 
-(* implicit state *)
+abstype theory_id =
+  Thy_Id of
+   {id: id,         (*identifier*)
+    ids: Intset.T,  (*cumulative identifiers -- symbolic body content*)
+    name: string,   (*official theory name*)
+    stage: int}     (*index for anonymous updates*)
+with
+  fun rep_theory_id (Thy_Id args) = args;
+  val make_theory_id = Thy_Id;
+end;
+
+
+(* theory allocation state *)
 
 type state = {stage: int} Synchronized.var;
 
@@ -138,44 +161,99 @@
   Synchronized.change_result state (fn {stage} => (stage + 1, {stage = stage + 1}));
 
 
-(* theory_id *)
+(* theory and proof context *)
+
+datatype theory =
+  Thy_Undef
+| Thy of
+    (*allocation state*)
+    state *
+    (*identity*)
+    {theory_id: theory_id,
+     theory_token: theory Unsynchronized.ref} *
+    (*ancestry*)
+    {parents: theory list,         (*immediate predecessors*)
+     ancestors: theory list} *     (*all predecessors -- canonical reverse order*)
+    (*data*)
+    Any.T Datatab.table;           (*body content*)
 
-type id = int;
-val new_id = Counter.make ();
+datatype proof =
+  Prf_Undef
+| Prf of
+    (*identity*)
+    proof Unsynchronized.ref *
+    theory *
+    (*data*)
+    Any.T Datatab.table;
+
+structure Proof = struct type context = proof end;
+
+datatype generic = Theory of theory | Proof of Proof.context;
+
+
+(* heap allocations *)
+
+val trace_theories = Unsynchronized.ref false;
+val trace_proofs = Unsynchronized.ref false;
+
+local
 
-abstype theory_id =
-  Theory_Id of
-   {id: id,                       (*identifier*)
-    ids: Intset.T,                (*cumulative identifiers -- symbolic body content*)
-    name: string,                 (*official theory name*)
-    stage: int}                   (*index for anonymous updates*)
-with
+fun make_token guard var token0 =
+  if ! guard then
+    let
+      val token = Unsynchronized.ref (! token0);
+      val _ = Synchronized.change var (cons (Weak.weak (SOME token)));
+    in (token, fn res => (token := res; res)) end
+  else (token0, I);
+
+val theory_tokens = Synchronized.var "theory_tokens" ([]: theory Unsynchronized.weak_ref list);
+val proof_tokens = Synchronized.var "proof_tokens" ([]: Proof.context Unsynchronized.weak_ref list);
+
+val theory_token0 = Unsynchronized.ref Thy_Undef;
+val proof_token0 = Unsynchronized.ref Prf_Undef;
+
+in
+
+fun theory_token () = make_token trace_theories theory_tokens theory_token0;
+fun proof_token () = make_token trace_proofs proof_tokens proof_token0;
 
-fun rep_theory_id (Theory_Id args) = args;
-val make_theory_id = Theory_Id;
+fun allocations_trace () =
+  let
+    val _ = ML_Heap.full_gc ();
+    val trace1 = Synchronized.value theory_tokens;
+    val trace2 = Synchronized.value proof_tokens;
+
+    fun cons1 (Unsynchronized.ref (SOME (Unsynchronized.ref (thy as Thy _)))) = cons (Theory thy)
+      | cons1 _ = I;
+    fun cons2 (Unsynchronized.ref (SOME (Unsynchronized.ref (ctxt as Prf _)))) = cons (Proof ctxt)
+      | cons2 _ = I;
+
+    val contexts = build (fold cons1 trace1 #> fold cons2 trace2);
+    val active_theories = fold (fn Theory _ => Integer.add 1 | _ => I) contexts 0;
+    val active_proofs = fold (fn Proof _ => Integer.add 1 | _ => I) contexts 0;
+
+    val total_theories = length trace1;
+    val total_proofs = length trace2;
+  in
+    {contexts = contexts,
+     active_contexts = active_theories + active_proofs,
+     active_theories = active_theories,
+     active_proofs = active_proofs,
+     total_contexts = total_theories + total_proofs,
+     total_theories = total_theories,
+     total_proofs = total_proofs}
+  end;
 
 end;
 
 
-(* theory *)
 
-datatype theory =
-  Theory of
-   (*allocation state*)
-   state *
-   (*identity*)
-   {theory_id: theory_id,
-    token: Position.T Unsynchronized.ref} *
-   (*ancestry*)
-   {parents: theory list,         (*immediate predecessors*)
-    ancestors: theory list} *     (*all predecessors -- canonical reverse order*)
-   (*data*)
-   Any.T Datatab.table;           (*body content*)
+(*** theory operations ***)
+
+fun rep_theory (Thy args) = args;
 
 exception THEORY of string * theory list;
 
-fun rep_theory (Theory args) = args;
-
 val state_of = #1 o rep_theory;
 val theory_identity = #2 o rep_theory;
 val theory_id = #theory_id o theory_identity;
@@ -343,45 +421,12 @@
 
 (* create theory *)
 
-val trace_theories = Unsynchronized.ref false;
-
-local
-
-val theories =
-  Synchronized.var "theory_tokens"
-    ([]: Position.T Unsynchronized.ref option Unsynchronized.ref list);
-
-val dummy_token = Unsynchronized.ref Position.none;
-
-fun make_token () =
-  if ! trace_theories then
-    let
-      val token = Unsynchronized.ref (Position.thread_data ());
-      val _ = Synchronized.change theories (cons (Weak.weak (SOME token)));
-    in token end
-  else dummy_token;
-
-in
-
-fun theories_trace () =
-  let
-    val trace = Synchronized.value theories;
-    val _ = ML_Heap.full_gc ();
-    val active_positions =
-      fold (fn Unsynchronized.ref (SOME pos) => cons (! pos) | _ => I) trace [];
-  in
-    {active_positions = active_positions,
-     active = length active_positions,
-     total = length trace}
-  end;
-
 fun create_thy state ids name stage ancestry data =
   let
     val theory_id = make_theory_id {id = new_id (), ids = ids, name = name, stage = stage};
-    val identity = {theory_id = theory_id, token = make_token ()};
-  in Theory (state, identity, ancestry, data) end;
-
-end;
+    val (token, assign) = theory_token ();
+    val identity = {theory_id = theory_id, theory_token = token};
+  in assign (Thy (state, identity, ancestry, data)) end;
 
 
 (* primitives *)
@@ -397,7 +442,7 @@
 fun change_thy finish f thy =
   let
     val {name, stage, ...} = identity_of thy;
-    val Theory (state, _, ancestry, data) = thy;
+    val Thy (state, _, ancestry, data) = thy;
     val ancestry' =
       if stage_final stage
       then make_ancestry [thy] (extend_ancestors thy (ancestors_of thy))
@@ -489,14 +534,6 @@
 
 (*** proof context ***)
 
-(* datatype Proof.context *)
-
-structure Proof =
-struct
-  datatype context = Context of Any.T Datatab.table * theory;
-end;
-
-
 (* proof data kinds *)
 
 local
@@ -518,16 +555,21 @@
 
 in
 
-fun raw_transfer thy' (Proof.Context (data, thy)) =
-  let
-    val _ = subthy (thy, thy') orelse error "Cannot transfer proof context: not a super theory";
-    val data' = init_new_data thy' data;
-  in Proof.Context (data', thy') end;
+fun raw_transfer thy' (ctxt as Prf (_, thy, data)) =
+  if eq_thy (thy, thy') then ctxt
+  else if proper_subthy (thy, thy') then
+    let
+      val (token', assign) = proof_token ();
+      val data' = init_new_data thy' data;
+    in assign (Prf (token', thy', data')) end
+  else error "Cannot transfer proof context: not a super theory";
 
 structure Proof_Context =
 struct
-  fun theory_of (Proof.Context (_, thy)) = thy;
-  fun init_global thy = Proof.Context (init_data thy, thy);
+  fun theory_of (Prf (_, thy, _)) = thy;
+  fun init_global thy =
+    let val (token, assign) = proof_token ()
+    in assign (Prf (token, thy, init_data thy)) end;
   fun get_global long thy name = init_global (get_theory long thy name);
 end;
 
@@ -540,13 +582,14 @@
     val _ = Synchronized.change kinds (Datatab.update (k, init));
   in k end;
 
-fun get k dest (Proof.Context (data, thy)) =
+fun get k dest (Prf (_, thy, data)) =
   (case Datatab.lookup data k of
     SOME x => x
   | NONE => init_fallback k thy) |> dest;
 
-fun put k make x (Proof.Context (data, thy)) =
-  Proof.Context (Datatab.update (k, make x) data, thy);
+fun put k make x (Prf (token, thy, data)) =
+  let val (token, assign) = proof_token ()
+  in assign (Prf (token, thy, Datatab.update (k, make x) data)) end;
 
 end;
 
@@ -583,8 +626,6 @@
 
 (*** generic context ***)
 
-datatype generic = Theory of theory | Proof of Proof.context;
-
 fun cases f _ (Theory thy) = f thy
   | cases _ g (Proof prf) = g prf;