@rsconcept/domain 3.0.0 → 3.0.1

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 (82) hide show
  1. package/dist/{analyzer-fNhkwO-6.d.ts → analyzer-CzFaWR7w.d.ts} +4 -4
  2. package/dist/{api-Bf0f_uiI.d.ts → api-DgecYHjR.d.ts} +5 -3
  3. package/dist/{arguments-extractor-ngatANBI.d.ts → arguments-extractor-CXWRT5Ou.d.ts} +4 -4
  4. package/dist/{ast-C8sIpKdL.d.ts → ast-D-D6Rq3T.d.ts} +2 -3
  5. package/dist/{ast-annotations-CiIx8qBM.d.ts → ast-annotations-x4PJ_Lhc.d.ts} +4 -4
  6. package/dist/{calculator-DE89LtIM.d.ts → calculator-uPaTV3hc.d.ts} +5 -5
  7. package/dist/cctext/language-api.d.ts +0 -1
  8. package/dist/{diagnostics-ndGYbvgh.js → diagnostics-D1Cp21nP.js} +16 -3
  9. package/dist/{diagnostics-ndGYbvgh.js.map → diagnostics-D1Cp21nP.js.map} +1 -1
  10. package/dist/{diagnostics-DsEhmFh0.d.ts → diagnostics-DKyMf6q-.d.ts} +20 -6
  11. package/dist/{expression-generator-CoucLIkE.d.ts → expression-generator-CADzBw-C.d.ts} +3 -2
  12. package/dist/graph/index.d.ts +1 -0
  13. package/dist/index-CnuO4w8e.d.ts +13 -0
  14. package/dist/index-D5RahF1K.d.ts +2 -0
  15. package/dist/{index-DpiTybDB.d.ts → index-DCO4mxiO.d.ts} +9 -7
  16. package/dist/index-DntDUXW1.d.ts +1 -0
  17. package/dist/index-x0_Y5uPV.d.ts +2 -0
  18. package/dist/index.d.ts +13 -13
  19. package/dist/index.js +1 -1
  20. package/dist/{lezer-tree-iS7LpLBJ.d.ts → lezer-tree-BQZqBT5A.d.ts} +1 -2
  21. package/dist/library/diagnostics.d.ts +1 -1
  22. package/dist/library/diagnostics.js +1 -1
  23. package/dist/library/index.d.ts +2 -3
  24. package/dist/library/index.js +1 -1
  25. package/dist/library/oss-api.d.ts +11 -3
  26. package/dist/library/oss-api.js +45 -4
  27. package/dist/library/oss-api.js.map +1 -1
  28. package/dist/library/oss-layout-api.d.ts +0 -1
  29. package/dist/library/oss.d.ts +21 -16
  30. package/dist/library/oss.js +19 -13
  31. package/dist/library/oss.js.map +1 -1
  32. package/dist/library/rsengine.d.ts +6 -5
  33. package/dist/library/rsengine.js +1 -1
  34. package/dist/library/rsform-api/index.d.ts +1 -1
  35. package/dist/library/rsform-api/index.js +1 -1
  36. package/dist/library/rsform.d.ts +1 -1
  37. package/dist/library/rsmodel-api.d.ts +5 -5
  38. package/dist/library/rsmodel-api.js +1 -1
  39. package/dist/library/rsmodel.d.ts +1 -1
  40. package/dist/library/structure-planner.d.ts +3 -3
  41. package/dist/library/structure-planner.js +1 -1
  42. package/dist/{parser-Bwd8LxJ1.d.ts → parser-DkejtiOR.d.ts} +1 -2
  43. package/dist/parsing/ast.d.ts +1 -1
  44. package/dist/parsing/index.d.ts +3 -2
  45. package/dist/parsing/lezer-tree.d.ts +1 -1
  46. package/dist/rslang/api.d.ts +2 -2
  47. package/dist/rslang/ast-annotations.d.ts +1 -1
  48. package/dist/rslang/eval/calculator.d.ts +1 -1
  49. package/dist/rslang/eval/evaluation-cache.d.ts +3 -3
  50. package/dist/rslang/eval/evaluator.d.ts +3 -3
  51. package/dist/rslang/eval/value-api.d.ts +1 -1
  52. package/dist/rslang/eval/value.d.ts +1 -1
  53. package/dist/rslang/index.d.ts +11 -10
  54. package/dist/rslang/labels.d.ts +3 -3
  55. package/dist/rslang/parser/expression-generator.d.ts +1 -1
  56. package/dist/rslang/parser/normalize.d.ts +2 -1
  57. package/dist/rslang/parser/parser.d.ts +1 -1
  58. package/dist/rslang/parser/parser.terms.d.ts +1 -40
  59. package/dist/rslang/parser/syntax-errors/index.d.ts +3 -3
  60. package/dist/rslang/semantic/analyzer.d.ts +1 -1
  61. package/dist/rslang/semantic/arguments-extractor.d.ts +1 -1
  62. package/dist/rslang/semantic/type-auditor.d.ts +3 -3
  63. package/dist/rslang/semantic/typification-api.d.ts +1 -2
  64. package/dist/rslang/semantic/typification-parser.d.ts +1 -1
  65. package/dist/rslang/semantic/typification.d.ts +1 -1
  66. package/dist/rslang/semantic/value-auditor.d.ts +2 -2
  67. package/dist/rslang/typification-graph.d.ts +1 -1
  68. package/dist/shared/index.d.ts +1 -0
  69. package/dist/{typification-graph-BY_oGT82.d.ts → typification-graph-CSxDt18X.d.ts} +2 -3
  70. package/dist/{typification-9lNu9R4k.d.ts → typification-hWUoWCba.d.ts} +2 -1
  71. package/dist/{typification-parser-Dytsv9CI.d.ts → typification-parser-DFxj4JiQ.d.ts} +2 -3
  72. package/dist/{value-BduA_ZGp.d.ts → value-XpJOVzMP.d.ts} +2 -1
  73. package/dist/{value-api-CXLl_zg0.d.ts → value-api-Dw8UkwCD.d.ts} +3 -4
  74. package/package.json +8 -8
  75. package/src/library/diagnostics.ts +16 -2
  76. package/src/library/oss-api.test.ts +100 -5
  77. package/src/library/oss-api.ts +71 -5
  78. package/src/library/oss.ts +22 -16
  79. package/dist/index-BKZ67WMa.d.ts +0 -1
  80. package/dist/index-BVVgDSdq.d.ts +0 -1
  81. package/dist/index-DmtQKWjk.d.ts +0 -1
  82. package/dist/index-_6s0AX1B.d.ts +0 -1
