def test_Card(self): n = 11 p = 3 a = exprvars('a', n) c, s = Card(a, p+1) self.assertEqual("[dd[0], c[1], c[2], c[3]]", str(c)) s.append(~c[p]) for i in range(n+1): for v in combinations(a, i): g = s[:] vv = list(v) + [~x for x in a if x not in v] g = vv + g constraint = And(*g) point = constraint.satisfy_one() if i > p: self.assertTrue(point is None) else: self.assertFalse(point is None)
def search(n, d, s, u=0, epsilon=1/4, opt='d', solver='picosat', lprefix=None, wsize=0, task=None, nthreads=4): if wsize <= 0: wsize = n + wsize print("n:", n, "d:", d, "s:", s, "u:", u, "opt:", opt, "solver:", solver, "wsize:", wsize, "task:", task, "prefix:", lprefix, "nthreads:", nthreads, file=sys.stderr) if opt.startswith('h'): # Comparator variables g = variables(n, d) # Empty prefix c_prefix = [] # valid constraints c_valid = valid_depth1(g, n, d) # size constraints if s: ncard = s gcard = [g[k, i, j] for i in range(n) for j in range(i+1, n) for k in range(d)] c, c_size = Card(gcard, ncard + 1, prefix='g_') if len(c) > ncard: c_size += [~c[ncard]] else: c_size = [] c_sorts = halver(g, n, 0, d, epsilon) elif opt.startswith('e'): m = n//2 g = exprvars('g', d*m, m) c_valid = valid_ehalver(g, n, d) c_prefix = [g[i, m+i] for i in range(m)] d0 = 1 c_size = [] net = Network(to_ehalver(c_prefix, g, n, d0)) xlist = net.outputs(n, range(1<<n)) c_sorts = halver(g, n, d0, d, epsilon, xlist) elif opt.startswith('s1'): d = s g = variables(n, d) c_prefix = [] c_valid = valid_size1(g, n, d) c_size = [] c_sorts = sorts_backward_size(g, n, 0, d, [], u) elif opt.startswith('s'): d = s g = variables(n, d) if lprefix is None: lprefix = [[(0, 1)]] c_prefix = [g[k, i, j] if (i, j) in layer else ~g[k, i, j] for k, layer in enumerate(lprefix) for i in range(n-1) for j in range(i+1, n)] if n > 3: c_prefix.append(Or(g[1, 0, 2], g[1, 2, 3])) else: c_prefix = [g[k, i, j] if (i, j) in layer else ~g[k, i, j] for k, layer in enumerate(lprefix) for i in range(n-1) for j in range(i+1, n)] net = Network(lprefix) d0 = len(net) c_valid = valid_size(g, n, d0, d) c_size = [] inputs = net.not_sorted(n) inputs = [x for x in inputs if window_size(x, n) > 2 and window_size(x, n) <= wsize] xlist = net.outputs(n, inputs) print("d0:", d0, "len(xlist):", len(xlist), file=sys.stderr) c_sorts = sorts(g, n, d0, d, xlist) elif opt.startswith('d1'): g = variables(n, d) c_valid = valid_depth1(g, n, d) c_prefix = [] if s: c, c_size = Card([g[k, i, j] for i in range(0, n) for j in range(i+1, n) for k in range(d)], s+1, prefix='g_') c_size += [~c[s]] else: c_size = [] c_sorts = sorts_backward_depth(g, n, 0, d, None, u) else: # Comparator variables g = variables(n, d) # Prefix constraints if lprefix is None: lprefix = [[(i, n-i-1) for i in range(n//2)]] sprefix = sum(len(layer) for layer in lprefix) c_prefix = [g[k, i, j] if (i, j) in layer else ~g[k, i, j] for k, layer in enumerate(lprefix) for i in range(n-1) for j in range(i+1, n)] net = Network(lprefix) d0 = len(net) # valid constraints c_valid = valid_depth(g, n, d0, d, s) # size constraints if s: ncard = s - sprefix gcard = [g[k, i, j] for i in range(n) for j in range(i+1, n) for k in range(d0, d)] c, c_size = Card(gcard, ncard + 1, prefix='g_') if len(c) > ncard: c_size += [~c[ncard]] else: c_size = [] inputs = net.not_sorted(n) inputs = [x for x in inputs if window_size(x, n) > 2 and window_size(x, n) <= wsize] xlist = net.outputs(n, inputs) print("d0:", d0, "len(xlist):", len(xlist), file=sys.stderr) c_sorts = sorts(g, n, d0, d, xlist) print("c_valid: ", len(c_valid), elapsed_time(), file=sys.stderr) print("c_prefix: ", len(c_prefix), elapsed_time(), file=sys.stderr) print("c_size: ", len(c_size), elapsed_time(), file=sys.stderr) print("c_sorts: ", len(c_sorts), elapsed_time(), file=sys.stderr) clauses = c_valid + c_prefix + c_sorts + c_size constraint = And(*clauses) print("Is cnf?", constraint.is_cnf(), "Size: ", len(clauses), elapsed_time(), file=sys.stderr) while True: if solver == "picosat": point = constraint.satisfy_one() res = point is not None else: litmap, cnf = expr2dimacscnf(constraint) task = task if task is not None else int(time.monotonic()) dimacscnf = "dimacscnf_{}.txt".format(task) litmapcnf = "litmap_{}.txt".format(task) with open(dimacscnf, "wt") as fp: print(cnf, file=fp) with open(litmapcnf, "wt") as fp: print(litmap, file=fp) ofile = "output_{}_{}_{}_{}.txt".format(n, d, s, task) with open(ofile+".log", "wt") as out: if solver == "minisat": subprocess.call(["minisat", dimacscnf, ofile], stdout=out) elif solver == "glucose": subprocess.call(["../../glucose-syrup-4.1/simp/glucose_release", "-model", dimacscnf], stdout=out) elif solver == "glucose-syrup": subprocess.call(["../../glucose-syrup-4.1/parallel/glucose-syrup_release", "-nthreads={}".format(nthreads), "-model", dimacscnf, ofile], stdout=out) else: subprocess.call(["../../cryptominisat-5.0.1/cryptominisat5", "-t", str(nthreads), dimacscnf], stdout=out) if solver == "minisat": res, soln = dimacs.read(ofile, minisat=True) else: res, soln = dimacs.read(ofile+".log") point = ConjNormalForm.soln2point(soln, litmap) print("len(point): ", len(point) if point else None, elapsed_time(), file=sys.stderr) if res is None: return 'UNDETERMINED' elif not res: return 'UNSATISFIABLE' else: if opt.startswith('h'): net = Halver(to_network(point, g, n, d)) return net elif opt.startswith('e'): net = Halver(to_ehalver(point, g, n, d)) return net else: net = to_network(point, g, n, d) xnew = net.not_sorted(n, log=False) if len(xnew) == u or opt not in ['d', 's']: return net else: m = 16 print("Unsorted:", len(xnew), file=sys.stderr) new_clauses = sorts(g, n, d0, d, xnew[:m]) clauses += new_clauses constraint = And(*clauses)