我正在使用Z3 Python API,我想获取一个表达式,并将其替换为已声明的函数。也就是说,我想执行以下操作:
from z3 import *
x, y = Ints('x y')
# In practice, this could be a dynamically
# generated expression
expr = x + y * 2
f = Function('f', IntSort(), IntSort(), IntSort())
# Not sure how to implement this
function_substitute(f(x, y) == f(y, x) + f(4,0), (f, [x,y], expr))
# Results in x + y * 2 == y + x * 2 + 4
最初,我以为我想要一个包装expr
的函数(Levent为其提供了一个很好的答案),但是考虑了一下,这对于替代方法并不是特别有用,并且肯定有点怪异
任何帮助或建议将不胜感激!
答案 0 :(得分:1)
这是不寻常的事情,但这是一个解决方案:
from z3 import *
def functionFromExpr(args, expr):
return lambda *fargs: substitute(expr, zip (args, fargs))
x, y = Ints ('x y')
expr = x + y
f = functionFromExpr([x, y], expr)
print (f (x, y))
print (f (x, IntVal(4)))
print (f (IntVal(3), IntVal(4)))
此打印:
x + y
x + 4
3 + 4
请注意,您需要显式传递表达式,方法是自己在调用站点进行适当的转换。如果要避免这种情况,可以改为执行以下操作:
def mkExpr(a):
if is_expr(a):
return a
elif isinstance(a, int):
return IntVal(a)
elif isinstance(a, float):
return FPVal(a)
else:
raise Exception("Don't know how to convert: %s" % a.__repr__())
def functionFromExpr(args, expr):
return lambda *fargs: substitute(expr, zip (args, [mkExpr(e) for e in fargs]))
x, y = Ints ('x y')
expr = x + y
f = functionFromExpr([x, y], expr)
print (f (x, y))
print (f (x, 4))
print (f (3, 4))
显然,您必须适当地修改mkExpr
才能处理可能要传递的各种常量。