Example #1
0
    def formula(self, p):
        ptyp = type(p)
        if ptyp is BD.GTZ or ptyp is BD.GEZ or ptyp is BD.EQZ:
            aform = self.affine(p.expr)
            if ptyp is BD.GTZ: return SMT.GT(aform, SMT.Int(0))
            elif ptyp is BD.GEZ: return SMT.GE(aform, SMT.Int(0))
            elif ptyp is BD.EQZ: return SMT.Equals(aform, SMT.Int(0))
            else: assert False

        elif ptyp is BD.Rel:
            rsym = self._ctxt.get(p.name)
            assert rsym is not None, f"expected relation name '{p.name}'"

            args = []
            for a in p.args:
                sym = self._ctxt.get(a)
                assert sym is not None, f"expected variable name '{a}'"
                args.append(sym)
            return SMT.Function(rsym, args)

        elif ptyp is BD.Conj or ptyp is BD.Disj:
            lhs = self.formula(p.lhs)
            rhs = self.formula(p.rhs)
            smtop = SMT.And if ptyp is BD.Conj else SMT.Or
            return smtop(lhs, rhs)
Example #2
0
    def _test_to_smt(self, operator):
        operator = operator.to_canonical()

        # FIXME Integer rounding only applicable if x >= 0

        def to_symbol(s):
            return smt.Symbol(s, typename=smt.types.INT)

        import math
        items = [smt.Times(smt.Int(int(math.floor(v))), to_symbol(k)) for k, v in operator.lhs.items()]
        lhs = smt.Plus([smt.Int(0)] + items)
        rhs = smt.Int(int(math.floor(operator.rhs)))

        assert operator.symbol == "<="

        return smt.LE(lhs, rhs)
Example #3
0
 def affine(self, a):
     """ return some positive rescaling of the affine expression
     s.t. the rescaled expression has integer coefficients
     safe, since positive rescaling preserves
     all of a >= 0, a > 0, and a == 0 """
     # find the lcm of the offset denominator
     # and all coefficient denominators
     mult = a.offset.denominator
     for t in a.terms:
         mult = _lcm(mult, t.coeff.denominator)
     # now, we can produce an integral affine equation,
     # by rescaling through with `mult`
     a = a * Fraction(mult)
     # Finally, convert this to an SMT formula
     assert a.offset.denominator == 1
     f = SMT.Int(a.offset.numerator)
     for t in a.terms:
         assert t.coeff.denominator == 1
         sym = self._ctxt.get(t.var)
         assert sym is not None, f"expected variable name '{t.var}'"
         term = SMT.Times(SMT.Int(t.coeff.numerator), sym)
         f = SMT.Plus(f, term)
     return f
Example #4
0
    def _exp_to_smt(self, expression):
        if isinstance(expression, sympy.Add):
            return smt.Plus([self._exp_to_smt(arg) for arg in expression.args])
        elif isinstance(expression, sympy.Mul):
            return smt.Times(*[self._exp_to_smt(arg) for arg in expression.args])
        elif isinstance(expression, sympy.Symbol):
            return smt.Symbol(str(expression), INT)

        try:
            expression = int(expression)
            return smt.Int(expression)
        except ValueError:
            pass
        raise RuntimeError("Could not parse {} of type {}".format(expression, type(expression)))
Example #5
0
 def __encodeTerminal(symbolicExpression, type):
     if isinstance(symbolicExpression, sympy.Symbol):
         if type.literal == 'Integer':
             return pysmt.Symbol(symbolicExpression.name, pysmt.INT)
         elif type.literal == 'Real':
             return pysmt.Symbol(symbolicExpression.name, pysmt.REAL)
         elif type.literal == 'Bool':
             return pysmt.Symbol(symbolicExpression.name, pysmt.BOOL)
         else:  # type.literal == 'BitVector'
             return pysmt.Symbol(symbolicExpression.name, pysmt.BVType(type.size))
     else:
         if type.literal == 'Integer':
             return pysmt.Int(symbolicExpression.p)
         elif type.literal == 'Real':
             if isinstance(symbolicExpression, sympy.Rational):
                 return pysmt.Real(symbolicExpression.p / symbolicExpression.q)
             else:  # isinstance(symbolicExpression, sympy.Float)
                 return pysmt.Real(symbolicExpression)
         elif type.literal == 'Bool':
             return pysmt.Bool(symbolicExpression)
         else:  # type.literal == 'BitVector'
             return pysmt.BV(symbolicExpression, type.size)
Example #6
0
variables = []
cap = 5
# add a_i, b_i, c_i variables for each equation
for n in range(1, cap + 1):
    variables.append(SMT.Symbol("a" + str(n), INT))
    variables.append(SMT.Symbol("b" + str(n), INT))
    variables.append(SMT.Symbol("c" + str(n), INT))
print(variables)

