module Satchmo.Boolean.Op 

( constant
, and, or, xor
, monadic
)

where

import Prelude hiding ( and, or, not )

import Satchmo.Internal
import Satchmo.Code
import Satchmo.Boolean.Data

and :: [ Boolean ] -> SAT Boolean
and xs = do
    y <- boolean
    sequence $ do
        x <- xs
        return $ assert [ not y, x ]
    assert $ y : map not xs
    return y

or :: [ Boolean ] -> SAT Boolean
or xs = do
    y <- and $ map not xs
    return $ not y

xor :: [ Boolean ] -> SAT Boolean
xor [x] = return x
xor (x : xs) = do
    rest <- xor xs
    xor2 x rest

xor2 :: Boolean -> Boolean -> SAT Boolean
xor2 x y = do
    a <- and [ x, not y ]
    b <- and [ not x, y ]
    or [ a, b ]