code wiki / _hdl_build / nx_stem_gate.nx

nx_stem_gate.nx source

↩ module page · 63 lines · 5197 B

1// nx_stem_gate.nx -- KAT for R-UX-2 (nx_stem): Porter Step 1a on real andelinwest/search vocabulary. expect_exit: 0 2import "nx_syscalls.nx" 3import "nx_stem.nx" 4 5func st_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 6func st_putb(p: *u8, n: i64) -> i64 { if n>0 { sys_write(1,p,n) } return 0 } 7func st_pn(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=(48 as u8);k=1}; while m>0{t[k]=((48+(m%10)) as u8);m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(1,bb,k); return 0 } 8func st_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 } 9func st_wn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=(48 as u8);k=1}; while m>0{t[k]=((48+(m%10)) as u8);m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(fd,bb,k); return 0 } 10func st_len(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 11 12// stem `word` and check the result == `expect` (length + bytes). prints the row. returns 1 pass / 0 fail. 13func st_case(word: *u8, expect: *u8) -> i64 { 14 let buf: *u8=sys_mmap(64) 15 let wl: i64=st_len(word) 16 var i: i64=0; while i<wl { buf[i]=word[i]; i=i+1 } 17 let nl: i64=vr_stem(buf, wl) 18 let el: i64=st_len(expect) 19 var ok: i64=1 20 if nl!=el { ok=0 } else { var j: i64=0; while j<nl { if buf[j]!=expect[j] { ok=0; j=nl } else { j=j+1 } } } 21 st_puts(" " as *u8); st_putb(word, wl); st_puts(" -> " as *u8); st_putb(buf, nl) 22 st_puts(" exp=" as *u8); st_putb(expect, el); st_puts(" " as *u8) 23 if ok==1 { st_puts("PASS\n" as *u8) } else { st_puts("FAIL\n" as *u8) } 24 return ok 25} 26 27func main() -> i64 { 28 st_puts("=== R-UX-2 STEMMING -- Porter Step 1a (plural normalization) on real search vocab ===\n" as *u8) 29 var pass: i64=0; var total: i64=0 30 total=total+1; pass=pass + st_case("plans\x00" as *u8, "plan\x00" as *u8) // s 31 total=total+1; pass=pass + st_case("claims\x00" as *u8, "claim\x00" as *u8) // s 32 total=total+1; pass=pass + st_case("contracts\x00" as *u8, "contract\x00" as *u8) // s 33 total=total+1; pass=pass + st_case("trusts\x00" as *u8, "trust\x00" as *u8) // s 34 total=total+1; pass=pass + st_case("businesses\x00" as *u8, "business\x00" as *u8) // sses->ss 35 total=total+1; pass=pass + st_case("families\x00" as *u8, "famili\x00" as *u8) // ies->i (Porter) 36 total=total+1; pass=pass + st_case("business\x00" as *u8, "business\x00" as *u8) // ss unchanged 37 total=total+1; pass=pass + st_case("car\x00" as *u8, "car\x00" as *u8) // no-s unchanged 38 39 // ---- PORTER-LITE conflation (2026-07-03 upgrade): -ed/-ing/-ly + derivational + over-stem safety ---- 40 st_puts("-- conflation (variants share a stem; distinct words must not) --\n" as *u8) 41 total=total+1; pass=pass + st_case("running\x00" as *u8, "run\x00" as *u8) // ing + de-double 42 total=total+1; pass=pass + st_case("ranked\x00" as *u8, "rank\x00" as *u8) // ed 43 total=total+1; pass=pass + st_case("ranking\x00" as *u8, "rank\x00" as *u8) // ing 44 total=total+1; pass=pass + st_case("indexing\x00" as *u8, "index\x00" as *u8) // ing 45 total=total+1; pass=pass + st_case("crawling\x00" as *u8, "crawl\x00" as *u8) // ing 46 total=total+1; pass=pass + st_case("computing\x00" as *u8, "comput\x00" as *u8) // ing 47 total=total+1; pass=pass + st_case("computed\x00" as *u8, "comput\x00" as *u8) // ed (same stem as computing) 48 // NEG over-stemming: distinct words must NOT collapse to the same root 49 let sa: *u8=sys_mmap(64); let sb: *u8=sys_mmap(64) 50 var i9: i64=0; while i9<3 { sa[i9]="run\x00"[i9]; i9=i9+1 } let la: i64=vr_stem(sa,3) 51 i9=0; while i9<4 { sb[i9]="rank\x00"[i9]; i9=i9+1 } let lb: i64=vr_stem(sb,4) 52 var diff: i64=1; if la==lb { var j9: i64=0; var eq: i64=1; while j9<la { if sa[j9]!=sb[j9] { eq=0; j9=la } else { j9=j9+1 } } if eq==1 { diff=0 } } 53 total=total+1; pass=pass+diff 54 st_puts(" NEG run != rank distinct: "); if diff==1 { st_puts("PASS\n") } else { st_puts("FAIL\n") } 55 56 st_puts("----\nSTEM gate " as *u8); st_pn(pass); st_puts("/" as *u8); st_pn(total); st_puts(" passed\n" as *u8) 57 st_puts("HONEST: Porter Step 1a (plural) only -- no irregulars (children->child needs a lexicon); fuller Porter\n" as *u8) 58 st_puts(" steps are the named extension. Recall win: query 'plan' now reaches docs that say 'plans'.\n" as *u8) 59 let lg: i64=sys_openat_append("knowledge/status/stem_gate.log" as *u8, 0x1a4) 60 if lg>=0 { st_w(lg, "R-UX-2 stem gate pass=" as *u8); st_wn(lg, pass); st_w(lg, "/" as *u8); st_wn(lg, total); if pass==total { st_w(lg, " GREEN\n" as *u8) } else { st_w(lg, " RED\n" as *u8) } sys_close(lg) } 61 if pass==total { st_puts("R-UX-2 GREEN (sovereign Porter-lite stemming: plurals + -ed/-ing/-ly + derivational, over-stem-guarded)\n" as *u8); sys_exit(0); return 0 } 62 st_puts("R-UX-2 RED\n" as *u8); sys_exit(1); return 1 63}