code wiki / (root) / nx_dr_elo_gate.nx

nx_dr_elo_gate.nx source

↩ module page · 86 lines · 3681 B

1// nx_dr_elo_gate.nx -- KAT + neg-control for the sovereign Elo tournament ranker (DR-1). 2// Proves: expected-score table (equal/symmetry/gap/monotonic), correct rating updates 3// (an UPSET is rewarded more than an expected win), a real 3-player tournament ranks 4// the dominant player #1, and the NEG-CONTROL: ignoring match outcomes CANNOT 5// reproduce that ranking (outcomes drive the result). Uses the DRY nx_gate_verdict 6// lib (D001 migrate-on-touch law). exit 0 = GREEN. Sovereign lane (nx_cc->nxasm). 7import "nx_dr_elo.nx" 8import "nx_gate_verdict.nx" 9 10func main() -> i64 { 11 let ctr: *i64 = gv_ctr() 12 gv_head("nx_dr_elo -- sovereign deterministic Elo tournament ranker (DR-1)") 13 let tab: *i64 = el_make_etab() 14 15 // T1: equal ratings -> expected 500 (coin flip) 16 let e_eq: i64 = el_expected(1500, 1500, tab) 17 var ok1: i64 = 0 18 if e_eq == 500 { ok1 = 1 } 19 gv_check("T1 equal ratings expect 500", ok1, ctr) 20 21 // T2: expected-score symmetry E(a,b)+E(b,a)=1000 22 let e_ab: i64 = el_expected(1700, 1500, tab) 23 let e_ba: i64 = el_expected(1500, 1700, tab) 24 var ok2: i64 = 0 25 if (e_ab + e_ba) == 1000 { ok2 = 1 } 26 gv_check("T2 expected-score symmetry sums 1000", ok2, ctr) 27 28 // T3: a +400 stronger player expects ~909 (0.91) 29 let e_400: i64 = el_expected(1900, 1500, tab) 30 var ok3: i64 = 0 31 if e_400 >= 900 { if e_400 <= 918 { ok3 = 1 } } 32 gv_check("T3 +400 gap expects ~909", ok3, ctr) 33 34 // T4: monotonic -- bigger gap -> higher expected 35 var ok4: i64 = 0 36 if e_400 > e_ab { if e_ab > e_eq { ok4 = 1 } } 37 gv_check("T4 expected monotonic in rating gap", ok4, ctr) 38 39 // T5/T6: an UPSET (underdog 1500 beats favorite 1700) is rewarded more than a 40 // favorite's expected win; and it moves both ratings the right way. 41 let e_up: i64 = el_expected(1500, 1700, tab) 42 let up_new: i64 = el_update(1500, e_up, 1000, 32) 43 let up_gain: i64 = up_new - 1500 44 let e_fav: i64 = el_expected(1700, 1500, tab) 45 let fav_win_new: i64 = el_update(1700, e_fav, 1000, 32) 46 let fav_gain: i64 = fav_win_new - 1700 47 let fav_lose_new: i64 = el_update(1700, e_fav, 0, 32) 48 var ok5: i64 = 0 49 if up_gain > fav_gain { ok5 = 1 } 50 gv_check("T5 upset gain exceeds expected-win gain", ok5, ctr) 51 var ok6: i64 = 0 52 if up_gain > 0 { if fav_lose_new < 1700 { ok6 = 1 } } 53 gv_check("T6 upset moves ratings (underdog+ favorite-)", ok6, ctr) 54 55 // A real 3-player tournament: C(2) beats A(0) and B(1); A beats B -> rank [C,A,B]. 56 let rat: *i64 = sys_mmap(3 * 8) as *i64 57 rat[0] = 1500; rat[1] = 1500; rat[2] = 1500 58 let ma: *i64 = sys_mmap(3 * 8) as *i64 59 let mb: *i64 = sys_mmap(3 * 8) as *i64 60 let mo: *i64 = sys_mmap(3 * 8) as *i64 61 ma[0] = 2; mb[0] = 0; mo[0] = 1000 62 ma[1] = 2; mb[1] = 1; mo[1] = 1000 63 ma[2] = 0; mb[2] = 1; mo[2] = 1000 64 65 // T7 NEG-CONTROL (before running): ignoring outcomes does NOT lead C(2). 66 let ord0: *i64 = sys_mmap(3 * 8) as *i64 67 el_rank(rat, 3, ord0) 68 var ok7: i64 = 0 69 if ord0[0] != 2 { ok7 = 1 } 70 gv_check("T7 neg-control ignoring outcomes does not lead C", ok7, ctr) 71 72 // run the tournament, then re-rank 73 el_run_tournament(rat, 3, ma, mb, mo, 3, 32, tab) 74 let ord1: *i64 = sys_mmap(3 * 8) as *i64 75 el_rank(rat, 3, ord1) 76 var ok8: i64 = 0 77 if ord1[0] == 2 { ok8 = 1 } 78 gv_check("T8 tournament ranks dominant player C first", ok8, ctr) 79 var ok9: i64 = 0 80 if ord1[0] == 2 { if ord1[1] == 0 { if ord1[2] == 1 { ok9 = 1 } } } 81 gv_check("T9 full order equals C A B", ok9, ctr) 82 83 let rc: i64 = gv_verdict("DR-ELO", ctr, "Elo table+update+tournament+rank, neg-control") 84 sys_exit(rc) 85 return rc 86}