packages feed

pseudo-boolean 0.1.0.1 → 0.1.1.0

raw patch · 8 files changed

+107/−16 lines, 8 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

+ CHANGELOG.markdown view
@@ -0,0 +1,5 @@+0.1.1.0+-------+* parse* functions fails if the parser does not consume all of the inputs+* generate '#product=', 'sizeproduct=' and '#soft=' in header line of OPB/WBO files+* sort literals in a non-linear term when generating OPB/WBO files
pseudo-boolean.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                pseudo-boolean-version:             0.1.0.1+version:             0.1.1.0 synopsis:            Reading/Writing OPB/WBO files used in pseudo boolean competition description:         Reading\/Writing OPB\/WBO files used in pseudo boolean competition homepage:            https://github.com/msakai/pseudo-boolean@@ -16,6 +16,7 @@ build-type:          Simple extra-source-files:     README.md+    CHANGELOG.markdown     test/samples/*.opb     test/samples/normalized-1096.cudf.paranoid.opb     test/samples/*.wbo
src/Data/PseudoBoolean/Attoparsec.hs view
@@ -33,7 +33,7 @@   ) where  import Prelude hiding (sum)-import Control.Applicative ((<|>))+import Control.Applicative ((<|>), (<*)) import Control.Monad import Data.Attoparsec.ByteString.Char8 hiding (isDigit) import qualified Data.Attoparsec.ByteString.Lazy as L@@ -201,7 +201,7 @@  -- | Parse a OPB format string containing pseudo boolean problem. parseOPBByteString :: BSLazy.ByteString -> Either String Formula-parseOPBByteString s = L.eitherResult $ L.parse formula s+parseOPBByteString s = L.eitherResult $ L.parse (formula <* endOfInput) s  -- | Parse a OPB file containing pseudo boolean problem. parseOPBFile :: FilePath -> IO (Either String Formula)@@ -260,7 +260,7 @@  -- | Parse a WBO format string containing weighted boolean optimization problem. parseWBOByteString :: BSLazy.ByteString -> Either String SoftFormula-parseWBOByteString s = L.eitherResult $ L.parse softformula s+parseWBOByteString s = L.eitherResult $ L.parse (softformula <* endOfInput) s  -- | Parse a WBO file containing weighted boolean optimization problem. parseWBOFile :: FilePath -> IO (Either String SoftFormula)
src/Data/PseudoBoolean/Builder.hs view
@@ -21,9 +21,14 @@   , toWBOString   ) where +import qualified Prelude import Prelude hiding (sum) import qualified Data.DList as DList+import qualified Data.IntSet as IntSet+import qualified Data.Set as Set+import Data.List (sortBy) import Data.Monoid hiding (Sum (..))+import Data.Ord import Data.String import Text.Printf import Data.PseudoBoolean.Types@@ -34,7 +39,12 @@   where     nv = pbNumVars opb     nc = pbNumConstraints opb-    size = fromString (printf "* #variable= %d #constraint= %d\n" nv nc)+    p = pbProducts opb+    np = Set.size p+    sp = Prelude.sum [IntSet.size tm | tm <- Set.toList p]+    size = fromString (printf "* #variable= %d #constraint= %d" nv nc)+         <> (if np >= 1 then fromString (printf " #product= %d sizeproduct= %d" np sp) else mempty)+         <> fromString "\n"     part1 =        case pbObjectiveFunction opb of         Nothing -> mempty@@ -47,7 +57,13 @@   where     nv = wboNumVars wbo     nc = wboNumConstraints wbo-    size = fromString (printf "* #variable= %d #constraint= %d\n" nv nc)+    p = wboProducts wbo+    np = Set.size p+    sp = Prelude.sum [IntSet.size tm | tm <- Set.toList p]+    size = fromString (printf "* #variable= %d #constraint= %d" nv nc)+         <> (if np >= 1 then fromString (printf " #product= %d sizeproduct= %d" np sp) else mempty)+         <> fromString (printf " #soft= %d" (wboNumSoft wbo))+         <> fromString "\n"     part1 =        case wboTopCost wbo of         Nothing -> fromString "soft: ;\n"@@ -61,7 +77,7 @@ showWeightedTerm (c, lits) = foldr (\f g -> f <> fromString " " <> g) mempty (x:xs)   where     x = if c >= 0 then fromString "+" <> fromString (show c) else fromString (show c)-    xs = map showLit lits+    xs = map showLit $ sortBy (comparing abs) lits  showLit :: (Monoid a, IsString a) => Lit -> a showLit lit = if lit > 0 then v else fromString "~" <> v
src/Data/PseudoBoolean/ByteStringBuilder.hs view
@@ -27,10 +27,15 @@   , hPutWBO   ) where +import qualified Prelude import Prelude hiding (sum)+import qualified Data.IntSet as IntSet+import qualified Data.Set as Set+import Data.List (sortBy) import Data.Monoid hiding (Sum (..)) import qualified Data.ByteString.Lazy as BS import Data.ByteString.Builder (Builder, intDec, integerDec, char7, string7, hPutBuilder, toLazyByteString)+import Data.Ord import System.IO import Data.PseudoBoolean.Types @@ -40,7 +45,12 @@   where     nv = pbNumVars opb     nc = pbNumConstraints opb-    size = string7 "* #variable= " <> intDec nv <> string7 " #constraint= " <> intDec nc <> char7 '\n'+    p = pbProducts opb+    np = Set.size p+    sp = Prelude.sum [IntSet.size tm | tm <- Set.toList p]+    size = string7 "* #variable= " <> intDec nv <> string7 " #constraint= " <> intDec nc+         <> (if np >= 1 then string7 " #product= " <> intDec np <> string7 " sizeproduct= " <> intDec sp else mempty)+         <> char7 '\n'     part1 =        case pbObjectiveFunction opb of         Nothing -> mempty@@ -53,7 +63,13 @@   where     nv = wboNumVars wbo     nc = wboNumConstraints wbo-    size = string7 "* #variable= " <> intDec nv <> string7 " #constraint= " <> intDec nc <> char7 '\n'+    p = wboProducts wbo+    np = Set.size p+    sp = Prelude.sum [IntSet.size tm | tm <- Set.toList p]+    size = string7 "* #variable= " <> intDec nv <> string7 " #constraint= " <> intDec nc+         <> (if np >= 1 then string7 " #product= " <> intDec np <> string7 " sizeproduct= " <> intDec sp else mempty)+         <> string7 " #soft= " <> intDec (wboNumSoft wbo)+         <> char7 '\n'     part1 =        case wboTopCost wbo of         Nothing -> string7 "soft: ;\n"@@ -67,7 +83,7 @@ showWeightedTerm (c, lits) = foldr (\f g -> f <> char7 ' ' <> g) mempty (x:xs)   where     x = if c >= 0 then char7 '+' <> integerDec c else integerDec c-    xs = map showLit lits+    xs = map showLit $ sortBy (comparing abs) lits  showLit :: Lit -> Builder showLit lit = if lit > 0 then v else char7 '~' <> v
src/Data/PseudoBoolean/Parsec.hs view
@@ -35,6 +35,7 @@   ) where  import Prelude hiding (sum)+import Control.Applicative ((<*)) import Control.Monad import Data.ByteString.Lazy (ByteString) import Data.Maybe@@ -200,15 +201,15 @@  -- | Parse a OPB format string containing pseudo boolean problem. parseOPBString :: SourceName -> String -> Either ParseError Formula-parseOPBString = parse formula+parseOPBString = parse (formula <* eof)  -- | Parse a OPB format lazy bytestring containing pseudo boolean problem. parseOPBByteString :: SourceName -> ByteString -> Either ParseError Formula-parseOPBByteString = parse formula+parseOPBByteString = parse (formula <* eof)  -- | Parse a OPB file containing pseudo boolean problem. parseOPBFile :: FilePath -> IO (Either ParseError Formula)-parseOPBFile = ParsecBS.parseFromFile formula+parseOPBFile = ParsecBS.parseFromFile (formula <* eof)   -- <softformula>::= <sequence_of_comments> <softheader> <sequence_of_comments_or_constraints>@@ -262,12 +263,12 @@  -- | Parse a WBO format string containing weighted boolean optimization problem. parseWBOString :: SourceName -> String -> Either ParseError SoftFormula-parseWBOString = parse softformula+parseWBOString = parse (softformula <* eof)  -- | Parse a WBO format lazy bytestring containing pseudo boolean problem. parseWBOByteString :: SourceName -> ByteString -> Either ParseError SoftFormula-parseWBOByteString = parse softformula+parseWBOByteString = parse (softformula <* eof)  -- | Parse a WBO file containing weighted boolean optimization problem. parseWBOFile :: FilePath -> IO (Either ParseError SoftFormula)-parseWBOFile = ParsecBS.parseFromFile softformula+parseWBOFile = ParsecBS.parseFromFile (softformula <* eof)
src/Data/PseudoBoolean/Types.hs view
@@ -33,12 +33,20 @@    -- * Internal utilities   , pbComputeNumVars+  , pbProducts   , wboComputeNumVars+  , wboProducts+  , wboNumSoft   ) where  import GHC.Generics (Generic)+import Control.Monad import Control.DeepSeq import Data.Data+import Data.Set (Set)+import qualified Data.Set as Set+import Data.IntSet (IntSet)+import qualified Data.IntSet as IntSet import Data.Hashable import Data.Maybe @@ -117,3 +125,22 @@       (_, tm) <- s       lit <- tm       return $ abs lit++pbProducts :: Formula -> Set IntSet+pbProducts formula = Set.fromList $ do  +  s <- maybeToList (pbObjectiveFunction formula) ++ [s | (s,_,_) <- pbConstraints formula]+  (_, tm)  <- s+  let tm2 = IntSet.fromList tm+  guard $ IntSet.size tm2 > 1+  return tm2++wboProducts :: SoftFormula -> Set IntSet+wboProducts softformula = Set.fromList $ do+  (_,(s,_,_)) <- wboConstraints softformula+  (_, tm) <- s+  let tm2 = IntSet.fromList tm+  guard $ IntSet.size tm2 > 1+  return tm2++wboNumSoft :: SoftFormula -> Int+wboNumSoft softformula = length [() | (Just _, _) <- wboConstraints softformula]
test/TestPBFile.hs view
@@ -2,6 +2,7 @@ {-# OPTIONS_GHC -Wall #-} module Main (main) where +import Data.Either import qualified Data.ByteString.Lazy.Char8 as BSChar8 import System.IO import System.IO.Temp@@ -36,6 +37,30 @@ case_normalized_mds_50_10_4 = checkOPBFile "test/samples/normalized-mds_50_10_4.opb" case_normalized_opt_market_split_4_30_2 = checkOPBFile "test/samples/normalized-opt-market-split_4_30_2.opb" case_pigeonhole_5_4 = checkOPBFile "test/samples/pigeonhole_5_4.opb"++case_trailing_junk = do+  isError (parseOPBString "" trailingJunk) @?= True+  isError (parseOPBByteString "" (BSChar8.pack trailingJunk)) @?= True+  isError (A.parseOPBByteString (BSChar8.pack trailingJunk)) @?= True+  where+    -- isLeft is available only on base >=4.7.0.0.+    isError :: Either a b -> Bool+    isError (Left _) = True+    isError (Right _) = False+    +    trailingJunk = unlines+      [ "* #variable= 5 #constraint= 4"+      , "*"+      , "* this is a dummy instance"+      , "*"+      , "min: 1 x2 -1 x3 ;"+      , "1 x1 +4 x2 -2 x5 >= 2;"+      , "-1 x1 +4 x2 -2 x5 >= +3;"+      , "12345678901234567890 x4 +4 x3 >= 10;"+      , "* an equality constraint"+      , "2 x2 +3 x4 +2 x1 +3 x5 = 5;"+      , "foo"+      ]  case_readUnsignedInteger_maxBound_bug :: IO () case_readUnsignedInteger_maxBound_bug =