datatype Aexp = num of int | loc of string | sum of Aexp * Aexp | diff of Aexp * Aexp | prod of Aexp * Aexp; datatype Bexp = trueb | falseb | eq of Aexp * Aexp | leq of Aexp * Aexp | neg of Bexp | conj of Bexp * Bexp | disj of Bexp * Bexp; datatype Cexp = skip | assign of string * Aexp | seq of Cexp * Cexp | ifthen of Bexp * Cexp * Cexp | whiledo of Bexp * Cexp; val dummy = []:(string*int) list; val state = ref dummy; fun aeq (num n) (num m) = m=n | aeq (loc s) (loc t) = s=t | aeq (sum (a1,a2)) (sum (a3,a4)) = (aeq a1 a3) andalso (aeq a2 a4) | aeq (diff (a1,a2)) (diff (a3,a4)) = (aeq a1 a3) andalso (aeq a2 a4) | aeq (prod (a1,a2)) (prod (a3,a4)) = (aeq a1 a3) andalso (aeq a2 a4) | aeq _ _ = false; fun beq trueb trueb = true | beq falseb falseb = true | beq (eq (a1,a2)) (eq (a3,a4)) = (aeq a1 a3) andalso (seq a2 a4) | beq (leq (a1,a2)) (leq (a3,a4)) = (aeq a1 a3) andalso (seq a2 a4) | beq (neg b1) (neg b2) = (beq b1 b2) | beq (conj (b1,b2)) (conj (b3,b4)) = (beq b1 b3) andalso (beq b2 b4) | beq (disj (b1,b2)) (disj (b3,b4)) = (beq b1 b3) andalso (beq b2 b4) | beq _ _ = false; fun ceq skip skip = true | ceq (assign (s1,a1)) (assign (s2,a2)) = (s1=s2) andalso (aeq a1 a2) | ceq (ifthen (b1,c1,c2)) (ifthen (b2,c3,c4)) = (beq b1 b2) andalso (ceq c1 c3) andalso (ceq c2 c4) | ceq (whiledo (b1,c1)) (whiledo (b2,c2)) = (beq b1 b2) andalso (ceq c1 c2) | ceq _ _ = false; fun lookup [] spot = raise Match | lookup ((l,n)::b) spot = if spot=l then n else lookup b spot; fun aeval (num n) = n | aeval (loc s) = lookup (!state) s | aeval (sum (a1,a2)) = (aeval a1) + (aeval a2) | aeval (diff (a1,a2)) = (aeval a1) - (aeval a2) | aeval (prod (a1,a2)) = (aeval a1) * (aeval a2); fun beval trueb = true | beval falseb = false | beval (eq (a1,a2)) = (aeval a1) = (aeval a2) | beval (leq (a1,a2)) = (aeval a1) <= (aeval a2) | beval (neg b1) = not (beval b1) | beval (conj (b1,b2)) = (beval b1) andalso (beval b2) | beval (disj (b1,b2)) = (beval b1) orelse (beval b2); fun update [] spot value = [(spot,value)] | update ((l,n)::b) spot value = if l=spot then (l,value)::b else (l,n)::(update b spot value); fun ceval skip = state := !state | ceval (assign (s1,a1)) = state := update (!state) s1 (aeval a1) | ceval (seq (c1,c2)) = (ceval c1; ceval c2); ceval (ifthen (b1,c1,c2)) = if (beval b1) then (ceval c1) else (ceval c2) | ceval (whiledo (b1,c1)) = if (beval b1) then (ceval c1;ceval (whiledo (b1,c1))) else state := !state;