packages feed

satchmo 1.8.1 → 1.9.1

raw patch · 17 files changed

+431/−136 lines, 17 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Satchmo.SAT: Header :: Int -> Int -> [Int] -> Header
- Satchmo.SAT: data Header
- Satchmo.SAT: data SAT a
- Satchmo.SAT: emit :: MonadSAT m => Clause -> m ()
- Satchmo.SAT: fresh :: MonadSAT m => m Literal
- Satchmo.SAT: fresh_forall :: MonadSAT m => m Literal
- Satchmo.SAT: instance Functor SAT
- Satchmo.SAT: instance Monad SAT
- Satchmo.SAT: instance MonadIO SAT
- Satchmo.SAT: instance MonadReader Handle SAT
- Satchmo.SAT: instance MonadSAT SAT
- Satchmo.SAT: instance MonadState Accu SAT
- Satchmo.SAT: numClauses :: Header -> Int
- Satchmo.SAT: numVars :: Header -> Int
- Satchmo.SAT: sat :: SAT a -> IO (ByteString, Header, a)
- Satchmo.SAT: type Weight = Int
- Satchmo.SAT: universals :: Header -> [Int]
+ Satchmo.Boolean: note :: MonadSAT m => String -> m ()
+ Satchmo.MonadSAT: Header :: !Int -> !Int -> ![Int] -> Header
+ Satchmo.MonadSAT: data Header
+ Satchmo.MonadSAT: instance Show Header
+ Satchmo.MonadSAT: note :: MonadSAT m => String -> m ()
+ Satchmo.MonadSAT: numClauses :: Header -> !Int
+ Satchmo.MonadSAT: numVars :: Header -> !Int
+ Satchmo.MonadSAT: universals :: Header -> ![Int]
+ Satchmo.SAT.BS: Header :: !Int -> !Int -> ![Int] -> Header
+ Satchmo.SAT.BS: data Header
+ Satchmo.SAT.BS: data SAT a
+ Satchmo.SAT.BS: emit :: MonadSAT m => Clause -> m ()
+ Satchmo.SAT.BS: fresh :: MonadSAT m => m Literal
+ Satchmo.SAT.BS: fresh_forall :: MonadSAT m => m Literal
+ Satchmo.SAT.BS: instance Functor SAT
+ Satchmo.SAT.BS: instance Monad SAT
+ Satchmo.SAT.BS: instance MonadSAT SAT
+ Satchmo.SAT.BS: instance MonadState Header SAT
+ Satchmo.SAT.BS: instance MonadWriter ByteString SAT
+ Satchmo.SAT.BS: numClauses :: Header -> !Int
+ Satchmo.SAT.BS: numVars :: Header -> !Int
+ Satchmo.SAT.BS: sat :: SAT a -> IO (ByteString, Header, a)
+ Satchmo.SAT.BS: type Weight = Int
+ Satchmo.SAT.BS: universals :: Header -> ![Int]
+ Satchmo.SAT.Seq: Header :: !Int -> !Int -> ![Int] -> Header
+ Satchmo.SAT.Seq: data Header
+ Satchmo.SAT.Seq: data SAT a
+ Satchmo.SAT.Seq: emit :: MonadSAT m => Clause -> m ()
+ Satchmo.SAT.Seq: fresh :: MonadSAT m => m Literal
+ Satchmo.SAT.Seq: fresh_forall :: MonadSAT m => m Literal
+ Satchmo.SAT.Seq: instance Functor SAT
+ Satchmo.SAT.Seq: instance Monad SAT
+ Satchmo.SAT.Seq: instance MonadSAT SAT
+ Satchmo.SAT.Seq: instance MonadState Header SAT
+ Satchmo.SAT.Seq: instance MonadWriter (Seq ByteString) SAT
+ Satchmo.SAT.Seq: numClauses :: Header -> !Int
+ Satchmo.SAT.Seq: numVars :: Header -> !Int
+ Satchmo.SAT.Seq: sat :: SAT a -> IO (ByteString, Header, a)
+ Satchmo.SAT.Seq: type Weight = Int
+ Satchmo.SAT.Seq: universals :: Header -> ![Int]
+ Satchmo.SAT.Sequence: Branch :: !Seq a -> !Seq a -> Seq a
+ Satchmo.SAT.Sequence: Empty :: Seq a
+ Satchmo.SAT.Sequence: Leaf :: !a -> Seq a
+ Satchmo.SAT.Sequence: data Seq a
+ Satchmo.SAT.Sequence: instance Foldable Seq
+ Satchmo.SAT.Sequence: instance Monoid (Seq a)
+ Satchmo.SAT.Tmpfile: Header :: !Int -> !Int -> ![Int] -> Header
+ Satchmo.SAT.Tmpfile: data Header
+ Satchmo.SAT.Tmpfile: data SAT a
+ Satchmo.SAT.Tmpfile: emit :: MonadSAT m => Clause -> m ()
+ Satchmo.SAT.Tmpfile: fresh :: MonadSAT m => m Literal
+ Satchmo.SAT.Tmpfile: fresh_forall :: MonadSAT m => m Literal
+ Satchmo.SAT.Tmpfile: instance Functor SAT
+ Satchmo.SAT.Tmpfile: instance Monad SAT
+ Satchmo.SAT.Tmpfile: instance MonadIO SAT
+ Satchmo.SAT.Tmpfile: instance MonadReader Handle SAT
+ Satchmo.SAT.Tmpfile: instance MonadSAT SAT
+ Satchmo.SAT.Tmpfile: instance MonadState Accu SAT
+ Satchmo.SAT.Tmpfile: numClauses :: Header -> !Int
+ Satchmo.SAT.Tmpfile: numVars :: Header -> !Int
+ Satchmo.SAT.Tmpfile: sat :: SAT a -> IO (ByteString, Header, a)
+ Satchmo.SAT.Tmpfile: type Weight = Int
+ Satchmo.SAT.Tmpfile: universals :: Header -> ![Int]
- Satchmo.Boolean: Constant :: Bool -> Boolean
+ Satchmo.Boolean: Constant :: !Bool -> Boolean
- Satchmo.Code: type Decoder a = Reader (Map Variable Bool) a
+ Satchmo.Code: type Decoder a = Reader (Array Variable Bool) a
- Satchmo.Solve: type Decoder a = Reader (Map Variable Bool) a
+ Satchmo.Solve: type Decoder a = Reader (Array Variable Bool) a
- Satchmo.Solve: type Implementation = ByteString -> Header -> IO (Maybe (Map Variable Bool))
+ Satchmo.Solve: type Implementation = ByteString -> Header -> IO (Maybe (Array Variable Bool))
- Satchmo.Solve: type WeightedImplementation = ByteString -> Header -> IO (Maybe (Map Variable Bool))
+ Satchmo.Solve: type WeightedImplementation = ByteString -> Header -> IO (Maybe (Array Variable Bool))

