code wiki / _hdl_build / nx_editdist_gate.nx
nx_editdist_gate.nx source
↩ module page · 46 lines · 3370 B
1// nx_editdist_gate.nx -- KATs for the bounded Levenshtein (the typo rung's math floor). license_tier: ORIGINAL
2import "nx_editdist.nx"
3// MIGRATED TO THE SHARED VERDICT MACHINERY 2026-08-15. This gate hand-rolled its own pass/total
4// counters and printed `=== editdist gate: 8/8 verdict=GREEN`, which nx_swcompare_evidence CANNOT READ:
5// once wired into knowledge/compare/search.gates it reported [GREEN] pass=0/0 -- the verdict travelled
6// (exit code) but the EVIDENCE did not, so a partial regression would have shown only as a binary flip.
7// ★A GATE WHOSE COUNT THE ROLLUP CANNOT READ IS HALF-WIRED. gv_ctr/gv_check make declared-equals-
8// executed BY CONSTRUCTION -- the denominator moves with the teeth instead of being maintained by hand,
9// which is how a hand-rolled counter ends up printing 7/5 or silently dropping a tooth that stopped running.
10import "nx_gate_verdict.nx"
11
12func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
13func g_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
14func g_num(v: i64) -> i64 {
15 let bb: *u8 = sys_mmap(28); var m: i64 = v
16 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
17 let t: *u8 = sys_mmap(28); var k: i64 = 0
18 if m == 0 { t[0] = 48 as u8; k = 1 }
19 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
20 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
21 sys_write(1, bb, k); return 0
22}
23func g_ed(a: *u8, b: *u8, bound: i64) -> i64 { return ed_bounded(a, g_len(a), b, g_len(b), bound) }
24// Thin delegate so the eight call sites below read unchanged while the COUNTING is the shared one.
25func g_check(name: *u8, cond: i64, ctr: *i64) -> i64 { return gv_check(name, cond, ctr) }
26
27func main() -> i64 {
28 let ctr: *i64 = gv_ctr()
29 gv_head("nx_editdist -- bounded Levenshtein KATs (the typo rung's math floor)" as *u8)
30
31 g_check("T1 identical -> 0" as *u8, (g_ed("probate" as *u8, "probate" as *u8, 2) == 0) as i64, ctr)
32 g_check("T2 one substitution -> 1 (probete/probate)" as *u8, (g_ed("probete" as *u8, "probate" as *u8, 2) == 1) as i64, ctr)
33 g_check("T3 one deletion -> 1 (probat/probate)" as *u8, (g_ed("probat" as *u8, "probate" as *u8, 2) == 1) as i64, ctr)
34 g_check("T4 one insertion -> 1 (proobate/probate)" as *u8, (g_ed("proobate" as *u8, "probate" as *u8, 2) == 1) as i64, ctr)
35 g_check("T5 kitten/sitting -> 3 exceeds bound 2 -> 3" as *u8, (g_ed("kitten" as *u8, "sitting" as *u8, 2) == 3) as i64, ctr)
36 g_check("T6 length-gap early-out (ab/abcdef bound 2 -> 3)" as *u8, (g_ed("ab" as *u8, "abcdef" as *u8, 2) == 3) as i64, ctr)
37 g_check("T7 transposition counts 2 (recieve/receive)" as *u8, (g_ed("recieve" as *u8, "receive" as *u8, 2) == 2) as i64, ctr)
38 // null ptr + len 0 (NEVER the `"" as *u8` literal -- the banked miscompile; len 0 is checked pre-deref)
39 g_check("T8 empty vs word -> len" as *u8, (ed_bounded(0 as *u8, 0, "abc" as *u8, 3, 3) == 3) as i64, ctr)
40
41 // Exit code comes FROM the verdict, not beside it: /api/gate_run and the evidence consumer both
42 // derive GREEN/RED from the exit status, so a bare `return 0` after printing RED blesses failures.
43 let rc: i64 = gv_verdict("EDITDIST" as *u8, ctr, "bounded Levenshtein KATs for the did-you-mean rung" as *u8)
44 sys_exit(rc)
45 return rc
46}