nx_fuzzy_match.nx source
↩ module page · 50 lines · 1767 B
1// nx_fuzzy_match.nx -- sovereign SAFE text matcher for the live-sourced census.
2//
3// Case- and separator-insensitive substring containment: normalizes both sides
4// by lowercasing and mapping '-'/'_' -> space, then substring-matches. This is
5// ZERO-false-positive normalization -- it fixes morphological mismatches the
6// exact matcher misses (e.g. needle "live-tv" vs prose "Live TV") WITHOUT
7// inventing semantics.
8//
9// DELIBERATELY does NOT do suffix stemming (transcode->transcoding) or synonyms
10// (media-browser->"media server"): those carry false-positive risk / require a
11// model seat. Keeping this matcher honest means the residual prose->feature
12// mapping stays a NAMED seat, not a faked match. license_tier: ORIGINAL
13
14import "nx_syscalls.nx"
15
16func fz_lc(b: i64) -> i64 { if b >= 65 { if b <= 90 { return b + 32 } } return b }
17
18// normalize one byte: lowercase, and '-'(45)/'_'(95) -> space(32).
19func fz_norm(b: i64) -> i64 {
20 let c: i64 = fz_lc(b)
21 if c == 45 { return 32 }
22 if c == 95 { return 32 }
23 return c
24}
25
26// does the normalized needle (m bytes) match hay starting at i?
27func fz_at(hay: *u8, hlen: i64, i: i64, needle: *u8, m: i64) -> i64 {
28 var j: i64 = 0
29 while j < m {
30 if i + j >= hlen { return 0 }
31 if fz_norm(hay[i + j] as i64) != fz_norm(needle[j] as i64) { return 0 }
32 j = j + 1
33 }
34 return 1
35}
36
37// case/separator-insensitive substring containment. Returns 0|1.
38func fuzzy_has(hay: *u8, hlen: i64, needle: *u8) -> i64 {
39 var m: i64 = 0
40 while needle[m] != (0 as u8) { m = m + 1 }
41 if m == 0 { return 0 }
42 var i: i64 = 0
43 while i + m <= hlen {
44 if fz_at(hay, hlen, i, needle, m) == 1 { return 1 }
45 i = i + 1
46 }
47 return 0
48}
49
50func main() -> i64 { return 0 }