code wiki / _hdl_build / nx_research_relations.nx

nx_research_relations.nx source

↩ module page · 110 lines · 4215 B

1// nx_research_relations.nx -- Researcher EXTRACT, rung 2: DOCUMENT-level claim 2// extraction. Splits a document into sentences and runs the rung-1 relation 3// organ on each, collecting a CLAIM SET (subject -> relation -> object). This is 4// what turns per-sentence extraction into research depth: ~one qualitative claim 5// per relational sentence across a whole page, vs the number-only extractor's 6// handful of digit-facts. Inspectable, sovereign, gated. license_tier: ORIGINAL. 7 8import "nx_syscalls.nx" 9import "nx_research_extract.nx" 10import "nx_research_relation.nx" 11import "nx_research_relation_clean.nx" 12const K_MAGIC_2048: i64 = 2048 13 14// sentence terminators ('.' '!' '?' newline) 15func rel_is_sent_end(c: u8) -> i64 { 16 if c == (46 as u8) { return 1 } 17 if c == (33 as u8) { return 1 } 18 if c == (63 as u8) { return 1 } 19 if c == (10 as u8) { return 1 } 20 return 0 21} 22 23// append NUL-terminated s into out at *off (bounded by out_cap) 24func rel_app(out: *u8, off: *i64, out_cap: i64, s: *u8) -> i64 { 25 var i: i64 = 0 26 while s[i] != (0 as u8) { 27 if off[0] >= out_cap - 1 { return 0 } 28 out[off[0]] = s[i]; off[0] = off[0] + 1; i = i + 1 29 } 30 return 0 31} 32 33// Extract all (subject,relation,object) claims from text[0..n); writes a 34// human-readable claim per line into out; returns the TOTAL claim count 35// (true count even if the report buffer fills -- never silently under-reports). 36func nx_rel_extract_doc(text: *u8, n: i64, out: *u8, out_cap: i64) -> i64 { 37 let subj: *u8 = sys_mmap(K_MAGIC_2048) 38 let obj: *u8 = sys_mmap(K_MAGIC_2048) 39 let off: *i64 = (sys_mmap(8)) as *i64 40 off[0] = 0 41 var count: i64 = 0 42 var s: i64 = 0 43 var i: i64 = 0 44 while i <= n { 45 var atend: i64 = 0 46 if i == n { atend = 1 } else { if rel_is_sent_end(text[i]) == 1 { atend = 1 } } 47 if atend == 1 { 48 let slen: i64 = i - s 49 if slen > 0 { 50 let ri: i64 = nx_rel_extract(text + s, slen, subj, obj) 51 if ri >= 0 { 52 if off[0] < out_cap - 512 { 53 rel_app(out, off, out_cap, subj) 54 rel_app(out, off, out_cap, " -> " as *u8) 55 rel_app(out, off, out_cap, rel_name(ri)) 56 rel_app(out, off, out_cap, " -> " as *u8) 57 rel_app(out, off, out_cap, obj) 58 rel_app(out, off, out_cap, "\n" as *u8) 59 } 60 count = count + 1 61 } 62 } 63 s = i + 1 64 } 65 i = i + 1 66 } 67 out[off[0]] = 0 as u8 68 return count 69} 70 71// document-level extraction WITH rung-3 cleanup: emits only clean, non-junk 72// claims (NP-trimmed subjects, pronouns/boilerplate rejected). Returns count. 73func nx_rel_extract_doc_clean(text: *u8, n: i64, out: *u8, out_cap: i64) -> i64 { 74 let subj: *u8 = sys_mmap(K_MAGIC_2048) 75 let obj: *u8 = sys_mmap(K_MAGIC_2048) 76 let cs: *u8 = sys_mmap(K_MAGIC_2048) 77 let co: *u8 = sys_mmap(K_MAGIC_2048) 78 let off: *i64 = (sys_mmap(8)) as *i64 79 off[0] = 0 80 var count: i64 = 0 81 var s: i64 = 0 82 var i: i64 = 0 83 while i <= n { 84 var atend: i64 = 0 85 if i == n { atend = 1 } else { if rel_is_sent_end(text[i]) == 1 { atend = 1 } } 86 if atend == 1 { 87 let slen: i64 = i - s 88 if slen > 0 { 89 let ri: i64 = nx_rel_extract(text + s, slen, subj, obj) 90 if ri >= 0 { 91 if nx_claim_clean(subj, obj, cs, co) == 1 { 92 if off[0] < out_cap - 512 { 93 rel_app(out, off, out_cap, cs) 94 rel_app(out, off, out_cap, " -> " as *u8) 95 rel_app(out, off, out_cap, rel_name(ri)) 96 rel_app(out, off, out_cap, " -> " as *u8) 97 rel_app(out, off, out_cap, co) 98 rel_app(out, off, out_cap, "\n" as *u8) 99 } 100 count = count + 1 101 } 102 } 103 } 104 s = i + 1 105 } 106 i = i + 1 107 } 108 out[off[0]] = 0 as u8 109 return count 110}