Up to index of Isabelle/HOL/Statespace
theory StateSpaceEx(* Title: StateSpaceEx.thy ID: $Id: StateSpaceEx.thy,v 1.1 2007/10/24 16:36:10 schirmer Exp $ Author: Norbert Schirmer, TU Muenchen *) header {* Examples \label{sec:Examples} *} theory StateSpaceEx imports StateSpaceLocale StateSpaceSyntax begin (* FIXME: Use proper keywords file *) (*<*) syntax "_statespace_updates" :: "('a => 'b) => updbinds => ('a => 'b)" ("_〈_〉" [900,0] 900) (*>*) text {* Did you ever dream about records with multiple inheritance. Then you should definitely have a look at statespaces. They may be what you are dreaming of. Or at least almost... *} text {* Isabelle allows to add new top-level commands to the system. Building on the locale infrastructure, we provide a command \isacommand{statespace} like this:*} statespace vars = n::nat b::bool text {* \noindent This resembles a \isacommand{record} definition, but introduces sophisticated locale infrastructure instead of HOL type schemes. The resulting context postulates two distinct names @{term "n"} and @{term "b"} and projection~/ injection functions that convert from abstract values to @{typ "nat"} and @{text "bool"}. The logical content of the locale is: *} locale vars' = fixes n::'name and b::'name assumes "distinct [n, b]" fixes project_nat::"'value => nat" and inject_nat::"nat => 'value" assumes "!!n. project_nat (inject_nat n) = n" fixes project_bool::"'value => bool" and inject_bool::"bool => 'value" assumes "!!b. project_bool (inject_bool b) = b" text {* \noindent The HOL predicate @{const "distinct"} describes distinctness of all names in the context. Locale @{text "vars'"} defines the raw logical content that is defined in the state space locale. We also maintain non-logical context information to support the user: \begin{itemize} \item Syntax for state lookup and updates that automatically inserts the corresponding projection and injection functions. \item Setup for the proof tools that exploit the distinctness information and the cancellation of projections and injections in deductions and simplifications. \end{itemize} This extra-logical information is added to the locale in form of declarations, which associate the name of a variable to the corresponding projection and injection functions to handle the syntax transformations, and a link from the variable name to the corresponding distinctness theorem. As state spaces are merged or extended there are multiple distinctness theorems in the context. Our declarations take care that the link always points to the strongest distinctness assumption. With these declarations in place, a lookup can be written as @{text "s·n"}, which is translated to @{text "project_nat (s n)"}, and an update as @{text "s〈n := 2〉"}, which is translated to @{text "s(n := inject_nat 2)"}. We can now establish the following lemma: *} lemma (in vars) foo: "s<n := 2>·b = s·b" by simp text {* \noindent Here the simplifier was able to refer to distinctness of @{term "b"} and @{term "n"} to solve the equation. The resulting lemma is also recorded in locale @{text "vars"} for later use and is automatically propagated to all its interpretations. Here is another example: *} statespace 'a varsX = vars [n=N, b=B] + vars + x::'a text {* \noindent The state space @{text "varsX"} imports two copies of the state space @{text "vars"}, where one has the variables renamed to upper-case letters, and adds another variable @{term "x"} of type @{typ "'a"}. This type is fixed inside the state space but may get instantiated later on, analogous to type parameters of an ML-functor. The distinctness assumption is now @{text "distinct [N, B, n, b, x]"}, from this we can derive both @{term "distinct [N,B]"} and @{term "distinct [n,b]"}, the distinction assumptions for the two versions of locale @{text "vars"} above. Moreover we have all necessary projection and injection assumptions available. These assumptions together allow us to establish state space @{term "varsX"} as an interpretation of both instances of locale @{term "vars"}. Hence we inherit both variants of theorem @{text "foo"}: @{text "s〈N := 2〉·B = s·B"} as well as @{text "s〈n := 2〉·b = s·b"}. These are immediate consequences of the locale interpretation action. The declarations for syntax and the distinctness theorems also observe the 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 distinctness predicate is refined to operate on balanced trees. Thus we get logarithmic certificates for the distinctness of two names by the distinctness of the paths in the tree. Asked for the distinctness of two names, our tool produces the paths of the variables in the tree (this is implemented in SML, outside the logic) and returns a certificate corresponding to the different paths. Merging state spaces requires to prove that the combined distinctness assumption implies the distinctness assumptions of the components. Such a proof is of the order $m \cdot \log n$, where $n$ and $m$ are the number of nodes 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 of 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 = '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 are known problems with syntax-declarations. They currently only work, when the context is already built. Hopefully this will be implemented correctly in future Isabelle versions. *} lemma includes foo shows True term "s<a := i>·a = i" by simp (* lemma includes foo shows "s<a := i>·a = i" *) text {* It would be nice to have nested state spaces. This is logically no problem. From the locale-implementation side this may be something like an 'includes' into a locale. When there is a more elaborate locale infrastructure in place this may be an easy exercise. *} end
lemma foo:
s〈n := 2〉·b = s·b
lemma foo:
s〈N := 2〉·x = s·x
lemma foo1:
s〈a := i〉·a = i
lemma foo2:
s〈a := i〉·a = i
lemma foo3:
s〈a := i〉·b = s·b
lemma foo4:
s〈a := i, b := j, c := k, a := x〉 = s〈b := j, c := k, a := x〉
lemma bar1:
s〈b := True〉·c = s·c
lemma loo1:
s〈a := i〉·B = s·B
lemma
s〈a := i〉·x = s·x
lemma
s〈A := i〉·a = s·a
lemma
s〈A := i〉·x = s·x
lemma
foo f a b c project_'a inject_'a project_nat_nat_fun inject_nat_nat_fun
project_nat inject_nat project_Int_int inject_Int_int
==> True