@@ -51,6 +51,7 @@ module Constrained.Generation (
5151 pattern SumSpec ,
5252) where
5353
54+ -- import Debug.Trace
5455import Constrained.AbstractSyntax
5556import Constrained.Base
5657import Constrained.Conformance
@@ -97,39 +98,40 @@ import Prelude hiding (cycle, pred)
9798-- generators are not flexible enough.
9899genFromSpecT ::
99100 forall a m . (HasCallStack , HasSpec a , MonadGenError m ) => Specification a -> GenT m a
100- genFromSpecT (simplifySpec -> spec) = case spec of
101- ExplainSpec [] s -> genFromSpecT s
102- ExplainSpec es s -> push es (genFromSpecT s)
103- MemberSpec as -> explain (" genFromSpecT on spec" ++ show spec) $ pureGen (elements (NE. toList as))
104- TrueSpec -> genFromSpecT (typeSpec $ emptySpec @ a )
105- SuspendedSpec x p
106- -- NOTE: If `x` isn't free in `p` we still have to try to generate things
107- -- from `p` to make sure `p` is sat and then we can throw it away. A better
108- -- approach would be to only do this in the case where we don't know if `p`
109- -- is sat. The proper way to implement such a sat check is to remove
110- -- sat-but-unnecessary variables in the optimiser.
111- | not $ Name x `appearsIn` p -> do
112- ! _ <- genFromPreds mempty p
113- genFromSpecT TrueSpec
114- | otherwise -> do
115- env <- genFromPreds mempty p
116- Env. find env x
117- TypeSpec s cant -> do
118- mode <- getMode
119- explainNE
120- ( NE. fromList
121- [ " genFromSpecT on (TypeSpec tspec cant) at type " ++ showType @ a
122- , " tspec = "
123- , show s
124- , " cant = " ++ show (short cant)
125- , " with mode " ++ show mode
126- ]
127- )
128- $
129- -- TODO: we could consider giving `cant` as an argument to `genFromTypeSpec` if this
130- -- starts giving us trouble.
131- genFromTypeSpec s `suchThatT` (`notElem` cant)
132- ErrorSpec e -> genErrorNE e
101+ genFromSpecT (simplifySpec -> spec) =
102+ case spec of
103+ ExplainSpec [] s -> genFromSpecT s
104+ ExplainSpec es s -> push es (genFromSpecT s)
105+ MemberSpec as -> explain (" genFromSpecT on spec" ++ show spec) $ pureGen (elements (NE. toList as))
106+ TrueSpec -> genFromSpecT (typeSpec $ emptySpec @ a )
107+ SuspendedSpec x p
108+ -- NOTE: If `x` isn't free in `p` we still have to try to generate things
109+ -- from `p` to make sure `p` is sat and then we can throw it away. A better
110+ -- approach would be to only do this in the case where we don't know if `p`
111+ -- is sat. The proper way to implement such a sat check is to remove
112+ -- sat-but-unnecessary variables in the optimiser.
113+ | not $ Name x `appearsIn` p -> do
114+ ! _ <- genFromPreds mempty p
115+ genFromSpecT TrueSpec
116+ | otherwise -> do
117+ env <- genFromPreds mempty p
118+ Env. find env x
119+ TypeSpec s cant -> do
120+ mode <- getMode
121+ explainNE
122+ ( NE. fromList
123+ [ " genFromSpecT on (TypeSpec tspec cant) at type " ++ showType @ a
124+ , " tspec = "
125+ , show s
126+ , " cant = " ++ show (short cant)
127+ , " with mode " ++ show mode
128+ ]
129+ )
130+ $
131+ -- TODO: we could consider giving `cant` as an argument to `genFromTypeSpec` if this
132+ -- starts giving us trouble.
133+ genFromTypeSpec s `suchThatT` (`notElem` cant)
134+ ErrorSpec e -> genErrorNE e
133135
134136-- | A version of `genFromSpecT` that simply errors if the generator fails
135137genFromSpec :: forall a . (HasCallStack , HasSpec a ) => Specification a -> Gen a
@@ -220,7 +222,10 @@ prepareLinearization p = do
220222 explainNE
221223 ( NE. fromList
222224 [ " Linearizing"
223- , show $ " preds: " <> pretty preds
225+ , show $
226+ " preds: "
227+ <> pretty (take 3 preds)
228+ <> (if length preds > 3 then fromString (" ... " ++ show (length preds - 3 ) ++ " more." ) else " " )
224229 , show $ " graph: " <> pretty graph
225230 ]
226231 )
@@ -846,7 +851,7 @@ isEmptyPlan (SolverPlan plan _) = null plan
846851
847852stepPlan :: MonadGenError m => Env -> SolverPlan -> GenT m (Env , SolverPlan )
848853stepPlan env plan@ (SolverPlan [] _) = pure (env, plan)
849- stepPlan env (SolverPlan (SolverStage x ps spec : pl) gr) = do
854+ stepPlan env (SolverPlan (SolverStage (x :: Var a ) ps spec : pl) gr) = do
850855 (spec', specs) <- runGE
851856 $ explain
852857 ( show
@@ -864,6 +869,8 @@ stepPlan env (SolverPlan (SolverStage x ps spec : pl) gr) = do
864869 ( NE. fromList
865870 ( ( " \n StepPlan for variable: "
866871 ++ show x
872+ ++ " ::"
873+ ++ showType @ a
867874 ++ " fails to produce Specification, probably overconstrained."
868875 ++ " PS = "
869876 ++ unlines (map show ps)
@@ -896,8 +903,10 @@ genFromPreds env0 (optimisePred . optimisePred -> preds) =
896903 go :: Env -> SolverPlan -> GenT m Env
897904 go env plan | isEmptyPlan plan = pure env
898905 go env plan = do
906+ (mess :: String ) <- (unlines . map NE. head ) <$> getMessages
899907 (env', plan') <-
900- explain (show $ " Stepping the plan:" /> vsep [pretty plan, pretty env]) $ stepPlan env plan
908+ explain (show (fromString (mess ++ " Stepping the plan:" ) /> vsep [pretty plan, pretty env])) $
909+ stepPlan env plan
901910 go env' plan'
902911
903912-- | Push as much information we can backwards through the plan.
@@ -1305,9 +1314,12 @@ data SolverStage where
13051314 } ->
13061315 SolverStage
13071316
1317+ docVar :: Typeable a => Var a -> Doc h
1318+ docVar (v :: Var a ) = fromString (show v ++ " :: " ++ showType @ a )
1319+
13081320instance Pretty SolverStage where
13091321 pretty SolverStage {.. } =
1310- viaShow stageVar
1322+ docVar stageVar
13111323 <+> " <-"
13121324 /> vsep'
13131325 ( [pretty stageSpec | not $ isTrueSpec stageSpec]
0 commit comments