用其他类型替换 SymPy 符号 (Z3Py)
Substitute SymPy Symbols with other types (Z3Py)
我正在使用 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
。
您不能将 sympy 表达式与 z3py 表达式混合搭配。它们是不同的内部数据结构。但是,您可以遍历 sympy 表达式并创建相应的 z3 表达式,但必须单独完成。请注意,对 subs
的调用正在 sympy 世界中进行替换:替换正在进行,但生成的表达式仍然是 sympy 表达式。 (而且很可能是非法的:如果您确实尝试在其上使用任何 sympy 函数,您很可能会从 sympy 本身获得类似的异常。)
您需要开发一个接受 sympy 表达式并为您提供 z3py 表达式的函数。
据我所知,没有 "official" 函数可以执行此操作,但请参阅此(有点过时)答案了解详细信息:How to use Z3py and Sympy together 您也许可以使用那里的代码来服务于您的目的。 (一个粗略的猜测:由于 sympy 的丰富性和不可避免的不匹配,从 sympy 到 z3py 的完整转换器很可能是不可能的,但你很可能得到一个处理你的用例的转换器。)
我正在使用 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
。
您不能将 sympy 表达式与 z3py 表达式混合搭配。它们是不同的内部数据结构。但是,您可以遍历 sympy 表达式并创建相应的 z3 表达式,但必须单独完成。请注意,对 subs
的调用正在 sympy 世界中进行替换:替换正在进行,但生成的表达式仍然是 sympy 表达式。 (而且很可能是非法的:如果您确实尝试在其上使用任何 sympy 函数,您很可能会从 sympy 本身获得类似的异常。)
您需要开发一个接受 sympy 表达式并为您提供 z3py 表达式的函数。
据我所知,没有 "official" 函数可以执行此操作,但请参阅此(有点过时)答案了解详细信息:How to use Z3py and Sympy together 您也许可以使用那里的代码来服务于您的目的。 (一个粗略的猜测:由于 sympy 的丰富性和不可避免的不匹配,从 sympy 到 z3py 的完整转换器很可能是不可能的,但你很可能得到一个处理你的用例的转换器。)