def If(cond, a, b): """ Conceptually computes ite(cond, a, b) but try to simplify out the ite if possible and supports more than just plain z3 datatypes. """ if not z3.is_expr(cond): raise ValueError("util.If: Expected cond to be a z3 expression, got {!r}".format(cond)) cond = simplify(cond) if is_true(cond): return a if is_false(cond): return b if hasattr(a, 'size') and hasattr(b, 'size'): assert a.size() == b.size( ), "Can not ite types of different size {} v. {}".format(a.size(), b.size()) if definitely_equal(a, b): return a if hasattr(a, 'ite'): assert type(a) == type(b), "{} v {}".format(type(a), type(b)) return a.ite(b, cond) is_z3_func = z3.is_func_decl(a) or z3.is_func_decl(b) is_py_func = isinstance(a, types.FunctionType) or isinstance(b, types.FunctionType) if is_z3_func or is_py_func: if not isinstance(a, types.FunctionType) and not isinstance(a, z3.FuncDeclRef): a = (lambda outer: lambda *args, **kwargs: outer)(a) if not isinstance(b, types.FunctionType) and not isinstance(b, z3.FuncDeclRef): b = (lambda outer: lambda *args, **kwargs: outer)(b) return lambda *args, **kwargs: If(cond, a(*args, **kwargs), b(*args, **kwargs)) if isinstance(a, dict) and isinstance(b, dict): # For simplicity, only ite dicts with exactly the same keys # and only if their values can be ite'd assert set(a.keys()) == set(b.keys()), 'Can not ite different dicts {} v. {}'.format(a.keys(), b.keys()) c = {} for k in a.keys(): c[k] = If(cond, a[k], b[k]) return c if isinstance(a, list): a = tuple(a) if isinstance(b, list): b = tuple(b) if isinstance(a, tuple) and isinstance(b, tuple): # For simplicity, only ite tuples of same length # and only if their values can be ite'd assert len(a) == len(b), 'Can not ite tuples of different length {} v. {}'.format(len(a), len(b)) return tuple([If(cond, ela, elb) for ela, elb in zip(a, b)]) if not hasattr(a, 'sexpr'): raise ValueError("Can not ite object of type {!r}".format(type(a))) return z3.If(cond, a, b)
def __call__(self, term): if is_func_decl(term): return term if is_quantifier(term): vars0 = [ Const(term.var_name(i), term.var_sort(i)) for i in xrange(term.num_vars()) ] #print("bounded variables: ", vars0) body = self(term.body()) all_active = And([self.curr_active_func(x) for x in vars0]) if term.is_forall(): #ForAll(x, body) -> ForAll(x, active(x) -> body) return ForAll(vars0, Implies(all_active, body)) #return ForAll(vars0, body) else: # assume 'exists' #Exist(x, body) -> exist(x, active(x) ^ body) return Exists(vars0, And(all_active, body)) else: chs = [self(ch) for ch in term.children()] if len(chs) == 0: return term else: if is_and(term): return And(chs) elif is_or(term): return Or(chs) else: r = term.decl() return r(chs) return term
def __call__(self, term): if is_func_decl(term): term_prime = self.d.get(get_id(term), term) #print self.d #print term, "--->", term_prime return term_prime if is_quantifier(term): vars0 = [ Const(term.var_name(i), term.var_sort(i)) for i in xrange(term.num_vars()) ] vars0.reverse() b = substitute_vars(term.body(), *vars0) body = self(b) if term.is_forall(): return ForAll(vars0, body) else: # assume 'exists' return Exists(vars0, body) else: chs = [self(ch) for ch in term.children()] if len(chs) == 0: return self.d.get(get_id(term), term) else: if is_and(term): return And(chs) elif is_or(term): return Or(chs) else: r = term.decl() try: r = self.d[get_id(r)] except KeyError: pass return r(chs) return term
def main(self, a): if z3.is_expr(a): return self.pp_expr(a, 0, []) elif z3.is_sort(a): return self.pp_sort(a) elif z3.is_func_decl(a): return self.pp_decl(a) elif isinstance(a, z3.Goal) or isinstance(a, z3.AstVector): return self.pp_seq(a, 0, []) elif isinstance(a, z3.Solver): return self.pp_seq(a.assertions(), 0, []) elif isinstance(a, z3.Fixedpoint): return a.sexpr() elif isinstance(a, z3.Optimize): return a.sexpr() elif isinstance(a, z3.ApplyResult): return self.pp_seq_seq(a, 0, []) elif isinstance(a, z3.ModelRef): return self.pp_model(a) elif isinstance(a, z3.FuncInterp): return self.pp_func_interp(a) elif isinstance(a, list) or isinstance(a, tuple): return self.pp_list(a) else: return to_format(self.pp_unknown())
def main(self, a): if z3.is_expr(a): return self.pp_expr(a, 0, []) elif z3.is_sort(a): return self.pp_sort(a) elif z3.is_func_decl(a): return self.pp_name(a) elif isinstance(a, z3.Goal) or isinstance(a, z3.AstVector): return self.pp_seq(a, 0, []) elif isinstance(a, z3.Solver): return self.pp_seq(a.assertions(), 0, []) elif isinstance(a, z3.Fixedpoint): return a.sexpr() elif isinstance(a, z3.Optimize): return a.sexpr() elif isinstance(a, z3.ApplyResult): return self.pp_seq_seq(a, 0, []) elif isinstance(a, z3.ModelRef): return self.pp_model(a) elif isinstance(a, z3.FuncInterp): return self.pp_func_interp(a) elif isinstance(a, list) or isinstance(a, tuple): return self.pp_list(a) else: return to_format(self.pp_unknown())
def translate(self, expr, bound_variables=[]): if z3.is_const(expr): return self.mk_const(expr) # raise Z3_Unexpected_Expression('Unrecognized constant') elif z3.is_var(expr): # a de Bruijn indexed bound variable bv_length = len(bound_variables) return bound_variables[bv_length - z3.get_var_index(expr) - 1] elif z3.is_app(expr): args = [self.translate(expr.arg(i), bound_variables) for i in range(expr.num_args())] return self.mk_fun(expr.decl())(*args) # else: # raise Z3_Unexpected_Expression(expr) elif z3.is_quantifier(expr): num_vars = expr.num_vars() # vars = [language.const_dict[expr.var_name(i)] # for i in range(num_vars)] vars = [const(expr.var_name(i), self.mk_sort(expr.var_sort(i))) \ for i in range(num_vars)] new_bound_variables = bound_variables + vars body = self.translate(expr.body(), new_bound_variables) if expr.is_forall(): return forall(vars, body) else: return exists(vars, body) elif z3.is_func_decl(expr): return self.mk_fun(expr) else: print expr.kind raise Z3_Unexpected_Expression(expr)
def _dup_symbol(cls, symbol, suffix): if is_func_decl(symbol): args = [symbol.domain(i) for i in xrange(symbol.arity())] name = symbol.name() return Function(name + suffix, *(args + [symbol.range()])) elif is_const(symbol): name = symbol.decl().name() return Const(name + suffix, symbol.sort())
def definitely_equal(a, b): """ A conservative equals function. Must return a Python boolean. Returns True only if we can definitely determine that a and b are equal. A value of False only means they are potentially not equal. """ if type(a) != type(b): return False container_types = [dict, list, tuple] if type(a) in container_types or type(b) in container_types: return a is b if a is b: return True if hasattr(a, 'sexpr'): if z3.is_func_decl(a) or z3.is_func_decl(b): return False return z3.is_true(simplify(a == b)) return a == b
def add_engine_object(self, elem): if isinstance(elem, tuple): # add object as (engine name, object) assert elem[0] in [MUZ, KANREN_LOGPY] self._engine_objects[elem[0]] = elem[1] elif z3.is_func_decl(elem): self._engine_objects[MUZ] = elem elif isinstance(elem, kanren.Relation): self._engine_objects[KANREN_LOGPY] = elem else: raise Exception(f"unsupported Predicate object {type(elem)}")