module Agda.Syntax.Common where
import Control.Applicative
import Control.DeepSeq
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as ByteString
import Data.Foldable
import Data.Hashable
import qualified Data.Strict.Maybe as Strict
import Data.Semigroup hiding (Arg)
import Data.Traversable
import Data.Typeable (Typeable)
import Data.Word
import GHC.Generics (Generic)
import Agda.Syntax.Position
import Agda.Utils.Functor
import Agda.Utils.Pretty hiding ((<>))
#include "undefined.h"
import Agda.Utils.Impossible
data Delayed = Delayed | NotDelayed
deriving (Typeable, Show, Eq, Ord)
instance KillRange Delayed where
killRange = id
data Induction = Inductive | CoInductive
deriving (Typeable, Eq, Ord)
instance Show Induction where
show Inductive = "inductive"
show CoInductive = "coinductive"
instance HasRange Induction where
getRange _ = noRange
instance KillRange Induction where
killRange = id
instance NFData Induction where
rnf Inductive = ()
rnf CoInductive = ()
data Hiding = Hidden | Instance | NotHidden
deriving (Typeable, Show, Eq, Ord)
instance Semigroup Hiding where
NotHidden <> h = h
h <> NotHidden = h
Hidden <> Hidden = Hidden
Instance <> Instance = Instance
_ <> _ = __IMPOSSIBLE__
instance Monoid Hiding where
mempty = NotHidden
mappend = (<>)
instance KillRange Hiding where
killRange = id
instance NFData Hiding where
rnf Hidden = ()
rnf Instance = ()
rnf NotHidden = ()
data WithHiding a = WithHiding !Hiding a
deriving (Typeable, Eq, Ord, Show, Functor, Foldable, Traversable)
instance Decoration WithHiding where
traverseF f (WithHiding h a) = WithHiding h <$> f a
instance Applicative WithHiding where
pure = WithHiding mempty
WithHiding h f <*> WithHiding h' a = WithHiding (mappend h h') (f a)
instance HasRange a => HasRange (WithHiding a) where
getRange = getRange . dget
instance SetRange a => SetRange (WithHiding a) where
setRange = fmap . setRange
instance KillRange a => KillRange (WithHiding a) where
killRange = fmap killRange
instance NFData a => NFData (WithHiding a) where
rnf (WithHiding _ a) = rnf a
class LensHiding a where
getHiding :: a -> Hiding
setHiding :: Hiding -> a -> a
setHiding h = mapHiding (const h)
mapHiding :: (Hiding -> Hiding) -> a -> a
mapHiding f a = setHiding (f $ getHiding a) a
instance LensHiding Hiding where
getHiding = id
setHiding = const
mapHiding = id
instance LensHiding (WithHiding a) where
getHiding (WithHiding h _) = h
setHiding h (WithHiding _ a) = WithHiding h a
mapHiding f (WithHiding h a) = WithHiding (f h) a
mergeHiding :: LensHiding a => WithHiding a -> a
mergeHiding (WithHiding h a) = mapHiding (mappend h) a
notHidden :: LensHiding a => a -> Bool
notHidden a = getHiding a == NotHidden
visible :: LensHiding a => a -> Bool
visible a = getHiding a == NotHidden
notVisible :: LensHiding a => a -> Bool
notVisible a = getHiding a /= NotHidden
hide :: LensHiding a => a -> a
hide = setHiding Hidden
hideOrKeepInstance :: LensHiding a => a -> a
hideOrKeepInstance x =
case getHiding x of
Hidden -> x
Instance -> x
NotHidden -> setHiding Hidden x
makeInstance :: LensHiding a => a -> a
makeInstance = setHiding Instance
data Big = Big | Small
deriving (Typeable, Show, Eq, Enum, Bounded)
instance Ord Big where
Big <= Small = False
_ <= _ = True
instance NFData Big where
rnf Big = ()
rnf Small = ()
data Relevance
= Relevant
| NonStrict
| Irrelevant
| Forced Big
| UnusedArg
deriving (Typeable, Show, Eq)
allRelevances :: [Relevance]
allRelevances =
[ Relevant
, NonStrict
, Irrelevant
, Forced Small
, Forced Big
, UnusedArg
]
instance KillRange Relevance where
killRange rel = rel
instance Ord Relevance where
(<=) = moreRelevant
instance NFData Relevance where
rnf Relevant = ()
rnf NonStrict = ()
rnf Irrelevant = ()
rnf (Forced a) = rnf a
rnf UnusedArg = ()
class LensRelevance a where
getRelevance :: a -> Relevance
setRelevance :: Relevance -> a -> a
setRelevance h = mapRelevance (const h)
mapRelevance :: (Relevance -> Relevance) -> a -> a
mapRelevance f a = setRelevance (f $ getRelevance a) a
instance LensRelevance Relevance where
getRelevance = id
setRelevance = const
mapRelevance = id
isRelevant :: LensRelevance a => a -> Bool
isRelevant a = getRelevance a == Relevant
isIrrelevant :: LensRelevance a => a -> Bool
isIrrelevant a = getRelevance a == Irrelevant
moreRelevant :: Relevance -> Relevance -> Bool
moreRelevant r r' =
case (r, r') of
(_, Irrelevant) -> True
(Irrelevant, _) -> False
(Relevant, _) -> True
(_, Relevant) -> False
(UnusedArg, _) -> True
(_, UnusedArg) -> False
(Forced{}, _) -> True
(_, Forced{}) -> False
(NonStrict,NonStrict) -> True
irrelevantOrUnused :: Relevance -> Bool
irrelevantOrUnused r =
case r of
Irrelevant -> True
UnusedArg -> True
NonStrict -> False
Relevant -> False
Forced{} -> False
unusableRelevance :: Relevance -> Bool
unusableRelevance rel = NonStrict `moreRelevant` rel
composeRelevance :: Relevance -> Relevance -> Relevance
composeRelevance r r' =
case (r, r') of
(Irrelevant, _) -> Irrelevant
(_, Irrelevant) -> Irrelevant
(NonStrict, _) -> NonStrict
(_, NonStrict) -> NonStrict
(Forced b, Forced b') -> Forced (max b b')
(Forced b, _) -> Forced b
(_, Forced b) -> Forced b
(UnusedArg, _) -> UnusedArg
(_, UnusedArg) -> UnusedArg
(Relevant, Relevant) -> Relevant
inverseComposeRelevance :: Relevance -> Relevance -> Relevance
inverseComposeRelevance r x =
case (r, x) of
(Relevant, x) -> x
_ | r == x -> Relevant
(Forced{}, Forced{}) -> Relevant
(UnusedArg, x) -> x
(Forced{}, UnusedArg) -> Relevant
(Forced{}, x) -> x
(Irrelevant, x) -> Relevant
(_, Irrelevant) -> Irrelevant
(NonStrict, _) -> Relevant
ignoreForced :: Relevance -> Relevance
ignoreForced Forced{} = Relevant
ignoreForced UnusedArg = Relevant
ignoreForced Relevant = Relevant
ignoreForced NonStrict = NonStrict
ignoreForced Irrelevant = Irrelevant
irrToNonStrict :: Relevance -> Relevance
irrToNonStrict Irrelevant = NonStrict
irrToNonStrict rel = rel
nonStrictToRel :: Relevance -> Relevance
nonStrictToRel NonStrict = Relevant
nonStrictToRel rel = rel
nonStrictToIrr :: Relevance -> Relevance
nonStrictToIrr NonStrict = Irrelevant
nonStrictToIrr rel = rel
data Origin = UserWritten | Inserted | Reflected
deriving (Typeable, Show, Eq, Ord)
instance KillRange Origin where
killRange = id
instance NFData Origin where
rnf UserWritten = ()
rnf Inserted = ()
rnf Reflected = ()
class LensOrigin a where
getOrigin :: a -> Origin
setOrigin :: Origin -> a -> a
setOrigin o = mapOrigin (const o)
mapOrigin :: (Origin -> Origin) -> a -> a
mapOrigin f a = setOrigin (f $ getOrigin a) a
instance LensOrigin Origin where
getOrigin = id
setOrigin = const
mapOrigin = id
data ArgInfo = ArgInfo
{ argInfoHiding :: Hiding
, argInfoRelevance :: Relevance
, argInfoOrigin :: Origin
, argInfoOverlappable :: Bool
} deriving (Typeable, Eq, Ord, Show)
instance KillRange ArgInfo where
killRange (ArgInfo h r o v) = killRange3 ArgInfo h r o v
class LensArgInfo a where
getArgInfo :: a -> ArgInfo
setArgInfo :: ArgInfo -> a -> a
setArgInfo ai = mapArgInfo (const ai)
mapArgInfo :: (ArgInfo -> ArgInfo) -> a -> a
mapArgInfo f a = setArgInfo (f $ getArgInfo a) a
instance LensArgInfo ArgInfo where
getArgInfo = id
setArgInfo = const
mapArgInfo = id
instance NFData ArgInfo where
rnf (ArgInfo a b c d) = rnf a `seq` rnf b `seq` rnf c `seq` rnf d
instance LensHiding ArgInfo where
getHiding = argInfoHiding
setHiding h ai = ai { argInfoHiding = h }
mapHiding f ai = ai { argInfoHiding = f (argInfoHiding ai) }
instance LensRelevance ArgInfo where
getRelevance = argInfoRelevance
setRelevance h ai = ai { argInfoRelevance = h }
mapRelevance f ai = ai { argInfoRelevance = f (argInfoRelevance ai) }
instance LensOrigin ArgInfo where
getOrigin = argInfoOrigin
setOrigin o ai = ai { argInfoOrigin = o }
mapOrigin f ai = ai { argInfoOrigin = f (argInfoOrigin ai) }
defaultArgInfo :: ArgInfo
defaultArgInfo = ArgInfo { argInfoHiding = NotHidden
, argInfoRelevance = Relevant
, argInfoOrigin = UserWritten
, argInfoOverlappable = False }
data Arg e = Arg
{ argInfo :: ArgInfo
, unArg :: e
} deriving (Typeable, Ord, Functor, Foldable, Traversable)
instance Decoration Arg where
traverseF f (Arg ai a) = Arg ai <$> f a
instance HasRange a => HasRange (Arg a) where
getRange = getRange . unArg
instance SetRange a => SetRange (Arg a) where
setRange r = fmap $ setRange r
instance KillRange a => KillRange (Arg a) where
killRange (Arg info a) = killRange2 Arg info a
instance Eq a => Eq (Arg a) where
Arg (ArgInfo h1 _ _ _) x1 == Arg (ArgInfo h2 _ _ _) x2 = (h1, x1) == (h2, x2)
instance Show a => Show (Arg a) where
show (Arg (ArgInfo h r o v) x) = showR r $ showO o $ showH h $ show x
where
showH Hidden s = "{" ++ s ++ "}"
showH NotHidden s = "(" ++ s ++ ")"
showH Instance s = (if v then "overlap " else "") ++ "{{" ++ s ++ "}}"
showR r s = case r of
Irrelevant -> "." ++ s
NonStrict -> "?" ++ s
Forced Big -> "!b" ++ s
Forced Small -> "!" ++ s
UnusedArg -> "k" ++ s
Relevant -> "r" ++ s
showO o s = case o of
UserWritten -> "u" ++ s
Inserted -> "i" ++ s
Reflected -> "g" ++ s
instance NFData e => NFData (Arg e) where
rnf (Arg a b) = rnf a `seq` rnf b
instance LensHiding (Arg e) where
getHiding = getHiding . argInfo
mapHiding = mapArgInfo . mapHiding
instance LensRelevance (Arg e) where
getRelevance = getRelevance . argInfo
mapRelevance = mapArgInfo . mapRelevance
instance LensOrigin (Arg e) where
getOrigin = getOrigin . argInfo
mapOrigin = mapArgInfo . mapOrigin
instance LensArgInfo (Arg a) where
getArgInfo = argInfo
mapArgInfo f arg = arg { argInfo = f $ argInfo arg }
defaultArg :: a -> Arg a
defaultArg = Arg defaultArgInfo
withArgsFrom :: [a] -> [Arg b] -> [Arg a]
xs `withArgsFrom` args =
zipWith (\x arg -> fmap (const x) arg) xs args
withNamedArgsFrom :: [a] -> [NamedArg b] -> [NamedArg a]
xs `withNamedArgsFrom` args =
zipWith (\x -> fmap (x <$)) xs args
class Eq a => Underscore a where
underscore :: a
isUnderscore :: a -> Bool
isUnderscore = (== underscore)
instance Underscore String where
underscore = "_"
instance Underscore ByteString where
underscore = ByteString.pack underscore
instance Underscore Doc where
underscore = text underscore
data Dom e = Dom
{ domInfo :: ArgInfo
, unDom :: e
} deriving (Typeable, Ord, Functor, Foldable, Traversable)
instance Decoration Dom where
traverseF f (Dom ai a) = Dom ai <$> f a
instance HasRange a => HasRange (Dom a) where
getRange = getRange . unDom
instance KillRange a => KillRange (Dom a) where
killRange (Dom info a) = killRange2 Dom info a
instance Eq a => Eq (Dom a) where
Dom (ArgInfo h1 r1 _ _) x1 == Dom (ArgInfo h2 r2 _ _) x2 =
(h1, ignoreForced r1, x1) == (h2, ignoreForced r2, x2)
instance Show a => Show (Dom a) where
show = show . argFromDom
instance LensHiding (Dom e) where
getHiding = getHiding . domInfo
mapHiding = mapArgInfo . mapHiding
instance LensRelevance (Dom e) where
getRelevance = getRelevance . domInfo
mapRelevance = mapArgInfo . mapRelevance
instance LensArgInfo (Dom e) where
getArgInfo = domInfo
mapArgInfo f arg = arg { domInfo = f $ domInfo arg }
argFromDom :: Dom a -> Arg a
argFromDom (Dom i a) = Arg i a
domFromArg :: Arg a -> Dom a
domFromArg (Arg i a) = Dom i a
defaultDom :: a -> Dom a
defaultDom = Dom defaultArgInfo
data Named name a =
Named { nameOf :: Maybe name
, namedThing :: a
}
deriving (Eq, Ord, Typeable, Functor, Foldable, Traversable)
type Named_ = Named RString
unnamed :: a -> Named name a
unnamed = Named Nothing
named :: name -> a -> Named name a
named = Named . Just
instance Decoration (Named name) where
traverseF f (Named n a) = Named n <$> f a
instance HasRange a => HasRange (Named name a) where
getRange = getRange . namedThing
instance SetRange a => SetRange (Named name a) where
setRange r = fmap $ setRange r
instance (KillRange name, KillRange a) => KillRange (Named name a) where
killRange (Named n a) = Named (killRange n) (killRange a)
instance Show a => Show (Named_ a) where
show (Named Nothing x) = show x
show (Named (Just n) x) = rawNameToString (rangedThing n) ++ " = " ++ show x
instance (NFData name, NFData a) => NFData (Named name a) where
rnf (Named a b) = rnf a `seq` rnf b
type NamedArg a = Arg (Named_ a)
namedArg :: NamedArg a -> a
namedArg = namedThing . unArg
defaultNamedArg :: a -> NamedArg a
defaultNamedArg = defaultArg . unnamed
updateNamedArg :: (a -> b) -> NamedArg a -> NamedArg b
updateNamedArg = fmap . fmap
data Ranged a = Ranged
{ rangeOf :: Range
, rangedThing :: a
}
deriving (Typeable, Functor, Foldable, Traversable)
unranged :: a -> Ranged a
unranged = Ranged noRange
instance Show a => Show (Ranged a) where
show = show . rangedThing
instance Eq a => Eq (Ranged a) where
Ranged _ x == Ranged _ y = x == y
instance Ord a => Ord (Ranged a) where
compare (Ranged _ x) (Ranged _ y) = compare x y
instance HasRange (Ranged a) where
getRange = rangeOf
instance KillRange (Ranged a) where
killRange (Ranged _ x) = Ranged noRange x
instance Decoration Ranged where
traverseF f (Ranged r x) = Ranged r <$> f x
instance NFData a => NFData (Ranged a) where
rnf (Ranged _ a) = rnf a
type RawName = String
rawNameToString :: RawName -> String
rawNameToString = id
stringToRawName :: String -> RawName
stringToRawName = id
type RString = Ranged RawName
data ConOrigin
= ConOSystem
| ConOCon
| ConORec
deriving (Typeable, Show, Eq, Ord, Enum, Bounded)
instance KillRange ConOrigin where
killRange = id
bestConInfo :: ConOrigin -> ConOrigin -> ConOrigin
bestConInfo ConOSystem o = o
bestConInfo o _ = o
data ProjOrigin
= ProjPrefix
| ProjPostfix
| ProjSystem
deriving (Typeable, Show, Eq, Ord, Enum, Bounded)
instance KillRange ProjOrigin where
killRange = id
data IsInfix = InfixDef | PrefixDef
deriving (Typeable, Show, Eq, Ord)
data Access
= PrivateAccess Origin
| PublicAccess
| OnlyQualified
deriving (Typeable, Show, Eq, Ord)
instance NFData Access where
rnf _ = ()
instance HasRange Access where
getRange _ = noRange
instance KillRange Access where
killRange = id
data IsAbstract = AbstractDef | ConcreteDef
deriving (Typeable, Show, Eq, Ord)
instance KillRange IsAbstract where
killRange = id
data IsInstance = InstanceDef | NotInstanceDef
deriving (Typeable, Show, Eq, Ord)
instance KillRange IsInstance where
killRange = id
instance HasRange IsInstance where
getRange _ = noRange
instance NFData IsInstance where
rnf InstanceDef = ()
rnf NotInstanceDef = ()
data IsMacro = MacroDef | NotMacroDef
deriving (Typeable, Show, Eq, Ord)
instance KillRange IsMacro where killRange = id
instance HasRange IsMacro where getRange _ = noRange
type Nat = Int
type Arity = Nat
data NameId = NameId !Word64 !Word64
deriving (Eq, Ord, Typeable, Generic)
instance KillRange NameId where
killRange = id
instance Show NameId where
show (NameId x i) = show x ++ "@" ++ show i
instance Enum NameId where
succ (NameId n m) = NameId (n + 1) m
pred (NameId n m) = NameId (n 1) m
toEnum n = __IMPOSSIBLE__
fromEnum (NameId n _) = fromIntegral n
instance NFData NameId where
rnf (NameId _ _) = ()
instance Hashable NameId where
hashWithSalt salt (NameId n m) = hashWithSalt salt (n, m)
newtype MetaId = MetaId { metaId :: Nat }
deriving (Eq, Ord, Num, Real, Enum, Integral, Typeable)
instance Pretty MetaId where
pretty (MetaId n) = text $ "_" ++ show n
instance Show MetaId where
showsPrec p (MetaId n) = showParen (p > 0) $
showString "MetaId " . shows n
instance NFData MetaId where
rnf (MetaId x) = rnf x
newtype Constr a = Constr a
data PositionInName
= Beginning
| Middle
| End
deriving (Show, Eq, Ord)
data MaybePlaceholder e
= Placeholder !PositionInName
| NoPlaceholder !(Strict.Maybe PositionInName) e
deriving (Typeable, Eq, Ord, Functor, Foldable, Traversable, Show)
noPlaceholder :: e -> MaybePlaceholder e
noPlaceholder = NoPlaceholder Strict.Nothing
instance HasRange a => HasRange (MaybePlaceholder a) where
getRange Placeholder{} = noRange
getRange (NoPlaceholder _ e) = getRange e
instance KillRange a => KillRange (MaybePlaceholder a) where
killRange p@Placeholder{} = p
killRange (NoPlaceholder p e) = killRange1 (NoPlaceholder p) e
instance NFData a => NFData (MaybePlaceholder a) where
rnf (Placeholder _) = ()
rnf (NoPlaceholder _ a) = rnf a
newtype InteractionId = InteractionId { interactionId :: Nat }
deriving (Eq,Ord,Num,Integral,Real,Enum)
instance Show InteractionId where
show (InteractionId x) = "?" ++ show x
instance KillRange InteractionId where killRange = id
data ImportDirective' a b = ImportDirective
{ importDirRange :: Range
, using :: Using' a b
, hiding :: [ImportedName' a b]
, impRenaming :: [Renaming' a b]
, publicOpen :: Bool
}
deriving (Typeable, Eq)
data Using' a b = UseEverything | Using [ImportedName' a b]
deriving (Typeable, Eq)
instance Semigroup (Using' a b) where
UseEverything <> u = u
u <> UseEverything = u
Using xs <> Using ys = Using (xs ++ ys)
instance Monoid (Using' a b) where
mempty = UseEverything
mappend = (<>)
defaultImportDir :: ImportDirective' a b
defaultImportDir = ImportDirective noRange UseEverything [] [] False
isDefaultImportDir :: ImportDirective' a b -> Bool
isDefaultImportDir (ImportDirective _ UseEverything [] [] False) = True
isDefaultImportDir _ = False
data ImportedName' a b
= ImportedModule b
| ImportedName a
deriving (Typeable, Eq, Ord)
setImportedName :: ImportedName' a a -> a -> ImportedName' a a
setImportedName (ImportedName x) y = ImportedName y
setImportedName (ImportedModule x) y = ImportedModule y
instance (Show a, Show b) => Show (ImportedName' a b) where
show (ImportedModule x) = "module " ++ show x
show (ImportedName x) = show x
data Renaming' a b = Renaming
{ renFrom :: ImportedName' a b
, renTo :: ImportedName' a b
, renToRange :: Range
}
deriving (Typeable, Eq)
instance (HasRange a, HasRange b) => HasRange (ImportDirective' a b) where
getRange = importDirRange
instance (HasRange a, HasRange b) => HasRange (Using' a b) where
getRange (Using xs) = getRange xs
getRange UseEverything = noRange
instance (HasRange a, HasRange b) => HasRange (Renaming' a b) where
getRange r = getRange (renFrom r, renTo r)
instance (HasRange a, HasRange b) => HasRange (ImportedName' a b) where
getRange (ImportedName x) = getRange x
getRange (ImportedModule x) = getRange x
instance (KillRange a, KillRange b) => KillRange (ImportDirective' a b) where
killRange (ImportDirective _ u h r p) =
killRange3 (\u h r -> ImportDirective noRange u h r p) u h r
instance (KillRange a, KillRange b) => KillRange (Using' a b) where
killRange (Using i) = killRange1 Using i
killRange UseEverything = UseEverything
instance (KillRange a, KillRange b) => KillRange (Renaming' a b) where
killRange (Renaming i n _) = killRange2 (\i n -> Renaming i n noRange) i n
instance (KillRange a, KillRange b) => KillRange (ImportedName' a b) where
killRange (ImportedModule n) = killRange1 ImportedModule n
killRange (ImportedName n) = killRange1 ImportedName n
instance (NFData a, NFData b) => NFData (ImportDirective' a b) where
rnf (ImportDirective _ a b c _) = rnf a `seq` rnf b `seq` rnf c
instance (NFData a, NFData b) => NFData (Using' a b) where
rnf UseEverything = ()
rnf (Using a) = rnf a
instance (NFData a, NFData b) => NFData (Renaming' a b) where
rnf (Renaming a b _) = rnf a `seq` rnf b
instance (NFData a, NFData b) => NFData (ImportedName' a b) where
rnf (ImportedModule a) = rnf a
rnf (ImportedName a) = rnf a
data TerminationCheck m
= TerminationCheck
| NoTerminationCheck
| NonTerminating
| Terminating
| TerminationMeasure Range m
deriving (Typeable, Show, Eq, Functor)
instance KillRange m => KillRange (TerminationCheck m) where
killRange (TerminationMeasure _ m) = TerminationMeasure noRange (killRange m)
killRange t = t
instance NFData a => NFData (TerminationCheck a) where
rnf TerminationCheck = ()
rnf NoTerminationCheck = ()
rnf NonTerminating = ()
rnf Terminating = ()
rnf (TerminationMeasure _ a) = rnf a
type PositivityCheck = Bool