@rsconcept/domain 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +55 -0
  3. package/dist/cctext/index.d.ts +1 -0
  4. package/dist/cctext/index.js +42 -0
  5. package/dist/cctext/index.js.map +1 -0
  6. package/dist/cctext/language-api.d.ts +43 -0
  7. package/dist/cctext/language-api.js +252 -0
  8. package/dist/cctext/language-api.js.map +1 -0
  9. package/dist/cctext/language.d.ts +58 -0
  10. package/dist/cctext/language.js +44 -0
  11. package/dist/cctext/language.js.map +1 -0
  12. package/dist/graph/graph.d.ts +62 -0
  13. package/dist/graph/graph.js +385 -0
  14. package/dist/graph/graph.js.map +1 -0
  15. package/dist/graph/index.d.ts +1 -0
  16. package/dist/graph/index.js +384 -0
  17. package/dist/graph/index.js.map +1 -0
  18. package/dist/index.d.ts +28 -0
  19. package/dist/index.js +5851 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/library/folder-tree.d.ts +32 -0
  22. package/dist/library/folder-tree.js +136 -0
  23. package/dist/library/folder-tree.js.map +1 -0
  24. package/dist/library/index.d.ts +17 -0
  25. package/dist/library/index.js +2800 -0
  26. package/dist/library/index.js.map +1 -0
  27. package/dist/library/library-api.d.ts +6 -0
  28. package/dist/library/library-api.js +13 -0
  29. package/dist/library/library-api.js.map +1 -0
  30. package/dist/library/library.d.ts +56 -0
  31. package/dist/library/library.js +23 -0
  32. package/dist/library/library.js.map +1 -0
  33. package/dist/library/oss-api.d.ts +47 -0
  34. package/dist/library/oss-api.js +1105 -0
  35. package/dist/library/oss-api.js.map +1 -0
  36. package/dist/library/oss-layout-api.d.ts +36 -0
  37. package/dist/library/oss-layout-api.js +330 -0
  38. package/dist/library/oss-layout-api.js.map +1 -0
  39. package/dist/library/oss-layout.d.ts +25 -0
  40. package/dist/library/oss-layout.js +1 -0
  41. package/dist/library/oss-layout.js.map +1 -0
  42. package/dist/library/oss.d.ts +136 -0
  43. package/dist/library/oss.js +30 -0
  44. package/dist/library/oss.js.map +1 -0
  45. package/dist/library/rsengine.d.ts +116 -0
  46. package/dist/library/rsengine.js +2604 -0
  47. package/dist/library/rsengine.js.map +1 -0
  48. package/dist/library/rsform-api.d.ts +74 -0
  49. package/dist/library/rsform-api.js +879 -0
  50. package/dist/library/rsform-api.js.map +1 -0
  51. package/dist/library/rsform.d.ts +206 -0
  52. package/dist/library/rsform.js +32 -0
  53. package/dist/library/rsform.js.map +1 -0
  54. package/dist/library/rsmodel-api.d.ts +43 -0
  55. package/dist/library/rsmodel-api.js +836 -0
  56. package/dist/library/rsmodel-api.js.map +1 -0
  57. package/dist/library/rsmodel.d.ts +52 -0
  58. package/dist/library/rsmodel.js +25 -0
  59. package/dist/library/rsmodel.js.map +1 -0
  60. package/dist/library/structure-planner.d.ts +33 -0
  61. package/dist/library/structure-planner.js +481 -0
  62. package/dist/library/structure-planner.js.map +1 -0
  63. package/dist/parsing/ast.d.ts +49 -0
  64. package/dist/parsing/ast.js +93 -0
  65. package/dist/parsing/ast.js.map +1 -0
  66. package/dist/parsing/index.d.ts +3 -0
  67. package/dist/parsing/index.js +141 -0
  68. package/dist/parsing/index.js.map +1 -0
  69. package/dist/parsing/lezer-tree.d.ts +13 -0
  70. package/dist/parsing/lezer-tree.js +50 -0
  71. package/dist/parsing/lezer-tree.js.map +1 -0
  72. package/dist/rslang/api.d.ts +53 -0
  73. package/dist/rslang/api.js +846 -0
  74. package/dist/rslang/api.js.map +1 -0
  75. package/dist/rslang/ast-annotations.d.ts +18 -0
  76. package/dist/rslang/ast-annotations.js +56 -0
  77. package/dist/rslang/ast-annotations.js.map +1 -0
  78. package/dist/rslang/error.d.ts +85 -0
  79. package/dist/rslang/error.js +159 -0
  80. package/dist/rslang/error.js.map +1 -0
  81. package/dist/rslang/eval/calculator.d.ts +43 -0
  82. package/dist/rslang/eval/calculator.js +1639 -0
  83. package/dist/rslang/eval/calculator.js.map +1 -0
  84. package/dist/rslang/eval/evaluation-cache.d.ts +36 -0
  85. package/dist/rslang/eval/evaluation-cache.js +310 -0
  86. package/dist/rslang/eval/evaluation-cache.js.map +1 -0
  87. package/dist/rslang/eval/evaluator.d.ts +70 -0
  88. package/dist/rslang/eval/evaluator.js +1514 -0
  89. package/dist/rslang/eval/evaluator.js.map +1 -0
  90. package/dist/rslang/eval/value-api.d.ts +48 -0
  91. package/dist/rslang/eval/value-api.js +490 -0
  92. package/dist/rslang/eval/value-api.js.map +1 -0
  93. package/dist/rslang/eval/value.d.ts +36 -0
  94. package/dist/rslang/eval/value.js +118 -0
  95. package/dist/rslang/eval/value.js.map +1 -0
  96. package/dist/rslang/index.d.ts +17 -0
  97. package/dist/rslang/index.js +4314 -0
  98. package/dist/rslang/index.js.map +1 -0
  99. package/dist/rslang/labels.d.ts +16 -0
  100. package/dist/rslang/labels.js +315 -0
  101. package/dist/rslang/labels.js.map +1 -0
  102. package/dist/rslang/parser/expression-generator.d.ts +10 -0
  103. package/dist/rslang/parser/expression-generator.js +451 -0
  104. package/dist/rslang/parser/expression-generator.js.map +1 -0
  105. package/dist/rslang/parser/normalize.d.ts +11 -0
  106. package/dist/rslang/parser/normalize.js +507 -0
  107. package/dist/rslang/parser/normalize.js.map +1 -0
  108. package/dist/rslang/parser/parser.d.ts +5 -0
  109. package/dist/rslang/parser/parser.js +24 -0
  110. package/dist/rslang/parser/parser.js.map +1 -0
  111. package/dist/rslang/parser/parser.terms.d.ts +42 -0
  112. package/dist/rslang/parser/parser.terms.js +84 -0
  113. package/dist/rslang/parser/parser.terms.js.map +1 -0
  114. package/dist/rslang/parser/syntax-errors.d.ts +11 -0
  115. package/dist/rslang/parser/syntax-errors.js +403 -0
  116. package/dist/rslang/parser/syntax-errors.js.map +1 -0
  117. package/dist/rslang/parser/token.d.ts +79 -0
  118. package/dist/rslang/parser/token.js +95 -0
  119. package/dist/rslang/parser/token.js.map +1 -0
  120. package/dist/rslang/semantic/analyzer.d.ts +39 -0
  121. package/dist/rslang/semantic/analyzer.js +2604 -0
  122. package/dist/rslang/semantic/analyzer.js.map +1 -0
  123. package/dist/rslang/semantic/arguments-extractor.d.ts +42 -0
  124. package/dist/rslang/semantic/arguments-extractor.js +366 -0
  125. package/dist/rslang/semantic/arguments-extractor.js.map +1 -0
  126. package/dist/rslang/semantic/type-auditor.d.ts +73 -0
  127. package/dist/rslang/semantic/type-auditor.js +1570 -0
  128. package/dist/rslang/semantic/type-auditor.js.map +1 -0
  129. package/dist/rslang/semantic/typification-api.d.ts +27 -0
  130. package/dist/rslang/semantic/typification-api.js +320 -0
  131. package/dist/rslang/semantic/typification-api.js.map +1 -0
  132. package/dist/rslang/semantic/typification-parser.d.ts +12 -0
  133. package/dist/rslang/semantic/typification-parser.js +226 -0
  134. package/dist/rslang/semantic/typification-parser.js.map +1 -0
  135. package/dist/rslang/semantic/typification.d.ts +119 -0
  136. package/dist/rslang/semantic/typification.js +74 -0
  137. package/dist/rslang/semantic/typification.js.map +1 -0
  138. package/dist/rslang/semantic/value-auditor.d.ts +43 -0
  139. package/dist/rslang/semantic/value-auditor.js +523 -0
  140. package/dist/rslang/semantic/value-auditor.js.map +1 -0
  141. package/dist/rslang/semantic/value-class.d.ts +10 -0
  142. package/dist/rslang/semantic/value-class.js +9 -0
  143. package/dist/rslang/semantic/value-class.js.map +1 -0
  144. package/dist/rslang/typification-graph.d.ts +33 -0
  145. package/dist/rslang/typification-graph.js +311 -0
  146. package/dist/rslang/typification-graph.js.map +1 -0
  147. package/dist/shared/branded.d.ts +7 -0
  148. package/dist/shared/branded.js +1 -0
  149. package/dist/shared/branded.js.map +1 -0
  150. package/dist/shared/hash.d.ts +6 -0
  151. package/dist/shared/hash.js +18 -0
  152. package/dist/shared/hash.js.map +1 -0
  153. package/dist/shared/index.d.ts +2 -0
  154. package/dist/shared/index.js +18 -0
  155. package/dist/shared/index.js.map +1 -0
  156. package/package.json +184 -0
  157. package/src/cctext/index.ts +9 -0
  158. package/src/cctext/language-api.test.ts +149 -0
  159. package/src/cctext/language-api.ts +285 -0
  160. package/src/cctext/language.ts +80 -0
  161. package/src/graph/graph.test.ts +392 -0
  162. package/src/graph/graph.ts +433 -0
  163. package/src/graph/index.ts +1 -0
  164. package/src/index.ts +96 -0
  165. package/src/library/folder-tree.test.ts +47 -0
  166. package/src/library/folder-tree.ts +156 -0
  167. package/src/library/index.ts +46 -0
  168. package/src/library/library-api.test.ts +32 -0
  169. package/src/library/library-api.ts +11 -0
  170. package/src/library/library.ts +61 -0
  171. package/src/library/oss-api.ts +449 -0
  172. package/src/library/oss-layout-api.ts +377 -0
  173. package/src/library/oss-layout.ts +27 -0
  174. package/src/library/oss.ts +150 -0
  175. package/src/library/rsengine.ts +593 -0
  176. package/src/library/rsform-api.ts +533 -0
  177. package/src/library/rsform.ts +228 -0
  178. package/src/library/rsmodel-api.ts +340 -0
  179. package/src/library/rsmodel.ts +50 -0
  180. package/src/library/structure-planner.ts +143 -0
  181. package/src/parsing/ast.ts +136 -0
  182. package/src/parsing/index.ts +15 -0
  183. package/src/parsing/lezer-tree.ts +69 -0
  184. package/src/rslang/api.test.ts +116 -0
  185. package/src/rslang/api.ts +183 -0
  186. package/src/rslang/ast-annotations.ts +70 -0
  187. package/src/rslang/error.ts +129 -0
  188. package/src/rslang/eval/calculator.test.ts +124 -0
  189. package/src/rslang/eval/calculator.ts +121 -0
  190. package/src/rslang/eval/evaluation-cache.ts +257 -0
  191. package/src/rslang/eval/evaluator.test.ts +352 -0
  192. package/src/rslang/eval/evaluator.ts +935 -0
  193. package/src/rslang/eval/value-api.test.ts +105 -0
  194. package/src/rslang/eval/value-api.ts +444 -0
  195. package/src/rslang/eval/value.ts +102 -0
  196. package/src/rslang/index.ts +23 -0
  197. package/src/rslang/labels.ts +191 -0
  198. package/src/rslang/parser/expression-generator.test.ts +100 -0
  199. package/src/rslang/parser/expression-generator.ts +466 -0
  200. package/src/rslang/parser/normalize.test.ts +99 -0
  201. package/src/rslang/parser/normalize.ts +462 -0
  202. package/src/rslang/parser/parser.terms.ts +42 -0
  203. package/src/rslang/parser/parser.test.ts +153 -0
  204. package/src/rslang/parser/parser.ts +20 -0
  205. package/src/rslang/parser/rslang.grammar +251 -0
  206. package/src/rslang/parser/syntax-errors.ts +209 -0
  207. package/src/rslang/parser/token.ts +106 -0
  208. package/src/rslang/semantic/analyzer.test.ts +59 -0
  209. package/src/rslang/semantic/analyzer.ts +179 -0
  210. package/src/rslang/semantic/arguments-extractor.ts +327 -0
  211. package/src/rslang/semantic/type-auditor.test.ts +326 -0
  212. package/src/rslang/semantic/type-auditor.ts +1049 -0
  213. package/src/rslang/semantic/typification-api.test.ts +46 -0
  214. package/src/rslang/semantic/typification-api.ts +321 -0
  215. package/src/rslang/semantic/typification-parser.test.ts +50 -0
  216. package/src/rslang/semantic/typification-parser.ts +220 -0
  217. package/src/rslang/semantic/typification.ts +180 -0
  218. package/src/rslang/semantic/value-auditor.test.ts +206 -0
  219. package/src/rslang/semantic/value-auditor.ts +332 -0
  220. package/src/rslang/semantic/value-class.ts +11 -0
  221. package/src/rslang/typification-graph.ts +155 -0
  222. package/src/shared/branded.ts +6 -0
  223. package/src/shared/hash.ts +17 -0
  224. package/src/shared/index.ts +2 -0
