code wiki / (root) / nx_conflict.nx

nx_conflict.nx source

↩ module page · 131 lines · 4945 B

1// nx_conflict.nx -- WRITING arc, rung W-ING-5: CONTRADICTION / CONTINUITY conflict 2// detection within a scene. Model: mutually-exclusive AXES. Terms that share an 3// axis id are mutually exclusive values of one attribute (facing: forward/backward/ 4// left/right ; dress-color: red/blue ; posture: standing/sitting ; time: day/night). 5// If two DIFFERENT terms of the SAME axis both appear in a scene, that is a 6// conflict -- the case the operator named: "facing forward" + "facing backward". 7// 8// Same term repeated is NOT a conflict (consistent). Different axes both present 9// is NOT a conflict (orthogonal). Per-scene by design: a character turning around 10// BETWEEN scenes is legitimate movement, not a contradiction. 11// 12// cf_detect(t, a, b, terms, axes, nterms, naxes, out) -> nconflicts 13// out[c*3+0]=axis id, out[c*3+1]=first term index, out[c*3+2]=second term index 14// (first conflicting pair per axis; caller allocates out >= naxes*3 i64) 15// 16// Pure integer, NO syscalls. Reuses nx_ingest whole-word counter (DRY) so 17// "forwards" never matches "forward". 18// 19// license_tier: ORIGINAL 20// module: nishi-core.write.conflict 21// depends: nishi-core.write.ingest 22// capability: WRITE_CONFLICT_DETECT 23import "nx_ingest.nx" 24import "nx_ingest_scene.nx" // ig_* scene/entity extractor 25 26func cf_detect(t: *u8, a: i64, b: i64, terms: *u8, axes: *i64, nterms: i64, naxes: i64, out: *i64) -> i64 { 27 var nconf: i64 = 0 28 var ax: i64 = 0 29 while ax < naxes { 30 var first: i64 = 0 - 1 31 var done: i64 = 0 32 var k: i64 = 0 33 while k < nterms { 34 if done == 0 { 35 if axes[k] == ax { 36 let off: i64 = ig_name_off(terms, k) 37 if ig_count_name_in(t, a, b, terms, off) > 0 { 38 if first < 0 { 39 first = k 40 } else { 41 out[nconf * 3 + 0] = ax 42 out[nconf * 3 + 1] = first 43 out[nconf * 3 + 2] = k 44 nconf = nconf + 1 45 done = 1 46 } 47 } 48 } 49 } 50 k = k + 1 51 } 52 ax = ax + 1 53 } 54 return nconf 55} 56 57// ---- per-character attribution (avoids the multi-character false positive) ---- 58 59// the character whose name occurs LATEST before position p within [a,p); -1 if none. 60// this is the "owner" of a descriptor occurring at p (nearest preceding mention). 61func cf_owner_at(t: *u8, a: i64, p: i64, roster: *u8, nnames: i64) -> i64 { 62 var bestq: i64 = a - 1 63 var bestc: i64 = 0 - 1 64 var c: i64 = 0 65 while c < nnames { 66 let off: i64 = ig_name_off(roster, c) 67 var q: i64 = a 68 while q < p { 69 if ig_match_at(t, q, p, roster, off) == 1 { 70 if q > bestq { bestq = q; bestc = c } 71 } 72 q = q + 1 73 } 74 c = c + 1 75 } 76 return bestc 77} 78 79// 1 if any whole-word occurrence of the term at terms[off] in t[a..b) is owned by char c 80func cf_term_owned(t: *u8, a: i64, b: i64, terms: *u8, off: i64, roster: *u8, nnames: i64, c: i64) -> i64 { 81 var p: i64 = a 82 while p < b { 83 if ig_match_at(t, p, b, terms, off) == 1 { 84 if cf_owner_at(t, a, p, roster, nnames) == c { return 1 } 85 var l: i64 = 0 86 while terms[off + l] != (0 as u8) { l = l + 1 } 87 p = p + l 88 } else { 89 p = p + 1 90 } 91 } 92 return 0 93} 94 95// per-character conflict: same character with >=2 distinct values of one axis. 96// out[c*4+0]=char idx, +1=axis, +2=term_i, +3=term_j. Returns conflict count. 97func cf_detect_owned(t: *u8, a: i64, b: i64, roster: *u8, nnames: i64, terms: *u8, axes: *i64, nterms: i64, naxes: i64, out: *i64) -> i64 { 98 var nconf: i64 = 0 99 var c: i64 = 0 100 while c < nnames { 101 var ax: i64 = 0 102 while ax < naxes { 103 var first: i64 = 0 - 1 104 var done: i64 = 0 105 var k: i64 = 0 106 while k < nterms { 107 if done == 0 { 108 if axes[k] == ax { 109 let off: i64 = ig_name_off(terms, k) 110 if cf_term_owned(t, a, b, terms, off, roster, nnames, c) == 1 { 111 if first < 0 { 112 first = k 113 } else { 114 out[nconf * 4 + 0] = c 115 out[nconf * 4 + 1] = ax 116 out[nconf * 4 + 2] = first 117 out[nconf * 4 + 3] = k 118 nconf = nconf + 1 119 done = 1 120 } 121 } 122 } 123 } 124 k = k + 1 125 } 126 ax = ax + 1 127 } 128 c = c + 1 129 } 130 return nconf 131}