code wiki / (root) / nx_research_extract.nx

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}