Ejemplo n.º 1
0
def model_value_to_python(value: z3.ExprRef) -> object:
    if z3.is_string_value(value):
        return value.as_string()
    elif z3.is_real(value):
        return float(value.as_fraction())
    else:
        return ast.literal_eval(repr(value))
Ejemplo n.º 2
0
def function_symbols(s: z3.ExprRef) -> Set[z3.FuncDeclRef]:
    fsymbols = set()
    if is_function_symbol(s):
        fsymbols.add(s.decl())

    for child in s.children():
        fsymbols.update(function_symbols(child))

    return fsymbols
def _get_expr_variables(expression: z3.ExprRef) -> List[z3.ExprRef]:
    """
    Gets the variables that make up the current expression
    :param expression:
    :return:
    """
    result = []
    if not expression.children() and not isinstance(expression,
                                                    z3.BitVecNumRef):
        result.append(expression)
    for child in expression.children():
        c_children = _get_expr_variables(child)
        result.extend(c_children)
    return result
Ejemplo n.º 4
0
def recreate_variable(key: str, variable: z3.ExprRef) -> z3.ExprRef:
    """
    Recreates the variable but renames it with a key that is used
    to make it distinct.
    :param key:
    :param variable:
    """

    return z3.Const(f"{key}_{variable}", variable.sort())
Ejemplo n.º 5
0
    def recreate_with_noise(expr: z3.ExprRef,
                            variables: Dict[z3.ArithRef, float]) -> z3.ExprRef:
        recreate = Expression.recreate_with_noise
        logger.debug("recreating expression with noise: %s", expr)
        d = expr.decl()
        if str(d) != '==':
            children = [recreate(c, variables) for c in expr.children()]
            # TODO find a better solution
            if str(d) == 'And':
                return z3.And(*children, expr.ctx)
            elif str(d) == 'Or':
                return z3.Or(*children, expr.ctx)
            return d(*children)
        lhs, rhs = expr.children()[0], expr.children()[1]
        if not isinstance(lhs, z3.ArithRef) or \
                not isinstance(rhs, z3.ArithRef):
            return d(lhs, rhs)

        def absolute(x):
            return z3.If(x > 0, x, -x, ctx=expr.ctx)

        expr = absolute(lhs - rhs) <= Expression.get_noise(expr, variables)
        logger.debug('recreated expression with noise: %s', expr)
        return expr
Ejemplo n.º 6
0
def is_function_symbol(s: z3.ExprRef) -> bool:
    if not z3.is_app(s):
        return False
    if z3.is_const(s):
        return False

    func = s.decl()
    if func.range() == z3.BoolSort():
        # predicate symbol
        return False

    if func.name().lower() == 'if':
        return False

    return True
Ejemplo n.º 7
0
    def eval(self,
             expression: z3.ExprRef,
             model_completion: bool = False) -> Union[None, z3.ExprRef]:
        """ Evaluate the expression using this model

        :param expression: The expression to evaluate
        :param model_completion: Use the default value if the model has no interpretation of the given expression
        :return: The evaluated expression
        """
        for internal_model in self.raw:
            is_last_model = self.raw.index(internal_model) == len(self.raw) - 1
            is_relevant_model = expression.decl() in list(
                internal_model.decls())
            if is_relevant_model or is_last_model:
                return internal_model.eval(expression, model_completion)
        return None
Ejemplo n.º 8
0
 def get_noise(expr: z3.ExprRef, variables: Dict[z3.ArithRef,
                                                 float]) -> float:
     logger.debug("getting noise for expression: %s", expr)
     if len(expr.children()) == 0:
         if isinstance(expr, z3.ArithRef) and str(expr) in variables:
             return variables[str(expr)]
         else:
             return 0.0
     noises = [Expression.get_noise(c, variables) for c in expr.children()]
     if str(expr.decl()) == '*':
         f = 1.0
         for i in noises:
             f *= i
         return f
     elif str(expr.decl()) == '**':
         if isinstance(expr.children()[1], z3.IntNumRef):
             return math.pow(noises[0], int(expr.children()[1]))
         else:
             # TODO: FIX
             return noises[0]
     else:
         return math.fsum(noises)
Ejemplo n.º 9
0
 def _eval(expr: z3.ExprRef) -> Element:
     assert sorts[expr.sort().name()] is sort, expr
     ans = z3model.eval(expr, model_completion=True)
     assert (sort, ans) in elements, (sort, expr, ans)
     return elements[sort, ans]
Ejemplo n.º 10
0
 def __init__(self, expr: ExprRef):
     self._id = expr.get_id()
     self._expr = expr
     Clause.clause_cache[self._id] = self
Ejemplo n.º 11
0
 def __new__(cls, expr: ExprRef):
     if expr.get_id() in Clause.clause_cache:
         return Clause.clause_cache[expr.get_id()]
     else:
         return super(Clause, cls).__new__(cls)
Ejemplo n.º 12
0
def z3_expr_to_boogie(expr: z3.ExprRef) -> AstExpr:
    d = expr.decl()
    if (d.arity() == 0):
        # Literals and Identifiers
        if (isinstance(expr, z3.BoolRef)):
            if (z3.is_true(expr)):  # No need for explicit ctx
                return AstTrue()
            elif (z3.is_false(expr)):  # No need for explicit ctx
                return AstFalse()
            else:
                return AstId(d.name())
        else:
            assert isinstance(expr.sort(), z3.ArithSortRef), \
                "For now only handle bools and ints"
            if (z3.is_int_value(expr)):  # No need for explicit ctx
                return AstNumber(int(str(expr)))
            else:
                return AstId(d.name())
    elif (d.arity() == 1):
        # Unary operators
        arg = z3_expr_to_boogie(cast(z3.ExprRef, expr.children()[0]))
        boogie_op = {
            '-': '-',
            'not': '!',
        }[d.name()]
        return AstUnExpr(boogie_op, arg)
    elif (d.name() == "if" and d.arity() == 2):
        c = cast(List[z3.ExprRef], expr.children())
        cond = z3_expr_to_boogie(c[0])
        thenB = z3_expr_to_boogie(c[1])
        return AstBinExpr(cond, "==>", thenB)
    elif (d.arity() == 2):
        # Binary operators
        try:
            boogie_op, assoc = {
                "+": ("+", "left"),
                "-": ("-", "left"),
                "*": ("*", "left"),
                "div": ("div", "left"),
                "mod": ("mod", "none"),
                "=": ("==", "none"),
                "distinct": ("!=", "none"),
                "<": ("<", "none"),
                ">": (">", "none"),
                "<=": ("<=", "none"),
                ">=": (">=", "none"),
                "and": ("&&", "left"),
                "or": ("||", "left"),
                "=>": ("==>", "none"),
                "Implies": ("==>", "none"),
            }[d.name()]
        except:
            boogie_op, assoc = d.name(), "func"
        c = cast(List[z3.ExprRef], expr.children())
        if assoc == "func":
            try:
                pars = list(map(z3_expr_to_boogie, c))
                fun = AstFuncExpr(boogie_op, pars)
            except Exception as ex:
                error(str(ex))
            return fun
        elif (assoc == "left"):
            return reduce(
                lambda acc, x: AstBinExpr(acc, boogie_op, z3_expr_to_boogie(x)
                                          ), c[1:], z3_expr_to_boogie(c[0]))
        elif (assoc == "none" or assoc == "right"):
            assert len(c) == 2, "NYI otherwise"
            lhs = z3_expr_to_boogie(c[0])
            rhs = z3_expr_to_boogie(c[1])
            return AstBinExpr(lhs, boogie_op, rhs)
        else:
            raise Exception("NYI")
    elif (d.name() == "if"):
        c = cast(List[z3.ExprRef], expr.children())
        cond = z3_expr_to_boogie(c[0])
        thenB = z3_expr_to_boogie(c[1])
        elseB = z3_expr_to_boogie(c[2])
        return AstBinExpr(AstBinExpr(cond, "==>", thenB), "&&",
                          AstBinExpr(AstUnExpr("!", cond), "==>", elseB))
    else:
        raise Exception("Can't translate z3 expression " + str(expr) +
                        " to boogie.")
Ejemplo n.º 13
0
def fast_ne(a: ExprRef, b: ExprRef):
  """Equivalent of z3 __ne__."""
  z3args = (Ast * 2)()
  z3args[0], z3args[1] = a.as_ast(), b.as_ast()
  return BoolRef(Z3_mk_distinct(CTX.ref(), 2, z3args), CTX)
Ejemplo n.º 14
0
def fast_eq(a: ExprRef, b: ExprRef):
  """Equivalent of z3 __eq__."""
  return BoolRef(Z3_mk_eq(CTX.ref(), a.as_ast(), b.as_ast()), CTX)