- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 my last question我问我如何解析一个命题表达式,然后在 SBV 库的帮助下找到公式的所有模型。我使用 hatt 库来解析 bool 表达式。
不幸的是,SBV 似乎不适合相当快速的 SAT 求解,或者查找所有模型的“allSat”功能没有实现速度。毕竟 SBV 是针对 SMT 解决的。
我使用证明器 Z3 和 CVC4 测试了 haskell SBV 包的性能,并与 picosat 进行了比较。我使用了一个包含 36 个变量和 840 个有效模型的命题公式。 picosat 的结果是用了 0.5 秒,而 Z3 用了 3 分钟,CVC4 用了 6 分钟。 SBV 和“allSat”函数有一些性能技巧可以为命题公式修剪它。或者其他一些证明器可能比 Z3 更快。
但我现在假设我可能需要使用更快的选项来解决 SAT 问题,并且我想使用 PicoSAT 或 MiniSAT,因为我过去取得了不错的成绩,而且 SAT 比赛的成绩看起来也不错。
问题:
Expr
类型的表达式开始在 hatt 库中,以适合于例如 picosat 的样式表示 CNF 公式。 Picosat 使用整数列表的常见 SAT 格式。请注意,我从字符串解析的公式最初已经在 CNF 中。要么我直接从一个 hat Expr 到 int 列表。否则,我使用 my last question 中的代码为适合 allSat
的格式SBV 的函数并重新实现 allSAT
的变体SBV 的函数使用 picosat/miniSAT 的 hasekll 绑定(bind)。 最佳答案
正如我在评论中所说,一个非常常见的解决方案是通过显式添加禁止先前发现的解决方案的子句来强制 SAT 求解器寻找其他解决方案。例如:
solveAll :: [[Int]] -> IO [[Int]]
solveAll e =
do s <- solve e
case s of
Solution x -> (x :) `fmap` solveAll (map negate x : e)
_ -> return []
solveAll
.当发现一个解决方案时,我们通过添加我们当前解决方案的否定作为新子句来返回该解决方案和所有剩余的解决方案。求解器最终将返回 unsat,这表明我们已找到所有解决方案,或者未知,这意味着可能存在未发现的解决方案,但求解器已放弃。
import Data.Logic.Propositional hiding (interpret)
import Picosat
import Control.Monad ((<=<))
main :: IO ()
main = do
let expr = [ [1, -2] , [3, -2] ]
putStrLn $ "Solving expr: " ++ show expr
(print <=< solve) expr
(print <=< solveAll) expr
solveAll :: [[Int]] -> IO [[Int]]
solveAll e =
do s <- solve e
case s of
Solution x -> (x :) `fmap` solveAll (map negate x : e)
_ -> return []
关于haskell - SBV lib 似乎在解决 SAT 问题时变慢了,如何使用 picosat/miniSAT?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23315614/
我正在尝试优化 C 程序 picosat,它是一个 SAT 求解器。我的上一个程序运行了 24 小时,因此优化可以节省我的时间。 picosat 注意:picosat 只是单线程的!多线程 SAT 求
链接: Z3 theorem prover picosat with pyhton bindings 我将 Z3 用作 SAT 求解器。对于较大的公式,似乎存在性能问题,这就是为什么我想查看 pico
在 my last question我问我如何解析一个命题表达式,然后在 SBV 库的帮助下找到公式的所有模型。我使用 hatt 库来解析 bool 表达式。 不幸的是,SBV 似乎不适合相当快速的
import Picosat import Control.Applicative main :: IO () main = do dimacsList1 getLine) :: IO [[In
我是一名优秀的程序员,十分优秀!