Files

Satchmo/Binary/Op/Common.hs view
@@ -17,6 +17,8 @@  import Satchmo.Counting +import Control.Monad ( forM )+ iszero :: (MonadSAT m) =>  Number -> m Boolean iszero a = equals a $ make [] @@ -26,13 +28,12 @@   equals' :: (MonadSAT m) =>  Booleans -> Booleans -> m Boolean-equals' [] [] = B.constant True-equals' (x:xs) (y:ys) = do-    z <- xor [x, y]-    rest <- equals' xs ys-    and [ not z, rest ]-equals' xs [] = and $ map not xs-equals' [] ys = and $ map not ys+equals' xs ys = do+    let n = min ( length xs ) ( length ys )+        (a,b) = splitAt n xs+        (c,d) = splitAt n ys+    ac <- forM ( zip a c ) $ \ (x,y) -> fun2 (==) x y+    and $ map not (b++d) ++ ac  le,lt,ge,gt,eq :: MonadSAT m => Number -> Number -> m Boolean le x y = do (l,e) <- compare x y ; or [l,e]@@ -71,9 +72,35 @@  full_adder :: (MonadSAT m)             => Boolean -> Boolean -> Boolean-           -> m ( Boolean, Boolean )-full_adder p1 p2 p3 = do+           -> m ( Boolean , Boolean ) -- ^ (result, carry)+full_adder = full_adder_1++full_adder_1 p1 p2 p3 = do     p4 <- boolean ; p5 <- boolean+    assert [not p1, not p2, p5]+    assert [not p1, not p3, p5]+    assert [not p1, p4, p5]+    assert [p1, p2, not p5]+    assert [p1, p3, not p5]+    assert [p1, not p4, not p5]+    assert [not p2, not p3, p5]+    assert [not p2, p4, p5]+    assert [p2, p3, not p5]+    assert [p2, not p4, not p5]+    assert [not p3, p4, p5]+    assert [p3, not p4, not p5]+    assert [not p1, not p2, not p3, p4]+    assert [not p1, not p2, p3, not p4]+    assert [not p1, p2, not p3, not p4]+    assert [not p1, p2, p3, p4]+    assert [p1, not p2, not p3, not p4]+    assert [p1, not p2, p3, p4]+    assert [p1, p2, not p3, p4]+    assert [p1, p2, p3, not p4]+    return ( p4, p5 )+       +full_adder_0 p1 p2 p3 = do+    p4 <- boolean ; p5 <- boolean     assert [not p2,p4,p5]     assert [p2,not p4,not p5]     assert [not p1,not p3,p5]@@ -94,8 +121,24 @@  half_adder :: (MonadSAT m)             => Boolean -> Boolean -           -> m ( Boolean, Boolean )-half_adder p1 p2 = do+           -> m ( Boolean, Boolean ) -- ^ (result, carry)+half_adder = half_adder_1++half_adder_1 p1 p2 = do+    p3 <- boolean ; p4 <- boolean+    assert [p1, not p4]+    assert [p2, not p4]+    assert [not p3, not p4]+    assert [not p1, not p2, not p3]+    assert [not p1, not p2, p4]+    assert [not p1, p2, p3]+    assert [not p1, p3, p4]+    assert [p1, not p2, p3]+    assert [p1, p2, not p3]+    assert [not p2, p3, p4]+    return (p3,p4)++half_adder_0 p1 p2 = do     p3 <- boolean ; p4 <- boolean     assert [not p2,p3,p4]     assert [p2,not p4]
Satchmo/Boolean/Data.hs view
@@ -18,18 +18,19 @@ import Satchmo.Data import Satchmo.MonadSAT -import Data.Map ( Map )-import qualified Data.Map as M+import Satchmo.SAT (SAT) -- for specializations++import Data.Array import Data.Maybe ( fromJust ) import Data.List ( partition )  import Control.Monad.Reader  data Boolean = Boolean-             { encode :: Literal-             , decode :: C.Decoder Bool+             { encode :: ! Literal+             -- , decode :: ! ( C.Decoder Bool )              }-     | Constant { value :: Bool }+     | Constant { value :: ! Bool }  {- @@ -65,49 +66,63 @@  instance C.Decode Boolean Bool where      decode b = case b of-        Boolean {} -> decode b+        -- Boolean {} -> decode b+        Boolean {} -> asks $ \ arr -> +              let x = encode b+              in  positive x == arr ! ( variable x )         Constant {} -> return $ value b  boolean :: MonadSAT m => m Boolean boolean = exists+{-# INLINABLE boolean #-}+{-# specialize inline boolean :: SAT Boolean #-}  exists :: MonadSAT m => m Boolean+{-# specialize inline exists :: SAT Boolean #-} exists = do     x <- fresh     return $ Boolean             { encode = x+{-                                  , decode = asks $ \ fm ->                        ( positive x == )                     $ fromJust                     $ M.lookup ( variable x ) fm+-}            }  forall :: MonadSAT m => m Boolean+{-# specialize inline forall :: SAT Boolean #-} forall = do     x <- fresh_forall     return $ Boolean             { encode = x-           , decode = error "Boolean.forall cannot be decoded"+--           , decode = error "Boolean.forall cannot be decoded"            }  constant :: MonadSAT m => Bool -> m Boolean+{-# specialize inline constant :: Bool -> SAT Boolean #-} constant v = do     return $ Constant { value = v } +{-# INLINABLE constant #-}  not :: Boolean -> Boolean not b = case b of     Boolean {} -> Boolean        { encode = nicht $ encode b-      , decode = do x <- decode b ; return $ Prelude.not x+      -- , decode = do x <- decode b ; return $ Prelude.not x       }     Constant {} -> Constant { value = Prelude.not $ value b }+{-# INLINABLE not #-}   assert :: MonadSAT m => [ Boolean ] -> m ()+{-# specialize inline assert :: [ Boolean ] -> SAT () #-} assert bs = do     let ( con, uncon ) = partition isConstant bs     let cval = Prelude.or $ map value con     when ( Prelude.not cval ) $ emit $ clause $ map encode uncon+{-# INLINABLE assert #-}  assertW :: MonadSAT m => Weight -> [ Boolean ] -> m () assertW w bs = do@@ -118,7 +133,8 @@ monadic :: Monad m         => ( [ a ] -> m b )         -> ( [ m a ] -> m b )+{-# specialize inline monadic :: ([a] -> SAT b) -> [SAT a] -> SAT b #-}         monadic f ms = do     xs <- sequence ms     f xs-+{-# INLINABLE monadic #-}
Satchmo/Boolean/Op.hs view
@@ -15,9 +15,12 @@ import Satchmo.Code import Satchmo.Boolean.Data +import Satchmo.SAT ( SAT) -- for specializations+ import Control.Monad ( foldM )  and :: MonadSAT m => [ Boolean ] -> m Boolean+{-# specialize inline and :: [ Boolean ] -> SAT Boolean #-} and [] = constant True and [x]= return x and xs = do@@ -29,6 +32,7 @@     return y  or :: MonadSAT m => [ Boolean ] -> m Boolean+{-# specialize inline or :: [ Boolean ] -> SAT Boolean #-} or [] = constant False or [x]= return x or xs = do@@ -36,6 +40,7 @@     return $ not y  xor :: MonadSAT m => [ Boolean ] -> m Boolean+{-# specialize inline xor :: [ Boolean ] -> SAT Boolean #-} xor [] = constant False xor (x:xs) = foldM xor2 x xs @@ -46,6 +51,7 @@         ( Bool -> Bool -> Bool )      -> Boolean -> Boolean       -> m Boolean+{-# specialize inline fun2 :: (Bool -> Bool -> Bool) -> Boolean -> Boolean -> SAT Boolean #-} fun2 f x y = do     r <- boolean     sequence_ $ do@@ -62,6 +68,7 @@         ( Bool -> Bool -> Bool -> Bool )      -> Boolean -> Boolean -> Boolean      -> m Boolean+{-# specialize inline fun3 :: (Bool -> Bool -> Bool -> Bool) -> Boolean -> Boolean -> Boolean -> SAT Boolean #-} fun3 f x y z = do     r <- boolean     sequence_ $ do@@ -76,7 +83,9 @@     return r  xor2 :: MonadSAT m => Boolean -> Boolean -> m Boolean+{-# specialize inline  xor2 :: Boolean -> Boolean -> SAT Boolean #-} xor2 = fun2 (/=)+-- xor2 = xor2_orig  -- for historic reasons: xor2_orig :: MonadSAT m => Boolean -> Boolean -> m Boolean
Satchmo/Code.hs view
@@ -10,17 +10,17 @@  import Satchmo.Data --import Data.Map ( Map )-import qualified Data.Map as M import Data.Array  import Control.Monad.Reader  -class Decode c a where decode :: c -> Decoder a+class Decode c a where +    {-# INLINABLE decode #-}+    decode :: c -> Decoder a -type Decoder a = Reader ( Map Variable Bool ) a+-- type Decoder a = Reader ( Map Variable Bool ) a+type Decoder a = Reader ( Array Variable Bool ) a  instance Decode () () where     decode () = return ()
Satchmo/Data.hs view
@@ -43,17 +43,20 @@ literal :: Bool -> Variable -> Literal literal p v | v /= 0 =      Literal $ if p then v else negate v-+{-# INLINE literal #-}  nicht :: Literal -> Literal nicht ( Literal i ) = Literal $ negate i+{-# INLINE nicht #-}  -- FIXME: should be newtype type Variable = Int  variable :: Literal -> Variable variable ( Literal v ) = abs v+{-# INLINE variable #-}  positive :: Literal -> Bool positive ( Literal v ) = 0 < v +{-# INLINE positive #-}
Satchmo/MonadSAT.hs view
@@ -5,6 +5,7 @@ module Satchmo.MonadSAT  ( MonadSAT(..), Weight+, Header (..)                 )  where@@ -27,9 +28,21 @@  class (Functor m, Monad m) => MonadSAT m where   fresh, fresh_forall :: m Literal+  {-# INLINABLE fresh #-}   emit  :: Clause -> m ()+  {-# INLINABLE emit #-}   emitW :: Weight -> Clause -> m ()+  -- | emit some note (could be printed by the backend)+  note :: String -> m () +type NumClauses = Integer+type NumVars    = Integer++data Header = +     Header { numClauses, numVars :: ! Int+            , universals :: ! [Int]+                     }+     deriving Show  -- ------------------------------------------------------- -- MonadSAT liftings for standard monad transformers
Satchmo/Relation/Data.hs view
@@ -12,15 +12,18 @@ import Satchmo.Code import Satchmo.Boolean +import Satchmo.SAT+ import qualified Data.Array as A import Data.Array hiding ( bounds, (!), indices, assocs )  import Control.Monad ( guard ) -data Relation a b = Relation ( Array (a,b) Boolean ) +newtype Relation a b = Relation ( Array (a,b) Boolean )   relation :: ( Ix a, Ix b, MonadSAT m )           => ((a,b),(a,b)) -> m ( Relation a b ) +{-# specialize inline relation :: ( Ix a, Ix b) => ((a,b),(a,b)) -> SAT ( Relation a b ) #-}  relation bnd = do     pairs <- sequence $ do          p <- range bnd
Satchmo/Relation/Op.hs view
@@ -22,6 +22,8 @@ import Control.Monad ( guard ) import Data.Ix +import Satchmo.SAT+ mirror :: ( Ix a , Ix b ) => Relation a b -> Relation b a mirror r =      let ((a,b),(c,d)) = bounds r@@ -34,6 +36,7 @@ union :: ( Ix a , Ix b, MonadSAT m )        => Relation a b -> Relation a b        -> m ( Relation a b )+{-# specialize inline union :: ( Ix a , Ix b ) => Relation a b -> Relation a b -> SAT ( Relation a b ) #-}       union r s = do     pairs <- sequence $ do         i <- indices r@@ -42,6 +45,7 @@  product :: ( Ix a , Ix b, Ix c, MonadSAT m )          => Relation a b -> Relation b c -> m ( Relation a c )+{-# specialize inline product ::  ( Ix a , Ix b, Ix c ) => Relation a b -> Relation b c -> SAT ( Relation a c ) #-}       product a b = do     let ((ao,al),(au,ar)) = bounds a         ((bo,bl),(bu,br)) = bounds b@@ -58,6 +62,7 @@ intersection :: ( Ix a , Ix b, MonadSAT m )        => Relation a b -> Relation a b        -> m ( Relation a b )+{-# specialize inline intersection ::  ( Ix a , Ix b ) => Relation a b -> Relation a b -> SAT ( Relation a b ) #-}  intersection r s = do     pairs <- sequence $ do         i <- indices r
Satchmo/Relation/Prop.hs view
@@ -22,29 +22,36 @@ import Control.Monad ( guard ) import Data.Ix +import Satchmo.SAT+ implies :: ( Ix a, Ix b, MonadSAT m )          => Relation a b -> Relation a b -> m Boolean+{-# specialize inline implies :: ( Ix a, Ix b ) => Relation a b -> Relation a b -> SAT Boolean #-}       implies r s = monadic and $ do     i <- indices r     return $ or [ not $ r ! i, s ! i ]   symmetric :: ( Ix a, MonadSAT m) => Relation a a -> m Boolean+{-# specialize inline symmetric :: ( Ix a ) => Relation a a -> SAT Boolean #-}       symmetric r = implies r ( mirror r )  irreflexive :: ( Ix a, MonadSAT m) => Relation a a -> m Boolean+{-# specialize inline irreflexive :: ( Ix a ) =>  Relation a a -> SAT Boolean #-}       irreflexive r = and $ do     let ((a,b),(c,d)) = bounds r     x <- range ( a, c)     return $ Satchmo.Boolean.not $ r ! (x,x)   reflexive :: ( Ix a, MonadSAT m) => Relation a a -> m Boolean+{-# specialize inline reflexive :: ( Ix a ) => Relation a a -> SAT Boolean #-}       reflexive r = and $ do     let ((a,b),(c,d)) = bounds r     x <- range (a,c)     return $ r ! (x,x)   regular :: ( Ix a, MonadSAT m) => Int -> Relation a a -> m Boolean+{-# specialize inline regular :: ( Ix a ) => Int -> Relation a a -> SAT Boolean #-}       regular deg r = monadic and $ do     let ((a,b),(c,d)) = bounds r     x <- range ( a , c )@@ -54,6 +61,7 @@  transitive :: ( Ix a, MonadSAT m )             => Relation a a -> m Boolean+{-# specialize inline transitive :: ( Ix a ) => Relation a a -> SAT Boolean #-}       transitive r = do     r2 <- product r r     implies r2 r
Satchmo/SAT.hs view
@@ -1,101 +1,9 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}--module Satchmo.SAT--( SAT, Header(..)-, fresh, fresh_forall-, emit, Weight-, sat-)--where--import Satchmo.Data-import Satchmo.MonadSAT--import Control.Exception-import Control.Monad.RWS.Strict-import qualified  Data.Set as Set-import qualified Data.ByteString.Lazy.Char8 as BS-import System.Directory-import System.Environment-import System.IO---instance MonadSAT SAT where-  fresh = satfresh-  fresh_forall = satfresh_forall-  emit    = satemit-  emitW _ _ = return ()---- ------------------ Implementation--- -----------------data Accu = Accu-          { next :: ! Int-          , universal :: [Int]-          , size :: ! Int-          }--start :: Accu-start = Accu-      { next = 1-      , universal = []-      , size = 0-      }--newtype SAT a = SAT {unsat::RWST Handle () Accu IO a}-    deriving (MonadState Accu, MonadReader Handle, Monad, MonadIO, Functor)--type NumClauses = Integer-type NumVars    = Integer--data Header = Header { numClauses, numVars :: Int-                     , universals :: [Int]-                     }---sat :: SAT a -> IO (BS.ByteString, Header, a )-sat (SAT m) =- bracket-    (getTemporaryDirectory >>= (`openTempFile`  "satchmo"))-    (\(fp, h) -> removeFile fp)-    (\(fp, h) -> do-       hSetBuffering h (BlockBuffering Nothing)-       ~(a, accu, _) <- runRWST m h start-       hClose h-       let header = Header (size accu) (next accu - 1) universals-           universals = reverse $ universal accu--       bs <- BS.readFile fp-       return (bs, header, a))---- | existentially quantified (implicitely so, before first fresh_forall)-satfresh :: SAT Literal-satfresh = do-    a <- get-    let n = next a-    put $ a { next = n + 1 }-    return $ literal True n---- | universally quantified-satfresh_forall :: SAT Literal-satfresh_forall = do-    a <- get-    let n = next a-    put $ a { next = n + 1, universal = n : universal a }-    return $ literal True n--satemit :: Clause -> SAT ()-satemit clause = do-    a <- get-    tellSat (bshowClause clause)-    put $ a-        { size = size a + 1-        }-  where bshowClause c = BS.pack (show c) `mappend` BS.pack "\n"---tellSat x = do {h <- ask; liftIO $ BS.hPut h x}+module Satchmo.SAT ( +  -- module Satchmo.SAT.BS +  -- module Satchmo.SAT.Seq+  module Satchmo.SAT.Tmpfile+) where +import Satchmo.SAT.Seq+import Satchmo.SAT.BS+import Satchmo.SAT.Tmpfile
+ Satchmo/SAT/BS.hs view
@@ -0,0 +1,67 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++module Satchmo.SAT.BS++( SAT, Header(..)+, fresh, fresh_forall+, emit, Weight+, sat+)++where++import Satchmo.Data+import Satchmo.MonadSAT++import Control.Exception++import Control.Monad.RWS.Strict+-- import Control.Monad.RWS.Lazy++-- import qualified Data.ByteString.Lazy.Char8 as BS+import qualified Data.ByteString.Char8 as BS++import Data.Foldable+import Data.String++newtype SAT a +      = SAT { unSAT :: -- WriterT BS.ByteString ( StateT Header Identity ) +                       -- StateT Header ( WriterT BS.ByteString Identity )+                       RWS () BS.ByteString Header+                       -- RWS () ( S.Seq BS.ByteString ) Header+                       a+            } +      deriving ( Functor, Monad+               , MonadState Header+               , MonadWriter BS.ByteString+               -- , MonadWriter ( S.Seq BS.ByteString )+               )+++instance MonadSAT SAT where+  fresh = do +      a <- get +      let v = numVars a+      put $ a { numVars = succ v } +      return $ literal True $ succ v+  emit cl = do+      a <- get+      put $ a { numClauses = succ $ numClauses a }+      tell $  fromString $ show  cl ++ "\n"+  note msg = do+      return ()+     +start :: Header+start = Header { numClauses = 0, numVars = 0+               , universals = []+               }+++sat :: SAT a -> IO (BS.ByteString, Header, a )+sat (SAT m) = do+    let -- ((res,bs),accu) = runState (runWriterT m) start+        -- ((res,accu),bs) = runWriter ( runStateT m  start )+        (res, accu, bs) = runRWS m () start +    return ( bs , accu, res )++
+ Satchmo/SAT/Seq.hs view
@@ -0,0 +1,70 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++module Satchmo.SAT.Seq++( SAT, Header(..)+, fresh, fresh_forall+, emit, Weight+, sat+)++where++import Satchmo.Data+import Satchmo.MonadSAT++import Control.Exception++import Control.Monad.RWS.Strict+-- import Control.Monad.RWS.Lazy++-- import qualified Data.Sequence as S+import qualified Satchmo.SAT.Sequence as S++import qualified Data.ByteString.Char8 as BS+-- import qualified Data.ByteString.Lazy.Char8 as BS++import Data.Foldable+import Data.String++newtype SAT a +      = SAT { unSAT :: -- WriterT BS.ByteString ( StateT Header Identity ) +                       -- StateT Header ( WriterT BS.ByteString Identity )+                       -- RWS () BS.ByteString Header+                       RWS () ( S.Seq BS.ByteString ) Header+                       a+            } +      deriving ( Functor, Monad+               , MonadState Header+               , MonadWriter ( S.Seq BS.ByteString )+               -- , MonadWriter BS.ByteString+               )+++instance MonadSAT SAT where+  note msg = do return ()+  fresh = do +      a <- get +      let v = numVars a+      put $ a { numVars = succ v } +      return $ literal True $ succ v+  emit cl = do+      a <- get+      put $ a { numClauses = succ $ numClauses a }+      tell $  S.singleton $ fromString $ show  cl ++ "\n"++     +start :: Header+start = Header { numClauses = 0, numVars = 0+               , universals = []+               }+++sat :: SAT a -> IO (BS.ByteString, Header, a )+sat (SAT m) = do+    let -- ((res,bs),accu) = runState (runWriterT m) start+        -- ((res,accu),bs) = runWriter ( runStateT m  start )+        (res, accu, bs) = runRWS m () start +    return ( fold bs , accu, res )++
+ Satchmo/SAT/Sequence.hs view
@@ -0,0 +1,26 @@+-- | binary trees without any balance++module Satchmo.SAT.Sequence where++import Data.Monoid+import Data.Foldable++data Seq a = Empty | Leaf !a +           | Branch !(Seq a) !(Seq a)++{-# INLINABLE singleton #-}+singleton x = Leaf x++instance Monoid (Seq a) where+    {-# INLINABLE mappend #-}+    mappend = Branch+    {-# INLINABLE mempty #-}+    mempty = Empty++instance Foldable Seq where+    {-# INLINABLE fold #-}+    fold s = case s of+        Empty -> mempty+        Leaf k -> k+        Branch l r -> mappend (fold l) (fold r)+        
+ Satchmo/SAT/Tmpfile.hs view
@@ -0,0 +1,116 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++module Satchmo.SAT.Tmpfile++( SAT, Header(..)+, fresh, fresh_forall+, emit, Weight+, sat+)++where++import Satchmo.Data+import Satchmo.MonadSAT++import Control.Exception+import Control.Monad.RWS.Strict+import qualified  Data.Set as Set++-- import qualified Data.ByteString.Lazy.Char8 as BS+import qualified Data.ByteString.Char8 as BS++import System.Directory+import System.Environment+import System.IO++import qualified Data.Map as M++import Data.List ( sortBy )+import Data.Ord ( comparing )++instance MonadSAT SAT where+  fresh = satfresh+  fresh_forall = satfresh_forall+  emit    = satemit+  emitW _ _ = return ()+  note msg = do a <- get ; put $ a { notes = msg : notes a }++-- ---------------+-- Implementation+-- ---------------++data Accu = Accu+          { next :: ! Int+          , universal :: [Int]+          , size :: ! Int+          , notes :: ! [ String ]+          , census :: ! ( M.Map Int Int )+          }++start :: Accu+start = Accu+      { next = 1+      , universal = []+      , size = 0+      , notes = [ "Satchmo.SAT.Tmpfile implementation" ]+      , census = M.empty          +      }++newtype SAT a = SAT {unsat::RWST Handle () Accu IO a}+    deriving (MonadState Accu, MonadReader Handle, Monad, MonadIO, Functor)+++sat :: SAT a -> IO (BS.ByteString, Header, a )+sat (SAT m) =+ bracket+    (getTemporaryDirectory >>= (`openTempFile`  "satchmo"))+    (\(fp, h) -> removeFile fp)+    (\(fp, h) -> do+       hSetBuffering h (BlockBuffering Nothing)+       ~(a, accu, _) <- runRWST m h start+       hClose h+       +       forM ( reverse $ notes accu ) $ hPutStrLn stderr +       hPutStrLn stderr $ unlines +           [ "(clause length, frequency)"+           , show $ sortBy ( comparing ( negate . snd )) +                        $ M.toList $ census accu+           ]  +       +       let header = Header (size accu) (next accu - 1) universals+           universals = reverse $ universal accu++       bs <- BS.readFile fp+       return (bs, header, a))++-- | existentially quantified (implicitely so, before first fresh_forall)+satfresh :: SAT Literal+satfresh = do+    a <- get+    let n = next a+    put $ a { next = n + 1 }+    return $ literal True n++-- | universally quantified+satfresh_forall :: SAT Literal+satfresh_forall = do+    a <- get+    let n = next a+    put $ a { next = n + 1, universal = n : universal a }+    return $ literal True n++satemit :: Clause -> SAT ()+satemit clause = do+    h <- ask ; liftIO $ hPutStrLn h $ show clause+    a <- get+    -- tellSat (bshowClause clause)+    put $ a+        { size = size a + 1+        , census = M.insertWith (+) (length $ literals clause) 1 $ census a         +        }+  where bshowClause c = BS.pack (show c) `mappend` BS.pack "\n"+++tellSat x = do {h <- ask; liftIO $ BS.hPut h x}+
Satchmo/SAT/Weighted.hs view
@@ -2,13 +2,14 @@ module Satchmo.SAT.Weighted (SAT, sat, MaxWeight, Header(..)) where  import Satchmo.Data-import Satchmo.MonadSAT+import Satchmo.MonadSAT hiding ( Header )  import Control.Exception import Control.Monad.RWS.Strict import Data.Maybe import qualified  Data.Set as Set-import qualified Data.ByteString.Lazy.Char8 as BS+-- import qualified Data.ByteString.Lazy.Char8 as BS+import qualified Data.ByteString.Char8 as BS import System.Directory import System.Environment import System.IO
Satchmo/Solve.hs view
@@ -15,23 +15,25 @@ import Satchmo.SAT import qualified Satchmo.SAT.Weighted as Weighted -import qualified Data.ByteString.Lazy.Char8 as BS+-- import qualified Data.ByteString.Lazy.Char8 as BS+import qualified Data.ByteString.Char8 as BS+ import Data.Map ( Map ) import qualified Data.Map as M-+import Data.Array import Control.Monad.Reader  import System.IO  type Implementation = BS.ByteString                      -> Header -                    -> IO ( Maybe ( Map Variable Bool ) )+                    -> IO ( Maybe ( Array Variable Bool ) )  type WeightedImplementation = BS.ByteString -                            -> Weighted.Header -                            -> IO ( Maybe ( Map Variable Bool ) )+    -> Weighted.Header +    -> IO ( Maybe ( Array Variable Bool ) ) -solve :: Implementation +solve :: Implementation       -> SAT ( Decoder a )        -> IO ( Maybe a ) solve implementation build = do
satchmo.cabal view
@@ -1,5 +1,5 @@ Name:           satchmo-Version:        1.8.1+Version:        1.9.1  License:        GPL License-file:	gpl-2.0.txt@@ -17,6 +17,7 @@ build-type: Simple  Library+    ghc-options: -funbox-strict-fields     Build-depends:  mtl, process, containers, base == 4.*, array, bytestring, directory     Exposed-modules:         Satchmo.Data@@ -36,6 +37,10 @@         Satchmo.Relation.Prop         Satchmo.MonadSAT         Satchmo.SAT+        Satchmo.SAT.Tmpfile+        Satchmo.SAT.BS+        Satchmo.SAT.Seq+        Satchmo.SAT.Sequence         Satchmo.Simple         Satchmo.SAT.Weighted     Other-modules: