def _isVar(self, elem):
     return any([
         z3.is_int_value(z3.simplify(elem)),
         z3.is_rational_value(z3.simplify(elem)),
         z3.is_algebraic_value(z3.simplify(elem)),
         is_const(z3.simplify(elem))
     ])
Exemple #2
0
def _is_literal(z3ast):
    if z3.is_int(z3ast):
        return z3.is_int_value(z3ast)
    if z3.is_bool(z3ast):
        return z3.is_true(z3ast) or z3.is_false(z3ast)
    if z3ast.sort_kind() == z3.Z3_UNINTERPRETED_SORT:
        return z3.is_const(z3ast) and '!' in str(z3ast)
    raise NotImplementedError('Don\'t know how to literal-check %s' % z3ast)
Exemple #3
0
def _is_literal(z3ast):
    if z3.is_int(z3ast):
        return z3.is_int_value(z3ast)
    if z3.is_bool(z3ast):
        return z3.is_true(z3ast) or z3.is_false(z3ast)
    if z3ast.sort_kind() == z3.Z3_UNINTERPRETED_SORT:
        return z3.is_const(z3ast) and '!' in str(z3ast)
    raise NotImplementedError('Don\'t know how to literal-check %s' % z3ast)
Exemple #4
0
def is_bool_or_int_value(value):
    if z3.is_int_value(value):
        return True
    if value.sort() == z3.BoolSort():
        if z3.is_true(value) or z3.is_false(value):
            return True
    else:
        return False
Exemple #5
0
def collect_numerals(z3term):
    if z3.is_int_value(z3term) or z3.is_bv_value(z3term):
        yield z3term
    elif z3.is_app_of(z3term, z3.Z3_OP_ITE):
        for z in collect_numerals(z3term.arg(1)):
            yield z
        for z in collect_numerals(z3term.arg(2)):
            yield z
Exemple #6
0
 def pp_app(self, a, d, xs):
     if z3.is_int_value(a):
         return self.pp_int(a)
     elif z3.is_rational_value(a):
         return self.pp_rational(a)
     elif z3.is_algebraic_value(a):
         return self.pp_algebraic(a)
     elif z3.is_bv_value(a):
         return self.pp_bv(a)
     elif z3.is_finite_domain_value(a):
         return self.pp_fd(a)
     elif z3.is_fprm_value(a):
         return self.pp_fprm_value(a)
     elif z3.is_fp_value(a):
         return self.pp_fp_value(a)
     elif z3.is_fp(a):
         return self.pp_fp(a, d, xs)
     elif z3.is_string_value(a):
         return self.pp_string(a)
     elif z3.is_const(a):
         return self.pp_const(a)
     else:
         f = a.decl()
         k = f.kind()
         if k == Z3_OP_POWER:
             return self.pp_power(a, d, xs)
         elif k == Z3_OP_DISTINCT:
             return self.pp_distinct(a, d, xs)
         elif k == Z3_OP_SELECT:
             return self.pp_select(a, d, xs)
         elif k == Z3_OP_SIGN_EXT or k == Z3_OP_ZERO_EXT or k == Z3_OP_REPEAT:
             return self.pp_unary_param(a, d, xs)
         elif k == Z3_OP_EXTRACT:
             return self.pp_extract(a, d, xs)
         elif k == Z3_OP_RE_LOOP:
             return self.pp_loop(a, d, xs)
         elif k == Z3_OP_DT_IS:
             return self.pp_is(a, d, xs)
         elif k == Z3_OP_ARRAY_MAP:
             return self.pp_map(a, d, xs)
         elif k == Z3_OP_CONST_ARRAY:
             return self.pp_K(a, d, xs)
         elif k == Z3_OP_PB_AT_MOST:
             return self.pp_atmost(a, d, f, xs)
         elif k == Z3_OP_PB_LE:
             return self.pp_pbcmp(a, d, f, xs)
         elif k == Z3_OP_PB_GE:
             return self.pp_pbcmp(a, d, f, xs)
         elif k == Z3_OP_PB_EQ:
             return self.pp_pbcmp(a, d, f, xs)
         elif z3.is_pattern(a):
             return self.pp_pattern(a, d, xs)
         elif self.is_infix(k):
             return self.pp_infix(a, d, xs)
         elif self.is_unary(k):
             return self.pp_unary(a, d, xs)
         else:
             return self.pp_prefix(a, d, xs)
Exemple #7
0
 def convert(t, values):
     if z3.is_int_value(t):
         return t.as_long()
     if z3.is_app(t):
         func = globals()[t.decl().name()]
         return func(
             *[convert(t.arg(i), values) for i in range(t.num_args())])
     elif z3.is_var(t):
         return values[z3.get_var_index(t)]
Exemple #8
0
 def pp_app(self, a, d, xs):
     if z3.is_int_value(a):
         return self.pp_int(a)
     elif z3.is_rational_value(a):
         return self.pp_rational(a)
     elif z3.is_algebraic_value(a):
         return self.pp_algebraic(a)        
     elif z3.is_bv_value(a):
         return self.pp_bv(a)
     elif z3.is_finite_domain_value(a):
         return self.pp_fd(a)
     elif z3.is_fprm_value(a):
         return self.pp_fprm_value(a)
     elif z3.is_fp_value(a):
         return self.pp_fp_value(a)
     elif z3.is_fp(a):
         return self.pp_fp(a, d, xs)
     elif z3.is_string_value(a):
         return self.pp_string(a)
     elif z3.is_const(a):
         return self.pp_const(a)
     else:
         f = a.decl()
         k = f.kind()
         if k == Z3_OP_POWER:
             return self.pp_power(a, d, xs)
         elif k == Z3_OP_DISTINCT:
             return self.pp_distinct(a, d, xs)
         elif k == Z3_OP_SELECT:
             return self.pp_select(a, d, xs)
         elif k == Z3_OP_SIGN_EXT or k == Z3_OP_ZERO_EXT or k == Z3_OP_REPEAT:
             return self.pp_unary_param(a, d, xs)
         elif k == Z3_OP_EXTRACT:
             return self.pp_extract(a, d, xs)
         elif k == Z3_OP_DT_IS:
             return self.pp_is(a, d, xs)
         elif k == Z3_OP_ARRAY_MAP:
             return self.pp_map(a, d, xs)
         elif k == Z3_OP_CONST_ARRAY:
             return self.pp_K(a, d, xs)
         elif k == Z3_OP_PB_AT_MOST:
             return self.pp_atmost(a, d, f, xs)
         elif k == Z3_OP_PB_LE:
             return self.pp_pbcmp(a, d, f, xs)
         elif k == Z3_OP_PB_GE:
             return self.pp_pbcmp(a, d, f, xs)
         elif k == Z3_OP_PB_EQ:
             return self.pp_pbcmp(a, d, f, xs)
         elif z3.is_pattern(a):
             return self.pp_pattern(a, d, xs)
         elif self.is_infix(k):
             return self.pp_infix(a, d, xs)
         elif self.is_unary(k):
             return self.pp_unary(a, d, xs)
         else:
             return self.pp_prefix(a, d, xs)
