Skip to content

Commit 33ef0a2

Browse files
constrained-generators: Improve documentation in a bunch of places
1 parent e250c6a commit 33ef0a2

File tree

48 files changed

+2771
-2399
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+2771
-2399
lines changed

docs/constrained-generators/DesignPrinciples.md

Lines changed: 110 additions & 110 deletions
Large diffs are not rendered by default.

hie.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,9 @@ cradle:
306306
- path: "libs/constrained-generators/src"
307307
component: "lib:constrained-generators"
308308

309+
- path: "libs/constrained-generators/examples"
310+
component: "constrained-generators:lib:examples"
311+
309312
- path: "libs/constrained-generators/testlib"
310313
component: "constrained-generators:lib:testlib"
311314

libs/cardano-ledger-conformance/src/Test/Cardano/Ledger/Conformance/ExecSpecRule/Core.hs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,15 @@ module Test.Cardano.Ledger.Conformance.ExecSpecRule.Core (
3030
import Cardano.Ledger.BaseTypes (Globals, Inject (..), ShelleyBase)
3131
import Cardano.Ledger.Binary (EncCBOR)
3232
import Cardano.Ledger.Core (Era, EraRule, eraProtVerLow)
33-
import qualified Constrained.API as CV2 (HasSpec, Specification, genFromSpec, genFromSpecT)
34-
import Constrained.GenT (GE (..), GenMode (..))
35-
import qualified Constrained.GenT as CV1 (runGenT)
36-
import Constrained.Generation (shrinkWithSpec, simplifySpec)
33+
import Constrained.API (GE (..))
34+
import qualified Constrained.API as CV2 (
35+
HasSpec,
36+
Specification,
37+
genFromSpec,
38+
genFromSpecT,
39+
looseGen,
40+
shrinkWithSpec,
41+
)
3742
import Control.Monad.Cont (ContT (..))
3843
import Control.Monad.Trans (MonadTrans (..))
3944
import Control.State.Transition.Extended (STS (..))
@@ -428,9 +433,8 @@ conformsToImpl = property @(ImpTestM era Property) . (`runContT` pure) $ do
428433
let
429434
forAllSpec spec = do
430435
let
431-
simplifiedSpec = simplifySpec spec
432-
generator = CV1.runGenT (CV2.genFromSpecT simplifiedSpec) Loose []
433-
shrinker (Result x) = pure <$> shrinkWithSpec simplifiedSpec x
436+
generator = CV2.looseGen (CV2.genFromSpecT spec)
437+
shrinker (Result x) = pure <$> CV2.shrinkWithSpec spec x
434438
shrinker _ = []
435439
res :: GE a <- ContT $ \c ->
436440
pure $ forAllShrinkBlind generator shrinker c

libs/cardano-ledger-test/src/Test/Cardano/Ledger/Constrained/Conway/Instances/Basic.hs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ import Cardano.Ledger.Conway.Scripts ()
4545
import Cardano.Ledger.Plutus.CostModels (CostModels)
4646
import Cardano.Ledger.Plutus.ExUnits
4747
import Cardano.Ledger.Shelley.PParams (ProposedPPUpdates (..))
48-
import Constrained.API
49-
import Constrained.GenT
50-
import Constrained.NumOrd
48+
import Constrained.API.Extend
5149
import Control.Monad.Identity (Identity (..))
5250
import Control.Monad.Trans.Fail.String
5351
import Data.Maybe

libs/cardano-ledger-test/src/Test/Cardano/Ledger/Constrained/Conway/Instances/Ledger.hs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,6 @@ import Cardano.Ledger.UMap
115115
import Cardano.Ledger.Val (Val)
116116
import Constrained.API.Extend hiding (Sized)
117117
import Constrained.API.Extend qualified as C
118-
import Constrained.GenT (pureGen, vectorOfT)
119-
import Constrained.Generic
120118
import Control.DeepSeq (NFData)
121119
import Crypto.Hash (Blake2b_224)
122120
import Data.ByteString qualified as BS

libs/cardano-ledger-test/src/Test/Cardano/Ledger/Constrained/Conway/WitnessUniverse.hs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ import Cardano.Ledger.Shelley (ShelleyEra)
6969
import Cardano.Ledger.Shelley.Scripts
7070
import Cardano.Ledger.Shelley.TxCert
7171
import Constrained.API
72-
import Constrained.GenT (pureGen)
7372
import Control.DeepSeq (NFData (..), deepseq)
7473
import Control.Monad (replicateM)
7574
import Data.ByteString (ByteString)

libs/constrained-generators/constrained-generators.cabal

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,6 @@ library
2626
Constrained.Core
2727
Constrained.DependencyInjection
2828
Constrained.Env
29-
Constrained.Examples
30-
Constrained.Examples.Basic
31-
Constrained.Examples.CheatSheet
32-
Constrained.Examples.Either
33-
Constrained.Examples.Fold
34-
Constrained.Examples.List
35-
Constrained.Examples.ManualExamples
36-
Constrained.Examples.Map
37-
Constrained.Examples.Set
38-
Constrained.Examples.Tree
3929
Constrained.FunctionSymbol
4030
Constrained.GenT
4131
Constrained.Generation
@@ -45,6 +35,7 @@ library
4535
Constrained.NumOrd
4636
Constrained.PrettyUtils
4737
Constrained.Properties
38+
Constrained.Spec.List
4839
Constrained.Spec.Map
4940
Constrained.Spec.Set
5041
Constrained.Spec.SumProd
@@ -76,6 +67,39 @@ library
7667
random,
7768
template-haskell,
7869

70+
library examples
71+
exposed-modules:
72+
Constrained.Examples
73+
Constrained.Examples.Basic
74+
Constrained.Examples.BinTree
75+
Constrained.Examples.CheatSheet
76+
Constrained.Examples.Either
77+
Constrained.Examples.Fold
78+
Constrained.Examples.List
79+
Constrained.Examples.ManualExamples
80+
Constrained.Examples.Map
81+
Constrained.Examples.Set
82+
Constrained.Examples.Tree
83+
84+
hs-source-dirs: examples
85+
default-language: Haskell2010
86+
ghc-options:
87+
-Wall
88+
-Wcompat
89+
-Wincomplete-record-updates
90+
-Wincomplete-uni-patterns
91+
-Wpartial-fields
92+
-Wredundant-constraints
93+
-Wunused-packages
94+
95+
build-depends:
96+
QuickCheck >=2.14,
97+
base >=4.18 && <5,
98+
constrained-generators,
99+
containers,
100+
prettyprinter,
101+
random,
102+
79103
library testlib
80104
exposed-modules:
81105
Test.Minimal.Base
@@ -122,6 +146,7 @@ test-suite constrained
122146
QuickCheck,
123147
base,
124148
constrained-generators,
149+
constrained-generators:examples,
125150
containers,
126151
hspec,
127152

libs/constrained-generators/src/Constrained/Examples.hs renamed to libs/constrained-generators/examples/Constrained/Examples.hs

File renamed without changes.

libs/constrained-generators/src/Constrained/Examples/Basic.hs renamed to libs/constrained-generators/examples/Constrained/Examples/Basic.hs

File renamed without changes.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
{-# LANGUAGE DeriveGeneric #-}
2+
{-# LANGUAGE FlexibleInstances #-}
3+
{-# LANGUAGE FunctionalDependencies #-}
4+
{-# LANGUAGE ScopedTypeVariables #-}
5+
{-# LANGUAGE TypeApplications #-}
6+
{-# LANGUAGE TypeFamilies #-}
7+
8+
module Constrained.Examples.BinTree where
9+
10+
import Constrained.API
11+
import GHC.Generics
12+
13+
------------------------------------------------------------------------
14+
-- The types
15+
------------------------------------------------------------------------
16+
17+
data BinTree a
18+
= BinTip
19+
| BinNode (BinTree a) a (BinTree a)
20+
deriving (Ord, Eq, Show, Generic)
21+
22+
------------------------------------------------------------------------
23+
-- HasSpec for BinTree
24+
------------------------------------------------------------------------
25+
26+
data BinTreeSpec a = BinTreeSpec (Maybe Integer) (Specification (BinTree a, a, BinTree a))
27+
deriving (Show)
28+
29+
instance Forallable (BinTree a) (BinTree a, a, BinTree a) where
30+
fromForAllSpec = typeSpec . BinTreeSpec Nothing
31+
forAllToList BinTip = []
32+
forAllToList (BinNode left a right) = (left, a, right) : forAllToList left ++ forAllToList right
33+
34+
instance HasSpec a => HasSpec (BinTree a) where
35+
type TypeSpec (BinTree a) = BinTreeSpec a
36+
37+
emptySpec = BinTreeSpec Nothing mempty
38+
39+
combineSpec (BinTreeSpec sz s) (BinTreeSpec sz' s') =
40+
typeSpec $ BinTreeSpec (unionWithMaybe min sz sz') (s <> s')
41+
42+
conformsTo BinTip _ = True
43+
conformsTo (BinNode left a right) s@(BinTreeSpec _ es) =
44+
and
45+
[ (left, a, right) `conformsToSpec` es
46+
, left `conformsTo` s
47+
, right `conformsTo` s
48+
]
49+
50+
genFromTypeSpec (BinTreeSpec msz s)
51+
| Just sz <- msz, sz <= 0 = pure BinTip
52+
| otherwise = do
53+
let sz = maybe 20 id msz
54+
sz' = sz `div` 2
55+
oneofT
56+
[ do
57+
(left, a, right) <- genFromSpecT @(BinTree a, a, BinTree a) $
58+
constrained $ \ctx ->
59+
[ match ctx $ \left _ right ->
60+
[ forAll left (`satisfies` s)
61+
, genHint sz' left
62+
, forAll right (`satisfies` s)
63+
, genHint sz' right
64+
]
65+
, ctx `satisfies` s
66+
]
67+
pure $ BinNode left a right
68+
, pure BinTip
69+
]
70+
71+
shrinkWithTypeSpec _ BinTip = []
72+
shrinkWithTypeSpec s (BinNode left a right) =
73+
BinTip
74+
: left
75+
: right
76+
: (BinNode left a <$> shrinkWithTypeSpec s right)
77+
++ ((\l -> BinNode l a right) <$> shrinkWithTypeSpec s left)
78+
79+
cardinalTypeSpec _ = mempty
80+
81+
toPreds t (BinTreeSpec msz s) =
82+
(forAll t $ \n -> n `satisfies` s)
83+
<> maybe mempty (flip genHint t) msz
84+
85+
instance HasSpec a => HasGenHint (BinTree a) where
86+
type Hint (BinTree a) = Integer
87+
giveHint h = typeSpec $ BinTreeSpec (Just h) mempty

0 commit comments

Comments
 (0)