summaryrefslogtreecommitdiff
path: root/backends/hol4
diff options
context:
space:
mode:
authorSon Ho2023-05-22 15:23:48 +0200
committerSon HO2023-06-04 21:54:38 +0200
commit1f0e5b3cb80e9334b07bf4b074c01150f4abd49d (patch)
treee66c708351b518bcda12bfa28ef3249eb3714cdb /backends/hol4
parent77d775ecea850576b24d097b402571889faa2a15 (diff)
Make the unfolding theorems collection from evalLib persistent
Diffstat (limited to 'backends/hol4')
-rw-r--r--backends/hol4/divDefLib.sml2
-rw-r--r--backends/hol4/divDefLibTestScript.sml16
-rw-r--r--backends/hol4/divDefLibTestTheory.sig9
-rw-r--r--backends/hol4/evalLib.sig5
-rw-r--r--backends/hol4/evalLib.sml73
-rw-r--r--backends/hol4/primitivesBaseTacLib.sml22
-rw-r--r--backends/hol4/primitivesLib.sml15
-rw-r--r--backends/hol4/primitivesScript.sml47
-rw-r--r--backends/hol4/saveThmsLib.sml275
9 files changed, 222 insertions, 242 deletions
diff --git a/backends/hol4/divDefLib.sml b/backends/hol4/divDefLib.sml
index 1e95b6c5..c9d8806d 100644
--- a/backends/hol4/divDefLib.sml
+++ b/backends/hol4/divDefLib.sml
@@ -904,6 +904,8 @@ fun DefineDiv (def_qt : term quotation) =
(we still do it: it doesn't cost much). *)
val _ = app delete_binding thm_names
val _ = map store_definition (zip thm_names def_eqs)
+ (* Also save the custom unfoldings, for evaluation (unit tests) *)
+ val _ = evalLib.add_unfold_thms thm_names
in
def_eqs
end
diff --git a/backends/hol4/divDefLibTestScript.sml b/backends/hol4/divDefLibTestScript.sml
index 2e6d56b6..b01ec053 100644
--- a/backends/hol4/divDefLibTestScript.sml
+++ b/backends/hol4/divDefLibTestScript.sml
@@ -13,6 +13,21 @@ Datatype:
| ListNil
End
+(* A version of [nth] which doesn't use machine integers *)
+val [nth0_def] = DefineDiv ‘
+ nth0 (ls : 't list_t) (i : int) : 't result =
+ case ls of
+ | ListCons x tl =>
+ if i = (0:int)
+ then (Return x)
+ else
+ do
+ nth0 tl (i - 1)
+ od
+ | ListNil => Fail Failure
+’
+val _ = primitivesLib.assert_return “nth0 (ListCons 0 ListNil) 0”
+
val [nth_def] = DefineDiv ‘
nth (ls : 't list_t) (i : u32) : 't result =
case ls of
@@ -26,6 +41,7 @@ val [nth_def] = DefineDiv ‘
od
| ListNil => Fail Failure
+val _ = primitivesLib.assert_return “nth (ListCons 0 ListNil) (int_to_u32 0)”
(* even, odd *)
diff --git a/backends/hol4/divDefLibTestTheory.sig b/backends/hol4/divDefLibTestTheory.sig
index 526f74a6..d8cc4ab5 100644
--- a/backends/hol4/divDefLibTestTheory.sig
+++ b/backends/hol4/divDefLibTestTheory.sig
@@ -13,6 +13,7 @@ sig
val list_t_size_def : thm
val node_TY_DEF : thm
val node_case_def : thm
+ val nth0_def : thm
val nth_def : thm
val odd_def : thm
val tree_TY_DEF : thm
@@ -180,6 +181,14 @@ sig
⊢ ∀a f. node_CASE (Node a) f = f a
+ [nth0_def] Definition
+
+ ⊢ ∀ls i.
+ nth0 ls i =
+ case ls of
+ ListCons x tl => if i = 0 then Return x else nth0 tl (i − 1)
+ | ListNil => Fail Failure
+
[nth_def] Definition
⊢ ∀ls i.
diff --git a/backends/hol4/evalLib.sig b/backends/hol4/evalLib.sig
index d045d3bb..f44cff13 100644
--- a/backends/hol4/evalLib.sig
+++ b/backends/hol4/evalLib.sig
@@ -8,10 +8,7 @@ sig
include Abbrev
- (* The following functions allow to register custom unfolding theorems *)
- (* TODO: permanence of theorems? *)
- val add_unfold : term * thm -> unit
- val add_unfolds : (term * thm) list -> unit
+ (* The following functions allow to *persistently* register custom unfolding theorems *)
val add_unfold_thm : thm -> unit
val add_unfold_thms : thm list -> unit
diff --git a/backends/hol4/evalLib.sml b/backends/hol4/evalLib.sml
index 30e28eed..85a6b94a 100644
--- a/backends/hol4/evalLib.sml
+++ b/backends/hol4/evalLib.sml
@@ -27,37 +27,61 @@ fun get_const_name (tm : term) : const_name =
(thy, name)
end
-(* TODO: should we rather use srw_ss ()?
- TODO: permanence of saved theorems? (see BasicProvers.export_rewrites) *)
-val custom_rewrites : ssfrag ref = ref empty_ssfrag
-val custom_unfolds : ((const_name, thm) Redblackmap.dict) ref = ref (Redblackmap.mkDict const_name_compare)
-val custom_unfolds_consts : (term Redblackset.set) ref = ref (Redblackset.empty Term.compare)
+(* Create the persistent collection, which is a pair:
+ (set of constants, map from constant name to theorem)
+ *)
+type state = term Redblackset.set * (const_name, thm) Redblackmap.dict
+fun get_custom_unfold_const (th : thm) : term = (fst o strip_comb o lhs o snd o strip_forall o concl) th
-fun add_rewrites (thms : thm list) : unit =
+(* Small helper *)
+fun add_to_state (th : thm) (s, m) =
let
- val rewrs = frag_rewrites (!custom_rewrites)
- val _ = custom_rewrites := rewrites (List.@ (thms, rewrs))
+ val k = get_custom_unfold_const th
+ val name = get_const_name k
+ val s = Redblackset.add (s, k)
+ val m = Redblackmap.insert (m, name, th)
in
- ()
+ (s, m)
end
-fun add_unfold (tm : term, th : thm) : unit =
+(* Persistently update the maps given a delta *)
+fun apply_delta (delta : ThmSetData.setdelta) st =
+ case delta of
+ ThmSetData.ADD (_, th) => add_to_state th st
+ | ThmSetData.REMOVE _ =>
+ raise mk_HOL_ERR "saveThmsLib" "create_map" ("Unexpected REMOVE")
+
+(* Initialize the collection *)
+val init_state = (Redblackset.empty compare, Redblackmap.mkDict const_name_compare)
+val {update_global_value, (* Local update *)
+ record_delta, (* Global update *)
+ get_global_value,
+ ...} =
+ ThmSetData.export_with_ancestry {
+ settype = "custom_unfold_theorems",
+ delta_ops = {apply_to_global = apply_delta,
+ uptodate_delta = K true,
+ thy_finaliser = NONE,
+ initial_value = init_state,
+ apply_delta = apply_delta}
+ }
+
+fun add_unfold_thm (s : string) : unit =
let
- val _ = custom_unfolds := Redblackmap.insert (!custom_unfolds, get_const_name tm, th)
- val _ = custom_unfolds_consts := Redblackset.add (!custom_unfolds_consts, tm)
+ val th = saveThmsLib.lookup_thm s
in
- ()
+ (* Record the delta - for persistence for the future sessions *)
+ record_delta (ThmSetData.ADD th);
+ (* Update the global value - for the current session: record_delta
+ doesn't update the state of the current session *)
+ update_global_value (add_to_state (snd th))
end
-fun add_unfolds (ls : (term * thm) list) : unit =
- app add_unfold ls
-
-fun get_custom_unfold_const (th : thm) : term = (fst o strip_comb o lhs o snd o strip_forall o concl) th
-fun add_unfold_thm (th : thm) : unit = add_unfold (get_custom_unfold_const th, th)
-fun add_unfold_thms (ls : thm list) : unit = app add_unfold_thm ls
+fun add_unfold_thms (ls : string list) : unit =
+ app add_unfold_thm ls
fun get_unfold_thms () : thm list =
- map snd (Redblackmap.listItems (!custom_unfolds))
+ map snd (Redblackmap.listItems (snd (get_global_value ())))
(* Apply a custom unfolding to the term, if possible.
@@ -65,6 +89,9 @@ fun get_unfold_thms () : thm list =
*)
fun apply_custom_unfold (tm : term) : thm =
let
+ (* Retrieve the custom unfoldings *)
+ val custom_unfolds = snd (get_global_value ())
+
(* Remove all the matches to find the top-most scrutinee *)
val scrut = strip_all_cases_get_scrutinee tm
(* Find an unfolding to apply: we look at the application itself, then
@@ -80,7 +107,7 @@ fun apply_custom_unfold (tm : term) : thm =
theorem *)
val c = (fst o strip_comb) tm
val cname = get_const_name c
- val unfold_th = Redblackmap.find (!custom_unfolds, cname)
+ val unfold_th = Redblackmap.find (custom_unfolds, cname)
handle Redblackmap.NotFound => failwith "No theorem found"
(* Instantiate the theorem *)
val unfold_th = SPEC_ALL unfold_th
@@ -121,7 +148,7 @@ fun apply_custom_unfold (tm : term) : thm =
fun eval_conv tm =
let
(* TODO: optimize: we recompute the list each time... *)
- val restr_tms = Redblackset.listItems (!custom_unfolds_consts)
+ val restr_tms = Redblackset.listItems (fst (get_global_value ()))
(* We do the following:
- use the standard EVAL conv, but restrains it from unfolding terms for
which we have custom unfolding theorems
@@ -129,7 +156,7 @@ fun eval_conv tm =
- simplify
*)
val standard_eval = RESTR_EVAL_CONV restr_tms
- val simp_no_fail_conv = (fn x => SIMP_CONV (srw_ss () ++ !custom_rewrites) [] x handle UNCHANGED => REFL x)
+ val simp_no_fail_conv = (fn x => SIMP_CONV (srw_ss ()) [] x handle UNCHANGED => REFL x)
val one_step_conv = standard_eval THENC (apply_custom_unfold THENC simp_no_fail_conv)
(* Wrap the conversion such that it fails if the term is unchanged *)
fun one_step_changed_conv tm = (CHANGED_CONV one_step_conv) tm
diff --git a/backends/hol4/primitivesBaseTacLib.sml b/backends/hol4/primitivesBaseTacLib.sml
index 3d6d9e3e..143e25ce 100644
--- a/backends/hol4/primitivesBaseTacLib.sml
+++ b/backends/hol4/primitivesBaseTacLib.sml
@@ -648,9 +648,27 @@ fun strip_all_cases_get_scrutinee (t : term) : term =
For instance: (fst o strip_case) “if i = 0 then ... else ...”
returns “i” while we want to get “i = 0”.
- We use [dest_case] for this reason.
+ Also, [dest_case] sometimes fails.
+
+ Ex.:
+ {[
+ val t = “result_CASE (if T then Return 0 else Fail Failure) (λy. Return ()) Fail Diverge”
+ dest_case t
+ ]}
+ TODO: file an issue
+
+ We use a custom function [get_case_scrutinee] instead of [dest_case] for this reason.
*)
- (strip_all_cases_get_scrutinee o (fn (_, x, _) => x) o TypeBase.dest_case) t
+ let
+ fun get_case_scrutinee t =
+ let
+ val (_, tms) = strip_comb t
+ in
+ hd tms
+ end
+ in
+ (strip_all_cases_get_scrutinee o get_case_scrutinee) t
+ end
else t
(*
diff --git a/backends/hol4/primitivesLib.sml b/backends/hol4/primitivesLib.sml
index eed50e25..776843bf 100644
--- a/backends/hol4/primitivesLib.sml
+++ b/backends/hol4/primitivesLib.sml
@@ -511,4 +511,19 @@ val progress : tactic =
map_first_tac progress_with thl (asms, g)
end
+(* Small utility: check that a term evaluates to “Return” (used by the unit tests) *)
+fun assert_return (tm0 : term) : unit =
+ let
+ (* Evaluate the term *)
+ val tm = evalLib.eval tm0
+ (* Deconstruct it *)
+ val (app, _) = strip_comb tm
+ val {Thy, Name, ...} = dest_thy_const app
+ handle HOL_ERR _ => raise (mk_HOL_ERR "primitivesLib" "assert_return" ("The term doesn't evaluate to “Return ...”: " ^ term_to_string tm ^ "\n, final result: " ^ term_to_string tm))
+ in
+ if Thy = "primitives" andalso Name = "Return" then ()
+ else
+ raise (mk_HOL_ERR "primitivesLib" "assert_return" ("The term doesn't evaluate to “Return ...”: " ^ term_to_string tm ^ "\n, final result: " ^ term_to_string tm))
+ end
+
end
diff --git a/backends/hol4/primitivesScript.sml b/backends/hol4/primitivesScript.sml
index 6f54fbfc..e10ce7e5 100644
--- a/backends/hol4/primitivesScript.sml
+++ b/backends/hol4/primitivesScript.sml
@@ -368,7 +368,21 @@ val all_int_to_scalar_to_int_unfold_lemmas = [
u64_to_int_int_to_u64_unfold,
u128_to_int_int_to_u128_unfold
]
-val _ = evalLib.add_unfold_thms (all_int_to_scalar_to_int_unfold_lemmas)
+
+val _ = evalLib.add_unfold_thms [
+ "isize_to_int_int_to_isize_unfold",
+ "i8_to_int_int_to_i8_unfold",
+ "i16_to_int_int_to_i16_unfold",
+ "i32_to_int_int_to_i32_unfold",
+ "i64_to_int_int_to_i64_unfold",
+ "i128_to_int_int_to_i128_unfold",
+ "usize_to_int_int_to_usize_unfold",
+ "u8_to_int_int_to_u8_unfold",
+ "u16_to_int_int_to_u16_unfold",
+ "u32_to_int_int_to_u32_unfold",
+ "u64_to_int_int_to_u64_unfold",
+ "u128_to_int_int_to_u128_unfold"
+]
val int_to_i8_i8_to_int = new_axiom ("int_to_i8_i8_to_int", “∀i. int_to_i8 (i8_to_int i) = i”)
val int_to_i16_i16_to_int = new_axiom ("int_to_i16_i16_to_int", “∀i. int_to_i16 (i16_to_int i) = i”)
@@ -1614,7 +1628,7 @@ Theorem mk_vec_unfold:
Proof
metis_tac [mk_vec_axiom]
QED
-val _ = evalLib.add_unfold_thm mk_vec_unfold
+val _ = evalLib.add_unfold_thm "mk_vec_unfold"
(* Defining ‘vec_insert_back’ *)
val vec_insert_back_def = Define ‘
@@ -1645,33 +1659,4 @@ Proof
sg_dep_rewrite_all_tac index_update_same >- cooper_tac >> fs []
QED
-(* TODO: add theorems to the rewriting theorems
-from listSimps.sml:
-
-val LIST_ss = BasicProvers.thy_ssfrag "list"
-val _ = BasicProvers.logged_addfrags {thyname="list"} [LIST_EQ_ss]
-
-val list_rws = computeLib.add_thms
- [
- ALL_DISTINCT, APPEND, APPEND_NIL, CONS_11, DROP_compute, EL_restricted,
- EL_simp_restricted, EVERY_DEF, EXISTS_DEF, FILTER, FIND_def, FLAT, FOLDL,
- FOLDR, FRONT_DEF, GENLIST_AUX_compute, GENLIST_NUMERALS, HD, INDEX_FIND_def,
- INDEX_OF_def, LAST_compute, LENGTH, LEN_DEF, LIST_APPLY_def, LIST_BIND_def,
- LIST_IGNORE_BIND_def, LIST_LIFT2_def, LIST_TO_SET_THM, LLEX_def, LRC_def,
- LUPDATE_compute, MAP, MAP2, NOT_CONS_NIL, NOT_NIL_CONS, NULL_DEF, oEL_def,
- oHD_def,
- PAD_LEFT, PAD_RIGHT, REVERSE_REV, REV_DEF, SHORTLEX_def, SNOC, SUM_ACC_DEF,
- SUM_SUM_ACC,
- TAKE_compute, TL, UNZIP, ZIP, computeLib.lazyfy_thm list_case_compute,
- dropWhile_def, isPREFIX, list_size_def, nub_def, splitAtPki_def
- ]
-
-fun list_compset () =
- let
- val base = reduceLib.num_compset()
- in
- list_rws base; base
- end
-*)
-
val _ = export_theory ()
diff --git a/backends/hol4/saveThmsLib.sml b/backends/hol4/saveThmsLib.sml
index d2523eeb..76b428cf 100644
--- a/backends/hol4/saveThmsLib.sml
+++ b/backends/hol4/saveThmsLib.sml
@@ -1,196 +1,107 @@
-structure saveThmsLib =
+structure saveThmsLib :> saveThmsLib =
struct
-type simpset = simpLib.simpset;
+open HolKernel Abbrev
-open HolKernel boolLib markerLib;
+type thname = KernelSig.kernelname
-val op++ = simpLib.++;
-val op-* = simpLib.-*;
-
-val ERR = mk_HOL_ERR "saveThmsLib";
-
-fun add_simpls tyinfo ss =
- (ss ++ simpLib.tyi_to_ssdata tyinfo) handle HOL_ERR _ => ss
-
-(* TODO: what is this? *)
-fun tyinfol() = TypeBasePure.listItems (TypeBase.theTypeBase())
-
-datatype stc_update = ADD_SSFRAG of simpLib.ssfrag | REMOVE_RWT of string
-type stc_state = simpset * bool * stc_update list
- (* theorems, initialised-flag, update list (most recent first) *)
-
-val initial_simpset = simpLib.empty_ss
-fun ssf1 nth = simpLib.empty_ssfrag |> simpLib.add_named_rwt nth
-
-val state0 : stc_state = (initial_simpset, false, [])
-fun apply_delta d ((sset,initp,upds):stc_state) : stc_state =
- case d of
- ThmSetData.ADD nth =>
- (sset ++ ssf1 nth, true, [])
- | ThmSetData.REMOVE s => (sset -* [s], true, [])
-
-fun apply_stc_update (ADD_SSFRAG ssf, ss) = ss ++ ssf
- | apply_stc_update (REMOVE_RWT n, ss) = ss -* [n]
-
-(* A stateful theorems collection *)
-datatype stc = STC_CON of {
- name : string,
- thy_ssfrag : string -> simpLib.ssfrag,
- thy_simpset : string -> simpset option,
- get_ss : unit -> simpset,
- export_thms : string list -> unit
+(* The user-provided functions *)
+type 'key key_fns = {
+ compare : 'key * 'key -> order,
+ get_key_from_thm : thm -> 'key
}
-(* Create a stateful theorems collection *)
-fun create_stateful_theorem_set (stc_name : string) =
- let
-(* val stc_name = "testStc" *)
-
- fun init_state (st as (sset,initp,upds)) =
- if initp then st
- else
- let fun init() =
- (List.foldl apply_stc_update sset (List.rev upds)
- |> rev_itlist add_simpls (tyinfol()),
- true, [])
- in
- HOL_PROGRESS_MESG ("Initialising STC simpset: " ^ stc_name ^ " ... ", "done") init ()
- end
-
- fun opt_partition f g ls =
- let
- fun recurse As Bs ls =
- case ls of
- [] => (List.rev As, List.rev Bs)
- | h::t => (case f h of
- SOME a => recurse (a::As) Bs t
- | NONE => (case g h of
- SOME b => recurse As (b::Bs) t
- | NONE => recurse As Bs t))
- in
- recurse [] [] ls
- end
-
- (* stale-ness is important for derived values. Derived values will get
- re-calculated if their flag is true when the value is requested.
- *)
- val stale_flags = Sref.new ([] : bool Sref.t list)
- fun notify () =
- List.app (fn br => Sref.update br (K true)) (Sref.value stale_flags)
-
- fun apply_to_global d (st as (sset,initp,upds):stc_state) : stc_state =
- if not initp then
- case d of
- ThmSetData.ADD nth =>
- let
- open simpLib
- val upds' =
- case upds of
- ADD_SSFRAG ssf :: rest =>
- ADD_SSFRAG (add_named_rwt nth ssf) :: rest
- | _ => ADD_SSFRAG (ssf1 nth) :: upds
- in
- (sset, initp, upds')
- end
- | ThmSetData.REMOVE s => (sset, initp, REMOVE_RWT s :: upds)
- else
- apply_delta d st before notify()
-
- fun finaliser {thyname} deltas (sset,initp,upds) =
- let
- fun toNamedAdd (ThmSetData.ADD p) = SOME p | toNamedAdd _ = NONE
- fun toRM (ThmSetData.REMOVE s) = SOME s | toRM _ = NONE
- val (adds,rms) = opt_partition toNamedAdd toRM deltas
- val ssfrag = simpLib.named_rewrites_with_names thyname (List.rev adds)
- (* List.rev here preserves old behaviour wrt to the way theorems were
- added to the global simpset; it will only make a difference when
- overall rewrite system is not confluent *)
- val new_upds = ADD_SSFRAG ssfrag :: map REMOVE_RWT rms
- in
- if initp then
- (List.foldl apply_stc_update sset new_upds, true, []) before notify()
- else (sset, false, List.revAppend(new_upds, upds))
- end
-
-
- val adresult as {DB,get_global_value,record_delta,update_global_value,...} =
- ThmSetData.export_with_ancestry {
- delta_ops = {
- apply_delta = apply_delta,
- apply_to_global = apply_to_global,
- thy_finaliser = SOME finaliser,
- initial_value = state0, uptodate_delta = K true
- },
- settype = stc_name
- }
-
- val get_deltas = #get_deltas adresult
-
- (*
- (* TODO: what is this? *)
- fun update_fn tyi =
- augment_stc_ss ([simpLib.tyi_to_ssdata tyi] handle HOL_ERR _ => [])
-
- val () = TypeBase.register_update_fn (fn tyi => (update_fn tyi; tyi))
- *)
-
- fun get_ss () =
- (update_global_value init_state;
- #1 (get_global_value()))
-
- fun export_thms slist =
- let val ds = map ThmSetData.mk_add slist
- in
- List.app record_delta ds;
- update_global_value (rev_itlist apply_to_global ds)
- end
+(* The functions we return to the user to manipulate the map *)
+type 'key map_fns = {
+ (* Persistently save a theorem *)
+ save_thm : string -> unit,
+ (* Temporarily save a theorem *)
+ temp_save_thm : thm -> unit,
+ (* Get the key set *)
+ get_keys : unit -> 'key Redblackset.set,
+ (* Get the theorems map *)
+ get_map : unit -> ('key, thm) Redblackmap.dict
+}
- (* assume that there aren't any removes for things added in this theory;
- it's not rational to do that; one should add it locally only, or not
- add it at all
- *)
- fun mkfrag_from thy setdeltas =
- let fun recurse ADDs [] = ADDs
- | recurse ADDs (ThmSetData.ADD p :: rest) = recurse (p::ADDs) rest
- | recurse ADDs (_ :: rest) = recurse ADDs rest
- val ADDs = recurse [] setdeltas
- (* order of addition is flipped; see above for why this is
- "reasonable" *)
- in
- simpLib.named_rewrites_with_names thy ADDs
- end
- fun thy_ssfrag s = get_deltas {thyname=s} |> mkfrag_from s
+(* This function is adapted from ThmSetData.sml.
- fun thy_simpset s = Option.map (#1 o init_state) (DB {thyname=s})
+ It raises an exception if it can't find a theorem.
+ *)
+fun lookup_thm (s : string) : thname * thm =
+ let
+ val name =
+ case String.fields (equal #".") s of
+ [s0] => {Thy = current_theory(), Name = s}
+ | [s1,s2] => {Thy = s1, Name = s2}
+ | _ => raise mk_HOL_ERR "saveThmsLib" "lookup_thm" ("Malformed name: " ^ s)
+ fun lookup_exn {Thy,Name} = DB.fetch Thy Name
in
- STC_CON { name = stc_name, thy_ssfrag = thy_ssfrag, thy_simpset = thy_simpset,
- get_ss = get_ss, export_thms = export_thms }
+ (name, lookup_exn name)
end
-fun rewrite_thms_of_simpset (ss : simpset) : thm list =
- List.concat (map simpLib.frag_rewrites (simpLib.ssfrags_of ss))
-
-(*
-(* Create a stateful theorems collection *)
-val STC_CON { name = stc_name, thy_ssfrag = thy_ssfrag, thy_simpset = thy_simpset, get_ss = get_ss, export_thms = export_thms } =
- create_stateful_theorem_set "testStc1"
+(* The state, a pair (set of keys, map from keys to theorems) *)
+type 'key state = 'key Redblackset.set * ('key, thm) Redblackmap.dict
-Theorem th1:
- T /\ (T /\ T)
-Proof
- fs []
-QED
-
-export_thms ["th1"]
-
-fun rewrite_thms_of_simpset (ss : simpset) : thm list =
- List.concat (map simpLib.frag_rewrites (simpLib.ssfrags_of ss))
-
-rewrite_thms_of_simpset (get_ss ())
-*)
-
-val STC_CON { name = stc_name, thy_ssfrag = thy_ssfrag, thy_simpset = thy_simpset, get_ss = get_ss, export_thms = export_thms } =
- create_stateful_theorem_set "testStc1"
+(* Initialize a persistent map *)
+fun create_map (kf : 'key key_fns) (name : string) : 'key map_fns =
+ let
+ val { compare, get_key_from_thm } = kf
+
+ (* Small helper *)
+ fun add_to_state (th : thm) (s, m) =
+ let
+ val k = get_key_from_thm th
+ val s = Redblackset.add (s, k)
+ val m = Redblackmap.insert (m, k, th)
+ in
+ (s, m)
+ end
+
+ (* Persistently update the map given a delta *)
+ fun apply_delta (delta : ThmSetData.setdelta) st =
+ case delta of
+ ThmSetData.ADD (_, th) => add_to_state th st
+ | ThmSetData.REMOVE _ =>
+ raise mk_HOL_ERR "saveThmsLib" "create_map" ("Unexpected REMOVE")
+
+ (* Initialize the dictionary *)
+ val init_state = (Redblackset.empty compare, Redblackmap.mkDict compare)
+ val {update_global_value, (* Local update *)
+ record_delta, (* Global update *)
+ get_deltas,
+ get_global_value,
+ DB = eval_ruleuction_map_by_theory,...} =
+ ThmSetData.export_with_ancestry {
+ settype = name,
+ delta_ops = {apply_to_global = apply_delta,
+ uptodate_delta = K true,
+ thy_finaliser = NONE,
+ initial_value = init_state,
+ apply_delta = apply_delta}
+ }
+
+ (* Temporarily save a theorem: update the current session, but don't
+ save the delta for the future sessions. *)
+ fun temp_save_thm (th : thm) : unit =
+ update_global_value (add_to_state th)
+
+ (* Persistently save a theorem *)
+ fun save_thm (s : string) : unit =
+ let
+ val th = lookup_thm s
+ in
+ (* Record delta saves a delta for the future sessions, but doesn't
+ update the current sessions, which is why we also call [temp_save_thm] *)
+ record_delta (ThmSetData.ADD th);
+ temp_save_thm (snd th)
+ end
+
+ (* *)
+ val get_keys = fst o get_global_value
+ val get_map = snd o get_global_value
+ in
+ { save_thm = save_thm, temp_save_thm = temp_save_thm,
+ get_keys = get_keys, get_map = get_map }
+ end
end