nx_recall_scale_gate.nx source
↩ module page · 70 lines · 3100 B
1// nx_recall_scale_gate.nx -- SCALE-ENVELOPE gate for the recall stack (the F227 scale-law:
2// fixture-proven-only tools with undeclared caps = false signals worse than gaps).
3// Proves nx_ir_eval + nx_recall_fuse + nx_recall_rerank CORRECT at N=2048 (three orders of
4// magnitude past the 5-doc fixtures) and DECLARES the envelope. exit 0 = pass, N = failed.
5//
6// DECLARED ENVELOPE (honest): metrics exact at any n (O(n) sums; i64 headroom); the fusion/
7// rerank ORDERING helpers are selection-sort O(n^2) -- correct at any n, sized for post-BM25
8// shortlists (<= ~4k candidates); a 100k+ SERP re-sort needs a heap/merge rung (future, named).
9
10import "fx.nx"
11import "nx_ir_eval.nx"
12import "nx_recall_fuse.nx"
13import "nx_recall_rerank.nx"
14import "syscalls.nx"
15
16const SG_N: i64 = 2048
17
18func main() -> i64 {
19 let one: i64 = fx_from_int(1)
20
21 // ---- ruler at scale ----
22 // ideal ranking: strictly descending gains 2048..1 -> nDCG MUST be exactly 1.0
23 let gi: *i64 = sys_mmap(SG_N * 8) as *i64
24 var i: i64 = 0
25 while i < SG_N { gi[i] = SG_N - i; i = i + 1 }
26 if ie_ndcg_at_k(gi, SG_N, SG_N) != one { return 1 }
27 // worst ranking (ascending) -> strictly < 1.0 and > 0
28 let gw: *i64 = sys_mmap(SG_N * 8) as *i64
29 i = 0
30 while i < SG_N { gw[i] = i + 1; i = i + 1 }
31 let nw: i64 = ie_ndcg_at_k(gw, SG_N, SG_N)
32 if nw >= one { return 2 }
33 if nw <= 0 { return 3 }
34 // sparse rels at scale: single relevant at rank 1024 -> MRR exactly 1/1024
35 let rs: *i64 = sys_mmap(SG_N * 8) as *i64
36 i = 0
37 while i < SG_N { rs[i] = 0; i = i + 1 }
38 rs[1023] = 1
39 if ie_mrr(rs, SG_N) != fx_from_frac(1, 1024) { return 4 }
40 if ie_recall_at_k(rs, SG_N, 1023, 1) != 0 { return 5 }
41 if ie_recall_at_k(rs, SG_N, 1024, 1) != one { return 6 }
42
43 // ---- fusion at scale ----
44 // ranker A = identity order, ranker B = reverse order; every id appears in both.
45 // id 0: A-rank 1 + B-rank 2048; id 2047: A-rank 2048 + B-rank 1 -> symmetric fused
46 // scores; the argmax must be a BOTH-STRONG item, and symmetry must hold exactly.
47 let oa: *i64 = sys_mmap(SG_N * 8) as *i64
48 let ob: *i64 = sys_mmap(SG_N * 8) as *i64
49 i = 0
50 while i < SG_N { oa[i] = i; ob[i] = SG_N - 1 - i; i = i + 1 }
51 let sc: *i64 = sys_mmap(SG_N * 8) as *i64
52 rf_fuse(oa, SG_N, ob, SG_N, SG_N, sc)
53 // exact endpoint symmetry: score(0) == score(2047)
54 if sc[0] != sc[SG_N - 1] { return 7 }
55 // every score positive (no dropped candidate = no silent truncation)
56 i = 0
57 while i < SG_N { if sc[i] <= 0 { return 8 } i = i + 1 }
58 // ---- rerank ordering at scale ----
59 // strictly increasing "cosine" vector -> rr_order_by_cos must emit the exact reverse
60 // permutation, all 2048 distinct (no silent cap, no duplicate emission).
61 let cs: *i64 = sys_mmap(SG_N * 8) as *i64
62 i = 0
63 while i < SG_N { cs[i] = i - 1000; i = i + 1 } // spans negative -> positive
64 let ord: *i64 = sys_mmap(SG_N * 8) as *i64
65 rr_order_by_cos(cs, SG_N, ord)
66 i = 0
67 while i < SG_N { if ord[i] != SG_N - 1 - i { return 9 } i = i + 1 }
68
69 return 0
70}