从Z3中的现有表达式生成新表达式

时间:2012-08-31 13:48:18

标签: python z3

给定表达式f,我想用v替换f中的所有变量v_dd是一个数字)。目前我必须通过以下步骤来实现这个目标

  1. 获取f
  2. 中的所有变量
  3. 对于v中的每个变量f,确定其排序,然后生成相应的v_d var。
  4. 进行替换
  5. 因为我还在尝试学习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_
    

0 个答案:

没有答案