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
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