code wiki / (root) / nx_maint_rul_test.nx

nx_maint_rul_test.nx source

↩ module page · 93 lines · 3371 B

1// nx_maint_rul_test.nx -- gate for RUL prognostics (the learning loop's prediction). 2// 3// Proves the RUL bands (plenty / plan / soon / imminent / failed), the stable 4// (not-wearing) case, and the liar-kill: the predicted life tracks the measured 5// wear RATE -- faster wear => shorter remaining life. This is the proactive 6// exceed over OBD/Sense (which only report the present). 7// 8// expect_exit: 0 9// 10// license_tier: ORIGINAL 11 12import "nx_syscalls_x86_64.nx" 13import "nx_maint_rul.nx" 14 15func main() -> i64 { 16 if nx_rul_verdict_is_valid(NX_RUL_IMMINENT) != 1 { return 1 } 17 if nx_rul_verdict_is_valid(NX_RUL_N) != 0 { return 2 } 18 19 let m: *i64 = sys_mmap(128) as *i64 20 let t: *i64 = sys_mmap(128) as *i64 21 let out: *RulEst = sys_mmap(64) as *RulEst 22 let spec: *RulSpec = sys_mmap(64) as *RulSpec 23 spec.fail_threshold = 150 24 spec.imminent_window = 5 25 spec.soon_window = 15 26 spec.plan_window = 40 27 28 // ===== PLAN: response rate declining 400->280 over 30 cycles ==== 29 m[0]=400; m[1]=360; m[2]=320; m[3]=280 30 t[0]=0; t[1]=10; t[2]=20; t[3]=30 31 nx_rul_estimate(m, t, 4, spec, out) 32 if out.verdict != NX_RUL_PLAN { return 10 } 33 if out.rul != 32 { return 11 } // ~32 cycles to failure 34 if out.wear_rate_milli != 4000 { return 12 } // 4.0 / cycle 35 if out.current != 280 { return 13 } 36 37 // ===== IMMINENT: near threshold, fast decline =================== 38 m[0]=200; m[1]=170; m[2]=158 39 t[0]=0; t[1]=10; t[2]=20 40 nx_rul_estimate(m, t, 3, spec, out) 41 if out.verdict != NX_RUL_IMMINENT { return 20 } 42 43 // ===== SOON ===================================================== 44 m[0]=215; m[1]=195; m[2]=175 45 t[0]=0; t[1]=10; t[2]=20 46 nx_rul_estimate(m, t, 3, spec, out) 47 if out.verdict != NX_RUL_SOON { return 30 } 48 49 // ===== PLENTY =================================================== 50 m[0]=500; m[1]=490; m[2]=480 51 t[0]=0; t[1]=10; t[2]=20 52 nx_rul_estimate(m, t, 3, spec, out) 53 if out.verdict != NX_RUL_PLENTY { return 40 } 54 55 // ===== STABLE: not wearing -> no predicted failure ============= 56 m[0]=400; m[1]=400; m[2]=400 57 t[0]=0; t[1]=10; t[2]=20 58 nx_rul_estimate(m, t, 3, spec, out) 59 if out.verdict != NX_RUL_STABLE { return 50 } 60 if out.rul != (0 - 1) { return 51 } 61 62 // ===== FAILED: already past threshold ========================== 63 m[0]=200; m[1]=170; m[2]=140 64 t[0]=0; t[1]=10; t[2]=20 65 nx_rul_estimate(m, t, 3, spec, out) 66 if out.verdict != NX_RUL_FAILED { return 60 } 67 if out.rul != 0 { return 61 } 68 69 // ===== BAD_ARG: zero time span ================================= 70 m[0]=400; m[1]=300 71 t[0]=0; t[1]=0 72 nx_rul_estimate(m, t, 2, spec, out) 73 if out.verdict != NX_RUL_BAD_ARG { return 70 } 74 75 // ===== INSUFFICIENT_DATA ======================================= 76 m[0]=400 77 t[0]=0 78 nx_rul_estimate(m, t, 1, spec, out) 79 if out.verdict != NX_RUL_INSUFFICIENT { return 80 } 80 81 // ===== LIAR-KILL: life tracks the wear rate ===================== 82 m[0]=400; m[1]=390 83 t[0]=0; t[1]=100 84 nx_rul_estimate(m, t, 2, spec, out) 85 let slow_rul: i64 = out.rul 86 m[0]=400; m[1]=300 87 t[0]=0; t[1]=100 88 nx_rul_estimate(m, t, 2, spec, out) 89 if out.rul >= slow_rul { return 90 } // faster wear -> SHORTER life 90 if slow_rul != 2400 { return 91 } 91 92 return 0 93}