quick-process-0.0.3: src/System/Process/Quick/Sbv/Arbitrary.hs
module System.Process.Quick.Sbv.Arbitrary where
import System.Process.Quick.Prelude
import Data.SBV
import Data.SBV.String qualified as S
import Data.SBV.RegExp
getSingleValue :: (SymVal b, Modelable m) => m -> Maybe b
getSingleValue m
| modelExists m =
case toPairs $ getModelDictionary m of
[(k, _)] -> getModelValue k m
_ -> Nothing
| otherwise = Nothing
satOne :: (Satisfiable a, SymVal b) => Int -> a -> Maybe b
satOne _n p = unsafePerformIO (getSingleValue <$> sat p)
satN :: (Satisfiable a, SymVal b) => Int -> a -> [b]
satN n p = unsafePerformIO (mapMaybe getSingleValue . allSatResults <$> asat)
where
asat = allSatWith defaultSMTCfg { allSatMaxModelCount = Just n } p
findStringByRegex :: (SymVal b) => RegExp -> Gen b
findStringByRegex r = go (3 :: Int)
where
go t = sized $ \l ->
if t > 0
then do
n <- chooseInt (0, l)
case trySat n of
Just y -> pure y
Nothing -> go $ t - 1
else do
case satN l matchRx of
[] -> error $ "No solution for regex: " <> show r
ss -> elements ss
matchRx (x :: SString) = match x r
trySat n =
satOne n (\x -> matchRx x
.&& S.length x .== literal (fromIntegral n))