module Satchmo.Unary.Data
( Number, bits, make
, width, number, constant )
where
import Prelude hiding ( and, or, not )
import qualified Satchmo.Code as C
import Satchmo.Boolean hiding ( constant )
import qualified Satchmo.Boolean as B
import Control.Monad ( forM, when )
data Number = Number
{ bits :: [ Boolean ]
}
instance C.Decode m Boolean Bool => C.Decode m Number Int where
decode n = do
bs <- forM ( bits n ) C.decode
return $ length $ filter id bs
instance C.Decode m Boolean Bool => C.Decode m Number Integer where
decode n = do
bs <- forM ( bits n ) C.decode
return $ fromIntegral $ length $ filter id bs
width :: Number -> Int
width n = length $ bits n
number :: MonadSAT m => Int -> m Number
number w = do
xs <- sequence $ replicate w boolean
forM ( zip xs $ tail xs ) $ \ (p, q) ->
assert [ p, not q ]
return $ make xs
make :: [ Boolean ] -> Number
make xs = Number { bits = xs }
constant :: MonadSAT m => Integer -> m Number
constant k = do
xs <- forM [ 1 .. k ] $ \ i -> B.constant True
return $ make xs