nx_research_extract.nx source
↩ module page · 59 lines · 2648 B
1// nx_research_extract.nx -- the Researcher's EXTRACT stage: parse FACTS from fetched text by PATTERN
2// (Claude was wrong to mark this an LLM-gap). Pulling "53" out of "53 percent of users abandon" is
3// substring + integer scan -- pure mechanizable string work the team owns. Only DEEP semantic
4// synthesis needs the LLM; fact/number/citation extraction does not. Pairs with nx_browse_text (the
5// team's sovereign fetch) so the Researcher does fetch+extract end to end. license_tier: ORIGINAL.
6
7import "nx_syscalls.nx"
8
9func re_strlen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
10
11// first index of `needle` in text[0..n), or -1.
12func re_find(text: *u8, n: i64, needle: *u8) -> i64 {
13 let m: i64 = re_strlen(needle)
14 if m == 0 { return 0 }
15 var i: i64 = 0
16 while i + m <= n {
17 var j: i64 = 0; var ok: i64 = 1
18 while j < m { if text[i + j] != needle[j] { ok = 0; j = m } else { j = j + 1 } }
19 if ok == 1 { return i }
20 i = i + 1
21 }
22 return 0 - 1
23}
24
25// parse the first integer appearing at or after `pos` (skipping non-digits); -1 if none.
26func re_int_from(text: *u8, n: i64, pos: i64) -> i64 {
27 var i: i64 = pos; var scanning: i64 = 1
28 while scanning == 1 {
29 if i >= n { scanning = 0 } else { if text[i] >= 48 { if text[i] <= 57 { scanning = 0 } else { i = i + 1 } } else { i = i + 1 } }
30 }
31 if i >= n { return 0 - 1 }
32 var val: i64 = 0; var parsing: i64 = 1
33 while parsing == 1 {
34 if i >= n { parsing = 0 } else { if text[i] >= 48 { if text[i] <= 57 { val = val * 10 + (text[i] - 48); i = i + 1 } else { parsing = 0 } } else { parsing = 0 } }
35 }
36 return val
37}
38
39// the STAT associated with a keyword: find the keyword, parse the first integer after it; -1 if absent.
40func re_stat_after(text: *u8, n: i64, keyword: *u8) -> i64 {
41 let idx: i64 = re_find(text, n, keyword)
42 if idx < 0 { return 0 - 1 }
43 return re_int_from(text, n, idx + re_strlen(keyword))
44}
45
46// does the text CONTAIN a term (e.g. "debunked", a citation author)? 1/0 -- the basis of verification.
47func re_has(text: *u8, n: i64, term: *u8) -> i64 { if re_find(text, n, term) >= 0 { return 1 } return 0 }
48
49// count occurrences of a term (e.g. how many citations / mentions).
50func re_count(text: *u8, n: i64, term: *u8) -> i64 {
51 let m: i64 = re_strlen(term); if m == 0 { return 0 }
52 var c: i64 = 0; var i: i64 = 0
53 while i + m <= n {
54 var j: i64 = 0; var ok: i64 = 1
55 while j < m { if text[i + j] != term[j] { ok = 0; j = m } else { j = j + 1 } }
56 if ok == 1 { c = c + 1; i = i + m } else { i = i + 1 }
57 }
58 return c
59}