code wiki / _hdl_build / nx_mt_r1_gate.nx
nx_mt_r1_gate.nx source
↩ module page · 217 lines · 9285 B
1// nx_mt_r1_gate.nx -- GATE for MT-R1: SEQUENCES. Proves, by RUNNING, that the sovereign MT core
2// (nx_mt_core) translates multi-token SEQUENCES with a SHARED, position-independent learned
3// word-map -- and that the map GENERALIZES to HELD-OUT sentences it was never trained on. This
4// is the seq2seq plumbing + the no-overfit test harness the rest of the arc rides on; R0 proved
5// the single-token atom, R2 will add cross-token CONTEXT (reordering) via fnet_mix.
6//
7// Dictionary (EN->ES), target indices are a PERMUTATION (not identity): tgt_map=[2,0,5,1,3,4].
8// src EN: 0 hello 1 family 2 love 3 good 4 day 5 water
9// tgt ES: 0 familia 1 bueno 2 hola 3 dia 4 agua 5 amor
10//
11// TRAIN = 4 sentences x 3 tokens, arranged so EVERY word occurs EXACTLY TWICE (m=2) -> with
12// lr=1/8 the GD factor (1-2*lr*m)=0.5 is stable+monotone for all weights. HELD-OUT = 3 sentences
13// whose token TRIPLES never appear in training (novel combinations of the same vocab).
14//
15// FOUR GATES:
16// A LEARNS (train set): per-token acc == all-train-tokens, sum-loss < 1/1000, loss decreased.
17// B GENERALIZES (held-out): per-token acc == all-held-tokens on sentences NEVER trained ->
18// the shared map is compositional/position-independent, not a per-sentence memorization.
19// C BIT-EXACT: retrain from zero-init -> identical W bits.
20// D UNTRAINED FAILS (liar-kill): zero-epoch model scores < all-held-tokens on held-out.
21//
22// genealogy_id: rumelhart_1986_backprop (realized_in nx_autograd)
23// lineage_id: sovereign_neural_mt_r1_sequences_v1
24// license_tier: ORIGINAL
25import "nx_mt_core.nx" // mt_train / mt_argmax / mt_seq_acc (shared word-map model)
26import "nx_autograd.nx" // ag_constf + nx_f32 compares + AG_F32_* + nx_syscalls
27import "nx_syscalls.nx"
28import "nx_gate_verdict.nx"
29
30const MR_LOG: *u8 = "knowledge/status/mt_r1.log"
31const MR_S: i64 = 6
32const MR_T: i64 = 6
33const MR_L: i64 = 3 // sequence length
34
35const EN0: *u8 = "hello" as *u8
36const EN1: *u8 = "family" as *u8
37const EN2: *u8 = "love" as *u8
38const EN3: *u8 = "good" as *u8
39const EN4: *u8 = "day" as *u8
40const EN5: *u8 = "water" as *u8
41const ES0: *u8 = "familia" as *u8
42const ES1: *u8 = "bueno" as *u8
43const ES2: *u8 = "hola" as *u8
44const ES3: *u8 = "dia" as *u8
45const ES4: *u8 = "agua" as *u8
46const ES5: *u8 = "amor" as *u8
47const ESQ: *u8 = "?" as *u8
48
49func mr_en(i: i64) -> *u8 {
50 if i == 0 { return EN0 }
51 if i == 1 { return EN1 }
52 if i == 2 { return EN2 }
53 if i == 3 { return EN3 }
54 if i == 4 { return EN4 }
55 if i == 5 { return EN5 }
56 return ESQ
57}
58func mr_es(j: i64) -> *u8 {
59 if j == 0 { return ES0 }
60 if j == 1 { return ES1 }
61 if j == 2 { return ES2 }
62 if j == 3 { return ES3 }
63 if j == 4 { return ES4 }
64 if j == 5 { return ES5 }
65 return ESQ
66}
67
68func mr_w(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 }
69func mr_wn(fd: i64, v: i64) -> i64 {
70 let bb: *u8 = sys_mmap(28); var m: i64 = v
71 if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) }
72 let t: *u8 = sys_mmap(28); var k: i64 = 0
73 if m == 0 { t[0] = 48; k = 1 }
74 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
75 var i: i64 = 0
76 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
77 sys_write(fd, bb, k); return 0
78}
79func mr_f32_to_milli(v: i64) -> i64 {
80 var s: i64 = nx_f32_mul(v, nx_i32_to_f32(1000))
81 var neg: i64 = 0
82 if nx_f32_lt(s, AG_F32_ZERO) == 1 { neg = 1; s = nx_f32_neg(s) }
83 let half: i64 = ag_constf(1, 2)
84 var m: i64 = 0
85 var go: i64 = 1
86 while go == 1 {
87 let mid: i64 = nx_f32_add(nx_i32_to_f32(m), half)
88 if nx_f32_lt(mid, s) == 1 {
89 m = m + 1
90 if m >= 100000 { go = 0 }
91 } else { go = 0 }
92 }
93 if neg == 1 { return 0 - m }
94 return m
95}
96
97// print each held-out token as en->es (predicted by the trained, frozen W). Honest demo.
98func mr_demo(fd: i64, W: *i64, held_src: *i64, n_held: i64) -> i64 {
99 mr_w(fd, "MT-R1 held-out (never trained):" as *u8)
100 var k: i64 = 0
101 let n: i64 = n_held * MR_L
102 while k < n {
103 let s: i64 = held_src[k]
104 let pj: i64 = mt_argmax(W, MR_S, MR_T, s)
105 mr_w(fd, " " as *u8); mr_w(fd, mr_en(s)); mr_w(fd, "->" as *u8); mr_w(fd, mr_es(pj))
106 k = k + 1
107 }
108 mr_w(fd, "\n" as *u8)
109 return 0
110}
111
112func mr_emit(fd: i64, r: *i64) -> i64 {
113 mr_w(fd, "MTR1GATE authored=organ engine=scalar-tape-autograd-f32 task=sequence-translate-shared-wordmap" as *u8)
114 mr_w(fd, " | A_learns_pass=" as *u8); mr_wn(fd, r[0])
115 mr_w(fd, " train_acc=" as *u8); mr_wn(fd, r[1]); mr_w(fd, "/" as *u8); mr_wn(fd, r[2])
116 mr_w(fd, " loss_first_milli=" as *u8); mr_wn(fd, r[3]); mr_w(fd, " loss_last_milli=" as *u8); mr_wn(fd, r[4])
117 mr_w(fd, " | B_generalizes_pass=" as *u8); mr_wn(fd, r[5])
118 mr_w(fd, " heldout_acc=" as *u8); mr_wn(fd, r[6]); mr_w(fd, "/" as *u8); mr_wn(fd, r[7])
119 mr_w(fd, " | C_bitexact_pass=" as *u8); mr_wn(fd, r[8])
120 mr_w(fd, " | D_untrained_fails_pass=" as *u8); mr_wn(fd, r[9]); mr_w(fd, " untrained_heldout_acc=" as *u8); mr_wn(fd, r[10])
121 if r[11] == 1 { mr_w(fd, " verdict=GREEN\n" as *u8) } else { mr_w(fd, " verdict=RED\n" as *u8) }
122 return 0
123}
124
125func main() -> i64 {
126 var ok: i64 = 1
127 let NW: i64 = MR_T * MR_S
128
129 // word-map (permutation)
130 let tmap: *i64 = (sys_mmap(MR_S * 8)) as *i64
131 tmap[0] = 2; tmap[1] = 0; tmap[2] = 5; tmap[3] = 1; tmap[4] = 3; tmap[5] = 4
132
133 // TRAIN: 4 sentences x 3, every word exactly twice
134 let n_train: i64 = 4
135 let ntr: i64 = n_train * MR_L
136 let tr_src: *i64 = (sys_mmap(ntr * 8)) as *i64
137 tr_src[0] = 0; tr_src[1] = 1; tr_src[2] = 2
138 tr_src[3] = 3; tr_src[4] = 4; tr_src[5] = 5
139 tr_src[6] = 2; tr_src[7] = 3; tr_src[8] = 0
140 tr_src[9] = 5; tr_src[10] = 1; tr_src[11] = 4
141 let tr_tgt: *i64 = (sys_mmap(ntr * 8)) as *i64
142 var k: i64 = 0
143 while k < ntr { tr_tgt[k] = tmap[tr_src[k]]; k = k + 1 }
144
145 // HELD-OUT: 3 sentences x 3, triples never appear in training
146 let n_held: i64 = 3
147 let nhd: i64 = n_held * MR_L
148 let hd_src: *i64 = (sys_mmap(nhd * 8)) as *i64
149 hd_src[0] = 1; hd_src[1] = 2; hd_src[2] = 3
150 hd_src[3] = 4; hd_src[4] = 5; hd_src[5] = 0
151 hd_src[6] = 3; hd_src[7] = 0; hd_src[8] = 5
152 let hd_tgt: *i64 = (sys_mmap(nhd * 8)) as *i64
153 k = 0
154 while k < nhd { hd_tgt[k] = tmap[hd_src[k]]; k = k + 1 }
155
156 let lr: i64 = ag_constf(1, 8) // m_max=2 -> factor (1-2*lr*m)=0.5, stable
157
158 // ---------- Gate A: LEARNS the training set ----------
159 let W: *i64 = (sys_mmap(NW * 8)) as *i64
160 let lf: *i64 = (sys_mmap(8)) as *i64
161 let ll: *i64 = (sys_mmap(8)) as *i64
162 mt_train(W, MR_S, MR_T, tr_src, tr_tgt, n_train, MR_L, 300, lr, lf, ll)
163 let tr_acc: i64 = mt_seq_acc(W, MR_S, MR_T, tr_src, tr_tgt, n_train, MR_L)
164 var learns_pass: i64 = 1
165 if tr_acc != ntr { learns_pass = 0 }
166 if nx_f32_lt(*ll, ag_constf(1, 1000)) != 1 { learns_pass = 0 }
167 if nx_f32_lt(*ll, *lf) != 1 { learns_pass = 0 }
168 if learns_pass != 1 { ok = 0 }
169
170 // ---------- Gate B: GENERALIZES to held-out sentences ----------
171 let hd_acc: i64 = mt_seq_acc(W, MR_S, MR_T, hd_src, hd_tgt, n_held, MR_L)
172 var gen_pass: i64 = 1
173 if hd_acc != nhd { gen_pass = 0 }
174 if gen_pass != 1 { ok = 0 }
175
176 // ---------- Gate C: bit-exact reproducible ----------
177 let Wr: *i64 = (sys_mmap(NW * 8)) as *i64
178 let lfr: *i64 = (sys_mmap(8)) as *i64
179 let llr: *i64 = (sys_mmap(8)) as *i64
180 mt_train(Wr, MR_S, MR_T, tr_src, tr_tgt, n_train, MR_L, 300, lr, lfr, llr)
181 var bitexact_pass: i64 = 1
182 var c: i64 = 0
183 while c < NW { if Wr[c] != W[c] { bitexact_pass = 0 } c = c + 1 }
184 if bitexact_pass != 1 { ok = 0 }
185
186 // ---------- Gate D: untrained model FAILS held-out (liar-kill) ----------
187 let W0: *i64 = (sys_mmap(NW * 8)) as *i64
188 let lf0: *i64 = (sys_mmap(8)) as *i64
189 let ll0: *i64 = (sys_mmap(8)) as *i64
190 mt_train(W0, MR_S, MR_T, tr_src, tr_tgt, n_train, MR_L, 0, lr, lf0, ll0)
191 let hd_acc0: i64 = mt_seq_acc(W0, MR_S, MR_T, hd_src, hd_tgt, n_held, MR_L)
192 var untrained_fails_pass: i64 = 1
193 if hd_acc0 >= nhd { untrained_fails_pass = 0 }
194 if untrained_fails_pass != 1 { ok = 0 }
195
196 // ---------- emit ----------
197 let r: *i64 = (sys_mmap(12 * 8)) as *i64
198 r[0] = learns_pass; r[1] = tr_acc; r[2] = ntr
199 r[3] = mr_f32_to_milli(*lf); r[4] = mr_f32_to_milli(*ll)
200 r[5] = gen_pass; r[6] = hd_acc; r[7] = nhd
201 r[8] = bitexact_pass; r[9] = untrained_fails_pass; r[10] = hd_acc0
202 r[11] = ok
203 mr_emit(1, r)
204 mr_demo(1, W, hd_src, n_held)
205 let logf: i64 = sys_openat_append(MR_LOG, 420)
206 if logf >= 0 { mr_emit(logf, r); mr_demo(logf, W, hd_src, n_held); sys_close(logf) }
207
208 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
209 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
210 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
211 let ctr__dry: *i64 = gv_ctr()
212 ctr__dry[0] = ok
213 ctr__dry[1] = 1
214 let rc__dry: i64 = gv_verdict("MT-R1-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
215 sys_exit(rc__dry)
216 return rc__dry
217}