code wiki / _hdl_build / nx_cdcl_lib.nx

nx_cdcl_lib.nx source

↩ module page · 58 lines · 4213 B

1// nx_cdcl_lib.nx -- the REAL CDCL SAT solver as a SHARED LIBRARY (no main): var_of/lit_true/lit_false/solve, extracted 2// verbatim from the verified nx_cdcl_sat_gate so BOTH the gate AND the neurosymbolic dispatch loop call the SAME proven 3// code (DRY, rule 15). 1-UIP clause learning + non-chronological backjump + VSIDS. Integer, deterministic, NO LLM. 4// license_tier: ORIGINAL 5import "nx_syscalls.nx" 6const K_MAGIC_2048: i64 = 2048 7 8func var_of(lit: i64) -> i64 { if lit<0 { return 0-lit } return lit } 9func lit_true(lit: i64, val: *i64) -> i64 { let v: i64=var_of(lit); if val[v]==0 { return 0 } if lit>0 { if val[v]==1 { return 1 } return 0 } if val[v]==(0-1) { return 1 } return 0 } 10func lit_false(lit: i64, val: *i64) -> i64 { let v: i64=var_of(lit); if val[v]==0 { return 0 } if lit>0 { if val[v]==(0-1) { return 1 } return 0 } if val[v]==1 { return 1 } return 0 } 11 12// CDCL. lits/cstart/clen hold clauses (capacity for learned). returns 1=SAT (model in val), 0=UNSAT. lc_out[0]=#learned. 13func solve(NV: i64, nc0: i64, lits: *i64, cstart: *i64, clen: *i64, val: *i64, lc_out: *i64) -> i64 { 14 let lvl: *i64=sys_mmap(256) as *i64; let ante: *i64=sys_mmap(256) as *i64; let seen: *i64=sys_mmap(256) as *i64; let act: *i64=sys_mmap(256) as *i64 15 let trail: *i64=sys_mmap(K_MAGIC_2048) as *i64; let learnt: *i64=sys_mmap(256) as *i64 16 var v: i64=0; while v<=NV { val[v]=0; lvl[v]=0; ante[v]=0-1; seen[v]=0; act[v]=0; v=v+1 } 17 var nt: i64=0; var dl: i64=0; var nc: i64=nc0; var nlearned: i64=0; var lits_top: i64=cstart[nc0-1]+clen[nc0-1] 18 while 1==1 { 19 var conflict: i64=0-1; var changed: i64=1 20 while changed==1 { 21 changed=0; var c: i64=0 22 while c<nc { 23 var sat: i64=0; var nun: i64=0; var ulit: i64=0; var k: i64=cstart[c]; let ke: i64=cstart[c]+clen[c] 24 while k<ke { let L: i64=lits[k]; if lit_true(L,val)==1 { sat=1; k=ke } else { if lit_false(L,val)==0 { nun=nun+1; ulit=L } k=k+1 } } 25 if sat==0 { if nun==0 { conflict=c; c=nc } else { if nun==1 { let vv: i64=var_of(ulit); if ulit>0 { val[vv]=1 } else { val[vv]=0-1 } lvl[vv]=dl; ante[vv]=c; trail[nt]=ulit; nt=nt+1; changed=1 } c=c+1 } } else { c=c+1 } 26 } 27 if conflict>=0 { changed=0 } 28 } 29 if conflict>=0 { 30 if dl==0 { lc_out[0]=nlearned; return 0 } 31 v=0; while v<=NV { seen[v]=0; v=v+1 } 32 var nl: i64=0; var counter: i64=0; var btlevel: i64=0; var p: i64=0; var pivot: i64=0; var cc: i64=conflict; var idx: i64=nt-1; var done: i64=0 33 while done==0 { 34 var k: i64=cstart[cc]; let ke: i64=cstart[cc]+clen[cc] 35 while k<ke { 36 let q: i64=lits[k]; let qv: i64=var_of(q) 37 if qv!=pivot { if seen[qv]==0 { if lvl[qv]>0 { seen[qv]=1; act[qv]=act[qv]+1 38 if lvl[qv]==dl { counter=counter+1 } else { learnt[nl]=q; nl=nl+1; if lvl[qv]>btlevel { btlevel=lvl[qv] } } } } } 39 k=k+1 40 } 41 while seen[var_of(trail[idx])]==0 { idx=idx-1 } 42 p=trail[idx]; idx=idx-1; pivot=var_of(p); seen[pivot]=0; counter=counter-1 43 if counter==0 { learnt[nl]=0-p; nl=nl+1; done=1 } else { cc=ante[pivot] } 44 } 45 cstart[nc]=lits_top; clen[nc]=nl; var j: i64=0; while j<nl { lits[lits_top+j]=learnt[j]; j=j+1 } lits_top=lits_top+nl 46 let lc: i64=nc; nc=nc+1; nlearned=nlearned+1 47 var bjdone: i64=0 48 while bjdone==0 { if nt==0 { bjdone=1 } else { let topv: i64=var_of(trail[nt-1]); if lvl[topv]>btlevel { val[topv]=0; lvl[topv]=0; ante[topv]=0-1; nt=nt-1 } else { bjdone=1 } } } 49 dl=btlevel 50 let uip: i64=learnt[nl-1]; let uv: i64=var_of(uip); if uip>0 { val[uv]=1 } else { val[uv]=0-1 } lvl[uv]=dl; ante[uv]=lc; trail[nt]=uip; nt=nt+1 51 } else { 52 var dvar: i64=0; var ba: i64=0-1; v=1; while v<=NV { if val[v]==0 { if act[v]>ba { ba=act[v]; dvar=v } } v=v+1 } 53 if dvar==0 { lc_out[0]=nlearned; return 1 } 54 dl=dl+1; val[dvar]=1; lvl[dvar]=dl; ante[dvar]=0-1; trail[nt]=dvar; nt=nt+1 55 } 56 } 57 lc_out[0]=nlearned; return 0 58}