def model_to_val(m, var):
    p = m[var]
    if is_int_value(p):
        return float(p.as_long())

    if is_algebraic_value(p):
        p = p.approx(5)  # Precise to 5 decimals
    if is_rational_value(p):
        x = float(p.numerator_as_long()) / \
            float(p.denominator_as_long())
    return x
Exemple #10
0
def collect_consts(smt_expr):
    """Returns list of all constants (as ExprRef instances) that appear in the given expression"""
    assert (isinstance(smt_expr, z3.ExprRef))
    non_unique_res = expr_fold(smt_expr, lambda t: [t]
                               if not z3.is_int_value(t) else [],
                               lambda _, cs: utils.flatten(cs))
    for c in non_unique_res:
        assert (z3.is_const(c))
    # Leaving the following in, in case conversion breaks again with strange z3 exceptions...
    #logger.info([c.__class__ for c in non_unique_res])
    res = set(non_unique_res)
    #logger.info("Consts in expr: {}".format(res))
    return [c for c in res if str(c) not in keywords]
Exemple #11
0
    def rec(e):
        if isinstance(e, z3.QuantifierRef):
            for n in range(e.num_vars()):
                mkvar(e.var_name(n), e.var_sort(n))
        elif z3.is_algebraic_value(e) or \
             z3.is_bv_value(e) or \
             z3.is_int_value(e) or \
             z3.is_rational_value(e):
            pass
        elif z3.is_const(e):
            mkvar(str(e), e.sort())

        for sub in e.children():
            rec(sub)
Exemple #12
0
def to_python(some_number):
    if isinstance(some_number, numbers.Number):
        return some_number

    some_number = z3.simplify(some_number)
    if z3.is_algebraic_value(some_number):
        some_number = some_number.approx(config.approx)

    if z3.is_int_value(some_number):
        return some_number.as_long()
    else:
        try:
            return float(some_number.numerator_as_long()) / float(
                some_number.denominator_as_long())
        except Exception:
            return str(some_number)  # last resort, return as string
Exemple #13
0
    def val(self, exp):
        '''Evaluate a z3 ref to a python value based on this solution.
         '''
        v = self.model.eval(exp)
        if z3.is_true(v):
            return True
        if z3.is_false(v):
            return False
        if z3.is_algebraic_value(v):
            v = v.approx(20)
        if z3.is_int_value(v):
            return v.as_long()
        if z3.is_rational_value(v):
            return v.numerator_as_long() / v.denominator_as_long()

        return z3.is_true(v)
Exemple #14
0
def to_python(some_number):
    raise DeprecationWarning("use config.to_python instead")
    if isinstance(some_number, (int, float, str, bool)):
        return some_number

    some_number = z3.simplify(some_number)
    if z3.is_algebraic_value(some_number):
        some_number = some_number.approx(config.approx)

    if z3.is_int_value(some_number):
        return some_number.as_long()
    else:
        try:
            return float(some_number.numerator_as_long()) / float(
                some_number.denominator_as_long())
        except Exception:
            return str(some_number)  # last resort
Exemple #15
0
def get_py_val_from_z3_val(z3_result):
    if z3_result is not None:
        if z3.is_int_value(z3_result):
            return z3_result.as_long()
        elif z3.is_real(z3_result):
            return float(z3_result.numerator_as_long()) / float(
                z3_result.denominator_as_long())
        elif z3.is_true(z3_result):
            return True
        elif z3.is_false(z3_result):
            return False
        elif z3.is_string_value(z3_result):
            return z3_result.as_string()
        else:
            raise NotImplementedError(
                "Z3 model result other than int, real, bool, string is not supported yet!"
            )
Exemple #16
0
 def z3ToPoint(self, point):
     res = []
     # get the variables corresponding to the axis names
     for idx, i in enumerate(self.axis_names):
         locals()[i] = Globals.z3variables[i]
         if i in Globals.z3types:  # non-numeric points -> coord to value
             value = Globals.z3types[i][point[locals()[i]].as_long()]
         elif None == point[locals()[i]]:
             info("no value for %s, take %r (incomplete model)" %
                  (self.axis_names[idx], self.axis_val_ranges[idx][0]))
             value = self.axis_val_ranges[idx][0]
         elif z3.is_int_value(point[locals()[i]]):
             value = point[locals()[i]].as_long()
         elif z3.is_true(point[locals()[i]]) or z3.is_false(
                 point[locals()[i]]):
             value = z3.is_true(point[locals()[i]])
         res.append(value)
     return res
Exemple #17
0
 def mk_const(self, c):
     if z3.is_int_value(c):
         return ii(c.as_long())
     if z3.is_rational_value(c):
         # TODO: what should we convert a rational to?
         return rr(Fraction(c.numerator_as_long(), \
                            c.denominator_as_long()))
     elif z3.is_true(c):
         return true
     elif z3.is_false(c):
         return false
     else:
         try:
             return self.context.decls[str(c)]
         except KeyError:
             #Constant is not found in the context
             typ = self.mk_sort(c.sort())
             return const(str(c), typ)
Exemple #18
0
 def mk_const(self, c):
     if z3.is_int_value(c):
         return ii(c.as_long())
     if z3.is_rational_value(c):
         # TODO: what should we convert a rational to?
         return rr(Fraction(c.numerator_as_long(), \
                            c.denominator_as_long()))
     elif z3.is_true(c):
         return true
     elif z3.is_false(c):
         return false
     else:
         try:
             return self.context.decls[str(c)]
         except KeyError:
             #Constant is not found in the context
             typ = self.mk_sort(c.sort())
             return const(str(c), typ)
def get_value(r):
    # https://stackoverflow.com/questions/12598408/z3-python-getting-python-values-from-model/12600208
    """
    Convert from Z3 to python values.
    """
    if z3.is_true(r):
        return z3.is_true(r)
    elif z3.is_false(r):
        return z3.is_false(r)
    elif z3.is_int_value(r):
        return r.as_long()
    elif z3.is_algebraic_value(r):
        return round(num(r.approx(15)), 10)
    elif z3.is_rational_value(r):
        return r.as_decimal(20)
    elif r is None:
        None
    else:
        return num(r)
