The registry provides a mechanism for including Istari data structures in an Istari file. Most data types can be stored, but, significantly, nothing involving ML code, which includes functions and tactics.
A value of type t
is stored using a key with type t key
. Keys
are constructed using a collection of combinators, one for each type
operator.
To write a value x
of type int * term
into the registry using the
name bar
, one would say:
Registry.write
(Symbol.fromValue "bar")
(Registry.pair Registry.int Registry.term)
x
With the customized parser, this can be rendered more conveniently:
Registry.write (parseIdent /bar/) (parseRegistryKey /int * term/) x
Using the pervasive function writeRegistry
, one can write it even
more briefly:
writeRegistry /bar/ /int * term/ x
If the current module is Foo
when an entry is written to bar
, it
will appear in the registry under the name Foo.bar
. It will use
that name immediately, even before the Foo
module is closed.
To read that same value, one would say:
Registry.read
(map Symbol.fromValue ["Foo", "bar"])
(Registry.pair Registry.int Registry.term)
or:
Registry.read (parseLongident /Foo.bar/) (parseRegistryKey /int * term/)
or just:
readRegistry /Foo.bar/ /int * term/
As a practical example, the notb_tru
reduction (with type
Reduction.reduction2
) is obtained by:
val notb_tru = readRegistry /Bool.notb_tru/ /reduction2/
Here, Registry.reduction2
(the result of parsing /reduction2/
)
has the type Reduction.reduction2 Registry.key
, so notb_tru
will
have the type Reduction.reduction2
.
The key parser has a special syntax for keys for collapsed
tuples. To construct the key for
((unit * bool) * int) * constant
, one can write
\[bool int constant]\
.
The full interface for the registry is:
signature REGISTRY =
sig
type 'a key
exception Registry of string
val write : Symbol.symbol -> 'a key -> 'a -> unit
val read : Symbol.symbol list -> 'a key -> 'a
val delete : Symbol.symbol list -> unit
val unit : unit key
val bool : bool key
val int : int key
val intInf : IntInf.int key
val string : string key
val symbol : Symbol.symbol key
val constant : Constant.constant key
val term : Term.term key
val reduction : Reduction.reduction key
val reduction1 : Reduction.reduction1 key
val reduction2 : Reduction.reduction2 key
val list : 'a key -> 'a list key
val option : 'a key -> 'a option key
val vector : 'a key -> 'a Vector.vector key
val seq : 'a key -> 'a Seq.seq key
val pair : 'a key -> 'b key -> ('a * 'b) key
val tuple2 : 'a key -> 'b key -> ('a * 'b) key (* alias for pair *)
val tuple3 : 'a key -> 'b key -> 'c key -> ('a * 'b * 'c) key
val tuple4 : 'a key -> 'b key -> 'c key -> 'd key -> ('a * 'b * 'c * 'd) key
val tuple5 : 'a key -> 'b key -> 'c key -> 'd key -> 'e key -> ('a * 'b * 'c * 'd * 'e) key
val tuple6 : 'a key -> 'b key -> 'c key -> 'd key -> 'e key -> 'f key -> ('a * 'b * 'c * 'd * 'e * 'f) key
val tuple7 : 'a key -> 'b key -> 'c key -> 'd key -> 'e key -> 'f key -> 'g key -> ('a * 'b * 'c * 'd * 'e * 'f * 'g) key
val tuple8 : 'a key -> 'b key -> 'c key -> 'd key -> 'e key -> 'f key -> 'g key -> 'h key -> ('a * 'b * 'c * 'd * 'e * 'f * 'g * 'h) key
val tuple9 : 'a key -> 'b key -> 'c key -> 'd key -> 'e key -> 'f key -> 'g key -> 'h key -> 'i key -> ('a * 'b * 'c * 'd * 'e * 'f * 'g * 'h * 'i) key
val tuple10 : 'a key -> 'b key -> 'c key -> 'd key -> 'e key -> 'f key -> 'g key -> 'h key -> 'i key -> 'j key -> ('a * 'b * 'c * 'd * 'e * 'f * 'g * 'h * 'i * 'j) key
end
The Registry
exception is raised in various error conditions, including:
Reading or deleting an entry that is not present.
Reading an entry with the wrong key.
Writing to a name that is already present.