• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

msakai / pseudo-boolean / 68

20 Mar 2024 04:06PM UTC coverage: 91.852% (-0.8%) from 92.655%
68

push

github

web-flow
Merge 8068d466f into 58d52c9b2

17 of 22 new or added lines in 6 files covered. (77.27%)

9 existing lines in 3 files now uncovered.

496 of 540 relevant lines covered (91.85%)

0.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.85
/src/Data/PseudoBoolean/ByteStringBuilder.hs
1
{-# OPTIONS_GHC -Wall #-}
2
-----------------------------------------------------------------------------
3
-- |
4
-- Module      :  Data.PseudoBoolean.ByteStringBuilder
5
-- Copyright   :  (c) Masahiro Sakai 2011-2015
6
-- License     :  BSD-style
7
-- 
8
-- Maintainer  :  masahiro.sakai@gmail.com
9
-- Portability :  portable
10
--
11
-----------------------------------------------------------------------------
12

13
module Data.PseudoBoolean.ByteStringBuilder
14
  (
15
  -- * Builder for (Lazy) ByteString generation
16
    opbBuilder
17
  , wboBuilder
18

19
  -- * Lazy ByteString generation
20
  , toOPBByteString
21
  , toWBOByteString
22

23
  -- * File I/O
24
  , writeOPBFile
25
  , writeWBOFile
26
  , hPutOPB
27
  , hPutWBO
28
  ) where
29

30
import qualified Prelude
31
import Prelude hiding (sum)
32
import qualified Data.IntSet as IntSet
33
import qualified Data.Set as Set
34
import Data.List (sortBy)
35
import qualified Data.ByteString.Lazy as BS
36
import Data.ByteString.Builder (Builder, intDec, integerDec, char7, string7, hPutBuilder, toLazyByteString)
37
import Data.Ord
38
import System.IO
39
import Data.PseudoBoolean.Types
40

41
-- | A ByteString Builder which renders a OPB format byte-string containing pseudo boolean problem.
42
opbBuilder :: Formula -> Builder
43
opbBuilder opb = (size <> part1 <> part2)
1✔
44
  where
45
    nv = pbNumVars opb
1✔
46
    nc = pbNumConstraints opb
1✔
47
    p = pbProducts opb
1✔
48
    np = Set.size p
1✔
49
    sp = Prelude.sum [IntSet.size tm | tm <- Set.toList p]
1✔
50
    size = string7 "* #variable= " <> intDec nv <> string7 " #constraint= " <> intDec nc
1✔
51
         <> (if np >= 1 then string7 " #product= " <> intDec np <> string7 " sizeproduct= " <> intDec sp else mempty)
1✔
52
         <> char7 '\n'
1✔
53
    part1 = 
1✔
54
      case pbObjectiveFunction opb of
1✔
55
        Nothing -> mempty
1✔
56
        Just (dir, o) ->
57
          (case dir of
1✔
58
            OptMin -> string7 "min"
1✔
NEW
59
            OptMax -> string7 "max")
×
60
          <> string7 ": " <> showSum o <> string7 ";\n"
1✔
61
    part2 = mconcat $ map showConstraint (pbConstraints opb)
1✔
62

63
-- | A ByteString Builder which renders a WBO format byte-string containing weighted boolean optimization problem.
64
wboBuilder :: SoftFormula -> Builder
65
wboBuilder wbo = size <> part1 <> part2
1✔
66
  where
67
    nv = wboNumVars wbo
1✔
68
    nc = wboNumConstraints wbo
1✔
69
    p = wboProducts wbo
1✔
70
    np = Set.size p
1✔
71
    sp = Prelude.sum [IntSet.size tm | tm <- Set.toList p]
×
72
    mincost =
1✔
73
      case [c | (Just c, _) <- wboConstraints wbo] of
1✔
74
        [] -> 1 -- this should not happen
×
75
        cs -> minimum cs
1✔
76
    maxcost = maximum $ 0 : [c | (Just c, _) <- wboConstraints wbo]
1✔
77
    sumcost = Prelude.sum [c | (Just c, _) <- wboConstraints wbo]
1✔
78
    size = string7 "* #variable= " <> intDec nv <> string7 " #constraint= " <> intDec nc
1✔
79
         <> (if np >= 1 then string7 " #product= " <> intDec np <> string7 " sizeproduct= " <> intDec sp else mempty)
×
80
         <> string7 " #soft= " <> intDec (wboNumSoft wbo)
1✔
81
         <> string7 " #mincost= " <> integerDec mincost
1✔
82
         <> string7 " #maxcost= " <> integerDec maxcost
1✔
83
         <> string7 " #sumcost= " <> integerDec sumcost
1✔
84
         <> char7 '\n'
1✔
85
    part1 = 
1✔
86
      case wboTopCost wbo of
1✔
87
        Nothing -> string7 "soft: ;\n"
1✔
88
        Just t -> string7 "soft: " <> integerDec t <> string7 ";\n"
1✔
89
    part2 = mconcat $ map showSoftConstraint (wboConstraints wbo)
1✔
90

91
showSum :: Sum -> Builder
92
showSum = mconcat . map showWeightedTerm
1✔
93

94
showWeightedTerm :: WeightedTerm -> Builder
95
showWeightedTerm (c, lits) = foldr (\f g -> f <> char7 ' ' <> g) mempty (x:xs)
1✔
96
  where
97
    x = if c >= 0 then char7 '+' <> integerDec c else integerDec c
1✔
98
    xs = map showLit $ sortBy (comparing abs) lits
1✔
99

100
showLit :: Lit -> Builder
101
showLit lit = if lit > 0 then v else char7 '~' <> v
1✔
102
  where
103
    v = char7 'x' <> intDec (abs lit)
1✔
104

105
showConstraint :: Constraint -> Builder
106
showConstraint (lhs, op, rhs) =
1✔
107
  showSum lhs <> f op <>  char7 ' ' <> integerDec rhs <> string7 ";\n"
1✔
108
  where
109
    f Eq = char7 '='
1✔
110
    f Ge = string7 ">="
1✔
111

112
showSoftConstraint :: SoftConstraint -> Builder
113
showSoftConstraint (cost, constr) =
1✔
114
  case cost of
1✔
115
    Nothing -> showConstraint constr
1✔
116
    Just c -> char7 '[' <> integerDec c <> string7 "] " <> showConstraint constr
1✔
117

118

119

120
-- | Generate a OPB format byte-string containing pseudo boolean problem.
121
toOPBByteString :: Formula -> BS.ByteString
122
toOPBByteString opb = toLazyByteString (opbBuilder opb)
1✔
123

124
-- | Generate a WBO format byte-string containing weighted boolean optimization problem.
125
toWBOByteString :: SoftFormula -> BS.ByteString
126
toWBOByteString wbo = toLazyByteString (wboBuilder wbo)
1✔
127

128
-- | Output a OPB file containing pseudo boolean problem.
129
writeOPBFile :: FilePath -> Formula -> IO ()
130
writeOPBFile filepath opb = withBinaryFile filepath WriteMode $ \h -> do
1✔
131
  hSetBuffering h (BlockBuffering Nothing)
1✔
132
  hPutOPB h opb
1✔
133

134
-- | Output a WBO file containing weighted boolean optimization problem.
135
writeWBOFile :: FilePath -> SoftFormula -> IO ()
136
writeWBOFile filepath wbo = withBinaryFile filepath WriteMode $ \h -> do
1✔
137
  hSetBuffering h (BlockBuffering Nothing)
1✔
138
  hPutWBO h wbo
1✔
139

140
-- | Output a OPB file to a 'Handle' using 'hPutBuilder'.
141
--
142
-- It is recommended that the 'Handle' is set to binary and
143
-- 'BlockBuffering' mode. See 'hSetBinaryMode' and 'hSetBuffering'.
144
--
145
-- This function is more efficient than 'hPut' . 'toOPBByteString'
146
-- because in many cases no buffer allocation has to be done.
147
hPutOPB :: Handle -> Formula -> IO ()
148
hPutOPB h opb = hPutBuilder h (opbBuilder opb)
1✔
149

150

151
-- | Output a WBO file to a 'Handle' using 'hPutBuilder'.
152
--
153
-- It is recommended that the 'Handle' is set to binary and
154
-- 'BlockBuffering' mode. See 'hSetBinaryMode' and 'hSetBuffering'.
155
--
156
-- This function is more efficient than 'hPut' . 'toWBOByteString'
157
-- because in many cases no buffer allocation has to be done.
158
hPutWBO :: Handle -> SoftFormula -> IO ()
159
hPutWBO h wbo = hPutBuilder h (wboBuilder wbo)
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc