给定表达式f,我想用v
替换f
中的所有变量v_d
(d
是一个数字)。目前我必须通过以下步骤来实现这个目标
f
v
中的每个变量f
,确定其排序,然后生成相应的v_d
var。 因为我还在尝试学习Z3 python,所以可能有更好的方法来做到这一点?
感谢。
我的完整代码如下:
def get_vars(f,rs=[]):
"""obtain variables from f"""
if is_const(f):
try:
f.as_string() #to differentiate btw Int('x') and IntVal('3')
return rs
except AttributeError:
return vset(rs + [f],str)
else:
for f_ in f.children():
rs = get_vars(f_,rs)
return vset(rs,str)
def gen_vars(vs,i):
"""
Generates a new set of variables
E.g. v => v_i , v_next => v_(i+1)
"""
assert i>=0
def mk_name(i,v):
next_kw = '_next'
if str(v).endswith(next_kw):
astr = str(v)[:-len(next_kw)] + '_' + str(i+1)
else:
astr = str(v) + '_' + str(i)
return astr
def mk_var(name,vsort):
if vsort.kind() == Z3_INT_SORT:
v = Int(name)
elif vsort.kind() == Z3_REAL_SORT:
v = Real(name)
elif vsort.kind() == Z3_BOOL_SORT:
v = Bool(name)
elif vsort.kind() == Z3_DATATYPE_SORT:
v = Const(name,vsort)
else:
assert False, 'Cannot handle this sort yet (id: %d)'%vsort.kind()
return v
#so that the longest one is replaced first
vs = sorted(vs,key=str,reverse=True)
names = [mk_name(i,v) for v in vs]
vs_ = [mk_var(ns,v.sort()) for ns,v in zip(names,vs)]
vss = zip(vs,vs_)
return vss
def substitute_f(f,i,vs=None):
"""
Replaces all variables v in f with v_(i*_)
vs: variables in f (could be automatically obtained from f)
"""
assert is_expr(f)
assert isinstance(vs,list) or vs is None
if vs is None:
vs = get_vars(f)
vss = gen_vars(vs,i)
f_ = f
for pvs in vss:
f_ = substitute(f_,pvs)
return f_