Exemple #20
0
 def pp_app(self, a, d, xs):
     if z3.is_int_value(a):
         return self.pp_int(a)
     elif z3.is_rational_value(a):
         return self.pp_rational(a)
     elif z3.is_algebraic_value(a):
         return self.pp_algebraic(a)
     elif z3.is_bv_value(a):
         return self.pp_bv(a)
     elif z3.is_fprm_value(a):
         return self.pp_fprm_value(a)
     elif z3.is_fp_value(a):
         return self.pp_fp_value(a)
     elif z3.is_fp(a):
         return self.pp_fp(a, d, xs)
     elif z3.is_const(a):
         return self.pp_const(a)
     else:
         f = a.decl()
         k = f.kind()
         if k == Z3_OP_POWER:
             return self.pp_power(a, d, xs)
         elif k == Z3_OP_DISTINCT:
             return self.pp_distinct(a, d, xs)
         elif k == Z3_OP_SELECT:
             return self.pp_select(a, d, xs)
         elif k == Z3_OP_SIGN_EXT or k == Z3_OP_ZERO_EXT or k == Z3_OP_REPEAT:
             return self.pp_unary_param(a, d, xs)
         elif k == Z3_OP_EXTRACT:
             return self.pp_extract(a, d, xs)
         elif k == Z3_OP_ARRAY_MAP:
             return self.pp_map(a, d, xs)
         elif k == Z3_OP_CONST_ARRAY:
             return self.pp_K(a, d, xs)
         elif z3.is_pattern(a):
             return self.pp_pattern(a, d, xs)
         elif self.is_infix(k):
             return self.pp_infix(a, d, xs)
         elif self.is_unary(k):
             return self.pp_unary(a, d, xs)
         else:
             return self.pp_prefix(a, d, xs)
Exemple #21
0
def coerceTypesIfPossible(var, other_var):
    if z3.is_or(other_var) and not z3.is_bool(var):
        other_var = transformNonBooleanLazyEvaluations(other_var)
    if z3.is_or(var) and not z3.is_bool(other_var):
        var = transformNonBooleanLazyEvaluations(var)

    if z3.is_and(other_var) and not z3.is_bool(var):
        other_var = transformNonBooleanLazyEvaluations(other_var)
    if z3.is_and(var) and not z3.is_bool(other_var):
        var = transformNonBooleanLazyEvaluations(var)
    if var.decl().kind() == z3.Z3_OP_UNINTERPRETED:
        if z3.is_bool(other_var) and not z3.is_bool(var):
            infered_types[str(var)] = 'boolean'
            return z3.Bool(str(var)), other_var
        if z3.is_string(other_var) and not z3.is_string(var):
            if other_var.as_string() == '':
                # we probably dont want to coerce in this specific case as this is merely a non empty check
                if z3.is_bool(var):
                    return var, z3.BoolVal(False)
                if z3.is_int(var):
                    return var, z3.IntVal(0)
            else:
                infered_types[str(var)] = 'string'
                return z3.String(str(var)), other_var
        if z3.is_int(other_var) and not z3.is_int(var):
            infered_types[str(var)] = 'number'
            return z3.Int(str(var)), other_var
    elif var.decl().kind() == z3.Z3_OP_UNINTERPRETED:
        if z3.is_bool(var):
            infered_types[str(var)] = 'boolean'
        if z3.is_string(var):
            infered_types[str(var)] = 'string'
        if z3.is_int(var):
            infered_types[str(var)] = 'number'
    else:
        # this means that it is non-interpreted and we need to coerce other var to the type of var
        if z3.is_string(var) and z3.is_int_value(other_var):
            other_var = z3.StringVal(str(other_var))
        if z3.is_arith(var) and z3.is_string(other_var):
            other_var = z3.IntVal(int(other_var.as_string()))

    return var, other_var
Exemple #22
0
    def check_value(self, val):
        assert val is not None, f"Setting a port's value to None is not allowed"

        # check that we only assign correct values to the ports
        if isinstance(self.domain, list):
            return val in self.domain
        elif self.domain is Types.INTEGER:
            return isinstance(val, int) or z3.is_int_value(val) or z3.is_int(val)
        elif self.domain is Types.REAL:  # z3 types
            return (isinstance(val, numbers.Number) and not isinstance(val, bool)) or z3.is_real(val)
        elif self.domain is Types.INT: # TODO: check also for these types
            return isinstance(val, int)
        elif self.domain is Types.FLOAT: # TODO: check also for these types
            return (isinstance(val, numbers.Number) and not isinstance(val, bool))
        elif self.domain is Types.STRING: # TODO: check also for these types
            return isinstance(val, str)
        elif self.domain is Types.BOOL: # TODO: check also for these types
            return isinstance(val, bool)
        else:
            return False
Exemple #23
0
def unique_leaves(exp, leaf_keys=None):
    def insert_and_yield(e):
        k = exp_key(e)
        if k not in leaf_keys:
            leaf_keys.append(k)
            yield e

    if leaf_keys is None: leaf_keys = []

    if z3.is_const(exp) and not (z3.is_int_value(exp)
                                 or z3.is_rational_value(exp)):
        for leaf in insert_and_yield(exp):
            yield leaf
    elif z3.is_app(exp):
        for i in range(exp.num_args()):
            for leaf in unique_leaves(exp.arg(i), leaf_keys):
                yield leaf
    else:
        assert z3.is_var(exp)
        for leaf in insert_and_yield(exp):
            yield leaf
Exemple #24
0
def z3_to_val(z3_expr):
    """Send a z3 expression to it's value
    as a python expression, if it has one,
    otherwise return the expresson itself.
    
    Arguments:
    - `z3_expr`: a z3 AST
    """
    if z3.is_int_value(z3_expr):
        return z3_expr.as_long()
    if z3.is_rational_value(z3_expr):
        return Fraction(z3_expr.numerator_as_long(), \
                        z3_expr.denominator_as_long())
    elif z3.is_true(z3_expr):
        return True
    elif z3.is_false(z3_expr):
        return False
    elif isinstance(z3_expr, z3.FuncInterp):
        return z3_to_fun(z3_expr)
    else:
        return z3_expr
