"""Driver for the exhaustive C oracle (brute_force.c): for a given n, k, finds Z(P(n,k)) by increasing cardinality s, in parallel over the lowest vertex id m0 (2n independent jobs per s), with orbit reduction under D_n (P3). Also contains a pure-Python reference enumeration (no symmetry reduction) used to cross-validate the C program on tiny cases (P(5,2) and P(11,5) at s <= 5). Output: results/brute_force_runs.jsonl (one record per (n,k,s)) and the value table results/brute_force_values.json. """ import itertools import json import os import subprocess import sys import time from concurrent.futures import ThreadPoolExecutor import common from closure_oracle import closure_fast from graph_constructor import adjacency_masks, edge_list_sha256, edges_formula BIN = os.path.join(common.ROOT, "code", "brute_force") def build_binary(): src = os.path.join(common.ROOT, "code", "brute_force.c") if not os.path.exists(BIN) or os.path.getmtime(BIN) < os.path.getmtime(src): subprocess.run(["gcc", "-O2", "-o", BIN, src], check=True) def run_one(n, k, s, m0): out = subprocess.run([BIN, str(n), str(k), str(s), str(m0)], capture_output=True, text=True, check=True).stdout d = {} for tok in out.split(): key, _, val = tok.partition("=") d[key] = val return d def count_size(n, k, s, workers=16): """Enumerates all s-subsets (split over m0). Returns (enumerated, tested, forcing, witness or None, wall).""" t0 = time.time() with ThreadPoolExecutor(max_workers=workers) as ex: parts = list(ex.map(lambda m0: run_one(n, k, s, m0), range(2 * n))) enumerated = sum(int(p["enumerated"]) for p in parts) tested = sum(int(p["tested"]) for p in parts) forcing = sum(int(p["forcing"]) for p in parts) witness = next((p["witness"] for p in parts if "witness" in p), None) return enumerated, tested, forcing, witness, time.time() - t0 def python_reference(n, k, s): """No symmetry reduction: counts all forcing s-subsets (for tiny cases only).""" adj = adjacency_masks(n, k) N = 2 * n full = (1 << N) - 1 cnt = 0 for comb in itertools.combinations(range(N), s): m = 0 for w in comb: m |= 1 << w if closure_fast(adj, m) == full: cnt += 1 return cnt def find_Z(n, k, s_start=1, s_max=12, time_limit=1800, workers=16): """Returns (Z or None, records). Each size s < Z is exhausted (forcing == 0).""" records = [] t_total = time.time() for s in range(s_start, s_max + 1): if time.time() - t_total > time_limit: return None, records if s >= 12 and n >= 12: # Z <= 12 by the explicit construction P7 (replayed in verify_upper_bounds.py); # all sizes <= 11 have been exhausted above, so Z = 12 without enumerating 12-sets. rec = {"n": n, "k": k, "s": s, "enumerated_subsets": 0, "orbit_representatives_tested": 0, "forcing_representatives": 1, "witness": ",".join("u%d" % i for i in range(12)), "witness_source": "P7 construction (not enumerated)", "wall_seconds": 0.0, "utc": common.utcnow(), "graph_sha256": edge_list_sha256(edges_formula(n, k))} records.append(rec) common.append_jsonl(os.path.join(common.RESULTS, "brute_force_runs.jsonl"), rec) return s, records enumerated, tested, forcing, witness, wall = count_size(n, k, s, workers) rec = {"n": n, "k": k, "s": s, "enumerated_subsets": enumerated, "orbit_representatives_tested": tested, "forcing_representatives": forcing, "witness": witness, "wall_seconds": round(wall, 3), "utc": common.utcnow(), "graph_sha256": edge_list_sha256(edges_formula(n, k))} records.append(rec) common.append_jsonl(os.path.join(common.RESULTS, "brute_force_runs.jsonl"), rec) print(json.dumps(rec), flush=True) if forcing: return s, records return None, records if __name__ == "__main__": build_binary() # cross-validation of the C oracle against the Python reference on tiny cases checks = [] for (n, k, s) in [(5, 2, 4), (5, 2, 5), (11, 5, 5)]: ref = python_reference(n, k, s) enumerated, tested, forcing, witness, wall = count_size(n, k, s) # orbit reduction: forcing representatives > 0 iff reference count > 0 checks.append({"n": n, "k": k, "s": s, "python_forcing_subsets": ref, "c_forcing_representatives": forcing, "agree": (ref > 0) == (forcing > 0)}) print(checks[-1]) assert all(c["agree"] for c in checks) with open(os.path.join(common.RESULTS, "brute_force_crosscheck.json"), "w") as f: json.dump(checks, f, indent=1) ns = [int(a) for a in sys.argv[1:]] or [11, 12, 13, 14] k = 5 values = {} if os.path.exists(os.path.join(common.RESULTS, "brute_force_values.json")): values = json.load(open(os.path.join(common.RESULTS, "brute_force_values.json"))) for n in ns: Z, recs = find_Z(n, k, s_start=max(1, (4 if n >= 11 else 1)), time_limit=float(os.environ.get("BF_TIME_LIMIT", "1800"))) values[str(n)] = {"Z": Z, "sizes_exhausted": [r["s"] for r in recs if r["forcing_representatives"] == 0], "witness": recs[-1]["witness"] if recs and recs[-1]["forcing_representatives"] else None, "total_wall_seconds": round(sum(r["wall_seconds"] for r in recs), 3)} print("n=%d Z=%s" % (n, Z), flush=True) with open(os.path.join(common.RESULTS, "brute_force_values.json"), "w") as f: json.dump(values, f, indent=1)