我使用SymPy表达式计算a + 3 * b
之类的表达式,然后我想用Z3验证(例如a + 3 * b > 0
表示所有正a, b
}。
我找不到用Z3对象替换a, b
和一般SymPy符号的方法。
import sympy
from z3 import *
a = sympy.Symbol('a')
b = sympy.Symbol('b')
t = Real('t')
w = Real('w')
e = a + 3 * b
e = e.subs({a:t, b:w}) # does nothing?
e = e.replace(a, t).replace(b, w) # e = t + 3 * w
And(True, e > 0) # raises z3.z3types.Z3Exception
将3
替换为RealVal('3')
也会引发异常。
我目前正在操作字符串,最后使用exec
更改上面的类型和表达式,但我计划停止使用exec
。
答案 0 :(得分:1)
你不能将sympy表达式与z3py表达式混合搭配。它们是不同的内部数据结构。但是,您可以遍历sympy表达式并创建相应的z3表达式,但必须单独完成。请注意,对subs
的调用正在交换世界中进行替换:替换正在发生,但结果表达仍然是一个表达式。 (而且很可能是非法的:如果你真的试图在其上使用任何交流功能,你很可能会从同情本身得到类似的例外。)
你需要开发一个带有sympy表达式并为你提供z3py表达式的函数。
据我所知,没有"官方"这样做的功能,但请看这个(有点过时)答案的详细信息:How to use Z3py and Sympy together您可以使用那里的代码来达到您的目的。 (一个粗略的猜测:由于丰富的情感和不可避免的不匹配,做一个从sympy到z3py的完整转换器可能是不可能的,但你最有可能得到一个处理你的用例的转换器。)