module ToySolver.Converter.WBO2PB (convert) where
import Data.Array.IArray
import qualified ToySolver.SAT.Types as SAT
import qualified Data.PseudoBoolean as PBFile
convert :: PBFile.SoftFormula -> (PBFile.Formula, SAT.Model -> SAT.Model)
convert wbo = (formula, mtrans)
where
nv = PBFile.wboNumVars wbo
cm = zip [nv+1..] (PBFile.wboConstraints wbo)
obj = [(w, [i]) | (i, (Just w,_)) <- cm]
f :: (PBFile.Var, PBFile.SoftConstraint) -> [PBFile.Constraint]
f (_, (Nothing, c)) = return c
f (i, (Just _, c)) = relax i c
relax :: PBFile.Var -> PBFile.Constraint -> [PBFile.Constraint]
relax i (lhs, PBFile.Ge, rhs) = [((d, [i]) : lhs, PBFile.Ge, rhs)]
where
d = rhs SAT.pbLowerBound [(c,1) | (c,_) <- lhs]
relax i (lhs, PBFile.Eq, rhs) =
relax i (lhs, PBFile.Ge, rhs) ++
relax i ([(c,ls) | (c,ls) <- lhs], PBFile.Ge, rhs)
topConstr :: [PBFile.Constraint]
topConstr =
case PBFile.wboTopCost wbo of
Nothing -> []
Just t -> [([(c,ls) | (c,ls) <- obj], PBFile.Ge, (t 1))]
formula =
PBFile.Formula
{ PBFile.pbObjectiveFunction = Just obj
, PBFile.pbConstraints = cs
, PBFile.pbNumVars = nv + PBFile.wboNumConstraints wbo
, PBFile.pbNumConstraints = length cs
}
where
cs = topConstr ++ concatMap f cm
mtrans :: SAT.Model -> SAT.Model
mtrans m =
array (1, nv) [(x, m ! x) | x <- [1..nv]]