nx_ir_eval_gate.nx source
↩ module page · 63 lines · 3059 B
1// nx_ir_eval_gate.nx -- KAT for nx_ir_eval (the search-SOTA ruler).
2// Native sovereign lane; exit 0 = all pass, N = assertion N failed.
3//
4// Every asserted value is either exact-by-construction (rank-1 discount is
5// log2(2)=1.0; an already-ideal ranking has nDCG==1.0 because DCG==IDCG) or a
6// plain integer ratio (MRR/Recall/Precision/AP) -- so the KAT verifies the
7// summation/ordering logic bit-exactly without depending on fx_log2's internal
8// bits for non-powers-of-two, which are checked by inequality/ordering instead.
9
10import "fx.nx"
11import "syscalls.nx"
12import "nx_ir_eval.nx"
13
14func main() -> i64 {
15 // gains fixtures
16 let gi: *i64 = sys_mmap(5 * 8) as *i64 // ideal ranking [3,2,1,0,0]
17 gi[0] = 3; gi[1] = 2; gi[2] = 1; gi[3] = 0; gi[4] = 0
18 let gm: *i64 = sys_mmap(5 * 8) as *i64 // mid ranking [3,0,2,0,1]
19 gm[0] = 3; gm[1] = 0; gm[2] = 2; gm[3] = 0; gm[4] = 1
20 let gb: *i64 = sys_mmap(5 * 8) as *i64 // bad ranking [0,0,1,2,3]
21 gb[0] = 0; gb[1] = 0; gb[2] = 1; gb[3] = 2; gb[4] = 3
22
23 let one: i64 = fx_from_int(1) // 1.0 in Q16.16 (65536)
24 let half: i64 = fx_from_frac(1, 2) // 0.5 in Q16.16 (32768)
25
26 // 1: DCG@1 of the ideal ranking = 3.0 exactly (rank-1 discount = log2(2)=1.0)
27 if ie_dcg_at_k(gi, 5, 1) != fx_from_int(3) { return 1 }
28 // 2: DCG@2 adds a positive 2/log2(3) term -> strictly greater than DCG@1
29 if ie_dcg_at_k(gi, 5, 2) <= ie_dcg_at_k(gi, 5, 1) { return 2 }
30 // 3: nDCG@5 of an already-ideal ranking == 1.0 exactly (DCG==IDCG)
31 if ie_ndcg_at_k(gi, 5, 5) != one { return 3 }
32 // 4: nDCG@5 of a non-ideal ranking is strictly < 1.0
33 if ie_ndcg_at_k(gm, 5, 5) >= one { return 4 }
34 // 5: ... and strictly > 0
35 if ie_ndcg_at_k(gm, 5, 5) <= 0 { return 5 }
36 // 6: a better ranking (mid) scores strictly higher nDCG than a worse one (bad)
37 if ie_ndcg_at_k(gm, 5, 5) <= ie_ndcg_at_k(gb, 5, 5) { return 6 }
38
39 // rels fixtures
40 let r1: *i64 = sys_mmap(5 * 8) as *i64 // [1,0,1,0,1], total_relevant = 3
41 r1[0] = 1; r1[1] = 0; r1[2] = 1; r1[3] = 0; r1[4] = 1
42 let r2: *i64 = sys_mmap(5 * 8) as *i64 // [0,1,0,0,0]
43 r2[0] = 0; r2[1] = 1; r2[2] = 0; r2[3] = 0; r2[4] = 0
44
45 // 7: MRR with first relevant at rank 1 == 1.0
46 if ie_mrr(r1, 5) != one { return 7 }
47 // 8: MRR with first relevant at rank 2 == 0.5
48 if ie_mrr(r2, 5) != half { return 8 }
49 // 9: Recall@5 = 3/3 = 1.0
50 if ie_recall_at_k(r1, 5, 5, 3) != one { return 9 }
51 // 10: Recall@2 = 1/3 (only rank-1 relevant inside top 2)
52 if ie_recall_at_k(r1, 5, 2, 3) != fx_from_frac(1, 3) { return 10 }
53 // 11: Precision@5 = 3/5
54 if ie_precision_at_k(r1, 5, 5) != fx_from_frac(3, 5) { return 11 }
55 // 12: Precision@2 = 1/2
56 if ie_precision_at_k(r1, 5, 2) != half { return 12 }
57 // 13: AP of [1,0,1,0,1], tot=3 = (1 + 2/3 + 3/5)/3 = 49515 in Q16.16
58 if ie_ap(r1, 5, 3) != 49515 { return 13 }
59 // 14: no relevant doc within the window -> MRR 0 (fail-closed)
60 if ie_mrr(r2, 1) != 0 { return 14 }
61
62 return 0
63}