clafer 0.4.3 → 0.4.4
raw patch · 50 files changed
+8539/−6394 lines, 50 filesdep +faildep +semigroupsdep ~aesondep ~claferdep ~lens-aesonsetup-changedPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: fail, semigroups
Dependency ranges changed: aeson, clafer, lens-aeson, transformers-compat
API changes (from Hackage documentation)
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Abstract
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Assertion
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Card
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Clafer
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Constraint
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Decl
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Declaration
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Element
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Elements
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0EnumId
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0ExInteger
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0GCard
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Goal
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Init
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0InitHow
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0LocId
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0ModId
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Module
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0NCard
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Name
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Pos
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0PosAlloy
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0PosBlockComment
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0PosChoco
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0PosDouble
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0PosIdent
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0PosInteger
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0PosLineComment
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0PosReal
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0PosString
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Quant
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Reference
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Span
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_0Super
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_10Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_11Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_12Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_13Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_14Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_15Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_16Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_17Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_18Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_19Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_1Abstract
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_1Card
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_1Declaration
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_1Element
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_1Elements
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_1ExInteger
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_1Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_1GCard
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_1Goal
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_1Init
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_1InitHow
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_1Quant
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_1Reference
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_1Super
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_20Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_21Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_22Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_23Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_24Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_25Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_26Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_27Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_28Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_29Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_2Card
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_2Element
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_2Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_2GCard
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_2Goal
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_2Quant
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_2Reference
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_30Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_31Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_32Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_33Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_34Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_35Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_36Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_37Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_38Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_39Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_3Card
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_3Element
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_3Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_3GCard
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_3Goal
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_3Quant
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_40Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_41Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_42Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_43Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_4Card
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_4Element
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_4Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_4GCard
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_4Quant
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_5Card
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_5Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_5GCard
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_6Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_7Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_8Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Constructor Language.Clafer.Front.AbsClafer.C1_9Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Abstract
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Assertion
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Card
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Clafer
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Constraint
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Decl
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Declaration
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Element
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Elements
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1EnumId
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1ExInteger
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Exp
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1GCard
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Goal
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Init
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1InitHow
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1LocId
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1ModId
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Module
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1NCard
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Name
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Pos
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1PosAlloy
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1PosBlockComment
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1PosChoco
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1PosDouble
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1PosIdent
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1PosInteger
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1PosLineComment
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1PosReal
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1PosString
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Quant
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Reference
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Span
- Language.Clafer.Front.AbsClafer: instance GHC.Generics.Datatype Language.Clafer.Front.AbsClafer.D1Super
- Language.Clafer.Front.LexClafer: iUnbox :: Int -> Int#
+ Language.Clafer.Front.LexClafer: alex_tab_size :: Int
+ Language.Clafer.Generator.Concat: infixr 5 +++
+ Language.Clafer.Intermediate.ResolverName: resolveTopLevelName :: Span -> SEnv -> String -> Resolve (HowResolved, String, [IClafer])
+ Language.Clafer.Intermediate.ResolverName: resolveTopLevelOnly :: Span -> SEnv -> String -> Resolve (Maybe (HowResolved, String, [IClafer]))
- Language.Clafer.Common: apply :: (t -> t1) -> t -> (t, t1)
+ Language.Clafer.Common: apply :: forall t t1. (t -> t1) -> t -> (t, t1)
- Language.Clafer.Common: bfs :: (b1 -> (b, [b1])) -> [b1] -> [b]
+ Language.Clafer.Common: bfs :: forall b b1. (b1 -> (b, [b1])) -> [b1] -> [b]
- Language.Clafer.Common: fst3 :: (t, t1, t2) -> t
+ Language.Clafer.Common: fst3 :: forall t t1 t2. (t, t1, t2) -> t
- Language.Clafer.Common: lurry :: ([t1] -> t) -> t1 -> t1 -> t
+ Language.Clafer.Common: lurry :: forall t t1. ([t1] -> t) -> t1 -> t1 -> t
- Language.Clafer.Common: snd3 :: (t, t1, t2) -> t1
+ Language.Clafer.Common: snd3 :: forall t t1 t2. (t, t1, t2) -> t1
- Language.Clafer.Common: toMTriple :: t -> (t1, t2) -> Maybe (t, t1, t2)
+ Language.Clafer.Common: toMTriple :: forall t t1 t2. t -> (t1, t2) -> Maybe (t, t1, t2)
- Language.Clafer.Common: toTriple :: t -> (t1, t2) -> (t, t1, t2)
+ Language.Clafer.Common: toTriple :: forall t t1 t2. t -> (t1, t2) -> (t, t1, t2)
- Language.Clafer.Common: trd3 :: (t, t1, t2) -> t2
+ Language.Clafer.Common: trd3 :: forall t t1 t2. (t, t1, t2) -> t2
- Language.Clafer.Front.LexClafer: alexScan :: AlexInput -> Int -> AlexReturn (Posn -> [Char] -> Token)
+ Language.Clafer.Front.LexClafer: alexScan :: (Posn, Char, [Byte], String) -> Int -> AlexReturn (Posn -> String -> Token)
- Language.Clafer.Front.LexClafer: alexScanUser :: t -> AlexInput -> Int -> AlexReturn (Posn -> [Char] -> Token)
+ Language.Clafer.Front.LexClafer: alexScanUser :: t -> (Posn, Char, [Byte], String) -> Int -> AlexReturn (Posn -> String -> Token)
- Language.Clafer.Front.LexClafer: alex_scan_tkn :: t -> t1 -> Int# -> AlexInput -> Int# -> AlexLastAcc (Posn -> [Char] -> Token) -> (AlexLastAcc (Posn -> [Char] -> Token), AlexInput)
+ Language.Clafer.Front.LexClafer: alex_scan_tkn :: t -> t1 -> Int# -> AlexInput -> Int# -> AlexLastAcc (Posn -> String -> Token) -> (AlexLastAcc (Posn -> String -> Token), (Posn, Char, [Byte], String))
- Language.Clafer.Front.LexClafer: quickIndex :: Array Int (AlexAcc (Posn -> [Char] -> Token) (Any *)) -> Int -> AlexAcc (Posn -> [Char] -> Token) (Any *)
+ Language.Clafer.Front.LexClafer: quickIndex :: Array Int (AlexAcc (Posn -> String -> Token) (Any *)) -> Int -> AlexAcc (Posn -> String -> Token) (Any *)
- Language.Clafer.Front.ParClafer: happyThen1 :: Err a -> (a -> t -> Err b) -> t -> Err b
+ Language.Clafer.Front.ParClafer: happyThen1 :: Err t -> (t -> t1 -> Err b) -> t1 -> Err b
- Language.Clafer.Intermediate.ResolverName: resolve :: (Monad f, Functor f) => SEnv -> String -> [SEnv -> String -> f (Maybe b)] -> f b
+ Language.Clafer.Intermediate.ResolverName: resolve :: Monad f => SEnv -> String -> [SEnv -> String -> f (Maybe b)] -> f b
- Language.Clafer.Intermediate.StringAnalyzer: astrClafer :: Functor m => MonadState (Map String Int) m => IClafer -> m IClafer
+ Language.Clafer.Intermediate.StringAnalyzer: astrClafer :: MonadState (Map String Int) m => IClafer -> m IClafer
- Language.Clafer.Intermediate.StringAnalyzer: astrElement :: Functor m => MonadState (Map String Int) m => IElement -> m IElement
+ Language.Clafer.Intermediate.StringAnalyzer: astrElement :: MonadState (Map String Int) m => IElement -> m IElement
- Language.Clafer.Intermediate.StringAnalyzer: astrIExp :: Functor m => MonadState (Map String Int) m => IExp -> m IExp
+ Language.Clafer.Intermediate.StringAnalyzer: astrIExp :: MonadState (Map String Int) m => IExp -> m IExp
- Language.Clafer.Intermediate.StringAnalyzer: astrPExp :: Functor m => MonadState (Map String Int) m => PExp -> m PExp
+ Language.Clafer.Intermediate.StringAnalyzer: astrPExp :: MonadState (Map String Int) m => PExp -> m PExp
- Language.Clafer.Intermediate.StringAnalyzer: astrReference :: Functor m => MonadState (Map String Int) m => Maybe IReference -> m (Maybe IReference)
+ Language.Clafer.Intermediate.StringAnalyzer: astrReference :: MonadState (Map String Int) m => Maybe IReference -> m (Maybe IReference)
Files
- CHANGES.md +67/−63
- LICENSE +17/−17
- Makefile +1/−1
- README.md +29/−30
- Setup.lhs +3/−3
- clafer.cabal +32/−20
- src-cmd/clafer.hs +54/−54
- src/GetURL.hs +24/−24
- src/Language/Clafer/ClaferArgs.hs +181/−181
- src/Language/Clafer/Comments.hs +87/−87
- src/Language/Clafer/Css.hs +31/−31
- src/Language/Clafer/Front/AbsClafer.hs +370/−370
- src/Language/Clafer/Front/ErrM.hs +2/−2
- src/Language/Clafer/Front/LayoutResolver.hs +334/−334
- src/Language/Clafer/Front/LexClafer.hs +420/−0
- src/Language/Clafer/Front/LexClafer.x +0/−206
- src/Language/Clafer/Front/ParClafer.hs +2188/−0
- src/Language/Clafer/Front/ParClafer.y +0/−317
- src/Language/Clafer/Generator/Alloy.hs +661/−659
- src/Language/Clafer/Generator/Choco.hs +3/−1
- src/Language/Clafer/Generator/Concat.hs +84/−84
- src/Language/Clafer/Generator/Graph.hs +438/−438
- src/Language/Clafer/Generator/Html.hs +472/−472
- src/Language/Clafer/Generator/Stats.hs +66/−66
- src/Language/Clafer/Intermediate/Desugarer.hs +482/−482
- src/Language/Clafer/Intermediate/Intclafer.hs +1/−1
- src/Language/Clafer/Intermediate/Resolver.hs +8/−7
- src/Language/Clafer/Intermediate/ResolverName.hs +49/−32
- src/Language/Clafer/Intermediate/ResolverType.hs +33/−25
- src/Language/Clafer/Intermediate/ScopeAnalysis.hs +31/−31
- src/Language/Clafer/Intermediate/SimpleScopeAnalyzer.hs +291/−291
- src/Language/Clafer/Intermediate/StringAnalyzer.hs +8/−8
- src/Language/Clafer/Intermediate/Tracing.hs +294/−294
- src/Language/Clafer/Intermediate/Transformer.hs +54/−54
- src/Language/Clafer/Intermediate/TypeSystem.hs +22/−10
- src/Language/Clafer/JSONMetaData.hs +124/−124
- src/Language/Clafer/Optimizer/Optimizer.hs +268/−268
- src/Language/Clafer/QNameUID.hs +161/−161
- src/Language/Clafer/SplitJoin.hs +53/−53
- src/Language/Clafer/clafer.css +14/−14
- src/Language/ClaferT.hs +336/−336
- stack.yaml +9/−6
- test/Functions.hs +72/−72
- test/Suite/Negative.hs +53/−53
- test/Suite/Positive.hs +83/−83
- test/Suite/Redefinition.hs +170/−170
- test/Suite/SimpleScopeAnalyser.hs +163/−163
- test/Suite/TypeSystem.hs +89/−89
- test/doctests.hs +4/−4
- test/test-suite.hs +103/−103
CHANGES.md view
@@ -1,63 +1,67 @@-##### Clafer Version 0.4.3 released on Dec 22, 2015 - -* [Release](https://github.com/gsdlab/clafer/pull/81) - -##### Clafer Version 0.4.2.1 released on Oct 19, 2015 - -* Fixed Haddock build, updated README, fixed a test case. - -##### Clafer Version 0.4.2 released on Oct 16, 2015 - -* [Release](https://github.com/gsdlab/clafer/pull/74) - -##### Clafer Version 0.4.1 released on Sep 1, 2015 - -* [Release](https://github.com/gsdlab/clafer/pull/71) - -##### Clafer Version 0.4.0 released on Jul 28, 2015 - -* [Release](https://github.com/gsdlab/clafer/pull/68) - -##### Clafer Version 0.3.10 released on April 24, 2015 - -* [Release](https://github.com/gsdlab/clafer/pull/66) - -##### Clafer Version 0.3.9 released on March 06, 2015 - -* [Release](https://github.com/gsdlab/clafer/pull/63) - -##### Clafer Version 0.3.8 released on January 27, 2015 - -* [Release](https://github.com/gsdlab/clafer/pull/60) - -##### Clafer Version 0.3.7 released on October 23, 2014 - -* [Release](https://github.com/gsdlab/clafer/pull/53) - -##### Clafer Version 0.3.6.1 released on July 08, 2014 - -* [Release](https://github.com/gsdlab/clafer/pull/50) - -##### Clafer Version 0.3.6 released on May 23, 2014 - -* [Release](https://github.com/gsdlab/clafer/pull/48) - -##### Clafer Version 0.3.5 released on January 20, 2014 - -* [Release](https://github.com/gsdlab/clafer/pull/44) - -##### Clafer Version 0.3.4 released on September 20, 2013 - -##### Clafer Version 0.3.3 released on August 14, 2013 - -* [Release](https://github.com/gsdlab/clafer/pull/35) - -##### Clafer Version 0.3.2 released on April 11, 2013 - -##### Clafer Version 0.3.1 released on October 17, 2012 - -##### Clafer Version 0.3 released on July 17, 2012 - -This was the first release of Clafer and included all code since the beginning of the project. - -Basic features - See the `README.md`. +##### Clafer Version 0.4.4 released on Jun 23, 2016++* [Release](https://github.com/gsdlab/clafer/pull/88)++##### Clafer Version 0.4.3 released on Dec 22, 2015++* [Release](https://github.com/gsdlab/clafer/pull/81)++##### Clafer Version 0.4.2.1 released on Oct 19, 2015++* Fixed Haddock build, updated README, fixed a test case.++##### Clafer Version 0.4.2 released on Oct 16, 2015++* [Release](https://github.com/gsdlab/clafer/pull/74)++##### Clafer Version 0.4.1 released on Sep 1, 2015++* [Release](https://github.com/gsdlab/clafer/pull/71)++##### Clafer Version 0.4.0 released on Jul 28, 2015++* [Release](https://github.com/gsdlab/clafer/pull/68)++##### Clafer Version 0.3.10 released on April 24, 2015++* [Release](https://github.com/gsdlab/clafer/pull/66)++##### Clafer Version 0.3.9 released on March 06, 2015++* [Release](https://github.com/gsdlab/clafer/pull/63)++##### Clafer Version 0.3.8 released on January 27, 2015++* [Release](https://github.com/gsdlab/clafer/pull/60)++##### Clafer Version 0.3.7 released on October 23, 2014++* [Release](https://github.com/gsdlab/clafer/pull/53)++##### Clafer Version 0.3.6.1 released on July 08, 2014++* [Release](https://github.com/gsdlab/clafer/pull/50)++##### Clafer Version 0.3.6 released on May 23, 2014++* [Release](https://github.com/gsdlab/clafer/pull/48)++##### Clafer Version 0.3.5 released on January 20, 2014++* [Release](https://github.com/gsdlab/clafer/pull/44)++##### Clafer Version 0.3.4 released on September 20, 2013++##### Clafer Version 0.3.3 released on August 14, 2013++* [Release](https://github.com/gsdlab/clafer/pull/35)++##### Clafer Version 0.3.2 released on April 11, 2013++##### Clafer Version 0.3.1 released on October 17, 2012++##### Clafer Version 0.3 released on July 17, 2012++This was the first release of Clafer and included all code since the beginning of the project.++Basic features - See the `README.md`.
LICENSE view
@@ -1,17 +1,17 @@-Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Permission is hereby granted, free of charge, to any person obtaining a copy of+this software and associated documentation files (the "Software"), to deal in+the Software without restriction, including without limitation the rights to+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+of the Software, and to permit persons to whom the Software is furnished to do+so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
Makefile view
@@ -44,10 +44,10 @@ .PHONY: clean clean: - stack clean $(MAKE) -C $(SRC_DIR) clean $(MAKE) cleanTools $(MAKE) cleanTest + stack clean .PHONY: cleanTest cleanTest:
README.md view
@@ -3,7 +3,7 @@ # Clafer, the language -##### v0.4.3 +##### v0.4.4 [Clafer](http://clafer.org) is a general-purpose lightweight structural modeling language developed by @@ -14,7 +14,7 @@ There are many possible applications of Clafer; however, three are prominent: -1. *Product-Line Modeling* - aims at representing and managing commonality and variability of assets in product lines and creating and verifying product configurations. +1. *Product-Line Architecture Modeling* - aims at representing and managing commonality and variability of assets in product lines and creating and verifying product configurations. Clafer naturally supports multi-staged configuration. 2. *Multi-Objective Product Optimization* - aims at finding a set of products in a given product line that are optimal with respect to a set of objectives. @@ -23,6 +23,8 @@ 3. *Domain Modeling* - aims at improving the understanding of the problem domain in the early stages of software development and determining the requirements with fewer defects. This is also known as *Concept Modeling* or *Ontology Modeling*. +May applications actually combine the three. For example, see [Technical Report: Case Studies on E/E Architectures for Power Window and Central Door Locks Systems](http://www.clafer.org/2016/06/technical-report-case-studies-on-ee.html). + ### Resources * [Learning Clafer](http://t3-necsis.cs.uwaterloo.ca:8091/#learning-clafer) @@ -67,6 +69,7 @@ * [Java Platform (JDK)](http://www.oracle.com/technetwork/java/javase/downloads/index.html) v8+, 64bit * only needed for running Alloy validation + * 32bit on Windows * [Alloy4.2](http://alloy.mit.edu/alloy/download.html) * only needed for Alloy output validation * [GraphViz](http://graphviz.org/) @@ -74,30 +77,31 @@ ### Installation from binaries -Binary distributions of the release 0.4.3 of Clafer Tools for Windows, Mac, and Linux, +Binary distributions of the release 0.4.4 of Clafer Tools for Windows, Mac, and Linux, can be downloaded from [Clafer Tools - Binary Distributions](http://gsd.uwaterloo.ca/clafer-tools-binary-distributions). -1. download the binaries and unpack `<target directory>` of your choice -2. add the `<target directory>` to your system path so that the executables can be found +1. Download the binaries and unpack `<target directory>` of your choice. +2. Add the `<target directory>` to your system path so that the executables can be found. ### Installation from Hackage -Clafer is now available on [Hackage](http://hackage.haskell.org/package/clafer-0.4.3/) and it can be installed using either [`stack`](https://github.com/commercialhaskell/stack) or [`cabal-install`](https://hackage.haskell.org/package/cabal-install). +Clafer is available on [Hackage](http://hackage.haskell.org/package/clafer-0.4.4/) and it can be installed using either [`stack`](https://github.com/commercialhaskell/stack) or [`cabal-install`](https://hackage.haskell.org/package/cabal-install). #### Installation using `stack` Stack is the only requirement: no other Haskell tooling needs to be installed because stack will automatically install everything that's needed. -1. [install `stack`](https://github.com/commercialhaskell/stack#how-to-install) -2. execute `stack install clafer` +1. [Install `stack`](https://github.com/commercialhaskell/stack#how-to-install) + * (first time only) Execute `stack setup`. +2. Execute `stack install clafer`. #### Installation using `cabal-install` Dependencies -* [GHC](https://www.haskell.org/downloads) >= 7.8.3. 7.10.2 is recommended, -* `cabal-install` >= 1.18, should be installed together with a GHC distribution, +* [GHC](https://www.haskell.org/downloads) >= 7.10.3 or 8.0.1 are recommended, +* `cabal-install` >= 1.22, should be installed together with a GHC distribution, * [alex](https://hackage.haskell.org/package/alex), * [happy](https://hackage.haskell.org/package/happy). @@ -105,8 +109,8 @@ 2. `cabal update` 3. `cabal install alex happy` 4. `cabal install clafer` -5. on Windows `cd C:\Users\<user>\AppData\Roaming\cabal\i386-windows-ghc-7.10.2\clafer-0.4.3` -6. on Linux `ca ~/.cabal/share/x86_64-linux-ghc-7.10.2/clafer-0.4.3/` +5. on Windows `cd C:\Users\<user>\AppData\Roaming\cabal\x86_64-windows-ghc-8.0.1\clafer-0.4.4` +6. on Linux `ca ~/.cabal/share/x86_64-linux-ghc-8.0.1/clafer-0.4.4/` 7. to automatically download Alloy jars, execute * `make alloy4.2.jar`, * move `alloy4.2.jar` to the location of the clafer executable. @@ -122,11 +126,12 @@ * [MSYS2](http://msys2.sourceforge.net/) * it is installed automatically by `stack setup` - * to open MinGW64 shell, execute `mingw64_shell.bat` in `C:\Users\<user>\AppData\Local\Programs\stack\x86_64-windows\msys2-<date>`, where `<date>` is the release date of your MSYS installation - * update MSYS2 packages - * follow guide for [III. Updating packages](http://sourceforge.net/p/msys2/wiki/MSYS2%20installation/) - * execute - * `pacman -S make wget unzip diffutils` + * update MSYS2 following the [update procedure](http://sourceforge.net/p/msys2/wiki/MSYS2%20installation/): + * `stack exec pacman -- -Sy` + * `stack exec pacman -- --needed -S bash pacman pacman-mirrors msys2-runtime` + * restart shell if the runtime was updated + * `stack exec pacman -- -Su` + * `stack exec pacman -- -S make wget unzip diffutils` #### Important: branches must correspond @@ -141,24 +146,18 @@ 1. in some `<source directory>` of your choice, execute * `git clone git://github.com/gsdlab/clafer.git` 2. in `<source directory>/clafer`, execute `stack setup`. This will install all dependencies, build tools, and MSYS2 (on Windows). -3. first time only on Windows - * open `MinGW64 Shell` using `C:\Users\<user>\AppData\Local\Programs\stack\i386-windows\msys2-20150512\mingw64_shell.bat` - * update MSYS2 following the [update procedure](http://sourceforge.net/p/msys2/wiki/MSYS2%20installation/): - * `pacman -Sy` - * `pacman --needed -S bash pacman pacman-mirrors msys2-runtime` - * restart shell if the runtime was updated - * `pacman -Su` - * `pacman -S make wget unzip diffutils` -4. `cd <source directory>` - * `make` +3. `cd <source directory>` + * `make` on Linux/Mac + * `stack exec make` on Windows ### Installation 1. Execute - * `make install to=<target directory>` + * `make install to=<target directory>` on Linux/Mac + * `stack exec make install to=<target directory>` on Windows #### Note: -> On Windows, use `/` with the `make` command instead of `\`, e.g., `make install to=/c/clafer-tools-0.4.3/` +> On Windows, use `/` with the `make` command instead of `\`, e.g., `make install to=/c/clafer-tools-0.4.4/` ## Integration with Sublime Text 2/3 @@ -175,7 +174,7 @@ (As printed by `clafer --help`) ``` -Clafer 0.4.3 +Clafer 0.4.4 clafer [OPTIONS] [FILE]
Setup.lhs view
@@ -1,4 +1,4 @@-#! /usr/bin/env runhaskell - -> import Distribution.Simple +#! /usr/bin/env runhaskell++> import Distribution.Simple > main = defaultMain
clafer.cabal view
@@ -1,5 +1,5 @@ Name: clafer -Version: 0.4.3 +Version: 0.4.4 Synopsis: Compiles Clafer models to other formats: Alloy, JavaScript, JSON, HTML, Dot. Description: Clafer is a general purpose, lightweight, structural modeling language developed at GSD Lab, University of Waterloo, and MODELS group at IT University of Copenhagen. Lightweight modeling aims at improving the understanding of the problem domain in the early stages of software development and determining the requirements with fewer defects. Clafer's goal is to make modeling more accessible to a wider range of users and domains. The tool provides a reference language implementation. It translates models to other formats (e.g. Alloy, JavaScript, JSON) to allow for reasoning with existing tools. Homepage: http://clafer.org @@ -10,12 +10,9 @@ Stability: Experimental Category: Model Build-type: Simple -tested-with: GHC == 7.8.3 - , GHC == 7.8.4 - , GHC == 7.10.1 - , GHC == 7.10.2 - , GHC == 7.10.3 -Cabal-version: >= 1.18 +tested-with: GHC == 7.10.3 + , GHC == 8.0.1 +Cabal-version: >= 1.22 data-files: README.md , CHANGES.md , logo.pdf @@ -27,10 +24,15 @@ type: git location: git://github.com/gsdlab/clafer.git Executable clafer - build-tools: ghc >= 7.8.3 + build-tools: ghc >= 7.10.3 default-language: Haskell2010 main-is: clafer.hs hs-source-dirs: src-cmd + if impl(ghc >= 8.0) + ghc-options: -Wcompat + -- -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances + else + build-depends: fail == 4.9.*, semigroups == 0.18.* build-depends: base >= 4.7.0.1 && < 5 , containers >= 0.5.5.1 , filepath >= 1.3.0.2 @@ -41,14 +43,19 @@ , cmdargs >= 0.10.12 , split >= 0.2.2 - , clafer == 0.4.3 + , clafer == 0.4.4 other-modules: Paths_clafer library - build-tools: ghc >= 7.8.3 - , alex - , happy + build-tools: ghc >= 7.10.3 + , alex >= 3.1.7 + , happy >= 1.19.5 default-language: Haskell2010 + if impl(ghc >= 8.0) + ghc-options: -Wcompat + -- -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances + else + build-depends: fail == 4.9.*, semigroups == 0.18.* build-depends: array >= 0.5.0.0 , base >= 4.7.0.1 && < 5 , bytestring >= 0.10.4.0 @@ -64,18 +71,18 @@ , parsec >= 3.1.5 , text >= 1.1.0.0 - , aeson >= 0.8.0.2 && < 0.10.0.0 + , aeson >= 0.11.1.2 , cmdargs >= 0.10.12 , data-stringmap >= 1.0.1.1 , executable-path >= 0.0.3 , file-embed >= 0.0.9 , json-builder >= 0.3 , lens >= 4.6.0.1 - , lens-aeson >= 1.0.0.3 + , lens-aeson >= 1.0.0.5 , network-uri >= 2.5.0.0 , string-conversions >= 0.3.0.3 , split >= 0.2.2 - , transformers-compat >= 0.3 && < 0.5 + , transformers-compat >= 0.3 , mtl-compat >= 0.2.1 hs-source-dirs: src @@ -118,11 +125,16 @@ other-modules: GetURL Test-Suite test-suite - build-tools: ghc >= 7.8.3 + build-tools: ghc >= 7.10.3 default-language: Haskell2010 type: exitcode-stdio-1.0 main-is: test-suite.hs hs-source-dirs: test + if impl(ghc >= 8.0) + ghc-options: -Wcompat + -- -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances + else + build-depends: fail == 4.9.*, semigroups == 0.18.* build-depends: base >= 4.7.0.1 && < 5 , containers >= 0.5.5.1 , directory >= 1.2.1.0 @@ -134,13 +146,13 @@ , data-stringmap >= 1.0.1.1 , lens >= 4.6.0.1 - , lens-aeson >= 1.0.0.3 + , lens-aeson >= 1.0.0.5 , tasty >= 0.10.1.2 , tasty-hunit >= 0.9.2 , tasty-th >= 0.1.3 - , transformers-compat >= 0.3 && < 0.5 + , transformers-compat >= 0.3 , mtl-compat >= 0.2.1 - , clafer == 0.4.3 + , clafer == 0.4.4 ghc-options: -Wall @@ -152,7 +164,7 @@ , Suite.TypeSystem Test-suite doctests - build-tools: ghc >= 7.8.3 + build-tools: ghc >= 7.10.3 default-language: Haskell2010 type: exitcode-stdio-1.0 ghc-options: -threaded -Wall
src-cmd/clafer.hs view
@@ -1,54 +1,54 @@-{- - Copyright (C) 2012-2015 Kacper Bak, Jimmy Liang, Michal Antkiewicz <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -{-# LANGUAGE DeriveDataTypeable, NamedFieldPuns #-} -module Main where - -import Prelude hiding (writeFile, readFile, print, putStrLn) - -import Data.Functor (void) -import System.IO -import System.Timeout -import System.Process (system) - -import Language.Clafer - -main :: IO () -main = do - (args', model) <- mainArgs - let timeInSec = (timeout_analysis args') * 10^(6::Integer) - if timeInSec > 0 - then timeout timeInSec $ start args' model - else Just `fmap` start args' model - return () - -start :: ClaferArgs -> InputModel-> IO () -start args' model = if ecore2clafer args' - then runEcore2Clafer (file args') $ (tooldir args') - else runCompiler Nothing args' model - -runEcore2Clafer :: FilePath -> FilePath -> IO () -runEcore2Clafer ecoreFile toolPath - | null ecoreFile = do - putStrLn "Error: Provide a file name of an ECore model." - | otherwise = do - putStrLn $ "Converting " ++ ecoreFile ++ " into Clafer" - void $ system $ "java -jar " ++ toolPath ++ "/ecore2clafer.jar " ++ ecoreFile +{-+ Copyright (C) 2012-2015 Kacper Bak, Jimmy Liang, Michal Antkiewicz <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+{-# LANGUAGE DeriveDataTypeable, NamedFieldPuns #-}+module Main where++import Prelude hiding (writeFile, readFile, print, putStrLn)++import Data.Functor (void)+import System.IO+import System.Timeout+import System.Process (system)++import Language.Clafer++main :: IO ()+main = do+ (args', model) <- mainArgs+ let timeInSec = (timeout_analysis args') * 10^(6::Integer)+ if timeInSec > 0+ then timeout timeInSec $ start args' model+ else Just `fmap` start args' model+ return ()++start :: ClaferArgs -> InputModel-> IO ()+start args' model = if ecore2clafer args'+ then runEcore2Clafer (file args') $ (tooldir args')+ else runCompiler Nothing args' model++runEcore2Clafer :: FilePath -> FilePath -> IO ()+runEcore2Clafer ecoreFile toolPath+ | null ecoreFile = do+ putStrLn "Error: Provide a file name of an ECore model."+ | otherwise = do+ putStrLn $ "Converting " ++ ecoreFile ++ " into Clafer"+ void $ system $ "java -jar " ++ toolPath ++ "/ecore2clafer.jar " ++ ecoreFile
src/GetURL.hs view
@@ -1,24 +1,24 @@--- (c) Simon Marlow 2011, see the file LICENSE for copying terms. - --- Simple wrapper around HTTP, allowing proxy use - -module GetURL (getURL) where - -import Network.HTTP -import Network.Browser -import Network.URI - -getURL :: String -> IO String -getURL url = do - Network.Browser.browse $ do - setCheckForProxy True - setDebugLog Nothing - setOutHandler (const (return ())) - (_, rsp) <- request (getRequest' (escapeURIString isUnescapedInURI url)) - return (rspBody rsp) - where - getRequest' :: String -> Request String - getRequest' urlString = - case parseURI urlString of - Nothing -> error ("getRequest: Not a valid URL - " ++ urlString) - Just u -> mkRequest GET u +-- (c) Simon Marlow 2011, see the file LICENSE for copying terms.++-- Simple wrapper around HTTP, allowing proxy use++module GetURL (getURL) where++import Network.HTTP+import Network.Browser+import Network.URI++getURL :: String -> IO String+getURL url = do+ Network.Browser.browse $ do+ setCheckForProxy True+ setDebugLog Nothing+ setOutHandler (const (return ()))+ (_, rsp) <- request (getRequest' (escapeURIString isUnescapedInURI url))+ return (rspBody rsp)+ where+ getRequest' :: String -> Request String+ getRequest' urlString =+ case parseURI urlString of+ Nothing -> error ("getRequest: Not a valid URL - " ++ urlString)+ Just u -> mkRequest GET u
src/Language/Clafer/ClaferArgs.hs view
@@ -1,181 +1,181 @@-{-# LANGUAGE DeriveDataTypeable #-} -{- - Copyright (C) 2012-2015 Kacper Bak, Jimmy Liang <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -{- | Command Line Arguments of the compiler. - -See also <http://t3-necsis.cs.uwaterloo.ca:8091/ClaferTools/CommandLineArguments a model of the arguments in Clafer>, including constraints and examples. --} -module Language.Clafer.ClaferArgs where - -import System.Console.CmdArgs -import System.Console.CmdArgs.Explicit hiding (mode) -import Data.List -import Language.Clafer.SplitJoin -import Paths_clafer (version) -import Data.Version (showVersion) - -import GetURL - --- | Type of output to be generated at the end of compilation -data ClaferMode = Alloy | JSON | Clafer | Html | Graph | CVLGraph | Choco - deriving (Eq, Show, Ord, Data, Typeable) -instance Default ClaferMode where - def = Alloy - --- | Scope inference strategy -data ScopeStrategy = None | Simple - deriving (Eq, Show, Data, Typeable) -instance Default ScopeStrategy where - def = Simple - -data ClaferArgs = ClaferArgs { - mode :: [ ClaferMode ], - console_output :: Bool, - flatten_inheritance :: Bool, - timeout_analysis :: Int, - no_layout :: Bool, - new_layout :: Bool, - check_duplicates :: Bool, - skip_resolver :: Bool, - keep_unused :: Bool, - no_stats :: Bool, - validate :: Bool, - tooldir :: FilePath, - alloy_mapping :: Bool, - self_contained :: Bool, - add_graph :: Bool, - show_references :: Bool, - add_comments :: Bool, - ecore2clafer :: Bool, - scope_strategy :: ScopeStrategy, - afm :: Bool, - meta_data :: Bool, - file :: FilePath - } deriving (Eq, Show, Data, Typeable) - -clafer :: ClaferArgs -clafer = ClaferArgs { - mode = [] &= help "Generated output type. Available CLAFERMODEs are: 'alloy' (default, Alloy 4.2); 'json' (intermediate representation of Clafer model); 'clafer' (analyzed and desugared clafer model); 'html' (original model in HTML); 'graph' (graphical representation written in DOT language); 'cvlgraph' (cvl notation representation written in DOT language); 'choco' (Choco constraint programming solver). Multiple modes can be specified at the same time, e.g., '-m alloy -m html'." &= name "m", - console_output = def &= help "Output code on console." &= name "o", - flatten_inheritance = def &= help "Flatten inheritance ('alloy' mode only)." &= name "i", - timeout_analysis = def &= help "Timeout for analysis.", - no_layout = def &= help "Don't resolve off-side rule layout." &= name "l", - new_layout = def &= help "Use new fast layout resolver (experimental)." &= name "nl", - check_duplicates = def &= help "Check duplicated clafer names in the entire model." &= name "c", - skip_resolver = def &= help "Skip name resolution." &= name "f", - keep_unused = def &= help "Keep uninstantated abstract clafers ('alloy' mode only)." &= name "k", - no_stats = def &= help "Don't print statistics." &= name "s", - validate = def &= help "Validate outputs of all modes. Uses '<tooldir>/alloy4.2.jar' for Alloy models, '<tooldir>/chocosolver.jar' for Alloy models, and Clafer translator for desugared Clafer models. Use '--tooldir' to override the default location ('.') of these tools." &= name "v", - tooldir = "." &= typDir &= help "Specify the tools directory ('validate' only). Default: '.' (current directory).", - alloy_mapping = def &= help "Generate mapping to Alloy source code ('alloy' mode only)." &= name "a", - self_contained = def &= help "Generate a self-contained html document ('html' mode only).", - add_graph = def &= help "Add a graph to the generated html model ('html' mode only). Requires the \"dot\" executable to be on the system path.", - show_references = def &= help "Whether the links for references should be rendered. ('html' and 'graph' modes only)." &= name "sr", - add_comments = def &= help "Include comments from the source file in the html output ('html' mode only).", - ecore2clafer = def &= help "Translate an ECore model into Clafer.", - scope_strategy = def &= help "Use scope computation strategy: none or simple (default)." &= name "ss", - afm = def &= help "Throws an error if the cardinality of any of the clafers is above 1." &= name "check-afm", - meta_data = def &= help "Generate a 'fully qualified name'-'least-partially-qualified name'-'unique ID' map ('.cfr-map'). In Alloy and Choco modes, generate the scopes map ('.cfr-scope').", - file = def &= args &= typ "FILE" - } &= summary ("Clafer " ++ showVersion Paths_clafer.version) &= program "clafer" - -mergeArgs :: ClaferArgs -> ClaferArgs -> ClaferArgs -mergeArgs a1 a2 = ClaferArgs (mode a1) coMergeArg - (mergeArg flatten_inheritance) (mergeArg timeout_analysis) - (mergeArg no_layout) (mergeArg new_layout) - (mergeArg check_duplicates) (mergeArg skip_resolver) - (mergeArg keep_unused) (mergeArg no_stats) - (mergeArg validate) toolMergeArg - (mergeArg alloy_mapping) (mergeArg self_contained) - (mergeArg add_graph) (mergeArg show_references) - (mergeArg add_comments) (mergeArg ecore2clafer) - (mergeArg scope_strategy) (mergeArg afm) - (mergeArg meta_data) (mergeArg file) - where - coMergeArg :: Bool - coMergeArg = if r1 then r1 else - if r2 then r2 else (null $ file a1) - where r1 = console_output a1;r2 = console_output a2 - toolMergeArg :: String - toolMergeArg = if r1 /= "" then r1 else - if r2 /= "" then r2 else "/tools" - where r1 = tooldir a1;r2 = tooldir a2 - mergeArg :: (Default a, Eq a) => (ClaferArgs -> a) -> a - mergeArg f = (\r -> if r /= def then r else f a2) $ f a1 - -mainArgs :: IO (ClaferArgs, String) -mainArgs = do - argsFromCmd <- cmdArgs clafer - model <- retrieveModelFromURL $ file argsFromCmd - let argsWithOpts = argsWithOPTIONS argsFromCmd model - -- Alloy should be the default mode but only if nothing else was specified - -- cannot use [ Alloy ] as the default in the definition of `clafer :: ClaferArgs` since - -- Alloy will always be a mode in addition to the other specified modes (it will become mandatory) - let argsWithDef = if null $ mode argsWithOpts - then argsWithOpts{mode = [ Alloy ]} - else argsWithOpts - return (argsWithDef, model) - -retrieveModelFromURL :: String -> IO String -retrieveModelFromURL url = - case url of - "" -> getContents -- this is the pre-module system behavior - ('f':'i':'l':'e':':':'/':'/':n) -> readFile n - ('h':'t':'t':'p':':':'/':'/':_) -> getURL url - ('f':'t':'p':':':'/':'/':_) -> getURL url - n -> readFile n -- this is the pre-module system behavior - -argsWithOPTIONS :: ClaferArgs -> String -> ClaferArgs -argsWithOPTIONS args' model = - if "//# OPTIONS " `isPrefixOf` model - then either (const args') (mergeArgs args' . cmdArgsValue) $ -- merge wth command line arguments, which take precedence - process (cmdArgsMode clafer) $ -- instantiate ClaferArgs record - Language.Clafer.SplitJoin.splitArgs $ -- extract individual arguments - drop 12 $ -- strip "//# OPTIONS " - takeWhile (/= '\n') model -- get first line - else args' - -defaultClaferArgs :: ClaferArgs -defaultClaferArgs = ClaferArgs - { mode = [ def ] - , console_output = True - , flatten_inheritance = False - , timeout_analysis = 0 - , no_layout = False - , new_layout = False - , check_duplicates = False - , skip_resolver = False - , keep_unused = False - , no_stats = False - , validate = False - , tooldir = "." - , alloy_mapping = False - , self_contained = False - , add_graph = False - , show_references = False - , add_comments = False - , ecore2clafer = False - , scope_strategy = Simple - , afm = False - , meta_data = False - , file = "" - } +{-# LANGUAGE DeriveDataTypeable #-}+{-+ Copyright (C) 2012-2015 Kacper Bak, Jimmy Liang <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+{- | Command Line Arguments of the compiler.++See also <http://t3-necsis.cs.uwaterloo.ca:8091/ClaferTools/CommandLineArguments a model of the arguments in Clafer>, including constraints and examples.+-}+module Language.Clafer.ClaferArgs where++import System.Console.CmdArgs+import System.Console.CmdArgs.Explicit hiding (mode)+import Data.List+import Language.Clafer.SplitJoin+import Paths_clafer (version)+import Data.Version (showVersion)++import GetURL++-- | Type of output to be generated at the end of compilation+data ClaferMode = Alloy | JSON | Clafer | Html | Graph | CVLGraph | Choco+ deriving (Eq, Show, Ord, Data, Typeable)+instance Default ClaferMode where+ def = Alloy++-- | Scope inference strategy+data ScopeStrategy = None | Simple+ deriving (Eq, Show, Data, Typeable)+instance Default ScopeStrategy where+ def = Simple++data ClaferArgs = ClaferArgs {+ mode :: [ ClaferMode ],+ console_output :: Bool,+ flatten_inheritance :: Bool,+ timeout_analysis :: Int,+ no_layout :: Bool,+ new_layout :: Bool,+ check_duplicates :: Bool,+ skip_resolver :: Bool,+ keep_unused :: Bool,+ no_stats :: Bool,+ validate :: Bool,+ tooldir :: FilePath,+ alloy_mapping :: Bool,+ self_contained :: Bool,+ add_graph :: Bool,+ show_references :: Bool,+ add_comments :: Bool,+ ecore2clafer :: Bool,+ scope_strategy :: ScopeStrategy,+ afm :: Bool,+ meta_data :: Bool,+ file :: FilePath+ } deriving (Eq, Show, Data, Typeable)++clafer :: ClaferArgs+clafer = ClaferArgs {+ mode = [] &= help "Generated output type. Available CLAFERMODEs are: 'alloy' (default, Alloy 4.2); 'json' (intermediate representation of Clafer model); 'clafer' (analyzed and desugared clafer model); 'html' (original model in HTML); 'graph' (graphical representation written in DOT language); 'cvlgraph' (cvl notation representation written in DOT language); 'choco' (Choco constraint programming solver). Multiple modes can be specified at the same time, e.g., '-m alloy -m html'." &= name "m",+ console_output = def &= help "Output code on console." &= name "o",+ flatten_inheritance = def &= help "Flatten inheritance ('alloy' mode only)." &= name "i",+ timeout_analysis = def &= help "Timeout for analysis.",+ no_layout = def &= help "Don't resolve off-side rule layout." &= name "l",+ new_layout = def &= help "Use new fast layout resolver (experimental)." &= name "nl",+ check_duplicates = def &= help "Check duplicated clafer names in the entire model." &= name "c",+ skip_resolver = def &= help "Skip name resolution." &= name "f",+ keep_unused = def &= help "Keep uninstantated abstract clafers ('alloy' mode only)." &= name "k",+ no_stats = def &= help "Don't print statistics." &= name "s",+ validate = def &= help "Validate outputs of all modes. Uses '<tooldir>/alloy4.2.jar' for Alloy models, '<tooldir>/chocosolver.jar' for Alloy models, and Clafer translator for desugared Clafer models. Use '--tooldir' to override the default location ('.') of these tools." &= name "v",+ tooldir = "." &= typDir &= help "Specify the tools directory ('validate' only). Default: '.' (current directory).",+ alloy_mapping = def &= help "Generate mapping to Alloy source code ('alloy' mode only)." &= name "a",+ self_contained = def &= help "Generate a self-contained html document ('html' mode only).",+ add_graph = def &= help "Add a graph to the generated html model ('html' mode only). Requires the \"dot\" executable to be on the system path.",+ show_references = def &= help "Whether the links for references should be rendered. ('html' and 'graph' modes only)." &= name "sr",+ add_comments = def &= help "Include comments from the source file in the html output ('html' mode only).",+ ecore2clafer = def &= help "Translate an ECore model into Clafer.",+ scope_strategy = def &= help "Use scope computation strategy: none or simple (default)." &= name "ss",+ afm = def &= help "Throws an error if the cardinality of any of the clafers is above 1." &= name "check-afm",+ meta_data = def &= help "Generate a 'fully qualified name'-'least-partially-qualified name'-'unique ID' map ('.cfr-map'). In Alloy and Choco modes, generate the scopes map ('.cfr-scope').",+ file = def &= args &= typ "FILE"+ } &= summary ("Clafer " ++ showVersion Paths_clafer.version) &= program "clafer"++mergeArgs :: ClaferArgs -> ClaferArgs -> ClaferArgs+mergeArgs a1 a2 = ClaferArgs (mode a1) coMergeArg+ (mergeArg flatten_inheritance) (mergeArg timeout_analysis)+ (mergeArg no_layout) (mergeArg new_layout)+ (mergeArg check_duplicates) (mergeArg skip_resolver)+ (mergeArg keep_unused) (mergeArg no_stats)+ (mergeArg validate) toolMergeArg+ (mergeArg alloy_mapping) (mergeArg self_contained)+ (mergeArg add_graph) (mergeArg show_references)+ (mergeArg add_comments) (mergeArg ecore2clafer)+ (mergeArg scope_strategy) (mergeArg afm)+ (mergeArg meta_data) (mergeArg file)+ where+ coMergeArg :: Bool+ coMergeArg = if r1 then r1 else+ if r2 then r2 else (null $ file a1)+ where r1 = console_output a1;r2 = console_output a2+ toolMergeArg :: String+ toolMergeArg = if r1 /= "" then r1 else+ if r2 /= "" then r2 else "/tools"+ where r1 = tooldir a1;r2 = tooldir a2+ mergeArg :: (Default a, Eq a) => (ClaferArgs -> a) -> a+ mergeArg f = (\r -> if r /= def then r else f a2) $ f a1++mainArgs :: IO (ClaferArgs, String)+mainArgs = do+ argsFromCmd <- cmdArgs clafer+ model <- retrieveModelFromURL $ file argsFromCmd+ let argsWithOpts = argsWithOPTIONS argsFromCmd model+ -- Alloy should be the default mode but only if nothing else was specified+ -- cannot use [ Alloy ] as the default in the definition of `clafer :: ClaferArgs` since+ -- Alloy will always be a mode in addition to the other specified modes (it will become mandatory)+ let argsWithDef = if null $ mode argsWithOpts+ then argsWithOpts{mode = [ Alloy ]}+ else argsWithOpts+ return (argsWithDef, model)++retrieveModelFromURL :: String -> IO String+retrieveModelFromURL url =+ case url of+ "" -> getContents -- this is the pre-module system behavior+ ('f':'i':'l':'e':':':'/':'/':n) -> readFile n+ ('h':'t':'t':'p':':':'/':'/':_) -> getURL url+ ('f':'t':'p':':':'/':'/':_) -> getURL url+ n -> readFile n -- this is the pre-module system behavior++argsWithOPTIONS :: ClaferArgs -> String -> ClaferArgs+argsWithOPTIONS args' model =+ if "//# OPTIONS " `isPrefixOf` model+ then either (const args') (mergeArgs args' . cmdArgsValue) $ -- merge wth command line arguments, which take precedence+ process (cmdArgsMode clafer) $ -- instantiate ClaferArgs record+ Language.Clafer.SplitJoin.splitArgs $ -- extract individual arguments+ drop 12 $ -- strip "//# OPTIONS "+ takeWhile (/= '\n') model -- get first line+ else args'++defaultClaferArgs :: ClaferArgs+defaultClaferArgs = ClaferArgs+ { mode = [ def ]+ , console_output = True+ , flatten_inheritance = False+ , timeout_analysis = 0+ , no_layout = False+ , new_layout = False+ , check_duplicates = False+ , skip_resolver = False+ , keep_unused = False+ , no_stats = False+ , validate = False+ , tooldir = "."+ , alloy_mapping = False+ , self_contained = False+ , add_graph = False+ , show_references = False+ , add_comments = False+ , ecore2clafer = False+ , scope_strategy = Simple+ , afm = False+ , meta_data = False+ , file = ""+ }
src/Language/Clafer/Comments.hs view
@@ -1,87 +1,87 @@-{- - Copyright (C) 2012 Christopher Walker <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} - -module Language.Clafer.Comments(getOptions, getFragments, getStats, getGraph, getComments) where - -import Data.Maybe (fromMaybe) -import Data.List (stripPrefix) -import Language.Clafer.Front.AbsClafer - -type InputModel = String - -getOptions :: InputModel -> String -getOptions model = case lines model of - [] -> "" - (s:_) -> fromMaybe "" $ stripPrefix "//# OPTIONS " s - -getFragments :: InputModel -> [Int] -getFragments [] = [] -getFragments xs = getFragments' (lines xs) 1 -getFragments' :: [ InputModel ] -> Int -> [Int] -getFragments' [] _ = [] -getFragments' ("//# FRAGMENT":xs) ln = ln:getFragments' xs (ln + 1) -getFragments' (_:xs) ln = getFragments' xs $ ln + 1 - -getStats :: InputModel -> [Int] -getStats [] = [] -getStats xs = getStats' (lines xs) 1 -getStats' :: [String] -> Int -> [Int] -getStats' [] _ = [] -getStats' ("//# SUMMARY":xs) ln = ln:getStats' xs (ln + 1) -getStats' ("//# STATS":xs) ln = ln:getStats' xs (ln + 1) -getStats' (_:xs) ln = getStats' xs $ ln + 1 - -getGraph :: InputModel -> [Int] -getGraph [] = [] -getGraph xs = getGraph' (lines xs) 1 -getGraph' :: [String] -> Int -> [Int] -getGraph' [] _ = [] -getGraph' ("//# SUMMARY":xs) ln = ln:getGraph' xs (ln + 1) -getGraph' ("//# GRAPH":xs) ln = ln:getGraph' xs (ln + 1) -getGraph' (_:xs) ln = getGraph' xs $ ln + 1 - -getComments :: InputModel -> [(Span, String)] -getComments input = getComments' input 1 1 -getComments' :: String -> Integer -> Integer -> [(Span, String)] -getComments' [] _ _ = [] -getComments' ('/':'/':xs) row col = readLine ('/':'/':xs) (Pos row col) -getComments' ('/':'*':xs) row col = readBlock ('/':'*':xs) (Pos row col) -getComments' ('\n':xs) row _ = getComments' xs (row + 1) 1 -getComments' (_:xs) row col = getComments' xs row $ col + 1 - -readLine :: String -> Pos -> [(Span, String)] -readLine [] _ = [] -readLine xs start@(Pos row col) = let comment = takeWhile (/= '\n') xs in - ((Span start (Pos row (col + toInteger (length comment)))), - comment): getComments' (drop (length comment + 1) xs) (row + 1) 1 - - -readBlock :: String -> Pos -> [(Span, String)] -readBlock xs start@(Pos row col) = let (end@(Pos row' col'), comment, rest) = readBlock' xs row col id in - ((Span start end), comment):getComments' rest row' col' -readBlock' :: String -> Integer - -> Integer -> (String -> String) - -> (Pos, String,String) -readBlock' ('*':'/':xs) row col comment = ((Pos row $ col + 2), comment "*/", xs) -readBlock' ('\n':xs) row _ comment = readBlock' xs (row + 1) 1 (comment "\n" ++) -readBlock' (x:xs) row col comment = readBlock' xs row (col + 1) (comment [x]++) -readBlock' [] row col comment = ((Pos row col), comment [], []) +{-+ Copyright (C) 2012 Christopher Walker <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}++module Language.Clafer.Comments(getOptions, getFragments, getStats, getGraph, getComments) where++import Data.Maybe (fromMaybe)+import Data.List (stripPrefix)+import Language.Clafer.Front.AbsClafer++type InputModel = String++getOptions :: InputModel -> String+getOptions model = case lines model of+ [] -> ""+ (s:_) -> fromMaybe "" $ stripPrefix "//# OPTIONS " s++getFragments :: InputModel -> [Int]+getFragments [] = []+getFragments xs = getFragments' (lines xs) 1+getFragments' :: [ InputModel ] -> Int -> [Int]+getFragments' [] _ = []+getFragments' ("//# FRAGMENT":xs) ln = ln:getFragments' xs (ln + 1)+getFragments' (_:xs) ln = getFragments' xs $ ln + 1++getStats :: InputModel -> [Int]+getStats [] = []+getStats xs = getStats' (lines xs) 1+getStats' :: [String] -> Int -> [Int]+getStats' [] _ = []+getStats' ("//# SUMMARY":xs) ln = ln:getStats' xs (ln + 1)+getStats' ("//# STATS":xs) ln = ln:getStats' xs (ln + 1)+getStats' (_:xs) ln = getStats' xs $ ln + 1++getGraph :: InputModel -> [Int]+getGraph [] = []+getGraph xs = getGraph' (lines xs) 1+getGraph' :: [String] -> Int -> [Int]+getGraph' [] _ = []+getGraph' ("//# SUMMARY":xs) ln = ln:getGraph' xs (ln + 1)+getGraph' ("//# GRAPH":xs) ln = ln:getGraph' xs (ln + 1)+getGraph' (_:xs) ln = getGraph' xs $ ln + 1++getComments :: InputModel -> [(Span, String)]+getComments input = getComments' input 1 1+getComments' :: String -> Integer -> Integer -> [(Span, String)]+getComments' [] _ _ = []+getComments' ('/':'/':xs) row col = readLine ('/':'/':xs) (Pos row col)+getComments' ('/':'*':xs) row col = readBlock ('/':'*':xs) (Pos row col)+getComments' ('\n':xs) row _ = getComments' xs (row + 1) 1+getComments' (_:xs) row col = getComments' xs row $ col + 1++readLine :: String -> Pos -> [(Span, String)]+readLine [] _ = []+readLine xs start@(Pos row col) = let comment = takeWhile (/= '\n') xs in+ ((Span start (Pos row (col + toInteger (length comment)))),+ comment): getComments' (drop (length comment + 1) xs) (row + 1) 1+++readBlock :: String -> Pos -> [(Span, String)]+readBlock xs start@(Pos row col) = let (end@(Pos row' col'), comment, rest) = readBlock' xs row col id in+ ((Span start end), comment):getComments' rest row' col'+readBlock' :: String -> Integer+ -> Integer -> (String -> String)+ -> (Pos, String,String)+readBlock' ('*':'/':xs) row col comment = ((Pos row $ col + 2), comment "*/", xs)+readBlock' ('\n':xs) row _ comment = readBlock' xs (row + 1) 1 (comment "\n" ++)+readBlock' (x:xs) row col comment = readBlock' xs row (col + 1) (comment [x]++)+readBlock' [] row col comment = ((Pos row col), comment [], [])
src/Language/Clafer/Css.hs view
@@ -1,31 +1,31 @@-{-# LANGUAGE TemplateHaskell #-} -{- - Copyright (C) 2012 Christopher Walker <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -module Language.Clafer.Css where - -import Data.FileEmbed - -header :: String -header = "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=9\">\n" - -css :: String -css = $(embedStringFile "src/Language/Clafer/clafer.css") +{-# LANGUAGE TemplateHaskell #-}+{-+ Copyright (C) 2012 Christopher Walker <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+module Language.Clafer.Css where++import Data.FileEmbed++header :: String+header = "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=9\">\n"++css :: String+css = $(embedStringFile "src/Language/Clafer/clafer.css")
src/Language/Clafer/Front/AbsClafer.hs view
@@ -1,370 +1,370 @@-{-# LANGUAGE DeriveDataTypeable #-} -{-# LANGUAGE DeriveGeneric #-} -module Language.Clafer.Front.AbsClafer where - --- Haskell module generated by the BNF converter - - -import Data.Data (Data,Typeable) -import GHC.Generics (Generic) -data Pos = Pos Integer Integer deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) -noPos :: Pos -noPos = Pos 0 0 - -data Span = Span Pos Pos deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) -noSpan :: Span -noSpan = Span noPos noPos - -class Spannable n where getSpan :: n -> Span - -instance Spannable n => Spannable [n] where - getSpan (x:xs) = foldr (\item acc -> getSpan item >- acc ) (getSpan x) xs - getSpan [] = noSpan - -(>-) :: Span -> Span -> Span -(>-) (Span (Pos 0 0) (Pos 0 0)) s = s -(>-) r (Span (Pos 0 0) (Pos 0 0)) = r -(>-) (Span m _) (Span _ p) = Span m p - -len :: [a] -> Integer -len = toInteger . length -newtype PosInteger = PosInteger ((Int,Int),String) - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) -newtype PosDouble = PosDouble ((Int,Int),String) - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) -newtype PosReal = PosReal ((Int,Int),String) - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) -newtype PosString = PosString ((Int,Int),String) - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) -newtype PosIdent = PosIdent ((Int,Int),String) - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) -newtype PosLineComment = PosLineComment ((Int,Int),String) - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) -newtype PosBlockComment = PosBlockComment ((Int,Int),String) - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) -newtype PosAlloy = PosAlloy ((Int,Int),String) - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) -newtype PosChoco = PosChoco ((Int,Int),String) - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) -instance Spannable PosInteger where - getSpan (PosInteger ((c, l), lex')) = - Span (Pos c' l') (Pos c' $ l' + len lex') - where - c' = toInteger c - l' = toInteger l -instance Spannable PosDouble where - getSpan (PosDouble ((c, l), lex')) = - Span (Pos c' l') (Pos c' $ l' + len lex') - where - c' = toInteger c - l' = toInteger l -instance Spannable PosReal where - getSpan (PosReal ((c, l), lex')) = - Span (Pos c' l') (Pos c' $ l' + len lex') - where - c' = toInteger c - l' = toInteger l -instance Spannable PosString where - getSpan (PosString ((c, l), lex')) = - Span (Pos c' l') (Pos c' $ l' + len lex') - where - c' = toInteger c - l' = toInteger l -instance Spannable PosIdent where - getSpan (PosIdent ((c, l), lex')) = - Span (Pos c' l') (Pos c' $ l' + len lex') - where - c' = toInteger c - l' = toInteger l -instance Spannable PosLineComment where - getSpan (PosLineComment ((c, l), lex')) = - Span (Pos c' l') (Pos c' $ l' + len lex') - where - c' = toInteger c - l' = toInteger l -instance Spannable PosBlockComment where - getSpan (PosBlockComment ((c, l), lex')) = - Span (Pos c' l') (Pos c' $ l' + len lex') - where - c' = toInteger c - l' = toInteger l -instance Spannable PosAlloy where - getSpan (PosAlloy ((c, l), lex')) = - Span (Pos c' l') (Pos c' $ l' + len lex') - where - c' = toInteger c - l' = toInteger l -instance Spannable PosChoco where - getSpan (PosChoco ((c, l), lex')) = - Span (Pos c' l') (Pos c' $ l' + len lex') - where - c' = toInteger c - l' = toInteger l -data Module = Module Span [Declaration] - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Module where - getSpan (Module s _ ) = s -data Declaration - = EnumDecl Span PosIdent [EnumId] | ElementDecl Span Element - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Declaration where - getSpan (EnumDecl s _ _ ) = s - getSpan (ElementDecl s _ ) = s -data Clafer - = Clafer Span Abstract GCard PosIdent Super Reference Card Init Elements - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Clafer where - getSpan (Clafer s _ _ _ _ _ _ _ _ ) = s -data Constraint = Constraint Span [Exp] - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Constraint where - getSpan (Constraint s _ ) = s -data Assertion = Assertion Span [Exp] - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Assertion where - getSpan (Assertion s _ ) = s -data Goal - = GoalMinDeprecated Span [Exp] - | GoalMaxDeprecated Span [Exp] - | GoalMinimize Span [Exp] - | GoalMaximize Span [Exp] - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Goal where - getSpan (GoalMinDeprecated s _ ) = s - getSpan (GoalMaxDeprecated s _ ) = s - getSpan (GoalMinimize s _ ) = s - getSpan (GoalMaximize s _ ) = s -data Abstract = AbstractEmpty Span | Abstract Span - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Abstract where - getSpan (AbstractEmpty s ) = s - getSpan (Abstract s ) = s -data Elements = ElementsEmpty Span | ElementsList Span [Element] - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Elements where - getSpan (ElementsEmpty s ) = s - getSpan (ElementsList s _ ) = s -data Element - = Subclafer Span Clafer - | ClaferUse Span Name Card Elements - | Subconstraint Span Constraint - | Subgoal Span Goal - | SubAssertion Span Assertion - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Element where - getSpan (Subclafer s _ ) = s - getSpan (ClaferUse s _ _ _ ) = s - getSpan (Subconstraint s _ ) = s - getSpan (Subgoal s _ ) = s - getSpan (SubAssertion s _ ) = s -data Super = SuperEmpty Span | SuperSome Span Exp - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Super where - getSpan (SuperEmpty s ) = s - getSpan (SuperSome s _ ) = s -data Reference - = ReferenceEmpty Span - | ReferenceSet Span Exp - | ReferenceBag Span Exp - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Reference where - getSpan (ReferenceEmpty s ) = s - getSpan (ReferenceSet s _ ) = s - getSpan (ReferenceBag s _ ) = s -data Init = InitEmpty Span | InitSome Span InitHow Exp - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Init where - getSpan (InitEmpty s ) = s - getSpan (InitSome s _ _ ) = s -data InitHow = InitConstant Span | InitDefault Span - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable InitHow where - getSpan (InitConstant s ) = s - getSpan (InitDefault s ) = s -data GCard - = GCardEmpty Span - | GCardXor Span - | GCardOr Span - | GCardMux Span - | GCardOpt Span - | GCardInterval Span NCard - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable GCard where - getSpan (GCardEmpty s ) = s - getSpan (GCardXor s ) = s - getSpan (GCardOr s ) = s - getSpan (GCardMux s ) = s - getSpan (GCardOpt s ) = s - getSpan (GCardInterval s _ ) = s -data Card - = CardEmpty Span - | CardLone Span - | CardSome Span - | CardAny Span - | CardNum Span PosInteger - | CardInterval Span NCard - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Card where - getSpan (CardEmpty s ) = s - getSpan (CardLone s ) = s - getSpan (CardSome s ) = s - getSpan (CardAny s ) = s - getSpan (CardNum s _ ) = s - getSpan (CardInterval s _ ) = s -data NCard = NCard Span PosInteger ExInteger - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable NCard where - getSpan (NCard s _ _ ) = s -data ExInteger = ExIntegerAst Span | ExIntegerNum Span PosInteger - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable ExInteger where - getSpan (ExIntegerAst s ) = s - getSpan (ExIntegerNum s _ ) = s -data Name = Path Span [ModId] - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Name where - getSpan (Path s _ ) = s -data Exp - = EDeclAllDisj Span Decl Exp - | EDeclAll Span Decl Exp - | EDeclQuantDisj Span Quant Decl Exp - | EDeclQuant Span Quant Decl Exp - | EImpliesElse Span Exp Exp Exp - | EIff Span Exp Exp - | EImplies Span Exp Exp - | EOr Span Exp Exp - | EXor Span Exp Exp - | EAnd Span Exp Exp - | ENeg Span Exp - | ELt Span Exp Exp - | EGt Span Exp Exp - | EEq Span Exp Exp - | ELte Span Exp Exp - | EGte Span Exp Exp - | ENeq Span Exp Exp - | EIn Span Exp Exp - | ENin Span Exp Exp - | EQuantExp Span Quant Exp - | EAdd Span Exp Exp - | ESub Span Exp Exp - | EMul Span Exp Exp - | EDiv Span Exp Exp - | ERem Span Exp Exp - | EGMax Span Exp - | EGMin Span Exp - | ESum Span Exp - | EProd Span Exp - | ECard Span Exp - | EMinExp Span Exp - | EDomain Span Exp Exp - | ERange Span Exp Exp - | EUnion Span Exp Exp - | EUnionCom Span Exp Exp - | EDifference Span Exp Exp - | EIntersection Span Exp Exp - | EIntersectionDeprecated Span Exp Exp - | EJoin Span Exp Exp - | ClaferId Span Name - | EInt Span PosInteger - | EDouble Span PosDouble - | EReal Span PosReal - | EStr Span PosString - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Exp where - getSpan (EDeclAllDisj s _ _ ) = s - getSpan (EDeclAll s _ _ ) = s - getSpan (EDeclQuantDisj s _ _ _ ) = s - getSpan (EDeclQuant s _ _ _ ) = s - getSpan (EImpliesElse s _ _ _ ) = s - getSpan (EIff s _ _ ) = s - getSpan (EImplies s _ _ ) = s - getSpan (EOr s _ _ ) = s - getSpan (EXor s _ _ ) = s - getSpan (EAnd s _ _ ) = s - getSpan (ENeg s _ ) = s - getSpan (ELt s _ _ ) = s - getSpan (EGt s _ _ ) = s - getSpan (EEq s _ _ ) = s - getSpan (ELte s _ _ ) = s - getSpan (EGte s _ _ ) = s - getSpan (ENeq s _ _ ) = s - getSpan (EIn s _ _ ) = s - getSpan (ENin s _ _ ) = s - getSpan (EQuantExp s _ _ ) = s - getSpan (EAdd s _ _ ) = s - getSpan (ESub s _ _ ) = s - getSpan (EMul s _ _ ) = s - getSpan (EDiv s _ _ ) = s - getSpan (ERem s _ _ ) = s - getSpan (EGMax s _ ) = s - getSpan (EGMin s _ ) = s - getSpan (ESum s _ ) = s - getSpan (EProd s _ ) = s - getSpan (ECard s _ ) = s - getSpan (EMinExp s _ ) = s - getSpan (EDomain s _ _ ) = s - getSpan (ERange s _ _ ) = s - getSpan (EUnion s _ _ ) = s - getSpan (EUnionCom s _ _ ) = s - getSpan (EDifference s _ _ ) = s - getSpan (EIntersection s _ _ ) = s - getSpan (EIntersectionDeprecated s _ _ ) = s - getSpan (EJoin s _ _ ) = s - getSpan (ClaferId s _ ) = s - getSpan (EInt s _ ) = s - getSpan (EDouble s _ ) = s - getSpan (EReal s _ ) = s - getSpan (EStr s _ ) = s -data Decl = Decl Span [LocId] Exp - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Decl where - getSpan (Decl s _ _ ) = s -data Quant - = QuantNo Span - | QuantNot Span - | QuantLone Span - | QuantOne Span - | QuantSome Span - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable Quant where - getSpan (QuantNo s ) = s - getSpan (QuantNot s ) = s - getSpan (QuantLone s ) = s - getSpan (QuantOne s ) = s - getSpan (QuantSome s ) = s -data EnumId = EnumIdIdent Span PosIdent - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable EnumId where - getSpan (EnumIdIdent s _ ) = s -data ModId = ModIdIdent Span PosIdent - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable ModId where - getSpan (ModIdIdent s _ ) = s -data LocId = LocIdIdent Span PosIdent - deriving (Eq, Ord, Show, Read, Data, Typeable, Generic) - -instance Spannable LocId where - getSpan (LocIdIdent s _ ) = s +{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric #-}+module Language.Clafer.Front.AbsClafer where++-- Haskell module generated by the BNF converter+++import Data.Data (Data,Typeable)+import GHC.Generics (Generic)+data Pos = Pos Integer Integer deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)+noPos :: Pos+noPos = Pos 0 0++data Span = Span Pos Pos deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)+noSpan :: Span+noSpan = Span noPos noPos++class Spannable n where getSpan :: n -> Span++instance Spannable n => Spannable [n] where+ getSpan (x:xs) = foldr (\item acc -> getSpan item >- acc ) (getSpan x) xs+ getSpan [] = noSpan++(>-) :: Span -> Span -> Span+(>-) (Span (Pos 0 0) (Pos 0 0)) s = s+(>-) r (Span (Pos 0 0) (Pos 0 0)) = r+(>-) (Span m _) (Span _ p) = Span m p++len :: [a] -> Integer+len = toInteger . length+newtype PosInteger = PosInteger ((Int,Int),String)+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)+newtype PosDouble = PosDouble ((Int,Int),String)+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)+newtype PosReal = PosReal ((Int,Int),String)+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)+newtype PosString = PosString ((Int,Int),String)+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)+newtype PosIdent = PosIdent ((Int,Int),String)+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)+newtype PosLineComment = PosLineComment ((Int,Int),String)+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)+newtype PosBlockComment = PosBlockComment ((Int,Int),String)+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)+newtype PosAlloy = PosAlloy ((Int,Int),String)+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)+newtype PosChoco = PosChoco ((Int,Int),String)+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)+instance Spannable PosInteger where+ getSpan (PosInteger ((c, l), lex')) = + Span (Pos c' l') (Pos c' $ l' + len lex')+ where+ c' = toInteger c+ l' = toInteger l+instance Spannable PosDouble where+ getSpan (PosDouble ((c, l), lex')) = + Span (Pos c' l') (Pos c' $ l' + len lex')+ where+ c' = toInteger c+ l' = toInteger l+instance Spannable PosReal where+ getSpan (PosReal ((c, l), lex')) = + Span (Pos c' l') (Pos c' $ l' + len lex')+ where+ c' = toInteger c+ l' = toInteger l+instance Spannable PosString where+ getSpan (PosString ((c, l), lex')) = + Span (Pos c' l') (Pos c' $ l' + len lex')+ where+ c' = toInteger c+ l' = toInteger l+instance Spannable PosIdent where+ getSpan (PosIdent ((c, l), lex')) = + Span (Pos c' l') (Pos c' $ l' + len lex')+ where+ c' = toInteger c+ l' = toInteger l+instance Spannable PosLineComment where+ getSpan (PosLineComment ((c, l), lex')) = + Span (Pos c' l') (Pos c' $ l' + len lex')+ where+ c' = toInteger c+ l' = toInteger l+instance Spannable PosBlockComment where+ getSpan (PosBlockComment ((c, l), lex')) = + Span (Pos c' l') (Pos c' $ l' + len lex')+ where+ c' = toInteger c+ l' = toInteger l+instance Spannable PosAlloy where+ getSpan (PosAlloy ((c, l), lex')) = + Span (Pos c' l') (Pos c' $ l' + len lex')+ where+ c' = toInteger c+ l' = toInteger l+instance Spannable PosChoco where+ getSpan (PosChoco ((c, l), lex')) = + Span (Pos c' l') (Pos c' $ l' + len lex')+ where+ c' = toInteger c+ l' = toInteger l+data Module = Module Span [Declaration]+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Module where+ getSpan (Module s _ ) = s+data Declaration+ = EnumDecl Span PosIdent [EnumId] | ElementDecl Span Element+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Declaration where+ getSpan (EnumDecl s _ _ ) = s+ getSpan (ElementDecl s _ ) = s+data Clafer+ = Clafer Span Abstract GCard PosIdent Super Reference Card Init Elements+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Clafer where+ getSpan (Clafer s _ _ _ _ _ _ _ _ ) = s+data Constraint = Constraint Span [Exp]+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Constraint where+ getSpan (Constraint s _ ) = s+data Assertion = Assertion Span [Exp]+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Assertion where+ getSpan (Assertion s _ ) = s+data Goal+ = GoalMinDeprecated Span [Exp]+ | GoalMaxDeprecated Span [Exp]+ | GoalMinimize Span [Exp]+ | GoalMaximize Span [Exp]+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Goal where+ getSpan (GoalMinDeprecated s _ ) = s+ getSpan (GoalMaxDeprecated s _ ) = s+ getSpan (GoalMinimize s _ ) = s+ getSpan (GoalMaximize s _ ) = s+data Abstract = AbstractEmpty Span | Abstract Span+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Abstract where+ getSpan (AbstractEmpty s ) = s+ getSpan (Abstract s ) = s+data Elements = ElementsEmpty Span | ElementsList Span [Element]+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Elements where+ getSpan (ElementsEmpty s ) = s+ getSpan (ElementsList s _ ) = s+data Element+ = Subclafer Span Clafer+ | ClaferUse Span Name Card Elements+ | Subconstraint Span Constraint+ | Subgoal Span Goal+ | SubAssertion Span Assertion+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Element where+ getSpan (Subclafer s _ ) = s+ getSpan (ClaferUse s _ _ _ ) = s+ getSpan (Subconstraint s _ ) = s+ getSpan (Subgoal s _ ) = s+ getSpan (SubAssertion s _ ) = s+data Super = SuperEmpty Span | SuperSome Span Exp+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Super where+ getSpan (SuperEmpty s ) = s+ getSpan (SuperSome s _ ) = s+data Reference+ = ReferenceEmpty Span+ | ReferenceSet Span Exp+ | ReferenceBag Span Exp+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Reference where+ getSpan (ReferenceEmpty s ) = s+ getSpan (ReferenceSet s _ ) = s+ getSpan (ReferenceBag s _ ) = s+data Init = InitEmpty Span | InitSome Span InitHow Exp+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Init where+ getSpan (InitEmpty s ) = s+ getSpan (InitSome s _ _ ) = s+data InitHow = InitConstant Span | InitDefault Span+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable InitHow where+ getSpan (InitConstant s ) = s+ getSpan (InitDefault s ) = s+data GCard+ = GCardEmpty Span+ | GCardXor Span+ | GCardOr Span+ | GCardMux Span+ | GCardOpt Span+ | GCardInterval Span NCard+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable GCard where+ getSpan (GCardEmpty s ) = s+ getSpan (GCardXor s ) = s+ getSpan (GCardOr s ) = s+ getSpan (GCardMux s ) = s+ getSpan (GCardOpt s ) = s+ getSpan (GCardInterval s _ ) = s+data Card+ = CardEmpty Span+ | CardLone Span+ | CardSome Span+ | CardAny Span+ | CardNum Span PosInteger+ | CardInterval Span NCard+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Card where+ getSpan (CardEmpty s ) = s+ getSpan (CardLone s ) = s+ getSpan (CardSome s ) = s+ getSpan (CardAny s ) = s+ getSpan (CardNum s _ ) = s+ getSpan (CardInterval s _ ) = s+data NCard = NCard Span PosInteger ExInteger+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable NCard where+ getSpan (NCard s _ _ ) = s+data ExInteger = ExIntegerAst Span | ExIntegerNum Span PosInteger+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable ExInteger where+ getSpan (ExIntegerAst s ) = s+ getSpan (ExIntegerNum s _ ) = s+data Name = Path Span [ModId]+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Name where+ getSpan (Path s _ ) = s+data Exp+ = EDeclAllDisj Span Decl Exp+ | EDeclAll Span Decl Exp+ | EDeclQuantDisj Span Quant Decl Exp+ | EDeclQuant Span Quant Decl Exp+ | EImpliesElse Span Exp Exp Exp+ | EIff Span Exp Exp+ | EImplies Span Exp Exp+ | EOr Span Exp Exp+ | EXor Span Exp Exp+ | EAnd Span Exp Exp+ | ENeg Span Exp+ | ELt Span Exp Exp+ | EGt Span Exp Exp+ | EEq Span Exp Exp+ | ELte Span Exp Exp+ | EGte Span Exp Exp+ | ENeq Span Exp Exp+ | EIn Span Exp Exp+ | ENin Span Exp Exp+ | EQuantExp Span Quant Exp+ | EAdd Span Exp Exp+ | ESub Span Exp Exp+ | EMul Span Exp Exp+ | EDiv Span Exp Exp+ | ERem Span Exp Exp+ | EGMax Span Exp+ | EGMin Span Exp+ | ESum Span Exp+ | EProd Span Exp+ | ECard Span Exp+ | EMinExp Span Exp+ | EDomain Span Exp Exp+ | ERange Span Exp Exp+ | EUnion Span Exp Exp+ | EUnionCom Span Exp Exp+ | EDifference Span Exp Exp+ | EIntersection Span Exp Exp+ | EIntersectionDeprecated Span Exp Exp+ | EJoin Span Exp Exp+ | ClaferId Span Name+ | EInt Span PosInteger+ | EDouble Span PosDouble+ | EReal Span PosReal+ | EStr Span PosString+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Exp where+ getSpan (EDeclAllDisj s _ _ ) = s+ getSpan (EDeclAll s _ _ ) = s+ getSpan (EDeclQuantDisj s _ _ _ ) = s+ getSpan (EDeclQuant s _ _ _ ) = s+ getSpan (EImpliesElse s _ _ _ ) = s+ getSpan (EIff s _ _ ) = s+ getSpan (EImplies s _ _ ) = s+ getSpan (EOr s _ _ ) = s+ getSpan (EXor s _ _ ) = s+ getSpan (EAnd s _ _ ) = s+ getSpan (ENeg s _ ) = s+ getSpan (ELt s _ _ ) = s+ getSpan (EGt s _ _ ) = s+ getSpan (EEq s _ _ ) = s+ getSpan (ELte s _ _ ) = s+ getSpan (EGte s _ _ ) = s+ getSpan (ENeq s _ _ ) = s+ getSpan (EIn s _ _ ) = s+ getSpan (ENin s _ _ ) = s+ getSpan (EQuantExp s _ _ ) = s+ getSpan (EAdd s _ _ ) = s+ getSpan (ESub s _ _ ) = s+ getSpan (EMul s _ _ ) = s+ getSpan (EDiv s _ _ ) = s+ getSpan (ERem s _ _ ) = s+ getSpan (EGMax s _ ) = s+ getSpan (EGMin s _ ) = s+ getSpan (ESum s _ ) = s+ getSpan (EProd s _ ) = s+ getSpan (ECard s _ ) = s+ getSpan (EMinExp s _ ) = s+ getSpan (EDomain s _ _ ) = s+ getSpan (ERange s _ _ ) = s+ getSpan (EUnion s _ _ ) = s+ getSpan (EUnionCom s _ _ ) = s+ getSpan (EDifference s _ _ ) = s+ getSpan (EIntersection s _ _ ) = s+ getSpan (EIntersectionDeprecated s _ _ ) = s+ getSpan (EJoin s _ _ ) = s+ getSpan (ClaferId s _ ) = s+ getSpan (EInt s _ ) = s+ getSpan (EDouble s _ ) = s+ getSpan (EReal s _ ) = s+ getSpan (EStr s _ ) = s+data Decl = Decl Span [LocId] Exp+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Decl where+ getSpan (Decl s _ _ ) = s+data Quant+ = QuantNo Span+ | QuantNot Span+ | QuantLone Span+ | QuantOne Span+ | QuantSome Span+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable Quant where+ getSpan (QuantNo s ) = s+ getSpan (QuantNot s ) = s+ getSpan (QuantLone s ) = s+ getSpan (QuantOne s ) = s+ getSpan (QuantSome s ) = s+data EnumId = EnumIdIdent Span PosIdent+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable EnumId where+ getSpan (EnumIdIdent s _ ) = s+data ModId = ModIdIdent Span PosIdent+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable ModId where+ getSpan (ModIdIdent s _ ) = s+data LocId = LocIdIdent Span PosIdent+ deriving (Eq, Ord, Show, Read, Data, Typeable, Generic)++instance Spannable LocId where+ getSpan (LocIdIdent s _ ) = s
src/Language/Clafer/Front/ErrM.hs view
@@ -16,7 +16,7 @@ deriving (Read, Show, Eq, Ord) instance Monad Err where - return = Ok + return = pure fail = Bad noPos Ok a >>= f = f a Bad p s >>= _ = Bad p s @@ -24,7 +24,7 @@ instance Applicative Err where pure = Ok (Bad p s) <*> _ = Bad p s - (Ok f) <*> o = liftM f o + (Ok f) <*> o = fmap f o instance Functor Err where
src/Language/Clafer/Front/LayoutResolver.hs view
@@ -1,334 +1,334 @@-{-# LANGUAGE FlexibleContexts #-} -{- - Copyright (C) 2012 Kacper Bak, Christopher Walker <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} --- | Resolves indentation into explicit nesting using { } -module Language.Clafer.Front.LayoutResolver where - --- very simple layout resolver -import Control.Monad.State -import Data.Functor.Identity (Identity) -import Language.ClaferT - -import Language.Clafer.Front.LexClafer -import Data.Maybe - -data LayEnv = LayEnv { - level :: Int, - levels :: [Int], - input :: String, - output :: String, - brCtr :: Int - } deriving Show - - --- | ident level of new line, current level or parenthesis -type LastNl = (Int, Int) - -type Position = Posn - -data ExToken = NewLine LastNl | ExToken Token deriving Show - --- | ident level stack, last new line -data LEnv = LEnv [Int] (Maybe LastNl) - -getToken :: (Monad m) => ExToken -> ClaferT m Token -getToken (ExToken t) = return t -getToken (NewLine (x, y)) = throwErr $ ParseErr (ErrPos 0 fPos fPos) $ "LayoutResolver.getToken: Cannot get ExToken NewLine"-- this shoud never happen - where - fPos = Pos (fromIntegral x) (fromIntegral y) - - -layoutOpen :: String -layoutOpen = "{" -layoutClose :: String -layoutClose = "}" - -resolveLayout :: (Monad m) => [Token] -> ClaferT m [Token] -resolveLayout xs = addNewLines xs >>= (resolve (LEnv [1] Nothing)) >>= adjust - -resolve :: (Monad m) => LEnv -> [ExToken] -> ClaferT m [Token] -resolve (LEnv st _) [] = return $ replicate (length st - 1) dedent -resolve (LEnv st _) ((NewLine lastNl):ts) = resolve (LEnv st (Just lastNl)) ts -resolve env@(LEnv st lastNl) (t:ts) - | isJust lastNl && parLev > 0 = do - r <- resolve env ts - t' >>= return . (:r) - | isJust lastNl && newLev > head st = do - r <- resolve (LEnv (newLev : st) Nothing) ts - t' >>= return . (indent:) . (:r) - | isJust lastNl && newLev == head st = do - r <- resolve (LEnv st Nothing) ts - t' >>= return . (:r) - | isJust lastNl = do - r <- resolve (LEnv st' Nothing) ts - t' >>= return . (replicate (length st - length st') dedent ++) . (:r) - | otherwise = do - r <- resolve env ts - t' >>= return . (:r) - where - t' = getToken t - (newLev, parLev) = fromJust lastNl - st' = dropWhile (newLev <) st - -indent :: Token -indent = PT (Pn 0 0 0) (TS "{" $ fromJust $ tokenLookup "{") -dedent :: Token -dedent = PT (Pn 0 0 0) (TS "}" $ fromJust $ tokenLookup "}") - -toToken :: ExToken -> [Token] -toToken (NewLine _) = [] -toToken (ExToken t) = [t] - -isExTokenIn :: [String] -> ExToken -> Bool -isExTokenIn l (ExToken t) = isTokenIn l t -isExTokenIn _ _ = False - - -isNewLine :: Token -> Token -> Bool -isNewLine t1 t2 = line t1 < line t2 - --- | Add to the global and column positions of a token. --- | The column position is only changed if the token is on --- | the same line as the given position. -incrGlobal :: (Monad m) => Position -- ^ If the token is on the same line - -- as this position, update the column position. - -> Int -- ^ Number of characters to add to the position. - -> Token -> ClaferT m Token -incrGlobal (Pn _ l0 _) i (PT (Pn g l c) t) = - return $ if l /= l0 then PT (Pn (g + i) l c) t - else PT (Pn (g + i) l (c + i)) t -incrGlobal _ _ (Err (Pn z x y)) = do - env <- getEnv - let claferModel = lines $ unlines $ modelFrags env - throwErr $ ParseErr (ErrPos z fPos fPos) $ "Cannot add token at '" ++ (take y $ claferModel !! (x-1)) ++ "'" - where - fPos = Pos (fromIntegral x) (fromIntegral y) - -tokenLookup :: String -> Maybe Int -tokenLookup s = treeFind resWords - where - treeFind N = Nothing - treeFind (B a t left right) | s < a = treeFind left - | s > a = treeFind right - | s == a = tokenCode t - treeFind (B _ _ _ _) = error "LayoutResolver.treeFind should never happen" - tokenCode :: Tok -> Maybe Int - tokenCode (TS _ c) = Just c - tokenCode _ = Nothing - --- | Get the position of a token. -position :: Token -> Position -position t = case t of - PT p _ -> p - Err p -> p - --- | Get the line number of a token. -line :: Token -> Int -line t = case position t of Pn _ l _ -> l - --- | Get the column number of a token. -column :: Token -> Int -column t = case position t of Pn _ _ c -> c - --- | Check if a token is one of the given symbols. -isTokenIn :: [String] -> Token -> Bool -isTokenIn ts t = case t of - PT _ (TS r _) | elem r ts -> True - _ -> False - --- | Check if a token is the layout open token. -isLayoutOpen :: Token -> Bool -isLayoutOpen = isTokenIn [layoutOpen] - -isBracketOpen :: Token -> Bool -isBracketOpen = isTokenIn ["["] - --- | Check if a token is the layout close token. -isLayoutClose :: Token -> Bool -isLayoutClose = isTokenIn [layoutClose] - -isBracketClose :: Token -> Bool -isBracketClose = isTokenIn ["]"] - --- | Get the number of characters in the token. -tokenLength :: Token -> Int -tokenLength t = length $ prToken t - --- data ExToken = NewLine (Int, Int) | ExToken Token -addNewLines :: (Monad m) => [Token] -> ClaferT m [ExToken] -addNewLines [] = return [] -addNewLines ts@(t:_) = addNewLines' (if isBracketOpen t then 1 else 0) ts - -addNewLines' :: (Monad m) => Int -> [Token] -> ClaferT m [ExToken] -addNewLines' _ [] = return [] -addNewLines' 0 (t:[]) = return [ExToken t] -addNewLines' 1 (t:[]) = return [ExToken t] -addNewLines' _ ((PT (Pn z x y) t):[]) = throwErr $ ParseErr (ErrPos z fPos fPos) $ "']' bracket missing for (" ++ show t ++ ")" - where - fPos = (Pos (fromIntegral x) (fromIntegral y)) -addNewLines' n (t0:t1:ts) - | isNewLine t0 t1 && isBracketOpen t1 = - addNewLines' (n + 1) (t1:ts) >>= (return . (ExToken t0:) . (NewLine (column t1, n):)) - | isNewLine t0 t1 && isBracketClose t1 = - addNewLines' (n - 1) (t1:ts) >>= (return . (ExToken t0:) . (NewLine (column t1, n):)) - | isLayoutOpen t1 || isBracketOpen t1 = - addNewLines' (n + 1) (t1:ts) >>= (return . (ExToken t0:)) - | isLayoutClose t1 || isBracketClose t1 = - addNewLines' (n - 1) (t1:ts) >>= (return . (ExToken t0:)) - | isNewLine t0 t1 = addNewLines' n (t1:ts) >>= (return . (ExToken t0:) . (NewLine (column t1, n):)) - | otherwise = addNewLines' n (t1:ts) >>= (return . (ExToken t0:)) -addNewLines' _ tokens' = throwErr (ClaferErr ("[bug] LayoutResolver.addNewLines': invalid argument:" ++ show tokens') :: CErr Span) -- This should never happen! - - -adjust :: (Monad m) => [Token] -> ClaferT m [Token] -adjust [] = return [] -adjust (t:[]) = return [t] -adjust (t:ts) = ((updToken (t:ts)) >>= adjust) >>= (return . (t:)) - -updToken :: (Monad m) => [Token] -> ClaferT m [Token] -updToken (t0:t1:ts) - | isLayoutOpen t1 || isLayoutClose t1 = addToken (nextPos t0) sym ts - | otherwise = return (t1:ts) - where - sym = if isLayoutOpen t1 then "{" else "}" - -- | Get the position immediately to the right of the given token. - nextPos :: Token -> Position - nextPos t = Pn (g + s) l (c + s + 1) - where Pn g l c = position t - s = tokenLength t -updToken [] = return [] -updToken (t:ts) = return (t:ts) - --- | Insert a new symbol token at the begninning of a list of tokens. -addToken :: (Monad m) => Position -- ^ Position of the new token. - -> String -- ^ Symbol in the new token. - -> [Token] -- ^ The rest of the tokens. These will have their - -- positions updated to make room for the new token. - -> ClaferT m [Token] -addToken p@(Pn z x y) s ts = do - when (not $ validToken t) $ throwErr $ ParseErr (ErrPos z fPos fPos) $ "not a reserved word: " ++ show s - (>>= (return . (PT p (TS s (fromJust t)):))) $ mapM (incrGlobal p (length s)) ts - where - fPos = Pos (fromIntegral x) (fromIntegral y) - validToken Nothing = False - validToken (Just _) = True - t = tokenLookup s - -resLayout :: String -> String -resLayout input' = - reverse $ output $ execState resolveLayout' $ LayEnv 0 [] input'' [] 0 - where - input'' = unlines $ filter (/= "") $ lines input' - - -resolveLayout' :: StateT LayEnv Identity () -resolveLayout' = do - stop <- isEof - when (not stop) $ do - c <- getc - c' <- handleIndent c - emit c' - resolveLayout' - -handleIndent :: Char -> StateT LayEnv Identity Char -handleIndent c = case c of - '\n' -> do - emit c - n <- eatSpaces - c' <- readC n - emitIndent n - emitDedent n - when (c' `elem` ['[', ']','{', '}']) $ void $ handleIndent c' - return c' - '[' -> do - modify (\e -> e {brCtr = brCtr e + 1}) - return c - '{' -> do - modify (\e -> e {brCtr = brCtr e + 1}) - return c - ']' -> do - modify (\e -> e {brCtr = brCtr e - 1}) - return c - '}' -> do - modify (\e -> e {brCtr = brCtr e - 1}) - return c - _ -> return c - - -emit :: MonadState LayEnv m => Char -> m () -emit c = modify (\e -> e {output = c : output e}) - - -readC :: (Num a, Ord a) => a -> StateT LayEnv Identity Char -readC n = if n > 0 then getc else return '\n' - - -eatSpaces :: StateT LayEnv Identity Int -eatSpaces = do - cs <- gets input - let (sp, rest) = break (/= ' ') cs - modify (\e -> e {input = rest, output = sp ++ output e}) - ctr <- gets brCtr - if ctr > 0 then gets level else return $ length sp - - -emitIndent :: MonadState LayEnv m => Int -> m () -emitIndent n = do - lev <- gets level - when (n > lev) $ do - ctr <- gets brCtr - when (ctr < 1) $ do - emit '{' - modify (\e -> e {level = n, levels = lev : levels e}) - - -emitDedent :: MonadState LayEnv m => Int -> m () -emitDedent n = do - lev <- gets level - when (n < lev) $ do - ctr <- gets brCtr - when (ctr < 1) $ emit '}' - modify (\e -> e {level = head $ levels e, levels = tail $ levels e}) - emitDedent n - - -isEof :: StateT LayEnv Identity Bool -isEof = null `liftM` (gets input) - - -getc :: StateT LayEnv Identity Char -getc = do - c <- gets (head.input) - modify (\e -> e {input = tail $ input e}) - return c - -revertLayout :: String -> String -revertLayout input' = unlines $ revertLayout' (lines input') 0 - -revertLayout' :: [String] -> Int -> [String] -revertLayout' [] _ = [] -revertLayout' ([]:xss) i = revertLayout' xss i -revertLayout' (('{':xs):xss) i = (replicate i' ' ' ++ xs):revertLayout' xss i' - where i' = i + 2 -revertLayout' (('}':xs):xss) i = (replicate i' ' ' ++ xs):revertLayout' xss i' - where i' = i - 2 -revertLayout' (xs:xss) i = (replicate i ' ' ++ xs):revertLayout' xss i +{-# LANGUAGE FlexibleContexts #-}+{-+ Copyright (C) 2012 Kacper Bak, Christopher Walker <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+-- | Resolves indentation into explicit nesting using { }+module Language.Clafer.Front.LayoutResolver where++-- very simple layout resolver+import Control.Monad.State+import Data.Functor.Identity (Identity)+import Language.ClaferT++import Language.Clafer.Front.LexClafer+import Data.Maybe++data LayEnv = LayEnv {+ level :: Int,+ levels :: [Int],+ input :: String,+ output :: String,+ brCtr :: Int+ } deriving Show+++-- | ident level of new line, current level or parenthesis+type LastNl = (Int, Int)++type Position = Posn++data ExToken = NewLine LastNl | ExToken Token deriving Show++-- | ident level stack, last new line+data LEnv = LEnv [Int] (Maybe LastNl)++getToken :: (Monad m) => ExToken -> ClaferT m Token+getToken (ExToken t) = return t+getToken (NewLine (x, y)) = throwErr $ ParseErr (ErrPos 0 fPos fPos) $ "LayoutResolver.getToken: Cannot get ExToken NewLine"-- this shoud never happen+ where+ fPos = Pos (fromIntegral x) (fromIntegral y)+++layoutOpen :: String+layoutOpen = "{"+layoutClose :: String+layoutClose = "}"++resolveLayout :: (Monad m) => [Token] -> ClaferT m [Token]+resolveLayout xs = addNewLines xs >>= (resolve (LEnv [1] Nothing)) >>= adjust++resolve :: (Monad m) => LEnv -> [ExToken] -> ClaferT m [Token]+resolve (LEnv st _) [] = return $ replicate (length st - 1) dedent+resolve (LEnv st _) ((NewLine lastNl):ts) = resolve (LEnv st (Just lastNl)) ts+resolve env@(LEnv st lastNl) (t:ts)+ | isJust lastNl && parLev > 0 = do+ r <- resolve env ts+ t' >>= return . (:r)+ | isJust lastNl && newLev > head st = do+ r <- resolve (LEnv (newLev : st) Nothing) ts+ t' >>= return . (indent:) . (:r)+ | isJust lastNl && newLev == head st = do+ r <- resolve (LEnv st Nothing) ts+ t' >>= return . (:r)+ | isJust lastNl = do+ r <- resolve (LEnv st' Nothing) ts+ t' >>= return . (replicate (length st - length st') dedent ++) . (:r)+ | otherwise = do+ r <- resolve env ts+ t' >>= return . (:r)+ where+ t' = getToken t+ (newLev, parLev) = fromJust lastNl+ st' = dropWhile (newLev <) st++indent :: Token+indent = PT (Pn 0 0 0) (TS "{" $ fromJust $ tokenLookup "{")+dedent :: Token+dedent = PT (Pn 0 0 0) (TS "}" $ fromJust $ tokenLookup "}")++toToken :: ExToken -> [Token]+toToken (NewLine _) = []+toToken (ExToken t) = [t]++isExTokenIn :: [String] -> ExToken -> Bool+isExTokenIn l (ExToken t) = isTokenIn l t+isExTokenIn _ _ = False+++isNewLine :: Token -> Token -> Bool+isNewLine t1 t2 = line t1 < line t2++-- | Add to the global and column positions of a token.+-- | The column position is only changed if the token is on+-- | the same line as the given position.+incrGlobal :: (Monad m) => Position -- ^ If the token is on the same line+ -- as this position, update the column position.+ -> Int -- ^ Number of characters to add to the position.+ -> Token -> ClaferT m Token+incrGlobal (Pn _ l0 _) i (PT (Pn g l c) t) =+ return $ if l /= l0 then PT (Pn (g + i) l c) t+ else PT (Pn (g + i) l (c + i)) t+incrGlobal _ _ (Err (Pn z x y)) = do+ env <- getEnv+ let claferModel = lines $ unlines $ modelFrags env+ throwErr $ ParseErr (ErrPos z fPos fPos) $ "Cannot add token at '" ++ (take y $ claferModel !! (x-1)) ++ "'"+ where+ fPos = Pos (fromIntegral x) (fromIntegral y)++tokenLookup :: String -> Maybe Int+tokenLookup s = treeFind resWords+ where+ treeFind N = Nothing+ treeFind (B a t left right) | s < a = treeFind left+ | s > a = treeFind right+ | s == a = tokenCode t+ treeFind (B _ _ _ _) = error "LayoutResolver.treeFind should never happen"+ tokenCode :: Tok -> Maybe Int+ tokenCode (TS _ c) = Just c+ tokenCode _ = Nothing++-- | Get the position of a token.+position :: Token -> Position+position t = case t of+ PT p _ -> p+ Err p -> p++-- | Get the line number of a token.+line :: Token -> Int+line t = case position t of Pn _ l _ -> l++-- | Get the column number of a token.+column :: Token -> Int+column t = case position t of Pn _ _ c -> c++-- | Check if a token is one of the given symbols.+isTokenIn :: [String] -> Token -> Bool+isTokenIn ts t = case t of+ PT _ (TS r _) | elem r ts -> True+ _ -> False++-- | Check if a token is the layout open token.+isLayoutOpen :: Token -> Bool+isLayoutOpen = isTokenIn [layoutOpen]++isBracketOpen :: Token -> Bool+isBracketOpen = isTokenIn ["["]++-- | Check if a token is the layout close token.+isLayoutClose :: Token -> Bool+isLayoutClose = isTokenIn [layoutClose]++isBracketClose :: Token -> Bool+isBracketClose = isTokenIn ["]"]++-- | Get the number of characters in the token.+tokenLength :: Token -> Int+tokenLength t = length $ prToken t++-- data ExToken = NewLine (Int, Int) | ExToken Token+addNewLines :: (Monad m) => [Token] -> ClaferT m [ExToken]+addNewLines [] = return []+addNewLines ts@(t:_) = addNewLines' (if isBracketOpen t then 1 else 0) ts++addNewLines' :: (Monad m) => Int -> [Token] -> ClaferT m [ExToken]+addNewLines' _ [] = return []+addNewLines' 0 (t:[]) = return [ExToken t]+addNewLines' 1 (t:[]) = return [ExToken t]+addNewLines' _ ((PT (Pn z x y) t):[]) = throwErr $ ParseErr (ErrPos z fPos fPos) $ "']' bracket missing for (" ++ show t ++ ")"+ where+ fPos = (Pos (fromIntegral x) (fromIntegral y))+addNewLines' n (t0:t1:ts)+ | isNewLine t0 t1 && isBracketOpen t1 =+ addNewLines' (n + 1) (t1:ts) >>= (return . (ExToken t0:) . (NewLine (column t1, n):))+ | isNewLine t0 t1 && isBracketClose t1 =+ addNewLines' (n - 1) (t1:ts) >>= (return . (ExToken t0:) . (NewLine (column t1, n):))+ | isLayoutOpen t1 || isBracketOpen t1 =+ addNewLines' (n + 1) (t1:ts) >>= (return . (ExToken t0:))+ | isLayoutClose t1 || isBracketClose t1 =+ addNewLines' (n - 1) (t1:ts) >>= (return . (ExToken t0:))+ | isNewLine t0 t1 = addNewLines' n (t1:ts) >>= (return . (ExToken t0:) . (NewLine (column t1, n):))+ | otherwise = addNewLines' n (t1:ts) >>= (return . (ExToken t0:))+addNewLines' _ tokens' = throwErr (ClaferErr ("[bug] LayoutResolver.addNewLines': invalid argument:" ++ show tokens') :: CErr Span) -- This should never happen!+++adjust :: (Monad m) => [Token] -> ClaferT m [Token]+adjust [] = return []+adjust (t:[]) = return [t]+adjust (t:ts) = ((updToken (t:ts)) >>= adjust) >>= (return . (t:))++updToken :: (Monad m) => [Token] -> ClaferT m [Token]+updToken (t0:t1:ts)+ | isLayoutOpen t1 || isLayoutClose t1 = addToken (nextPos t0) sym ts+ | otherwise = return (t1:ts)+ where+ sym = if isLayoutOpen t1 then "{" else "}"+ -- | Get the position immediately to the right of the given token.+ nextPos :: Token -> Position+ nextPos t = Pn (g + s) l (c + s + 1)+ where Pn g l c = position t+ s = tokenLength t+updToken [] = return []+updToken (t:ts) = return (t:ts)++-- | Insert a new symbol token at the begninning of a list of tokens.+addToken :: (Monad m) => Position -- ^ Position of the new token.+ -> String -- ^ Symbol in the new token.+ -> [Token] -- ^ The rest of the tokens. These will have their+ -- positions updated to make room for the new token.+ -> ClaferT m [Token]+addToken p@(Pn z x y) s ts = do+ when (not $ validToken t) $ throwErr $ ParseErr (ErrPos z fPos fPos) $ "not a reserved word: " ++ show s+ (>>= (return . (PT p (TS s (fromJust t)):))) $ mapM (incrGlobal p (length s)) ts+ where+ fPos = Pos (fromIntegral x) (fromIntegral y)+ validToken Nothing = False+ validToken (Just _) = True+ t = tokenLookup s++resLayout :: String -> String+resLayout input' =+ reverse $ output $ execState resolveLayout' $ LayEnv 0 [] input'' [] 0+ where+ input'' = unlines $ filter (/= "") $ lines input'+++resolveLayout' :: StateT LayEnv Identity ()+resolveLayout' = do+ stop <- isEof+ when (not stop) $ do+ c <- getc+ c' <- handleIndent c+ emit c'+ resolveLayout'++handleIndent :: Char -> StateT LayEnv Identity Char+handleIndent c = case c of+ '\n' -> do+ emit c+ n <- eatSpaces+ c' <- readC n+ emitIndent n+ emitDedent n+ when (c' `elem` ['[', ']','{', '}']) $ void $ handleIndent c'+ return c'+ '[' -> do+ modify (\e -> e {brCtr = brCtr e + 1})+ return c+ '{' -> do+ modify (\e -> e {brCtr = brCtr e + 1})+ return c+ ']' -> do+ modify (\e -> e {brCtr = brCtr e - 1})+ return c+ '}' -> do+ modify (\e -> e {brCtr = brCtr e - 1})+ return c+ _ -> return c+++emit :: MonadState LayEnv m => Char -> m ()+emit c = modify (\e -> e {output = c : output e})+++readC :: (Num a, Ord a) => a -> StateT LayEnv Identity Char+readC n = if n > 0 then getc else return '\n'+++eatSpaces :: StateT LayEnv Identity Int+eatSpaces = do+ cs <- gets input+ let (sp, rest) = break (/= ' ') cs+ modify (\e -> e {input = rest, output = sp ++ output e})+ ctr <- gets brCtr+ if ctr > 0 then gets level else return $ length sp+++emitIndent :: MonadState LayEnv m => Int -> m ()+emitIndent n = do+ lev <- gets level+ when (n > lev) $ do+ ctr <- gets brCtr+ when (ctr < 1) $ do+ emit '{'+ modify (\e -> e {level = n, levels = lev : levels e})+++emitDedent :: MonadState LayEnv m => Int -> m ()+emitDedent n = do+ lev <- gets level+ when (n < lev) $ do+ ctr <- gets brCtr+ when (ctr < 1) $ emit '}'+ modify (\e -> e {level = head $ levels e, levels = tail $ levels e})+ emitDedent n+++isEof :: StateT LayEnv Identity Bool+isEof = null `liftM` (gets input)+++getc :: StateT LayEnv Identity Char+getc = do+ c <- gets (head.input)+ modify (\e -> e {input = tail $ input e})+ return c++revertLayout :: String -> String+revertLayout input' = unlines $ revertLayout' (lines input') 0++revertLayout' :: [String] -> Int -> [String]+revertLayout' [] _ = []+revertLayout' ([]:xss) i = revertLayout' xss i+revertLayout' (('{':xs):xss) i = (replicate i' ' ' ++ xs):revertLayout' xss i'+ where i' = i + 2+revertLayout' (('}':xs):xss) i = (replicate i' ' ' ++ xs):revertLayout' xss i'+ where i' = i - 2+revertLayout' (xs:xss) i = (replicate i ' ' ++ xs):revertLayout' xss i
+ src/Language/Clafer/Front/LexClafer.hs view
@@ -0,0 +1,420 @@+{-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-missing-signatures #-} +{-# LANGUAGE CPP,MagicHash #-} +{-# LINE 3 "Language/Clafer/Front/LexClafer.x" #-} + +{-# OPTIONS -fno-warn-incomplete-patterns #-} +{-# OPTIONS_GHC -w #-} +module Language.Clafer.Front.LexClafer where + + + +import qualified Data.Bits +import Data.Word (Word8) + +#if __GLASGOW_HASKELL__ >= 603 +#include "ghcconfig.h" +#elif defined(__GLASGOW_HASKELL__) +#include "config.h" +#endif +#if __GLASGOW_HASKELL__ >= 503 +import Data.Array +import Data.Char (ord) +import Data.Array.Base (unsafeAt) +#else +import Array +import Char (ord) +#endif +#if __GLASGOW_HASKELL__ >= 503 +import GHC.Exts +#else +import GlaExts +#endif +alex_tab_size :: Int +alex_tab_size = 8 +alex_base :: AlexAddr +alex_base = AlexA# "\xf8\xff\xff\xff\x4c\x00\x00\x00\xef\x00\x00\x00\x92\x01\x00\x00\x35\x02\x00\x00\xd8\x02\x00\x00\x8d\xff\xff\xff\x98\xff\xff\xff\x99\xff\xff\xff\xa6\xff\xff\xff\x9b\xff\xff\xff\xa3\xff\xff\xff\xa0\xff\xff\xff\xa1\xff\xff\xff\xd8\x03\x00\x00\x92\xff\xff\xff\x98\x03\x00\x00\x98\x04\x00\x00\x93\xff\xff\xff\x58\x04\x00\x00\x58\x05\x00\x00\x18\x05\x00\x00\x9c\x05\x00\x00\x20\x06\x00\x00\xa4\x06\x00\x00\x28\x07\x00\x00\xfe\x07\x00\x00\xfe\x08\x00\x00\x34\x00\x00\x00\x69\x07\x00\x00\x7e\x09\x00\x00\x3e\x09\x00\x00\xbe\x09\x00\x00\x33\x0a\x00\x00\x4d\x00\x00\x00\x61\x00\x00\x00\x79\x00\x00\x00\x7e\x00\x00\x00\xe5\xff\xff\xff\x4f\x00\x00\x00\xd4\xff\xff\xff\xd5\xff\xff\xff\xed\xff\xff\xff\xb3\xff\xff\xff\x00\x00\x00\x00\xbc\xff\xff\xff\xd7\xff\xff\xff\x3d\x00\x00\x00\xf1\xff\xff\xff\x2d\x00\x00\x00\x52\x00\x00\x00\x8c\x00\x00\x00\x1d\x01\x00\x00\x03\x0b\x00\x00\x00\x00\x00\x00\x28\x0b\x00\x00\x79\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd\x0b\x00\x00\x00\x00\x00\x00\x81\x0c\x00\x00"# + +alex_table :: AlexAddr +alex_table = AlexA# "\x00\x00\x25\x00\x25\x00\x25\x00\x25\x00\x25\x00\x12\x00\x0f\x00\x06\x00\x07\x00\x09\x00\x0a\x00\x0d\x00\x08\x00\x17\x00\x19\x00\x2c\x00\x2c\x00\x2c\x00\x2c\x00\x0c\x00\x2c\x00\x0b\x00\x1a\x00\x25\x00\x28\x00\x21\x00\x2c\x00\x38\x00\x2c\x00\x32\x00\x2c\x00\x2c\x00\x2c\x00\x31\x00\x26\x00\x2c\x00\x27\x00\x30\x00\x2a\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x29\x00\x2c\x00\x2f\x00\x2e\x00\x29\x00\x2c\x00\x2c\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x2b\x00\x2c\x00\x2c\x00\x21\x00\x2c\x00\x2c\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x2c\x00\x2d\x00\x2c\x00\x01\x00\x2c\x00\x2c\x00\x2c\x00\x2e\x00\x39\x00\x2c\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x25\x00\x25\x00\x25\x00\x25\x00\x25\x00\x00\x00\x2e\x00\x24\x00\x00\x00\x21\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x00\x00\x00\x00\x00\x00\x25\x00\x00\x00\x00\x00\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x21\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x22\x00\x20\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x14\x00\x15\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3a\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x11\x00\x13\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x11\x00\x13\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x10\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x10\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x05\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x10\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x04\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x10\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x03\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x11\x00\x13\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x02\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x11\x00\x13\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x14\x00\x15\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x36\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x00\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1b\x00\x1d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x35\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x37\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x23\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\xff\xff\x00\x00\x00\x00\x00\x00\x37\x00\x00\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1e\x00\x1f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x02\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x11\x00\x13\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x04\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x10\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"# + +alex_check :: AlexAddr +alex_check = AlexA# "\xff\xff\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x79\x00\x6f\x00\x6f\x00\x63\x00\x6f\x00\x68\x00\x6c\x00\x6c\x00\x7c\x00\x7c\x00\x2b\x00\x3d\x00\x3d\x00\x3e\x00\x61\x00\x3e\x00\x63\x00\x2a\x00\x20\x00\x21\x00\x22\x00\x23\x00\x2f\x00\x25\x00\x26\x00\x2e\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x7c\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x22\x00\x2a\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x2a\x00\x3a\x00\x26\x00\x3c\x00\x3d\x00\x2f\x00\x2d\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\x3e\x00\x2d\x00\xff\xff\x5c\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\x20\x00\xff\xff\xff\xff\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x74\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2e\x00\xc3\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x5d\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x5d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x5d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x5d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x7c\x00\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x7c\x00\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x7c\x00\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x7c\x00\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x2a\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x22\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xff\xff\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x65\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x0a\x00\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc3\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x7c\x00\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x7c\x00\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00"# + +alex_deflt :: AlexAddr +alex_deflt = AlexA# "\xff\xff\x1a\x00\x19\x00\x19\x00\x17\x00\x17\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x17\x00\xff\xff\x17\x00\x19\x00\xff\xff\x19\x00\x1a\x00\x1a\x00\x17\x00\x17\x00\x19\x00\x19\x00\x1a\x00\x21\x00\xff\xff\x21\x00\x38\x00\x38\x00\xff\xff\x21\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x38\x00\xff\xff\xff\xff\x19\x00\xff\xff\x17\x00"# + +alex_accept = listArray (0::Int,61) [AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccSkip,AlexAcc (alex_action_1),AlexAcc (alex_action_1),AlexAcc (alex_action_1),AlexAcc (alex_action_1),AlexAcc (alex_action_1),AlexAcc (alex_action_1),AlexAcc (alex_action_1),AlexAcc (alex_action_1),AlexAcc (alex_action_1),AlexAcc (alex_action_1),AlexAcc (alex_action_1),AlexAcc (alex_action_1),AlexAcc (alex_action_1),AlexAcc (alex_action_2),AlexAcc (alex_action_3),AlexAcc (alex_action_4),AlexAcc (alex_action_5),AlexAcc (alex_action_6),AlexAcc (alex_action_7),AlexAcc (alex_action_8),AlexAcc (alex_action_9),AlexAcc (alex_action_9),AlexAcc (alex_action_10),AlexAcc (alex_action_10)] +{-# LINE 45 "Language/Clafer/Front/LexClafer.x" #-} + + +tok :: (Posn -> String -> Token) -> (Posn -> String -> Token) +tok f p s = f p s + +share :: String -> String +share = id + +data Tok = + TS !String !Int -- reserved words and symbols + | TL !String -- string literals + | TI !String -- integer literals + | TV !String -- identifiers + | TD !String -- double precision float literals + | TC !String -- character literals + | T_PosInteger !String + | T_PosDouble !String + | T_PosReal !String + | T_PosString !String + | T_PosIdent !String + | T_PosLineComment !String + | T_PosBlockComment !String + | T_PosAlloy !String + | T_PosChoco !String + + deriving (Eq,Show,Ord) + +data Token = + PT Posn Tok + | Err Posn + deriving (Eq,Show,Ord) + +tokenPos :: [Token] -> String +tokenPos (PT (Pn _ l _) _ :_) = "line " ++ show l +tokenPos (Err (Pn _ l _) :_) = "line " ++ show l +tokenPos _ = "end of file" + +tokenPosn :: Token -> Posn +tokenPosn (PT p _) = p +tokenPosn (Err p) = p + +tokenLineCol :: Token -> (Int, Int) +tokenLineCol = posLineCol . tokenPosn + +posLineCol :: Posn -> (Int, Int) +posLineCol (Pn _ l c) = (l,c) + +mkPosToken :: Token -> ((Int, Int), String) +mkPosToken t@(PT p _) = (posLineCol p, prToken t) + +prToken :: Token -> String +prToken t = case t of + PT _ (TS s _) -> s + PT _ (TL s) -> show s + PT _ (TI s) -> s + PT _ (TV s) -> s + PT _ (TD s) -> s + PT _ (TC s) -> s + PT _ (T_PosInteger s) -> s + PT _ (T_PosDouble s) -> s + PT _ (T_PosReal s) -> s + PT _ (T_PosString s) -> s + PT _ (T_PosIdent s) -> s + PT _ (T_PosLineComment s) -> s + PT _ (T_PosBlockComment s) -> s + PT _ (T_PosAlloy s) -> s + PT _ (T_PosChoco s) -> s + + +data BTree = N | B String Tok BTree BTree deriving (Show) + +eitherResIdent :: (String -> Tok) -> String -> Tok +eitherResIdent tv s = treeFind resWords + where + treeFind N = tv s + treeFind (B a t left right) | s < a = treeFind left + | s > a = treeFind right + | s == a = t + +resWords :: BTree +resWords = b ">>" 34 (b "->>" 17 (b "*" 9 (b "&" 5 (b "#" 3 (b "!=" 2 (b "!" 1 N N) N) (b "%" 4 N N)) (b "(" 7 (b "&&" 6 N N) (b ")" 8 N N))) (b "," 13 (b "+" 11 (b "**" 10 N N) (b "++" 12 N N)) (b "--" 15 (b "-" 14 N N) (b "->" 16 N N)))) (b "<:" 26 (b ":=" 22 (b "/" 20 (b ".." 19 (b "." 18 N N) N) (b ":" 21 N N)) (b ";" 24 (b ":>" 23 N N) (b "<" 25 N N))) (b "=" 30 (b "<=" 28 (b "<<" 27 N N) (b "<=>" 29 N N)) (b ">" 32 (b "=>" 31 N N) (b ">=" 33 N N))))) (b "min" 51 (b "disj" 43 (b "`" 39 (b "\\" 37 (b "[" 36 (b "?" 35 N N) N) (b "]" 38 N N)) (b "all" 41 (b "abstract" 40 N N) (b "assert" 42 N N))) (b "in" 47 (b "enum" 45 (b "else" 44 N N) (b "if" 46 N N)) (b "max" 49 (b "lone" 48 N N) (b "maximize" 50 N N)))) (b "some" 60 (b "one" 56 (b "no" 54 (b "mux" 53 (b "minimize" 52 N N) N) (b "not" 55 N N)) (b "or" 58 (b "opt" 57 N N) (b "product" 59 N N))) (b "{" 64 (b "then" 62 (b "sum" 61 N N) (b "xor" 63 N N)) (b "||" 66 (b "|" 65 N N) (b "}" 67 N N))))) + where b s n = let bs = id s + in B bs (TS bs n) + +unescapeInitTail :: String -> String +unescapeInitTail = id . unesc . tail . id where + unesc s = case s of + '\\':c:cs | elem c ['\"', '\\', '\''] -> c : unesc cs + '\\':'n':cs -> '\n' : unesc cs + '\\':'t':cs -> '\t' : unesc cs + '"':[] -> [] + c:cs -> c : unesc cs + _ -> [] + +------------------------------------------------------------------- +-- Alex wrapper code. +-- A modified "posn" wrapper. +------------------------------------------------------------------- + +data Posn = Pn !Int !Int !Int + deriving (Eq, Show,Ord) + +alexStartPos :: Posn +alexStartPos = Pn 0 1 1 + +alexMove :: Posn -> Char -> Posn +alexMove (Pn a l c) '\t' = Pn (a+1) l (((c+7) `div` 8)*8+1) +alexMove (Pn a l c) '\n' = Pn (a+1) (l+1) 1 +alexMove (Pn a l c) _ = Pn (a+1) l (c+1) + +type Byte = Word8 + +type AlexInput = (Posn, -- current position, + Char, -- previous char + [Byte], -- pending bytes on the current char + String) -- current input string + +tokens :: String -> [Token] +tokens str = go (alexStartPos, '\n', [], str) + where + go :: AlexInput -> [Token] + go inp@(pos, _, _, str) = + case alexScan inp 0 of + AlexEOF -> [] + AlexError (pos, _, _, _) -> [Err pos] + AlexSkip inp' len -> go inp' + AlexToken inp' len act -> act pos (take len str) : (go inp') + +alexGetByte :: AlexInput -> Maybe (Byte,AlexInput) +alexGetByte (p, c, (b:bs), s) = Just (b, (p, c, bs, s)) +alexGetByte (p, _, [], s) = + case s of + [] -> Nothing + (c:s) -> + let p' = alexMove p c + (b:bs) = utf8Encode c + in p' `seq` Just (b, (p', c, bs, s)) + +alexInputPrevChar :: AlexInput -> Char +alexInputPrevChar (p, c, bs, s) = c + +-- | Encode a Haskell String to a list of Word8 values, in UTF8 format. +utf8Encode :: Char -> [Word8] +utf8Encode = map fromIntegral . go . ord + where + go oc + | oc <= 0x7f = [oc] + + | oc <= 0x7ff = [ 0xc0 + (oc `Data.Bits.shiftR` 6) + , 0x80 + oc Data.Bits..&. 0x3f + ] + + | oc <= 0xffff = [ 0xe0 + (oc `Data.Bits.shiftR` 12) + , 0x80 + ((oc `Data.Bits.shiftR` 6) Data.Bits..&. 0x3f) + , 0x80 + oc Data.Bits..&. 0x3f + ] + | otherwise = [ 0xf0 + (oc `Data.Bits.shiftR` 18) + , 0x80 + ((oc `Data.Bits.shiftR` 12) Data.Bits..&. 0x3f) + , 0x80 + ((oc `Data.Bits.shiftR` 6) Data.Bits..&. 0x3f) + , 0x80 + oc Data.Bits..&. 0x3f + ] + +alex_action_1 = tok (\p s -> PT p (eitherResIdent (TV . share) s)) +alex_action_2 = tok (\p s -> PT p (eitherResIdent (T_PosInteger . share) s)) +alex_action_3 = tok (\p s -> PT p (eitherResIdent (T_PosDouble . share) s)) +alex_action_4 = tok (\p s -> PT p (eitherResIdent (T_PosReal . share) s)) +alex_action_5 = tok (\p s -> PT p (eitherResIdent (T_PosString . share) s)) +alex_action_6 = tok (\p s -> PT p (eitherResIdent (T_PosIdent . share) s)) +alex_action_7 = tok (\p s -> PT p (eitherResIdent (T_PosLineComment . share) s)) +alex_action_8 = tok (\p s -> PT p (eitherResIdent (T_PosBlockComment . share) s)) +alex_action_9 = tok (\p s -> PT p (eitherResIdent (T_PosAlloy . share) s)) +alex_action_10 = tok (\p s -> PT p (eitherResIdent (T_PosChoco . share) s)) +alex_action_11 = tok (\p s -> PT p (eitherResIdent (TV . share) s)) +{-# LINE 1 "templates\GenericTemplate.hs" #-} +{-# LINE 1 "templates\\GenericTemplate.hs" #-} +{-# LINE 1 "<built-in>" #-} +{-# LINE 1 "<command-line>" #-} +{-# LINE 11 "<command-line>" #-} +{-# LINE 1 "C:\\Users\\mantkiew\\AppData\\Local\\Programs\\stack\\x86_64-windows\\ghc-7.10.3\\lib/include\\ghcversion.h" #-} + + + + + + + + + + + + + + + + + +{-# LINE 11 "<command-line>" #-} +{-# LINE 1 "templates\\GenericTemplate.hs" #-} +-- ----------------------------------------------------------------------------- +-- ALEX TEMPLATE +-- +-- This code is in the PUBLIC DOMAIN; you may copy it freely and use +-- it for any purpose whatsoever. + +-- ----------------------------------------------------------------------------- +-- INTERNALS and main scanner engine + +{-# LINE 21 "templates\\GenericTemplate.hs" #-} + + + + + +-- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex. +#if __GLASGOW_HASKELL__ > 706 +#define GTE(n,m) (tagToEnum# (n >=# m)) +#define EQ(n,m) (tagToEnum# (n ==# m)) +#else +#define GTE(n,m) (n >=# m) +#define EQ(n,m) (n ==# m) +#endif +{-# LINE 51 "templates\\GenericTemplate.hs" #-} + + +data AlexAddr = AlexA# Addr# +-- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex. +#if __GLASGOW_HASKELL__ < 503 +uncheckedShiftL# = shiftL# +#endif + +{-# INLINE alexIndexInt16OffAddr #-} +alexIndexInt16OffAddr (AlexA# arr) off = +#ifdef WORDS_BIGENDIAN + narrow16Int# i + where + i = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low) + high = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#))) + low = int2Word# (ord# (indexCharOffAddr# arr off')) + off' = off *# 2# +#else + indexInt16OffAddr# arr off +#endif + + + + + +{-# INLINE alexIndexInt32OffAddr #-} +alexIndexInt32OffAddr (AlexA# arr) off = +#ifdef WORDS_BIGENDIAN + narrow32Int# i + where + i = word2Int# ((b3 `uncheckedShiftL#` 24#) `or#` + (b2 `uncheckedShiftL#` 16#) `or#` + (b1 `uncheckedShiftL#` 8#) `or#` b0) + b3 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 3#))) + b2 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 2#))) + b1 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#))) + b0 = int2Word# (ord# (indexCharOffAddr# arr off')) + off' = off *# 4# +#else + indexInt32OffAddr# arr off +#endif + + + + + + +#if __GLASGOW_HASKELL__ < 503 +quickIndex arr i = arr ! i +#else +-- GHC >= 503, unsafeAt is available from Data.Array.Base. +quickIndex = unsafeAt +#endif + + + + +-- ----------------------------------------------------------------------------- +-- Main lexing routines + +data AlexReturn a + = AlexEOF + | AlexError !AlexInput + | AlexSkip !AlexInput !Int + | AlexToken !AlexInput !Int a + +-- alexScan :: AlexInput -> StartCode -> AlexReturn a +alexScan input (I# (sc)) + = alexScanUser undefined input (I# (sc)) + +alexScanUser user input (I# (sc)) + = case alex_scan_tkn user input 0# input sc AlexNone of + (AlexNone, input') -> + case alexGetByte input of + Nothing -> + + + + AlexEOF + Just _ -> + + + + AlexError input' + + (AlexLastSkip input'' len, _) -> + + + + AlexSkip input'' len + + (AlexLastAcc k input''' len, _) -> + + + + AlexToken input''' len k + + +-- Push the input through the DFA, remembering the most recent accepting +-- state it encountered. + +alex_scan_tkn user orig_input len input s last_acc = + input `seq` -- strict in the input + let + new_acc = (check_accs (alex_accept `quickIndex` (I# (s)))) + in + new_acc `seq` + case alexGetByte input of + Nothing -> (new_acc, input) + Just (c, new_input) -> + + + + case fromIntegral c of { (I# (ord_c)) -> + let + base = alexIndexInt32OffAddr alex_base s + offset = (base +# ord_c) + check = alexIndexInt16OffAddr alex_check offset + + new_s = if GTE(offset,0#) && EQ(check,ord_c) + then alexIndexInt16OffAddr alex_table offset + else alexIndexInt16OffAddr alex_deflt s + in + case new_s of + -1# -> (new_acc, input) + -- on an error, we want to keep the input *before* the + -- character that failed, not after. + _ -> alex_scan_tkn user orig_input (if c < 0x80 || c >= 0xC0 then (len +# 1#) else len) + -- note that the length is increased ONLY if this is the 1st byte in a char encoding) + new_input new_s new_acc + } + where + check_accs (AlexAccNone) = last_acc + check_accs (AlexAcc a ) = AlexLastAcc a input (I# (len)) + check_accs (AlexAccSkip) = AlexLastSkip input (I# (len)) +{-# LINE 198 "templates\\GenericTemplate.hs" #-} + +data AlexLastAcc a + = AlexNone + | AlexLastAcc a !AlexInput !Int + | AlexLastSkip !AlexInput !Int + +instance Functor AlexLastAcc where + fmap _ AlexNone = AlexNone + fmap f (AlexLastAcc x y z) = AlexLastAcc (f x) y z + fmap _ (AlexLastSkip x y) = AlexLastSkip x y + +data AlexAcc a user + = AlexAccNone + | AlexAcc a + | AlexAccSkip
− src/Language/Clafer/Front/LexClafer.x
@@ -1,206 +0,0 @@--- -*- haskell -*---- This Alex file was machine-generated by the BNF converter-{-{-# OPTIONS -fno-warn-incomplete-patterns #-}-{-# OPTIONS_GHC -w #-}-module Language.Clafer.Front.LexClafer where----import qualified Data.Bits-import Data.Word (Word8)-}---$l = [a-zA-Z\192 - \255] # [\215 \247] -- isolatin1 letter FIXME-$c = [A-Z\192-\221] # [\215] -- capital isolatin1 letter FIXME-$s = [a-z\222-\255] # [\247] -- small isolatin1 letter FIXME-$d = [0-9] -- digit-$i = [$l $d _ '] -- identifier character-$u = [\0-\255] -- universal: any character--@rsyms = -- symbols and non-identifier-like reserved words- \= | \[ | \] | \< \< | \> \> | \{ | \} | \` | \: | \- \> | \- \> \> | \: \= | \? | \+ | \* | \. \. | \| | \< \= \> | \= \> | \| \| | \& \& | \! | \< | \> | \< \= | \> \= | \! \= | \- | \/ | \% | \# | \< \: | \: \> | \+ \+ | \, | \- \- | \* \* | \& | \. | \; | \\ | \( | \)--:---$white+ ;-@rsyms { tok (\p s -> PT p (eitherResIdent (TV . share) s)) }-$d + { tok (\p s -> PT p (eitherResIdent (T_PosInteger . share) s)) }-$d + \. $d + e \- ? $d + { tok (\p s -> PT p (eitherResIdent (T_PosDouble . share) s)) }-$d + \. $d + { tok (\p s -> PT p (eitherResIdent (T_PosReal . share) s)) }-\" ($u # [\" \\]| \\ [\" \\ n t]) * \" { tok (\p s -> PT p (eitherResIdent (T_PosString . share) s)) }-$l ($l | $d | \_ | \')* { tok (\p s -> PT p (eitherResIdent (T_PosIdent . share) s)) }-\/ \/ ($u # \n)* { tok (\p s -> PT p (eitherResIdent (T_PosLineComment . share) s)) }-\/ \* ($u # \* | \* + ($u # [\* \/]))* \* + \/ { tok (\p s -> PT p (eitherResIdent (T_PosBlockComment . share) s)) }-\[ a l l o y \| ($u # \| | \| + ($u # \])) * (\| \]) { tok (\p s -> PT p (eitherResIdent (T_PosAlloy . share) s)) }-\[ c h o c o \| ($u # \| | \| + ($u # \])) * (\| \]) { tok (\p s -> PT p (eitherResIdent (T_PosChoco . share) s)) }--$l $i* { tok (\p s -> PT p (eitherResIdent (TV . share) s)) }------{--tok :: (Posn -> String -> Token) -> (Posn -> String -> Token)-tok f p s = f p s--share :: String -> String-share = id--data Tok =- TS !String !Int -- reserved words and symbols- | TL !String -- string literals- | TI !String -- integer literals- | TV !String -- identifiers- | TD !String -- double precision float literals- | TC !String -- character literals- | T_PosInteger !String- | T_PosDouble !String- | T_PosReal !String- | T_PosString !String- | T_PosIdent !String- | T_PosLineComment !String- | T_PosBlockComment !String- | T_PosAlloy !String- | T_PosChoco !String-- deriving (Eq,Show,Ord)--data Token =- PT Posn Tok- | Err Posn- deriving (Eq,Show,Ord)--tokenPos :: [Token] -> String-tokenPos (PT (Pn _ l _) _ :_) = "line " ++ show l-tokenPos (Err (Pn _ l _) :_) = "line " ++ show l-tokenPos _ = "end of file"--tokenPosn :: Token -> Posn-tokenPosn (PT p _) = p-tokenPosn (Err p) = p--tokenLineCol :: Token -> (Int, Int)-tokenLineCol = posLineCol . tokenPosn--posLineCol :: Posn -> (Int, Int)-posLineCol (Pn _ l c) = (l,c)--mkPosToken :: Token -> ((Int, Int), String)-mkPosToken t@(PT p _) = (posLineCol p, prToken t)--prToken :: Token -> String-prToken t = case t of- PT _ (TS s _) -> s- PT _ (TL s) -> show s- PT _ (TI s) -> s- PT _ (TV s) -> s- PT _ (TD s) -> s- PT _ (TC s) -> s- PT _ (T_PosInteger s) -> s- PT _ (T_PosDouble s) -> s- PT _ (T_PosReal s) -> s- PT _ (T_PosString s) -> s- PT _ (T_PosIdent s) -> s- PT _ (T_PosLineComment s) -> s- PT _ (T_PosBlockComment s) -> s- PT _ (T_PosAlloy s) -> s- PT _ (T_PosChoco s) -> s---data BTree = N | B String Tok BTree BTree deriving (Show)--eitherResIdent :: (String -> Tok) -> String -> Tok-eitherResIdent tv s = treeFind resWords- where- treeFind N = tv s- treeFind (B a t left right) | s < a = treeFind left- | s > a = treeFind right- | s == a = t--resWords :: BTree-resWords = b ">>" 34 (b "->>" 17 (b "*" 9 (b "&" 5 (b "#" 3 (b "!=" 2 (b "!" 1 N N) N) (b "%" 4 N N)) (b "(" 7 (b "&&" 6 N N) (b ")" 8 N N))) (b "," 13 (b "+" 11 (b "**" 10 N N) (b "++" 12 N N)) (b "--" 15 (b "-" 14 N N) (b "->" 16 N N)))) (b "<:" 26 (b ":=" 22 (b "/" 20 (b ".." 19 (b "." 18 N N) N) (b ":" 21 N N)) (b ";" 24 (b ":>" 23 N N) (b "<" 25 N N))) (b "=" 30 (b "<=" 28 (b "<<" 27 N N) (b "<=>" 29 N N)) (b ">" 32 (b "=>" 31 N N) (b ">=" 33 N N))))) (b "min" 51 (b "disj" 43 (b "`" 39 (b "\\" 37 (b "[" 36 (b "?" 35 N N) N) (b "]" 38 N N)) (b "all" 41 (b "abstract" 40 N N) (b "assert" 42 N N))) (b "in" 47 (b "enum" 45 (b "else" 44 N N) (b "if" 46 N N)) (b "max" 49 (b "lone" 48 N N) (b "maximize" 50 N N)))) (b "some" 60 (b "one" 56 (b "no" 54 (b "mux" 53 (b "minimize" 52 N N) N) (b "not" 55 N N)) (b "or" 58 (b "opt" 57 N N) (b "product" 59 N N))) (b "{" 64 (b "then" 62 (b "sum" 61 N N) (b "xor" 63 N N)) (b "||" 66 (b "|" 65 N N) (b "}" 67 N N)))))- where b s n = let bs = id s- in B bs (TS bs n)--unescapeInitTail :: String -> String-unescapeInitTail = id . unesc . tail . id where- unesc s = case s of- '\\':c:cs | elem c ['\"', '\\', '\''] -> c : unesc cs- '\\':'n':cs -> '\n' : unesc cs- '\\':'t':cs -> '\t' : unesc cs- '"':[] -> []- c:cs -> c : unesc cs- _ -> []------------------------------------------------------------------------ Alex wrapper code.--- A modified "posn" wrapper.----------------------------------------------------------------------data Posn = Pn !Int !Int !Int- deriving (Eq, Show,Ord)--alexStartPos :: Posn-alexStartPos = Pn 0 1 1--alexMove :: Posn -> Char -> Posn-alexMove (Pn a l c) '\t' = Pn (a+1) l (((c+7) `div` 8)*8+1)-alexMove (Pn a l c) '\n' = Pn (a+1) (l+1) 1-alexMove (Pn a l c) _ = Pn (a+1) l (c+1)--type Byte = Word8--type AlexInput = (Posn, -- current position,- Char, -- previous char- [Byte], -- pending bytes on the current char- String) -- current input string--tokens :: String -> [Token]-tokens str = go (alexStartPos, '\n', [], str)- where- go :: AlexInput -> [Token]- go inp@(pos, _, _, str) =- case alexScan inp 0 of- AlexEOF -> []- AlexError (pos, _, _, _) -> [Err pos]- AlexSkip inp' len -> go inp'- AlexToken inp' len act -> act pos (take len str) : (go inp')--alexGetByte :: AlexInput -> Maybe (Byte,AlexInput)-alexGetByte (p, c, (b:bs), s) = Just (b, (p, c, bs, s))-alexGetByte (p, _, [], s) =- case s of- [] -> Nothing- (c:s) ->- let p' = alexMove p c- (b:bs) = utf8Encode c- in p' `seq` Just (b, (p', c, bs, s))--alexInputPrevChar :: AlexInput -> Char-alexInputPrevChar (p, c, bs, s) = c---- | Encode a Haskell String to a list of Word8 values, in UTF8 format.-utf8Encode :: Char -> [Word8]-utf8Encode = map fromIntegral . go . ord- where- go oc- | oc <= 0x7f = [oc]-- | oc <= 0x7ff = [ 0xc0 + (oc `Data.Bits.shiftR` 6)- , 0x80 + oc Data.Bits..&. 0x3f- ]-- | oc <= 0xffff = [ 0xe0 + (oc `Data.Bits.shiftR` 12)- , 0x80 + ((oc `Data.Bits.shiftR` 6) Data.Bits..&. 0x3f)- , 0x80 + oc Data.Bits..&. 0x3f- ]- | otherwise = [ 0xf0 + (oc `Data.Bits.shiftR` 18)- , 0x80 + ((oc `Data.Bits.shiftR` 12) Data.Bits..&. 0x3f)- , 0x80 + ((oc `Data.Bits.shiftR` 6) Data.Bits..&. 0x3f)- , 0x80 + oc Data.Bits..&. 0x3f- ]-}
+ src/Language/Clafer/Front/ParClafer.hs view
@@ -0,0 +1,2188 @@+{-# OPTIONS_GHC -w #-} +{-# OPTIONS -fglasgow-exts -cpp #-} +{-# OPTIONS_GHC -fno-warn-incomplete-patterns -fno-warn-overlapping-patterns #-} +module Language.Clafer.Front.ParClafer where +import Language.Clafer.Front.AbsClafer +import Language.Clafer.Front.LexClafer +import Language.Clafer.Front.ErrM +import qualified Data.Array as Happy_Data_Array +import qualified GHC.Exts as Happy_GHC_Exts +import Control.Applicative(Applicative(..)) +import Control.Monad (ap) + +-- parser produced by Happy Version 1.19.5 + +newtype HappyAbsSyn = HappyAbsSyn HappyAny +#if __GLASGOW_HASKELL__ >= 607 +type HappyAny = Happy_GHC_Exts.Any +#else +type HappyAny = forall a . a +#endif +happyIn8 :: (PosInteger) -> (HappyAbsSyn ) +happyIn8 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn8 #-} +happyOut8 :: (HappyAbsSyn ) -> (PosInteger) +happyOut8 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut8 #-} +happyIn9 :: (PosDouble) -> (HappyAbsSyn ) +happyIn9 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn9 #-} +happyOut9 :: (HappyAbsSyn ) -> (PosDouble) +happyOut9 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut9 #-} +happyIn10 :: (PosReal) -> (HappyAbsSyn ) +happyIn10 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn10 #-} +happyOut10 :: (HappyAbsSyn ) -> (PosReal) +happyOut10 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut10 #-} +happyIn11 :: (PosString) -> (HappyAbsSyn ) +happyIn11 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn11 #-} +happyOut11 :: (HappyAbsSyn ) -> (PosString) +happyOut11 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut11 #-} +happyIn12 :: (PosIdent) -> (HappyAbsSyn ) +happyIn12 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn12 #-} +happyOut12 :: (HappyAbsSyn ) -> (PosIdent) +happyOut12 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut12 #-} +happyIn13 :: (PosLineComment) -> (HappyAbsSyn ) +happyIn13 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn13 #-} +happyOut13 :: (HappyAbsSyn ) -> (PosLineComment) +happyOut13 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut13 #-} +happyIn14 :: (PosBlockComment) -> (HappyAbsSyn ) +happyIn14 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn14 #-} +happyOut14 :: (HappyAbsSyn ) -> (PosBlockComment) +happyOut14 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut14 #-} +happyIn15 :: (PosAlloy) -> (HappyAbsSyn ) +happyIn15 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn15 #-} +happyOut15 :: (HappyAbsSyn ) -> (PosAlloy) +happyOut15 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut15 #-} +happyIn16 :: (PosChoco) -> (HappyAbsSyn ) +happyIn16 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn16 #-} +happyOut16 :: (HappyAbsSyn ) -> (PosChoco) +happyOut16 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut16 #-} +happyIn17 :: (Module) -> (HappyAbsSyn ) +happyIn17 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn17 #-} +happyOut17 :: (HappyAbsSyn ) -> (Module) +happyOut17 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut17 #-} +happyIn18 :: (Declaration) -> (HappyAbsSyn ) +happyIn18 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn18 #-} +happyOut18 :: (HappyAbsSyn ) -> (Declaration) +happyOut18 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut18 #-} +happyIn19 :: (Clafer) -> (HappyAbsSyn ) +happyIn19 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn19 #-} +happyOut19 :: (HappyAbsSyn ) -> (Clafer) +happyOut19 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut19 #-} +happyIn20 :: (Constraint) -> (HappyAbsSyn ) +happyIn20 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn20 #-} +happyOut20 :: (HappyAbsSyn ) -> (Constraint) +happyOut20 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut20 #-} +happyIn21 :: (Assertion) -> (HappyAbsSyn ) +happyIn21 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn21 #-} +happyOut21 :: (HappyAbsSyn ) -> (Assertion) +happyOut21 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut21 #-} +happyIn22 :: (Goal) -> (HappyAbsSyn ) +happyIn22 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn22 #-} +happyOut22 :: (HappyAbsSyn ) -> (Goal) +happyOut22 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut22 #-} +happyIn23 :: (Abstract) -> (HappyAbsSyn ) +happyIn23 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn23 #-} +happyOut23 :: (HappyAbsSyn ) -> (Abstract) +happyOut23 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut23 #-} +happyIn24 :: (Elements) -> (HappyAbsSyn ) +happyIn24 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn24 #-} +happyOut24 :: (HappyAbsSyn ) -> (Elements) +happyOut24 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut24 #-} +happyIn25 :: (Element) -> (HappyAbsSyn ) +happyIn25 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn25 #-} +happyOut25 :: (HappyAbsSyn ) -> (Element) +happyOut25 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut25 #-} +happyIn26 :: (Super) -> (HappyAbsSyn ) +happyIn26 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn26 #-} +happyOut26 :: (HappyAbsSyn ) -> (Super) +happyOut26 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut26 #-} +happyIn27 :: (Reference) -> (HappyAbsSyn ) +happyIn27 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn27 #-} +happyOut27 :: (HappyAbsSyn ) -> (Reference) +happyOut27 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut27 #-} +happyIn28 :: (Init) -> (HappyAbsSyn ) +happyIn28 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn28 #-} +happyOut28 :: (HappyAbsSyn ) -> (Init) +happyOut28 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut28 #-} +happyIn29 :: (InitHow) -> (HappyAbsSyn ) +happyIn29 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn29 #-} +happyOut29 :: (HappyAbsSyn ) -> (InitHow) +happyOut29 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut29 #-} +happyIn30 :: (GCard) -> (HappyAbsSyn ) +happyIn30 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn30 #-} +happyOut30 :: (HappyAbsSyn ) -> (GCard) +happyOut30 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut30 #-} +happyIn31 :: (Card) -> (HappyAbsSyn ) +happyIn31 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn31 #-} +happyOut31 :: (HappyAbsSyn ) -> (Card) +happyOut31 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut31 #-} +happyIn32 :: (NCard) -> (HappyAbsSyn ) +happyIn32 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn32 #-} +happyOut32 :: (HappyAbsSyn ) -> (NCard) +happyOut32 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut32 #-} +happyIn33 :: (ExInteger) -> (HappyAbsSyn ) +happyIn33 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn33 #-} +happyOut33 :: (HappyAbsSyn ) -> (ExInteger) +happyOut33 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut33 #-} +happyIn34 :: (Name) -> (HappyAbsSyn ) +happyIn34 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn34 #-} +happyOut34 :: (HappyAbsSyn ) -> (Name) +happyOut34 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut34 #-} +happyIn35 :: (Exp) -> (HappyAbsSyn ) +happyIn35 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn35 #-} +happyOut35 :: (HappyAbsSyn ) -> (Exp) +happyOut35 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut35 #-} +happyIn36 :: (Exp) -> (HappyAbsSyn ) +happyIn36 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn36 #-} +happyOut36 :: (HappyAbsSyn ) -> (Exp) +happyOut36 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut36 #-} +happyIn37 :: (Exp) -> (HappyAbsSyn ) +happyIn37 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn37 #-} +happyOut37 :: (HappyAbsSyn ) -> (Exp) +happyOut37 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut37 #-} +happyIn38 :: (Exp) -> (HappyAbsSyn ) +happyIn38 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn38 #-} +happyOut38 :: (HappyAbsSyn ) -> (Exp) +happyOut38 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut38 #-} +happyIn39 :: (Exp) -> (HappyAbsSyn ) +happyIn39 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn39 #-} +happyOut39 :: (HappyAbsSyn ) -> (Exp) +happyOut39 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut39 #-} +happyIn40 :: (Exp) -> (HappyAbsSyn ) +happyIn40 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn40 #-} +happyOut40 :: (HappyAbsSyn ) -> (Exp) +happyOut40 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut40 #-} +happyIn41 :: (Exp) -> (HappyAbsSyn ) +happyIn41 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn41 #-} +happyOut41 :: (HappyAbsSyn ) -> (Exp) +happyOut41 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut41 #-} +happyIn42 :: (Exp) -> (HappyAbsSyn ) +happyIn42 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn42 #-} +happyOut42 :: (HappyAbsSyn ) -> (Exp) +happyOut42 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut42 #-} +happyIn43 :: (Exp) -> (HappyAbsSyn ) +happyIn43 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn43 #-} +happyOut43 :: (HappyAbsSyn ) -> (Exp) +happyOut43 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut43 #-} +happyIn44 :: (Exp) -> (HappyAbsSyn ) +happyIn44 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn44 #-} +happyOut44 :: (HappyAbsSyn ) -> (Exp) +happyOut44 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut44 #-} +happyIn45 :: (Exp) -> (HappyAbsSyn ) +happyIn45 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn45 #-} +happyOut45 :: (HappyAbsSyn ) -> (Exp) +happyOut45 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut45 #-} +happyIn46 :: (Exp) -> (HappyAbsSyn ) +happyIn46 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn46 #-} +happyOut46 :: (HappyAbsSyn ) -> (Exp) +happyOut46 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut46 #-} +happyIn47 :: (Exp) -> (HappyAbsSyn ) +happyIn47 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn47 #-} +happyOut47 :: (HappyAbsSyn ) -> (Exp) +happyOut47 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut47 #-} +happyIn48 :: (Exp) -> (HappyAbsSyn ) +happyIn48 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn48 #-} +happyOut48 :: (HappyAbsSyn ) -> (Exp) +happyOut48 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut48 #-} +happyIn49 :: (Exp) -> (HappyAbsSyn ) +happyIn49 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn49 #-} +happyOut49 :: (HappyAbsSyn ) -> (Exp) +happyOut49 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut49 #-} +happyIn50 :: (Exp) -> (HappyAbsSyn ) +happyIn50 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn50 #-} +happyOut50 :: (HappyAbsSyn ) -> (Exp) +happyOut50 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut50 #-} +happyIn51 :: (Exp) -> (HappyAbsSyn ) +happyIn51 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn51 #-} +happyOut51 :: (HappyAbsSyn ) -> (Exp) +happyOut51 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut51 #-} +happyIn52 :: (Exp) -> (HappyAbsSyn ) +happyIn52 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn52 #-} +happyOut52 :: (HappyAbsSyn ) -> (Exp) +happyOut52 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut52 #-} +happyIn53 :: (Exp) -> (HappyAbsSyn ) +happyIn53 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn53 #-} +happyOut53 :: (HappyAbsSyn ) -> (Exp) +happyOut53 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut53 #-} +happyIn54 :: (Decl) -> (HappyAbsSyn ) +happyIn54 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn54 #-} +happyOut54 :: (HappyAbsSyn ) -> (Decl) +happyOut54 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut54 #-} +happyIn55 :: (Quant) -> (HappyAbsSyn ) +happyIn55 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn55 #-} +happyOut55 :: (HappyAbsSyn ) -> (Quant) +happyOut55 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut55 #-} +happyIn56 :: (EnumId) -> (HappyAbsSyn ) +happyIn56 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn56 #-} +happyOut56 :: (HappyAbsSyn ) -> (EnumId) +happyOut56 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut56 #-} +happyIn57 :: (ModId) -> (HappyAbsSyn ) +happyIn57 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn57 #-} +happyOut57 :: (HappyAbsSyn ) -> (ModId) +happyOut57 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut57 #-} +happyIn58 :: (LocId) -> (HappyAbsSyn ) +happyIn58 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn58 #-} +happyOut58 :: (HappyAbsSyn ) -> (LocId) +happyOut58 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut58 #-} +happyIn59 :: ([Declaration]) -> (HappyAbsSyn ) +happyIn59 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn59 #-} +happyOut59 :: (HappyAbsSyn ) -> ([Declaration]) +happyOut59 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut59 #-} +happyIn60 :: ([EnumId]) -> (HappyAbsSyn ) +happyIn60 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn60 #-} +happyOut60 :: (HappyAbsSyn ) -> ([EnumId]) +happyOut60 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut60 #-} +happyIn61 :: ([Element]) -> (HappyAbsSyn ) +happyIn61 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn61 #-} +happyOut61 :: (HappyAbsSyn ) -> ([Element]) +happyOut61 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut61 #-} +happyIn62 :: ([Exp]) -> (HappyAbsSyn ) +happyIn62 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn62 #-} +happyOut62 :: (HappyAbsSyn ) -> ([Exp]) +happyOut62 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut62 #-} +happyIn63 :: ([LocId]) -> (HappyAbsSyn ) +happyIn63 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn63 #-} +happyOut63 :: (HappyAbsSyn ) -> ([LocId]) +happyOut63 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut63 #-} +happyIn64 :: ([ModId]) -> (HappyAbsSyn ) +happyIn64 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn64 #-} +happyOut64 :: (HappyAbsSyn ) -> ([ModId]) +happyOut64 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut64 #-} +happyIn65 :: (Exp) -> (HappyAbsSyn ) +happyIn65 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn65 #-} +happyOut65 :: (HappyAbsSyn ) -> (Exp) +happyOut65 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut65 #-} +happyInTok :: (Token) -> (HappyAbsSyn ) +happyInTok x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyInTok #-} +happyOutTok :: (HappyAbsSyn ) -> (Token) +happyOutTok x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOutTok #-} + + +happyActOffsets :: HappyAddr +happyActOffsets = HappyA# "\x00\x00\x10\x01\x15\x01\x09\x01\x13\x01\xf0\x00\x00\x00\xe2\x00\x95\x00\xe2\x00\x02\x01\xda\x00\x00\x00\xda\x00\xa0\x00\x00\x00\xda\x00\xac\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\x00\xe1\x00\x0f\x01\xd8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x00\xb2\x00\x6a\x00\x22\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x05\x01\xd9\x00\xdf\x00\x14\x01\x00\x00\xc2\x05\x00\x00\x61\x00\x09\x00\x00\x00\x00\x00\xff\x00\x01\x01\xc4\x00\x03\x01\x0b\x00\xfe\x00\x00\x00\x66\x01\xea\x00\x00\x00\x00\x00\xcf\x00\x1d\x00\x42\x01\x1d\x00\x00\x00\xde\xff\x42\x01\x00\x00\x3c\x00\x3c\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\x00\xfd\xff\xef\x00\xfc\xff\xfb\x00\xc9\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x00\x00\x00\x00\x00\x00\x00\xab\x00\x1d\x00\xe4\x00\xe4\x00\x00\x00\x00\x00\x11\x00\x00\x00\xc2\x00\xdc\x00\xde\x00\xb4\x00\xd6\x00\x04\x00\xd6\x00\xc2\x05\x3c\x00\xad\x00\xfe\xff\x00\x00\xb1\x00\xa9\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\xcf\x00\xcf\x00\xcf\x00\xcf\x00\xcf\x00\xcf\x00\xcf\x00\xbd\x00\x87\x00\x87\x00\x87\x00\x87\x00\x87\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5\x00\xac\x00\xe0\x00\x00\x00\xcf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x09\x00\x00\x00\x00\x00\x00\x00\xc7\x00\x9e\x00\xd2\x00\xd2\x00\x0b\x00\xaf\x00\xaf\x00\x00\x00\x96\x00\x42\x01\x00\x00\x00\x00\x75\x00\x1d\x00\x8b\x00\x42\x01\x42\x01\x92\x00\xfc\xff\x1d\x00\x1d\x00\x00\x00\x58\x00\x00\x00\x00\x00\x00\x00\xf0\xff\x6c\x00\x9e\x00\x9e\x00\x38\x00\xed\xff\x81\x00\x00\x00\x9e\x00\x42\x01\x81\x00\x42\x01\x00\x00\x81\x00\x81\x00\x42\x01\x56\x00\x42\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x7f\x00\x00\x00"# + +happyGotoOffsets :: HappyAddr +happyGotoOffsets = HappyA# "\xf8\xff\x13\x00\x85\x00\x80\x00\x64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\x00\x00\x00\x7c\x00\x00\x00\x00\x00\xd0\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x7a\x00\x00\x00\x36\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5b\x03\x53\x00\x51\x00\x45\x00\x3a\x00\x1b\x00\x5b\x03\x5b\x03\x5b\x03\x5b\x03\x5b\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd6\x05\x00\x00\x00\x00\x00\x00\x70\x04\x1c\x07\x29\x03\xfd\x06\x00\x00\x71\x00\xf7\x02\x00\x00\xb6\x06\x97\x06\x00\x00\x00\x00\x00\x00\xe9\x06\x00\x00\xca\x06\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x03\x00\x00\x00\x6e\x00\x00\x00\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8\x00\x00\x00\x00\x00\x00\x00\x08\x00\x02\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x83\x06\x0a\x00\x00\x00\x00\x00\x00\x00\x29\x00\x08\x08\xfc\x07\xc9\x07\xc3\x07\xbb\x07\xa7\x07\x88\x07\x30\x07\x64\x06\x50\x06\x31\x06\x1d\x06\xeb\x05\xa4\x05\x89\x05\x57\x05\x3c\x05\x0a\x05\xef\x04\xbd\x04\x00\x00\x55\x04\x23\x04\xf1\x03\xbf\x03\x8d\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\x02\x00\x00\x00\x00\x00\x00\x74\x07\x93\x00\x93\x02\x61\x02\x00\x00\x5c\x00\x6b\x07\x39\x07\x00\x00\x00\x00\x00\x00\x00\x00\xdc\xff\xfa\x01\x79\x00\x00\x00\x00\x00\x7b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2f\x02\x00\x00\xfd\x01\x00\x00\x00\x00\x00\x00\xcb\x01\x18\x00\x99\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# + +happyDefActions :: HappyAddr +happyDefActions = HappyA# "\x7d\xff\xe7\xff\x00\x00\x00\x00\x00\x00\x00\x00\xfa\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\xff\x00\x00\xd5\xff\xe6\xff\x00\x00\xe7\xff\x7c\xff\xe3\xff\xe1\xff\xdf\xff\xe0\xff\xef\xff\x00\x00\x00\x00\x00\x00\x00\x00\xd0\xff\xd2\xff\xd1\xff\xd3\xff\xd4\xff\x00\x00\x77\xff\x77\xff\x77\xff\x77\xff\x77\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b\xff\x8a\xff\x89\xff\x88\xff\x7f\xff\x8c\xff\x76\xff\x71\xff\xbd\xff\xbb\xff\xb9\xff\xb7\xff\xb5\xff\xac\xff\xaa\xff\xa7\xff\xa3\xff\xa0\xff\x9b\xff\x99\xff\x97\xff\x94\xff\x92\xff\x8f\xff\x8d\xff\x00\x00\x73\xff\xc6\xff\xbf\xff\x00\x00\x00\x00\x00\x00\x00\x00\xed\xff\x00\x00\x00\x00\x83\xff\x00\x00\x00\x00\x85\xff\x84\xff\x82\xff\x00\x00\x81\xff\x00\x00\xf9\xff\xf8\xff\xf7\xff\xf6\xff\xde\xff\x00\x00\x00\x00\xcf\xff\xcb\xff\xe5\xff\xca\xff\xcc\xff\xcd\xff\xce\xff\x00\x00\xc7\xff\xc9\xff\xc8\xff\xdc\xff\x00\x00\x9f\xff\x9e\xff\xa1\xff\xa2\xff\x00\x00\x7e\xff\x00\x00\x75\xff\x00\x00\x00\x00\x9c\xff\x00\x00\x9d\xff\xb6\xff\x00\x00\x00\x00\x7f\xff\xab\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec\xff\xea\xff\xe8\xff\xeb\xff\xe9\xff\xc0\xff\xbe\xff\xbc\xff\xba\xff\xb8\xff\x00\x00\xae\xff\xb0\xff\xb3\xff\xb2\xff\xb1\xff\xb4\xff\xaf\xff\xa8\xff\xa9\xff\xa5\xff\xa6\xff\xa4\xff\x9a\xff\x98\xff\x95\xff\x96\xff\x93\xff\x91\xff\x90\xff\x8e\xff\x00\x00\x00\x00\x72\xff\x87\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdd\xff\xcf\xff\x00\x00\x00\x00\x80\xff\x7b\xff\xf0\xff\xe2\xff\x79\xff\xe7\xff\x00\x00\xda\xff\xdb\xff\xd9\xff\x00\x00\xc4\xff\x74\xff\x86\xff\x00\x00\xc2\xff\x00\x00\xad\xff\xc3\xff\xc5\xff\x00\x00\xe5\xff\x00\x00\xd6\xff\xd7\xff\x7a\xff\x78\xff\xe4\xff\xd8\xff\xee\xff\xc1\xff"# + +happyCheck :: HappyAddr +happyCheck = HappyA# "\xff\xff\x09\x00\x01\x00\x00\x00\x03\x00\x09\x00\x09\x00\x0b\x00\x07\x00\x2b\x00\x1d\x00\x1b\x00\x08\x00\x04\x00\x04\x00\x0e\x00\x05\x00\x35\x00\x09\x00\x15\x00\x24\x00\x0a\x00\x18\x00\x27\x00\x28\x00\x2c\x00\x2a\x00\x13\x00\x19\x00\x14\x00\x0b\x00\x23\x00\x04\x00\x1d\x00\x0f\x00\x01\x00\x07\x00\x03\x00\x48\x00\x26\x00\x10\x00\x07\x00\x29\x00\x33\x00\x12\x00\x04\x00\x1d\x00\x2e\x00\x0e\x00\x30\x00\x31\x00\x43\x00\x33\x00\x10\x00\x1a\x00\x36\x00\x37\x00\x38\x00\x04\x00\x31\x00\x3b\x00\x3c\x00\x3d\x00\x03\x00\x44\x00\x44\x00\x38\x00\x07\x00\x22\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x0e\x00\x29\x00\x04\x00\x31\x00\x16\x00\x3e\x00\x2e\x00\x36\x00\x30\x00\x31\x00\x38\x00\x33\x00\x1e\x00\x2e\x00\x36\x00\x37\x00\x38\x00\x32\x00\x00\x00\x3b\x00\x3c\x00\x3d\x00\x37\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x01\x00\x0b\x00\x03\x00\x00\x00\x0e\x00\x36\x00\x07\x00\x0e\x00\x17\x00\x18\x00\x04\x00\x2e\x00\x3b\x00\x0e\x00\x3d\x00\x32\x00\x36\x00\x00\x00\x04\x00\x04\x00\x37\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x17\x00\x18\x00\x36\x00\x01\x00\x36\x00\x03\x00\x36\x00\x22\x00\x0d\x00\x07\x00\x14\x00\x15\x00\x0c\x00\x16\x00\x29\x00\x18\x00\x0e\x00\x40\x00\x04\x00\x2e\x00\x41\x00\x30\x00\x31\x00\x1d\x00\x33\x00\x1d\x00\x2e\x00\x36\x00\x37\x00\x38\x00\x32\x00\x12\x00\x3b\x00\x3c\x00\x3d\x00\x37\x00\x30\x00\x0c\x00\x0d\x00\x04\x00\x34\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x01\x00\x48\x00\x03\x00\x41\x00\x30\x00\x31\x00\x07\x00\x33\x00\x10\x00\x11\x00\x36\x00\x37\x00\x38\x00\x0e\x00\x12\x00\x3b\x00\x3c\x00\x3d\x00\x32\x00\x31\x00\x32\x00\x33\x00\x34\x00\x37\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x0c\x00\x0d\x00\x03\x00\x48\x00\x22\x00\x35\x00\x07\x00\x41\x00\x30\x00\x39\x00\x3a\x00\x29\x00\x34\x00\x0e\x00\x17\x00\x3f\x00\x2e\x00\x0f\x00\x30\x00\x31\x00\x44\x00\x33\x00\x06\x00\x42\x00\x36\x00\x37\x00\x38\x00\x3f\x00\x2f\x00\x3b\x00\x3c\x00\x3d\x00\x1a\x00\x48\x00\x41\x00\x15\x00\x18\x00\x48\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x01\x00\x48\x00\x03\x00\x1a\x00\x30\x00\x31\x00\x07\x00\x33\x00\x41\x00\x48\x00\x36\x00\x37\x00\x38\x00\x0e\x00\x40\x00\x3b\x00\x3c\x00\x3d\x00\x1e\x00\x13\x00\x25\x00\x12\x00\x15\x00\x0f\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x17\x00\x1a\x00\x06\x00\x42\x00\x22\x00\x1d\x00\x3f\x00\x01\x00\x48\x00\x03\x00\x13\x00\x29\x00\x1f\x00\x07\x00\x24\x00\x4d\x00\x2e\x00\x48\x00\x30\x00\x31\x00\x0e\x00\x33\x00\x1b\x00\x4d\x00\x36\x00\x37\x00\x38\x00\x2a\x00\x44\x00\x3b\x00\x3c\x00\x3d\x00\x28\x00\x24\x00\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x01\x00\x26\x00\x03\x00\xff\xff\x29\x00\xff\xff\x07\x00\xff\xff\xff\xff\x2e\x00\xff\xff\x30\x00\x31\x00\x0e\x00\x33\x00\xff\xff\x03\x00\x36\x00\x37\x00\x38\x00\x07\x00\xff\xff\x3b\x00\x3c\x00\x3d\x00\xff\xff\xff\xff\x0e\x00\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\xff\xff\xff\xff\x03\x00\xff\xff\x29\x00\xff\xff\x07\x00\xff\xff\xff\xff\x2e\x00\xff\xff\x30\x00\x31\x00\x0e\x00\x33\x00\xff\xff\xff\xff\x36\x00\x37\x00\x38\x00\xff\xff\xff\xff\x3b\x00\x3c\x00\x3d\x00\xff\xff\x31\x00\xff\xff\x33\x00\xff\xff\xff\xff\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x3b\x00\xff\xff\x3d\x00\xff\xff\xff\xff\xff\xff\x2b\x00\xff\xff\xff\xff\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x1b\x00\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x24\x00\x38\x00\x39\x00\x27\x00\x28\x00\xff\xff\x2a\x00\xff\xff\xff\xff\x2d\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\xff\xff\xff\xff\xff\xff\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x4d\x00\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\x39\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\xff\xff\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\xff\xff\xff\xff\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\xff\xff\xff\xff\xff\xff\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\xff\xff\xff\xff\xff\xff\x1a\x00\xff\xff\xff\xff\x38\x00\xff\xff\xff\xff\xff\xff\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\xff\xff\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\xff\xff\xff\xff\xff\xff\x1a\x00\xff\xff\xff\xff\x38\x00\xff\xff\xff\xff\xff\xff\xff\xff\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\xff\xff\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\xff\xff\xff\xff\xff\xff\x1a\x00\xff\xff\xff\xff\x38\x00\xff\xff\xff\xff\xff\xff\xff\xff\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\xff\xff\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\xff\xff\xff\xff\xff\xff\x1a\x00\xff\xff\xff\xff\x38\x00\xff\xff\xff\xff\xff\xff\xff\xff\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\xff\xff\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\xff\xff\xff\xff\xff\xff\x1a\x00\xff\xff\xff\xff\x38\x00\xff\xff\xff\xff\x02\x00\xff\xff\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x19\x00\x38\x00\xff\xff\x1c\x00\xff\xff\x1e\x00\xff\xff\x20\x00\x21\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x1a\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x37\x00\xff\xff\xff\xff\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x1a\x00\xff\xff\x31\x00\x32\x00\xff\xff\xff\xff\xff\xff\xff\xff\x37\x00\x38\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\xff\xff\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x1a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x1a\x00\xff\xff\xff\xff\x31\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x38\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\xff\xff\xff\xff\x31\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x38\x00\x1a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x1a\x00\xff\xff\xff\xff\x31\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x38\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\xff\xff\xff\xff\x31\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x38\x00\x1a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x1a\x00\xff\xff\xff\xff\x31\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x38\x00\xff\xff\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\xff\xff\xff\xff\x31\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x38\x00\x1a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x1a\x00\xff\xff\xff\xff\x31\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x38\x00\xff\xff\xff\xff\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\xff\xff\xff\xff\x31\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x38\x00\x1a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x1a\x00\xff\xff\xff\xff\x31\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x38\x00\xff\xff\xff\xff\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\xff\xff\xff\xff\x31\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x38\x00\x1a\x00\xff\xff\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x1a\x00\xff\xff\xff\xff\x31\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\x38\x00\xff\xff\xff\xff\xff\xff\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\xff\xff\xff\xff\x31\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\x38\x00\xff\xff\x31\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x38\x00\xff\xff\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\xff\xff\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x1a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\xff\xff\xff\xff\x31\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x1a\x00\x38\x00\xff\xff\x31\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x38\x00\xff\xff\xff\xff\xff\xff\xff\xff\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\xff\xff\xff\xff\x31\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x38\x00\x1a\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x1a\x00\xff\xff\xff\xff\x31\x00\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\xff\xff\x38\x00\xff\xff\xff\xff\xff\xff\x1a\x00\xff\xff\x2a\x00\x2b\x00\x2c\x00\x2d\x00\xff\xff\xff\xff\xff\xff\x31\x00\xff\xff\x2b\x00\x2c\x00\x2d\x00\xff\xff\xff\xff\x38\x00\x31\x00\x2c\x00\x2d\x00\xff\xff\xff\xff\xff\xff\x31\x00\x38\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x38\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2c\x00\x2d\x00\xff\xff\xff\xff\xff\xff\x31\x00\x2c\x00\x2d\x00\xff\xff\xff\xff\xff\xff\x31\x00\x38\x00\x2d\x00\xff\xff\xff\xff\xff\xff\x31\x00\x38\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x38\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"# + +happyTable :: HappyAddr +happyTable = HappyA# "\x00\x00\x10\x00\x4a\x00\x68\x00\x4b\x00\x65\x00\x6b\x00\x66\x00\x4c\x00\x77\x00\x9b\x00\x09\x00\xbe\x00\x8a\x00\x30\x00\x4d\x00\x83\x00\xcc\x00\x8b\x00\x7e\xff\x0d\x00\x84\x00\x7e\xff\x19\x00\x10\x00\xdc\x00\x0b\x00\xc4\x00\x69\x00\x8c\x00\x0d\x00\x67\x00\x30\x00\x9b\x00\x0e\x00\x4a\x00\x4c\x00\x4b\x00\x5d\x00\x9c\x00\xe4\x00\x4c\x00\x4f\x00\x11\x00\x6b\x00\x72\x00\x9b\x00\x50\x00\x4d\x00\x51\x00\x52\x00\xe3\x00\x53\x00\xca\x00\x60\x00\x54\x00\x55\x00\x56\x00\x5d\x00\x46\x00\x57\x00\x58\x00\x59\x00\x4b\x00\x07\x00\x07\x00\xbc\x00\x4c\x00\x9d\x00\x07\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x4d\x00\x4f\x00\x72\x00\x46\x00\xdf\x00\xc3\x00\x50\x00\x27\x00\x51\x00\x52\x00\x47\x00\x53\x00\xe0\x00\xba\x00\x54\x00\x55\x00\x56\x00\x74\x00\x61\x00\x57\x00\x58\x00\x59\x00\x75\x00\x07\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x07\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x4a\x00\x8d\x00\x4b\x00\x61\x00\x8e\x00\x28\x00\x4c\x00\x07\x00\xd0\x00\x63\x00\x72\x00\xbe\x00\x57\x00\x4d\x00\x59\x00\x74\x00\x29\x00\x1a\x00\xc7\x00\x5f\x00\x75\x00\x07\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x62\x00\x63\x00\x2a\x00\x4a\x00\x2b\x00\x4b\x00\x21\x00\x9e\x00\x09\x00\x4c\x00\xdc\x00\xdd\x00\x0b\x00\x1b\x00\x4f\x00\x1c\x00\x4d\x00\xcc\x00\x72\x00\x50\x00\xce\x00\x51\x00\x52\x00\x9b\x00\x53\x00\x9b\x00\x73\x00\x54\x00\x55\x00\x56\x00\x74\x00\x82\x00\x57\x00\x58\x00\x59\x00\x75\x00\xc8\x00\x86\x00\x87\x00\xc7\x00\xe0\x00\x07\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x4a\x00\x5d\x00\x4b\x00\xd6\x00\x51\x00\x52\x00\x4c\x00\x53\x00\xc6\x00\xc7\x00\x54\x00\x55\x00\x56\x00\x4d\x00\x82\x00\x57\x00\x58\x00\x59\x00\x74\x00\x24\x00\x25\x00\x26\x00\x27\x00\xd3\x00\x07\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x86\x00\x87\x00\x4b\x00\x5d\x00\x9f\x00\x1e\x00\x4c\x00\xd8\x00\xc8\x00\x1f\x00\x20\x00\x4f\x00\xc9\x00\x4d\x00\x88\x00\x21\x00\x50\x00\x85\x00\x51\x00\x52\x00\x07\x00\x53\x00\x97\x00\x99\x00\x54\x00\x55\x00\x56\x00\x98\x00\xa6\x00\x57\x00\x58\x00\x59\x00\x89\x00\x5d\x00\xbc\x00\xc0\x00\xc1\x00\x5d\x00\x07\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x4a\x00\x5d\x00\x4b\x00\x89\x00\x51\x00\x52\x00\x4c\x00\x53\x00\xc2\x00\x5d\x00\x54\x00\x55\x00\x56\x00\x4d\x00\xcc\x00\x57\x00\x58\x00\x59\x00\x68\x00\x5f\x00\x7d\x00\x82\x00\x6d\x00\x85\x00\x07\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x88\x00\x89\x00\x97\x00\x99\x00\xa0\x00\x9b\x00\x98\x00\x4a\x00\x5d\x00\x4b\x00\x5f\x00\x4f\x00\x9a\x00\x4c\x00\x23\x00\xff\xff\x50\x00\x5d\x00\x51\x00\x52\x00\x4d\x00\x53\x00\x09\x00\xff\xff\x54\x00\x55\x00\x56\x00\x0b\x00\x07\x00\x57\x00\x58\x00\x59\x00\x10\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x4a\x00\x4e\x00\x4b\x00\x00\x00\x4f\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x50\x00\x00\x00\x51\x00\x52\x00\x4d\x00\x53\x00\x00\x00\x4b\x00\x54\x00\x55\x00\x56\x00\x4c\x00\x00\x00\x57\x00\x58\x00\x59\x00\x00\x00\x00\x00\x4d\x00\x00\x00\x00\x00\x00\x00\x07\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x00\x00\x00\x00\x4b\x00\x00\x00\x4f\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x50\x00\x00\x00\x51\x00\x52\x00\x4d\x00\x53\x00\x00\x00\x00\x00\x54\x00\x55\x00\x56\x00\x00\x00\x00\x00\x57\x00\x58\x00\x59\x00\x00\x00\x52\x00\x00\x00\x53\x00\x00\x00\x00\x00\x07\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x57\x00\x00\x00\x59\x00\x00\x00\x00\x00\x00\x00\x81\x00\x00\x00\x00\x00\x07\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x00\x00\x00\x00\x57\x00\x00\x00\x59\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\xe3\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x09\x00\x45\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x0d\x00\x47\x00\x48\x00\x19\x00\x10\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x1a\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x0e\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x31\x00\xe5\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\xf1\xff\x45\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x48\x00\x13\x00\x14\x00\x15\x00\x16\x00\x0e\x00\x00\x00\xe1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\xd9\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x45\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\xda\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x45\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\xd1\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x45\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\xd2\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x45\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\xd6\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x45\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x71\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x45\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x78\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x45\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x45\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x7b\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x00\x00\xa1\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x7b\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x7b\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x7b\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\xa4\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x7b\x00\x00\x00\x46\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x7b\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x00\x00\xd8\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x7b\x00\x00\x00\x46\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa6\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x7b\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x00\x00\xa7\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x7b\x00\x00\x00\x46\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x7b\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x00\x00\xa9\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x7b\x00\x00\x00\x46\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x7b\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x00\x00\xab\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x7b\x00\x00\x00\x46\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x00\x00\x47\x00\x00\x00\x00\x00\x8f\x00\x00\x00\xac\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x7b\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x7d\x00\x90\x00\x47\x00\x00\x00\x91\x00\x00\x00\x92\x00\x00\x00\x93\x00\x94\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x95\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\x00\x00\x00\x00\x00\x7e\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x7f\x00\x31\x00\x00\x00\x46\x00\x74\x00\x00\x00\x00\x00\x00\x00\x00\x00\x75\x00\x47\x00\xad\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x00\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x31\x00\x00\x00\x00\x00\x46\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x47\x00\xaf\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x00\x00\x00\x00\x46\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x47\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x31\x00\x00\x00\x00\x00\x46\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x47\x00\xb1\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x00\x00\x00\x00\x46\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x47\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7e\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x31\x00\x00\x00\x00\x00\x46\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x47\x00\x00\x00\x6f\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x00\x00\x00\x00\x46\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x47\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x31\x00\x00\x00\x00\x00\x46\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x47\x00\x00\x00\x00\x00\x6d\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x00\x00\x00\x00\x46\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x47\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x31\x00\x00\x00\x00\x00\x46\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x47\x00\x00\x00\x00\x00\x77\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x00\x00\x00\x00\x46\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x47\x00\x31\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x79\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x31\x00\x00\x00\x00\x00\x46\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x47\x00\x00\x00\x00\x00\x00\x00\xb2\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x00\x00\x00\x00\x46\x00\xce\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x47\x00\x00\x00\x46\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x47\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x00\x00\x00\x00\x46\x00\xd4\x00\x41\x00\x42\x00\x43\x00\x44\x00\x31\x00\x47\x00\x00\x00\x46\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb3\x00\x41\x00\x42\x00\x43\x00\x44\x00\x00\x00\x00\x00\x00\x00\x46\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x47\x00\x31\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x00\x00\x00\x00\xb4\x00\x42\x00\x43\x00\x44\x00\x31\x00\x00\x00\x00\x00\x46\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\xb5\x00\x42\x00\x43\x00\x44\x00\x00\x00\x00\x00\x00\x00\x46\x00\x00\x00\xb6\x00\x43\x00\x44\x00\x00\x00\x00\x00\x47\x00\x46\x00\xb7\x00\x44\x00\x00\x00\x00\x00\x00\x00\x46\x00\x47\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x47\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8\x00\x44\x00\x00\x00\x00\x00\x00\x00\x46\x00\xc3\x00\x44\x00\x00\x00\x00\x00\x00\x00\x46\x00\x47\x00\xb9\x00\x00\x00\x00\x00\x00\x00\x46\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# + +happyReduceArr = Happy_Data_Array.array (5, 142) [ + (5 , happyReduce_5), + (6 , happyReduce_6), + (7 , happyReduce_7), + (8 , happyReduce_8), + (9 , happyReduce_9), + (10 , happyReduce_10), + (11 , happyReduce_11), + (12 , happyReduce_12), + (13 , happyReduce_13), + (14 , happyReduce_14), + (15 , happyReduce_15), + (16 , happyReduce_16), + (17 , happyReduce_17), + (18 , happyReduce_18), + (19 , happyReduce_19), + (20 , happyReduce_20), + (21 , happyReduce_21), + (22 , happyReduce_22), + (23 , happyReduce_23), + (24 , happyReduce_24), + (25 , happyReduce_25), + (26 , happyReduce_26), + (27 , happyReduce_27), + (28 , happyReduce_28), + (29 , happyReduce_29), + (30 , happyReduce_30), + (31 , happyReduce_31), + (32 , happyReduce_32), + (33 , happyReduce_33), + (34 , happyReduce_34), + (35 , happyReduce_35), + (36 , happyReduce_36), + (37 , happyReduce_37), + (38 , happyReduce_38), + (39 , happyReduce_39), + (40 , happyReduce_40), + (41 , happyReduce_41), + (42 , happyReduce_42), + (43 , happyReduce_43), + (44 , happyReduce_44), + (45 , happyReduce_45), + (46 , happyReduce_46), + (47 , happyReduce_47), + (48 , happyReduce_48), + (49 , happyReduce_49), + (50 , happyReduce_50), + (51 , happyReduce_51), + (52 , happyReduce_52), + (53 , happyReduce_53), + (54 , happyReduce_54), + (55 , happyReduce_55), + (56 , happyReduce_56), + (57 , happyReduce_57), + (58 , happyReduce_58), + (59 , happyReduce_59), + (60 , happyReduce_60), + (61 , happyReduce_61), + (62 , happyReduce_62), + (63 , happyReduce_63), + (64 , happyReduce_64), + (65 , happyReduce_65), + (66 , happyReduce_66), + (67 , happyReduce_67), + (68 , happyReduce_68), + (69 , happyReduce_69), + (70 , happyReduce_70), + (71 , happyReduce_71), + (72 , happyReduce_72), + (73 , happyReduce_73), + (74 , happyReduce_74), + (75 , happyReduce_75), + (76 , happyReduce_76), + (77 , happyReduce_77), + (78 , happyReduce_78), + (79 , happyReduce_79), + (80 , happyReduce_80), + (81 , happyReduce_81), + (82 , happyReduce_82), + (83 , happyReduce_83), + (84 , happyReduce_84), + (85 , happyReduce_85), + (86 , happyReduce_86), + (87 , happyReduce_87), + (88 , happyReduce_88), + (89 , happyReduce_89), + (90 , happyReduce_90), + (91 , happyReduce_91), + (92 , happyReduce_92), + (93 , happyReduce_93), + (94 , happyReduce_94), + (95 , happyReduce_95), + (96 , happyReduce_96), + (97 , happyReduce_97), + (98 , happyReduce_98), + (99 , happyReduce_99), + (100 , happyReduce_100), + (101 , happyReduce_101), + (102 , happyReduce_102), + (103 , happyReduce_103), + (104 , happyReduce_104), + (105 , happyReduce_105), + (106 , happyReduce_106), + (107 , happyReduce_107), + (108 , happyReduce_108), + (109 , happyReduce_109), + (110 , happyReduce_110), + (111 , happyReduce_111), + (112 , happyReduce_112), + (113 , happyReduce_113), + (114 , happyReduce_114), + (115 , happyReduce_115), + (116 , happyReduce_116), + (117 , happyReduce_117), + (118 , happyReduce_118), + (119 , happyReduce_119), + (120 , happyReduce_120), + (121 , happyReduce_121), + (122 , happyReduce_122), + (123 , happyReduce_123), + (124 , happyReduce_124), + (125 , happyReduce_125), + (126 , happyReduce_126), + (127 , happyReduce_127), + (128 , happyReduce_128), + (129 , happyReduce_129), + (130 , happyReduce_130), + (131 , happyReduce_131), + (132 , happyReduce_132), + (133 , happyReduce_133), + (134 , happyReduce_134), + (135 , happyReduce_135), + (136 , happyReduce_136), + (137 , happyReduce_137), + (138 , happyReduce_138), + (139 , happyReduce_139), + (140 , happyReduce_140), + (141 , happyReduce_141), + (142 , happyReduce_142) + ] + +happy_n_terms = 78 :: Int +happy_n_nonterms = 58 :: Int + +happyReduce_5 = happySpecReduce_1 0# happyReduction_5 +happyReduction_5 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn8 + (PosInteger (mkPosToken happy_var_1) + )} + +happyReduce_6 = happySpecReduce_1 1# happyReduction_6 +happyReduction_6 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn9 + (PosDouble (mkPosToken happy_var_1) + )} + +happyReduce_7 = happySpecReduce_1 2# happyReduction_7 +happyReduction_7 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn10 + (PosReal (mkPosToken happy_var_1) + )} + +happyReduce_8 = happySpecReduce_1 3# happyReduction_8 +happyReduction_8 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn11 + (PosString (mkPosToken happy_var_1) + )} + +happyReduce_9 = happySpecReduce_1 4# happyReduction_9 +happyReduction_9 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn12 + (PosIdent (mkPosToken happy_var_1) + )} + +happyReduce_10 = happySpecReduce_1 5# happyReduction_10 +happyReduction_10 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn13 + (PosLineComment (mkPosToken happy_var_1) + )} + +happyReduce_11 = happySpecReduce_1 6# happyReduction_11 +happyReduction_11 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn14 + (PosBlockComment (mkPosToken happy_var_1) + )} + +happyReduce_12 = happySpecReduce_1 7# happyReduction_12 +happyReduction_12 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn15 + (PosAlloy (mkPosToken happy_var_1) + )} + +happyReduce_13 = happySpecReduce_1 8# happyReduction_13 +happyReduction_13 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn16 + (PosChoco (mkPosToken happy_var_1) + )} + +happyReduce_14 = happySpecReduce_1 9# happyReduction_14 +happyReduction_14 happy_x_1 + = case happyOut59 happy_x_1 of { happy_var_1 -> + happyIn17 + (Language.Clafer.Front.AbsClafer.Module ((mkCatSpan happy_var_1)) (reverse happy_var_1) + )} + +happyReduce_15 = happyReduce 4# 10# happyReduction_15 +happyReduction_15 (happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut12 happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + case happyOut60 happy_x_4 of { happy_var_4 -> + happyIn18 + (Language.Clafer.Front.AbsClafer.EnumDecl ((mkTokenSpan happy_var_1) >- (mkCatSpan happy_var_2) >- (mkTokenSpan happy_var_3) >- (mkCatSpan happy_var_4)) happy_var_2 happy_var_4 + ) `HappyStk` happyRest}}}} + +happyReduce_16 = happySpecReduce_1 10# happyReduction_16 +happyReduction_16 happy_x_1 + = case happyOut25 happy_x_1 of { happy_var_1 -> + happyIn18 + (Language.Clafer.Front.AbsClafer.ElementDecl ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_17 = happyReduce 8# 11# happyReduction_17 +happyReduction_17 (happy_x_8 `HappyStk` + happy_x_7 `HappyStk` + happy_x_6 `HappyStk` + happy_x_5 `HappyStk` + happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOut23 happy_x_1 of { happy_var_1 -> + case happyOut30 happy_x_2 of { happy_var_2 -> + case happyOut12 happy_x_3 of { happy_var_3 -> + case happyOut26 happy_x_4 of { happy_var_4 -> + case happyOut27 happy_x_5 of { happy_var_5 -> + case happyOut31 happy_x_6 of { happy_var_6 -> + case happyOut28 happy_x_7 of { happy_var_7 -> + case happyOut24 happy_x_8 of { happy_var_8 -> + happyIn19 + (Language.Clafer.Front.AbsClafer.Clafer ((mkCatSpan happy_var_1) >- (mkCatSpan happy_var_2) >- (mkCatSpan happy_var_3) >- (mkCatSpan happy_var_4) >- (mkCatSpan happy_var_5) >- (mkCatSpan happy_var_6) >- (mkCatSpan happy_var_7) >- (mkCatSpan happy_var_8)) happy_var_1 happy_var_2 happy_var_3 happy_var_4 happy_var_5 happy_var_6 happy_var_7 happy_var_8 + ) `HappyStk` happyRest}}}}}}}} + +happyReduce_18 = happySpecReduce_3 12# happyReduction_18 +happyReduction_18 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut62 happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + happyIn20 + (Language.Clafer.Front.AbsClafer.Constraint ((mkTokenSpan happy_var_1) >- (mkCatSpan happy_var_2) >- (mkTokenSpan happy_var_3)) (reverse happy_var_2) + )}}} + +happyReduce_19 = happyReduce 4# 13# happyReduction_19 +happyReduction_19 (happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut62 happy_x_3 of { happy_var_3 -> + case happyOutTok happy_x_4 of { happy_var_4 -> + happyIn21 + (Language.Clafer.Front.AbsClafer.Assertion ((mkTokenSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3) >- (mkTokenSpan happy_var_4)) (reverse happy_var_3) + ) `HappyStk` happyRest}}}} + +happyReduce_20 = happyReduce 4# 14# happyReduction_20 +happyReduction_20 (happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut62 happy_x_3 of { happy_var_3 -> + case happyOutTok happy_x_4 of { happy_var_4 -> + happyIn22 + (Language.Clafer.Front.AbsClafer.GoalMinDeprecated ((mkTokenSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3) >- (mkTokenSpan happy_var_4)) (reverse happy_var_3) + ) `HappyStk` happyRest}}}} + +happyReduce_21 = happyReduce 4# 14# happyReduction_21 +happyReduction_21 (happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut62 happy_x_3 of { happy_var_3 -> + case happyOutTok happy_x_4 of { happy_var_4 -> + happyIn22 + (Language.Clafer.Front.AbsClafer.GoalMaxDeprecated ((mkTokenSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3) >- (mkTokenSpan happy_var_4)) (reverse happy_var_3) + ) `HappyStk` happyRest}}}} + +happyReduce_22 = happyReduce 4# 14# happyReduction_22 +happyReduction_22 (happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut62 happy_x_3 of { happy_var_3 -> + case happyOutTok happy_x_4 of { happy_var_4 -> + happyIn22 + (Language.Clafer.Front.AbsClafer.GoalMinimize ((mkTokenSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3) >- (mkTokenSpan happy_var_4)) (reverse happy_var_3) + ) `HappyStk` happyRest}}}} + +happyReduce_23 = happyReduce 4# 14# happyReduction_23 +happyReduction_23 (happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut62 happy_x_3 of { happy_var_3 -> + case happyOutTok happy_x_4 of { happy_var_4 -> + happyIn22 + (Language.Clafer.Front.AbsClafer.GoalMaximize ((mkTokenSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3) >- (mkTokenSpan happy_var_4)) (reverse happy_var_3) + ) `HappyStk` happyRest}}}} + +happyReduce_24 = happySpecReduce_0 15# happyReduction_24 +happyReduction_24 = happyIn23 + (Language.Clafer.Front.AbsClafer.AbstractEmpty noSpan + ) + +happyReduce_25 = happySpecReduce_1 15# happyReduction_25 +happyReduction_25 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn23 + (Language.Clafer.Front.AbsClafer.Abstract ((mkTokenSpan happy_var_1)) + )} + +happyReduce_26 = happySpecReduce_0 16# happyReduction_26 +happyReduction_26 = happyIn24 + (Language.Clafer.Front.AbsClafer.ElementsEmpty noSpan + ) + +happyReduce_27 = happySpecReduce_3 16# happyReduction_27 +happyReduction_27 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut61 happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + happyIn24 + (Language.Clafer.Front.AbsClafer.ElementsList ((mkTokenSpan happy_var_1) >- (mkCatSpan happy_var_2) >- (mkTokenSpan happy_var_3)) (reverse happy_var_2) + )}}} + +happyReduce_28 = happySpecReduce_1 17# happyReduction_28 +happyReduction_28 happy_x_1 + = case happyOut19 happy_x_1 of { happy_var_1 -> + happyIn25 + (Language.Clafer.Front.AbsClafer.Subclafer ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_29 = happyReduce 4# 17# happyReduction_29 +happyReduction_29 (happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut34 happy_x_2 of { happy_var_2 -> + case happyOut31 happy_x_3 of { happy_var_3 -> + case happyOut24 happy_x_4 of { happy_var_4 -> + happyIn25 + (Language.Clafer.Front.AbsClafer.ClaferUse ((mkTokenSpan happy_var_1) >- (mkCatSpan happy_var_2) >- (mkCatSpan happy_var_3) >- (mkCatSpan happy_var_4)) happy_var_2 happy_var_3 happy_var_4 + ) `HappyStk` happyRest}}}} + +happyReduce_30 = happySpecReduce_1 17# happyReduction_30 +happyReduction_30 happy_x_1 + = case happyOut20 happy_x_1 of { happy_var_1 -> + happyIn25 + (Language.Clafer.Front.AbsClafer.Subconstraint ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_31 = happySpecReduce_1 17# happyReduction_31 +happyReduction_31 happy_x_1 + = case happyOut22 happy_x_1 of { happy_var_1 -> + happyIn25 + (Language.Clafer.Front.AbsClafer.Subgoal ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_32 = happySpecReduce_1 17# happyReduction_32 +happyReduction_32 happy_x_1 + = case happyOut21 happy_x_1 of { happy_var_1 -> + happyIn25 + (Language.Clafer.Front.AbsClafer.SubAssertion ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_33 = happySpecReduce_0 18# happyReduction_33 +happyReduction_33 = happyIn26 + (Language.Clafer.Front.AbsClafer.SuperEmpty noSpan + ) + +happyReduce_34 = happySpecReduce_2 18# happyReduction_34 +happyReduction_34 happy_x_2 + happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut52 happy_x_2 of { happy_var_2 -> + happyIn26 + (Language.Clafer.Front.AbsClafer.SuperSome ((mkTokenSpan happy_var_1) >- (mkCatSpan happy_var_2)) happy_var_2 + )}} + +happyReduce_35 = happySpecReduce_0 19# happyReduction_35 +happyReduction_35 = happyIn27 + (Language.Clafer.Front.AbsClafer.ReferenceEmpty noSpan + ) + +happyReduce_36 = happySpecReduce_2 19# happyReduction_36 +happyReduction_36 happy_x_2 + happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut49 happy_x_2 of { happy_var_2 -> + happyIn27 + (Language.Clafer.Front.AbsClafer.ReferenceSet ((mkTokenSpan happy_var_1) >- (mkCatSpan happy_var_2)) happy_var_2 + )}} + +happyReduce_37 = happySpecReduce_2 19# happyReduction_37 +happyReduction_37 happy_x_2 + happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut49 happy_x_2 of { happy_var_2 -> + happyIn27 + (Language.Clafer.Front.AbsClafer.ReferenceBag ((mkTokenSpan happy_var_1) >- (mkCatSpan happy_var_2)) happy_var_2 + )}} + +happyReduce_38 = happySpecReduce_0 20# happyReduction_38 +happyReduction_38 = happyIn28 + (Language.Clafer.Front.AbsClafer.InitEmpty noSpan + ) + +happyReduce_39 = happySpecReduce_2 20# happyReduction_39 +happyReduction_39 happy_x_2 + happy_x_1 + = case happyOut29 happy_x_1 of { happy_var_1 -> + case happyOut35 happy_x_2 of { happy_var_2 -> + happyIn28 + (Language.Clafer.Front.AbsClafer.InitSome ((mkCatSpan happy_var_1) >- (mkCatSpan happy_var_2)) happy_var_1 happy_var_2 + )}} + +happyReduce_40 = happySpecReduce_1 21# happyReduction_40 +happyReduction_40 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn29 + (Language.Clafer.Front.AbsClafer.InitConstant ((mkTokenSpan happy_var_1)) + )} + +happyReduce_41 = happySpecReduce_1 21# happyReduction_41 +happyReduction_41 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn29 + (Language.Clafer.Front.AbsClafer.InitDefault ((mkTokenSpan happy_var_1)) + )} + +happyReduce_42 = happySpecReduce_0 22# happyReduction_42 +happyReduction_42 = happyIn30 + (Language.Clafer.Front.AbsClafer.GCardEmpty noSpan + ) + +happyReduce_43 = happySpecReduce_1 22# happyReduction_43 +happyReduction_43 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn30 + (Language.Clafer.Front.AbsClafer.GCardXor ((mkTokenSpan happy_var_1)) + )} + +happyReduce_44 = happySpecReduce_1 22# happyReduction_44 +happyReduction_44 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn30 + (Language.Clafer.Front.AbsClafer.GCardOr ((mkTokenSpan happy_var_1)) + )} + +happyReduce_45 = happySpecReduce_1 22# happyReduction_45 +happyReduction_45 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn30 + (Language.Clafer.Front.AbsClafer.GCardMux ((mkTokenSpan happy_var_1)) + )} + +happyReduce_46 = happySpecReduce_1 22# happyReduction_46 +happyReduction_46 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn30 + (Language.Clafer.Front.AbsClafer.GCardOpt ((mkTokenSpan happy_var_1)) + )} + +happyReduce_47 = happySpecReduce_1 22# happyReduction_47 +happyReduction_47 happy_x_1 + = case happyOut32 happy_x_1 of { happy_var_1 -> + happyIn30 + (Language.Clafer.Front.AbsClafer.GCardInterval ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_48 = happySpecReduce_0 23# happyReduction_48 +happyReduction_48 = happyIn31 + (Language.Clafer.Front.AbsClafer.CardEmpty noSpan + ) + +happyReduce_49 = happySpecReduce_1 23# happyReduction_49 +happyReduction_49 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn31 + (Language.Clafer.Front.AbsClafer.CardLone ((mkTokenSpan happy_var_1)) + )} + +happyReduce_50 = happySpecReduce_1 23# happyReduction_50 +happyReduction_50 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn31 + (Language.Clafer.Front.AbsClafer.CardSome ((mkTokenSpan happy_var_1)) + )} + +happyReduce_51 = happySpecReduce_1 23# happyReduction_51 +happyReduction_51 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn31 + (Language.Clafer.Front.AbsClafer.CardAny ((mkTokenSpan happy_var_1)) + )} + +happyReduce_52 = happySpecReduce_1 23# happyReduction_52 +happyReduction_52 happy_x_1 + = case happyOut8 happy_x_1 of { happy_var_1 -> + happyIn31 + (Language.Clafer.Front.AbsClafer.CardNum ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_53 = happySpecReduce_1 23# happyReduction_53 +happyReduction_53 happy_x_1 + = case happyOut32 happy_x_1 of { happy_var_1 -> + happyIn31 + (Language.Clafer.Front.AbsClafer.CardInterval ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_54 = happySpecReduce_3 24# happyReduction_54 +happyReduction_54 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut8 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut33 happy_x_3 of { happy_var_3 -> + happyIn32 + (Language.Clafer.Front.AbsClafer.NCard ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_55 = happySpecReduce_1 25# happyReduction_55 +happyReduction_55 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn33 + (Language.Clafer.Front.AbsClafer.ExIntegerAst ((mkTokenSpan happy_var_1)) + )} + +happyReduce_56 = happySpecReduce_1 25# happyReduction_56 +happyReduction_56 happy_x_1 + = case happyOut8 happy_x_1 of { happy_var_1 -> + happyIn33 + (Language.Clafer.Front.AbsClafer.ExIntegerNum ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_57 = happySpecReduce_1 26# happyReduction_57 +happyReduction_57 happy_x_1 + = case happyOut64 happy_x_1 of { happy_var_1 -> + happyIn34 + (Language.Clafer.Front.AbsClafer.Path ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_58 = happyReduce 5# 27# happyReduction_58 +happyReduction_58 (happy_x_5 `HappyStk` + happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut54 happy_x_3 of { happy_var_3 -> + case happyOutTok happy_x_4 of { happy_var_4 -> + case happyOut35 happy_x_5 of { happy_var_5 -> + happyIn35 + (Language.Clafer.Front.AbsClafer.EDeclAllDisj ((mkTokenSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3) >- (mkTokenSpan happy_var_4) >- (mkCatSpan happy_var_5)) happy_var_3 happy_var_5 + ) `HappyStk` happyRest}}}}} + +happyReduce_59 = happyReduce 4# 27# happyReduction_59 +happyReduction_59 (happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut54 happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + case happyOut35 happy_x_4 of { happy_var_4 -> + happyIn35 + (Language.Clafer.Front.AbsClafer.EDeclAll ((mkTokenSpan happy_var_1) >- (mkCatSpan happy_var_2) >- (mkTokenSpan happy_var_3) >- (mkCatSpan happy_var_4)) happy_var_2 happy_var_4 + ) `HappyStk` happyRest}}}} + +happyReduce_60 = happyReduce 5# 27# happyReduction_60 +happyReduction_60 (happy_x_5 `HappyStk` + happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOut55 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut54 happy_x_3 of { happy_var_3 -> + case happyOutTok happy_x_4 of { happy_var_4 -> + case happyOut35 happy_x_5 of { happy_var_5 -> + happyIn35 + (Language.Clafer.Front.AbsClafer.EDeclQuantDisj ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3) >- (mkTokenSpan happy_var_4) >- (mkCatSpan happy_var_5)) happy_var_1 happy_var_3 happy_var_5 + ) `HappyStk` happyRest}}}}} + +happyReduce_61 = happyReduce 4# 27# happyReduction_61 +happyReduction_61 (happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOut55 happy_x_1 of { happy_var_1 -> + case happyOut54 happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + case happyOut35 happy_x_4 of { happy_var_4 -> + happyIn35 + (Language.Clafer.Front.AbsClafer.EDeclQuant ((mkCatSpan happy_var_1) >- (mkCatSpan happy_var_2) >- (mkTokenSpan happy_var_3) >- (mkCatSpan happy_var_4)) happy_var_1 happy_var_2 happy_var_4 + ) `HappyStk` happyRest}}}} + +happyReduce_62 = happyReduce 6# 27# happyReduction_62 +happyReduction_62 (happy_x_6 `HappyStk` + happy_x_5 `HappyStk` + happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut35 happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + case happyOut35 happy_x_4 of { happy_var_4 -> + case happyOutTok happy_x_5 of { happy_var_5 -> + case happyOut35 happy_x_6 of { happy_var_6 -> + happyIn35 + (Language.Clafer.Front.AbsClafer.EImpliesElse ((mkTokenSpan happy_var_1) >- (mkCatSpan happy_var_2) >- (mkTokenSpan happy_var_3) >- (mkCatSpan happy_var_4) >- (mkTokenSpan happy_var_5) >- (mkCatSpan happy_var_6)) happy_var_2 happy_var_4 happy_var_6 + ) `HappyStk` happyRest}}}}}} + +happyReduce_63 = happySpecReduce_3 27# happyReduction_63 +happyReduction_63 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut35 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut65 happy_x_3 of { happy_var_3 -> + happyIn35 + (Language.Clafer.Front.AbsClafer.EIff ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_64 = happySpecReduce_1 27# happyReduction_64 +happyReduction_64 happy_x_1 + = case happyOut65 happy_x_1 of { happy_var_1 -> + happyIn35 + (happy_var_1 + )} + +happyReduce_65 = happySpecReduce_3 28# happyReduction_65 +happyReduction_65 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut36 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut37 happy_x_3 of { happy_var_3 -> + happyIn36 + (Language.Clafer.Front.AbsClafer.EImplies ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_66 = happySpecReduce_1 28# happyReduction_66 +happyReduction_66 happy_x_1 + = case happyOut37 happy_x_1 of { happy_var_1 -> + happyIn36 + (happy_var_1 + )} + +happyReduce_67 = happySpecReduce_3 29# happyReduction_67 +happyReduction_67 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut37 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut38 happy_x_3 of { happy_var_3 -> + happyIn37 + (Language.Clafer.Front.AbsClafer.EOr ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_68 = happySpecReduce_1 29# happyReduction_68 +happyReduction_68 happy_x_1 + = case happyOut38 happy_x_1 of { happy_var_1 -> + happyIn37 + (happy_var_1 + )} + +happyReduce_69 = happySpecReduce_3 30# happyReduction_69 +happyReduction_69 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut38 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut39 happy_x_3 of { happy_var_3 -> + happyIn38 + (Language.Clafer.Front.AbsClafer.EXor ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_70 = happySpecReduce_1 30# happyReduction_70 +happyReduction_70 happy_x_1 + = case happyOut39 happy_x_1 of { happy_var_1 -> + happyIn38 + (happy_var_1 + )} + +happyReduce_71 = happySpecReduce_3 31# happyReduction_71 +happyReduction_71 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut39 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut40 happy_x_3 of { happy_var_3 -> + happyIn39 + (Language.Clafer.Front.AbsClafer.EAnd ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_72 = happySpecReduce_1 31# happyReduction_72 +happyReduction_72 happy_x_1 + = case happyOut40 happy_x_1 of { happy_var_1 -> + happyIn39 + (happy_var_1 + )} + +happyReduce_73 = happySpecReduce_2 32# happyReduction_73 +happyReduction_73 happy_x_2 + happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut41 happy_x_2 of { happy_var_2 -> + happyIn40 + (Language.Clafer.Front.AbsClafer.ENeg ((mkTokenSpan happy_var_1) >- (mkCatSpan happy_var_2)) happy_var_2 + )}} + +happyReduce_74 = happySpecReduce_1 32# happyReduction_74 +happyReduction_74 happy_x_1 + = case happyOut41 happy_x_1 of { happy_var_1 -> + happyIn40 + (happy_var_1 + )} + +happyReduce_75 = happySpecReduce_3 33# happyReduction_75 +happyReduction_75 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut41 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut42 happy_x_3 of { happy_var_3 -> + happyIn41 + (Language.Clafer.Front.AbsClafer.ELt ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_76 = happySpecReduce_3 33# happyReduction_76 +happyReduction_76 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut41 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut42 happy_x_3 of { happy_var_3 -> + happyIn41 + (Language.Clafer.Front.AbsClafer.EGt ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_77 = happySpecReduce_3 33# happyReduction_77 +happyReduction_77 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut41 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut42 happy_x_3 of { happy_var_3 -> + happyIn41 + (Language.Clafer.Front.AbsClafer.EEq ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_78 = happySpecReduce_3 33# happyReduction_78 +happyReduction_78 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut41 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut42 happy_x_3 of { happy_var_3 -> + happyIn41 + (Language.Clafer.Front.AbsClafer.ELte ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_79 = happySpecReduce_3 33# happyReduction_79 +happyReduction_79 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut41 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut42 happy_x_3 of { happy_var_3 -> + happyIn41 + (Language.Clafer.Front.AbsClafer.EGte ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_80 = happySpecReduce_3 33# happyReduction_80 +happyReduction_80 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut41 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut42 happy_x_3 of { happy_var_3 -> + happyIn41 + (Language.Clafer.Front.AbsClafer.ENeq ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_81 = happySpecReduce_3 33# happyReduction_81 +happyReduction_81 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut41 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut42 happy_x_3 of { happy_var_3 -> + happyIn41 + (Language.Clafer.Front.AbsClafer.EIn ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_82 = happyReduce 4# 33# happyReduction_82 +happyReduction_82 (happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOut41 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOutTok happy_x_3 of { happy_var_3 -> + case happyOut42 happy_x_4 of { happy_var_4 -> + happyIn41 + (Language.Clafer.Front.AbsClafer.ENin ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkTokenSpan happy_var_3) >- (mkCatSpan happy_var_4)) happy_var_1 happy_var_4 + ) `HappyStk` happyRest}}}} + +happyReduce_83 = happySpecReduce_1 33# happyReduction_83 +happyReduction_83 happy_x_1 + = case happyOut42 happy_x_1 of { happy_var_1 -> + happyIn41 + (happy_var_1 + )} + +happyReduce_84 = happySpecReduce_2 34# happyReduction_84 +happyReduction_84 happy_x_2 + happy_x_1 + = case happyOut55 happy_x_1 of { happy_var_1 -> + case happyOut46 happy_x_2 of { happy_var_2 -> + happyIn42 + (Language.Clafer.Front.AbsClafer.EQuantExp ((mkCatSpan happy_var_1) >- (mkCatSpan happy_var_2)) happy_var_1 happy_var_2 + )}} + +happyReduce_85 = happySpecReduce_1 34# happyReduction_85 +happyReduction_85 happy_x_1 + = case happyOut43 happy_x_1 of { happy_var_1 -> + happyIn42 + (happy_var_1 + )} + +happyReduce_86 = happySpecReduce_3 35# happyReduction_86 +happyReduction_86 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut43 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut44 happy_x_3 of { happy_var_3 -> + happyIn43 + (Language.Clafer.Front.AbsClafer.EAdd ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_87 = happySpecReduce_3 35# happyReduction_87 +happyReduction_87 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut43 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut44 happy_x_3 of { happy_var_3 -> + happyIn43 + (Language.Clafer.Front.AbsClafer.ESub ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_88 = happySpecReduce_1 35# happyReduction_88 +happyReduction_88 happy_x_1 + = case happyOut44 happy_x_1 of { happy_var_1 -> + happyIn43 + (happy_var_1 + )} + +happyReduce_89 = happySpecReduce_3 36# happyReduction_89 +happyReduction_89 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut44 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut45 happy_x_3 of { happy_var_3 -> + happyIn44 + (Language.Clafer.Front.AbsClafer.EMul ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_90 = happySpecReduce_3 36# happyReduction_90 +happyReduction_90 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut44 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut45 happy_x_3 of { happy_var_3 -> + happyIn44 + (Language.Clafer.Front.AbsClafer.EDiv ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_91 = happySpecReduce_3 36# happyReduction_91 +happyReduction_91 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut44 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut45 happy_x_3 of { happy_var_3 -> + happyIn44 + (Language.Clafer.Front.AbsClafer.ERem ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_92 = happySpecReduce_1 36# happyReduction_92 +happyReduction_92 happy_x_1 + = case happyOut45 happy_x_1 of { happy_var_1 -> + happyIn44 + (happy_var_1 + )} + +happyReduce_93 = happySpecReduce_2 37# happyReduction_93 +happyReduction_93 happy_x_2 + happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut46 happy_x_2 of { happy_var_2 -> + happyIn45 + (Language.Clafer.Front.AbsClafer.EGMax ((mkTokenSpan happy_var_1) >- (mkCatSpan happy_var_2)) happy_var_2 + )}} + +happyReduce_94 = happySpecReduce_2 37# happyReduction_94 +happyReduction_94 happy_x_2 + happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut46 happy_x_2 of { happy_var_2 -> + happyIn45 + (Language.Clafer.Front.AbsClafer.EGMin ((mkTokenSpan happy_var_1) >- (mkCatSpan happy_var_2)) happy_var_2 + )}} + +happyReduce_95 = happySpecReduce_1 37# happyReduction_95 +happyReduction_95 happy_x_1 + = case happyOut46 happy_x_1 of { happy_var_1 -> + happyIn45 + (happy_var_1 + )} + +happyReduce_96 = happySpecReduce_2 38# happyReduction_96 +happyReduction_96 happy_x_2 + happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut47 happy_x_2 of { happy_var_2 -> + happyIn46 + (Language.Clafer.Front.AbsClafer.ESum ((mkTokenSpan happy_var_1) >- (mkCatSpan happy_var_2)) happy_var_2 + )}} + +happyReduce_97 = happySpecReduce_2 38# happyReduction_97 +happyReduction_97 happy_x_2 + happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut47 happy_x_2 of { happy_var_2 -> + happyIn46 + (Language.Clafer.Front.AbsClafer.EProd ((mkTokenSpan happy_var_1) >- (mkCatSpan happy_var_2)) happy_var_2 + )}} + +happyReduce_98 = happySpecReduce_2 38# happyReduction_98 +happyReduction_98 happy_x_2 + happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut47 happy_x_2 of { happy_var_2 -> + happyIn46 + (Language.Clafer.Front.AbsClafer.ECard ((mkTokenSpan happy_var_1) >- (mkCatSpan happy_var_2)) happy_var_2 + )}} + +happyReduce_99 = happySpecReduce_2 38# happyReduction_99 +happyReduction_99 happy_x_2 + happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut47 happy_x_2 of { happy_var_2 -> + happyIn46 + (Language.Clafer.Front.AbsClafer.EMinExp ((mkTokenSpan happy_var_1) >- (mkCatSpan happy_var_2)) happy_var_2 + )}} + +happyReduce_100 = happySpecReduce_1 38# happyReduction_100 +happyReduction_100 happy_x_1 + = case happyOut47 happy_x_1 of { happy_var_1 -> + happyIn46 + (happy_var_1 + )} + +happyReduce_101 = happySpecReduce_3 39# happyReduction_101 +happyReduction_101 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut47 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut48 happy_x_3 of { happy_var_3 -> + happyIn47 + (Language.Clafer.Front.AbsClafer.EDomain ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_102 = happySpecReduce_1 39# happyReduction_102 +happyReduction_102 happy_x_1 + = case happyOut48 happy_x_1 of { happy_var_1 -> + happyIn47 + (happy_var_1 + )} + +happyReduce_103 = happySpecReduce_3 40# happyReduction_103 +happyReduction_103 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut48 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut49 happy_x_3 of { happy_var_3 -> + happyIn48 + (Language.Clafer.Front.AbsClafer.ERange ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_104 = happySpecReduce_1 40# happyReduction_104 +happyReduction_104 happy_x_1 + = case happyOut49 happy_x_1 of { happy_var_1 -> + happyIn48 + (happy_var_1 + )} + +happyReduce_105 = happySpecReduce_3 41# happyReduction_105 +happyReduction_105 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut49 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut50 happy_x_3 of { happy_var_3 -> + happyIn49 + (Language.Clafer.Front.AbsClafer.EUnion ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_106 = happySpecReduce_3 41# happyReduction_106 +happyReduction_106 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut49 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut50 happy_x_3 of { happy_var_3 -> + happyIn49 + (Language.Clafer.Front.AbsClafer.EUnionCom ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_107 = happySpecReduce_1 41# happyReduction_107 +happyReduction_107 happy_x_1 + = case happyOut50 happy_x_1 of { happy_var_1 -> + happyIn49 + (happy_var_1 + )} + +happyReduce_108 = happySpecReduce_3 42# happyReduction_108 +happyReduction_108 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut50 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut51 happy_x_3 of { happy_var_3 -> + happyIn50 + (Language.Clafer.Front.AbsClafer.EDifference ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_109 = happySpecReduce_1 42# happyReduction_109 +happyReduction_109 happy_x_1 + = case happyOut51 happy_x_1 of { happy_var_1 -> + happyIn50 + (happy_var_1 + )} + +happyReduce_110 = happySpecReduce_3 43# happyReduction_110 +happyReduction_110 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut51 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut52 happy_x_3 of { happy_var_3 -> + happyIn51 + (Language.Clafer.Front.AbsClafer.EIntersection ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_111 = happySpecReduce_3 43# happyReduction_111 +happyReduction_111 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut51 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut52 happy_x_3 of { happy_var_3 -> + happyIn51 + (Language.Clafer.Front.AbsClafer.EIntersectionDeprecated ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_112 = happySpecReduce_1 43# happyReduction_112 +happyReduction_112 happy_x_1 + = case happyOut52 happy_x_1 of { happy_var_1 -> + happyIn51 + (happy_var_1 + )} + +happyReduce_113 = happySpecReduce_3 44# happyReduction_113 +happyReduction_113 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut52 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut53 happy_x_3 of { happy_var_3 -> + happyIn52 + (Language.Clafer.Front.AbsClafer.EJoin ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_114 = happySpecReduce_1 44# happyReduction_114 +happyReduction_114 happy_x_1 + = case happyOut53 happy_x_1 of { happy_var_1 -> + happyIn52 + (happy_var_1 + )} + +happyReduce_115 = happySpecReduce_1 45# happyReduction_115 +happyReduction_115 happy_x_1 + = case happyOut34 happy_x_1 of { happy_var_1 -> + happyIn53 + (Language.Clafer.Front.AbsClafer.ClaferId ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_116 = happySpecReduce_1 45# happyReduction_116 +happyReduction_116 happy_x_1 + = case happyOut8 happy_x_1 of { happy_var_1 -> + happyIn53 + (Language.Clafer.Front.AbsClafer.EInt ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_117 = happySpecReduce_1 45# happyReduction_117 +happyReduction_117 happy_x_1 + = case happyOut9 happy_x_1 of { happy_var_1 -> + happyIn53 + (Language.Clafer.Front.AbsClafer.EDouble ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_118 = happySpecReduce_1 45# happyReduction_118 +happyReduction_118 happy_x_1 + = case happyOut10 happy_x_1 of { happy_var_1 -> + happyIn53 + (Language.Clafer.Front.AbsClafer.EReal ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_119 = happySpecReduce_1 45# happyReduction_119 +happyReduction_119 happy_x_1 + = case happyOut11 happy_x_1 of { happy_var_1 -> + happyIn53 + (Language.Clafer.Front.AbsClafer.EStr ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_120 = happySpecReduce_3 45# happyReduction_120 +happyReduction_120 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut35 happy_x_2 of { happy_var_2 -> + happyIn53 + (happy_var_2 + )} + +happyReduce_121 = happySpecReduce_3 46# happyReduction_121 +happyReduction_121 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut63 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { happy_var_2 -> + case happyOut49 happy_x_3 of { happy_var_3 -> + happyIn54 + (Language.Clafer.Front.AbsClafer.Decl ((mkCatSpan happy_var_1) >- (mkTokenSpan happy_var_2) >- (mkCatSpan happy_var_3)) happy_var_1 happy_var_3 + )}}} + +happyReduce_122 = happySpecReduce_1 47# happyReduction_122 +happyReduction_122 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn55 + (Language.Clafer.Front.AbsClafer.QuantNo ((mkTokenSpan happy_var_1)) + )} + +happyReduce_123 = happySpecReduce_1 47# happyReduction_123 +happyReduction_123 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn55 + (Language.Clafer.Front.AbsClafer.QuantNot ((mkTokenSpan happy_var_1)) + )} + +happyReduce_124 = happySpecReduce_1 47# happyReduction_124 +happyReduction_124 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn55 + (Language.Clafer.Front.AbsClafer.QuantLone ((mkTokenSpan happy_var_1)) + )} + +happyReduce_125 = happySpecReduce_1 47# happyReduction_125 +happyReduction_125 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn55 + (Language.Clafer.Front.AbsClafer.QuantOne ((mkTokenSpan happy_var_1)) + )} + +happyReduce_126 = happySpecReduce_1 47# happyReduction_126 +happyReduction_126 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn55 + (Language.Clafer.Front.AbsClafer.QuantSome ((mkTokenSpan happy_var_1)) + )} + +happyReduce_127 = happySpecReduce_1 48# happyReduction_127 +happyReduction_127 happy_x_1 + = case happyOut12 happy_x_1 of { happy_var_1 -> + happyIn56 + (Language.Clafer.Front.AbsClafer.EnumIdIdent ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_128 = happySpecReduce_1 49# happyReduction_128 +happyReduction_128 happy_x_1 + = case happyOut12 happy_x_1 of { happy_var_1 -> + happyIn57 + (Language.Clafer.Front.AbsClafer.ModIdIdent ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_129 = happySpecReduce_1 50# happyReduction_129 +happyReduction_129 happy_x_1 + = case happyOut12 happy_x_1 of { happy_var_1 -> + happyIn58 + (Language.Clafer.Front.AbsClafer.LocIdIdent ((mkCatSpan happy_var_1)) happy_var_1 + )} + +happyReduce_130 = happySpecReduce_0 51# happyReduction_130 +happyReduction_130 = happyIn59 + ([] + ) + +happyReduce_131 = happySpecReduce_2 51# happyReduction_131 +happyReduction_131 happy_x_2 + happy_x_1 + = case happyOut59 happy_x_1 of { happy_var_1 -> + case happyOut18 happy_x_2 of { happy_var_2 -> + happyIn59 + (flip (:) happy_var_1 happy_var_2 + )}} + +happyReduce_132 = happySpecReduce_1 52# happyReduction_132 +happyReduction_132 happy_x_1 + = case happyOut56 happy_x_1 of { happy_var_1 -> + happyIn60 + ((:[]) happy_var_1 + )} + +happyReduce_133 = happySpecReduce_3 52# happyReduction_133 +happyReduction_133 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut56 happy_x_1 of { happy_var_1 -> + case happyOut60 happy_x_3 of { happy_var_3 -> + happyIn60 + ((:) happy_var_1 happy_var_3 + )}} + +happyReduce_134 = happySpecReduce_0 53# happyReduction_134 +happyReduction_134 = happyIn61 + ([] + ) + +happyReduce_135 = happySpecReduce_2 53# happyReduction_135 +happyReduction_135 happy_x_2 + happy_x_1 + = case happyOut61 happy_x_1 of { happy_var_1 -> + case happyOut25 happy_x_2 of { happy_var_2 -> + happyIn61 + (flip (:) happy_var_1 happy_var_2 + )}} + +happyReduce_136 = happySpecReduce_0 54# happyReduction_136 +happyReduction_136 = happyIn62 + ([] + ) + +happyReduce_137 = happySpecReduce_2 54# happyReduction_137 +happyReduction_137 happy_x_2 + happy_x_1 + = case happyOut62 happy_x_1 of { happy_var_1 -> + case happyOut35 happy_x_2 of { happy_var_2 -> + happyIn62 + (flip (:) happy_var_1 happy_var_2 + )}} + +happyReduce_138 = happySpecReduce_1 55# happyReduction_138 +happyReduction_138 happy_x_1 + = case happyOut58 happy_x_1 of { happy_var_1 -> + happyIn63 + ((:[]) happy_var_1 + )} + +happyReduce_139 = happySpecReduce_3 55# happyReduction_139 +happyReduction_139 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut58 happy_x_1 of { happy_var_1 -> + case happyOut63 happy_x_3 of { happy_var_3 -> + happyIn63 + ((:) happy_var_1 happy_var_3 + )}} + +happyReduce_140 = happySpecReduce_1 56# happyReduction_140 +happyReduction_140 happy_x_1 + = case happyOut57 happy_x_1 of { happy_var_1 -> + happyIn64 + ((:[]) happy_var_1 + )} + +happyReduce_141 = happySpecReduce_3 56# happyReduction_141 +happyReduction_141 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut57 happy_x_1 of { happy_var_1 -> + case happyOut64 happy_x_3 of { happy_var_3 -> + happyIn64 + ((:) happy_var_1 happy_var_3 + )}} + +happyReduce_142 = happySpecReduce_1 57# happyReduction_142 +happyReduction_142 happy_x_1 + = case happyOut36 happy_x_1 of { happy_var_1 -> + happyIn65 + (happy_var_1 + )} + +happyNewToken action sts stk [] = + happyDoAction 77# notHappyAtAll action sts stk [] + +happyNewToken action sts stk (tk:tks) = + let cont i = happyDoAction i tk action sts stk tks in + case tk of { + PT _ (TS _ 1) -> cont 1#; + PT _ (TS _ 2) -> cont 2#; + PT _ (TS _ 3) -> cont 3#; + PT _ (TS _ 4) -> cont 4#; + PT _ (TS _ 5) -> cont 5#; + PT _ (TS _ 6) -> cont 6#; + PT _ (TS _ 7) -> cont 7#; + PT _ (TS _ 8) -> cont 8#; + PT _ (TS _ 9) -> cont 9#; + PT _ (TS _ 10) -> cont 10#; + PT _ (TS _ 11) -> cont 11#; + PT _ (TS _ 12) -> cont 12#; + PT _ (TS _ 13) -> cont 13#; + PT _ (TS _ 14) -> cont 14#; + PT _ (TS _ 15) -> cont 15#; + PT _ (TS _ 16) -> cont 16#; + PT _ (TS _ 17) -> cont 17#; + PT _ (TS _ 18) -> cont 18#; + PT _ (TS _ 19) -> cont 19#; + PT _ (TS _ 20) -> cont 20#; + PT _ (TS _ 21) -> cont 21#; + PT _ (TS _ 22) -> cont 22#; + PT _ (TS _ 23) -> cont 23#; + PT _ (TS _ 24) -> cont 24#; + PT _ (TS _ 25) -> cont 25#; + PT _ (TS _ 26) -> cont 26#; + PT _ (TS _ 27) -> cont 27#; + PT _ (TS _ 28) -> cont 28#; + PT _ (TS _ 29) -> cont 29#; + PT _ (TS _ 30) -> cont 30#; + PT _ (TS _ 31) -> cont 31#; + PT _ (TS _ 32) -> cont 32#; + PT _ (TS _ 33) -> cont 33#; + PT _ (TS _ 34) -> cont 34#; + PT _ (TS _ 35) -> cont 35#; + PT _ (TS _ 36) -> cont 36#; + PT _ (TS _ 37) -> cont 37#; + PT _ (TS _ 38) -> cont 38#; + PT _ (TS _ 39) -> cont 39#; + PT _ (TS _ 40) -> cont 40#; + PT _ (TS _ 41) -> cont 41#; + PT _ (TS _ 42) -> cont 42#; + PT _ (TS _ 43) -> cont 43#; + PT _ (TS _ 44) -> cont 44#; + PT _ (TS _ 45) -> cont 45#; + PT _ (TS _ 46) -> cont 46#; + PT _ (TS _ 47) -> cont 47#; + PT _ (TS _ 48) -> cont 48#; + PT _ (TS _ 49) -> cont 49#; + PT _ (TS _ 50) -> cont 50#; + PT _ (TS _ 51) -> cont 51#; + PT _ (TS _ 52) -> cont 52#; + PT _ (TS _ 53) -> cont 53#; + PT _ (TS _ 54) -> cont 54#; + PT _ (TS _ 55) -> cont 55#; + PT _ (TS _ 56) -> cont 56#; + PT _ (TS _ 57) -> cont 57#; + PT _ (TS _ 58) -> cont 58#; + PT _ (TS _ 59) -> cont 59#; + PT _ (TS _ 60) -> cont 60#; + PT _ (TS _ 61) -> cont 61#; + PT _ (TS _ 62) -> cont 62#; + PT _ (TS _ 63) -> cont 63#; + PT _ (TS _ 64) -> cont 64#; + PT _ (TS _ 65) -> cont 65#; + PT _ (TS _ 66) -> cont 66#; + PT _ (TS _ 67) -> cont 67#; + PT _ (T_PosInteger _) -> cont 68#; + PT _ (T_PosDouble _) -> cont 69#; + PT _ (T_PosReal _) -> cont 70#; + PT _ (T_PosString _) -> cont 71#; + PT _ (T_PosIdent _) -> cont 72#; + PT _ (T_PosLineComment _) -> cont 73#; + PT _ (T_PosBlockComment _) -> cont 74#; + PT _ (T_PosAlloy _) -> cont 75#; + PT _ (T_PosChoco _) -> cont 76#; + _ -> happyError' (tk:tks) + } + +happyError_ 77# tk tks = happyError' tks +happyError_ _ tk tks = happyError' (tk:tks) + +happyThen :: () => Err a -> (a -> Err b) -> Err b +happyThen = (thenM) +happyReturn :: () => a -> Err a +happyReturn = (returnM) +happyThen1 m k tks = (thenM) m (\a -> k a tks) +happyReturn1 :: () => a -> b -> Err a +happyReturn1 = \a tks -> (returnM) a +happyError' :: () => [(Token)] -> Err a +happyError' = happyError + +pModule tks = happySomeParser where + happySomeParser = happyThen (happyParse 0# tks) (\x -> happyReturn (happyOut17 x)) + +pClafer tks = happySomeParser where + happySomeParser = happyThen (happyParse 1# tks) (\x -> happyReturn (happyOut19 x)) + +pConstraint tks = happySomeParser where + happySomeParser = happyThen (happyParse 2# tks) (\x -> happyReturn (happyOut20 x)) + +pAssertion tks = happySomeParser where + happySomeParser = happyThen (happyParse 3# tks) (\x -> happyReturn (happyOut21 x)) + +pGoal tks = happySomeParser where + happySomeParser = happyThen (happyParse 4# tks) (\x -> happyReturn (happyOut22 x)) + +happySeq = happyDontSeq + + +returnM :: a -> Err a +returnM = return + +thenM :: Err a -> (a -> Err b) -> Err b +thenM = (>>=) + +happyError :: [Token] -> Err a +happyError ts = + Bad (pp ts) $ "syntax error at " ++ tokenPos ts ++ + case ts of + [] -> [] + [Err _] -> " due to lexer error" + _ -> " before " ++ unwords (map (id . prToken) (take 4 ts)) + +myLexer = tokens + +gp x@(PT (Pn _ l c) _) = Span (Pos (toInteger l) (toInteger c)) (Pos (toInteger l) (toInteger c + toInteger (length $ prToken x))) +pp (PT (Pn _ l c) _ :_) = Pos (toInteger l) (toInteger c) +pp (Err (Pn _ l c) :_) = Pos (toInteger l) (toInteger c) +pp _ = error "EOF" + +mkCatSpan :: (Spannable c) => c -> Span +mkCatSpan = getSpan + +mkTokenSpan :: Token -> Span +mkTokenSpan = gp +{-# LINE 1 "templates\GenericTemplate.hs" #-} +{-# LINE 1 "templates\\GenericTemplate.hs" #-} +{-# LINE 1 "<built-in>" #-} +{-# LINE 1 "<command-line>" #-} +{-# LINE 12 "<command-line>" #-} +{-# LINE 1 "C:\\Users\\mantkiew\\AppData\\Local\\Programs\\stack\\x86_64-windows\\ghc-7.10.3\\lib/include\\ghcversion.h" #-} + + + + + + + + + + + + + + + + + +{-# LINE 12 "<command-line>" #-} +{-# LINE 1 "templates\\GenericTemplate.hs" #-} +-- Id: GenericTemplate.hs,v 1.26 2005/01/14 14:47:22 simonmar Exp + +{-# LINE 13 "templates\\GenericTemplate.hs" #-} + + + + + +-- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex. +#if __GLASGOW_HASKELL__ > 706 +#define LT(n,m) ((Happy_GHC_Exts.tagToEnum# (n Happy_GHC_Exts.<# m)) :: Bool) +#define GTE(n,m) ((Happy_GHC_Exts.tagToEnum# (n Happy_GHC_Exts.>=# m)) :: Bool) +#define EQ(n,m) ((Happy_GHC_Exts.tagToEnum# (n Happy_GHC_Exts.==# m)) :: Bool) +#else +#define LT(n,m) (n Happy_GHC_Exts.<# m) +#define GTE(n,m) (n Happy_GHC_Exts.>=# m) +#define EQ(n,m) (n Happy_GHC_Exts.==# m) +#endif +{-# LINE 46 "templates\\GenericTemplate.hs" #-} + + +data Happy_IntList = HappyCons Happy_GHC_Exts.Int# Happy_IntList + + + + + +{-# LINE 67 "templates\\GenericTemplate.hs" #-} + +{-# LINE 77 "templates\\GenericTemplate.hs" #-} + +{-# LINE 86 "templates\\GenericTemplate.hs" #-} + +infixr 9 `HappyStk` +data HappyStk a = HappyStk a (HappyStk a) + +----------------------------------------------------------------------------- +-- starting the parse + +happyParse start_state = happyNewToken start_state notHappyAtAll notHappyAtAll + +----------------------------------------------------------------------------- +-- Accepting the parse + +-- If the current token is 0#, it means we've just accepted a partial +-- parse (a %partial parser). We must ignore the saved token on the top of +-- the stack in this case. +happyAccept 0# tk st sts (_ `HappyStk` ans `HappyStk` _) = + happyReturn1 ans +happyAccept j tk st sts (HappyStk ans _) = + (happyTcHack j (happyTcHack st)) (happyReturn1 ans) + +----------------------------------------------------------------------------- +-- Arrays only: do the next action + + + +happyDoAction i tk st + = {- nothing -} + + + case action of + 0# -> {- nothing -} + happyFail i tk st + -1# -> {- nothing -} + happyAccept i tk st + n | LT(n,(0# :: Happy_GHC_Exts.Int#)) -> {- nothing -} + + (happyReduceArr Happy_Data_Array.! rule) i tk st + where rule = (Happy_GHC_Exts.I# ((Happy_GHC_Exts.negateInt# ((n Happy_GHC_Exts.+# (1# :: Happy_GHC_Exts.Int#)))))) + n -> {- nothing -} + + + happyShift new_state i tk st + where new_state = (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) + where off = indexShortOffAddr happyActOffsets st + off_i = (off Happy_GHC_Exts.+# i) + check = if GTE(off_i,(0# :: Happy_GHC_Exts.Int#)) + then EQ(indexShortOffAddr happyCheck off_i, i) + else False + action + | check = indexShortOffAddr happyTable off_i + | otherwise = indexShortOffAddr happyDefActions st + + +indexShortOffAddr (HappyA# arr) off = + Happy_GHC_Exts.narrow16Int# i + where + i = Happy_GHC_Exts.word2Int# (Happy_GHC_Exts.or# (Happy_GHC_Exts.uncheckedShiftL# high 8#) low) + high = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr (off' Happy_GHC_Exts.+# 1#))) + low = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr off')) + off' = off Happy_GHC_Exts.*# 2# + + + + + +data HappyAddr = HappyA# Happy_GHC_Exts.Addr# + + + + +----------------------------------------------------------------------------- +-- HappyState data type (not arrays) + +{-# LINE 170 "templates\\GenericTemplate.hs" #-} + +----------------------------------------------------------------------------- +-- Shifting a token + +happyShift new_state 0# tk st sts stk@(x `HappyStk` _) = + let i = (case Happy_GHC_Exts.unsafeCoerce# x of { (Happy_GHC_Exts.I# (i)) -> i }) in +-- trace "shifting the error token" $ + happyDoAction i tk new_state (HappyCons (st) (sts)) (stk) + +happyShift new_state i tk st sts stk = + happyNewToken new_state (HappyCons (st) (sts)) ((happyInTok (tk))`HappyStk`stk) + +-- happyReduce is specialised for the common cases. + +happySpecReduce_0 i fn 0# tk st sts stk + = happyFail 0# tk st sts stk +happySpecReduce_0 nt fn j tk st@((action)) sts stk + = happyGoto nt j tk st (HappyCons (st) (sts)) (fn `HappyStk` stk) + +happySpecReduce_1 i fn 0# tk st sts stk + = happyFail 0# tk st sts stk +happySpecReduce_1 nt fn j tk _ sts@((HappyCons (st@(action)) (_))) (v1`HappyStk`stk') + = let r = fn v1 in + happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk')) + +happySpecReduce_2 i fn 0# tk st sts stk + = happyFail 0# tk st sts stk +happySpecReduce_2 nt fn j tk _ (HappyCons (_) (sts@((HappyCons (st@(action)) (_))))) (v1`HappyStk`v2`HappyStk`stk') + = let r = fn v1 v2 in + happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk')) + +happySpecReduce_3 i fn 0# tk st sts stk + = happyFail 0# tk st sts stk +happySpecReduce_3 nt fn j tk _ (HappyCons (_) ((HappyCons (_) (sts@((HappyCons (st@(action)) (_))))))) (v1`HappyStk`v2`HappyStk`v3`HappyStk`stk') + = let r = fn v1 v2 v3 in + happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk')) + +happyReduce k i fn 0# tk st sts stk + = happyFail 0# tk st sts stk +happyReduce k nt fn j tk st sts stk + = case happyDrop (k Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) sts of + sts1@((HappyCons (st1@(action)) (_))) -> + let r = fn stk in -- it doesn't hurt to always seq here... + happyDoSeq r (happyGoto nt j tk st1 sts1 r) + +happyMonadReduce k nt fn 0# tk st sts stk + = happyFail 0# tk st sts stk +happyMonadReduce k nt fn j tk st sts stk = + case happyDrop k (HappyCons (st) (sts)) of + sts1@((HappyCons (st1@(action)) (_))) -> + let drop_stk = happyDropStk k stk in + happyThen1 (fn stk tk) (\r -> happyGoto nt j tk st1 sts1 (r `HappyStk` drop_stk)) + +happyMonad2Reduce k nt fn 0# tk st sts stk + = happyFail 0# tk st sts stk +happyMonad2Reduce k nt fn j tk st sts stk = + case happyDrop k (HappyCons (st) (sts)) of + sts1@((HappyCons (st1@(action)) (_))) -> + let drop_stk = happyDropStk k stk + + off = indexShortOffAddr happyGotoOffsets st1 + off_i = (off Happy_GHC_Exts.+# nt) + new_state = indexShortOffAddr happyTable off_i + + + + in + happyThen1 (fn stk tk) (\r -> happyNewToken new_state sts1 (r `HappyStk` drop_stk)) + +happyDrop 0# l = l +happyDrop n (HappyCons (_) (t)) = happyDrop (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) t + +happyDropStk 0# l = l +happyDropStk n (x `HappyStk` xs) = happyDropStk (n Happy_GHC_Exts.-# (1#::Happy_GHC_Exts.Int#)) xs + +----------------------------------------------------------------------------- +-- Moving to a new state after a reduction + + +happyGoto nt j tk st = + {- nothing -} + happyDoAction j tk new_state + where off = indexShortOffAddr happyGotoOffsets st + off_i = (off Happy_GHC_Exts.+# nt) + new_state = indexShortOffAddr happyTable off_i + + + + +----------------------------------------------------------------------------- +-- Error recovery (0# is the error token) + +-- parse error if we are in recovery and we fail again +happyFail 0# tk old_st _ stk@(x `HappyStk` _) = + let i = (case Happy_GHC_Exts.unsafeCoerce# x of { (Happy_GHC_Exts.I# (i)) -> i }) in +-- trace "failing" $ + happyError_ i tk + +{- We don't need state discarding for our restricted implementation of + "error". In fact, it can cause some bogus parses, so I've disabled it + for now --SDM + +-- discard a state +happyFail 0# tk old_st (HappyCons ((action)) (sts)) + (saved_tok `HappyStk` _ `HappyStk` stk) = +-- trace ("discarding state, depth " ++ show (length stk)) $ + happyDoAction 0# tk action sts ((saved_tok`HappyStk`stk)) +-} + +-- Enter error recovery: generate an error token, +-- save the old token and carry on. +happyFail i tk (action) sts stk = +-- trace "entering error recovery" $ + happyDoAction 0# tk action sts ( (Happy_GHC_Exts.unsafeCoerce# (Happy_GHC_Exts.I# (i))) `HappyStk` stk) + +-- Internal happy errors: + +notHappyAtAll :: a +notHappyAtAll = error "Internal Happy error\n" + +----------------------------------------------------------------------------- +-- Hack to get the typechecker to accept our action functions + + +happyTcHack :: Happy_GHC_Exts.Int# -> a -> a +happyTcHack x y = y +{-# INLINE happyTcHack #-} + + +----------------------------------------------------------------------------- +-- Seq-ing. If the --strict flag is given, then Happy emits +-- happySeq = happyDoSeq +-- otherwise it emits +-- happySeq = happyDontSeq + +happyDoSeq, happyDontSeq :: a -> b -> b +happyDoSeq a b = a `seq` b +happyDontSeq a b = b + +----------------------------------------------------------------------------- +-- Don't inline any functions from the template. GHC has a nasty habit +-- of deciding to inline happyGoto everywhere, which increases the size of +-- the generated parser quite a bit. + + +{-# NOINLINE happyDoAction #-} +{-# NOINLINE happyTable #-} +{-# NOINLINE happyCheck #-} +{-# NOINLINE happyActOffsets #-} +{-# NOINLINE happyGotoOffsets #-} +{-# NOINLINE happyDefActions #-} + +{-# NOINLINE happyShift #-} +{-# NOINLINE happySpecReduce_0 #-} +{-# NOINLINE happySpecReduce_1 #-} +{-# NOINLINE happySpecReduce_2 #-} +{-# NOINLINE happySpecReduce_3 #-} +{-# NOINLINE happyReduce #-} +{-# NOINLINE happyMonadReduce #-} +{-# NOINLINE happyGoto #-} +{-# NOINLINE happyFail #-} + +-- end of Happy Template.
− src/Language/Clafer/Front/ParClafer.y
@@ -1,317 +0,0 @@--- This Happy file was machine-generated by the BNF converter -{ -{-# OPTIONS_GHC -fno-warn-incomplete-patterns -fno-warn-overlapping-patterns #-} -module Language.Clafer.Front.ParClafer where -import Language.Clafer.Front.AbsClafer -import Language.Clafer.Front.LexClafer -import Language.Clafer.Front.ErrM - -} - -%name pModule Module -%name pClafer Clafer -%name pConstraint Constraint -%name pAssertion Assertion -%name pGoal Goal --- no lexer declaration -%monad { Err } { thenM } { returnM } -%tokentype {Token} -%token - '!' { PT _ (TS _ 1) } - '!=' { PT _ (TS _ 2) } - '#' { PT _ (TS _ 3) } - '%' { PT _ (TS _ 4) } - '&' { PT _ (TS _ 5) } - '&&' { PT _ (TS _ 6) } - '(' { PT _ (TS _ 7) } - ')' { PT _ (TS _ 8) } - '*' { PT _ (TS _ 9) } - '**' { PT _ (TS _ 10) } - '+' { PT _ (TS _ 11) } - '++' { PT _ (TS _ 12) } - ',' { PT _ (TS _ 13) } - '-' { PT _ (TS _ 14) } - '--' { PT _ (TS _ 15) } - '->' { PT _ (TS _ 16) } - '->>' { PT _ (TS _ 17) } - '.' { PT _ (TS _ 18) } - '..' { PT _ (TS _ 19) } - '/' { PT _ (TS _ 20) } - ':' { PT _ (TS _ 21) } - ':=' { PT _ (TS _ 22) } - ':>' { PT _ (TS _ 23) } - ';' { PT _ (TS _ 24) } - '<' { PT _ (TS _ 25) } - '<:' { PT _ (TS _ 26) } - '<<' { PT _ (TS _ 27) } - '<=' { PT _ (TS _ 28) } - '<=>' { PT _ (TS _ 29) } - '=' { PT _ (TS _ 30) } - '=>' { PT _ (TS _ 31) } - '>' { PT _ (TS _ 32) } - '>=' { PT _ (TS _ 33) } - '>>' { PT _ (TS _ 34) } - '?' { PT _ (TS _ 35) } - '[' { PT _ (TS _ 36) } - '\\' { PT _ (TS _ 37) } - ']' { PT _ (TS _ 38) } - '`' { PT _ (TS _ 39) } - 'abstract' { PT _ (TS _ 40) } - 'all' { PT _ (TS _ 41) } - 'assert' { PT _ (TS _ 42) } - 'disj' { PT _ (TS _ 43) } - 'else' { PT _ (TS _ 44) } - 'enum' { PT _ (TS _ 45) } - 'if' { PT _ (TS _ 46) } - 'in' { PT _ (TS _ 47) } - 'lone' { PT _ (TS _ 48) } - 'max' { PT _ (TS _ 49) } - 'maximize' { PT _ (TS _ 50) } - 'min' { PT _ (TS _ 51) } - 'minimize' { PT _ (TS _ 52) } - 'mux' { PT _ (TS _ 53) } - 'no' { PT _ (TS _ 54) } - 'not' { PT _ (TS _ 55) } - 'one' { PT _ (TS _ 56) } - 'opt' { PT _ (TS _ 57) } - 'or' { PT _ (TS _ 58) } - 'product' { PT _ (TS _ 59) } - 'some' { PT _ (TS _ 60) } - 'sum' { PT _ (TS _ 61) } - 'then' { PT _ (TS _ 62) } - 'xor' { PT _ (TS _ 63) } - '{' { PT _ (TS _ 64) } - '|' { PT _ (TS _ 65) } - '||' { PT _ (TS _ 66) } - '}' { PT _ (TS _ 67) } - -L_PosInteger { PT _ (T_PosInteger _) } -L_PosDouble { PT _ (T_PosDouble _) } -L_PosReal { PT _ (T_PosReal _) } -L_PosString { PT _ (T_PosString _) } -L_PosIdent { PT _ (T_PosIdent _) } -L_PosLineComment { PT _ (T_PosLineComment _) } -L_PosBlockComment { PT _ (T_PosBlockComment _) } -L_PosAlloy { PT _ (T_PosAlloy _) } -L_PosChoco { PT _ (T_PosChoco _) } - - -%% - -PosInteger :: { PosInteger} : L_PosInteger { PosInteger (mkPosToken $1)} -PosDouble :: { PosDouble} : L_PosDouble { PosDouble (mkPosToken $1)} -PosReal :: { PosReal} : L_PosReal { PosReal (mkPosToken $1)} -PosString :: { PosString} : L_PosString { PosString (mkPosToken $1)} -PosIdent :: { PosIdent} : L_PosIdent { PosIdent (mkPosToken $1)} -PosLineComment :: { PosLineComment} : L_PosLineComment { PosLineComment (mkPosToken $1)} -PosBlockComment :: { PosBlockComment} : L_PosBlockComment { PosBlockComment (mkPosToken $1)} -PosAlloy :: { PosAlloy} : L_PosAlloy { PosAlloy (mkPosToken $1)} -PosChoco :: { PosChoco} : L_PosChoco { PosChoco (mkPosToken $1)} - -Module :: { Module } -Module : ListDeclaration { Language.Clafer.Front.AbsClafer.Module ((mkCatSpan $1)) (reverse $1) } -Declaration :: { Declaration } -Declaration : 'enum' PosIdent '=' ListEnumId { Language.Clafer.Front.AbsClafer.EnumDecl ((mkTokenSpan $1) >- (mkCatSpan $2) >- (mkTokenSpan $3) >- (mkCatSpan $4)) $2 $4 } - | Element { Language.Clafer.Front.AbsClafer.ElementDecl ((mkCatSpan $1)) $1 } -Clafer :: { Clafer } -Clafer : Abstract GCard PosIdent Super Reference Card Init Elements { Language.Clafer.Front.AbsClafer.Clafer ((mkCatSpan $1) >- (mkCatSpan $2) >- (mkCatSpan $3) >- (mkCatSpan $4) >- (mkCatSpan $5) >- (mkCatSpan $6) >- (mkCatSpan $7) >- (mkCatSpan $8)) $1 $2 $3 $4 $5 $6 $7 $8 } -Constraint :: { Constraint } -Constraint : '[' ListExp ']' { Language.Clafer.Front.AbsClafer.Constraint ((mkTokenSpan $1) >- (mkCatSpan $2) >- (mkTokenSpan $3)) (reverse $2) } -Assertion :: { Assertion } -Assertion : 'assert' '[' ListExp ']' { Language.Clafer.Front.AbsClafer.Assertion ((mkTokenSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3) >- (mkTokenSpan $4)) (reverse $3) } -Goal :: { Goal } -Goal : '<<' 'min' ListExp '>>' { Language.Clafer.Front.AbsClafer.GoalMinDeprecated ((mkTokenSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3) >- (mkTokenSpan $4)) (reverse $3) } - | '<<' 'max' ListExp '>>' { Language.Clafer.Front.AbsClafer.GoalMaxDeprecated ((mkTokenSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3) >- (mkTokenSpan $4)) (reverse $3) } - | '<<' 'minimize' ListExp '>>' { Language.Clafer.Front.AbsClafer.GoalMinimize ((mkTokenSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3) >- (mkTokenSpan $4)) (reverse $3) } - | '<<' 'maximize' ListExp '>>' { Language.Clafer.Front.AbsClafer.GoalMaximize ((mkTokenSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3) >- (mkTokenSpan $4)) (reverse $3) } -Abstract :: { Abstract } -Abstract : {- empty -} { Language.Clafer.Front.AbsClafer.AbstractEmpty noSpan } - | 'abstract' { Language.Clafer.Front.AbsClafer.Abstract ((mkTokenSpan $1)) } -Elements :: { Elements } -Elements : {- empty -} { Language.Clafer.Front.AbsClafer.ElementsEmpty noSpan } - | '{' ListElement '}' { Language.Clafer.Front.AbsClafer.ElementsList ((mkTokenSpan $1) >- (mkCatSpan $2) >- (mkTokenSpan $3)) (reverse $2) } -Element :: { Element } -Element : Clafer { Language.Clafer.Front.AbsClafer.Subclafer ((mkCatSpan $1)) $1 } - | '`' Name Card Elements { Language.Clafer.Front.AbsClafer.ClaferUse ((mkTokenSpan $1) >- (mkCatSpan $2) >- (mkCatSpan $3) >- (mkCatSpan $4)) $2 $3 $4 } - | Constraint { Language.Clafer.Front.AbsClafer.Subconstraint ((mkCatSpan $1)) $1 } - | Goal { Language.Clafer.Front.AbsClafer.Subgoal ((mkCatSpan $1)) $1 } - | Assertion { Language.Clafer.Front.AbsClafer.SubAssertion ((mkCatSpan $1)) $1 } -Super :: { Super } -Super : {- empty -} { Language.Clafer.Front.AbsClafer.SuperEmpty noSpan } - | ':' Exp18 { Language.Clafer.Front.AbsClafer.SuperSome ((mkTokenSpan $1) >- (mkCatSpan $2)) $2 } -Reference :: { Reference } -Reference : {- empty -} { Language.Clafer.Front.AbsClafer.ReferenceEmpty noSpan } - | '->' Exp15 { Language.Clafer.Front.AbsClafer.ReferenceSet ((mkTokenSpan $1) >- (mkCatSpan $2)) $2 } - | '->>' Exp15 { Language.Clafer.Front.AbsClafer.ReferenceBag ((mkTokenSpan $1) >- (mkCatSpan $2)) $2 } -Init :: { Init } -Init : {- empty -} { Language.Clafer.Front.AbsClafer.InitEmpty noSpan } - | InitHow Exp { Language.Clafer.Front.AbsClafer.InitSome ((mkCatSpan $1) >- (mkCatSpan $2)) $1 $2 } -InitHow :: { InitHow } -InitHow : '=' { Language.Clafer.Front.AbsClafer.InitConstant ((mkTokenSpan $1)) } - | ':=' { Language.Clafer.Front.AbsClafer.InitDefault ((mkTokenSpan $1)) } -GCard :: { GCard } -GCard : {- empty -} { Language.Clafer.Front.AbsClafer.GCardEmpty noSpan } - | 'xor' { Language.Clafer.Front.AbsClafer.GCardXor ((mkTokenSpan $1)) } - | 'or' { Language.Clafer.Front.AbsClafer.GCardOr ((mkTokenSpan $1)) } - | 'mux' { Language.Clafer.Front.AbsClafer.GCardMux ((mkTokenSpan $1)) } - | 'opt' { Language.Clafer.Front.AbsClafer.GCardOpt ((mkTokenSpan $1)) } - | NCard { Language.Clafer.Front.AbsClafer.GCardInterval ((mkCatSpan $1)) $1 } -Card :: { Card } -Card : {- empty -} { Language.Clafer.Front.AbsClafer.CardEmpty noSpan } - | '?' { Language.Clafer.Front.AbsClafer.CardLone ((mkTokenSpan $1)) } - | '+' { Language.Clafer.Front.AbsClafer.CardSome ((mkTokenSpan $1)) } - | '*' { Language.Clafer.Front.AbsClafer.CardAny ((mkTokenSpan $1)) } - | PosInteger { Language.Clafer.Front.AbsClafer.CardNum ((mkCatSpan $1)) $1 } - | NCard { Language.Clafer.Front.AbsClafer.CardInterval ((mkCatSpan $1)) $1 } -NCard :: { NCard } -NCard : PosInteger '..' ExInteger { Language.Clafer.Front.AbsClafer.NCard ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } -ExInteger :: { ExInteger } -ExInteger : '*' { Language.Clafer.Front.AbsClafer.ExIntegerAst ((mkTokenSpan $1)) } - | PosInteger { Language.Clafer.Front.AbsClafer.ExIntegerNum ((mkCatSpan $1)) $1 } -Name :: { Name } -Name : ListModId { Language.Clafer.Front.AbsClafer.Path ((mkCatSpan $1)) $1 } -Exp :: { Exp } -Exp : 'all' 'disj' Decl '|' Exp { Language.Clafer.Front.AbsClafer.EDeclAllDisj ((mkTokenSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3) >- (mkTokenSpan $4) >- (mkCatSpan $5)) $3 $5 } - | 'all' Decl '|' Exp { Language.Clafer.Front.AbsClafer.EDeclAll ((mkTokenSpan $1) >- (mkCatSpan $2) >- (mkTokenSpan $3) >- (mkCatSpan $4)) $2 $4 } - | Quant 'disj' Decl '|' Exp { Language.Clafer.Front.AbsClafer.EDeclQuantDisj ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3) >- (mkTokenSpan $4) >- (mkCatSpan $5)) $1 $3 $5 } - | Quant Decl '|' Exp { Language.Clafer.Front.AbsClafer.EDeclQuant ((mkCatSpan $1) >- (mkCatSpan $2) >- (mkTokenSpan $3) >- (mkCatSpan $4)) $1 $2 $4 } - | 'if' Exp 'then' Exp 'else' Exp { Language.Clafer.Front.AbsClafer.EImpliesElse ((mkTokenSpan $1) >- (mkCatSpan $2) >- (mkTokenSpan $3) >- (mkCatSpan $4) >- (mkTokenSpan $5) >- (mkCatSpan $6)) $2 $4 $6 } - | Exp '<=>' Exp1 { Language.Clafer.Front.AbsClafer.EIff ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp1 { $1 } -Exp2 :: { Exp } -Exp2 : Exp2 '=>' Exp3 { Language.Clafer.Front.AbsClafer.EImplies ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp3 { $1 } -Exp3 :: { Exp } -Exp3 : Exp3 '||' Exp4 { Language.Clafer.Front.AbsClafer.EOr ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp4 { $1 } -Exp4 :: { Exp } -Exp4 : Exp4 'xor' Exp5 { Language.Clafer.Front.AbsClafer.EXor ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp5 { $1 } -Exp5 :: { Exp } -Exp5 : Exp5 '&&' Exp6 { Language.Clafer.Front.AbsClafer.EAnd ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp6 { $1 } -Exp6 :: { Exp } -Exp6 : '!' Exp7 { Language.Clafer.Front.AbsClafer.ENeg ((mkTokenSpan $1) >- (mkCatSpan $2)) $2 } - | Exp7 { $1 } -Exp7 :: { Exp } -Exp7 : Exp7 '<' Exp8 { Language.Clafer.Front.AbsClafer.ELt ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp7 '>' Exp8 { Language.Clafer.Front.AbsClafer.EGt ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp7 '=' Exp8 { Language.Clafer.Front.AbsClafer.EEq ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp7 '<=' Exp8 { Language.Clafer.Front.AbsClafer.ELte ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp7 '>=' Exp8 { Language.Clafer.Front.AbsClafer.EGte ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp7 '!=' Exp8 { Language.Clafer.Front.AbsClafer.ENeq ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp7 'in' Exp8 { Language.Clafer.Front.AbsClafer.EIn ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp7 'not' 'in' Exp8 { Language.Clafer.Front.AbsClafer.ENin ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkTokenSpan $3) >- (mkCatSpan $4)) $1 $4 } - | Exp8 { $1 } -Exp8 :: { Exp } -Exp8 : Quant Exp12 { Language.Clafer.Front.AbsClafer.EQuantExp ((mkCatSpan $1) >- (mkCatSpan $2)) $1 $2 } - | Exp9 { $1 } -Exp9 :: { Exp } -Exp9 : Exp9 '+' Exp10 { Language.Clafer.Front.AbsClafer.EAdd ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp9 '-' Exp10 { Language.Clafer.Front.AbsClafer.ESub ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp10 { $1 } -Exp10 :: { Exp } -Exp10 : Exp10 '*' Exp11 { Language.Clafer.Front.AbsClafer.EMul ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp10 '/' Exp11 { Language.Clafer.Front.AbsClafer.EDiv ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp10 '%' Exp11 { Language.Clafer.Front.AbsClafer.ERem ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp11 { $1 } -Exp11 :: { Exp } -Exp11 : 'max' Exp12 { Language.Clafer.Front.AbsClafer.EGMax ((mkTokenSpan $1) >- (mkCatSpan $2)) $2 } - | 'min' Exp12 { Language.Clafer.Front.AbsClafer.EGMin ((mkTokenSpan $1) >- (mkCatSpan $2)) $2 } - | Exp12 { $1 } -Exp12 :: { Exp } -Exp12 : 'sum' Exp13 { Language.Clafer.Front.AbsClafer.ESum ((mkTokenSpan $1) >- (mkCatSpan $2)) $2 } - | 'product' Exp13 { Language.Clafer.Front.AbsClafer.EProd ((mkTokenSpan $1) >- (mkCatSpan $2)) $2 } - | '#' Exp13 { Language.Clafer.Front.AbsClafer.ECard ((mkTokenSpan $1) >- (mkCatSpan $2)) $2 } - | '-' Exp13 { Language.Clafer.Front.AbsClafer.EMinExp ((mkTokenSpan $1) >- (mkCatSpan $2)) $2 } - | Exp13 { $1 } -Exp13 :: { Exp } -Exp13 : Exp13 '<:' Exp14 { Language.Clafer.Front.AbsClafer.EDomain ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp14 { $1 } -Exp14 :: { Exp } -Exp14 : Exp14 ':>' Exp15 { Language.Clafer.Front.AbsClafer.ERange ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp15 { $1 } -Exp15 :: { Exp } -Exp15 : Exp15 '++' Exp16 { Language.Clafer.Front.AbsClafer.EUnion ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp15 ',' Exp16 { Language.Clafer.Front.AbsClafer.EUnionCom ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp16 { $1 } -Exp16 :: { Exp } -Exp16 : Exp16 '--' Exp17 { Language.Clafer.Front.AbsClafer.EDifference ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp17 { $1 } -Exp17 :: { Exp } -Exp17 : Exp17 '**' Exp18 { Language.Clafer.Front.AbsClafer.EIntersection ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp17 '&' Exp18 { Language.Clafer.Front.AbsClafer.EIntersectionDeprecated ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp18 { $1 } -Exp18 :: { Exp } -Exp18 : Exp18 '.' Exp19 { Language.Clafer.Front.AbsClafer.EJoin ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } - | Exp19 { $1 } -Exp19 :: { Exp } -Exp19 : Name { Language.Clafer.Front.AbsClafer.ClaferId ((mkCatSpan $1)) $1 } - | PosInteger { Language.Clafer.Front.AbsClafer.EInt ((mkCatSpan $1)) $1 } - | PosDouble { Language.Clafer.Front.AbsClafer.EDouble ((mkCatSpan $1)) $1 } - | PosReal { Language.Clafer.Front.AbsClafer.EReal ((mkCatSpan $1)) $1 } - | PosString { Language.Clafer.Front.AbsClafer.EStr ((mkCatSpan $1)) $1 } - | '(' Exp ')' { $2 } -Decl :: { Decl } -Decl : ListLocId ':' Exp15 { Language.Clafer.Front.AbsClafer.Decl ((mkCatSpan $1) >- (mkTokenSpan $2) >- (mkCatSpan $3)) $1 $3 } -Quant :: { Quant } -Quant : 'no' { Language.Clafer.Front.AbsClafer.QuantNo ((mkTokenSpan $1)) } - | 'not' { Language.Clafer.Front.AbsClafer.QuantNot ((mkTokenSpan $1)) } - | 'lone' { Language.Clafer.Front.AbsClafer.QuantLone ((mkTokenSpan $1)) } - | 'one' { Language.Clafer.Front.AbsClafer.QuantOne ((mkTokenSpan $1)) } - | 'some' { Language.Clafer.Front.AbsClafer.QuantSome ((mkTokenSpan $1)) } -EnumId :: { EnumId } -EnumId : PosIdent { Language.Clafer.Front.AbsClafer.EnumIdIdent ((mkCatSpan $1)) $1 } -ModId :: { ModId } -ModId : PosIdent { Language.Clafer.Front.AbsClafer.ModIdIdent ((mkCatSpan $1)) $1 } -LocId :: { LocId } -LocId : PosIdent { Language.Clafer.Front.AbsClafer.LocIdIdent ((mkCatSpan $1)) $1 } -ListDeclaration :: { [Declaration] } -ListDeclaration : {- empty -} { [] } - | ListDeclaration Declaration { flip (:) $1 $2 } -ListEnumId :: { [EnumId] } -ListEnumId : EnumId { (:[]) $1 } - | EnumId '|' ListEnumId { (:) $1 $3 } -ListElement :: { [Element] } -ListElement : {- empty -} { [] } - | ListElement Element { flip (:) $1 $2 } -ListExp :: { [Exp] } -ListExp : {- empty -} { [] } | ListExp Exp { flip (:) $1 $2 } -ListLocId :: { [LocId] } -ListLocId : LocId { (:[]) $1 } - | LocId ';' ListLocId { (:) $1 $3 } -ListModId :: { [ModId] } -ListModId : ModId { (:[]) $1 } - | ModId '\\' ListModId { (:) $1 $3 } -Exp1 :: { Exp } -Exp1 : Exp2 { $1 } -{ - -returnM :: a -> Err a -returnM = return - -thenM :: Err a -> (a -> Err b) -> Err b -thenM = (>>=) - -happyError :: [Token] -> Err a -happyError ts = - Bad (pp ts) $ "syntax error at " ++ tokenPos ts ++ - case ts of - [] -> [] - [Err _] -> " due to lexer error" - _ -> " before " ++ unwords (map (id . prToken) (take 4 ts)) - -myLexer = tokens - -gp x@(PT (Pn _ l c) _) = Span (Pos (toInteger l) (toInteger c)) (Pos (toInteger l) (toInteger c + toInteger (length $ prToken x))) -pp (PT (Pn _ l c) _ :_) = Pos (toInteger l) (toInteger c) -pp (Err (Pn _ l c) :_) = Pos (toInteger l) (toInteger c) -pp _ = error "EOF" - -mkCatSpan :: (Spannable c) => c -> Span -mkCatSpan = getSpan - -mkTokenSpan :: Token -> Span -mkTokenSpan = gp -} -
src/Language/Clafer/Generator/Alloy.hs view
@@ -1,659 +1,661 @@-{-# LANGUAGE RankNTypes, FlexibleContexts #-} -{- - Copyright (C) 2012-2015 Kacper Bak, Jimmy Liang, Michal Antkiewicz, Rafael Olaechea <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} --- | Generates Alloy4.2 code for a Clafer model -module Language.Clafer.Generator.Alloy (genModule) where - -import Control.Applicative -import Control.Monad.State -import Data.List -import Data.Maybe -import Prelude - -import Language.Clafer.Common -import Language.Clafer.ClaferArgs -import Language.Clafer.Front.AbsClafer -import Language.Clafer.Front.LexClafer -import Language.Clafer.Generator.Concat -import Language.Clafer.Intermediate.Intclafer hiding (exp) - - -data GenEnv = GenEnv - { claferargs :: ClaferArgs - , uidIClaferMap :: UIDIClaferMap - , forScopes :: String - } deriving (Show) - - --- | Alloy code generation -genModule :: ClaferArgs -> (IModule, GEnv) -> [(UID, Integer)] -> [Token] -> (Result, [(Span, IrTrace)]) -genModule claferargs' (imodule, genv) scopes otherTokens' = (flatten output, filter ((/= NoTrace) . snd) $ mapLineCol output) - where - - genScopes :: [(UID, Integer)] -> String - genScopes [] = "" - genScopes scopes' = " but " ++ intercalate ", " (map (\ (uid', scope) -> show scope ++ " " ++ uid') scopes') - - forScopes' = "for 1" ++ genScopes scopes - genEnv = GenEnv claferargs' (uidClaferMap genv) forScopes' - output = header genEnv otherTokens' +++ (cconcat $ map (genDeclaration genEnv) (_mDecls imodule)) - -header :: GenEnv -> [Token] -> Concat -header genEnv otherTokens' = CString $ unlines - [ "open util/integer" - , genAlloyEscapes otherTokens' ++ "pred show {}" - , if (validate $ claferargs genEnv) - then "" - else "run show " ++ forScopes genEnv - , ""] - -genAlloyEscapes :: [Token] -> String -genAlloyEscapes otherTokens' = concat $ map printAlloyEscape otherTokens' - where - printAlloyEscape (PT _ (T_PosAlloy code)) = let - code' = fromJust $ stripPrefix "[alloy|" code - in - (take ((length code') - 2) code') ++ "\n" - - printAlloyEscape _ = "" - --- 07th Mayo 2012 Rafael Olaechea -genDeclaration :: GenEnv -> IElement -> Concat -genDeclaration genEnv x = case x of - IEClafer clafer' -> (genClafer genEnv [] clafer') +++ (mkFact $ cconcat $ genSetUniquenessConstraint clafer') - IEConstraint True pexp -> mkFact $ genPExp genEnv [] pexp - IEConstraint False pexp -> mkAssert genEnv (genAssertName pexp) $ genPExp genEnv [] pexp - IEGoal _ _ -> CString "" - -mkFact :: Concat -> Concat -mkFact x@(CString "") = x -mkFact xs = cconcat [CString "fact ", mkSet xs, CString "\n"] - -genAssertName :: PExp -> Concat -genAssertName PExp{_inPos=(Span _ (Pos line _))} = CString $ "assertOnLine_" ++ show line - -mkAssert :: GenEnv -> Concat -> Concat -> Concat -mkAssert _ _ x@(CString "") = x -mkAssert genEnv name xs = cconcat - [ CString "assert ", name, CString " " - , mkSet xs - , CString "\n" - , CString "check ", name, CString " " - , CString $ forScopes genEnv - , CString "\n\n" - ] - -mkSet :: Concat -> Concat -mkSet xs = cconcat [CString "{ ", xs, CString " }"] - -showSet :: Concat -> [Concat] -> Concat -showSet delim xs = showSet' delim $ filterNull xs - where - showSet' _ [] = CString "{}" - showSet' delim' xs' = mkSet $ cintercalate delim' xs' - -optShowSet :: [Concat] -> Concat -optShowSet [] = CString "" -optShowSet xs = CString "\n" +++ showSet (CString "\n ") xs - --- optimization: top level cardinalities --- optimization: if only boolean parents, then set card is known -genClafer :: GenEnv -> [String] -> IClafer -> Concat -genClafer genEnv resPath clafer' - = (cunlines $ filterNull - [ cardFact - +++ claferDecl clafer' ( - (showSet (CString "\n, ") $ genRelations genEnv clafer') - +++ (optShowSet $ filterNull $ genConstraints genEnv resPath clafer') - ) - ] - ) - +++ CString "\n" - +++ children' - where - children' = cconcat $ filterNull $ map - (genClafer genEnv ((_uid clafer') : resPath)) $ - getSubclafers $ _elements clafer' - cardFact - | null resPath && (null $ flatten $ genOptCard clafer') = - case genCard (_uid clafer') $ _card clafer' of - CString "set" -> CString "" - c -> mkFact c - | otherwise = CString "" - -claferDecl :: IClafer -> Concat -> Concat -claferDecl c rest = cconcat - [ genOptCard c - , CString $ if _isAbstract c then "abstract " else "" - , CString "sig " - , Concat NoTrace [CString $ _uid c, genExtends $ _super c, CString "\n", rest] - ] - where - genExtends Nothing = CString "" - genExtends (Just (PExp _ _ _ (IClaferId _ i _ _))) = CString " " +++ Concat NoTrace [CString $ "extends " ++ i] - -- todo: handle multiple inheritance - genExtends _ = CString "" - -genOptCard :: IClafer -> Concat -genOptCard c - | glCard' `elem` ["lone", "one", "some"] = cardConcat (_uid c) False [CString glCard'] +++ (CString " ") - | otherwise = CString "" - where - glCard' = genIntervalCrude $ _glCard c - - --- ----------------------------------------------------------------------------- --- overlapping inheritance is a new clafer with val (unlike only relation) --- relations: overlapping inheritance (val rel), children --- adds parent relation --- 29/March/2012 Rafael Olaechea: ref is now prepended with clafer name to be able to refer to it from partial instances. -genRelations :: GenEnv -> IClafer -> [Concat] -genRelations genEnv c = maybeToList r ++ (map mkRel $ getSubclafers $ _elements c) - where - r = if isJust $ _reference c - then - Just $ Concat NoTrace [CString $ genRel (genRefName $ _uid c) - c {_card = Just (1, 1)} $ - flatten $ refType genEnv c] - else - Nothing - mkRel c' = Concat NoTrace [CString $ genRel (genRelName $ _uid c') c' $ _uid c'] - -genRelName :: String -> String -genRelName name = "r_" ++ name - -genRefName :: String -> String -genRefName name = name ++ "_ref" - -genRel :: String -> IClafer -> String -> String -genRel name c rType = genAlloyRel name (genCardCrude $ _card c) rType' - where - rType' = if isPrimitive rType then "Int" else rType - -genAlloyRel :: String -> String -> String -> String -genAlloyRel name card' rType = concat [name, " : ", card', " ", rType] - -refType :: GenEnv -> IClafer -> Concat -refType genEnv c = fromMaybe (CString "") (((genType genEnv).getTarget) <$> (_ref <$> _reference c)) - - -getTarget :: PExp -> PExp -getTarget x = case x of - PExp _ _ _ (IFunExp op' (_:pexp:_)) -> if op' == iJoin then pexp else x - _ -> x - -genType :: GenEnv -> PExp -> Concat -genType genEnv x@(PExp _ _ _ y@(IClaferId _ _ _ _)) = genPExp genEnv [] - x{_exp = y{_isTop = True}} -genType m x = genPExp m [] x - - --- ----------------------------------------------------------------------------- --- constraints --- parent + group constraints + reference + user constraints --- a = NUMBER do all x : a | x = NUMBER (otherwise alloy sums a set) -genConstraints :: GenEnv -> [String] -> IClafer -> [Concat] -genConstraints genEnv resPath c - = (genParentConst resPath c) - : (genGroupConst genEnv c) - : (genRefSubrelationConstriant (uidIClaferMap genEnv) c) -{- genPathConst produces incorrect code for top-level clafers - -abstract System - abstract Connection - connections -> Connection * - -sig c0_connections -{ ref : one c0_Connection } -{ one @r_c0_connections.this - ref = (@r_c0_System.@r_c0_Connection) } - -r_c0_System does not exist because System is top-level. The constraint is useless anyway, since all instances -of Connection are nested under all Systems anyway. - disabled code: - : genPathConst genEnv (if (noalloyruncommand $ claferargs genEnv) then (_uid c ++ "_ref") else "ref") resPath c --} - : constraints - where - constraints = concatMap genConst $ _elements c - genConst x = case x of - IEConstraint True pexp -> [ genPExp genEnv (_uid c : resPath) pexp ] - IEConstraint False pexp -> [ CString "// Assertion " +++ (genAssertName pexp) +++ CString " ignored since nested assertions are not supported in Alloy.\n"] - IEClafer c' -> - (if genCardCrude (_card c') `elem` ["one", "lone", "some"] - then CString "" - else mkCard ({- do not use the genRelName as the constraint name -} _uid c') False (genRelName $ _uid c') $ fromJust (_card c') - ) - : (genParentSubrelationConstriant (uidIClaferMap genEnv) c') - : (genSetUniquenessConstraint c') - IEGoal _ _ -> error "[bug] Alloy.getConst: should not be given a goal." -- This should never happen - - -genSetUniquenessConstraint :: IClafer -> [Concat] -genSetUniquenessConstraint c = - (case _reference c of - Just (IReference True _) -> - (case _card c of - Just (lb, ub) -> if (lb > 1 || ub > 1 || ub == -1) - then [ CString $ ( - (case isTopLevel c of - False -> "all disj x, y : this.@" ++ (genRelName $ _uid c) - True -> " all disj x, y : " ++ (_uid c))) - ++ " | (x.@" ++ genRefName (_uid c) ++ ") != (y.@" ++ genRefName (_uid c) ++ ") " - ] - else [] - _ -> []) - _ -> [] - ) - -genParentSubrelationConstriant :: UIDIClaferMap -> IClafer -> Concat -genParentSubrelationConstriant uidIClaferMap' headClafer = - case match of - Nothing -> CString "" - Just NestedInheritanceMatch { - _superClafer = superClafer - } -> if (isProperNesting uidIClaferMap' match) && (not $ isTopLevel superClafer) - then CString $ concat - [ genRelName $ _uid headClafer - , " in " - , genRelName $ _uid superClafer - ] - else CString "" - where - match = matchNestedInheritance uidIClaferMap' headClafer - --- See Common.NestedInheritanceMatch -genRefSubrelationConstriant :: UIDIClaferMap -> IClafer -> Concat -genRefSubrelationConstriant uidIClaferMap' headClafer = - if isJust $ _reference headClafer - then - case match of - Nothing -> CString "" - Just NestedInheritanceMatch - { _superClafer = superClafer - , _superClafersTarget = superClafersTarget - } -> case (isProperRefinement uidIClaferMap' match, not $ null superClafersTarget) of - ((True, True, True), True) -> CString $ concat - [ genRefName $ _uid headClafer - , " in " - , genRefName $ _uid superClafer - ] - _ -> CString "" - else CString "" - where - match = matchNestedInheritance uidIClaferMap' headClafer - - --- optimization: if only boolean features then the parent is unique -genParentConst :: [String] -> IClafer -> Concat -genParentConst [] _ = CString "" -genParentConst _ c = genOptParentConst c - -genOptParentConst :: IClafer -> Concat -genOptParentConst c - | glCard' == "one" = CString "" - | glCard' == "lone" = Concat NoTrace [CString $ "one " ++ rel] - | otherwise = Concat NoTrace [CString $ "one @" ++ rel ++ ".this"] - -- eliminating problems with cyclic containment; - -- should be added to cases when cyclic containment occurs - -- , " && no iden & @", rel, " && no ~@", rel, " & @", rel] - where - rel = genRelName $ _uid c - glCard' = genIntervalCrude $ _glCard c - -genGroupConst :: GenEnv -> IClafer -> Concat -genGroupConst genEnv clafer' - | _isAbstract clafer' || null children' || flatten card' == "" = CString "" - | otherwise = cconcat [CString "let children = ", brArg id $ CString children', CString" | ", card'] - where - superHierarchy :: [IClafer] - superHierarchy = findHierarchy getSuper (uidIClaferMap genEnv) clafer' - children' = intercalate " + " $ map (genRelName._uid) $ - getSubclafers $ concatMap _elements superHierarchy - card' = mkCard (_uid clafer') True "children" $ _interval $ fromJust $ _gcard $ clafer' - -mkCard :: String -> Bool -> String -> (Integer, Integer) -> Concat -mkCard constraintName group' element' crd - | crd' == "set" || crd' == "" = CString "" - | crd' `elem` ["one", "lone", "some"] = CString $ crd' ++ " " ++ element' - | otherwise = interval' - where - interval' = genInterval constraintName group' element' crd - crd' = flatten $ interval' - -{- --- generates expression for references that point to expressions (not single clafers) -genPathConst :: GenEnv -> String -> [String] -> IClafer -> Concat -genPathConst genEnv name resPath c - | isRefPath (c ^. reference) = cconcat [CString name, CString " = ", - fromMaybe (error "genPathConst: impossible.") $ - fmap ((brArg id).(genPExp genEnv resPath)) $ - _ref <$> _reference c] - | otherwise = CString "" - -isRefPath :: Maybe IReference -> Bool -isRefPath Nothing = False -isRefPath (Just IReference{_ref=s}) = not $ isSimplePath s - -isSimplePath :: PExp -> Bool -isSimplePath (PExp _ _ _ (IClaferId _ _ _ _)) = True -isSimplePath (PExp _ _ _ (IFunExp op' _)) = op' == iUnion -isSimplePath _ = False --} --- ----------------------------------------------------------------------------- --- Not used? --- genGCard element gcard = genInterval element $ interval $ fromJust gcard - - -genCard :: String -> Maybe Interval -> Concat -genCard element' crd = genInterval element' False element' $ fromJust crd - -genCardCrude :: Maybe Interval -> String -genCardCrude crd = genIntervalCrude $ fromJust crd - -genIntervalCrude :: Interval -> String -genIntervalCrude x = case x of - (1, 1) -> "one" - (0, 1) -> "lone" - (1, -1) -> "some" - _ -> "set" - - -genInterval :: String -> Bool -> String -> Interval -> Concat -genInterval constraintName group' element' x = case x of - (1, 1) -> cardConcat constraintName group' [CString "one"] - (0, 1) -> cardConcat constraintName group' [CString "lone"] - (1, -1) -> cardConcat constraintName group' [CString "some"] - (0, -1) -> CString "set" -- "set" - (n, exinteger) -> - case (s1, s2) of - (Just c1, Just c2) -> cconcat [c1, CString " and ", c2] - (Just c1, Nothing) -> c1 - (Nothing, Just c2) -> c2 - (Nothing, Nothing) -> undefined - where - s1 = if n == 0 - then Nothing - else Just $ cardLowerConcat constraintName group' [CString $ concat [show n, " <= #", element']] - s2 = - do - result <- genExInteger element' x exinteger - return $ cardUpperConcat constraintName group' [CString result] - - -cardConcat :: String -> Bool -> [Concat] -> Concat -cardConcat constraintName = Concat . ExactCard constraintName - - -cardLowerConcat :: String -> Bool -> [Concat] -> Concat -cardLowerConcat constraintName = Concat . LowerCard constraintName - - -cardUpperConcat :: String -> Bool -> [Concat] -> Concat -cardUpperConcat constraintName = Concat . UpperCard constraintName - - -genExInteger :: String -> Interval -> Integer -> Maybe Result -genExInteger element' (y,z) x = - if (y==0 && z==0) then Just $ concat ["#", element', " = ", "0"] else - if x == -1 then Nothing else Just $ concat ["#", element', " <= ", show x] - - --- ----------------------------------------------------------------------------- --- Generate code for logical expressions - -genPExp :: GenEnv -> [String] -> PExp -> Concat -genPExp genEnv resPath x = genPExp' genEnv resPath $ adjustPExp resPath x - -genPExp' :: GenEnv -> [String] -> PExp -> Concat -genPExp' genEnv resPath (PExp iType' pid' pos exp') = case exp' of - IDeclPExp q d pexp -> Concat (IrPExp pid') $ - [ CString $ genQuant q, CString " " - , cintercalate (CString ", ") $ map (genDecl genEnv resPath) d - , CString $ optBar d, genPExp' genEnv resPath pexp] - where - optBar [] = "" - optBar _ = " | " - IClaferId _ "integer" _ _ -> CString "Int" - IClaferId _ "int" _ _ -> CString "Int" - IClaferId _ "string" _ _ -> CString "Int" - IClaferId _ "dref" _ _ -> CString $ "@" ++ getTClaferUID iType' ++ "_ref" - where - getTClaferUID (Just TMap{_so = TClafer{_hi = [u]}}) = u - getTClaferUID (Just TMap{_so = TClafer{_hi = (u:_)}}) = u - getTClaferUID t = error $ "[bug] Alloy.genPExp'.getTClaferUID: unknown type: " ++ show t - IClaferId _ sid istop _ -> CString $ - if head sid == '~' - then sid - else case iType' of - Just TInteger -> vsident - Just TDouble -> vsident - Just TReal -> vsident - Just TString -> vsident - _ -> sid' - where - sid' = (if istop then "" else '@' : genRelName "") ++ sid - vsident = sid' ++ ".@" ++ genRefName (if sid == "this" then head resPath else sid) - IFunExp _ _ -> case exp'' of - IFunExp _ _ -> genIFunExp pid' genEnv resPath exp'' - _ -> genPExp' genEnv resPath $ PExp iType' pid' pos exp'' - where - exp'' = transformExp exp' - IInt n -> CString $ show n - IDouble _ -> error "no double numbers allowed" - IReal _ -> error "no real numbers allowed" - IStr _ -> error "no strings allowed" - - - --- 3-May-2012 Rafael Olaechea. --- Removed transfromation from x = -2 to x = (0-2) as this creates problem with partial instances. --- See http://gsd.uwaterloo.ca:8888/question/461/new-translation-of-negative-number-x-into-0-x-is. -transformExp :: IExp -> IExp -transformExp (IFunExp op' (e1:_)) - | op' == iMin = IFunExp iMul [PExp (_iType e1) "" noSpan $ IInt (-1), e1] -transformExp x@(IFunExp op' exps'@(e1:e2:_)) - | op' == iXor = IFunExp iNot [PExp (Just TBoolean) "" noSpan (IFunExp iIff exps')] - | op' == iJoin && isClaferName' e1 && isClaferName' e2 && - getClaferName e1 == thisIdent && head (getClaferName e2) == '~' = - IFunExp op' [e1{_iType = Just $ TClafer []}, e2] - | otherwise = x -transformExp x = x - -genIFunExp :: String -> GenEnv -> [String] -> IExp -> Concat -genIFunExp pid' genEnv resPath (IFunExp "min" [exp']) = Concat (IrPExp pid') $ (CString "min[") : (genPExp' genEnv resPath exp') : [CString "]"] -genIFunExp pid' genEnv resPath (IFunExp "max" [exp']) = Concat (IrPExp pid') $ (CString "max[") : (genPExp' genEnv resPath exp') : [CString "]"] -genIFunExp pid' genEnv resPath (IFunExp op' exps') - | op' == iSumSet = genIFunExp pid' genEnv resPath (IFunExp iSumSet' [(removeright (head exps')), (getRight $ head exps')]) - | op' == iSumSet' = Concat (IrPExp pid') $ intl exps'' (map CString $ genOp iSumSet) - | otherwise = Concat (IrPExp pid') $ intl exps'' (map CString $ genOp op') - where - iSumSet' = "sum'" - intl - | op' == iSumSet' = flip interleave - | op' `elem` arithBinOps && length exps' == 2 = interleave - | otherwise = \xs ys -> reverse $ interleave (reverse xs) (reverse ys) - exps'' = map (optBrArg genEnv resPath) exps' -genIFunExp _ _ _ x = error $ "[bug] Alloy.genIFunExp: expecting a IFunExp, instead got: " ++ show x--This should never happen - - -optBrArg :: GenEnv -> [String] -> PExp -> Concat -optBrArg genEnv resPath x = brFun (genPExp' genEnv resPath) x - where - brFun = case x of - PExp _ _ _ IClaferId{} -> ($) - PExp _ _ _ (IInt _) -> ($) - _ -> brArg - -interleave :: [Concat] -> [Concat] -> [Concat] -interleave [] [] = [] -interleave (x:xs) [] = x:xs -interleave [] (x:xs) = x:xs -interleave (x:xs) ys = x : interleave ys xs - -brArg :: (a -> Concat) -> a -> Concat -brArg f arg = cconcat [CString "(", f arg, CString ")"] - -genOp :: String -> [String] -genOp op' - | op' == iPlus = [".plus[", "]"] - | op' == iSub = [".minus[", "]"] - | op' == iSumSet = ["sum temp : "," | temp."] - | op' == iProdSet = ["prod temp : "," | temp."] - | op' `elem` unOps = [op'] - | op' == iPlus = [".add[", "]"] - | op' == iSub = [".sub[", "]"] - | op' == iMul = [".mul[", "]"] - | op' == iDiv = [".div[", "]"] - | op' == iRem = [".rem[", "]"] - | op' `elem` logBinOps ++ relBinOps ++ arithBinOps = [" " ++ op' ++ " "] - | op' == iUnion = [" + "] - | op' == iDifference = [" - "] - | op' == iIntersection = [" & "] - | op' == iDomain = [" <: "] - | op' == iRange = [" :> "] - | op' == iJoin = ["."] - | op' == iIfThenElse = [" => ", " else "] -genOp op' = error $ "[bug] Alloy.genOp: Unmatched operator: " ++ op' - --- adjust parent -adjustPExp :: [String] -> PExp -> PExp -adjustPExp resPath (PExp t pid' pos x) = PExp t pid' pos $ adjustIExp resPath x - -adjustIExp :: [String] -> IExp -> IExp -adjustIExp resPath x = case x of - IDeclPExp q d pexp -> IDeclPExp q d $ adjustPExp resPath pexp - IFunExp op' exps' -> adjNav $ IFunExp op' $ map adjExps exps' - where - (adjNav, adjExps) = if op' == iJoin then (aNav, id) - else (id, adjustPExp resPath) - IClaferId{} -> aNav x - _ -> x - where - aNav = fst.(adjustNav resPath) - -adjustNav :: [String] -> IExp -> (IExp, [String]) -adjustNav resPath x@(IFunExp op' (pexp0:pexp:_)) - | op' == iJoin = (IFunExp iJoin - [pexp0{_exp = iexp0}, - pexp{_exp = iexp}], path') - | otherwise = (x, resPath) - where - (iexp0, path) = adjustNav resPath (_exp pexp0) - (iexp, path') = adjustNav path (_exp pexp) -adjustNav resPath x@(IClaferId _ id' _ _) - | id' == parentIdent = (x{_sident = "~@" ++ (genRelName $ head resPath)}, tail resPath) - | otherwise = (x, resPath) -adjustNav _ _ = error "Function adjustNav Expect a IFunExp or IClaferID as one of it's argument but it was given a differnt IExp" --This should never happen - -genQuant :: IQuant -> String -genQuant x = case x of - INo -> "no" - ILone -> "lone" - IOne -> "one" - ISome -> "some" - IAll -> "all" - - -genDecl :: GenEnv -> [String] -> IDecl -> Concat -genDecl genEnv resPath x = case x of - IDecl disj locids pexp -> cconcat [CString $ genDisj disj, CString " ", - CString $ intercalate ", " locids, CString " : ", genPExp genEnv resPath pexp] - - -genDisj :: Bool -> String -genDisj True = "disj" -genDisj False = "" - --- mapping line/columns between Clafer and Alloy code - -data AlloyEnv = AlloyEnv { - lineCol :: (LineNo, ColNo), - mapping :: [(Span, IrTrace)] - } deriving (Eq,Show) - -mapLineCol :: Concat -> [(Span, IrTrace)] -mapLineCol code = mapping $ execState (mapLineCol' code) (AlloyEnv (firstLine, firstCol) []) - -addCode :: MonadState AlloyEnv m => String -> m () -addCode str = modify (\s -> s {lineCol = lineno (lineCol s) str}) - -mapLineCol' :: MonadState AlloyEnv m => Concat -> m () -mapLineCol' (CString str) = addCode str -mapLineCol' c@(Concat srcPos' n) = do - posStart <- gets lineCol - _ <- mapM mapLineCol' n - posEnd <- gets lineCol - - {- - - Alloy only counts inner parenthesis as part of the constraint, but not outer parenthesis. - - ex1. the constraint looks like this in the file - - (constraint a) <=> (constraint b) - - But the actual constraint in the API is - - constraint a) <=> (constraint b - - - - ex2. the constraint looks like this in the file - - (((#((this.@r_c2_Finger).@r_c3_Pinky)).add[(#((this.@r_c2_Finger).@r_c4_Index))]).add[(#((this.@r_c2_Finger).@r_c5_Middle))]) = 0 - - But the actual constraint in the API is - - #((this.@r_c2_Finger).@r_c3_Pinky)).add[(#((this.@r_c2_Finger).@r_c4_Index))]).add[(#((this.@r_c2_Finger).@r_c5_Middle))]) = 0 - - - - Seems unintuitive since the brackets are now unbalanced but that's how they work in Alloy. The next - - few lines of code is counting the beginning and ending parenthesis's and subtracting them from the - - positions in the map file. - - Same is true for square brackets. - - This next little snippet is rather inefficient since we are retraversing the Concat's to flatten. - - But it's the simplest and correct solution I can think of right now. - -} - let flat = flatten c - raiseStart = countLeading "([" flat - deductEnd = -(countTrailing ")]" flat) - modify (\s -> s {mapping = (Span (uncurry Pos $ posStart `addColumn` raiseStart) (uncurry Pos $ posEnd `addColumn` deductEnd), srcPos') : (mapping s)}) - -addColumn :: Interval -> Integer -> Interval -addColumn (x, y) c = (x, y + c) -countLeading :: String -> String -> Integer -countLeading c xs = toInteger $ length $ takeWhile (`elem` c) xs -countTrailing :: String -> String -> Integer -countTrailing c xs = countLeading c (reverse xs) - -lineno :: (Integer, ColNo) -> String -> (Integer, ColNo) -lineno (l, c) str = (l + newLines, (if newLines > 0 then firstCol else c) + newCol) - where - newLines = toInteger $ length $ filter (== '\n') str - newCol = toInteger $ length $ takeWhile (/= '\n') $ reverse str - -firstCol :: ColNo -firstCol = 1 :: ColNo -firstLine :: LineNo -firstLine = 1 :: LineNo - -removeright :: PExp -> PExp -removeright (PExp _ _ _ (IFunExp _ (x : (PExp _ _ _ IClaferId{}) : _))) = x -removeright (PExp _ _ _ (IFunExp _ (x : (PExp _ _ _ (IInt _ )) : _))) = x -removeright (PExp _ _ _ (IFunExp _ (x : (PExp _ _ _ (IStr _ )) : _))) = x -removeright (PExp _ _ _ (IFunExp _ (x : (PExp _ _ _ (IDouble _ )) : _))) = x -removeright (PExp t id' pos (IFunExp o (x1:x2:xs))) = PExp t id' pos (IFunExp o (x1:(removeright x2):xs)) -removeright x@PExp{} = error $ "[bug] AlloyGenerator.removeright: expects a PExp with a IFunExp inside but was given: " ++ show x --This should never happen - -getRight :: PExp -> PExp -getRight (PExp _ _ _ (IFunExp _ (_:x:_))) = getRight x -getRight p = p +{-# LANGUAGE RankNTypes, FlexibleContexts #-}+{-+ Copyright (C) 2012-2015 Kacper Bak, Jimmy Liang, Michal Antkiewicz, Rafael Olaechea <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+-- | Generates Alloy4.2 code for a Clafer model+module Language.Clafer.Generator.Alloy (genModule) where++import Control.Applicative+import Control.Monad.State+import Data.List+import Data.Maybe+import Prelude++import Language.Clafer.Common+import Language.Clafer.ClaferArgs+import Language.Clafer.Front.AbsClafer+import Language.Clafer.Front.LexClafer+import Language.Clafer.Generator.Concat+import Language.Clafer.Intermediate.Intclafer hiding (exp)+++data GenEnv = GenEnv+ { claferargs :: ClaferArgs+ , uidIClaferMap :: UIDIClaferMap+ , forScopes :: String+ } deriving (Show)+++-- | Alloy code generation+genModule :: ClaferArgs -> (IModule, GEnv) -> [(UID, Integer)] -> [Token] -> (Result, [(Span, IrTrace)])+genModule claferargs' (imodule, genv) scopes otherTokens' = (flatten output, filter ((/= NoTrace) . snd) $ mapLineCol output)+ where++ genScopes :: [(UID, Integer)] -> String+ genScopes [] = ""+ genScopes scopes' = " but " ++ intercalate ", " (map (\ (uid', scope) -> show scope ++ " " ++ uid') scopes')++ forScopes' = "for 1" ++ genScopes scopes+ genEnv = GenEnv claferargs' (uidClaferMap genv) forScopes'+ output = header genEnv otherTokens' +++ (cconcat $ map (genDeclaration genEnv) (_mDecls imodule))++header :: GenEnv -> [Token] -> Concat+header genEnv otherTokens' = CString $ unlines+ [ "open util/integer"+ , genAlloyEscapes otherTokens' ++ "pred show {}"+ , if (validate $ claferargs genEnv)+ then ""+ else "run show " ++ forScopes genEnv+ , ""]++genAlloyEscapes :: [Token] -> String+genAlloyEscapes otherTokens' = concat $ map printAlloyEscape otherTokens'+ where+ printAlloyEscape (PT _ (T_PosAlloy code)) = let+ code' = fromJust $ stripPrefix "[alloy|" code+ in+ (take ((length code') - 2) code') ++ "\n"++ printAlloyEscape _ = ""++-- 07th Mayo 2012 Rafael Olaechea+genDeclaration :: GenEnv -> IElement -> Concat+genDeclaration genEnv x = case x of+ IEClafer clafer' -> (genClafer genEnv [] clafer') +++ (mkFact $ cconcat $ genSetUniquenessConstraint clafer')+ IEConstraint True pexp -> mkFact $ genPExp genEnv [] pexp+ IEConstraint False pexp -> mkAssert genEnv (genAssertName pexp) $ genPExp genEnv [] pexp+ IEGoal _ _ -> CString ""++mkFact :: Concat -> Concat+mkFact x@(CString "") = x+mkFact xs = cconcat [CString "fact ", mkSet xs, CString "\n"]++genAssertName :: PExp -> Concat+genAssertName PExp{_inPos=(Span _ (Pos line _))} = CString $ "assertOnLine_" ++ show line++mkAssert :: GenEnv -> Concat -> Concat -> Concat+mkAssert _ _ x@(CString "") = x+mkAssert genEnv name xs = cconcat+ [ CString "assert ", name, CString " "+ , mkSet xs+ , CString "\n"+ , CString "check ", name, CString " "+ , CString $ forScopes genEnv+ , CString "\n\n"+ ]++mkSet :: Concat -> Concat+mkSet xs = cconcat [CString "{ ", xs, CString " }"]++showSet :: Concat -> [Concat] -> Concat+showSet delim xs = showSet' delim $ filterNull xs+ where+ showSet' _ [] = CString "{}"+ showSet' delim' xs' = mkSet $ cintercalate delim' xs'++optShowSet :: [Concat] -> Concat+optShowSet [] = CString ""+optShowSet xs = CString "\n" +++ showSet (CString "\n ") xs++-- optimization: top level cardinalities+-- optimization: if only boolean parents, then set card is known+genClafer :: GenEnv -> [String] -> IClafer -> Concat+genClafer genEnv resPath clafer'+ = (cunlines $ filterNull+ [ cardFact+ +++ claferDecl clafer' (+ (showSet (CString "\n, ") $ genRelations genEnv clafer')+ +++ (optShowSet $ filterNull $ genConstraints genEnv resPath clafer')+ )+ ]+ )+ +++ CString "\n"+ +++ children'+ where+ children' = cconcat $ filterNull $ map+ (genClafer genEnv ((_uid clafer') : resPath)) $+ getSubclafers $ _elements clafer'+ cardFact+ | null resPath && (null $ flatten $ genOptCard clafer') =+ case genCard (_uid clafer') $ _card clafer' of+ CString "set" -> CString ""+ c -> mkFact c+ | otherwise = CString ""++claferDecl :: IClafer -> Concat -> Concat+claferDecl c rest = cconcat+ [ genOptCard c+ , CString $ if _isAbstract c then "abstract " else ""+ , CString "sig "+ , Concat NoTrace [CString $ _uid c, genExtends $ _super c, CString "\n", rest]+ ]+ where+ genExtends Nothing = CString ""+ genExtends (Just (PExp _ _ _ (IClaferId _ i _ _))) = CString " " +++ Concat NoTrace [CString $ "extends " ++ i]+ -- todo: handle multiple inheritance+ genExtends _ = CString ""++genOptCard :: IClafer -> Concat+genOptCard c+ | glCard' `elem` ["lone", "one", "some"] = cardConcat (_uid c) False [CString glCard'] +++ (CString " ")+ | otherwise = CString ""+ where+ glCard' = genIntervalCrude $ _glCard c+++-- -----------------------------------------------------------------------------+-- overlapping inheritance is a new clafer with val (unlike only relation)+-- relations: overlapping inheritance (val rel), children+-- adds parent relation+-- 29/March/2012 Rafael Olaechea: ref is now prepended with clafer name to be able to refer to it from partial instances.+genRelations :: GenEnv -> IClafer -> [Concat]+genRelations genEnv c = maybeToList r ++ (map mkRel $ getSubclafers $ _elements c)+ where+ r = if isJust $ _reference c+ then+ Just $ Concat NoTrace [CString $ genRel (genRefName $ _uid c)+ c {_card = Just (1, 1)} $+ flatten $ refType genEnv c]+ else+ Nothing+ mkRel c' = Concat NoTrace [CString $ genRel (genRelName $ _uid c') c' $ _uid c']++genRelName :: String -> String+genRelName name = "r_" ++ name++genRefName :: String -> String+genRefName name = name ++ "_ref"++genRel :: String -> IClafer -> String -> String+genRel name c rType = genAlloyRel name (genCardCrude $ _card c) rType'+ where+ rType' = if isPrimitive rType then "Int" else rType++genAlloyRel :: String -> String -> String -> String+genAlloyRel name card' rType = concat [name, " : ", card', " ", rType]++refType :: GenEnv -> IClafer -> Concat+refType genEnv c = fromMaybe (CString "") (((genType genEnv).getTarget) <$> (_ref <$> _reference c))+++getTarget :: PExp -> PExp+getTarget x = case x of+ PExp _ _ _ (IFunExp op' (_:pexp:_)) -> if op' == iJoin then pexp else x+ _ -> x++genType :: GenEnv -> PExp -> Concat+genType genEnv x@(PExp _ _ _ y@(IClaferId _ _ _ _)) = genPExp genEnv []+ x{_exp = y{_isTop = True}}+genType m x = genPExp m [] x+++-- -----------------------------------------------------------------------------+-- constraints+-- parent + group constraints + reference + user constraints+-- a = NUMBER do all x : a | x = NUMBER (otherwise alloy sums a set)+genConstraints :: GenEnv -> [String] -> IClafer -> [Concat]+genConstraints genEnv resPath c+ = genParentConst resPath c+ : genGroupConst genEnv c+ : genRefSubrelationConstriant (uidIClaferMap genEnv) c+{- genPathConst produces incorrect code for top-level clafers++abstract System+ abstract Connection+ connections -> Connection *++sig c0_connections+{ ref : one c0_Connection }+{ one @r_c0_connections.this+ ref = (@r_c0_System.@r_c0_Connection) }++r_c0_System does not exist because System is top-level. The constraint is useless anyway, since all instances+of Connection are nested under all Systems anyway.+ disabled code:+ : genPathConst genEnv (if (noalloyruncommand $ claferargs genEnv) then (_uid c ++ "_ref") else "ref") resPath c+-}+ : constraints+ where+ constraints = concatMap genConst $ _elements c+ genConst x = case x of+ IEConstraint True pexp -> [ genPExp genEnv (_uid c : resPath) pexp ]+ IEConstraint False pexp -> [ CString "// Assertion " +++ (genAssertName pexp) +++ CString " ignored since nested assertions are not supported in Alloy.\n"]+ IEClafer c' ->+ (if genCardCrude (_card c') `elem` ["one", "lone", "some"]+ then CString ""+ else mkCard ({- do not use the genRelName as the constraint name -} _uid c') False (genRelName $ _uid c') $ fromJust (_card c')+ )+ : (genParentSubrelationConstriant (uidIClaferMap genEnv) c')+ : (genSetUniquenessConstraint c')+ IEGoal _ _ -> error "[bug] Alloy.getConst: should not be given a goal." -- This should never happen+++genSetUniquenessConstraint :: IClafer -> [Concat]+genSetUniquenessConstraint c =+ (case _reference c of+ Just (IReference True _) ->+ (case _card c of+ Just (lb, ub) -> if (lb > 1 || ub > 1 || ub == -1)+ then [ CString $ (+ (case isTopLevel c of+ False -> "all disj x, y : this.@" ++ (genRelName $ _uid c)+ True -> " all disj x, y : " ++ (_uid c)))+ ++ " | (x.@" ++ genRefName (_uid c) ++ ") != (y.@" ++ genRefName (_uid c) ++ ") "+ ]+ else []+ _ -> [])+ _ -> []+ )++genParentSubrelationConstriant :: UIDIClaferMap -> IClafer -> Concat+genParentSubrelationConstriant uidIClaferMap' headClafer =+ case match of+ Nothing -> CString ""+ Just NestedInheritanceMatch {+ _superClafer = superClafer+ } -> if (isProperNesting uidIClaferMap' match) && (not $ isTopLevel superClafer)+ then CString $ concat+ [ genRelName $ _uid headClafer+ , " in "+ , genRelName $ _uid superClafer+ ]+ else CString ""+ where+ match = matchNestedInheritance uidIClaferMap' headClafer++-- See Common.NestedInheritanceMatch+genRefSubrelationConstriant :: UIDIClaferMap -> IClafer -> Concat+genRefSubrelationConstriant uidIClaferMap' headClafer =+ if isJust $ _reference headClafer+ then+ case match of+ Nothing -> CString ""+ Just NestedInheritanceMatch+ { _superClafer = superClafer+ , _superClafersTarget = superClafersTarget+ } -> case (isProperRefinement uidIClaferMap' match, not $ null superClafersTarget) of+ ((True, True, True), True) -> CString $ concat+ [ genRefName $ _uid headClafer+ , " in "+ , genRefName $ _uid superClafer+ ]+ _ -> CString ""+ else CString ""+ where+ match = matchNestedInheritance uidIClaferMap' headClafer+++-- optimization: if only boolean features then the parent is unique+genParentConst :: [String] -> IClafer -> Concat+genParentConst [] _ = CString ""+genParentConst _ c = genOptParentConst c++genOptParentConst :: IClafer -> Concat+genOptParentConst c+ | glCard' == "one" = CString ""+ | glCard' == "lone" = Concat NoTrace [CString $ "one " ++ rel]+ | otherwise = Concat NoTrace [CString $ "one @" ++ rel ++ ".this"]+ -- eliminating problems with cyclic containment;+ -- should be added to cases when cyclic containment occurs+ -- , " && no iden & @", rel, " && no ~@", rel, " & @", rel]+ where+ rel = genRelName $ _uid c+ glCard' = genIntervalCrude $ _glCard c++genGroupConst :: GenEnv -> IClafer -> Concat+genGroupConst genEnv clafer'+ | _isAbstract clafer' || null children' || flatten card' == "" = CString ""+ | otherwise = cconcat [CString "let children = ", brArg id $ CString children', CString" | ", card']+ where+ superHierarchy :: [IClafer]+ superHierarchy = findHierarchy getSuper (uidIClaferMap genEnv) clafer'+ children' = intercalate " + " $ map (genRelName._uid) $+ getSubclafers $ concatMap _elements superHierarchy+ card' = mkCard (_uid clafer') True "children" $ _interval $ fromJust $ _gcard $ clafer'++mkCard :: String -> Bool -> String -> (Integer, Integer) -> Concat+mkCard constraintName group' element' crd+ | crd' == "set" || crd' == "" = CString ""+ | crd' `elem` ["one", "lone", "some"] = CString $ crd' ++ " " ++ element'+ | otherwise = interval'+ where+ interval' = genInterval constraintName group' element' crd+ crd' = flatten $ interval'++{-+-- generates expression for references that point to expressions (not single clafers)+genPathConst :: GenEnv -> String -> [String] -> IClafer -> Concat+genPathConst genEnv name resPath c+ | isRefPath (c ^. reference) = cconcat [CString name, CString " = ",+ fromMaybe (error "genPathConst: impossible.") $+ fmap ((brArg id).(genPExp genEnv resPath)) $+ _ref <$> _reference c]+ | otherwise = CString ""++isRefPath :: Maybe IReference -> Bool+isRefPath Nothing = False+isRefPath (Just IReference{_ref=s}) = not $ isSimplePath s++isSimplePath :: PExp -> Bool+isSimplePath (PExp _ _ _ (IClaferId _ _ _ _)) = True+isSimplePath (PExp _ _ _ (IFunExp op' _)) = op' == iUnion+isSimplePath _ = False+-}+-- -----------------------------------------------------------------------------+-- Not used?+-- genGCard element gcard = genInterval element $ interval $ fromJust gcard+++genCard :: String -> Maybe Interval -> Concat+genCard element' crd = genInterval element' False element' $ fromJust crd++genCardCrude :: Maybe Interval -> String+genCardCrude crd = genIntervalCrude $ fromJust crd++genIntervalCrude :: Interval -> String+genIntervalCrude x = case x of+ (1, 1) -> "one"+ (0, 1) -> "lone"+ (1, -1) -> "some"+ _ -> "set"+++genInterval :: String -> Bool -> String -> Interval -> Concat+genInterval constraintName group' element' x = case x of+ (1, 1) -> cardConcat constraintName group' [CString "one"]+ (0, 1) -> cardConcat constraintName group' [CString "lone"]+ (1, -1) -> cardConcat constraintName group' [CString "some"]+ (0, -1) -> CString "set" -- "set"+ (n, exinteger) ->+ case (s1, s2) of+ (Just c1, Just c2) -> cconcat [c1, CString " and ", c2]+ (Just c1, Nothing) -> c1+ (Nothing, Just c2) -> c2+ (Nothing, Nothing) -> undefined+ where+ s1 = if n == 0+ then Nothing+ else Just $ cardLowerConcat constraintName group' [CString $ concat [show n, " <= #", element']]+ s2 =+ do+ result <- genExInteger element' x exinteger+ return $ cardUpperConcat constraintName group' [CString result]+++cardConcat :: String -> Bool -> [Concat] -> Concat+cardConcat constraintName = Concat . ExactCard constraintName+++cardLowerConcat :: String -> Bool -> [Concat] -> Concat+cardLowerConcat constraintName = Concat . LowerCard constraintName+++cardUpperConcat :: String -> Bool -> [Concat] -> Concat+cardUpperConcat constraintName = Concat . UpperCard constraintName+++genExInteger :: String -> Interval -> Integer -> Maybe Result+genExInteger element' (y,z) x =+ if (y==0 && z==0) then Just $ concat ["#", element', " = ", "0"] else+ if x == -1 then Nothing else Just $ concat ["#", element', " <= ", show x]+++-- -----------------------------------------------------------------------------+-- Generate code for logical expressions++genPExp :: GenEnv -> [String] -> PExp -> Concat+genPExp genEnv resPath x = genPExp' genEnv resPath $ adjustPExp resPath x++genPExp' :: GenEnv -> [String] -> PExp -> Concat+genPExp' genEnv resPath (PExp iType' pid' pos exp') = case exp' of+ IDeclPExp q d pexp -> Concat (IrPExp pid') $+ [ CString $ genQuant q, CString " "+ , cintercalate (CString ", ") $ map (genDecl genEnv resPath) d+ , CString $ optBar d, genPExp' genEnv resPath pexp]+ where+ optBar [] = ""+ optBar _ = " | "+ IClaferId _ "integer" _ _ -> CString "Int"+ IClaferId _ "int" _ _ -> CString "Int"+ IClaferId _ "string" _ _ -> CString "Int"+ IClaferId _ "dref" _ _ -> CString $ "@" ++ getTClaferUID iType' ++ "_ref"+ where+ getTClaferUID (Just TMap{_so = TClafer{_hi = [u]}}) = u+ getTClaferUID (Just TMap{_so = TClafer{_hi = (u:_)}}) = u+ getTClaferUID t = error $ "[bug] Alloy.genPExp'.getTClaferUID: unknown type: " ++ show t+ IClaferId _ sid istop _ -> CString $+ if head sid == '~'+ then sid+ else case iType' of+ Just TInteger -> vsident+ Just TDouble -> vsident+ Just TReal -> vsident+ Just TString -> vsident+ _ -> sid'+ where+ sid' = (if istop then "" else '@' : genRelName "") ++ sid+ vsident = sid' ++ ".@" ++ genRefName (if sid == "this" then head resPath else sid)+ IFunExp _ _ -> case exp'' of+ IFunExp _ _ -> genIFunExp pid' genEnv resPath exp''+ _ -> genPExp' genEnv resPath $ PExp iType' pid' pos exp''+ where+ exp'' = transformExp exp'+ IInt n -> CString $ show n+ IDouble _ -> error "no double numbers allowed"+ IReal _ -> error "no real numbers allowed"+ IStr _ -> error "no strings allowed"++++-- 3-May-2012 Rafael Olaechea.+-- Removed transfromation from x = -2 to x = (0-2) as this creates problem with partial instances.+-- See http://gsd.uwaterloo.ca:8888/question/461/new-translation-of-negative-number-x-into-0-x-is.+transformExp :: IExp -> IExp+transformExp (IFunExp op' (e1:_))+ | op' == iMin = IFunExp iMul [PExp (_iType e1) "" noSpan $ IInt (-1), e1]+transformExp x@(IFunExp op' exps'@(e1:e2:_))+ | op' == iXor = IFunExp iNot [PExp (Just TBoolean) "" noSpan (IFunExp iIff exps')]+ | op' == iJoin && isClaferName' e1 && isClaferName' e2 &&+ getClaferName e1 == thisIdent && head (getClaferName e2) == '~' =+ IFunExp op' [e1{_iType = Just $ TClafer []}, e2]+ | otherwise = x+transformExp x = x++genIFunExp :: String -> GenEnv -> [String] -> IExp -> Concat+genIFunExp pid' genEnv resPath (IFunExp "min" [exp']) = Concat (IrPExp pid') $ (CString "min[") : (genPExp' genEnv resPath exp') : [CString "]"]+genIFunExp pid' genEnv resPath (IFunExp "max" [exp']) = Concat (IrPExp pid') $ (CString "max[") : (genPExp' genEnv resPath exp') : [CString "]"]+-- ignore navigation from the root+genIFunExp pid' genEnv resPath (IFunExp "." [PExp{_exp=IClaferId{_sident="root"}}, exp2]) = genPExp' genEnv resPath exp2+genIFunExp pid' genEnv resPath (IFunExp op' exps')+ | op' == iSumSet = genIFunExp pid' genEnv resPath (IFunExp iSumSet' [(removeright (head exps')), (getRight $ head exps')])+ | op' == iSumSet' = Concat (IrPExp pid') $ intl exps'' (map CString $ genOp iSumSet)+ | otherwise = Concat (IrPExp pid') $ intl exps'' (map CString $ genOp op')+ where+ iSumSet' = "sum'"+ intl+ | op' == iSumSet' = flip interleave+ | op' `elem` arithBinOps && length exps' == 2 = interleave+ | otherwise = \xs ys -> reverse $ interleave (reverse xs) (reverse ys)+ exps'' = map (optBrArg genEnv resPath) exps'+genIFunExp _ _ _ x = error $ "[bug] Alloy.genIFunExp: expecting a IFunExp, instead got: " ++ show x--This should never happen+++optBrArg :: GenEnv -> [String] -> PExp -> Concat+optBrArg genEnv resPath x = brFun (genPExp' genEnv resPath) x+ where+ brFun = case x of+ PExp _ _ _ IClaferId{} -> ($)+ PExp _ _ _ (IInt _) -> ($)+ _ -> brArg++interleave :: [Concat] -> [Concat] -> [Concat]+interleave [] [] = []+interleave (x:xs) [] = x:xs+interleave [] (x:xs) = x:xs+interleave (x:xs) ys = x : interleave ys xs++brArg :: (a -> Concat) -> a -> Concat+brArg f arg = cconcat [CString "(", f arg, CString ")"]++genOp :: String -> [String]+genOp op'+ | op' == iPlus = [".plus[", "]"]+ | op' == iSub = [".minus[", "]"]+ | op' == iSumSet = ["sum temp : "," | temp."]+ | op' == iProdSet = ["prod temp : "," | temp."]+ | op' `elem` unOps = [op']+ | op' == iPlus = [".add[", "]"]+ | op' == iSub = [".sub[", "]"]+ | op' == iMul = [".mul[", "]"]+ | op' == iDiv = [".div[", "]"]+ | op' == iRem = [".rem[", "]"]+ | op' `elem` logBinOps ++ relBinOps ++ arithBinOps = [" " ++ op' ++ " "]+ | op' == iUnion = [" + "]+ | op' == iDifference = [" - "]+ | op' == iIntersection = [" & "]+ | op' == iDomain = [" <: "]+ | op' == iRange = [" :> "]+ | op' == iJoin = ["."]+ | op' == iIfThenElse = [" => ", " else "]+genOp op' = error $ "[bug] Alloy.genOp: Unmatched operator: " ++ op'++-- adjust parent+adjustPExp :: [String] -> PExp -> PExp+adjustPExp resPath (PExp t pid' pos x) = PExp t pid' pos $ adjustIExp resPath x++adjustIExp :: [String] -> IExp -> IExp+adjustIExp resPath x = case x of+ IDeclPExp q d pexp -> IDeclPExp q d $ adjustPExp resPath pexp+ IFunExp op' exps' -> adjNav $ IFunExp op' $ map adjExps exps'+ where+ (adjNav, adjExps) = if op' == iJoin then (aNav, id)+ else (id, adjustPExp resPath)+ IClaferId{} -> aNav x+ _ -> x+ where+ aNav = fst.(adjustNav resPath)++adjustNav :: [String] -> IExp -> (IExp, [String])+adjustNav resPath x@(IFunExp op' (pexp0:pexp:_))+ | op' == iJoin = (IFunExp iJoin+ [pexp0{_exp = iexp0},+ pexp{_exp = iexp}], path')+ | otherwise = (x, resPath)+ where+ (iexp0, path) = adjustNav resPath (_exp pexp0)+ (iexp, path') = adjustNav path (_exp pexp)+adjustNav resPath x@(IClaferId _ id' _ _)+ | id' == parentIdent = (x{_sident = "~@" ++ (genRelName $ head resPath)}, tail resPath)+ | otherwise = (x, resPath)+adjustNav _ _ = error "Function adjustNav Expect a IFunExp or IClaferID as one of it's argument but it was given a differnt IExp" --This should never happen++genQuant :: IQuant -> String+genQuant x = case x of+ INo -> "no"+ ILone -> "lone"+ IOne -> "one"+ ISome -> "some"+ IAll -> "all"+++genDecl :: GenEnv -> [String] -> IDecl -> Concat+genDecl genEnv resPath x = case x of+ IDecl disj locids pexp -> cconcat [CString $ genDisj disj, CString " ",+ CString $ intercalate ", " locids, CString " : ", genPExp genEnv resPath pexp]+++genDisj :: Bool -> String+genDisj True = "disj"+genDisj False = ""++-- mapping line/columns between Clafer and Alloy code++data AlloyEnv = AlloyEnv {+ lineCol :: (LineNo, ColNo),+ mapping :: [(Span, IrTrace)]+ } deriving (Eq,Show)++mapLineCol :: Concat -> [(Span, IrTrace)]+mapLineCol code = mapping $ execState (mapLineCol' code) (AlloyEnv (firstLine, firstCol) [])++addCode :: MonadState AlloyEnv m => String -> m ()+addCode str = modify (\s -> s {lineCol = lineno (lineCol s) str})++mapLineCol' :: MonadState AlloyEnv m => Concat -> m ()+mapLineCol' (CString str) = addCode str+mapLineCol' c@(Concat srcPos' n) = do+ posStart <- gets lineCol+ _ <- mapM mapLineCol' n+ posEnd <- gets lineCol++ {-+ - Alloy only counts inner parenthesis as part of the constraint, but not outer parenthesis.+ - ex1. the constraint looks like this in the file+ - (constraint a) <=> (constraint b)+ - But the actual constraint in the API is+ - constraint a) <=> (constraint b+ -+ - ex2. the constraint looks like this in the file+ - (((#((this.@r_c2_Finger).@r_c3_Pinky)).add[(#((this.@r_c2_Finger).@r_c4_Index))]).add[(#((this.@r_c2_Finger).@r_c5_Middle))]) = 0+ - But the actual constraint in the API is+ - #((this.@r_c2_Finger).@r_c3_Pinky)).add[(#((this.@r_c2_Finger).@r_c4_Index))]).add[(#((this.@r_c2_Finger).@r_c5_Middle))]) = 0+ -+ - Seems unintuitive since the brackets are now unbalanced but that's how they work in Alloy. The next+ - few lines of code is counting the beginning and ending parenthesis's and subtracting them from the+ - positions in the map file.+ - Same is true for square brackets.+ - This next little snippet is rather inefficient since we are retraversing the Concat's to flatten.+ - But it's the simplest and correct solution I can think of right now.+ -}+ let flat = flatten c+ raiseStart = countLeading "([" flat+ deductEnd = -(countTrailing ")]" flat)+ modify (\s -> s {mapping = (Span (uncurry Pos $ posStart `addColumn` raiseStart) (uncurry Pos $ posEnd `addColumn` deductEnd), srcPos') : (mapping s)})++addColumn :: Interval -> Integer -> Interval+addColumn (x, y) c = (x, y + c)+countLeading :: String -> String -> Integer+countLeading c xs = toInteger $ length $ takeWhile (`elem` c) xs+countTrailing :: String -> String -> Integer+countTrailing c xs = countLeading c (reverse xs)++lineno :: (Integer, ColNo) -> String -> (Integer, ColNo)+lineno (l, c) str = (l + newLines, (if newLines > 0 then firstCol else c) + newCol)+ where+ newLines = toInteger $ length $ filter (== '\n') str+ newCol = toInteger $ length $ takeWhile (/= '\n') $ reverse str++firstCol :: ColNo+firstCol = 1 :: ColNo+firstLine :: LineNo+firstLine = 1 :: LineNo++removeright :: PExp -> PExp+removeright (PExp _ _ _ (IFunExp _ (x : (PExp _ _ _ IClaferId{}) : _))) = x+removeright (PExp _ _ _ (IFunExp _ (x : (PExp _ _ _ (IInt _ )) : _))) = x+removeright (PExp _ _ _ (IFunExp _ (x : (PExp _ _ _ (IStr _ )) : _))) = x+removeright (PExp _ _ _ (IFunExp _ (x : (PExp _ _ _ (IDouble _ )) : _))) = x+removeright (PExp t id' pos (IFunExp o (x1:x2:xs))) = PExp t id' pos (IFunExp o (x1:(removeright x2):xs))+removeright x@PExp{} = error $ "[bug] AlloyGenerator.removeright: expects a PExp with a IFunExp inside but was given: " ++ show x --This should never happen++getRight :: PExp -> PExp+getRight (PExp _ _ _ (IFunExp _ (_:x:_))) = getRight x+getRight p = p
src/Language/Clafer/Generator/Choco.hs view
@@ -36,7 +36,7 @@ ++ (genClafers =<< _elements) genClafers _ = "" - genClaferNesting (IClafer{_isAbstract=True, _uid, _parentUID="root"}) + genClaferNesting (IClafer{_isAbstract=True, _uid, _parentUID="clafer"}) = " = Abstract(\"" ++ _uid ++ "\")" genClaferNesting (IClafer{_isAbstract=True, _uid, _parentUID}) = " = " ++ _parentUID ++ ".addAbstractChild(\"" ++ _uid ++ "\")" @@ -153,6 +153,8 @@ genLocal local = local ++ " = local(\"" ++ local ++ "\")" + genConstraintExp (IFunExp "." [PExp{_exp = IClaferId{_sident = "root"}}, e2]) = + genConstraintPExp e2 genConstraintExp (IFunExp "." [e1, PExp{_exp = IClaferId{_sident = "dref"}}]) = "joinRef(" ++ genConstraintPExp e1 ++ ")" genConstraintExp (IFunExp "." [e1, PExp{_exp = IClaferId{_sident = "parent"}}]) =
src/Language/Clafer/Generator/Concat.hs view
@@ -1,84 +1,84 @@-{- - Copyright (C) 2012-2015 Kacper Bak <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -module Language.Clafer.Generator.Concat where - -import Data.List -import Language.Clafer.Common -import Language.Clafer.Intermediate.Intclafer hiding (exp) - --- | representation of strings in chunks (for line/column numbering) -data Concat = CString String | Concat { - srcPos :: IrTrace, - nodes :: [Concat] - } deriving (Eq, Show) -type Position = ((LineNo, ColNo), (LineNo, ColNo)) - -data IrTrace = - IrPExp {pUid::String} | - LowerCard {pUid::String, isGroup::Bool} | - UpperCard {pUid::String, isGroup::Bool} | - ExactCard {pUid::String, isGroup::Bool} | - NoTrace - deriving (Eq, Show) - -mkConcat :: IrTrace -> String -> Concat -mkConcat pos str = Concat pos [CString str] - -mapToCStr :: [String] -> [Concat] -mapToCStr xs = map CString xs - -iscPrimitive :: Concat -> Bool -iscPrimitive x = isPrimitive $ flatten x - -flatten :: Concat -> String -flatten (CString x) = x -flatten (Concat _ nodes') = nodes' >>= flatten - -infixr 5 +++ -(+++) :: Concat -> Concat -> Concat -(+++) (CString x) (CString y) = CString $ x ++ y -(+++) (CString "") y@Concat{} = y -(+++) x y@(Concat src ys) - | src == NoTrace = Concat NoTrace $ x : ys - | otherwise = Concat NoTrace $ [x, y] -(+++) x@Concat{} (CString "") = x -(+++) x@(Concat src xs) y - | src == NoTrace = Concat NoTrace $ xs ++ [y] - | otherwise = Concat NoTrace $ [x, y] - -cconcat :: [Concat] -> Concat -cconcat = foldr (+++) (CString "") - -cintercalate :: Concat -> [Concat] -> Concat -cintercalate xs xss = cconcat (intersperse xs xss) - -filterNull :: [Concat] -> [Concat] -filterNull = filter (not.isNull) - -isNull :: Concat -> Bool -isNull (CString "") = True -isNull (Concat _ []) = True -isNull _ = False - -cunlines :: [Concat] -> Concat -cunlines xs = cconcat $ map (+++ (CString "\n")) xs - +{-+ Copyright (C) 2012-2015 Kacper Bak <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+module Language.Clafer.Generator.Concat where++import Data.List+import Language.Clafer.Common+import Language.Clafer.Intermediate.Intclafer hiding (exp)++-- | representation of strings in chunks (for line/column numbering)+data Concat = CString String | Concat {+ srcPos :: IrTrace,+ nodes :: [Concat]+ } deriving (Eq, Show)+type Position = ((LineNo, ColNo), (LineNo, ColNo))++data IrTrace =+ IrPExp {pUid::String} |+ LowerCard {pUid::String, isGroup::Bool} |+ UpperCard {pUid::String, isGroup::Bool} |+ ExactCard {pUid::String, isGroup::Bool} |+ NoTrace+ deriving (Eq, Show)++mkConcat :: IrTrace -> String -> Concat+mkConcat pos str = Concat pos [CString str]++mapToCStr :: [String] -> [Concat]+mapToCStr xs = map CString xs++iscPrimitive :: Concat -> Bool+iscPrimitive x = isPrimitive $ flatten x++flatten :: Concat -> String+flatten (CString x) = x+flatten (Concat _ nodes') = nodes' >>= flatten++infixr 5 ++++(+++) :: Concat -> Concat -> Concat+(+++) (CString x) (CString y) = CString $ x ++ y+(+++) (CString "") y@Concat{} = y+(+++) x y@(Concat src ys)+ | src == NoTrace = Concat NoTrace $ x : ys+ | otherwise = Concat NoTrace $ [x, y]+(+++) x@Concat{} (CString "") = x+(+++) x@(Concat src xs) y+ | src == NoTrace = Concat NoTrace $ xs ++ [y]+ | otherwise = Concat NoTrace $ [x, y]++cconcat :: [Concat] -> Concat+cconcat = foldr (+++) (CString "")++cintercalate :: Concat -> [Concat] -> Concat+cintercalate xs xss = cconcat (intersperse xs xss)++filterNull :: [Concat] -> [Concat]+filterNull = filter (not.isNull)++isNull :: Concat -> Bool+isNull (CString "") = True+isNull (Concat _ []) = True+isNull _ = False++cunlines :: [Concat] -> Concat+cunlines xs = cconcat $ map (+++ (CString "\n")) xs+
src/Language/Clafer/Generator/Graph.hs view
@@ -1,438 +1,438 @@-{- - Copyright (C) 2012 Christopher Walker <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} --- | Generates simple graph and CVL graph representation for a Clafer model in GraphViz DOT. -module Language.Clafer.Generator.Graph (genSimpleGraph, genCVLGraph, traceAstModule, traceIrModule) where - -import Language.Clafer.Common(fst3,snd3,trd3) -import Language.Clafer.Front.AbsClafer -import Language.Clafer.Intermediate.Tracing -import Language.Clafer.Intermediate.Intclafer -import Language.Clafer.Generator.Html(genTooltip) -import Control.Applicative -import qualified Data.Map as Map -import Data.Maybe -import Prelude hiding (exp) - --- | Generate a graph in the simplified notation -genSimpleGraph :: Module -> IModule -> String -> Bool -> String -genSimpleGraph m ir name showRefs = cleanOutput $ "digraph \"" ++ name ++ "\"\n{\n\nrankdir=BT;\nranksep=0.3;\nnodesep=0.1;\ngraph [fontname=Sans fontsize=11];\nnode [shape=box color=lightgray fontname=Sans fontsize=11 margin=\"0.02,0.02\" height=0.2 ];\nedge [fontname=Sans fontsize=11];\n" ++ b ++ "}" - where b = graphSimpleModule m (traceIrModule ir) showRefs - --- | Generate a graph in CVL variability abstraction notation -genCVLGraph :: Module -> IModule -> String -> String -genCVLGraph m ir name = cleanOutput $ "digraph \"" ++ name ++ "\"\n{\nrankdir=BT;\nranksep=0.1;\nnodesep=0.1;\nnode [shape=box margin=\"0.025,0.025\"];\nedge [arrowhead=none];\n" ++ b ++ "}" - where b = graphCVLModule m $ traceIrModule ir - --- Simplified Notation Printer -- ---toplevel: (Top_level (Boolean), Maybe Topmost parent, Maybe immediate parent) -graphSimpleModule :: Module -> Map.Map Span [Ir] -> Bool -> String -graphSimpleModule (Module _ []) _ _ = "" -graphSimpleModule (Module s (x:xs)) irMap showRefs = graphSimpleDeclaration x (True, Nothing, Nothing) irMap showRefs ++ graphSimpleModule (Module s xs) irMap showRefs - -graphSimpleDeclaration :: Declaration - -> (Bool, Maybe String, Maybe String) - -> Map.Map Span [Ir] - -> Bool - -> String -graphSimpleDeclaration (ElementDecl _ element) topLevel irMap showRefs = graphSimpleElement element topLevel irMap showRefs -graphSimpleDeclaration _ _ _ _ = "" - -graphSimpleElement :: Element - -> (Bool, Maybe String, Maybe String) - -> Map.Map Span [Ir] - -> Bool - -> String -graphSimpleElement (Subclafer _ clafer) topLevel irMap showRefs = graphSimpleClafer clafer topLevel irMap showRefs -graphSimpleElement (ClaferUse s _ _ _) topLevel irMap _ = if snd3 topLevel == Nothing then "" else "\"" ++ fromJust (snd3 topLevel) ++ "\" -> \"" ++ getUseId s irMap ++ "\" [arrowhead=vee arrowtail=diamond dir=both style=solid constraint=true weight=5 minlen=2 arrowsize=0.6 penwidth=0.5 ];\n" -graphSimpleElement _ _ _ _ = "" - -graphSimpleElements :: Elements - -> (Bool, Maybe String, Maybe String) - -> Map.Map Span [Ir] - -> Bool - -> String -graphSimpleElements (ElementsEmpty _) _ _ _ = "" -graphSimpleElements (ElementsList _ es) topLevel irMap showRefs = concatMap (\x -> graphSimpleElement x topLevel irMap showRefs ++ "\n") es - -graphSimpleClafer :: Clafer - -> (Bool, Maybe String, Maybe String) - -> Map.Map Span [Ir] - -> Bool - -> String --- top-level abstract and concrete -graphSimpleClafer (Clafer s abstract gCard id' super' reference' crd init' es) (True, _, _) irMap showRefs = - let - tooltip = genTooltip (Module s [ElementDecl s (Subclafer s (Clafer s abstract gCard id' super' reference' crd init' es))]) irMap - firstLineQuoted = htmlChars $ head $ lines tooltip - tooltipQuoted = htmlChars tooltip - uid' = getDivId s irMap - in - "\"" ++ - uid' ++ - "\" [label=\"" ++ - firstLineQuoted ++ - "\" URL=\"#" ++ - uid' ++ - "\" tooltip=\"" ++ - tooltipQuoted ++ - "\"];\n" ++ - graphSimpleSuper super' (True, Just uid', Just uid') irMap showRefs ++ - graphSimpleReference reference' (True, Just uid', Just uid') irMap showRefs ++ - graphSimpleElements es (False, Just uid', Just uid') irMap showRefs --- nested abstract -graphSimpleClafer (Clafer s abstract@(Abstract _) gCard id' super' reference' crd init' es) (False, _, _) irMap showRefs = - let - tooltip = genTooltip (Module s [ElementDecl s (Subclafer s (Clafer s abstract gCard id' super' reference' crd init' es))]) irMap - firstLineQuoted = htmlChars $ head $ lines tooltip - tooltipQuoted = htmlChars tooltip - uid' = getDivId s irMap - in - "\"" ++ - uid' ++ - "\" [label=\"" ++ - firstLineQuoted ++ - "\" URL=\"#" ++ - uid' ++ - "\" tooltip=\"" ++ - tooltipQuoted ++ - "\"];\n" ++ - graphSimpleSuper super' (False, Just uid', Just uid') irMap showRefs ++ - graphSimpleReference reference' (False, Just uid', Just uid') irMap showRefs ++ - graphSimpleElements es (False, Just uid', Just uid') irMap showRefs --- nested concrete -graphSimpleClafer (Clafer _ _ _ id' super' reference' _ _ es) topLevel irMap showRefs = - let - (PosIdent (_,ident')) = id' - in - graphSimpleSuper super' (fst3 topLevel, snd3 topLevel, Just ident') irMap showRefs ++ - graphSimpleReference reference' (fst3 topLevel, snd3 topLevel, Just ident') irMap showRefs ++ - graphSimpleElements es (fst3 topLevel, snd3 topLevel, Just ident') irMap showRefs - -graphSimpleSuper :: Super - -> (Bool, Maybe String, Maybe String) - -> Map.Map Span [Ir] - -> Bool - -> String - -parent :: [String] -> String -parent [] = "error" -parent (uid'@('c':xs):xss) = if '_' `elem` xs then uid' else parent xss -parent (_:xss) = parent xss - -graphSimpleSuper (SuperEmpty _) _ _ _ = "" -graphSimpleSuper (SuperSome _ setExp) topLevel irMap _ = - let - super' = parent $ graphSimpleExp setExp topLevel irMap - in - if super' == "error" - then "" - else "\"" ++ - fromJust (snd3 topLevel) ++ - "\" -> \"" ++ - parent (graphSimpleExp setExp topLevel irMap) ++ - "\"" ++ - " [" ++ if fst3 topLevel == True - then "arrowhead=onormal constraint=true weight=100];\n" - else "arrowhead=vee arrowtail=diamond dir=both style=solid weight=10 color=gray arrowsize=0.6 minlen=2 penwidth=0.5 constraint=true];\n" - -graphSimpleReference :: Reference -> (Bool, Maybe String, Maybe String) -> Map.Map Span [Ir] -> Bool -> String -graphSimpleReference (ReferenceEmpty _) _ _ _ = "" -graphSimpleReference (ReferenceSet _ setExp) topLevel irMap showRefs = - case graphSimpleExp setExp topLevel irMap of - ["integer"] -> "" - ["int"] -> "" - ["double"] -> "" - ["real"] -> "" - ["string"] -> "" - [target] -> - "\"" ++ - fromJust (snd3 topLevel) ++ - "\" -> \"" ++ - target ++ - "\"" ++ - " [arrowhead=vee arrowsize=0.6 penwidth=0.5 constraint=true weight=10 color=" ++ - refColour showRefs ++ - " fontcolor=" ++ - refColour showRefs ++ - (if fst3 topLevel == True then "" else " label=" ++ - (fromJust $ trd3 topLevel)) ++ - "];\n" - _ -> "" -graphSimpleReference (ReferenceBag _ setExp) topLevel irMap showRefs = - case graphSimpleExp setExp topLevel irMap of - ["integer"] -> "" - ["int"] -> "" - ["real"] -> "" - ["double"] -> "" - ["string"] -> "" - [target] -> - ("\"" ++ - fromJust (snd3 topLevel) ++ - "\" -> \"" ++ - target ++ - "\"" ++ - " [arrowhead=veevee arrowsize=0.6 minlen=1.5 penwidth=0.5 constraint=true weight=10 color=" ++ - refColour showRefs ++ - " fontcolor=" ++ - refColour showRefs ++ - (if fst3 topLevel == True then "" else " label=" ++ - (fromJust $ trd3 topLevel)) ++ "];\n") - _ -> "" -refColour :: Bool -> String -refColour True = "lightgray" -refColour False = "transparent" - -graphSimpleName :: Name -> (Bool, Maybe String, Maybe String) -> Map.Map Span [Ir] -> String -graphSimpleName (Path _ modids) topLevel irMap = unwords $ map (\x -> graphSimpleModId x topLevel irMap) modids - -graphSimpleModId :: ModId -> (Bool, Maybe String, Maybe String) -> Map.Map Span [Ir] -> String -graphSimpleModId (ModIdIdent _ posident) _ irMap = graphSimplePosIdent posident irMap - -graphSimplePosIdent :: PosIdent -> Map.Map Span [Ir] -> String -graphSimplePosIdent (PosIdent (pos, id')) irMap = getUid (PosIdent (pos, id')) irMap - -{-graphSimpleCard _ _ _ = "" -graphSimpleConstraint _ _ _ = "" -graphSimpleDecl _ _ _ = "" -graphSimpleInit _ _ _ = "" -graphSimpleInitHow _ _ _ = "" -graphSimpleExp _ _ _ = "" -graphSimpleQuant _ _ _ = "" -graphSimpleGoal _ _ _ = "" -graphSimpleAssertion _ _ _ = "" -graphSimpleAbstract _ _ _ = "" -graphSimpleGCard _ _ _ = "" -graphSimpleNCard _ _ _ = "" -graphSimpleExInteger _ _ _ = ""-} - -graphSimpleExp :: Exp -> (Bool, Maybe String, Maybe String) -> Map.Map Span [Ir] -> [String] -graphSimpleExp (ClaferId _ name) topLevel irMap = [graphSimpleName name topLevel irMap] -graphSimpleExp (EUnion _ set1 set2) topLevel irMap = graphSimpleExp set1 topLevel irMap ++ graphSimpleExp set2 topLevel irMap -graphSimpleExp (EUnionCom _ set1 set2) topLevel irMap = graphSimpleExp set1 topLevel irMap ++ graphSimpleExp set2 topLevel irMap -graphSimpleExp (EDifference _ set1 set2) topLevel irMap = graphSimpleExp set1 topLevel irMap ++ graphSimpleExp set2 topLevel irMap -graphSimpleExp (EIntersection _ set1 set2) topLevel irMap = graphSimpleExp set1 topLevel irMap ++ graphSimpleExp set2 topLevel irMap -graphSimpleExp (EDomain _ set1 set2) topLevel irMap = graphSimpleExp set1 topLevel irMap ++ graphSimpleExp set2 topLevel irMap -graphSimpleExp (ERange _ set1 set2) topLevel irMap = graphSimpleExp set1 topLevel irMap ++ graphSimpleExp set2 topLevel irMap -graphSimpleExp (EJoin _ set1 set2) topLevel irMap = graphSimpleExp set1 topLevel irMap ++ graphSimpleExp set2 topLevel irMap -graphSimpleExp _ _ _ = [] - -{-graphSimpleEnumId :: EnumId -> (Bool, Maybe String, Maybe String) -> Map.Map Span [Ir] -> String -graphSimpleEnumId (EnumIdIdent posident) _ irMap = graphSimplePosIdent posident irMap -graphSimpleEnumId (PosEnumIdIdent _ posident) topLevel irMap = graphSimpleEnumId (EnumIdIdent posident) topLevel irMap-} - --- CVL Printer -- ---parent is Maybe the uid of the immediate parent -graphCVLModule :: Module -> Map.Map Span [Ir] -> String -graphCVLModule (Module _ []) _ = "" -graphCVLModule (Module s (x:xs)) irMap = graphCVLDeclaration x Nothing irMap ++ graphCVLModule (Module s xs) irMap - -graphCVLDeclaration :: Declaration -> Maybe String -> Map.Map Span [Ir] -> String -graphCVLDeclaration (ElementDecl _ element) parent' irMap = graphCVLElement element parent' irMap -graphCVLDeclaration _ _ _ = "" - -graphCVLElement :: Element -> Maybe String -> Map.Map Span [Ir] -> String -graphCVLElement (Subclafer _ clafer) parent' irMap = graphCVLClafer clafer parent' irMap ---graphCVLElement (ClaferUse _ name _ _) parent' irMap = if parent' == Nothing then "" else "?" ++ " -> " ++ graphCVLName name parent' irMap ++ " [arrowhead = onormal style = dashed constraint = false];\n" -graphCVLElement (ClaferUse s _ _ _) parent' irMap = if parent' == Nothing then "" else "?" ++ " -> " ++ getUseId s irMap ++ " [arrowhead = onormal style = dashed constraint = false];\n" -graphCVLElement (Subconstraint _ constraint) parent' irMap = graphCVLConstraint constraint parent' irMap -graphCVLElement (Subgoal _ constraint) parent' irMap = graphCVLGoal constraint parent' irMap -graphCVLElement (SubAssertion _ constraint) parent' irMap = graphCVLAssertion constraint parent' irMap - -graphCVLElements :: Elements -> Maybe String -> Map.Map Span [Ir] -> String -graphCVLElements (ElementsEmpty _) _ _ = "" -graphCVLElements (ElementsList _ es) parent' irMap = concatMap (\x -> graphCVLElement x parent' irMap ++ "\n") es - -graphCVLClafer :: Clafer -> Maybe String -> Map.Map Span [Ir] -> String -graphCVLClafer (Clafer s _ gCard _ super' reference' crd _ es) parent' irMap - = let {{-tooltip = genTooltip (Module [ElementDecl (Subclafer (Clafer abstract gCard id' super' crd init' es))]) irMap;-} - uid' = getDivId s irMap; - gcrd = graphCVLGCard gCard parent' irMap; - super'' = graphCVLSuper super' parent' irMap; - reference'' = graphCVLReference reference' parent' irMap} in - "\"" ++ uid' ++ "\" [URL=\"#" ++ uid' ++ "\" label=\"" ++ dropUid uid' ++ super'' ++ reference'' ++ (if choiceCard crd then "\" style=rounded" else " [" ++ graphCVLCard crd parent' irMap ++ "]\"") - ++ (if super'' == "" then "" else " shape=oval") ++ "];\n" - ++ (if gcrd == "" then "" else "g" ++ uid' ++ " [label=\"" ++ gcrd ++ "\" fontsize=10 shape=triangle];\ng" ++ uid' ++ " -> " ++ uid' ++ " [weight=10];\n") - ++ (if parent'==Nothing then "" else uid' ++ " -> " ++ fromJust parent' ++ (if lowerCard crd == "0" then " [style=dashed]" else "") ++ ";\n") - ++ graphCVLElements es (if gcrd == "" then (Just uid') else (Just $ "g" ++ uid')) irMap - -graphCVLSuper :: Super -> Maybe String -> Map.Map Span [Ir] -> String -graphCVLSuper (SuperEmpty _) _ _ = "" -graphCVLSuper (SuperSome _ setExp) parent' irMap = ":" ++ concat (graphCVLExp setExp parent' irMap) - -graphCVLReference :: Reference -> Maybe String -> Map.Map Span [Ir] -> String -graphCVLReference (ReferenceEmpty _) _ _ = "" -graphCVLReference (ReferenceSet _ setExp) parent' irMap = "->" ++ concat (graphCVLExp setExp parent' irMap) -graphCVLReference (ReferenceBag _ setExp) parent' irMap = "->>" ++ concat (graphCVLExp setExp parent' irMap) - -graphCVLName :: Name -> Maybe String -> Map.Map Span [Ir] -> String -graphCVLName (Path _ modids) parent' irMap = unwords $ map (\x -> graphCVLModId x parent' irMap) modids - -graphCVLModId :: ModId -> Maybe String -> Map.Map Span [Ir] -> String -graphCVLModId (ModIdIdent _ posident) _ irMap = graphCVLPosIdent posident irMap - -graphCVLPosIdent :: PosIdent -> Map.Map Span [Ir] -> String -graphCVLPosIdent (PosIdent (pos, id')) irMap = getUid (PosIdent (pos, id')) irMap - -graphCVLConstraint :: Constraint -> Maybe String -> Map.Map Span [Ir] -> String -graphCVLConstraint (Constraint s exps') parent' irMap = let body' = htmlChars $ genTooltip (Module s [ElementDecl s (Subconstraint s (Constraint s exps'))]) irMap; - uid' = "\"" ++ getExpId s irMap ++ "\"" - in uid' ++ " [label=\"" ++ body' ++ "\" shape=parallelogram];\n" ++ - if parent' == Nothing then "" else uid' ++ " -> \"" ++ fromJust parent' ++ "\";\n" - -graphCVLAssertion :: Assertion -> Maybe String -> Map.Map Span [Ir] -> String -graphCVLAssertion (Assertion s exps') parent' irMap = let body' = htmlChars $ genTooltip (Module s [ElementDecl s (SubAssertion s (Assertion s exps'))]) irMap; - uid' = "\"" ++ getExpId s irMap ++ "\"" - in uid' ++ " [label=\"" ++ body' ++ "\" shape=parallelogram];\n" ++ - if parent' == Nothing then "" else uid' ++ " -> \"" ++ fromJust parent' ++ "\";\n" - -graphCVLGoal :: Goal -> Maybe String -> Map.Map Span [Ir] -> String -graphCVLGoal goal parent' irMap = let - s = getSpan goal - body' = htmlChars $ genTooltip (Module s [ElementDecl s (Subgoal s goal)]) irMap - uid' = "\"" ++ getExpId s irMap ++ "\"" - in - uid' ++ - " [label=\"" ++ body' ++ "\" shape=parallelogram];\n" ++ - if parent' == Nothing - then "" - else uid' ++ " -> \"" ++ fromJust parent' ++ "\";\n" - -graphCVLCard :: Card -> Maybe String -> Map.Map Span [Ir] -> String -graphCVLCard (CardEmpty _) _ _ = "1..1" -graphCVLCard (CardLone _) _ _ = "0..1" -graphCVLCard (CardSome _) _ _ = "1..*" -graphCVLCard (CardAny _) _ _ = "0..*" -graphCVLCard (CardNum _ (PosInteger (_, n))) _ _ = n ++ ".." ++ n -graphCVLCard (CardInterval _ ncard) parent' irMap = graphCVLNCard ncard parent' irMap - -graphCVLNCard :: NCard -> Maybe String -> Map.Map Span [Ir] -> String -graphCVLNCard (NCard _ (PosInteger (_, num)) exInteger) parent' irMap = num ++ ".." ++ graphCVLExInteger exInteger parent' irMap - -graphCVLExInteger :: ExInteger -> Maybe String -> Map.Map Span [Ir] -> String -graphCVLExInteger (ExIntegerAst _) _ _ = "*" -graphCVLExInteger (ExIntegerNum _ (PosInteger(_, num))) _ _ = num - -graphCVLGCard :: GCard -> Maybe String -> Map.Map Span [Ir] -> String -graphCVLGCard (GCardInterval _ ncard) parent' irMap = graphCVLNCard ncard parent' irMap -graphCVLGCard (GCardEmpty _) _ _ = "" -graphCVLGCard (GCardXor _) _ _ = "1..1" -graphCVLGCard (GCardOr _) _ _ = "1..*" -graphCVLGCard (GCardMux _) _ _ = "0..1" -graphCVLGCard (GCardOpt _) _ _ = "" - - -{-graphCVLDecl _ _ _ = "" -graphCVLInit _ _ _ = "" -graphCVLInitHow _ _ _ = "" -graphCVLExp _ _ _ = "" -graphCVLQuant _ _ _ = "" -graphCVLGoal _ _ _ = "" -graphCVLAssertion _ _ _ = "" -graphCVLAbstract _ _ _ = ""-} - -graphCVLExp :: Exp -> Maybe String -> Map.Map Span [Ir] -> [String] -graphCVLExp (ClaferId _ name) parent' irMap = [graphCVLName name parent' irMap] -graphCVLExp (EUnion _ set1 set2) parent' irMap = graphCVLExp set1 parent' irMap ++ graphCVLExp set2 parent' irMap -graphCVLExp (EUnionCom _ set1 set2) parent' irMap = graphCVLExp set1 parent' irMap ++ graphCVLExp set2 parent' irMap -graphCVLExp (EDifference _ set1 set2) parent' irMap = graphCVLExp set1 parent' irMap ++ graphCVLExp set2 parent' irMap -graphCVLExp (EIntersection _ set1 set2) parent' irMap = graphCVLExp set1 parent' irMap ++ graphCVLExp set2 parent' irMap -graphCVLExp (EDomain _ set1 set2) parent' irMap = graphCVLExp set1 parent' irMap ++ graphCVLExp set2 parent' irMap -graphCVLExp (ERange _ set1 set2) parent' irMap = graphCVLExp set1 parent' irMap ++ graphCVLExp set2 parent' irMap -graphCVLExp (EJoin _ set1 set2) parent' irMap = graphCVLExp set1 parent' irMap ++ graphCVLExp set2 parent' irMap -graphCVLExp _ _ _ = [] - -{-graphCVLEnumId (EnumIdIdent posident) _ irMap = graphCVLPosIdent posident irMap -graphCVLEnumId (PosEnumIdIdent _ posident) parent irMap = graphCVLEnumId (EnumIdIdent posident) parent irMap-} - -choiceCard :: Card -> Bool -choiceCard (CardEmpty _) = True -choiceCard (CardLone _) = True -choiceCard (CardInterval _ (NCard _ (PosInteger (_, low)) exInteger)) = if low == "0" || low == "1" - then case exInteger of - (ExIntegerAst _) -> False - (ExIntegerNum _ (PosInteger (_, high))) -> high == "0" || high == "1" - else False -choiceCard _ = False - -lowerCard :: Card -> String -lowerCard crd = takeWhile (/= '.') $ graphCVLCard crd Nothing Map.empty - ---Miscellaneous functions -dropUid :: String -> String -dropUid uid' = let id' = rest $ dropWhile (\x -> x /= '_') uid' in if id' == "" then uid' else id' - -rest :: String -> String -rest [] = [] -rest (_:xs) = xs - -getUid :: PosIdent -> Map.Map Span [Ir] -> String -getUid (PosIdent (pos, id')) irMap = if Map.lookup (getSpan (PosIdent (pos, id'))) irMap == Nothing - then id' - else let IRPExp pexp = head $ fromJust $ Map.lookup (getSpan (PosIdent (pos, id'))) irMap in - findUid id' $ getIdentPExp pexp - where {getIdentPExp (PExp _ _ _ exp') = getIdentIExp exp'; - getIdentIExp (IFunExp _ exps') = concatMap getIdentPExp exps'; - getIdentIExp (IClaferId _ id'' _ _) = [id'']; - getIdentIExp (IDeclPExp _ _ pexp) = getIdentPExp pexp; - getIdentIExp _ = []; - findUid name (x:xs) = if name == dropUid x then x else findUid name xs; - findUid name [] = name} - -getDivId :: Span -> Map.Map Span [Ir] -> String -getDivId s irMap = if Map.lookup s irMap == Nothing - then "Uid not Found" - else let IRClafer iClaf = head $ fromJust $ Map.lookup s irMap in - _uid iClaf - -getUseId :: Span -> Map.Map Span [Ir] -> String -getUseId s irMap = if Map.lookup s irMap == Nothing - then "Uid not Found" - else let - IRClafer iClaf = head $ fromJust $ Map.lookup s irMap - in - fromMaybe "" $ _sident <$> _exp <$> _super iClaf - -getExpId :: Span -> Map.Map Span [Ir] -> String -getExpId s irMap = if Map.lookup s irMap == Nothing - then "Uid not Found" - else let IRPExp pexp = head $ fromJust $ Map.lookup s irMap in _pid pexp - -{-while :: Bool -> [IExp] -> [IExp] -while bool exp' = if bool then exp' else []-} - -htmlChars :: String -> String -htmlChars "" = "" -htmlChars ('\n':xs) = " " ++ htmlChars xs -htmlChars ('\"':xs) = """ ++ htmlChars xs -htmlChars ('\'':xs) = "'" ++ htmlChars xs -htmlChars ('&':xs) = "&" ++ htmlChars xs -htmlChars ('~':xs) = "˜" ++ htmlChars xs -htmlChars ('-':'>':'>':xs) = "->>" ++ htmlChars xs -htmlChars ('-':'>':xs) = "->" ++ htmlChars xs -htmlChars (x:xs) = x:htmlChars xs - -cleanOutput :: String -> String -cleanOutput "" = "" -cleanOutput (' ':'\n':xs) = cleanOutput $ '\n':xs -cleanOutput ('\n':'\n':xs) = cleanOutput $ '\n':xs -cleanOutput (' ':'<':'b':'r':'>':xs) = "<br>"++cleanOutput xs -cleanOutput (x:xs) = x : cleanOutput xs +{-+ Copyright (C) 2012 Christopher Walker <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+-- | Generates simple graph and CVL graph representation for a Clafer model in GraphViz DOT.+module Language.Clafer.Generator.Graph (genSimpleGraph, genCVLGraph, traceAstModule, traceIrModule) where++import Language.Clafer.Common(fst3,snd3,trd3)+import Language.Clafer.Front.AbsClafer+import Language.Clafer.Intermediate.Tracing+import Language.Clafer.Intermediate.Intclafer+import Language.Clafer.Generator.Html(genTooltip)+import Control.Applicative+import qualified Data.Map as Map+import Data.Maybe+import Prelude hiding (exp)++-- | Generate a graph in the simplified notation+genSimpleGraph :: Module -> IModule -> String -> Bool -> String+genSimpleGraph m ir name showRefs = cleanOutput $ "digraph \"" ++ name ++ "\"\n{\n\nrankdir=BT;\nranksep=0.3;\nnodesep=0.1;\ngraph [fontname=Sans fontsize=11];\nnode [shape=box color=lightgray fontname=Sans fontsize=11 margin=\"0.02,0.02\" height=0.2 ];\nedge [fontname=Sans fontsize=11];\n" ++ b ++ "}"+ where b = graphSimpleModule m (traceIrModule ir) showRefs++-- | Generate a graph in CVL variability abstraction notation+genCVLGraph :: Module -> IModule -> String -> String+genCVLGraph m ir name = cleanOutput $ "digraph \"" ++ name ++ "\"\n{\nrankdir=BT;\nranksep=0.1;\nnodesep=0.1;\nnode [shape=box margin=\"0.025,0.025\"];\nedge [arrowhead=none];\n" ++ b ++ "}"+ where b = graphCVLModule m $ traceIrModule ir++-- Simplified Notation Printer --+--toplevel: (Top_level (Boolean), Maybe Topmost parent, Maybe immediate parent)+graphSimpleModule :: Module -> Map.Map Span [Ir] -> Bool -> String+graphSimpleModule (Module _ []) _ _ = ""+graphSimpleModule (Module s (x:xs)) irMap showRefs = graphSimpleDeclaration x (True, Nothing, Nothing) irMap showRefs ++ graphSimpleModule (Module s xs) irMap showRefs++graphSimpleDeclaration :: Declaration+ -> (Bool, Maybe String, Maybe String)+ -> Map.Map Span [Ir]+ -> Bool+ -> String+graphSimpleDeclaration (ElementDecl _ element) topLevel irMap showRefs = graphSimpleElement element topLevel irMap showRefs+graphSimpleDeclaration _ _ _ _ = ""++graphSimpleElement :: Element+ -> (Bool, Maybe String, Maybe String)+ -> Map.Map Span [Ir]+ -> Bool+ -> String+graphSimpleElement (Subclafer _ clafer) topLevel irMap showRefs = graphSimpleClafer clafer topLevel irMap showRefs+graphSimpleElement (ClaferUse s _ _ _) topLevel irMap _ = if snd3 topLevel == Nothing then "" else "\"" ++ fromJust (snd3 topLevel) ++ "\" -> \"" ++ getUseId s irMap ++ "\" [arrowhead=vee arrowtail=diamond dir=both style=solid constraint=true weight=5 minlen=2 arrowsize=0.6 penwidth=0.5 ];\n"+graphSimpleElement _ _ _ _ = ""++graphSimpleElements :: Elements+ -> (Bool, Maybe String, Maybe String)+ -> Map.Map Span [Ir]+ -> Bool+ -> String+graphSimpleElements (ElementsEmpty _) _ _ _ = ""+graphSimpleElements (ElementsList _ es) topLevel irMap showRefs = concatMap (\x -> graphSimpleElement x topLevel irMap showRefs ++ "\n") es++graphSimpleClafer :: Clafer+ -> (Bool, Maybe String, Maybe String)+ -> Map.Map Span [Ir]+ -> Bool+ -> String+-- top-level abstract and concrete+graphSimpleClafer (Clafer s abstract gCard id' super' reference' crd init' es) (True, _, _) irMap showRefs =+ let+ tooltip = genTooltip (Module s [ElementDecl s (Subclafer s (Clafer s abstract gCard id' super' reference' crd init' es))]) irMap+ firstLineQuoted = htmlChars $ head $ lines tooltip+ tooltipQuoted = htmlChars tooltip+ uid' = getDivId s irMap+ in+ "\"" +++ uid' +++ "\" [label=\"" +++ firstLineQuoted +++ "\" URL=\"#" +++ uid' +++ "\" tooltip=\"" +++ tooltipQuoted +++ "\"];\n" +++ graphSimpleSuper super' (True, Just uid', Just uid') irMap showRefs +++ graphSimpleReference reference' (True, Just uid', Just uid') irMap showRefs +++ graphSimpleElements es (False, Just uid', Just uid') irMap showRefs+-- nested abstract+graphSimpleClafer (Clafer s abstract@(Abstract _) gCard id' super' reference' crd init' es) (False, _, _) irMap showRefs =+ let+ tooltip = genTooltip (Module s [ElementDecl s (Subclafer s (Clafer s abstract gCard id' super' reference' crd init' es))]) irMap+ firstLineQuoted = htmlChars $ head $ lines tooltip+ tooltipQuoted = htmlChars tooltip+ uid' = getDivId s irMap+ in+ "\"" +++ uid' +++ "\" [label=\"" +++ firstLineQuoted +++ "\" URL=\"#" +++ uid' +++ "\" tooltip=\"" +++ tooltipQuoted +++ "\"];\n" +++ graphSimpleSuper super' (False, Just uid', Just uid') irMap showRefs +++ graphSimpleReference reference' (False, Just uid', Just uid') irMap showRefs +++ graphSimpleElements es (False, Just uid', Just uid') irMap showRefs+-- nested concrete+graphSimpleClafer (Clafer _ _ _ id' super' reference' _ _ es) topLevel irMap showRefs =+ let+ (PosIdent (_,ident')) = id'+ in+ graphSimpleSuper super' (fst3 topLevel, snd3 topLevel, Just ident') irMap showRefs +++ graphSimpleReference reference' (fst3 topLevel, snd3 topLevel, Just ident') irMap showRefs +++ graphSimpleElements es (fst3 topLevel, snd3 topLevel, Just ident') irMap showRefs++graphSimpleSuper :: Super+ -> (Bool, Maybe String, Maybe String)+ -> Map.Map Span [Ir]+ -> Bool+ -> String++parent :: [String] -> String+parent [] = "error"+parent (uid'@('c':xs):xss) = if '_' `elem` xs then uid' else parent xss+parent (_:xss) = parent xss++graphSimpleSuper (SuperEmpty _) _ _ _ = ""+graphSimpleSuper (SuperSome _ setExp) topLevel irMap _ =+ let+ super' = parent $ graphSimpleExp setExp topLevel irMap+ in+ if super' == "error"+ then ""+ else "\"" +++ fromJust (snd3 topLevel) +++ "\" -> \"" +++ parent (graphSimpleExp setExp topLevel irMap) +++ "\"" +++ " [" ++ if fst3 topLevel == True+ then "arrowhead=onormal constraint=true weight=100];\n"+ else "arrowhead=vee arrowtail=diamond dir=both style=solid weight=10 color=gray arrowsize=0.6 minlen=2 penwidth=0.5 constraint=true];\n"++graphSimpleReference :: Reference -> (Bool, Maybe String, Maybe String) -> Map.Map Span [Ir] -> Bool -> String+graphSimpleReference (ReferenceEmpty _) _ _ _ = ""+graphSimpleReference (ReferenceSet _ setExp) topLevel irMap showRefs =+ case graphSimpleExp setExp topLevel irMap of+ ["integer"] -> ""+ ["int"] -> ""+ ["double"] -> ""+ ["real"] -> ""+ ["string"] -> ""+ [target] ->+ "\"" +++ fromJust (snd3 topLevel) +++ "\" -> \"" +++ target +++ "\"" +++ " [arrowhead=vee arrowsize=0.6 penwidth=0.5 constraint=true weight=10 color=" +++ refColour showRefs +++ " fontcolor=" +++ refColour showRefs +++ (if fst3 topLevel == True then "" else " label=" +++ (fromJust $ trd3 topLevel)) +++ "];\n"+ _ -> ""+graphSimpleReference (ReferenceBag _ setExp) topLevel irMap showRefs =+ case graphSimpleExp setExp topLevel irMap of+ ["integer"] -> ""+ ["int"] -> ""+ ["real"] -> ""+ ["double"] -> ""+ ["string"] -> ""+ [target] ->+ ("\"" +++ fromJust (snd3 topLevel) +++ "\" -> \"" +++ target +++ "\"" +++ " [arrowhead=veevee arrowsize=0.6 minlen=1.5 penwidth=0.5 constraint=true weight=10 color=" +++ refColour showRefs +++ " fontcolor=" +++ refColour showRefs +++ (if fst3 topLevel == True then "" else " label=" +++ (fromJust $ trd3 topLevel)) ++ "];\n")+ _ -> ""+refColour :: Bool -> String+refColour True = "lightgray"+refColour False = "transparent"++graphSimpleName :: Name -> (Bool, Maybe String, Maybe String) -> Map.Map Span [Ir] -> String+graphSimpleName (Path _ modids) topLevel irMap = unwords $ map (\x -> graphSimpleModId x topLevel irMap) modids++graphSimpleModId :: ModId -> (Bool, Maybe String, Maybe String) -> Map.Map Span [Ir] -> String+graphSimpleModId (ModIdIdent _ posident) _ irMap = graphSimplePosIdent posident irMap++graphSimplePosIdent :: PosIdent -> Map.Map Span [Ir] -> String+graphSimplePosIdent (PosIdent (pos, id')) irMap = getUid (PosIdent (pos, id')) irMap++{-graphSimpleCard _ _ _ = ""+graphSimpleConstraint _ _ _ = ""+graphSimpleDecl _ _ _ = ""+graphSimpleInit _ _ _ = ""+graphSimpleInitHow _ _ _ = ""+graphSimpleExp _ _ _ = ""+graphSimpleQuant _ _ _ = ""+graphSimpleGoal _ _ _ = ""+graphSimpleAssertion _ _ _ = ""+graphSimpleAbstract _ _ _ = ""+graphSimpleGCard _ _ _ = ""+graphSimpleNCard _ _ _ = ""+graphSimpleExInteger _ _ _ = ""-}++graphSimpleExp :: Exp -> (Bool, Maybe String, Maybe String) -> Map.Map Span [Ir] -> [String]+graphSimpleExp (ClaferId _ name) topLevel irMap = [graphSimpleName name topLevel irMap]+graphSimpleExp (EUnion _ set1 set2) topLevel irMap = graphSimpleExp set1 topLevel irMap ++ graphSimpleExp set2 topLevel irMap+graphSimpleExp (EUnionCom _ set1 set2) topLevel irMap = graphSimpleExp set1 topLevel irMap ++ graphSimpleExp set2 topLevel irMap+graphSimpleExp (EDifference _ set1 set2) topLevel irMap = graphSimpleExp set1 topLevel irMap ++ graphSimpleExp set2 topLevel irMap+graphSimpleExp (EIntersection _ set1 set2) topLevel irMap = graphSimpleExp set1 topLevel irMap ++ graphSimpleExp set2 topLevel irMap+graphSimpleExp (EDomain _ set1 set2) topLevel irMap = graphSimpleExp set1 topLevel irMap ++ graphSimpleExp set2 topLevel irMap+graphSimpleExp (ERange _ set1 set2) topLevel irMap = graphSimpleExp set1 topLevel irMap ++ graphSimpleExp set2 topLevel irMap+graphSimpleExp (EJoin _ set1 set2) topLevel irMap = graphSimpleExp set1 topLevel irMap ++ graphSimpleExp set2 topLevel irMap+graphSimpleExp _ _ _ = []++{-graphSimpleEnumId :: EnumId -> (Bool, Maybe String, Maybe String) -> Map.Map Span [Ir] -> String+graphSimpleEnumId (EnumIdIdent posident) _ irMap = graphSimplePosIdent posident irMap+graphSimpleEnumId (PosEnumIdIdent _ posident) topLevel irMap = graphSimpleEnumId (EnumIdIdent posident) topLevel irMap-}++-- CVL Printer --+--parent is Maybe the uid of the immediate parent+graphCVLModule :: Module -> Map.Map Span [Ir] -> String+graphCVLModule (Module _ []) _ = ""+graphCVLModule (Module s (x:xs)) irMap = graphCVLDeclaration x Nothing irMap ++ graphCVLModule (Module s xs) irMap++graphCVLDeclaration :: Declaration -> Maybe String -> Map.Map Span [Ir] -> String+graphCVLDeclaration (ElementDecl _ element) parent' irMap = graphCVLElement element parent' irMap+graphCVLDeclaration _ _ _ = ""++graphCVLElement :: Element -> Maybe String -> Map.Map Span [Ir] -> String+graphCVLElement (Subclafer _ clafer) parent' irMap = graphCVLClafer clafer parent' irMap+--graphCVLElement (ClaferUse _ name _ _) parent' irMap = if parent' == Nothing then "" else "?" ++ " -> " ++ graphCVLName name parent' irMap ++ " [arrowhead = onormal style = dashed constraint = false];\n"+graphCVLElement (ClaferUse s _ _ _) parent' irMap = if parent' == Nothing then "" else "?" ++ " -> " ++ getUseId s irMap ++ " [arrowhead = onormal style = dashed constraint = false];\n"+graphCVLElement (Subconstraint _ constraint) parent' irMap = graphCVLConstraint constraint parent' irMap+graphCVLElement (Subgoal _ constraint) parent' irMap = graphCVLGoal constraint parent' irMap+graphCVLElement (SubAssertion _ constraint) parent' irMap = graphCVLAssertion constraint parent' irMap++graphCVLElements :: Elements -> Maybe String -> Map.Map Span [Ir] -> String+graphCVLElements (ElementsEmpty _) _ _ = ""+graphCVLElements (ElementsList _ es) parent' irMap = concatMap (\x -> graphCVLElement x parent' irMap ++ "\n") es++graphCVLClafer :: Clafer -> Maybe String -> Map.Map Span [Ir] -> String+graphCVLClafer (Clafer s _ gCard _ super' reference' crd _ es) parent' irMap+ = let {{-tooltip = genTooltip (Module [ElementDecl (Subclafer (Clafer abstract gCard id' super' crd init' es))]) irMap;-}+ uid' = getDivId s irMap;+ gcrd = graphCVLGCard gCard parent' irMap;+ super'' = graphCVLSuper super' parent' irMap;+ reference'' = graphCVLReference reference' parent' irMap} in+ "\"" ++ uid' ++ "\" [URL=\"#" ++ uid' ++ "\" label=\"" ++ dropUid uid' ++ super'' ++ reference'' ++ (if choiceCard crd then "\" style=rounded" else " [" ++ graphCVLCard crd parent' irMap ++ "]\"")+ ++ (if super'' == "" then "" else " shape=oval") ++ "];\n"+ ++ (if gcrd == "" then "" else "g" ++ uid' ++ " [label=\"" ++ gcrd ++ "\" fontsize=10 shape=triangle];\ng" ++ uid' ++ " -> " ++ uid' ++ " [weight=10];\n")+ ++ (if parent'==Nothing then "" else uid' ++ " -> " ++ fromJust parent' ++ (if lowerCard crd == "0" then " [style=dashed]" else "") ++ ";\n")+ ++ graphCVLElements es (if gcrd == "" then (Just uid') else (Just $ "g" ++ uid')) irMap++graphCVLSuper :: Super -> Maybe String -> Map.Map Span [Ir] -> String+graphCVLSuper (SuperEmpty _) _ _ = ""+graphCVLSuper (SuperSome _ setExp) parent' irMap = ":" ++ concat (graphCVLExp setExp parent' irMap)++graphCVLReference :: Reference -> Maybe String -> Map.Map Span [Ir] -> String+graphCVLReference (ReferenceEmpty _) _ _ = ""+graphCVLReference (ReferenceSet _ setExp) parent' irMap = "->" ++ concat (graphCVLExp setExp parent' irMap)+graphCVLReference (ReferenceBag _ setExp) parent' irMap = "->>" ++ concat (graphCVLExp setExp parent' irMap)++graphCVLName :: Name -> Maybe String -> Map.Map Span [Ir] -> String+graphCVLName (Path _ modids) parent' irMap = unwords $ map (\x -> graphCVLModId x parent' irMap) modids++graphCVLModId :: ModId -> Maybe String -> Map.Map Span [Ir] -> String+graphCVLModId (ModIdIdent _ posident) _ irMap = graphCVLPosIdent posident irMap++graphCVLPosIdent :: PosIdent -> Map.Map Span [Ir] -> String+graphCVLPosIdent (PosIdent (pos, id')) irMap = getUid (PosIdent (pos, id')) irMap++graphCVLConstraint :: Constraint -> Maybe String -> Map.Map Span [Ir] -> String+graphCVLConstraint (Constraint s exps') parent' irMap = let body' = htmlChars $ genTooltip (Module s [ElementDecl s (Subconstraint s (Constraint s exps'))]) irMap;+ uid' = "\"" ++ getExpId s irMap ++ "\""+ in uid' ++ " [label=\"" ++ body' ++ "\" shape=parallelogram];\n" +++ if parent' == Nothing then "" else uid' ++ " -> \"" ++ fromJust parent' ++ "\";\n"++graphCVLAssertion :: Assertion -> Maybe String -> Map.Map Span [Ir] -> String+graphCVLAssertion (Assertion s exps') parent' irMap = let body' = htmlChars $ genTooltip (Module s [ElementDecl s (SubAssertion s (Assertion s exps'))]) irMap;+ uid' = "\"" ++ getExpId s irMap ++ "\""+ in uid' ++ " [label=\"" ++ body' ++ "\" shape=parallelogram];\n" +++ if parent' == Nothing then "" else uid' ++ " -> \"" ++ fromJust parent' ++ "\";\n"++graphCVLGoal :: Goal -> Maybe String -> Map.Map Span [Ir] -> String+graphCVLGoal goal parent' irMap = let+ s = getSpan goal+ body' = htmlChars $ genTooltip (Module s [ElementDecl s (Subgoal s goal)]) irMap+ uid' = "\"" ++ getExpId s irMap ++ "\""+ in+ uid' +++ " [label=\"" ++ body' ++ "\" shape=parallelogram];\n" +++ if parent' == Nothing+ then ""+ else uid' ++ " -> \"" ++ fromJust parent' ++ "\";\n"++graphCVLCard :: Card -> Maybe String -> Map.Map Span [Ir] -> String+graphCVLCard (CardEmpty _) _ _ = "1..1"+graphCVLCard (CardLone _) _ _ = "0..1"+graphCVLCard (CardSome _) _ _ = "1..*"+graphCVLCard (CardAny _) _ _ = "0..*"+graphCVLCard (CardNum _ (PosInteger (_, n))) _ _ = n ++ ".." ++ n+graphCVLCard (CardInterval _ ncard) parent' irMap = graphCVLNCard ncard parent' irMap++graphCVLNCard :: NCard -> Maybe String -> Map.Map Span [Ir] -> String+graphCVLNCard (NCard _ (PosInteger (_, num)) exInteger) parent' irMap = num ++ ".." ++ graphCVLExInteger exInteger parent' irMap++graphCVLExInteger :: ExInteger -> Maybe String -> Map.Map Span [Ir] -> String+graphCVLExInteger (ExIntegerAst _) _ _ = "*"+graphCVLExInteger (ExIntegerNum _ (PosInteger(_, num))) _ _ = num++graphCVLGCard :: GCard -> Maybe String -> Map.Map Span [Ir] -> String+graphCVLGCard (GCardInterval _ ncard) parent' irMap = graphCVLNCard ncard parent' irMap+graphCVLGCard (GCardEmpty _) _ _ = ""+graphCVLGCard (GCardXor _) _ _ = "1..1"+graphCVLGCard (GCardOr _) _ _ = "1..*"+graphCVLGCard (GCardMux _) _ _ = "0..1"+graphCVLGCard (GCardOpt _) _ _ = ""+++{-graphCVLDecl _ _ _ = ""+graphCVLInit _ _ _ = ""+graphCVLInitHow _ _ _ = ""+graphCVLExp _ _ _ = ""+graphCVLQuant _ _ _ = ""+graphCVLGoal _ _ _ = ""+graphCVLAssertion _ _ _ = ""+graphCVLAbstract _ _ _ = ""-}++graphCVLExp :: Exp -> Maybe String -> Map.Map Span [Ir] -> [String]+graphCVLExp (ClaferId _ name) parent' irMap = [graphCVLName name parent' irMap]+graphCVLExp (EUnion _ set1 set2) parent' irMap = graphCVLExp set1 parent' irMap ++ graphCVLExp set2 parent' irMap+graphCVLExp (EUnionCom _ set1 set2) parent' irMap = graphCVLExp set1 parent' irMap ++ graphCVLExp set2 parent' irMap+graphCVLExp (EDifference _ set1 set2) parent' irMap = graphCVLExp set1 parent' irMap ++ graphCVLExp set2 parent' irMap+graphCVLExp (EIntersection _ set1 set2) parent' irMap = graphCVLExp set1 parent' irMap ++ graphCVLExp set2 parent' irMap+graphCVLExp (EDomain _ set1 set2) parent' irMap = graphCVLExp set1 parent' irMap ++ graphCVLExp set2 parent' irMap+graphCVLExp (ERange _ set1 set2) parent' irMap = graphCVLExp set1 parent' irMap ++ graphCVLExp set2 parent' irMap+graphCVLExp (EJoin _ set1 set2) parent' irMap = graphCVLExp set1 parent' irMap ++ graphCVLExp set2 parent' irMap+graphCVLExp _ _ _ = []++{-graphCVLEnumId (EnumIdIdent posident) _ irMap = graphCVLPosIdent posident irMap+graphCVLEnumId (PosEnumIdIdent _ posident) parent irMap = graphCVLEnumId (EnumIdIdent posident) parent irMap-}++choiceCard :: Card -> Bool+choiceCard (CardEmpty _) = True+choiceCard (CardLone _) = True+choiceCard (CardInterval _ (NCard _ (PosInteger (_, low)) exInteger)) = if low == "0" || low == "1"+ then case exInteger of+ (ExIntegerAst _) -> False+ (ExIntegerNum _ (PosInteger (_, high))) -> high == "0" || high == "1"+ else False+choiceCard _ = False++lowerCard :: Card -> String+lowerCard crd = takeWhile (/= '.') $ graphCVLCard crd Nothing Map.empty++--Miscellaneous functions+dropUid :: String -> String+dropUid uid' = let id' = rest $ dropWhile (\x -> x /= '_') uid' in if id' == "" then uid' else id'++rest :: String -> String+rest [] = []+rest (_:xs) = xs++getUid :: PosIdent -> Map.Map Span [Ir] -> String+getUid (PosIdent (pos, id')) irMap = if Map.lookup (getSpan (PosIdent (pos, id'))) irMap == Nothing+ then id'+ else let IRPExp pexp = head $ fromJust $ Map.lookup (getSpan (PosIdent (pos, id'))) irMap in+ findUid id' $ getIdentPExp pexp+ where {getIdentPExp (PExp _ _ _ exp') = getIdentIExp exp';+ getIdentIExp (IFunExp _ exps') = concatMap getIdentPExp exps';+ getIdentIExp (IClaferId _ id'' _ _) = [id''];+ getIdentIExp (IDeclPExp _ _ pexp) = getIdentPExp pexp;+ getIdentIExp _ = [];+ findUid name (x:xs) = if name == dropUid x then x else findUid name xs;+ findUid name [] = name}++getDivId :: Span -> Map.Map Span [Ir] -> String+getDivId s irMap = if Map.lookup s irMap == Nothing+ then "Uid not Found"+ else let IRClafer iClaf = head $ fromJust $ Map.lookup s irMap in+ _uid iClaf++getUseId :: Span -> Map.Map Span [Ir] -> String+getUseId s irMap = if Map.lookup s irMap == Nothing+ then "Uid not Found"+ else let+ IRClafer iClaf = head $ fromJust $ Map.lookup s irMap+ in+ fromMaybe "" $ _sident <$> _exp <$> _super iClaf++getExpId :: Span -> Map.Map Span [Ir] -> String+getExpId s irMap = if Map.lookup s irMap == Nothing+ then "Uid not Found"+ else let IRPExp pexp = head $ fromJust $ Map.lookup s irMap in _pid pexp++{-while :: Bool -> [IExp] -> [IExp]+while bool exp' = if bool then exp' else []-}++htmlChars :: String -> String+htmlChars "" = ""+htmlChars ('\n':xs) = " " ++ htmlChars xs+htmlChars ('\"':xs) = """ ++ htmlChars xs+htmlChars ('\'':xs) = "'" ++ htmlChars xs+htmlChars ('&':xs) = "&" ++ htmlChars xs+htmlChars ('~':xs) = "˜" ++ htmlChars xs+htmlChars ('-':'>':'>':xs) = "->>" ++ htmlChars xs+htmlChars ('-':'>':xs) = "->" ++ htmlChars xs+htmlChars (x:xs) = x:htmlChars xs++cleanOutput :: String -> String+cleanOutput "" = ""+cleanOutput (' ':'\n':xs) = cleanOutput $ '\n':xs+cleanOutput ('\n':'\n':xs) = cleanOutput $ '\n':xs+cleanOutput (' ':'<':'b':'r':'>':xs) = "<br>"++cleanOutput xs+cleanOutput (x:xs) = x : cleanOutput xs
src/Language/Clafer/Generator/Html.hs view
@@ -1,472 +1,472 @@-{- - Copyright (C) 2012 Christopher Walker, Michal Antkiewicz <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} --- | Generates HTML and plain text rendering of a Clafer model. -module Language.Clafer.Generator.Html - ( genHtml - , genText - , genTooltip - , printModule - , printDeclaration - , printDecl - , traceAstModule - , traceIrModule - , cleanOutput - , revertLayout - , printComment - , printPreComment - , printStandaloneComment - , printInlineComment - , highlightErrors - ) where - -import Language.ClaferT -import Language.Clafer.Front.AbsClafer -import Language.Clafer.Front.LayoutResolver(revertLayout) -import Language.Clafer.Intermediate.Tracing -import Language.Clafer.Intermediate.Intclafer - -import Control.Applicative -import Data.List (intersperse,genericSplitAt) -import qualified Data.Map as Map -import Data.Maybe -import Data.Char (isSpace) -import Prelude hiding (exp) - -printPreComment :: Span -> [(Span, String)] -> ([(Span, String)], String) -printPreComment _ [] = ([], []) -printPreComment (Span (Pos r _) _) (c@((Span (Pos r' _) _), _):cs) - | r > r' = findAll r ((c:cs), []) - | otherwise = (c:cs, "") - where findAll _ ([],comments) = ([],comments) - findAll row ((c'@((Span (Pos row' col') _), comment):cs'), comments) - | row > row' = case take 3 comment of - '/':'/':'#':[] -> findAll row (cs', concat [comments, "<!-- " ++ trim (drop 2 comment) ++ " /-->\n"]) - '/':'/':_:[] -> if col' == 1 - then findAll row (cs', concat [comments, printStandaloneComment comment ++ "\n"]) - else findAll row (cs', concat [comments, printInlineComment comment ++ "\n"]) - '/':'*':_:[] -> findAll row (cs', concat [comments, printStandaloneComment comment ++ "\n"]) - _ -> (cs', "") - | otherwise = ((c':cs'), comments) -printComment :: Span -> [(Span, String)] -> ([(Span, String)], String) -printComment _ [] = ([],[]) -printComment (Span (Pos row _) _) (c@(Span (Pos row' col') _, comment):cs) - | row == row' = case take 3 comment of - '/':'/':'#':[] -> (cs,"<!-- " ++ trim' (drop 2 comment) ++ " /-->\n") - '/':'/':_:[] -> if col' == 1 - then (cs, printStandaloneComment comment ++ "\n") - else (cs, printInlineComment comment ++ "\n") - '/':'*':_:[] -> (cs, printStandaloneComment comment ++ "\n") - _ -> (cs, "") - | otherwise = (c:cs, "") - where trim' = let f = reverse. dropWhile isSpace in f . f -printStandaloneComment :: String -> String -printStandaloneComment comment = "<div class=\"standalonecomment\">" ++ replaceNLwithBR comment ++ "</div>" - where - replaceNLwithBR :: String -> String - replaceNLwithBR "" = "" - replaceNLwithBR ('\n':cs) = "<br>\n" ++ replaceNLwithBR cs - replaceNLwithBR (c:cs) = c : replaceNLwithBR cs - - -printInlineComment :: String -> String -printInlineComment comment = "<span class=\"inlinecomment\">" ++ comment ++ "</span>" - -printDeprecated :: String -> String -> Bool -> String -printDeprecated s m html = (while html $ "<span class=\"deprecated\" title=\"" ++ "Deprecated. " ++ m ++ "\">") - ++ s - ++ (while html "</span>") - --- | Generate the model as HTML document -genHtml :: Module -> IModule -> String -genHtml x ir = cleanOutput $ revertLayout $ printModule x (traceIrModule ir) True --- | Generate the model as plain text --- | This is used by the graph generator for tooltips -genText :: Module -> IModule -> String -genText x ir = cleanOutput $ revertLayout $ printModule x (traceIrModule ir) False -genTooltip :: Module -> Map.Map Span [Ir] -> String -genTooltip m ir = unlines $ filter (\x -> trim x /= []) $ lines $ cleanOutput $ revertLayout $ printModule m ir False - -printModule :: Module -> Map.Map Span [Ir] -> Bool -> String -printModule (Module _ []) _ _ = "" -printModule (Module s (x:xs)) irMap html = (printDeclaration x 0 irMap html []) ++ printModule (Module s xs) irMap html - -printDeclaration :: Declaration -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printDeclaration (EnumDecl s posIdent enumIds) indent irMap html comments = - preComments ++ - printIndentId 0 html ++ - (while html "<span class=\"keyword\">") ++ "enum" ++ (while html "</span>") ++ - " " ++ - (printPosIdent posIdent mUid' html) ++ - " = " ++ - (concat $ intersperse " | " (map (\x -> printEnumId x indent irMap html comments) enumIds)) ++ - comment ++ - printIndentEnd html - where - mUid' = getUid posIdent irMap; - (comments', preComments) = printPreComment s comments; - (_, comment) = printComment s comments' -printDeclaration (ElementDecl _ element) indent irMap html comments = printElement element indent irMap html comments - -printElement :: Element -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printElement (Subclafer _ clafer) indent irMap html comments = printClafer clafer indent irMap html comments - -printElement (ClaferUse s name crd es) indent irMap html comments = - preComments ++ - printIndentId indent html ++ - "`" ++ (while html ("<a href=\"#" ++ superId ++ "\"><span class=\"reference\">")) ++ - printName name indent irMap False [] --trick the printer into only printing the name - ++ (while html "</span></a>") ++ - printCard crd ++ - comment ++ - printIndentEnd html ++ - printElements es indent irMap html comments'' - where - (_, superId) = getUseId s irMap; - (comments', preComments) = printPreComment s comments; - (comments'', comment) = printComment s comments' - -printElement (Subgoal s goal) indent irMap html comments = - preComments ++ - printIndent 0 html ++ - printGoal goal indent irMap html comments'' ++ - comment ++ - printIndentEnd html - where - (comments', preComments) = printPreComment s comments; - (comments'', comment) = printComment s comments' - -printElement (Subconstraint s constraint) indent irMap html comments = - preComments ++ - printIndent indent html ++ - printConstraint constraint indent irMap html comments'' ++ - comment ++ - printIndentEnd html - where - (comments', preComments) = printPreComment s comments; - (comments'', comment) = printComment s comments' - -printElement (SubAssertion s constraint) indent irMap html comments = - preComments ++ - printIndent indent html ++ - printAssertion constraint indent irMap html comments'' ++ - comment ++ - printIndentEnd html - where - (comments', preComments) = printPreComment s comments; - (comments'', comment) = printComment s comments' - -printElements :: Elements -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printElements (ElementsEmpty _) _ _ _ _ = "" -printElements (ElementsList _ es) indent irMap html comments = "\n{" ++ mapElements es indent irMap html comments ++ "\n}" - where mapElements [] _ _ _ _ = [] - mapElements (e':es') indent' irMap' html' comments' = if span' e' == noSpan - then (printElement e' (indent' + 1) irMap' html' comments' {-++ "\n"-}) ++ mapElements es' indent' irMap' html' comments' - else (printElement e' (indent' + 1) irMap' html' comments' {-++ "\n"-}) ++ mapElements es' indent' irMap' html' (afterSpan (span' e') comments') - afterSpan s comments' = let (Span _ (Pos line _)) = s in dropWhile (\(x, _) -> let (Span _ (Pos line' _)) = x in line' <= line) comments' - span' (Subclafer s _) = s - span' (Subconstraint s _) = s - span' (ClaferUse s _ _ _) = s - span' (Subgoal s _) = s - span' (SubAssertion s _) = s - -printClafer :: Clafer -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printClafer (Clafer s abstract gCard id' super' reference' crd init' es) indent irMap html comments = - preComments ++ - printIndentId indent html ++ - claferDeclaration ++ - comment ++ - printElements es indent irMap html comments'' ++ - printIndentEnd html - where - uid' = getDivId s irMap; - (comments', preComments) = printPreComment s comments; - (comments'', comment) = printComment s comments' - claferDeclaration = concat [ - printAbstract abstract html, - printGCard gCard html, - printPosIdent id' (Just uid') html, - printSuper super' indent irMap html comments, - printReference reference' indent irMap html comments, - printCard crd, - printInit init' indent irMap html comments] - -printGoal :: Goal -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printGoal goal indent irMap html comments = - (if html then "<<" else "<<") ++ - (case goal of - (GoalMinimize _ exps') -> (while html "<span class=\"keyword\">") ++ "minimize" ++ (while html "</span>") ++ " " ++ concatMap (\x -> printExp x indent irMap html comments) exps' - (GoalMaximize _ exps') -> (while html "<span class=\"keyword\">") ++ "maximize" ++ (while html "</span>") ++ " " ++ concatMap (\x -> printExp x indent irMap html comments) exps' - (GoalMinDeprecated _ exps') -> printDeprecated "min " "Use `minimize` instead." html ++ concatMap (\x -> printExp x indent irMap html comments) exps' - (GoalMaxDeprecated _ exps') -> printDeprecated "max " "Use `maximize` instead." html ++ concatMap (\x -> printExp x indent irMap html comments) exps' - ) ++ - if html then ">>" else ">>" - -printAbstract :: Abstract -> Bool -> String -printAbstract (Abstract _) html = (while html "<span class=\"keyword\">") ++ "abstract" ++ (while html "</span>") ++ " " -printAbstract (AbstractEmpty _) _ = "" - -printGCard :: GCard -> Bool -> String -printGCard gCard html = case gCard of - (GCardInterval _ ncard) -> printNCard ncard - (GCardEmpty _) -> "" - (GCardXor _) -> (while html "<span class=\"keyword\">") ++ "xor" ++ (while html "</span>") ++ " " - (GCardOr _) -> (while html "<span class=\"keyword\">") ++ "or" ++ (while html "</span>") ++ " " - (GCardMux _) -> (while html "<span class=\"keyword\">") ++ "mux" ++ (while html "</span>") ++ " " - (GCardOpt _) -> (while html "<span class=\"keyword\">") ++ "opt" ++ (while html "</span>") ++ " " - -printNCard :: NCard -> String -printNCard (NCard _ (PosInteger (_, num)) exInteger) = num ++ ".." ++ printExInteger exInteger ++ " " - -printExInteger :: ExInteger -> String -printExInteger (ExIntegerAst _) = "*" -printExInteger (ExIntegerNum _ (PosInteger(_, num))) = num - -printName :: Name -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printName (Path _ modids) indent irMap html comments = unwords $ map (\x -> printModId x indent irMap html comments) modids - -printModId :: ModId -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printModId (ModIdIdent _ posident) _ irMap html _ = printPosIdentRef posident irMap html - -printPosIdent :: PosIdent -> Maybe String -> Bool -> String -printPosIdent (PosIdent (_, id')) Nothing _ = id' -printPosIdent (PosIdent (_, id')) (Just uid') html = (while html $ "<span class=\"claferDecl\" id=\"" ++ uid' ++ "\">") ++ id' ++ (while html "</span>") - -printPosIdentRef :: PosIdent -> Map.Map Span [Ir] -> Bool -> String -printPosIdentRef (PosIdent (_, "dref")) _ html - = (while html "<span class=\"keyword\">") ++ "dref" ++ (while html "</span>") -printPosIdentRef (PosIdent (_, "this")) _ html - = (while html "<span class=\"keyword\">") ++ "this" ++ (while html "</span>") -printPosIdentRef (PosIdent (_, "parent")) _ html - = (while html "<span class=\"keyword\">") ++ "parent" ++ (while html "</span>") -printPosIdentRef (PosIdent (_, "root")) _ html - = (while html "<span class=\"keyword\">") ++ "root" ++ (while html "</span>") -printPosIdentRef (PosIdent (_, "ref")) _ html - = printDeprecated "ref" "Use `dref` instead." html -printPosIdentRef (PosIdent (_, id')) _ False = id' -printPosIdentRef (PosIdent (p, id')) irMap True - = case mUid' of - Just uid' -> "<a href=\"#" ++ uid' ++ "\"><span class=\"reference\">" ++ id' ++ "</span></a>" - Nothing -> id' - where - mUid' = getUid (PosIdent (p, id')) irMap - -printSuper :: Super -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printSuper (SuperEmpty _) _ _ _ _ = "" -printSuper (SuperSome _ setExp) indent irMap html comments = (while html "<span class=\"keyword\">") ++ " : " ++ (while html "</span>") ++ printExp setExp indent irMap html comments - -printReference :: Reference -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printReference (ReferenceEmpty _) _ _ _ _ = "" -printReference (ReferenceSet _ setExp) indent irMap html comments = (while html "<span class=\"keyword\">") ++ " -> " ++ (while html "</span>") ++ printExp setExp indent irMap html comments -printReference (ReferenceBag _ setExp) indent irMap html comments = (while html "<span class=\"keyword\">") ++ " ->> " ++ (while html "</span>") ++ printExp setExp indent irMap html comments - - -printCard :: Card -> String -printCard (CardEmpty _) = "" -printCard (CardLone _) = " ?" -printCard (CardSome _) = " +" -printCard (CardAny _) = " *" -printCard (CardNum _ (PosInteger (_,num))) = " " ++ num -printCard (CardInterval _ nCard) = " " ++ printNCard nCard - -printConstraint :: Constraint -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printConstraint (Constraint _ exps') indent irMap html comments = (concatMap (\x -> printConstraint' x indent irMap html comments) exps') - -printConstraint' :: Exp -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printConstraint' exp' indent irMap html comments = - while html "<span class=\"keyword\">" ++ "[" ++ while html "</span>" ++ - " " ++ - printExp exp' indent irMap html comments ++ - " " ++ - while html "<span class=\"keyword\">" ++ "]" ++ while html "</span>" - -printAssertion :: Assertion -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printAssertion (Assertion _ exps') indent irMap html comments = concatMap (\x -> printAssertion' x indent irMap html comments) exps' -printAssertion' :: Exp -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printAssertion' exp' indent' irMap html comments = - while html "<span class=\"keyword\">" ++ "assert [" ++ while html "</span>" ++ - " " ++ - printExp exp' indent' irMap html comments ++ - " " ++ - while html "<span class=\"keyword\">" ++ "]" ++ while html "</span>" - -printDecl :: Decl-> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printDecl (Decl _ locids setExp) indent irMap html comments = - (concat $ intersperse "; " $ map printLocId locids) ++ - (while html "<span class=\"keyword\">") ++ " : " ++ (while html "</span>") ++ printExp setExp indent irMap html comments - where - printLocId :: LocId -> String - printLocId (LocIdIdent _ (PosIdent (_, ident'))) = ident' - -printInit :: Init -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printInit (InitEmpty _) _ _ _ _ = "" -printInit (InitSome _ initHow exp') indent irMap html comments = printInitHow initHow ++ printExp exp' indent irMap html comments - -printInitHow :: InitHow -> String -printInitHow (InitConstant _) = " = " -printInitHow (InitDefault _) = " := " - -printExp :: Exp -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printExp (EDeclAllDisj _ decl exp') indent irMap html comments = "all disj " ++ (printDecl decl indent irMap html comments) ++ " | " ++ (printExp exp' indent irMap html comments) -printExp (EDeclAll _ decl exp') indent irMap html comments = "all " ++ (printDecl decl indent irMap html comments) ++ " | " ++ (printExp exp' indent irMap html comments) -printExp (EDeclQuantDisj _ quant' decl exp') indent irMap html comments = (printQuant quant' html) ++ "disj" ++ (printDecl decl indent irMap html comments) ++ " | " ++ (printExp exp' indent irMap html comments) -printExp (EDeclQuant _ quant' decl exp') indent irMap html comments = (printQuant quant' html) ++ (printDecl decl indent irMap html comments) ++ " | " ++ (printExp exp' indent irMap html comments) -printExp (EGMax _ exp') indent irMap html comments = "max " ++ printExp exp' indent irMap html comments -printExp (EGMin _ exp') indent irMap html comments = "min " ++ printExp exp' indent irMap html comments -printExp (ENeq _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ " != " ++ (printExp exp'2 indent irMap html comments) -printExp (EQuantExp _ quant' exp') indent irMap html comments = printQuant quant' html ++ printExp exp' indent irMap html comments -printExp (EImplies _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " => " else " => ") ++ printExp exp'2 indent irMap html comments -printExp (EAnd _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " && " else " && ") ++ printExp exp'2 indent irMap html comments -printExp (EOr _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " || " else " || ") ++ printExp exp'2 indent irMap html comments -printExp (EXor _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ " xor " ++ printExp exp'2 indent irMap html comments -printExp (ENeg _ exp') indent irMap html comments = " ! " ++ printExp exp' indent irMap html comments -printExp (ELt _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " < " else " < ") ++ printExp exp'2 indent irMap html comments -printExp (EGt _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " > " else " > ") ++ printExp exp'2 indent irMap html comments -printExp (EEq _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ " = " ++ printExp exp'2 indent irMap html comments -printExp (ELte _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " <= " else " <= ") ++ printExp exp'2 indent irMap html comments -printExp (EGte _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " >= " else " >= ") ++ printExp exp'2 indent irMap html comments -printExp (EIn _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ " in " ++ printExp exp'2 indent irMap html comments -printExp (ENin _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ " not in " ++ printExp exp'2 indent irMap html comments -printExp (EIff _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " <=> " else " <=> ") ++ printExp exp'2 indent irMap html comments -printExp (EAdd _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ " + " ++ printExp exp'2 indent irMap html comments -printExp (ESub _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ " - " ++ printExp exp'2 indent irMap html comments -printExp (EMul _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ " * " ++ printExp exp'2 indent irMap html comments -printExp (EDiv _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " / " else " / ") ++ printExp exp'2 indent irMap html comments -printExp (ERem _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " % " else " % ") ++ printExp exp'2 indent irMap html comments -printExp (ESum _ exp') indent irMap html comments = "sum " ++ printExp exp' indent irMap html comments -printExp (EProd _ exp') indent irMap html comments = "product " ++ printExp exp' indent irMap html comments -printExp (ECard _ exp') indent irMap html comments = "# " ++ printExp exp' indent irMap html comments -printExp (EMinExp _ exp') indent irMap html comments = "-" ++ printExp exp' indent irMap html comments -printExp (EImpliesElse _ exp'1 exp'2 exp'3) indent irMap html comments = "if " ++ (printExp exp'1 indent irMap html comments) ++ " then " ++ (printExp exp'2 indent irMap html comments) ++ " else " ++ (printExp exp'3 indent irMap html comments) -printExp (ClaferId _ name) indent irMap html comments = printName name indent irMap html comments -printExp (EUnion _ set1 set2) indent irMap html comments = (printExp set1 indent irMap html comments) ++ "++" ++ (printExp set2 indent irMap html comments) -printExp (EUnionCom _ set1 set2) indent irMap html comments = (printExp set1 indent irMap html comments) ++ ", " ++ (printExp set2 indent irMap html comments) -printExp (EDifference _ set1 set2) indent irMap html comments = (printExp set1 indent irMap html comments) ++ "--" ++ (printExp set2 indent irMap html comments) -printExp (EIntersection _ set1 set2) indent irMap html comments = (printExp set1 indent irMap html comments) ++ "**" ++ (printExp set2 indent irMap html comments) -printExp (EIntersectionDeprecated _ set1 set2) indent irMap html comments = (printExp set1 indent irMap html comments) ++ printDeprecated "&" "Use `**` instead." html ++ (printExp set2 indent irMap html comments) -printExp (EDomain _ set1 set2) indent irMap html comments = (printExp set1 indent irMap html comments) ++ "<:" ++ (printExp set2 indent irMap html comments) -printExp (ERange _ set1 set2) indent irMap html comments = (printExp set1 indent irMap html comments) ++ ":>" ++ (printExp set2 indent irMap html comments) -printExp (EJoin _ set1 set2) indent irMap html comments = (printExp set1 indent irMap html comments) ++ "." ++ (printExp set2 indent irMap html comments) -printExp (EInt _ (PosInteger (_, num))) _ _ _ _ = num -printExp (EDouble _ (PosDouble (_, num))) _ _ _ _ = num -printExp (EReal _ (PosReal (_, num))) _ _ _ _ = num -printExp (EStr _ (PosString (_, str))) _ _ _ _ = str - -printQuant :: Quant -> Bool -> String -printQuant quant' html = case quant' of - (QuantNo _) -> (while html "<span class=\"keyword\">") ++ "no" ++ (while html "</span>") ++ " " - (QuantNot _) -> (while html "<span class=\"keyword\">") ++ "not" ++ (while html "</span>") ++ " " - (QuantLone _) -> (while html "<span class=\"keyword\">") ++ "lone" ++ (while html "</span>") ++ " " - (QuantOne _) -> (while html "<span class=\"keyword\">") ++ "one" ++ (while html "</span>") ++ " " - (QuantSome _) -> (while html "<span class=\"keyword\">") ++ "some" ++ (while html "</span>") ++ " " - -printEnumId :: EnumId -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String -printEnumId (EnumIdIdent _ posident) _ irMap html _ = printPosIdent posident mUid' html - where - mUid' = getUid posident irMap - -printIndent :: Int -> Bool -> String -printIndent 0 html = (while html "<div>") ++ "\n" -printIndent _ html = (while html "<div class=\"indent\">") ++ "\n" - -printIndentId :: Int -> Bool -> String -printIndentId 0 html = while html ("<div>") ++ "\n" -printIndentId _ html = while html ("<div class=\"indent\">") ++ "\n" - -printIndentEnd :: Bool -> String -printIndentEnd html = (while html "</div>") ++ "\n" - -dropUid :: String -> String -dropUid uid' = let id' = rest $ dropWhile (/= '_') uid' - in if id' == "" - then uid' - else id' - ---so it fails more gracefully on empty lists -{-first :: String -> String -first [] = [] -first (x:_) = x-} -rest :: String -> String -rest [] = [] -rest (_:xs) = xs - -getUid :: PosIdent -> Map.Map Span [Ir] -> Maybe String -getUid posIdent@(PosIdent (_, id')) irMap = - case Map.lookup (getSpan posIdent) irMap of - Nothing -> Nothing - Just wrappedResultList -> listToMaybe $ catMaybes $ map (findUid id') $ map unwrap wrappedResultList - where - unwrap (IRPExp pexp') = getIdentPExp pexp' - unwrap (IRClafer iClafer') = [ _uid iClafer' ] - unwrap x = error $ "Html:getUid:unwrap called on: " ++ show x - getIdentPExp (PExp _ _ _ exp') = getIdentIExp exp' - getIdentIExp (IFunExp _ exps') = concatMap getIdentPExp exps' - getIdentIExp (IClaferId _ id'' _ _) = [id''] - getIdentIExp (IDeclPExp _ _ pexp) = getIdentPExp pexp - getIdentIExp _ = [] - findUid name (x:xs) = if name == dropUid x then Just x else findUid name xs - findUid _ [] = Nothing - -getDivId :: Span -> Map.Map Span [Ir] -> String -getDivId s irMap = if Map.lookup s irMap == Nothing - then "Uid not Found" - else let IRClafer iClaf = head $ fromJust $ Map.lookup s irMap in - _uid iClaf - -getUseId :: Span -> Map.Map Span [Ir] -> (String, String) -getUseId s irMap = if Map.lookup s irMap == Nothing - then ("Uid not Found", "Uid not Found") - else let IRClafer iClaf = head $ fromJust $ Map.lookup s irMap in - (_uid iClaf, fromMaybe "" $ _sident <$> _exp <$> _super iClaf) - -while :: Bool -> String -> String -while bool exp' = if bool then exp' else "" - -cleanOutput :: String -> String -cleanOutput "" = "" -cleanOutput (' ':'\n':xs) = cleanOutput $ '\n':xs -cleanOutput ('\n':'\n':xs) = cleanOutput $ '\n':xs -cleanOutput (' ':'<':'b':'r':'>':xs) = "<br>"++cleanOutput xs -cleanOutput (x:xs) = x : cleanOutput xs - -trim :: String -> String -trim = let f = reverse . dropWhile isSpace in f . f - -highlightErrors :: String -> [ClaferErr] -> String -highlightErrors model errors = "<pre>\n" ++ unlines (replace "<!-- # FRAGMENT /-->" "</pre>\n<!-- # FRAGMENT /-->\n<pre>" --assumes the fragments have been concatenated - (highlightErrors' (replace "//# FRAGMENT" "<!-- # FRAGMENT /-->" (lines model)) errors)) ++ "</pre>" - where - replace _ _ [] = [] - replace x y (z:zs) = (if x == z then y else z):replace x y zs - -highlightErrors' :: [String] -> [ClaferErr] -> [String] -highlightErrors' model' [] = model' -highlightErrors' model' ((ClaferErr _):es) = highlightErrors' model' es -highlightErrors' model' ((ParseErr ErrPos{modelPos = Pos l c, fragId = n} msg'):es) = - let (ls, lss) = genericSplitAt (l + toInteger n) model' - newLine = fst (genericSplitAt (c - 1) $ last ls) ++ "<span class=\"error\" title=\"Parsing failed at line " ++ show l ++ " column " ++ show c ++ - "...\n" ++ msg' ++ "\">" ++ (if snd (genericSplitAt (c - 1) $ last ls) == "" then " " else snd (genericSplitAt (c - 1) $ last ls)) ++ "</span>" - in highlightErrors' (init ls ++ [newLine] ++ lss) es -highlightErrors' model' ((SemanticErr ErrPos{modelPos = Pos l c, fragId = n} msg'):es) = - let (ls, lss) = genericSplitAt (l + toInteger n) model' - newLine = fst (genericSplitAt (c - 1) $ last ls) ++ "<span class=\"error\" title=\"Compiling failed at line " ++ show l ++ " column " ++ show c ++ - "...\n" ++ msg' ++ "\">" ++ (if snd (genericSplitAt (c - 1) $ last ls) == "" then " " else snd (genericSplitAt (c - 1) $ last ls)) ++ "</span>" - in highlightErrors' (init ls ++ [newLine] ++ lss) es +{-+ Copyright (C) 2012 Christopher Walker, Michal Antkiewicz <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+-- | Generates HTML and plain text rendering of a Clafer model.+module Language.Clafer.Generator.Html+ ( genHtml+ , genText+ , genTooltip+ , printModule+ , printDeclaration+ , printDecl+ , traceAstModule+ , traceIrModule+ , cleanOutput+ , revertLayout+ , printComment+ , printPreComment+ , printStandaloneComment+ , printInlineComment+ , highlightErrors+ ) where++import Language.ClaferT+import Language.Clafer.Front.AbsClafer+import Language.Clafer.Front.LayoutResolver(revertLayout)+import Language.Clafer.Intermediate.Tracing+import Language.Clafer.Intermediate.Intclafer++import Control.Applicative+import Data.List (intersperse,genericSplitAt)+import qualified Data.Map as Map+import Data.Maybe+import Data.Char (isSpace)+import Prelude hiding (exp)++printPreComment :: Span -> [(Span, String)] -> ([(Span, String)], String)+printPreComment _ [] = ([], [])+printPreComment (Span (Pos r _) _) (c@((Span (Pos r' _) _), _):cs)+ | r > r' = findAll r ((c:cs), [])+ | otherwise = (c:cs, "")+ where findAll _ ([],comments) = ([],comments)+ findAll row ((c'@((Span (Pos row' col') _), comment):cs'), comments)+ | row > row' = case take 3 comment of+ '/':'/':'#':[] -> findAll row (cs', concat [comments, "<!-- " ++ trim (drop 2 comment) ++ " /-->\n"])+ '/':'/':_:[] -> if col' == 1+ then findAll row (cs', concat [comments, printStandaloneComment comment ++ "\n"])+ else findAll row (cs', concat [comments, printInlineComment comment ++ "\n"])+ '/':'*':_:[] -> findAll row (cs', concat [comments, printStandaloneComment comment ++ "\n"])+ _ -> (cs', "")+ | otherwise = ((c':cs'), comments)+printComment :: Span -> [(Span, String)] -> ([(Span, String)], String)+printComment _ [] = ([],[])+printComment (Span (Pos row _) _) (c@(Span (Pos row' col') _, comment):cs)+ | row == row' = case take 3 comment of+ '/':'/':'#':[] -> (cs,"<!-- " ++ trim' (drop 2 comment) ++ " /-->\n")+ '/':'/':_:[] -> if col' == 1+ then (cs, printStandaloneComment comment ++ "\n")+ else (cs, printInlineComment comment ++ "\n")+ '/':'*':_:[] -> (cs, printStandaloneComment comment ++ "\n")+ _ -> (cs, "")+ | otherwise = (c:cs, "")+ where trim' = let f = reverse. dropWhile isSpace in f . f+printStandaloneComment :: String -> String+printStandaloneComment comment = "<div class=\"standalonecomment\">" ++ replaceNLwithBR comment ++ "</div>"+ where+ replaceNLwithBR :: String -> String+ replaceNLwithBR "" = ""+ replaceNLwithBR ('\n':cs) = "<br>\n" ++ replaceNLwithBR cs+ replaceNLwithBR (c:cs) = c : replaceNLwithBR cs+++printInlineComment :: String -> String+printInlineComment comment = "<span class=\"inlinecomment\">" ++ comment ++ "</span>"++printDeprecated :: String -> String -> Bool -> String+printDeprecated s m html = (while html $ "<span class=\"deprecated\" title=\"" ++ "Deprecated. " ++ m ++ "\">")+ ++ s+ ++ (while html "</span>")++-- | Generate the model as HTML document+genHtml :: Module -> IModule -> String+genHtml x ir = cleanOutput $ revertLayout $ printModule x (traceIrModule ir) True+-- | Generate the model as plain text+-- | This is used by the graph generator for tooltips+genText :: Module -> IModule -> String+genText x ir = cleanOutput $ revertLayout $ printModule x (traceIrModule ir) False+genTooltip :: Module -> Map.Map Span [Ir] -> String+genTooltip m ir = unlines $ filter (\x -> trim x /= []) $ lines $ cleanOutput $ revertLayout $ printModule m ir False++printModule :: Module -> Map.Map Span [Ir] -> Bool -> String+printModule (Module _ []) _ _ = ""+printModule (Module s (x:xs)) irMap html = (printDeclaration x 0 irMap html []) ++ printModule (Module s xs) irMap html++printDeclaration :: Declaration -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printDeclaration (EnumDecl s posIdent enumIds) indent irMap html comments =+ preComments +++ printIndentId 0 html +++ (while html "<span class=\"keyword\">") ++ "enum" ++ (while html "</span>") +++ " " +++ (printPosIdent posIdent mUid' html) +++ " = " +++ (concat $ intersperse " | " (map (\x -> printEnumId x indent irMap html comments) enumIds)) +++ comment +++ printIndentEnd html+ where+ mUid' = getUid posIdent irMap;+ (comments', preComments) = printPreComment s comments;+ (_, comment) = printComment s comments'+printDeclaration (ElementDecl _ element) indent irMap html comments = printElement element indent irMap html comments++printElement :: Element -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printElement (Subclafer _ clafer) indent irMap html comments = printClafer clafer indent irMap html comments++printElement (ClaferUse s name crd es) indent irMap html comments =+ preComments +++ printIndentId indent html +++ "`" ++ (while html ("<a href=\"#" ++ superId ++ "\"><span class=\"reference\">")) +++ printName name indent irMap False [] --trick the printer into only printing the name+ ++ (while html "</span></a>") +++ printCard crd +++ comment +++ printIndentEnd html +++ printElements es indent irMap html comments''+ where+ (_, superId) = getUseId s irMap;+ (comments', preComments) = printPreComment s comments;+ (comments'', comment) = printComment s comments'++printElement (Subgoal s goal) indent irMap html comments =+ preComments +++ printIndent 0 html +++ printGoal goal indent irMap html comments'' +++ comment +++ printIndentEnd html+ where+ (comments', preComments) = printPreComment s comments;+ (comments'', comment) = printComment s comments'++printElement (Subconstraint s constraint) indent irMap html comments =+ preComments +++ printIndent indent html +++ printConstraint constraint indent irMap html comments'' +++ comment +++ printIndentEnd html+ where+ (comments', preComments) = printPreComment s comments;+ (comments'', comment) = printComment s comments'++printElement (SubAssertion s constraint) indent irMap html comments =+ preComments +++ printIndent indent html +++ printAssertion constraint indent irMap html comments'' +++ comment +++ printIndentEnd html+ where+ (comments', preComments) = printPreComment s comments;+ (comments'', comment) = printComment s comments'++printElements :: Elements -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printElements (ElementsEmpty _) _ _ _ _ = ""+printElements (ElementsList _ es) indent irMap html comments = "\n{" ++ mapElements es indent irMap html comments ++ "\n}"+ where mapElements [] _ _ _ _ = []+ mapElements (e':es') indent' irMap' html' comments' = if span' e' == noSpan+ then (printElement e' (indent' + 1) irMap' html' comments' {-++ "\n"-}) ++ mapElements es' indent' irMap' html' comments'+ else (printElement e' (indent' + 1) irMap' html' comments' {-++ "\n"-}) ++ mapElements es' indent' irMap' html' (afterSpan (span' e') comments')+ afterSpan s comments' = let (Span _ (Pos line _)) = s in dropWhile (\(x, _) -> let (Span _ (Pos line' _)) = x in line' <= line) comments'+ span' (Subclafer s _) = s+ span' (Subconstraint s _) = s+ span' (ClaferUse s _ _ _) = s+ span' (Subgoal s _) = s+ span' (SubAssertion s _) = s++printClafer :: Clafer -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printClafer (Clafer s abstract gCard id' super' reference' crd init' es) indent irMap html comments =+ preComments +++ printIndentId indent html +++ claferDeclaration +++ comment +++ printElements es indent irMap html comments'' +++ printIndentEnd html+ where+ uid' = getDivId s irMap;+ (comments', preComments) = printPreComment s comments;+ (comments'', comment) = printComment s comments'+ claferDeclaration = concat [+ printAbstract abstract html,+ printGCard gCard html,+ printPosIdent id' (Just uid') html,+ printSuper super' indent irMap html comments,+ printReference reference' indent irMap html comments,+ printCard crd,+ printInit init' indent irMap html comments]++printGoal :: Goal -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printGoal goal indent irMap html comments =+ (if html then "<<" else "<<") +++ (case goal of+ (GoalMinimize _ exps') -> (while html "<span class=\"keyword\">") ++ "minimize" ++ (while html "</span>") ++ " " ++ concatMap (\x -> printExp x indent irMap html comments) exps'+ (GoalMaximize _ exps') -> (while html "<span class=\"keyword\">") ++ "maximize" ++ (while html "</span>") ++ " " ++ concatMap (\x -> printExp x indent irMap html comments) exps'+ (GoalMinDeprecated _ exps') -> printDeprecated "min " "Use `minimize` instead." html ++ concatMap (\x -> printExp x indent irMap html comments) exps'+ (GoalMaxDeprecated _ exps') -> printDeprecated "max " "Use `maximize` instead." html ++ concatMap (\x -> printExp x indent irMap html comments) exps'+ ) +++ if html then ">>" else ">>"++printAbstract :: Abstract -> Bool -> String+printAbstract (Abstract _) html = (while html "<span class=\"keyword\">") ++ "abstract" ++ (while html "</span>") ++ " "+printAbstract (AbstractEmpty _) _ = ""++printGCard :: GCard -> Bool -> String+printGCard gCard html = case gCard of+ (GCardInterval _ ncard) -> printNCard ncard+ (GCardEmpty _) -> ""+ (GCardXor _) -> (while html "<span class=\"keyword\">") ++ "xor" ++ (while html "</span>") ++ " "+ (GCardOr _) -> (while html "<span class=\"keyword\">") ++ "or" ++ (while html "</span>") ++ " "+ (GCardMux _) -> (while html "<span class=\"keyword\">") ++ "mux" ++ (while html "</span>") ++ " "+ (GCardOpt _) -> (while html "<span class=\"keyword\">") ++ "opt" ++ (while html "</span>") ++ " "++printNCard :: NCard -> String+printNCard (NCard _ (PosInteger (_, num)) exInteger) = num ++ ".." ++ printExInteger exInteger ++ " "++printExInteger :: ExInteger -> String+printExInteger (ExIntegerAst _) = "*"+printExInteger (ExIntegerNum _ (PosInteger(_, num))) = num++printName :: Name -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printName (Path _ modids) indent irMap html comments = unwords $ map (\x -> printModId x indent irMap html comments) modids++printModId :: ModId -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printModId (ModIdIdent _ posident) _ irMap html _ = printPosIdentRef posident irMap html++printPosIdent :: PosIdent -> Maybe String -> Bool -> String+printPosIdent (PosIdent (_, id')) Nothing _ = id'+printPosIdent (PosIdent (_, id')) (Just uid') html = (while html $ "<span class=\"claferDecl\" id=\"" ++ uid' ++ "\">") ++ id' ++ (while html "</span>")++printPosIdentRef :: PosIdent -> Map.Map Span [Ir] -> Bool -> String+printPosIdentRef (PosIdent (_, "dref")) _ html+ = (while html "<span class=\"keyword\">") ++ "dref" ++ (while html "</span>")+printPosIdentRef (PosIdent (_, "this")) _ html+ = (while html "<span class=\"keyword\">") ++ "this" ++ (while html "</span>")+printPosIdentRef (PosIdent (_, "parent")) _ html+ = (while html "<span class=\"keyword\">") ++ "parent" ++ (while html "</span>")+printPosIdentRef (PosIdent (_, "root")) _ html+ = (while html "<span class=\"keyword\">") ++ "root" ++ (while html "</span>")+printPosIdentRef (PosIdent (_, "ref")) _ html+ = printDeprecated "ref" "Use `dref` instead." html+printPosIdentRef (PosIdent (_, id')) _ False = id'+printPosIdentRef (PosIdent (p, id')) irMap True+ = case mUid' of+ Just uid' -> "<a href=\"#" ++ uid' ++ "\"><span class=\"reference\">" ++ id' ++ "</span></a>"+ Nothing -> id'+ where+ mUid' = getUid (PosIdent (p, id')) irMap++printSuper :: Super -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printSuper (SuperEmpty _) _ _ _ _ = ""+printSuper (SuperSome _ setExp) indent irMap html comments = (while html "<span class=\"keyword\">") ++ " : " ++ (while html "</span>") ++ printExp setExp indent irMap html comments++printReference :: Reference -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printReference (ReferenceEmpty _) _ _ _ _ = ""+printReference (ReferenceSet _ setExp) indent irMap html comments = (while html "<span class=\"keyword\">") ++ " -> " ++ (while html "</span>") ++ printExp setExp indent irMap html comments+printReference (ReferenceBag _ setExp) indent irMap html comments = (while html "<span class=\"keyword\">") ++ " ->> " ++ (while html "</span>") ++ printExp setExp indent irMap html comments+++printCard :: Card -> String+printCard (CardEmpty _) = ""+printCard (CardLone _) = " ?"+printCard (CardSome _) = " +"+printCard (CardAny _) = " *"+printCard (CardNum _ (PosInteger (_,num))) = " " ++ num+printCard (CardInterval _ nCard) = " " ++ printNCard nCard++printConstraint :: Constraint -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printConstraint (Constraint _ exps') indent irMap html comments = (concatMap (\x -> printConstraint' x indent irMap html comments) exps')++printConstraint' :: Exp -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printConstraint' exp' indent irMap html comments =+ while html "<span class=\"keyword\">" ++ "[" ++ while html "</span>" +++ " " +++ printExp exp' indent irMap html comments +++ " " +++ while html "<span class=\"keyword\">" ++ "]" ++ while html "</span>"++printAssertion :: Assertion -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printAssertion (Assertion _ exps') indent irMap html comments = concatMap (\x -> printAssertion' x indent irMap html comments) exps'+printAssertion' :: Exp -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printAssertion' exp' indent' irMap html comments =+ while html "<span class=\"keyword\">" ++ "assert [" ++ while html "</span>" +++ " " +++ printExp exp' indent' irMap html comments +++ " " +++ while html "<span class=\"keyword\">" ++ "]" ++ while html "</span>"++printDecl :: Decl-> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printDecl (Decl _ locids setExp) indent irMap html comments =+ (concat $ intersperse "; " $ map printLocId locids) +++ (while html "<span class=\"keyword\">") ++ " : " ++ (while html "</span>") ++ printExp setExp indent irMap html comments+ where+ printLocId :: LocId -> String+ printLocId (LocIdIdent _ (PosIdent (_, ident'))) = ident'++printInit :: Init -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printInit (InitEmpty _) _ _ _ _ = ""+printInit (InitSome _ initHow exp') indent irMap html comments = printInitHow initHow ++ printExp exp' indent irMap html comments++printInitHow :: InitHow -> String+printInitHow (InitConstant _) = " = "+printInitHow (InitDefault _) = " := "++printExp :: Exp -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printExp (EDeclAllDisj _ decl exp') indent irMap html comments = "all disj " ++ (printDecl decl indent irMap html comments) ++ " | " ++ (printExp exp' indent irMap html comments)+printExp (EDeclAll _ decl exp') indent irMap html comments = "all " ++ (printDecl decl indent irMap html comments) ++ " | " ++ (printExp exp' indent irMap html comments)+printExp (EDeclQuantDisj _ quant' decl exp') indent irMap html comments = (printQuant quant' html) ++ "disj" ++ (printDecl decl indent irMap html comments) ++ " | " ++ (printExp exp' indent irMap html comments)+printExp (EDeclQuant _ quant' decl exp') indent irMap html comments = (printQuant quant' html) ++ (printDecl decl indent irMap html comments) ++ " | " ++ (printExp exp' indent irMap html comments)+printExp (EGMax _ exp') indent irMap html comments = "max " ++ printExp exp' indent irMap html comments+printExp (EGMin _ exp') indent irMap html comments = "min " ++ printExp exp' indent irMap html comments+printExp (ENeq _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ " != " ++ (printExp exp'2 indent irMap html comments)+printExp (EQuantExp _ quant' exp') indent irMap html comments = printQuant quant' html ++ printExp exp' indent irMap html comments+printExp (EImplies _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " => " else " => ") ++ printExp exp'2 indent irMap html comments+printExp (EAnd _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " && " else " && ") ++ printExp exp'2 indent irMap html comments+printExp (EOr _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " || " else " || ") ++ printExp exp'2 indent irMap html comments+printExp (EXor _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ " xor " ++ printExp exp'2 indent irMap html comments+printExp (ENeg _ exp') indent irMap html comments = " ! " ++ printExp exp' indent irMap html comments+printExp (ELt _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " < " else " < ") ++ printExp exp'2 indent irMap html comments+printExp (EGt _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " > " else " > ") ++ printExp exp'2 indent irMap html comments+printExp (EEq _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ " = " ++ printExp exp'2 indent irMap html comments+printExp (ELte _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " <= " else " <= ") ++ printExp exp'2 indent irMap html comments+printExp (EGte _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " >= " else " >= ") ++ printExp exp'2 indent irMap html comments+printExp (EIn _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ " in " ++ printExp exp'2 indent irMap html comments+printExp (ENin _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ " not in " ++ printExp exp'2 indent irMap html comments+printExp (EIff _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " <=> " else " <=> ") ++ printExp exp'2 indent irMap html comments+printExp (EAdd _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ " + " ++ printExp exp'2 indent irMap html comments+printExp (ESub _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ " - " ++ printExp exp'2 indent irMap html comments+printExp (EMul _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ " * " ++ printExp exp'2 indent irMap html comments+printExp (EDiv _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " / " else " / ") ++ printExp exp'2 indent irMap html comments+printExp (ERem _ exp'1 exp'2) indent irMap html comments = (printExp exp'1 indent irMap html comments) ++ (if html then " % " else " % ") ++ printExp exp'2 indent irMap html comments+printExp (ESum _ exp') indent irMap html comments = "sum " ++ printExp exp' indent irMap html comments+printExp (EProd _ exp') indent irMap html comments = "product " ++ printExp exp' indent irMap html comments+printExp (ECard _ exp') indent irMap html comments = "# " ++ printExp exp' indent irMap html comments+printExp (EMinExp _ exp') indent irMap html comments = "-" ++ printExp exp' indent irMap html comments+printExp (EImpliesElse _ exp'1 exp'2 exp'3) indent irMap html comments = "if " ++ (printExp exp'1 indent irMap html comments) ++ " then " ++ (printExp exp'2 indent irMap html comments) ++ " else " ++ (printExp exp'3 indent irMap html comments)+printExp (ClaferId _ name) indent irMap html comments = printName name indent irMap html comments+printExp (EUnion _ set1 set2) indent irMap html comments = (printExp set1 indent irMap html comments) ++ "++" ++ (printExp set2 indent irMap html comments)+printExp (EUnionCom _ set1 set2) indent irMap html comments = (printExp set1 indent irMap html comments) ++ ", " ++ (printExp set2 indent irMap html comments)+printExp (EDifference _ set1 set2) indent irMap html comments = (printExp set1 indent irMap html comments) ++ "--" ++ (printExp set2 indent irMap html comments)+printExp (EIntersection _ set1 set2) indent irMap html comments = (printExp set1 indent irMap html comments) ++ "**" ++ (printExp set2 indent irMap html comments)+printExp (EIntersectionDeprecated _ set1 set2) indent irMap html comments = (printExp set1 indent irMap html comments) ++ printDeprecated "&" "Use `**` instead." html ++ (printExp set2 indent irMap html comments)+printExp (EDomain _ set1 set2) indent irMap html comments = (printExp set1 indent irMap html comments) ++ "<:" ++ (printExp set2 indent irMap html comments)+printExp (ERange _ set1 set2) indent irMap html comments = (printExp set1 indent irMap html comments) ++ ":>" ++ (printExp set2 indent irMap html comments)+printExp (EJoin _ set1 set2) indent irMap html comments = (printExp set1 indent irMap html comments) ++ "." ++ (printExp set2 indent irMap html comments)+printExp (EInt _ (PosInteger (_, num))) _ _ _ _ = num+printExp (EDouble _ (PosDouble (_, num))) _ _ _ _ = num+printExp (EReal _ (PosReal (_, num))) _ _ _ _ = num+printExp (EStr _ (PosString (_, str))) _ _ _ _ = str++printQuant :: Quant -> Bool -> String+printQuant quant' html = case quant' of+ (QuantNo _) -> (while html "<span class=\"keyword\">") ++ "no" ++ (while html "</span>") ++ " "+ (QuantNot _) -> (while html "<span class=\"keyword\">") ++ "not" ++ (while html "</span>") ++ " "+ (QuantLone _) -> (while html "<span class=\"keyword\">") ++ "lone" ++ (while html "</span>") ++ " "+ (QuantOne _) -> (while html "<span class=\"keyword\">") ++ "one" ++ (while html "</span>") ++ " "+ (QuantSome _) -> (while html "<span class=\"keyword\">") ++ "some" ++ (while html "</span>") ++ " "++printEnumId :: EnumId -> Int -> Map.Map Span [Ir] -> Bool -> [(Span, String)] -> String+printEnumId (EnumIdIdent _ posident) _ irMap html _ = printPosIdent posident mUid' html+ where+ mUid' = getUid posident irMap++printIndent :: Int -> Bool -> String+printIndent 0 html = (while html "<div>") ++ "\n"+printIndent _ html = (while html "<div class=\"indent\">") ++ "\n"++printIndentId :: Int -> Bool -> String+printIndentId 0 html = while html ("<div>") ++ "\n"+printIndentId _ html = while html ("<div class=\"indent\">") ++ "\n"++printIndentEnd :: Bool -> String+printIndentEnd html = (while html "</div>") ++ "\n"++dropUid :: String -> String+dropUid uid' = let id' = rest $ dropWhile (/= '_') uid'+ in if id' == ""+ then uid'+ else id'++--so it fails more gracefully on empty lists+{-first :: String -> String+first [] = []+first (x:_) = x-}+rest :: String -> String+rest [] = []+rest (_:xs) = xs++getUid :: PosIdent -> Map.Map Span [Ir] -> Maybe String+getUid posIdent@(PosIdent (_, id')) irMap =+ case Map.lookup (getSpan posIdent) irMap of+ Nothing -> Nothing+ Just wrappedResultList -> listToMaybe $ catMaybes $ map (findUid id') $ map unwrap wrappedResultList+ where+ unwrap (IRPExp pexp') = getIdentPExp pexp'+ unwrap (IRClafer iClafer') = [ _uid iClafer' ]+ unwrap x = error $ "Html:getUid:unwrap called on: " ++ show x+ getIdentPExp (PExp _ _ _ exp') = getIdentIExp exp'+ getIdentIExp (IFunExp _ exps') = concatMap getIdentPExp exps'+ getIdentIExp (IClaferId _ id'' _ _) = [id'']+ getIdentIExp (IDeclPExp _ _ pexp) = getIdentPExp pexp+ getIdentIExp _ = []+ findUid name (x:xs) = if name == dropUid x then Just x else findUid name xs+ findUid _ [] = Nothing++getDivId :: Span -> Map.Map Span [Ir] -> String+getDivId s irMap = if Map.lookup s irMap == Nothing+ then "Uid not Found"+ else let IRClafer iClaf = head $ fromJust $ Map.lookup s irMap in+ _uid iClaf++getUseId :: Span -> Map.Map Span [Ir] -> (String, String)+getUseId s irMap = if Map.lookup s irMap == Nothing+ then ("Uid not Found", "Uid not Found")+ else let IRClafer iClaf = head $ fromJust $ Map.lookup s irMap in+ (_uid iClaf, fromMaybe "" $ _sident <$> _exp <$> _super iClaf)++while :: Bool -> String -> String+while bool exp' = if bool then exp' else ""++cleanOutput :: String -> String+cleanOutput "" = ""+cleanOutput (' ':'\n':xs) = cleanOutput $ '\n':xs+cleanOutput ('\n':'\n':xs) = cleanOutput $ '\n':xs+cleanOutput (' ':'<':'b':'r':'>':xs) = "<br>"++cleanOutput xs+cleanOutput (x:xs) = x : cleanOutput xs++trim :: String -> String+trim = let f = reverse . dropWhile isSpace in f . f++highlightErrors :: String -> [ClaferErr] -> String+highlightErrors model errors = "<pre>\n" ++ unlines (replace "<!-- # FRAGMENT /-->" "</pre>\n<!-- # FRAGMENT /-->\n<pre>" --assumes the fragments have been concatenated+ (highlightErrors' (replace "//# FRAGMENT" "<!-- # FRAGMENT /-->" (lines model)) errors)) ++ "</pre>"+ where+ replace _ _ [] = []+ replace x y (z:zs) = (if x == z then y else z):replace x y zs++highlightErrors' :: [String] -> [ClaferErr] -> [String]+highlightErrors' model' [] = model'+highlightErrors' model' ((ClaferErr _):es) = highlightErrors' model' es+highlightErrors' model' ((ParseErr ErrPos{modelPos = Pos l c, fragId = n} msg'):es) =+ let (ls, lss) = genericSplitAt (l + toInteger n) model'+ newLine = fst (genericSplitAt (c - 1) $ last ls) ++ "<span class=\"error\" title=\"Parsing failed at line " ++ show l ++ " column " ++ show c +++ "...\n" ++ msg' ++ "\">" ++ (if snd (genericSplitAt (c - 1) $ last ls) == "" then " " else snd (genericSplitAt (c - 1) $ last ls)) ++ "</span>"+ in highlightErrors' (init ls ++ [newLine] ++ lss) es+highlightErrors' model' ((SemanticErr ErrPos{modelPos = Pos l c, fragId = n} msg'):es) =+ let (ls, lss) = genericSplitAt (l + toInteger n) model'+ newLine = fst (genericSplitAt (c - 1) $ last ls) ++ "<span class=\"error\" title=\"Compiling failed at line " ++ show l ++ " column " ++ show c +++ "...\n" ++ msg' ++ "\">" ++ (if snd (genericSplitAt (c - 1) $ last ls) == "" then " " else snd (genericSplitAt (c - 1) $ last ls)) ++ "</span>"+ in highlightErrors' (init ls ++ [newLine] ++ lss) es
src/Language/Clafer/Generator/Stats.hs view
@@ -1,66 +1,66 @@-{-# LANGUAGE FlexibleContexts #-} -{- - Copyright (C) 2012 Kacper Bak, Michal Antkiewicz <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -module Language.Clafer.Generator.Stats where - -import Control.Monad.State -import Data.Maybe (isJust) - -import Language.Clafer.Intermediate.Intclafer - -data Stats = Stats { - naClafers :: Int, - nrClafers :: Int, - ncClafers :: Int, - nConstraints :: Int, - nGoals :: Int, - sglCard :: Interval - } deriving Show - - -statsModule :: IModule -> Stats -statsModule imodule = - execState (mapM statsElement $ _mDecls imodule) $ Stats 0 0 0 0 0 (1, 1) - -statsClafer :: MonadState Stats m => IClafer -> m () -statsClafer claf = do - if _isAbstract claf - then modify (\e -> e {naClafers = naClafers e + 1}) - else modify (\e -> e {ncClafers = ncClafers e + 1}) - - when (isJust $ _reference claf) $ - modify (\e -> e {nrClafers = nrClafers e + 1}) - sglCard' <- gets sglCard - modify (\e -> e {sglCard = statsCard sglCard' $ _glCard claf}) - mapM_ statsElement $ _elements claf - - -statsCard :: Interval -> Interval -> Interval -statsCard (m1, n1) (m2, n2) = (max m1 m2, maxEx n1 n2) - where - maxEx m' n' = if m' == -1 || n' == -1 then -1 else max m' n' - -statsElement :: MonadState Stats m => IElement -> m () -statsElement x = case x of - IEClafer clafer -> statsClafer clafer - IEConstraint _ _ -> modify (\e -> e {nConstraints = nConstraints e + 1}) - IEGoal _ _ -> modify (\e -> e {nGoals = nGoals e + 1}) +{-# LANGUAGE FlexibleContexts #-}+{-+ Copyright (C) 2012 Kacper Bak, Michal Antkiewicz <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+module Language.Clafer.Generator.Stats where++import Control.Monad.State+import Data.Maybe (isJust)++import Language.Clafer.Intermediate.Intclafer++data Stats = Stats {+ naClafers :: Int,+ nrClafers :: Int,+ ncClafers :: Int,+ nConstraints :: Int,+ nGoals :: Int,+ sglCard :: Interval+ } deriving Show+++statsModule :: IModule -> Stats+statsModule imodule =+ execState (mapM statsElement $ _mDecls imodule) $ Stats 0 0 0 0 0 (1, 1)++statsClafer :: MonadState Stats m => IClafer -> m ()+statsClafer claf = do+ if _isAbstract claf+ then modify (\e -> e {naClafers = naClafers e + 1})+ else modify (\e -> e {ncClafers = ncClafers e + 1})++ when (isJust $ _reference claf) $+ modify (\e -> e {nrClafers = nrClafers e + 1})+ sglCard' <- gets sglCard+ modify (\e -> e {sglCard = statsCard sglCard' $ _glCard claf})+ mapM_ statsElement $ _elements claf+++statsCard :: Interval -> Interval -> Interval+statsCard (m1, n1) (m2, n2) = (max m1 m2, maxEx n1 n2)+ where+ maxEx m' n' = if m' == -1 || n' == -1 then -1 else max m' n'++statsElement :: MonadState Stats m => IElement -> m ()+statsElement x = case x of+ IEClafer clafer -> statsClafer clafer+ IEConstraint _ _ -> modify (\e -> e {nConstraints = nConstraints e + 1})+ IEGoal _ _ -> modify (\e -> e {nGoals = nGoals e + 1})
src/Language/Clafer/Intermediate/Desugarer.hs view
@@ -1,482 +1,482 @@-{-# LANGUAGE RankNTypes #-} -{- - Copyright (C) 2012-2015 Kacper Bak, Jimmy Liang, Michal Antkiewicz, Paulius Juodisius <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -{- | Transforms an Abstract Syntax Tree (AST) from "Language.Clafer.Front.AbsClafer" -into Intermediate representation (IR) from "Language.Clafer.Intermediate.Intclafer" of a Clafer model. --} -module Language.Clafer.Intermediate.Desugarer where - -import Language.Clafer.Common -import Data.Maybe (fromMaybe) -import Language.Clafer.Front.AbsClafer -import Language.Clafer.Intermediate.Intclafer - --- | Transform the AST into the intermediate representation (IR) -desugarModule :: Maybe String -> Module -> IModule -desugarModule mURL (Module _ declarations) = IModule - (fromMaybe "" mURL) - (declarations >>= desugarEnums >>= desugarDeclaration) - -sugarModule :: IModule -> Module -sugarModule x = Module noSpan $ map sugarDeclaration $ _mDecls x -- (fragments x >>= mDecls) - --- | desugars enumeration to abstract and global singleton features -desugarEnums :: Declaration -> [Declaration] -desugarEnums (EnumDecl (Span p1 p2) id' enumids) = absEnum : map mkEnum enumids - where - p2' = case enumids of - -- the abstract enum clafer should end before the first literal begins - ((EnumIdIdent (Span (Pos y' x') _) _):_) -> Pos y' (x'-3) -- cutting the ' = ' - [] -> p2 -- should never happen - cannot have enum without any literals. Return the original end pos. - oneToOne pos' = (CardInterval noSpan $ - NCard noSpan (PosInteger (pos', "1")) (ExIntegerNum noSpan $ PosInteger (pos', "1"))) - absEnum = let - s1 = Span p1 p2' - in - ElementDecl s1 $ - Subclafer s1 $ - Clafer s1 (Abstract s1) (GCardEmpty s1) id' (SuperEmpty s1) (ReferenceEmpty s1) (CardEmpty s1) (InitEmpty s1) (ElementsList s1 []) - mkEnum (EnumIdIdent s2 eId) = -- each concrete clafer must fit within the original span of the literal - ElementDecl s2 $ - Subclafer s2 $ - Clafer s2 (AbstractEmpty s2) (GCardEmpty s2) eId ((SuperSome s2) (ClaferId s2 $ Path s2 [ModIdIdent s2 id'])) (ReferenceEmpty s2) (oneToOne (0, 0)) (InitEmpty s2) (ElementsList s2 []) -desugarEnums x = [x] - - -desugarDeclaration :: Declaration -> [IElement] -desugarDeclaration (ElementDecl _ element) = desugarElement element -desugarDeclaration _ = error "Desugarer.desugarDeclaration: enum declarations should have already been converted to clafers. BUG." - - -sugarDeclaration :: IElement -> Declaration -sugarDeclaration (IEClafer clafer) = ElementDecl (_cinPos clafer) $ Subclafer (_cinPos clafer) $ sugarClafer clafer -sugarDeclaration (IEConstraint True constraint) = - ElementDecl (_inPos constraint) $ Subconstraint (_inPos constraint) $ sugarConstraint constraint -sugarDeclaration (IEConstraint False assertion) = - ElementDecl (_inPos assertion) $ SubAssertion (_inPos assertion) $ sugarAssertion assertion -sugarDeclaration (IEGoal isMaximize' goal) = ElementDecl (_inPos goal) $ Subgoal (_inPos goal) $ sugarGoal goal isMaximize' - - -desugarClafer :: Clafer -> [IElement] -desugarClafer claf@(Clafer s abstract gcrd' id' super' reference' crd' init' elements') = - case (super', reference') of - (SuperSome ss setExp, ReferenceEmpty _) -> if isPrimitive $ getPExpClaferIdent setExp - then desugarClafer (Clafer s abstract gcrd' id' (SuperEmpty s) (ReferenceSet ss setExp) crd' init' elements') - else desugarClafer' claf - (SuperSome _ setExp, ReferenceSet _ _) -> if isPrimitive $ getPExpClaferIdent setExp - then error "Desugarer: cannot rewrite : with primitive type into -> because a reference is also present. Using : with primitive types is discouraged." - else desugarClafer' claf - (SuperSome _ setExp, ReferenceBag _ _) -> if isPrimitive $ getPExpClaferIdent setExp - then error "Desugarer: cannot rewrite : with primitive type into -> because a reference is also present. Using : with primitive types is discouraged." - else desugarClafer' claf - _ -> desugarClafer' claf - where - desugarClafer' (Clafer s'' abstract'' gcrd'' id'' super'' reference'' crd'' init'' elements'') = - (IEClafer $ IClafer s'' (desugarAbstract abstract'') (desugarGCard gcrd'') (transIdent id'') - "" "" (desugarSuper super'') (desugarReference reference'') (desugarCard crd'') (0, -1) - (desugarElements elements'')) : (desugarInit id'' init'') - -getPExpClaferIdent :: Exp -> String -getPExpClaferIdent (ClaferId _ (Path _ [ (ModIdIdent _ pident') ] )) = transIdent pident' -getPExpClaferIdent (EJoin _ _ e2) = getPExpClaferIdent e2 -getPExpClaferIdent _ = error "Desugarer:getPExpClaferIdent not given a ClaferId PExp" - -sugarClafer :: IClafer -> Clafer -sugarClafer (IClafer s abstract gcard' _ uid' _ super' reference' crd' _ elements') = - Clafer s (sugarAbstract abstract) (sugarGCard gcard') (mkIdent uid') - (sugarSuper super') (sugarReference reference') (sugarCard crd') (InitEmpty s) (sugarElements elements') - - -desugarSuper :: Super -> Maybe PExp -desugarSuper (SuperEmpty _) = Nothing -desugarSuper (SuperSome _ (ClaferId _ (Path _ [ (ModIdIdent _ (PosIdent (_, "clafer"))) ] ))) = Nothing -desugarSuper (SuperSome _ setexp) = Just $ desugarExp setexp - -desugarReference :: Reference -> Maybe IReference -desugarReference (ReferenceEmpty _) = Nothing -desugarReference (ReferenceSet _ setexp) = Just $ IReference True $ desugarExp setexp -desugarReference (ReferenceBag _ setexp) = Just $ IReference False $ desugarExp setexp - -desugarInit :: PosIdent -> Init -> [IElement] -desugarInit _ (InitEmpty _) = [] -desugarInit id' (InitSome s inithow exp') = [ IEConstraint (desugarInitHow inithow) (pExpDefPid s implIExp) ] - where - cId :: PExp - cId = mkPLClaferId (getSpan id') (snd $ getIdent id') False Nothing - -- <id> = <exp'> - assignIExp :: IExp - assignIExp = (IFunExp "=" [cId, desugarExp exp']) - -- some <id> => <assignIExp> - implIExp :: IExp - implIExp = (IFunExp "=>" [ pExpDefPid s $ IDeclPExp ISome [] cId, pExpDefPid s assignIExp ]) - getIdent (PosIdent y) = y - -desugarInitHow :: InitHow -> Bool -desugarInitHow (InitConstant _) = True -desugarInitHow (InitDefault _ )= False - - -desugarName :: Name -> IExp -desugarName (Path _ path) = - IClaferId (concatMap ((++ modSep).desugarModId) (init path)) - (desugarModId $ last path) True Nothing - -desugarModId :: ModId -> Result -desugarModId (ModIdIdent _ id') = transIdent id' - -sugarModId :: String -> ModId -sugarModId modid = ModIdIdent noSpan $ mkIdent modid - -sugarSuper :: Maybe PExp -> Super -sugarSuper Nothing = SuperEmpty noSpan -sugarSuper (Just pexp') = SuperSome noSpan (sugarExp pexp') - -sugarReference :: Maybe IReference -> Reference -sugarReference Nothing = ReferenceEmpty noSpan -sugarReference (Just (IReference True pexp')) = ReferenceSet noSpan (sugarExp pexp') -sugarReference (Just (IReference False pexp')) = ReferenceBag noSpan (sugarExp pexp') - -sugarInitHow :: Bool -> InitHow -sugarInitHow True = InitConstant noSpan -sugarInitHow False = InitDefault noSpan - - -desugarConstraint :: Constraint -> PExp -desugarConstraint (Constraint _ exps') = desugarPath $ desugarExp $ - (if length exps' > 1 then foldl1 (EAnd noSpan) else head) exps' - -desugarAssertion :: Assertion -> PExp -desugarAssertion (Assertion _ exps') = desugarPath $ desugarExp $ - (if length exps' > 1 then foldl1 (EAnd noSpan) else head) exps' - -desugarGoal :: Goal -> IElement -desugarGoal (GoalMinimize s [exp']) = mkMinimizeMaximizePExp False s exp' -desugarGoal (GoalMinDeprecated s [exp']) = mkMinimizeMaximizePExp False s exp' -desugarGoal (GoalMaximize s [exp']) = mkMinimizeMaximizePExp True s exp' -desugarGoal (GoalMaxDeprecated s [exp']) = mkMinimizeMaximizePExp True s exp' -desugarGoal goal = error $ "Desugarer.desugarGoal: malformed objective:\n" ++ show goal - -mkMinimizeMaximizePExp :: Bool -> Span -> Exp -> IElement -mkMinimizeMaximizePExp isMaximize' s exp' = - IEGoal isMaximize' $ desugarPath $ PExp Nothing "" s $ IFunExp (if isMaximize' then iMaximize else iMinimize) [desugarExp exp'] - -sugarConstraint :: PExp -> Constraint -sugarConstraint pexp = Constraint (_inPos pexp) $ map sugarExp [pexp] - -sugarAssertion :: PExp -> Assertion -sugarAssertion pexp = Assertion (_inPos pexp) $ map sugarExp [pexp] - -sugarGoal :: PExp -> Bool -> Goal -sugarGoal PExp{_exp=IFunExp _ [pexp]} True = GoalMaximize (_inPos pexp) $ map sugarExp [pexp] -sugarGoal PExp{_exp=IFunExp _ [pexp]} False = GoalMinimize (_inPos pexp) $ map sugarExp [pexp] -sugarGoal goal _ = error $ "Desugarer.sugarGoal: malformed objective:\n" ++ show goal - -desugarAbstract :: Abstract -> Bool -desugarAbstract (AbstractEmpty _) = False -desugarAbstract (Abstract _) = True - - -sugarAbstract :: Bool -> Abstract -sugarAbstract False = AbstractEmpty noSpan -sugarAbstract True = Abstract noSpan - - -desugarElements :: Elements -> [IElement] -desugarElements (ElementsEmpty _) = [] -desugarElements (ElementsList _ es) = es >>= desugarElement - - -sugarElements :: [IElement] -> Elements -sugarElements x = ElementsList noSpan $ map sugarElement x - - -desugarElement :: Element -> [IElement] -desugarElement x = case x of - Subclafer _ claf -> (desugarClafer claf) - ClaferUse s name crd es -> desugarClafer $ Clafer s - (AbstractEmpty s) (GCardEmpty s) (mkIdent $ _sident $ desugarName name) - (SuperSome s (ClaferId s name)) (ReferenceEmpty s) crd (InitEmpty s) es - Subconstraint _ constraint -> - [IEConstraint True $ desugarConstraint constraint] - SubAssertion _ assertion -> - [IEConstraint False $ desugarAssertion assertion] - Subgoal _ goal -> [desugarGoal goal] - - -sugarElement :: IElement -> Element -sugarElement x = case x of - IEClafer claf -> Subclafer noSpan $ sugarClafer claf - IEConstraint True constraint -> Subconstraint noSpan $ sugarConstraint constraint - IEConstraint False assertion -> SubAssertion noSpan $ sugarAssertion assertion - IEGoal isMaximize' goal -> Subgoal noSpan $ sugarGoal goal isMaximize' - -desugarGCard :: GCard -> Maybe IGCard -desugarGCard x = case x of - GCardEmpty _ -> Nothing - GCardXor _ -> Just $ IGCard True (1, 1) - GCardOr _ -> Just $ IGCard True (1, -1) - GCardMux _ -> Just $ IGCard True (0, 1) - GCardOpt _ -> Just $ IGCard True (0, -1) - GCardInterval _ ncard -> - Just $ IGCard (isOptionalDef ncard) $ desugarNCard ncard - -isOptionalDef :: NCard -> Bool -isOptionalDef (NCard _ m n) = ((0::Integer) == mkInteger m) && (not $ isExIntegerAst n) - -isExIntegerAst :: ExInteger -> Bool -isExIntegerAst (ExIntegerAst _) = True -isExIntegerAst _ = False - -sugarGCard :: Maybe IGCard -> GCard -sugarGCard x = case x of - Nothing -> GCardEmpty noSpan - Just (IGCard _ (i, ex)) -> GCardInterval noSpan $ NCard noSpan (PosInteger ((0, 0), show i)) (sugarExInteger ex) - - -desugarCard :: Card -> Maybe Interval -desugarCard x = case x of - CardEmpty _ -> Nothing - CardLone _ -> Just (0, 1) - CardSome _ -> Just (1, -1) - CardAny _ -> Just (0, -1) - CardNum _ n -> Just (mkInteger n, mkInteger n) - CardInterval _ ncard -> Just $ desugarNCard ncard - -desugarNCard :: NCard -> (Integer, Integer) -desugarNCard (NCard _ i ex) = (mkInteger i, desugarExInteger ex) - -desugarExInteger :: ExInteger -> Integer -desugarExInteger (ExIntegerAst _) = -1 -desugarExInteger (ExIntegerNum _ n) = mkInteger n - -sugarCard :: Maybe Interval -> Card -sugarCard x = case x of - Nothing -> CardEmpty noSpan - Just (i, ex) -> - CardInterval noSpan $ NCard noSpan (PosInteger ((0, 0), show i)) (sugarExInteger ex) - -sugarExInteger :: Integer -> ExInteger -sugarExInteger n = if n == -1 then ExIntegerAst noSpan else (ExIntegerNum noSpan $ PosInteger ((0, 0), show n)) - -desugarExp :: Exp -> PExp -desugarExp x = pExpDefPid (getSpan x) $ desugarExp' x - -desugarExp' :: Exp -> IExp -desugarExp' x = case x of - EDeclAllDisj _ decl exp' -> - IDeclPExp IAll [desugarDecl True decl] (dpe exp') - EDeclAll _ decl exp' -> IDeclPExp IAll [desugarDecl False decl] (dpe exp') - EDeclQuantDisj _ quant' decl exp' -> - IDeclPExp (desugarQuant quant') [desugarDecl True decl] (dpe exp') - EDeclQuant _ quant' decl exp' -> - IDeclPExp (desugarQuant quant') [desugarDecl False decl] (dpe exp') - EIff _ exp0 exp' -> dop iIff [exp0, exp'] - EImplies _ exp0 exp' -> dop iImpl [exp0, exp'] - EImpliesElse _ exp0 exp1 exp' -> dop iIfThenElse [exp0, exp1, exp'] - EOr _ exp0 exp' -> dop iOr [exp0, exp'] - EXor _ exp0 exp' -> dop iXor [exp0, exp'] - EAnd _ exp0 exp' -> dop iAnd [exp0, exp'] - ENeg _ exp' -> dop iNot [exp'] - EQuantExp _ quant' exp' -> - IDeclPExp (desugarQuant quant') [] (desugarExp exp') - ELt _ exp0 exp' -> dop iLt [exp0, exp'] - EGt _ exp0 exp' -> dop iGt [exp0, exp'] - EEq _ exp0 exp' -> dop iEq [exp0, exp'] - ELte _ exp0 exp' -> dop iLte [exp0, exp'] - EGte _ exp0 exp' -> dop iGte [exp0, exp'] - ENeq _ exp0 exp' -> dop iNeq [exp0, exp'] - EIn _ exp0 exp' -> dop iIn [exp0, exp'] - ENin _ exp0 exp' -> dop iNin [exp0, exp'] - EAdd _ exp0 exp' -> dop iPlus [exp0, exp'] - ESub _ exp0 exp' -> dop iSub [exp0, exp'] - EMul _ exp0 exp' -> dop iMul [exp0, exp'] - EDiv _ exp0 exp' -> dop iDiv [exp0, exp'] - ERem _ exp0 exp' -> dop iRem [exp0, exp'] - ECard _ exp' -> dop iCSet [exp'] - ESum _ exp' -> dop iSumSet [exp'] - EProd _ exp' -> dop iProdSet [exp'] - EMinExp _ exp' -> dop iMin [exp'] - EGMax _ exp' -> dop iMaximum [exp'] - EGMin _ exp' -> dop iMinimum [exp'] - EInt _ n -> IInt $ mkInteger n - EDouble _ (PosDouble n) -> IDouble $ read $ snd n - EReal _ (PosReal n) -> IReal $ read $ snd n - EStr _ (PosString str) -> IStr $ snd str - EUnion _ exp0 exp' -> dop iUnion [exp0, exp'] - EUnionCom _ exp0 exp' -> dop iUnion [exp0, exp'] - EDifference _ exp0 exp' -> dop iDifference [exp0, exp'] - EIntersection _ exp0 exp' -> dop iIntersection [exp0, exp'] - EIntersectionDeprecated _ exp0 exp' -> dop iIntersection [exp0, exp'] - EDomain _ exp0 exp' -> dop iDomain [exp0, exp'] - ERange _ exp0 exp' -> dop iRange [exp0, exp'] - EJoin _ exp0 exp' -> dop iJoin [exp0, exp'] - ClaferId _ name -> desugarName name - where - dop = desugarOp desugarExp - dpe = desugarPath.desugarExp - -desugarOp :: (a -> PExp) -> String -> [a] -> IExp -desugarOp f op' exps' = - if (op' == iIfThenElse) - then IFunExp op' $ (desugarPath $ head mappedList) : (map reducePExp $ tail mappedList) - else IFunExp op' $ map (trans.f) exps' - where - mappedList = map f exps' - trans = if op' `elem` ([iNot, iIfThenElse] ++ logBinOps) - then desugarPath else id - -sugarExp :: PExp -> Exp -sugarExp x = sugarExp' $ _exp x - - -sugarExp' :: IExp -> Exp -sugarExp' x = case x of - IDeclPExp quant' [] pexp -> EQuantExp noSpan (sugarQuant quant') (sugarExp pexp) - IDeclPExp IAll (decl@(IDecl True _ _):[]) pexp -> - EDeclAllDisj noSpan (sugarDecl decl) (sugarExp pexp) - IDeclPExp IAll (decl@(IDecl False _ _):[]) pexp -> - EDeclAll noSpan (sugarDecl decl) (sugarExp pexp) - IDeclPExp quant' (decl@(IDecl True _ _):[]) pexp -> - EDeclQuantDisj noSpan (sugarQuant quant') (sugarDecl decl) (sugarExp pexp) - IDeclPExp quant' (decl@(IDecl False _ _):[]) pexp -> - EDeclQuant noSpan (sugarQuant quant') (sugarDecl decl) (sugarExp pexp) - IClaferId "" id' _ _ -> ClaferId noSpan $ Path noSpan [ModIdIdent noSpan $ mkIdent id'] - IClaferId modName' id' _ _ -> ClaferId noSpan $ Path noSpan $ (sugarModId modName') : [sugarModId id'] - IInt n -> EInt noSpan $ PosInteger ((0, 0), show n) - IDouble n -> EDouble noSpan $ PosDouble ((0, 0), show n) - IReal n -> EReal noSpan $ PosReal ((0, 0), show n) - IStr str -> EStr noSpan $ PosString ((0, 0), str) - IFunExp op' exps' -> - if op' `elem` unOps then (sugarUnOp op') (exps''!!0) - else if op' `elem` binOps then (sugarOp op') (exps''!!0) (exps''!!1) - else (sugarTerOp op') (exps''!!0) (exps''!!1) (exps''!!2) - where - exps'' = map sugarExp exps' - x' -> error $ "Desugarer.sugarExp': invalid argument: " ++ show x' -- This should never happen - where - sugarUnOp op'' - | op'' == iNot = ENeg noSpan - | op'' == iCSet = ECard noSpan - | op'' == iMin = EMinExp noSpan - | op'' == iMaximum = EGMax noSpan - | op'' == iMinimum = EGMin noSpan - | op'' == iSumSet = ESum noSpan - | op'' == iProdSet = EProd noSpan - | otherwise = error $ show op'' ++ "is not an op" - sugarOp op'' - | op'' == iIff = EIff noSpan - | op'' == iImpl = EImplies noSpan - | op'' == iOr = EOr noSpan - | op'' == iXor = EXor noSpan - | op'' == iAnd = EAnd noSpan - | op'' == iLt = ELt noSpan - | op'' == iGt = EGt noSpan - | op'' == iEq = EEq noSpan - | op'' == iLte = ELte noSpan - | op'' == iGte = EGte noSpan - | op'' == iNeq = ENeq noSpan - | op'' == iIn = EIn noSpan - | op'' == iNin = ENin noSpan - | op'' == iPlus = EAdd noSpan - | op'' == iSub = ESub noSpan - | op'' == iMul = EMul noSpan - | op'' == iDiv = EDiv noSpan - | op'' == iRem = ERem noSpan - | op'' == iUnion = EUnion noSpan - | op'' == iDifference = EDifference noSpan - | op'' == iIntersection = EIntersection noSpan - | op'' == iDomain = EDomain noSpan - | op'' == iRange = ERange noSpan - | op'' == iJoin = EJoin noSpan - | otherwise = error $ show op'' ++ "is not an op" - sugarTerOp op'' - | op'' == iIfThenElse = EImpliesElse noSpan - | otherwise = error $ show op'' ++ "is not an op" - - -desugarPath :: PExp -> PExp -desugarPath (PExp iType' pid' pos' x) = reducePExp $ PExp iType' pid' pos' result - where - result - | isSetExp x = IDeclPExp ISome [] (pExpDefPid pos' x) - | isNegSome x = IDeclPExp INo [] $ _bpexp $ _exp $ head $ _exps x - | otherwise = x - isNegSome (IFunExp op' [PExp _ _ _ (IDeclPExp ISome [] _)]) = op' == iNot - isNegSome _ = False - - -isSetExp :: IExp -> Bool -isSetExp (IClaferId _ _ _ _) = True -isSetExp (IFunExp op' _) = op' `elem` setBinOps -isSetExp _ = False - - --- reduce parent -reducePExp :: PExp -> PExp -reducePExp (PExp t pid' pos' x) = PExp t pid' pos' $ reduceIExp x - -reduceIExp :: IExp -> IExp -reduceIExp (IDeclPExp quant' decls' pexp) = IDeclPExp quant' decls' $ reducePExp pexp -reduceIExp (IFunExp op' exps') = redNav $ IFunExp op' $ map redExps exps' - where - (redNav, redExps) = if op' == iJoin then (reduceNav, id) else (id, reducePExp) -reduceIExp x = x - -reduceNav :: IExp -> IExp -reduceNav x@(IFunExp op' exps'@((PExp _ _ _ iexp@(IFunExp _ (pexp0:pexp:_))):pPexp:_)) = - if op' == iJoin && isParent pPexp && isClaferName pexp - then reduceNav $ _exp pexp0 - else x{_exps = (head exps'){_exp = reduceIExp iexp} : - tail exps'} -reduceNav x = x - - -desugarDecl :: Bool -> Decl -> IDecl -desugarDecl isDisj' (Decl _ locids exp') = - IDecl isDisj' (map desugarLocId locids) (desugarExp exp') - - -sugarDecl :: IDecl -> Decl -sugarDecl (IDecl _ locids exp') = - Decl noSpan (map sugarLocId locids) (sugarExp exp') - - -desugarLocId :: LocId -> String -desugarLocId (LocIdIdent _ id') = transIdent id' - - -sugarLocId :: String -> LocId -sugarLocId x = LocIdIdent noSpan $ mkIdent x - -desugarQuant :: Quant -> IQuant -desugarQuant (QuantNo _) = INo -desugarQuant (QuantNot _) = INo -desugarQuant (QuantLone _) = ILone -desugarQuant (QuantOne _) = IOne -desugarQuant (QuantSome _) = ISome - -sugarQuant :: IQuant -> Quant -sugarQuant INo = QuantNo noSpan -- will never sugar to QuantNOT -sugarQuant ILone = QuantLone noSpan -sugarQuant IOne = QuantOne noSpan -sugarQuant ISome = QuantSome noSpan -sugarQuant IAll = error "sugarQaunt was called on IAll, this is not allowed!" --Should never happen +{-# LANGUAGE RankNTypes #-}+{-+ Copyright (C) 2012-2015 Kacper Bak, Jimmy Liang, Michal Antkiewicz, Paulius Juodisius <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+{- | Transforms an Abstract Syntax Tree (AST) from "Language.Clafer.Front.AbsClafer"+into Intermediate representation (IR) from "Language.Clafer.Intermediate.Intclafer" of a Clafer model.+-}+module Language.Clafer.Intermediate.Desugarer where++import Language.Clafer.Common+import Data.Maybe (fromMaybe)+import Language.Clafer.Front.AbsClafer+import Language.Clafer.Intermediate.Intclafer++-- | Transform the AST into the intermediate representation (IR)+desugarModule :: Maybe String -> Module -> IModule+desugarModule mURL (Module _ declarations) = IModule+ (fromMaybe "" mURL)+ (declarations >>= desugarEnums >>= desugarDeclaration)++sugarModule :: IModule -> Module+sugarModule x = Module noSpan $ map sugarDeclaration $ _mDecls x -- (fragments x >>= mDecls)++-- | desugars enumeration to abstract and global singleton features+desugarEnums :: Declaration -> [Declaration]+desugarEnums (EnumDecl (Span p1 p2) id' enumids) = absEnum : map mkEnum enumids+ where+ p2' = case enumids of+ -- the abstract enum clafer should end before the first literal begins+ ((EnumIdIdent (Span (Pos y' x') _) _):_) -> Pos y' (x'-3) -- cutting the ' = '+ [] -> p2 -- should never happen - cannot have enum without any literals. Return the original end pos.+ oneToOne pos' = (CardInterval noSpan $+ NCard noSpan (PosInteger (pos', "1")) (ExIntegerNum noSpan $ PosInteger (pos', "1")))+ absEnum = let+ s1 = Span p1 p2'+ in+ ElementDecl s1 $+ Subclafer s1 $+ Clafer s1 (Abstract s1) (GCardEmpty s1) id' (SuperEmpty s1) (ReferenceEmpty s1) (CardEmpty s1) (InitEmpty s1) (ElementsList s1 [])+ mkEnum (EnumIdIdent s2 eId) = -- each concrete clafer must fit within the original span of the literal+ ElementDecl s2 $+ Subclafer s2 $+ Clafer s2 (AbstractEmpty s2) (GCardEmpty s2) eId ((SuperSome s2) (ClaferId s2 $ Path s2 [ModIdIdent s2 id'])) (ReferenceEmpty s2) (oneToOne (0, 0)) (InitEmpty s2) (ElementsList s2 [])+desugarEnums x = [x]+++desugarDeclaration :: Declaration -> [IElement]+desugarDeclaration (ElementDecl _ element) = desugarElement element+desugarDeclaration _ = error "Desugarer.desugarDeclaration: enum declarations should have already been converted to clafers. BUG."+++sugarDeclaration :: IElement -> Declaration+sugarDeclaration (IEClafer clafer) = ElementDecl (_cinPos clafer) $ Subclafer (_cinPos clafer) $ sugarClafer clafer+sugarDeclaration (IEConstraint True constraint) =+ ElementDecl (_inPos constraint) $ Subconstraint (_inPos constraint) $ sugarConstraint constraint+sugarDeclaration (IEConstraint False assertion) =+ ElementDecl (_inPos assertion) $ SubAssertion (_inPos assertion) $ sugarAssertion assertion+sugarDeclaration (IEGoal isMaximize' goal) = ElementDecl (_inPos goal) $ Subgoal (_inPos goal) $ sugarGoal goal isMaximize'+++desugarClafer :: Clafer -> [IElement]+desugarClafer claf@(Clafer s abstract gcrd' id' super' reference' crd' init' elements') =+ case (super', reference') of+ (SuperSome ss setExp, ReferenceEmpty _) -> if isPrimitive $ getPExpClaferIdent setExp+ then desugarClafer (Clafer s abstract gcrd' id' (SuperEmpty s) (ReferenceSet ss setExp) crd' init' elements')+ else desugarClafer' claf+ (SuperSome _ setExp, ReferenceSet _ _) -> if isPrimitive $ getPExpClaferIdent setExp+ then error "Desugarer: cannot rewrite : with primitive type into -> because a reference is also present. Using : with primitive types is discouraged."+ else desugarClafer' claf+ (SuperSome _ setExp, ReferenceBag _ _) -> if isPrimitive $ getPExpClaferIdent setExp+ then error "Desugarer: cannot rewrite : with primitive type into -> because a reference is also present. Using : with primitive types is discouraged."+ else desugarClafer' claf+ _ -> desugarClafer' claf+ where+ desugarClafer' (Clafer s'' abstract'' gcrd'' id'' super'' reference'' crd'' init'' elements'') =+ (IEClafer $ IClafer s'' (desugarAbstract abstract'') (desugarGCard gcrd'') (transIdent id'')+ "" "" (desugarSuper super'') (desugarReference reference'') (desugarCard crd'') (0, -1)+ (desugarElements elements'')) : (desugarInit id'' init'')++getPExpClaferIdent :: Exp -> String+getPExpClaferIdent (ClaferId _ (Path _ [ (ModIdIdent _ pident') ] )) = transIdent pident'+getPExpClaferIdent (EJoin _ _ e2) = getPExpClaferIdent e2+getPExpClaferIdent _ = error "Desugarer:getPExpClaferIdent not given a ClaferId PExp"++sugarClafer :: IClafer -> Clafer+sugarClafer (IClafer s abstract gcard' _ uid' _ super' reference' crd' _ elements') =+ Clafer s (sugarAbstract abstract) (sugarGCard gcard') (mkIdent uid')+ (sugarSuper super') (sugarReference reference') (sugarCard crd') (InitEmpty s) (sugarElements elements')+++desugarSuper :: Super -> Maybe PExp+desugarSuper (SuperEmpty _) = Nothing+desugarSuper (SuperSome _ (ClaferId _ (Path _ [ (ModIdIdent _ (PosIdent (_, "clafer"))) ] ))) = Nothing+desugarSuper (SuperSome _ setexp) = Just $ desugarExp setexp++desugarReference :: Reference -> Maybe IReference+desugarReference (ReferenceEmpty _) = Nothing+desugarReference (ReferenceSet _ setexp) = Just $ IReference True $ desugarExp setexp+desugarReference (ReferenceBag _ setexp) = Just $ IReference False $ desugarExp setexp++desugarInit :: PosIdent -> Init -> [IElement]+desugarInit _ (InitEmpty _) = []+desugarInit id' (InitSome s inithow exp') = [ IEConstraint (desugarInitHow inithow) (pExpDefPid s implIExp) ]+ where+ cId :: PExp+ cId = mkPLClaferId (getSpan id') (snd $ getIdent id') False Nothing+ -- <id> = <exp'>+ assignIExp :: IExp+ assignIExp = (IFunExp "=" [cId, desugarExp exp'])+ -- some <id> => <assignIExp>+ implIExp :: IExp+ implIExp = (IFunExp "=>" [ pExpDefPid s $ IDeclPExp ISome [] cId, pExpDefPid s assignIExp ])+ getIdent (PosIdent y) = y++desugarInitHow :: InitHow -> Bool+desugarInitHow (InitConstant _) = True+desugarInitHow (InitDefault _ )= False+++desugarName :: Name -> IExp+desugarName (Path _ path) =+ IClaferId (concatMap ((++ modSep).desugarModId) (init path))+ (desugarModId $ last path) True Nothing++desugarModId :: ModId -> Result+desugarModId (ModIdIdent _ id') = transIdent id'++sugarModId :: String -> ModId+sugarModId modid = ModIdIdent noSpan $ mkIdent modid++sugarSuper :: Maybe PExp -> Super+sugarSuper Nothing = SuperEmpty noSpan+sugarSuper (Just pexp') = SuperSome noSpan (sugarExp pexp')++sugarReference :: Maybe IReference -> Reference+sugarReference Nothing = ReferenceEmpty noSpan+sugarReference (Just (IReference True pexp')) = ReferenceSet noSpan (sugarExp pexp')+sugarReference (Just (IReference False pexp')) = ReferenceBag noSpan (sugarExp pexp')++sugarInitHow :: Bool -> InitHow+sugarInitHow True = InitConstant noSpan+sugarInitHow False = InitDefault noSpan+++desugarConstraint :: Constraint -> PExp+desugarConstraint (Constraint _ exps') = desugarPath $ desugarExp $+ (if length exps' > 1 then foldl1 (EAnd noSpan) else head) exps'++desugarAssertion :: Assertion -> PExp+desugarAssertion (Assertion _ exps') = desugarPath $ desugarExp $+ (if length exps' > 1 then foldl1 (EAnd noSpan) else head) exps'++desugarGoal :: Goal -> IElement+desugarGoal (GoalMinimize s [exp']) = mkMinimizeMaximizePExp False s exp'+desugarGoal (GoalMinDeprecated s [exp']) = mkMinimizeMaximizePExp False s exp'+desugarGoal (GoalMaximize s [exp']) = mkMinimizeMaximizePExp True s exp'+desugarGoal (GoalMaxDeprecated s [exp']) = mkMinimizeMaximizePExp True s exp'+desugarGoal goal = error $ "Desugarer.desugarGoal: malformed objective:\n" ++ show goal++mkMinimizeMaximizePExp :: Bool -> Span -> Exp -> IElement+mkMinimizeMaximizePExp isMaximize' s exp' =+ IEGoal isMaximize' $ desugarPath $ PExp Nothing "" s $ IFunExp (if isMaximize' then iMaximize else iMinimize) [desugarExp exp']++sugarConstraint :: PExp -> Constraint+sugarConstraint pexp = Constraint (_inPos pexp) $ map sugarExp [pexp]++sugarAssertion :: PExp -> Assertion+sugarAssertion pexp = Assertion (_inPos pexp) $ map sugarExp [pexp]++sugarGoal :: PExp -> Bool -> Goal+sugarGoal PExp{_exp=IFunExp _ [pexp]} True = GoalMaximize (_inPos pexp) $ map sugarExp [pexp]+sugarGoal PExp{_exp=IFunExp _ [pexp]} False = GoalMinimize (_inPos pexp) $ map sugarExp [pexp]+sugarGoal goal _ = error $ "Desugarer.sugarGoal: malformed objective:\n" ++ show goal++desugarAbstract :: Abstract -> Bool+desugarAbstract (AbstractEmpty _) = False+desugarAbstract (Abstract _) = True+++sugarAbstract :: Bool -> Abstract+sugarAbstract False = AbstractEmpty noSpan+sugarAbstract True = Abstract noSpan+++desugarElements :: Elements -> [IElement]+desugarElements (ElementsEmpty _) = []+desugarElements (ElementsList _ es) = es >>= desugarElement+++sugarElements :: [IElement] -> Elements+sugarElements x = ElementsList noSpan $ map sugarElement x+++desugarElement :: Element -> [IElement]+desugarElement x = case x of+ Subclafer _ claf -> (desugarClafer claf)+ ClaferUse s name crd es -> desugarClafer $ Clafer s+ (AbstractEmpty s) (GCardEmpty s) (mkIdent $ _sident $ desugarName name)+ (SuperSome s (ClaferId s name)) (ReferenceEmpty s) crd (InitEmpty s) es+ Subconstraint _ constraint ->+ [IEConstraint True $ desugarConstraint constraint]+ SubAssertion _ assertion ->+ [IEConstraint False $ desugarAssertion assertion]+ Subgoal _ goal -> [desugarGoal goal]+++sugarElement :: IElement -> Element+sugarElement x = case x of+ IEClafer claf -> Subclafer noSpan $ sugarClafer claf+ IEConstraint True constraint -> Subconstraint noSpan $ sugarConstraint constraint+ IEConstraint False assertion -> SubAssertion noSpan $ sugarAssertion assertion+ IEGoal isMaximize' goal -> Subgoal noSpan $ sugarGoal goal isMaximize'++desugarGCard :: GCard -> Maybe IGCard+desugarGCard x = case x of+ GCardEmpty _ -> Nothing+ GCardXor _ -> Just $ IGCard True (1, 1)+ GCardOr _ -> Just $ IGCard True (1, -1)+ GCardMux _ -> Just $ IGCard True (0, 1)+ GCardOpt _ -> Just $ IGCard True (0, -1)+ GCardInterval _ ncard ->+ Just $ IGCard (isOptionalDef ncard) $ desugarNCard ncard++isOptionalDef :: NCard -> Bool+isOptionalDef (NCard _ m n) = ((0::Integer) == mkInteger m) && (not $ isExIntegerAst n)++isExIntegerAst :: ExInteger -> Bool+isExIntegerAst (ExIntegerAst _) = True+isExIntegerAst _ = False++sugarGCard :: Maybe IGCard -> GCard+sugarGCard x = case x of+ Nothing -> GCardEmpty noSpan+ Just (IGCard _ (i, ex)) -> GCardInterval noSpan $ NCard noSpan (PosInteger ((0, 0), show i)) (sugarExInteger ex)+++desugarCard :: Card -> Maybe Interval+desugarCard x = case x of+ CardEmpty _ -> Nothing+ CardLone _ -> Just (0, 1)+ CardSome _ -> Just (1, -1)+ CardAny _ -> Just (0, -1)+ CardNum _ n -> Just (mkInteger n, mkInteger n)+ CardInterval _ ncard -> Just $ desugarNCard ncard++desugarNCard :: NCard -> (Integer, Integer)+desugarNCard (NCard _ i ex) = (mkInteger i, desugarExInteger ex)++desugarExInteger :: ExInteger -> Integer+desugarExInteger (ExIntegerAst _) = -1+desugarExInteger (ExIntegerNum _ n) = mkInteger n++sugarCard :: Maybe Interval -> Card+sugarCard x = case x of+ Nothing -> CardEmpty noSpan+ Just (i, ex) ->+ CardInterval noSpan $ NCard noSpan (PosInteger ((0, 0), show i)) (sugarExInteger ex)++sugarExInteger :: Integer -> ExInteger+sugarExInteger n = if n == -1 then ExIntegerAst noSpan else (ExIntegerNum noSpan $ PosInteger ((0, 0), show n))++desugarExp :: Exp -> PExp+desugarExp x = pExpDefPid (getSpan x) $ desugarExp' x++desugarExp' :: Exp -> IExp+desugarExp' x = case x of+ EDeclAllDisj _ decl exp' ->+ IDeclPExp IAll [desugarDecl True decl] (dpe exp')+ EDeclAll _ decl exp' -> IDeclPExp IAll [desugarDecl False decl] (dpe exp')+ EDeclQuantDisj _ quant' decl exp' ->+ IDeclPExp (desugarQuant quant') [desugarDecl True decl] (dpe exp')+ EDeclQuant _ quant' decl exp' ->+ IDeclPExp (desugarQuant quant') [desugarDecl False decl] (dpe exp')+ EIff _ exp0 exp' -> dop iIff [exp0, exp']+ EImplies _ exp0 exp' -> dop iImpl [exp0, exp']+ EImpliesElse _ exp0 exp1 exp' -> dop iIfThenElse [exp0, exp1, exp']+ EOr _ exp0 exp' -> dop iOr [exp0, exp']+ EXor _ exp0 exp' -> dop iXor [exp0, exp']+ EAnd _ exp0 exp' -> dop iAnd [exp0, exp']+ ENeg _ exp' -> dop iNot [exp']+ EQuantExp _ quant' exp' ->+ IDeclPExp (desugarQuant quant') [] (desugarExp exp')+ ELt _ exp0 exp' -> dop iLt [exp0, exp']+ EGt _ exp0 exp' -> dop iGt [exp0, exp']+ EEq _ exp0 exp' -> dop iEq [exp0, exp']+ ELte _ exp0 exp' -> dop iLte [exp0, exp']+ EGte _ exp0 exp' -> dop iGte [exp0, exp']+ ENeq _ exp0 exp' -> dop iNeq [exp0, exp']+ EIn _ exp0 exp' -> dop iIn [exp0, exp']+ ENin _ exp0 exp' -> dop iNin [exp0, exp']+ EAdd _ exp0 exp' -> dop iPlus [exp0, exp']+ ESub _ exp0 exp' -> dop iSub [exp0, exp']+ EMul _ exp0 exp' -> dop iMul [exp0, exp']+ EDiv _ exp0 exp' -> dop iDiv [exp0, exp']+ ERem _ exp0 exp' -> dop iRem [exp0, exp']+ ECard _ exp' -> dop iCSet [exp']+ ESum _ exp' -> dop iSumSet [exp']+ EProd _ exp' -> dop iProdSet [exp']+ EMinExp _ exp' -> dop iMin [exp']+ EGMax _ exp' -> dop iMaximum [exp']+ EGMin _ exp' -> dop iMinimum [exp']+ EInt _ n -> IInt $ mkInteger n+ EDouble _ (PosDouble n) -> IDouble $ read $ snd n+ EReal _ (PosReal n) -> IReal $ read $ snd n+ EStr _ (PosString str) -> IStr $ snd str+ EUnion _ exp0 exp' -> dop iUnion [exp0, exp']+ EUnionCom _ exp0 exp' -> dop iUnion [exp0, exp']+ EDifference _ exp0 exp' -> dop iDifference [exp0, exp']+ EIntersection _ exp0 exp' -> dop iIntersection [exp0, exp']+ EIntersectionDeprecated _ exp0 exp' -> dop iIntersection [exp0, exp']+ EDomain _ exp0 exp' -> dop iDomain [exp0, exp']+ ERange _ exp0 exp' -> dop iRange [exp0, exp']+ EJoin _ exp0 exp' -> dop iJoin [exp0, exp']+ ClaferId _ name -> desugarName name+ where+ dop = desugarOp desugarExp+ dpe = desugarPath.desugarExp++desugarOp :: (a -> PExp) -> String -> [a] -> IExp+desugarOp f op' exps' =+ if (op' == iIfThenElse)+ then IFunExp op' $ (desugarPath $ head mappedList) : (map reducePExp $ tail mappedList)+ else IFunExp op' $ map (trans.f) exps'+ where+ mappedList = map f exps'+ trans = if op' `elem` ([iNot, iIfThenElse] ++ logBinOps)+ then desugarPath else id++sugarExp :: PExp -> Exp+sugarExp x = sugarExp' $ _exp x+++sugarExp' :: IExp -> Exp+sugarExp' x = case x of+ IDeclPExp quant' [] pexp -> EQuantExp noSpan (sugarQuant quant') (sugarExp pexp)+ IDeclPExp IAll (decl@(IDecl True _ _):[]) pexp ->+ EDeclAllDisj noSpan (sugarDecl decl) (sugarExp pexp)+ IDeclPExp IAll (decl@(IDecl False _ _):[]) pexp ->+ EDeclAll noSpan (sugarDecl decl) (sugarExp pexp)+ IDeclPExp quant' (decl@(IDecl True _ _):[]) pexp ->+ EDeclQuantDisj noSpan (sugarQuant quant') (sugarDecl decl) (sugarExp pexp)+ IDeclPExp quant' (decl@(IDecl False _ _):[]) pexp ->+ EDeclQuant noSpan (sugarQuant quant') (sugarDecl decl) (sugarExp pexp)+ IClaferId "" id' _ _ -> ClaferId noSpan $ Path noSpan [ModIdIdent noSpan $ mkIdent id']+ IClaferId modName' id' _ _ -> ClaferId noSpan $ Path noSpan $ (sugarModId modName') : [sugarModId id']+ IInt n -> EInt noSpan $ PosInteger ((0, 0), show n)+ IDouble n -> EDouble noSpan $ PosDouble ((0, 0), show n)+ IReal n -> EReal noSpan $ PosReal ((0, 0), show n)+ IStr str -> EStr noSpan $ PosString ((0, 0), str)+ IFunExp op' exps' ->+ if op' `elem` unOps then (sugarUnOp op') (exps''!!0)+ else if op' `elem` binOps then (sugarOp op') (exps''!!0) (exps''!!1)+ else (sugarTerOp op') (exps''!!0) (exps''!!1) (exps''!!2)+ where+ exps'' = map sugarExp exps'+ x' -> error $ "Desugarer.sugarExp': invalid argument: " ++ show x' -- This should never happen+ where+ sugarUnOp op''+ | op'' == iNot = ENeg noSpan+ | op'' == iCSet = ECard noSpan+ | op'' == iMin = EMinExp noSpan+ | op'' == iMaximum = EGMax noSpan+ | op'' == iMinimum = EGMin noSpan+ | op'' == iSumSet = ESum noSpan+ | op'' == iProdSet = EProd noSpan+ | otherwise = error $ show op'' ++ "is not an op"+ sugarOp op''+ | op'' == iIff = EIff noSpan+ | op'' == iImpl = EImplies noSpan+ | op'' == iOr = EOr noSpan+ | op'' == iXor = EXor noSpan+ | op'' == iAnd = EAnd noSpan+ | op'' == iLt = ELt noSpan+ | op'' == iGt = EGt noSpan+ | op'' == iEq = EEq noSpan+ | op'' == iLte = ELte noSpan+ | op'' == iGte = EGte noSpan+ | op'' == iNeq = ENeq noSpan+ | op'' == iIn = EIn noSpan+ | op'' == iNin = ENin noSpan+ | op'' == iPlus = EAdd noSpan+ | op'' == iSub = ESub noSpan+ | op'' == iMul = EMul noSpan+ | op'' == iDiv = EDiv noSpan+ | op'' == iRem = ERem noSpan+ | op'' == iUnion = EUnion noSpan+ | op'' == iDifference = EDifference noSpan+ | op'' == iIntersection = EIntersection noSpan+ | op'' == iDomain = EDomain noSpan+ | op'' == iRange = ERange noSpan+ | op'' == iJoin = EJoin noSpan+ | otherwise = error $ show op'' ++ "is not an op"+ sugarTerOp op''+ | op'' == iIfThenElse = EImpliesElse noSpan+ | otherwise = error $ show op'' ++ "is not an op"+++desugarPath :: PExp -> PExp+desugarPath (PExp iType' pid' pos' x) = reducePExp $ PExp iType' pid' pos' result+ where+ result+ | isSetExp x = IDeclPExp ISome [] (pExpDefPid pos' x)+ | isNegSome x = IDeclPExp INo [] $ _bpexp $ _exp $ head $ _exps x+ | otherwise = x+ isNegSome (IFunExp op' [PExp _ _ _ (IDeclPExp ISome [] _)]) = op' == iNot+ isNegSome _ = False+++isSetExp :: IExp -> Bool+isSetExp (IClaferId _ _ _ _) = True+isSetExp (IFunExp op' _) = op' `elem` setBinOps+isSetExp _ = False+++-- reduce parent+reducePExp :: PExp -> PExp+reducePExp (PExp t pid' pos' x) = PExp t pid' pos' $ reduceIExp x++reduceIExp :: IExp -> IExp+reduceIExp (IDeclPExp quant' decls' pexp) = IDeclPExp quant' decls' $ reducePExp pexp+reduceIExp (IFunExp op' exps') = redNav $ IFunExp op' $ map redExps exps'+ where+ (redNav, redExps) = if op' == iJoin then (reduceNav, id) else (id, reducePExp)+reduceIExp x = x++reduceNav :: IExp -> IExp+reduceNav x@(IFunExp op' exps'@((PExp _ _ _ iexp@(IFunExp _ (pexp0:pexp:_))):pPexp:_)) =+ if op' == iJoin && isParent pPexp && isClaferName pexp+ then reduceNav $ _exp pexp0+ else x{_exps = (head exps'){_exp = reduceIExp iexp} :+ tail exps'}+reduceNav x = x+++desugarDecl :: Bool -> Decl -> IDecl+desugarDecl isDisj' (Decl _ locids exp') =+ IDecl isDisj' (map desugarLocId locids) (desugarExp exp')+++sugarDecl :: IDecl -> Decl+sugarDecl (IDecl _ locids exp') =+ Decl noSpan (map sugarLocId locids) (sugarExp exp')+++desugarLocId :: LocId -> String+desugarLocId (LocIdIdent _ id') = transIdent id'+++sugarLocId :: String -> LocId+sugarLocId x = LocIdIdent noSpan $ mkIdent x++desugarQuant :: Quant -> IQuant+desugarQuant (QuantNo _) = INo+desugarQuant (QuantNot _) = INo+desugarQuant (QuantLone _) = ILone+desugarQuant (QuantOne _) = IOne+desugarQuant (QuantSome _) = ISome++sugarQuant :: IQuant -> Quant+sugarQuant INo = QuantNo noSpan -- will never sugar to QuantNOT+sugarQuant ILone = QuantLone noSpan+sugarQuant IOne = QuantOne noSpan+sugarQuant ISome = QuantSome noSpan+sugarQuant IAll = error "sugarQaunt was called on IAll, this is not allowed!" --Should never happen
src/Language/Clafer/Intermediate/Intclafer.hs view
@@ -89,7 +89,7 @@ , _gcard :: Maybe IGCard -- ^ group cardinality , _ident :: CName -- ^ name declared in the model , _uid :: UID -- ^ a unique identifier - , _parentUID :: UID -- ^ "root" if top-level, "" if unresolved or for root clafer, otherwise UID of the parent clafer + , _parentUID :: UID -- ^ "root" if top-level concrete, "clafer" if top-level abstract, "" if unresolved or for root clafer, otherwise UID of the parent clafer , _super :: Maybe PExp -- ^ superclafer - only allowed PExp is IClaferId. Nothing = default super "clafer" , _reference :: Maybe IReference -- ^ reference type, bag or set , _card :: Maybe Interval -- ^ clafer cardinality
src/Language/Clafer/Intermediate/Resolver.hs view
@@ -39,10 +39,10 @@ resolveModule args' imodule = do r <- resolveNModule $ nameModule (skip_resolver args') imodule - resolveNamesModule args' =<< (rom' $ rem' r) + 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 + rom' = if skip_resolver args' then return else resolveOModule -- | Name resolver @@ -56,14 +56,15 @@ 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) + IEClafer claf -> IEClafer <$> nameClafer skipResolver puid claf + IEConstraint isHard' pexp -> IEConstraint isHard' <$> namePExp pexp + IEGoal isMaximize' pexp -> IEGoal isMaximize' <$> 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 + let puid' = if _isAbstract claf && puid == "root" then baseClafer else puid + 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'} @@ -81,7 +82,7 @@ decls'' <- mapM nameIDecl decls' pexp' <- namePExp pexp return $ IDeclPExp quant' decls'' pexp' - IFunExp op' pexps -> IFunExp op' `liftM` (mapM namePExp pexps) + IFunExp op' pexps -> IFunExp op' `liftM` mapM namePExp pexps _ -> return x nameIDecl :: MonadState GEnv m => IDecl -> m IDecl
src/Language/Clafer/Intermediate/ResolverName.hs view
@@ -53,7 +53,7 @@ -- | How a given name was resolved data HowResolved - = Special -- ^ "this", "parent", "dref", "root", and "children" + = Special -- ^ "this", "parent", "dref", "root", "clafer", and "children" | TypeSpecial -- ^ primitive type: "integer", "string" | Binding -- ^ local variable (in constraints) | Subclafers -- ^ clafer's descendant @@ -127,7 +127,7 @@ where env' = env {context = Just clafer, resPath = clafer : resPath env} subClafers' = tail $ bfs toNodeDeep [env'{resPath = [clafer]}] - ancClafers' = (init $ tails $ resPath env) >>= (mkAncestorList env) + ancClafers' = init (tails $ resPath env) >>= (mkAncestorList env) mkAncestorList :: SEnv -> [IClafer] -> [(IClafer, [IClafer])] mkAncestorList env rp = @@ -141,6 +141,7 @@ resolvePExp :: SEnv -> PExp -> Resolve PExp resolvePExp env pexp@PExp{_exp=x} = case x of + -- only local declarations change the environment IDeclPExp quant' decls' pexp2 -> do let (decls'', env') = runState (runExceptT $ (mapM (ExceptT . processDecl) decls')) env exp' <- IDeclPExp quant' <$> decls'' <*> resolvePExp env' pexp2 @@ -161,35 +162,38 @@ processDecl :: MonadState SEnv m => IDecl -> m (Resolve IDecl) processDecl decl = runExceptT $ do - env <- lift $ get + env <- lift get (body', path) <- liftError $ resolveNav env (_body decl) True lift $ modify (\e -> e { bindings = (_decls decl, path) : bindings e }) return $ decl {_body = body'} resolveNav :: SEnv -> PExp -> Bool -> Resolve (PExp, [IClafer]) -resolveNav env pexp0@PExp{_inPos=pos', _exp=x} isFirst = case x of - IFunExp "." [pexp1,pexp2] -> do - (pexp1', path1) <- resolveNav env pexp1 True - (pexp2', path2) <- resolveNav env{context = listToMaybe path1, resPath = path1} pexp2 False - -- if `dref` was added to the RHS we need to left rotate the tree - case pexp2' of - PExp{_exp=IFunExp "." [pexp2'l, pexp2'r]} -> (case pexp2'l of - PExp{_exp=IClaferId{_sident="dref"}} -> - let -- move the `dref` to the LHS - pexp0' = pexp0{_exp=IFunExp iJoin [pexp1', pexp2'l]} - in -- keep the RHS as is - return (pexp2{_exp=IFunExp iJoin [pexp0', pexp2'r]}, path2) +resolveNav env pexp0@PExp{_inPos=pos', _exp=x} isFirst = + case x of + IFunExp "." [pexp1,pexp2] -> do + (pexp1', path1) <- resolveNav env pexp1 True + (pexp2', path2) <- resolveNav env{context = listToMaybe path1, resPath = path1} pexp2 False + -- if `dref` was added to the RHS we need to left rotate the tree + case pexp2' of + PExp{_exp=IFunExp "." [pexp2'l, pexp2'r]} -> case pexp2'l of + PExp{_exp=IClaferId{_sident="dref"}} -> + let -- move the `dref` to the LHS + pexp0' = pexp0{_exp=IFunExp iJoin [pexp1', pexp2'l]} + in -- keep the RHS as is + return (pexp2{_exp=IFunExp iJoin [pexp0', pexp2'r]}, path2) + _ -> return (pexp0{_exp=IFunExp iJoin [pexp1', pexp2']}, path2) _ -> return (pexp0{_exp=IFunExp iJoin [pexp1', pexp2']}, path2) - ) - _ -> return (pexp0{_exp=IFunExp iJoin [pexp1', pexp2']}, path2) - IClaferId modName' id' _ _ -> if isFirst - then do - (exp', path') <- mkPath pos' env <$> resolveName pos' env id' - return (pexp0{_exp=exp'}, path') - else do - (exp', path') <- mkPath' pos' modName' <$> resolveImmName pos' env id' - return (pexp0{_exp=exp'}, path') - y -> throwError $ SemanticErr pos' $ "Cannot resolve nav of " ++ show y + IClaferId _ "root" _ _ -> return (pexp0, []) + IClaferId modName' id' _ _ -> if isFirst + then do + (exp', path') <- mkPath pos' env <$> resolveName pos' env id' + return (pexp0{_exp=exp'}, path') + else do + (exp', path') <- case resPath env of + [] -> mkPath' pos' modName' <$> resolveTopLevelName pos' env id' + _ -> mkPath' pos' modName' <$> resolveImmName pos' env id' + return (pexp0{_exp=exp'}, path') + y -> throwError $ SemanticErr pos' $ "Cannot resolve nav of " ++ show y -- | Depending on how resolved construct a navigation path from 'context env' mkPath :: Span -> SEnv -> (HowResolved, String, [IClafer]) -> (IExp, [IClafer]) @@ -236,12 +240,16 @@ Reference -> (toNav' pos' (zip ["dref", id'] (map Just path)), path) _ -> (IClaferId modName' id' False (_uid <$> bind), path) where - bind = case path of - [] -> Nothing - c:_ -> Just c + bind = case path of + [] -> Nothing + c:_ -> Just c -- ----------------------------------------------------------------------------- +resolveTopLevelName :: Span -> SEnv -> String -> Resolve (HowResolved, String, [IClafer]) +resolveTopLevelName pos' env id' = resolve env id' + [resolveTopLevelOnly pos', resolveNone pos'] + resolveName :: Span -> SEnv -> String -> Resolve (HowResolved, String, [IClafer]) resolveName pos' env id' = resolve env id' [resolveSpecial, resolveBind, resolveDescendants, resolveAncestor pos', resolveTopLevel pos', resolveNone pos'] @@ -253,7 +261,7 @@ -- when one strategy fails, we want to move to the next one -resolve :: (Monad f, Functor f) => SEnv -> String -> [SEnv -> String -> f (Maybe b)] -> f b +resolve :: Monad f => SEnv -> String -> [SEnv -> String -> f (Maybe b)] -> f b resolve env id' fs = fromJust <$> (runMaybeT $ msum $ map (\x -> MaybeT $ x env id') fs) @@ -290,7 +298,6 @@ resolveDescendants env id' = return $ (context env) >> (findFirst id' $ subClafers env) >>= (toMTriple Subclafers) - -- searches for a name in immediate subclafers (BFS) resolveChildren :: Span -> SEnv -> String -> Resolve (Maybe (HowResolved, String, [IClafer])) resolveChildren pos' env id' = resolveChildren' pos' env id' allInhChildren Subclafers @@ -324,6 +331,16 @@ (\(cs, hr) -> MaybeT (findUnique pos' id' cs) >>= (liftMaybe . toMTriple hr)) [(aClafers env, AbsClafer), (cClafers env, TopClafer)] +-- searches for a name in all subclafers (BFS) +resolveTopLevelOnly :: Span -> SEnv -> String -> Resolve (Maybe (HowResolved, String, [IClafer])) +resolveTopLevelOnly _ env id' = return result + where + found = filter (\c -> _ident c == id') $ clafers env + result = case found of + [c] -> Just (TopClafer, _uid c, found) + _ -> Nothing + + toNodeDeep :: SEnv -> ((IClafer, [IClafer]), [SEnv]) -- ((curr. clafer, resolution path), remaining children to traverse) toNodeDeep env @@ -352,8 +369,8 @@ findUnique :: Span -> String -> [(IClafer, [IClafer])] -> Resolve (Maybe (String, [IClafer])) findUnique pos' x xs = case filterPaths x $ nub xs of - [] -> return $ Nothing - [elem'] -> return $ Just $ (_uid $ fst elem', snd elem') + [] -> return Nothing + [elem'] -> return $ Just (_uid $ fst elem', snd elem') xs' -> throwError $ SemanticErr pos' $ "clafer " ++ show x ++ " " ++ errMsg where xs'' = map ((map _uid).snd) xs'
src/Language/Clafer/Intermediate/ResolverType.hs view
@@ -83,17 +83,17 @@ addTypeDecls t@TypeInfo{iTypeDecls = c} = t{iTypeDecls = extra ++ c} instance MonadTypeAnalysis m => MonadTypeAnalysis (ListT m) where - curThis = lift $ curThis + curThis = lift curThis localCurThis = mapListT . localCurThis - curPath = lift $ curPath + curPath = lift curPath localCurPath = mapListT . localCurPath typeDecls = lift typeDecls localDecls = mapListT . localDecls instance MonadTypeAnalysis m => MonadTypeAnalysis (ExceptT ClaferSErr m) where - curThis = lift $ curThis + curThis = lift curThis localCurThis = mapExceptT . localCurThis - curPath = lift $ curPath + curPath = lift curPath localCurPath = mapExceptT . localCurPath typeDecls = lift typeDecls localDecls = mapExceptT . localDecls @@ -122,19 +122,19 @@ isIndirectChild :: (Monad m) => UIDIClaferMap -> UID -> UID -> m Bool isIndirectChild uidIClaferMap' child parent = do (_:allSupers) <- hierarchy uidIClaferMap' parent - childOfSupers <- mapM ((isChild uidIClaferMap' child)._uid) $ allSupers + childOfSupers <- mapM ((isChild uidIClaferMap' child)._uid) allSupers return $ or childOfSupers isChild :: (Monad m) => UIDIClaferMap -> UID -> UID -> m Bool isChild uidIClaferMap' child parent = - (case findIClafer uidIClaferMap' child of - Nothing -> return False - Just childIClafer -> do - let directChild = (parent == _parentUID childIClafer) - indirectChild <- isIndirectChild uidIClaferMap' child parent - return $ directChild || indirectChild - ) + case findIClafer uidIClaferMap' child of + Nothing -> return False + Just childIClafer -> do + let directChild = (parent == _parentUID childIClafer) + indirectChild <- isIndirectChild uidIClaferMap' child parent + return $ directChild || indirectChild + str :: IType -> String str t = case unionType t of @@ -183,8 +183,8 @@ Just t -> if isTBoolean t then Nothing else Just $ oRef{_ref=r'} -resolveTElement TAReferences _ iec@(IEConstraint{}) = return iec -resolveTElement TAReferences _ ieg@(IEGoal{}) = return ieg +resolveTElement TAReferences _ iec@IEConstraint{} = return iec +resolveTElement TAReferences _ ieg@IEGoal{} = return ieg -- Phase two: only process constraints and goals resolveTElement TAExpressions _ (IEClafer iclafer) = @@ -207,7 +207,7 @@ do uidIClaferMap' <- asks iUIDIClaferMap curThis'' <- claferWithUid uidIClaferMap' curThis' - head <$> (localCurThis curThis'' $ (resolveTPExp constraint :: TypeAnalysis [PExp])) + head <$> localCurThis curThis'' (resolveTPExp constraint :: TypeAnalysis [PExp]) resolveTPExp :: PExp -> TypeAnalysis [PExp] @@ -248,7 +248,7 @@ resolveTPExp' p@PExp{_exp = IClaferId{_sident = "string"}} = runListT $ runExceptT $ return $ p `withType` TString resolveTPExp' p@PExp{_exp = IClaferId{_sident = "double"}} = runListT $ runExceptT $ return $ p `withType` TDouble resolveTPExp' p@PExp{_exp = IClaferId{_sident = "real"}} = runListT $ runExceptT $ return $ p `withType` TReal -resolveTPExp' p@PExp{_inPos, _exp = IClaferId{_sident="this"}} = do +resolveTPExp' p@PExp{_inPos, _exp = IClaferId{_sident="this"}} = runListT $ runExceptT $ do sident' <- _uid <$> curThis result <- (p `withType`) <$> typeOfUid sident' @@ -262,7 +262,8 @@ sident' <- if _sident == "this" then _uid <$> curThis else return _sident when (isJust curPath') $ do c <- mapM (isChild uidIClaferMap' sident') $ unionType $ fromJust curPath' - unless (or c) $ throwError $ SemanticErr _inPos ("'" ++ sident' ++ "' is not a child of type '" ++ str (fromJust curPath') ++ "'") + let parentId' = str (fromJust curPath') + unless (or c || parentId' == "root") $ throwError $ SemanticErr _inPos ("'" ++ sident' ++ "' is not a child of type '" ++ parentId' ++ "'") result <- (p `withType`) <$> typeOfUid sident' if _isTop then return result -- Case 1: Use the sident @@ -318,14 +319,21 @@ result' <- result return (result', e{_exps = [arg']}) - resolveTExp e@IFunExp {_op = "++", _exps = [arg1, arg2]} = - do - arg1s' <- resolveTPExp arg1 - arg2s' <- resolveTPExp arg2 - let union' a b = typeOf a +++ typeOf b - return $ [ return (union' arg1' arg2', e{_exps = [arg1', arg2']}) - | (arg1', arg2') <- sortBy (comparing $ length . unionType . uncurry union') $ liftM2 (,) arg1s' arg2s' - , (not $ isTBoolean $ typeOf arg1') && (not $ isTBoolean $ typeOf arg2') ] + resolveTExp e@IFunExp {_op = "++", _exps = [arg1, arg2]} = do + -- arg1s' <- resolveTPExp arg1 + -- arg2s' <- resolveTPExp arg2 + -- let union' a b = typeOf a +++ typeOf b + -- return [ return (union' arg1' arg2', e{_exps = [arg1', arg2']}) + -- | (arg1', arg2') <- sortBy (comparing $ length . unionType . uncurry union') $ liftM2 (,) arg1s' arg2s' + -- , not (isTBoolean $ typeOf arg1') && not (isTBoolean $ typeOf arg2') ] + runListT $ runExceptT $ do + arg1' <- lift $ ListT $ resolveTPExp arg1 + arg2' <- lift $ ListT $ resolveTPExp arg2 + let t1 = typeOf arg1' + let t2 = typeOf arg2' + return (t1 +++ t2, e{_exps = [arg1', arg2']}) + + resolveTExp e@IFunExp {_op, _exps = [arg1, arg2]} = do uidIClaferMap' <- asks iUIDIClaferMap runListT $ runExceptT $ do
src/Language/Clafer/Intermediate/ScopeAnalysis.hs view
@@ -1,31 +1,31 @@-{- - Copyright (C) 2013 Michal Antkiewicz <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -module Language.Clafer.Intermediate.ScopeAnalysis where - -import Language.Clafer.ClaferArgs -import Language.Clafer.Intermediate.Intclafer -import Language.Clafer.Intermediate.SimpleScopeAnalyzer - --- | Return an appropriate scope analysis for a given strategy -getScopeStrategy :: ScopeStrategy -> IModule -> [(String, Integer)] -getScopeStrategy Simple = simpleScopeAnalysis -getScopeStrategy _ = const [] +{-+ Copyright (C) 2013 Michal Antkiewicz <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+module Language.Clafer.Intermediate.ScopeAnalysis where++import Language.Clafer.ClaferArgs+import Language.Clafer.Intermediate.Intclafer+import Language.Clafer.Intermediate.SimpleScopeAnalyzer++-- | Return an appropriate scope analysis for a given strategy+getScopeStrategy :: ScopeStrategy -> IModule -> [(String, Integer)]+getScopeStrategy Simple = simpleScopeAnalysis+getScopeStrategy _ = const []
src/Language/Clafer/Intermediate/SimpleScopeAnalyzer.hs view
@@ -1,291 +1,291 @@-{- - Copyright (C) 2012-2015 Jimmy Liang, Kacper Bak, Michał Antkiewicz <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -module Language.Clafer.Intermediate.SimpleScopeAnalyzer (simpleScopeAnalysis) where - -import Control.Applicative -import Control.Lens hiding (elements, assign) -import Data.Graph -import Data.List -import Data.Data.Lens (biplate) -import Data.Map (Map) -import qualified Data.Map as Map -import Data.Maybe -import Data.Ord -import Data.Ratio -import Prelude hiding (exp) - -import Language.Clafer.Common -import Language.Clafer.Intermediate.Intclafer - --- | Collects the global cardinality and hierarchy information into proper, not necessarily lower, bounds. -simpleScopeAnalysis :: IModule -> [(String, Integer)] -simpleScopeAnalysis iModule@IModule{_mDecls = decls'} = - [(a, b) | (a, b) <- finalAnalysis, b /= 1] - where - uidClaferMap' = createUidIClaferMap iModule - findClafer :: UID -> IClafer - findClafer uid' = fromJust $ findIClafer uidClaferMap' uid' - - finalAnalysis = Map.toList $ foldl analyzeComponent supersAndRefsAnalysis connectedComponents - - upperCards u = - Map.findWithDefault (error $ "No upper cardinality for clafer named \"" ++ u ++ "\".") u upperCardsMap - upperCardsMap = Map.fromList [(_uid c, snd $ fromJust $ _card c) | c <- clafers] - - supersAnalysis = foldl (analyzeSupers uidClaferMap' clafers) Map.empty decls' - supersAndRefsAnalysis = foldl (analyzeRefs uidClaferMap' clafers) supersAnalysis decls' - constraintAnalysis = analyzeConstraints constraints upperCards - (subclaferMap, parentMap) = analyzeHierarchy uidClaferMap' clafers - connectedComponents = analyzeDependencies uidClaferMap' clafers - clafers :: [ IClafer ] - clafers = universeOn biplate iModule - constraints = concatMap findConstraints decls' - - lowerOrUpperFixedCard analysis' clafer = - maximum [cardLb, cardUb, lowFromConstraints, oneForStar, targetScopeForStar ] - where - Just (cardLb, cardUb) = _card clafer - oneForStar = if (cardLb == 0 && cardUb == -1) then 1 else 0 - targetScopeForStar = if ((isJust $ _reference clafer) && cardUb == -1) - then case getReference clafer of - [ref'] -> Map.findWithDefault 1 (fromMaybe "unknown" $ _uid <$> findIClafer uidClaferMap' ref' ) analysis' - _ -> 0 - else 0 - lowFromConstraints = Map.findWithDefault 0 (_uid clafer) constraintAnalysis - - analyzeComponent analysis' component = - case flattenSCC component of - [uid'] -> analyzeSingleton uid' analysis' - uids -> - foldr analyzeSingleton assume uids - where - -- assume that each of the scopes in the component is 1 while solving - assume = foldr (`Map.insert` 1) analysis' uids - where - analyzeSingleton uid' analysis'' = analyze analysis'' $ findClafer uid' - - analyze :: Map String Integer -> IClafer -> Map String Integer - analyze analysis' clafer = - -- Take the max between the supers and references analysis and this analysis - Map.insertWith max (_uid clafer) scope analysis' - where - scope - | _isAbstract clafer = sum subclaferScopes - | otherwise = parentScope * (lowerOrUpperFixedCard analysis' clafer) - - subclaferScopes = map (findOrError " subclafer scope not found" analysis') subclafers - parentScope = - case parentMaybe of - Just parent'' -> findOrError " parent scope not found" analysis' parent'' - Nothing -> rootScope - subclafers = Map.findWithDefault [] (_uid clafer) subclaferMap - parentMaybe = Map.lookup (_uid clafer) parentMap - rootScope = 1 - findOrError message m key = Map.findWithDefault (error $ key ++ message) key m - -analyzeSupers :: UIDIClaferMap -> [IClafer] -> Map String Integer -> IElement -> Map String Integer -analyzeSupers uidClaferMap' clafers analysis (IEClafer clafer) = - foldl (analyzeSupers uidClaferMap' clafers) analysis' (_elements clafer) - where - (Just (cardLb, cardUb)) = _card clafer - lowerOrFixedUpperBound = maximum [1, cardLb, cardUb ] - analysis' = if (isJust $ _reference clafer) - then analysis - else case (directSuper uidClaferMap' clafer) of - (Just c) -> Map.alter (incLB lowerOrFixedUpperBound) (_uid c) analysis - Nothing -> analysis - incLB lb' Nothing = Just lb' - incLB lb' (Just lb) = Just (lb + lb') -analyzeSupers _ _ analysis _ = analysis - -analyzeRefs :: UIDIClaferMap -> [IClafer] -> Map String Integer -> IElement -> Map String Integer -analyzeRefs uidClaferMap' clafers analysis (IEClafer clafer) = - foldl (analyzeRefs uidClaferMap' clafers) analysis' (_elements clafer) - where - (Just (cardLb, cardUb)) = _card clafer - lowerOrFixedUpperBound = maximum [1, cardLb, cardUb] - analysis' = if (isJust $ _reference clafer) - then case (directSuper uidClaferMap' clafer) of - (Just c) -> Map.alter (maxLB lowerOrFixedUpperBound) (_uid c) analysis - Nothing -> analysis - else analysis - maxLB lb' Nothing = Just lb' - maxLB lb' (Just lb) = Just (max lb lb') -analyzeRefs _ _ analysis _ = analysis - -analyzeConstraints :: [PExp] -> (String -> Integer) -> Map String Integer -analyzeConstraints constraints upperCards = - foldr analyzeConstraint Map.empty $ filter isOneOrSomeConstraint constraints - where - isOneOrSomeConstraint PExp{_exp = IDeclPExp{_quant = quant'}} = - -- Only these two quantifiers requires an increase in scope to satisfy. - case quant' of - IOne -> True - ISome -> True - _ -> False - isOneOrSomeConstraint _ = False - - -- Only considers how quantifiers affect scope. Other types of constraints are not considered. - -- Constraints of the type [some path1.path2] or [no path1.path2], etc. - analyzeConstraint PExp{_exp = IDeclPExp{_oDecls = [], _bpexp = bpexp'}} analysis = - foldr atLeastOne analysis path' - where - path' = dropThisAndParent $ unfoldJoins bpexp' - atLeastOne = Map.insertWith max `flip` 1 - - -- Constraints of the type [all disj a : path1.path2] or [some b : path3.path4], etc. - analyzeConstraint PExp{_exp = IDeclPExp{_oDecls = decls'}} analysis = - foldr analyzeDecl analysis decls' - analyzeConstraint _ analysis = analysis - - analyzeDecl IDecl{_isDisj = isDisj', _decls = decls', _body = body'} analysis = - foldr (uncurry insert') analysis $ zip path' scores - where - -- Take the first element in the path', and change its effective lower cardinality. - -- Can overestimate the scope. - path' = dropThisAndParent $ unfoldJoins body' - -- "disj a;b;c" implies at least 3 whereas "a;b;c" implies at least one. - minScope = if isDisj' then fromIntegral $ length decls' else 1 - insert' = Map.insertWith max - - scores = assign path' minScope - - {- - - abstract Z - - C * - - D : integer * - - - - A : Z - - B : integer - - [some disj a;b;c;d : D | a = 1 && b = 2 && c = 3 && d = B] - -} - -- Need at least 4 D's per A. - -- Either - -- a) Make the effective lower cardinality of C=4 and D=1 - -- b) Make the effective lower cardinality of C=1 and D=4 - -- c) Some other combination. - -- Choose b, a greedy algorithm that starts from the lowest child progressing upwards. - - {- - - abstract Z - - C * - - D : integer 3..* - - - - A : Z - - B : integer - - [some disj a;b;c;d : D | a = 1 && b = 2 && c = 3 && d = B] - -} - -- The algorithm we do is greedy so it will chose D=3. - -- However, it still needs more D's so it will choose C=2 - -- C=2, D=3 - -- This might not be optimum since now the scope allows for 6 D's. - -- A better solution might be C=2, D=2. - -- Well too bad, we are using the greedy algorithm. - assign [] _ = [1] - assign (p : ps) score = - pScore : ps' - where - --upper = upperCards p - ps' = assign ps score - psScore = product $ ps' - pDesireScore = ceiling (score % psScore) - pMaxScore = upperCards p - pScore = min' pDesireScore pMaxScore - - min' a b = if b == -1 then a else min a b - - -- The each child has at most one parent. No matter what the path in a quantifier - -- looks like, we ignore the parent parts. - dropThisAndParent = dropWhile (== "parent") . dropWhile (== "this") - - -analyzeDependencies :: UIDIClaferMap -> [IClafer] -> [SCC String] -analyzeDependencies uidClaferMap' clafers = connComponents - where - connComponents = stronglyConnComp [(key, key, depends) | (key, depends) <- dependencyGraph] - dependencies = concatMap (dependency uidClaferMap') clafers - dependencyGraph = Map.toList $ Map.fromListWith (++) [(a, [b]) | (a, b) <- dependencies] - -dependency :: UIDIClaferMap -> IClafer -> [(String, String)] -dependency uidClaferMap' clafer = - selfDependency : (maybeToList superDependency ++ childDependencies) - where - -- This is to make the "stronglyConnComp" from Data.Graph play nice. Otherwise, - -- clafers with no dependencies will not appear in the result. - selfDependency = (_uid clafer, _uid clafer) - superDependency - | isNothing $ _super clafer = Nothing - | otherwise = - do - super' <- directSuper uidClaferMap' clafer - -- Need to analyze clafer before its super - return (_uid super', _uid clafer) - -- Need to analyze clafer before its children - childDependencies = [(_uid child, _uid clafer) | child <- childClafers clafer] - - -analyzeHierarchy :: UIDIClaferMap -> [IClafer] -> (Map String [String], Map String String) -analyzeHierarchy uidClaferMap' clafers = - foldl hierarchy (Map.empty, Map.empty) clafers - where - hierarchy (subclaferMap, parentMap) clafer = (subclaferMap', parentMap') - where - subclaferMap' = - case super' of - Just super'' -> Map.insertWith (++) (_uid super'') [_uid clafer] subclaferMap - Nothing -> subclaferMap - super' = directSuper uidClaferMap' clafer - parentMap' = foldr (flip Map.insert $ _uid clafer) parentMap (map _uid $ childClafers clafer) - -directSuper :: UIDIClaferMap -> IClafer -> Maybe IClafer -directSuper uidClaferMap' clafer = - second $ findHierarchy getSuper uidClaferMap' clafer - where - second [] = Nothing - second [_] = Nothing - second (_:x:_) = Just x - - --- Find all constraints -findConstraints :: IElement -> [PExp] -findConstraints IEConstraint{_cpexp = c} = [c] -findConstraints (IEClafer clafer) = concatMap findConstraints (_elements clafer) -findConstraints _ = [] - --- Finds all the direct ancestors (ie. children) -childClafers :: IClafer -> [IClafer] -childClafers clafer = clafer ^.. elements.traversed.iClafer - --- Unfold joins --- If the expression is a tree of only joins, then this function will flatten --- the joins into a list. --- Otherwise, returns an empty list. -unfoldJoins :: PExp -> [String] -unfoldJoins pexp = - fromMaybe [] $ unfoldJoins' pexp - where - unfoldJoins' PExp{_exp = (IFunExp "." args)} = - return $ args >>= unfoldJoins - unfoldJoins' PExp{_exp = IClaferId{_sident = sident'}} = - return $ [sident'] - unfoldJoins' _ = - fail "not a join" +{-+ Copyright (C) 2012-2015 Jimmy Liang, Kacper Bak, Michał Antkiewicz <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+module Language.Clafer.Intermediate.SimpleScopeAnalyzer (simpleScopeAnalysis) where++import Control.Applicative+import Control.Lens hiding (elements, assign)+import Data.Graph+import Data.List+import Data.Data.Lens (biplate)+import Data.Map (Map)+import qualified Data.Map as Map+import Data.Maybe+import Data.Ord+import Data.Ratio+import Prelude hiding (exp)++import Language.Clafer.Common+import Language.Clafer.Intermediate.Intclafer++-- | Collects the global cardinality and hierarchy information into proper, not necessarily lower, bounds.+simpleScopeAnalysis :: IModule -> [(String, Integer)]+simpleScopeAnalysis iModule@IModule{_mDecls = decls'} =+ [(a, b) | (a, b) <- finalAnalysis, b /= 1]+ where+ uidClaferMap' = createUidIClaferMap iModule+ findClafer :: UID -> IClafer+ findClafer uid' = fromJust $ findIClafer uidClaferMap' uid'++ finalAnalysis = Map.toList $ foldl analyzeComponent supersAndRefsAnalysis connectedComponents++ upperCards u =+ Map.findWithDefault (error $ "No upper cardinality for clafer named \"" ++ u ++ "\".") u upperCardsMap+ upperCardsMap = Map.fromList [(_uid c, snd $ fromJust $ _card c) | c <- clafers]++ supersAnalysis = foldl (analyzeSupers uidClaferMap' clafers) Map.empty decls'+ supersAndRefsAnalysis = foldl (analyzeRefs uidClaferMap' clafers) supersAnalysis decls'+ constraintAnalysis = analyzeConstraints constraints upperCards+ (subclaferMap, parentMap) = analyzeHierarchy uidClaferMap' clafers+ connectedComponents = analyzeDependencies uidClaferMap' clafers+ clafers :: [ IClafer ]+ clafers = universeOn biplate iModule+ constraints = concatMap findConstraints decls'++ lowerOrUpperFixedCard analysis' clafer =+ maximum [cardLb, cardUb, lowFromConstraints, oneForStar, targetScopeForStar ]+ where+ Just (cardLb, cardUb) = _card clafer+ oneForStar = if (cardLb == 0 && cardUb == -1) then 1 else 0+ targetScopeForStar = if ((isJust $ _reference clafer) && cardUb == -1)+ then case getReference clafer of+ [ref'] -> Map.findWithDefault 1 (fromMaybe "unknown" $ _uid <$> findIClafer uidClaferMap' ref' ) analysis'+ _ -> 0+ else 0+ lowFromConstraints = Map.findWithDefault 0 (_uid clafer) constraintAnalysis++ analyzeComponent analysis' component =+ case flattenSCC component of+ [uid'] -> analyzeSingleton uid' analysis'+ uids ->+ foldr analyzeSingleton assume uids+ where+ -- assume that each of the scopes in the component is 1 while solving+ assume = foldr (`Map.insert` 1) analysis' uids+ where+ analyzeSingleton uid' analysis'' = analyze analysis'' $ findClafer uid'++ analyze :: Map String Integer -> IClafer -> Map String Integer+ analyze analysis' clafer =+ -- Take the max between the supers and references analysis and this analysis+ Map.insertWith max (_uid clafer) scope analysis'+ where+ scope+ | _isAbstract clafer = sum subclaferScopes+ | otherwise = parentScope * (lowerOrUpperFixedCard analysis' clafer)++ subclaferScopes = map (findOrError " subclafer scope not found" analysis') subclafers+ parentScope =+ case parentMaybe of+ Just parent'' -> findOrError " parent scope not found" analysis' parent''+ Nothing -> rootScope+ subclafers = Map.findWithDefault [] (_uid clafer) subclaferMap+ parentMaybe = Map.lookup (_uid clafer) parentMap+ rootScope = 1+ findOrError message m key = Map.findWithDefault (error $ key ++ message) key m++analyzeSupers :: UIDIClaferMap -> [IClafer] -> Map String Integer -> IElement -> Map String Integer+analyzeSupers uidClaferMap' clafers analysis (IEClafer clafer) =+ foldl (analyzeSupers uidClaferMap' clafers) analysis' (_elements clafer)+ where+ (Just (cardLb, cardUb)) = _card clafer+ lowerOrFixedUpperBound = maximum [1, cardLb, cardUb ]+ analysis' = if (isJust $ _reference clafer)+ then analysis+ else case (directSuper uidClaferMap' clafer) of+ (Just c) -> Map.alter (incLB lowerOrFixedUpperBound) (_uid c) analysis+ Nothing -> analysis+ incLB lb' Nothing = Just lb'+ incLB lb' (Just lb) = Just (lb + lb')+analyzeSupers _ _ analysis _ = analysis++analyzeRefs :: UIDIClaferMap -> [IClafer] -> Map String Integer -> IElement -> Map String Integer+analyzeRefs uidClaferMap' clafers analysis (IEClafer clafer) =+ foldl (analyzeRefs uidClaferMap' clafers) analysis' (_elements clafer)+ where+ (Just (cardLb, cardUb)) = _card clafer+ lowerOrFixedUpperBound = maximum [1, cardLb, cardUb]+ analysis' = if (isJust $ _reference clafer)+ then case (directSuper uidClaferMap' clafer) of+ (Just c) -> Map.alter (maxLB lowerOrFixedUpperBound) (_uid c) analysis+ Nothing -> analysis+ else analysis+ maxLB lb' Nothing = Just lb'+ maxLB lb' (Just lb) = Just (max lb lb')+analyzeRefs _ _ analysis _ = analysis++analyzeConstraints :: [PExp] -> (String -> Integer) -> Map String Integer+analyzeConstraints constraints upperCards =+ foldr analyzeConstraint Map.empty $ filter isOneOrSomeConstraint constraints+ where+ isOneOrSomeConstraint PExp{_exp = IDeclPExp{_quant = quant'}} =+ -- Only these two quantifiers requires an increase in scope to satisfy.+ case quant' of+ IOne -> True+ ISome -> True+ _ -> False+ isOneOrSomeConstraint _ = False++ -- Only considers how quantifiers affect scope. Other types of constraints are not considered.+ -- Constraints of the type [some path1.path2] or [no path1.path2], etc.+ analyzeConstraint PExp{_exp = IDeclPExp{_oDecls = [], _bpexp = bpexp'}} analysis =+ foldr atLeastOne analysis path'+ where+ path' = dropThisAndParent $ unfoldJoins bpexp'+ atLeastOne = Map.insertWith max `flip` 1++ -- Constraints of the type [all disj a : path1.path2] or [some b : path3.path4], etc.+ analyzeConstraint PExp{_exp = IDeclPExp{_oDecls = decls'}} analysis =+ foldr analyzeDecl analysis decls'+ analyzeConstraint _ analysis = analysis++ analyzeDecl IDecl{_isDisj = isDisj', _decls = decls', _body = body'} analysis =+ foldr (uncurry insert') analysis $ zip path' scores+ where+ -- Take the first element in the path', and change its effective lower cardinality.+ -- Can overestimate the scope.+ path' = dropThisAndParent $ unfoldJoins body'+ -- "disj a;b;c" implies at least 3 whereas "a;b;c" implies at least one.+ minScope = if isDisj' then fromIntegral $ length decls' else 1+ insert' = Map.insertWith max++ scores = assign path' minScope++ {-+ - abstract Z+ - C *+ - D : integer *+ -+ - A : Z+ - B : integer+ - [some disj a;b;c;d : D | a = 1 && b = 2 && c = 3 && d = B]+ -}+ -- Need at least 4 D's per A.+ -- Either+ -- a) Make the effective lower cardinality of C=4 and D=1+ -- b) Make the effective lower cardinality of C=1 and D=4+ -- c) Some other combination.+ -- Choose b, a greedy algorithm that starts from the lowest child progressing upwards.++ {-+ - abstract Z+ - C *+ - D : integer 3..*+ -+ - A : Z+ - B : integer+ - [some disj a;b;c;d : D | a = 1 && b = 2 && c = 3 && d = B]+ -}+ -- The algorithm we do is greedy so it will chose D=3.+ -- However, it still needs more D's so it will choose C=2+ -- C=2, D=3+ -- This might not be optimum since now the scope allows for 6 D's.+ -- A better solution might be C=2, D=2.+ -- Well too bad, we are using the greedy algorithm.+ assign [] _ = [1]+ assign (p : ps) score =+ pScore : ps'+ where+ --upper = upperCards p+ ps' = assign ps score+ psScore = product $ ps'+ pDesireScore = ceiling (score % psScore)+ pMaxScore = upperCards p+ pScore = min' pDesireScore pMaxScore++ min' a b = if b == -1 then a else min a b++ -- The each child has at most one parent. No matter what the path in a quantifier+ -- looks like, we ignore the parent parts.+ dropThisAndParent = dropWhile (== "parent") . dropWhile (== "this")+++analyzeDependencies :: UIDIClaferMap -> [IClafer] -> [SCC String]+analyzeDependencies uidClaferMap' clafers = connComponents+ where+ connComponents = stronglyConnComp [(key, key, depends) | (key, depends) <- dependencyGraph]+ dependencies = concatMap (dependency uidClaferMap') clafers+ dependencyGraph = Map.toList $ Map.fromListWith (++) [(a, [b]) | (a, b) <- dependencies]++dependency :: UIDIClaferMap -> IClafer -> [(String, String)]+dependency uidClaferMap' clafer =+ selfDependency : (maybeToList superDependency ++ childDependencies)+ where+ -- This is to make the "stronglyConnComp" from Data.Graph play nice. Otherwise,+ -- clafers with no dependencies will not appear in the result.+ selfDependency = (_uid clafer, _uid clafer)+ superDependency+ | isNothing $ _super clafer = Nothing+ | otherwise =+ do+ super' <- directSuper uidClaferMap' clafer+ -- Need to analyze clafer before its super+ return (_uid super', _uid clafer)+ -- Need to analyze clafer before its children+ childDependencies = [(_uid child, _uid clafer) | child <- childClafers clafer]+++analyzeHierarchy :: UIDIClaferMap -> [IClafer] -> (Map String [String], Map String String)+analyzeHierarchy uidClaferMap' clafers =+ foldl hierarchy (Map.empty, Map.empty) clafers+ where+ hierarchy (subclaferMap, parentMap) clafer = (subclaferMap', parentMap')+ where+ subclaferMap' =+ case super' of+ Just super'' -> Map.insertWith (++) (_uid super'') [_uid clafer] subclaferMap+ Nothing -> subclaferMap+ super' = directSuper uidClaferMap' clafer+ parentMap' = foldr (flip Map.insert $ _uid clafer) parentMap (map _uid $ childClafers clafer)++directSuper :: UIDIClaferMap -> IClafer -> Maybe IClafer+directSuper uidClaferMap' clafer =+ second $ findHierarchy getSuper uidClaferMap' clafer+ where+ second [] = Nothing+ second [_] = Nothing+ second (_:x:_) = Just x+++-- Find all constraints+findConstraints :: IElement -> [PExp]+findConstraints IEConstraint{_cpexp = c} = [c]+findConstraints (IEClafer clafer) = concatMap findConstraints (_elements clafer)+findConstraints _ = []++-- Finds all the direct ancestors (ie. children)+childClafers :: IClafer -> [IClafer]+childClafers clafer = clafer ^.. elements.traversed.iClafer++-- Unfold joins+-- If the expression is a tree of only joins, then this function will flatten+-- the joins into a list.+-- Otherwise, returns an empty list.+unfoldJoins :: PExp -> [String]+unfoldJoins pexp =+ fromMaybe [] $ unfoldJoins' pexp+ where+ unfoldJoins' PExp{_exp = (IFunExp "." args)} =+ return $ args >>= unfoldJoins+ unfoldJoins' PExp{_exp = IClaferId{_sident = sident'}} =+ return $ [sident']+ unfoldJoins' _ =+ fail "not a join"
src/Language/Clafer/Intermediate/StringAnalyzer.hs view
@@ -42,37 +42,37 @@ flipMap = Map.fromList . map swap . Map.toList -astrClafer :: Functor m => MonadState (Map.Map String Int) m => IClafer -> m IClafer +astrClafer :: MonadState (Map.Map String Int) m => IClafer -> m IClafer astrClafer (IClafer s isAbstract' gcrd' ident' uid' puid' super' reference' crd' gCard elements') = do reference'' <- astrReference reference' elements'' <- astrElement `mapM` elements' return $ IClafer s isAbstract' gcrd' ident' uid' puid' super' reference'' crd' gCard elements'' -astrReference :: Functor m => MonadState (Map.Map String Int) m => Maybe IReference -> m (Maybe IReference) +astrReference :: MonadState (Map.Map String Int) m => Maybe IReference -> m (Maybe IReference) astrReference Nothing = return Nothing astrReference (Just (IReference isSet' ref')) = Just <$> IReference isSet' `liftM` astrPExp ref' -- astrs single subclafer -astrElement :: Functor m => MonadState (Map.Map String Int) m => IElement -> m IElement +astrElement :: MonadState (Map.Map String Int) m => IElement -> m IElement astrElement x = case x of IEClafer clafer -> IEClafer `liftM` astrClafer clafer IEConstraint isHard' pexp -> IEConstraint isHard' `liftM` astrPExp pexp IEGoal isMaximize' pexp -> IEGoal isMaximize' `liftM` astrPExp pexp -astrPExp :: Functor m => MonadState (Map.Map String Int) m => PExp -> m PExp +astrPExp :: MonadState (Map.Map String Int) m => PExp -> m PExp astrPExp (PExp (Just TString) pid' pos' exp') = PExp (Just TInteger) pid' pos' `liftM` astrIExp exp' astrPExp (PExp t pid' pos' (IFunExp op' exps')) = PExp t pid' pos' `liftM` (IFunExp op' `liftM` mapM astrPExp exps') -astrPExp (PExp t pid' pos' (IDeclPExp quant' oDecls' bpexp')) = PExp t pid' pos' `liftM` - (IDeclPExp quant' oDecls' `liftM` (astrPExp bpexp')) +astrPExp (PExp t pid' pos' (IDeclPExp quant' oDecls' bpexp')) = + PExp t pid' pos' `liftM` (IDeclPExp quant' oDecls' `liftM` astrPExp bpexp') astrPExp x = return x -astrIExp :: Functor m => MonadState (Map.Map String Int) m => IExp -> m IExp +astrIExp :: MonadState (Map.Map String Int) m => IExp -> m IExp astrIExp x = case x of IFunExp op' exps' -> IFunExp op' `liftM` mapM astrPExp exps' IStr str -> do modify (\e -> Map.insertWith (flip const) str (Map.size e) e) st <- get - return $ (IInt $ toInteger $ (Map.!) st str) + return (IInt $ toInteger $ (Map.!) st str) _ -> return x
src/Language/Clafer/Intermediate/Tracing.hs view
@@ -1,294 +1,294 @@-{- - Copyright (C) 2012 Kacper Bak <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -module Language.Clafer.Intermediate.Tracing (traceIrModule, traceAstModule, Ast(..), printAstNode) where - -import Data.Map (Map) -import qualified Data.Map as Map -import Language.Clafer.Front.AbsClafer -import Language.Clafer.Front.PrintClafer (printTree) -import Language.Clafer.Intermediate.Intclafer - -traceIrModule :: IModule -> Map Span [Ir] --Map Span [Union (IRClafer IClafer) (IRPExp PExp)] -traceIrModule = foldMapIR getMap - where - insert :: Span -> Ir -> Map Span [Ir] -> Map Span [Ir] - insert k a = Map.insertWith (++) k [a] - getMap :: Ir -> Map Span [Ir] --Map Span [Union (IRClafer IClafer) (IRPExp PExp)] - getMap (IRPExp (p@PExp{_inPos = s})) = insert s (IRPExp p) Map.empty - getMap (IRClafer (c@IClafer{_cinPos = s})) = insert s (IRClafer c) Map.empty - getMap _ = Map.empty - -traceAstModule :: Module -> Map Span [Ast] -traceAstModule x = - foldr - ins - Map.empty - (traverseModule x) - where - ins y = Map.insertWith (++) (i y) [y] - i (AstModule a) = getSpan a - i (AstDeclaration a) = getSpan a - i (AstClafer a) = getSpan a - i (AstConstraint a) = getSpan a - i (AstAssertion a) = getSpan a - i (AstGoal a) = getSpan a - i (AstAbstract a) = getSpan a - i (AstElements a) = getSpan a - i (AstElement a) = getSpan a - i (AstSuper a) = getSpan a - i (AstReference a) = getSpan a - i (AstInit a) = getSpan a - i (AstInitHow a) = getSpan a - i (AstGCard a) = getSpan a - i (AstCard a) = getSpan a - i (AstNCard a) = getSpan a - i (AstExInteger a) = getSpan a - i (AstName a) = getSpan a - i (AstExp a) = getSpan a - i (AstDecl a) = getSpan a - i (AstQuant a) = getSpan a - i (AstEnumId a) = getSpan a - i (AstModId a) = getSpan a - i (AstLocId a) = getSpan a - -traverseModule :: Module -> [Ast] -traverseModule x@(Module _ d) = AstModule x : concatMap traverseDeclaration d - -traverseDeclaration :: Declaration -> [Ast] -traverseDeclaration x = - AstDeclaration x : - case x of - EnumDecl _ _ e -> concatMap traverseEnumId e - ElementDecl _ e -> traverseElement e - -traverseClafer :: Clafer -> [Ast] -traverseClafer x@(Clafer _ a b _ d r e f g) = AstClafer x : (traverseAbstract a ++ traverseGCard b ++ traverseSuper d ++ traverseReference r ++ traverseCard e ++ traverseInit f ++ traverseElements g) - -traverseConstraint :: Constraint -> [Ast] -traverseConstraint x@(Constraint _ e) = AstConstraint x : concatMap traverseExp e - -traverseAssertion :: Assertion -> [Ast] -traverseAssertion x@(Assertion _ e) = AstAssertion x : concatMap traverseExp e - -traverseGoal :: Goal -> [Ast] -traverseGoal x@(GoalMinimize _ e) = AstGoal x : concatMap traverseExp e -traverseGoal x@(GoalMaximize _ e) = AstGoal x : concatMap traverseExp e -traverseGoal x@(GoalMinDeprecated _ e) = AstGoal x : concatMap traverseExp e -traverseGoal x@(GoalMaxDeprecated _ e) = AstGoal x : concatMap traverseExp e - -traverseAbstract :: Abstract -> [Ast] -traverseAbstract x = - AstAbstract x : [{- no other children -}] - -traverseElements :: Elements -> [Ast] -traverseElements x = - AstElements x : - case x of - ElementsEmpty _ -> [] - ElementsList _ e -> concatMap traverseElement e - -traverseElement :: Element -> [Ast] -traverseElement x = - AstElement x : - case x of - Subclafer _ c -> traverseClafer c - ClaferUse _ n c e -> traverseName n ++ traverseCard c ++ traverseElements e - Subconstraint _ c -> traverseConstraint c - Subgoal _ g -> traverseGoal g - SubAssertion _ c -> traverseAssertion c - -traverseSuper :: Super -> [Ast] -traverseSuper x = - AstSuper x : - case x of - SuperEmpty _ -> [] - SuperSome _ se -> traverseExp se - -traverseReference :: Reference -> [Ast] -traverseReference x = - AstReference x : - case x of - ReferenceEmpty _ -> [] - ReferenceSet _ se -> traverseExp se - ReferenceBag _ se -> traverseExp se - -traverseInit :: Init -> [Ast] -traverseInit x = - AstInit x : - case x of - InitEmpty _ -> [] - InitSome _ ih e -> traverseInitHow ih ++ traverseExp e - -traverseInitHow :: InitHow -> [Ast] -traverseInitHow x = - AstInitHow x : [{- no other children -}] - -traverseGCard :: GCard -> [Ast] -traverseGCard x = - AstGCard x : - case x of - GCardEmpty _ -> [] - GCardXor _ -> [] - GCardOr _ -> [] - GCardMux _ -> [] - GCardOpt _ -> [] - GCardInterval _ n -> traverseNCard n - -traverseCard :: Card -> [Ast] -traverseCard x = - AstCard x : - case x of - CardEmpty _ -> [] - CardLone _ -> [] - CardSome _ -> [] - CardAny _ -> [] - CardNum _ _ -> [] - CardInterval _ n -> traverseNCard n - -traverseNCard :: NCard -> [Ast] -traverseNCard x@(NCard _ _ e) = AstNCard x : traverseExInteger e - -traverseExInteger :: ExInteger -> [Ast] -traverseExInteger x = - AstExInteger x : [{- no other children -}] - -traverseName :: Name -> [Ast] -traverseName x@(Path _ m) = AstName x : concatMap traverseModId m - -traverseExp :: Exp -> [Ast] -traverseExp x = - AstExp x : - case x of - EDeclAllDisj _ d e -> traverseDecl d ++ traverseExp e - EDeclAll _ d e -> traverseDecl d ++ traverseExp e - EDeclQuantDisj _ q d e -> traverseQuant q ++ traverseDecl d ++ traverseExp e - EDeclQuant _ q d e -> traverseQuant q ++ traverseDecl d ++ traverseExp e - EGMax _ e -> traverseExp e - EGMin _ e -> traverseExp e - EIff _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - EImplies _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - EOr _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - EXor _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - EAnd _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - ENeg _ e -> traverseExp e - ELt _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - EGt _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - EEq _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - ELte _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - EGte _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - ENeq _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - EIn _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - ENin _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - EQuantExp _ q e -> traverseQuant q ++ traverseExp e - EAdd _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - ESub _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - EMul _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - EDiv _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - ERem _ e1 e2 -> traverseExp e1 ++ traverseExp e2 - ESum _ e -> traverseExp e - EProd _ e -> traverseExp e - ECard _ e -> traverseExp e - EMinExp _ e -> traverseExp e - EImpliesElse _ e1 e2 e3 -> traverseExp e1 ++ traverseExp e2 ++ traverseExp e3 - EInt _ _ -> [] - EDouble _ _ -> [] - EReal _ _ -> [] - EStr _ _ -> [] - EUnion _ s1 s2 -> traverseExp s1 ++ traverseExp s2 - EUnionCom _ s1 s2 -> traverseExp s1 ++ traverseExp s2 - EDifference _ s1 s2 -> traverseExp s1 ++ traverseExp s2 - EIntersection _ s1 s2 -> traverseExp s1 ++ traverseExp s2 - EIntersectionDeprecated _ s1 s2 -> traverseExp s1 ++ traverseExp s2 - EDomain _ s1 s2 -> traverseExp s1 ++ traverseExp s2 - ERange _ s1 s2 -> traverseExp s1 ++ traverseExp s2 - EJoin _ s1 s2 -> traverseExp s1 ++ traverseExp s2 - ClaferId _ n -> traverseName n - -traverseDecl :: Decl -> [Ast] -traverseDecl x@(Decl _ l s) = - AstDecl x : (concatMap traverseLocId l ++ traverseExp s) - -traverseQuant :: Quant -> [Ast] -traverseQuant x = - AstQuant x : [{- no other children -}] - -traverseEnumId :: EnumId -> [Ast] -traverseEnumId _ = [] - -traverseModId :: ModId -> [Ast] -traverseModId _ = [] - -traverseLocId :: LocId -> [Ast] -traverseLocId _ = [] - -data Ast = - AstModule Module | - AstDeclaration Declaration | - AstClafer Clafer | - AstConstraint Constraint | - AstAssertion Assertion | - AstGoal Goal | - AstAbstract Abstract | - AstElements Elements | - AstElement Element | - AstSuper Super | - AstReference Reference | - AstInit Init | - AstInitHow InitHow | - AstGCard GCard | - AstCard Card | - AstNCard NCard | - AstExInteger ExInteger | - AstName Name | - AstExp Exp | - AstDecl Decl | - AstQuant Quant | - AstEnumId EnumId | - AstModId ModId | - AstLocId LocId - deriving (Eq, Show) - -printAstNode :: Ast -> String -printAstNode (AstModule x) = printTree x -printAstNode (AstDeclaration x) = printTree x -printAstNode (AstClafer x) = printTree x -printAstNode (AstConstraint x) = printTree x -printAstNode (AstAssertion x) = printTree x -printAstNode (AstGoal x) = printTree x -printAstNode (AstAbstract x) = printTree x -printAstNode (AstElements x) = printTree x -printAstNode (AstElement x) = printTree x -printAstNode (AstSuper x) = printTree x -printAstNode (AstReference x) = printTree x -printAstNode (AstInit x) = printTree x -printAstNode (AstInitHow x) = printTree x -printAstNode (AstGCard x) = printTree x -printAstNode (AstCard x) = printTree x -printAstNode (AstNCard x) = printTree x -printAstNode (AstExInteger x) = printTree x -printAstNode (AstName x) = printTree x -printAstNode (AstExp x) = printTree x -printAstNode (AstDecl x) = printTree x -printAstNode (AstQuant x) = printTree x -printAstNode (AstEnumId x) = printTree x -printAstNode (AstModId x) = printTree x -printAstNode (AstLocId x) = printTree x +{-+ Copyright (C) 2012 Kacper Bak <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+module Language.Clafer.Intermediate.Tracing (traceIrModule, traceAstModule, Ast(..), printAstNode) where++import Data.Map (Map)+import qualified Data.Map as Map+import Language.Clafer.Front.AbsClafer+import Language.Clafer.Front.PrintClafer (printTree)+import Language.Clafer.Intermediate.Intclafer++traceIrModule :: IModule -> Map Span [Ir] --Map Span [Union (IRClafer IClafer) (IRPExp PExp)]+traceIrModule = foldMapIR getMap+ where+ insert :: Span -> Ir -> Map Span [Ir] -> Map Span [Ir]+ insert k a = Map.insertWith (++) k [a]+ getMap :: Ir -> Map Span [Ir] --Map Span [Union (IRClafer IClafer) (IRPExp PExp)]+ getMap (IRPExp (p@PExp{_inPos = s})) = insert s (IRPExp p) Map.empty+ getMap (IRClafer (c@IClafer{_cinPos = s})) = insert s (IRClafer c) Map.empty+ getMap _ = Map.empty++traceAstModule :: Module -> Map Span [Ast]+traceAstModule x =+ foldr+ ins+ Map.empty+ (traverseModule x)+ where+ ins y = Map.insertWith (++) (i y) [y]+ i (AstModule a) = getSpan a+ i (AstDeclaration a) = getSpan a+ i (AstClafer a) = getSpan a+ i (AstConstraint a) = getSpan a+ i (AstAssertion a) = getSpan a+ i (AstGoal a) = getSpan a+ i (AstAbstract a) = getSpan a+ i (AstElements a) = getSpan a+ i (AstElement a) = getSpan a+ i (AstSuper a) = getSpan a+ i (AstReference a) = getSpan a+ i (AstInit a) = getSpan a+ i (AstInitHow a) = getSpan a+ i (AstGCard a) = getSpan a+ i (AstCard a) = getSpan a+ i (AstNCard a) = getSpan a+ i (AstExInteger a) = getSpan a+ i (AstName a) = getSpan a+ i (AstExp a) = getSpan a+ i (AstDecl a) = getSpan a+ i (AstQuant a) = getSpan a+ i (AstEnumId a) = getSpan a+ i (AstModId a) = getSpan a+ i (AstLocId a) = getSpan a++traverseModule :: Module -> [Ast]+traverseModule x@(Module _ d) = AstModule x : concatMap traverseDeclaration d++traverseDeclaration :: Declaration -> [Ast]+traverseDeclaration x =+ AstDeclaration x :+ case x of+ EnumDecl _ _ e -> concatMap traverseEnumId e+ ElementDecl _ e -> traverseElement e++traverseClafer :: Clafer -> [Ast]+traverseClafer x@(Clafer _ a b _ d r e f g) = AstClafer x : (traverseAbstract a ++ traverseGCard b ++ traverseSuper d ++ traverseReference r ++ traverseCard e ++ traverseInit f ++ traverseElements g)++traverseConstraint :: Constraint -> [Ast]+traverseConstraint x@(Constraint _ e) = AstConstraint x : concatMap traverseExp e++traverseAssertion :: Assertion -> [Ast]+traverseAssertion x@(Assertion _ e) = AstAssertion x : concatMap traverseExp e++traverseGoal :: Goal -> [Ast]+traverseGoal x@(GoalMinimize _ e) = AstGoal x : concatMap traverseExp e+traverseGoal x@(GoalMaximize _ e) = AstGoal x : concatMap traverseExp e+traverseGoal x@(GoalMinDeprecated _ e) = AstGoal x : concatMap traverseExp e+traverseGoal x@(GoalMaxDeprecated _ e) = AstGoal x : concatMap traverseExp e++traverseAbstract :: Abstract -> [Ast]+traverseAbstract x =+ AstAbstract x : [{- no other children -}]++traverseElements :: Elements -> [Ast]+traverseElements x =+ AstElements x :+ case x of+ ElementsEmpty _ -> []+ ElementsList _ e -> concatMap traverseElement e++traverseElement :: Element -> [Ast]+traverseElement x =+ AstElement x :+ case x of+ Subclafer _ c -> traverseClafer c+ ClaferUse _ n c e -> traverseName n ++ traverseCard c ++ traverseElements e+ Subconstraint _ c -> traverseConstraint c+ Subgoal _ g -> traverseGoal g+ SubAssertion _ c -> traverseAssertion c++traverseSuper :: Super -> [Ast]+traverseSuper x =+ AstSuper x :+ case x of+ SuperEmpty _ -> []+ SuperSome _ se -> traverseExp se++traverseReference :: Reference -> [Ast]+traverseReference x =+ AstReference x :+ case x of+ ReferenceEmpty _ -> []+ ReferenceSet _ se -> traverseExp se+ ReferenceBag _ se -> traverseExp se++traverseInit :: Init -> [Ast]+traverseInit x =+ AstInit x :+ case x of+ InitEmpty _ -> []+ InitSome _ ih e -> traverseInitHow ih ++ traverseExp e++traverseInitHow :: InitHow -> [Ast]+traverseInitHow x =+ AstInitHow x : [{- no other children -}]++traverseGCard :: GCard -> [Ast]+traverseGCard x =+ AstGCard x :+ case x of+ GCardEmpty _ -> []+ GCardXor _ -> []+ GCardOr _ -> []+ GCardMux _ -> []+ GCardOpt _ -> []+ GCardInterval _ n -> traverseNCard n++traverseCard :: Card -> [Ast]+traverseCard x =+ AstCard x :+ case x of+ CardEmpty _ -> []+ CardLone _ -> []+ CardSome _ -> []+ CardAny _ -> []+ CardNum _ _ -> []+ CardInterval _ n -> traverseNCard n++traverseNCard :: NCard -> [Ast]+traverseNCard x@(NCard _ _ e) = AstNCard x : traverseExInteger e++traverseExInteger :: ExInteger -> [Ast]+traverseExInteger x =+ AstExInteger x : [{- no other children -}]++traverseName :: Name -> [Ast]+traverseName x@(Path _ m) = AstName x : concatMap traverseModId m++traverseExp :: Exp -> [Ast]+traverseExp x =+ AstExp x :+ case x of+ EDeclAllDisj _ d e -> traverseDecl d ++ traverseExp e+ EDeclAll _ d e -> traverseDecl d ++ traverseExp e+ EDeclQuantDisj _ q d e -> traverseQuant q ++ traverseDecl d ++ traverseExp e+ EDeclQuant _ q d e -> traverseQuant q ++ traverseDecl d ++ traverseExp e+ EGMax _ e -> traverseExp e+ EGMin _ e -> traverseExp e+ EIff _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ EImplies _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ EOr _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ EXor _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ EAnd _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ ENeg _ e -> traverseExp e+ ELt _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ EGt _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ EEq _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ ELte _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ EGte _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ ENeq _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ EIn _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ ENin _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ EQuantExp _ q e -> traverseQuant q ++ traverseExp e+ EAdd _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ ESub _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ EMul _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ EDiv _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ ERem _ e1 e2 -> traverseExp e1 ++ traverseExp e2+ ESum _ e -> traverseExp e+ EProd _ e -> traverseExp e+ ECard _ e -> traverseExp e+ EMinExp _ e -> traverseExp e+ EImpliesElse _ e1 e2 e3 -> traverseExp e1 ++ traverseExp e2 ++ traverseExp e3+ EInt _ _ -> []+ EDouble _ _ -> []+ EReal _ _ -> []+ EStr _ _ -> []+ EUnion _ s1 s2 -> traverseExp s1 ++ traverseExp s2+ EUnionCom _ s1 s2 -> traverseExp s1 ++ traverseExp s2+ EDifference _ s1 s2 -> traverseExp s1 ++ traverseExp s2+ EIntersection _ s1 s2 -> traverseExp s1 ++ traverseExp s2+ EIntersectionDeprecated _ s1 s2 -> traverseExp s1 ++ traverseExp s2+ EDomain _ s1 s2 -> traverseExp s1 ++ traverseExp s2+ ERange _ s1 s2 -> traverseExp s1 ++ traverseExp s2+ EJoin _ s1 s2 -> traverseExp s1 ++ traverseExp s2+ ClaferId _ n -> traverseName n++traverseDecl :: Decl -> [Ast]+traverseDecl x@(Decl _ l s) =+ AstDecl x : (concatMap traverseLocId l ++ traverseExp s)++traverseQuant :: Quant -> [Ast]+traverseQuant x =+ AstQuant x : [{- no other children -}]++traverseEnumId :: EnumId -> [Ast]+traverseEnumId _ = []++traverseModId :: ModId -> [Ast]+traverseModId _ = []++traverseLocId :: LocId -> [Ast]+traverseLocId _ = []++data Ast =+ AstModule Module |+ AstDeclaration Declaration |+ AstClafer Clafer |+ AstConstraint Constraint |+ AstAssertion Assertion |+ AstGoal Goal |+ AstAbstract Abstract |+ AstElements Elements |+ AstElement Element |+ AstSuper Super |+ AstReference Reference |+ AstInit Init |+ AstInitHow InitHow |+ AstGCard GCard |+ AstCard Card |+ AstNCard NCard |+ AstExInteger ExInteger |+ AstName Name |+ AstExp Exp |+ AstDecl Decl |+ AstQuant Quant |+ AstEnumId EnumId |+ AstModId ModId |+ AstLocId LocId+ deriving (Eq, Show)++printAstNode :: Ast -> String+printAstNode (AstModule x) = printTree x+printAstNode (AstDeclaration x) = printTree x+printAstNode (AstClafer x) = printTree x+printAstNode (AstConstraint x) = printTree x+printAstNode (AstAssertion x) = printTree x+printAstNode (AstGoal x) = printTree x+printAstNode (AstAbstract x) = printTree x+printAstNode (AstElements x) = printTree x+printAstNode (AstElement x) = printTree x+printAstNode (AstSuper x) = printTree x+printAstNode (AstReference x) = printTree x+printAstNode (AstInit x) = printTree x+printAstNode (AstInitHow x) = printTree x+printAstNode (AstGCard x) = printTree x+printAstNode (AstCard x) = printTree x+printAstNode (AstNCard x) = printTree x+printAstNode (AstExInteger x) = printTree x+printAstNode (AstName x) = printTree x+printAstNode (AstExp x) = printTree x+printAstNode (AstDecl x) = printTree x+printAstNode (AstQuant x) = printTree x+printAstNode (AstEnumId x) = printTree x+printAstNode (AstModId x) = printTree x+printAstNode (AstLocId x) = printTree x
src/Language/Clafer/Intermediate/Transformer.hs view
@@ -1,54 +1,54 @@-{- - Copyright (C) 2012 Kacper Bak <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -module Language.Clafer.Intermediate.Transformer where - -import Control.Lens -import Data.Maybe -import Language.Clafer.Common -import qualified Language.Clafer.Intermediate.Intclafer as I (exp, elements) -import Language.Clafer.Intermediate.Intclafer hiding (exp, elements, op) -import Language.Clafer.Intermediate.Desugarer - -transModule :: IModule -> IModule -transModule = mDecls . traversed %~ transElement - -transElement :: IElement -> IElement -transElement (IEClafer clafer) = IEClafer $ transClafer clafer -transElement (IEConstraint isHard' pexp) = IEConstraint isHard' $ transPExp False pexp -transElement (IEGoal isMaximize' pexp) = IEGoal isMaximize' $ transPExp False pexp - -transClafer :: IClafer -> IClafer -transClafer = I.elements . traversed %~ transElement - -transPExp :: Bool -> PExp -> PExp -transPExp True pexp'@(PExp iType' _ _ _) = desugarPath $ I.exp %~ transIExp (fromJust $ iType') $ pexp' -transPExp False pexp' = pexp' - -transIExp :: IType -> IExp -> IExp -transIExp _ idpe@(IDeclPExp _ _ _) = bpexp %~ transPExp False $ idpe -transIExp iType' ife@(IFunExp op' _) = exps . traversed %~ transPExp cond $ ife - where - cond = op' == iIfThenElse && - iType' `elem` [TBoolean, TClafer []] -transIExp _ iexp' = iexp' - - +{-+ Copyright (C) 2012 Kacper Bak <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+module Language.Clafer.Intermediate.Transformer where++import Control.Lens+import Data.Maybe+import Language.Clafer.Common+import qualified Language.Clafer.Intermediate.Intclafer as I (exp, elements)+import Language.Clafer.Intermediate.Intclafer hiding (exp, elements, op)+import Language.Clafer.Intermediate.Desugarer++transModule :: IModule -> IModule+transModule = mDecls . traversed %~ transElement++transElement :: IElement -> IElement+transElement (IEClafer clafer) = IEClafer $ transClafer clafer+transElement (IEConstraint isHard' pexp) = IEConstraint isHard' $ transPExp False pexp+transElement (IEGoal isMaximize' pexp) = IEGoal isMaximize' $ transPExp False pexp++transClafer :: IClafer -> IClafer+transClafer = I.elements . traversed %~ transElement++transPExp :: Bool -> PExp -> PExp+transPExp True pexp'@(PExp iType' _ _ _) = desugarPath $ I.exp %~ transIExp (fromJust $ iType') $ pexp'+transPExp False pexp' = pexp'++transIExp :: IType -> IExp -> IExp+transIExp _ idpe@(IDeclPExp _ _ _) = bpexp %~ transPExp False $ idpe+transIExp iType' ife@(IFunExp op' _) = exps . traversed %~ transPExp cond $ ife+ where+ cond = op' == iIfThenElse &&+ iType' `elem` [TBoolean, TClafer []]+transIExp _ iexp' = iexp'++
src/Language/Clafer/Intermediate/TypeSystem.hs view
@@ -132,7 +132,7 @@ "clafer" -> claferTClafer _ -> case _super iClafer' of Nothing -> TClafer [ _uid iClafer'] - Just super' -> (fromJust $ _iType super') & hi %~ ((:) (_uid iClafer')) + Just super' -> fromJust (_iType super') & hi %~ (:) (_uid iClafer') -- | Get TClafer for a given Clafer by its UID -- can only be called after inheritance resolver @@ -202,6 +202,8 @@ ["int"] -> Just TInteger ["double"] -> Just TDouble ["real"] -> Just TReal + ["root"] -> Just rootTClafer + ["clafer"] -> Just claferTClafer [] -> Nothing u' -> Just $ TClafer u' @@ -234,6 +236,12 @@ >>> tClaferAlice +++ tClaferAlice TClafer {_hi = ["Alice","Student","Person"]} + +>>> (TClafer {_hi = ["A", "X"]} +++ TClafer {_hi = ["B", "X"]}) +++ TClafer {_hi = ["C", "X"]} +TClafer {_hi = ["A","X","B","C"]} + +>>> TClafer {_hi = ["A", "X"]} +++ (TClafer {_hi = ["B", "X"]} +++ TClafer {_hi = ["C", "X"]}) +TClafer {_hi = ["A","X","B","C"]} -} (+++) :: IType -> IType -> IType TBoolean +++ TBoolean = TBoolean @@ -243,7 +251,7 @@ TInteger +++ TInteger = TInteger t1@(TClafer u1) +++ t2@(TClafer u2) = if t1 == t2 then t1 - else (TClafer $ nub $ u1 ++ u2) -- should be TUnion [t1,t2] + else TClafer $ nub $ u1 ++ u2 -- should be TUnion [t1,t2] (TMap so1 ta1) +++ (TMap so2 ta2) = TMap (so1 +++ so2) (ta1 +++ ta2) (TUnion un1) +++ (TUnion un2) = collapseUnion (TUnion $ nub $ un1 ++ un2) (TUnion un1) +++ t2 = collapseUnion (TUnion $ nub $ un1 ++ [t2]) @@ -281,6 +289,8 @@ >>> runListT $ intersection undefined TReal tDrefMapDOB [Nothing] +runListT $ intersection undefined TClafer {_hi = ["A","X","B","C"]} TClafer {_hi = ["X"]} +[ Just TClafer {_hi = ["X"]] -} intersection :: Monad m => UIDIClaferMap -> IType -> IType -> m (Maybe IType) @@ -295,6 +305,8 @@ intersection _ TDouble TInteger = return $ Just TDouble intersection _ TInteger TDouble = return $ Just TDouble intersection _ TInteger TInteger = return $ Just TInteger +intersection _ t (TClafer ["clafer"]) = return $ Just t +intersection _ (TClafer ["clafer"]) t = return $ Just t intersection uidIClaferMap' (TUnion t1s) t2@(TClafer _) = do t1s' <- mapM (intersection uidIClaferMap' t2) t1s return $ case catMaybes t1s' of @@ -310,8 +322,8 @@ intersection uidIClaferMap' t@(TClafer ut1) (TClafer ut2) = if ut1 == ut2 then return $ Just t else do - h1 <- (mapM (hierarchyMap uidIClaferMap' _uid) ut1) - h2 <- (mapM (hierarchyMap uidIClaferMap' _uid) ut2) + h1 <- mapM (hierarchyMap uidIClaferMap' _uid) ut1 + h2 <- mapM (hierarchyMap uidIClaferMap' _uid) ut2 return $ fromUnionType $ catMaybes [contains (head u1) u2 `mplus` contains (head u2) u1 | u1 <- h1, u2 <- h2 ] where contains i is = if i `elem` is then Just i else Nothing @@ -385,12 +397,12 @@ commonHierarchy :: [UID] -> [UID] -> Maybe UID commonHierarchy h1 h2 = commonHierarchy' (reverse h1) (reverse h2) Nothing commonHierarchy' (x:xs) (y:ys) accumulator = - if (x == y) - then - if (null xs || null ys) - then Just x - else commonHierarchy' xs ys $ Just x - else accumulator + if x == y + then + if null xs || null ys + then Just x + else commonHierarchy' xs ys $ Just x + else accumulator commonHierarchy' _ _ _ = error "ResolverType.commonHierarchy' expects two non empty lists but was given at least one empty list!" -- Should never happen getIfThenElseType _ _ _ = return Nothing
src/Language/Clafer/JSONMetaData.hs view
@@ -1,124 +1,124 @@-{-# LANGUAGE OverloadedStrings #-} -{- - Copyright (C) 2014 Michal Antkiewicz <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} --- | Creates JSON outputs for different kinds of metadata. -module Language.Clafer.JSONMetaData ( - generateJSONnameUIDMap, - generateJSONScopes, - parseJSONScopes, - writeCfrScopeFile, - readCfrScopeFile -) - -where - -import Control.Lens hiding (element) -import Data.Aeson.Lens -import qualified Data.List as List -import Data.Maybe -import Data.Json.Builder -import Data.String.Conversions -import qualified Data.Text as T -import System.FilePath -import System.Directory - -import Language.Clafer.QNameUID - --- | Generate a JSON list of triples containing a fully-qualified-, least-partially-qualified name, and unique id. --- | Both the FQNames and UIDs are brittle. LPQNames are the least brittle. -generateJSONnameUIDMap :: QNameMaps -> String -generateJSONnameUIDMap qNameMaps = - prettyPrintJSON $ convertString $ toJsonBS $ foldl generateQNameUIDArrayEntry mempty sortedTriples - where - sortedTriples :: [(FQName, PQName, UID)] - sortedTriples = List.sortBy (\(fqName1, _, _) (fqName2, _, _) -> compare fqName1 fqName2) $ getQNameUIDTriples qNameMaps - -generateQNameUIDArrayEntry :: Array -> (FQName, PQName, UID) -> Array -generateQNameUIDArrayEntry array (fqName, lpqName, uid) = - mappend array $ element $ mconcat [ - row ("fqName" :: String) fqName, - row ("lpqName" :: String) lpqName, - row ("uid" :: String) uid ] - --- | Generate a JSON list of tuples containing a least-partially-qualified name and a scope -generateJSONScopes :: QNameMaps -> [(UID, Integer)] -> String -generateJSONScopes qNameMaps scopes = - prettyPrintJSON $ convertString $ toJsonBS $ foldl generateLpqNameScopeArrayEntry mempty sortedLpqNameScopeList - where - lpqNameScopeList = map (\(uid, scope) -> (fromMaybe uid $ getLPQName qNameMaps uid, scope)) scopes - sortedLpqNameScopeList :: [(PQName, Integer)] - sortedLpqNameScopeList = List.sortBy (\(lpqName1, _) (lpqName2, _) -> compare lpqName1 lpqName2) lpqNameScopeList - - -generateLpqNameScopeArrayEntry :: Array -> (PQName, Integer) -> Array -generateLpqNameScopeArrayEntry array (lpqName, scope) = - mappend array $ element $ mconcat [ - row ("lpqName" :: String) lpqName, - row ("scope" :: String) scope ] - --- insert a new line after [, {, and , -prettyPrintJSON :: String -> String -prettyPrintJSON ('[':line) = '[':'\n':(prettyPrintJSON line) -prettyPrintJSON ('{':line) = '{':'\n':(prettyPrintJSON line) -prettyPrintJSON (',':line) = ',':'\n':(prettyPrintJSON line) --- insert a new line before ], } -prettyPrintJSON (']':line) = '\n':']':(prettyPrintJSON line) -prettyPrintJSON ('}':line) = '\n':'}':(prettyPrintJSON line) --- just rewrite and continue -prettyPrintJSON (c:line) = c:(prettyPrintJSON line) -prettyPrintJSON "" = "" - --- | given the QNameMaps, parse the JSON scopes and return list of scopes -parseJSONScopes :: QNameMaps -> String -> [ (UID, Integer) ] -parseJSONScopes qNameMaps scopesJSON = - foldl (\uidScopes qScope -> (qNameToUIDs qScope) ++ uidScopes) [] decodedScopes - where - -- QName - decodedScopes :: [ (T.Text, Integer) ] - decodedScopes = scopesJSON ^.. _Array . traverse - . to (\o -> ( o ^?! key "lpqName" . _String - , o ^?! key "scope" . _Integer) - ) - -- a QName may resolve to potentially multiple UIDs - qNameToUIDs :: (T.Text, Integer) -> [ (UID, Integer) ] - qNameToUIDs (qName, scope) = if T.null qName - then [ ("", scope) ] - else [ (uid, scope) | uid <- getUIDs qNameMaps $ convertString qName] - --- | Write a .cfr-scope file -writeCfrScopeFile :: [ (UID, Integer) ] -> QNameMaps -> FilePath -> IO () -writeCfrScopeFile uidScopes qNameMaps modelName = do - let - scopesInJSON = generateJSONScopes qNameMaps uidScopes - writeFile (replaceExtension modelName ".cfr-scope") scopesInJSON - --- | Read a .cfr-scope file -readCfrScopeFile :: QNameMaps -> FilePath -> IO (Maybe [ (UID, Integer) ]) -readCfrScopeFile qNameMaps modelName = do - let - cfrScopeFileName = replaceExtension modelName ".cfr-scope" - exists <- doesFileExist cfrScopeFileName - if exists - then do - scopesInJSON <- readFile cfrScopeFileName - return $ Just $ parseJSONScopes qNameMaps scopesInJSON - else return Nothing +{-# LANGUAGE OverloadedStrings #-}+{-+ Copyright (C) 2014 Michal Antkiewicz <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+-- | Creates JSON outputs for different kinds of metadata.+module Language.Clafer.JSONMetaData (+ generateJSONnameUIDMap,+ generateJSONScopes,+ parseJSONScopes,+ writeCfrScopeFile,+ readCfrScopeFile+)++where++import Control.Lens hiding (element)+import Data.Aeson.Lens+import qualified Data.List as List+import Data.Maybe+import Data.Json.Builder+import Data.String.Conversions+import qualified Data.Text as T+import System.FilePath+import System.Directory++import Language.Clafer.QNameUID++-- | Generate a JSON list of triples containing a fully-qualified-, least-partially-qualified name, and unique id.+-- | Both the FQNames and UIDs are brittle. LPQNames are the least brittle.+generateJSONnameUIDMap :: QNameMaps -> String+generateJSONnameUIDMap qNameMaps =+ prettyPrintJSON $ convertString $ toJsonBS $ foldl generateQNameUIDArrayEntry mempty sortedTriples+ where+ sortedTriples :: [(FQName, PQName, UID)]+ sortedTriples = List.sortBy (\(fqName1, _, _) (fqName2, _, _) -> compare fqName1 fqName2) $ getQNameUIDTriples qNameMaps++generateQNameUIDArrayEntry :: Array -> (FQName, PQName, UID) -> Array+generateQNameUIDArrayEntry array (fqName, lpqName, uid) =+ mappend array $ element $ mconcat [+ row ("fqName" :: String) fqName,+ row ("lpqName" :: String) lpqName,+ row ("uid" :: String) uid ]++-- | Generate a JSON list of tuples containing a least-partially-qualified name and a scope+generateJSONScopes :: QNameMaps -> [(UID, Integer)] -> String+generateJSONScopes qNameMaps scopes =+ prettyPrintJSON $ convertString $ toJsonBS $ foldl generateLpqNameScopeArrayEntry mempty sortedLpqNameScopeList+ where+ lpqNameScopeList = map (\(uid, scope) -> (fromMaybe uid $ getLPQName qNameMaps uid, scope)) scopes+ sortedLpqNameScopeList :: [(PQName, Integer)]+ sortedLpqNameScopeList = List.sortBy (\(lpqName1, _) (lpqName2, _) -> compare lpqName1 lpqName2) lpqNameScopeList+++generateLpqNameScopeArrayEntry :: Array -> (PQName, Integer) -> Array+generateLpqNameScopeArrayEntry array (lpqName, scope) =+ mappend array $ element $ mconcat [+ row ("lpqName" :: String) lpqName,+ row ("scope" :: String) scope ]++-- insert a new line after [, {, and ,+prettyPrintJSON :: String -> String+prettyPrintJSON ('[':line) = '[':'\n':(prettyPrintJSON line)+prettyPrintJSON ('{':line) = '{':'\n':(prettyPrintJSON line)+prettyPrintJSON (',':line) = ',':'\n':(prettyPrintJSON line)+-- insert a new line before ], }+prettyPrintJSON (']':line) = '\n':']':(prettyPrintJSON line)+prettyPrintJSON ('}':line) = '\n':'}':(prettyPrintJSON line)+-- just rewrite and continue+prettyPrintJSON (c:line) = c:(prettyPrintJSON line)+prettyPrintJSON "" = ""++-- | given the QNameMaps, parse the JSON scopes and return list of scopes+parseJSONScopes :: QNameMaps -> String -> [ (UID, Integer) ]+parseJSONScopes qNameMaps scopesJSON =+ foldl (\uidScopes qScope -> (qNameToUIDs qScope) ++ uidScopes) [] decodedScopes+ where+ -- QName+ decodedScopes :: [ (T.Text, Integer) ]+ decodedScopes = scopesJSON ^.. _Array . traverse+ . to (\o -> ( o ^?! key "lpqName" . _String+ , o ^?! key "scope" . _Integer)+ )+ -- a QName may resolve to potentially multiple UIDs+ qNameToUIDs :: (T.Text, Integer) -> [ (UID, Integer) ]+ qNameToUIDs (qName, scope) = if T.null qName+ then [ ("", scope) ]+ else [ (uid, scope) | uid <- getUIDs qNameMaps $ convertString qName]++-- | Write a .cfr-scope file+writeCfrScopeFile :: [ (UID, Integer) ] -> QNameMaps -> FilePath -> IO ()+writeCfrScopeFile uidScopes qNameMaps modelName = do+ let+ scopesInJSON = generateJSONScopes qNameMaps uidScopes+ writeFile (replaceExtension modelName ".cfr-scope") scopesInJSON++-- | Read a .cfr-scope file+readCfrScopeFile :: QNameMaps -> FilePath -> IO (Maybe [ (UID, Integer) ])+readCfrScopeFile qNameMaps modelName = do+ let+ cfrScopeFileName = replaceExtension modelName ".cfr-scope"+ exists <- doesFileExist cfrScopeFileName+ if exists+ then do+ scopesInJSON <- readFile cfrScopeFileName+ return $ Just $ parseJSONScopes qNameMaps scopesInJSON+ else return Nothing
src/Language/Clafer/Optimizer/Optimizer.hs view
@@ -1,268 +1,268 @@-{-# LANGUAGE FlexibleContexts #-} -{- - Copyright (C) 2012 Kacper Bak, Jimmy Liang <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -module Language.Clafer.Optimizer.Optimizer where - -import Data.Maybe -import Data.List -import Control.Applicative -import Control.Lens hiding (elements, children, un) -import Control.Monad.State -import Data.Data.Lens (biplate) -import qualified Data.Map as Map -import Prelude - -import Language.Clafer.Common -import Language.Clafer.ClaferArgs -import Language.Clafer.Front.AbsClafer (Span(..)) -import Language.Clafer.Intermediate.Intclafer -import Language.ClaferT (ClaferErr, CErr(..)) - --- | Apply optimizations for unused abstract clafers and inheritance flattening -optimizeModule :: ClaferArgs -> (IModule, GEnv) -> IModule -optimizeModule args (imodule, genv) = - imodule{_mDecls = em $ rm $ map (optimizeElement (1, 1)) $ - markTopModule $ _mDecls imodule} - where - rm = if keep_unused args then makeZeroUnusedAbs else remUnusedAbs - em = if flatten_inheritance args then flip (curry expModule) genv else id - -optimizeElement :: Interval -> IElement -> IElement -optimizeElement interval' x = case x of - IEClafer c -> IEClafer $ optimizeClafer interval' c - IEConstraint _ _ -> x - IEGoal _ _ -> x - -optimizeClafer :: Interval -> IClafer -> IClafer -optimizeClafer interval' c = c {_glCard = glCard', - _elements = map (optimizeElement glCard') $ _elements c} - where - glCard' = multInt (fromJust $ _card c) interval' - - -multInt :: Interval -> Interval -> Interval -multInt (m, n) (m', n') = (m * m', multExInt n n') - -multExInt :: Integer -> Integer -> Integer -multExInt 0 _ = 0 -multExInt _ 0 = 0 -multExInt m n = if m == -1 || n == -1 then -1 else m * n - --- ----------------------------------------------------------------------------- - -makeZeroUnusedAbs :: [IElement] -> [IElement] -makeZeroUnusedAbs decls' = map (\x -> if (x `elem` unusedAbs) then IEClafer (getIClafer x){_card = Just (0, 0)} else x) decls' - where - unusedAbs = map IEClafer $ findUnusedAbs clafers $ map _uid $ - filter (not._isAbstract) clafers - clafers = toClafers decls' - getIClafer (IEClafer c) = c - getIClafer _ = error "Function makeZeroUnusedAbs from Optimizer expected paramter of type IClafer got a differnt IElement" --This should never happen - -remUnusedAbs :: [IElement] -> [IElement] -remUnusedAbs decls' = decls' \\ unusedAbs - where - unusedAbs = map IEClafer $ findUnusedAbs clafers $ map _uid $ - filter (not._isAbstract) clafers - clafers = toClafers decls' - - -findUnusedAbs :: [IClafer] -> [String] -> [IClafer] -findUnusedAbs maybeUsed [] = maybeUsed -findUnusedAbs [] _ = [] -findUnusedAbs maybeUsed used = findUnusedAbs maybeUsed' $ getUniqExtended used' - where - (used', maybeUsed') = partition (\c -> _uid c `elem` used) maybeUsed - -getUniqExtended :: [IClafer] -> [String] -getUniqExtended used = nub $ used >>= getExtended - - -getExtended :: IClafer -> [String] -getExtended c = - sName ++ ((getSubclafers $ _elements c) >>= getExtended) - where - sName = getSuper c - --- ----------------------------------------------------------------------------- --- inheritance expansions - -expModule :: ([IElement], GEnv) -> [IElement] -expModule (decls', genv) = evalState (mapM expElement decls') genv - -expClafer :: MonadState GEnv m => IClafer -> m IClafer -expClafer claf = do - super' <- case _super claf of - Nothing -> return Nothing - (Just pexp') -> Just `liftM` expPExp pexp' - elements' <- mapM expElement $ _elements claf - return $ claf {_super = super', _elements = elements'} - -expElement :: MonadState GEnv m => IElement -> m IElement -expElement x = case x of - IEClafer claf -> IEClafer `liftM` expClafer claf - IEConstraint isHard' constraint -> IEConstraint isHard' `liftM` expPExp constraint - IEGoal isMaximize' goal -> IEGoal isMaximize' `liftM` expPExp goal - -expPExp :: MonadState GEnv m => PExp -> m PExp -expPExp (PExp t pid' pos' exp') = PExp t pid' pos' `liftM` expIExp pos' exp' - -expIExp :: MonadState GEnv m => Span -> IExp -> m IExp -expIExp pos' x = case x of - IDeclPExp quant' decls' pexp -> do - decls'' <- mapM expDecl decls' - pexp' <- expPExp pexp - return $ IDeclPExp quant' decls'' pexp' - IFunExp op' exps' -> if op' == iJoin - then expNav pos' x else IFunExp op' `liftM` mapM expPExp exps' - IClaferId _ _ _ _ -> expNav pos' x - _ -> return x - -expDecl :: MonadState GEnv m => IDecl -> m IDecl -expDecl x = case x of - IDecl disj locids pexp -> IDecl disj locids `liftM` expPExp pexp - -expNav :: MonadState GEnv m => Span -> IExp -> m IExp -expNav pos' x = do - xs <- split' x return - xs' <- mapM (expNav' pos' "") xs - return $ mkIFunExp pos' iUnion $ map fst xs' - -expNav' :: MonadState GEnv m => Span -> String -> IExp -> m (IExp, String) -expNav' pos' context (IFunExp _ (p0:p:_)) = do - (exp0', context') <- expNav' pos' context $ _exp p0 - (exp', context'') <- expNav' pos' context' $ _exp p - return (IFunExp iJoin [ p0 {_exp = exp0'} - , p {_exp = exp'}], context'') -expNav' pos' context x@(IClaferId modName' id' isTop' bind' ) = do - st <- gets stable - if Map.member id' st - then do - let impls = (Map.!) st id' - let (impls', context') = maybe (impls, "") - (\y -> ([[head y]], head y)) $ - find (\z -> context == (head.tail) z) impls - return (mkIFunExp pos' iUnion $ map (\u -> IClaferId modName' u isTop' bind') $ - map head impls', context') - else do - return (x, id') -expNav' pos' _ _ = error $ "Function expNav' from Optimizer expects an argument of type ClaferId or IFunExp but was given another IExp, " ++ show pos' - -split' :: MonadState GEnv m => IExp -> (IExp -> m IExp) -> m [IExp] -split'(IFunExp _ (p:pexp:_)) f = - split' (_exp p) (\s -> f $ IFunExp iJoin - [p {_exp = s}, pexp]) -split' (IClaferId modName' id' isTop' bind') f = do - st <- gets stable - mapM f $ map (\y -> IClaferId modName' y isTop' bind') $ maybe [id'] (map head) $ Map.lookup id' st -split' _ _ = error "Function split' from Optimizer expects an argument of type ClaferId or IFunExp but was given another IExp" - --- ----------------------------------------------------------------------------- --- checking if all clafers have unique names and don't extend other clafers - -allUnique :: IModule -> Bool -allUnique iModule = dontExtend && identsUnique - where - allClafers :: [ IClafer ] - allClafers = universeOn biplate iModule - - -- True when getSuper always returns Nothing and therefore concatMap returned [] - dontExtend = null $ concatMap getSuper allClafers - allIdents = map _ident allClafers - -- all idents are unique when nub cannot remove any duplicates - identsUnique = (length allIdents) == (length $ nub allIdents) - -checkConstraintElement :: [String] -> IElement -> Bool -checkConstraintElement idents x = case x of - IEClafer claf -> and $ map (checkConstraintElement idents) $ _elements claf - IEConstraint _ pexp -> checkConstraintPExp idents pexp - IEGoal _ _ -> True - -checkConstraintPExp :: [String] -> PExp -> Bool -checkConstraintPExp idents pexp = checkConstraintIExp idents $ _exp pexp - -checkConstraintIExp :: [String] -> IExp -> Bool -checkConstraintIExp idents x = case x of - IDeclPExp _ oDecls' pexp -> - checkConstraintPExp ((oDecls' >>= (checkConstraintIDecl idents)) ++ idents) pexp - IClaferId _ ident' _ _ -> if ident' `elem` (specialNames ++ (rootIdent : idents)) then True - else error $ "optimizer: " ++ ident' ++ " not found" - _ -> True - -checkConstraintIDecl :: [String] -> IDecl -> [String] -checkConstraintIDecl idents (IDecl _ decls' pexp) - | checkConstraintPExp idents pexp = decls' - | otherwise = [] - --- ----------------------------------------------------------------------------- -findDupModule :: ClaferArgs -> IModule -> Either ClaferErr IModule -findDupModule args iModule = if check_duplicates args && (not $ null dups) - then Left $ ClaferErr $ "--check-duplicates: Duplicate clafer names: " ++ (intercalate ", " dups) - else Right iModule - where - allClafers :: [ IClafer ] - allClafers = universeOn biplate iModule - dups = findDuplicates allClafers - - findDuplicates :: [IClafer] -> [String] - findDuplicates clafers = - map head $ filter (\xs -> 1 < length xs) $ group $ sort $ map _ident clafers - --- ----------------------------------------------------------------------------- --- marks top clafers - -markTopModule :: [IElement] -> [IElement] -markTopModule decls' = map (markTopElement ( - specialNames ++ primitiveTypes ++ - (map _uid $ toClafers decls'))) decls' - - -markTopClafer :: [String] -> IClafer -> IClafer -markTopClafer clafers c = - c {_super = markTopPExp clafers <$> _super c, - _elements = map (markTopElement clafers) $ _elements c} - - -markTopElement :: [String] -> IElement -> IElement -markTopElement clafers x = case x of - IEClafer c -> IEClafer $ markTopClafer clafers c - IEConstraint isHard' pexp -> IEConstraint isHard' $ markTopPExp clafers pexp - IEGoal isMaximize' pexp -> IEGoal isMaximize' $ markTopPExp clafers pexp - -markTopPExp :: [String] -> PExp -> PExp -markTopPExp clafers pexp = - pexp {_exp = markTopIExp clafers $ _exp pexp} - - -markTopIExp :: [String] -> IExp -> IExp -markTopIExp clafers x = case x of - IDeclPExp quant' decl pexp -> IDeclPExp quant' (map (markTopDecl clafers) decl) - (markTopPExp ((decl >>= _decls) ++ clafers) pexp) - IFunExp op' exps' -> IFunExp op' $ map (markTopPExp clafers) exps' - IClaferId modName' sident' _ bind'-> - IClaferId modName' sident' (sident' `elem` clafers) bind' - _ -> x - - -markTopDecl :: [String] -> IDecl -> IDecl -markTopDecl clafers x = case x of - IDecl disj locids pexp -> IDecl disj locids $ markTopPExp clafers pexp +{-# LANGUAGE FlexibleContexts #-}+{-+ Copyright (C) 2012 Kacper Bak, Jimmy Liang <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+module Language.Clafer.Optimizer.Optimizer where++import Data.Maybe+import Data.List+import Control.Applicative+import Control.Lens hiding (elements, children, un)+import Control.Monad.State+import Data.Data.Lens (biplate)+import qualified Data.Map as Map+import Prelude++import Language.Clafer.Common+import Language.Clafer.ClaferArgs+import Language.Clafer.Front.AbsClafer (Span(..))+import Language.Clafer.Intermediate.Intclafer+import Language.ClaferT (ClaferErr, CErr(..))++-- | Apply optimizations for unused abstract clafers and inheritance flattening+optimizeModule :: ClaferArgs -> (IModule, GEnv) -> IModule+optimizeModule args (imodule, genv) =+ imodule{_mDecls = em $ rm $ map (optimizeElement (1, 1)) $+ markTopModule $ _mDecls imodule}+ where+ rm = if keep_unused args then makeZeroUnusedAbs else remUnusedAbs+ em = if flatten_inheritance args then flip (curry expModule) genv else id++optimizeElement :: Interval -> IElement -> IElement+optimizeElement interval' x = case x of+ IEClafer c -> IEClafer $ optimizeClafer interval' c+ IEConstraint _ _ -> x+ IEGoal _ _ -> x++optimizeClafer :: Interval -> IClafer -> IClafer+optimizeClafer interval' c = c {_glCard = glCard',+ _elements = map (optimizeElement glCard') $ _elements c}+ where+ glCard' = multInt (fromJust $ _card c) interval'+++multInt :: Interval -> Interval -> Interval+multInt (m, n) (m', n') = (m * m', multExInt n n')++multExInt :: Integer -> Integer -> Integer+multExInt 0 _ = 0+multExInt _ 0 = 0+multExInt m n = if m == -1 || n == -1 then -1 else m * n++-- -----------------------------------------------------------------------------++makeZeroUnusedAbs :: [IElement] -> [IElement]+makeZeroUnusedAbs decls' = map (\x -> if (x `elem` unusedAbs) then IEClafer (getIClafer x){_card = Just (0, 0)} else x) decls'+ where+ unusedAbs = map IEClafer $ findUnusedAbs clafers $ map _uid $+ filter (not._isAbstract) clafers+ clafers = toClafers decls'+ getIClafer (IEClafer c) = c+ getIClafer _ = error "Function makeZeroUnusedAbs from Optimizer expected paramter of type IClafer got a differnt IElement" --This should never happen++remUnusedAbs :: [IElement] -> [IElement]+remUnusedAbs decls' = decls' \\ unusedAbs+ where+ unusedAbs = map IEClafer $ findUnusedAbs clafers $ map _uid $+ filter (not._isAbstract) clafers+ clafers = toClafers decls'+++findUnusedAbs :: [IClafer] -> [String] -> [IClafer]+findUnusedAbs maybeUsed [] = maybeUsed+findUnusedAbs [] _ = []+findUnusedAbs maybeUsed used = findUnusedAbs maybeUsed' $ getUniqExtended used'+ where+ (used', maybeUsed') = partition (\c -> _uid c `elem` used) maybeUsed++getUniqExtended :: [IClafer] -> [String]+getUniqExtended used = nub $ used >>= getExtended+++getExtended :: IClafer -> [String]+getExtended c =+ sName ++ ((getSubclafers $ _elements c) >>= getExtended)+ where+ sName = getSuper c++-- -----------------------------------------------------------------------------+-- inheritance expansions++expModule :: ([IElement], GEnv) -> [IElement]+expModule (decls', genv) = evalState (mapM expElement decls') genv++expClafer :: MonadState GEnv m => IClafer -> m IClafer+expClafer claf = do+ super' <- case _super claf of+ Nothing -> return Nothing+ (Just pexp') -> Just `liftM` expPExp pexp'+ elements' <- mapM expElement $ _elements claf+ return $ claf {_super = super', _elements = elements'}++expElement :: MonadState GEnv m => IElement -> m IElement+expElement x = case x of+ IEClafer claf -> IEClafer `liftM` expClafer claf+ IEConstraint isHard' constraint -> IEConstraint isHard' `liftM` expPExp constraint+ IEGoal isMaximize' goal -> IEGoal isMaximize' `liftM` expPExp goal++expPExp :: MonadState GEnv m => PExp -> m PExp+expPExp (PExp t pid' pos' exp') = PExp t pid' pos' `liftM` expIExp pos' exp'++expIExp :: MonadState GEnv m => Span -> IExp -> m IExp+expIExp pos' x = case x of+ IDeclPExp quant' decls' pexp -> do+ decls'' <- mapM expDecl decls'+ pexp' <- expPExp pexp+ return $ IDeclPExp quant' decls'' pexp'+ IFunExp op' exps' -> if op' == iJoin+ then expNav pos' x else IFunExp op' `liftM` mapM expPExp exps'+ IClaferId _ _ _ _ -> expNav pos' x+ _ -> return x++expDecl :: MonadState GEnv m => IDecl -> m IDecl+expDecl x = case x of+ IDecl disj locids pexp -> IDecl disj locids `liftM` expPExp pexp++expNav :: MonadState GEnv m => Span -> IExp -> m IExp+expNav pos' x = do+ xs <- split' x return+ xs' <- mapM (expNav' pos' "") xs+ return $ mkIFunExp pos' iUnion $ map fst xs'++expNav' :: MonadState GEnv m => Span -> String -> IExp -> m (IExp, String)+expNav' pos' context (IFunExp _ (p0:p:_)) = do+ (exp0', context') <- expNav' pos' context $ _exp p0+ (exp', context'') <- expNav' pos' context' $ _exp p+ return (IFunExp iJoin [ p0 {_exp = exp0'}+ , p {_exp = exp'}], context'')+expNav' pos' context x@(IClaferId modName' id' isTop' bind' ) = do+ st <- gets stable+ if Map.member id' st+ then do+ let impls = (Map.!) st id'+ let (impls', context') = maybe (impls, "")+ (\y -> ([[head y]], head y)) $+ find (\z -> context == (head.tail) z) impls+ return (mkIFunExp pos' iUnion $ map (\u -> IClaferId modName' u isTop' bind') $+ map head impls', context')+ else do+ return (x, id')+expNav' pos' _ _ = error $ "Function expNav' from Optimizer expects an argument of type ClaferId or IFunExp but was given another IExp, " ++ show pos'++split' :: MonadState GEnv m => IExp -> (IExp -> m IExp) -> m [IExp]+split'(IFunExp _ (p:pexp:_)) f =+ split' (_exp p) (\s -> f $ IFunExp iJoin+ [p {_exp = s}, pexp])+split' (IClaferId modName' id' isTop' bind') f = do+ st <- gets stable+ mapM f $ map (\y -> IClaferId modName' y isTop' bind') $ maybe [id'] (map head) $ Map.lookup id' st+split' _ _ = error "Function split' from Optimizer expects an argument of type ClaferId or IFunExp but was given another IExp"++-- -----------------------------------------------------------------------------+-- checking if all clafers have unique names and don't extend other clafers++allUnique :: IModule -> Bool+allUnique iModule = dontExtend && identsUnique+ where+ allClafers :: [ IClafer ]+ allClafers = universeOn biplate iModule++ -- True when getSuper always returns Nothing and therefore concatMap returned []+ dontExtend = null $ concatMap getSuper allClafers+ allIdents = map _ident allClafers+ -- all idents are unique when nub cannot remove any duplicates+ identsUnique = (length allIdents) == (length $ nub allIdents)++checkConstraintElement :: [String] -> IElement -> Bool+checkConstraintElement idents x = case x of+ IEClafer claf -> and $ map (checkConstraintElement idents) $ _elements claf+ IEConstraint _ pexp -> checkConstraintPExp idents pexp+ IEGoal _ _ -> True++checkConstraintPExp :: [String] -> PExp -> Bool+checkConstraintPExp idents pexp = checkConstraintIExp idents $ _exp pexp++checkConstraintIExp :: [String] -> IExp -> Bool+checkConstraintIExp idents x = case x of+ IDeclPExp _ oDecls' pexp ->+ checkConstraintPExp ((oDecls' >>= (checkConstraintIDecl idents)) ++ idents) pexp+ IClaferId _ ident' _ _ -> if ident' `elem` (specialNames ++ (rootIdent : idents)) then True+ else error $ "optimizer: " ++ ident' ++ " not found"+ _ -> True++checkConstraintIDecl :: [String] -> IDecl -> [String]+checkConstraintIDecl idents (IDecl _ decls' pexp)+ | checkConstraintPExp idents pexp = decls'+ | otherwise = []++-- -----------------------------------------------------------------------------+findDupModule :: ClaferArgs -> IModule -> Either ClaferErr IModule+findDupModule args iModule = if check_duplicates args && (not $ null dups)+ then Left $ ClaferErr $ "--check-duplicates: Duplicate clafer names: " ++ (intercalate ", " dups)+ else Right iModule+ where+ allClafers :: [ IClafer ]+ allClafers = universeOn biplate iModule+ dups = findDuplicates allClafers++ findDuplicates :: [IClafer] -> [String]+ findDuplicates clafers =+ map head $ filter (\xs -> 1 < length xs) $ group $ sort $ map _ident clafers++-- -----------------------------------------------------------------------------+-- marks top clafers++markTopModule :: [IElement] -> [IElement]+markTopModule decls' = map (markTopElement (+ specialNames ++ primitiveTypes +++ (map _uid $ toClafers decls'))) decls'+++markTopClafer :: [String] -> IClafer -> IClafer+markTopClafer clafers c =+ c {_super = markTopPExp clafers <$> _super c,+ _elements = map (markTopElement clafers) $ _elements c}+++markTopElement :: [String] -> IElement -> IElement+markTopElement clafers x = case x of+ IEClafer c -> IEClafer $ markTopClafer clafers c+ IEConstraint isHard' pexp -> IEConstraint isHard' $ markTopPExp clafers pexp+ IEGoal isMaximize' pexp -> IEGoal isMaximize' $ markTopPExp clafers pexp++markTopPExp :: [String] -> PExp -> PExp+markTopPExp clafers pexp =+ pexp {_exp = markTopIExp clafers $ _exp pexp}+++markTopIExp :: [String] -> IExp -> IExp+markTopIExp clafers x = case x of+ IDeclPExp quant' decl pexp -> IDeclPExp quant' (map (markTopDecl clafers) decl)+ (markTopPExp ((decl >>= _decls) ++ clafers) pexp)+ IFunExp op' exps' -> IFunExp op' $ map (markTopPExp clafers) exps'+ IClaferId modName' sident' _ bind'->+ IClaferId modName' sident' (sident' `elem` clafers) bind'+ _ -> x+++markTopDecl :: [String] -> IDecl -> IDecl+markTopDecl clafers x = case x of+ IDecl disj locids pexp -> IDecl disj locids $ markTopPExp clafers pexp
src/Language/Clafer/QNameUID.hs view
@@ -1,161 +1,161 @@-{- - Copyright (C) 2014 Michal Antkiewicz <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} --- | Support for dealing with unique IDs (UIDs), fully- and least-partially qualified names. -module Language.Clafer.QNameUID ( - QName, - FQName, - PQName, - QNameMaps, - UID, - deriveQNameMaps, - getUIDs, - getFQName, - getLPQName, - getQNameUIDTriples -) - -where - -import Data.Maybe -import Data.List.Split -import qualified Data.Map as Map -import qualified Data.StringMap as SMap - -import Language.Clafer.Intermediate.Intclafer - --- | a fully- or partially-qualified name -type QName = String - --- | fully-qualified name, must begin with :: --- | e.g., `::Person::name`, `::Company::Department::chair` -type FQName = String - --- a reversed FQName used as a key in the FQNameUIDMap -type FQKey = String - --- | partially-qualified name, must not begin with :: --- | e.g., `Person::name`, `chair` -type PQName = String - --- a map from reversed FQName (FQKey) to UID -type FQNameUIDMap = SMap.StringMap UID - -type UIDFqNameMap = Map.Map UID FQName -type UIDLpqNameMap = Map.Map UID PQName - --- | maps between fully-, least-partially-qualified names and UIDs -data QNameMaps = QNameMaps FQNameUIDMap UIDFqNameMap UIDLpqNameMap - --- | get the UID of a clafer given a fully qualifed name or potentially many UIDs given a partially qualified name -getUIDs :: QNameMaps -> QName -> [UID] -getUIDs (QNameMaps fqNameUIDMap _ _) qName = findUIDsByFQName fqNameUIDMap qName - --- | get the fully-qualified name of a clafer given its UID -getFQName :: QNameMaps -> UID -> Maybe FQName -getFQName (QNameMaps _ uidFqNameMap _) uid' = Map.lookup uid' uidFqNameMap - --- | get the least-partially-qualified name of a clafer given its UID -getLPQName :: QNameMaps -> UID -> Maybe PQName -getLPQName (QNameMaps _ _ uidLpqNameMap) uid' = Map.lookup uid' uidLpqNameMap - --- | derive maps between fully-, partially-qualified names, and UIDs -deriveQNameMaps :: IModule -> QNameMaps -deriveQNameMaps iModule = - let - (fqNameUIDMap, uidFqNameMap) = deriveFQNameUIDMaps iModule - uidLpqNameMap = deriveUidLpqNameMap fqNameUIDMap - in - QNameMaps fqNameUIDMap uidFqNameMap uidLpqNameMap - -deriveFQNameUIDMaps :: IModule -> (FQNameUIDMap, UIDFqNameMap) -deriveFQNameUIDMaps iModule = addElements ["::"] (_mDecls iModule) (SMap.empty, Map.empty) - -addElements :: [String] -> [IElement] -> (FQNameUIDMap, UIDFqNameMap) -> (FQNameUIDMap, UIDFqNameMap) -addElements path elems maps = foldl (addClafer path) maps elems - -addClafer :: [String] -> (FQNameUIDMap, UIDFqNameMap) -> IElement -> (FQNameUIDMap, UIDFqNameMap) -addClafer path (fqNameUIDMap, uidFqNameMap) (IEClafer iClaf) = - let - newPath = (_ident iClaf) : path - fqKey :: FQKey - fqKey = concat newPath - fqName :: FQName - fqName = getQNameFromKey fqKey - fqNameUIDMap' = SMap.insert fqKey (_uid iClaf) fqNameUIDMap - uidFqNameMap' = Map.insert (_uid iClaf) fqName uidFqNameMap - in - addElements ("::" : newPath) (_elements iClaf) (fqNameUIDMap', uidFqNameMap') -addClafer _ maps _ = maps - -findUIDsByFQName :: FQNameUIDMap -> FQName -> [ UID ] -findUIDsByFQName fqNameUIDMap fqName@(':':':':_) = SMap.lookup (getFQKey fqName) fqNameUIDMap -findUIDsByFQName fqNameUIDMap fqName = SMap.prefixFind (getFQKey fqName) fqNameUIDMap - -reverseOnQualifier :: FQName -> FQName -reverseOnQualifier fqName = concat $ reverse $ split (onSublist "::") fqName - -getFQKey :: FQName -> FQKey -getFQKey = reverseOnQualifier - -getQNameFromKey :: FQKey -> QName -getQNameFromKey = reverseOnQualifier - -deriveUidLpqNameMap :: FQNameUIDMap -> UIDLpqNameMap -deriveUidLpqNameMap fqNameUIDMap = - SMap.foldrWithKey (generateUIDLpqMapEntry fqNameUIDMap) Map.empty fqNameUIDMap - -generateUIDLpqMapEntry :: FQNameUIDMap -> SMap.Key -> UID -> UIDLpqNameMap -> UIDLpqNameMap -generateUIDLpqMapEntry fqNameUIDMap fqKey uid' uidLpqNameMap = - Map.insert uid' lpqName uidLpqNameMap - where - -- need to reverse the key to get a fully qualified name - fqName :: FQName - fqName = getQNameFromKey fqKey - - -- name qualified just sufficiently to uniquely identify the clafer - -- can be both FQName or PQName - lpqName :: QName - lpqName = findLeastQualifiedName fqName fqNameUIDMap - - findLeastQualifiedName :: String -> FQNameUIDMap -> String - -- handle fully qualified name case - findLeastQualifiedName fqName'@(':':':':pqName) fqNameUIDMap' = - if (length (findUIDsByFQName fqNameUIDMap' pqName) > 1) - then fqName' - else findLeastQualifiedName pqName fqNameUIDMap' - -- handle partially qualified name case - findLeastQualifiedName pqName fqNameUIDMap' = - let - -- remove one segment of qualification - lessQName = concat $ drop 2 $ split (onSublist "::") pqName - in - if (length (findUIDsByFQName fqNameUIDMap' lessQName) > 1) - then pqName - else findLeastQualifiedName lessQName fqNameUIDMap' - -getQNameUIDTriples :: QNameMaps -> [(FQName, PQName, UID)] -getQNameUIDTriples qNameMaps@(QNameMaps _ uidFqNameMap _) = - let - uidFqNameList :: [(UID, FQName)] - uidFqNameList = Map.toList uidFqNameMap - in - map (\(uid', fqName) -> (fqName, fromMaybe fqName $ getLPQName qNameMaps uid', uid')) uidFqNameList +{-+ Copyright (C) 2014 Michal Antkiewicz <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+-- | Support for dealing with unique IDs (UIDs), fully- and least-partially qualified names.+module Language.Clafer.QNameUID (+ QName,+ FQName,+ PQName,+ QNameMaps,+ UID,+ deriveQNameMaps,+ getUIDs,+ getFQName,+ getLPQName,+ getQNameUIDTriples+)++where++import Data.Maybe+import Data.List.Split+import qualified Data.Map as Map+import qualified Data.StringMap as SMap++import Language.Clafer.Intermediate.Intclafer++-- | a fully- or partially-qualified name+type QName = String++-- | fully-qualified name, must begin with ::+-- | e.g., `::Person::name`, `::Company::Department::chair`+type FQName = String++-- a reversed FQName used as a key in the FQNameUIDMap+type FQKey = String++-- | partially-qualified name, must not begin with ::+-- | e.g., `Person::name`, `chair`+type PQName = String++-- a map from reversed FQName (FQKey) to UID+type FQNameUIDMap = SMap.StringMap UID++type UIDFqNameMap = Map.Map UID FQName+type UIDLpqNameMap = Map.Map UID PQName++-- | maps between fully-, least-partially-qualified names and UIDs+data QNameMaps = QNameMaps FQNameUIDMap UIDFqNameMap UIDLpqNameMap++-- | get the UID of a clafer given a fully qualifed name or potentially many UIDs given a partially qualified name+getUIDs :: QNameMaps -> QName -> [UID]+getUIDs (QNameMaps fqNameUIDMap _ _) qName = findUIDsByFQName fqNameUIDMap qName++-- | get the fully-qualified name of a clafer given its UID+getFQName :: QNameMaps -> UID -> Maybe FQName+getFQName (QNameMaps _ uidFqNameMap _) uid' = Map.lookup uid' uidFqNameMap++-- | get the least-partially-qualified name of a clafer given its UID+getLPQName :: QNameMaps -> UID -> Maybe PQName+getLPQName (QNameMaps _ _ uidLpqNameMap) uid' = Map.lookup uid' uidLpqNameMap++-- | derive maps between fully-, partially-qualified names, and UIDs+deriveQNameMaps :: IModule -> QNameMaps+deriveQNameMaps iModule =+ let+ (fqNameUIDMap, uidFqNameMap) = deriveFQNameUIDMaps iModule+ uidLpqNameMap = deriveUidLpqNameMap fqNameUIDMap+ in+ QNameMaps fqNameUIDMap uidFqNameMap uidLpqNameMap++deriveFQNameUIDMaps :: IModule -> (FQNameUIDMap, UIDFqNameMap)+deriveFQNameUIDMaps iModule = addElements ["::"] (_mDecls iModule) (SMap.empty, Map.empty)++addElements :: [String] -> [IElement] -> (FQNameUIDMap, UIDFqNameMap) -> (FQNameUIDMap, UIDFqNameMap)+addElements path elems maps = foldl (addClafer path) maps elems++addClafer :: [String] -> (FQNameUIDMap, UIDFqNameMap) -> IElement -> (FQNameUIDMap, UIDFqNameMap)+addClafer path (fqNameUIDMap, uidFqNameMap) (IEClafer iClaf) =+ let+ newPath = (_ident iClaf) : path+ fqKey :: FQKey+ fqKey = concat newPath+ fqName :: FQName+ fqName = getQNameFromKey fqKey+ fqNameUIDMap' = SMap.insert fqKey (_uid iClaf) fqNameUIDMap+ uidFqNameMap' = Map.insert (_uid iClaf) fqName uidFqNameMap+ in+ addElements ("::" : newPath) (_elements iClaf) (fqNameUIDMap', uidFqNameMap')+addClafer _ maps _ = maps++findUIDsByFQName :: FQNameUIDMap -> FQName -> [ UID ]+findUIDsByFQName fqNameUIDMap fqName@(':':':':_) = SMap.lookup (getFQKey fqName) fqNameUIDMap+findUIDsByFQName fqNameUIDMap fqName = SMap.prefixFind (getFQKey fqName) fqNameUIDMap++reverseOnQualifier :: FQName -> FQName+reverseOnQualifier fqName = concat $ reverse $ split (onSublist "::") fqName++getFQKey :: FQName -> FQKey+getFQKey = reverseOnQualifier++getQNameFromKey :: FQKey -> QName+getQNameFromKey = reverseOnQualifier++deriveUidLpqNameMap :: FQNameUIDMap -> UIDLpqNameMap+deriveUidLpqNameMap fqNameUIDMap =+ SMap.foldrWithKey (generateUIDLpqMapEntry fqNameUIDMap) Map.empty fqNameUIDMap++generateUIDLpqMapEntry :: FQNameUIDMap -> SMap.Key -> UID -> UIDLpqNameMap -> UIDLpqNameMap+generateUIDLpqMapEntry fqNameUIDMap fqKey uid' uidLpqNameMap =+ Map.insert uid' lpqName uidLpqNameMap+ where+ -- need to reverse the key to get a fully qualified name+ fqName :: FQName+ fqName = getQNameFromKey fqKey++ -- name qualified just sufficiently to uniquely identify the clafer+ -- can be both FQName or PQName+ lpqName :: QName+ lpqName = findLeastQualifiedName fqName fqNameUIDMap++ findLeastQualifiedName :: String -> FQNameUIDMap -> String+ -- handle fully qualified name case+ findLeastQualifiedName fqName'@(':':':':pqName) fqNameUIDMap' =+ if (length (findUIDsByFQName fqNameUIDMap' pqName) > 1)+ then fqName'+ else findLeastQualifiedName pqName fqNameUIDMap'+ -- handle partially qualified name case+ findLeastQualifiedName pqName fqNameUIDMap' =+ let+ -- remove one segment of qualification+ lessQName = concat $ drop 2 $ split (onSublist "::") pqName+ in+ if (length (findUIDsByFQName fqNameUIDMap' lessQName) > 1)+ then pqName+ else findLeastQualifiedName lessQName fqNameUIDMap'++getQNameUIDTriples :: QNameMaps -> [(FQName, PQName, UID)]+getQNameUIDTriples qNameMaps@(QNameMaps _ uidFqNameMap _) =+ let+ uidFqNameList :: [(UID, FQName)]+ uidFqNameList = Map.toList uidFqNameMap+ in+ map (\(uid', fqName) -> (fqName, fromMaybe fqName $ getLPQName qNameMaps uid', uid')) uidFqNameList
src/Language/Clafer/SplitJoin.hs view
@@ -1,53 +1,53 @@-{-# LANGUAGE RecordWildCards #-} -module Language.Clafer.SplitJoin(splitArgs, joinArgs) where - -import Data.Char -import Data.Maybe - - --- | Given a sequence of arguments, join them together in a manner that could be used on --- | the command line, giving preference to the Windows @cmd@ shell quoting conventions. --- | For an alternative version, intended for actual running the result in a shell, see "System.Process.showCommandForUser" -joinArgs :: [String] -> String -joinArgs = unwords . map f - where - f x = q ++ g x ++ q - where - hasSpace = any isSpace x - q = ['\"' | hasSpace || null x] - - g ('\\':'\"':xs') = '\\':'\\':'\\':'\"': g xs' - g "\\" | hasSpace = "\\\\" - g ('\"':xs') = '\\':'\"': g xs' - g (x':xs') = x' : g xs' - g [] = [] - - -data State = Init -- either I just started, or just emitted something - | Norm -- I'm seeing characters - | Quot -- I've seen a quote - --- | Given a string, split into the available arguments. The inverse of 'joinArgs'. -splitArgs :: String -> [String] -splitArgs = join . f Init - where - -- Nothing is start a new string - -- Just x is accumulate onto the existing string - join :: [Maybe Char] -> [String] - join [] = [] - join xs = map fromJust a : join (drop 1 b) - where (a,b) = break isNothing xs - - f Init (x:xs) | isSpace x = f Init xs - f Init "\"\"" = [Nothing] - f Init "\"" = [Nothing] - f Init xs = f Norm xs - f m ('\"':'\"':'\"':xs) = Just '\"' : f m xs - f m ('\\':'\"':xs) = Just '\"' : f m xs - f m ('\\':'\\':'\"':xs) = Just '\\' : f m ('\"':xs) - f Norm ('\"':xs) = f Quot xs - f Quot ('\"':'\"':xs) = Just '\"' : f Norm xs - f Quot ('\"':xs) = f Norm xs - f Norm (x:xs) | isSpace x = Nothing : f Init xs - f m (x:xs) = Just x : f m xs - f _ [] = [] +{-# LANGUAGE RecordWildCards #-}+module Language.Clafer.SplitJoin(splitArgs, joinArgs) where++import Data.Char+import Data.Maybe+++-- | Given a sequence of arguments, join them together in a manner that could be used on+-- | the command line, giving preference to the Windows @cmd@ shell quoting conventions.+-- | For an alternative version, intended for actual running the result in a shell, see "System.Process.showCommandForUser"+joinArgs :: [String] -> String+joinArgs = unwords . map f+ where+ f x = q ++ g x ++ q+ where+ hasSpace = any isSpace x+ q = ['\"' | hasSpace || null x]++ g ('\\':'\"':xs') = '\\':'\\':'\\':'\"': g xs'+ g "\\" | hasSpace = "\\\\"+ g ('\"':xs') = '\\':'\"': g xs'+ g (x':xs') = x' : g xs'+ g [] = []+++data State = Init -- either I just started, or just emitted something+ | Norm -- I'm seeing characters+ | Quot -- I've seen a quote++-- | Given a string, split into the available arguments. The inverse of 'joinArgs'.+splitArgs :: String -> [String]+splitArgs = join . f Init+ where+ -- Nothing is start a new string+ -- Just x is accumulate onto the existing string+ join :: [Maybe Char] -> [String]+ join [] = []+ join xs = map fromJust a : join (drop 1 b)+ where (a,b) = break isNothing xs++ f Init (x:xs) | isSpace x = f Init xs+ f Init "\"\"" = [Nothing]+ f Init "\"" = [Nothing]+ f Init xs = f Norm xs+ f m ('\"':'\"':'\"':xs) = Just '\"' : f m xs+ f m ('\\':'\"':xs) = Just '\"' : f m xs+ f m ('\\':'\\':'\"':xs) = Just '\\' : f m ('\"':xs)+ f Norm ('\"':xs) = f Quot xs+ f Quot ('\"':'\"':xs) = Just '\"' : f Norm xs+ f Quot ('\"':xs) = f Norm xs+ f Norm (x:xs) | isSpace x = Nothing : f Init xs+ f m (x:xs) = Just x : f m xs+ f _ [] = []
src/Language/Clafer/clafer.css view
@@ -1,14 +1,14 @@-.identifier{} -.keyword{font-weight:bold} -.reference{} -.code { background-color: lightgray; padding: 5px 5px 5px 5px; border: 1px solid darkgray; margin-bottom: 15px; - font-family: Pragmata, Menlo, 'DejaVu LGC Sans Mono', 'DejaVu Sans Mono', Consolas, 'Everson Mono', 'Lucida Console', 'Andale Mono', 'Nimbus Mono L', 'Liberation Mono', FreeMono, 'Osaka Monospaced', Courier, 'New Courier', monospace; } -.standalonecomment { color: green; font-style:italic } -.inlinecomment { color: green; padding-left:20px; font-style:italic } -.error{background-color: yellow; color: red } -.deprecated{color: orange } -.indent{padding-left:20px} -a[href$='Lookup failed'] {color: red} -a[href$='Uid not found'] {color: red} -a[href$='Ambiguous name'] {color: yellow} - +.identifier{}+.keyword{font-weight:bold}+.reference{}+.code { background-color: lightgray; padding: 5px 5px 5px 5px; border: 1px solid darkgray; margin-bottom: 15px; + font-family: Pragmata, Menlo, 'DejaVu LGC Sans Mono', 'DejaVu Sans Mono', Consolas, 'Everson Mono', 'Lucida Console', 'Andale Mono', 'Nimbus Mono L', 'Liberation Mono', FreeMono, 'Osaka Monospaced', Courier, 'New Courier', monospace; }+.standalonecomment { color: green; font-style:italic }+.inlinecomment { color: green; padding-left:20px; font-style:italic }+.error{background-color: yellow; color: red }+.deprecated{color: orange }+.indent{padding-left:20px}+a[href$='Lookup failed'] {color: red}+a[href$='Uid not found'] {color: red}+a[href$='Ambiguous name'] {color: yellow}+
src/Language/ClaferT.hs view
@@ -1,336 +1,336 @@-{-# LANGUAGE RankNTypes #-} -{- - Copyright (C) 2012-2015 Kacper Bak, Jimmy Liang, Michal Antkiewicz <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} - -{- | -This is in a separate module from the module "Language.Clafer" so that other modules that require -ClaferEnv can just import this module without all the parsing/compiline/generating functionality. - -} -module Language.ClaferT - ( ClaferEnv(..) - , irModuleTrace - , uidIClaferMap - , makeEnv - , getAst - , getIr - , ClaferM - , ClaferT - , CErr(..) - , CErrs(..) - , ClaferErr - , ClaferErrs - , ClaferSErr - , ClaferSErrs - , ErrPos(..) - , PartialErrPos(..) - , throwErrs - , throwErr - , catchErrs - , getEnv - , getsEnv - , modifyEnv - , putEnv - , runClafer - , runClaferT - , Throwable(..) - , Span(..) - , Pos(..) - ) where - -import Control.Monad.Except -import Control.Monad.Identity -import Control.Monad.State -import Data.List -import qualified Data.Map as Map - -import Language.Clafer.ClaferArgs -import Language.Clafer.Common -import Language.Clafer.Front.AbsClafer -import Language.Clafer.Front.LexClafer -import Language.Clafer.Intermediate.Intclafer -import Language.Clafer.Intermediate.Tracing - -{- - - Examples. - - - - If you need ClaferEnv: - - runClafer args $ - - do - - env <- getEnv - - env' = ... - - putEnv env' - - - - Remember to putEnv if you do any modification to the ClaferEnv or else your updates - - are lost! - - - - - - Throwing errors: - - - - throwErr $ ParseErr (ErrFragPos fragId fragPos) "failed parsing" - - throwErr $ ParseErr (ErrModelPos modelPos) "failed parsing" - - - - There is two ways of defining the position of the error. Either define the position - - relative to a fragment, or relative to the model. Pick the one that is convenient. - - Once thrown, the "partial" positions will be automatically updated to contain both - - the model and fragment positions. - - Use throwErrs to throw multiple errors. - - Use catchErrs to catch errors (usually not needed). - - - -} - -data ClaferEnv - = ClaferEnv - { args :: ClaferArgs - , modelFrags :: [String] -- original text of the model fragments - , cAst :: Maybe Module - , cIr :: Maybe (IModule, GEnv, Bool) - , frags :: [Pos] -- line numbers of fragment markers - , astModuleTrace :: Map.Map Span [Ast] -- can keep the Ast map since it never changes - , otherTokens :: [Token] -- non-parseable tokens: comments and escape blocks - } deriving Show - --- | This simulates a field in the ClaferEnv that will always recompute the map, --- since the IR always changes and the map becomes obsolete -irModuleTrace :: ClaferEnv -> Map.Map Span [Ir] -irModuleTrace env = traceIrModule $ getIModule $ cIr env - where - getIModule (Just (imodule, _, _)) = imodule - getIModule Nothing = error "BUG: irModuleTrace: cannot request IR map before desugaring." - --- | This simulates a field in the ClaferEnv that will always recompute the map, --- since the IR always changes and the map becomes obsolete --- maps from a UID to an IClafer with the given UID -uidIClaferMap :: ClaferEnv -> UIDIClaferMap -uidIClaferMap env = createUidIClaferMap $ getIModule $ cIr env - where - getIModule (Just (iModule, _, _)) = iModule - getIModule Nothing = error "BUG: uidIClaferMap: cannot request IClafer map before desugaring." - -getAst :: (Monad m) => ClaferT m Module -getAst = do - env <- getEnv - case cAst env of - (Just a) -> return a - _ -> throwErr (ClaferErr "No AST. Did you forget to add fragments or parse?" :: CErr Span) -- Indicates a bug in the Clafer translator. - -getIr :: (Monad m) => ClaferT m (IModule, GEnv, Bool) -getIr = do - env <- getEnv - case cIr env of - (Just i) -> return i - _ -> throwErr (ClaferErr "No IR. Did you forget to compile?" :: CErr Span) -- Indicates a bug in the Clafer translator. - -makeEnv :: ClaferArgs -> ClaferEnv -makeEnv args' = - ClaferEnv - { args = args'' - , modelFrags = [] - , cAst = Nothing - , cIr = Nothing - , frags = [] - , astModuleTrace = Map.empty - , otherTokens = [] - } - where - args'' = if (CVLGraph `elem` (mode args') || - Html `elem` (mode args') || - Graph `elem` (mode args')) - then args'{keep_unused=True} - else args' - --- | Monad for using Clafer. -type ClaferM = ClaferT Identity - --- | Monad Transformer for using Clafer. -type ClaferT m = ExceptT ClaferErrs (StateT ClaferEnv m) - -type ClaferErr = CErr ErrPos -type ClaferErrs = CErrs ErrPos - -type ClaferSErr = CErr Span -type ClaferSErrs = CErrs Span - --- | Possible errors that can occur when using Clafer --- | Generate errors using throwErr/throwErrs: -data CErr p - -- | Generic error - = ClaferErr - { msg :: String - } - -- | Error generated by the parser - | ParseErr - { pos :: p -- ^ Position of the error - , msg :: String - } - -- | Error generated by semantic analysis - | SemanticErr - { pos :: p - , msg :: String - } - deriving Show - --- | Clafer keeps track of multiple errors. -data CErrs p = - ClaferErrs {errs :: [CErr p]} - deriving Show - -data ErrPos = - ErrPos { - -- | The fragment where the error occurred. - fragId :: Int, - -- | Error positions are relative to their fragments. - -- | For example an error at (Pos 2 3) means line 2 column 3 of the fragment, not the entire model. - fragPos :: Pos, - -- | The error position relative to the model. - modelPos :: Pos - } - deriving Show - - --- | The full ErrPos requires lots of information that needs to be consistent. Every time we throw an error, --- | we need BOTH the (fragId, fragPos) AND modelPos. This makes it easier for developers using ClaferT so they --- | only need to provide part of the information and the rest is automatically calculated. The code using --- | ClaferT is more concise and less error-prone. --- | --- | modelPos <- modelPosFromFragPos fragdId fragPos --- | throwErr $ ParserErr (ErrPos fragId fragPos modelPos) --- | --- | vs --- | --- | throwErr $ ParseErr (ErrFragPos fragId fragPos) --- | --- | Hopefully making the error handling easier will make it more universal. -data PartialErrPos = - -- | Position relative to the start of the fragment. Will calculate model position automatically. - -- | fragId starts at 0 - -- | The position is relative to the start of the fragment. - ErrFragPos { - pFragId :: Int, - pFragPos :: Pos - } | - ErrFragSpan { - pFragId :: Int, - pFragSpan :: Span - } | - -- | Position relative to the start of the complete model. Will calculate fragId and fragPos automatically. - -- | The position is relative to the entire complete model. - ErrModelPos { - pModelPos :: Pos - } - | - ErrModelSpan { - pModelSpan :: Span - } - deriving Show - -class ClaferErrPos p where - toErrPos :: Monad m => p -> ClaferT m ErrPos - -instance ClaferErrPos Span where - toErrPos = toErrPos . ErrModelSpan - -instance ClaferErrPos ErrPos where - toErrPos = return . id - -instance ClaferErrPos PartialErrPos where - toErrPos (ErrFragPos frgId frgPos) = - do - f <- getsEnv frags - let pos' = ((Pos 1 1 : f) !! frgId) `addPos` frgPos - return $ ErrPos frgId frgPos pos' - toErrPos (ErrFragSpan frgId (Span frgPos _)) = toErrPos $ ErrFragPos frgId frgPos - toErrPos (ErrModelPos modelPos') = - do - f <- getsEnv frags - let fragSpans = zipWith Span (Pos 1 1 : f) f - case findFrag modelPos' fragSpans of - Just (frgId, Span fragStart _) -> return $ ErrPos frgId (modelPos' `minusPos` fragStart) modelPos' - Nothing -> return $ ErrPos 1 noPos noPos -- error $ show modelPos' ++ " not within any frag spans: " ++ show fragSpans -- Indicates a bug in the Clafer translator - where - findFrag pos'' spans = - find (inSpan pos'' . snd) (zip [0..] spans) - toErrPos (ErrModelSpan (Span modelPos'' _)) = toErrPos $ ErrModelPos modelPos'' - -class Throwable t where - toErr :: t -> Monad m => ClaferT m ClaferErr - -instance ClaferErrPos p => Throwable (CErr p) where - toErr (ClaferErr mesg) = return $ ClaferErr mesg - toErr err = - do - pos' <- toErrPos $ pos err - return $ err{pos = pos'} - --- | Throw many errors. -throwErrs :: (Monad m, Throwable t) => [t] -> ClaferT m a -throwErrs throws = - do - errors <- mapM toErr throws - throwError $ ClaferErrs errors - --- | Throw one error. -throwErr :: (Monad m, Throwable t) => t -> ClaferT m a -throwErr throw = throwErrs [throw] - --- | Catch errors -catchErrs :: Monad m => ClaferT m a -> ([ClaferErr] -> ClaferT m a) -> ClaferT m a -catchErrs e h = e `catchError` (h . errs) - -addPos :: Pos -> Pos -> Pos -addPos (Pos l c) (Pos 1 d) = Pos l (c + d - 1) -- Same line -addPos (Pos l _) (Pos m d) = Pos (l + m - 1) d -- Different line -minusPos :: Pos -> Pos -> Pos -minusPos (Pos l c) (Pos 1 d) = Pos l (c - d + 1) -- Same line -minusPos (Pos l c) (Pos m _) = Pos (l - m + 1) c -- Different line - -inSpan :: Pos -> Span -> Bool -inSpan pos' (Span start end) = pos' >= start && pos' <= end - --- | Get the ClaferEnv -getEnv :: Monad m => ClaferT m ClaferEnv -getEnv = get - -getsEnv :: Monad m => (ClaferEnv -> a) -> ClaferT m a -getsEnv = gets - --- | Modify the ClaferEnv -modifyEnv :: Monad m => (ClaferEnv -> ClaferEnv) -> ClaferT m () -modifyEnv = modify - --- | Set the ClaferEnv. Remember to set the env after every change. -putEnv :: Monad m => ClaferEnv -> ClaferT m () -putEnv = put - --- | Uses the ErrorT convention: --- | Left is for error (a string containing the error message) --- | Right is for success (with the result) -runClaferT :: Monad m => ClaferArgs -> ClaferT m a -> m (Either [ClaferErr] a) -runClaferT args' exec = - mapLeft errs `liftM` evalStateT (runExceptT exec) (makeEnv args') - where - mapLeft :: (a -> c) -> Either a b -> Either c b - mapLeft f (Left l) = Left (f l) - mapLeft _ (Right r) = Right r - --- | Convenience -runClafer :: ClaferArgs -> ClaferM a -> Either [ClaferErr] a -runClafer args' = runIdentity . runClaferT args' +{-# LANGUAGE RankNTypes #-}+{-+ Copyright (C) 2012-2015 Kacper Bak, Jimmy Liang, Michal Antkiewicz <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}++{- |+This is in a separate module from the module "Language.Clafer" so that other modules that require+ClaferEnv can just import this module without all the parsing/compiline/generating functionality.+ -}+module Language.ClaferT+ ( ClaferEnv(..)+ , irModuleTrace+ , uidIClaferMap+ , makeEnv+ , getAst+ , getIr+ , ClaferM+ , ClaferT+ , CErr(..)+ , CErrs(..)+ , ClaferErr+ , ClaferErrs+ , ClaferSErr+ , ClaferSErrs+ , ErrPos(..)+ , PartialErrPos(..)+ , throwErrs+ , throwErr+ , catchErrs+ , getEnv+ , getsEnv+ , modifyEnv+ , putEnv+ , runClafer+ , runClaferT+ , Throwable(..)+ , Span(..)+ , Pos(..)+ ) where++import Control.Monad.Except+import Control.Monad.Identity+import Control.Monad.State+import Data.List+import qualified Data.Map as Map++import Language.Clafer.ClaferArgs+import Language.Clafer.Common+import Language.Clafer.Front.AbsClafer+import Language.Clafer.Front.LexClafer+import Language.Clafer.Intermediate.Intclafer+import Language.Clafer.Intermediate.Tracing++{-+ - Examples.+ -+ - If you need ClaferEnv:+ - runClafer args $+ - do+ - env <- getEnv+ - env' = ...+ - putEnv env'+ -+ - Remember to putEnv if you do any modification to the ClaferEnv or else your updates+ - are lost!+ -+ -+ - Throwing errors:+ -+ - throwErr $ ParseErr (ErrFragPos fragId fragPos) "failed parsing"+ - throwErr $ ParseErr (ErrModelPos modelPos) "failed parsing"+ -+ - There is two ways of defining the position of the error. Either define the position+ - relative to a fragment, or relative to the model. Pick the one that is convenient.+ - Once thrown, the "partial" positions will be automatically updated to contain both+ - the model and fragment positions.+ - Use throwErrs to throw multiple errors.+ - Use catchErrs to catch errors (usually not needed).+ -+ -}++data ClaferEnv+ = ClaferEnv+ { args :: ClaferArgs+ , modelFrags :: [String] -- original text of the model fragments+ , cAst :: Maybe Module+ , cIr :: Maybe (IModule, GEnv, Bool)+ , frags :: [Pos] -- line numbers of fragment markers+ , astModuleTrace :: Map.Map Span [Ast] -- can keep the Ast map since it never changes+ , otherTokens :: [Token] -- non-parseable tokens: comments and escape blocks+ } deriving Show++-- | This simulates a field in the ClaferEnv that will always recompute the map,+-- since the IR always changes and the map becomes obsolete+irModuleTrace :: ClaferEnv -> Map.Map Span [Ir]+irModuleTrace env = traceIrModule $ getIModule $ cIr env+ where+ getIModule (Just (imodule, _, _)) = imodule+ getIModule Nothing = error "BUG: irModuleTrace: cannot request IR map before desugaring."++-- | This simulates a field in the ClaferEnv that will always recompute the map,+-- since the IR always changes and the map becomes obsolete+-- maps from a UID to an IClafer with the given UID+uidIClaferMap :: ClaferEnv -> UIDIClaferMap+uidIClaferMap env = createUidIClaferMap $ getIModule $ cIr env+ where+ getIModule (Just (iModule, _, _)) = iModule+ getIModule Nothing = error "BUG: uidIClaferMap: cannot request IClafer map before desugaring."++getAst :: (Monad m) => ClaferT m Module+getAst = do+ env <- getEnv+ case cAst env of+ (Just a) -> return a+ _ -> throwErr (ClaferErr "No AST. Did you forget to add fragments or parse?" :: CErr Span) -- Indicates a bug in the Clafer translator.++getIr :: (Monad m) => ClaferT m (IModule, GEnv, Bool)+getIr = do+ env <- getEnv+ case cIr env of+ (Just i) -> return i+ _ -> throwErr (ClaferErr "No IR. Did you forget to compile?" :: CErr Span) -- Indicates a bug in the Clafer translator.++makeEnv :: ClaferArgs -> ClaferEnv+makeEnv args' =+ ClaferEnv+ { args = args''+ , modelFrags = []+ , cAst = Nothing+ , cIr = Nothing+ , frags = []+ , astModuleTrace = Map.empty+ , otherTokens = []+ }+ where+ args'' = if (CVLGraph `elem` (mode args') ||+ Html `elem` (mode args') ||+ Graph `elem` (mode args'))+ then args'{keep_unused=True}+ else args'++-- | Monad for using Clafer.+type ClaferM = ClaferT Identity++-- | Monad Transformer for using Clafer.+type ClaferT m = ExceptT ClaferErrs (StateT ClaferEnv m)++type ClaferErr = CErr ErrPos+type ClaferErrs = CErrs ErrPos++type ClaferSErr = CErr Span+type ClaferSErrs = CErrs Span++-- | Possible errors that can occur when using Clafer+-- | Generate errors using throwErr/throwErrs:+data CErr p+ -- | Generic error+ = ClaferErr+ { msg :: String+ }+ -- | Error generated by the parser+ | ParseErr+ { pos :: p -- ^ Position of the error+ , msg :: String+ }+ -- | Error generated by semantic analysis+ | SemanticErr+ { pos :: p+ , msg :: String+ }+ deriving Show++-- | Clafer keeps track of multiple errors.+data CErrs p =+ ClaferErrs {errs :: [CErr p]}+ deriving Show++data ErrPos =+ ErrPos {+ -- | The fragment where the error occurred.+ fragId :: Int,+ -- | Error positions are relative to their fragments.+ -- | For example an error at (Pos 2 3) means line 2 column 3 of the fragment, not the entire model.+ fragPos :: Pos,+ -- | The error position relative to the model.+ modelPos :: Pos+ }+ deriving Show+++-- | The full ErrPos requires lots of information that needs to be consistent. Every time we throw an error,+-- | we need BOTH the (fragId, fragPos) AND modelPos. This makes it easier for developers using ClaferT so they+-- | only need to provide part of the information and the rest is automatically calculated. The code using+-- | ClaferT is more concise and less error-prone.+-- |+-- | modelPos <- modelPosFromFragPos fragdId fragPos+-- | throwErr $ ParserErr (ErrPos fragId fragPos modelPos)+-- |+-- | vs+-- |+-- | throwErr $ ParseErr (ErrFragPos fragId fragPos)+-- |+-- | Hopefully making the error handling easier will make it more universal.+data PartialErrPos =+ -- | Position relative to the start of the fragment. Will calculate model position automatically.+ -- | fragId starts at 0+ -- | The position is relative to the start of the fragment.+ ErrFragPos {+ pFragId :: Int,+ pFragPos :: Pos+ } |+ ErrFragSpan {+ pFragId :: Int,+ pFragSpan :: Span+ } |+ -- | Position relative to the start of the complete model. Will calculate fragId and fragPos automatically.+ -- | The position is relative to the entire complete model.+ ErrModelPos {+ pModelPos :: Pos+ }+ |+ ErrModelSpan {+ pModelSpan :: Span+ }+ deriving Show++class ClaferErrPos p where+ toErrPos :: Monad m => p -> ClaferT m ErrPos++instance ClaferErrPos Span where+ toErrPos = toErrPos . ErrModelSpan++instance ClaferErrPos ErrPos where+ toErrPos = return . id++instance ClaferErrPos PartialErrPos where+ toErrPos (ErrFragPos frgId frgPos) =+ do+ f <- getsEnv frags+ let pos' = ((Pos 1 1 : f) !! frgId) `addPos` frgPos+ return $ ErrPos frgId frgPos pos'+ toErrPos (ErrFragSpan frgId (Span frgPos _)) = toErrPos $ ErrFragPos frgId frgPos+ toErrPos (ErrModelPos modelPos') =+ do+ f <- getsEnv frags+ let fragSpans = zipWith Span (Pos 1 1 : f) f+ case findFrag modelPos' fragSpans of+ Just (frgId, Span fragStart _) -> return $ ErrPos frgId (modelPos' `minusPos` fragStart) modelPos'+ Nothing -> return $ ErrPos 1 noPos noPos -- error $ show modelPos' ++ " not within any frag spans: " ++ show fragSpans -- Indicates a bug in the Clafer translator+ where+ findFrag pos'' spans =+ find (inSpan pos'' . snd) (zip [0..] spans)+ toErrPos (ErrModelSpan (Span modelPos'' _)) = toErrPos $ ErrModelPos modelPos''++class Throwable t where+ toErr :: t -> Monad m => ClaferT m ClaferErr++instance ClaferErrPos p => Throwable (CErr p) where+ toErr (ClaferErr mesg) = return $ ClaferErr mesg+ toErr err =+ do+ pos' <- toErrPos $ pos err+ return $ err{pos = pos'}++-- | Throw many errors.+throwErrs :: (Monad m, Throwable t) => [t] -> ClaferT m a+throwErrs throws =+ do+ errors <- mapM toErr throws+ throwError $ ClaferErrs errors++-- | Throw one error.+throwErr :: (Monad m, Throwable t) => t -> ClaferT m a+throwErr throw = throwErrs [throw]++-- | Catch errors+catchErrs :: Monad m => ClaferT m a -> ([ClaferErr] -> ClaferT m a) -> ClaferT m a+catchErrs e h = e `catchError` (h . errs)++addPos :: Pos -> Pos -> Pos+addPos (Pos l c) (Pos 1 d) = Pos l (c + d - 1) -- Same line+addPos (Pos l _) (Pos m d) = Pos (l + m - 1) d -- Different line+minusPos :: Pos -> Pos -> Pos+minusPos (Pos l c) (Pos 1 d) = Pos l (c - d + 1) -- Same line+minusPos (Pos l c) (Pos m _) = Pos (l - m + 1) c -- Different line++inSpan :: Pos -> Span -> Bool+inSpan pos' (Span start end) = pos' >= start && pos' <= end++-- | Get the ClaferEnv+getEnv :: Monad m => ClaferT m ClaferEnv+getEnv = get++getsEnv :: Monad m => (ClaferEnv -> a) -> ClaferT m a+getsEnv = gets++-- | Modify the ClaferEnv+modifyEnv :: Monad m => (ClaferEnv -> ClaferEnv) -> ClaferT m ()+modifyEnv = modify++-- | Set the ClaferEnv. Remember to set the env after every change.+putEnv :: Monad m => ClaferEnv -> ClaferT m ()+putEnv = put++-- | Uses the ErrorT convention:+-- | Left is for error (a string containing the error message)+-- | Right is for success (with the result)+runClaferT :: Monad m => ClaferArgs -> ClaferT m a -> m (Either [ClaferErr] a)+runClaferT args' exec =+ mapLeft errs `liftM` evalStateT (runExceptT exec) (makeEnv args')+ where+ mapLeft :: (a -> c) -> Either a b -> Either c b+ mapLeft f (Left l) = Left (f l)+ mapLeft _ (Right r) = Right r++-- | Convenience+runClafer :: ClaferArgs -> ClaferM a -> Either [ClaferErr] a+runClafer args' = runIdentity . runClaferT args'
stack.yaml view
@@ -1,10 +1,13 @@-# for GHC-7.10.2 -extra-deps: [ data-stringmap-1.0.1.1 ] -resolver: lts-3.19 +# for GHC-8.0.1 +extra-deps: + - data-stringmap-1.0.1.1 + - json-builder-0.3 +resolver: nightly-2016-06-21 -# for GHC-7.8.4 -# extra-deps: [ data-stringmap-1.0.1.1, json-builder-0.3 ] -# resolver: lts-2.22 +# for GHC-7.10.3 +# extra-deps: +# - data-stringmap-1.0.1.1 +# resolver: lts-6.4 flags: {} packages:
test/Functions.hs view
@@ -1,72 +1,72 @@-{- - Copyright (C) 2013-2015 Luke Brown, Michal Antkiewicz <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -module Functions where - -import qualified Data.List as List -import qualified Data.Map as Map -import Language.Clafer -import System.Directory - -getClafers :: FilePath -> IO [(String, String)] -getClafers dir = do - files <- getDirectoryContents dir - let claferFiles = List.filter checkClaferExt files - claferModels <- mapM (\x -> readFile (dir++"/"++x)) claferFiles - return $ zip claferFiles claferModels - -checkClaferExt :: String -> Bool -checkClaferExt "des.cfr" = True -checkClaferExt file' = if ((eman == "")) then False else (txe == "rfc") && (takeWhile (/='.') (tail eman) /= "esd") - where (txe, eman) = span (/='.') (reverse file') - - -compileOneFragment :: ClaferArgs -> InputModel -> Either [ClaferErr] (Map.Map ClaferMode CompilerResult) -compileOneFragment args' model = - runClafer (argsWithOPTIONS args' model) $ - do - addModuleFragment model - parse - iModule <- desugar Nothing - compile iModule - generate - -getCompilerResult :: InputModel -> CompilerResult -getCompilerResult model = case compileOneFragment defaultClaferArgs{keep_unused=True} model of - Left errors -> error $ show errors - Right compilerResultMap -> case Map.lookup Alloy compilerResultMap of - Nothing -> error "No Alloy result in the result map" - Just compilerResult -> compilerResult - -compiledCheck :: Either a b -> Bool -compiledCheck (Left _) = False -compiledCheck (Right _) = True - -fromLeft :: Either a b -> a -fromLeft (Left a) = a -fromLeft (Right _) = error "Function fromLeft expects argument of the form 'Left a'" - -fromRight :: Either a b -> b -fromRight (Right b) = b -fromRight (Left _) = error "Function fromLeft expects argument of the form 'Right b'" - -andMap :: (a -> Bool) -> [a] -> Bool -andMap f lst = and $ map f lst +{-+ Copyright (C) 2013-2015 Luke Brown, Michal Antkiewicz <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+module Functions where++import qualified Data.List as List+import qualified Data.Map as Map+import Language.Clafer+import System.Directory++getClafers :: FilePath -> IO [(String, String)]+getClafers dir = do+ files <- getDirectoryContents dir+ let claferFiles = List.filter checkClaferExt files+ claferModels <- mapM (\x -> readFile (dir++"/"++x)) claferFiles+ return $ zip claferFiles claferModels++checkClaferExt :: String -> Bool+checkClaferExt "des.cfr" = True+checkClaferExt file' = if ((eman == "")) then False else (txe == "rfc") && (takeWhile (/='.') (tail eman) /= "esd")+ where (txe, eman) = span (/='.') (reverse file')+++compileOneFragment :: ClaferArgs -> InputModel -> Either [ClaferErr] (Map.Map ClaferMode CompilerResult)+compileOneFragment args' model =+ runClafer (argsWithOPTIONS args' model) $+ do+ addModuleFragment model+ parse+ iModule <- desugar Nothing+ compile iModule+ generate++getCompilerResult :: InputModel -> CompilerResult+getCompilerResult model = case compileOneFragment defaultClaferArgs{keep_unused=True} model of+ Left errors -> error $ show errors+ Right compilerResultMap -> case Map.lookup Alloy compilerResultMap of+ Nothing -> error "No Alloy result in the result map"+ Just compilerResult -> compilerResult++compiledCheck :: Either a b -> Bool+compiledCheck (Left _) = False+compiledCheck (Right _) = True++fromLeft :: Either a b -> a+fromLeft (Left a) = a+fromLeft (Right _) = error "Function fromLeft expects argument of the form 'Left a'"++fromRight :: Either a b -> b+fromRight (Right b) = b+fromRight (Left _) = error "Function fromLeft expects argument of the form 'Right b'"++andMap :: (a -> Bool) -> [a] -> Bool+andMap f lst = and $ map f lst
test/Suite/Negative.hs view
@@ -1,53 +1,53 @@-{-# LANGUAGE TemplateHaskell #-} -{- - Copyright (C) 2013 Luke Brown <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -module Suite.Negative (tg_Test_Suite_Negative) where - -import Functions -import Control.Monad -import Test.Tasty -import Test.Tasty.HUnit -import Test.Tasty.TH -import Language.Clafer.ClaferArgs - -tg_Test_Suite_Negative :: TestTree -tg_Test_Suite_Negative = $(testGroupGenerator) - -negativeClaferModels :: IO [([Char], String)] -negativeClaferModels = do - claferModels <- getClafers "test/negative" - return $ filter ((`notElem` crashModels) . fst ) claferModels - where - crashModels = ["i127-loop.cfr", "i141-constraints.cfr"] -{-Put models in the list above that completly crash - the compiler, this will avoid crashing the test suite - Note: If the model is giving an unexpected error it - should be located in failing/negative not here!-} - -case_failTest :: Assertion -case_failTest = do - claferModels <- negativeClaferModels - let compiledClafers = map (\(file', model) -> (file', compileOneFragment defaultClaferArgs model)) claferModels - forM_ compiledClafers (\(file', compiled) -> - when (compiledCheck compiled) $ putStrLn (file' ++ " compiled when it should not have.")) - (andMap (not . compiledCheck . snd) compiledClafers - @? "test/negative fail: The above clafer models compiled.") +{-# LANGUAGE TemplateHaskell #-}+{-+ Copyright (C) 2013 Luke Brown <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+module Suite.Negative (tg_Test_Suite_Negative) where++import Functions+import Control.Monad+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.TH+import Language.Clafer.ClaferArgs++tg_Test_Suite_Negative :: TestTree+tg_Test_Suite_Negative = $(testGroupGenerator)++negativeClaferModels :: IO [([Char], String)]+negativeClaferModels = do+ claferModels <- getClafers "test/negative"+ return $ filter ((`notElem` crashModels) . fst ) claferModels+ where+ crashModels = ["i127-loop.cfr", "i141-constraints.cfr"]+{-Put models in the list above that completly crash+ the compiler, this will avoid crashing the test suite+ Note: If the model is giving an unexpected error it+ should be located in failing/negative not here!-}++case_failTest :: Assertion+case_failTest = do+ claferModels <- negativeClaferModels+ let compiledClafers = map (\(file', model) -> (file', compileOneFragment defaultClaferArgs model)) claferModels+ forM_ compiledClafers (\(file', compiled) ->+ when (compiledCheck compiled) $ putStrLn (file' ++ " compiled when it should not have."))+ (andMap (not . compiledCheck . snd) compiledClafers+ @? "test/negative fail: The above clafer models compiled.")
test/Suite/Positive.hs view
@@ -1,83 +1,83 @@-{-# LANGUAGE TemplateHaskell #-} -{- - Copyright (C) 2013 Luke Brown <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -module Suite.Positive (tg_Test_Suite_Positive) where - -import Functions -import Language.Clafer.Intermediate.Intclafer -import Data.Foldable hiding (forM_) -import Data.Maybe -import Control.Monad -import Language.Clafer -import Language.ClaferT -import Test.Tasty -import Test.Tasty.HUnit -import Test.Tasty.TH -import qualified Data.Map as Map -import Prelude - -tg_Test_Suite_Positive :: TestTree -tg_Test_Suite_Positive = $(testGroupGenerator) - -positiveClaferModels :: IO [(String, String)] -positiveClaferModels = getClafers "test/positive" - -case_compileTest :: Assertion -case_compileTest = do - claferModels <- positiveClaferModels - let compiledClafers = map (\(file', model) -> (file', compileOneFragment defaultClaferArgs{keep_unused = True} model)) claferModels - forM_ compiledClafers (\(file', compiled) -> - when (not $ compiledCheck compiled) $ putStrLn (file' ++ " Error: " ++ (show $ fromLeft compiled))) - (andMap (compiledCheck . snd) compiledClafers - @? "test/positive fail: The above claferModels did not compile.") - -case_reference_Unused_Abstract_Clafer :: Assertion -case_reference_Unused_Abstract_Clafer = do - model <- readFile "test/positive/i235.cfr" - let compiledClafers = [("None", compileOneFragment defaultClaferArgs{scope_strategy = None} model), ("Simple", compileOneFragment defaultClaferArgs{scope_strategy = Simple} model)] - forM_ compiledClafers (\(ss, compiled) -> - when (not $ compiledCheck compiled) $ putStrLn ("i235.cfr failed for scope_strategy = " ++ ss)) - (andMap (compiledCheck . snd) compiledClafers - @? "reference_Unused_Abstract_Clafer (i235) failed, error for referencing unused abstract clafer") - -case_nonempty_cards :: Assertion -case_nonempty_cards = do - claferModels <- positiveClaferModels - let compiledClafeIrs = foldMap getIR $ map (\(file', model) -> (file', compileOneFragment defaultClaferArgs{keep_unused = True} model)) claferModels - forM_ compiledClafeIrs (\(file', ir') -> - let emptys = foldMapIR isEmptyCard ir' - in when (emptys /= []) $ putStrLn (file' ++ " Error: Contains empty cardinalities after analysis at\n" ++ emptys)) - (andMap ((==[]) . foldMapIR isEmptyCard . snd) compiledClafeIrs - @? "nonempty card test failed. Files contain empty cardinalities after fully compiling") - where - getIR (file', (Right (resultMap))) = - case Map.lookup Alloy resultMap of - Just CompilerResult{claferEnv = ClaferEnv{cIr = Just (iMod, _, _)}} -> [(file', iMod)] - _ -> [] - getIR (_, _) = [] - isEmptyCard (IRClafer (IClafer{_cinPos=(Span (Pos l c) _), _card = Nothing})) = "Line " ++ show l ++ " column " ++ show c ++ "\n" - isEmptyCard _ = "" - -case_stringEqual :: Assertion -case_stringEqual = do - let strMap = stringMap $ fromJust $ Map.lookup Alloy $ fromRight $ compileOneFragment defaultClaferArgs "A\n text1 -> string = \"some text\"\n text2 -> string = \"some text\"" - (Map.size strMap) == 1 @? "Error: same string assigned to differnet numbers!" +{-# LANGUAGE TemplateHaskell #-}+{-+ Copyright (C) 2013 Luke Brown <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+module Suite.Positive (tg_Test_Suite_Positive) where++import Functions+import Language.Clafer.Intermediate.Intclafer+import Data.Foldable hiding (forM_)+import Data.Maybe+import Control.Monad+import Language.Clafer+import Language.ClaferT+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.TH+import qualified Data.Map as Map+import Prelude++tg_Test_Suite_Positive :: TestTree+tg_Test_Suite_Positive = $(testGroupGenerator)++positiveClaferModels :: IO [(String, String)]+positiveClaferModels = getClafers "test/positive"++case_compileTest :: Assertion+case_compileTest = do+ claferModels <- positiveClaferModels+ let compiledClafers = map (\(file', model) -> (file', compileOneFragment defaultClaferArgs{keep_unused = True} model)) claferModels+ forM_ compiledClafers (\(file', compiled) ->+ when (not $ compiledCheck compiled) $ putStrLn (file' ++ " Error: " ++ (show $ fromLeft compiled)))+ (andMap (compiledCheck . snd) compiledClafers+ @? "test/positive fail: The above claferModels did not compile.")++case_reference_Unused_Abstract_Clafer :: Assertion+case_reference_Unused_Abstract_Clafer = do+ model <- readFile "test/positive/i235.cfr"+ let compiledClafers = [("None", compileOneFragment defaultClaferArgs{scope_strategy = None} model), ("Simple", compileOneFragment defaultClaferArgs{scope_strategy = Simple} model)]+ forM_ compiledClafers (\(ss, compiled) ->+ when (not $ compiledCheck compiled) $ putStrLn ("i235.cfr failed for scope_strategy = " ++ ss))+ (andMap (compiledCheck . snd) compiledClafers+ @? "reference_Unused_Abstract_Clafer (i235) failed, error for referencing unused abstract clafer")++case_nonempty_cards :: Assertion+case_nonempty_cards = do+ claferModels <- positiveClaferModels+ let compiledClafeIrs = foldMap getIR $ map (\(file', model) -> (file', compileOneFragment defaultClaferArgs{keep_unused = True} model)) claferModels+ forM_ compiledClafeIrs (\(file', ir') ->+ let emptys = foldMapIR isEmptyCard ir'+ in when (emptys /= []) $ putStrLn (file' ++ " Error: Contains empty cardinalities after analysis at\n" ++ emptys))+ (andMap ((==[]) . foldMapIR isEmptyCard . snd) compiledClafeIrs+ @? "nonempty card test failed. Files contain empty cardinalities after fully compiling")+ where+ getIR (file', (Right (resultMap))) =+ case Map.lookup Alloy resultMap of+ Just CompilerResult{claferEnv = ClaferEnv{cIr = Just (iMod, _, _)}} -> [(file', iMod)]+ _ -> []+ getIR (_, _) = []+ isEmptyCard (IRClafer (IClafer{_cinPos=(Span (Pos l c) _), _card = Nothing})) = "Line " ++ show l ++ " column " ++ show c ++ "\n"+ isEmptyCard _ = ""++case_stringEqual :: Assertion+case_stringEqual = do+ let strMap = stringMap $ fromJust $ Map.lookup Alloy $ fromRight $ compileOneFragment defaultClaferArgs "A\n text1 -> string = \"some text\"\n text2 -> string = \"some text\""+ (Map.size strMap) == 1 @? "Error: same string assigned to differnet numbers!"
test/Suite/Redefinition.hs view
@@ -1,170 +1,170 @@-{-# LANGUAGE TemplateHaskell #-} -{- - Copyright (C) 2013 Luke Brown <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -module Suite.Redefinition (tg_Test_Suite_Redefinition) where - -import Language.Clafer -import Language.ClaferT -import Language.Clafer.Common -import Language.Clafer.Intermediate.Intclafer - -import Functions - -import Control.Applicative -import qualified Data.Map as M -import Data.Maybe (isNothing, isJust, fromJust) -import Data.StringMap -import Test.Tasty -import Test.Tasty.HUnit -import Test.Tasty.TH -import Prelude - -tg_Test_Suite_Redefinition :: TestTree -tg_Test_Suite_Redefinition = $(testGroupGenerator) - -model :: String -model = unlines - [ "abstract Component" - , " abstract InPort ->> Signal" - , " abstract OutPort ->> Signal" - , "abstract Signal" - , "abstract Command : Signal" - , "abstract MotorCommand : Command" - , "abstract Request : Signal" - , "stop : Request" - , "abstract Controller : Component" - , " abstract req : InPort -> Request ?" -- bag to set and cardinality refinement - , " down : Request" - , "WinController : Controller" - , " req : req -> stop" -- redefinition and cardinality refinement - , " cmd : OutPort -> MotorCommand" -- nested inheritance which requires inheritance hierarchy traversal - -- |> Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> |> - , " powerDown : Exception" - , "abstract Exception : OutPort" - -- <| Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> <| - ] - -case_NestedInheritanceMatchTest :: Assertion -case_NestedInheritanceMatchTest = case compileOneFragment defaultClaferArgs model of - Left errors -> assertFailure $ show errors - Right compilerResultMap -> case M.lookup Alloy compilerResultMap of - Nothing -> assertFailure "No Alloy result in the result map" - Just compilerResult -> let - uidIClaferMap' :: StringMap IClafer - uidIClaferMap' = uidIClaferMap $ claferEnv compilerResult - c0_req = fromJust $ findIClafer uidIClaferMap' "c0_req" - c0_req_match = matchNestedInheritance uidIClaferMap' c0_req - c1_req = fromJust $ findIClafer uidIClaferMap' "c1_req" - c1_req_match = matchNestedInheritance uidIClaferMap' c1_req - c0_cmd = fromJust $ findIClafer uidIClaferMap' "c0_cmd" - c0_cmd_match = matchNestedInheritance uidIClaferMap' c0_cmd - c0_Component = fromJust $ findIClafer uidIClaferMap' "c0_Component" - c0_Component_match = matchNestedInheritance uidIClaferMap' c0_Component - c0_InPort = fromJust $ findIClafer uidIClaferMap' "c0_InPort" - c0_InPort_match = matchNestedInheritance uidIClaferMap' c0_InPort - c0_WinController = fromJust $ findIClafer uidIClaferMap' "c0_WinController" - c0_WinController_match = matchNestedInheritance uidIClaferMap' c0_WinController - c0_down = fromJust $ findIClafer uidIClaferMap' "c0_down" - c0_down_match = matchNestedInheritance uidIClaferMap' c0_down - c0_Exception = fromJust $ findIClafer uidIClaferMap' "c0_Exception" - c0_Exception_match = matchNestedInheritance uidIClaferMap' c0_Exception - c0_powerDown = fromJust $ findIClafer uidIClaferMap' "c0_powerDown" - c0_powerDown_match = matchNestedInheritance uidIClaferMap' c0_powerDown - {-c0_Alice = fromJust $ findIClafer uidIClaferMap' "c0_Alice" - c0_Alice_match = matchNestedInheritance uidIClaferMap' c0_Alice - c0_Bob = fromJust $ findIClafer uidIClaferMap' "c0_Bob" - c0_Bob_match = matchNestedInheritance uidIClaferMap' c0_Bob-} - in do - isJust c0_req_match @? ("NestedInheritanceMatch not found for " ++ show c0_req) - isProperNesting uidIClaferMap' (c0_req_match) @? ("Improper nesting for " ++ show c0_req) - (True, True, True) == isProperRefinement uidIClaferMap' (c0_req_match) @? ("Improper refinement for " ++ show c0_req) - (not $ isRedefinition (c0_req_match)) @? ("Improper redefinition for " ++ show c0_req) - - isJust c1_req_match @? ("NestedInheritanceMatch not found for " ++ show c1_req) - isProperNesting uidIClaferMap' (c1_req_match) @? ("Improper nesting for " ++ show c1_req) - (True, True, True) == isProperRefinement uidIClaferMap' (c1_req_match) @? ("Improper refinement for " ++ show c1_req) - isRedefinition (c1_req_match) @? ("Improper redefinition for " ++ show c1_req) - - isJust c0_cmd_match @? ("NestedInheritanceMatch not found for " ++ show c0_cmd) - isProperNesting uidIClaferMap' (c0_cmd_match) @? ("Improper nesting for " ++ show c0_cmd) - (True, True, True) == isProperRefinement uidIClaferMap' (c0_cmd_match) @? ("Improper refinement for " ++ show c0_cmd) - (not $ isRedefinition (c0_cmd_match)) @? ("Improper redefinition for " ++ show c0_cmd) - - isNothing c0_Component_match @? ("Non-existing match found for " ++ show c0_Component) - isNothing c0_InPort_match @? ("Non-existing match found for " ++ show c0_InPort) - - isJust c0_WinController_match @? ("NestedInheritanceMatch not found for" ++ show c0_WinController) - - isJust c0_down_match @? ("NestedInheritanceMatch not found for" ++ show c0_down) - (isProperNesting uidIClaferMap' (c0_down_match)) @? ("Improper nesting for " ++ show c0_down) - (True, True, True) == (isProperRefinement uidIClaferMap' (c0_down_match)) @? ("Improper refinement for " ++ show c0_down) - (not $ isRedefinition (c0_down_match)) @? ("Improper redefinition for " ++ show c0_down) - - isJust c0_powerDown_match @? ("NestedInheritanceMatch not found for" ++ show c0_powerDown) - (isProperNesting uidIClaferMap' (c0_powerDown_match)) @? ("Improper nesting for " ++ show c0_powerDown) - - (not $ isTopLevel c0_Exception) @? ("isTopLevel c0_Exception must return False") - _parentUID c0_Exception == "c0_Component" @? ("Parent of c0_Exception should be c0_Component but it is " ++ _parentUID c0_Exception) - (_uid <$> _parentClafer <$> c0_Exception_match) == (Just "c0_Component") @? ("_parentClafer of c0_Exception should be c0_Component in the match") - {- isJust c0_Alice_match @? ("NestedInheritanceMatch not found for " ++ show c0_Alice) - isProperNesting uidIClaferMap' (c0_Alice_match) @? ("Improper nesting for " ++ show c0_Alice) - (False, False, True) == (isProperRefinement uidIClaferMap' (c0_Alice_match)) @? ("Improper refinement for " ++ show c0_Alice) - (not $ isRedefinition (c0_Alice_match)) @? ("Improper redefinition for " ++ show c0_Alice) - - isJust c0_Bob_match @? ("NestedInheritanceMatch not found for " ++ show c0_Bob) - isProperNesting uidIClaferMap' (c0_Bob_match) @? ("Improper nesting for " ++ show c0_Bob) - (True, True, True) == (isProperRefinement uidIClaferMap' (c0_Bob_match)) @? ("Improper refinement for " ++ show c0_Bob) - (not $ isRedefinition (c0_Bob_match)) @? ("Improper redefinition for " ++ show c0_Bob)-} - -model2 :: String -model2 = unlines - [ "abstract Person -> Bob 0..2" - , "Alice : Person -> Bob 3" -- Improper cardinality refinement for clafer 'Alice' on line 2 column 1 - , "Bob : Person ->> Person" -- Improper bag to set refinement for clafer 'Bob' on line 3 column 1 - , "Carol : Person -> Person 2" -- Improper target subtyping for clafer 'Carol' on line 4 column 1 - ] - - -case_NestedInheritanceFailTest :: Assertion -case_NestedInheritanceFailTest = case compileOneFragment defaultClaferArgs model2 of - Left errors -> (show errors) == correctErrMsg @? "Incorrect error message:\nGot:\n" ++ show errors ++ "\nExpected:\n" ++ correctErrMsg - Right _ -> assertFailure "The model2 is not expected to compile." - where - correctErrMsg = "[SemanticErr {pos = ErrPos {fragId = 1, fragPos = Pos 0 0, modelPos = Pos 0 0}, msg = \"Refinement errors in the following places:\\nImproper cardinality refinement for clafer 'Alice' on line 2 column 1\\nImproper bag to set refinement for clafer 'Bob' on line 3 column 1\\nImproper target subtyping for clafer 'Carol' on line 4 column 1\\n\"}]" - --- |> Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> |> -model3 :: String -model3 = unlines - [ "abstract Component" - , " abstract Port" - , "abstract Exception : Port" - , "powerDown : Exception" -- Improper nesting - ] - - -case_NestedInheritanceFailTest2 :: Assertion -case_NestedInheritanceFailTest2 = case compileOneFragment defaultClaferArgs model3 of - Left errors -> (show errors) == correctErrMsg @? "Incorrect error message:\nGot:\n" ++ show errors ++ "\nExpected:\n" ++ correctErrMsg - Right _ -> assertFailure "The model3 is not expected to compile." - where - correctErrMsg = "[SemanticErr {pos = ErrPos {fragId = 1, fragPos = Pos 0 0, modelPos = Pos 0 0}, msg = \"Refinement errors in the following places:\\nImproperly nested clafer 'powerDown' on line 4 column 1\\n\"}]" --- <| Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> <| +{-# LANGUAGE TemplateHaskell #-}+{-+ Copyright (C) 2013 Luke Brown <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+module Suite.Redefinition (tg_Test_Suite_Redefinition) where++import Language.Clafer+import Language.ClaferT+import Language.Clafer.Common+import Language.Clafer.Intermediate.Intclafer++import Functions++import Control.Applicative+import qualified Data.Map as M+import Data.Maybe (isNothing, isJust, fromJust)+import Data.StringMap+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.TH+import Prelude++tg_Test_Suite_Redefinition :: TestTree+tg_Test_Suite_Redefinition = $(testGroupGenerator)++model :: String+model = unlines+ [ "abstract Component"+ , " abstract InPort ->> Signal"+ , " abstract OutPort ->> Signal"+ , "abstract Signal"+ , "abstract Command : Signal"+ , "abstract MotorCommand : Command"+ , "abstract Request : Signal"+ , "stop : Request"+ , "abstract Controller : Component"+ , " abstract req : InPort -> Request ?" -- bag to set and cardinality refinement+ , " down : Request"+ , "WinController : Controller"+ , " req : req -> stop" -- redefinition and cardinality refinement+ , " cmd : OutPort -> MotorCommand" -- nested inheritance which requires inheritance hierarchy traversal+ -- |> Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> |>+ , " powerDown : Exception"+ , "abstract Exception : OutPort"+ -- <| Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> <|+ ]++case_NestedInheritanceMatchTest :: Assertion+case_NestedInheritanceMatchTest = case compileOneFragment defaultClaferArgs model of+ Left errors -> assertFailure $ show errors+ Right compilerResultMap -> case M.lookup Alloy compilerResultMap of+ Nothing -> assertFailure "No Alloy result in the result map"+ Just compilerResult -> let+ uidIClaferMap' :: StringMap IClafer+ uidIClaferMap' = uidIClaferMap $ claferEnv compilerResult+ c0_req = fromJust $ findIClafer uidIClaferMap' "c0_req"+ c0_req_match = matchNestedInheritance uidIClaferMap' c0_req+ c1_req = fromJust $ findIClafer uidIClaferMap' "c1_req"+ c1_req_match = matchNestedInheritance uidIClaferMap' c1_req+ c0_cmd = fromJust $ findIClafer uidIClaferMap' "c0_cmd"+ c0_cmd_match = matchNestedInheritance uidIClaferMap' c0_cmd+ c0_Component = fromJust $ findIClafer uidIClaferMap' "c0_Component"+ c0_Component_match = matchNestedInheritance uidIClaferMap' c0_Component+ c0_InPort = fromJust $ findIClafer uidIClaferMap' "c0_InPort"+ c0_InPort_match = matchNestedInheritance uidIClaferMap' c0_InPort+ c0_WinController = fromJust $ findIClafer uidIClaferMap' "c0_WinController"+ c0_WinController_match = matchNestedInheritance uidIClaferMap' c0_WinController+ c0_down = fromJust $ findIClafer uidIClaferMap' "c0_down"+ c0_down_match = matchNestedInheritance uidIClaferMap' c0_down+ c0_Exception = fromJust $ findIClafer uidIClaferMap' "c0_Exception"+ c0_Exception_match = matchNestedInheritance uidIClaferMap' c0_Exception+ c0_powerDown = fromJust $ findIClafer uidIClaferMap' "c0_powerDown"+ c0_powerDown_match = matchNestedInheritance uidIClaferMap' c0_powerDown+ {-c0_Alice = fromJust $ findIClafer uidIClaferMap' "c0_Alice"+ c0_Alice_match = matchNestedInheritance uidIClaferMap' c0_Alice+ c0_Bob = fromJust $ findIClafer uidIClaferMap' "c0_Bob"+ c0_Bob_match = matchNestedInheritance uidIClaferMap' c0_Bob-}+ in do+ isJust c0_req_match @? ("NestedInheritanceMatch not found for " ++ show c0_req)+ isProperNesting uidIClaferMap' (c0_req_match) @? ("Improper nesting for " ++ show c0_req)+ (True, True, True) == isProperRefinement uidIClaferMap' (c0_req_match) @? ("Improper refinement for " ++ show c0_req)+ (not $ isRedefinition (c0_req_match)) @? ("Improper redefinition for " ++ show c0_req)++ isJust c1_req_match @? ("NestedInheritanceMatch not found for " ++ show c1_req)+ isProperNesting uidIClaferMap' (c1_req_match) @? ("Improper nesting for " ++ show c1_req)+ (True, True, True) == isProperRefinement uidIClaferMap' (c1_req_match) @? ("Improper refinement for " ++ show c1_req)+ isRedefinition (c1_req_match) @? ("Improper redefinition for " ++ show c1_req)++ isJust c0_cmd_match @? ("NestedInheritanceMatch not found for " ++ show c0_cmd)+ isProperNesting uidIClaferMap' (c0_cmd_match) @? ("Improper nesting for " ++ show c0_cmd)+ (True, True, True) == isProperRefinement uidIClaferMap' (c0_cmd_match) @? ("Improper refinement for " ++ show c0_cmd)+ (not $ isRedefinition (c0_cmd_match)) @? ("Improper redefinition for " ++ show c0_cmd)++ isNothing c0_Component_match @? ("Non-existing match found for " ++ show c0_Component)+ isNothing c0_InPort_match @? ("Non-existing match found for " ++ show c0_InPort)++ isJust c0_WinController_match @? ("NestedInheritanceMatch not found for" ++ show c0_WinController)++ isJust c0_down_match @? ("NestedInheritanceMatch not found for" ++ show c0_down)+ (isProperNesting uidIClaferMap' (c0_down_match)) @? ("Improper nesting for " ++ show c0_down)+ (True, True, True) == (isProperRefinement uidIClaferMap' (c0_down_match)) @? ("Improper refinement for " ++ show c0_down)+ (not $ isRedefinition (c0_down_match)) @? ("Improper redefinition for " ++ show c0_down)++ isJust c0_powerDown_match @? ("NestedInheritanceMatch not found for" ++ show c0_powerDown)+ (isProperNesting uidIClaferMap' (c0_powerDown_match)) @? ("Improper nesting for " ++ show c0_powerDown)++ (not $ isTopLevel c0_Exception) @? ("isTopLevel c0_Exception must return False")+ _parentUID c0_Exception == "c0_Component" @? ("Parent of c0_Exception should be c0_Component but it is " ++ _parentUID c0_Exception)+ (_uid <$> _parentClafer <$> c0_Exception_match) == (Just "c0_Component") @? ("_parentClafer of c0_Exception should be c0_Component in the match")+ {- isJust c0_Alice_match @? ("NestedInheritanceMatch not found for " ++ show c0_Alice)+ isProperNesting uidIClaferMap' (c0_Alice_match) @? ("Improper nesting for " ++ show c0_Alice)+ (False, False, True) == (isProperRefinement uidIClaferMap' (c0_Alice_match)) @? ("Improper refinement for " ++ show c0_Alice)+ (not $ isRedefinition (c0_Alice_match)) @? ("Improper redefinition for " ++ show c0_Alice)++ isJust c0_Bob_match @? ("NestedInheritanceMatch not found for " ++ show c0_Bob)+ isProperNesting uidIClaferMap' (c0_Bob_match) @? ("Improper nesting for " ++ show c0_Bob)+ (True, True, True) == (isProperRefinement uidIClaferMap' (c0_Bob_match)) @? ("Improper refinement for " ++ show c0_Bob)+ (not $ isRedefinition (c0_Bob_match)) @? ("Improper redefinition for " ++ show c0_Bob)-}++model2 :: String+model2 = unlines+ [ "abstract Person -> Bob 0..2"+ , "Alice : Person -> Bob 3" -- Improper cardinality refinement for clafer 'Alice' on line 2 column 1+ , "Bob : Person ->> Person" -- Improper bag to set refinement for clafer 'Bob' on line 3 column 1+ , "Carol : Person -> Person 2" -- Improper target subtyping for clafer 'Carol' on line 4 column 1+ ]+++case_NestedInheritanceFailTest :: Assertion+case_NestedInheritanceFailTest = case compileOneFragment defaultClaferArgs model2 of+ Left errors -> (show errors) == correctErrMsg @? "Incorrect error message:\nGot:\n" ++ show errors ++ "\nExpected:\n" ++ correctErrMsg+ Right _ -> assertFailure "The model2 is not expected to compile."+ where+ correctErrMsg = "[SemanticErr {pos = ErrPos {fragId = 1, fragPos = Pos 0 0, modelPos = Pos 0 0}, msg = \"Refinement errors in the following places:\\nImproper cardinality refinement for clafer 'Alice' on line 2 column 1\\nImproper bag to set refinement for clafer 'Bob' on line 3 column 1\\nImproper target subtyping for clafer 'Carol' on line 4 column 1\\n\"}]"++-- |> Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> |>+model3 :: String+model3 = unlines+ [ "abstract Component"+ , " abstract Port"+ , "abstract Exception : Port"+ , "powerDown : Exception" -- Improper nesting+ ]+++case_NestedInheritanceFailTest2 :: Assertion+case_NestedInheritanceFailTest2 = case compileOneFragment defaultClaferArgs model3 of+ Left errors -> (show errors) == correctErrMsg @? "Incorrect error message:\nGot:\n" ++ show errors ++ "\nExpected:\n" ++ correctErrMsg+ Right _ -> assertFailure "The model3 is not expected to compile."+ where+ correctErrMsg = "[SemanticErr {pos = ErrPos {fragId = 1, fragPos = Pos 0 0, modelPos = Pos 0 0}, msg = \"Refinement errors in the following places:\\nImproperly nested clafer 'powerDown' on line 4 column 1\\n\"}]"+-- <| Top-level abstract clafer extending a nested abstract clafer <https://github.com/gsdlab/clafer/issues/67> <|
test/Suite/SimpleScopeAnalyser.hs view
@@ -1,163 +1,163 @@-{-# LANGUAGE TemplateHaskell #-} -{- - Copyright (C) 2013 Luke Brown <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -module Suite.SimpleScopeAnalyser (tg_Test_Suite_SimpleScopeAnalyser) where - -import Language.Clafer -import Language.Clafer.Intermediate.Intclafer -import Language.Clafer.JSONMetaData -import Language.Clafer.QNameUID -import Functions - -import qualified Data.Map as M - -import Test.Tasty -import Test.Tasty.HUnit -import Test.Tasty.TH - - -tg_Test_Suite_SimpleScopeAnalyser :: TestTree -tg_Test_Suite_SimpleScopeAnalyser = $(testGroupGenerator) - -model :: String -model = unlines - [ "a 0..0" - , "b ?" - , "c" - , "d *" - , "e +" - , "f 2..4" - , "g 3..*" - , "gs -> g 2" - , "abstract H" - , " i ?" - , " j *" - , " k 2" - , "Hs -> H 3..*" - , "H1 : H 2" - , " H12 : H 2" - , "H2 : H 4..4" - , "H3 : H 1..2" - , "H4 : H 5..*" - , "Hs2 -> H 0..*" - , "Hs3 -> H 5..8" - , " l ?" - , "abstract FF : H" - , "f1 : FF 2..5" - , " m 0" - , "i1 -> integer 2..4" - , "i2 ->> integer ?" - , "i3 -> integer *" - , "i4 ->> integer *" - , "s1 -> string 2..*" - , "s2 ->> string" - , "s3 -> string +" - , "s4 ->> string +" - ] - -expectedScopesSet :: M.Map UID Integer -expectedScopesSet = M.fromList $ [ ("c0_a", 0) - -- , ("c0_b", 1) -- uses global scope - -- , ("c0_c", 1) -- uses global scope - -- , ("c0_d", 1) -- uses global scope - -- , ("c0_e", 1) -- uses global scope - , ("c0_f", 4) - , ("c0_g", 3) - , ("c0_gs", 2) - , ("c0_H", 22) - , ("c0_i", 22) - , ("c0_j", 22) - , ("c0_k", 44) - , ("c0_Hs", 16) - , ("c0_H1", 2) - , ("c0_H12", 4) - , ("c0_H2", 4) - , ("c0_H3", 2) - , ("c0_H4", 5) - , ("c0_Hs2", 16) - , ("c0_Hs3", 8) - , ("c0_l", 8) - , ("c0_FF", 5) - , ("c0_f1", 5) - , ("c0_m", 0) - , ("c0_i1", 4) - -- , ("c0_i2", 1) -- uses global scope - -- , ("c0_i3", 1) -- uses global scope - -- , ("c0_i4", 1) -- uses global scope - , ("c0_s1", 2) - -- , ("c0_s2", 1) -- uses global scope - -- , ("c0_s3", 1) -- uses global scope - -- , ("c0_s4", 1) -- uses global scope - ] - - --- aggregates a difference -aggregateDifference :: UID -> Integer -> Integer -> Maybe String -aggregateDifference k computedV expectedV = - if computedV == expectedV - then Nothing - else Just $ k ++ " | computed: " ++ show computedV ++ " | expected: " ++ show expectedV ++ " |" - --- prints only computed scopes missing in expected -onlyComputed :: M.Map UID Integer -> M.Map UID String -onlyComputed = M.mapWithKey (\k v -> k ++ " | computed: " ++ show v ++ " | no expected |") - - --- prints only expected scopes missing in computed -onlyExpected :: M.Map UID Integer -> M.Map UID String -onlyExpected = M.mapWithKey (\k v -> k ++ " | no computed | expected: " ++ show v ++ " |") - -case_ScopeTest :: Assertion -case_ScopeTest = do - let - -- use simple scope inference - (Right compilerResultMap) = compileOneFragment defaultClaferArgs model - (Just compilerResult) = M.lookup Alloy compilerResultMap - computedScopesSet :: M.Map UID Integer - computedScopesSet = M.fromList $ scopesList compilerResult - - differences = M.mergeWithKey aggregateDifference onlyComputed onlyExpected computedScopesSet expectedScopesSet - - (M.size differences) == 0 @? - "Computed scopes different from expected:\n" ++ (unlines $ M.foldl (\acc v -> v:acc) [] differences) - - -case_ReadScopesJSON :: Assertion -case_ReadScopesJSON = do - let - -- use simple scope inference - (Right compilerResultMap) = compileOneFragment defaultClaferArgs model - (Just compilerResult) = M.lookup Alloy compilerResultMap - Just (iModule, _, _) = cIr $ claferEnv compilerResult - - qNameMaps = deriveQNameMaps iModule - - computedScopes :: [ (UID, Integer) ] - computedScopes = scopesList compilerResult - - scopesInJSON = generateJSONScopes qNameMaps computedScopes - decodedScopes = parseJSONScopes qNameMaps scopesInJSON - - differences = M.mergeWithKey aggregateDifference onlyComputed onlyExpected (M.fromList computedScopes) (M.fromList decodedScopes) - - (M.size differences) == 0 @? - "Parsed scopes different from original:\n" ++ (unlines $ M.foldl (\acc v -> v:acc) [] differences) +{-# LANGUAGE TemplateHaskell #-}+{-+ Copyright (C) 2013 Luke Brown <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+module Suite.SimpleScopeAnalyser (tg_Test_Suite_SimpleScopeAnalyser) where++import Language.Clafer+import Language.Clafer.Intermediate.Intclafer+import Language.Clafer.JSONMetaData+import Language.Clafer.QNameUID+import Functions++import qualified Data.Map as M++import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.TH+++tg_Test_Suite_SimpleScopeAnalyser :: TestTree+tg_Test_Suite_SimpleScopeAnalyser = $(testGroupGenerator)++model :: String+model = unlines+ [ "a 0..0"+ , "b ?"+ , "c"+ , "d *"+ , "e +"+ , "f 2..4"+ , "g 3..*"+ , "gs -> g 2"+ , "abstract H"+ , " i ?"+ , " j *"+ , " k 2"+ , "Hs -> H 3..*"+ , "H1 : H 2"+ , " H12 : H 2"+ , "H2 : H 4..4"+ , "H3 : H 1..2"+ , "H4 : H 5..*"+ , "Hs2 -> H 0..*"+ , "Hs3 -> H 5..8"+ , " l ?"+ , "abstract FF : H"+ , "f1 : FF 2..5"+ , " m 0"+ , "i1 -> integer 2..4"+ , "i2 ->> integer ?"+ , "i3 -> integer *"+ , "i4 ->> integer *"+ , "s1 -> string 2..*"+ , "s2 ->> string"+ , "s3 -> string +"+ , "s4 ->> string +"+ ]++expectedScopesSet :: M.Map UID Integer+expectedScopesSet = M.fromList $ [ ("c0_a", 0)+ -- , ("c0_b", 1) -- uses global scope+ -- , ("c0_c", 1) -- uses global scope+ -- , ("c0_d", 1) -- uses global scope+ -- , ("c0_e", 1) -- uses global scope+ , ("c0_f", 4)+ , ("c0_g", 3)+ , ("c0_gs", 2)+ , ("c0_H", 22)+ , ("c0_i", 22)+ , ("c0_j", 22)+ , ("c0_k", 44)+ , ("c0_Hs", 16)+ , ("c0_H1", 2)+ , ("c0_H12", 4)+ , ("c0_H2", 4)+ , ("c0_H3", 2)+ , ("c0_H4", 5)+ , ("c0_Hs2", 16)+ , ("c0_Hs3", 8)+ , ("c0_l", 8)+ , ("c0_FF", 5)+ , ("c0_f1", 5)+ , ("c0_m", 0)+ , ("c0_i1", 4)+ -- , ("c0_i2", 1) -- uses global scope+ -- , ("c0_i3", 1) -- uses global scope+ -- , ("c0_i4", 1) -- uses global scope+ , ("c0_s1", 2)+ -- , ("c0_s2", 1) -- uses global scope+ -- , ("c0_s3", 1) -- uses global scope+ -- , ("c0_s4", 1) -- uses global scope+ ]+++-- aggregates a difference+aggregateDifference :: UID -> Integer -> Integer -> Maybe String+aggregateDifference k computedV expectedV =+ if computedV == expectedV+ then Nothing+ else Just $ k ++ " | computed: " ++ show computedV ++ " | expected: " ++ show expectedV ++ " |"++-- prints only computed scopes missing in expected+onlyComputed :: M.Map UID Integer -> M.Map UID String+onlyComputed = M.mapWithKey (\k v -> k ++ " | computed: " ++ show v ++ " | no expected |")+++-- prints only expected scopes missing in computed+onlyExpected :: M.Map UID Integer -> M.Map UID String+onlyExpected = M.mapWithKey (\k v -> k ++ " | no computed | expected: " ++ show v ++ " |")++case_ScopeTest :: Assertion+case_ScopeTest = do+ let+ -- use simple scope inference+ (Right compilerResultMap) = compileOneFragment defaultClaferArgs model+ (Just compilerResult) = M.lookup Alloy compilerResultMap+ computedScopesSet :: M.Map UID Integer+ computedScopesSet = M.fromList $ scopesList compilerResult++ differences = M.mergeWithKey aggregateDifference onlyComputed onlyExpected computedScopesSet expectedScopesSet++ (M.size differences) == 0 @?+ "Computed scopes different from expected:\n" ++ (unlines $ M.foldl (\acc v -> v:acc) [] differences)+++case_ReadScopesJSON :: Assertion+case_ReadScopesJSON = do+ let+ -- use simple scope inference+ (Right compilerResultMap) = compileOneFragment defaultClaferArgs model+ (Just compilerResult) = M.lookup Alloy compilerResultMap+ Just (iModule, _, _) = cIr $ claferEnv compilerResult++ qNameMaps = deriveQNameMaps iModule++ computedScopes :: [ (UID, Integer) ]+ computedScopes = scopesList compilerResult++ scopesInJSON = generateJSONScopes qNameMaps computedScopes+ decodedScopes = parseJSONScopes qNameMaps scopesInJSON++ differences = M.mergeWithKey aggregateDifference onlyComputed onlyExpected (M.fromList computedScopes) (M.fromList decodedScopes)++ (M.size differences) == 0 @?+ "Parsed scopes different from original:\n" ++ (unlines $ M.foldl (\acc v -> v:acc) [] differences)
test/Suite/TypeSystem.hs view
@@ -1,89 +1,89 @@-{-# LANGUAGE TemplateHaskell #-} -{- - Copyright (C) 2015 Michal Antkiewicz <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -module Suite.TypeSystem (tg_Test_Suite_TypeSystem) where - -import Language.Clafer -import Language.ClaferT -import Language.Clafer.Common -import Language.Clafer.Intermediate.Intclafer -import Language.Clafer.Intermediate.TypeSystem - -import Functions - -import qualified Data.Map as M -import Data.Maybe (isJust) -import Data.StringMap -import Test.Tasty -import Test.Tasty.HUnit -import Test.Tasty.TH - -tg_Test_Suite_TypeSystem :: TestTree -tg_Test_Suite_TypeSystem = $(testGroupGenerator) - -model :: String -model = unlines - [ "abstract A" -- c0_A - , " abstract as -> A *" -- c0_as - , "abstract B : A" -- c0_B - , " as : as -> B *" -- c1_as - , "b : B" -- c0_b - , " [ as = b ]" - , " [ as.ref = b ]" - ] - -case_TypeSystemTest :: Assertion -case_TypeSystemTest = case compileOneFragment defaultClaferArgs{keep_unused=True} model of - Left errors -> assertFailure $ show errors - Right compilerResultMap -> case M.lookup Alloy compilerResultMap of - Nothing -> assertFailure "No Alloy result in the result map" - Just compilerResult -> - let - um' :: StringMap IClafer - um' = uidIClaferMap $ claferEnv compilerResult - - root_TClafer = getTClaferByUID um' "root" - clafer_TClafer = getTClaferByUID um' "clafer" - c0_A_TClafer = getTClaferByUID um' "c0_A" - c0_A_TClaferR = Just $ TClafer [ "c0_A" ] - c0_A_TMap = getDrefTMapByUID um' "c0_A" - c0_as_TMap = getDrefTMapByUID um' "c0_as" - c0_as_TMapR = Just (TMap {_so = TClafer {_hi = ["c0_as"]}, _ta = TClafer {_hi = ["c0_A"]}}) - c0_B_TClafer = getTClaferByUID um' "c0_B" - c0_B_TClaferR = Just $ TClafer [ "c0_B", "c0_A" ] - c1_as_TClafer = getTClaferByUID um' "c1_as" - c1_as_TClaferR = Just $ TClafer [ "c1_as", "c0_as" ] - c1_as_TMap = getDrefTMapByUID um' "c1_as" - c1_as_TMapR = Just (TMap {_so = TClafer {_hi = ["c1_as","c0_as"]}, _ta = TClafer {_hi = [ "c0_B", "c0_A" ]}}) - c0_b_TClafer = getTClaferByUID um' "c0_b" - c0_b_TClaferR = Just $ TClafer [ "c0_b", "c0_B", "c0_A" ] - in do - (isJust $ findIClafer um' "c0_A") @? ("Clafer c0_A not found" ++ show um') - root_TClafer == Just rootTClafer @? ("Incorrect class type for 'root':\ngot '" ++ show root_TClafer ++ "'\ninstead of '" ++ show rootTClafer ++ "'") - clafer_TClafer == Just claferTClafer @? ("Incorrect class type for 'clafer':\ngot '" ++ show clafer_TClafer ++ "'\ninstead of '" ++ show claferTClafer ++ "'") - c0_A_TClafer == c0_A_TClaferR @? ("Incorrect class type for 'c0_A':\ngot '" ++ show c0_A_TClafer ++ "'\ninstead of '" ++ show c0_A_TClaferR ++ "'") - c0_A_TMap == Nothing @? ("Incorrect map type for 'c0_A':\ngot '" ++ show c0_A_TMap ++ "'\nbut it is \nt a reference.") - c0_as_TMap == c0_as_TMapR @? ("Incorrect map type for 'c0_as':\ngot '" ++ show c0_as_TMap ++ "'\ninstead of '" ++ show c0_as_TMapR ++ "'") - c0_B_TClafer == c0_B_TClaferR @? ("Incorrect class type for 'c0_B':\ngot '" ++ show c0_B_TClafer ++ "'\ninstead of '" ++ show c0_B_TClaferR ++ "'") - c1_as_TClafer == c1_as_TClaferR @? ("Incorrect class type for 'c1_as':\ngot '" ++ show c1_as_TClafer ++ "'\ninstead of '" ++ show c1_as_TClaferR ++ "'") - c1_as_TMap == c1_as_TMapR @? ("Incorrect map type for 'c1_as':\ngot '" ++ show c1_as_TMap ++ "'\ninstead of '" ++ show c1_as_TMapR ++ "'") - c0_b_TClafer == c0_b_TClaferR @? ("Incorrect class type for 'c0_b':\ngot '" ++ show c0_b_TClafer ++ "'\ninstead of '" ++ show c0_b_TClaferR ++ "'") +{-# LANGUAGE TemplateHaskell #-}+{-+ Copyright (C) 2015 Michal Antkiewicz <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+module Suite.TypeSystem (tg_Test_Suite_TypeSystem) where++import Language.Clafer+import Language.ClaferT+import Language.Clafer.Common+import Language.Clafer.Intermediate.Intclafer+import Language.Clafer.Intermediate.TypeSystem++import Functions++import qualified Data.Map as M+import Data.Maybe (isJust)+import Data.StringMap+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.TH++tg_Test_Suite_TypeSystem :: TestTree+tg_Test_Suite_TypeSystem = $(testGroupGenerator)++model :: String+model = unlines+ [ "abstract A" -- c0_A+ , " abstract as -> A *" -- c0_as+ , "abstract B : A" -- c0_B+ , " as : as -> B *" -- c1_as+ , "b : B" -- c0_b+ , " [ as = b ]"+ , " [ as.ref = b ]"+ ]++case_TypeSystemTest :: Assertion+case_TypeSystemTest = case compileOneFragment defaultClaferArgs{keep_unused=True} model of+ Left errors -> assertFailure $ show errors+ Right compilerResultMap -> case M.lookup Alloy compilerResultMap of+ Nothing -> assertFailure "No Alloy result in the result map"+ Just compilerResult ->+ let+ um' :: StringMap IClafer+ um' = uidIClaferMap $ claferEnv compilerResult++ root_TClafer = getTClaferByUID um' "root"+ clafer_TClafer = getTClaferByUID um' "clafer"+ c0_A_TClafer = getTClaferByUID um' "c0_A"+ c0_A_TClaferR = Just $ TClafer [ "c0_A" ]+ c0_A_TMap = getDrefTMapByUID um' "c0_A"+ c0_as_TMap = getDrefTMapByUID um' "c0_as"+ c0_as_TMapR = Just (TMap {_so = TClafer {_hi = ["c0_as"]}, _ta = TClafer {_hi = ["c0_A"]}})+ c0_B_TClafer = getTClaferByUID um' "c0_B"+ c0_B_TClaferR = Just $ TClafer [ "c0_B", "c0_A" ]+ c1_as_TClafer = getTClaferByUID um' "c1_as"+ c1_as_TClaferR = Just $ TClafer [ "c1_as", "c0_as" ]+ c1_as_TMap = getDrefTMapByUID um' "c1_as"+ c1_as_TMapR = Just (TMap {_so = TClafer {_hi = ["c1_as","c0_as"]}, _ta = TClafer {_hi = [ "c0_B", "c0_A" ]}})+ c0_b_TClafer = getTClaferByUID um' "c0_b"+ c0_b_TClaferR = Just $ TClafer [ "c0_b", "c0_B", "c0_A" ]+ in do+ (isJust $ findIClafer um' "c0_A") @? ("Clafer c0_A not found" ++ show um')+ root_TClafer == Just rootTClafer @? ("Incorrect class type for 'root':\ngot '" ++ show root_TClafer ++ "'\ninstead of '" ++ show rootTClafer ++ "'")+ clafer_TClafer == Just claferTClafer @? ("Incorrect class type for 'clafer':\ngot '" ++ show clafer_TClafer ++ "'\ninstead of '" ++ show claferTClafer ++ "'")+ c0_A_TClafer == c0_A_TClaferR @? ("Incorrect class type for 'c0_A':\ngot '" ++ show c0_A_TClafer ++ "'\ninstead of '" ++ show c0_A_TClaferR ++ "'")+ c0_A_TMap == Nothing @? ("Incorrect map type for 'c0_A':\ngot '" ++ show c0_A_TMap ++ "'\nbut it is \nt a reference.")+ c0_as_TMap == c0_as_TMapR @? ("Incorrect map type for 'c0_as':\ngot '" ++ show c0_as_TMap ++ "'\ninstead of '" ++ show c0_as_TMapR ++ "'")+ c0_B_TClafer == c0_B_TClaferR @? ("Incorrect class type for 'c0_B':\ngot '" ++ show c0_B_TClafer ++ "'\ninstead of '" ++ show c0_B_TClaferR ++ "'")+ c1_as_TClafer == c1_as_TClaferR @? ("Incorrect class type for 'c1_as':\ngot '" ++ show c1_as_TClafer ++ "'\ninstead of '" ++ show c1_as_TClaferR ++ "'")+ c1_as_TMap == c1_as_TMapR @? ("Incorrect map type for 'c1_as':\ngot '" ++ show c1_as_TMap ++ "'\ninstead of '" ++ show c1_as_TMapR ++ "'")+ c0_b_TClafer == c0_b_TClaferR @? ("Incorrect class type for 'c0_b':\ngot '" ++ show c0_b_TClafer ++ "'\ninstead of '" ++ show c0_b_TClaferR ++ "'")
test/doctests.hs view
@@ -1,4 +1,4 @@-import Test.DocTest - -main :: IO () -main = doctest ["-isrc", "src/Language/Clafer/Intermediate/TypeSystem.hs"] +import Test.DocTest++main :: IO ()+main = doctest ["-isrc", "src/Language/Clafer/Intermediate/TypeSystem.hs"]
test/test-suite.hs view
@@ -1,103 +1,103 @@-{-# LANGUAGE TemplateHaskell, DeriveDataTypeable #-} -{- - Copyright (C) 2013 Luke Brown <http://gsd.uwaterloo.ca> - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is furnished to do - so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. --} -import Control.Lens -import Data.Data.Lens -import Data.List -import qualified Data.Map as Map -import Data.Maybe -import Language.Clafer -import Language.Clafer.QNameUID -import Language.Clafer.Intermediate.Intclafer - -import Suite.Positive -import Suite.Negative -import Suite.SimpleScopeAnalyser -import Suite.Redefinition -import Suite.TypeSystem -import Functions -import Test.Tasty -import Test.Tasty.HUnit -import Test.Tasty.TH - -tg_Main_Test_Suite :: TestTree -tg_Main_Test_Suite = $(testGroupGenerator) - -main :: IO () -main = defaultMain $ testGroup "Tests" - [ tg_Test_Suite_TypeSystem - , tg_Test_Suite_Redefinition - , tg_Main_Test_Suite - , tg_Test_Suite_Positive - , tg_Test_Suite_Negative - , tg_Test_Suite_SimpleScopeAnalyser - ] - -{- -a // ::a -> c0_a - b // ::a::b -> c0_b -b // ::b -> c1_b -c // ::c -> c0_c - d // ::c::d -> c0_d - b // ::c::d::b -> c2_b -d // ::d -> c1_d - b // ::d::b -> c3_b - -"b" -> "c0_b", "c1_b", "c2_b", "c3_b" -"d::b" -> "c2_b", "c3_b" -"c::d" -> "c0_d" -"d" -> "c0_d", "c1_d" -"x" -> [] - -a\n b\nb\nc\n d\n b\nd\n b --} -model :: String -model = "a\n b\nb\nc\n d\n b\nd\n b" - -case_FQMapLookup :: Assertion -case_FQMapLookup = do - let - (Just (iModule, _, _)) = cIr $ claferEnv $ fromJust $ Map.lookup Alloy $ fromRight $ compileOneFragment defaultClaferArgs model - qNameMaps = deriveQNameMaps iModule - [ "c0_a" ] == getUIDs qNameMaps "::a" @? "UID for `::a` different from `c0_a`" - [ "c0_b" ] == getUIDs qNameMaps "::a::b" @? "UID for `::a::b` different from `c0_b`" - [ "c1_b" ] == getUIDs qNameMaps "::b" @? "UID for `::b` different from `c1_b`" - [ "c0_c" ] == getUIDs qNameMaps "::c" @? "UID for `::c` different from `c0_c`" - [ "c0_d" ] == getUIDs qNameMaps "::c::d" @? "UID for `::c::d` different from `c0_d`" - [ "c0_d" ] == getUIDs qNameMaps "c::d" @? "UID for `c::d` different from `c0_d`" - [ "c2_b" ] == getUIDs qNameMaps "::c::d::b" @? "UID for `::c::d::b` different from `c2_b`" - [ "c1_d" ] == getUIDs qNameMaps "::d" @? "UID for `::d` different from `c1_d`" - [ "c3_b" ] == getUIDs qNameMaps "::d::b" @? "UID for `::d::b` different from `c3_d`" - null ([ "c0_b", "c1_b", "c2_b", "c3_b" ] \\ (getUIDs qNameMaps "b" )) @? "UIDs for `b` different from `c0_b`, `c1_b`, `c2_b`, `c3_b` " - null ([ "c2_b", "c3_b" ] \\ (getUIDs qNameMaps "d::b" )) @? "UIDs for `d::b` different from `c2_b`, `c3_b` " - null ([ "c0_d", "c1_d" ] \\ (getUIDs qNameMaps "d" )) @? "UIDs for `d` different from `c0_d`, `c1_d` " - null (getUIDs qNameMaps "x") @? "UID for `x` different from []" - null (getUIDs qNameMaps "::x") @? "UID for `::x` different from []" - -case_AllClafersGenerics :: Assertion -case_AllClafersGenerics = do - let - (Just (iModule, _, _)) = cIr $ claferEnv $ fromJust $ Map.lookup Alloy $ fromRight $ compileOneFragment defaultClaferArgs model - allClafers :: [ IClafer ] - allClafers = universeOn biplate iModule - allClafersUids = map _uid allClafers - allClafersUids == [ "c0_a", "c0_b", "c1_b", "c0_c", "c0_d", "c2_b", "c1_d", "c3_b"] @? "All clafers\n" ++ show allClafersUids +{-# LANGUAGE TemplateHaskell, DeriveDataTypeable #-}+{-+ Copyright (C) 2013 Luke Brown <http://gsd.uwaterloo.ca>++ Permission is hereby granted, free of charge, to any person obtaining a copy of+ this software and associated documentation files (the "Software"), to deal in+ the Software without restriction, including without limitation the rights to+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+ of the Software, and to permit persons to whom the Software is furnished to do+ so, subject to the following conditions:++ The above copyright notice and this permission notice shall be included in all+ copies or substantial portions of the Software.++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ SOFTWARE.+-}+import Control.Lens+import Data.Data.Lens+import Data.List+import qualified Data.Map as Map+import Data.Maybe+import Language.Clafer+import Language.Clafer.QNameUID+import Language.Clafer.Intermediate.Intclafer++import Suite.Positive+import Suite.Negative+import Suite.SimpleScopeAnalyser+import Suite.Redefinition+import Suite.TypeSystem+import Functions+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.TH++tg_Main_Test_Suite :: TestTree+tg_Main_Test_Suite = $(testGroupGenerator)++main :: IO ()+main = defaultMain $ testGroup "Tests"+ [ tg_Test_Suite_TypeSystem+ , tg_Test_Suite_Redefinition+ , tg_Main_Test_Suite+ , tg_Test_Suite_Positive+ , tg_Test_Suite_Negative+ , tg_Test_Suite_SimpleScopeAnalyser+ ]++{-+a // ::a -> c0_a+ b // ::a::b -> c0_b+b // ::b -> c1_b+c // ::c -> c0_c+ d // ::c::d -> c0_d+ b // ::c::d::b -> c2_b+d // ::d -> c1_d+ b // ::d::b -> c3_b++"b" -> "c0_b", "c1_b", "c2_b", "c3_b"+"d::b" -> "c2_b", "c3_b"+"c::d" -> "c0_d"+"d" -> "c0_d", "c1_d"+"x" -> []++a\n b\nb\nc\n d\n b\nd\n b+-}+model :: String+model = "a\n b\nb\nc\n d\n b\nd\n b"++case_FQMapLookup :: Assertion+case_FQMapLookup = do+ let+ (Just (iModule, _, _)) = cIr $ claferEnv $ fromJust $ Map.lookup Alloy $ fromRight $ compileOneFragment defaultClaferArgs model+ qNameMaps = deriveQNameMaps iModule+ [ "c0_a" ] == getUIDs qNameMaps "::a" @? "UID for `::a` different from `c0_a`"+ [ "c0_b" ] == getUIDs qNameMaps "::a::b" @? "UID for `::a::b` different from `c0_b`"+ [ "c1_b" ] == getUIDs qNameMaps "::b" @? "UID for `::b` different from `c1_b`"+ [ "c0_c" ] == getUIDs qNameMaps "::c" @? "UID for `::c` different from `c0_c`"+ [ "c0_d" ] == getUIDs qNameMaps "::c::d" @? "UID for `::c::d` different from `c0_d`"+ [ "c0_d" ] == getUIDs qNameMaps "c::d" @? "UID for `c::d` different from `c0_d`"+ [ "c2_b" ] == getUIDs qNameMaps "::c::d::b" @? "UID for `::c::d::b` different from `c2_b`"+ [ "c1_d" ] == getUIDs qNameMaps "::d" @? "UID for `::d` different from `c1_d`"+ [ "c3_b" ] == getUIDs qNameMaps "::d::b" @? "UID for `::d::b` different from `c3_d`"+ null ([ "c0_b", "c1_b", "c2_b", "c3_b" ] \\ (getUIDs qNameMaps "b" )) @? "UIDs for `b` different from `c0_b`, `c1_b`, `c2_b`, `c3_b` "+ null ([ "c2_b", "c3_b" ] \\ (getUIDs qNameMaps "d::b" )) @? "UIDs for `d::b` different from `c2_b`, `c3_b` "+ null ([ "c0_d", "c1_d" ] \\ (getUIDs qNameMaps "d" )) @? "UIDs for `d` different from `c0_d`, `c1_d` "+ null (getUIDs qNameMaps "x") @? "UID for `x` different from []"+ null (getUIDs qNameMaps "::x") @? "UID for `::x` different from []"++case_AllClafersGenerics :: Assertion+case_AllClafersGenerics = do+ let+ (Just (iModule, _, _)) = cIr $ claferEnv $ fromJust $ Map.lookup Alloy $ fromRight $ compileOneFragment defaultClaferArgs model+ allClafers :: [ IClafer ]+ allClafers = universeOn biplate iModule+ allClafersUids = map _uid allClafers+ allClafersUids == [ "c0_a", "c0_b", "c1_b", "c0_c", "c0_d", "c2_b", "c1_d", "c3_b"] @? "All clafers\n" ++ show allClafersUids