Exemple #25
0
def z3_to_val(z3_expr):
    """Send a z3 expression to its value
    as a python expression, if it has one,
    otherwise return the expresson itself.
    
    Arguments:
    - `z3_expr`: a z3 AST
    """
    if z3.is_int_value(z3_expr):
        return z3_expr.as_long()
    if z3.is_rational_value(z3_expr):
        return Fraction(z3_expr.numerator_as_long(), \
                        z3_expr.denominator_as_long())
    elif z3.is_true(z3_expr):
        return True
    elif z3.is_false(z3_expr):
        return False
    elif isinstance(z3_expr, z3.FuncInterp):
        return z3_to_fun(z3_expr)
    else:
        return z3_expr
Exemple #26
0
 def pp_app(self, a, d, xs):
     if z3.is_int_value(a):
         return self.pp_int(a)
     elif z3.is_rational_value(a):
         rat = self.pp_rational(a)
         return rat
     elif z3.is_algebraic_value(a):
         return self.pp_algebraic(a)
     elif z3.is_bv_value(a):
         return self.pp_bv(a)
     elif z3.is_const(a):
         return self.pp_const(a)
     else:
         f = a.decl()
         k = f.kind()
         if k == Z3_OP_POWER:
             return self.pp_power(a, d, xs)
         elif k == Z3_OP_DISTINCT:
             return self.pp_distinct(a, d, xs)
         elif k == Z3_OP_SELECT:
             return self.pp_select(a, d, xs)
         elif k == Z3_OP_SIGN_EXT or k == Z3_OP_ZERO_EXT or k == Z3_OP_REPEAT:
             return self.pp_unary_param(a, d, xs)
         elif k == Z3_OP_EXTRACT:
             return self.pp_extract(a, d, xs)
         elif k == Z3_OP_ARRAY_MAP:
             return self.pp_map(a, d, xs)
         elif k == Z3_OP_CONST_ARRAY:
             return self.pp_K(a, d, xs)
         elif z3.is_pattern(a):
             return self.pp_pattern(a, d, xs)
         elif self.is_infix(k):
             return self.pp_infix(a, d, xs)
         elif self.is_unary(k):
             return self.pp_unary(a, d, xs)
         else:
             return self.pp_prefix(a, d, xs)
Exemple #27
0
 def _state_id_to_prism_variable_to_value(self, state_id):
     """
         Returns a dict from prism variables to z3 values representing the valuation of state_id.
     :param state_id:
     :return:
     """
     state_valuation = self.state_graph.get_state_valuation(state_id)
     return {input_variable.get_prism_variable(): z3.is_true(z3_value) for input_variable, z3_value in state_valuation.items() if not (z3.is_int_value(z3_value) or z3.is_rational_value(z3_value))}, {input_variable.get_prism_variable() : z3_value.as_long() for input_variable, z3_value in state_valuation.items() if (z3.is_int_value(z3_value) or z3.is_rational_value(z3_value))}
Exemple #28
0
    def _back_single_term(self, expr, args, model=None):
        assert z3.is_expr(expr)

        if z3.is_quantifier(expr):
            raise NotImplementedError(
                "Quantified back conversion is currently not supported")

        assert not len(args) > 2 or \
            (z3.is_and(expr) or z3.is_or(expr) or
             z3.is_add(expr) or z3.is_mul(expr) or
             (len(args) == 3 and (z3.is_ite(expr) or z3.is_array_store(expr)))),\
            "Unexpected n-ary term: %s" % expr

        res = None
        try:
            decl = z3.Z3_get_app_decl(expr.ctx_ref(), expr.as_ast())
            kind = z3.Z3_get_decl_kind(expr.ctx.ref(), decl)
            # Try to get the back-conversion function for the given Kind
            fun = self._back_fun[kind]
            return fun(args, expr)
        except KeyError as ex:
            pass

        if z3.is_const(expr):
            # Const or Symbol
            if z3.is_rational_value(expr):
                n = expr.numerator_as_long()
                d = expr.denominator_as_long()
                f = Fraction(n, d)
                return self.mgr.Real(f)
            elif z3.is_int_value(expr):
                n = expr.as_long()
                return self.mgr.Int(n)
            elif z3.is_bv_value(expr):
                n = expr.as_long()
                w = expr.size()
                return self.mgr.BV(n, w)
            elif z3.is_as_array(expr):
                if model is None:
                    raise NotImplementedError("As-array expressions cannot be" \
                                              " handled as they are not " \
                                              "self-contained")
                else:
                    interp_decl = z3.get_as_array_func(expr)
                    interp = model[interp_decl]
                    default = self.back(interp.else_value(), model=model)
                    assign = {}
                    for i in xrange(interp.num_entries()):
                        e = interp.entry(i)
                        assert e.num_args() == 1
                        idx = self.back(e.arg_value(0), model=model)
                        val = self.back(e.value(), model=model)
                        assign[idx] = val
                    arr_type = self._z3_to_type(expr.sort())
                    return self.mgr.Array(arr_type.index_type, default, assign)
            elif z3.is_algebraic_value(expr):
                # Algebraic value
                return self.mgr._Algebraic(Numeral(expr))
            else:
                # it must be a symbol
                try:
                    return self.mgr.get_symbol(str(expr))
                except UndefinedSymbolError:
                    import warnings
                    symb_type = self._z3_to_type(expr.sort())
                    warnings.warn("Defining new symbol: %s" % str(expr))
                    return self.mgr.FreshSymbol(symb_type,
                                                template="__z3_%d")
        elif z3.is_function(expr):
            # This needs to be after we try to convert regular Symbols
            fsymbol = self.mgr.get_symbol(expr.decl().name())
            return self.mgr.Function(fsymbol, args)

        # If we reach this point, we did not manage to translate the expression
        raise ConvertExpressionError(message=("Unsupported expression: %s" %
                                              (str(expr))),
                                     expression=expr)
Exemple #29
0
 def expression_evaluable(self, name):
     expr = self.expression_get(name)
     return z3.is_int_value(expr) or z3.is_bv_value(expr)
Exemple #30
0
 def _isNum(self, elem):
     return z3.is_rational_value(elem) or z3.is_int_value(elem)
Exemple #31
0
def collect_numerals(z3term):
    if z3.is_int_value(z3term) or z3.is_bv_value(z3term):
        yield z3term
    elif z3.is_app_of(z3term, z3.Z3_OP_ITE):
        yield collect_numerals(z3term.arg(1))
        yield collect_numerals(z3term.arg(2))
