visual-graphrewrite-0.4.0.1: GraphRewrite/Internal/RewriteApp.hs
-- | This module contains functions to convert a 'SimpleHaskell' module to a 'RewriteSystem'.
module GraphRewrite.Internal.RewriteApp
( makeRewriteRules, makeRewriteSystem )
where
import Prelude hiding (exp)
import qualified Data.IntMap as I
import qualified Data.List as L
import GraphRewrite.Internal.RewriteTypes
import qualified GraphRewrite.Internal.SimpleHaskell as SH
-- | Create a 'RewriteSystem' from a Haskell module with 'Int' identifiers.
makeRewriteSystem
:: SH.SimpModule Int -- ^ A Haskell module with identifiers already replaced by unique integers.
-> I.IntMap String -- ^ A mapping from identifiers to names
-> RewriteSystem
makeRewriteSystem m nms = (makeRewriteRules m) { names = nms }
-- | Build the rules part of a 'RewriteSystem'.
makeRewriteRules :: SH.SimpModule Int -> RewriteSystem
makeRewriteRules [] = defaultRS
makeRewriteRules (h:t) = case I.lookup hid (rules rest) of -- FIXME vv
Just rs -> defaultRS { rules = I.insert hid (extend rs h) (rules rest) }
Nothing -> defaultRS { rules = I.insert hid (extend [] h) (rules rest) }
where
hid = SH.name' h
rest = makeRewriteRules t
extend l (SH.FunBind as) = L.nub $ l ++ map makeRule as
extend l (SH.PatBind (SH.Var v) e) = extend l (SH.FunBind [(v, [], e)]) -- special case to handle variable bindings
extend l _ = l
makeRule :: SH.FunAlt Int -> Rule
makeRule (_, ps, e) = fixExpr Rule { patts = map makePat ps,
exp = makeRefExpr e,
graph = makeGraph (e:ps) }
makePat :: SH.Expr Int -> Expr
makePat (SH.AsPat _ e) = makeExpr e
makePat x = makeExpr x
makeExpr :: SH.Expr Int -> Expr
makeExpr (SH.Var v) = SHole v
makeExpr (SH.Cons c) = SCons c
makeExpr (SH.Lit l) = SLit l
makeExpr (SH.Let _ e) = makeRefExpr e
makeExpr (SH.Apply ((SH.Lit l):t)) = SApp (SLit l) (map makeExpr t) -- this really shouldn't be used.
makeExpr (SH.Apply ((SH.Cons c):t)) = SApp (SCons c) (map makeExpr t)
makeExpr (SH.Apply ((SH.Var v):t)) = SApp (SFun (length t) v) (map makeExpr t)
makeExpr (SH.Apply (h@(SH.Apply (_:_)):t)) = uncurry SApp la
where
la = liftApp $ makeExpr h
liftApp (SApp (SFun a f) l) = (SFun (a + length t) f, l ++ map makeExpr t)
liftApp (SApp (SCons c) l) = (SCons c, l ++ map makeExpr t)
makeRefExpr :: SH.Expr Int -> Expr
makeRefExpr = holeToRef . makeExpr
where
holeToRef (SHole h) = SRef h
holeToRef (SApp e es) = SApp (holeToRef e) (map holeToRef es)
holeToRef e = e
fixExpr :: Rule -> Rule
fixExpr r@(Rule {exp = e, graph = g}) = r { exp = doFix e }
where
doFix x@(SHole h) = case I.lookup h g of
Just _ -> SRef h
_ -> x
doFix (SApp e es) = SApp (doFix e) (map doFix es)
doFix x = x
makeGraph :: [SH.Expr Int] -> Graph
makeGraph (p:ps) = case p of
SH.AsPat a e -> I.insert a (makeExpr e) (makeGraph ps)
SH.Let ((SH.PatBind p pe):ds) e -> let patid = read (exprID $ makePat p) :: Int in
I.insert patid (makeRefExpr pe) (makeGraph (SH.Let ds e : ps))
SH.Let [] _ -> makeGraph ps --redundant
SH.Let ((SH.FunBind _):_) _ -> error "makeGraph error: FunBinds unsupported in Let"
_ -> makeGraph ps
makeGraph [] = I.empty
{- invMakeExpr :: Expr -> SH.Expr Int
invMakeExpr (SCons c) = SH.Cons c
invMakeExpr (SLit l) = SH.Lit l
invMakeExpr (SFun _ f) = SH.Var f
invMakeExpr (SHole v) = SH.Lit ("THIS IS A BUG - " ++ show v)
invMakeExpr (SApp x xs) = SH.Apply (invMakeExpr x : map invMakeExpr xs)
-}