moonlight-algebra-0.1.0.0: src-finite-lattice/Moonlight/FiniteLattice/Internal/Types.hs
{-# LANGUAGE GHC2024 #-}
{-# LANGUAGE RoleAnnotations #-}
module Moonlight.FiniteLattice.Internal.Types
( ContextLattice (..),
ContextOrderDecl (..),
ContextCompileLimits (..),
defaultContextCompileLimits,
unlimitedContextCompileLimits,
ContextRepresentation (..),
ContextLatticeCompileError (..),
ContextLatticeLookupError (..),
ResidentContext (..),
ResidentContextKey (..),
ResidentContextKeySet (..),
ResidentContextElement (..),
contextKeyForMaybe,
contextValueForKey,
residentKeyFromContextKey,
contextKeyFromResidentKey,
residentContextElementForKey,
)
where
import Data.Kind (Type)
import Data.Map.Strict (Map)
import Data.Map.Strict qualified as Map
import Data.Set (Set)
import Data.Vector qualified as Vector
import Moonlight.FiniteLattice.Internal.Invariant
( boxedIndexInvariant,
)
import Moonlight.FiniteLattice.Internal.Key
( ContextKey (..),
ContextKeySet,
)
import Moonlight.FiniteLattice.Internal.Plan (ContextPlan)
import Numeric.Natural (Natural)
type ContextLattice :: Type -> Type
data ContextLattice c = ContextLattice
{ clTop :: !c,
clBottom :: !c,
clTopKey :: !ContextKey,
clBottomKey :: !ContextKey,
clContextsByKey :: !(Vector.Vector c),
clKeyByContext :: !(Map c ContextKey),
clPlan :: !ContextPlan,
clSize :: !Int
}
type role ContextLattice nominal
type ContextOrderDecl :: Type -> Type
data ContextOrderDecl c = ContextOrderDecl
{ codTop :: !c,
codBottom :: !c,
-- | Generating pairs @(lower, upper)@. Reflexive and transitive pairs may
-- be omitted; compilation takes the reflexive-transitive closure.
codGeneratingPairs :: !(Set (c, c))
}
deriving stock (Eq, Ord, Show, Read)
type role ContextOrderDecl nominal
type ContextCompileLimits :: Type
data ContextCompileLimits = ContextCompileLimits
{ cclMaximumRelationBytes :: !(Maybe Natural),
cclMaximumBinaryTableBytes :: !(Maybe Natural)
}
deriving stock (Eq, Ord, Show, Read)
defaultContextCompileLimits :: ContextCompileLimits
defaultContextCompileLimits =
ContextCompileLimits
{ cclMaximumRelationBytes = Just (mebibytes 512),
cclMaximumBinaryTableBytes = Just (mebibytes 1024)
}
unlimitedContextCompileLimits :: ContextCompileLimits
unlimitedContextCompileLimits =
ContextCompileLimits
{ cclMaximumRelationBytes = Nothing,
cclMaximumBinaryTableBytes = Nothing
}
mebibytes :: Natural -> Natural
mebibytes count =
count * 1024 * 1024
type ContextRepresentation :: Type
data ContextRepresentation
= ContextRelationWords
deriving stock (Eq, Ord, Show, Read)
type ContextLatticeCompileError :: Type -> Type
data ContextLatticeCompileError c
= ContextLatticeEmptyUniverse
| ContextLatticeDuplicateElement !c
| ContextLatticeUnknownTop !c
| ContextLatticeUnknownBottom !c
| ContextLatticeUnknownRelationEndpoint !(c, c)
| ContextLatticeAntisymmetryViolation !c !c
| ContextLatticeTopNotGreatest !c
| ContextLatticeBottomNotLeast !c
| ContextLatticeJoinDoesNotExist !c !c !(Set c)
| ContextLatticeMeetDoesNotExist !c !c !(Set c)
| ContextLatticeNotReflexive !c
| ContextLatticeNotTransitive !c !c !c
| ContextLatticeJoinOutsideUniverse !c !c !c
| ContextLatticeMeetOutsideUniverse !c !c !c
| ContextLatticeInvalidJoin !c !c !c
| ContextLatticeInvalidMeet !c !c !c
| ContextLatticeRepresentationOverflow !ContextRepresentation !Integer
| ContextLatticeRepresentationLimitExceeded
!ContextRepresentation
!Integer
!Natural
deriving stock (Eq, Ord, Show, Read)
type role ContextLatticeCompileError nominal
type ContextLatticeLookupError :: Type -> Type
data ContextLatticeLookupError c
= ContextLatticeUnknownContext !c
deriving stock (Eq, Ord, Show, Read)
type role ContextLatticeLookupError nominal
type ResidentContext :: Type -> Type -> Type
newtype ResidentContext s c = ResidentContext
{ residentContextLattice :: ContextLattice c
}
type role ResidentContext nominal nominal
type ResidentContextKey :: Type -> Type
newtype ResidentContextKey s = ResidentContextKey
{ residentContextKeyOrdinal :: Int
}
deriving stock (Eq, Ord, Show)
type role ResidentContextKey nominal
type ResidentContextKeySet :: Type -> Type
newtype ResidentContextKeySet s = ResidentContextKeySet ContextKeySet
deriving stock (Eq, Show)
type role ResidentContextKeySet nominal
type ResidentContextElement :: Type -> Type -> Type
data ResidentContextElement s c = ResidentContextElement
{ residentContextElementKey :: !(ResidentContextKey s),
residentContextElementValue :: !c
}
deriving stock (Eq, Ord, Show)
type role ResidentContextElement nominal nominal
contextKeyForMaybe :: Ord c => ContextLattice c -> c -> Maybe ContextKey
contextKeyForMaybe lattice contextValue =
Map.lookup contextValue (clKeyByContext lattice)
-- | Total for internal keys produced by this lattice. The constructor of
-- 'ContextKey' is never exported by a public module.
contextValueForKey :: ContextLattice c -> ContextKey -> c
contextValueForKey lattice (ContextKey keyOrdinal) =
contextValueAtOrdinal lattice keyOrdinal
{-# INLINE contextValueForKey #-}
residentKeyFromContextKey :: ContextKey -> ResidentContextKey s
residentKeyFromContextKey (ContextKey keyOrdinal) =
ResidentContextKey keyOrdinal
{-# INLINE residentKeyFromContextKey #-}
contextKeyFromResidentKey :: ResidentContextKey s -> ContextKey
contextKeyFromResidentKey (ResidentContextKey keyOrdinal) =
ContextKey keyOrdinal
{-# INLINE contextKeyFromResidentKey #-}
residentContextElementForKey ::
ResidentContext s c ->
ResidentContextKey s ->
ResidentContextElement s c
residentContextElementForKey (ResidentContext lattice) residentKey =
ResidentContextElement
{ residentContextElementKey = residentKey,
residentContextElementValue =
contextValueForKey lattice (contextKeyFromResidentKey residentKey)
}
contextValueAtOrdinal :: ContextLattice c -> Int -> c
contextValueAtOrdinal lattice =
boxedIndexInvariant (clContextsByKey lattice)
{-# INLINE contextValueAtOrdinal #-}