feat(allsat): add model enumeration over all solutions
This commit is contained in:
1 parent
95cd91cedc
commit
40b43a927f
1 file changed
+38
@@ -0,0 +1,38 @@
|
|||||||
|
module Sift.Enumerate
|
||||||
|
( projectModel
|
||||||
|
, blockingClause
|
||||||
|
, allModels
|
||||||
|
, countModels
|
||||||
|
, countQueensSolutions
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Sift.Types
|
||||||
|
import Sift.Cdcl (CdclResult(..), solveCdcl)
|
||||||
|
import Sift.Encode.Queens (queens, queensCell)
|
||||||
|
import qualified Data.Map.Strict as Map
|
||||||
|
|
||||||
|
projectModel :: [Var] -> Assignment -> Assignment
|
||||||
|
projectModel vars model =
|
||||||
|
Map.fromList [ (v, Map.findWithDefault False v model) | v <- vars ]
|
||||||
|
|
||||||
|
blockingClause :: [Var] -> Assignment -> Clause
|
||||||
|
blockingClause vars model =
|
||||||
|
[ if Map.findWithDefault False v model then negLit v else posLit v | v <- vars ]
|
||||||
|
|
||||||
|
allModels :: [Var] -> CNF -> [Assignment]
|
||||||
|
allModels projVars (CNF cs0) = go cs0
|
||||||
|
where
|
||||||
|
go cs = case solveCdcl (CNF cs) of
|
||||||
|
CdclUnsat -> []
|
||||||
|
CdclSat model ->
|
||||||
|
let projected = projectModel projVars model
|
||||||
|
in projected : go (blockingClause projVars projected : cs)
|
||||||
|
|
||||||
|
countModels :: [Var] -> CNF -> Int
|
||||||
|
countModels projVars = length . allModels projVars
|
||||||
|
|
||||||
|
countQueensSolutions :: Int -> Int
|
||||||
|
countQueensSolutions n =
|
||||||
|
countModels boardVars (queens n)
|
||||||
|
where
|
||||||
|
boardVars = [ queensCell n r c | r <- [1 .. n], c <- [1 .. n] ]
|
||||||
Reference in new issue
Block a user