示例#1
0
 def visit_float_is_infinite(self, e):
     arg = e.arg(0)
     self._check_fp_sort(arg)
     arg_sort = arg.sort()
     pos_inf = None
     neg_inf = None
     if self._is_float32_sort(arg_sort):
         pos_inf = z3.fpPlusInfinity(z3.Float32())
         neg_inf = z3.fpMinusInfinity(z3.Float32())
     elif self._is_float64_sort(arg_sort):
         pos_inf = z3.fpPlusInfinity(z3.Float64())
         neg_inf = z3.fpMinusInfinity(z3.Float64())
     else:
         raise CoralPrinterException('Unhandled fp.isInfinite op case')
     temp = z3.Or(z3.fpEQ(arg, pos_inf), z3.fpEQ(arg, neg_inf))
     self.visit(temp)
示例#2
0
 def visit_eq(self, e):
     sort = e.arg(0).sort()
     if sort.kind() == z3.Z3_BOOL_SORT:
         self.sio.write('BNOT(BXOR(')
         self.visit(e.arg(0))
         self.sio.write(',')
         self.visit(e.arg(1))
         self.sio.write('))')
     elif sort.kind() == z3.Z3_BV_SORT:
         raise NotImplementedError('BitVector equal')
         self._check_bv_sort(e.arg(0))
         self._check_bv_sort(e.arg(1))
     elif sort.kind() == z3.Z3_FLOATING_POINT_SORT:
         self._check_fp_sort(e.arg(0))
         # Either FEQ or both args are NaN
         # FIXME: This isn't quite right because +zero is != to -zero
         # but we have no way in Coral's constraint language of distinguishing
         # between them
         self._unsound_translation('=')
         new_expr = z3.Or(
             z3.And(z3.fpIsNaN(e.arg(0)), z3.fpIsNaN(e.arg(1))),
             z3.fpEQ(e.arg(0), e.arg(1)))
         self.visit(new_expr)
     else:
         raise CoralPrinterUnsupportedSort(sort)
示例#3
0
  def _float_binary_operator(self, term, op):
    x = self.eval(term.x)
    y = self.eval(term.y)

    if 'nnan' in term.flags:
      self.add_defs(z3.Not(z3.fpIsNaN(x)), z3.Not(z3.fpIsNaN(y)),
        z3.Not(z3.fpIsNaN(op(x,y))))

    if 'ninf' in term.flags:
      self.add_defs(z3.Not(z3.fpIsInf(x)), z3.Not(z3.fpIsInf(y)),
        z3.Not(z3.fpIsInf(op(x,y))))

    if 'nsz' in term.flags:
      # NOTE: this will return a different qvar for each (in)direct reference
      # to this term. Is this desirable?
      q = self.fresh_var(self.type(term))
      self.add_qvar(q)  # FIXME
      self.add_defs(z3.fpEQ(q,0))
      z = op(x,y)
      return z3.If(z3.fpEQ(z,0), q, z)

    return op(x,y)
示例#4
0
    def _float_binary_operator(self, term, op):
        x = self.eval(term.x)
        y = self.eval(term.y)

        if 'nnan' in term.flags:
            self.add_defs(z3.Not(z3.fpIsNaN(x)), z3.Not(z3.fpIsNaN(y)),
                          z3.Not(z3.fpIsNaN(op(x, y))))

        if 'ninf' in term.flags:
            self.add_defs(z3.Not(z3.fpIsInf(x)), z3.Not(z3.fpIsInf(y)),
                          z3.Not(z3.fpIsInf(op(x, y))))

        if 'nsz' in term.flags:
            # NOTE: this will return a different qvar for each (in)direct reference
            # to this term. Is this desirable?
            q = self.fresh_var(self.type(term))
            self.add_qvar(q)  # FIXME
            self.add_defs(z3.fpEQ(q, 0))
            z = op(x, y)
            return z3.If(z3.fpEQ(z, 0), q, z)

        return op(x, y)
示例#5
0
 def visit_float_is_zero(self, e):
     arg = e.arg(0)
     self._check_fp_sort(arg)
     arg_sort = arg.sort()
     zero = None
     # It doesn't matter if we pick +0 or -0 as we are using
     # the fp.eq operator which can't distinguish them, so
     # the choice of +0 is arbitrary.
     if self._is_float32_sort(arg_sort):
         zero = z3.fpPlusZero(z3.Float32())
     elif self._is_float64_sort(arg_sort):
         zero = z3.fpPlusZero(z3.Float64())
     else:
         raise CoralPrinterException('Unhandled fp.isZero op case')
     temp = z3.fpEQ(arg, zero)
     self.visit(temp)
示例#6
0
 def _op_raw_fpEQ(self, a, b):
     return z3.fpEQ(a, b, ctx=self._context)
示例#7
0
def fpUEQ(x, y):
    return z3.Or(z3.fpEQ(x, y), z3.fpIsNaN(x), z3.fpIsNaN(y))
示例#8
0
 def _op_raw_fpEQ(self, a, b):
     return z3.fpEQ(a, b, ctx=self._context)
示例#9
0
def fpUEQ(x, y):
  return z3.Or(z3.fpEQ(x,y), z3.fpIsNaN(x), z3.fpIsNaN(y))