nx_txtscan_gate.nx source
↩ module page · 120 lines · 6855 B
1// nx_txtscan_gate.nx -- REFEREE for nx_txtscan_lib (byte-oriented text search).
2//
3// Inherits the canonical verdict base class (nx_gate_verdict, D001) rather than rolling its own
4// counters, so nx_gate_green can judge this gate from outside and every run records a harness.jrnl
5// frame. The promote path REFUSED this gate while it hand-rolled a verdict, which is the guard
6// doing exactly its job -- a gate nothing can read is a gate whose flake stays invisible.
7//
8// TEETH:
9// [T1] u2605BITE: the search fires on a present pattern and stays SILENT on an absent one. A search
10// that cannot report absence always "finds" something.
11// [T2] boundary: a match at offset 0.
12// [T3] boundary: a match ending on the FINAL byte -- where an off-by-one reads past the buffer.
13// [T4] POSITION: successive calls return every distinct offset, strictly increasing, and the
14// count agrees with the walk.
15// [T5] u2605THE REGRESSION THIS ORGAN EXISTS FOR: a haystack containing NO newline at all still
16// resolves distinct offsets. This is the exact input on which the estate's line-oriented
17// greps degenerate to echoing the whole file (measured on a 112,755-byte one-line corpus).
18// [T6] overlap semantics are DEFINED, not accidental: "aaa" occurs 3x overlapping, 1x disjoint.
19// [T7] u2605BITE: case folding -- insensitive finds it, sensitive does not.
20// [T8] u2605NEG-CONTROL: an empty needle matches NOTHING. The natural implementation makes it match
21// at every offset, which would report a clean file as entirely corrupt.
22// [T9] u2605BITE: the control-byte detector fires on a 119-byte 0x0E run and stays SILENT on text
23// made only of tab/LF/CR. Without the silent half it flags every source file in the estate
24// and the sweep that found the real defect would have been worthless.
25// [T10] run length is measured exactly -- the signature that separates a mechanical overwrite
26// from a stray byte.
27// [T11] context windows clamp at BOTH ends.
28//
29// Hermetic: every fixture is in memory. No filesystem, no network, no engine.
30// Sovereign x86_64. license_tier: ORIGINAL expect_exit: 0
31import "nx_gate_verdict.nx"
32import "nx_txtscan_lib.nx"
33
34func tq(a: i64, b: i64) -> i64 { if a == b { return 1 } return 0 }
35func tfound(h: i64) -> i64 { if h == TX_NOT_FOUND { return 0 } return 1 }
36
37func main(argc: i64, argv: *i64) -> i64 {
38 let ctr: *i64 = gv_ctr()
39 gv_head("NX-TXTSCAN-GATE -- byte-oriented search: the record is an OFFSET, never a line" as *u8)
40
41 let hay: *u8 = "the cartographer folded the map and the coastline moved" as *u8
42 let hn: i64 = tx_len(hay)
43
44 // u2605T1 BITE: fires on what is there, silent on what is not.
45 gv_bite("T1 substring search (present vs absent)" as *u8,
46 tfound(tx_next(hay, hn, 0, "coastline" as *u8, 9, TX_CASE_SENSITIVE)),
47 tfound(tx_next(hay, hn, 0, "sextant" as *u8, 7, TX_CASE_SENSITIVE)), ctr)
48 gv_check("T1b absent pattern counts 0" as *u8,
49 tq(tx_count(hay, hn, "sextant" as *u8, 7, TX_CASE_SENSITIVE, TX_STEP_OVERLAP), 0), ctr)
50
51 // T2/T3 the two boundaries a hand-written test is least likely to cover
52 gv_check("T2 match at offset 0" as *u8,
53 tq(tx_next(hay, hn, 0, "the" as *u8, 3, TX_CASE_SENSITIVE), 0), ctr)
54 gv_check("T3 match ending on the final byte" as *u8,
55 tq(tx_next(hay, hn, 0, "moved" as *u8, 5, TX_CASE_SENSITIVE), hn - 5), ctr)
56
57 // T4 POSITION: the primitive returns WHERE, and the walk enumerates every hit
58 let h1: i64 = tx_next(hay, hn, 0, "the" as *u8, 3, TX_CASE_SENSITIVE)
59 let h2: i64 = tx_next(hay, hn, h1 + 1, "the" as *u8, 3, TX_CASE_SENSITIVE)
60 let h3: i64 = tx_next(hay, hn, h2 + 1, "the" as *u8, 3, TX_CASE_SENSITIVE)
61 var ordered: i64 = 0
62 if h1 < h2 { if h2 < h3 { ordered = 1 } }
63 gv_check("T4 successive offsets strictly increase" as *u8, ordered, ctr)
64 gv_check("T4b count agrees with the walk (3)" as *u8,
65 tq(tx_count(hay, hn, "the" as *u8, 3, TX_CASE_SENSITIVE, TX_STEP_OVERLAP), 3), ctr)
66
67 // u2605T5 the regression: zero newlines in the fixture, offsets still resolve
68 gv_check("T5 fixture genuinely contains ZERO newlines" as *u8,
69 tq(tx_count(hay, hn, "\x0a" as *u8, 1, TX_CASE_SENSITIVE, TX_STEP_OVERLAP), 0), ctr)
70 gv_check("T5b distinct offsets resolved with no line structure" as *u8, ordered, ctr)
71
72 // T6 overlap is a DEFINED policy, not an accident of the loop
73 let aaa: *u8 = "aaaaa" as *u8
74 gv_check("T6 aaa in aaaaa overlapping = 3" as *u8,
75 tq(tx_count(aaa, 5, "aaa" as *u8, 3, TX_CASE_SENSITIVE, TX_STEP_OVERLAP), 3), ctr)
76 gv_check("T6b aaa in aaaaa disjoint = 1" as *u8,
77 tq(tx_count(aaa, 5, "aaa" as *u8, 3, TX_CASE_SENSITIVE, TX_STEP_DISJOINT), 1), ctr)
78
79 // u2605T7 BITE: case folding works in BOTH directions
80 let mixed: *u8 = "The Coastline" as *u8
81 gv_bite("T7 case folding (insensitive vs sensitive)" as *u8,
82 tfound(tx_next(mixed, 13, 0, "the" as *u8, 3, TX_CASE_INSENSITIVE)),
83 tfound(tx_next(mixed, 13, 0, "the" as *u8, 3, TX_CASE_SENSITIVE)), ctr)
84
85 // u2605T8 NEG-CONTROL: an empty needle must match nothing, not everything
86 gv_check("T8 empty needle -> TX_NOT_FOUND" as *u8,
87 tq(tx_next(hay, hn, 0, "" as *u8, 0, TX_CASE_SENSITIVE), TX_NOT_FOUND), ctr)
88 gv_check("T8b empty needle -> count 0" as *u8,
89 tq(tx_count(hay, hn, "" as *u8, 0, TX_CASE_SENSITIVE, TX_STEP_OVERLAP), 0), ctr)
90
91 // T9/T10 the real corruption signature: "ok" + 119 x 0x0E + "ok"
92 let RUN: i64 = 119
93 let cbuf: *u8 = sys_mmap(256)
94 cbuf[0] = 111 as u8
95 cbuf[1] = 107 as u8
96 var i: i64 = 0
97 while i < RUN { cbuf[2 + i] = 14 as u8; i = i + 1 }
98 cbuf[2 + RUN] = 111 as u8
99 cbuf[3 + RUN] = 107 as u8
100 let cn: i64 = 4 + RUN
101 let clean: *u8 = "a\x09b\x0ac\x0dd" as *u8
102
103 // u2605BITE: fires on the corrupt buffer, silent on ordinary whitespace.
104 gv_bite("T9 control-byte detector (0x0E run vs tab/LF/CR)" as *u8,
105 tfound(tx_next_ctl(cbuf, cn, 0)),
106 tfound(tx_next_ctl(clean, 7, 0)), ctr)
107 let cpos: i64 = tx_next_ctl(cbuf, cn, 0)
108 gv_check("T9b run located at offset 2" as *u8, tq(cpos, 2), ctr)
109 gv_check("T10 run length measured exactly (119)" as *u8, tq(tx_run_len(cbuf, cn, cpos), RUN), ctr)
110 gv_check("T10b space is not a control byte" as *u8, tq(tx_is_ctl(32), 0), ctr)
111
112 // T11 context clamps at both ends
113 gv_check("T11 lo clamps to 0" as *u8, tq(tx_ctx_lo(2, 40), 0), ctr)
114 gv_check("T11b hi clamps to n" as *u8, tq(tx_ctx_hi(hn - 5, 5, 40, hn), hn), ctr)
115
116 let rc: i64 = gv_verdict("TXTSCAN-GATE" as *u8, ctr,
117 "byte-oriented search proven on the one-line input where line-grep degenerates" as *u8)
118 sys_exit(rc)
119 return rc
120}