{-
Haskell version of ...
! rewrite functions for Boyer benchmark
! Started by Tony Kitto on 30 March 1988
! Changes Log
! 08-04-88 ADK bug fix = rewrite(Atom(x),A) returns Atom(x) not Nil
! 25-05-88 ADK added applysubst to this module and assoclist replaced by LUT
Haskell version:
23-06-93 JSM initial version
-}
module Rewritefns (applysubst, rewrite) where
import Lisplikefns
applysubst :: Lisplist -> Lisplist -> Lisplist
applysubst alist Nil = Nil
applysubst alist term@(Atom x) =
case assoc (term, alist) of
Cons (yh, yt) -> yt
_ -> term
applysubst alist (Cons (x, y)) = Cons (x, applysubstlst alist y)
applysubstlst :: Lisplist -> Lisplist -> Lisplist
applysubstlst alist Nil = Nil
applysubstlst alist (Atom x) = error "Malformed list"
applysubstlst alist (Cons (x, y)) =
Cons (applysubst alist x, applysubstlst alist y)
rewrite :: Lisplist -> LUT -> Lisplist
rewrite Nil term = Nil
rewrite expr@(Atom x) term = expr
rewrite (Cons (l1, l2)) term =
rewritewithlemmas (Cons (l1, rewriteargs l2 term))
(getLUT (tv l1, term)) term
rewriteargs :: Lisplist -> LUT -> Lisplist
rewriteargs Nil term = Nil
rewriteargs (Atom x) term = error "Malformed list"
rewriteargs (Cons (x, y)) term = Cons (rewrite x term, rewriteargs y term)
rewritewithlemmas :: Lisplist -> [Lisplist] -> LUT -> Lisplist
rewritewithlemmas t [] term = t
rewritewithlemmas t (lh:lt) term
| b = rewrite (applysubst u (caddr lh)) term
| otherwise = rewritewithlemmas t lt term
where (b, u) = onewayunify t (cadr lh)
onewayunify :: Lisplist -> Lisplist -> (Bool, Lisplist)
onewayunify t1 t2 = onewayunify1 t1 t2 Nil
onewayunify1 :: Lisplist -> Lisplist -> Lisplist -> (Bool, Lisplist)
onewayunify1 t1 t2 u | atom t2 = case assoc (t2, u) of
Cons (x, y) -> (t1 == y, u)
_ -> (True, Cons (Cons (t2, t1), u))
| atom t1 = (False, u)
| car t1 == car t2 = onewayunify1lst (cdr t1) (cdr t2) u
| otherwise = (False, u)
onewayunify1lst :: Lisplist -> Lisplist -> Lisplist -> (Bool, Lisplist)
onewayunify1lst Nil _ u = (True, u)
onewayunify1lst l1 l2 u
| b = onewayunify1lst (cdr l1) (cdr l2) u1
| otherwise = (False, u1)
where (b, u1) = onewayunify1 (car l1) (car l2) u
|