Skip to content

Commit 0ca479a

Browse files
Start looking at optimizing num spec
1 parent df5f8f4 commit 0ca479a

File tree

3 files changed

+15
-7
lines changed

3 files changed

+15
-7
lines changed

bench/Constrained/Bench.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
module Constrained.Bench where
1111

1212
import Constrained.API
13+
import Constrained.Generation
1314
import Control.DeepSeq
1415
import Criterion
1516
import Data.Map (Map)
@@ -30,8 +31,12 @@ benchmarks =
3031
(giveHint (Nothing, 30) <> trueSpec :: Specification (Tree Int))
3132
, benchSpec 10 30 "roseTreeMaybe" roseTreeMaybe
3233
, benchSpec 10 30 "listSumPair" listSumPair
34+
, benchSpec 10 30 "intSpec" (simplifySpec intSpecSimple)
3335
]
3436

37+
intSpecSimple :: Specification Int
38+
intSpecSimple = constrained $ \ x -> 0 <. x
39+
3540
roseTreeMaybe :: Specification (Tree (Maybe (Int, Int)))
3641
roseTreeMaybe = constrained $ \t ->
3742
[ forAll' t $ \mp ts ->

src/Constrained/Generation.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,9 @@ genFromSpecT (simplifySpec -> spec) = case spec of
132132
$
133133
-- TODO: we could consider giving `cant` as an argument to `genFromTypeSpec` if this
134134
-- starts giving us trouble.
135-
genFromTypeSpec s `suchThatT` (`notElem` cant)
135+
case cant of
136+
[] -> genFromTypeSpec s
137+
_ -> genFromTypeSpec s `suchThatT` (`notElem` cant)
136138
ErrorSpec e -> genErrorNE e
137139

138140
-- | A version of `genFromSpecT` that simply errors if the generator fails

src/Constrained/NumOrd.hs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,8 @@ genFromNumSpec ::
313313
GenT m n
314314
genFromNumSpec (NumSpecInterval ml mu) = do
315315
n <- sizeT
316-
pureGen . choose =<< constrainInterval (ml <|> lowerBound) (mu <|> upperBound) (fromIntegral n)
316+
interval <- constrainInterval (ml <|> lowerBound) (mu <|> upperBound) (fromIntegral n)
317+
pureGen $ choose interval
317318

318319
-- TODO: fixme
319320

@@ -326,6 +327,7 @@ shrinkWithNumSpec _ = shrink
326327
fixupWithNumSpec :: Arbitrary n => NumSpec n -> n -> Maybe n
327328
fixupWithNumSpec _ = listToMaybe . shrink
328329

330+
{-# SCC constrainInterval #-}
329331
constrainInterval ::
330332
(MonadGenError m, Ord a, Num a, Show a) => Maybe a -> Maybe a -> Integer -> m (a, a)
331333
constrainInterval ml mu r =
@@ -336,21 +338,20 @@ constrainInterval ml mu r =
336338
| otherwise -> pure (l, l + 2 * r')
337339
(Nothing, Just u)
338340
| u > 0 -> pure (negate r', min u r')
339-
| otherwise -> pure (u - r' - r', u)
341+
| otherwise -> pure (u - 2 * r', u)
340342
(Just l, Just u)
341343
| l > u -> genError ("bad interval: " ++ show l ++ " " ++ show u)
342344
| u < 0 -> pure (safeSub l (safeSub l u r') r', u)
343-
| l >= 0 -> pure (l, safeAdd u (safeAdd u l r') r')
345+
| l >= 0 -> pure (l, safeAdd u l r')
344346
-- TODO: this is a bit suspect if the bounds are lopsided
345347
| otherwise -> pure (max l (-r'), min u r')
346348
where
347349
r' = abs $ fromInteger r
348350
safeSub l a b
349351
| a - b > a = l
350352
| otherwise = max l (a - b)
351-
safeAdd u a b
352-
| a + b < a = u
353-
| otherwise = min u (a + b)
353+
safeAdd u a b =
354+
let ab = a + b in if ab < a then u else min u ab
354355

355356
-- | Check that a value is in the spec
356357
conformsToNumSpec :: Ord n => n -> NumSpec n -> Bool

0 commit comments

Comments
 (0)