nx_caplab_products_test.nx source
↩ module page · 95 lines · 4323 B
1// nx_caplab_products_test.nx -- gate for Capitalism Lab R5 (products + categories).
2//
3// Proves: (1) two category markets resolve independently, (2) per-product P&L,
4// (3) a firm's PORTFOLIO profit sums across its products, (4) a bigger category
5// yields more total sales, (5) capacity caps within a category, (6) each
6// category's split is CONSERVED.
7
8import "nx_syscalls.nx"
9import "nx_runtime.nx"
10import "nx_tier.nx"
11import "nx_caplab_products.nx"
12
13func nx_assert_eq(label: *u8, got: nx_int, want: nx_int, pass_n: *nx_int, fail_n: *nx_int) {
14 print(label); print(": got=" as *u8); print_i64(got); print(" want=" as *u8); print_i64(want)
15 if got == want { println(" PASS" as *u8); pass_n[0] = pass_n[0] + 1; return }
16 println(" FAIL" as *u8); fail_n[0] = fail_n[0] + 1
17}
18
19func nx_assert_gt(label: *u8, got: nx_int, floor: nx_int, pass_n: *nx_int, fail_n: *nx_int) {
20 print(label); print(": got=" as *u8); print_i64(got); print(" > " as *u8); print_i64(floor)
21 if got > floor { println(" PASS" as *u8); pass_n[0] = pass_n[0] + 1; return }
22 println(" FAIL" as *u8); fail_n[0] = fail_n[0] + 1
23}
24
25func mk2(a: nx_int, b: nx_int) -> *i64 {
26 let p: *i64 = (sys_mmap(16)) as *i64
27 p[0] = a
28 p[1] = b
29 return p
30}
31
32func main() -> nx_exit {
33 let pass_n: *nx_int = (sys_mmap(8)) as *nx_int
34 let fail_n: *nx_int = (sys_mmap(8)) as *nx_int
35 pass_n[0] = 0
36 fail_n[0] = 0
37 let wp: nx_int = 1
38 let wq: nx_int = 2
39 let wb: nx_int = 1
40
41 println("=== CAPLAB R5: products + categories ===" as *u8)
42
43 // --- Category A "Soda": choke 100, M 120. firm0 cheap, firm1 premium ---
44 let aPr: *i64 = mk2(40, 60)
45 let aQ: *i64 = mk2(0, 30)
46 let aB: *i64 = mk2(0, 20)
47 let aCap: *i64 = mk2(100, 100)
48 let aSold: *i64 = mk2(0, 0)
49 nx_clab_category_run(2, aPr, aQ, aB, 100, wp, wq, wb, 120, aCap, aSold)
50 nx_assert_eq("catA: firm0 sold " as *u8, aSold[0], 40, pass_n, fail_n)
51 nx_assert_eq("catA: firm1 sold " as *u8, aSold[1], 80, pass_n, fail_n)
52 nx_assert_eq("catA: conserved (=120) " as *u8, aSold[0] + aSold[1], 120, pass_n, fail_n)
53
54 // --- Category B "Shoes": choke 80, M 60 (different market) ---
55 let bPr: *i64 = mk2(30, 50)
56 let bQ: *i64 = mk2(0, 20)
57 let bB: *i64 = mk2(0, 10)
58 let bCap: *i64 = mk2(100, 100)
59 let bSold: *i64 = mk2(0, 0)
60 nx_clab_category_run(2, bPr, bQ, bB, 80, wp, wq, wb, 60, bCap, bSold)
61 nx_assert_eq("catB: firm0 sold " as *u8, bSold[0], 23, pass_n, fail_n)
62 nx_assert_eq("catB: firm1 sold " as *u8, bSold[1], 37, pass_n, fail_n)
63 nx_assert_eq("catB: conserved (=60) " as *u8, bSold[0] + bSold[1], 60, pass_n, fail_n)
64
65 // --- Independence: A unchanged by B; bigger category sells more ---
66 nx_assert_gt("bigger cat sells more " as *u8, aSold[0] + aSold[1], bSold[0] + bSold[1], pass_n, fail_n)
67
68 // --- Per-product P&L (cost 20 each) ---
69 nx_assert_eq("product P&L (premium A)" as *u8, nx_clab_product_profit(60, 20, aSold[1]), 3200, pass_n, fail_n)
70
71 // --- Portfolio: firm totals across BOTH categories ---
72 // firm1 sells premium in A(80) + B(37): (60-20)*80 + (50-20)*37 = 3200+1110 = 4310
73 let p1: *i64 = mk2(60, 50)
74 let c1: *i64 = mk2(20, 20)
75 let s1: *i64 = mk2(aSold[1], bSold[1])
76 nx_assert_eq("portfolio firm1 total " as *u8, nx_clab_portfolio_profit(2, p1, c1, s1), 4310, pass_n, fail_n)
77 // firm0 cheap in A(40) + B(23): (40-20)*40 + (30-20)*23 = 800+230 = 1030
78 let p0: *i64 = mk2(40, 30)
79 let c0: *i64 = mk2(20, 20)
80 let s0: *i64 = mk2(aSold[0], bSold[0])
81 nx_assert_eq("portfolio firm0 total " as *u8, nx_clab_portfolio_profit(2, p0, c0, s0), 1030, pass_n, fail_n)
82 nx_assert_gt("premium firm out-earns " as *u8, nx_clab_portfolio_profit(2, p1, c1, s1), nx_clab_portfolio_profit(2, p0, c0, s0), pass_n, fail_n)
83
84 // --- Capacity caps within a category (firm1 cap 50 < demand 80) ---
85 let xCap: *i64 = mk2(100, 50)
86 let xSold: *i64 = mk2(0, 0)
87 nx_clab_category_run(2, aPr, aQ, aB, 100, wp, wq, wb, 120, xCap, xSold)
88 nx_assert_eq("catA capacity-capped " as *u8, xSold[1], 50, pass_n, fail_n)
89
90 println("" as *u8)
91 print("PASS=" as *u8); print_i64(pass_n[0])
92 print(" FAIL=" as *u8); print_i64(fail_n[0]); println("" as *u8)
93 if fail_n[0] > 0 { return 1 }
94 return 0
95}