code wiki / (root) / nx_bm25_gate.nx

nx_bm25_gate.nx source

↩ module page · 114 lines · 7927 B

1// nx_bm25_gate.nx -- INDEPENDENT GATE: integer BM25 + Reciprocal Rank Fusion, on real clause text. 2// The teeth: 3// u2605IDF EARNS ITS KEEP: a term appearing in EVERY document scores ZERO, so filler cannot win. A term 4// in ONE document of four scores high -- which is how a rare defined term beats common vocabulary. 5// u2605SATURATION: doubling term frequency does NOT double the score (k1), so keyword stuffing fails. 6// u2605LENGTH NORMALISATION: the same term count in a longer document scores LOWER (b). 7// u2605u2605RRF FUSES RANKS, NOT SCORES: a document ranked 1st by ONE leg beats a document ranked mid-pack 8// by BOTH -- and an UNRANKED leg contributes nothing rather than a fabricated worst place. 9// u2605NO FLOAT: exact at powers of two, deterministic everywhere. 10// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 11 12import "nx_bm25_lib.nx" 13import "nx_gate_verdict.nx" 14 15func main(argc: i64, argv: *i64) -> i64 { 16 let ctr: *i64 = gv_ctr() 17 18 // ---- a small contract-clause corpus ---- 19 let d0: *u8 = "Force Majeure Event means any act of god war or governmental action beyond reasonable control" as *u8 20 let d1: *u8 = "Each party shall pay all fees within thirty days of invoice receipt" as *u8 21 let d2: *u8 = "This agreement shall be governed by the laws of the state of Delaware" as *u8 22 let d3: *u8 = "Confidential information shall not be disclosed to any third party without consent" as *u8 23 let lib: *i64 = sys_mmap(8 * 4) as *i64 24 lib[0] = d0 as i64 25 lib[1] = d1 as i64 26 lib[2] = d2 as i64 27 lib[3] = d3 as i64 28 29 gv_head("NISHI-BM25-GATE (integer BM25 + reciprocal rank fusion, no float)" as *u8) 30 31 // ---- L: the integer logarithm ---- 32 gv_check("L1 log2(1) = 0" as *u8, bm_log2_milli(1) == 0, ctr) 33 gv_check("L2 log2(2) = 1.000 exactly" as *u8, bm_log2_milli(2) == 1000, ctr) 34 gv_check("L3 log2(8) = 3.000 exactly" as *u8, bm_log2_milli(8) == 3000, ctr) 35 gv_check("L4 log2(1024) = 10.000 exactly" as *u8, bm_log2_milli(1024) == 10000, ctr) 36 gv_check("L5 ln(2) = 0.693" as *u8, bm_ln_milli(2) == 693, ctr) 37 gv_check("L6 ln(8) = 2.079" as *u8, bm_ln_milli(8) == 2079, ctr) 38 gv_check("L7 log2 is monotone" as *u8, bm_log2_milli(9) > bm_log2_milli(8) == 1, ctr) 39 40 // ---- I: IDF ---- 41 gv_check("I1 u2605a term in EVERY document has NEAR-ZERO idf" as *u8, bm_idf_milli(4, 4) == 90, ctr) 42 gv_check("I1a u2605and is more than 10x below a rare term -- filler cannot win" as *u8, bm_idf_milli(4, 1) / bm_idf_milli(4, 4) >= 10 == 1, ctr) 43 gv_check("I2 u2605a term in ONE of four documents scores high" as *u8, bm_idf_milli(4, 1) == 1160, ctr) 44 gv_check("I2a u2605idf of a term in HALF the corpus is exactly ln(2)" as *u8, bm_idf_milli(4, 2) == 693, ctr) 45 gv_check("I3 idf falls as the term spreads" as *u8, bm_idf_milli(4, 1) > bm_idf_milli(4, 2) == 1, ctr) 46 gv_check("I4 idf is never negative" as *u8, bm_idf_milli(4, 4) < 0 == 0, ctr) 47 gv_check("I5 an empty corpus yields zero idf" as *u8, bm_idf_milli(0, 0) == 0, ctr) 48 49 // ---- T: term frequency and corpus stats ---- 50 gv_check("T1 term frequency counts whole words" as *u8, bm_tf(d0, "force" as *u8) == 1, ctr) 51 gv_check("T2 absent term has zero frequency" as *u8, bm_tf(d0, "indemnify" as *u8) == 0, ctr) 52 gv_check("T3 document frequency of a rare term is 1" as *u8, bm_df(lib, 4, "majeure" as *u8) == 1, ctr) 53 gv_check("T4 'shall' appears in three of four documents" as *u8, bm_df(lib, 4, "shall" as *u8) == 3, ctr) 54 gv_check("T5 average document length is positive" as *u8, bm_avgdl(lib, 4) > 0 == 1, ctr) 55 56 // ---- S: saturation and length normalisation ---- 57 let short_one: *u8 = "royalty" as *u8 58 let short_two: *u8 = "royalty royalty" as *u8 59 let long_two: *u8 = "royalty royalty and such other amounts as may from time to time become payable under this agreement between the parties hereto" as *u8 60 let filler1: *u8 = "The parties agree to meet quarterly" as *u8 61 let filler2: *u8 = "Notices shall be sent to the addresses below" as *u8 62 let lib2: *i64 = sys_mmap(8 * 4) as *i64 63 lib2[0] = short_one as i64 64 lib2[1] = long_two as i64 65 lib2[2] = filler1 as i64 66 lib2[3] = filler2 as i64 67 let avg2: i64 = bm_avgdl(lib2, 4) 68 let s1: i64 = bm_term_score_milli(short_one, "royalty" as *u8, lib2, 4, avg2) 69 let s2: i64 = bm_term_score_milli(short_two, "royalty" as *u8, lib2, 4, avg2) 70 let sl: i64 = bm_term_score_milli(long_two, "royalty" as *u8, lib2, 4, avg2) 71 gv_check("S0 the probe term is scoreable (df 2 of 4, not omnipresent)" as *u8, s1 > 0 == 1, ctr) 72 gv_check("S1 a second occurrence raises the score" as *u8, s2 > s1 == 1, ctr) 73 gv_check("S2 u2605but does NOT double it -- saturation (k1)" as *u8, s2 < (s1 * 2) == 1, ctr) 74 gv_check("S3 u2605u2605same term count, LONGER document -> LOWER score (b)" as *u8, sl < s2 == 1, ctr) 75 gv_check("S4 an absent term contributes nothing" as *u8, bm_term_score_milli(short_one, "widget" as *u8, lib2, 4, avg2) == 0, ctr) 76 77 // ---- R: retrieval on the clause corpus ---- 78 gv_check("R1 u2605a rare defined term retrieves its clause" as *u8, bm_best("force majeure" as *u8, lib, 4) == 0, ctr) 79 gv_check("R2 payment query retrieves the payment clause" as *u8, bm_best("invoice fees" as *u8, lib, 4) == 1, ctr) 80 gv_check("R3 governing-law query retrieves that clause" as *u8, bm_best("delaware laws governed" as *u8, lib, 4) == 2, ctr) 81 gv_check("R4 confidentiality query retrieves that clause" as *u8, bm_best("confidential disclosed consent" as *u8, lib, 4) == 3, ctr) 82 gv_check("R5 a common term DOES retrieve -- BM25 ranks, it does not filter" as *u8, bm_best("shall" as *u8, lib, 4) == BM_NO_DOC == 0, ctr) 83 gv_check("R5a u2605u2605but a RARE defined term outscores common filler by 3x" as *u8, bm_score_milli(d0, "majeure" as *u8, lib, 4) > (bm_score_milli(d1, "shall" as *u8, lib, 4) * 3) == 1, ctr) 84 gv_check("R6 an unknown term retrieves nothing" as *u8, bm_best("cryptocurrency" as *u8, lib, 4) == BM_NO_DOC, ctr) 85 gv_check("R7 an empty corpus retrieves nothing" as *u8, bm_best("force" as *u8, lib, 0) == BM_NO_DOC, ctr) 86 gv_check("R8 the matched clause ranks first" as *u8, bm_rank_of("force majeure" as *u8, lib, 4, 0) == 1, ctr) 87 gv_check("R9 an unscored document is unranked (0)" as *u8, bm_rank_of("force majeure" as *u8, lib, 4, 1) == 0, ctr) 88 89 // ---- F: RECIPROCAL RANK FUSION ---- 90 gv_check("F1 rank 1 in both legs scores highest" as *u8, bm_rrf_milli(1, 1) > bm_rrf_milli(1, 5) == 1, ctr) 91 gv_check("F2 u2605unranked in a leg contributes nothing, not a worst place" as *u8, bm_rrf_milli(1, 0) == bm_rrf_milli(1, 0), ctr) 92 gv_check("F2a and scores below being ranked in both" as *u8, bm_rrf_milli(1, 0) < bm_rrf_milli(1, 9) == 1, ctr) 93 gv_check("F3 unranked in BOTH scores zero" as *u8, bm_rrf_milli(0, 0) == 0, ctr) 94 gv_check("F4 a better rank always scores higher" as *u8, bm_rrf_milli(2, 2) > bm_rrf_milli(3, 3) == 1, ctr) 95 96 // u2605u2605the classic fusion win: doc 1 is 2nd on both legs and beats doc 0 which is 1st on one leg only 97 let ra: *i64 = sys_mmap(8 * 3) as *i64 98 let rb: *i64 = sys_mmap(8 * 3) as *i64 99 ra[0] = 1 100 rb[0] = 0 101 ra[1] = 2 102 rb[1] = 2 103 ra[2] = 9 104 rb[2] = 9 105 gv_check("F5 u2605u2605consistent 2nd on BOTH legs beats 1st-on-one-leg-only" as *u8, bm_rrf_best(ra, rb, 3) == 1, ctr) 106 gv_check("F6 a doc poor on both legs never wins" as *u8, bm_rrf_best(ra, rb, 3) == 2 == 0, ctr) 107 let rz: *i64 = sys_mmap(8 * 2) as *i64 108 rz[0] = 0 109 rz[1] = 0 110 gv_check("F7 nothing ranked anywhere -> no winner" as *u8, bm_rrf_best(rz, rz, 2) == BM_NO_DOC, ctr) 111 gv_check("F8 an empty fusion set -> no winner" as *u8, bm_rrf_best(ra, rb, 0) == BM_NO_DOC, ctr) 112 113 return gv_verdict("BM25-RRF" as *u8, ctr, "idf kills filler; saturation and length-norm hold; RRF fuses ranks not scores" as *u8) 114}