Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
### Removed

- `LowerInitialCharacter` is no longer exported from `PlutusCore.Evaluation.Machine.ExBudget`; it existed solely to support `deriving-aeson`, which `plutus-core` no longer depends on.

### Changed

- Replaced the `deriving-aeson`-based JSON instances of the cost model types with plain `aeson` generic instances. The JSON format is unchanged.
2 changes: 1 addition & 1 deletion plutus-core/cost-model/CostModelGeneration.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ our case, the costing function is given by the
type. The type prefix `ModelTwoArguments` is removed from the
constructor name and the remaining `MinSize` is converted to
`min_size` by the Aeson library's
[`CamelToSnake`](https://hackage.haskell.org/package/deriving-aeson-0.2.8/docs/Deriving-Aeson.html#t:CamelToSnake)
[`camelTo2`](https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#v:camelTo2)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was a bit worried that these might give different results, but if you look at the implementation in deriving-aeson it has

data CamelTo (separator :: Symbol)
...
type CamelToSnake = CamelTo  "_"
...
instance (KnownSymbol separator, NonEmptyString separator) => StringModifier (CamelTo separator) where
  getStringModifier = camelTo2 char
    where
      char = case symbolVal (Proxy @separator) of
        c : _ -> c
        _ -> error "Impossible"

so the previous code was secretly using camelTo2 anyway.

It does look as if you have to be a bit careful about what conversion functions like this do in general. For example we have a constructor called LinearInMaxYZ and there's a question of what happens if you have a sequence of multiple uppercase letters. In this case camelTo2 '_' gives linear_in_max_yz, but linear_in_max_y_z might be justifiable as well (and it looks as if there are functions in other libraries that would do that).

transformation. Similarly, the names of the
`modelMinSizeIntercept` and `modelMinSizeSlope` fields in the
`ModelMinSize` type are converted to `slope` and `intercept`. In
Expand Down
5 changes: 4 additions & 1 deletion plutus-core/plutus-core.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,6 @@ library
, data-default-class
, deepseq
, dependent-sum >=0.7.1.0
, deriving-aeson >=0.2.3
, deriving-compat
, dlist
, exceptions
Expand Down Expand Up @@ -382,6 +381,7 @@ test-suite plutus-core-test
CBOR.DataStability
Check.Spec
CostModelInterface.Spec
CostModelJSON.Spec
CostModelSafety.Spec
Evaluation.Machines
Evaluation.Spec
Expand All @@ -398,6 +398,9 @@ test-suite plutus-core-test
default-language: Haskell2010
build-depends:
, aeson
, aeson-diff
, aeson-pretty
, barbies
, base >=4.9 && <5
, base16-bytestring ^>=1.0
, bytestring
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
-- editorconfig-checker-disable-file
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE StrictData #-}
Expand Down Expand Up @@ -57,13 +56,12 @@ import PlutusPrelude hiding (toList)

import PlutusCore.Evaluation.Machine.CostingFun.Core
import PlutusCore.Evaluation.Machine.CostingFun.JSON ()
import PlutusCore.Evaluation.Machine.ExBudget

import Barbies

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe qualify this so we can see what we're using?

I tried import Barbies (ConstraintsB, TraversableB, FunctorB) but that mysteriously gave me several errors like this:

plutus-core/src/PlutusCore/Evaluation/Machine/BuiltinCostModel.hs:202:46: error: [GHC-18872]
    • Couldn't match representation of type: GHC.Generics.K1
                                               GHC.Generics.R (f ModelFourArguments)
                               with that of: barbies-2.1.1.0:Data.Generics.GenericN.Rec
                                               (barbies-2.1.1.0:Data.Generics.GenericN.Param
                                                  0 f ModelFourArguments)
                                               (f ModelFourArguments)
        arising from the 'deriving' clause of a data type declaration
        The data constructor ‘GHC.Generics.K1’
          of newtype ‘GHC.Generics.K1’ is not in scope
    • When deriving the instance for (ConstraintsB
                                        BuiltinCostModelBase)
    |
202 |   deriving anyclass (FunctorB, TraversableB, ConstraintsB)
    |                                              ^^^^^^^^^^^^

Not sure what's going on there.

import Data.Aeson
import Data.Kind qualified as Kind
import Data.List (stripPrefix)
import Data.Monoid
import Deriving.Aeson
import Language.Haskell.TH.Syntax hiding (Name, newName)

type BuiltinCostModel = BuiltinCostModelBase CostingFun
Expand Down Expand Up @@ -203,18 +201,21 @@ data BuiltinCostModelBase f
deriving stock (Generic)
deriving anyclass (FunctorB, TraversableB, ConstraintsB)

deriving via
CustomJSON
'[FieldLabelModifier (StripPrefix "param", LowerInitialCharacter)]
(BuiltinCostModelBase CostingFun)
instance
ToJSON (BuiltinCostModelBase CostingFun)
deriving via
CustomJSON
'[FieldLabelModifier (StripPrefix "param", LowerInitialCharacter)]
(BuiltinCostModelBase CostingFun)
instance
FromJSON (BuiltinCostModelBase CostingFun)
{-| JSON options for 'BuiltinCostModelBase': drop the @param@ prefix and lower the initial
character, so that the names of the JSON fields are exactly the same as the names of the
builtins. -}
builtinCostModelOptions :: Options
builtinCostModelOptions =
defaultOptions {fieldLabelModifier = lowerInitialChar . dropPrefix "param"}
where
dropPrefix prefix s = fromMaybe s (stripPrefix prefix s)

instance ToJSON (BuiltinCostModelBase CostingFun) where
toJSON = genericToJSON builtinCostModelOptions
toEncoding = genericToEncoding builtinCostModelOptions

instance FromJSON (BuiltinCostModelBase CostingFun) where
parseJSON = genericParseJSON builtinCostModelOptions

{-| Same as 'CostingFun' but maybe missing.
We could use 'Compose Maybe CostinFun' instead but we would then need an orphan ToJSON instance. -}
Expand All @@ -223,12 +224,12 @@ newtype MCostingFun a = MCostingFun (Maybe (CostingFun a))
deriving (Semigroup, Monoid) via (Alt Maybe (CostingFun a)) -- for mempty == MCostingFun Nothing

-- Omit generating JSON for any costing functions that have not been set (are missing).
deriving via
CustomJSON
'[OmitNothingFields, FieldLabelModifier (StripPrefix "param", LowerInitialCharacter)]
(BuiltinCostModelBase MCostingFun)
instance
ToJSON (BuiltinCostModelBase MCostingFun)
instance ToJSON (BuiltinCostModelBase MCostingFun) where
toJSON = genericToJSON mBuiltinCostModelOptions
toEncoding = genericToEncoding mBuiltinCostModelOptions

mBuiltinCostModelOptions :: Options
mBuiltinCostModelOptions = builtinCostModelOptions {omitNothingFields = True}

-- Needed to help derive various instances for BuiltinCostModelBase
type AllArgumentModels (constraint :: Kind.Type -> Kind.Constraint) f =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ import PlutusCore.Evaluation.Machine.ExMemoryUsage
import Control.DeepSeq
import Data.Default.Class
import Data.Hashable
import Deriving.Aeson
import GHC.Exts
import GHC.Generics (Generic)
import Language.Haskell.TH.Syntax hiding
( Name
, newName
Expand Down
Loading
Loading