@@ -2,14 +2,16 @@ import { describe, expect, it } from 'vitest';
2
2
 
3
3
  import { Graph } from '../graph';
4
4
 
5
+ import { SubstitutionErrorType } from './oss';
5
6
  import { SubstitutionValidator } from './oss-api';
6
7
  import { type Constituenta, CstClass, CstType, type RSForm } from './rsform';
7
8
 
8
9
  function mockConstituenta(
9
- partial: Pick<Constituenta, 'id' | 'alias' | 'definition_formal' | 'cst_class' | 'cst_type'>
10
+ partial: Pick<Constituenta, 'id' | 'alias' | 'definition_formal' | 'cst_class' | 'cst_type'> &
11
+ Partial<Pick<Constituenta, 'schema'>>
10
12
  ): Constituenta {
11
13
  return {
12
- schema: 790,
14
+ schema: partial.schema ?? 790,
13
15
  crucial: false,
14
16
  convention: '',
15
17
  definition_raw: '',
@@ -37,11 +39,16 @@ function mockConstituenta(
37
39
  };
38
40
  }
39
41
 
40
- function mockSchema(items: Constituenta[]): RSForm {
42
+ function mockSchema(items: Constituenta[], edges: number[][] = [], id = 790, alias = 'S1'): RSForm {
41
43
  const graph = new Graph(items.map(item => [item.id]));
44
+ for (const edge of edges) {
45
+ if (edge.length === 2) {
46
+ graph.addEdge(edge[0], edge[1]);
47
+ }
48
+ }
42
49
  return {
43
- id: 790,
44
- alias: 'S1',
50
+ id,
51
+ alias,
45
52
  items,
46
53
  graph,
47
54
  cstByAlias: new Map(items.map(item => [item.alias, item]))
@@ -72,4 +79,92 @@ describe('SubstitutionValidator', () => {
72
79
  expect(() => validator.validate()).not.toThrow();
73
80
  expect(validator.validate()).toBe(true);
74
81
  });
82
+
83
+ it('reports definitionCycle when identification closes a formal dependency loop', () => {
84
+ // D16 := F2[D15] ⇒ edge D15 → D16; identifying D15 → D16 yields D16 := F2[D16]
85
+ const schema = mockSchema(
86
+ [
87
+ mockConstituenta({
88
+ id: 1,
89
+ alias: 'X1',
90
+ cst_class: CstClass.BASIC,
91
+ cst_type: CstType.BASE,
92
+ definition_formal: ''
93
+ }),
94
+ mockConstituenta({
95
+ id: 2,
96
+ alias: 'F2',
97
+ cst_class: CstClass.DERIVED,
98
+ cst_type: CstType.FUNCTION,
99
+ definition_formal: '[α∈X1] α'
100
+ }),
101
+ mockConstituenta({
102
+ id: 3,
103
+ alias: 'D15',
104
+ cst_class: CstClass.DERIVED,
105
+ cst_type: CstType.TERM,
106
+ definition_formal: 'X1'
107
+ }),
108
+ mockConstituenta({
109
+ id: 4,
110
+ alias: 'D16',
111
+ cst_class: CstClass.DERIVED,
112
+ cst_type: CstType.TERM,
113
+ definition_formal: 'F2[D15]'
114
+ })
115
+ ],
116
+ [
117
+ [2, 4],
118
+ [3, 4]
119
+ ]
120
+ );
121
+
122
+ const validator = new SubstitutionValidator([schema], [{ original: 3, substitution: 4 }]);
123
+
124
+ expect(validator.validate()).toBe(false);
125
+ expect(validator.errors).toEqual([
126
+ {
127
+ code: SubstitutionErrorType.definitionCycle,
128
+ params: ['D16 → D16']
129
+ }
130
+ ]);
131
+ expect(SubstitutionErrorType.definitionCycle).toBe(0x8906);
132
+ });
133
+
134
+ it('allows identification that does not create a definition cycle', () => {
135
+ const schema = mockSchema(
136
+ [
137
+ mockConstituenta({
138
+ id: 1,
139
+ alias: 'X1',
140
+ cst_class: CstClass.BASIC,
141
+ cst_type: CstType.BASE,
142
+ definition_formal: ''
143
+ }),
144
+ mockConstituenta({
145
+ id: 2,
146
+ alias: 'D1',
147
+ cst_class: CstClass.DERIVED,
148
+ cst_type: CstType.TERM,
149
+ definition_formal: 'X1'
150
+ }),
151
+ mockConstituenta({
152
+ id: 3,
153
+ alias: 'D2',
154
+ cst_class: CstClass.DERIVED,
155
+ cst_type: CstType.TERM,
156
+ definition_formal: 'X1'
157
+ })
158
+ ],
159
+ [
160
+ [1, 2],
161
+ [1, 3]
162
+ ]
163
+ );
164
+
165
+ const validator = new SubstitutionValidator([schema], [{ original: 2, substitution: 3 }]);
166
+
167
+ expect(validator.validate()).toBe(true);
168
+ expect(validator.errors.every(error => error.code !== SubstitutionErrorType.definitionCycle)).toBe(true);
169
+ });
75
170
  });
@@ -7,6 +7,7 @@ import { type AliasMapping, applyAliasMapping, applyTypificationMapping, isSetTy
7
7
  import { labelType } from '../rslang/labels';
8
8
  import { extractBases } from '../rslang/semantic/typification-api';
9
9
 
10
+ import { formatDependencyCycle } from './diagnostics';
10
11
  import { type LibraryItem } from './library';
11
12
  import { NodeType, type OperationSchema, type SubstitutionErrorDescription, SubstitutionErrorType } from './oss';
12
13
  import { type Constituenta, CstClass, CstType, type RSForm, type Substitution } from './rsform';
@@ -101,7 +102,10 @@ export class SubstitutionValidator {
101
102
  if (!this.checkTypes()) {
102
103
  return false;
103
104
  }
104
- if (!this.checkCycles()) {
105
+ if (!this.checkTypificationCycles()) {
106
+ return false;
107
+ }
108
+ if (!this.checkDefinitionCycles()) {
105
109
  return false;
106
110
  }
107
111
  if (!this.checkSubstitutions()) {
@@ -238,7 +242,11 @@ export class SubstitutionValidator {
238
242
  return true;
239
243
  }
240
244
 
241
- private checkCycles(): boolean {
245
+ /**
246
+ * Detect cycles among base/constant sets implied by typifications of non-base
247
+ * constituents under the substitution table.
248
+ */
249
+ private checkTypificationCycles(): boolean {
242
250
  const graph = new Graph();
243
251
  for (const schema of this.schemas) {
244
252
  for (const cst of schema.items) {
@@ -286,6 +294,64 @@ export class SubstitutionValidator {
286
294
  return true;
287
295
  }
288
296
 
297
+ /**
298
+ * Detect logical cycles in formal definitions after applying the substitution table
299
+ * (e.g. D16 := F2[D15] with identification D15 → D16 yields D16 := F2[D16]).
300
+ */
301
+ private checkDefinitionCycles(): boolean {
302
+ const graph = new Graph();
303
+ for (const schema of this.schemas) {
304
+ for (const [id, node] of schema.graph.nodes) {
305
+ graph.addNode(id);
306
+ for (const output of node.outputs) {
307
+ graph.addEdge(id, output);
308
+ }
309
+ }
310
+ }
311
+
312
+ const deleted = new Map<number, number>();
313
+ for (const item of this.substitutions) {
314
+ deleted.set(item.original, item.substitution);
315
+ }
316
+ const resolve = (id: number): number => deleted.get(id) ?? id;
317
+
318
+ const result = new Graph();
319
+ for (const id of graph.nodes.keys()) {
320
+ if (!deleted.has(id)) {
321
+ result.addNode(id);
322
+ }
323
+ }
324
+ for (const substitutionId of deleted.values()) {
325
+ result.addNode(substitutionId);
326
+ }
327
+
328
+ for (const [id, node] of graph.nodes) {
329
+ for (const output of node.outputs) {
330
+ if (deleted.has(output)) {
331
+ continue;
332
+ }
333
+ result.addEdge(resolve(id), output);
334
+ }
335
+ }
336
+
337
+ const cycle = result.findCycle();
338
+ if (cycle !== null) {
339
+ const aliases = cycle.map(id => {
340
+ const cst = this.cstByID.get(id);
341
+ if (!cst) {
342
+ return String(id);
343
+ }
344
+ if (this.schemas.length > 1) {
345
+ const schema = this.schemaByID.get(cst.schema);
346
+ return schema ? `[${schema.alias}]-${cst.alias}` : cst.alias;
347
+ }
348
+ return cst.alias;
349
+ });
350
+ return this.reportError(SubstitutionErrorType.definitionCycle, [formatDependencyCycle(aliases)]);
351
+ }
352
+ return true;
353
+ }
354
+
289
355
  private checkSubstitutions(): boolean {
290
356
  const baseMappings = this.prepareBaseMappings();
291
357
  const typeMappings = this.calculateSubstituteMappings(baseMappings);
@@ -407,10 +473,10 @@ export class SubstitutionValidator {
407
473
  return expression1.replace(/\s+/g, '') === expression2.replace(/\s+/g, '');
408
474
  }
409
475
 
410
- private reportError(errorType: SubstitutionErrorType, params: string[]): boolean {
476
+ private reportError(code: SubstitutionErrorType, params: string[]): boolean {
411
477
  this.errors.push({
412
- errorType: errorType,
413
- params: params
478
+ code,
479
+ params
414
480
  });
415
481
  return false;
416
482
  }
@@ -4,6 +4,7 @@
4
4
 
5
5
  import { type Graph } from '../graph';
6
6
 
7
+ import { RSDiagnosticCode } from './diagnostics';
7
8
  import { type LibraryItem } from './library';
8
9
  import { type NodePosition, type OssLayout } from './oss-layout';
9
10
 
@@ -126,25 +127,30 @@ export interface OperationSchema extends LibraryItem {
126
127
  itemByNodeID: Map<string, OssItem>;
127
128
  }
128
129
 
129
- /** Represents substitution error description. */
130
+ /** Represents substitution error description (same code space as {@link RSDiagnosticCode}). */
130
131
  export interface SubstitutionErrorDescription {
131
- errorType: SubstitutionErrorType;
132
+ code: SubstitutionErrorType;
132
133
  params: string[];
133
134
  }
134
135
 
135
- /** Represents Substitution table error types. */
136
+ /**
137
+ * Substitution-table error codes — aliases into {@link RSDiagnosticCode}.
138
+ * Logical definition cycles reuse {@link RSDiagnosticCode.schemaDependencyCycle}.
139
+ */
136
140
  export const SubstitutionErrorType = {
137
- invalidIDs: 0,
138
- incorrectCst: 1,
139
- invalidClasses: 2,
140
- invalidBasic: 3,
141
- invalidConstant: 4,
142
- typificationCycle: 5,
143
- baseSubstitutionNotSet: 6,
144
- unequalTypification: 7,
145
- unequalExpressions: 8,
146
- unequalArgsCount: 9,
147
- unequalArgs: 10,
148
- invalidNominal: 11
149
- } as const;
141
+ invalidIDs: RSDiagnosticCode.substitutionInvalidIDs,
142
+ incorrectCst: RSDiagnosticCode.substitutionIncorrectCst,
143
+ invalidClasses: RSDiagnosticCode.substitutionInvalidClasses,
144
+ invalidBasic: RSDiagnosticCode.substitutionInvalidBasic,
145
+ invalidConstant: RSDiagnosticCode.substitutionInvalidConstant,
146
+ typificationCycle: RSDiagnosticCode.substitutionTypificationCycle,
147
+ baseSubstitutionNotSet: RSDiagnosticCode.substitutionBaseNotSet,
148
+ unequalTypification: RSDiagnosticCode.substitutionUnequalTypification,
149
+ unequalExpressions: RSDiagnosticCode.substitutionUnequalExpressions,
150
+ unequalArgsCount: RSDiagnosticCode.substitutionUnequalArgsCount,
151
+ unequalArgs: RSDiagnosticCode.substitutionUnequalArgs,
152
+ invalidNominal: RSDiagnosticCode.substitutionInvalidNominal,
153
+ /** Same code as constituent schema dependency cycle. */
154
+ definitionCycle: RSDiagnosticCode.schemaDependencyCycle
155
+ } as const satisfies Record<string, (typeof RSDiagnosticCode)[keyof typeof RSDiagnosticCode]>;
150
156
  export type SubstitutionErrorType = (typeof SubstitutionErrorType)[keyof typeof SubstitutionErrorType];
@@ -1 +0,0 @@
1
- export { };
@@ -1 +0,0 @@
1
- export { };
@@ -1 +0,0 @@
1
- export { };
@@ -1 +0,0 @@
1
- export { };