packages feed

puresat-0.1: test/puresat-small.hs

module Main where

import Control.Monad      (forM_)
import Control.Monad.ST   (runST)
import System.Environment (getArgs)
import System.Exit        (exitFailure)

import PureSAT

main :: IO ()
main = do
    args <- getArgs
    case args of
        "pigeonhole"  : _ -> main' example2
        "pigeonhole3" : _ -> main' example3
        _                 -> main' example1

main' :: Bool -> IO ()
main' example = do
    print example
    if example then exitFailure else return ()

-- this example is unsat
example1 :: Bool
example1 = runST $ do
    s <- newSolver

    a <- newLit s
    b <- newLit s
    c <- newLit s
    d <- newLit s
    e <- newLit s
    f <- newLit s

    _ <- addClause s [a, b, c]
    _ <- addClause s [a, b, neg c]
    _ <- addClause s [neg b, d]
    _ <- addClause s [a, neg b, neg d]
    _ <- addClause s [neg a, e, f]
    _ <- addClause s [neg a, e, neg f]
    _ <- addClause s [neg e, neg f]
    _ <- addClause s [neg a, neg e, f]

    solve s

-- pigeonhole: 3 pigeons, 2 holes
example2 :: Bool
example2  = runST $ do
    s <- newSolver

    p11 <- newLit s
    p12 <- newLit s
    p21 <- newLit s
    p22 <- newLit s
    p31 <- newLit s
    p32 <- newLit s

    -- each pigeon is somewhere
    _ <- addClause s [p11, p12]
    _ <- addClause s [p21, p22]
    _ <- addClause s [p31, p32]

    -- there's only one pigeon in each hole
    _ <- addClause s [neg p11, neg p21]
    _ <- addClause s [neg p21, neg p31]
    _ <- addClause s [neg p31, neg p11]

    _ <- addClause s [neg p12, neg p22]
    _ <- addClause s [neg p22, neg p32]
    _ <- addClause s [neg p32, neg p12]

    solve s

-- pigeonhole: 4 pigeons, 3 holes
example3 :: Bool
example3  = runST $ do
    s <- newSolver

    p11 <- newLit s
    p12 <- newLit s
    p13 <- newLit s

    p21 <- newLit s
    p22 <- newLit s
    p23 <- newLit s

    p31 <- newLit s
    p32 <- newLit s
    p33 <- newLit s

    p41 <- newLit s
    p42 <- newLit s
    p43 <- newLit s

    -- each pigeon is somewhere
    _ <- addClause s [p11, p12, p13]
    _ <- addClause s [p21, p22, p23]
    _ <- addClause s [p31, p32, p33]
    _ <- addClause s [p41, p42, p43]

    -- there's only one pigeon in each hole
    _ <- forM_ (pairs [p11, p21, p31, p41]) $ \(x,y) -> addClause s [neg x, neg y]
    _ <- forM_ (pairs [p12, p22, p32, p42]) $ \(x,y) -> addClause s [neg x, neg y]
    _ <- forM_ (pairs [p13, p23, p33, p43]) $ \(x,y) -> addClause s [neg x, neg y]

    solve s

pairs :: [a] -> [(a,a)]
pairs []     = []
pairs (x:xs) = map ((,) x) xs ++ pairs xs