toysolver-0.6.0: src/ToySolver/SAT/Encoder/Cardinality/Internal/Naive.hs
{-# OPTIONS_GHC -Wall #-}
-----------------------------------------------------------------------------
-- |
-- Module : ToySolver.SAT.Encoder.Cardinality.Internal.Naive
-- Copyright : (c) Masahiro Sakai 2019
-- License : BSD-style
--
-- Maintainer : masahiro.sakai@gmail.com
-- Stability : provisional
-- Portability : portable
--
-----------------------------------------------------------------------------
module ToySolver.SAT.Encoder.Cardinality.Internal.Naive
( addAtLeastNaive
, encodeAtLeastNaive
) where
import Control.Monad.Primitive
import qualified ToySolver.SAT.Types as SAT
import qualified ToySolver.SAT.Encoder.Tseitin as Tseitin
addAtLeastNaive :: PrimMonad m => Tseitin.Encoder m -> SAT.AtLeast -> m ()
addAtLeastNaive enc (lhs,rhs) = do
let n = length lhs
if n < rhs then do
SAT.addClause enc []
else do
mapM_ (SAT.addClause enc) (comb (n - rhs + 1) lhs)
-- TODO: consider polarity
encodeAtLeastNaive :: PrimMonad m => Tseitin.Encoder m -> SAT.AtLeast -> m SAT.Lit
encodeAtLeastNaive enc (lhs,rhs) = do
let n = length lhs
if n < rhs then do
Tseitin.encodeDisj enc []
else do
ls <- mapM (Tseitin.encodeDisj enc) (comb (n - rhs + 1) lhs)
Tseitin.encodeConj enc ls
comb :: Int -> [a] -> [[a]]
comb 0 _ = [[]]
comb _ [] = []
comb n (x:xs) = map (x:) (comb (n-1) xs) ++ comb n xs