{-# OPTIONS_GHC -Wall -Werror #-}
module Documentation.SBV.Examples.Puzzles.Newspaper where
import Data.SBV
import Data.SBV.Either
puzzle :: Symbolic ()
puzzle :: Symbolic ()
puzzle = do
a <- String -> Symbolic SInteger
sInteger String
"a"
b <- sInteger "b"
c <- sBool "c"
d <- sInteger "d"
e <- sBool "e"
f <- sInteger "f"
g <- sBool "g"
h <- sInteger "h"
i <- sBool "i"
j <- sEither "j"
jIsInt <- sBool "jIsInt"
let ints Bool
intj = [SInteger
a, SInteger
b, SInteger
d, SInteger
f, SInteger
h] [SInteger] -> [SInteger] -> [SInteger]
forall a. [a] -> [a] -> [a]
++ [SEither Bool Integer -> SInteger
forall a b. (SymVal a, SymVal b) => SEither a b -> SBV b
fromRight SEither Bool Integer
j | Bool
intj]
bools Bool
intj = [SBool
c, SBool
e, SBool
g, SBool
i] [SBool] -> [SBool] -> [SBool]
forall a. [a] -> [a] -> [a]
++ [SEither Bool Integer -> SBool
forall a b. (SymVal a, SymVal b) => SEither a b -> SBV a
fromLeft SEither Bool Integer
j | Bool -> Bool
not Bool
intj]
choice Bool -> a
fn = SBool -> a -> a -> a
forall a. Mergeable a => SBool -> a -> a -> a
ite SBool
jIsInt (Bool -> a
fn Bool
True) (Bool -> a
fn Bool
False)
constrain $ a .== choice (sum . ints)
constrain $ b .== choice (sum . map oneIf . bools)
constrain $ c .== (a .== choice (foldr1 smax . ints))
constrain $ d .== choice (sum . map (oneIf . (d .==)) . ints)
constrain $ e .== choice (sAll (.> 0) . ints)
constrain $ f * choice (literal . toInteger . length . ints) .== choice (sum . ints)
constrain $ g .== (d .> b)
constrain $ h * h .== a
constrain $ i .== (f .== d - b - h * d)
constrain $ ite jIsInt (isRight j) (isLeft j)
solvePuzzle :: IO ()
solvePuzzle :: IO ()
solvePuzzle = AllSatResult -> IO ()
forall a. Show a => a -> IO ()
print (AllSatResult -> IO ()) -> IO AllSatResult -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< SMTConfig -> Symbolic () -> IO AllSatResult
forall a. Satisfiable a => SMTConfig -> a -> IO AllSatResult
allSatWith SMTConfig
z3{isNonModelVar = (== "jIsInt")} Symbolic ()
puzzle