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}