{- $Id: PPT.hs,v 1.20.2.31 2009/02/20 18:00:02 orlov Exp $ -}
{- vim: set syntax=haskell expandtab tabstop=4: -}
module PPT (
Tree(..),
getTid, ppt
) where
import Prelude
import List (partition)
import Maybe (mapMaybe)
import XSG
------------------------------ DATA ------------------------------
type Tid = Index
type Tids = [Tid]
type Needs = Tids
data Tree = LEAF Exps | NODE State [(Subst, Tree)]
------------------------------ SHOW ------------------------------
instance MyShow Tree where
myShow (LEAF es ) = "LEAF\n "++(myShow es)++"\n\n"
myShow (NODE st brs) = "NODE\n"++(shiftStr " " $ myShow st)++"\n"++
(myShow brs)
instance MyShow (Subst, Tree) where
myShow (s, tree) = (myShow s)++" :=> "++(myShow tree)
instance MyShow [(Subst, Tree)] where
myShow trs = concatMap myShow trs
------------------------------ TIDS ------------------------------
getTid :: Term -> Tid
getTid (((L idx):_):=_) = idx
findTerm :: Tid -> Terms -> (Term, Terms)
findTerm ti ts = (t, ts')
where ([t], ts') = partition ((ti==) . getTid) ts
mkTids :: Vars -> Terms -> Tids
mkTids vs ts = [getTid t | t@(vs':=_) <- ts, (not.null) (vs'*.vs)]
mkNeeds :: Needs -> State -> Needs
mkNeeds nds (ts, cd, res) = nds+.(mkTids (vs1+.vs2) ts)
where vs1 = getTopLVars cd
vs2 = getLVars res
------------------------------ PPT -------------------------------
ppt :: Prog -> Exps -> Index -> Tree
ppt prog arg idx = eval prog st (mkNeeds [] st) idx1
where main = head prog
res = fresh (funcCoarity main) L idx2
st = ([res:=(funcName main, arg)], [], v2e res)
-- idx1:idx2:_ = newIdxs idx
idx2:idx1:_ = newIdxs idx
eval :: Prog -> State -> Needs -> Index -> Tree
eval prog st@(_ , _ , res) [] idx = LEAF res
eval prog st@(ts, cd, res) (ti:nds) idx = NODE st (map g ssts')
where (vs:=(fN, arg), ts') = findTerm ti ts
FUNC _ vsB body = findFunc fN prog idx1
ssts = mapMaybe (evalState . f) (body/.(mkSubst vsB arg))
ssts' = filter isNoYVars ssts
f (tsB,cdB,resB)=(tsB++ts',cdB++cd,res)/.(mkSubst vs resB)
g (s, st) = (s, eval prog st (mkNeeds nds st) idx2)
-- idx1:idx2:_ = newIdxs idx
idx1@(i:is) = idx
idx2 = (i+1):is
evalState :: State -> Maybe (Subst, State)
evalState (ts, cd, res) =
do (sW, sL, sX) <- fmap unmixSubst (mgu cd)
let (ts', res') = (ts, res)/.sW/.sX
sLX = renaming X (getLVars sX)
sWX = renaming X (getWVars sX)
renaming f = map (\v -> v:->(v2e $ mkVar v))
where mkVar (W idx) = f idx
mkVar (L idx) = f idx
mkVar (X idx) = f idx
return $ (sX/.sLX, (ts', v2e (sL++sLX), res'))/.sWX
isNoYVars :: (Subst, State) -> Bool
isNoYVars (_, (_, _, res)) = getYVars res == []