module Language.Clafer.Intermediate.Intclafer where
import Language.Clafer.Front.AbsClafer
import Control.Lens
import Data.Data
import Data.Monoid
import Data.Foldable (foldMap)
type UID = String
type CName = String
type URL = String
data Ir
= IRIModule IModule
| IRIElement IElement
| IRIType IType
| IRClafer IClafer
| IRIExp IExp
| IRPExp PExp
| IRIReference (Maybe IReference)
| IRIQuant IQuant
| IRIDecl IDecl
| IRIGCard (Maybe IGCard)
deriving (Eq, Show)
data IType
= TBoolean
| TString
| TInteger
| TReal
| TClafer [UID]
deriving (Eq,Ord,Show,Data,Typeable)
data IModule
= IModule
{ _mName :: String
, _mDecls :: [IElement]
}
deriving (Eq,Ord,Show,Data,Typeable)
data IClafer
= IClafer
{ _cinPos :: Span
, _isAbstract :: Bool
, _gcard :: Maybe IGCard
, _ident :: CName
, _uid :: UID
, _parentUID :: UID
, _super :: Maybe PExp
, _reference :: Maybe IReference
, _card :: Maybe Interval
, _glCard :: Interval
, _elements :: [IElement]
}
deriving (Eq,Ord,Show,Data,Typeable)
data IElement
= IEClafer
{ _iClafer :: IClafer
}
| IEConstraint
{ _isHard :: Bool
, _cpexp :: PExp
}
| IEGoal
{ _isMaximize :: Bool
, _cpexp :: PExp
}
deriving (Eq,Ord,Show,Data,Typeable)
data IReference
= IReference
{ _isSet :: Bool
, _ref :: PExp
}
deriving (Eq,Ord,Show,Data,Typeable)
data IGCard
= IGCard
{ _isKeyword :: Bool
, _interval :: Interval
} deriving (Eq,Ord,Show,Data,Typeable)
type Interval = (Integer, Integer)
data PExp
= PExp
{ _iType :: Maybe IType
, _pid :: String
, _inPos :: Span
, _exp :: IExp
}
deriving (Eq,Ord,Show,Data,Typeable)
type ClaferBinding = Maybe UID
data IExp
= IDeclPExp
{ _quant :: IQuant
, _oDecls :: [IDecl]
, _bpexp :: PExp
}
| IFunExp
{ _op :: String
, _exps :: [PExp]
}
| IInt
{ _iint :: Integer
}
| IDouble
{ _idouble :: Double
}
| IStr
{ _istr :: String
}
| IClaferId
{ _modName :: String
, _sident :: CName
, _isTop :: Bool
, _binding :: ClaferBinding
}
deriving (Eq,Ord,Show,Data,Typeable)
data IDecl
= IDecl
{ _isDisj :: Bool
, _decls :: [CName]
, _body :: PExp
}
deriving (Eq,Ord,Show,Data,Typeable)
data IQuant
= INo
| ILone
| IOne
| ISome
| IAll
deriving (Eq,Ord,Show,Data,Typeable)
type LineNo = Integer
type ColNo = Integer
mapIR :: (Ir -> Ir) -> IModule -> IModule
mapIR f (IModule name decls') =
unWrapIModule $ f $ IRIModule $ IModule name $ map (unWrapIElement . iMap f . IRIElement) decls'
foldMapIR :: (Monoid m) => (Ir -> m) -> IModule -> m
foldMapIR f i@(IModule _ decls') =
(f $ IRIModule i) `mappend` foldMap (iFoldMap f . IRIElement) decls'
foldIR :: (Ir -> a -> a) -> a -> IModule -> a
foldIR f e m = appEndo (foldMapIR (Endo . f) m) e
iMap :: (Ir -> Ir) -> Ir -> Ir
iMap f (IRIElement (IEClafer c)) =
f $ IRIElement $ IEClafer $ unWrapIClafer $ iMap f $ IRClafer c
iMap f (IRIElement (IEConstraint h pexp)) =
f $ IRIElement $ IEConstraint h $ unWrapPExp $ iMap f $ IRPExp pexp
iMap f (IRIElement (IEGoal m pexp)) =
f $ IRIElement $ IEGoal m $ unWrapPExp $ iMap f $ IRPExp pexp
iMap f (IRClafer (IClafer p a grc i u pu Nothing r c goc elems)) =
f $ IRClafer $ IClafer p a (unWrapIGCard $ iMap f $ IRIGCard grc) i u pu Nothing (unWrapIReference $ iMap f $ IRIReference r) c goc $ map (unWrapIElement . iMap f . IRIElement) elems
iMap f (IRClafer (IClafer p a grc i u pu (Just s) r c goc elems)) =
f $ IRClafer $ IClafer p a (unWrapIGCard $ iMap f $ IRIGCard grc) i u pu (Just $ unWrapPExp $ iMap f $ IRPExp s) (unWrapIReference $ iMap f $ IRIReference r) c goc $ map (unWrapIElement . iMap f . IRIElement) elems
iMap f (IRIExp (IDeclPExp q decs p)) =
f $ IRIExp $ IDeclPExp (unWrapIQuant $ iMap f $ IRIQuant q) (map (unWrapIDecl . iMap f . IRIDecl) decs) $ unWrapPExp $ iMap f $ IRPExp p
iMap f (IRIExp (IFunExp o pexps)) =
f $ IRIExp $ IFunExp o $ map (unWrapPExp . iMap f . IRPExp) pexps
iMap f (IRPExp (PExp (Just iType') pID p iExp)) =
f $ IRPExp $ PExp (Just $ unWrapIType $ iMap f $ IRIType iType') pID p $ unWrapIExp $ iMap f $ IRIExp iExp
iMap f (IRPExp (PExp Nothing pID p iExp)) =
f $ IRPExp $ PExp Nothing pID p $ unWrapIExp $ iMap f $ IRIExp iExp
iMap _ x@(IRIReference Nothing) = x
iMap f (IRIReference (Just (IReference is ref))) =
f $ IRIReference $ Just $ IReference is $ (unWrapPExp . iMap f . IRPExp) ref
iMap f (IRIDecl (IDecl i d body')) =
f $ IRIDecl $ IDecl i d $ unWrapPExp $ iMap f $ IRPExp body'
iMap f i = f i
iFoldMap :: (Monoid m) => (Ir -> m) -> Ir -> m
iFoldMap f i@(IRIElement (IEConstraint _ pexp)) =
f i `mappend` (iFoldMap f $ IRPExp pexp)
iFoldMap f i@(IRIElement (IEGoal _ pexp)) =
f i `mappend` (iFoldMap f $ IRPExp pexp)
iFoldMap f i@(IRClafer (IClafer _ _ grc _ _ _ Nothing r _ _ elems)) =
f i `mappend` (iFoldMap f $ IRIReference r) `mappend` (iFoldMap f $ IRIGCard grc) `mappend` foldMap (iFoldMap f . IRIElement) elems
iFoldMap f i@(IRClafer (IClafer _ _ grc _ _ _ (Just s) r _ _ elems)) =
f i `mappend` (iFoldMap f $ IRPExp s) `mappend` (iFoldMap f $ IRIReference r) `mappend` (iFoldMap f $ IRIGCard grc) `mappend` foldMap (iFoldMap f . IRIElement) elems
iFoldMap f i@(IRIExp (IDeclPExp q decs p)) =
f i `mappend` (iFoldMap f $ IRIQuant q) `mappend` (iFoldMap f $ IRPExp p) `mappend` foldMap (iFoldMap f . IRIDecl) decs
iFoldMap f i@(IRIExp (IFunExp _ pexps)) =
f i `mappend` foldMap (iFoldMap f . IRPExp) pexps
iFoldMap f i@(IRPExp (PExp (Just iType') _ _ iExp)) =
f i `mappend` (iFoldMap f $ IRIType iType') `mappend` (iFoldMap f $ IRIExp iExp)
iFoldMap f i@(IRPExp (PExp Nothing _ _ iExp)) =
f i `mappend` (iFoldMap f $ IRIExp iExp)
iFoldMap f i@(IRIReference Nothing) = f i
iFoldMap f i@(IRIReference (Just (IReference _ ref))) =
f i `mappend` (iFoldMap f . IRPExp) ref
iFoldMap f i@(IRIDecl (IDecl _ _ body')) =
f i `mappend` (iFoldMap f $ IRPExp body')
iFoldMap f (IRIElement (IEClafer c)) = iFoldMap f $ IRClafer c
iFoldMap f i = f i
iFold :: (Ir -> a -> a) -> a -> Ir -> a
iFold f e m = appEndo (iFoldMap (Endo . f) m) e
unWrapIModule :: Ir -> IModule
unWrapIModule (IRIModule x) = x
unWrapIModule x = error $ "Can't call unWarpIModule on " ++ show x
unWrapIElement :: Ir -> IElement
unWrapIElement (IRIElement x) = x
unWrapIElement x = error $ "Can't call unWarpIElement on " ++ show x
unWrapIType :: Ir -> IType
unWrapIType (IRIType x) = x
unWrapIType x = error $ "Can't call unWarpIType on " ++ show x
unWrapIClafer :: Ir -> IClafer
unWrapIClafer (IRClafer x) = x
unWrapIClafer x = error $ "Can't call unWarpIClafer on " ++ show x
unWrapIExp :: Ir -> IExp
unWrapIExp (IRIExp x) = x
unWrapIExp x = error $ "Can't call unWarpIExp on " ++ show x
unWrapPExp :: Ir -> PExp
unWrapPExp (IRPExp x) = x
unWrapPExp x = error $ "Can't call unWarpPExp on " ++ show x
unWrapIReference :: Ir -> Maybe IReference
unWrapIReference (IRIReference x) = x
unWrapIReference x = error $ "Can't call unWarpIReference on " ++ show x
unWrapIQuant :: Ir -> IQuant
unWrapIQuant (IRIQuant x) = x
unWrapIQuant x = error $ "Can't call unWarpIQuant on " ++ show x
unWrapIDecl :: Ir -> IDecl
unWrapIDecl (IRIDecl x) = x
unWrapIDecl x = error $ "Can't call unWarpIDecl on " ++ show x
unWrapIGCard :: Ir -> Maybe IGCard
unWrapIGCard (IRIGCard x) = x
unWrapIGCard x = error $ "Can't call unWarpIGcard on " ++ show x
instance Plated IClafer
instance Plated PExp
instance Plated IExp
makeLenses ''IModule
makeLenses ''IClafer
makeLenses ''IElement
makeLenses ''IReference
makeLenses ''IGCard
makeLenses ''PExp
makeLenses ''IExp
makeLenses ''IDecl