code wiki / (root) / nx_xform_gate.nx

nx_xform_gate.nx source

↩ module page · 115 lines · 6239 B

1// nx_xform_gate.nx -- proves the transform-DAG engine: topological ordering, CYCLE refusal, the three 2// data-test operators, whole-token dep matching (the subtle bug: "avg" must NOT match "avg_price"), and 3// end-to-end DESCENDANT-ONLY fail-closed skipping over the real conf + azdemo store. D001 verdict via 4// nx_gate_verdict. expect_exit: 0 license_tier: ORIGINAL 5import "nx_gate_verdict.nx" 6import "nx_xform.nx" 7 8func xg_eq(a: i64, b: i64) -> i64 { if a == b { return 1 } return 0 } 9func xg_has(hay: *u8, needle: *u8) -> i64 { 10 var hn: i64 = 0 11 while hay[hn] != (0 as u8) { hn = hn + 1 } 12 var nl: i64 = 0 13 while needle[nl] != (0 as u8) { nl = nl + 1 } 14 var i: i64 = 0 15 while i + nl <= hn { 16 var j: i64 = 0 17 var eq: i64 = 1 18 while j < nl { if hay[i+j] != needle[j] { eq = 0 } j = j + 1 } 19 if eq == 1 { return 1 } 20 i = i + 1 21 } 22 return 0 23} 24// index of id in order[] (position); -1 if absent 25func xg_pos(order: *i64, n: i64, ids: *i64, name: *u8) -> i64 { 26 var i: i64 = 0 27 while i < n { if xf_streq(ids[order[i]] as *u8, name) == 1 { return i } i = i + 1 } 28 return 0 - 1 29} 30 31func main() -> i64 { 32 let ctr: *i64 = gv_ctr() 33 gv_head("nx_xform_gate -- models as data, topo-ordered, fail-closed data-tests" as *u8) 34 35 // ---- whole-token dep matching: the subtle correctness point -------------------------------- 36 gv_check("T1 csv_has finds a whole element" as *u8, xg_eq(xf_csv_has("avg_price,max_size" as *u8, "max_size" as *u8), 1), ctr) 37 gv_check("T2 csv_has does NOT match a PREFIX (avg is not avg_price)" as *u8, xg_eq(xf_csv_has("avg_price" as *u8, "avg" as *u8), 0), ctr) 38 gv_check("T3 csv_has does NOT match a SUFFIX (price is not avg_price)" as *u8, xg_eq(xf_csv_has("avg_price" as *u8, "price" as *u8), 0), ctr) 39 gv_check("T4 a lone dash means no deps" as *u8, xg_eq(xf_csv_has("-" as *u8, "anything" as *u8), 0), ctr) 40 41 // ---- topological order on hand-built graphs ------------------------------------------------- 42 // chain: c depends on b depends on a => order must be a,b,c 43 let ids: *i64 = sys_mmap(8 * 8) as *i64 44 let deps: *i64 = sys_mmap(8 * 8) as *i64 45 ids[0] = "c" as *u8 as i64 46 deps[0] = "b" as *u8 as i64 47 ids[1] = "a" as *u8 as i64 48 deps[1] = "-" as *u8 as i64 49 ids[2] = "b" as *u8 as i64 50 deps[2] = "a" as *u8 as i64 51 let order: *i64 = sys_mmap(8 * 8) as *i64 52 let em: i64 = xf_topo(ids, deps, 3, order) 53 var t5: i64 = 0 54 if em == 3 { if xg_pos(order, 3, ids, "a" as *u8) < xg_pos(order, 3, ids, "b" as *u8) { if xg_pos(order, 3, ids, "b" as *u8) < xg_pos(order, 3, ids, "c" as *u8) { t5 = 1 } } } 55 gv_check("T5 a<-b<-c chain topo-sorts to a,b,c regardless of file order" as *u8, t5, ctr) 56 57 // diamond: d deps b,c ; b deps a ; c deps a => a first, d last 58 let id2: *i64 = sys_mmap(8 * 8) as *i64 59 let dp2: *i64 = sys_mmap(8 * 8) as *i64 60 id2[0] = "d" as *u8 as i64 61 dp2[0] = "b,c" as *u8 as i64 62 id2[1] = "b" as *u8 as i64 63 dp2[1] = "a" as *u8 as i64 64 id2[2] = "c" as *u8 as i64 65 dp2[2] = "a" as *u8 as i64 66 id2[3] = "a" as *u8 as i64 67 dp2[3] = "-" as *u8 as i64 68 let ord2: *i64 = sys_mmap(8 * 8) as *i64 69 let em2: i64 = xf_topo(id2, dp2, 4, ord2) 70 var t6: i64 = 0 71 if em2 == 4 { if xg_pos(ord2, 4, id2, "a" as *u8) == 0 { if xg_pos(ord2, 4, id2, "d" as *u8) == 3 { t6 = 1 } } } 72 gv_check("T6 a diamond (d<-b,c<-a) puts a first and d last" as *u8, t6, ctr) 73 74 // CYCLE: a<-b, b<-a => emitted < m, engine refuses 75 let id3: *i64 = sys_mmap(8 * 8) as *i64 76 let dp3: *i64 = sys_mmap(8 * 8) as *i64 77 id3[0] = "a" as *u8 as i64 78 dp3[0] = "b" as *u8 as i64 79 id3[1] = "b" as *u8 as i64 80 dp3[1] = "a" as *u8 as i64 81 let ord3: *i64 = sys_mmap(8 * 8) as *i64 82 let em3: i64 = xf_topo(id3, dp3, 2, ord3) 83 gv_check("T7 a 2-cycle emits FEWER than all models -> detected as a non-DAG" as *u8, xg_eq(em3, 0), ctr) 84 85 // ---- data-test operators (known answers) ---------------------------------------------------- 86 gv_check("T8a gt: 590 gt 400 passes" as *u8, xg_eq(xf_test(590, "gt" as *u8, 400), 1), ctr) 87 gv_check("T8b gt: 100 gt 400 fails" as *u8, xg_eq(xf_test(100, "gt" as *u8, 400), 0), ctr) 88 gv_check("T8c lt: 3 lt 10 passes" as *u8, xg_eq(xf_test(3, "lt" as *u8, 10), 1), ctr) 89 gv_check("T8d nonzero: 0 fails, 5 passes" as *u8, xg_eq(xf_test(0, "nonzero" as *u8, 0) + xf_test(5, "nonzero" as *u8, 0), 1), ctr) 90 91 // ---- END TO END over the real conf + azdemo store ------------------------------------------ 92 let out: *u8 = sys_mmap(XF_OUT) 93 xf_order_json(out) 94 gv_puts(out) 95 gv_puts("\n" as *u8) 96 gv_check("T9 order verb resolves a DAG (ok:true) over the seeded conf" as *u8, xg_has(out, "\"ok\":true" as *u8), ctr) 97 // avg_price and max_size have no deps; summary depends on both -> summary must come AFTER both 98 var t10: i64 = 0 99 if xg_has(out, "\"order\":[\"avg_price\",\"max_size\"" as *u8) == 1 { t10 = 1 } 100 gv_check("T10 the no-dep models order before the dependent summary" as *u8, t10, ctr) 101 102 xf_run_json(out) 103 gv_puts(out) 104 gv_puts("\n---\n" as *u8) 105 gv_check("T11 run computes each model metric and tests it" as *u8, xg_has(out, "\"id\":\"avg_price\",\"deps\":\"-\",\"op\":\"mean\",\"result\":" as *u8), ctr) 106 gv_check("T12 the deliberately-failing bad_check model reports pass:false" as *u8, xg_has(out, "\"id\":\"bad_check\"" as *u8), ctr) 107 gv_check("T13 its dependent is SKIPPED (descendant-only fail-closed), not silently built" as *u8, xg_has(out, "SKIPPED (a dependency failed" as *u8), ctr) 108 // the UNRELATED summary must still build -- fail-closed skips DESCENDANTS, not the whole run 109 gv_check("T14 an UNRELATED model still builds despite the failure elsewhere (not global halt)" as *u8, xg_has(out, "\"id\":\"summary\",\"deps\":\"avg_price,max_size\",\"op\":\"count\"" as *u8), ctr) 110 gv_check("T15 the pipeline is honestly marked NOT passing (a test failed)" as *u8, xg_has(out, "\"pipeline_pass\":false" as *u8), ctr) 111 112 let rc: i64 = gv_verdict("XFORM-GATE" as *u8, ctr, "transform-DAG: models as data, topo-ordered, cycle-refusing, descendant-only fail-closed tests" as *u8) 113 sys_exit(rc) 114 return rc 115}