module Language.Clafer.Intermediate.Resolver where
import Control.Monad
import Control.Monad.State
import qualified Data.Map as Map
import qualified Data.StringMap as SMap
import Language.Clafer.Common
import Language.Clafer.ClaferArgs
import Language.Clafer.Intermediate.Intclafer
import Language.Clafer.Intermediate.ResolverName
import Language.Clafer.Intermediate.ResolverType
import Language.Clafer.Intermediate.ResolverInheritance
resolveModule :: ClaferArgs -> IModule -> Resolve (IModule, GEnv)
resolveModule args' imodule =
do
r <- resolveNModule $ nameModule (skip_resolver args') imodule
resolveNamesModule args' =<< (rom' $ rem' r)
where
rem' = if flatten_inheritance args' then resolveEModule else id
rom' = if skip_resolver args' then return . id else resolveOModule
nameModule :: Bool -> IModule -> (IModule, GEnv)
nameModule skipResolver imodule = (imodule', genv'')
where
(decls', genv') = runState (mapM (nameElement skipResolver "root") $ _mDecls imodule) $ GEnv Map.empty 0 Map.empty [] SMap.empty
imodule' = imodule{_mDecls = decls'}
genv'' = genv'{uidClaferMap = createUidIClaferMap imodule'}
nameElement :: MonadState GEnv m => Bool -> UID -> IElement -> m IElement
nameElement skipResolver puid x = case x of
IEClafer claf -> IEClafer `liftM` (nameClafer skipResolver puid claf)
IEConstraint isHard' pexp -> IEConstraint isHard' `liftM` (namePExp pexp)
IEGoal isMaximize' pexp -> IEGoal isMaximize' `liftM` (namePExp pexp)
nameClafer :: MonadState GEnv m => Bool -> UID -> IClafer -> m IClafer
nameClafer skipResolver puid claf = do
claf' <- if skipResolver then return claf{_uid = _ident claf, _parentUID = puid} else renameClafer True puid claf
elements' <- mapM (nameElement skipResolver (_uid claf')) $ _elements claf
return $ claf' {_elements = elements'}
namePExp :: MonadState GEnv m => PExp -> m PExp
namePExp pexp@(PExp _ _ _ exp') = do
n <- gets expCount
modify (\e -> e {expCount = 1 + n})
exp'' <- nameIExp exp'
return $ pexp {_pid = concat [ "e", show n, "_"], _exp = exp''}
nameIExp :: MonadState GEnv m => IExp -> m IExp
nameIExp x = case x of
IDeclPExp quant' decls' pexp -> do
decls'' <- mapM nameIDecl decls'
pexp' <- namePExp pexp
return $ IDeclPExp quant' decls'' pexp'
IFunExp op' pexps -> IFunExp op' `liftM` (mapM namePExp pexps)
_ -> return x
nameIDecl :: MonadState GEnv m => IDecl -> m IDecl
nameIDecl (IDecl isDisj' dels body') = IDecl isDisj' dels `liftM` (namePExp body')
resolveNamesModule :: ClaferArgs -> (IModule, GEnv) -> Resolve (IModule, GEnv)
resolveNamesModule args' (imodule, genv') =
do
imodule' <- foldM (flip ($)) imodule $ map (\f -> flip (curry f) genv') funs
return (imodule', genv'{uidClaferMap = createUidIClaferMap imodule'})
where
funs :: [(IModule, GEnv) -> Resolve IModule]
funs
| skip_resolver args' = [return . analyzeModule, resolveRedefinition, resolveTModule]
| otherwise = [ return . analyzeModule, resolveModuleNames, resolveRedefinition, resolveTModule]