Python 用Z3中的表达式替换函数

Python 用Z3中的表达式替换函数,python,z3,smt,z3py,Python,Z3,Smt,Z3py,我正在使用pythonapi,我想用一个表达式来代替一个声明的函数。也就是说,我想做如下事情: 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

我正在使用pythonapi,我想用一个表达式来代替一个声明的函数。也就是说,我想做如下事情:


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))
从z3导入*
x、 y=整数('x y')
#实际上,这可能是一个动态的问题
#生成表达式
expr=x+y*2
f=函数('f',IntSort(),IntSort(),IntSort())
#不知道该如何实现这一点
函数(f(x,y)=f(y,x)+f(4,0),(f[x,y],expr))
#结果为x+y*2==y+x*2+4
起初,我认为我想要一个包装
expr
(Levent提供了一个很好的答案)的函数,但考虑到它,从替换方法来看,这并没有特别大的帮助,而且肯定感觉有点不对劲


任何帮助或建议都将不胜感激

这是一件不同寻常的事情,但这里有一个解决方案:

从z3导入*
def函数FROMEXPR(参数,expr):
返回lambda*fargs:替换(expr,zip(args,fargs))
x、 y=整数('x y')
expr=x+y
f=函数fromExpr([x,y],expr)
打印(f(x,y))
打印(f(x,IntVal(4)))
打印(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
,以处理可能传递的各种常量。

谢谢!为什么这是一件不寻常的事情?我本以为生成表达式,并想将它们替换成更大的表达式是一件比较常见的事情?因为我只想用上面的表达式替换f(x,y)的实例,我是否最好编写
expr=z3.Lambda([xy],x+y)
并找到一些方法将
f
映射到
expr
?为什么不
def(x,y):返回x+y
?除了
f(3,4)
,它将返回
7
,而不是
3+4
,这将适用于您发布的所有示例;我不知道你为什么要区分这两者。所以我希望能够对任意动态生成的表达式
expr
做到这一点。也许我的问题措词不当,但我希望能够采用一个动态生成的表达式,
expr
,它有一些自由(任意数量,但以前定义过)变量,并用
expr(x,y)
替换
f(x,y)
expr
可以是
x+y
,也可以是
x*y+x**2
或任何其他z3表达式。我一直在玩弄它,但是
substitute
并不像我希望的那样灵活。