Пример #1
0
    def __init__(self, **base_options):
        SolverOptions.__init__(self, **base_options)
        if self.unsat_cores_mode is not None:
            raise PyomtValueError("'unsat_cores_mode' option not supported.")

        # Set Defaults
        self.preprocessing = True
        self.propagation_limit = None
        self.more_important_lit = None
        self.less_important_lit = None
        self.global_default_phase = None
        self.enable_trace_generation = False
        self.output = None
        self.verbosity = 0

        for k, v in self.solver_options.items():
            if k == "enable_trace_generation":
                if v not in (True, False):
                    raise PyomtValueError("Invalid value for %s: %s" % \
                                     (str(k),str(v)))
            elif k == "output":
                if v is not None and not hasattr(v, "fileno"):
                    raise PyomtValueError("Invalid value for %s: %s" % \
                                     (str(k),str(v)))

            elif k == "global_default_phase":
                if v is not None and v not in PicosatOptions.ALL_GLOBAL_DEFAULT_PHASE:
                    raise PyomtValueError("Invalid value for %s: %s" % \
                                     (str(k),str(v)))
            elif k == "preprocessing":
                if v not in (True, False):
                    raise PyomtValueError("Invalid value for %s: %s" % \
                                     (str(k),str(v)))
            elif k == "verbosity":
                if not is_python_integer(v):
                    raise PyomtValueError("Invalid value for %s: %s" % \
                                     (str(k),str(v)))
            elif k == "propagation_limit":
                if not is_python_integer(v):
                    raise PyomtValueError("Invalid value for %s: %s" % \
                                     (str(k),str(v)))
            elif k in ("more_important_lit", "less_important_lit"):
                if v is not None:
                    try:
                        valid = all(x.is_symbol(types.BOOL) for x in v)
                    except:
                        valid = False
                    if not valid:
                        raise PyomtValueError("'more_important_lit' and "
                                              "'less_important_lit' require a "
                                              "list of Boolean variables")
            else:
                raise PyomtValueError("Unrecognized option '%s'." % k)
            # Store option
            setattr(self, k, v)

        # Consistency
        if self.output is not None and self.verbosity == 0:
            self.verbosity = 1
Пример #2
0
    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))
Пример #3
0
 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(), ))
Пример #4
0
    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 PyomtValueError(
                    "Need to specify a width for the constant")

            min_val = -(2**(width - 1))
            max_val = (2**(width - 1)) - 1
            if value < min_val:
                raise PyomtValueError("Cannot represent a value (%d) lower " \
                                      "than %d in %d bits" % (value, min_val,
                                                              width))
            if value > max_val:
                raise PyomtValueError("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)
Пример #5
0
 def BVAShr(self, left, right):
     """Returns the RIGHT arithmetic rotation of the left BV by the number
     of steps specified by the right BV."""
     if is_python_integer(right):
         right = self.BV(right, left.bv_width())
     return self.create_node(node_type=op.BV_ASHR,
                             args=(left, right),
                             payload=(left.bv_width(), ))
Пример #6
0
 def BVRor(self, formula, steps):
     """Returns the RIGHT rotation of the BV by the number of steps."""
     if not is_python_integer(steps):
         raise PyomtTypeError("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))
Пример #7
0
 def __rsub__(self, left):
     # Swap operators to perform right-subtract
     # For BVs we might need to build the BV constant
     if self.get_type().is_bv_type():
         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)
Пример #8
0
    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 PyomtTypeError("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))
Пример #9
0
    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 PyomtTypeError("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))
Пример #10
0
    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 PyomtValueError("Expecting binary value as string, got " \
                                      "%s instead." % value)

            if width is not None and width != str_width:
                raise PyomtValueError("Specified width does not match string " \
                                      "width (%d != %d)" % (width, str_width))
            width = str_width

        if width is None:
            raise PyomtValueError("Need to specify a width for the constant")

        if is_pyomt_integer(value):
            _value = value
        elif is_python_integer(value):
            _value = pyomt_integer_from_integer(value)
        else:
            raise PyomtTypeError("Invalid type in constant. The type was: %s" \
                                 % str(type(value)))
        if _value < 0:
            raise PyomtValueError("Cannot specify a negative value: %d" \
                                  % _value)
        if _value >= 2**width:
            raise PyomtValueError("Cannot express %d in %d bits" \
                                  % (_value, width))
        return self.create_node(node_type=op.BV_CONSTANT,
                                args=tuple(),
                                payload=(_value, width))
Пример #11
0
    def Int(self, value):
        """Return a constant of type INT."""
        if value in self.int_constants:
            return self.int_constants[value]

        if is_pyomt_integer(value):
            val = value
        elif is_python_integer(value):
            val = pyomt_integer_from_integer(value)
        else:
            raise PyomtTypeError("Invalid type in constant. The type was:" + \
                                 str(type(value)))
        n = self.create_node(node_type=op.INT_CONSTANT,
                             args=tuple(),
                             payload=val)
        self.int_constants[value] = n
        return n