code wiki / (root) / nx_lbclimb_lib.nx

nx_lbclimb_lib.nx source

↩ module page · 320 lines · 15276 B

1// nx_lbclimb_lib.nx -- THE ONE climb ruler (search R0d, ecosystem EC62, 2026-09-17): does a board's DECLARED ladder 2// reach the leader of the public leaderboard it names, and which rank does each declared gate reach? 3// 4// WHY. The operator asked "what ladder do we need to climb to beat rank 1" and a seat answered by hand, staging the 5// rungs with accept numbers NO rung had pre-declared. The estate already held every input as DATA -- the leaderboard 6// rows (<dom>.leaderboard, nx_leaderboard_lib) and the dated targets and rung roles (<dom>.plan, nx_ladder_lib) -- and 7// lacked only the JOIN and one datum: the score each contender rung must reach on the board. This lib is that join. 8// climbboard|<board>|<sotatarget id>|<note> which leaderboard board measures which target 9// climbgate|<rung>|<board>|<floor>|<basis> the rung's accept floor on that board: a score (22.9), a single 10// dash (declared UNMEASURED) or the word leader (strictly above the 11// leader of the day, so the gate moves when the public board does) 12// The floor is never the last field, so a CRLF-terminated row parses (the trailing CR lands in the prose). 13// POPULATION: the rungs whose rungrole row says contender toward the board's target. PARTITION (the CLI prints it): 14// contenders = gated + ungated + nogate + badfloor. A climbgate row naming a rung outside that population is a STRAY: 15// counted, never voting (a gate planted on a substrate rung cannot make a ladder reach). 16// VERDICT: REACHES when at least one gated contender's floor is strictly above the leader; SHORT when numeric gates 17// exist and none clears the leader; NOGATES when no contender carries a numeric gate; NOBOARD when the leaderboard 18// holds no rival row for the board; BADTARGET when the climbboard row names no declared sotatarget. SHORT is the 19// forcing verdict: the declared ladder cannot reach the target whatever ships, so the board owes a rung whose gate does. 20// Pure over two buffers (plan, leaderboard): the gate drives it in-process; the CLI, the goal mapper and the emitter 21// compose it and never re-derive it. 22// license_tier: ORIGINAL. No hw writes (Rule 26). 23import "nx_syscalls.nx" 24import "nx_barfresh_lib.nx" 25import "nx_ladder_lib.nx" 26import "nx_leaderboard_lib.nx" 27 28const LBC_BOARD_TAG: *u8 = "climbboard|" 29const LBC_GATE_TAG: *u8 = "climbgate|" 30const LBC_F_B_BOARD: i64 = 1 31const LBC_F_B_TARGET: i64 = 2 32const LBC_F_G_RUNG: i64 = 1 33const LBC_F_G_BOARD: i64 = 2 34const LBC_F_G_FLOOR: i64 = 3 35const LBC_F_G_BASIS: i64 = 4 36const LBC_FLOOR_UNGATED: *u8 = "-" 37const LBC_FLOOR_LEADER: *u8 = "leader" 38const LBC_LEADER_STEP: i64 = 1 // one tenth of a point above the leader, in the x10 scale the boards print 39// per-contender states 40const LBC_S_GATED: i64 = 0 41const LBC_S_UNGATED: i64 = 1 // a climbgate row whose floor is the dash: declared unmeasured 42const LBC_S_NOGATE: i64 = 2 // no climbgate row for this board at all 43const LBC_S_BADFLOOR: i64 = 3 // a floor that is neither a score, the dash nor the word leader 44// verdicts 45const LBC_V_REACHES: i64 = 0 46const LBC_V_SHORT: i64 = 1 47const LBC_V_NOGATES: i64 = 3 48const LBC_V_NOBOARD: i64 = 4 49const LBC_V_BADTARGET: i64 = 5 50// exits the CLI maps the verdicts onto 51const LBC_EXIT_REACHES: i64 = 0 52const LBC_EXIT_SHORT: i64 = 1 53const LBC_EXIT_ABSTAIN: i64 = 3 54// the per-contender record handed back to the caller (stride LBC_KF) 55const LBC_KF: i64 = 5 56const LBC_K_ROFF: i64 = 0 // line start of the rung row 57const LBC_K_STATE: i64 = 1 58const LBC_K_FLOOR: i64 = 2 // floor x10, LBC_NONE when not gated 59const LBC_K_REACH: i64 = 3 // the rank the floor reaches, LBC_NONE when not gated 60const LBC_K_GATE: i64 = 4 // line start of the deciding climbgate row, LBC_NONE when there is none 61// the per-board record of lbc_boards (stride LBC_BF) 62const LBC_BF: i64 = 5 63const LBC_B_LINE: i64 = 0 64const LBC_B_NAMEOFF: i64 = 1 65const LBC_B_NAMELEN: i64 = 2 66const LBC_B_TGTOFF: i64 = 3 67const LBC_B_TGTLEN: i64 = 4 68// census slots 69const LBC_N_CONTENDERS: i64 = 0 70const LBC_N_GATED: i64 = 1 71const LBC_N_UNGATED: i64 = 2 72const LBC_N_NOGATE: i64 = 3 73const LBC_N_BADFLOOR: i64 = 4 74const LBC_N_STRAY: i64 = 5 // climbgate rows for this board naming a rung outside the contender population 75const LBC_N_DUPGATE: i64 = 6 // further climbgate rows for a (rung, board) pair an earlier row already gated 76const LBC_N_LEADER_X10: i64 = 7 77const LBC_N_ESTATE_X10: i64 = 8 78const LBC_N_ESTATE_RANK: i64 = 9 79const LBC_N_RIVALS: i64 = 10 80const LBC_N_BEST_FLOOR_X10: i64 = 11 81const LBC_N_BEST_REACH: i64 = 12 82const LBC_N_REACHERS: i64 = 13 // gated contenders whose floor is strictly above the leader 83const LBC_N_MOVERS: i64 = 14 // gated contenders whose floor reaches a better rank than the estate holds 84const LBC_N_DYNAMIC: i64 = 15 // gates spelled with the word leader 85const LBC_N_COUNT: i64 = 16 86const LBC_NONE: i64 = 0 - 1 87const LBC_I64: i64 = 8 88const LBC_NAME_CAP: i64 = 128 89 90// copy a span into a NUL-terminated name buffer (the leaderboard lib takes the board as a C string) 91func lbc_span_z(buf: *u8, off: i64, len: i64, dst: *u8) -> i64 { 92 var n: i64 = len 93 if n < 0 { n = 0 } 94 if n > LBC_NAME_CAP - 1 { n = LBC_NAME_CAP - 1 } 95 var i: i64 = 0 96 while i < n { dst[i] = buf[off + i]; i = i + 1 } 97 dst[n] = 0 as u8 98 return n 99} 100 101// the climbboard rows of a plan, in file order: records of stride LBC_BF; returns how many were written (at most cap) 102func lbc_boards(pbuf: *u8, pn: i64, b: *i64, cap: i64) -> i64 { 103 let fo: *i64 = sys_mmap(LBC_I64) as *i64 104 var nb: i64 = 0 105 var p: i64 = 0 106 while p < pn { 107 let e: i64 = bf_line_end(pbuf, pn, p) 108 if bf_line_starts(pbuf, p, e, LBC_BOARD_TAG) == 1 { 109 if nb < cap { 110 let nl: i64 = bf_field(pbuf, p, e, LBC_F_B_BOARD, fo) 111 let no: i64 = fo[0] 112 let tl: i64 = bf_field(pbuf, p, e, LBC_F_B_TARGET, fo) 113 let to: i64 = fo[0] 114 if nl > 0 { 115 b[nb * LBC_BF + LBC_B_LINE] = p 116 b[nb * LBC_BF + LBC_B_NAMEOFF] = no 117 b[nb * LBC_BF + LBC_B_NAMELEN] = nl 118 b[nb * LBC_BF + LBC_B_TGTOFF] = to 119 b[nb * LBC_BF + LBC_B_TGTLEN] = tl 120 nb = nb + 1 121 } 122 } 123 } 124 p = e + 1 125 } 126 return nb 127} 128 129// the FIRST climbgate row for this board that names the rung whose id is the span [ridoff, ridoff+ridlen) of the plan; 130// returns its line start or LBC_NONE; dups[0] receives how many FURTHER rows name the same pair (they never vote) 131func lbc_gate_find(pbuf: *u8, pn: i64, board: *u8, ridoff: i64, ridlen: i64, dups: *i64) -> i64 { 132 let fo: *i64 = sys_mmap(LBC_I64) as *i64 133 var found: i64 = LBC_NONE 134 dups[0] = 0 135 var p: i64 = 0 136 while p < pn { 137 let e: i64 = bf_line_end(pbuf, pn, p) 138 if bf_line_starts(pbuf, p, e, LBC_GATE_TAG) == 1 { 139 let bl: i64 = bf_field(pbuf, p, e, LBC_F_G_BOARD, fo) 140 var mine: i64 = 0 141 if bl > 0 { mine = ld_span_is(pbuf, fo[0], bl, board) } 142 if mine == 1 { 143 let rl: i64 = bf_field(pbuf, p, e, LBC_F_G_RUNG, fo) 144 if rl > 0 { if bf_span_eq(pbuf, fo[0], rl, ridoff, ridlen) == 1 { 145 if found == LBC_NONE { found = p } else { dups[0] = dups[0] + 1 } 146 } } 147 } 148 } 149 p = e + 1 150 } 151 return found 152} 153 154// THE JOIN. k receives one record per contender (stride LBC_KF, in plan order; the caller sizes it from the plan's rung 155// row count), c the census. Returns the verdict. 156func lbc_climb(pbuf: *u8, pn: i64, lbuf: *u8, ln: i64, board: *u8, tgtoff: i64, tgtlen: i64, k: *i64, c: *i64) -> i64 { 157 var z: i64 = 0 158 while z < LBC_N_COUNT { c[z] = 0; z = z + 1 } 159 c[LBC_N_LEADER_X10] = LBC_NONE 160 c[LBC_N_ESTATE_X10] = LBC_NONE 161 c[LBC_N_ESTATE_RANK] = LBC_NONE 162 c[LBC_N_BEST_FLOOR_X10] = LBC_NONE 163 c[LBC_N_BEST_REACH] = LBC_NONE 164 let nt: i64 = bf_count_rows(pbuf, pn, LD_TARGET_TAG) 165 let nrmax: i64 = bf_count_rows(pbuf, pn, LD_RUNG_TAG) 166 let toff: *i64 = sys_mmap((nt + 1) * LBC_I64) as *i64 167 let tcls: *i64 = sys_mmap((nt + 1) * LBC_I64) as *i64 168 let tst: *i64 = sys_mmap((nt + 1) * LBC_I64) as *i64 169 let roff: *i64 = sys_mmap((nrmax + 1) * LBC_I64) as *i64 170 let rrole: *i64 = sys_mmap((nrmax + 1) * LBC_I64) as *i64 171 let rtgt: *i64 = sys_mmap((nrmax + 1) * LBC_I64) as *i64 172 let rst: *i64 = sys_mmap((nrmax + 1) * LBC_I64) as *i64 173 let ldc: *i64 = sys_mmap(LD_N_COUNT * LBC_I64) as *i64 174 let nr: i64 = ld_classify(pbuf, pn, toff, tcls, tst, roff, rrole, rtgt, rst, ldc) 175 let fo: *i64 = sys_mmap(LBC_I64) as *i64 176 // the board's target, by id 177 var ti: i64 = LBC_NONE 178 var t: i64 = 0 179 while t < nt { 180 let te: i64 = bf_line_end(pbuf, pn, toff[t]) 181 let il: i64 = bf_field(pbuf, toff[t], te, LD_F_T_ID, fo) 182 if il > 0 { if ti == LBC_NONE { if tgtlen > 0 { if bf_span_eq(pbuf, fo[0], il, tgtoff, tgtlen) == 1 { ti = t } } } } 183 t = t + 1 184 } 185 if ti == LBC_NONE { return LBC_V_BADTARGET } 186 // the public board: rivals, leader, the estate's own latest row and the rank it holds 187 let heads: *i64 = sys_mmap(LBC_I64) as *i64 188 let rivals: *i64 = sys_mmap(LBC_I64) as *i64 189 let est: *i64 = sys_mmap(LBC_I64) as *i64 190 heads[0] = 0 191 rivals[0] = 0 192 est[0] = 0 193 lb_count(lbuf, ln, board, heads, rivals, est) 194 c[LBC_N_RIVALS] = rivals[0] 195 if rivals[0] <= 0 { return LBC_V_NOBOARD } 196 let leader: i64 = lb_leader(lbuf, ln, board) 197 c[LBC_N_LEADER_X10] = leader 198 let ero: *i64 = sys_mmap(LBC_I64) as *i64 199 let erl: *i64 = sys_mmap(LBC_I64) as *i64 200 let estate: i64 = lb_estate_latest(lbuf, ln, board, ero, erl) 201 c[LBC_N_ESTATE_X10] = estate 202 var erank: i64 = rivals[0] + 1 203 if estate != LB_NONE { erank = lb_rank_of(lbuf, ln, board, estate) } 204 c[LBC_N_ESTATE_RANK] = erank 205 // the contenders toward the target, each with the first gate that names it on this board 206 let dups: *i64 = sys_mmap(LBC_I64) as *i64 207 var nk: i64 = 0 208 var i: i64 = 0 209 while i < nr { 210 var isc: i64 = 0 211 if rrole[i] == LD_R_CONTENDER { if rtgt[i] == ti { isc = 1 } } 212 if isc == 1 { 213 let re: i64 = bf_line_end(pbuf, pn, roff[i]) 214 let idl: i64 = bf_field(pbuf, roff[i], re, LD_F_R_ID, fo) 215 let ido: i64 = fo[0] 216 var st: i64 = LBC_S_NOGATE 217 var fl: i64 = LBC_NONE 218 var rc: i64 = LBC_NONE 219 var gp: i64 = LBC_NONE 220 if idl > 0 { 221 gp = lbc_gate_find(pbuf, pn, board, ido, idl, dups) 222 c[LBC_N_DUPGATE] = c[LBC_N_DUPGATE] + dups[0] 223 } 224 if gp != LBC_NONE { 225 let ge: i64 = bf_line_end(pbuf, pn, gp) 226 let fll: i64 = bf_field(pbuf, gp, ge, LBC_F_G_FLOOR, fo) 227 st = LBC_S_BADFLOOR 228 if fll > 0 { 229 if ld_span_is(pbuf, fo[0], fll, LBC_FLOOR_UNGATED) == 1 { st = LBC_S_UNGATED } else { 230 if ld_span_is(pbuf, fo[0], fll, LBC_FLOOR_LEADER) == 1 { 231 st = LBC_S_GATED 232 fl = leader + LBC_LEADER_STEP 233 c[LBC_N_DYNAMIC] = c[LBC_N_DYNAMIC] + 1 234 } else { 235 let sv: i64 = lb_score_x10((pbuf as i64 + fo[0]) as *u8, fll) 236 if sv != LB_NONE { st = LBC_S_GATED; fl = sv } 237 } 238 } 239 } 240 } 241 if st == LBC_S_GATED { 242 rc = lb_rank_of(lbuf, ln, board, fl) 243 c[LBC_N_GATED] = c[LBC_N_GATED] + 1 244 if fl > leader { c[LBC_N_REACHERS] = c[LBC_N_REACHERS] + 1 } 245 if rc < erank { c[LBC_N_MOVERS] = c[LBC_N_MOVERS] + 1 } 246 if fl > c[LBC_N_BEST_FLOOR_X10] { c[LBC_N_BEST_FLOOR_X10] = fl; c[LBC_N_BEST_REACH] = rc } 247 } 248 if st == LBC_S_UNGATED { c[LBC_N_UNGATED] = c[LBC_N_UNGATED] + 1 } 249 if st == LBC_S_NOGATE { c[LBC_N_NOGATE] = c[LBC_N_NOGATE] + 1 } 250 if st == LBC_S_BADFLOOR { c[LBC_N_BADFLOOR] = c[LBC_N_BADFLOOR] + 1 } 251 k[nk * LBC_KF + LBC_K_ROFF] = roff[i] 252 k[nk * LBC_KF + LBC_K_STATE] = st 253 k[nk * LBC_KF + LBC_K_FLOOR] = fl 254 k[nk * LBC_KF + LBC_K_REACH] = rc 255 k[nk * LBC_KF + LBC_K_GATE] = gp 256 nk = nk + 1 257 } 258 i = i + 1 259 } 260 c[LBC_N_CONTENDERS] = nk 261 // strays: climbgate rows for this board whose rung is not one of the contenders above 262 var p: i64 = 0 263 while p < pn { 264 let e: i64 = bf_line_end(pbuf, pn, p) 265 if bf_line_starts(pbuf, p, e, LBC_GATE_TAG) == 1 { 266 let bl: i64 = bf_field(pbuf, p, e, LBC_F_G_BOARD, fo) 267 var mine: i64 = 0 268 if bl > 0 { mine = ld_span_is(pbuf, fo[0], bl, board) } 269 if mine == 1 { 270 let rl: i64 = bf_field(pbuf, p, e, LBC_F_G_RUNG, fo) 271 let ro: i64 = fo[0] 272 var hit: i64 = 0 273 var q: i64 = 0 274 while q < nk { 275 let kro: i64 = k[q * LBC_KF + LBC_K_ROFF] 276 let kre: i64 = bf_line_end(pbuf, pn, kro) 277 let kil: i64 = bf_field(pbuf, kro, kre, LD_F_R_ID, fo) 278 if kil > 0 { if rl > 0 { if bf_span_eq(pbuf, fo[0], kil, ro, rl) == 1 { hit = 1 } } } 279 q = q + 1 280 } 281 if hit == 0 { c[LBC_N_STRAY] = c[LBC_N_STRAY] + 1 } 282 } 283 } 284 p = e + 1 285 } 286 if c[LBC_N_GATED] == 0 { return LBC_V_NOGATES } 287 if c[LBC_N_REACHERS] > 0 { return LBC_V_REACHES } 288 return LBC_V_SHORT 289} 290 291// the partition the CLI prints beside the population: it must equal c[LBC_N_CONTENDERS] 292func lbc_partition_sum(c: *i64) -> i64 { 293 return c[LBC_N_GATED] + c[LBC_N_UNGATED] + c[LBC_N_NOGATE] + c[LBC_N_BADFLOOR] 294} 295 296func lbc_verdict_name(v: i64) -> *u8 { 297 if v == LBC_V_REACHES { return "REACHES" as *u8 } 298 if v == LBC_V_SHORT { return "SHORT" as *u8 } 299 if v == LBC_V_NOGATES { return "NOGATES" as *u8 } 300 if v == LBC_V_NOBOARD { return "NOBOARD" as *u8 } 301 if v == LBC_V_BADTARGET { return "BADTARGET" as *u8 } 302 return "UNKNOWN" as *u8 303} 304 305func lbc_state_name(s: i64) -> *u8 { 306 if s == LBC_S_GATED { return "GATED" as *u8 } 307 if s == LBC_S_UNGATED { return "UNGATED" as *u8 } 308 if s == LBC_S_NOGATE { return "NOGATE" as *u8 } 309 if s == LBC_S_BADFLOOR { return "BADFLOOR" as *u8 } 310 return "UNKNOWN" as *u8 311} 312 313// the exit a verdict maps onto: REACHES 0; SHORT and BADTARGET 1 (declared and unable, or declared and broken); 314// NOGATES and NOBOARD 3 (the ruler could not judge -- it abstains, it never acquits) 315func lbc_exit_of(v: i64) -> i64 { 316 if v == LBC_V_REACHES { return LBC_EXIT_REACHES } 317 if v == LBC_V_SHORT { return LBC_EXIT_SHORT } 318 if v == LBC_V_BADTARGET { return LBC_EXIT_SHORT } 319 return LBC_EXIT_ABSTAIN 320}