Ejemplo n.º 1
0
    def _back_single_term(self, term, mgr, args):
        """Builds the pysmt formula given a term and the list of formulae
        obtained by converting the term children.

        :param term: The MathSAT term to be transformed in pysmt formulae
        :type term: MathSAT term

        :param mgr: The formula manager to be sued to build the
        formulae, it should allow for type unsafety.
        :type mgr: Formula manager

        :param args: List of the pysmt formulae obtained by converting
        all the args (obtained by mathsat.msat_term_get_arg()) to
        pysmt formulae
        :type args: List of pysmt formulae

        :returns The pysmt formula representing the given term
        :rtype Pysmt formula
        """
        res = None
        arity = len(args)

        if mathsat.msat_term_is_true(self.msat_env(), term):
            res = mgr.TRUE()

        elif mathsat.msat_term_is_false(self.msat_env(), term):
            res = mgr.FALSE()

        elif mathsat.msat_term_is_number(self.msat_env(), term):
            ty = mathsat.msat_term_get_type(term)
            if mathsat.msat_is_integer_type(self.msat_env(), ty):
                res = mgr.Int(int(mathsat.msat_term_repr(term)))
            elif mathsat.msat_is_rational_type(self.msat_env(), ty):
                res = mgr.Real(Fraction(mathsat.msat_term_repr(term)))
            else:
                assert "_" in str(term), "Unsupported type for '%s'" % str(term)
                val, width = str(term).split("_")
                val = int(val)
                width = int(width)
                res = mgr.BV(val, width)

        elif mathsat.msat_term_is_and(self.msat_env(), term):
            res = mgr.And(args)

        elif mathsat.msat_term_is_or(self.msat_env(), term):
            res = mgr.Or(args)

        elif mathsat.msat_term_is_not(self.msat_env(), term):
            assert arity == 1
            res = mgr.Not(args[0])

        elif mathsat.msat_term_is_iff(self.msat_env(), term):
            assert arity == 2
            res = mgr.Iff(args[0], args[1])

        elif mathsat.msat_term_is_term_ite(self.msat_env(), term):
            assert arity == 3
            res = mgr.Ite(args[0], args[1], args[2])

        elif mathsat.msat_term_is_equal(self.msat_env(), term):
            assert arity == 2
            res = mgr.Equals(args[0], args[1])

        elif mathsat.msat_term_is_leq(self.msat_env(), term):
            assert arity == 2
            res = mgr.LE(args[0], args[1])

        elif mathsat.msat_term_is_plus(self.msat_env(), term):
            res = mgr.Plus(args)

        elif mathsat.msat_term_is_times(self.msat_env(), term):
            assert arity == 2
            res = mgr.Times(args[0], args[1])

        elif mathsat.msat_term_is_boolean_constant(self.msat_env(), term):
            rep = mathsat.msat_term_repr(term)
            res = mgr.Symbol(rep, types.BOOL)

        elif mathsat.msat_term_is_constant(self.msat_env(), term):
            rep = mathsat.msat_term_repr(term)

            ty = mathsat.msat_term_get_type(term)
            if mathsat.msat_is_rational_type(self.msat_env(), ty):
                res = mgr.Symbol(rep, types.REAL)
            elif mathsat.msat_is_integer_type(self.msat_env(), ty):
                res = mgr.Symbol(rep, types.INT)
            else:
                _, width = mathsat.msat_is_bv_type(self.msat_env(), ty)
                assert width is not None, "Unsupported variable type for '%s'"%str(term)
                res = mgr.Symbol(rep, types.BVType(width))

        elif mathsat.msat_term_is_uf(self.msat_env(), term):
            d = mathsat.msat_term_get_decl(term)
            fun = self.get_symbol_from_declaration(d)
            res = mgr.Function(fun, args)

        elif mathsat.msat_term_is_bv_times(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVMul(args[0], args[1])

        elif mathsat.msat_term_is_bv_plus(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVAdd(args[0], args[1])

        elif mathsat.msat_term_is_bv_udiv(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVUDiv(args[0], args[1])

        elif mathsat.msat_term_is_bv_urem(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVURem(args[0], args[1])

        elif mathsat.msat_term_is_bv_extract(self.msat_env(), term)[0]:
            assert arity == 1
            res, msb, lsb = mathsat.msat_term_is_bv_extract(self.msat_env(), term)
            assert res
            res = mgr.BVExtract(args[0], lsb, msb)

        elif mathsat.msat_term_is_bv_concat(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVConcat(args[0], args[1])

        elif mathsat.msat_term_is_bv_or(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVOr(args[0], args[1])

        elif mathsat.msat_term_is_bv_xor(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVXor(args[0], args[1])

        elif mathsat.msat_term_is_bv_and(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVAnd(args[0], args[1])

        elif mathsat.msat_term_is_bv_not(self.msat_env(), term):
            assert arity == 1
            res = mgr.BVNot(args[0])

        elif mathsat.msat_term_is_bv_minus(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVSub(args[0], args[1])

        elif mathsat.msat_term_is_bv_neg(self.msat_env(), term):
            assert arity == 1
            res = mgr.BVSub(args[0])

        elif mathsat.msat_term_is_bv_srem(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVSRem(args[0], args[1])

        elif mathsat.msat_term_is_bv_sdiv(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVSDiv(args[0], args[1])

        elif mathsat.msat_term_is_bv_ult(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVULT(args[0], args[1])

        elif mathsat.msat_term_is_bv_slt(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVSLT(args[0], args[1])

        elif mathsat.msat_term_is_bv_uleq(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVULE(args[0], args[1])

        elif mathsat.msat_term_is_bv_sleq(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVSLE(args[0], args[1])

        elif mathsat.msat_term_is_bv_lshl(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVLShl(args[0], args[1])

        elif mathsat.msat_term_is_bv_lshr(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVLShr(args[0], args[1])

        elif mathsat.msat_term_is_bv_ashr(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVAShr(args[0], args[1])

        elif mathsat.msat_term_is_bv_comp(self.msat_env(), term):
            assert arity == 2
            res = mgr.BVComp(args[0], args[1])

        elif mathsat.msat_term_is_bv_zext(self.msat_env(), term)[0]:
            assert arity == 2
            res, amount = mathsat.msat_term_is_bv_zext(self.msat_env(), term)
            assert res
            res = mgr.BVZExt(args[0], amount)

        elif mathsat.msat_term_is_bv_sext(self.msat_env(), term)[0]:
            assert arity == 2
            res, amount = mathsat.msat_term_is_bv_sext(self.msat_env(), term)
            assert res
            res = mgr.BVSExt(args[0], amount)

        elif mathsat.msat_term_is_bv_rol(self.msat_env(), term)[0]:
            assert arity == 2
            res, amount = mathsat.msat_term_is_bv_ror(self.msat_env(), term)
            assert res
            res = mgr.BVRol(args[0], amount)

        elif mathsat.msat_term_is_bv_ror(self.msat_env(), term)[0]:
            assert arity == 2
            res, amount = mathsat.msat_term_is_bv_ror(self.msat_env(), term)
            assert res
            res = mgr.BVRor(args[0], amount)

        else:
            raise TypeError("Unsupported expression:",
                            mathsat.msat_term_repr(term))
        return res
Ejemplo n.º 2
0
Archivo: msat.py Proyecto: idkwim/pysmt
    def _back_single_term(self, term, mgr, args):
        """Builds the pysmt formula given a term and the list of formulae
        obtained by converting the term children.

        :param term: The MathSAT term to be transformed in pysmt formulae
        :type term: MathSAT term

        :param mgr: The formula manager to be sued to build the
        formulae, it should allow for type unsafety.
        :type mgr: Formula manager

        :param args: List of the pysmt formulae obtained by converting
        all the args (obtained by mathsat.msat_term_get_arg()) to
        pysmt formulae
        :type args: List of pysmt formulae

        :returns The pysmt formula representing the given term
        :rtype Pysmt formula
        """
        res = None
        arity = len(args)

        if mathsat.msat_term_is_true(self.msat_env, term):
            res = mgr.TRUE()

        elif mathsat.msat_term_is_false(self.msat_env, term):
            res = mgr.FALSE()

        elif mathsat.msat_term_is_number(self.msat_env, term):
            ty = mathsat.msat_term_get_type(term)
            if mathsat.msat_is_integer_type(self.msat_env, ty):
                res = mgr.Int(int(mathsat.msat_term_repr(term)))
            elif mathsat.msat_is_rational_type(self.msat_env, ty):
                res = mgr.Real(Fraction(mathsat.msat_term_repr(term)))
            else:
                assert "_" in str(
                    term), "Unsupported type for '%s'" % str(term)
                val, width = str(term).split("_")
                val = int(val)
                width = int(width)
                res = mgr.BV(val, width)

        elif mathsat.msat_term_is_and(self.msat_env, term):
            res = mgr.And(args)

        elif mathsat.msat_term_is_or(self.msat_env, term):
            res = mgr.Or(args)

        elif mathsat.msat_term_is_not(self.msat_env, term):
            assert arity == 1
            res = mgr.Not(args[0])

        elif mathsat.msat_term_is_iff(self.msat_env, term):
            assert arity == 2
            res = mgr.Iff(args[0], args[1])

        elif mathsat.msat_term_is_term_ite(self.msat_env, term):
            assert arity == 3
            res = mgr.Ite(args[0], args[1], args[2])

        elif mathsat.msat_term_is_equal(self.msat_env, term):
            assert arity == 2
            res = mgr.Equals(args[0], args[1])

        elif mathsat.msat_term_is_leq(self.msat_env, term):
            assert arity == 2
            res = mgr.LE(args[0], args[1])

        elif mathsat.msat_term_is_plus(self.msat_env, term):
            res = mgr.Plus(args)

        elif mathsat.msat_term_is_times(self.msat_env, term):
            assert arity == 2
            res = mgr.Times(args[0], args[1])

        elif mathsat.msat_term_is_boolean_constant(self.msat_env, term):
            rep = mathsat.msat_term_repr(term)
            res = mgr.Symbol(rep, types.BOOL)

        elif mathsat.msat_term_is_constant(self.msat_env, term):
            rep = mathsat.msat_term_repr(term)

            ty = mathsat.msat_term_get_type(term)
            if mathsat.msat_is_rational_type(self.msat_env, ty):
                res = mgr.Symbol(rep, types.REAL)
            elif mathsat.msat_is_integer_type(self.msat_env, ty):
                res = mgr.Symbol(rep, types.INT)
            else:
                _, width = mathsat.msat_is_bv_type(self.msat_env, ty)
                assert width is not None, "Unsupported variable type for '%s'" % str(
                    term)
                res = mgr.Symbol(rep, types.BVType(width))

        elif mathsat.msat_term_is_uf(self.msat_env, term):
            d = mathsat.msat_term_get_decl(term)
            fun = self.get_symbol_from_declaration(d)
            res = mgr.Function(fun, args)

        elif mathsat.msat_term_is_bv_times(self.msat_env, term):
            assert arity == 2
            res = mgr.BVMul(args[0], args[1])

        elif mathsat.msat_term_is_bv_plus(self.msat_env, term):
            assert arity == 2
            res = mgr.BVAdd(args[0], args[1])

        elif mathsat.msat_term_is_bv_udiv(self.msat_env, term):
            assert arity == 2
            res = mgr.BVUDiv(args[0], args[1])

        elif mathsat.msat_term_is_bv_urem(self.msat_env, term):
            assert arity == 2
            res = mgr.BVURem(args[0], args[1])

        elif mathsat.msat_term_is_bv_extract(self.msat_env, term)[0]:
            assert arity == 1
            res, msb, lsb = mathsat.msat_term_is_bv_extract(
                self.msat_env, term)
            assert res
            res = mgr.BVExtract(args[0], lsb, msb)

        elif mathsat.msat_term_is_bv_concat(self.msat_env, term):
            assert arity == 2
            res = mgr.BVConcat(args[0], args[1])

        elif mathsat.msat_term_is_bv_or(self.msat_env, term):
            assert arity == 2
            res = mgr.BVOr(args[0], args[1])

        elif mathsat.msat_term_is_bv_xor(self.msat_env, term):
            assert arity == 2
            res = mgr.BVXor(args[0], args[1])

        elif mathsat.msat_term_is_bv_and(self.msat_env, term):
            assert arity == 2
            res = mgr.BVAnd(args[0], args[1])

        elif mathsat.msat_term_is_bv_not(self.msat_env, term):
            assert arity == 1
            res = mgr.BVNot(args[0])

        elif mathsat.msat_term_is_bv_minus(self.msat_env, term):
            assert arity == 2
            res = mgr.BVSub(args[0], args[1])

        elif mathsat.msat_term_is_bv_neg(self.msat_env, term):
            assert arity == 1
            res = mgr.BVSub(args[0])

        elif mathsat.msat_term_is_bv_srem(self.msat_env, term):
            assert arity == 2
            res = mgr.BVSRem(args[0], args[1])

        elif mathsat.msat_term_is_bv_sdiv(self.msat_env, term):
            assert arity == 2
            res = mgr.BVSDiv(args[0], args[1])

        elif mathsat.msat_term_is_bv_ult(self.msat_env, term):
            assert arity == 2
            res = mgr.BVULT(args[0], args[1])

        elif mathsat.msat_term_is_bv_slt(self.msat_env, term):
            assert arity == 2
            res = mgr.BVSLT(args[0], args[1])

        elif mathsat.msat_term_is_bv_uleq(self.msat_env, term):
            assert arity == 2
            res = mgr.BVULE(args[0], args[1])

        elif mathsat.msat_term_is_bv_sleq(self.msat_env, term):
            assert arity == 2
            res = mgr.BVSLE(args[0], args[1])

        elif mathsat.msat_term_is_bv_lshl(self.msat_env, term):
            assert arity == 2
            res = mgr.BVLShl(args[0], args[1])

        elif mathsat.msat_term_is_bv_lshr(self.msat_env, term):
            assert arity == 2
            res = mgr.BVLShr(args[0], args[1])

        elif mathsat.msat_term_is_bv_ashr(self.msat_env, term):
            assert arity == 2
            res = mgr.BVAShr(args[0], args[1])

        elif mathsat.msat_term_is_bv_comp(self.msat_env, term):
            assert arity == 2
            res = mgr.BVComp(args[0], args[1])

        elif mathsat.msat_term_is_bv_zext(self.msat_env, term)[0]:
            assert arity == 2
            res, amount = mathsat.msat_term_is_bv_zext(self.msat_env, term)
            assert res
            res = mgr.BVZExt(args[0], amount)

        elif mathsat.msat_term_is_bv_sext(self.msat_env, term)[0]:
            assert arity == 2
            res, amount = mathsat.msat_term_is_bv_sext(self.msat_env, term)
            assert res
            res = mgr.BVSExt(args[0], amount)

        elif mathsat.msat_term_is_bv_rol(self.msat_env, term)[0]:
            assert arity == 2
            res, amount = mathsat.msat_term_is_bv_ror(self.msat_env, term)
            assert res
            res = mgr.BVRol(args[0], amount)

        elif mathsat.msat_term_is_bv_ror(self.msat_env, term)[0]:
            assert arity == 2
            res, amount = mathsat.msat_term_is_bv_ror(self.msat_env, term)
            assert res
            res = mgr.BVRor(args[0], amount)

        else:
            raise TypeError("Unsupported expression:",
                            mathsat.msat_term_repr(term))
        return res
Ejemplo n.º 3
0
    def _get_signature(self, term, args):
        """Returns the signature of the given term.
        For example:
        - a term x & y returns a function type Bool -> Bool -> Bool,
        - a term 14 returns Int
        - a term x ? 13 : 15.0 returns Bool -> Real -> Real -> Real
        """
        res = None

        if mathsat.msat_term_is_true(self.msat_env(), term) or \
            mathsat.msat_term_is_false(self.msat_env(), term) or \
            mathsat.msat_term_is_boolean_constant(self.msat_env(), term):
            res = types.BOOL

        elif mathsat.msat_term_is_number(self.msat_env(), term):
            ty = mathsat.msat_term_get_type(term)
            if mathsat.msat_is_integer_type(self.msat_env(), ty):
                res = types.INT
            elif mathsat.msat_is_rational_type(self.msat_env(), ty):
                res = types.REAL
            else:
                assert "_" in str(term), "Unrecognized type for '%s'" % str(term)
                width = int(str(term).split("_")[1])
                res = types.BVType(width)

        elif mathsat.msat_term_is_and(self.msat_env(), term) or \
             mathsat.msat_term_is_or(self.msat_env(), term) or \
             mathsat.msat_term_is_iff(self.msat_env(), term):
            res = types.FunctionType(types.BOOL, [types.BOOL, types.BOOL])

        elif mathsat.msat_term_is_not(self.msat_env(), term):
            res = types.FunctionType(types.BOOL, [types.BOOL])

        elif mathsat.msat_term_is_term_ite(self.msat_env(), term):
            t1 = self.env.stc.get_type(args[1])
            t2 = self.env.stc.get_type(args[2])
            t = self._most_generic(t1, t2)
            res = types.FunctionType(t, [types.BOOL, t, t])

        elif mathsat.msat_term_is_equal(self.msat_env(), term) or \
             mathsat.msat_term_is_leq(self.msat_env(), term):
            t1 = self.env.stc.get_type(args[0])
            t2 = self.env.stc.get_type(args[1])
            t = self._most_generic(t1, t2)
            res = types.FunctionType(types.BOOL, [t, t])

        elif mathsat.msat_term_is_plus(self.msat_env(), term) or \
             mathsat.msat_term_is_times(self.msat_env(), term):
            t1 = self.env.stc.get_type(args[0])
            t2 = self.env.stc.get_type(args[1])
            t = self._most_generic(t1, t2)
            res = types.FunctionType(t, [t, t])

        elif mathsat.msat_term_is_constant(self.msat_env(), term):
            ty = mathsat.msat_term_get_type(term)
            if mathsat.msat_is_rational_type(self.msat_env(), ty):
                res = types.REAL
            elif mathsat.msat_is_integer_type(self.msat_env(), ty):
                res = types.INT
            else:
                _, width = mathsat.msat_is_bv_type(self.msat_env(), ty)
                assert width is not None, "Unsupported type for '%s'" % str(term)
                res = types.BVType(width)

        elif mathsat.msat_term_is_uf(self.msat_env(), term):
            d = mathsat.msat_term_get_decl(term)
            fun = self.get_symbol_from_declaration(d)
            res = fun.symbol_type()

        elif mathsat.msat_term_is_bv_times(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_plus(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_minus(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_or(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_and(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_lshl(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_lshr(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_ashr(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_xor(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_urem(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_udiv(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_sdiv(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_srem(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_concat(self.msat_env(), term):
            t = self.env.stc.get_type(args[0])
            res = types.FunctionType(t, [t, t])

        elif mathsat.msat_term_is_bv_not(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_neg(self.msat_env(), term):
            t = self.env.stc.get_type(args[0])
            res = types.FunctionType(t, [t])

        elif mathsat.msat_term_is_bv_ult(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_slt(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_uleq(self.msat_env(), term) or \
             mathsat.msat_term_is_bv_sleq(self.msat_env(), term):
            t = self.env.stc.get_type(args[0])
            res = types.FunctionType(types.BOOL, [t, t])

        elif mathsat.msat_term_is_bv_comp(self.msat_env(), term):
            t = self.env.stc.get_type(args[0])
            res = types.FunctionType(types.BVType(1), [t, t])

        elif mathsat.msat_term_is_bv_rol(self.msat_env(), term)[0] or \
             mathsat.msat_term_is_bv_ror(self.msat_env(), term)[0]:
            t = self.env.stc.get_type(args[0])
            res = types.FunctionType(t, [t])

        elif mathsat.msat_term_is_bv_sext(self.msat_env(), term)[0]:
            _, amount = mathsat.msat_term_is_bv_sext(self.msat_env(), term)
            t = self.env.stc.get_type(args[0])
            res = types.FunctionType(types.BVType(amount + t.width), [t])

        elif mathsat.msat_term_is_bv_zext(self.msat_env(), term)[0]:
            _, amount = mathsat.msat_term_is_bv_zext(self.msat_env(), term)
            t = self.env.stc.get_type(args[0])
            res = types.FunctionType(types.BVType(amount + t.width), [t])

        elif mathsat.msat_term_is_bv_extract(self.msat_env(), term)[0]:
            _, msb, lsb = mathsat.msat_term_is_bv_extract(self.msat_env(), term)
            t = self.env.stc.get_type(args[0])
            res = types.FunctionType(types.BVType(msb - lsb + 1), [t])

        else:
            raise TypeError("Unsupported expression:",
                            mathsat.msat_term_repr(term))
        return res
Ejemplo n.º 4
0
Archivo: msat.py Proyecto: idkwim/pysmt
    def _get_signature(self, term, args):
        """Returns the signature of the given term.
        For example:
        - a term x & y returns a function type Bool -> Bool -> Bool,
        - a term 14 returns Int
        - a term x ? 13 : 15.0 returns Bool -> Real -> Real -> Real
        """
        res = None

        if mathsat.msat_term_is_true(self.msat_env, term) or \
            mathsat.msat_term_is_false(self.msat_env, term) or \
            mathsat.msat_term_is_boolean_constant(self.msat_env, term):
            res = types.BOOL

        elif mathsat.msat_term_is_number(self.msat_env, term):
            ty = mathsat.msat_term_get_type(term)
            if mathsat.msat_is_integer_type(self.msat_env, ty):
                res = types.INT
            elif mathsat.msat_is_rational_type(self.msat_env, ty):
                res = types.REAL
            else:
                assert "_" in str(
                    term), "Unrecognized type for '%s'" % str(term)
                width = int(str(term).split("_")[1])
                res = types.BVType(width)


        elif mathsat.msat_term_is_and(self.msat_env, term) or \
             mathsat.msat_term_is_or(self.msat_env, term) or \
             mathsat.msat_term_is_iff(self.msat_env, term):
            res = types.FunctionType(types.BOOL, [types.BOOL, types.BOOL])

        elif mathsat.msat_term_is_not(self.msat_env, term):
            res = types.FunctionType(types.BOOL, [types.BOOL])

        elif mathsat.msat_term_is_term_ite(self.msat_env, term):
            t1 = self.env.stc.get_type(args[1])
            t2 = self.env.stc.get_type(args[2])
            t = self._most_generic(t1, t2)
            res = types.FunctionType(t, [types.BOOL, t, t])

        elif mathsat.msat_term_is_equal(self.msat_env, term) or \
             mathsat.msat_term_is_leq(self.msat_env, term):
            t1 = self.env.stc.get_type(args[0])
            t2 = self.env.stc.get_type(args[1])
            t = self._most_generic(t1, t2)
            res = types.FunctionType(types.BOOL, [t, t])

        elif mathsat.msat_term_is_plus(self.msat_env, term) or \
             mathsat.msat_term_is_times(self.msat_env, term):
            t1 = self.env.stc.get_type(args[0])
            t2 = self.env.stc.get_type(args[1])
            t = self._most_generic(t1, t2)
            res = types.FunctionType(t, [t, t])

        elif mathsat.msat_term_is_constant(self.msat_env, term):
            ty = mathsat.msat_term_get_type(term)
            if mathsat.msat_is_rational_type(self.msat_env, ty):
                res = types.REAL
            elif mathsat.msat_is_integer_type(self.msat_env, ty):
                res = types.INT
            else:
                _, width = mathsat.msat_is_bv_type(self.msat_env, ty)
                assert width is not None, "Unsupported type for '%s'" % str(
                    term)
                res = types.BVType(width)

        elif mathsat.msat_term_is_uf(self.msat_env, term):
            d = mathsat.msat_term_get_decl(term)
            fun = self.get_symbol_from_declaration(d)
            res = fun.symbol_type()

        elif mathsat.msat_term_is_bv_times(self.msat_env, term) or \
             mathsat.msat_term_is_bv_plus(self.msat_env, term) or \
             mathsat.msat_term_is_bv_minus(self.msat_env, term) or \
             mathsat.msat_term_is_bv_or(self.msat_env, term) or \
             mathsat.msat_term_is_bv_and(self.msat_env, term) or \
             mathsat.msat_term_is_bv_lshl(self.msat_env, term) or \
             mathsat.msat_term_is_bv_lshr(self.msat_env, term) or \
             mathsat.msat_term_is_bv_ashr(self.msat_env, term) or \
             mathsat.msat_term_is_bv_xor(self.msat_env, term) or \
             mathsat.msat_term_is_bv_urem(self.msat_env, term) or \
             mathsat.msat_term_is_bv_udiv(self.msat_env, term) or \
             mathsat.msat_term_is_bv_sdiv(self.msat_env, term) or \
             mathsat.msat_term_is_bv_srem(self.msat_env, term) or \
             mathsat.msat_term_is_bv_concat(self.msat_env, term):
            t = self.env.stc.get_type(args[0])
            res = types.FunctionType(t, [t, t])

        elif mathsat.msat_term_is_bv_not(self.msat_env, term) or \
             mathsat.msat_term_is_bv_neg(self.msat_env, term):
            t = self.env.stc.get_type(args[0])
            res = types.FunctionType(t, [t])

        elif mathsat.msat_term_is_bv_ult(self.msat_env, term) or \
             mathsat.msat_term_is_bv_slt(self.msat_env, term) or \
             mathsat.msat_term_is_bv_uleq(self.msat_env, term) or \
             mathsat.msat_term_is_bv_sleq(self.msat_env, term):
            t = self.env.stc.get_type(args[0])
            res = types.FunctionType(types.BOOL, [t, t])

        elif mathsat.msat_term_is_bv_comp(self.msat_env, term):
            t = self.env.stc.get_type(args[0])
            res = types.FunctionType(types.BVType(1), [t, t])

        elif mathsat.msat_term_is_bv_rol(self.msat_env, term)[0] or \
             mathsat.msat_term_is_bv_ror(self.msat_env, term)[0]:
            t = self.env.stc.get_type(args[0])
            res = types.FunctionType(t, [t])

        elif mathsat.msat_term_is_bv_sext(self.msat_env, term)[0]:
            _, amount = mathsat.msat_term_is_bv_sext(self.msat_env, term)
            t = self.env.stc.get_type(args[0])
            res = types.FunctionType(types.BVType(amount + t.width), [t])

        elif mathsat.msat_term_is_bv_zext(self.msat_env, term)[0]:
            _, amount = mathsat.msat_term_is_bv_zext(self.msat_env, term)
            t = self.env.stc.get_type(args[0])
            res = types.FunctionType(types.BVType(amount + t.width), [t])

        elif mathsat.msat_term_is_bv_extract(self.msat_env, term)[0]:
            _, msb, lsb = mathsat.msat_term_is_bv_extract(self.msat_env, term)
            t = self.env.stc.get_type(args[0])
            res = types.FunctionType(types.BVType(msb - lsb + 1), [t])

        else:
            raise TypeError("Unsupported expression:",
                            mathsat.msat_term_repr(term))
        return res