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

msakai / pseudo-boolean / 56

13 Mar 2024 02:01PM UTC coverage: 92.655% (-1.1%) from 93.714%
56

push

github

msakai
Merge branch 'update-ci-202403'

492 of 531 relevant lines covered (92.66%)

0.93 hits per line

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

95.16
/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 Data.Monoid hiding (Sum (..))
36
import qualified Data.ByteString.Lazy as BS
37
import Data.ByteString.Builder (Builder, intDec, integerDec, char7, string7, hPutBuilder, toLazyByteString)
38
import Data.Ord
39
import System.IO
40
import Data.PseudoBoolean.Types
41

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

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

88
showSum :: Sum -> Builder
89
showSum = mconcat . map showWeightedTerm
1✔
90

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

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

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

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

115

116

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

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

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

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

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

147

148
-- | Output a WBO file to a 'Handle' using 'hPutBuilder'.
149
--
150
-- It is recommended that the 'Handle' is set to binary and
151
-- 'BlockBuffering' mode. See 'hSetBinaryMode' and 'hSetBuffering'.
152
--
153
-- This function is more efficient than 'hPut' . 'toWBOByteString'
154
-- because in many cases no buffer allocation has to be done.
155
hPutWBO :: Handle -> SoftFormula -> IO ()
156
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