constraints = []
for var in variables:
    string = var.__repr__()
    # add requirement that all a_i, c_i > -1
    if string[0] == "a" or string[0] == "c":
        constraints.append(SMT.GT(var, SMT.Int(-1)))
    # add requirement that b_i > 0
    else:
        constraints.append(SMT.GT(var, SMT.Int(0)))

for i in range(0, 3 * cap, 3):
    # add requirement that either a_i =0 or c_i = 0
    constraints.append(
        SMT.Or(SMT.Equals(variables[i], SMT.Int(0)),
               SMT.Equals(variables[i + 2], SMT.Int(0))))
    # add requirement that if a_i = 0 and c_i = 0 then b_i = 1
    constraints.append(
        SMT.Or(
            SMT.Or(SMT.GT(variables[i], SMT.Int(0)),
                   SMT.GT(variables[i + 2], SMT.Int(0))),
            SMT.Equals(variables[i + 1], SMT.Int(1))))
Example #7
0
    def __getExpressionTree(symbolicExpression):
        # TODO LATER: take into account bitwise shift operations
        args = []
        castType = None
        if len(symbolicExpression.args) > 0:
            for symbolicArg in symbolicExpression.args:
                arg, type = Solver.__getExpressionTree(symbolicArg)
                args.append(arg)
                if castType is None:
                    castType = type
                else:
                    if castType.literal == 'Integer':
                        if type.literal == 'Real':
                            castType = type
                    # TODO LATER: consider other possible castings
            if castType.literal == 'Real':
                for i in range(len(args)):
                    args[i] = pysmt.ToReal(args[i])

        if isinstance(symbolicExpression, sympy.Not):
            if castType.literal == 'Integer':
                return pysmt.Equals(args[0], pysmt.Int(0)), Type('Bool')
            elif castType.literal == 'Real':
                return pysmt.Equals(args[0], pysmt.Real(0)), Type('Bool')
            elif castType.literal == 'Bool':
                return pysmt.Not(args[0]), Type('Bool')
            else: # castType.literal == 'BitVector'
                return pysmt.BVNot(args[0]), Type('BitVector')
        elif isinstance(symbolicExpression, sympy.Lt):
            return pysmt.LT(args[0], args[1]), Type('Bool')
        elif isinstance(symbolicExpression, sympy.Gt):
            return pysmt.GT(args[0], args[1]), Type('Bool')
        elif isinstance(symbolicExpression, sympy.Ge):
            return pysmt.GE(args[0], args[1]), Type('Bool')
        elif isinstance(symbolicExpression, sympy.Le):
            return pysmt.LE(args[0], args[1]), Type('Bool')
        elif isinstance(symbolicExpression, sympy.Eq):
            return pysmt.Equals(args[0], args[1]), Type('Bool')
        elif isinstance(symbolicExpression, sympy.Ne):
            return pysmt.NotEquals(args[0], args[1]), Type('Bool')
        elif isinstance(symbolicExpression, sympy.And):
            if castType.literal == 'Bool':
                return pysmt.And(args[0], args[1]), Type('Bool')
            else: # type.literal == 'BitVector'
                return pysmt.BVAnd(args[0], args[1]), castType
        elif isinstance(symbolicExpression, sympy.Or):
            if castType.literal == 'Bool':
                return pysmt.Or(args[0], args[1]), Type('Bool')
            else:  # type.literal == 'BitVector'
                return pysmt.BVOr(args[0], args[1]), castType
        elif isinstance(symbolicExpression, sympy.Xor):
            return pysmt.BVXor(args[0], args[1]), castType
        elif isinstance(symbolicExpression, sympy.Add):
            return pysmt.Plus(args), castType
        elif isinstance(symbolicExpression, sympy.Mul):
            return pysmt.Times(args), castType
        elif isinstance(symbolicExpression, sympy.Pow):
            return pysmt.Pow(args[0], args[1]), castType
        # TODO LATER: deal with missing modulo operator from pysmt
        else:
            if isinstance(symbolicExpression, sympy.Symbol):
                symbolType = Variable.symbolTypes[symbolicExpression.name]
                literal = symbolType.getTypeForSolver()
                designator = symbolType.designatorExpr1
                type = Type(literal, designator)
                return Solver.__encodeTerminal(symbolicExpression, type), type
            elif isinstance(symbolicExpression, sympy.Integer):
                type = Type('Integer')
                return Solver.__encodeTerminal(symbolicExpression, type), type
            elif isinstance(symbolicExpression, sympy.Rational):
                type = Type('Real')
                return Solver.__encodeTerminal(symbolicExpression, type), type
            elif isinstance(symbolicExpression, sympy.Float):
                type = Type('Real')
                return Solver.__encodeTerminal(symbolicExpression, type), type
            else:
                type = Type('Real')
                return Solver.__encodeTerminal(symbolicExpression, type), type