code wiki / _hdl_build / nx_story_vm_gate.nx
nx_story_vm_gate.nx source
↩ module page · 68 lines · 3762 B
1import "nx_gate_gn.nx"
2import "nx_gate_base.nx"
3// nx_story_vm_gate.nx -- proves S-R1 (the story-graph VM) with a branch-correct playthrough + negative
4// controls. Story: N0 start -> N1 door-room -> {N2 GOOD end (needs KEY), N3 BAD end}. Flag bit0 = KEY.
5// N0 c0 "take key" -> N1, sets KEY N0 c1 "skip key" -> N1
6// N1 c0 "open door" -> N2, REQUIRES KEY N1 c1 "give up" -> N3
7// Playthrough A (take key) must reach GOOD; B (skip key) must be BLOCKED at the door then reach BAD.
8// GREEN only if every assertion holds = a real win-assert, no false green. license_tier: ORIGINAL expect_exit: 0
9import "nx_syscalls.nx"
10import "nx_story_vm.nx"
11
12func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw("
13" as *u8); return ok }
14
15func main() -> i64 {
16 let N: i64 = 4
17 let ch_target: *i64 = sys_mmap(8 * 16) as *i64
18 let ch_req: *i64 = sys_mmap(8 * 16) as *i64
19 let ch_set: *i64 = sys_mmap(8 * 16) as *i64
20 let node_is_end: *i64 = sys_mmap(8 * 8) as *i64
21 var i: i64 = 0
22 while i < 16 { ch_target[i] = -1; ch_req[i] = -1; ch_set[i] = -1; i = i + 1 }
23 node_is_end[0]=0; node_is_end[1]=0; node_is_end[2]=1; node_is_end[3]=1
24
25 // N0 (idx base 0): c0 take key -> N1 set KEY(bit0); c1 skip -> N1
26 ch_target[0]=1; ch_req[0]=-1; ch_set[0]=1
27 ch_target[1]=1; ch_req[1]=-1; ch_set[1]=-1
28 // N1 (idx base 4): c0 open door -> N2 REQ KEY(mask bit0=1); c1 give up -> N3
29 ch_target[4]=2; ch_req[4]=1; ch_set[4]=-1
30 ch_target[5]=3; ch_req[5]=-1; ch_set[5]=-1
31
32 var pass: i64 = 0
33 var total: i64 = 0
34
35 // ---- PLAYTHROUGH A: take the key -> GOOD ending ----
36 let fa: *i64 = sys_mmap(8) as *i64
37 fa[0] = 0
38 var cur: i64 = 0
39 cur = sv_choose(ch_target, ch_req, ch_set, cur, 0, fa) // take key
40 total=total+1; if cur==1 { if sv_has_flag(fa,0)==1 { pass=pass+1 } else { gw("A1 FAIL no KEY\n") } } else { gw("A1 FAIL cur="); gn(cur); gw("\n") }
41 cur = sv_choose(ch_target, ch_req, ch_set, cur, 0, fa) // open door (have KEY)
42 total=total+1; if cur==2 { pass=pass+1 } else { gw("A2 FAIL cur="); gn(cur); gw("\n") }
43 total=total+1; if sv_is_end(node_is_end, cur)==1 { pass=pass+1 } else { gw("A3 FAIL not end\n") }
44
45 // ---- PLAYTHROUGH B: skip the key -> BLOCKED at door -> BAD ending ----
46 let fb: *i64 = sys_mmap(8) as *i64
47 fb[0] = 0
48 var cur2: i64 = 0
49 cur2 = sv_choose(ch_target, ch_req, ch_set, cur2, 1, fb) // skip key
50 total=total+1; if cur2==1 { if sv_has_flag(fb,0)==0 { pass=pass+1 } else { gw("B1 FAIL has KEY\n") } } else { gw("B1 FAIL\n") }
51 let blocked: i64 = sv_choose(ch_target, ch_req, ch_set, cur2, 0, fb) // open door WITHOUT key -> BLOCKED
52 total=total+1; if blocked == -1 { pass=pass+1 } else { gw("B2 FAIL not blocked, got "); gn(blocked); gw("\n") } // NEG-CONTROL
53 cur2 = sv_choose(ch_target, ch_req, ch_set, cur2, 1, fb) // give up -> BAD
54 total=total+1; if cur2==3 { pass=pass+1 } else { gw("B3 FAIL cur="); gn(cur2); gw("\n") }
55 total=total+1; if sv_is_end(node_is_end, cur2)==1 { pass=pass+1 } else { gw("B4 FAIL not end\n") }
56
57 // ---- NEG-CONTROL: invalid choice index (N0 has no c3) returns -1 ----
58 let inv: i64 = sv_choose(ch_target, ch_req, ch_set, 0, 3, fa)
59 total=total+1; if inv == -1 { pass=pass+1 } else { gw("C1 FAIL invalid-choice not -1\n") }
60
61 // ---- branch divergence: A ended GOOD(2), B ended BAD(3) = real branching ----
62 total=total+1; if cur != cur2 { pass=pass+1 } else { gw("D1 FAIL branches did not diverge\n") }
63
64 gw("STORY-VM "); gn(pass); gw("/"); gn(total); gw("\n")
65 if pass == total { gw("STORY-VM ALL-PASS (branch-correct playthrough + blocked + invalid + divergence)\n"); sys_exit(0) }
66 sys_exit(1)
67 return 1
68}