code wiki / (root) / nx_rank_fused.nx

nx_rank_fused.nx source

↩ module page · 75 lines · 2779 B

1// nx_rank_fused.nx -- the additive, SEO-resistant ranker (tier + BM25 via RRF). 2// 3// module: nishi-core.search.rank_fused 4// depends: fx.nx, nx_source_tier.nx, nx_bm25.nx, nx_rrf.nx 5// capability: CORE_COMPUTE 6// wired_status: FULLY_WIRED 7// 8// The capstone of the ranking layer: fuse the source-tier PRIOR rank with the 9// BM25 CONTENT rank via Reciprocal Rank Fusion. Because RRF rewards items that 10// rank well in BOTH signals, a high-tier page with no relevant content cannot 11// win on authority alone, and a UNIQUE low-tier page with strong content rises 12// -- the operator cardinal (deliver information, additive, no prejudging) made 13// operational. Novelty (nx_simhash) and provenance join as further RRF inputs 14// once the crawler supplies page content. Deterministic Q16.16 throughout. 15 16import "fx.nx" 17import "syscalls.nx" 18import "nx_source_tier.nx" 19import "nx_bm25.nx" 20import "nx_rrf.nx" 21 22// item-ids sorted by score descending (ties -> lower id first). 23func nx_rank_order_desc(scores: *i64, n: i64, order_out: *i64) -> i64 { 24 let used: *i64 = sys_mmap(n * 8) as *i64 25 var i: i64 = 0 26 while i < n { used[i] = 0; i = i + 1 } 27 var k: i64 = 0 28 while k < n { 29 var best: i64 = 0 - 1 30 var bestsc: i64 = 0 31 var j: i64 = 0 32 while j < n { 33 if used[j] == 0 { 34 if best < 0 { best = j; bestsc = scores[j] } 35 else { if scores[j] > bestsc { best = j; bestsc = scores[j] } } 36 } 37 j = j + 1 38 } 39 used[best] = 1 40 order_out[k] = best 41 k = k + 1 42 } 43 return 0 44} 45 46// Fused ranking of a corpus for a query. urls/titles drive the tier prior; 47// texts drive BM25 content relevance. Writes the fused item order (best first) 48// into order_out. 49func nx_rank_fused(urls: **u8, titles: **u8, texts: **u8, text_lens: *i64, n: i64, 50 q_terms: **u8, q_term_lens: *i64, nterms: i64, 51 order_out: *i64) -> i64 { 52 let tier_sc: *i64 = sys_mmap(n * 8) as *i64 53 let v: *NxTierVerdict = sys_mmap(NX_TIER_VERDICT_BYTES) as *NxTierVerdict 54 var i: i64 = 0 55 while i < n { 56 nx_tier_classify(urls[i], titles[i], v) 57 tier_sc[i] = nx_tier_gain(v) 58 i = i + 1 59 } 60 let bm: *i64 = sys_mmap(n * 8) as *i64 61 nx_bm25_score(texts, text_lens, n, q_terms, q_term_lens, nterms, bm) 62 63 let tier_order: *i64 = sys_mmap(n * 8) as *i64 64 let bm_order: *i64 = sys_mmap(n * 8) as *i64 65 nx_rank_order_desc(tier_sc, n, tier_order) 66 nx_rank_order_desc(bm, n, bm_order) 67 68 let fused: *i64 = sys_mmap(n * 8) as *i64 69 var j: i64 = 0 70 while j < n { fused[j] = 0; j = j + 1 } 71 nx_rrf_add(tier_order, n, fused) 72 nx_rrf_add(bm_order, n, fused) 73 nx_rank_order_desc(fused, n, order_out) 74 return 0 75}