pseudo-boolean-0.1.0.0: src/Data/PseudoBoolean/Builder.hs
{-# OPTIONS_GHC -Wall #-}
-----------------------------------------------------------------------------
-- |
-- Module : Data.PseudoBoolean.Builder
-- Copyright : (c) Masahiro Sakai 2011-2015
-- License : BSD-style
--
-- Maintainer : masahiro.sakai@gmail.com
-- Portability : portable
--
-----------------------------------------------------------------------------
module Data.PseudoBoolean.Builder
(
-- * Builder for String-like Monoid
opbBuilder
, wboBuilder
-- * String generation
, toOPBString
, toWBOString
) where
import Prelude hiding (sum)
import qualified Data.DList as DList
import Data.Monoid hiding (Sum (..))
import Data.String
import Text.Printf
import Data.PseudoBoolean.Types
-- | A builder which renders a OPB format in any String-like 'Monoid'.
opbBuilder :: (Monoid a, IsString a) => Formula -> a
opbBuilder opb = (size <> part1 <> part2)
where
nv = pbNumVars opb
nc = pbNumConstraints opb
size = fromString (printf "* #variable= %d #constraint= %d\n" nv nc)
part1 =
case pbObjectiveFunction opb of
Nothing -> mempty
Just o -> fromString "min: " <> showSum o <> fromString ";\n"
part2 = mconcat $ map showConstraint (pbConstraints opb)
-- | A builder which renders a WBO format in any String-like 'Monoid'.
wboBuilder :: (Monoid a, IsString a) => SoftFormula -> a
wboBuilder wbo = size <> part1 <> part2
where
nv = wboNumVars wbo
nc = wboNumConstraints wbo
size = fromString (printf "* #variable= %d #constraint= %d\n" nv nc)
part1 =
case wboTopCost wbo of
Nothing -> fromString "soft: ;\n"
Just t -> fromString "soft: " <> fromString (show t) <> fromString ";\n"
part2 = mconcat $ map showSoftConstraint (wboConstraints wbo)
showSum :: (Monoid a, IsString a) => Sum -> a
showSum = mconcat . map showWeightedTerm
showWeightedTerm :: (Monoid a, IsString a) => WeightedTerm -> a
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
showLit :: (Monoid a, IsString a) => Lit -> a
showLit lit = if lit > 0 then v else fromString "~" <> v
where
v = fromString "x" <> fromString (show (abs lit))
showConstraint :: (Monoid a, IsString a) => Constraint -> a
showConstraint (lhs, op, rhs) =
showSum lhs <> f op <> fromString " " <> fromString (show rhs) <> fromString ";\n"
where
f Eq = fromString "="
f Ge = fromString ">="
showSoftConstraint :: (Monoid a, IsString a) => SoftConstraint -> a
showSoftConstraint (cost, constr) =
case cost of
Nothing -> showConstraint constr
Just c -> fromString "[" <> fromString (show c) <> fromString "] " <> showConstraint constr
-- | Generate a OPB format string containing pseudo boolean problem.
toOPBString :: Formula -> String
toOPBString opb = DList.apply (opbBuilder opb) ""
-- | Generate a WBO format string containing weighted boolean optimization problem.
toWBOString :: SoftFormula -> String
toWBOString wbo = DList.apply (wboBuilder wbo) ""