text‹Did you ever dream about records with multiple inheritance?
you should definitely have a look at statespaces. They may be
you are dreaming of. Or at least almost \dots›
text‹Isabelle allows to add new top-level commands to the
. Building on the locale infrastructure, we provide a command 🪙‹statespace› like this:›
statespace vars =
n::nat
b::bool
print_locale vars_namespace print_locale vars_valuetypes print_locale vars
text‹\noindent This resembles a 🪙‹record› definition,
introduces sophisticated locale
instead of HOL type schemes. The resulting context
two distinct names term‹n› and term‹b› and
~/ injection functions that convert from abstract values to 🍋‹nat› and ‹bool›. The logical content of the locale is:›
locale vars' = fixes n::'name and b::'name assumes"distinct [n, b]"
text‹\noindent The HOL predicate const‹distinct› describes
of all names in the context. Locale ‹vars'›
the raw logical content that is defined in the state space
. We also maintain non-logical context information to support
user:
▪ Syntax for state lookup and updates that automatically inserts
corresponding projection and injection functions.
▪ Setup for the proof tools that exploit the distinctness
and the cancellation of projections and injections in
and simplifications.
extra-logical information is added to the locale in form of
, which associate the name of a variable to the
projection and injection functions to handle the syntax
, and a link from the variable name to the
distinctness theorem. As state spaces are merged or
there are multiple distinctness theorems in the context. Our
take care that the link always points to the strongest
assumption. With these declarations in place, a lookup
be written as ‹s⋅n›, which is translated to ‹project_nat (s n)›, and an
as ‹s⟨n := 2⟩›, which is translated to ‹s(n := inject_nat 2)›.
can now establish the
lemma:›
lemma (in vars) foo: "s<n := 2>⋅b = s⋅b"by simp
text‹\noindent Here the simplifier was able to refer to
of term‹b› and term‹n› to solve the equation.
resulting lemma is also recorded in locale ‹vars› for
use and is automatically propagated to all its interpretations.
is another example:›
statespace 'a varsX = NB: vars [n=N, b=B] + vars + x::'a
text‹\noindent The state space ‹varsX› imports two copies
the state space ‹vars›, where one has the variables renamed
upper-case letters, and adds another variable term‹x› of type 🍋‹'a›. This type is fixed inside the state space but may get
later on, analogous to type parameters of an ML-functor.
distinctness assumption is now ‹distinct [N, B, n, b, x]›,
this we can derive both term‹distinct [N,B]› and term‹distinct [n,b]›,
distinction assumptions for the two versions of ‹vars› above. Moreover we have all necessary
and injection assumptions available. These assumptions
allow us to establish state space term‹varsX› as an
of both instances of locale term‹vars›. Hence we
both variants of theorem ‹foo›: ‹s⟨N := 2⟩⋅B = ⋅B› as well as ‹s⟨n := 2⟩⋅b = s⋅b›. These are immediate
of the locale interpretation action.
declarations for syntax and the distinctness theorems also observe
morphisms generated by the locale package due to the renaming term‹n = N›:›
lemma (in varsX) foo: "s⟨N := 2⟩⋅x = s⋅x"by simp
text‹To assure scalability towards many distinct names, the
predicate is refined to operate on balanced trees. Thus
get logarithmic certificates for the distinctness of two names by
distinctness of the paths in the tree. Asked for the distinctness
two names, our tool produces the paths of the variables in the tree
this is implemented in Isabelle/ML, outside the logic) and returns a
corresponding to the different paths. Merging state
requires to prove that the combined distinctness assumption
the distinctness assumptions of the components. Such a proof
of the order $m \cdot\log n$, where $n$ and $m$ are the number of
in the larger and smaller tree, respectively.›
text‹We continue with more examples.›
statespace 'a foo =
f::"nat==>nat"
a::int
b::nat
c::'a
lemma (in foo) foo1: shows"s⟨a := i⟩⋅a = i" by simp
lemma (in foo) foo2: shows"(s⟨a:=i⟩)⋅a = i" by simp
lemma (in foo) foo3: shows"(s⟨a:=i⟩)⋅b = s⋅b" by simp
lemma (in foo) foo4: shows"(s⟨a:=i,b:=j,c:=k,a:=x⟩) = (s⟨b:=j,c:=k,a:=x⟩)" by simp
statespace bar =
b::bool
c::string
lemma (in bar) bar1: shows"(s⟨b:=True⟩)⋅c = s⋅c" by simp
text‹You can define a derived state space by inheriting existing state spaces, renaming
components if you like, and by declaring new components. ›
statespace ('a,'b) loo = 'a foo + bar [b=B,c=C] +
X::'b
lemma (in loo) loo1: shows"s⟨a:=i⟩⋅B = s⋅B" proof - thm foo1 txt‹The Lemma @{thm [source] foo1} from the parent state space
is also available here: \begin{center}@{thm foo1}\end{center}› have"s<a:=i>⋅a = i" by (rule foo1) thm bar1 txt‹Note the renaming of the parameters in Lemma @{thm [source] bar1}: \begin{center}@{thm bar1}\end{center}› have"s<B:=True>⋅C = s⋅C" by (rule bar1) show ?thesis by simp qed
statespace 'a dup = FA: 'a foo [f=F, a=A] + 'a foo +
x::int
lemma (in dup) shows"s<a := i>⋅x = s⋅x" by simp
lemma (in dup) shows"s<A := i>⋅a = s⋅a" by simp
lemma (in dup) shows"s<A := i>⋅x = s⋅x" by simp
text‹There were known problems with syntax-declarations. They only
when the context is already completely built. This is now overcome. e.g.:›
locale fooX = foo + assumes"s<a:=i>⋅b = k"
text‹
can also put statespaces side-by-side by using ordinary @{command locale} expressions
instead of the @{command statespace}). ›
locale side_by_side = foo + bar where b="B::'a"and c=C for B C
context side_by_side begin text‹Simplification within one of the statespaces works as expected.› lemma"s<B := i>⋅C = s⋅C" by simp
lemma"s<a := i>⋅b = s⋅b" by simp
text‹In contrast to the statespace @{locale loo} there is no 'inter' statespace distinctness
the names of @{locale foo} and @{locale bar}.› end
text‹Sharing of names in side-by-side statespaces is also possible as long as they are mapped
the same type.›
text‹Note that the distinctness theorem for @{locale vars1} is selected here to do the proof.› lemma"s<n := i>⋅m = s⋅m" by simp
text‹Note that the distinctness theorem for @{locale vars2} is selected here to do the proof.› lemma"s<n := i>⋅k = s⋅k" by simp
text‹Still there is no inter-statespace distinctness.› lemma"s<k := i>⋅m = s⋅m" (* apply simp *) oops end
statespace merge_vars1_vars2 = vars1 + vars2
context merge_vars1_vars2 begin text‹When defining a statespace instead of a side-by-side locale we get the distinctness of
variables.› lemma"s<k := i>⋅m = s⋅m" by simp end
subsection‹Benchmarks›
text‹Here are some bigger examples for benchmarking.›
ML ‹
fun make_benchmark n =
writeln (Active.sendback_markup_command
("statespace benchmark" ^ string_of_int n ^ " =\n" ^
(cat_lines (map (fn i => "A" ^ string_of_int i ^ "::nat") (1 upto n))))); ›
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.