@@ -152,38 +152,41 @@ genFromSpecWithSeed seed size spec = unGen (genFromSpec spec) (mkQCGen seed) siz
152152shrinkWithSpec :: forall a . HasSpec a => Specification a -> a -> [a ]
153153-- TODO: possibly allow for ignoring the `conformsToSpec` check in the `TypeSpec`
154154-- case when you know what you're doing
155- shrinkWithSpec (simplifySpec -> spec) a = filter ( `conformsToSpec` spec) $ case spec of
155+ shrinkWithSpec (simplifySpec -> spec) a = case spec of
156156 ExplainSpec _ s -> shrinkWithSpec s a
157157 -- TODO: filter on can't if we have a known to be sound shrinker
158- TypeSpec s _ -> shrinkWithTypeSpec s a
159- SuspendedSpec x p -> shrinkFromPreds p x a ++ shr a
160- MemberSpec {} -> shr a
161- TrueSpec -> shr a
158+ TypeSpec s _ -> soundify $ shrinkWithTypeSpec s a
159+ SuspendedSpec x p -> shrinkFromPreds p x a
160+ -- TODO: it would be nice if there was some better way of doing this
161+ MemberSpec {} -> soundify $ shrinkWithTypeSpec (emptySpec @ a ) a
162+ TrueSpec -> shrinkWithTypeSpec (emptySpec @ a ) a
162163 ErrorSpec {} -> []
163- where
164- shr = shrinkWithTypeSpec (emptySpec @ a )
164+ where soundify = filter (`conformsToSpec` spec)
165165
166- shrinkFromPreds :: HasSpec a => Pred -> Var a -> a -> [a ]
166+ shrinkFromPreds :: forall a . HasSpec a => Pred -> Var a -> a -> [a ]
167167shrinkFromPreds p
168168 | Result plan <- prepareLinearization p = \ x a -> listFromGE $ do
169169 -- NOTE: we do this to e.g. guard against bad construction functions in Exists
170170 case checkPredE (Env. singleton x a) (NE. fromList [] ) p of
171171 Nothing -> pure ()
172172 Just err -> explainNE err $ fatalError " Trying to shrink a bad value, don't do that!"
173- -- Get an `env` for the original value
174- initialEnv <- envFromPred (Env. singleton x a) p
175- return
176- [ a'
177- | -- Shrink the initialEnv
178- env' <- shrinkEnvFromPlan initialEnv plan
179- , -- Get the value of the constrained variable `x` in the shrunk env
180- Just a' <- [Env. lookup env' x]
181- , -- NOTE: this is necessary because it's possible that changing
182- -- a particular value in the env during shrinking might not result
183- -- in the value of `x` changing and there is no better way to know than
184- -- to do this.
185- a' /= a
186- ]
173+ if not $ Name x `appearsIn` p -- NOTE: this is safe because we just checked that p is SAT above
174+ then return $ shrinkWithTypeSpec (emptySpec @ a ) a
175+ else do
176+ -- Get an `env` for the original value
177+ initialEnv <- envFromPred (Env. singleton x a) p
178+ return
179+ [ a'
180+ | -- Shrink the initialEnv
181+ env' <- shrinkEnvFromPlan initialEnv plan
182+ , -- Get the value of the constrained variable `x` in the shrunk env
183+ Just a' <- [Env. lookup env' x]
184+ , -- NOTE: this is necessary because it's possible that changing
185+ -- a particular value in the env during shrinking might not result
186+ -- in the value of `x` changing and there is no better way to know than
187+ -- to do this.
188+ a' /= a
189+ ]
187190 | otherwise = error " Bad pred"
188191
189192-- Start with a valid Env for the plan and try to shrink it
0 commit comments