code wiki / _hdl_build / nx_work_predict_lib.nx

nx_work_predict_lib.nx source

↩ module page · 240 lines · 9238 B

1// nx_work_predict_lib.nx -- the FUTURE axis: GENEALOGY-grounded prediction of what work grows next. 2// Reads capability_ladder.tsv (itself COMPUTED from real deps+DONE status -- "NOT asserted", so it is 3// already a non-hallucinated source) and finds the ADJACENT-POSSIBLE frontier: a capability whose 4// status is not DONE but ALL of its prerequisites ARE DONE -- i.e. the parent just got built, so this 5// node is the next thing that can grow "out from god". Prediction as DATA, never prose from a model: 6// every prediction is a row whose deps are mechanically verified DONE, with the WHY = which 7// prerequisite unlocked it. (per author-by-organ-not-claude + no-wave-measured-exceed.) 8// 9// columns of capability_ladder.tsv: layer<TAB>id<TAB>status<TAB>grounding<TAB>deps (deps "-" or a,b,c) 10// REUSE (DRY): jx_find / jx_len from nx_json_lib. Sovereign. license_tier: ORIGINAL 11import "nx_syscalls.nx" 12import "nx_json_lib.nx" 13const WP_MAGIC_1024: i64 = 1024 14 15const WP_DONE: i64 = 0 // status already DONE -> not a prediction 16const WP_ADJACENT: i64 = 1 // not DONE, has real dep(s), ALL deps DONE -> probable-next (the gold) 17const WP_ROOT: i64 = 2 // not DONE, deps "-" -> foundational-available (no parent to grow from) 18const WP_BLOCKED: i64 = 3 // not DONE, some dep NOT DONE -> still blocked, not yet predictable 19 20const WP_MAXADJ: i64 = 1024 21const WP_IDCAP: i64 = 96 22const WP_DONECAP: i64 = 262144 23 24func wp_streq(a: *u8, b: *u8) -> i64 { 25 var i: i64 = 0 26 while i < 256 { 27 if a[i] != b[i] { return 0 } 28 if a[i] == (0 as u8) { return 1 } 29 i = i + 1 30 } 31 return 1 32} 33func wp_cat(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64 = off; var i: i64 = 0; while s[i] != (0 as u8) { dst[o] = s[i]; o = o + 1; i = i + 1 } return o } 34func wp_catn(dst: *u8, off: i64, v: i64) -> i64 { 35 var o: i64 = off; var m: i64 = v 36 if m == 0 { dst[o] = 48 as u8; return o + 1 } 37 if m < 0 { dst[o] = 45 as u8; o = o + 1; m = 0 - m } 38 let t: *u8 = sys_mmap(32); var k: i64 = 0 39 while m > 0 { t[k] = ((48 + (m % 10)) as u8); m = m / 10; k = k + 1 } 40 while k > 0 { dst[o] = t[k - 1]; o = o + 1; k = k - 1 } 41 return o 42} 43 44// is `id` present in doneset (a "\tID1\tID2\t...\t" tab-bounded buffer)? boundary tabs prevent the 45// X-B0-1 / X-B0-10 partial-match class. 46func wp_is_done(doneset: *u8, donelen: i64, id: *u8) -> i64 { 47 let needle: *u8 = sys_mmap(jx_len(id) + 4) 48 var o: i64 = 0 49 needle[o] = 9 as u8; o = o + 1 50 var i: i64 = 0 51 while id[i] != (0 as u8) { needle[o] = id[i]; o = o + 1; i = i + 1 } 52 needle[o] = 9 as u8; o = o + 1 53 needle[o] = 0 as u8 54 if jx_find(doneset, donelen, 0, needle) >= 0 { return 1 } 55 return 0 56} 57 58// classify a row from its status + deps (pure -- the gateable core). 59func wp_classify(status: *u8, deps: *u8, doneset: *u8, donelen: i64) -> i64 { 60 if wp_streq(status, "DONE" as *u8) == 1 { return WP_DONE } 61 if deps[0] == (45 as u8) { if deps[1] == (0 as u8) { return WP_ROOT } } // deps == "-" 62 let sub: *u8 = sys_mmap(256) 63 let n: i64 = jx_len(deps) 64 var i: i64 = 0 65 var so: i64 = 0 66 var alldone: i64 = 1 67 var anydep: i64 = 0 68 while i <= n { 69 let c: i64 = deps[i] as i64 // deps[n] == 0 (terminator) 70 var brk: i64 = 0 71 if c == 44 { brk = 1 } // ',' 72 if c == 0 { brk = 1 } 73 if brk == 1 { 74 if so > 0 { 75 sub[so] = 0 as u8 76 anydep = 1 77 if wp_is_done(doneset, donelen, sub) == 0 { alldone = 0 } 78 } 79 so = 0 80 } else { 81 if so < 255 { sub[so] = c as u8; so = so + 1 } 82 } 83 i = i + 1 84 } 85 if anydep == 0 { return WP_ROOT } 86 if alldone == 1 { return WP_ADJACENT } 87 return WP_BLOCKED 88} 89 90// copy field k (0-based, TAB-separated) of the line buf[ls..le) into out (NUL-term). returns length, 91// or -1 if the line has fewer than k+1 fields. 92func wp_field(buf: *u8, ls: i64, le: i64, k: i64, out: *u8, outcap: i64) -> i64 { 93 var fi: i64 = 0 94 var i: i64 = ls 95 var o: i64 = 0 96 while i < le { 97 let c: i64 = buf[i] as i64 98 if c == 9 { 99 if fi == k { out[o] = 0 as u8; return o } 100 fi = fi + 1 101 o = 0 102 } else { 103 if fi == k { if o < outcap - 1 { out[o] = c as u8; o = o + 1 } } 104 } 105 i = i + 1 106 } 107 out[o] = 0 as u8 108 if fi == k { return o } 109 return 0 - 1 110} 111func wp_atoi(s: *u8) -> i64 { 112 var v: i64 = 0; var i: i64 = 0 113 while s[i] != (0 as u8) { let c: i64 = s[i] as i64; if c >= 48 { if c <= 57 { v = v * 10 + (c - 48) } } i = i + 1 } 114 return v 115} 116 117// copy `deps` up to the first ',' (the first prerequisite -- used as the WHY) into out. 118func wp_first_dep(deps: *u8, out: *u8) -> i64 { 119 var k: i64 = 0 120 var stop: i64 = 0 121 while stop == 0 { 122 let c: i64 = deps[k] as i64 123 if c == 0 { stop = 1 } else { if c == 44 { stop = 1 } else { out[k] = c as u8; k = k + 1 } } 124 } 125 out[k] = 0 as u8 126 return k 127} 128 129// PASS 1: build the DONE-set buffer ("\tID\tID\t...\t") from every status==DONE row. 130func wp_build_doneset(buf: *u8, len: i64, ds: *u8, dscap: i64) -> i64 { 131 var dlen: i64 = 0 132 ds[dlen] = 9 as u8; dlen = dlen + 1 // leading tab boundary 133 let id: *u8 = sys_mmap(WP_IDCAP) 134 let st: *u8 = sys_mmap(64) 135 var ls: i64 = 0 136 while ls < len { 137 var le: i64 = ls 138 var d: i64 = 0 139 while d == 0 { if le >= len { d = 1 } else { if buf[le] == (10 as u8) { d = 1 } else { le = le + 1 } } } 140 if ls < le { if buf[ls] != (35 as u8) { // skip '#' comment lines 141 wp_field(buf, ls, le, 2, st, 64) 142 if wp_streq(st, "DONE" as *u8) == 1 { 143 wp_field(buf, ls, le, 1, id, WP_IDCAP) 144 var j: i64 = 0 145 while id[j] != (0 as u8) { if dlen < dscap - 2 { ds[dlen] = id[j]; dlen = dlen + 1 } j = j + 1 } 146 if dlen < dscap - 1 { ds[dlen] = 9 as u8; dlen = dlen + 1 } 147 } 148 } } 149 ls = le + 1 150 } 151 ds[dlen] = 0 as u8 152 return dlen 153} 154 155// PASS 2 + emit: collect ADJACENT rows, sort by layer ascending (the growth front nearest the root), 156// emit "id\t(layer L)\t<- dep DONE" lines into out. stats[0..4]=rows,done,adjacent,root,blocked. 157// returns the adjacent (probable-next) count. 158func wp_predict(buf: *u8, len: i64, out: *u8, outcap: i64, stats: *i64) -> i64 { 159 let ds: *u8 = sys_mmap(WP_DONECAP) 160 let dslen: i64 = wp_build_doneset(buf, len, ds, WP_DONECAP) 161 162 let layers: *i64 = sys_mmap(8 * WP_MAXADJ) as *i64 163 let idps: *i64 = sys_mmap(8 * WP_MAXADJ) as *i64 164 let depps: *i64 = sys_mmap(8 * WP_MAXADJ) as *i64 165 var nadj: i64 = 0 166 var nrows: i64 = 0 167 var ndone: i64 = 0 168 var nroot: i64 = 0 169 var nblock: i64 = 0 170 171 let st: *u8 = sys_mmap(64) 172 let dp: *u8 = sys_mmap(WP_MAGIC_1024) 173 var ls: i64 = 0 174 while ls < len { 175 var le: i64 = ls 176 var d: i64 = 0 177 while d == 0 { if le >= len { d = 1 } else { if buf[le] == (10 as u8) { d = 1 } else { le = le + 1 } } } 178 if ls < le { if buf[ls] != (35 as u8) { 179 nrows = nrows + 1 180 wp_field(buf, ls, le, 2, st, 64) 181 wp_field(buf, ls, le, 4, dp, WP_MAGIC_1024) 182 let cls: i64 = wp_classify(st, dp, ds, dslen) 183 if cls == WP_DONE { ndone = ndone + 1 } 184 if cls == WP_ROOT { nroot = nroot + 1 } 185 if cls == WP_BLOCKED { nblock = nblock + 1 } 186 if cls == WP_ADJACENT { 187 if nadj < WP_MAXADJ { 188 let lf: *u8 = sys_mmap(16) 189 wp_field(buf, ls, le, 0, lf, 16) 190 let idb: *u8 = sys_mmap(WP_IDCAP) 191 wp_field(buf, ls, le, 1, idb, WP_IDCAP) 192 let depb: *u8 = sys_mmap(WP_IDCAP) 193 wp_first_dep(dp, depb) 194 layers[nadj] = wp_atoi(lf) 195 idps[nadj] = idb as i64 196 depps[nadj] = depb as i64 197 nadj = nadj + 1 198 } 199 } 200 } } 201 ls = le + 1 202 } 203 204 // insertion sort by layer ascending (carry id + dep pointers). 205 var a: i64 = 1 206 while a < nadj { 207 let lv: i64 = layers[a] 208 let iv: i64 = idps[a] 209 let dv: i64 = depps[a] 210 var b: i64 = a - 1 211 var go: i64 = 1 212 while go == 1 { 213 if b < 0 { go = 0 } else { 214 if layers[b] > lv { layers[b + 1] = layers[b]; idps[b + 1] = idps[b]; depps[b + 1] = depps[b]; b = b - 1 } else { go = 0 } 215 } 216 } 217 layers[b + 1] = lv; idps[b + 1] = iv; depps[b + 1] = dv 218 a = a + 1 219 } 220 221 var o: i64 = 0 222 var i: i64 = 0 223 while i < nadj { 224 o = wp_cat(out, o, idps[i] as *u8) 225 o = wp_cat(out, o, "\t(layer " as *u8) 226 o = wp_catn(out, o, layers[i]) 227 o = wp_cat(out, o, ")\t<- " as *u8) 228 o = wp_cat(out, o, depps[i] as *u8) 229 o = wp_cat(out, o, " DONE\n" as *u8) 230 i = i + 1 231 } 232 out[o] = 0 as u8 233 234 stats[0] = nrows 235 stats[1] = ndone 236 stats[2] = nadj 237 stats[3] = nroot 238 stats[4] = nblock 239 return nadj 240}