nx_capabilities_test.nx source
↩ module page · 253 lines · 10283 B
1// nx_capabilities_test.nx -- exercise registry + units + calc + linalg
2// + render engines end-to-end.
3
4import "nx_primitive_registry.nx"
5import "nx_units.nx"
6import "nx_calc.nx"
7import "nx_linalg.nx"
8import "nx_render_cli.nx"
9import "nx_render_svg.nx"
10import "nx_chem.nx"
11
12// ===== T1: registry register + lookup + per-domain count ============
13func t1_registry() -> nx_int {
14 let r: *PrimRegistry = nx_prim_registry_new(64)
15 let id1: nx_int = nx_prim_register(r, "nx_calc_deriv" as *u8, 13, 1, NX_DOMAIN_CALC,
16 NX_COMPLEX_O_N, NX_PRIM_PROVED_NATIVE)
17 if id1 < 0 { return 1 }
18 let id2: nx_int = nx_prim_register(r, "nx_mat_mul" as *u8, 10, 2, NX_DOMAIN_LINALG,
19 NX_COMPLEX_O_N3, NX_PRIM_PROVED_NATIVE)
20 if id2 < 0 { return 1 }
21 let id3: nx_int = nx_prim_register(r, "nx_dim_mul" as *u8, 10, 2, NX_DOMAIN_PHYSICS,
22 NX_COMPLEX_O1, NX_PRIM_PROVED_NATIVE)
23 if id3 < 0 { return 1 }
24 if nx_prim_lookup(r, "nx_mat_mul" as *u8, 10) != id2 { return 1 }
25 if nx_prim_lookup(r, "nx_unknown" as *u8, 10) != (0 - 1) { return 1 }
26 if nx_prim_count_by_domain(r, NX_DOMAIN_CALC) != 1 { return 1 }
27 if nx_prim_count_by_status(r, NX_PRIM_PROVED_NATIVE) != 3 { return 1 }
28 return 0
29}
30
31// ===== T2: dimensional analysis -- F = m * a ========================
32func t2_dim_analysis() -> nx_int {
33 // Force = mass * acceleration. Newton dim must equal kg-dim mul accel-dim.
34 let dim_force_lhs: *Dim = nx_dim_newton()
35 let dim_force_rhs: *Dim = nx_dim_mul(nx_dim_kg(), nx_dim_acceleration())
36 if nx_dim_eq(dim_force_lhs, dim_force_rhs) != 1 { return 2 }
37
38 // Energy = mass * c^2. Joule == kg * (m/s)^2.
39 let c2: *Dim = nx_dim_pow(nx_dim_velocity(), 2)
40 let mc2: *Dim = nx_dim_mul(nx_dim_kg(), c2)
41 if nx_dim_eq(nx_dim_joule(), mc2) != 1 { return 2 }
42
43 // Power = energy / time. Watt == J / s.
44 let p: *Dim = nx_dim_div(nx_dim_joule(), nx_dim_sec())
45 if nx_dim_eq(nx_dim_watt(), p) != 1 { return 2 }
46 return 0
47}
48
49// ===== T3: physical constants attached to dim vectors ==============
50func t3_constants() -> nx_int {
51 let c: *PhysConst = nx_const_speed_of_light()
52 if c.mantissa != 299792458 { return 3 }
53 if nx_dim_eq(c.dim, nx_dim_velocity()) != 1 { return 3 }
54
55 let h: *PhysConst = nx_const_planck()
56 if nx_dim_eq(h.dim, nx_dim_mul(nx_dim_joule(), nx_dim_sec())) != 1 { return 3 }
57 return 0
58}
59
60// ===== T4: symbolic differentiation -- d/dx[x^2] = 2 * x^1 * 1 =====
61func t4_calc_deriv_power() -> nx_int {
62 let x: *Term = nx_calc_x()
63 let x2: *Term = nx_calc_pow(x, nx_calc_const_int(2))
64 let d: *Term = nx_calc_deriv(x2, NX_CALC_SYM_X)
65 // Output structure: (2 * (x ^ (2 - 1))) * 1
66 if d.kind != NX_TERM_APP { return 4 }
67 if d.sym != NX_CALC_SYM_MUL { return 4 }
68 return 0
69}
70
71// ===== T5: symbolic differentiation -- d/dx[sin(x)] = cos(x) * 1 ===
72func t5_calc_deriv_sin() -> nx_int {
73 let x: *Term = nx_calc_x()
74 let s: *Term = nx_calc_sin(x)
75 let d: *Term = nx_calc_deriv(s, NX_CALC_SYM_X)
76 if d.kind != NX_TERM_APP { return 5 }
77 if d.sym != NX_CALC_SYM_MUL { return 5 }
78 let lhs: *Term = nx_term_arg(d, 0)
79 if lhs.sym != NX_CALC_SYM_COS { return 5 }
80 return 0
81}
82
83// ===== T6: symbolic chain rule -- d/dx[sin(x^2)] = cos(x^2) * (2*x*1) =
84func t6_chain_rule() -> nx_int {
85 let x: *Term = nx_calc_x()
86 let x2: *Term = nx_calc_pow(x, nx_calc_const_int(2))
87 let s: *Term = nx_calc_sin(x2)
88 let d: *Term = nx_calc_deriv(s, NX_CALC_SYM_X)
89 if d.sym != NX_CALC_SYM_MUL { return 6 }
90 let outer: *Term = nx_term_arg(d, 0)
91 if outer.sym != NX_CALC_SYM_COS { return 6 }
92 return 0
93}
94
95// ===== T7: vector ops + dot product ================================
96func t7_vec() -> nx_int {
97 let v1: *Vec = nx_vec_new(3)
98 let _s1: nx_int = nx_vec_set(v1, 0, 1)
99 let _s2: nx_int = nx_vec_set(v1, 1, 2)
100 let _s3: nx_int = nx_vec_set(v1, 2, 3)
101 let v2: *Vec = nx_vec_new(3)
102 let _t1: nx_int = nx_vec_set(v2, 0, 4)
103 let _t2: nx_int = nx_vec_set(v2, 1, 5)
104 let _t3: nx_int = nx_vec_set(v2, 2, 6)
105 let dot: nx_int = nx_vec_dot(v1, v2)
106 if dot != 32 { return 7 } // 4 + 10 + 18
107 let sum: *Vec = nx_vec_add(v1, v2)
108 if nx_vec_get(sum, 0) != 5 { return 7 }
109 if nx_vec_get(sum, 2) != 9 { return 7 }
110 let scaled: *Vec = nx_vec_scale(v1, 3)
111 if nx_vec_get(scaled, 1) != 6 { return 7 }
112 return 0
113}
114
115// ===== T8: matrix multiplication =================================
116func t8_matmul() -> nx_int {
117 let a: *Mat = nx_mat_new(2, 2)
118 let _s1: nx_int = nx_mat_set(a, 0, 0, 1)
119 let _s2: nx_int = nx_mat_set(a, 0, 1, 2)
120 let _s3: nx_int = nx_mat_set(a, 1, 0, 3)
121 let _s4: nx_int = nx_mat_set(a, 1, 1, 4)
122 let b: *Mat = nx_mat_new(2, 2)
123 let _t1: nx_int = nx_mat_set(b, 0, 0, 5)
124 let _t2: nx_int = nx_mat_set(b, 0, 1, 6)
125 let _t3: nx_int = nx_mat_set(b, 1, 0, 7)
126 let _t4: nx_int = nx_mat_set(b, 1, 1, 8)
127 let c: *Mat = nx_mat_mul(a, b)
128 // [1 2] [5 6] [19 22]
129 // [3 4] [7 8] = [43 50]
130 if nx_mat_get(c, 0, 0) != 19 { return 8 }
131 if nx_mat_get(c, 0, 1) != 22 { return 8 }
132 if nx_mat_get(c, 1, 0) != 43 { return 8 }
133 if nx_mat_get(c, 1, 1) != 50 { return 8 }
134 let det: nx_int = nx_mat_det2(a)
135 if det != 0 - 2 { return 8 }
136 return 0
137}
138
139// ===== T9: ASCII chart renders without crashing ===================
140func t9_render() -> nx_int {
141 let data: *nx_int = (sys_mmap(48)) as *nx_int
142 data[0] = 1
143 data[1] = 4
144 data[2] = 9
145 data[3] = 16
146 data[4] = 25
147 data[5] = 36
148 let _b: nx_int = nx_render_bar(data, 6)
149 let _l: nx_int = nx_render_line(data, 6)
150 let mat: *nx_int = (sys_mmap(72)) as *nx_int
151 mat[0] = 1; mat[1] = 2; mat[2] = 3
152 mat[3] = 4; mat[4] = 5; mat[5] = 6
153 mat[6] = 7; mat[7] = 8; mat[8] = 9
154 let _m: nx_int = nx_render_matrix(mat, 3, 3)
155 return 0
156}
157
158// ===== T10: chemistry -- molar mass of H2O, CO2 =====================
159func t10_chem() -> nx_int {
160 let table: *Element = nx_chem_periodic_table()
161 let h: *Element = nx_chem_element_by_z(table, 1)
162 if h.z != 1 { return 10 }
163 if h.mass_q3 != 1008 { return 10 }
164 let o: *Element = nx_chem_element_by_z(table, 8)
165 if o.mass_q3 != 15999 { return 10 }
166 // H2O = 2*1.008 + 1*15.999 = 18.015
167 let water: *Molecule = nx_chem_water()
168 let mw: nx_int = nx_chem_molar_mass_q3(water, table)
169 if mw != 18015 { return 10 }
170 // CO2 = 12.011 + 2*15.999 = 44.009
171 let co2: *Molecule = nx_chem_co2()
172 let mc: nx_int = nx_chem_molar_mass_q3(co2, table)
173 if mc != 44009 { return 10 }
174 return 0
175}
176
177// ===== T11: SVG output -- bar chart + line plot ====================
178func t11_svg() -> nx_int {
179 let data: *nx_int = (sys_mmap(48)) as *nx_int
180 data[0] = 1
181 data[1] = 4
182 data[2] = 9
183 data[3] = 16
184 data[4] = 25
185 data[5] = 36
186 println("---- SVG bar chart (browser-native) ----" as *u8)
187 let _b: nx_int = nx_svg_bar_chart(data, 6, "y = x^2 (bar)" as *u8)
188 println("---- SVG line plot (browser-native) ----" as *u8)
189 let _l: nx_int = nx_svg_line_plot(data, 6, "y = x^2 (line)" as *u8)
190 return 0
191}
192
193func main() -> nx_exit {
194 println("=== nx_capabilities -- registry + physics + calc + linalg + render ===" as *u8)
195
196 let r1: nx_int = t1_registry()
197 if r1 != 0 { println("T1 registry FAIL" as *u8); return r1 }
198 println("T1 registry PASS callable-by-name dispatch + per-domain count" as *u8)
199
200 let r2: nx_int = t2_dim_analysis()
201 if r2 != 0 { println("T2 dim_analysis FAIL" as *u8); return r2 }
202 println("T2 dim_analysis PASS F=ma, E=mc^2, P=E/t verify dimensionally" as *u8)
203
204 let r3: nx_int = t3_constants()
205 if r3 != 0 { println("T3 constants FAIL" as *u8); return r3 }
206 println("T3 constants PASS c, h, G, e shipped with attached dims" as *u8)
207
208 let r4: nx_int = t4_calc_deriv_power()
209 if r4 != 0 { println("T4 deriv_power FAIL" as *u8); return r4 }
210 println("T4 deriv_power PASS d/dx[x^2] symbolic structure correct" as *u8)
211
212 let r5: nx_int = t5_calc_deriv_sin()
213 if r5 != 0 { println("T5 deriv_sin FAIL" as *u8); return r5 }
214 println("T5 deriv_sin PASS d/dx[sin x] = cos(x) * 1 chain rule" as *u8)
215
216 let r6: nx_int = t6_chain_rule()
217 if r6 != 0 { println("T6 chain_rule FAIL" as *u8); return r6 }
218 println("T6 chain_rule PASS d/dx[sin(x^2)] composes correctly" as *u8)
219
220 let r7: nx_int = t7_vec()
221 if r7 != 0 { println("T7 vec FAIL" as *u8); return r7 }
222 println("T7 vec PASS vector add + scale + dot product" as *u8)
223
224 let r8: nx_int = t8_matmul()
225 if r8 != 0 { println("T8 matmul FAIL" as *u8); return r8 }
226 println("T8 matmul PASS 2x2 matrix multiplication + determinant" as *u8)
227
228 let r9: nx_int = t9_render()
229 if r9 != 0 { println("T9 render FAIL" as *u8); return r9 }
230 println("T9 render PASS ASCII bar + line plot + matrix display" as *u8)
231
232 let r10: nx_int = t10_chem()
233 if r10 != 0 { println("T10 chem FAIL" as *u8); return r10 }
234 println("T10 chem PASS H2O molar mass = 18.015 g/mol; CO2 = 44.009" as *u8)
235
236 let r11: nx_int = t11_svg()
237 if r11 != 0 { println("T11 svg FAIL" as *u8); return r11 }
238 println("T11 svg PASS browser-native SVG bar + line plot" as *u8)
239
240 println("" as *u8)
241 println("=== Domain audit ===" as *u8)
242 println(" LOGIC v2 kernel + nx_prove_propositional (prior commits)" as *u8)
243 println(" ARITH nx_arith.nx (prior commit)" as *u8)
244 println(" PROOF nx_tactics + auto-prover + emitter (prior commits)" as *u8)
245 println(" PROB nx_probability + Kolmogorov (prior commit)" as *u8)
246 println(" PHYSICS nx_units + 7-D dim analysis + consts NEW" as *u8)
247 println(" CALC nx_calc symbolic deriv + chain rule NEW" as *u8)
248 println(" LINALG nx_linalg vec + matmul + det NEW" as *u8)
249 println(" RENDER nx_render_cli ASCII charts native NEW" as *u8)
250 println(" CHEM nx_chem periodic table + molar mass NEW" as *u8)
251 println(" RENDER/SVG nx_render_svg browser-native SVG NEW" as *u8)
252 return 0
253}