code wiki / _hdl_build / nx_wiki_answer.nx

nx_wiki_answer.nx

buildroot/runtime/_hdl_build/nx_wiki_answer.nx

23412 B439 linesdepth 6pulls 12 transitivereach 2 importersview sourcekind tooltopic wiki
docsdependenciesstructsconstsfunctions

about

nx_wiki_answer.nx -- THE INSTANT-ANSWER organ for the live 12-page wiki corpus (IMS Thrust B rung 1). answer(query) returns THE ANSWER -- a direct snippet + its source page -- in ONE step, NOT a results list. This is the operator's "<10s / 1-click answer" surface: type a question, get the passage that answers it with a source link, no second click into a SERP. FLOW (compose proven engines, ZERO ranking/snippet math reinvented): 1. registry-driven site lookup (site=wiki -> idx + manifest + base_url) over the committed onsite registry knowledge/index/onsite_sites.tsv -- the SAME data-driven model nx_onsite_search uses (per-site isolation by construction: the wiki index file physically cannot return another site's docs). 2. nx_inv_load (nx_search_inverted_persist) -> the durable inverted index; parse the manifest into url/title(=slug)/body slices (docid = line), EXACTLY as nx_onsite_search does. 3. BM25F top page: shortlist via nx_inv_query_term, score every candidate with bmf_score (nx_bm25f -- title-field=slug boost + body), pick top-1. Title hits (the slug) outrank body hits. 4. best answer passage from that top page via nx_search_snippet_extract (densest-cluster window picker below) + <mark> highlight over the query terms. 5. threshold gate: if the top-1 BM25F score (x1e6) does NOT exceed wiki_answer_min_score (READ from the params.tsv ledger -- no magic number, rule 11) -> WA_NO_ANSWER. We REFUSE rather than fabricate. REUSE: nx_search_inverted_persist (nx_inv_load + nx_inv_query_term), nx_bm25f (bmf_score/bm_token_count), nx_search_snippet_extract (nx_search_snippet_extract + NxSearchQuery via nx_search_query_parser), nx_syscalls. Library organ (no main when imported by the gate; the self-test main below makes it runnable standalone). ADDITIVE-ONLY: reads index+manifest+params; writes nothing. license_tier: ORIGINAL

dependencies 3 imports · 2 importers

nx_search_inverted_persist.nx nx_bm25f.nx nx_search_snippet_extract.nx nx_wiki_answer.nx nx_wiki_answer_gate.nx nx_wiki_search_page.nx

imports: nx_search_inverted_persist.nxnx_bm25f.nxnx_search_snippet_extract.nx

imported by: nx_wiki_answer_gate.nxnx_wiki_search_page.nx

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main wa_puts wa_demo wa_new answer answer_ex wa_strlen sys_read_file sys_openat_rd sys_lseek sys_mmap sys_read sys_close wa_lookup_site wa_streq nx_inv_load sys_read_file ↻ nx_inv_is_token_char nx_inv_query_term nx_inv_hash_bytes_lower nx_inv_lookup_slot nx_inv_slot_at nx_inv_slot_hash nx_inv_slot_postings_count nx_inv_slot_postings_offse nx_inv_slot_write_cursor wa_fold bmf_score re_count re_strlen bmf_contrib bmf_df re_count ↻ bm_idf_micro bm_ln_micro wa_read_threshold sys_read_file ↻ wa_strlen ↻ nx_search_query_init sys_mmap ↻

structs

56struct WaAnswer

consts

26const WA_MAGIC_1000000: i64 = 1000000
27const WA_MAGIC_10000: i64 = 10000
30const WA_OK: i64 = 0
31const WA_NO_ANSWER: i64 = 5200 // top-1 below threshold OR no candidate matched -> refuse (no fabrication)
32const WA_BAD_INPUT: i64 = 5201
33const WA_NO_REGISTRY: i64 = 5202 // onsite registry missing / site row absent
34const WA_NO_INDEX: i64 = 5203 // index or manifest missing / stale pair
35const WA_QUERY_FAIL: i64 = 5204 // query parse failed
38const WA_REG_PATH: *u8 = "knowledge/index/onsite_sites.tsv" // committed production onsite registry
39const WA_PARAMS_PATH: *u8 = "knowledge/registry/params.tsv" // measured-parameters ledger
40const WA_PARAM_NAME: *u8 = "wiki_answer_min_score" // the NO_ANSWER floor (BM25F x1e6)
41const WA_MIN_FALLBACK: i64 = 100000 // used ONLY if the params row is unreadable
42const WA_SITE: *u8 = "wiki"
43const WA_ROWID_CAP: i64 = 16384 // matches NX_INV_MAX_POSTINGS_PER
44const WA_MAX_TERMS: i64 = 16 // query terms considered for BM25F (parser caps at 32)
45const WA_SNIP_CAP: i64 = 2048 // snippet output buffer (>= NX_SSE_DEFAULT_OUTPUT_CAP)
46const WA_TERMS_CAP: i64 = 1024 // NxSearchQuery terms buffer (NX_SQP_TERMS_BUF_MIN_CAP)
47const WA_SLUG_CAP: i64 = 256
48const WA_DENSE_WIN: i64 = 240 // densest-cluster scan window (bytes) for the answer passage

functions

65func wa_strlen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
66func wa_streq(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } if b[i] != (0 as u8) { return 0 } return 1 }
called by 1: wa_lookup_site
67func wa_fold(s: *u8, n: i64) -> i64 { var i: i64 = 0; while i < n { let c: i64 = s[i] as i64; if c >= 65 { if c <= 90 { s[i] = (c + 32) as u8 } } i = i + 1 } return 0 }
called by 1: answer_ex
71func wa_lookup_site(reg: *u8, n: i64, site: *u8, out_idx: *i64, out_mf: *i64, out_base: *i64) -> i64
called by 1: answer_ex calls 1: wa_streq
108func wa_read_threshold() -> i64
called by 1: answer_ex calls 2: sys_read_filewa_strlen
157func wa_best_window(body: *u8, blen: i64, qterms: *i64, qlens: *i64, nq: i64) -> i64
called by 1: answer_ex
191func answer_ex(reg_path: *u8, site: *u8, query: *u8, out: *WaAnswer) -> i64
379func answer(query: *u8, out: *WaAnswer) -> i64
384func wa_new() -> *WaAnswer
395func wa_verdict_name(v: i64) -> *u8
407func wa_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
called by 2: wa_demomain
408func wa_pscore(v: i64) -> i64
called by 1: wa_demo
420func wa_demo(query: *u8) -> i64
432func main() -> i64
calls 2: wa_putswa_demo