sat-simple-0.1.0.0: examples/sat-simple-tseitin.hs
module Main (main) where
import Control.Applicative (liftA2)
import Control.Monad (void)
import Control.Monad.IO.Class (liftIO)
import Data.Foldable (toList)
import Control.Monad.SAT
data H3 a = H3 a a a
deriving (Show, Functor, Foldable, Traversable)
instance Applicative H3 where
pure x = H3 x x x
H3 f1 f2 f3 <*> H3 x1 x2 x3 = H3 (f1 x1) (f2 x2) (f3 x3)
data H5 a = H5 a a a a a
deriving (Show, Functor, Foldable, Traversable)
instance Applicative H5 where
pure x = H5 x x x x x
H5 f1 f2 f3 f4 f5 <*> H5 x1 x2 x3 x4 x5 = H5 (f1 x1) (f2 x2) (f3 x3) (f4 x4) (f5 x5)
eval :: H5 Bool -> Bool
eval (H5 p q r s t) =
not ((p && q) == r) && (impl s (p && t))
where
impl x y = not x || y
title :: String -> IO ()
title s = do
putStrLn ""
putStrLn s
putStrLn $ '-' <$ s
main :: IO ()
main = do
title "addDefinition >>= addClause . singleton"
void $ runSATMaybe $ do
-- ~ ((p /\ q) <-> r) /\ (s -> (p /\ t))
p <- newLit
q <- newLit
r <- newLit
s <- newLit
t <- newLit
let prop = neg ((lit p /\ lit q) <-> lit r) /\ (lit s --> (lit p /\ lit t))
liftIO $ print prop
f <- addDefinition prop
addClause [f]
let lits = H5 p q r s t
let loop = do
res <- solve lits
liftIO $ print (eval res, res)
let n True l = neg l
n False l = l
addClause $ toList $ liftA2 n res lits
loop
loop
title "addProp"
void $ runSATMaybe $ do
-- ~ ((p /\ q) <-> r) /\ (s -> (p /\ t))
p <- newLit
q <- newLit
r <- newLit
s <- newLit
t <- newLit
addProp $ neg ((lit p /\ lit q) <-> lit r) /\ (lit s --> (lit p /\ lit t))
let lits = H5 p q r s t
let loop = do
res <- solve lits
liftIO $ print (eval res, res)
let n True l = neg l
n False l = l
addClause $ toList $ liftA2 n res lits
loop
loop
title "Same using addProp"
void $ runSATMaybe $ do
p <- newLit
q <- newLit
r <- newLit
s <- newLit
t <- newLit
let prop = (lit p /\ lit q /\ lit r /\ lit s /\ lit t) \/ (neg (lit p) /\ neg (lit q) /\ neg (lit r) /\ neg (lit s) /\ neg (lit t))
liftIO $ print prop
addProp prop
let lits = H5 p q r s t
let loop = do
res <- solve lits
liftIO $ print res
let n True l = neg l
n False l = l
addClause $ toList $ liftA2 n res lits
loop
loop
title "Same using assertAllEqual"
void $ runSATMaybe $ do
p <- newLit
q <- newLit
r <- newLit
s <- newLit
t <- newLit
assertAllEqual [p, q, r, s, t]
let lits = H5 p q r s t
let loop = do
res <- solve lits
liftIO $ print res
let n True l = neg l
n False l = l
addClause $ toList $ liftA2 n res lits
loop
loop
title "Same using <->"
void $ runSATMaybe $ do
p <- newLit
q <- newLit
r <- newLit
s <- newLit
t <- newLit
let prop = (lit p <-> lit q) /\
(lit q <-> lit r) /\
(lit r <-> lit s) /\
(lit s <-> lit t)
liftIO $ print prop
addProp prop
let lits = H5 p q r s t
let loop = do
res <- solve lits
liftIO $ print res
let n True l = neg l
n False l = l
addClause $ toList $ liftA2 n res lits
loop
loop
title "if-then-else"
void $ runSATMaybe $ do
c <- newLit
t <- newLit
f <- newLit
let prop = ite (lit c) (lit t) (lit f)
liftIO $ putStrLn $ "prop = " ++ show prop
-- addProp prop
addDefinition prop >>= addClause . pure
let lits = H3 c t f
let loop = do
res <- solve lits
liftIO $ print res
let n True l = neg l
n False l = l
addClause $ toList $ liftA2 n res lits
loop
loop