nx_build_plan_sim_test.nx source
↩ module page · 84 lines · 3647 B
1// nx_build_plan_sim_test.nx -- verify build_plan simulator second
2// stone of the simulation discipline.
3//
4// Closed-form invariants:
5// (a) Null inputs -> 0 issues written
6// (b) Christus 3-process plan (total 2910min, max cure 2880min)
7// under deadline=3000min + max_cure=3000min -> 0 issues
8// (c) Same plan under deadline=1000min -> DEADLINE_MISSED, magnitude
9// = 2910-1000 = 1910 min
10// (d) Same plan under max_cure=1000min -> POST_CURE_OVERRUN issues
11// for the two parts that exceed (base 1440min, crown 2880min)
12// (e) Tight deadline + tight cure together -> multiple issues
13// (f) Issue records have correct part_id mapping
14//
15// expect_exit: 0
16// license_tier: ORIGINAL
17
18import "nx_syscalls.nx"
19import "nx_print_process.nx"
20import "nx_build_plan.nx"
21import "nx_build_plan_sim.nx"
22
23func main() -> i64 {
24 // Build the Christus 3-process plan:
25 // Body (FDM_POLYMER, 240 print, 0 cure)
26 // Base (DIW_CEMENT, 60 print, 1440 cure)
27 // Crown (FDM_METAL, 30 print, 2880 cure)
28 let plan: *NxBuildPlan = nx_build_plan_new(8)
29 let body: i64 = nx_build_plan_add_part(plan, NX_PROCESS_FDM_POLYMER, 240, 0)
30 let base: i64 = nx_build_plan_add_part(plan, NX_PROCESS_DIW_CEMENT, 60, 1440)
31 let crown: i64 = nx_build_plan_add_part(plan, NX_PROCESS_FDM_METAL, 30, 2880)
32 let total: i64 = nx_build_plan_solve(plan)
33 if total != 2910 { return 5 }
34
35 let cap: i64 = 32
36 let issues: *NxBuildPlanSimIssue = (sys_mmap(cap * NX_BUILD_PLAN_SIM_ISSUE_BYTES)) as *NxBuildPlanSimIssue
37
38 // --- (a) Null plan -> 0 issues ---
39 let n_null: i64 = nx_build_plan_sim_check(
40 0 as *NxBuildPlan, 3000, 3000, issues, cap)
41 if n_null != 0 { return 10 }
42
43 // --- (b) Slack constraints -> 0 issues ---
44 let n_slack: i64 = nx_build_plan_sim_check(plan, 3000, 3000, issues, cap)
45 if n_slack != 0 { return 20 }
46
47 // --- (c) Tight deadline -> DEADLINE_MISSED issue ---
48 let n_dead: i64 = nx_build_plan_sim_check(plan, 1000, 3000, issues, cap)
49 if n_dead != 1 { return 30 }
50 let i0: *NxBuildPlanSimIssue = issues
51 if i0.kind != NX_BUILD_SIM_ISSUE_DEADLINE_MISSED { return 31 }
52 if i0.part_id != -1 { return 32 }
53 if i0.magnitude_min != 1910 { return 33 } // 2910 - 1000
54
55 // --- (d) Tight cure -> POST_CURE_OVERRUN for base + crown ---
56 let n_cure: i64 = nx_build_plan_sim_check(plan, 3000, 1000, issues, cap)
57 if n_cure != 2 { return 40 }
58 // Both issues should be POST_CURE_OVERRUN, on parts base and crown
59 // (not body, since body has 0 cure)
60 let c0: *NxBuildPlanSimIssue = issues
61 let c1: *NxBuildPlanSimIssue = (((issues as i64) + 1 * NX_BUILD_PLAN_SIM_ISSUE_BYTES)) as *NxBuildPlanSimIssue
62 if c0.kind != NX_BUILD_SIM_ISSUE_POST_CURE_OVERRUN { return 41 }
63 if c1.kind != NX_BUILD_SIM_ISSUE_POST_CURE_OVERRUN { return 42 }
64 // Magnitudes: base = 1440-1000 = 440; crown = 2880-1000 = 1880
65 if c0.part_id != base { return 43 }
66 if c0.magnitude_min != 440 { return 44 }
67 if c1.part_id != crown { return 45 }
68 if c1.magnitude_min != 1880 { return 46 }
69
70 // --- (e) Tight deadline + tight cure -> 3 issues
71 // (DEADLINE_MISSED + 2 POST_CURE_OVERRUN) ---
72 let n_both: i64 = nx_build_plan_sim_check(plan, 1000, 1000, issues, cap)
73 if n_both != 3 { return 50 }
74
75 // --- (f) Sealed enum kinds valid ---
76 var ki: i64 = 0
77 while ki < n_both {
78 let ip: *NxBuildPlanSimIssue = (((issues as i64) + ki * NX_BUILD_PLAN_SIM_ISSUE_BYTES)) as *NxBuildPlanSimIssue
79 if nx_build_sim_issue_is_valid(ip.kind) != 1 { return 60 }
80 ki = ki + 1
81 }
82
83 return 0
84}