{-# OPTIONS_GHC -Wall #-} {-# LANGUAGE OverloadedStrings #-} ----------------------------------------------------------------------------- -- | -- Module : ToySolver.Converter.PB2SMP -- Copyright : (c) Masahiro Sakai 2013,2016 -- License : BSD-style -- -- Maintainer : masahiro.sakai@gmail.com -- Stability : experimental -- Portability : non-portable (OverloadedStrings) -- ----------------------------------------------------------------------------- module ToySolver.Converter.PB2SMP ( convert ) where import Data.ByteString.Builder import Data.List import Data.Monoid import qualified Data.PseudoBoolean as PBFile convert :: Bool -> PBFile.Formula -> Builder convert isUnix formula = header <> decls <> char7 '\n' <> obj2 <> char7 '\n' <> constrs <> char7 '\n' <> actions <> footer where nv = PBFile.pbNumVars formula header = if isUnix then byteString "#include \"simple.h\"\nvoid ufun()\n{\n\n" else mempty footer = if isUnix then "\n}\n" else mempty actions = byteString $ "solve();\n" <> "x[i].val.print();\n" <> "cost.val.print();\n" decls = byteString "Element i(set=\"1 .. " <> intDec nv <> byteString "\");\nIntegerVariable x(type=binary, index=i);\n" constrs = mconcat [ showSum lhs <> op2 <> integerDec rhs <> ";\n" | (lhs, op, rhs) <- PBFile.pbConstraints formula , let op2 = case op of PBFile.Ge -> " >= " PBFile.Eq -> " == " ] showSum :: PBFile.Sum -> Builder showSum [] = char7 '0' showSum xs = mconcat $ intersperse " + " $ map showTerm xs showTerm (n,ls) = mconcat $ intersperse (char7 '*') $ showCoeff n ++ [showLit l | l<-ls] showCoeff n | n == 1 = [] | n < 0 = [char7 '(' <> integerDec n <> char7 ')'] | otherwise = [integerDec n] showLit l = if l < 0 then "(1-x[" <> intDec (abs l) <> "])" else "x[" <> intDec l <> "]" obj2 = case PBFile.pbObjectiveFunction formula of Just obj' -> byteString "Objective cost(type=minimize);\ncost = " <> showSum obj' <> ";\n" Nothing -> mempty