示例#1
0
文件: card.py 项目: cryhot/pysat
    def atmost(cls, lits, bound=1, top_id=None, vpool=None,
            encoding=EncType.seqcounter):
        """
            This method can be used for creating a CNF encoding of an AtMostK
            constraint, i.e. of :math:`\sum_{i=1}^{n}{x_i}\leq k`. The method
            shares the arguments and the return type with method
            :meth:`CardEnc.atleast`. Please, see it for details.
        """

        if encoding < 0 or encoding > 9:
            raise(NoSuchEncodingError(encoding))

        assert not top_id or not vpool, \
                'Use either a top id or a pool of variables but not both.'

        # we are going to return this formula
        ret = CNFPlus()

        # if the list of literals is empty, return empty formula
        if not lits:
            return ret

        # obtaining the top id from the variable pool
        if vpool:
            top_id = vpool.top

        # choosing the maximum id among the current top and the list of literals
        top_id = max(map(lambda x: abs(x), lits + [top_id if top_id != None else 0]))

        # MiniCard's native representation is handled separately
        if encoding == 9:
            ret.atmosts, ret.nv = [(lits, bound)], top_id
            return ret

        if MainThread.check() == True:
            # saving default SIGINT handler
            def_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_DFL)

            res = pycard.encode_atmost(lits, bound, top_id, encoding, 1)

            # recovering default SIGINT handler
            def_sigint_handler = signal.signal(signal.SIGINT, def_sigint_handler)
        else:
            res = pycard.encode_atmost(lits, bound, top_id, encoding, 0)

        if res:
            ret.clauses, ret.nv = res

        # updating vpool if necessary
        if vpool:
            if vpool._occupied and vpool.top <= vpool._occupied[0][0] <= ret.nv:
                cls._update_vids(ret, vpool)
            else:
                vpool.top = ret.nv - 1
                vpool._next()

        return ret
示例#2
0
    def atmost(cls, lits, bound=1, top_id=None, encoding=EncType.seqcounter):
        """
            This method can be used for creating a CNF encoding of an AtMostK
            constraint, i.e. of :math:`\sum_{i=1}^{n}{x_i}\leq k`. The method
            shares the arguments and the return type with method
            :meth:`CardEnc.atleast`. Please, see it for details.
        """

        if encoding < 0 or encoding > 9:
            raise (NoSuchEncodingError(encoding))

        if not top_id:
            top_id = max(map(lambda x: abs(x), lits))

        # we are going to return this formula
        ret = CNFPlus()

        # MiniCard's native representation is handled separately
        if encoding == 9:
            ret.atmosts, ret.nv = [(lits, bound)], top_id
            return ret

        # saving default SIGINT handler
        def_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_DFL)

        res = pycard.encode_atmost(lits, bound, top_id, encoding)

        # recovering default SIGINT handler
        def_sigint_handler = signal.signal(signal.SIGINT, def_sigint_handler)

        if res:
            ret.clauses, ret.nv = res

        return ret
示例#3
0
    def atmost(cls, lits, bound=1, top_id=None, vpool=None,
            encoding=EncType.seqcounter):
        """
            This method can be used for creating a CNF encoding of an AtMostK
            constraint, i.e. of :math:`\sum_{i=1}^{n}{x_i}\leq k`. The method
            shares the arguments and the return type with method
            :meth:`CardEnc.atleast`. Please, see it for details.
        """

        if encoding < 0 or encoding > 9:
            raise(NoSuchEncodingError(encoding))

        # checking if the bound is meaningless for any encoding
        if bound < 0:
            raise ValueError('Wrong bound: {0}'.format(bound))

        if encoding in (0, 4, 5) and 1 < bound < len(lits) - 1:
            raise(UnsupportedBound(encoding, bound))

        assert not top_id or not vpool, \
                'Use either a top id or a pool of variables but not both.'

        # we are going to return this formula
        ret = CNFPlus()

        # if the list of literals is empty, return empty formula
        if not lits:
            return ret

        # obtaining the top id from the variable pool
        if vpool:
            top_id = vpool.top

        # making sure we are dealing with a list of literals
        lits = list(lits)

        # choosing the maximum id among the current top and the list of literals
        top_id = max(map(lambda x: abs(x), lits + [top_id if top_id != None else 0]))

        # MiniCard's native representation is handled separately
        if encoding == 9:
            ret.atmosts, ret.nv = [(lits, bound)], top_id
            return ret

        res = pycard.encode_atmost(lits, bound, top_id, encoding,
                int(MainThread.check()))

        if res:
            ret.clauses, ret.nv = res

            # updating vpool if necessary
            if vpool:
                if vpool._occupied and vpool.top <= vpool._occupied[0][0] <= ret.nv:
                    cls._update_vids(ret, vpool)
                else:
                    # here, ret.nv id is assumed to be larger than the top id
                    vpool.top = ret.nv - 1
                    vpool._next()

        return ret