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)
def visit_float_is_positive(self, e): arg = e.arg(0) self._check_fp_sort(arg) arg_sort = e.arg(0).sort() zero = None # FIXME: This isn't sound. We can't distinguish +0 and -0 # in Coral's constraint language self._unsound_translation('fp.isPositive') 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.isPositive case') tmp = z3.fpGT(arg, zero) self.visit(tmp)
def visit_float_is_subnormal(self, e): arg = e.arg(0) self._check_fp_sort(arg) arg_sort = e.arg(0).sort() smallest_positive_normal = self._get_smallest_positive_normal_for( arg_sort) largest_negative_normal = self._get_largest_negative_normal_for( arg_sort) temp = z3.Or( z3.And(z3.fpLT(arg, smallest_positive_normal), z3.fpGT(arg, z3.fpPlusZero(arg_sort))), z3.And(z3.fpGT(arg, largest_negative_normal), z3.fpLT(arg, z3.fpMinusZero(arg_sort)))) self.visit(temp)
def FPV(self, ast): #pylint:disable=unused-argument val = str(ast.args[0]) sort = self._convert(ast.args[1]) if val == 'inf': return z3.fpPlusInfinity(sort) elif val == '-inf': return z3.fpMinusInfinity(sort) elif val == '0.0': return z3.fpPlusZero(sort) elif val == '-0.0': return z3.fpMinusZero(sort) elif val == 'nan': return z3.fpNaN(sort) else: better_val = str(Decimal(ast.args[0])) return z3.FPVal(better_val, sort, ctx=self._context)
def FPV(self, ast, result=None): #pylint:disable=unused-argument val = str(ast.args[0]) sort = self._convert(ast.args[1]) if val == 'inf': return z3.fpPlusInfinity(sort) elif val == '-inf': return z3.fpMinusInfinity(sort) elif val == '0.0': return z3.fpPlusZero(sort) elif val == '-0.0': return z3.fpMinusZero(sort) elif val == 'nan': return z3.fpNaN(sort) else: better_val = str(Decimal(ast.args[0])) return z3.FPVal(better_val, sort, ctx=self._context)
def _convert(self, obj, result=None): if type(obj) is NativeBVV: return z3.BitVecVal(obj.value, obj.bits) elif isinstance(obj, FSort): return z3.FPSort(obj.exp, obj.mantissa) elif isinstance(obj, RM): if obj == RM_RNE: return z3.RNE() elif obj == RM_RNA: return z3.RNA() elif obj == RM_RTP: return z3.RTP() elif obj == RM_RTN: return z3.RTN() elif obj == RM_RTZ: return z3.RTZ() else: raise BackendError("unrecognized rounding mode") elif isinstance(obj, NativeFPV): val = str(obj.value) sort = self._convert(obj.sort) if val == 'inf': return z3.fpPlusInfinity(sort) elif val == '-inf': return z3.fpMinusInfinity(sort) elif val == '0.0': return z3.fpPlusZero(sort) elif val == '-0.0': return z3.fpMinusZero(sort) elif val == 'nan': return z3.fpNaN(sort) else: better_val = str(Decimal(obj.value)) return z3.FPVal(better_val, sort) elif obj is True: return z3.BoolVal(True) elif obj is False: return z3.BoolVal(False) elif type(obj) in (int, long, float, str): return obj elif hasattr(obj, '__module__') and obj.__module__ == 'z3': return obj else: l.debug("BackendZ3 encountered unexpected type %s", type(obj)) raise BackendError("unexpected type %s encountered in BackendZ3" % type(obj))