code wiki / _hdl_build / nx_varcensus_gate.nx

nx_varcensus_gate.nx source

↩ module page · 163 lines · 10747 B

1// nx_varcensus_gate.nx -- PROVE THE VaM CENSUS CLASSIFIER IS DATA, FIRST-MATCH, A PARTITION ON BOTH AXES, AND THAT A 2// MALFORMED RULE REFUSES. In-process over nx_varcensus_lib with fixture rules and fixture member names: no corpus is read and 3// no asset byte exists anywhere in this gate. The rules text is assembled at runtime with real TAB bytes. 4// license_tier: ORIGINAL No hw writes (Rule 26). 5import "nx_syscalls.nx" 6import "nx_gate_verdict.nx" 7import "nx_varcensus_lib.nx" 8 9const VG_TAB: i64 = 9 10const VG_LF: i64 = 10 11const VG_KEYS: i64 = 1000 12 13func vg_row(a: *i64, f0: *u8, f1: *u8, f2: *u8, f3: *u8, f4: *u8, f5: *u8) -> i64 { 14 vcl_apps(a, f0) 15 vcl_appc(a, VG_TAB) 16 vcl_apps(a, f1) 17 vcl_appc(a, VG_TAB) 18 vcl_apps(a, f2) 19 vcl_appc(a, VG_TAB) 20 vcl_apps(a, f3) 21 if vcl_slen(f4) > 0 { 22 vcl_appc(a, VG_TAB) 23 vcl_apps(a, f4) 24 vcl_appc(a, VG_TAB) 25 vcl_apps(a, f5) 26 } 27 vcl_appc(a, VG_LF) 28 return 0 29} 30func vg_ptr(s: *u8) -> i64 { return s as i64 } 31func vg_cls(rs: *i64, axis: i64, name: *u8) -> i64 { 32 let buf: *u8 = sys_mmap(vcl_slen(name) + 1) 33 let n: i64 = vcl_lower(name, vcl_slen(name), buf) 34 return vcl_classify(rs, axis, buf, n) 35} 36func vg_idx(rs: *i64, axis: i64, cls: *u8) -> i64 { 37 if axis == VCL_AX_ROLE { return vcl_counter_find(rs[VCL_RS_CLASS_ROLE] as *i64, cls, 0, vcl_slen(cls)) } 38 return vcl_counter_find(rs[VCL_RS_CLASS_FORMAT] as *i64, cls, 0, vcl_slen(cls)) 39} 40 41func main(argc: i64, argv: *i64) -> i64 { 42 let ctr: *i64 = gv_ctr() 43 gv_head("nx_varcensus_gate -- the classifier is data, first match wins, both axes partition, a malformed rule refuses" as *u8) 44 45 let rt: *i64 = vcl_arena_new(4096) 46 vcl_apps(rt, "# fixture rules for the census gate\n" as *u8) 47 vg_row(rt, "role" as *u8, "dir" as *u8, "dirent" as *u8, "/" as *u8, "" as *u8, "" as *u8) 48 vg_row(rt, "role" as *u8, "meta" as *u8, "exact" as *u8, "meta.json" as *u8, "" as *u8, "" as *u8) 49 vg_row(rt, "role" as *u8, "scene" as *u8, "prefix" as *u8, "saves/scene/" as *u8, "" as *u8, "" as *u8) 50 vg_row(rt, "role" as *u8, "person_appearance" as *u8, "prefix" as *u8, "custom/atom/person/appearance/" as *u8, "" as *u8, "" as *u8) 51 vg_row(rt, "role" as *u8, "person_morphs" as *u8, "prefix" as *u8, "custom/atom/person/morphs/" as *u8, "" as *u8, "" as *u8) 52 vg_row(rt, "role" as *u8, "hair" as *u8, "prefix" as *u8, "custom/hair/" as *u8, "" as *u8, "" as *u8) 53 vg_row(rt, "format" as *u8, "dir" as *u8, "dirent" as *u8, "/" as *u8, "" as *u8, "" as *u8) 54 vg_row(rt, "format" as *u8, "scene_json" as *u8, "prefix" as *u8, "saves/scene/" as *u8, "suffix" as *u8, ".json" as *u8) 55 vg_row(rt, "format" as *u8, "json" as *u8, "suffix" as *u8, ".json" as *u8, "" as *u8, "" as *u8) 56 vg_row(rt, "format" as *u8, "morph_vmi" as *u8, "suffix" as *u8, ".vmi" as *u8, "" as *u8, "" as *u8) 57 vg_row(rt, "format" as *u8, "image" as *u8, "suffix" as *u8, ".jpg" as *u8, "" as *u8, "" as *u8) 58 vg_row(rt, "screen" as *u8, "A" as *u8, "class" as *u8, "person_appearance" as *u8, "" as *u8, "" as *u8) 59 vg_row(rt, "screen" as *u8, "N" as *u8, "namecontains" as *u8, "look" as *u8, "" as *u8, "" as *u8) 60 vg_row(rt, "deptag" as *u8, "timeline" as *u8, "prefix" as *u8, "acidbubbles.timeline." as *u8, "" as *u8, "" as *u8) 61 let rs: *i64 = vcl_rules_parse(vcl_at(rt, 0), vcl_used(rt)) 62 63 gv_check_eq("T1 fixture rules parse with zero errors (a comment row is skipped, not counted)" as *u8, rs[VCL_RS_ERRORS], 0, ctr) 64 gv_check_eq("T1a role classes = 6 declared + the implicit other" as *u8, vcl_nclasses(rs, VCL_AX_ROLE), 7, ctr) 65 gv_check_eq("T1b format classes = 5 declared + the implicit other" as *u8, vcl_nclasses(rs, VCL_AX_FORMAT), 6, ctr) 66 gv_check_eq("T1c two screen rows and one deptag row are loaded" as *u8, rs[VCL_RS_NSCREEN] * 10 + rs[VCL_RS_NDEPTAG], 21, ctr) 67 68 // T2 FIRST MATCH WINS, and a two-condition row needs both 69 gv_check_eq("T2 a scene json takes the EARLIER two-condition row scene_json, not the later json row" as *u8, vg_cls(rs, VCL_AX_FORMAT, "Saves/scene/Creator/Pack/A.JSON" as *u8), vg_idx(rs, VCL_AX_FORMAT, "scene_json" as *u8), ctr) 70 gv_check_eq("T2a a json outside saves/scene fails the prefix condition and falls to json" as *u8, vg_cls(rs, VCL_AX_FORMAT, "Custom/Atom/Person/Pose/p.json" as *u8), vg_idx(rs, VCL_AX_FORMAT, "json" as *u8), ctr) 71 gv_check_eq("T2b matching is case-insensitive through the caller's lowercasing" as *u8, vg_cls(rs, VCL_AX_ROLE, "CUSTOM/Hair/Female/X/y.vab" as *u8), vg_idx(rs, VCL_AX_ROLE, "hair" as *u8), ctr) 72 gv_check_eq("T2c exact is exact: a nested meta.json is NOT the package meta" as *u8, vg_cls(rs, VCL_AX_ROLE, "Custom/meta.json" as *u8), rs[VCL_RS_OTHER_ROLE], ctr) 73 gv_check_eq("T2d a name no row covers lands in other" as *u8, vg_cls(rs, VCL_AX_ROLE, "luts/plut4.png" as *u8), rs[VCL_RS_OTHER_ROLE], ctr) 74 75 // T3 BOTH AXES PARTITION a fixture member list 76 let names: *i64 = vcl_arena_new(4096) 77 vcl_push(names, vg_ptr("meta.json" as *u8)) 78 vcl_push(names, vg_ptr("Custom/" as *u8)) 79 vcl_push(names, vg_ptr("Saves/scene/C/P/s.json" as *u8)) 80 vcl_push(names, vg_ptr("Saves/scene/C/P/s.jpg" as *u8)) 81 vcl_push(names, vg_ptr("Custom/Atom/Person/Morphs/female/C/a.vmi" as *u8)) 82 vcl_push(names, vg_ptr("Custom/Atom/Person/Morphs/female/C/a.vmb" as *u8)) 83 vcl_push(names, vg_ptr("Custom/Atom/Person/Appearance/C/look.vap" as *u8)) 84 vcl_push(names, vg_ptr("readme.txt" as *u8)) 85 let nn: i64 = vcl_vec_n(names) 86 let rc_role: *i64 = sys_mmap(16 * 8) as *i64 87 let rc_fmt: *i64 = sys_mmap(16 * 8) as *i64 88 var i: i64 = 0 89 while i < nn { 90 let nm: *u8 = vcl_vec_at(names, i) as *u8 91 let r: i64 = vg_cls(rs, VCL_AX_ROLE, nm) 92 let f: i64 = vg_cls(rs, VCL_AX_FORMAT, nm) 93 rc_role[r] = rc_role[r] + 1 94 rc_fmt[f] = rc_fmt[f] + 1 95 i = i + 1 96 } 97 var sr: i64 = 0 98 var sf: i64 = 0 99 i = 0 100 while i < vcl_nclasses(rs, VCL_AX_ROLE) { sr = sr + rc_role[i]; i = i + 1 } 101 i = 0 102 while i < vcl_nclasses(rs, VCL_AX_FORMAT) { sf = sf + rc_fmt[i]; i = i + 1 } 103 gv_check_eq("T3 the role axis sums to the member count" as *u8, sr, nn, ctr) 104 gv_check_eq("T3a the format axis sums to the member count" as *u8, sf, nn, ctr) 105 gv_check_eq("T3b role person_morphs holds the vmi AND the vmb" as *u8, rc_role[vg_idx(rs, VCL_AX_ROLE, "person_morphs" as *u8)], 2, ctr) 106 gv_check_eq("T3c format other holds the vmb, the vap and the txt (no rule names them in this fixture)" as *u8, rc_fmt[rs[VCL_RS_OTHER_FORMAT]], 3, ctr) 107 108 // T4 THE REAL-PERSON SCREEN: reasons from a role class count and from the package id, never adjudicated here 109 let idb: *u8 = sys_mmap(64) 110 let idn: i64 = vcl_lower("TGC.Look_Lana" as *u8, 13, idb) 111 gv_check_eq("T4 an appearance member sets reason A (bit 0) and a look token sets N (bit 13): mask 8193" as *u8, vcl_screen(rs, rc_role, idb, idn), 8193, ctr) 112 let zc: *i64 = sys_mmap(16 * 8) as *i64 113 let idb2: *u8 = sys_mmap(64) 114 let idn2: i64 = vcl_lower("AcidBubbles.Timeline" as *u8, 20, idb2) 115 gv_check_eq("neg-control-T4a a plugin package with no appearance member and no token is not flagged" as *u8, vcl_screen(rs, zc, idb2, idn2), 0, ctr) 116 117 // T5 DEPTAG: the prefix carries its trailing dot, so a lookalike id is not tagged 118 gv_check_eq("T5 acidbubbles.timeline.210 is tagged timeline (tag 0)" as *u8, vcl_deptag(rs, "acidbubbles.timeline.210" as *u8, 24), 0, ctr) 119 gv_check_eq("neg-control-T5a acidbubbles.timelinex.1 is NOT tagged" as *u8, vcl_deptag(rs, "acidbubbles.timelinex.1" as *u8, 23), 0 - 1, ctr) 120 121 // T6 THE COUNTER GROWS PAST ITS INITIAL SLOT TABLE WITHOUT LOSING A KEY 122 let c: *i64 = vcl_counter_new() 123 let kb: *i64 = vcl_arena_new(64) 124 i = 0 125 while i < VG_KEYS { 126 kb[VCL_A_USED] = 0 127 vcl_appc(kb, 107) 128 vcl_appn(kb, i) 129 vcl_counter_add(c, vcl_at(kb, 0), 0, vcl_used(kb), 1) 130 i = i + 1 131 } 132 vcl_counter_add(c, "k7" as *u8, 0, 2, 1) 133 gv_check_eq("T6 1000 distinct keys survive three rehashes" as *u8, vcl_counter_n(c), VG_KEYS, ctr) 134 gv_check_eq("T6a a repeated key increments, it does not duplicate" as *u8, vcl_counter_count(c, vcl_counter_find(c, "k7" as *u8, 0, 2)), 2, ctr) 135 gv_check("T6b the last key is findable after growth" as *u8, (vcl_counter_find(c, "k999" as *u8, 0, 4) >= 0) as i64, ctr) 136 gv_check_eq("neg-control-T6c a key never added is not found" as *u8, vcl_counter_find(c, "k1000" as *u8, 0, 5), 0 - 1, ctr) 137 138 // T7 A MALFORMED RULE REFUSES, WITH ITS LINE NUMBER 139 let bad: *i64 = vcl_arena_new(1024) 140 vg_row(bad, "role" as *u8, "scene" as *u8, "prefix" as *u8, "saves/scene/" as *u8, "" as *u8, "" as *u8) 141 vg_row(bad, "role" as *u8, "hair" as *u8, "startswith" as *u8, "custom/hair/" as *u8, "" as *u8, "" as *u8) 142 let rb: *i64 = vcl_rules_parse(vcl_at(bad, 0), vcl_used(bad)) 143 gv_check_eq("neg-control-T7 an unknown match kind is ONE error" as *u8, rb[VCL_RS_ERRORS], 1, ctr) 144 gv_check_eq("neg-control-T7a and the error names line 2" as *u8, rb[VCL_RS_FIRST_ERR_LINE], 2, ctr) 145 let bad2: *i64 = vcl_arena_new(1024) 146 vg_row(bad2, "screen" as *u8, "A" as *u8, "class" as *u8, "person_appearance" as *u8, "" as *u8, "" as *u8) 147 vg_row(bad2, "role" as *u8, "hair" as *u8, "prefix" as *u8, "custom/hair/" as *u8, "" as *u8, "" as *u8) 148 let rb2: *i64 = vcl_rules_parse(vcl_at(bad2, 0), vcl_used(bad2)) 149 gv_check_eq("neg-control-T7b a screen row naming an undeclared class is an error even though it precedes every class row" as *u8, rb2[VCL_RS_ERRORS], 1, ctr) 150 151 // T8 ANTI-VACUITY: an axis with no rows classifies everything as other -- a classifier that always answered its first 152 // class would pass T2 on a lucky fixture and fail here 153 let onlyrole: *i64 = vcl_arena_new(1024) 154 vg_row(onlyrole, "role" as *u8, "hair" as *u8, "prefix" as *u8, "custom/hair/" as *u8, "" as *u8, "" as *u8) 155 let ro: *i64 = vcl_rules_parse(vcl_at(onlyrole, 0), vcl_used(onlyrole)) 156 gv_check_eq("T8 a rules file with no format rows yields exactly one format class" as *u8, vcl_nclasses(ro, VCL_AX_FORMAT), 1, ctr) 157 gv_check_eq("T8a and every name lands in it" as *u8, vg_cls(ro, VCL_AX_FORMAT, "Custom/Hair/F/C/h.vab" as *u8), ro[VCL_RS_OTHER_FORMAT], ctr) 158 gv_check_eq("T8b while the role axis still separates hair from other" as *u8, vg_cls(ro, VCL_AX_ROLE, "Custom/Hair/F/C/h.vab" as *u8) * 10 + vg_cls(ro, VCL_AX_ROLE, "Saves/scene/x.json" as *u8), ro[VCL_RS_OTHER_ROLE], ctr) 159 160 let rc: i64 = gv_verdict("VARCENSUS-GATE", ctr, "fixture rules and names only, first match, two partitions, refusal on a malformed rule" as *u8) 161 sys_exit(rc) 162 return rc 163}