123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- A calculus of definitions, with normalisation as evaluation
- -------------------------
- We present a small calculus with constructors and functions
- defined by pattern-matching. The difficulty is to do computations
- on open terms and to give the result in the expected form.
- Example: f 0 = 0, f (S x) = f x
- We may want to evaluate f (S (S X)), X variable. The expected form
- for the result is f X.
- We give a simple way to implement this language, using the idea
- of normalisation as evaluation. We describe a notion of values for the
- language, and the normal form of an expression will be its semantics.
- More example: we want to be able to define (all definitions are recursive)
- f 0 = 0
- f (S n) = g n
- g 0 = S 0
- g (S n) = f n
- h 0 = g (f 0)
- h (S n) = g (h n)
- and then to evaluate symbolically, for instance
- h (S (S x))
- the result should be g (g (h x))
- We want also to have definitions inside a definition. For instance
- f x = let
- h 0 = x
- h (S n) = f (h n)
- in h x
- If we evaluate symbolically f (S y), the result will be f ((f y).h y)
- If we rewrite this naively we get f (h y).
- Notice that the name h is local to the function f. We represent this
- by writing (f y).h instead of h. We indicate that this is the function
- h, which occurs in the definition of f, with the argument y.
- 1. Basic language
- --------------
- Language: syntax of terms
- M ::= x | M M | \x M | c M1 ... Mk
- The name x can be a variable bound by an abstraction, or by a definition.
- The definitions are
- E ::= \ x E | D E | H
- H ::= M | F
- F ::= <c1 E1,...,ck Ek>
- D ::= x1=E1,...,xn=En
- The definitions are recursive.
- V ::= Lam f | N | c V1 ... Vk
- N ::= P | N V | P N
- P ::= () | P.x | P V
- We define [M]r as usual.
- [x]r = r(x)
- [M1 M2]r = [M1]r ([M2]r)
- [\x M]r = Lam f where f V = [M](r,x=V)
- The crucial point is the computation of [D](P,r)
- [D](P,r) is x1 = V1,...,xn = Vn
- where
- Vi = [Ei](P.xi,r') with r' = r,x1=V1,...,xn=Vn
- [\x E](P,r) = Lam f where f V = [E](P V,(r,x=V))
- [D E] (P,r) = [E](P,r') where r' = r + [D](P,r)
- [M](P,r) = [M]r
- [<c1 E1,...,ck Ek>](P,r) = Lam f
- where f (ci w) = [Ei](P,r) w
- f V = P V if V is not of the form ci w
- 2. Addition of infinite objects
- -----------------------------
- To see how we can represent infinite objects, we can add records
- (that may be infinite)
- M ::= x | M M | \x M | c M1 ... Mk | M.x
- E ::= \ x E | D E | H
- H ::= M | F | R
- R ::= (x1=M1,...,xn=Mn)
- The new values are
- V ::= Lam f | N | c V1 ... Vk | (P,W)
- N ::= P | N V | P N | N.x
- P ::= () | P.x | P V
- W ::= (x1 = V1,...,xn=Vn)
- We have added "infinite values" (P,W) that have
- two components.
- If R = (x1=M1,...,xn=Mn) we define [R](P,r) as
- (P,(x1 = [M1]r,...,xn = [Mn]r))
- Examples:
- f = (u = f,v = 0)
- This is an infinite object. If we compute [f] we get
- (f,(u=[f],v=0))
- If we compute [f.u] we get the same as [f] and if we
- compute [f.v] we get 0.
- Another example is
- f = \ x (u = f 0,v = f (f x))
- We can then form
- f (S 0)
- the value is [f (S 0)] = (f (S 0),V) where
- V = (u = [f 0],v = [f (f (S 0))])
-
- Thus if we take (f (S 0)).u we get something of the form
- (f 0,...).
- 3. Package
- -------
- We can package the definitions arbitrarily, with parameters. This is actually
- definable as soon as we have records.
- p = \ x1...\ xk D1...Dn (y1 = y1,...,ym = ym)
- where y1,...,ym are the definitions among D1,...,Dn that we want to make
- accessible for outside.
- For instance
- p = \ x
- let
- w = (u = x,v = f 0)
- f 0 = x
- f (S n) = (u = f n,v = w)
- in
- (w=w,f = f)
- We can then consider
- (p 0).f (S 0)
- which has for values
- (p 0).f (S 0), (u = 0,v = (p 0).w)
- Thus if we compute ((p 0).f (S 0)).v we get (p 0).w
-
|