code wiki / _hdl_build / nx_worldsim_gate.nx
nx_worldsim_gate.nx source
↩ module page · 219 lines · 8851 B
1// nx_worldsim_gate.nx -- CERTIFICATION of nx_worldsim (gamebench rank 1, hard GAP, Strive:Conquest keystone).
2// T1 ★CONSERVATION -- 500 randomised trades move wealth without minting or burning a single unit
3// T2 ★SYMMETRIC RELATIONS -- rel(A,B) and rel(B,A) can never disagree, after arbitrary one-sided edits
4// T3 ACCOUNTED PRODUCTION -- a tick adds EXACTLY ws_production(), no more, no less
5// T4 DETERMINISM -- two worlds, same seed, 200 ticks -> identical state
6// T5 BOUNDED -- relations clamp to [-1000,1000]; resources never go negative; overdraw is refused
7// T6 NO SELF-DEALING -- a faction cannot trade with itself or edit its own relation
8// T7 ★ANTI-VACUITY -- the world actually EVOLVES (wealth grows, relations move). A frozen world would
9// satisfy conservation, symmetry and determinism perfectly while simulating nothing.
10// T8 composes with nx_gamesave: a whole world arena round-trips through save/load
11// license_tier: ORIGINAL expect_exit: 0
12import "nx_syscalls.nx"
13import "nx_worldsim.nx"
14import "nx_gamesave.nx"
15
16func ww(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
17func wn(v: i64) -> i64 {
18 if v==0 { sys_write(1,"0" as *u8,1); return 0 }
19 var m: i64=v; if m<0 { sys_write(1,"-" as *u8,1); m=0-m }
20 let t: *u8=sys_mmap(32); var k: i64=0
21 while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 }
22 let o: *u8=sys_mmap(32); var q: i64=k-1; var i: i64=0
23 while q>=0 { o[i]=t[q]; i=i+1; q=q-1 }
24 sys_write(1,o,i); return 0
25}
26func seedworld(a: *i64, n: i64, seed: i64) -> i64 {
27 ws_init(a, n, seed)
28 var i: i64 = 0
29 while i < n {
30 ws_set_res(a, i, 1000 + i*250)
31 ws_set_pop(a, i, 500 + i*100)
32 ws_set_terr(a, i, 3 + i)
33 i = i + 1
34 }
35 return 0
36}
37
38func main() -> i64 {
39 ww("=== nx_worldsim_gate: is the faction/economy world sim safe to build a campaign on? ===\n\n")
40 var pass: i64 = 0
41 var checks: i64 = 0
42 let N: i64 = 6
43 let a: *i64 = sys_mmap(ws_bytes(N)) as *i64
44
45 // ---------- T1 conservation ----------
46 checks = checks + 1
47 seedworld(a, N, 12345)
48 let before: i64 = ws_total_res(a)
49 var moved: i64 = 0
50 var t: i64 = 0
51 while t < 500 {
52 let f: i64 = ws_rng(a) % N
53 let g: i64 = ws_rng(a) % N
54 let amt: i64 = ws_rng(a) % 400
55 moved = moved + ws_trade(a, f, g, amt)
56 t = t + 1
57 }
58 let after: i64 = ws_total_res(a)
59 var neg: i64 = 0
60 var i: i64 = 0
61 while i < N { if ws_res(a,i) < 0 { neg = neg + 1 } i = i + 1 }
62 if before==after { if neg==0 {
63 ww("T1 GREEN conservation: 500 trades moved "); wn(moved); wn(0)
64 ww(" units, total "); wn(before); ww(" -> "); wn(after); ww(" (exact, 0 negative balances)\n")
65 pass=pass+1
66 } }
67 if before!=after { ww("T1 RED wealth leaked/minted: "); wn(before); ww(" -> "); wn(after); ww("\n") }
68 if before==after { if neg>0 { ww("T1 RED negative balances: "); wn(neg); ww("\n") } }
69
70 // ---------- T2 symmetric relations ----------
71 checks = checks + 1
72 seedworld(a, N, 999)
73 ws_adjust_rel(a, 0, 3, 250)
74 ws_adjust_rel(a, 3, 0, 0-100) // opposite direction, same pair
75 ws_adjust_rel(a, 1, 4, 0-400)
76 ws_adjust_rel(a, 2, 5, 700)
77 var sym: i64 = 1
78 i = 0
79 while i < N {
80 var j: i64 = 0
81 while j < N {
82 if ws_rel(a,i,j) != ws_rel(a,j,i) { sym = 0 }
83 j = j + 1
84 }
85 i = i + 1
86 }
87 if sym==1 { if ws_rel(a,0,3)==150 {
88 ww("T2 GREEN relations symmetric by construction: rel(0,3)=rel(3,0)="); wn(ws_rel(a,0,3))
89 ww(" after opposing one-sided edits -- diplomacy cannot desync\n")
90 pass=pass+1
91 } }
92 if sym==0 { ww("T2 RED asymmetric relation found\n") }
93 if sym==1 { if ws_rel(a,0,3)!=150 { ww("T2 RED edits did not accumulate: "); wn(ws_rel(a,0,3)); ww("\n") } }
94
95 // ---------- T3 accounted production ----------
96 checks = checks + 1
97 seedworld(a, N, 4242)
98 let RATE: i64 = 7
99 let pre: i64 = ws_total_res(a)
100 let expect: i64 = ws_production(a, RATE)
101 ws_tick(a, RATE)
102 let post: i64 = ws_total_res(a)
103 if post - pre == expect { if expect > 0 {
104 ww("T3 GREEN production accounted: tick added exactly "); wn(expect)
105 ww(" (predicted == actual), total "); wn(pre); ww(" -> "); wn(post); ww("\n")
106 pass=pass+1
107 } }
108 if post - pre != expect {
109 ww("T3 RED production unaccounted: expected +"); wn(expect); ww(" got +"); wn(post-pre); ww("\n")
110 }
111
112 // ---------- T4 determinism ----------
113 checks = checks + 1
114 let w1: *i64 = sys_mmap(ws_bytes(N)) as *i64
115 let w2: *i64 = sys_mmap(ws_bytes(N)) as *i64
116 seedworld(w1, N, 777); seedworld(w2, N, 777)
117 var k: i64 = 0
118 while k < 200 { ws_tick(w1, 5); ws_tick(w2, 5); k = k + 1 }
119 var det: i64 = 1
120 i = 0
121 while i < ws_words(N) { if w1[i]!=w2[i] { det=0 } i=i+1 }
122 if det==1 {
123 ww("T4 GREEN deterministic: 2 worlds, same seed, 200 ticks -> identical arena (tick=")
124 wn(ws_tickno(w1)); ww(", total="); wn(ws_total_res(w1)); ww(")\n")
125 pass=pass+1
126 } else { ww("T4 RED worlds diverged -- campaigns would not replay\n") }
127
128 // ---------- T5 bounded ----------
129 checks = checks + 1
130 seedworld(a, N, 31)
131 ws_adjust_rel(a, 0, 1, 999999)
132 let relhi: i64 = ws_rel(a,0,1)
133 ws_adjust_rel(a, 2, 3, 0-999999)
134 let rello: i64 = ws_rel(a,2,3)
135 ws_set_res(a, 4, 100)
136 let over: i64 = ws_trade(a, 4, 5, 100000) // overdraw attempt
137 let left: i64 = ws_res(a, 4)
138 var t5: i64 = 0
139 if relhi==WS_RELMAX { if rello==WS_RELMIN { if over==100 { if left==0 { t5=1 } } } }
140 if t5==1 {
141 ww("T5 GREEN bounded: rel clamps "); wn(rello); ww("/"); wn(relhi)
142 ww("; overdraw of 100000 moved only the "); wn(over); ww(" held, balance "); wn(left); ww("\n")
143 pass=pass+1
144 } else {
145 ww("T5 RED bounds breached: relhi="); wn(relhi); ww(" rello="); wn(rello)
146 ww(" moved="); wn(over); ww(" left="); wn(left); ww("\n")
147 }
148
149 // ---------- T6 no self-dealing ----------
150 checks = checks + 1
151 seedworld(a, N, 55)
152 let r0: i64 = ws_res(a,0)
153 let self_trade: i64 = ws_trade(a, 0, 0, 500)
154 let selfrel_before: i64 = ws_rel(a,2,2)
155 ws_adjust_rel(a, 2, 2, 0-500)
156 let selfrel_after: i64 = ws_rel(a,2,2)
157 var t6: i64 = 0
158 if self_trade==0 { if ws_res(a,0)==r0 { if selfrel_before==selfrel_after { t6=1 } } }
159 if t6==1 {
160 ww("T6 GREEN no self-dealing: self-trade refused (balance unchanged "); wn(r0)
161 ww("), self-relation immutable\n"); pass=pass+1
162 } else { ww("T6 RED self-dealing permitted, moved="); wn(self_trade); ww("\n") }
163
164 // ---------- T7 anti-vacuity ----------
165 checks = checks + 1
166 seedworld(a, N, 20260720)
167 let v0_total: i64 = ws_total_res(a)
168 let v0_rel: i64 = ws_rel(a,0,1)
169 var relmoved: i64 = 0
170 k = 0
171 while k < 300 {
172 ws_tick(a, 4)
173 if ws_rel(a,0,1) != v0_rel { relmoved = 1 }
174 k = k + 1
175 }
176 let v1_total: i64 = ws_total_res(a)
177 var t7: i64 = 0
178 if v1_total > v0_total { if ws_tickno(a)==300 { if relmoved==1 { t7=1 } } }
179 if t7==1 {
180 ww("T7 GREEN anti-vacuity: 300 ticks grew wealth "); wn(v0_total); ww(" -> "); wn(v1_total)
181 ww(" and relations moved -- the world actually simulates\n"); pass=pass+1
182 } else {
183 ww("T7 RED world is frozen: total "); wn(v0_total); ww(" -> "); wn(v1_total)
184 ww(" relmoved="); wn(relmoved); ww("\n")
185 }
186
187 // ---------- T8 composes with nx_gamesave ----------
188 checks = checks + 1
189 let WP: *u8 = "knowledge/nx_worldsim_world.sav" as *u8
190 sys_unlinkat(WP)
191 let words: i64 = ws_words(N)
192 let wrote: i64 = gs_save(WP, 60613, a, words, 1784579500)
193 let rd: *i64 = sys_mmap(ws_bytes(N)) as *i64
194 let got: i64 = gs_load(WP, rd, words, 0 as *i64)
195 var t8: i64 = 1
196 if got != words { t8=0 }
197 if wrote <= 0 { t8=0 }
198 i = 0
199 while i < words { if rd[i]!=a[i] { t8=0 } i=i+1 }
200 // and the restored world must keep simulating identically
201 if t8==1 {
202 let cont: *i64 = sys_mmap(ws_bytes(N)) as *i64
203 i = 0
204 while i < words { cont[i]=rd[i]; i=i+1 }
205 ws_tick(a, 4); ws_tick(cont, 4)
206 i = 0
207 while i < words { if cont[i]!=a[i] { t8=0 } i=i+1 }
208 }
209 if t8==1 {
210 ww("T8 GREEN composes with nx_gamesave: "); wn(N); ww("-faction world ("); wn(words)
211 ww(" words, "); wn(wrote); ww("B) round-tripped AND resumed simulating identically\n")
212 pass=pass+1
213 } else { ww("T8 RED world did not survive save/load or diverged on resume, rc="); wn(got); ww("\n") }
214
215 ww("\n=== nx_worldsim_gate "); wn(pass); ww("/"); wn(checks)
216 if pass == checks { ww(" verdict=GREEN ===\n"); return 0 }
217 ww(" RED ===\n")
218 return 1
219}