Skip to content

Commit

Permalink
constrained-generators: Cheat sheet for constraints
Browse files Browse the repository at this point in the history
  • Loading branch information
MaximilianAlgehed committed Jul 25, 2024
1 parent aa1dbc4 commit 4a1222b
Show file tree
Hide file tree
Showing 5 changed files with 733 additions and 15 deletions.
1 change: 1 addition & 0 deletions libs/constrained-generators/constrained-generators.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ library
Constrained.Examples.List
Constrained.Examples.Tree
Constrained.Examples.Either
Constrained.Examples.CheatSheet
Constrained.Properties
Constrained.Syntax

Expand Down
4 changes: 4 additions & 0 deletions libs/constrained-generators/src/Constrained.hs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ module Constrained (
length_,
cNothing_,
cJust_,
null_,
injectFn,
app,
lit,
Expand All @@ -130,6 +131,9 @@ module Constrained (
algebra,
inject,
toPred,
-- Understanding the execution of specs
printPlan,
-- Re-exports
module X,
)
where
Expand Down
24 changes: 17 additions & 7 deletions libs/constrained-generators/src/Constrained/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -425,11 +425,16 @@ toCtx ::
, Typeable v
, MonadGenError m
, HasCallStack
, HasSpec fn a
, HasSpec fn v
) =>
Var v ->
Term fn a ->
m (Ctx fn v a)
toCtx v = go
toCtx v t
| countOf (Name v) t > 1 =
fatalError1 ("Can't build a single-hole context for variable " ++ show v ++ " in term " ++ show t)
| otherwise = go t
where
go :: forall b. Term fn b -> m (Ctx fn v b)
go (Lit i) = fatalError1 ("toCtx has literal: (Lit " ++ show i ++ ")")
Expand All @@ -451,13 +456,17 @@ toCtx v = go

toCtxList ::
forall m fn v as.
(BaseUniverse fn, Typeable v, MonadGenError m, HasCallStack) =>
(BaseUniverse fn, All (HasSpec fn) as, HasSpec fn v, Typeable v, MonadGenError m, HasCallStack) =>
Var v ->
List (Term fn) as ->
m (ListCtx Value as (Ctx fn v))
toCtxList v = prefix
where
prefix :: forall as'. HasCallStack => List (Term fn) as' -> m (ListCtx Value as' (Ctx fn v))
prefix ::
forall as'.
(HasCallStack, All (HasSpec fn) as') =>
List (Term fn) as' ->
m (ListCtx Value as' (Ctx fn v))
prefix Nil = fatalError1 "toCtxList without hole"
prefix (Lit l :> ts) = do
ctx <- prefix ts
Expand Down Expand Up @@ -1041,7 +1050,7 @@ genFromSpecT (simplifySpec -> spec) = case spec of
-- TODO: we could consider giving `cant` as an argument to `genFromTypeSpec` if this
-- starts giving us trouble.
genFromTypeSpec @fn s `suchThatT` (`notElem` cant)
ErrorSpec e -> genError e
ErrorSpec e -> explain1 "genFromSpecT ErrorSpec{} with explanation:" $ genError e

shrinkWithSpec :: forall fn a. HasSpec fn a => Specification fn a -> a -> [a]
-- TODO: possibly allow for ignoring the `conformsToSpec` check in the `TypeSpec`
Expand Down Expand Up @@ -1295,7 +1304,7 @@ isEmptyPlan (SolverPlan plan _) = null plan

stepPlan :: MonadGenError m => SolverPlan fn -> GenT m (Env, SolverPlan fn)
stepPlan plan@(SolverPlan [] _) = pure (mempty, plan)
stepPlan plan@(SolverPlan (SolverStage x ps spec : pl) gr) = explain1 (show $ pretty plan) $ do
stepPlan (SolverPlan (SolverStage x ps spec : pl) gr) = do
spec' <- runGE $ explain1 (show $ "Computing specs for:" /> vsep' (map pretty ps)) $ do
specs <- mapM (computeSpec x) ps
pure $ fold specs
Expand All @@ -1320,8 +1329,9 @@ genFromPreds (optimisePred . optimisePred -> preds) = explain1 (show $ "genFromP
go :: MonadGenError m => Env -> SolverPlan fn -> GenT m Env
go env plan | isEmptyPlan plan = pure env
go env plan = do
(env', plan') <- explain1 (show env) $ stepPlan plan
explain1 (show $ pretty plan') $ go (env <> env') plan'
(env', plan') <-
explain1 (show $ "Stepping the plan:" /> vsep [pretty plan, viaShow env]) $ stepPlan plan
go (env <> env') plan'

-- TODO: here we can compute both the explicit hints (i.e. constraints that
-- define the order of two variables) and any whole-program smarts.
Expand Down
Loading

0 comments on commit 4a1222b

Please sign in to comment.