@@ -0,0 +1,449 @@
1
+ /**
2
+ * Module: API for OperationSystem.
3
+ */
4
+
5
+ import { Graph } from '../graph';
6
+ import { type AliasMapping, applyAliasMapping, applyTypificationMapping, isSetTypification } from '../rslang/api';
7
+ import { labelType } from '../rslang/labels';
8
+ import { extractBases } from '../rslang/semantic/typification-api';
9
+
10
+ import { type LibraryItem } from './library';
11
+ import { NodeType, type OperationSchema, type SubstitutionErrorDescription, SubstitutionErrorType } from './oss';
12
+ import { type Constituenta, CstClass, CstType, type RSForm, type Substitution } from './rsform';
13
+
14
+ const STARTING_SUB_INDEX = 900; // max semantic index for starting substitution
15
+
16
+ export function constructNodeID(type: NodeType, itemID: number): string {
17
+ return type === NodeType.OPERATION ? 'o' + String(itemID) : 'b' + String(itemID);
18
+ }
19
+
20
+ /** Sorts library items relevant for the specified {@link OperationSchema}. */
21
+ export function sortItemsForOSS(oss: OperationSchema, items: readonly LibraryItem[]): LibraryItem[] {
22
+ const result = items.filter(item => item.location === oss.location);
23
+ for (const item of items) {
24
+ if (item.visible && item.owner === oss.owner && !result.includes(item)) {
25
+ result.push(item);
26
+ }
27
+ }
28
+ for (const item of items) {
29
+ if (item.visible && !result.includes(item)) {
30
+ result.push(item);
31
+ }
32
+ }
33
+ for (const item of items) {
34
+ if (!result.includes(item)) {
35
+ result.push(item);
36
+ }
37
+ }
38
+ return result;
39
+ }
40
+
41
+ type CrossMapping = Map<number, AliasMapping>;
42
+
43
+ /** Validator for Substitution table. */
44
+ export class SubstitutionValidator {
45
+ public errors: SubstitutionErrorDescription[] = [];
46
+ public suggestions: Substitution[] = [];
47
+
48
+ private schemas: RSForm[];
49
+ private substitutions: Substitution[];
50
+ private constituents = new Set<number>();
51
+ private originals = new Set<number>();
52
+ private mapping: CrossMapping = new Map();
53
+
54
+ private cstByID = new Map<number, Constituenta>();
55
+ private schemaByID = new Map<number, RSForm>();
56
+ private schemaByCst = new Map<number, RSForm>();
57
+
58
+ constructor(schemas: RSForm[], substitutions: Substitution[]) {
59
+ this.schemas = schemas;
60
+ this.substitutions = substitutions;
61
+ if (schemas.length === 0 || substitutions.length === 0) {
62
+ return;
63
+ }
64
+
65
+ for (const schema of schemas) {
66
+ this.schemaByID.set(schema.id, schema);
67
+ this.mapping.set(schema.id, {});
68
+ for (const item of schema.items) {
69
+ this.cstByID.set(item.id, item);
70
+ this.schemaByCst.set(item.id, schema);
71
+ }
72
+ }
73
+ let index = STARTING_SUB_INDEX;
74
+ for (const item of substitutions) {
75
+ this.constituents.add(item.original);
76
+ this.constituents.add(item.substitution);
77
+ this.originals.add(item.original);
78
+ const original = this.cstByID.get(item.original);
79
+ const substitution = this.cstByID.get(item.substitution);
80
+ if (!original || !substitution) {
81
+ return;
82
+ }
83
+ index++;
84
+ const newAlias = `${substitution.alias[0]}${index}`;
85
+ this.mapping.get(original.schema)![original.alias] = newAlias;
86
+ this.mapping.get(substitution.schema)![substitution.alias] = newAlias;
87
+ }
88
+ }
89
+
90
+ public validate(): boolean {
91
+ this.errors = [];
92
+ this.suggestions = [];
93
+ this.calculateSuggestions();
94
+ if (this.substitutions.length === 0) {
95
+ return true;
96
+ }
97
+ if (!this.checkTypes()) {
98
+ return false;
99
+ }
100
+ if (!this.checkCycles()) {
101
+ return false;
102
+ }
103
+ if (!this.checkSubstitutions()) {
104
+ return false;
105
+ }
106
+ return true;
107
+ }
108
+
109
+ private calculateSuggestions(): void {
110
+ const candidates = new Map<number, string>();
111
+ const minors = new Set<number>();
112
+ const schemaByCst = new Map<number, RSForm>();
113
+ for (const schema of this.schemas) {
114
+ for (const cst of schema.items) {
115
+ if (this.originals.has(cst.id)) {
116
+ continue;
117
+ }
118
+ if (cst.cst_class === CstClass.BASIC || cst.definition_formal.length === 0) {
119
+ continue;
120
+ }
121
+ const inputs = schema.graph.at(cst.id)!.inputs;
122
+ if (inputs.some(id => !this.constituents.has(id))) {
123
+ continue;
124
+ }
125
+ if (inputs.some(id => this.originals.has(id))) {
126
+ minors.add(cst.id);
127
+ }
128
+ candidates.set(cst.id, applyAliasMapping(cst.definition_formal, this.mapping.get(schema.id)!).replace(' ', ''));
129
+ schemaByCst.set(cst.id, schema);
130
+ }
131
+ }
132
+ for (const [key1, value1] of candidates) {
133
+ for (const [key2, value2] of candidates) {
134
+ if (key1 >= key2) {
135
+ continue;
136
+ }
137
+ if (schemaByCst.get(key1) === schemaByCst.get(key2)) {
138
+ continue;
139
+ }
140
+ if (value1 != value2) {
141
+ continue;
142
+ }
143
+ if (minors.has(key2)) {
144
+ this.suggestions.push({
145
+ original: key2,
146
+ substitution: key1
147
+ });
148
+ } else {
149
+ this.suggestions.push({
150
+ original: key1,
151
+ substitution: key2
152
+ });
153
+ }
154
+ }
155
+ }
156
+ }
157
+
158
+ private checkTypes(): boolean {
159
+ for (const item of this.substitutions) {
160
+ const original = this.cstByID.get(item.original);
161
+ const substitution = this.cstByID.get(item.substitution);
162
+ if (!original || !substitution) {
163
+ return this.reportError(SubstitutionErrorType.invalidIDs, []);
164
+ }
165
+ if (
166
+ substitution.analysis &&
167
+ original.analysis &&
168
+ (!original.analysis.success || !substitution.analysis.success)
169
+ ) {
170
+ return this.reportError(SubstitutionErrorType.incorrectCst, [substitution.alias, original.alias]);
171
+ }
172
+ switch (substitution.cst_type) {
173
+ case CstType.NOMINAL: {
174
+ if (original.cst_type !== CstType.NOMINAL) {
175
+ return this.reportError(SubstitutionErrorType.invalidNominal, [substitution.alias, original.alias]);
176
+ }
177
+ break;
178
+ }
179
+ case CstType.BASE: {
180
+ if (
181
+ original.cst_type !== CstType.BASE &&
182
+ original.cst_type !== CstType.CONSTANT &&
183
+ original.cst_type !== CstType.NOMINAL
184
+ ) {
185
+ return this.reportError(SubstitutionErrorType.invalidBasic, [substitution.alias, original.alias]);
186
+ }
187
+ break;
188
+ }
189
+
190
+ case CstType.CONSTANT: {
191
+ if (original.cst_type !== CstType.CONSTANT) {
192
+ return this.reportError(SubstitutionErrorType.invalidConstant, [substitution.alias, original.alias]);
193
+ }
194
+ break;
195
+ }
196
+
197
+ case CstType.AXIOM:
198
+ case CstType.STATEMENT: {
199
+ if (original.cst_type !== CstType.AXIOM && original.cst_type !== CstType.STATEMENT) {
200
+ return this.reportError(SubstitutionErrorType.invalidClasses, [substitution.alias, original.alias]);
201
+ }
202
+ break;
203
+ }
204
+
205
+ case CstType.FUNCTION: {
206
+ if (original.cst_type !== CstType.FUNCTION) {
207
+ return this.reportError(SubstitutionErrorType.invalidClasses, [substitution.alias, original.alias]);
208
+ }
209
+ break;
210
+ }
211
+ case CstType.PREDICATE: {
212
+ if (original.cst_type !== CstType.PREDICATE) {
213
+ return this.reportError(SubstitutionErrorType.invalidClasses, [substitution.alias, original.alias]);
214
+ }
215
+ break;
216
+ }
217
+
218
+ case CstType.TERM:
219
+ case CstType.STRUCTURED: {
220
+ if (
221
+ original.cst_type !== CstType.TERM &&
222
+ original.cst_type !== CstType.STRUCTURED &&
223
+ original.cst_type !== CstType.BASE
224
+ ) {
225
+ return this.reportError(SubstitutionErrorType.invalidClasses, [substitution.alias, original.alias]);
226
+ }
227
+ break;
228
+ }
229
+ }
230
+ }
231
+ return true;
232
+ }
233
+
234
+ private checkCycles(): boolean {
235
+ const graph = new Graph();
236
+ for (const schema of this.schemas) {
237
+ for (const cst of schema.items) {
238
+ if (cst.cst_type === CstType.BASE || cst.cst_type === CstType.CONSTANT) {
239
+ graph.addNode(cst.id);
240
+ }
241
+ }
242
+ }
243
+ for (const item of this.substitutions) {
244
+ const original = this.cstByID.get(item.original)!;
245
+ const substitution = this.cstByID.get(item.substitution)!;
246
+ for (const cst of [original, substitution]) {
247
+ if (cst.cst_type === CstType.BASE || cst.cst_type === CstType.CONSTANT) {
248
+ continue;
249
+ }
250
+ graph.addNode(cst.id);
251
+ if (cst.effectiveType === null) {
252
+ continue;
253
+ }
254
+ const parents = extractBases(cst.effectiveType);
255
+ if (parents.size === 0) {
256
+ continue;
257
+ }
258
+ const schema = this.schemaByID.get(cst.schema)!;
259
+ for (const alias of parents) {
260
+ const parent = schema.cstByAlias.get(alias);
261
+ if (parent) {
262
+ graph.addEdge(parent.id, cst.id);
263
+ }
264
+ }
265
+ }
266
+ graph.addEdge(substitution.id, original.id);
267
+ }
268
+ const cycle = graph.findCycle();
269
+ if (cycle !== null) {
270
+ const cycleMsg = cycle
271
+ .map(id => {
272
+ const cst = this.cstByID.get(id)!;
273
+ const schema = this.schemaByID.get(cst.schema)!;
274
+ return `[${schema.alias}]-${cst.alias}`;
275
+ })
276
+ .join(', ');
277
+ return this.reportError(SubstitutionErrorType.typificationCycle, [cycleMsg]);
278
+ }
279
+ return true;
280
+ }
281
+
282
+ private checkSubstitutions(): boolean {
283
+ const baseMappings = this.prepareBaseMappings();
284
+ const typeMappings = this.calculateSubstituteMappings(baseMappings);
285
+ if (typeMappings === null) {
286
+ return false;
287
+ }
288
+ for (const item of this.substitutions) {
289
+ const original = this.cstByID.get(item.original)!;
290
+ if (
291
+ original.cst_type === CstType.BASE ||
292
+ original.cst_type === CstType.CONSTANT ||
293
+ original.cst_type === CstType.NOMINAL
294
+ ) {
295
+ continue;
296
+ }
297
+ const substitution = this.cstByID.get(item.substitution)!;
298
+ if (original.cst_type === substitution.cst_type && original.cst_class !== CstClass.BASIC) {
299
+ if (!this.checkEqual(original, substitution)) {
300
+ this.reportError(SubstitutionErrorType.unequalExpressions, [substitution.alias, original.alias]);
301
+ // Note: do not interrupt the validation process. Only warn about the problem.
302
+ }
303
+ }
304
+
305
+ if (original.analysis.success !== substitution.analysis.success) {
306
+ return this.reportError(SubstitutionErrorType.unequalTypification, [substitution.alias, original.alias]);
307
+ }
308
+ if (!original.analysis.success || !substitution.analysis.success) {
309
+ continue;
310
+ }
311
+
312
+ const originalType = applyTypificationMapping(
313
+ applyAliasMapping(labelType(original.effectiveType), baseMappings.get(original.schema)!),
314
+ typeMappings
315
+ );
316
+ const substitutionType = applyTypificationMapping(
317
+ applyAliasMapping(labelType(substitution.effectiveType), baseMappings.get(substitution.schema)!),
318
+ typeMappings
319
+ );
320
+ if (originalType !== substitutionType) {
321
+ return this.reportError(SubstitutionErrorType.unequalTypification, [substitution.alias, original.alias]);
322
+ }
323
+ }
324
+ return true;
325
+ }
326
+
327
+ private prepareBaseMappings(): CrossMapping {
328
+ const result: CrossMapping = new Map();
329
+ let baseCount = 0;
330
+ let constCount = 0;
331
+ for (const schema of this.schemas) {
332
+ const mapping: AliasMapping = {};
333
+ for (const cst of schema.items) {
334
+ if (cst.cst_type === CstType.BASE) {
335
+ baseCount++;
336
+ mapping[cst.alias] = `X${baseCount}`;
337
+ } else if (cst.cst_type === CstType.CONSTANT) {
338
+ constCount++;
339
+ mapping[cst.alias] = `C${constCount}`;
340
+ }
341
+ result.set(schema.id, mapping);
342
+ }
343
+ }
344
+ return result;
345
+ }
346
+
347
+ private calculateSubstituteMappings(baseMappings: CrossMapping): AliasMapping | null {
348
+ const result: AliasMapping = {};
349
+ const processed = new Set<string>();
350
+ for (const item of this.substitutions) {
351
+ const original = this.cstByID.get(item.original)!;
352
+ if (original.cst_type !== CstType.BASE && original.cst_type !== CstType.CONSTANT) {
353
+ continue;
354
+ }
355
+ const originalAlias = baseMappings.get(original.schema)![original.alias];
356
+
357
+ const substitution = this.cstByID.get(item.substitution)!;
358
+ let substitutionText = '';
359
+ if (substitution.cst_type === original.cst_type || !substitution.effectiveType) {
360
+ substitutionText = baseMappings.get(substitution.schema)![substitution.alias];
361
+ } else {
362
+ const typeText = labelType(substitution.effectiveType);
363
+ substitutionText = applyAliasMapping(typeText, baseMappings.get(substitution.schema)!);
364
+ substitutionText = applyTypificationMapping(substitutionText, result);
365
+ if (!isSetTypification(substitutionText)) {
366
+ this.reportError(SubstitutionErrorType.baseSubstitutionNotSet, [substitution.alias, typeText]);
367
+ return null;
368
+ }
369
+ if (substitutionText.includes('×') || substitutionText.startsWith('ℬℬ')) {
370
+ substitutionText = substitutionText.slice(1);
371
+ } else {
372
+ substitutionText = substitutionText.slice(2, -1);
373
+ }
374
+ }
375
+ for (const prevAlias of processed) {
376
+ result[prevAlias] = applyTypificationMapping(result[prevAlias], { [originalAlias]: substitutionText });
377
+ }
378
+ result[originalAlias] = substitutionText;
379
+ processed.add(originalAlias);
380
+ }
381
+ return result;
382
+ }
383
+
384
+ private checkEqual(left: Constituenta, right: Constituenta): boolean {
385
+ const schema1 = this.schemaByID.get(left.schema)!;
386
+ const inputs1 = schema1.graph.at(left.id)!.inputs;
387
+ if (inputs1.some(id => !this.constituents.has(id))) {
388
+ return false;
389
+ }
390
+ const schema2 = this.schemaByID.get(right.schema)!;
391
+ const inputs2 = schema2.graph.at(right.id)!.inputs;
392
+ if (inputs2.some(id => !this.constituents.has(id))) {
393
+ return false;
394
+ }
395
+ const expression1 = applyAliasMapping(left.definition_formal, this.mapping.get(schema1.id)!);
396
+ const expression2 = applyAliasMapping(right.definition_formal, this.mapping.get(schema2.id)!);
397
+ return expression1.replace(' ', '') === expression2.replace(' ', '');
398
+ }
399
+
400
+ private reportError(errorType: SubstitutionErrorType, params: string[]): boolean {
401
+ this.errors.push({
402
+ errorType: errorType,
403
+ params: params
404
+ });
405
+ return false;
406
+ }
407
+ }
408
+
409
+ /** Filter relocate candidates from gives schema. */
410
+ export function getRelocateCandidates(
411
+ source: number,
412
+ destination: number,
413
+ schema: RSForm,
414
+ oss: OperationSchema
415
+ ): Constituenta[] {
416
+ const destinationSchema = oss.operationByID.get(destination)?.result;
417
+ if (!destinationSchema) {
418
+ return [];
419
+ }
420
+ const node = oss.graph.at(source);
421
+ if (!node) {
422
+ return [];
423
+ }
424
+
425
+ if (node.outputs.includes(destination)) {
426
+ return schema.items;
427
+ }
428
+
429
+ const addedCst = schema.items.filter(item => !item.is_inherited).map(cst => cst.id);
430
+
431
+ const unreachableBases: number[] = [];
432
+ for (const cst of schema.items.filter(item => item.is_inherited)) {
433
+ if (cst.parent_schema == destinationSchema) {
434
+ continue;
435
+ }
436
+ const parent = schema.inheritance.find(item => item.child === cst.id && item.child_source === cst.schema)?.parent;
437
+ if (parent) {
438
+ const original = oss.substitutions.find(sub => sub.substitution === parent)?.original;
439
+ if (original) {
440
+ continue;
441
+ }
442
+ }
443
+ unreachableBases.push(cst.id);
444
+ }
445
+ const unreachable = schema.graph.expandAllOutputs(unreachableBases);
446
+ return schema.items.filter(
447
+ cst => cst.parent_schema === destinationSchema || (addedCst.includes(cst.id) && !unreachable.includes(cst.id))
448
+ );
449
+ }