Exemple #32
0
    def _back_single_term(self, expr, args, model=None):
        assert z3.is_expr(expr)

        if z3.is_quantifier(expr):
            raise NotImplementedError(
                "Quantified back conversion is currently not supported")

        res = None
        if z3.is_and(expr):
            res = self.mgr.And(args)
        elif z3.is_or(expr):
            res = self.mgr.Or(args)
        elif z3.is_add(expr):
            res = self.mgr.Plus(args)
        elif z3.is_div(expr):
            res = self.mgr.Div(args[0], args[1])
        elif z3.is_eq(expr):
            if self._get_type(args[0]).is_bool_type():
                res = self.mgr.Iff(args[0], args[1])
            else:
                res = self.mgr.Equals(args[0], args[1])
        elif z3.is_iff(expr):
            res = self.mgr.Iff(args[0], args[1])
        elif z3.is_xor(expr):
            res = self.mgr.Xor(args[0], args[1])
        elif z3.is_false(expr):
            res = self.mgr.FALSE()
        elif z3.is_true(expr):
            res = self.mgr.TRUE()
        elif z3.is_gt(expr):
            res = self.mgr.GT(args[0], args[1])
        elif z3.is_ge(expr):
            res = self.mgr.GE(args[0], args[1])
        elif z3.is_lt(expr):
            res = self.mgr.LT(args[0], args[1])
        elif z3.is_le(expr):
            res = self.mgr.LE(args[0], args[1])
        elif z3.is_mul(expr):
            res = self.mgr.Times(args[0], args[1])
        elif z3.is_uminus(expr):
            tp = self._get_type(args[0])
            if tp.is_real_type():
                minus_one = self.mgr.Real(-1)
            else:
                assert tp.is_int_type()
                minus_one = self.mgr.Int(-1)
            res = self.mgr.Times(args[0], minus_one)
        elif z3.is_sub(expr):
            res = self.mgr.Minus(args[0], args[1])
        elif z3.is_not(expr):
            res = self.mgr.Not(args[0])
        elif z3.is_implies(expr):
            res = self.mgr.Implies(args[0], args[1])
        elif z3.is_quantifier(expr):
            raise NotImplementedError
        elif z3.is_const(expr):
            if z3.is_rational_value(expr):
                n = expr.numerator_as_long()
                d = expr.denominator_as_long()
                f = Fraction(n, d)
                res = self.mgr.Real(f)
            elif z3.is_int_value(expr):
                n = expr.as_long()
                res = self.mgr.Int(n)
            elif z3.is_bv_value(expr):
                n = expr.as_long()
                w = expr.size()
                res = self.mgr.BV(n, w)
            elif z3.is_as_array(expr):
                if model is None:
                    raise NotImplementedError("As-array expressions cannot be" \
                                              " handled as they are not " \
                                              "self-contained")
                else:
                    interp_decl = z3.get_as_array_func(expr)
                    interp = model[interp_decl]
                    default = self.back(interp.else_value(), model=model)
                    assign = {}
                    for i in xrange(interp.num_entries()):
                        e = interp.entry(i)
                        assert e.num_args() == 1
                        idx = self.back(e.arg_value(0), model=model)
                        val = self.back(e.value(), model=model)
                        assign[idx] = val
                    arr_type = self._z3_to_type(expr.sort())
                    res = self.mgr.Array(arr_type.index_type, default, assign)
            elif z3.is_algebraic_value(expr):
                # Algebraic value
                return self.mgr._Algebraic(Numeral(expr))
            else:
                # it must be a symbol
                res = self.mgr.get_symbol(str(expr))
        elif z3.is_ite(expr):
            res = self.mgr.Ite(args[0], args[1], args[2])
        elif z3.is_function(expr):
            res = self.mgr.Function(self.mgr.get_symbol(expr.decl().name()), args)
        elif z3.is_to_real(expr):
            res = self.mgr.ToReal(args[0])
        elif z3.is_bv_and(expr):
            res = self.mgr.BVAnd(args[0], args[1])
        elif z3.is_bv_or(expr):
            res = self.mgr.BVOr(args[0], args[1])
        elif z3.is_bv_xor(expr):
            res = self.mgr.BVXor(args[0], args[1])
        elif z3.is_bv_not(expr):
            res = self.mgr.BVNot(args[0])
        elif z3.is_bv_neg(expr):
            res = self.mgr.BVNeg(args[0])
        elif z3.is_bv_concat(expr):
            res = self.mgr.BVConcat(args[0], args[1])
        elif z3.is_bv_ult(expr):
            res = self.mgr.BVULT(args[0], args[1])
        elif z3.is_bv_uleq(expr):
            res = self.mgr.BVULE(args[0], args[1])
        elif z3.is_bv_slt(expr):
            res = self.mgr.BVSLT(args[0], args[1])
        elif z3.is_bv_sleq(expr):
            res = self.mgr.BVSLE(args[0], args[1])
        elif z3.is_bv_ugt(expr):
            res = self.mgr.BVUGT(args[0], args[1])
        elif z3.is_bv_ugeq(expr):
            res = self.mgr.BVUGE(args[0], args[1])
        elif z3.is_bv_sgt(expr):
            res = self.mgr.BVSGT(args[0], args[1])
        elif z3.is_bv_sgeq(expr):
            res = self.mgr.BVSGE(args[0], args[1])
        elif z3.is_bv_extract(expr):
            end = z3.get_payload(expr, 0)
            start = z3.get_payload(expr, 1)
            res = self.mgr.BVExtract(args[0], start, end)
        elif z3.is_bv_add(expr):
            res = self.mgr.BVAdd(args[0], args[1])
        elif z3.is_bv_mul(expr):
            res = self.mgr.BVMul(args[0], args[1])
        elif z3.is_bv_udiv(expr):
            res = self.mgr.BVUDiv(args[0], args[1])
        elif z3.is_bv_sdiv(expr):
            res = self.mgr.BVSDiv(args[0], args[1])
        elif z3.is_bv_urem(expr):
            res = self.mgr.BVURem(args[0], args[1])
        elif z3.is_bv_srem(expr):
            res = self.mgr.BVSRem(args[0], args[1])
        elif z3.is_bv_lshl(expr):
            res = self.mgr.BVLShl(args[0], args[1])
        elif z3.is_bv_lshr(expr):
            res = self.mgr.BVLShr(args[0], args[1])
        elif z3.is_bv_ashr(expr):
            res = self.mgr.BVAShr(args[0], args[1])
        elif z3.is_bv_sub(expr):
            res = self.mgr.BVSub(args[0], args[1])
        elif z3.is_bv_rol(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVRol(args[0], amount)
        elif z3.is_bv_ror(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVRor(args[0], amount)
        elif z3.is_bv_ext_rol(expr):
            amount = args[1].bv_unsigned_value()
            res = self.mgr.BVRol(args[0], amount)
        elif z3.is_bv_ext_ror(expr):
            amount = args[1].bv_unsigned_value()
            res = self.mgr.BVRor(args[0], amount)
        elif z3.is_bv_sext(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVSExt(args[0], amount)
        elif z3.is_bv_zext(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVZExt(args[0], amount)
        elif z3.is_array_select(expr):
            res = self.mgr.Select(args[0], args[1])
        elif z3.is_array_store(expr):
            res = self.mgr.Store(args[0], args[1], args[2])
        elif z3.is_const_array(expr):
            arr_ty = self._z3_to_type(expr.sort())
            k = args[0]
            res = self.mgr.Array(arr_ty.index_type, k)
        elif z3.is_power(expr):
            res = self.mgr.Pow(args[0], args[1])
        if res is None:
            raise ConvertExpressionError(message=("Unsupported expression: %s" %
                                                   str(expr)),
                                         expression=expr)
        return res
Exemple #33
0
    def back(self, expr):
        assert z3.is_expr(expr)

        if askey(expr) in self.backconversion:
            return self.backconversion[askey(expr)]

        if z3.is_quantifier(expr):
            raise NotImplementedError(
                "Quantified back conversion is currently not supported")

        args = [self.back(x) for x in expr.children()]
        res = None
        if z3.is_and(expr):
            res = self.mgr.And(args)

        elif z3.is_or(expr):
            res = self.mgr.Or(args)

        elif z3.is_add(expr):
            res = self.mgr.Plus(args)

        elif z3.is_div(expr):
            res = self.mgr.Div(args[0], args[1])

        elif z3.is_eq(expr):
            if self._get_type(args[0]) == types.BOOL:
                res = self.mgr.Iff(args[0], args[1])
            else:
                res = self.mgr.Equals(args[0], args[1])

        elif z3.is_false(expr):
            res = self.mgr.FALSE()

        elif z3.is_true(expr):
            res = self.mgr.TRUE()

        elif z3.is_gt(expr):
            res = self.mgr.GT(args[0], args[1])

        elif z3.is_ge(expr):
            res = self.mgr.GE(args[0], args[1])

        elif z3.is_lt(expr):
            res = self.mgr.LT(args[0], args[1])

        elif z3.is_le(expr):
            res = self.mgr.LE(args[0], args[1])

        elif z3.is_mul(expr):
            res = self.mgr.Times(args[0], args[1])

        elif z3.is_sub(expr):
            res = self.mgr.Minus(args[0], args[1])

        elif z3.is_not(expr):
            res = self.mgr.Not(args[0])

        elif z3.is_quantifier(expr):
            if expr.is_forall():
                pass
            else:
                pass
            raise NotImplementedError

        elif z3.is_const(expr):
            if z3.is_rational_value(expr):
                n = expr.numerator_as_long()
                d = expr.denominator_as_long()
                f = Fraction(n, d)
                res = self.mgr.Real(f)
            elif z3.is_int_value(expr):
                n = expr.as_long()
                res = self.mgr.Int(n)
            else:
                # it must be a symbol
                res = self.mgr.get_symbol(str(expr))

        elif z3.is_ite(expr):
            res = self.mgr.Ite(args[0], args[1], args[2])

        else:
            raise TypeError("Unsupported expression:", expr)

        if res is None:
            raise TypeError("Unsupported expression:", expr)

        self.backconversion[askey(expr)] = res

        return res
Exemple #34
0
    def _back_single_term(self, expr, args):
        assert z3.is_expr(expr)

        if z3.is_quantifier(expr):
            raise NotImplementedError(
                "Quantified back conversion is currently not supported")

        res = None
        if z3.is_and(expr):
            res = self.mgr.And(args)
        elif z3.is_or(expr):
            res = self.mgr.Or(args)
        elif z3.is_add(expr):
            res = self.mgr.Plus(args)
        elif z3.is_div(expr):
            res = self.mgr.Div(args[0], args[1])
        elif z3.is_eq(expr):
            if self._get_type(args[0]).is_bool_type():
                res = self.mgr.Iff(args[0], args[1])
            else:
                res = self.mgr.Equals(args[0], args[1])
        elif z3.is_iff(expr):
            res = self.mgr.Iff(args[0], args[1])
        elif z3.is_xor(expr):
            res = self.mgr.Xor(args[0], args[1])
        elif z3.is_false(expr):
            res = self.mgr.FALSE()
        elif z3.is_true(expr):
            res = self.mgr.TRUE()
        elif z3.is_gt(expr):
            res = self.mgr.GT(args[0], args[1])
        elif z3.is_ge(expr):
            res = self.mgr.GE(args[0], args[1])
        elif z3.is_lt(expr):
            res = self.mgr.LT(args[0], args[1])
        elif z3.is_le(expr):
            res = self.mgr.LE(args[0], args[1])
        elif z3.is_mul(expr):
            res = self.mgr.Times(args[0], args[1])
        elif z3.is_uminus(expr):
            tp = self._get_type(args[0])
            if tp.is_real_type():
                minus_one = self.mgr.Real(-1)
            else:
                assert tp.is_int_type()
                minus_one = self.mgr.Int(-1)
            res = self.mgr.Times(args[0], minus_one)
        elif z3.is_sub(expr):
            res = self.mgr.Minus(args[0], args[1])
        elif z3.is_not(expr):
            res = self.mgr.Not(args[0])
        elif z3.is_implies(expr):
            res = self.mgr.Implies(args[0], args[1])
        elif z3.is_quantifier(expr):
            raise NotImplementedError
        elif z3.is_const(expr):
            if z3.is_rational_value(expr):
                n = expr.numerator_as_long()
                d = expr.denominator_as_long()
                f = Fraction(n, d)
                res = self.mgr.Real(f)
            elif z3.is_int_value(expr):
                n = expr.as_long()
                res = self.mgr.Int(n)
            elif z3.is_bv_value(expr):
                n = expr.as_long()
                w = expr.size()
                res = self.mgr.BV(n, w)
            else:
                # it must be a symbol
                res = self.mgr.get_symbol(str(expr))
        elif z3.is_ite(expr):
            res = self.mgr.Ite(args[0], args[1], args[2])
        elif z3.is_function(expr):
            res = self.mgr.Function(self.mgr.get_symbol(expr.decl().name()), args)
        elif z3.is_to_real(expr):
            res = self.mgr.ToReal(args[0])
        elif z3.is_bv_and(expr):
            res = self.mgr.BVAnd(args[0], args[1])
        elif z3.is_bv_or(expr):
            res = self.mgr.BVOr(args[0], args[1])
        elif z3.is_bv_xor(expr):
            res = self.mgr.BVXor(args[0], args[1])
        elif z3.is_bv_not(expr):
            res = self.mgr.BVNot(args[0])
        elif z3.is_bv_neg(expr):
            res = self.mgr.BVNeg(args[0])
        elif z3.is_bv_concat(expr):
            res = self.mgr.BVConcat(args[0], args[1])
        elif z3.is_bv_ult(expr):
            res = self.mgr.BVULT(args[0], args[1])
        elif z3.is_bv_uleq(expr):
            res = self.mgr.BVULE(args[0], args[1])
        elif z3.is_bv_slt(expr):
            res = self.mgr.BVSLT(args[0], args[1])
        elif z3.is_bv_sleq(expr):
            res = self.mgr.BVSLE(args[0], args[1])
        elif z3.is_bv_ugt(expr):
            res = self.mgr.BVUGT(args[0], args[1])
        elif z3.is_bv_ugeq(expr):
            res = self.mgr.BVUGE(args[0], args[1])
        elif z3.is_bv_sgt(expr):
            res = self.mgr.BVSGT(args[0], args[1])
        elif z3.is_bv_sgeq(expr):
            res = self.mgr.BVSGE(args[0], args[1])
        elif z3.is_bv_extract(expr):
            end = z3.get_payload(expr, 0)
            start = z3.get_payload(expr, 1)
            res = self.mgr.BVExtract(args[0], start, end)
        elif z3.is_bv_add(expr):
            res = self.mgr.BVAdd(args[0], args[1])
        elif z3.is_bv_mul(expr):
            res = self.mgr.BVMul(args[0], args[1])
        elif z3.is_bv_udiv(expr):
            res = self.mgr.BVUDiv(args[0], args[1])
        elif z3.is_bv_sdiv(expr):
            res = self.mgr.BVSDiv(args[0], args[1])
        elif z3.is_bv_urem(expr):
            res = self.mgr.BVURem(args[0], args[1])
        elif z3.is_bv_srem(expr):
            res = self.mgr.BVSRem(args[0], args[1])
        elif z3.is_bv_lshl(expr):
            res = self.mgr.BVLShl(args[0], args[1])
        elif z3.is_bv_lshr(expr):
            res = self.mgr.BVLShr(args[0], args[1])
        elif z3.is_bv_ashr(expr):
            res = self.mgr.BVAShr(args[0], args[1])
        elif z3.is_bv_sub(expr):
            res = self.mgr.BVSub(args[0], args[1])
        elif z3.is_bv_rol(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVRol(args[0], amount)
        elif z3.is_bv_ror(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVRor(args[0], amount)
        elif z3.is_bv_ext_rol(expr):
            amount = args[1].bv_unsigned_value()
            res = self.mgr.BVRol(args[0], amount)
        elif z3.is_bv_ext_ror(expr):
            amount = args[1].bv_unsigned_value()
            res = self.mgr.BVRor(args[0], amount)
        elif z3.is_bv_sext(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVSExt(args[0], amount)
        elif z3.is_bv_zext(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVZExt(args[0], amount)

        if res is None:
            raise ConvertExpressionError(message=("Unsupported expression: %s" %
                                                   str(expr)),
                                         expression=expr)
        return res
Exemple #35
0
 def _eval_int(expr: z3.ExprRef) -> str:  # TODO: this should return int
     assert z3.is_int(expr), expr
     ans = z3model.eval(expr, model_completion=True)
     assert z3.is_int_value(ans), (expr, ans)
     return str(ans.as_long())
Exemple #36
0
    def _back_single_term(self, expr, args, model=None):
        assert z3.is_expr(expr)

        if z3.is_quantifier(expr):
            raise NotImplementedError(
                "Quantified back conversion is currently not supported")

        assert not len(args) > 2 or \
            (z3.is_and(expr) or z3.is_or(expr) or
             z3.is_add(expr) or z3.is_mul(expr) or
             (len(args) == 3 and (z3.is_ite(expr) or z3.is_array_store(expr)))),\
            "Unexpected n-ary term: %s" % expr

        res = None
        try:
            decl = z3.Z3_get_app_decl(expr.ctx_ref(), expr.as_ast())
            kind = z3.Z3_get_decl_kind(expr.ctx.ref(), decl)
            # Try to get the back-conversion function for the given Kind
            fun = self._back_fun[kind]
            return fun(args, expr)
        except KeyError as ex:
            pass

        if z3.is_const(expr):
            # Const or Symbol
            if z3.is_rational_value(expr):
                n = expr.numerator_as_long()
                d = expr.denominator_as_long()
                f = Fraction(n, d)
                return self.mgr.Real(f)
            elif z3.is_int_value(expr):
                n = expr.as_long()
                return self.mgr.Int(n)
            elif z3.is_bv_value(expr):
                n = expr.as_long()
                w = expr.size()
                return self.mgr.BV(n, w)
            elif z3.is_as_array(expr):
                if model is None:
                    raise NotImplementedError("As-array expressions cannot be" \
                                              " handled as they are not " \
                                              "self-contained")
                else:
                    interp_decl = z3.get_as_array_func(expr)
                    interp = model[interp_decl]
                    default = self.back(interp.else_value(), model=model)
                    assign = {}
                    for i in xrange(interp.num_entries()):
                        e = interp.entry(i)
                        assert e.num_args() == 1
                        idx = self.back(e.arg_value(0), model=model)
                        val = self.back(e.value(), model=model)
                        assign[idx] = val
                    arr_type = self._z3_to_type(expr.sort())
                    return self.mgr.Array(arr_type.index_type, default, assign)
            elif z3.is_algebraic_value(expr):
                # Algebraic value
                return self.mgr._Algebraic(Numeral(expr))
            else:
                # it must be a symbol
                try:
                    return self.mgr.get_symbol(str(expr))
                except UndefinedSymbolError:
                    import warnings
                    symb_type = self._z3_to_type(expr.sort())
                    warnings.warn("Defining new symbol: %s" % str(expr))
                    return self.mgr.FreshSymbol(symb_type, template="__z3_%d")
        elif z3.is_function(expr):
            # This needs to be after we try to convert regular Symbols
            fsymbol = self.mgr.get_symbol(expr.decl().name())
            return self.mgr.Function(fsymbol, args)

        # If we reach this point, we did not manage to translate the expression
        raise ConvertExpressionError(message=("Unsupported expression: %s" %
                                              (str(expr))),
                                     expression=expr)
Exemple #37
0
    def _old_model_to_trace(z3model: z3.ModelRef,
                            num_states: int,
                            allow_undefined: bool = False) -> Trace:
        '''
        Convert z3 model to Trace with given number of states.

        If allow_undefined is True, the resulting trace may leave some symbols undefined.
        '''
        trace = Trace(num_states)
        keys = Z3Translator._get_keys(num_states)

        def rename(s: str) -> str:
            return s.replace('!val!', '').replace('@uc_', '')

        def _eval(expr: z3.ExprRef) -> z3.ExprRef:
            ans = z3model.eval(expr, model_completion=True)
            assert bool(ans) is True or bool(ans) is False, (expr, ans)
            return ans

        prog = syntax.the_program

        for z3sort in sorted(z3model.sorts(), key=str):
            sort = prog.scope.get_sort(str(z3sort))
            assert sort is not None
            univ = z3model.get_universe(z3sort)
            trace.univs[sort] = tuple(sorted(rename(str(x)) for x in univ))

        model_decls = z3model.decls()
        all_decls = model_decls
        for z3decl in sorted(all_decls, key=str):
            z3name = str(z3decl)
            for i, k in enumerate(keys):
                if z3name.startswith(k):
                    name = z3name[len(k + '_'):]
                    R = trace.rel_interps[i]
                    C = trace.const_interps[i]
                    F = trace.func_interps[i]
                    break
            else:
                name = z3name
                R = trace.immut_rel_interps
                C = trace.immut_const_interps
                F = trace.immut_func_interps

            decl = prog.scope.get(name)
            assert not isinstance(decl, syntax.Sort) and \
                not isinstance(decl, syntax.SortInferencePlaceholder)
            if decl is not None:
                if isinstance(decl, RelationDecl):
                    if decl.arity:
                        rl: RelationInterp = {}
                        domains = [
                            z3model.get_universe(z3decl.domain(i))
                            for i in range(z3decl.arity())
                        ]
                        if not any(x is None for x in domains):
                            # Note: if any domain is None, we silently drop this symbol.
                            # It's not entirely clear that this is an ok thing to do.
                            g = product(*domains)
                            for row in g:
                                relation_expr = z3decl(*row)
                                ans = _eval(relation_expr)
                                rl[tuple(rename(str(col))
                                         for col in row)] = bool(ans)
                            assert decl not in R
                            R[decl] = rl
                    else:
                        ans = z3model.eval(z3decl())
                        assert decl not in R
                        R[decl] = {(): bool(ans)}
                elif isinstance(decl, FunctionDecl):
                    fl: FunctionInterp = {}
                    domains = [
                        z3model.get_universe(z3decl.domain(i))
                        for i in range(z3decl.arity())
                    ]
                    if not any(x is None for x in domains):
                        # Note: if any domain is None, we silently drop this symbol.
                        # It's not entirely clear that this is an ok thing to do.
                        g = product(*domains)
                        for row in g:
                            ans = z3model.eval(z3decl(*row))
                            if z3.is_int_value(ans):
                                ans_str = str(ans.as_long())
                            else:
                                ans_str = rename(ans.decl().name())

                            fl[tuple(rename(str(col))
                                     for col in row)] = ans_str
                        assert decl not in F
                        F[decl] = fl
                else:
                    assert isinstance(decl, ConstantDecl)
                    v = z3model.eval(z3decl())
                    if z3.is_int_value(v) or isinstance(v, CVC4Int):
                        v_str = str(v.as_long())
                    else:
                        v_str = rename(v.decl().name())

                    assert decl not in C
                    C[decl] = v_str
            else:
                if name.startswith(TRANSITION_INDICATOR +
                                   '_') and z3model.eval(z3decl()):
                    name = name[len(TRANSITION_INDICATOR + '_'):]
                    istr, name = name.split('_', maxsplit=1)
                    i = int(istr)
                    if i < len(trace.transitions):
                        trace.transitions[i] = name
                    else:
                        # TODO: not sure what's going on here with check_bmc and pd.check_k_state_implication
                        # assert False
                        pass

        if allow_undefined:
            return trace

        def get_univ(d: SortDecl) -> Tuple[Element, ...]:
            if d not in trace.univs:
                trace.univs[d] = (d.name + '0', )
            return trace.univs[d]

        def arbitrary_interp_r(r: RelationDecl) -> RelationInterp:
            doms = [get_univ(syntax.get_decl_from_sort(s)) for s in r.arity]
            return dict.fromkeys(product(*doms), False)

        def ensure_defined_r(r: RelationDecl) -> None:
            arb_interp: Optional[RelationInterp] = None
            for m in (trace.rel_interps
                      if r.mutable else [trace.immut_rel_interps]):
                if r not in m:
                    if arb_interp is None:
                        arb_interp = arbitrary_interp_r(r)
                    m[r] = arb_interp

        def arbitrary_interp_c(c: ConstantDecl) -> Element:
            if isinstance(c.sort, syntax._BoolSort):
                return 'false'
            elif isinstance(c.sort, syntax._IntSort):
                return '0'
            assert isinstance(c.sort, syntax.UninterpretedSort)
            sort = c.sort
            return get_univ(syntax.get_decl_from_sort(sort))[0]

        def ensure_defined_c(c: ConstantDecl) -> None:
            arb_interp = arbitrary_interp_c(c)
            for m in (trace.const_interps
                      if c.mutable else [trace.immut_const_interps]):
                if c not in m:
                    m[c] = arb_interp

        def arbitrary_interp_f(f: FunctionDecl) -> FunctionInterp:
            doms = [get_univ(syntax.get_decl_from_sort(s)) for s in f.arity]
            image = get_univ(syntax.get_decl_from_sort(f.sort))[0]
            return dict.fromkeys(product(*doms), image)

        def ensure_defined_f(f: FunctionDecl) -> None:
            arb_interp: Optional[FunctionInterp] = None
            for m in (trace.func_interps
                      if f.mutable else [trace.immut_func_interps]):
                if f not in m:
                    if arb_interp is None:
                        arb_interp = arbitrary_interp_f(f)
                    m[f] = arb_interp

        for decl in prog.relations_constants_and_functions():
            if isinstance(decl, RelationDecl):
                ensure_defined_r(decl)
            elif isinstance(decl, ConstantDecl):
                ensure_defined_c(decl)
            elif isinstance(decl, FunctionDecl):
                ensure_defined_f(decl)
            else:
                assert False, decl

        return trace
Exemple #38
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.")