nx_dr_ocm_cli.nx source
↩ module page · 89 lines · 4363 B
1// nx_dr_ocm_cli.nx -- callable MCP/API surface for the opportunity-cost ranker (DR-6).
2// Ranks candidate research vectors by Priority=(V*M)/C, reports each pick's
3// OPPORTUNITY COST (forgone best alternative), and does budget-aware greedy selection.
4// nx_dr_ocm <budget> [v m c]... v=value m=momentum c=cost (per vector, 3 ints)
5// e.g. nx_dr_ocm 10 8 9 3 9 8 6 5 10 1 10 10 10
6// -> {"tool":"nx_dr_ocm","selected":3,"spent":10,"forgone_priority":10000,"ranking":[...]}
7// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
8import "nx_dr_ocm.nx"
9import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
10import "nx_syscalls.nx"
11
12func oc_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
13func oc_q() -> i64 { let b: *u8 = sys_mmap(1); b[0] = 34 as u8; sys_write(1, b, 1); return 0 }
14func oc_key(name: *u8) -> i64 { oc_q(); oc_puts(name); oc_q(); oc_puts(":" as *u8); return 0 }
15// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
16// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
17// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
18// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
19func oc_num(v: i64) -> i64 { nxi_out(v); return 0 }
20func oc_atoi(a: *u8) -> i64 {
21 var v: i64 = 0; var i: i64 = 0
22 while a[i] != (0 as u8) {
23 let ch: i64 = a[i] as i64
24 if ch >= 48 { if ch <= 57 { v = v * 10 + (ch - 48) } }
25 i = i + 1
26 }
27 return v
28}
29
30func main(argc: i64, argv: *i64) -> i64 {
31 if argc < 2 { oc_puts("{" as *u8); oc_key("error" as *u8); oc_q(); oc_puts("usage: nx_dr_ocm <budget> [v m c]..." as *u8); oc_q(); oc_puts("}\n" as *u8); sys_exit(2); return 2 }
32 let budget: i64 = oc_atoi(argv[1] as *u8)
33 let n: i64 = (argc - 2) / 3
34 if n <= 0 { oc_puts("{" as *u8); oc_key("error" as *u8); oc_q(); oc_puts("need >=1 vector: v m c" as *u8); oc_q(); oc_puts("}\n" as *u8); sys_exit(1); return 1 }
35
36 let v: *i64 = sys_mmap(n * 8) as *i64
37 let m: *i64 = sys_mmap(n * 8) as *i64
38 let c: *i64 = sys_mmap(n * 8) as *i64
39 var t: i64 = 0
40 while t < n {
41 v[t] = oc_atoi(argv[2 + t * 3] as *u8)
42 m[t] = oc_atoi(argv[2 + t * 3 + 1] as *u8)
43 c[t] = oc_atoi(argv[2 + t * 3 + 2] as *u8)
44 t = t + 1
45 }
46
47 let pr: *i64 = sys_mmap(n * 8) as *i64
48 ocm_fill_priorities(v, m, c, n, pr)
49 let ord: *i64 = sys_mmap(n * 8) as *i64
50 ocm_rank(pr, n, ord)
51 let oc: *i64 = sys_mmap(n * 8) as *i64
52 ocm_opp_cost(pr, ord, n, oc)
53 let sel: *i64 = sys_mmap(n * 8) as *i64
54 let spent: *i64 = sys_mmap(8) as *i64
55 let cnt: i64 = ocm_select(pr, c, ord, n, budget, sel, spent)
56
57 var forgone: i64 = 0
58 var i: i64 = 0
59 while i < n { if sel[i] == 0 { forgone = forgone + pr[i] } i = i + 1 }
60
61 oc_puts("{" as *u8)
62 oc_key("tool" as *u8); oc_q(); oc_puts("nx_dr_ocm" as *u8); oc_q(); oc_puts("," as *u8)
63 oc_key("n" as *u8); oc_num(n); oc_puts("," as *u8)
64 oc_key("budget" as *u8); oc_num(budget); oc_puts("," as *u8)
65 oc_key("selected" as *u8); oc_num(cnt); oc_puts("," as *u8)
66 oc_key("spent" as *u8); oc_num(spent[0]); oc_puts("," as *u8)
67 oc_key("forgone_priority" as *u8); oc_num(forgone); oc_puts("," as *u8)
68 oc_key("ranking" as *u8); oc_puts("[" as *u8)
69 var r: i64 = 0
70 while r < n {
71 if r > 0 { oc_puts("," as *u8) }
72 let id: i64 = ord[r]
73 oc_puts("{" as *u8)
74 oc_key("rank" as *u8); oc_num(r + 1); oc_puts("," as *u8)
75 oc_key("id" as *u8); oc_num(id); oc_puts("," as *u8)
76 oc_key("value" as *u8); oc_num(v[id]); oc_puts("," as *u8)
77 oc_key("momentum" as *u8); oc_num(m[id]); oc_puts("," as *u8)
78 oc_key("cost" as *u8); oc_num(c[id]); oc_puts("," as *u8)
79 oc_key("priority" as *u8); oc_num(pr[id]); oc_puts("," as *u8)
80 oc_key("opportunity_cost" as *u8); oc_num(oc[r]); oc_puts("," as *u8)
81 oc_key("selected" as *u8); oc_num(sel[id])
82 oc_puts("}" as *u8)
83 r = r + 1
84 }
85 oc_puts("]," as *u8)
86 oc_key("note" as *u8); oc_q(); oc_puts("priority=(V*M*1000)/C; opp_cost=forgone best alt; budget=greedy-by-priority; sovereign integer" as *u8); oc_q()
87 oc_puts("}\n" as *u8)
88 sys_exit(0); return 0
89}