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
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
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 if not top_id: top_id = max(map(lambda x: abs(x), lits)) # 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 # 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
def atleast(cls, lits, bound=1, top_id=None, vpool=None, encoding=EncType.seqcounter): """ This method can be used for creating a CNF encoding of an AtLeastK constraint, i.e. of :math:`\sum_{i=1}^{n}{x_i}\geq k`. The method takes 1 mandatory argument ``lits`` and 3 default arguments can be specified: ``bound``, ``top_id``, ``vpool``, and ``encoding``. :param lits: a list of literals in the sum. :param bound: the value of bound :math:`k`. :param top_id: top variable identifier used so far. :param vpool: variable pool for counting the number of variables. :param encoding: identifier of the encoding to use. :type lits: iterable(int) :type bound: int :type top_id: integer or None :type vpool: :class:`.IDPool` :type encoding: integer Parameter ``top_id`` serves to increase integer identifiers of auxiliary variables introduced during the encoding process. This is helpful when augmenting an existing CNF formula with the new cardinality encoding to make sure there is no collision between identifiers of the variables. If specified, the identifiers of the first auxiliary variable will be ``top_id+1``. Instead of ``top_id``, one may want to use a pool of variable identifiers ``vpool``, which is automatically updated during the method call. In many circumstances, this is more convenient than using ``top_id``. Also note that parameters ``top_id`` and ``vpool`` **cannot** be specified *simultaneusly*. The default value of ``encoding`` is :attr:`Enctype.seqcounter`. The method *translates* the AtLeast constraint into an AtMost constraint by *negating* the literals of ``lits``, creating a new bound :math:`n-k` and invoking :meth:`CardEnc.atmost` with the modified list of literals and the new bound. :raises CardEnc.NoSuchEncodingError: if encoding does not exist. :rtype: a :class:`.CNFPlus` object where the new \ clauses (or the new native atmost constraint) are stored. """ 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 if not top_id: top_id = max(map(lambda x: abs(x), lits)) # Minicard's native representation is handled separately if encoding == 9: ret.atmosts, ret.nv = [([-l for l in lits], len(lits) - bound) ], top_id return ret # saving default SIGINT handler def_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_DFL) res = pycard.encode_atleast(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 # 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
def atleast(cls, lits, bound=1, top_id=None, encoding=EncType.seqcounter): """ This method can be used for creating a CNF encoding of an AtLeastK constraint, i.e. of :math:`\sum_{i=1}^{n}{x_i}\geq k`. The method takes 1 mandatory argument ``lits`` and 3 default arguments can be specified: ``bound``, ``top_id``, and ``encoding``. :param lits: a list of literals in the sum. :param bound: the value of bound :math:`k`. :param top_id: top variable identifier used so far. :param encoding: identifier of the encoding to use. :type lits: iterable(int) :type bound: int :type top_id: integer or None :type encoding: integer Parameter ``top_id`` serves to increase integer identifiers of auxiliary variables introduced during the encoding process. This is helpful when augmenting an existing CNF formula with the new cardinality encoding to make sure there is no collision between identifiers of the variables. If specified the identifiers of the first auxiliary variable will be ``top_id+1``. The default value of ``encoding`` is :attr:`Enctype.seqcounter`. The method *translates* the AtLeast constraint into an AtMost constraint by *negating* the literals of ``lits``, creating a new bound :math:`n-k` and invoking :meth:`CardEnc.atmost` with the modified list of literals and the new bound. :raises CardEnc.NoSuchEncodingError: if encoding does not exist. :rtype: a :class:`.CNFPlus` object where the new \ clauses (or the new native atmost constraint) are stored. """ if encoding < 0 or encoding > 9: raise (NoSuchEncodingError(encoding)) # we are going to return this formula ret = CNFPlus() # if the list of literals is empty, return empty formula if not lits: return ret if not top_id: top_id = max(map(lambda x: abs(x), lits)) # Minicard's native representation is handled separately if encoding == 9: ret.atmosts, ret.nv = [([-l for l in lits], len(lits) - bound) ], top_id return ret # saving default SIGINT handler def_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_DFL) res = pycard.encode_atleast(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