def to_cnf(self, x_vars, cnf): d_vars = [[cnf.nv + 1 + j + (j * i) for j in range(self.out_dim)] for i in range(self.out_dim)] cnf.nv += self.out_dim**2 for j in range(self.out_dim): for i in range(self.out_dim): E_ij = np.ceil((self.b[i] - self.b[j] + np.sum(self.A[i]) - np.sum(self.A[j])) / 2) lits = [ x if (ai > 0 and aj < 0) else -x for (x, ai, aj) in zip(x_vars, self.A[i], self.A[j]) if not (np.sign(ai) == np.sign(aj)) ] ale = CardEnc.atleast(lits, np.ceil(E_ij / 2.0), cnf.nv, EncType.seqcounter) r = ale.nv # TODO: Check assumption that this is "r(n, D)" of AAAI paper cnf.extend(ale.clauses) cnf.append([-r, d_vars[i][j]]) cnf.append([r, -d_vars[i][j]]) return d_vars
def get_constraint(idpool: IDPool, id2varmap, constraint: tConstraint) -> CNFPlus: """ Generate formula for a given cardinality constraint""" validate_constraint(constraint) lits = [] for ta in constraint.tas: t1 = tuple((constraint.course_name, ta)) if t1 not in id2varmap.keys(): id1 = idpool.id(t1) id2varmap[t1] = id1 else: id1 = id2varmap[t1] lits.append(id1) if constraint.type == tCardType.GREATEROREQUALS: if (constraint.bound == 1): cnf = CNFPlus() cnf.append(lits) elif (constraint.bound > len(lits)): msg = "Num TAs available for constraint:" + constraint.con_str + "is more than the bound in the constraint. \ Changing the bound to " + str(len(lits)) + ".\n" print(msg, file=sys.stderr) constraint.bound = len(lits) cnf = CardEnc.atleast(lits, vpool=idpool, bound=constraint.bound) elif constraint.type == tCardType.LESSOREQUALS: cnf = CardEnc.atmost(lits, vpool=idpool, bound=constraint.bound) return cnf
def closest_string(bitarray_list, distance=4): """ Return if a bitarray exists of distance at most 'distance'. Use example: s1=bitarray('0010') s2=bitarray('0011') closest_string([s1,s2], distance=0) > False closest_string([s1,s2], distance=2) > True """ if distance < 0: raise ValueError('Distance must be positive integer') logging.info('\nCodifying SAT Solver...') length = max(len(bit_arr) for bit_arr in bitarray_list) solver = Solver(name='mcm') vpool = IDPool() local_list = bitarray_list.copy() logging.info(' -> Codifying: normalizing strings') for index, bitarr in enumerate(bitarray_list): aux = (length - len(bitarr)) * bitarray('0') local_list[index] = bitarr + aux logging.info(' -> Codifying: imposing distance condition') for index, word in enumerate(local_list): for pos in range(length): vpool.id(ut.xvar(index, pos)) for pos in range(length): vpool.id(ut.yvar(pos)) for index, word in enumerate(local_list): for pos in range(length): vpool.id(ut.zvar(index, pos)) for index, word in enumerate(local_list): for pos in range(length): for clause in ut.triple_equal(ut.xvar(index, pos), ut.yvar(pos), ut.zvar(index, pos), vpool=vpool): solver.add_clause(clause) cnf = CardEnc.atleast( lits=[vpool.id(ut.zvar(index, pos)) for pos in range(length)], bound=length - distance, vpool=vpool) solver.append_formula(cnf) logging.info(' -> Codifying: Words Value') assumptions = [] for index, word in enumerate(local_list): for pos in range(length): assumptions += [ vpool.id(ut.xvar(index, pos)) * (-1)**(not word[pos]) ] logging.info('Running SAT Solver...') return solver.solve(assumptions=assumptions)