mios-1.5.4: src/SAT/Mios/Util/DIMACS/MinisatReader.hs
{-# LANGUAGE Safe #-}
-- | Read an output file of minisat
module SAT.Mios.Util.DIMACS.MinisatReader
(
-- * Interface
fromMinisatOutput
, clauseListFromMinisatOutput
)
where
-- import Control.Applicative ((<$>), (<*>), (<*), (*>))
import Data.Char
import Text.ParserCombinators.ReadP
-- parser
-- |parse a non-signed integer
{-# INLINE pint #-}
pint :: ReadP Int
pint = do
n <- munch isDigit
return (read n :: Int)
{-# INLINE mint #-}
mint :: ReadP Int
mint = do
char '-'
n <- munch isDigit
return (- (read n::Int))
-- |parse a (signed) integer
{-# INLINE int #-}
int :: ReadP Int
int = mint <++ pint
-- |return integer list that terminates at zero
{-# INLINE seqNums #-}
seqNums :: ReadP [Int]
seqNums = do
skipSpaces
x <- int
skipSpaces
if x == 0 then return [] else (x :) <$> seqNums
-- |top level interface for parsing CNF
{-# INLINE parseMinisatOutput #-}
parseMinisatOutput :: ReadP ((Int, Int), [Int])
parseMinisatOutput = do
string "SAT"
skipSpaces
l <- seqNums
return ((length l,0), l)
-- |read a minisat output:
-- ((numbefOfVariables, 0), [Literal])
--
-- >>> fromFile "result"
-- ((3, 0), [1, -2, 3])
--
{-# INLINE fromMinisatOutput #-}
fromMinisatOutput :: FilePath -> IO (Maybe ((Int, Int), [Int]))
fromMinisatOutput f = do
c <- readFile f
case readP_to_S parseMinisatOutput c of
[(a, _)] -> return $ Just a
_ -> return Nothing
-- | return clauses as [[Int]] from 'file'
--
-- >>> clauseListFromMinisatOutput "result"
-- [1,-2,3]
--
clauseListFromMinisatOutput :: FilePath -> IO [Int]
clauseListFromMinisatOutput l = do
res <- fromMinisatOutput l
case res of
Just p -> return (snd p)
_ -> return []