{-# OPTIONS_HADDOCK show-extensions #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
module ToySolver.SAT.Types
(
Var
, VarSet
, VarMap
, validVar
, IModel (..)
, Model
, restrictModel
, Lit
, LitSet
, LitMap
, litUndef
, validLit
, literal
, litNot
, litVar
, litPolarity
, evalLit
, Clause
, normalizeClause
, instantiateClause
, clauseSubsume
, evalClause
, clauseToPBLinAtLeast
, PackedVar
, PackedLit
, packLit
, unpackLit
, PackedClause
, packClause
, unpackClause
, AtLeast
, Exactly
, normalizeAtLeast
, instantiateAtLeast
, evalAtLeast
, evalExactly
, PBLinTerm
, PBLinSum
, PBLinAtLeast
, PBLinExactly
, normalizePBLinSum
, normalizePBLinAtLeast
, normalizePBLinExactly
, instantiatePBLinAtLeast
, instantiatePBLinExactly
, cutResolve
, cardinalityReduction
, negatePBLinAtLeast
, evalPBLinSum
, evalPBLinAtLeast
, evalPBLinExactly
, pbLinLowerBound
, pbLinUpperBound
, pbLinSubsume
, PBTerm
, PBSum
, evalPBSum
, evalPBConstraint
, evalPBFormula
, pbLowerBound
, pbUpperBound
, removeNegationFromPBSum
, XORClause
, normalizeXORClause
, instantiateXORClause
, evalXORClause
, NewVar (..)
, AddClause (..)
, AddCardinality (..)
, AddPBLin (..)
, AddPBNL (..)
, AddXORClause (..)
) where
import Control.Monad
import Control.Exception
import Data.Array.Unboxed
import Data.Ord
import Data.List
import Data.Int
import Data.IntMap.Strict (IntMap)
import qualified Data.IntMap.Strict as IntMap
import Data.IntSet (IntSet)
import qualified Data.IntSet as IntSet
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as VU
import qualified Data.PseudoBoolean as PBFile
import ToySolver.Data.LBool
import qualified ToySolver.Combinatorial.SubsetSum as SubsetSum
type Var = Int
type VarSet = IntSet
type VarMap = IntMap
{-# INLINE validVar #-}
validVar :: Var -> Bool
validVar :: Lit -> Bool
validVar Lit
v = Lit
v forall a. Ord a => a -> a -> Bool
> Lit
0
class IModel a where
evalVar :: a -> Var -> Bool
type Model = UArray Var Bool
restrictModel :: Int -> Model -> Model
restrictModel :: Lit -> Model -> Model
restrictModel Lit
nv Model
m = forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
(i, i) -> [(i, e)] -> a i e
array (Lit
1,Lit
nv) [(Lit
v, Model
m forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Lit
v) | Lit
v <- [Lit
1..Lit
nv]]
instance IModel (UArray Var Bool) where
evalVar :: Model -> Lit -> Bool
evalVar Model
m Lit
v = Model
m forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Lit
v
instance IModel (Array Var Bool) where
evalVar :: Array Lit Bool -> Lit -> Bool
evalVar Array Lit Bool
m Lit
v = Array Lit Bool
m forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Lit
v
instance IModel (Var -> Bool) where
evalVar :: (Lit -> Bool) -> Lit -> Bool
evalVar Lit -> Bool
m Lit
v = Lit -> Bool
m Lit
v
type Lit = Int
{-# INLINE litUndef #-}
litUndef :: Lit
litUndef :: Lit
litUndef = Lit
0
type LitSet = IntSet
type LitMap = IntMap
{-# INLINE validLit #-}
validLit :: Lit -> Bool
validLit :: Lit -> Bool
validLit Lit
l = Lit
l forall a. Eq a => a -> a -> Bool
/= Lit
0
{-# INLINE literal #-}
literal :: Var
-> Bool
-> Lit
literal :: Lit -> Bool -> Lit
literal Lit
v Bool
polarity =
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Lit -> Bool
validVar Lit
v) forall a b. (a -> b) -> a -> b
$ if Bool
polarity then Lit
v else Lit -> Lit
litNot Lit
v
{-# INLINE litNot #-}
litNot :: Lit -> Lit
litNot :: Lit -> Lit
litNot Lit
l = forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Lit -> Bool
validLit Lit
l) forall a b. (a -> b) -> a -> b
$ forall a. Num a => a -> a
negate Lit
l
{-# INLINE litVar #-}
litVar :: Lit -> Var
litVar :: Lit -> Lit
litVar Lit
l = forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Lit -> Bool
validLit Lit
l) forall a b. (a -> b) -> a -> b
$ forall a. Num a => a -> a
abs Lit
l
{-# INLINE litPolarity #-}
litPolarity :: Lit -> Bool
litPolarity :: Lit -> Bool
litPolarity Lit
l = forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Lit -> Bool
validLit Lit
l) forall a b. (a -> b) -> a -> b
$ Lit
l forall a. Ord a => a -> a -> Bool
> Lit
0
{-# INLINEABLE evalLit #-}
{-# SPECIALIZE evalLit :: Model -> Lit -> Bool #-}
evalLit :: IModel m => m -> Lit -> Bool
evalLit :: forall m. IModel m => m -> Lit -> Bool
evalLit m
m Lit
l = if Lit
l forall a. Ord a => a -> a -> Bool
> Lit
0 then forall m. IModel m => m -> Lit -> Bool
evalVar m
m Lit
l else Bool -> Bool
not (forall m. IModel m => m -> Lit -> Bool
evalVar m
m (forall a. Num a => a -> a
abs Lit
l))
type Clause = [Lit]
normalizeClause :: Clause -> Maybe Clause
normalizeClause :: Clause -> Maybe Clause
normalizeClause Clause
lits = forall a. (?callStack::CallStack) => Bool -> a -> a
assert (VarSet -> Lit
IntSet.size VarSet
ys forall a. Integral a => a -> a -> a
`mod` Lit
2 forall a. Eq a => a -> a -> Bool
== Lit
0) forall a b. (a -> b) -> a -> b
$
if VarSet -> Bool
IntSet.null VarSet
ys
then forall a. a -> Maybe a
Just (VarSet -> Clause
IntSet.toList VarSet
xs)
else forall a. Maybe a
Nothing
where
xs :: VarSet
xs = Clause -> VarSet
IntSet.fromList Clause
lits
ys :: VarSet
ys = VarSet
xs VarSet -> VarSet -> VarSet
`IntSet.intersection` ((Lit -> Lit) -> VarSet -> VarSet
IntSet.map Lit -> Lit
litNot VarSet
xs)
{-# SPECIALIZE instantiateClause :: (Lit -> IO LBool) -> Clause -> IO (Maybe Clause) #-}
instantiateClause :: forall m. Monad m => (Lit -> m LBool) -> Clause -> m (Maybe Clause)
instantiateClause :: forall (m :: * -> *).
Monad m =>
(Lit -> m LBool) -> Clause -> m (Maybe Clause)
instantiateClause Lit -> m LBool
evalLitM = Clause -> Clause -> m (Maybe Clause)
loop []
where
loop :: [Lit] -> [Lit] -> m (Maybe Clause)
loop :: Clause -> Clause -> m (Maybe Clause)
loop Clause
ret [] = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just Clause
ret
loop Clause
ret (Lit
l:Clause
ls) = do
LBool
val <- Lit -> m LBool
evalLitM Lit
l
if LBool
valforall a. Eq a => a -> a -> Bool
==LBool
lTrue then
forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
else if LBool
valforall a. Eq a => a -> a -> Bool
==LBool
lFalse then
Clause -> Clause -> m (Maybe Clause)
loop Clause
ret Clause
ls
else
Clause -> Clause -> m (Maybe Clause)
loop (Lit
l forall a. a -> [a] -> [a]
: Clause
ret) Clause
ls
clauseSubsume :: Clause -> Clause -> Bool
clauseSubsume :: Clause -> Clause -> Bool
clauseSubsume Clause
cl1 Clause
cl2 = VarSet
cl1' VarSet -> VarSet -> Bool
`IntSet.isSubsetOf` VarSet
cl2'
where
cl1' :: VarSet
cl1' = Clause -> VarSet
IntSet.fromList Clause
cl1
cl2' :: VarSet
cl2' = Clause -> VarSet
IntSet.fromList Clause
cl2
evalClause :: IModel m => m -> Clause -> Bool
evalClause :: forall m. IModel m => m -> Clause -> Bool
evalClause m
m Clause
cl = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (forall m. IModel m => m -> Lit -> Bool
evalLit m
m) Clause
cl
clauseToPBLinAtLeast :: Clause -> PBLinAtLeast
clauseToPBLinAtLeast :: Clause -> PBLinAtLeast
clauseToPBLinAtLeast Clause
xs = ([(Integer
1,Lit
l) | Lit
l <- Clause
xs], Integer
1)
type PackedVar = PackedLit
type PackedLit = Int32
packLit :: Lit -> PackedLit
packLit :: Lit -> PackedLit
packLit = forall a b. (Integral a, Num b) => a -> b
fromIntegral
unpackLit :: PackedLit -> Lit
unpackLit :: PackedLit -> Lit
unpackLit = forall a b. (Integral a, Num b) => a -> b
fromIntegral
type PackedClause = VU.Vector PackedLit
packClause :: Clause -> PackedClause
packClause :: Clause -> PackedClause
packClause = forall a. Unbox a => [a] -> Vector a
VU.fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map Lit -> PackedLit
packLit
unpackClause :: PackedClause -> Clause
unpackClause :: PackedClause -> Clause
unpackClause = forall a b. (a -> b) -> [a] -> [b]
map PackedLit -> Lit
unpackLit forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Unbox a => Vector a -> [a]
VU.toList
type AtLeast = ([Lit], Int)
type Exactly = ([Lit], Int)
normalizeAtLeast :: AtLeast -> AtLeast
normalizeAtLeast :: AtLeast -> AtLeast
normalizeAtLeast (Clause
lits,Lit
n) = forall a. (?callStack::CallStack) => Bool -> a -> a
assert (VarSet -> Lit
IntSet.size VarSet
ys forall a. Integral a => a -> a -> a
`mod` Lit
2 forall a. Eq a => a -> a -> Bool
== Lit
0) forall a b. (a -> b) -> a -> b
$
(VarSet -> Clause
IntSet.toList VarSet
lits', Lit
n')
where
xs :: VarSet
xs = Clause -> VarSet
IntSet.fromList Clause
lits
ys :: VarSet
ys = VarSet
xs VarSet -> VarSet -> VarSet
`IntSet.intersection` ((Lit -> Lit) -> VarSet -> VarSet
IntSet.map Lit -> Lit
litNot VarSet
xs)
lits' :: VarSet
lits' = VarSet
xs VarSet -> VarSet -> VarSet
`IntSet.difference` VarSet
ys
n' :: Lit
n' = Lit
n forall a. Num a => a -> a -> a
- (VarSet -> Lit
IntSet.size VarSet
ys forall a. Integral a => a -> a -> a
`div` Lit
2)
{-# SPECIALIZE instantiateAtLeast :: (Lit -> IO LBool) -> AtLeast -> IO AtLeast #-}
instantiateAtLeast :: forall m. Monad m => (Lit -> m LBool) -> AtLeast -> m AtLeast
instantiateAtLeast :: forall (m :: * -> *).
Monad m =>
(Lit -> m LBool) -> AtLeast -> m AtLeast
instantiateAtLeast Lit -> m LBool
evalLitM (Clause
xs,Lit
n) = AtLeast -> Clause -> m AtLeast
loop ([],Lit
n) Clause
xs
where
loop :: AtLeast -> [Lit] -> m AtLeast
loop :: AtLeast -> Clause -> m AtLeast
loop AtLeast
ret [] = forall (m :: * -> *) a. Monad m => a -> m a
return AtLeast
ret
loop (Clause
ys,Lit
m) (Lit
l:Clause
ls) = do
LBool
val <- Lit -> m LBool
evalLitM Lit
l
if LBool
val forall a. Eq a => a -> a -> Bool
== LBool
lTrue then
AtLeast -> Clause -> m AtLeast
loop (Clause
ys, Lit
mforall a. Num a => a -> a -> a
-Lit
1) Clause
ls
else if LBool
val forall a. Eq a => a -> a -> Bool
== LBool
lFalse then
AtLeast -> Clause -> m AtLeast
loop (Clause
ys, Lit
m) Clause
ls
else
AtLeast -> Clause -> m AtLeast
loop (Lit
lforall a. a -> [a] -> [a]
:Clause
ys, Lit
m) Clause
ls
evalAtLeast :: IModel m => m -> AtLeast -> Bool
evalAtLeast :: forall m. IModel m => m -> AtLeast -> Bool
evalAtLeast m
m (Clause
lits,Lit
n) = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Lit
1 | Lit
lit <- Clause
lits, forall m. IModel m => m -> Lit -> Bool
evalLit m
m Lit
lit] forall a. Ord a => a -> a -> Bool
>= Lit
n
evalExactly :: IModel m => m -> Exactly -> Bool
evalExactly :: forall m. IModel m => m -> AtLeast -> Bool
evalExactly m
m (Clause
lits,Lit
n) = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Lit
1 | Lit
lit <- Clause
lits, forall m. IModel m => m -> Lit -> Bool
evalLit m
m Lit
lit] forall a. Eq a => a -> a -> Bool
== Lit
n
type PBLinTerm = (Integer, Lit)
type PBLinSum = [PBLinTerm]
type PBLinAtLeast = (PBLinSum, Integer)
type PBLinExactly = (PBLinSum, Integer)
normalizePBLinSum :: (PBLinSum, Integer) -> (PBLinSum, Integer)
normalizePBLinSum :: PBLinAtLeast -> PBLinAtLeast
normalizePBLinSum = PBLinAtLeast -> PBLinAtLeast
step2 forall b c a. (b -> c) -> (a -> b) -> a -> c
. PBLinAtLeast -> PBLinAtLeast
step1
where
step1 :: (PBLinSum, Integer) -> (PBLinSum, Integer)
step1 :: PBLinAtLeast -> PBLinAtLeast
step1 ([PBLinTerm]
xs,Integer
n) =
case (VarMap Integer, Integer)
-> [PBLinTerm] -> (VarMap Integer, Integer)
loop (forall a. IntMap a
IntMap.empty,Integer
n) [PBLinTerm]
xs of
(VarMap Integer
ys,Integer
n') -> ([(Integer
c,Lit
v) | (Lit
v,Integer
c) <- forall a. IntMap a -> [(Lit, a)]
IntMap.toList VarMap Integer
ys], Integer
n')
where
loop :: (VarMap Integer, Integer) -> PBLinSum -> (VarMap Integer, Integer)
loop :: (VarMap Integer, Integer)
-> [PBLinTerm] -> (VarMap Integer, Integer)
loop (VarMap Integer
ys,Integer
m) [] = (VarMap Integer
ys,Integer
m)
loop (VarMap Integer
ys,Integer
m) ((Integer
c,Lit
l):[PBLinTerm]
zs) =
if Lit -> Bool
litPolarity Lit
l
then (VarMap Integer, Integer)
-> [PBLinTerm] -> (VarMap Integer, Integer)
loop (forall a. (a -> a -> a) -> Lit -> a -> IntMap a -> IntMap a
IntMap.insertWith forall a. Num a => a -> a -> a
(+) Lit
l Integer
c VarMap Integer
ys, Integer
m) [PBLinTerm]
zs
else (VarMap Integer, Integer)
-> [PBLinTerm] -> (VarMap Integer, Integer)
loop (forall a. (a -> a -> a) -> Lit -> a -> IntMap a -> IntMap a
IntMap.insertWith forall a. Num a => a -> a -> a
(+) (Lit -> Lit
litNot Lit
l) (forall a. Num a => a -> a
negate Integer
c) VarMap Integer
ys, Integer
mforall a. Num a => a -> a -> a
+Integer
c) [PBLinTerm]
zs
step2 :: (PBLinSum, Integer) -> (PBLinSum, Integer)
step2 :: PBLinAtLeast -> PBLinAtLeast
step2 ([PBLinTerm]
xs,Integer
n) = forall {b}.
(Num b, Ord b) =>
([(b, Lit)], b) -> [(b, Lit)] -> ([(b, Lit)], b)
loop ([],Integer
n) [PBLinTerm]
xs
where
loop :: ([(b, Lit)], b) -> [(b, Lit)] -> ([(b, Lit)], b)
loop ([(b, Lit)]
ys,b
m) [] = ([(b, Lit)]
ys,b
m)
loop ([(b, Lit)]
ys,b
m) (t :: (b, Lit)
t@(b
c,Lit
l):[(b, Lit)]
zs)
| b
c forall a. Eq a => a -> a -> Bool
== b
0 = ([(b, Lit)], b) -> [(b, Lit)] -> ([(b, Lit)], b)
loop ([(b, Lit)]
ys,b
m) [(b, Lit)]
zs
| b
c forall a. Ord a => a -> a -> Bool
< b
0 = ([(b, Lit)], b) -> [(b, Lit)] -> ([(b, Lit)], b)
loop ((forall a. Num a => a -> a
negate b
c,Lit -> Lit
litNot Lit
l)forall a. a -> [a] -> [a]
:[(b, Lit)]
ys, b
mforall a. Num a => a -> a -> a
+b
c) [(b, Lit)]
zs
| Bool
otherwise = ([(b, Lit)], b) -> [(b, Lit)] -> ([(b, Lit)], b)
loop ((b, Lit)
tforall a. a -> [a] -> [a]
:[(b, Lit)]
ys,b
m) [(b, Lit)]
zs
normalizePBLinAtLeast :: PBLinAtLeast -> PBLinAtLeast
normalizePBLinAtLeast :: PBLinAtLeast -> PBLinAtLeast
normalizePBLinAtLeast PBLinAtLeast
a =
case PBLinAtLeast -> PBLinAtLeast
step1 PBLinAtLeast
a of
([PBLinTerm]
xs,Integer
n)
| Integer
n forall a. Ord a => a -> a -> Bool
> Integer
0 -> PBLinAtLeast -> PBLinAtLeast
step4 forall a b. (a -> b) -> a -> b
$ PBLinAtLeast -> PBLinAtLeast
step3 ([PBLinTerm]
xs,Integer
n)
| Bool
otherwise -> ([], Integer
0)
where
step1 :: PBLinAtLeast -> PBLinAtLeast
step1 :: PBLinAtLeast -> PBLinAtLeast
step1 ([PBLinTerm]
xs,Integer
n) =
case PBLinAtLeast -> PBLinAtLeast
normalizePBLinSum ([PBLinTerm]
xs,-Integer
n) of
([PBLinTerm]
ys,Integer
m) -> ([PBLinTerm]
ys, -Integer
m)
step3 :: PBLinAtLeast -> PBLinAtLeast
step3 :: PBLinAtLeast -> PBLinAtLeast
step3 ([PBLinTerm]
xs,Integer
n) =
case [Integer
c | (Integer
c,Lit
_) <- [PBLinTerm]
xs, forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Integer
cforall a. Ord a => a -> a -> Bool
>Integer
0) (Integer
c forall a. Ord a => a -> a -> Bool
< Integer
n)] of
[] -> ([(Integer
1,Lit
l) | (Integer
c,Lit
l) <- [PBLinTerm]
xs], Integer
1)
[Integer]
cs ->
let d :: Integer
d = forall a. (a -> a -> a) -> [a] -> a
foldl1' forall a. Integral a => a -> a -> a
gcd [Integer]
cs
m :: Integer
m = (Integer
nforall a. Num a => a -> a -> a
+Integer
dforall a. Num a => a -> a -> a
-Integer
1) forall a. Integral a => a -> a -> a
`div` Integer
d
in ([(if Integer
c forall a. Ord a => a -> a -> Bool
>= Integer
n then Integer
m else Integer
c forall a. Integral a => a -> a -> a
`div` Integer
d, Lit
l) | (Integer
c,Lit
l) <- [PBLinTerm]
xs], Integer
m)
step4 :: PBLinAtLeast -> PBLinAtLeast
step4 :: PBLinAtLeast -> PBLinAtLeast
step4 ([PBLinTerm]
xs,Integer
n) =
case forall (v :: * -> *).
Vector v Integer =>
v Integer -> Integer -> Maybe (Integer, Vector Bool)
SubsetSum.minSubsetSum (forall a. [a] -> Vector a
V.fromList [Integer
c | (Integer
c,Lit
_) <- [PBLinTerm]
xs]) Integer
n of
Just (Integer
m, Vector Bool
_) -> ([PBLinTerm]
xs, Integer
m)
Maybe (Integer, Vector Bool)
Nothing -> ([], Integer
1)
normalizePBLinExactly :: PBLinExactly -> PBLinExactly
normalizePBLinExactly :: PBLinAtLeast -> PBLinAtLeast
normalizePBLinExactly PBLinAtLeast
a =
case PBLinAtLeast -> PBLinAtLeast
step1 forall a b. (a -> b) -> a -> b
$ PBLinAtLeast
a of
([PBLinTerm]
xs,Integer
n)
| Integer
n forall a. Ord a => a -> a -> Bool
>= Integer
0 -> PBLinAtLeast -> PBLinAtLeast
step3 forall a b. (a -> b) -> a -> b
$ PBLinAtLeast -> PBLinAtLeast
step2 ([PBLinTerm]
xs, Integer
n)
| Bool
otherwise -> ([], Integer
1)
where
step1 :: PBLinExactly -> PBLinExactly
step1 :: PBLinAtLeast -> PBLinAtLeast
step1 ([PBLinTerm]
xs,Integer
n) =
case PBLinAtLeast -> PBLinAtLeast
normalizePBLinSum ([PBLinTerm]
xs,-Integer
n) of
([PBLinTerm]
ys,Integer
m) -> ([PBLinTerm]
ys, -Integer
m)
step2 :: PBLinExactly -> PBLinExactly
step2 :: PBLinAtLeast -> PBLinAtLeast
step2 ([],Integer
n) = ([],Integer
n)
step2 ([PBLinTerm]
xs,Integer
n)
| Integer
n forall a. Integral a => a -> a -> a
`mod` Integer
d forall a. Eq a => a -> a -> Bool
== Integer
0 = ([(Integer
c forall a. Integral a => a -> a -> a
`div` Integer
d, Lit
l) | (Integer
c,Lit
l) <- [PBLinTerm]
xs], Integer
n forall a. Integral a => a -> a -> a
`div` Integer
d)
| Bool
otherwise = ([], Integer
1)
where
d :: Integer
d = forall a. (a -> a -> a) -> [a] -> a
foldl1' forall a. Integral a => a -> a -> a
gcd [Integer
c | (Integer
c,Lit
_) <- [PBLinTerm]
xs]
step3 :: PBLinExactly -> PBLinExactly
step3 :: PBLinAtLeast -> PBLinAtLeast
step3 constr :: PBLinAtLeast
constr@([PBLinTerm]
xs,Integer
n) =
case forall (v :: * -> *).
Vector v Integer =>
v Integer -> Integer -> Maybe (Vector Bool)
SubsetSum.subsetSum (forall a. [a] -> Vector a
V.fromList [Integer
c | (Integer
c,Lit
_) <- [PBLinTerm]
xs]) Integer
n of
Just Vector Bool
_ -> PBLinAtLeast
constr
Maybe (Vector Bool)
Nothing -> ([], Integer
1)
{-# SPECIALIZE instantiatePBLinAtLeast :: (Lit -> IO LBool) -> PBLinAtLeast -> IO PBLinAtLeast #-}
instantiatePBLinAtLeast :: forall m. Monad m => (Lit -> m LBool) -> PBLinAtLeast -> m PBLinAtLeast
instantiatePBLinAtLeast :: forall (m :: * -> *).
Monad m =>
(Lit -> m LBool) -> PBLinAtLeast -> m PBLinAtLeast
instantiatePBLinAtLeast Lit -> m LBool
evalLitM ([PBLinTerm]
xs,Integer
n) = PBLinAtLeast -> [PBLinTerm] -> m PBLinAtLeast
loop ([],Integer
n) [PBLinTerm]
xs
where
loop :: PBLinAtLeast -> PBLinSum -> m PBLinAtLeast
loop :: PBLinAtLeast -> [PBLinTerm] -> m PBLinAtLeast
loop PBLinAtLeast
ret [] = forall (m :: * -> *) a. Monad m => a -> m a
return PBLinAtLeast
ret
loop ([PBLinTerm]
ys,Integer
m) ((Integer
c,Lit
l):[PBLinTerm]
ts) = do
LBool
val <- Lit -> m LBool
evalLitM Lit
l
if LBool
val forall a. Eq a => a -> a -> Bool
== LBool
lTrue then
PBLinAtLeast -> [PBLinTerm] -> m PBLinAtLeast
loop ([PBLinTerm]
ys, Integer
mforall a. Num a => a -> a -> a
-Integer
c) [PBLinTerm]
ts
else if LBool
val forall a. Eq a => a -> a -> Bool
== LBool
lFalse then
PBLinAtLeast -> [PBLinTerm] -> m PBLinAtLeast
loop ([PBLinTerm]
ys, Integer
m) [PBLinTerm]
ts
else
PBLinAtLeast -> [PBLinTerm] -> m PBLinAtLeast
loop ((Integer
c,Lit
l)forall a. a -> [a] -> [a]
:[PBLinTerm]
ys, Integer
m) [PBLinTerm]
ts
{-# SPECIALIZE instantiatePBLinExactly :: (Lit -> IO LBool) -> PBLinExactly -> IO PBLinExactly #-}
instantiatePBLinExactly :: Monad m => (Lit -> m LBool) -> PBLinExactly -> m PBLinExactly
instantiatePBLinExactly :: forall (m :: * -> *).
Monad m =>
(Lit -> m LBool) -> PBLinAtLeast -> m PBLinAtLeast
instantiatePBLinExactly = forall (m :: * -> *).
Monad m =>
(Lit -> m LBool) -> PBLinAtLeast -> m PBLinAtLeast
instantiatePBLinAtLeast
cutResolve :: PBLinAtLeast -> PBLinAtLeast -> Var -> PBLinAtLeast
cutResolve :: PBLinAtLeast -> PBLinAtLeast -> Lit -> PBLinAtLeast
cutResolve ([PBLinTerm]
lhs1,Integer
rhs1) ([PBLinTerm]
lhs2,Integer
rhs2) Lit
v = forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Lit
l1 forall a. Eq a => a -> a -> Bool
== Lit -> Lit
litNot Lit
l2) forall a b. (a -> b) -> a -> b
$ PBLinAtLeast -> PBLinAtLeast
normalizePBLinAtLeast PBLinAtLeast
pb
where
(Integer
c1,Lit
l1) = forall a. [a] -> a
head [(Integer
c,Lit
l) | (Integer
c,Lit
l) <- [PBLinTerm]
lhs1, Lit -> Lit
litVar Lit
l forall a. Eq a => a -> a -> Bool
== Lit
v]
(Integer
c2,Lit
l2) = forall a. [a] -> a
head [(Integer
c,Lit
l) | (Integer
c,Lit
l) <- [PBLinTerm]
lhs2, Lit -> Lit
litVar Lit
l forall a. Eq a => a -> a -> Bool
== Lit
v]
g :: Integer
g = forall a. Integral a => a -> a -> a
gcd Integer
c1 Integer
c2
s1 :: Integer
s1 = Integer
c2 forall a. Integral a => a -> a -> a
`div` Integer
g
s2 :: Integer
s2 = Integer
c1 forall a. Integral a => a -> a -> a
`div` Integer
g
pb :: PBLinAtLeast
pb = ([(Integer
s1forall a. Num a => a -> a -> a
*Integer
c,Lit
l) | (Integer
c,Lit
l) <- [PBLinTerm]
lhs1] forall a. [a] -> [a] -> [a]
++ [(Integer
s2forall a. Num a => a -> a -> a
*Integer
c,Lit
l) | (Integer
c,Lit
l) <- [PBLinTerm]
lhs2], Integer
s1forall a. Num a => a -> a -> a
*Integer
rhs1 forall a. Num a => a -> a -> a
+ Integer
s2 forall a. Num a => a -> a -> a
* Integer
rhs2)
cardinalityReduction :: PBLinAtLeast -> AtLeast
cardinalityReduction :: PBLinAtLeast -> AtLeast
cardinalityReduction ([PBLinTerm]
lhs,Integer
rhs) = (Clause
ls, Lit
rhs')
where
rhs' :: Lit
rhs' = forall {t} {b}. Num t => Integer -> t -> [(Integer, b)] -> t
go1 Integer
0 Lit
0 (forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (forall a b c. (a -> b -> c) -> b -> a -> c
flip (forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing forall a b. (a, b) -> a
fst)) [PBLinTerm]
lhs)
go1 :: Integer -> t -> [(Integer, b)] -> t
go1 !Integer
s !t
k ((Integer
a,b
_):[(Integer, b)]
ts)
| Integer
s forall a. Ord a => a -> a -> Bool
< Integer
rhs = Integer -> t -> [(Integer, b)] -> t
go1 (Integer
sforall a. Num a => a -> a -> a
+Integer
a) (t
kforall a. Num a => a -> a -> a
+t
1) [(Integer, b)]
ts
| Bool
otherwise = t
k
go1 Integer
_ t
_ [] = forall a. (?callStack::CallStack) => [Char] -> a
error [Char]
"ToySolver.SAT.Types.cardinalityReduction: should not happen"
ls :: Clause
ls = forall {a} {b}. (Ord a, Num a) => a -> [(a, b)] -> [b]
go2 (forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum (Integer
rhs forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map (forall a. Num a => a -> a -> a
subtract Integer
1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) [PBLinTerm]
lhs)) (forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing forall a b. (a, b) -> a
fst) [PBLinTerm]
lhs)
go2 :: a -> [(a, b)] -> [b]
go2 !a
guard' ((a
a,b
_) : [(a, b)]
ts)
| a
a forall a. Num a => a -> a -> a
- a
1 forall a. Ord a => a -> a -> Bool
< a
guard' = a -> [(a, b)] -> [b]
go2 (a
guard' forall a. Num a => a -> a -> a
- a
a) [(a, b)]
ts
| Bool
otherwise = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd [(a, b)]
ts
go2 a
_ [] = forall a. (?callStack::CallStack) => [Char] -> a
error [Char]
"ToySolver.SAT.Types.cardinalityReduction: should not happen"
negatePBLinAtLeast :: PBLinAtLeast -> PBLinAtLeast
negatePBLinAtLeast :: PBLinAtLeast -> PBLinAtLeast
negatePBLinAtLeast ([PBLinTerm]
xs, Integer
rhs) = ([(-Integer
c,Lit
lit) | (Integer
c,Lit
lit)<-[PBLinTerm]
xs] , -Integer
rhs forall a. Num a => a -> a -> a
+ Integer
1)
evalPBLinSum :: IModel m => m -> PBLinSum -> Integer
evalPBLinSum :: forall m. IModel m => m -> [PBLinTerm] -> Integer
evalPBLinSum m
m [PBLinTerm]
xs = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Integer
c | (Integer
c,Lit
lit) <- [PBLinTerm]
xs, forall m. IModel m => m -> Lit -> Bool
evalLit m
m Lit
lit]
evalPBLinAtLeast :: IModel m => m -> PBLinAtLeast -> Bool
evalPBLinAtLeast :: forall m. IModel m => m -> PBLinAtLeast -> Bool
evalPBLinAtLeast m
m ([PBLinTerm]
lhs,Integer
rhs) = forall m. IModel m => m -> [PBLinTerm] -> Integer
evalPBLinSum m
m [PBLinTerm]
lhs forall a. Ord a => a -> a -> Bool
>= Integer
rhs
evalPBLinExactly :: IModel m => m -> PBLinAtLeast -> Bool
evalPBLinExactly :: forall m. IModel m => m -> PBLinAtLeast -> Bool
evalPBLinExactly m
m ([PBLinTerm]
lhs,Integer
rhs) = forall m. IModel m => m -> [PBLinTerm] -> Integer
evalPBLinSum m
m [PBLinTerm]
lhs forall a. Eq a => a -> a -> Bool
== Integer
rhs
pbLinLowerBound :: PBLinSum -> Integer
pbLinLowerBound :: [PBLinTerm] -> Integer
pbLinLowerBound [PBLinTerm]
xs = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [if Integer
c forall a. Ord a => a -> a -> Bool
< Integer
0 then Integer
c else Integer
0 | (Integer
c,Lit
_) <- [PBLinTerm]
xs]
pbLinUpperBound :: PBLinSum -> Integer
pbLinUpperBound :: [PBLinTerm] -> Integer
pbLinUpperBound [PBLinTerm]
xs = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [if Integer
c forall a. Ord a => a -> a -> Bool
> Integer
0 then Integer
c else Integer
0 | (Integer
c,Lit
_) <- [PBLinTerm]
xs]
pbLinSubsume :: PBLinAtLeast -> PBLinAtLeast -> Bool
pbLinSubsume :: PBLinAtLeast -> PBLinAtLeast -> Bool
pbLinSubsume ([PBLinTerm]
lhs1,Integer
rhs1) ([PBLinTerm]
lhs2,Integer
rhs2) =
Integer
rhs1 forall a. Ord a => a -> a -> Bool
>= Integer
rhs2 Bool -> Bool -> Bool
&& forall (t :: * -> *). Foldable t => t Bool -> Bool
and [Integer
di forall a. Ord a => a -> a -> Bool
>= Integer
ci | (Integer
ci,Lit
li) <- [PBLinTerm]
lhs1, let di :: Integer
di = forall a. a -> Lit -> IntMap a -> a
IntMap.findWithDefault Integer
0 Lit
li VarMap Integer
lhs2']
where
lhs2' :: VarMap Integer
lhs2' = forall a. [(Lit, a)] -> IntMap a
IntMap.fromList [(Lit
l,Integer
c) | (Integer
c,Lit
l) <- [PBLinTerm]
lhs2]
type PBTerm = (Integer, [Lit])
type PBSum = [PBTerm]
evalPBSum :: IModel m => m -> PBSum -> Integer
evalPBSum :: forall m. IModel m => m -> PBSum -> Integer
evalPBSum m
m PBSum
xs = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Integer
c | (Integer
c,Clause
lits) <- PBSum
xs, forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall m. IModel m => m -> Lit -> Bool
evalLit m
m) Clause
lits]
evalPBConstraint :: IModel m => m -> PBFile.Constraint -> Bool
evalPBConstraint :: forall m. IModel m => m -> Constraint -> Bool
evalPBConstraint m
m (PBSum
lhs,Op
op,Integer
rhs) = Integer -> Integer -> Bool
op' (forall m. IModel m => m -> PBSum -> Integer
evalPBSum m
m PBSum
lhs) Integer
rhs
where
op' :: Integer -> Integer -> Bool
op' = case Op
op of
Op
PBFile.Ge -> forall a. Ord a => a -> a -> Bool
(>=)
Op
PBFile.Eq -> forall a. Eq a => a -> a -> Bool
(==)
evalPBFormula :: IModel m => m -> PBFile.Formula -> Maybe Integer
evalPBFormula :: forall m. IModel m => m -> Formula -> Maybe Integer
evalPBFormula m
m Formula
formula = do
forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall m. IModel m => m -> Constraint -> Bool
evalPBConstraint m
m) forall a b. (a -> b) -> a -> b
$ Formula -> [Constraint]
PBFile.pbConstraints Formula
formula
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall m. IModel m => m -> PBSum -> Integer
evalPBSum m
m forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a -> a
fromMaybe [] forall a b. (a -> b) -> a -> b
$ Formula -> Maybe PBSum
PBFile.pbObjectiveFunction Formula
formula
pbLowerBound :: PBSum -> Integer
pbLowerBound :: PBSum -> Integer
pbLowerBound PBSum
xs = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Integer
c | (Integer
c,Clause
ls) <- PBSum
xs, Integer
c forall a. Ord a => a -> a -> Bool
< Integer
0 Bool -> Bool -> Bool
|| forall (t :: * -> *) a. Foldable t => t a -> Bool
null Clause
ls]
pbUpperBound :: PBSum -> Integer
pbUpperBound :: PBSum -> Integer
pbUpperBound PBSum
xs = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Integer
c | (Integer
c,Clause
ls) <- PBSum
xs, Integer
c forall a. Ord a => a -> a -> Bool
> Integer
0 Bool -> Bool -> Bool
|| forall (t :: * -> *) a. Foldable t => t a -> Bool
null Clause
ls]
removeNegationFromPBSum :: PBSum -> PBSum
removeNegationFromPBSum :: PBSum -> PBSum
removeNegationFromPBSum PBSum
ts =
[(Integer
c, VarSet -> Clause
IntSet.toList VarSet
m) | (VarSet
m, Integer
c) <- forall k a. Map k a -> [(k, a)]
Map.toList forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
(a -> a -> a) -> f (Map k a) -> Map k a
Map.unionsWith forall a. Num a => a -> a -> a
(+) forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (Integer, Clause) -> Map VarSet Integer
f PBSum
ts, Integer
c forall a. Eq a => a -> a -> Bool
/= Integer
0]
where
f :: PBTerm -> Map VarSet Integer
f :: (Integer, Clause) -> Map VarSet Integer
f (Integer
c, Clause
ls) = forall a. (a -> Lit -> a) -> a -> VarSet -> a
IntSet.foldl' Map VarSet Integer -> Lit -> Map VarSet Integer
g (forall k a. k -> a -> Map k a
Map.singleton VarSet
IntSet.empty Integer
c) (Clause -> VarSet
IntSet.fromList Clause
ls)
g :: Map VarSet Integer -> Lit -> Map VarSet Integer
g :: Map VarSet Integer -> Lit -> Map VarSet Integer
g Map VarSet Integer
m Lit
l
| Lit
l forall a. Ord a => a -> a -> Bool
> Lit
0 = forall k2 a k1.
Ord k2 =>
(a -> a -> a) -> (k1 -> k2) -> Map k1 a -> Map k2 a
Map.mapKeysWith forall a. Num a => a -> a -> a
(+) (Lit -> VarSet -> VarSet
IntSet.insert Lit
v) Map VarSet Integer
m
| Bool
otherwise = forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith forall a. Num a => a -> a -> a
(+) Map VarSet Integer
m forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
Map.fromListWith forall a. Num a => a -> a -> a
(+) [(Lit -> VarSet -> VarSet
IntSet.insert Lit
v VarSet
xs, forall a. Num a => a -> a
negate Integer
c) | (VarSet
xs,Integer
c) <- forall k a. Map k a -> [(k, a)]
Map.toList Map VarSet Integer
m]
where
v :: Lit
v = Lit -> Lit
litVar Lit
l
type XORClause = ([Lit], Bool)
normalizeXORClause :: XORClause -> XORClause
normalizeXORClause :: XORClause -> XORClause
normalizeXORClause (Clause
lits, Bool
b) =
case forall a. IntMap a -> Clause
IntMap.keys IntMap Bool
m of
Lit
0:Clause
xs -> (Clause
xs, Bool -> Bool
not Bool
b)
Clause
xs -> (Clause
xs, Bool
b)
where
m :: IntMap Bool
m = forall a. (a -> Bool) -> IntMap a -> IntMap a
IntMap.filter forall a. a -> a
id forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a.
Foldable f =>
(a -> a -> a) -> f (IntMap a) -> IntMap a
IntMap.unionsWith Bool -> Bool -> Bool
xor [Lit -> IntMap Bool
f Lit
lit | Lit
lit <- Clause
lits]
xor :: Bool -> Bool -> Bool
xor = forall a. Eq a => a -> a -> Bool
(/=)
f :: Lit -> IntMap Bool
f Lit
0 = forall a. Lit -> a -> IntMap a
IntMap.singleton Lit
0 Bool
True
f Lit
lit =
if Lit -> Bool
litPolarity Lit
lit
then forall a. Lit -> a -> IntMap a
IntMap.singleton Lit
lit Bool
True
else forall a. [(Lit, a)] -> IntMap a
IntMap.fromList [(Lit -> Lit
litVar Lit
lit, Bool
True), (Lit
0, Bool
True)]
{-# SPECIALIZE instantiateXORClause :: (Lit -> IO LBool) -> XORClause -> IO XORClause #-}
instantiateXORClause :: forall m. Monad m => (Lit -> m LBool) -> XORClause -> m XORClause
instantiateXORClause :: forall (m :: * -> *).
Monad m =>
(Lit -> m LBool) -> XORClause -> m XORClause
instantiateXORClause Lit -> m LBool
evalLitM (Clause
ls,Bool
b) = Clause -> Bool -> Clause -> m XORClause
loop [] Bool
b Clause
ls
where
loop :: [Lit] -> Bool -> [Lit] -> m XORClause
loop :: Clause -> Bool -> Clause -> m XORClause
loop Clause
lhs !Bool
rhs [] = forall (m :: * -> *) a. Monad m => a -> m a
return (Clause
lhs, Bool
rhs)
loop Clause
lhs !Bool
rhs (Lit
l:Clause
ls) = do
LBool
val <- Lit -> m LBool
evalLitM Lit
l
if LBool
valforall a. Eq a => a -> a -> Bool
==LBool
lTrue then
Clause -> Bool -> Clause -> m XORClause
loop Clause
lhs (Bool -> Bool
not Bool
rhs) Clause
ls
else if LBool
valforall a. Eq a => a -> a -> Bool
==LBool
lFalse then
Clause -> Bool -> Clause -> m XORClause
loop Clause
lhs Bool
rhs Clause
ls
else
Clause -> Bool -> Clause -> m XORClause
loop (Lit
l forall a. a -> [a] -> [a]
: Clause
lhs) Bool
rhs Clause
ls
evalXORClause :: IModel m => m -> XORClause -> Bool
evalXORClause :: forall m. IModel m => m -> XORClause -> Bool
evalXORClause m
m (Clause
lits, Bool
rhs) = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Bool -> Bool -> Bool
xor Bool
False (forall a b. (a -> b) -> [a] -> [b]
map Lit -> Bool
f Clause
lits) forall a. Eq a => a -> a -> Bool
== Bool
rhs
where
xor :: Bool -> Bool -> Bool
xor = forall a. Eq a => a -> a -> Bool
(/=)
f :: Lit -> Bool
f Lit
0 = Bool
True
f Lit
lit = forall m. IModel m => m -> Lit -> Bool
evalLit m
m Lit
lit
class Monad m => NewVar m a | a -> m where
{-# MINIMAL newVar #-}
newVar :: a -> m Var
newVars :: a -> Int -> m [Var]
newVars a
a Lit
n = forall (m :: * -> *) a. Applicative m => Lit -> m a -> m [a]
replicateM Lit
n (forall (m :: * -> *) a. NewVar m a => a -> m Lit
newVar a
a)
newVars_ :: a -> Int -> m ()
newVars_ a
a Lit
n = forall (m :: * -> *) a. Applicative m => Lit -> m a -> m ()
replicateM_ Lit
n (forall (m :: * -> *) a. NewVar m a => a -> m Lit
newVar a
a)
class NewVar m a => AddClause m a | a -> m where
addClause :: a -> Clause -> m ()
class AddClause m a => AddCardinality m a | a -> m where
{-# MINIMAL addAtLeast #-}
addAtLeast
:: a
-> [Lit]
-> Int
-> m ()
addAtMost
:: a
-> [Lit]
-> Int
-> m ()
addAtMost a
a Clause
lits Lit
n = do
forall (m :: * -> *) a.
AddCardinality m a =>
a -> Clause -> Lit -> m ()
addAtLeast a
a (forall a b. (a -> b) -> [a] -> [b]
map Lit -> Lit
litNot Clause
lits) (forall (t :: * -> *) a. Foldable t => t a -> Lit
length Clause
lits forall a. Num a => a -> a -> a
- Lit
n)
addExactly
:: a
-> [Lit]
-> Int
-> m ()
addExactly a
a Clause
lits Lit
n = do
forall (m :: * -> *) a.
AddCardinality m a =>
a -> Clause -> Lit -> m ()
addAtLeast a
a Clause
lits Lit
n
forall (m :: * -> *) a.
AddCardinality m a =>
a -> Clause -> Lit -> m ()
addAtMost a
a Clause
lits Lit
n
class AddCardinality m a => AddPBLin m a | a -> m where
{-# MINIMAL addPBAtLeast #-}
addPBAtLeast
:: a
-> PBLinSum
-> Integer
-> m ()
addPBAtMost
:: a
-> PBLinSum
-> Integer
-> m ()
addPBAtMost a
a [PBLinTerm]
ts Integer
n = forall (m :: * -> *) a.
AddPBLin m a =>
a -> [PBLinTerm] -> Integer -> m ()
addPBAtLeast a
a [(-Integer
c,Lit
l) | (Integer
c,Lit
l) <- [PBLinTerm]
ts] (forall a. Num a => a -> a
negate Integer
n)
addPBExactly
:: a
-> PBLinSum
-> Integer
-> m ()
addPBExactly a
a [PBLinTerm]
ts Integer
n = do
forall (m :: * -> *) a.
AddPBLin m a =>
a -> [PBLinTerm] -> Integer -> m ()
addPBAtLeast a
a [PBLinTerm]
ts Integer
n
forall (m :: * -> *) a.
AddPBLin m a =>
a -> [PBLinTerm] -> Integer -> m ()
addPBAtMost a
a [PBLinTerm]
ts Integer
n
addPBAtLeastSoft
:: a
-> Lit
-> PBLinSum
-> Integer
-> m ()
addPBAtLeastSoft a
a Lit
sel [PBLinTerm]
lhs Integer
rhs = do
let ([PBLinTerm]
lhs2,Integer
rhs2) = PBLinAtLeast -> PBLinAtLeast
normalizePBLinAtLeast ([PBLinTerm]
lhs,Integer
rhs)
forall (m :: * -> *) a.
AddPBLin m a =>
a -> [PBLinTerm] -> Integer -> m ()
addPBAtLeast a
a ((Integer
rhs2, Lit -> Lit
litNot Lit
sel) forall a. a -> [a] -> [a]
: [PBLinTerm]
lhs2) Integer
rhs2
addPBAtMostSoft
:: a
-> Lit
-> PBLinSum
-> Integer
-> m ()
addPBAtMostSoft a
a Lit
sel [PBLinTerm]
lhs Integer
rhs =
forall (m :: * -> *) a.
AddPBLin m a =>
a -> Lit -> [PBLinTerm] -> Integer -> m ()
addPBAtLeastSoft a
a Lit
sel [(forall a. Num a => a -> a
negate Integer
c, Lit
lit) | (Integer
c,Lit
lit) <- [PBLinTerm]
lhs] (forall a. Num a => a -> a
negate Integer
rhs)
addPBExactlySoft
:: a
-> Lit
-> PBLinSum
-> Integer
-> m ()
addPBExactlySoft a
a Lit
sel [PBLinTerm]
lhs Integer
rhs = do
forall (m :: * -> *) a.
AddPBLin m a =>
a -> Lit -> [PBLinTerm] -> Integer -> m ()
addPBAtLeastSoft a
a Lit
sel [PBLinTerm]
lhs Integer
rhs
forall (m :: * -> *) a.
AddPBLin m a =>
a -> Lit -> [PBLinTerm] -> Integer -> m ()
addPBAtMostSoft a
a Lit
sel [PBLinTerm]
lhs Integer
rhs
class AddPBLin m a => AddPBNL m a | a -> m where
{-# MINIMAL addPBNLAtLeast #-}
addPBNLAtLeast
:: a
-> PBSum
-> Integer
-> m ()
addPBNLAtMost
:: a
-> PBSum
-> Integer
-> m ()
addPBNLAtMost a
a PBSum
ts Integer
n = forall (m :: * -> *) a.
AddPBNL m a =>
a -> PBSum -> Integer -> m ()
addPBNLAtLeast a
a [(-Integer
c,Clause
ls) | (Integer
c,Clause
ls) <- PBSum
ts] (forall a. Num a => a -> a
negate Integer
n)
addPBNLExactly
:: a
-> PBSum
-> Integer
-> m ()
addPBNLExactly a
a PBSum
ts Integer
n = do
forall (m :: * -> *) a.
AddPBNL m a =>
a -> PBSum -> Integer -> m ()
addPBNLAtLeast a
a PBSum
ts Integer
n
forall (m :: * -> *) a.
AddPBNL m a =>
a -> PBSum -> Integer -> m ()
addPBNLAtMost a
a PBSum
ts Integer
n
addPBNLAtLeastSoft
:: a
-> Lit
-> PBSum
-> Integer
-> m ()
addPBNLAtLeastSoft a
a Lit
sel PBSum
lhs Integer
rhs = do
let n :: Integer
n = Integer
rhs forall a. Num a => a -> a -> a
- forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [forall a. Ord a => a -> a -> a
min Integer
c Integer
0 | (Integer
c,Clause
_) <- PBSum
lhs]
forall (m :: * -> *) a.
AddPBNL m a =>
a -> PBSum -> Integer -> m ()
addPBNLAtLeast a
a ((Integer
n, [Lit -> Lit
litNot Lit
sel]) forall a. a -> [a] -> [a]
: PBSum
lhs) Integer
rhs
addPBNLAtMostSoft
:: a
-> Lit
-> PBSum
-> Integer
-> m ()
addPBNLAtMostSoft a
a Lit
sel PBSum
lhs Integer
rhs =
forall (m :: * -> *) a.
AddPBNL m a =>
a -> Lit -> PBSum -> Integer -> m ()
addPBNLAtLeastSoft a
a Lit
sel [(forall a. Num a => a -> a
negate Integer
c, Clause
ls) | (Integer
c,Clause
ls) <- PBSum
lhs] (forall a. Num a => a -> a
negate Integer
rhs)
addPBNLExactlySoft
:: a
-> Lit
-> PBSum
-> Integer
-> m ()
addPBNLExactlySoft a
a Lit
sel PBSum
lhs Integer
rhs = do
forall (m :: * -> *) a.
AddPBNL m a =>
a -> Lit -> PBSum -> Integer -> m ()
addPBNLAtLeastSoft a
a Lit
sel PBSum
lhs Integer
rhs
forall (m :: * -> *) a.
AddPBNL m a =>
a -> Lit -> PBSum -> Integer -> m ()
addPBNLAtMostSoft a
a Lit
sel PBSum
lhs Integer
rhs
class AddClause m a => AddXORClause m a | a -> m where
{-# MINIMAL addXORClause #-}
addXORClause
:: a
-> [Lit]
-> Bool
-> m ()
addXORClauseSoft
:: a
-> Lit
-> [Lit]
-> Bool
-> m ()
addXORClauseSoft a
a Lit
sel Clause
lits Bool
rhs = do
Lit
reified <- forall (m :: * -> *) a. NewVar m a => a -> m Lit
newVar a
a
forall (m :: * -> *) a.
AddXORClause m a =>
a -> Clause -> Bool -> m ()
addXORClause a
a (Lit -> Lit
litNot Lit
reified forall a. a -> [a] -> [a]
: Clause
lits) Bool
rhs
forall (m :: * -> *) a. AddClause m a => a -> Clause -> m ()
addClause a
a [Lit -> Lit
litNot Lit
sel, Lit
reified]