{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Cardano.Ledger.Plutus.CostModels (
CostModel,
mkCostModel,
mkCostModelsLenient,
encodeCostModel,
getCostModelLanguage,
getCostModelParams,
getCostModelEvaluationContext,
getEvaluationContext,
costModelParamNames,
costModelToMap,
costModelFromMap,
costModelParamsCount,
decodeCostModel,
CostModels,
mkCostModels,
emptyCostModels,
updateCostModels,
decodeCostModelsLenient,
decodeCostModelsFailing,
costModelsValid,
costModelsUnknown,
flattenCostModels,
)
where
import Cardano.Ledger.Binary (
DecCBOR (decCBOR),
Decoder,
EncCBOR (encCBOR),
Encoding,
decodeMapByKey,
encodeFoldableAsDefLenList,
ifDecoderVersionAtLeast,
)
import Cardano.Ledger.Binary.Version (natVersion)
import Cardano.Ledger.Plutus.Language (
Language (..),
languageToText,
mkLanguageEnum,
nonNativeLanguages,
)
import Control.DeepSeq (NFData (..), deepseq)
import Control.Monad (forM, when)
import Control.Monad.Trans.Writer (WriterT (runWriterT))
import Data.Aeson (
FromJSON (..),
Object,
ToJSON (..),
Value (Array, Object),
withObject,
(.!=),
(.:?),
)
import Data.Aeson.Key (fromString)
import Data.Aeson.Types (Parser)
import Data.Int
import Data.List.NonEmpty as NE (toList)
import Data.Map (Map)
import qualified Data.Map.Strict as Map
import Data.Text as T (Text, pack)
import Data.Word (Word8)
import GHC.Generics (Generic)
import NoThunks.Class (NoThunks (..))
import qualified PlutusLedgerApi.Common as P (
CostModelApplyError (..),
CostModelApplyWarn,
EvaluationContext,
showParamName,
)
import qualified PlutusLedgerApi.V1 as PV1 (
ParamName,
mkEvaluationContext,
)
import qualified PlutusLedgerApi.V2 as PV2 (ParamName, mkEvaluationContext)
import qualified PlutusLedgerApi.V3 as PV3 (ParamName, mkEvaluationContext)
import Validation (failure, validationToEither)
data CostModel = CostModel
{ CostModel -> Language
cmLanguage :: !Language
, CostModel -> [Int64]
cmValues :: ![Int64]
, CostModel -> EvaluationContext
cmEvalCtx :: !P.EvaluationContext
}
deriving (forall x. Rep CostModel x -> CostModel
forall x. CostModel -> Rep CostModel x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CostModel x -> CostModel
$cfrom :: forall x. CostModel -> Rep CostModel x
Generic)
instance Eq CostModel where
CostModel Language
l1 [Int64]
x EvaluationContext
_ == :: CostModel -> CostModel -> Bool
== CostModel Language
l2 [Int64]
y EvaluationContext
_ = Language
l1 forall a. Eq a => a -> a -> Bool
== Language
l2 Bool -> Bool -> Bool
&& [Int64]
x forall a. Eq a => a -> a -> Bool
== [Int64]
y
instance Show CostModel where
show :: CostModel -> [Char]
show (CostModel Language
lang [Int64]
cm EvaluationContext
_) = [Char]
"CostModel " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> [Char]
show Language
lang forall a. Semigroup a => a -> a -> a
<> [Char]
" " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> [Char]
show [Int64]
cm
instance Ord CostModel where
compare :: CostModel -> CostModel -> Ordering
compare (CostModel Language
l1 [Int64]
x EvaluationContext
_) (CostModel Language
l2 [Int64]
y EvaluationContext
_) = forall a. Ord a => a -> a -> Ordering
compare Language
l1 Language
l2 forall a. Semigroup a => a -> a -> a
<> forall a. Ord a => a -> a -> Ordering
compare [Int64]
x [Int64]
y
instance NoThunks CostModel
instance NFData CostModel where
rnf :: CostModel -> ()
rnf (CostModel Language
lang [Int64]
cm EvaluationContext
ectx) = Language
lang forall a b. NFData a => a -> b -> b
`deepseq` [Int64]
cm forall a b. NFData a => a -> b -> b
`deepseq` forall a. NFData a => a -> ()
rnf EvaluationContext
ectx
instance FromJSON CostModels where
parseJSON :: Value -> Parser CostModels
parseJSON = forall a. [Char] -> (Object -> Parser a) -> Value -> Parser a
withObject [Char]
"CostModels" forall a b. (a -> b) -> a -> b
$ \Object
o -> do
[Maybe CostModel]
cms <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Object -> Language -> Parser (Maybe CostModel)
parseCostModel Object
o) [Language]
nonNativeLanguages
let cmsMap :: Map Language CostModel
cmsMap = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(CostModel -> Language
cmLanguage CostModel
cm, CostModel
cm) | Just CostModel
cm <- [Maybe CostModel]
cms]
Map Word8 [Int64]
unknown <- Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"Unknown" forall a. Parser (Maybe a) -> a -> Parser a
.!= forall a. Monoid a => a
mempty
CostModels
unknownCostModels <- forall (m :: * -> *).
MonadFail m =>
Map Word8 [Int64] -> m CostModels
mkCostModelsLenient Map Word8 [Int64]
unknown
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Map Language CostModel -> CostModels
mkCostModels Map Language CostModel
cmsMap forall a. Semigroup a => a -> a -> a
<> CostModels
unknownCostModels
parseCostModel :: Object -> Language -> Parser (Maybe CostModel)
parseCostModel :: Object -> Language -> Parser (Maybe CostModel)
parseCostModel Object
o Language
lang = do
Maybe Value
plutusCostModelValueMaybe <- Object
o forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? [Char] -> Key
fromString (forall a. Show a => a -> [Char]
show Language
lang)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM Maybe Value
plutusCostModelValueMaybe forall a b. (a -> b) -> a -> b
$ \Value
plutusCostModelValue ->
case Value
plutusCostModelValue of
Object Object
_ -> forall (m :: * -> *).
MonadFail m =>
Language -> Map Text Int64 -> m CostModel
costModelFromMap Language
lang forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. FromJSON a => Value -> Parser a
parseJSON Value
plutusCostModelValue
Array Array
_ -> forall (m :: * -> *).
MonadFail m =>
Language -> [Int64] -> m CostModel
validateCostModel Language
lang forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. FromJSON a => Value -> Parser a
parseJSON Value
plutusCostModelValue
Value
_ -> forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail forall a b. (a -> b) -> a -> b
$ [Char]
"Expected either an Array or an Object, but got: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Value
plutusCostModelValue
costModelFromMap :: MonadFail m => Language -> Map Text Int64 -> m CostModel
costModelFromMap :: forall (m :: * -> *).
MonadFail m =>
Language -> Map Text Int64 -> m CostModel
costModelFromMap Language
lang Map Text Int64
cmMap =
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail forall b c a. (b -> c) -> (a -> b) -> a -> c
. Context -> [Char]
unlines forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char]
header forall a. a -> [a] -> [a]
:) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. NonEmpty a -> [a]
NE.toList) (forall (m :: * -> *).
MonadFail m =>
Language -> [Int64] -> m CostModel
validateCostModel Language
lang) forall a b. (a -> b) -> a -> b
$
forall e a. Validation e a -> Either e a
validationToEither (forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Text -> Validation (NonEmpty [Char]) Int64
lookupFail [Text]
paramNames)
where
header :: [Char]
header = [Char]
"Cost model language: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Language
lang
paramNames :: [Text]
paramNames = Language -> [Text]
costModelParamNames Language
lang
lookupFail :: Text -> Validation (NonEmpty [Char]) Int64
lookupFail Text
paramName =
case forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Text
paramName Map Text Int64
cmMap of
Maybe Int64
Nothing -> forall e a. e -> Validation (NonEmpty e) a
failure forall a b. (a -> b) -> a -> b
$ [Char]
" Parameter name missing from cost model: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Text
paramName
Just Int64
v -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Int64
v
costModelToMap :: CostModel -> Map Text Int64
costModelToMap :: CostModel -> Map Text Int64
costModelToMap CostModel
cm =
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip (Language -> [Text]
costModelParamNames (CostModel -> Language
cmLanguage CostModel
cm)) (CostModel -> [Int64]
cmValues CostModel
cm)
costModelParamNames :: Language -> [Text]
costModelParamNames :: Language -> [Text]
costModelParamNames Language
PlutusV1 = [Text]
plutusV1ParamNames
costModelParamNames Language
lang = Language -> [Text]
plutusVXParamNames Language
lang
plutusV1ParamNames :: [Text]
plutusV1ParamNames :: [Text]
plutusV1ParamNames =
forall a b. (a -> b) -> [a] -> [b]
map (\Text
newName -> forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault Text
newName Text
newName Map Text Text
oldNewMapping) [Text]
newNames
where
newNames :: [Text]
newNames = Language -> [Text]
plutusVXParamNames Language
PlutusV1
oldNewMapping :: Map Text Text
oldNewMapping =
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
[ (Text
"blake2b_256-cpu-arguments-intercept", Text
"blake2b-cpu-arguments-intercept")
, (Text
"blake2b_256-cpu-arguments-slope", Text
"blake2b-cpu-arguments-slope")
, (Text
"blake2b_256-memory-arguments", Text
"blake2b-memory-arguments")
, (Text
"verifyEd25519Signature-cpu-arguments-intercept", Text
"verifySignature-cpu-arguments-intercept")
, (Text
"verifyEd25519Signature-cpu-arguments-slope", Text
"verifySignature-cpu-arguments-slope")
, (Text
"verifyEd25519Signature-memory-arguments", Text
"verifySignature-memory-arguments")
]
plutusVXParamNames :: Language -> [Text]
plutusVXParamNames :: Language -> [Text]
plutusVXParamNames Language
PlutusV1 = forall a. IsParamName a => a -> Text
P.showParamName forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [forall a. Bounded a => a
minBound .. forall a. Bounded a => a
maxBound :: PV1.ParamName]
plutusVXParamNames Language
PlutusV2 = forall a. IsParamName a => a -> Text
P.showParamName forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [forall a. Bounded a => a
minBound .. forall a. Bounded a => a
maxBound :: PV2.ParamName]
plutusVXParamNames Language
PlutusV3 = forall a. IsParamName a => a -> Text
P.showParamName forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [forall a. Bounded a => a
minBound .. forall a. Bounded a => a
maxBound :: PV3.ParamName]
validateCostModel :: MonadFail m => Language -> [Int64] -> m CostModel
validateCostModel :: forall (m :: * -> *).
MonadFail m =>
Language -> [Int64] -> m CostModel
validateCostModel Language
lang [Int64]
cmps =
case Language -> [Int64] -> Either CostModelApplyError CostModel
mkCostModel Language
lang [Int64]
cmps of
Left CostModelApplyError
err -> forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> [Char]
show CostModelApplyError
err
Right CostModel
cm -> forall (f :: * -> *) a. Applicative f => a -> f a
pure CostModel
cm
mkCostModel :: Language -> [Int64] -> Either P.CostModelApplyError CostModel
mkCostModel :: Language -> [Int64] -> Either CostModelApplyError CostModel
mkCostModel Language
lang [Int64]
cm =
case Either
CostModelApplyError (EvaluationContext, [CostModelApplyWarn])
eCostModel of
Right (EvaluationContext
evalCtx, [CostModelApplyWarn]
_) -> forall a b. b -> Either a b
Right (Language -> [Int64] -> EvaluationContext -> CostModel
CostModel Language
lang [Int64]
cm EvaluationContext
evalCtx)
Left CostModelApplyError
e -> forall a b. a -> Either a b
Left CostModelApplyError
e
where
mkEvaluationContext :: [Int64]
-> WriterT
[CostModelApplyWarn] (Either CostModelApplyError) EvaluationContext
mkEvaluationContext =
case Language
lang of
Language
PlutusV1 -> forall (m :: * -> *).
(MonadError CostModelApplyError m,
MonadWriter [CostModelApplyWarn] m) =>
[Int64] -> m EvaluationContext
PV1.mkEvaluationContext
Language
PlutusV2 -> forall (m :: * -> *).
(MonadError CostModelApplyError m,
MonadWriter [CostModelApplyWarn] m) =>
[Int64] -> m EvaluationContext
PV2.mkEvaluationContext
Language
PlutusV3 -> forall (m :: * -> *).
(MonadError CostModelApplyError m,
MonadWriter [CostModelApplyWarn] m) =>
[Int64] -> m EvaluationContext
PV3.mkEvaluationContext
eCostModel :: Either P.CostModelApplyError (P.EvaluationContext, [P.CostModelApplyWarn])
eCostModel :: Either
CostModelApplyError (EvaluationContext, [CostModelApplyWarn])
eCostModel = forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
runWriterT ([Int64]
-> WriterT
[CostModelApplyWarn] (Either CostModelApplyError) EvaluationContext
mkEvaluationContext [Int64]
cm)
getCostModelLanguage :: CostModel -> Language
getCostModelLanguage :: CostModel -> Language
getCostModelLanguage (CostModel Language
lang [Int64]
_ EvaluationContext
_) = Language
lang
getCostModelParams :: CostModel -> [Int64]
getCostModelParams :: CostModel -> [Int64]
getCostModelParams (CostModel Language
_ [Int64]
cm EvaluationContext
_) = [Int64]
cm
getCostModelEvaluationContext :: CostModel -> P.EvaluationContext
getCostModelEvaluationContext :: CostModel -> EvaluationContext
getCostModelEvaluationContext = CostModel -> EvaluationContext
cmEvalCtx
decodeCostModelsLenient :: Decoder s CostModels
decodeCostModelsLenient :: forall s. Decoder s CostModels
decodeCostModelsLenient = forall a s. DecCBOR a => Decoder s a
decCBOR forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *).
MonadFail m =>
Map Word8 [Int64] -> m CostModels
mkCostModelsLenient
{-# INLINE decodeCostModelsLenient #-}
decodeCostModelsFailing :: Decoder s CostModels
decodeCostModelsFailing :: forall s. Decoder s CostModels
decodeCostModelsFailing =
Map Language CostModel -> Map Word8 [Int64] -> CostModels
CostModels forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall k s v.
Ord k =>
Decoder s k -> (k -> Decoder s v) -> Decoder s (Map k v)
decodeMapByKey forall a s. DecCBOR a => Decoder s a
decCBOR forall s. Language -> Decoder s CostModel
decodeCostModelLegacy forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Monoid a => a
mempty
{-# INLINE decodeCostModelsFailing #-}
decodeCostModels :: Decoder s CostModels
decodeCostModels :: forall s. Decoder s CostModels
decodeCostModels =
forall s a. Version -> Decoder s a -> Decoder s a -> Decoder s a
ifDecoderVersionAtLeast
(forall (v :: Natural).
(KnownNat v, MinVersion <= v, v <= MaxVersion) =>
Version
natVersion @9)
forall s. Decoder s CostModels
decodeCostModelsLenient
forall s. Decoder s CostModels
decodeCostModelsFailing
{-# INLINEABLE decodeCostModels #-}
costModelParamsCount :: Language -> Int
costModelParamsCount :: Language -> Int
costModelParamsCount Language
PlutusV1 = Int
166
costModelParamsCount Language
PlutusV2 = Int
175
costModelParamsCount Language
PlutusV3 = Int
231
decodeCostModelLegacy :: Language -> Decoder s CostModel
decodeCostModelLegacy :: forall s. Language -> Decoder s CostModel
decodeCostModelLegacy Language
lang = do
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Language
lang forall a. Ord a => a -> a -> Bool
> Language
PlutusV2) forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail forall a b. (a -> b) -> a -> b
$
[Char]
"Legacy CostModel decoding is not supported for " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Language
lang forall a. [a] -> [a] -> [a]
++ [Char]
" language version"
[Int64]
values <- forall a s. DecCBOR a => Decoder s a
decCBOR
let numValues :: Int
numValues = forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int64]
values
expectedNumValues :: Int
expectedNumValues = Language -> Int
costModelParamsCount Language
lang
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
numValues forall a. Eq a => a -> a -> Bool
/= Int
expectedNumValues) forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail forall a b. (a -> b) -> a -> b
$
[Char]
"Expected array with "
forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> [Char]
show Int
expectedNumValues
forall a. Semigroup a => a -> a -> a
<> [Char]
" entries, but encoded array has "
forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> [Char]
show Int
numValues
forall a. Semigroup a => a -> a -> a
<> [Char]
" entries."
case Language -> [Int64] -> Either CostModelApplyError CostModel
mkCostModel Language
lang [Int64]
values of
Left CostModelApplyError
e -> forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> [Char]
show CostModelApplyError
e
Right CostModel
cm -> forall (f :: * -> *) a. Applicative f => a -> f a
pure CostModel
cm
{-# INLINEABLE decodeCostModelLegacy #-}
decodeCostModel :: Language -> Decoder s CostModel
decodeCostModel :: forall s. Language -> Decoder s CostModel
decodeCostModel Language
lang = do
forall s a. Version -> Decoder s a -> Decoder s a -> Decoder s a
ifDecoderVersionAtLeast
(forall (v :: Natural).
(KnownNat v, MinVersion <= v, v <= MaxVersion) =>
Version
natVersion @9)
Decoder s CostModel
decodeCostModelLenient
(forall s. Language -> Decoder s CostModel
decodeCostModelLegacy Language
lang)
where
decodeCostModelLenient :: Decoder s CostModel
decodeCostModelLenient = do
Either CostModelApplyError CostModel
checked <- Language -> [Int64] -> Either CostModelApplyError CostModel
mkCostModel Language
lang forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a s. DecCBOR a => Decoder s a
decCBOR
case Either CostModelApplyError CostModel
checked of
Left CostModelApplyError
e -> forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> [Char]
show CostModelApplyError
e
Right CostModel
cm -> forall (f :: * -> *) a. Applicative f => a -> f a
pure CostModel
cm
{-# INLINEABLE decodeCostModel #-}
getEvaluationContext :: CostModel -> P.EvaluationContext
getEvaluationContext :: CostModel -> EvaluationContext
getEvaluationContext (CostModel Language
_ [Int64]
_ EvaluationContext
ec) = EvaluationContext
ec
data CostModels = CostModels
{ CostModels -> Map Language CostModel
_costModelsValid :: !(Map Language CostModel)
, CostModels -> Map Word8 [Int64]
_costModelsUnknown :: !(Map Word8 [Int64])
}
deriving stock (CostModels -> CostModels -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CostModels -> CostModels -> Bool
$c/= :: CostModels -> CostModels -> Bool
== :: CostModels -> CostModels -> Bool
$c== :: CostModels -> CostModels -> Bool
Eq, Eq CostModels
CostModels -> CostModels -> Bool
CostModels -> CostModels -> Ordering
CostModels -> CostModels -> CostModels
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: CostModels -> CostModels -> CostModels
$cmin :: CostModels -> CostModels -> CostModels
max :: CostModels -> CostModels -> CostModels
$cmax :: CostModels -> CostModels -> CostModels
>= :: CostModels -> CostModels -> Bool
$c>= :: CostModels -> CostModels -> Bool
> :: CostModels -> CostModels -> Bool
$c> :: CostModels -> CostModels -> Bool
<= :: CostModels -> CostModels -> Bool
$c<= :: CostModels -> CostModels -> Bool
< :: CostModels -> CostModels -> Bool
$c< :: CostModels -> CostModels -> Bool
compare :: CostModels -> CostModels -> Ordering
$ccompare :: CostModels -> CostModels -> Ordering
Ord, Int -> CostModels -> ShowS
[CostModels] -> ShowS
CostModels -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [CostModels] -> ShowS
$cshowList :: [CostModels] -> ShowS
show :: CostModels -> [Char]
$cshow :: CostModels -> [Char]
showsPrec :: Int -> CostModels -> ShowS
$cshowsPrec :: Int -> CostModels -> ShowS
Show, forall x. Rep CostModels x -> CostModels
forall x. CostModels -> Rep CostModels x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CostModels x -> CostModels
$cfrom :: forall x. CostModels -> Rep CostModels x
Generic)
instance Semigroup CostModels where
<> :: CostModels -> CostModels -> CostModels
(<>) = CostModels -> CostModels -> CostModels
updateCostModels
instance Monoid CostModels where
mempty :: CostModels
mempty = CostModels
emptyCostModels
costModelsValid :: CostModels -> Map Language CostModel
costModelsValid :: CostModels -> Map Language CostModel
costModelsValid = CostModels -> Map Language CostModel
_costModelsValid
costModelsUnknown :: CostModels -> Map Word8 [Int64]
costModelsUnknown :: CostModels -> Map Word8 [Int64]
costModelsUnknown = CostModels -> Map Word8 [Int64]
_costModelsUnknown
emptyCostModels :: CostModels
emptyCostModels :: CostModels
emptyCostModels = Map Language CostModel -> Map Word8 [Int64] -> CostModels
CostModels forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty
updateCostModels ::
CostModels ->
CostModels ->
CostModels
updateCostModels :: CostModels -> CostModels -> CostModels
updateCostModels (CostModels Map Language CostModel
oldValid Map Word8 [Int64]
oldUnk) (CostModels Map Language CostModel
modValid Map Word8 [Int64]
modUnk) =
Map Language CostModel -> Map Word8 [Int64] -> CostModels
CostModels
Map Language CostModel
newValid
(forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union Map Word8 [Int64]
modUnk Map Word8 [Int64]
oldUnk forall k a b. Ord k => Map k a -> Map k b -> Map k a
Map.\\ forall k2 k1 a. Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a
Map.mapKeys Language -> Word8
languageToWord8 Map Language CostModel
newValid)
where
newValid :: Map Language CostModel
newValid = forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union Map Language CostModel
modValid Map Language CostModel
oldValid
mkCostModels :: Map Language CostModel -> CostModels
mkCostModels :: Map Language CostModel -> CostModels
mkCostModels Map Language CostModel
cms = Map Language CostModel -> Map Word8 [Int64] -> CostModels
CostModels Map Language CostModel
cms forall a. Monoid a => a
mempty
mkCostModelsLenient :: MonadFail m => Map Word8 [Int64] -> m CostModels
mkCostModelsLenient :: forall (m :: * -> *).
MonadFail m =>
Map Word8 [Int64] -> m CostModels
mkCostModelsLenient = forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
Map.foldrWithKey forall (m :: * -> *).
MonadFail m =>
Word8 -> [Int64] -> m CostModels -> m CostModels
addRawCostModel (forall (f :: * -> *) a. Applicative f => a -> f a
pure (Map Language CostModel -> Map Word8 [Int64] -> CostModels
CostModels forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty))
where
addRawCostModel :: MonadFail m => Word8 -> [Int64] -> m CostModels -> m CostModels
addRawCostModel :: forall (m :: * -> *).
MonadFail m =>
Word8 -> [Int64] -> m CostModels -> m CostModels
addRawCostModel Word8
langW8 [Int64]
cmIds m CostModels
costModelsM = do
CostModels Map Language CostModel
validCostModels Map Word8 [Int64]
unknownCostModels <- m CostModels
costModelsM
case Int -> Maybe Language
mkLanguageEnum (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
langW8) of
Just Language
lang ->
case Language -> [Int64] -> Either CostModelApplyError CostModel
mkCostModel Language
lang [Int64]
cmIds of
Right CostModel
cm -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Map Language CostModel -> Map Word8 [Int64] -> CostModels
CostModels (forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Language
lang CostModel
cm Map Language CostModel
validCostModels) Map Word8 [Int64]
unknownCostModels
Left CostModelApplyError
err -> forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail forall a b. (a -> b) -> a -> b
$ [Char]
"CostModel construction failure: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show CostModelApplyError
err
Maybe Language
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Map Language CostModel -> Map Word8 [Int64] -> CostModels
CostModels Map Language CostModel
validCostModels (forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Word8
langW8 [Int64]
cmIds Map Word8 [Int64]
unknownCostModels)
flattenCostModels :: CostModels -> Map Word8 [Int64]
flattenCostModels :: CostModels -> Map Word8 [Int64]
flattenCostModels (CostModels Map Language CostModel
validCostModels Map Word8 [Int64]
unknownCostModels) =
forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
Map.foldrWithKey
(\Language
lang CostModel
cm -> forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert (Language -> Word8
languageToWord8 Language
lang) (CostModel -> [Int64]
cmValues CostModel
cm))
Map Word8 [Int64]
unknownCostModels
Map Language CostModel
validCostModels
languageToWord8 :: Language -> Word8
languageToWord8 :: Language -> Word8
languageToWord8 Language
lang
| Int
0 forall a. Ord a => a -> a -> Bool
<= Int
li Bool -> Bool -> Bool
&& Int
li forall a. Ord a => a -> a -> Bool
<= forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. Bounded a => a
maxBound :: Word8) = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
li
| Bool
otherwise =
forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"Impossible: Overflow encountered during conversion of the language: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Language
lang
where
li :: Int
li = forall a. Enum a => a -> Int
fromEnum Language
lang
instance NoThunks CostModels
instance NFData CostModels
instance DecCBOR CostModels where
decCBOR :: forall s. Decoder s CostModels
decCBOR = forall s. Decoder s CostModels
decodeCostModels
{-# INLINE decCBOR #-}
instance EncCBOR CostModels where
encCBOR :: CostModels -> Encoding
encCBOR = forall a. EncCBOR a => a -> Encoding
encCBOR forall b c a. (b -> c) -> (a -> b) -> a -> c
. CostModels -> Map Word8 [Int64]
flattenCostModels
instance ToJSON CostModel where
toJSON :: CostModel -> Value
toJSON = forall a. ToJSON a => a -> Value
toJSON forall b c a. (b -> c) -> (a -> b) -> a -> c
. CostModel -> [Int64]
getCostModelParams
instance ToJSON CostModels where
toJSON :: CostModels -> Value
toJSON CostModels
cms = forall a. ToJSON a => a -> Value
toJSON forall a b. (a -> b) -> a -> b
$ Map Text Value
jsonValid forall a. Semigroup a => a -> a -> a
<> Map Text Value
jsonUnknown
where
jsonMap :: (k1 -> k2) -> Map k1 a -> Map k2 Value
jsonMap k1 -> k2
toKey = forall k2 k1 a. Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a
Map.mapKeys k1 -> k2
toKey forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b k. (a -> b) -> Map k a -> Map k b
Map.map forall a. ToJSON a => a -> Value
toJSON
jsonValid :: Map Text Value
jsonValid = forall {k2} {a} {k1}.
(Ord k2, ToJSON a) =>
(k1 -> k2) -> Map k1 a -> Map k2 Value
jsonMap Language -> Text
languageToText forall a b. (a -> b) -> a -> b
$ CostModels -> Map Language CostModel
costModelsValid CostModels
cms
jsonUnknown :: Map Text Value
jsonUnknown
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null (CostModels -> Map Word8 [Int64]
costModelsUnknown CostModels
cms) = forall a. Monoid a => a
mempty
| Bool
otherwise =
forall k a. k -> a -> Map k a
Map.singleton Text
"Unknown" forall a b. (a -> b) -> a -> b
$ forall a. ToJSON a => a -> Value
toJSON forall a b. (a -> b) -> a -> b
$ forall {k2} {a} {k1}.
(Ord k2, ToJSON a) =>
(k1 -> k2) -> Map k1 a -> Map k2 Value
jsonMap ([Char] -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> [Char]
show) forall a b. (a -> b) -> a -> b
$ CostModels -> Map Word8 [Int64]
costModelsUnknown CostModels
cms
encodeCostModel :: CostModel -> Encoding
encodeCostModel :: CostModel -> Encoding
encodeCostModel = forall (f :: * -> *) a.
Foldable f =>
(a -> Encoding) -> f a -> Encoding
encodeFoldableAsDefLenList forall a. EncCBOR a => a -> Encoding
encCBOR forall b c a. (b -> c) -> (a -> b) -> a -> c
. CostModel -> [Int64]
getCostModelParams