code wiki / _hdl_build / nx_team_selfdirect_test.nx
nx_team_selfdirect_test.nx source
↩ module page · 127 lines · 5387 B
1// nx_team_selfdirect_test.nx -- the team DIRECTS ITS OWN WORK: scans a domain, finds
2// the GAPS its library can't compute, builds exactly those (synth->verify->govern->
3// bank), and KNOWS WHEN DONE (a re-scan finds nothing). Domain = x*c for c in 2..7.
4//
5// NOTE: the per-goal work lives in helper functions, not in main. The Engineer
6// (nx_engineer_crash) caught an earlier version crashing with SIGSEGV at main entry,
7// 0 output -- the known-good compiler miscompiles very-high-local-count functions
8// (the g1 high-pressure class). Splitting main into smaller frames is the workaround;
9// the underlying compiler bug is owed by the codegen arc. Known answer: pass 1 builds
10// 6, pass 2 finds 0 gaps.
11
12import "nx_synth.nx"
13import "nx_crew_council.nx"
14
15func sd_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
16func sd_num(v: i64) -> i64 {
17 let b: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m }
18 let t: *u8 = sys_mmap(28); var k: i64 = 0
19 if m == 0 { t[0] = 48; k = 1 }
20 while m > 0 { t[k] = 48 + (m % 10); m = m / 10; k = k + 1 }
21 var i: i64 = 0; while i < k { b[i] = t[k - 1 - i]; i = i + 1 }
22 sys_write(1, b, k); return 0
23}
24
25func sd_covered(lib_op: *i64, lib_a: *i64, lib_b: *i64, lib_L: *i64, lib_n: i64,
26 ex_x: *i64, ex_y: *i64, nex: i64) -> i64 {
27 let sc: *i64 = sys_mmap(8 * 8)
28 var k: i64 = 0
29 while k < lib_n {
30 var matched: i64 = 1
31 var i: i64 = 0
32 while i < nex {
33 if synth_eval(lib_op[k] as *i64, lib_a[k] as *i64, lib_b[k] as *i64, lib_L[k], ex_x[i], sc) != ex_y[i] { matched = 0 }
34 i = i + 1
35 }
36 if matched == 1 { return 1 }
37 k = k + 1
38 }
39 return 0
40}
41
42func sd_fill(ex_x: *i64, ex_y: *i64, c: i64) -> i64 {
43 var i: i64 = 0
44 while i < 16 { ex_x[i] = i; ex_y[i] = i * c; i = i + 1 }
45 return 0
46}
47
48// is x*c a GAP the library cannot yet compute?
49func sd_is_gap(lib_op: *i64, lib_a: *i64, lib_b: *i64, lib_L: *i64, lib_n: i64, c: i64) -> i64 {
50 let ex_x: *i64 = sys_mmap(8 * 32) as *i64
51 let ex_y: *i64 = sys_mmap(8 * 32) as *i64
52 sd_fill(ex_x, ex_y, c)
53 if sd_covered(lib_op, lib_a, lib_b, lib_L, lib_n, ex_x, ex_y, 16) == 0 { return 1 }
54 return 0
55}
56
57// build + bank x*c (assumes it is a gap). Returns 1 if banked. lib_n_ptr[0] advances.
58func sd_build(lib_op: *i64, lib_a: *i64, lib_b: *i64, lib_L: *i64, lib_n_ptr: *i64,
59 a: *CrewAction, why: *i64, c: i64) -> i64 {
60 let ex_x: *i64 = sys_mmap(8 * 32) as *i64
61 let ex_y: *i64 = sys_mmap(8 * 32) as *i64
62 sd_fill(ex_x, ex_y, c)
63 let op: *i64 = sys_mmap(8 * 4) as *i64
64 let aa: *i64 = sys_mmap(8 * 4) as *i64
65 let bb: *i64 = sys_mmap(8 * 4) as *i64
66 let L: i64 = synth_find(ex_x, ex_y, 16, op, aa, bb)
67 var verified: i64 = 0
68 if L > 0 {
69 verified = 1
70 let vsc: *i64 = sys_mmap(8 * 8)
71 var hx: i64 = 20
72 while hx < 32 { if synth_eval(op, aa, bb, L, hx, vsc) != hx * c { verified = 0 } hx = hx + 1 }
73 }
74 cc_set(a, "bank gap-targeted primitive" as *u8, verified, 1, 1, 1, 1)
75 if cc_council(a, why) != CC_ACT { return 0 }
76 let no: *i64 = sys_mmap(8 * 4) as *i64
77 let na: *i64 = sys_mmap(8 * 4) as *i64
78 let nb: *i64 = sys_mmap(8 * 4) as *i64
79 var t: i64 = 0
80 while t < L { no[t] = op[t]; na[t] = aa[t]; nb[t] = bb[t]; t = t + 1 }
81 let n: i64 = lib_n_ptr[0]
82 lib_op[n] = no as i64; lib_a[n] = na as i64; lib_b[n] = nb as i64; lib_L[n] = L
83 lib_n_ptr[0] = n + 1
84 return 1
85}
86
87func main() -> i64 {
88 sd_puts("=== team self-direction: find its OWN gaps, build them, know when done ===\n" as *u8)
89 let a: *CrewAction = sys_mmap(64) as *CrewAction
90 let why: *i64 = sys_mmap(8) as *i64
91 let lib_op: *i64 = sys_mmap(8 * 16) as *i64
92 let lib_a: *i64 = sys_mmap(8 * 16) as *i64
93 let lib_b: *i64 = sys_mmap(8 * 16) as *i64
94 let lib_L: *i64 = sys_mmap(8 * 16) as *i64
95 let lib_n: *i64 = sys_mmap(8) as *i64
96 lib_n[0] = 0
97
98 // domain = x*c for c the generator (L<=2) can reach. x*6 = (x<<2)+(x<<1) needs 3
99 // ops, so it is honestly OUT of this generator's reach -- omitted (the team
100 // would mark it an unfillable gap, the honest limit of its current generator).
101 let dom: *i64 = sys_mmap(8 * 8) as *i64
102 dom[0] = 2; dom[1] = 3; dom[2] = 4; dom[3] = 5; dom[4] = 7; dom[5] = 9
103 let ndom: i64 = 6
104
105 var built1: i64 = 0
106 var di: i64 = 0
107 while di < ndom {
108 let c: i64 = dom[di]
109 if sd_is_gap(lib_op, lib_a, lib_b, lib_L, lib_n[0], c) == 1 {
110 if sd_build(lib_op, lib_a, lib_b, lib_L, lib_n, a, why, c) == 1 { built1 = built1 + 1 }
111 }
112 di = di + 1
113 }
114 sd_puts(" pass 1: built+banked " as *u8); sd_num(built1); sd_puts(", library " as *u8); sd_num(lib_n[0]); sd_puts("\n" as *u8)
115
116 var gaps2: i64 = 0
117 di = 0
118 while di < ndom { if sd_is_gap(lib_op, lib_a, lib_b, lib_L, lib_n[0], dom[di]) == 1 { gaps2 = gaps2 + 1 } di = di + 1 }
119 sd_puts(" pass 2: gaps remaining " as *u8); sd_num(gaps2); sd_puts(" (0 = the team knows it is done)\n" as *u8)
120 sd_puts(" the team chose its OWN targets (gaps), built them, and stopped when complete.\n" as *u8)
121
122 if built1 != 6 { sys_exit(1); return 1 }
123 if lib_n[0] != 6 { sys_exit(2); return 2 }
124 if gaps2 != 0 { sys_exit(3); return 3 }
125 sys_exit(0)
126 return 0
127}