- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想解析 String
它描述了一个命题公式,然后使用 SAT 求解器找到该命题公式的所有模型。
现在我可以用 hatt 解析一个命题公式包裹;见testParse
下面的功能。
我还可以使用 SBV 库运行 SAT 求解器调用;见testParse
下面的功能。
问题:
如何在运行时生成 Predicate
类型的值喜欢 myPredicate
在 SBV 库中表示我刚刚从字符串解析的命题公式?我只知道如何手动输入 forSome_ $ \x y z -> ...
表达式,但不是如何从 Expr
编写转换器函数值转换为 Predicate
类型的值.
-- cabal install sbv hatt
import Data.Logic.Propositional
import Data.SBV
-- Random test formula:
-- (x or ~z) and (y or ~z)
-- graphical depiction, see: https://www.wolframalpha.com/input/?i=%28x+or+~z%29+and+%28y+or+~z%29
testParse = parseExpr "test source" "((X | ~Z) & (Y | ~Z))"
myPredicate :: Predicate
myPredicate = forSome_ $ \x y z -> ((x :: SBool) ||| (bnot z)) &&& (y ||| (bnot z))
testSat = do
x <- allSat $ myPredicate
putStrLn $ show x
main = do
putStrLn $ show $ testParse
testSat
{-
Need a function that dynamically creates a Predicate
(as I did with the function (like "\x y z -> ..") for an arbitrary expression of type "Expr" that is parsed from String.
-}
import Data.SBV
genPowerSet :: [SBool] -> SBool
genPowerSet = bAll isBool
where isBool x = x .== true ||| x .== false
powerSet :: [Word8] -> IO ()
powerSet xs = do putStrLn $ "Finding all subsets of " ++ show xs
res <- allSat $ genPowerSet `fmap` mkExistVars n
data Expr = Variable Var
| Negation Expr
| Conjunction Expr Expr
| Disjunction Expr Expr
| Conditional Expr Expr
| Biconditional Expr Expr
deriving Eq
最佳答案
与 SBV 合作
使用 SBV 要求您遵循类型并实现 Predicate
只是一个 Symbolic SBool
.在这一步之后,调查和发现 Symbolic
很重要。是一个单子(monad) - 是的,一个单子(monad)!
既然你知道你有一个单子(monad),那么黑线鳕中的任何东西都是Symbolic
结合起来构建您想要的任何 SAT 应该是微不足道的。对于您的问题,您只需要在 AST 上构建一个简单的解释器即可构建 Predicate
.
代码演练
代码全部包含在下面的一个连续形式中,但我将逐步介绍有趣的部分。入口点是solveExpr
它接受表达式并产生一个 SAT 结果:
solveExpr :: Expr -> IO AllSatResult
solveExpr e0 = allSat prd
allSat
谓词是显而易见的。要构建该谓词,我们需要声明一个存在的
SBool
对于我们表达式中的每个变量。现在让我们假设我们有
vs :: [String]
其中每个字符串对应于
Var
之一从表达式。
prd :: Predicate
prd = do
syms <- mapM exists vs
let env = M.fromList (zip vs syms)
interpret env e0
Predicate
.解释函数使用环境并仅应用与 hatt 的
Expr
中的每个构造函数的意图相匹配的 SBV 函数。类型。
interpret :: Env -> Expr -> Predicate
interpret env expr = do
let interp = interpret env
case expr of
Variable v -> return (envLookup v env)
Negation e -> bnot `fmap` interp e
Conjunction e1 e2 ->
do r1 <- interp e1
r2 <- interp e2
return (r1 &&& r2)
Disjunction e1 e2 ->
do r1 <- interp e1
r2 <- interp e2
return (r1 ||| r2)
Conditional e1 e2 -> error "And so on"
Biconditional e1 e2 -> error "And so on"
import Data.Logic.Propositional hiding (interpret)
import Data.SBV
import Text.Parsec.Error (ParseError)
import qualified Data.Map as M
import qualified Data.Set as Set
import Data.Foldable (foldMap)
import Control.Monad ((<=<))
testParse :: Either ParseError Expr
testParse = parseExpr "test source" "((X | ~Z) & (Y | ~Z))"
type Env = M.Map String SBool
envLookup :: Var -> Env -> SBool
envLookup (Var v) e = maybe (error $ "Var not found: " ++ show v) id
(M.lookup [v] e)
solveExpr :: Expr -> IO AllSatResult
solveExpr e0 = allSat go
where
vs :: [String]
vs = map (\(Var c) -> [c]) (variables e0)
go :: Predicate
go = do
syms <- mapM exists vs
let env = M.fromList (zip vs syms)
interpret env e0
interpret :: Env -> Expr -> Predicate
interpret env expr = do
let interp = interpret env
case expr of
Variable v -> return (envLookup v env)
Negation e -> bnot `fmap` interp e
Conjunction e1 e2 ->
do r1 <- interp e1
r2 <- interp e2
return (r1 &&& r2)
Disjunction e1 e2 ->
do r1 <- interp e1
r2 <- interp e2
return (r1 ||| r2)
Conditional e1 e2 -> error "And so on"
Biconditional e1 e2 -> error "And so on"
main :: IO ()
main = do
let expr = testParse
putStrLn $ "Solving expr: " ++ show expr
either (error . show) (print <=< solveExpr) expr
关于haskell - SAT 解决与 haskell SBV 库 : how to generate a predicate from a parsed string?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23233969/
使用 SBV 库,我试图满足状态符号列表上的条件: data State = Intro | Start | Content | Comma | Dot mkSymbolicEnumeration '
我的数据类型如下 data X = X {foo :: SInteger, bar :: SInteger} 我想证明例如 forAll_ $ \x -> foo x + bar x .== bar
我有这个定理(不确定这个词是否正确),并且我想得到所有的解决方案。 pairCube limit = do m Symbolic SBool pairCube limit = do
我的数据类型如下 data X = X {foo :: SInteger, bar :: SInteger} 我想证明例如 forAll_ $ \x -> foo x + bar x .== bar
我正在使用 SBV (使用 Z3 后端)在 Haskell 中创建一些理论证明。我想检查一下是否为 x和 y在给定的约束条件下(如 x + y = y + x ,其中 + 是“加号运算符”,而不是加法
假设一棵树,其中节点可能存在也可能不存在,我想生成一个公式,其中: 每个节点都有一个 bool 变量(表示它是否存在), 根(如果空闲)(可能存在也可能不存在),并且 只有当其父节点存在时,节点才能存
以下代码(使用 SBV): {-# LANGUAGE ScopedTypeVariables #-} import Data.SBV main :: IO () main = do res =
我看到很多使用 SBV 库的示例,如下所示: f :: IO SatResult f = sat $ do x IO SatResult f i = sat $ do
为了学习 Z3,我尝试使用 Haskell 绑定(bind) sbv 解决我最喜欢的代码出现问题之一(一个特别困难的问题,2018 day 23, part 2)。 .前面代码中的剧透... modu
在 my last question我问我如何解析一个命题表达式,然后在 SBV 库的帮助下找到公式的所有模型。我使用 hatt 库来解析 bool 表达式。 不幸的是,SBV 似乎不适合相当快速的
我想解析 String它描述了一个命题公式,然后使用 SAT 求解器找到该命题公式的所有模型。 现在我可以用 hatt 解析一个命题公式包裹;见testParse下面的功能。 我还可以使用 SBV 库
我是一名优秀的程序员,十分优秀!