Here are a few things you can write in GimML.
The following declares a type of first-order terms, where application is written using an infix operator $
(the 0
in the declaration infix 0 $
declares it with precedence 0, but let us skip that). This is just as in Standard ML. A term is either a variable, for example V "x"
(standing for x), or an application, say "f" $ [V "x"]
(standing for f(x)).
infix 0 $
datatype term = V of string
| $ of string * term listi
Now here is something particular to GimML. A substitution theta
is a map from variable names (of type string
) to terms. A GimML map is just a table: you may think of it as a hash table; if you are more mathematically minded, it is a function with finite domain.
It is easy to define a substitution function tsubst
, which applies a substitution theta
to a term t
. I will give the definition below. Its type is:
tsubst : (string -m> term) -> term -> term
Note that the type of maps from string
to term
is written with the map arrow operator -m>
. Let us apply it to an example. We define two constants a
and b
, two helper functions that build applications of function symbols f
and g
respectively, then two terms t1
and t2
. theta
is our first substitution!
val a = "a" $ []; (* the constant a *)
val b = "b" $ []; (* the constant b *)
fun f (s, t) = "f" $ [s, t]; (* applying the binary function symbol f *)
fun g (t) = "g" $ [t]; (* applying the unary function symbol g *)
val t1 = f (a, g (a)); (* a first term *)
val t2 = f(a,f(b,g(f(a,b)))); (* a second term *)
val theta = {"x" => t1, "y" => t2}; (* a substitution *)
Now can you guess what the following term will evaluate to?
tsubst theta (f (V "x", V "y"));
Try it under the GimML toplevel, and compare that to the expected term f (t1
, t2
) = f(f(a,g(a)), f(a,f(b,g(f(a,b))))).
Oh, and here is the definition of tsubst
, in case you would like to see how it is done.
fun tsubst (theta : string -m> term) =
let fun tsubst_theta (V x) =
if x inset theta (* if x is in the domain of theta *)
then ?theta x (* read off the value associated with x in theta, *)
else V x (* else return the variable itself *)
| tsubst_theta (f $ l) =
f $ [tsubst_theta t | t in list l] (* list comprehension *)
in
tsubst_theta
end;