解决 Sympy 中的约束满足问题

And*_*een 1 sympy constraint-programming smt

我正在尝试解决 Sympy 中的一些简单的布尔可满足性问题。在这里,我尝试解决包含逻辑运算符的约束Or

from sympy import *
a,b = symbols("a b")

print(solve(Or(Eq(3, b*2), Eq(3, b*3))))
# In other words: (3 equals b*2) or (3 equals b*3)
# [1,3/2] was the answer that I expected
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,这会导致错误:

TypeError: unsupported operand type(s) for -: 'Or' and 'int'
Run Code Online (Sandbox Code Playgroud)

我可以使用 解决这个问题Piecewise,但这更加冗长:

from sympy import *
a,b = symbols("a b")
print(solve(Piecewise((Eq(3, b*2),Eq(3, b*2)), (Eq(3, b*3),Eq(3, b*3)))))
#prints [1,3/2], as expected
Run Code Online (Sandbox Code Playgroud)

不幸的是,当我尝试求解两个变量而不是一个变量时,这种解决方法失败了:

from sympy import *
a,b = symbols("a b")

print(solve([Eq(a,3+b),Piecewise((Eq(b,3),Eq(b,3)), (Eq(b,4),Eq(b,4)))]))
#AttributeError: 'BooleanTrue' object has no attribute 'n'
Run Code Online (Sandbox Code Playgroud)

Sympy 中是否有更可靠的方法来解决此类约束?

asm*_*rer 5

为了扩展 zaq 的答案,SymPy 无法识别 中的逻辑运算符solve,但您可以使用以下事实:

a*b = 0
Run Code Online (Sandbox Code Playgroud)

相当于

a = 0 OR b = 0
Run Code Online (Sandbox Code Playgroud)

也就是说,将两个方程相乘

solve((3 - 2*b)*(3 - 3*b), b)
Run Code Online (Sandbox Code Playgroud)

作为补充说明,如果您想使用 AND 而不是 OR,则可以求解系统。那是,

solve([eq1, eq2])
Run Code Online (Sandbox Code Playgroud)

相当于求解

eq1 = 0 AND eq2 = 0
Run Code Online (Sandbox Code Playgroud)