z3公式中函数符号的代入

z3公式中函数符号的代入,z3,Z3,用另一个函数替换公式中的函数符号的最佳方法是什么? Z3py的替换似乎只适用于表达式,我现在要做的是尝试猜测函数可以应用到的所有可能的常量/变量组合,然后用另一个函数的应用来替换它们。有更好的方法吗?我们可以实现一个简单的自下而上重写器,给定一个术语s,一个函数f和术语t将用t[r\u 1,…,r\n>替换s中的每个f(r\u 1,…,r\n)。我使用符号t[r_1,…,r_n]来表示通过用术语r_1,…,r_n替换t中的自由变量而获得的术语 重写器可以通过Z3API实现。我使用AstMap缓存

用另一个函数替换公式中的函数符号的最佳方法是什么?
Z3py的替换似乎只适用于表达式,我现在要做的是尝试猜测函数可以应用到的所有可能的常量/变量组合,然后用另一个函数的应用来替换它们。有更好的方法吗?

我们可以实现一个简单的自下而上重写器,给定一个术语
s
,一个函数
f
和术语
t
将用
t[r\u 1,…,r\n>替换
s中的每个
f(r\u 1,…,r\n)
。我使用符号
t[r_1,…,r_n]
来表示通过用术语
r_1
,…,
r_n
替换
t
中的自由变量而获得的术语

重写器可以通过Z3API实现。我使用
AstMap
缓存结果,使用
todo
列表存储仍需处理的表达式

下面是一个简单的例子,它用
g(t+1)
替换
s
f(t)
形式的
f(t)
应用程序

x = Var(0, IntSort())
print rewrite(s, f, g(x + 1))
下面是代码和更多示例。注意,我只在一小部分示例中测试了代码

从z3导入*
def更新_术语(t,参数):
#用args更新术语t的子级。
#len(args)必须等于t中的子级数。
#如果t是一个应用程序,那么len(args)=t.num_args()
#如果t是一个量词,那么len(args)==1
n=len(args)
_args=(Ast*n)()
对于范围(n)中的i:
_args[i]=args[i].as_ast()
将z3.\u返回到\u expr\u ref(z3\u update\u term(t.ctx\u ref(),t.as\u ast(),n,_args),t.ctx)
def重写(s、f、t):
"""
将s中的f应用程序f(r_1,…,r_n)替换为t[r_1,…,r_n]。
"""
待办事项=[]#待办事项列表
todo.append(s)
cache=AstMap(ctx=s.ctx)
待办事项:
n=todo[len(todo)-1]
如果为_var(n):
todo.pop()
缓存[n]=n
elif是应用程序(n):
访问=真
新参数=[]
对于范围内的i(n.num_args()):
arg=n.arg(i)
如果缓存中没有arg:
todo.append(arg)
访问=错误
其他:
新参数追加(缓存[arg])
如果访问:
todo.pop()
g=n.decl()
如果等式(g,f):
新参数=替换变量(t,*新参数)
其他:
新建\u n=更新\u项(n,新参数)
缓存[n]=新的\u n
其他:
断言(是量词(n))
b=n.body()
如果b在缓存中:
todo.pop()
新建\u n=更新\u项(n[cache[b]]
缓存[n]=新的\u n
其他:
todo.append(b)
返回缓存[s]
f=函数('f',IntSort(),IntSort())
a、 b=整数('AB')
s=或(f(a)=0,f(a)=1,f(a+a)==2)
#示例1:将所有f应用程序替换为b
打印重写(s、f、b)
#示例2:将所有f应用程序f(t)替换为g(t+1)
g=函数('g',IntSort(),IntSort())
x=Var(0,IntSort())
打印重写(s、f、g(x+1))
#现在,f和g是二元函数。
f=函数('f',IntSort(),IntSort(),IntSort())
g=函数('g',IntSort(),IntSort(),IntSort())
#示例3:将所有f应用f(t1,t2)替换为g(t2,t1)
s=或(f(a,f(a,b))==0,f(b,a)==1,f(f(1,0),0)==2)
#第一个参数是变量0,第二个参数是变量1。
y=Var(1,IntSort())
打印重写(s、f、g(y、x))
#例4:量词
s=ForAll([a],f(a,b)>=0)
打印重写(s、f、g(y、x+1))

是否可以在将来的版本中将其添加到官方/标准API(如expr.substitute)中?这似乎是一个有用的特性——我需要经常这样做,并且不久前在我的工具中实现了一种方法。你的方法比我的好,特别是在性能方面。是的,这是可能的。我将把这个项目放在待办事项列表中。请随时添加任何功能请求:太好了,非常感谢——我会在codeplex上发布任何其他请求@LeonardodeMoura这个功能已经实现了吗?不幸的是,我从来没有使用Python,我不知道如何用C++代码翻译你的解决方案。