def to_smt(self, expr_object, smt_context_object, var_subst_map): smt_binding_var = [ semantics_types.expression_to_smt(bv, smt_context_object, var_subst_map) for bv in self.binding_vars ] smt_children = [ semantics_types.expression_to_smt(child, smt_context_object, var_subst_map) for child in expr_object.children ] return z3.substitute(smt_children[-1], list(zip(smt_binding_var, smt_children[:-1])))
def _check_equivalence_under_constraint(expr1, expr2, smt_ctx, arg_vars, constraint, random): import z3 expr1_smt = semantics_types.expression_to_smt(expr1, smt_ctx, arg_vars) expr2_smt = semantics_types.expression_to_smt(expr2, smt_ctx, arg_vars) if constraint is not None: constraint_smt = semantics_types.expression_to_smt(constraint, smt_ctx, arg_vars) else: constraint_smt = z3.BoolVal(True, ctx=smt_ctx.ctx()) condition = z3.And(constraint_smt, (expr1_smt != expr2_smt), smt_ctx.ctx()) if random: return random_sample(condition, smt_ctx.ctx(), arg_vars) else: return _z3_solve(condition, arg_vars)
def sample(pred_or_pred_smt, smt_ctx, arg_vars): if is_expression(pred_or_pred_smt): pred_smt = semantics_types.expression_to_smt(pred_or_pred_smt, smt_ctx, arg_vars) else: pred_smt = pred_or_pred_smt return _z3_solve(pred_smt, arg_vars)
def random_sample(pred_or_pred_smt, smt_ctx, arg_vars): import z3 import random if len(arg_vars) != 1 or type(arg_vars[0]) != z3.BitVecRef: raise NotImplementedError arg = arg_vars[0] bit_vec_size = arg.size() positions = list(range(bit_vec_size)) random.shuffle(positions) if is_expression(pred_or_pred_smt): pred_smt = semantics_types.expression_to_smt(pred_or_pred_smt, smt_ctx, arg_vars) else: pred_smt = pred_or_pred_smt orig_sample = _z3_solve(pred_smt, arg_vars) if orig_sample is None: return None zero = z3.BitVecVal(0, bit_vec_size, pred_smt.ctx) for position in positions: mask = z3.BitVecVal((1 << position), bit_vec_size, pred_smt.ctx) with_one = z3.And(pred_smt, (arg & mask == mask), pred_smt.ctx) with_zero = z3.And(pred_smt, (arg & mask == zero), pred_smt.ctx) with_one_sat = _z3_solve(with_one, arg_vars) with_zero_sat = _z3_solve(with_zero, arg_vars) assert with_one_sat is not None or with_zero_sat is not None if with_one_sat == None: pred_smt = with_zero elif with_zero_sat == None: pred_smt = with_one else: # Choose randomly pred_smt = random.choice([with_one, with_zero]) result = _z3_solve(pred_smt, arg_vars) assert result is not None return result