def BVExtract(self, formula, start=0, end=None): """Returns the slice of formula from start to end (inclusive).""" if end is None: end = formula.bv_width() - 1 assert is_python_integer(start) and is_python_integer(end) assert end >= start and start >= 0, "Start: %d ; End: %d" % (start, end) size = end - start + 1 assert size <= formula.bv_width(), "Invalid size: start=%d, end=%d, width=%d" % (start, end, formula.bv_width()) return self.create_node(node_type=op.BV_EXTRACT, args=(formula,), payload=(size, start, end))
def BVExtract(self, formula, start=0, end=None): """Returns the slice of formula from start to end (inclusive).""" if end is None: end = formula.bv_width() - 1 assert is_python_integer(start) and is_python_integer(end) assert end >= start and start >= 0, "Start: %d ; End: %d" % (start, end) size = end - start + 1 assert size <= formula.bv_width(), \ "Invalid size: start=%d, end=%d, width=%d" % \ (start, end, formula.bv_width()) return self.create_node(node_type=op.BV_EXTRACT, args=(formula, ), payload=(size, start, end))
def BVRor(self, formula, steps): """Returns the RIGHT rotation of the BV by the number of steps.""" if not is_python_integer(steps): raise TypeError("BVRor: 'steps' should be an integer. Got %s" % steps) return self.create_node(node_type=op.BV_ROR, args=(formula,), payload=(formula.bv_width(), steps))
def SBV(self, value, width=None): """Returns a constant of type BitVector interpreting the sign. If the specified value is an integer, it is converted in the 2-complement representation of the given number, otherwise the behavior is the same as BV(). """ if is_python_integer(value): if width is None: raise ValueError("Need to specify a width for the constant") min_val = -(2**(width - 1)) max_val = (2**(width - 1)) - 1 if value < min_val: raise ValueError("Cannot represent a value (%d) lower than %d" \ " in %d bits" % (value, min_val, width)) if value > max_val: raise ValueError("Cannot represent a value (%d) greater than " \ "%d in %d bits" % (value, max_val, width)) if value >= 0: return self.BV(value, width) else: comp_value = (2**width) + value # value is negative! return self.BV(comp_value, width) else: return self.BV(value, width=width)
def Real(self, value): """ Returns a Real-type constant of the given value. value can be: - A Fraction(n,d) - A tuple (n,d) - A long or int n - A float """ if value in self.real_constants: return self.real_constants[value] if type(value) == Fraction: val = value elif type(value) == tuple: val = Fraction(value[0], value[1]) elif is_python_integer(value): val = Fraction(value, 1) elif type(value) == float: val = Fraction.from_float(value) else: raise TypeError("Invalid type in constant. The type was:" + \ str(type(value))) n = self.create_node(node_type=op.REAL_CONSTANT, args=tuple(), payload=val) self.real_constants[value] = n return n
def BVLShr(self, left, right): """Returns the logical right shift the BV.""" if is_python_integer(right): right = self.BV(right, left.bv_width()) return self.create_node(node_type=op.BV_LSHR, args=(left, right), payload=(left.bv_width(),))
def SBV(self, value, width=None): """Returns a constant of type BitVector interpreting the sign. If the specified value is an integer, it is converted in the 2-complement representation of the given number, otherwise the behavior is the same as BV(). """ if is_python_integer(value): if width is None: raise ValueError("Need to specify a width for the constant") min_val = -(2**(width-1)) max_val = (2**(width-1)) - 1 if value < min_val: raise ValueError("Cannot represent a value (%d) lower than %d" \ " in %d bits" % (value, min_val, width)) if value > max_val: raise ValueError("Cannot represent a value (%d) greater than " \ "%d in %d bits" % (value, max_val, width)) if value >= 0: return self.BV(value, width) else: comp_value = (2**width) + value # value is negative! return self.BV(comp_value, width) else: return self.BV(value, width=width)
def BVLShr(self, left, right): """Returns the logical right shift the BV.""" if is_python_integer(right): right = self.BV(right, left.bv_width()) return self.create_node(node_type=op.BV_LSHR, args=(left, right), payload=(left.bv_width(), ))
def BVRor(self, formula, steps): """Returns the RIGHT rotation of the BV by the number of steps.""" if not is_python_integer(steps): raise TypeError("BVRor: 'steps' should be an integer. Got %s" % steps) return self.create_node(node_type=op.BV_ROR, args=(formula, ), payload=(formula.bv_width(), steps))
def __rsub__(self, left): # Swap operators to perform right-subtract # For BVs we might need to build the BV constant if _is_bv(self): if is_python_integer(left): left = _mgr().BV(left, width=self.bv_width()) return left._apply_infix(self, _mgr().BVSub) # (x - y) = (-y + x) minus_self = -self return minus_self._apply_infix(left, _mgr().Plus)
def BVSExt(self, formula, increase): """Returns the signed extension of the BV with 'increase' additional bits New bits are set according to the most-significant-bit. """ if not is_python_integer(increase): raise TypeError("BVSext: 'increase' should be an integer. Got %s" % increase) return self.create_node( node_type=op.BV_SEXT, args=(formula,), payload=(formula.bv_width() + increase, increase) )
def BVZExt(self, formula, increase): """Returns the extension of the BV with 'increase' additional bits New bits are set to zero. """ if not is_python_integer(increase): raise TypeError("BVZext: 'increase' should be an integer. Got %s" % increase) return self.create_node( node_type=op.BV_ZEXT, args=(formula,), payload=(formula.bv_width() + increase, increase) )
def Int(self, value): """Return a constant of type INT.""" if value in self.int_constants: return self.int_constants[value] if is_python_integer(value): n = self.create_node(node_type=op.INT_CONSTANT, args=tuple(), payload=value) self.int_constants[value] = n return n else: raise TypeError("Invalid type in constant. The type was:" + str(type(value)))
def BVSExt(self, formula, increase): """Returns the signed extension of the BV with 'increase' additional bits New bits are set according to the most-significant-bit. """ if not is_python_integer(increase): raise TypeError("BVSext: 'increase' should be an integer. Got %s" % increase) return self.create_node(node_type=op.BV_SEXT, args=(formula, ), payload=(formula.bv_width() + increase, increase))
def BVZExt(self, formula, increase): """Returns the extension of the BV with 'increase' additional bits New bits are set to zero. """ if not is_python_integer(increase): raise TypeError("BVZext: 'increase' should be an integer. Got %s" % increase) return self.create_node(node_type=op.BV_ZEXT, args=(formula, ), payload=(formula.bv_width() + increase, increase))
def Int(self, value): """Return a constant of type INT.""" if value in self.int_constants: return self.int_constants[value] if is_python_integer(value): n = self.create_node(node_type=op.INT_CONSTANT, args=tuple(), payload=value) self.int_constants[value] = n return n else: raise TypeError("Invalid type in constant. The type was:" + \ str(type(value)))
def _apply_infix(self, right, function, bv_function=None): if _env().enable_infix_notation: mgr = _mgr() # BVs # Default bv_function to function if bv_function is None: bv_function = function if _is_bv(self): if is_python_integer(right): right = mgr.BV(right, width=self.bv_width()) return bv_function(self, right) # Boolean, Integer and Arithmetic if is_python_boolean(right): right = mgr.Bool(right) elif is_python_integer(right): ty = self.get_type() if ty.is_real_type(): right = mgr.Real(right) else: right = mgr.Int(right) elif is_python_rational(right): right = mgr.Real(right) return function(self, right) else: raise Exception("Cannot use infix notation")
def _apply_infix(self, right, function): if _env().enable_infix_notation: mgr = _mgr() if is_python_boolean(right): right = mgr.Bool(right) elif is_python_integer(right): ty = self.get_type() if ty.is_real_type(): right = mgr.Real(right) else: right = mgr.Int(right) elif is_python_rational(right): right = mgr.Real(right) return function(self, right) else: raise Exception("Cannot use infix notation")
def BV(self, value, width=None): """Return a constant of type BitVector. value can be either: - a string of 0s and 1s - a string starting with "#b" followed by a sequence of 0s and 1s - an integer number s.t. 0 <= value < 2**width In order to create the BV representation of a signed integer, the SBV() method shall be used. """ if type(value) is str: if value.startswith("#b"): str_width = len(value) - 2 value = int(value[2:], 2) elif all(v in ["0", "1"] for v in value): str_width = len(value) value = int(value, 2) else: raise ValueError("Expecting binary value as string, got %s" \ " instead." % value) if width is not None and width != str_width: raise ValueError("Specified width does not match string width" \ " (%d != %d)" % (width, str_width)) width = str_width if width is None: raise ValueError("Need to specify a width for the constant") if is_python_integer(value): if value < 0: raise ValueError("Cannot specify a negative value: %d" % value) if value >= 2**width: raise ValueError("Cannot express %d in %d bits" % (value, width)) n = self.create_node(node_type=op.BV_CONSTANT, args=tuple(), payload=(value, width)) return n else: raise TypeError("Invalid type in constant. The type was:" + \ str(type(value)))
def BV(self, value, width=None): """Return a constant of type BitVector. value can be either: - a string of 0s and 1s - a string starting with "#b" followed by a sequence of 0s and 1s - an integer number s.t. 0 <= value < 2**width In order to create the BV representation of a signed integer, the SBV() method shall be used. """ if type(value) is str: if value.startswith("#b"): str_width = len(value)-2 value = int(value[2:],2) elif all(v in ["0", "1"] for v in value): str_width = len(value) value = int(value, 2) else: raise ValueError("Expecting binary value as string, got %s" \ " instead." % value) if width is not None and width != str_width: raise ValueError("Specified width does not match string width" \ " (%d != %d)" % (width, str_width)) width = str_width if width is None: raise ValueError("Need to specify a width for the constant") if is_python_integer(value): if value < 0: raise ValueError("Cannot specify a negative value: %d" % value) if value >= 2**width: raise ValueError("Cannot express %d in %d bits" % (value, width)) n = self.create_node(node_type=op.BV_CONSTANT, args=tuple(), payload=(value, width)) return n else: raise TypeError("Invalid type in constant. The type was:" + \ str(type(value)))