let rec ------------------------------------------- semantic types ------------ type Val = IntVal Int + -- Int BoolVal Bool + -- Bool ListVal Val Val + NilVal + -- Lists FnVal (Val->Kont->State->Val) + -- Abstractions Thunk (Kont->State->Val) + -- params, bindings LogicVar Locn + -- see Store unground + -- unground LogicVar's value Wrong String -- error and type Env == Ide -> Val -- rho :Env, maps Identifiers to their values and rho0 x = Wrong("undeclared: " @ x) -- empty, initial environment and type Locn == Int -- "addresses" of logic variables and type Store == Locn -> Val -- gives Vals of logic vars if known and s0 addr = unground and type State = st Locn Store -- freeCounter # Store and st0 = st 0 s0 and type Kont == Val -> State -> Val -- Expression Kontinuations and k0 = Copy 0 and deref (LogicVar n) k (st f s) = let v = s n in case v in unground : k (LogicVar n) (st f s) || LogicVar m: deref (LogicVar m) k (st f s) || v : deref v k (st f s) end || deref (Thunk t) k s = let k2 v = deref v k in t k2 s || deref v k s = k v s and ShowVal (IntVal n) = itos n || ShowVal (BoolVal b) = if b then "T" else "F" || ShowVal (ListVal h t) = "(" @ (ShowVal h) @ "::" @ (ShowVal t) @ ")" || ShowVal NilVal = "Nil" || ShowVal (FnVal f) = "function()" || ShowVal (Thunk _) = "thunk" || ShowVal (LogicVar n) = "LV_" @ (itos n) || ShowVal unground = "unground" || ShowVal (Wrong s) = "Wrong: " @ s and Copy f (LogicVar n) s = let k (LogicVar n) s &(n>=f) = unground || -- a "local" unground one k (LogicVar n) s = LogicVar n || -- non-local unground k v s = Copy f v s -- ground to v in deref (LogicVar n) k s || Copy f (ListVal h t) s = ListVal (Copy f h s) (Copy f t s) || Copy f (Thunk t) s = t (Copy f) s || Copy f v _ = v and append NilVal L = L || append (ListVal h t) L = ListVal h (append t L) and update f x v y = if x=y then v else f y -- esp' f is Store or Env in let rec -------------------------------------------------------------------- -- E : Exp -> Env -> Kont -> State -> Val E (Ident x) rho k s = deref (rho x) k s || E (Num n) _ k s = k(IntVal n) s || E (Boolean b) _ k s = k(BoolVal b) s || E NIL _ k s = k(NilVal) s || E (LogicExp x C) rho k (st f s) = -- list of x s.t. constraint C let rho2 = update rho x (LogicVar f) and st2 = st (f+1) s in let k2 (BoolVal b) st3 = if b then let k3 v s = ListVal (Copy f v st3) NilVal in E (Ident x) rho2 k3 st3 -- one soln else NilVal -- no solution in k( E C rho2 k2 st2 ) (st f s) || E (Block isRec Local Body) rho k s = E Body (D isRec Local rho) k s || E (Apply Fn Actual) rho k s = let k2 (FnVal f) s = f (Thunk(E Actual rho)) k s in E Fn rho k2 s || E (LambdaExp x Body) rho k s = let f v = E Body (update rho x v) in k (FnVal f) s || E (IfExp Se Te Fe) rho k s = let k2 (BoolVal b) = E (if b then Te else Fe) rho k in E Se rho k2 s || E (UExp Opr Argh) rho k s = let k2 v = let k3 v = U Opr v k in deref v k3 in E Argh rho k2 s || E (BExp consSy A1 A2) rho k s = B consSy (Thunk(E A1 rho)) (Thunk(E A2 rho)) k s || -- cons lazy E (BExp Opr A1 A2) rho k s = let k1 v1 = let k1b v1 = let k2 v2 = let k2b v2 = B Opr v1 v2 k in deref v2 k2b in E A2 rho k2 in deref v1 k1b in E A1 rho k1 s -- D : Bool -> Dec -> Env -> Env and D isRec L oldRho = let rec newRho = DD L (if isRec then newRho else oldRho) oldRho and DD (Decs d1 ds) useRho grow = DD d1 useRho (DD ds useRho grow) || DD (Bind x e) useRho grow = let eVal = Thunk(E e useRho) in update grow x eVal in newRho --------------------------------------------------------------------- Operators and setHT n (st f s) = -- bind H::T to n where H, T new logic vars let H=LogicVar f and T=LogicVar(f+1) -- new Locns in st (f+2) (update s n (ListVal H T)) -- n := H::T and U plusSy (IntVal n) k s = k(IntVal n) s || U minusSy (IntVal n) k s = k(IntVal (-n)) s || U notSy (BoolVal b) k s = k(BoolVal (~b)) s || U nullSy (ListVal _ _) k s = k(BoolVal false) s || U nullSy NilVal k s = k(BoolVal true) s || U nullSy (LogicVar n) k (st f s) = append (k (BoolVal true) (st f (update s n NilVal))) -- nil or ... (k (BoolVal false) (setHT n (st f s))) || -- ... not nil U hdSy (ListVal h t) k s = k h s || U tlSy (ListVal h t) k s = k t s || U hdSy (LogicVar n) k (st f s) = k (LogicVar f) (setHT n (st f s)) || U tlSy (LogicVar n) k (st f s) = k (LogicVar (f+1)) (setHT n (st f s)) ------------------------------------------------------------------------------- and B eqSy (LogicVar n) v k (st f s) = -- Unification append (k(BoolVal true )(st f (update s n v))) (k(BoolVal false)(st f s)) || -- ??? should constrain n<>v B eqSy v (LogicVar n) k s = B eqSy (LogicVar n) v k s || -- switch B consSy h t k s = k (ListVal h t) s || B opr (IntVal m) (IntVal n) k s = case opr in plusSy : k(IntVal( m+n )) s || minusSy : k(IntVal( m-n )) s || timesSy : k(IntVal( m*n )) s || divSy : k(IntVal( m%n )) s || eqSy : k(BoolVal( m=n)) s || neSy : k(BoolVal( m~=n)) s || leSy : k(BoolVal( m<=n )) s || ltSy : k(BoolVal( m=n )) s || gtSy : k(BoolVal( m>n )) s end || B opr (BoolVal p) (BoolVal q) k s = case opr in orSy : k(BoolVal( p|q )) s || andSy : k(BoolVal( p&q )) s end ------------------------------------------------------------------------------- -- Executable Denotational Semantics of Lambda Calculus / FP -- Continuation Style -- (c) L. Allison 1994