Beispiel #1
0
        def f(_cache, e, seen):
            def f_cache(e):
                return _cache(f, e, seen)

            if z3.is_app_of(e, z3.Z3_OP_UMINUS):
                return f_cache((-1) * (e.arg(0)))
            elif z3.is_sub(e):
                return f_cache(e.arg(0) + (-1) * e.arg(1))
            elif z3.is_app(e) and e.num_args() == 2:
                c1 = f_cache(e.arg(0))
                c2 = f_cache(e.arg(1))
                if z3.is_add(e):
                    return c1 + c2
                elif z3.is_mul(e):
                    if z3.is_add(c1):
                        c11 = c1.arg(0)
                        c12 = c1.arg(1)
                        return f_cache(c11 * c2 + c12 * c2)
                    elif z3.is_add(c2):
                        c21 = c2.arg(0)
                        c22 = c2.arg(1)
                        return f_cache(c1 * c21 + c1 * c22)
                    else:
                        return c1 * c2
                else:
                    return e
            else:
                return e
Beispiel #2
0
 def mk_app(self, f, args):
     if z3.is_eq(f):
         return args[0] == args[1]
     elif z3.is_and(f):
         return And(*args)
     elif z3.is_or(f):
         return Or(*args)
     elif z3.is_not(f):
         return Not(*args)
     elif z3.is_add(f):
         return reduce(operator.add, args[1:], args[0])
     elif z3.is_mul(f):
         return reduce(operator.mul, args[1:], args[0])
     elif z3.is_sub(f):
         return args[0] - args[1]
     elif z3.is_div(f):
         return args[0] / args[1]
     elif z3.is_lt(f):
         return args[0] < args[1]
     elif z3.is_le(f):
         return args[0] <= args[1]
     elif z3.is_gt(f):
         return args[0] > args[1]
     elif z3.is_ge(f):
         return args[0] >= args[1]
     elif z3.is_to_real(f):    # TODO: ignore coercions?
         return args[0]
     elif z3.is_to_int(f):
         return args[0]
     elif f.name() == '=>':
         return implies(args[0], args[1])
     else:
         dom_types = [self.mk_sort(f.domain(i))\
                      for i in range(0, f.arity())]
         cod_type = self.mk_sort(f.range())
         dom_types.reverse()
         fun_type = reduce((lambda X, Y: type_arrow(Y, X)), \
                           dom_types, cod_type)
         func = self.mk_fun(f)
         return func(*args)
Beispiel #3
0
 def mk_app(self, f, args):
     if z3.is_eq(f):
         return args[0] == args[1]
     elif z3.is_and(f):
         return And(*args)
     elif z3.is_or(f):
         return Or(*args)
     elif z3.is_not(f):
         return Not(*args)
     elif z3.is_add(f):
         return reduce(operator.add, args[1:], args[0])
     elif z3.is_mul(f):
         return reduce(operator.mul, args[1:], args[0])
     elif z3.is_sub(f):
         return args[0] - args[1]
     elif z3.is_div(f):
         return args[0] / args[1]
     elif z3.is_lt(f):
         return args[0] < args[1]
     elif z3.is_le(f):
         return args[0] <= args[1]
     elif z3.is_gt(f):
         return args[0] > args[1]
     elif z3.is_ge(f):
         return args[0] >= args[1]
     elif z3.is_to_real(f):    # TODO: ignore coercions?
         return args[0]
     elif z3.is_to_int(f):
         return args[0]
     elif f.name() == '=>':
         return implies(args[0], args[1])
     else:
         dom_types = [self.mk_sort(f.domain(i))\
                      for i in range(0, f.arity())]
         cod_type = self.mk_sort(f.range())
         dom_types.reverse()
         fun_type = reduce((lambda X, Y: type_arrow(Y, X)), \
                           dom_types, cod_type)
         func = self.mk_fun(f)
         return func(*args)
Beispiel #4
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)
Beispiel #5
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)
Beispiel #6
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
Beispiel #7
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
Beispiel #8
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