示例#1
0
    def back(self, expr):
        res = None
        if expr.isConst():
            if expr.getType().isBoolean():
                v = expr.getConstBoolean()
                res = self.mgr.Bool(v)
            elif expr.getType().isInteger():
                v = expr.getConstRational().toString()
                res = self.mgr.Int(int(v))
            elif expr.getType().isReal():
                v = expr.getConstRational().toString()
                res = self.mgr.Real(Fraction(v))
            elif expr.getType().isBitVector():
                bv = expr.getConstBitVector()
                v = bv.getValue().toString()
                width = bv.getSize()
                res = self.mgr.BV(int(v), width)
            elif expr.getType().isString():
                v = expr.getConstString()
                res = self.mgr.String(v.toString())
            elif expr.getType().isArray():
                const_ = expr.getConstArrayStoreAll()
                array_type = self._cvc4_type_to_type(const_.getType())
                base_value = self.back(const_.getExpr())
                res = self.mgr.Array(array_type.index_type, base_value)
            else:
                raise PyomtTypeError("Unsupported constant type:",
                                     expr.getType().toString())
        else:
            raise PyomtTypeError("Unsupported expression:", expr.toString())

        return res
示例#2
0
    def Real(self, value):
        """ Returns a Real-type constant of the given value.

        value can be:
          - A Fraction(n,d)
          - A tuple (n,d)
          - A long or int n
          - A float
          - (Optionally) a mpq or mpz object
        """
        if value in self.real_constants:
            return self.real_constants[value]

        if is_pyomt_fraction(value):
            val = value
        elif type(value) == tuple:
            val = Fraction(value[0], value[1])
        elif is_python_rational(value):
            val = pyomt_fraction_from_rational(value)
        else:
            raise PyomtTypeError("Invalid type in constant. The type was:" + \
                                 str(type(value)))

        n = self.create_node(node_type=op.REAL_CONSTANT,
                             args=tuple(),
                             payload=val)
        self.real_constants[value] = n
        return n
示例#3
0
 def get_value(self, item):
     self._assert_no_function_type(item)
     term = self.converter.convert(item)
     cvc4_res = self.cvc4.getValue(term)
     res = self.converter.back(cvc4_res)
     if self.environment.stc.get_type(item).is_real_type() and \
        self.environment.stc.get_type(res).is_int_type():
         res = self.environment.formula_manager.Real(
             Fraction(res.constant_value(), 1))
     return res
示例#4
0
 def algebraic_approx_value(self, precision=10):
     value = self.constant_value()
     approx = value.approx(precision)
     # MG: This is a workaround python 3 since Z3 mixes int and long.
     #     The bug was fixed in master of Z3, but no official relase
     #     has been done containing it.
     # In the most recent version of z3, this can be done with:
     #   return approx.as_fraction()
     n = int(str(approx.numerator()))
     d = int(str(approx.denominator()))
     return Fraction(n, d)
示例#5
0
    def Div(self, left, right):
        """ Creates an expression of the form: left / right """
        if right.is_constant(types.REAL):
            # If right is a constant we rewrite as left * 1/right
            inverse = Fraction(1) / right.constant_value()
            return self.Times(left, self.Real(inverse))
        elif right.is_constant(types.INT):
            raise NotImplementedError

        # This is a non-linear expression
        return self.create_node(node_type=op.DIV, args=(left, right))
示例#6
0
    def get_value(self, item):
        self._assert_no_function_type(item)

        titem = self.converter.convert(item)
        ty = self.environment.stc.get_type(item)
        if ty.is_bool_type():
            status, res = yicespy.yices_get_bool_value(self.model, titem)
            self._check_error(status)
            return self.mgr.Bool(bool(res))
        elif ty.is_int_type():
            res = yicespy.yices_get_integer_value(self.model, titem)
            return self.mgr.Int(res)
        elif ty.is_real_type():
            status, val = yicespy.yices_get_rational_value(self.model, titem)
            self._check_error(status)
            return self.mgr.Real(Fraction(val))
        elif ty.is_bv_type():
            status, res = yicespy.yices_get_bv_value(self.model, titem,
                                                     ty.width)
            self._check_error(status)
            str_val = "".join(str(x) for x in reversed(res))
            return self.mgr.BV("#b" + str_val)
        else:
            raise NotImplementedError()
示例#7
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)
示例#8
0
 def real_constant(self, read):
     return Constant(self.mgr.Real(Fraction(read)))