code wiki / _hdl_build / nx_nofloat_induction_gate.nx
nx_nofloat_induction_gate.nx source
↩ module page · 134 lines · 8091 B
1// nx_nofloat_induction_gate.nx -- CONTENT-BASED INDUCTION (CAP-NF-INDUCTION), REBUILT after the 3rd adversarial
2// review showed the old fixed-repeat-position version could be solved by a fixed-offset head (no content match).
3// FIX: the repeated "key" token now appears at a VARYING earlier position p; the target is its FOLLOWER S[p+1].
4// Context tokens 0..T-2 are DISTINCT (shuffled) so the key matches a unique earlier position. Because p varies,
5// a fixed-offset(-k) head and a fixed-absolute-position head BOTH score ~chance; the ONLY way to win is true
6// content-induction: at the last position, match the current token to its earlier occurrence BY CONTENT, then
7// copy what followed it. Every example fresh-random -> no memorization. 2-block attention (the induction circuit).
8// T1 induction acc (predict S[p+1]) >> chance(1/V) = content-induction works on unseen data.
9// T2 (teeth) acc > copy-back-1 rate (predict S[T-2]) = it is content-match, not a fixed offset.
10// HONEST: research-hard for a tiny fixed-point model; if it only ties chance/copy-back-1 it has NOT earned the
11// word and stays downgraded. The measured numbers are the evidence. Sovereign. expect_exit: 0
12import "nx_nofloat_autograd.nx"
13import "nx_syscalls.nx"
14import "nx_gate_emit_lib.nx"
15const Q16: i64 = 65536
16
17
18func dini(a: *i64, n: i64, sd: i64) -> i64 { var i: i64=0; while i<n { a[i]=(((i*7+sd*13+1)%11)-5)*13107; i=i+1 } return 0 }
19func lcg(st: *i64) -> i64 { st[0]=(st[0]*1103515245 + 12345) & 2147483647; return (st[0] >> 15) }
20// VARYING-position induction example. positions 0..T-2 = distinct shuffled tokens; key at random p in [0,T-3];
21// S[T-1]=S[p] (the repeat); tgt[T-1]=S[p+1] (its follower). pk[0]=p for eval.
22func make_ind(S: *i64, tgt: *i64, V: i64, T: i64, st: *i64, arr: *i64, pk: *i64) -> i64 {
23 var i: i64=0; while i<V { arr[i]=i; i=i+1 }
24 i=0
25 while i<T-1 { let j: i64=i + lcg(st)%(V-i); let t: i64=arr[i]; arr[i]=arr[j]; arr[j]=t; S[i]=arr[i]; i=i+1 } // distinct context
26 let p: i64 = lcg(st)%(T-2) // p in [0, T-3]
27 S[T-1]=S[p] // repeat the key at the end (varying earlier match)
28 i=0; while i<T-1 { tgt[i]=S[i+1]; i=i+1 }
29 tgt[T-1]=S[p+1] // the follower of the key's first occurrence
30 pk[0]=p
31 return 0
32}
33// 2-block attention-only forward. W=[E,Wlm,Wq0,Wk0,Wv0,Wo0,Wq1,Wk1,Wv1,Wo1]; leaves[0..9]=weights, leaves[10]=logits.
34func ind_fwd(tape: *i64, vals: *i64, st: *i64, W: *i64, ids: *i64, tgt: *i64, T: i64, dm: i64, V: i64, scale: i64, leaves: *i64) -> i64 {
35 let E: *i64=W[0] as *i64; let Wlm: *i64=W[1] as *i64
36 st[0]=0; st[1]=0
37 let nE: i64=nfa_leaf(tape,vals,st,V,dm,E,0)
38 let nWlm: i64=nfa_leaf(tape,vals,st,dm,V,Wlm,0)
39 leaves[0]=nE; leaves[1]=nWlm
40 var cur: i64=nfa_embed(tape,vals,st,nE,ids,T)
41 var bk: i64=0
42 while bk<2 {
43 let base: i64 = 2 + bk*4
44 let Wq: *i64=W[base+0] as *i64; let Wk: *i64=W[base+1] as *i64; let Wv: *i64=W[base+2] as *i64; let Wo: *i64=W[base+3] as *i64
45 let nWq: i64=nfa_leaf(tape,vals,st,dm,dm,Wq,0)
46 let nWk: i64=nfa_leaf(tape,vals,st,dm,dm,Wk,0)
47 let nWv: i64=nfa_leaf(tape,vals,st,dm,dm,Wv,0)
48 let nWo: i64=nfa_leaf(tape,vals,st,dm,dm,Wo,0)
49 leaves[base+0]=nWq; leaves[base+1]=nWk; leaves[base+2]=nWv; leaves[base+3]=nWo
50 let nXn: i64=nfa_rmsnorm_rows(tape,vals,st,cur)
51 let nQ: i64=nfa_matmul(tape,vals,st,nXn,nWq)
52 let nK: i64=nfa_matmul(tape,vals,st,nXn,nWk)
53 let nV: i64=nfa_matmul(tape,vals,st,nXn,nWv)
54 let nQr: i64=nfa_rope(tape,vals,st,nQ)
55 let nKr: i64=nfa_rope(tape,vals,st,nK)
56 let nS: i64=nfa_matmul_nt(tape,vals,st,nQr,nKr)
57 let nSs: i64=nfa_cmul(tape,vals,st,nS,scale)
58 let nA: i64=nfa_softmax_rows(tape,vals,st,nSs,1)
59 let nO: i64=nfa_matmul(tape,vals,st,nA,nV)
60 let nOp: i64=nfa_matmul(tape,vals,st,nO,nWo)
61 cur=nfa_vadd(tape,vals,st,cur,nOp)
62 bk=bk+1
63 }
64 let nYn: i64=nfa_rmsnorm_rows(tape,vals,st,cur)
65 let nLg: i64=nfa_matmul(tape,vals,st,nYn,nWlm)
66 let nLoss: i64=nfa_softce_rows(tape,vals,st,nLg,tgt)
67 leaves[10]=nLg
68 return nLoss
69}
70func step_all(tape: *i64, grads: *i64, W: *i64, WN: *i64, lnodes: *i64, nW: i64, lr: i64, clip: i64, gb: *i64) -> i64 {
71 var i: i64=0
72 while i<nW { let ar: *i64=W[i] as *i64; let cn: i64=WN[i]; let nd: i64=lnodes[i]; var c: i64=0; while c<cn { var g: i64=nfa_grad(tape,grads,nd,c); if g>clip{g=clip} if g<0-clip{g=0-clip} gb[c]=g; c=c+1 } nfa_sgd(ar,gb,cn,lr); i=i+1 }
73 return 0
74}
75
76func main() -> i64 {
77 g_puts("nx_nofloat_induction gate (REBUILT: VARYING repeat-position -> only content-match wins, not fixed-offset)\n" as *u8)
78 var pass: i64=0; var total: i64=0
79 let V: i64=6; let T: i64=6; let dm: i64=24; let scale: i64=13377
80 let tape: *i64 = sys_mmap(1024*7*8) as *i64
81 let vals: *i64 = sys_mmap(65536*8) as *i64
82 let grads: *i64 = sys_mmap(65536*8) as *i64
83 let st: *i64 = sys_mmap(2*8) as *i64
84 let nW: i64=10
85 let W: *i64 = sys_mmap(nW*8) as *i64
86 let WN: *i64 = sys_mmap(nW*8) as *i64
87 WN[0]=V*dm; WN[1]=dm*V; WN[2]=dm*dm; WN[3]=dm*dm; WN[4]=dm*dm; WN[5]=dm*dm; WN[6]=dm*dm; WN[7]=dm*dm; WN[8]=dm*dm; WN[9]=dm*dm
88 var wi: i64=0
89 while wi<nW { let a: *i64=sys_mmap(WN[wi]*8) as *i64; dini(a,WN[wi],wi+1); W[wi]=a as i64; wi=wi+1 }
90 let leaves: *i64 = sys_mmap(16*8) as *i64
91 let gbuf: *i64 = sys_mmap(4096*8) as *i64
92 let S: *i64 = sys_mmap(T*8) as *i64; let tgt: *i64 = sys_mmap(T*8) as *i64
93 let arr: *i64 = sys_mmap(V*8) as *i64; let pk: *i64 = sys_mmap(8) as *i64
94 let sdat: *i64 = sys_mmap(8) as *i64
95
96 sdat[0]=12345
97 var ep: i64=0
98 while ep < 50000 {
99 make_ind(S,tgt,V,T,sdat,arr,pk)
100 let nl: i64=ind_fwd(tape,vals,st,W,S,tgt,T,dm,V,scale,leaves)
101 nfa_backward(tape,vals,grads,st[0],nl)
102 step_all(tape,grads,W,WN,leaves,nW,4096,262144,gbuf)
103 ep=ep+1
104 }
105
106 // held-out eval: fresh examples; at last position count == S[p+1] (induction) and == S[T-2] (copy-back-1)
107 sdat[0]=777777
108 var nind: i64=0; var ncopy: i64=0; var nex: i64=300; var e: i64=0
109 while e<nex {
110 make_ind(S,tgt,V,T,sdat,arr,pk)
111 let nl: i64=ind_fwd(tape,vals,st,W,S,tgt,T,dm,V,scale,leaves)
112 let off: i64=tape[7*leaves[10]+5]
113 var b: i64=0; var bv: i64=vals[off+(T-1)*V]; var j: i64=1
114 while j<V { if vals[off+(T-1)*V+j]>bv { bv=vals[off+(T-1)*V+j]; b=j } j=j+1 }
115 if b==tgt[T-1] { nind=nind+1 }
116 if b==S[T-2] { ncopy=ncopy+1 }
117 e=e+1
118 }
119 g_puts(" [measure] held-out @last: content-induction(predict S[p+1])=" as *u8); g_pn(nind); g_puts("/" as *u8); g_pn(nex); g_puts(" copy-back-1(predict S[T-2])=" as *u8); g_pn(ncopy); g_puts("/" as *u8); g_pn(nex); g_puts(" (chance~" as *u8); g_pn(nex/V); g_puts(", repeat-pos VARIES so fixed-offset~chance)\n" as *u8)
120
121 var t1: i64=0; if nind*V >= nex*2 { t1=1 } // induction acc >= 2x chance
122 pass=pass+g_check("T1: CONTENT-based induction on unseen data (predict the follower S[p+1] >> chance)" as *u8, t1); total=total+1
123 var t2: i64=0; if nind > ncopy { t2=1 }
124 pass=pass+g_check("T2: content-match beats copy-back-1 (varying position => fixed-offset cannot win)" as *u8, t2); total=total+1
125
126 var okall: i64=0; if pass==total { okall=1 }
127 g_puts("---- induction gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8)
128 if okall==1 {
129 let logf: i64 = sys_openat_append("knowledge/status/nofloat_induction.log" as *u8, 420)
130 if logf >= 0 { let w0: i64=sys_write(logf,"NOFLOATINDUCTION varying-position content-induction GREEN\n" as *u8,57); sys_close(logf) }
131 g_puts("verdict=GREEN (EARNED content-based induction: matches by content + copies follower, varying repeat-position, unseen data)\n" as *u8); sys_exit(0); return 0
132 }
133 g_puts("verdict=RED (did not earn content-induction at this scale -- claim stays downgraded)\n" as *u8); sys_exit(1); return 1
134}