@rsconcept/domain 1.7.7 → 1.8.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 (60) hide show
  1. package/dist/{analyzer-DqjdciC5.d.ts → analyzer-iqAXyROE.d.ts} +2 -3
  2. package/dist/{arguments-extractor-Dd1lFom9.d.ts → arguments-extractor-ngatANBI.d.ts} +2 -2
  3. package/dist/{ast-annotations-CZCzs9Uk.d.ts → ast-annotations-D6KZDu12.d.ts} +2 -2
  4. package/dist/{calculator-Dt03dsnd.d.ts → calculator-k8BGIKmj.d.ts} +2 -2
  5. package/dist/index.d.ts +8 -8
  6. package/dist/library/index.d.ts +97 -1
  7. package/dist/library/index.js +283 -1
  8. package/dist/library/index.js.map +1 -0
  9. package/dist/library/oss-api.js +1 -1
  10. package/dist/library/rsengine.d.ts +1 -1
  11. package/dist/library/rsform-api.d.ts +13 -3
  12. package/dist/library/rsform-api.js +24 -2
  13. package/dist/library/rsform-api.js.map +1 -1
  14. package/dist/library/rsform.d.ts +2 -2
  15. package/dist/library/rsmodel-api.d.ts +1 -1
  16. package/dist/library/structure-planner.d.ts +1 -1
  17. package/dist/library/structure-planner.js +1 -1
  18. package/dist/rslang/api.d.ts +13 -2
  19. package/dist/rslang/api.js +31 -2
  20. package/dist/rslang/api.js.map +1 -1
  21. package/dist/rslang/ast-annotations.d.ts +1 -1
  22. package/dist/rslang/eval/calculator.d.ts +1 -1
  23. package/dist/rslang/eval/value-api.d.ts +1 -1
  24. package/dist/rslang/index.d.ts +8 -8
  25. package/dist/rslang/labels.d.ts +4 -2
  26. package/dist/rslang/labels.js +8 -2
  27. package/dist/rslang/labels.js.map +1 -1
  28. package/dist/rslang/parser/syntax-errors/index.d.ts +1 -1
  29. package/dist/rslang/semantic/analyzer.d.ts +1 -1
  30. package/dist/rslang/semantic/analyzer.js +5 -13
  31. package/dist/rslang/semantic/analyzer.js.map +1 -1
  32. package/dist/rslang/semantic/arguments-extractor.d.ts +1 -1
  33. package/dist/rslang/semantic/type-auditor.d.ts +1 -1
  34. package/dist/rslang/semantic/type-auditor.js +2 -2
  35. package/dist/rslang/semantic/type-auditor.js.map +1 -1
  36. package/dist/rslang/semantic/typification-api.d.ts +1 -1
  37. package/dist/rslang/semantic/typification-parser.d.ts +1 -1
  38. package/dist/rslang/semantic/typification.d.ts +2 -2
  39. package/dist/rslang/semantic/typification.js +14 -6
  40. package/dist/rslang/semantic/typification.js.map +1 -1
  41. package/dist/rslang/typification-graph.d.ts +1 -1
  42. package/dist/{typification-DDuv88ir.d.ts → typification-9lNu9R4k.d.ts} +8 -4
  43. package/dist/{typification-graph-8VdK6_Fh.d.ts → typification-graph-BY_oGT82.d.ts} +2 -2
  44. package/dist/{typification-parser-DHO42ZRc.d.ts → typification-parser-Dytsv9CI.d.ts} +2 -2
  45. package/dist/{value-api-C2X4Pom5.d.ts → value-api-CXLl_zg0.d.ts} +2 -2
  46. package/package.json +1 -1
  47. package/src/library/index.ts +8 -0
  48. package/src/library/rsform-api.test.ts +11 -1
  49. package/src/library/rsform-api.ts +40 -1
  50. package/src/library/template-instantiation.test.ts +427 -0
  51. package/src/library/template-instantiation.ts +456 -0
  52. package/src/rslang/api.test.ts +28 -0
  53. package/src/rslang/api.ts +32 -2
  54. package/src/rslang/labels.ts +10 -1
  55. package/src/rslang/semantic/analyzer.ts +6 -14
  56. package/src/rslang/semantic/type-auditor.test.ts +25 -6
  57. package/src/rslang/semantic/type-auditor.ts +2 -1
  58. package/src/rslang/semantic/typification-api.test.ts +21 -5
  59. package/src/rslang/semantic/typification-parser.test.ts +6 -1
  60. package/src/rslang/semantic/typification.ts +16 -6
@@ -0,0 +1,427 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ import { type ArgumentValue, type Constituenta, CstClass, CstType, type RSForm } from './rsform';
4
+ import { planTemplateInstantiation } from './template-instantiation';
5
+
6
+ function mockSchema(items: Constituenta[]): RSForm {
7
+ return { items } as RSForm;
8
+ }
9
+
10
+ function mockCst(partial: Pick<Constituenta, 'id' | 'alias' | 'cst_type'> & Partial<Constituenta>): Constituenta {
11
+ return {
12
+ schema: 1,
13
+ crucial: false,
14
+ convention: '',
15
+ definition_raw: '',
16
+ definition_resolved: '',
17
+ term_raw: '',
18
+ term_resolved: '',
19
+ term_forms: [],
20
+ typification_manual: '',
21
+ value_is_property: false,
22
+ homonyms: [],
23
+ formalDuplicates: [],
24
+ analysis: { success: true } as Constituenta['analysis'],
25
+ effectiveType: null,
26
+ is_type_mismatch: false,
27
+ status: 'verified',
28
+ is_template: true,
29
+ is_simple_expression: true,
30
+ parent_schema_index: 0,
31
+ parent_schema: null,
32
+ is_inherited: false,
33
+ has_inherited_children: false,
34
+ attributes: [],
35
+ spawn: [],
36
+ spawn_alias: [],
37
+ cst_class: CstClass.TEMPLATE,
38
+ definition_formal: '',
39
+ ...partial
40
+ };
41
+ }
42
+
43
+ describe('planTemplateInstantiation', () => {
44
+ const f42 = mockCst({
45
+ id: 1,
46
+ alias: 'F42',
47
+ cst_type: CstType.FUNCTION,
48
+ term_raw: 'операция',
49
+ definition_formal: '[α∈R1, β∈R1, σ∈ℬ((R1×R1)×R1)] debool(Pr2(Fi1[{(α,β)}](σ)))'
50
+ });
51
+
52
+ const p29 = mockCst({
53
+ id: 2,
54
+ alias: 'P29',
55
+ cst_type: CstType.PREDICATE,
56
+ term_raw: 'замкнутость',
57
+ definition_formal: '[α∈ℬ(R1), σ∈ℬ((R1×R1)×R1)] Pr1(σ) = α×α & card(σ) = card(Pr1(σ))'
58
+ });
59
+
60
+ const p30 = mockCst({
61
+ id: 3,
62
+ alias: 'P30',
63
+ cst_type: CstType.PREDICATE,
64
+ term_raw: 'ассоциативность',
65
+ definition_formal: '[σ∈ℬ((R1×R1)×R1)] ∀α,β,γ∈Pr1(Pr1(σ)) F42[F42[α,β,σ],γ,σ] = F42[α,F42[β,γ,σ],σ]'
66
+ });
67
+
68
+ const p35 = mockCst({
69
+ id: 4,
70
+ alias: 'P35',
71
+ cst_type: CstType.PREDICATE,
72
+ term_raw: 'полугруппа',
73
+ definition_formal: '[α∈ℬ(R1), σ∈ℬ((R1×R1)×R1)] P29[α, σ] & P30[σ]'
74
+ });
75
+
76
+ const templateItems = [f42, p29, p30, p35];
77
+ const targetSchema = mockSchema([
78
+ mockCst({ id: 10, alias: 'S1', cst_type: CstType.STRUCTURED, definition_formal: 'ℬ(X1)' }),
79
+ mockCst({ id: 11, alias: 'S2', cst_type: CstType.STRUCTURED, definition_formal: 'ℬ((X1×X1)×X1)' })
80
+ ]);
81
+
82
+ it('creates nested template functions with propagated argument bindings', () => {
83
+ const userArgs: ArgumentValue[] = [
84
+ { alias: 'α', typification: 'ℬ(R1)', value: 'S1' },
85
+ { alias: 'σ', typification: 'ℬ((R1×R1)×R1)', value: 'S2' }
86
+ ];
87
+
88
+ const plan = planTemplateInstantiation({
89
+ targetSchema,
90
+ templateItems,
91
+ prototype: p35,
92
+ userArgs,
93
+ mainItem: {
94
+ alias: 'A1',
95
+ cst_type: CstType.PREDICATE,
96
+ crucial: false,
97
+ convention: '',
98
+ definition_formal: p35.definition_formal,
99
+ definition_raw: p35.definition_raw,
100
+ term_raw: p35.term_raw,
101
+ term_forms: [],
102
+ typification_manual: '',
103
+ value_is_property: false
104
+ }
105
+ });
106
+
107
+ expect(plan.items.length).toBe(4);
108
+ expect(plan.items[0].alias).toBe('F1');
109
+ expect(plan.items[0].cst_type).toBe(CstType.FUNCTION);
110
+ expect(plan.items[0].definition_formal).toContain('S2');
111
+ expect(plan.items[0].definition_formal).not.toContain('F42');
112
+
113
+ const p29Item = plan.items.find(item => item.term_raw === 'замкнутость');
114
+ const p30Item = plan.items.find(item => item.term_raw === 'ассоциативность');
115
+ expect(p29Item?.cst_type).toBe(CstType.AXIOM);
116
+ expect(p30Item?.cst_type).toBe(CstType.AXIOM);
117
+ expect(p30Item?.definition_formal).toContain('F1[');
118
+
119
+ const main = plan.items.at(-1)!;
120
+ expect(main.alias).toBe('A1');
121
+ expect(main.cst_type).toBe(CstType.AXIOM);
122
+ expect(main.definition_formal).toContain(`${p29Item?.alias}[S1, S2]`);
123
+ expect(main.definition_formal).toContain(`${p30Item?.alias}[S2]`);
124
+ });
125
+
126
+ it('does not assign dependency aliases that collide with the main constituent alias', () => {
127
+ const userArgs: ArgumentValue[] = [
128
+ { alias: 'α', typification: 'ℬ(R1)', value: 'S1' },
129
+ { alias: 'σ', typification: 'ℬ((R1×R1)×R1)', value: 'S2' }
130
+ ];
131
+
132
+ const plan = planTemplateInstantiation({
133
+ targetSchema: mockSchema([
134
+ ...targetSchema.items,
135
+ mockCst({ id: 12, alias: 'P1', cst_type: CstType.PREDICATE, definition_formal: 'true' }),
136
+ mockCst({ id: 13, alias: 'P2', cst_type: CstType.PREDICATE, definition_formal: 'true' }),
137
+ mockCst({ id: 14, alias: 'P3', cst_type: CstType.PREDICATE, definition_formal: 'true' }),
138
+ mockCst({ id: 15, alias: 'P4', cst_type: CstType.PREDICATE, definition_formal: 'true' }),
139
+ mockCst({ id: 16, alias: 'P5', cst_type: CstType.PREDICATE, definition_formal: 'true' })
140
+ ]),
141
+ templateItems,
142
+ prototype: p35,
143
+ userArgs,
144
+ mainItem: {
145
+ alias: 'P6',
146
+ cst_type: CstType.PREDICATE,
147
+ crucial: false,
148
+ convention: '',
149
+ definition_formal: p35.definition_formal,
150
+ definition_raw: p35.definition_raw,
151
+ term_raw: p35.term_raw,
152
+ term_forms: [],
153
+ typification_manual: '',
154
+ value_is_property: false
155
+ }
156
+ });
157
+
158
+ const aliases = plan.items.map(item => item.alias);
159
+ expect(new Set(aliases).size).toBe(aliases.length);
160
+ expect(aliases.at(-1)).toBe('P6');
161
+ expect(aliases.slice(0, -1).every(alias => alias !== 'P6')).toBe(true);
162
+ });
163
+
164
+ it('reuses schema constituent matched by normalized substituted expression', () => {
165
+ const userArgs: ArgumentValue[] = [{ alias: 'σ', typification: 'ℬ((R1×R1)×R1)', value: 'S2' }];
166
+
167
+ const baseline = planTemplateInstantiation({
168
+ targetSchema,
169
+ templateItems,
170
+ prototype: p30,
171
+ userArgs,
172
+ mainItem: {
173
+ alias: 'A2',
174
+ cst_type: CstType.PREDICATE,
175
+ crucial: false,
176
+ convention: '',
177
+ definition_formal: p30.definition_formal,
178
+ definition_raw: '',
179
+ term_raw: p30.term_raw,
180
+ term_forms: [],
181
+ typification_manual: '',
182
+ value_is_property: false
183
+ }
184
+ });
185
+
186
+ const existingFunction = baseline.items[0];
187
+ const schemaWithEquivalentFunction = mockSchema([
188
+ ...targetSchema.items,
189
+ mockCst({
190
+ id: 12,
191
+ alias: 'F9',
192
+ cst_type: existingFunction.cst_type,
193
+ definition_formal: existingFunction.definition_formal
194
+ })
195
+ ]);
196
+
197
+ const plan = planTemplateInstantiation({
198
+ targetSchema: schemaWithEquivalentFunction,
199
+ templateItems,
200
+ prototype: p30,
201
+ userArgs,
202
+ mainItem: {
203
+ alias: 'A2',
204
+ cst_type: CstType.PREDICATE,
205
+ crucial: false,
206
+ convention: '',
207
+ definition_formal: p30.definition_formal,
208
+ definition_raw: '',
209
+ term_raw: p30.term_raw,
210
+ term_forms: [],
211
+ typification_manual: '',
212
+ value_is_property: false
213
+ }
214
+ });
215
+
216
+ expect(plan.items).toHaveLength(1);
217
+ expect(plan.items[0].alias).toBe('A2');
218
+ expect(plan.items[0].definition_formal).toContain('F9[');
219
+ expect(plan.items[0].definition_formal).not.toContain('F42[');
220
+ });
221
+
222
+ it('instantiates bank dependency when target alias collides but definition differs', () => {
223
+ const schemaWithUnrelatedF42 = mockSchema([
224
+ ...targetSchema.items,
225
+ mockCst({
226
+ id: 12,
227
+ alias: 'F42',
228
+ cst_type: CstType.FUNCTION,
229
+ definition_formal: '[α∈R1] α'
230
+ })
231
+ ]);
232
+
233
+ const plan = planTemplateInstantiation({
234
+ targetSchema: schemaWithUnrelatedF42,
235
+ templateItems,
236
+ prototype: p30,
237
+ userArgs: [{ alias: 'σ', typification: 'ℬ((R1×R1)×R1)', value: 'S2' }],
238
+ mainItem: {
239
+ alias: 'A2',
240
+ cst_type: CstType.PREDICATE,
241
+ crucial: false,
242
+ convention: '',
243
+ definition_formal: p30.definition_formal,
244
+ definition_raw: '',
245
+ term_raw: p30.term_raw,
246
+ term_forms: [],
247
+ typification_manual: '',
248
+ value_is_property: false
249
+ }
250
+ });
251
+
252
+ const dependency = plan.items[0];
253
+ expect(plan.items).toHaveLength(2);
254
+ expect(dependency.alias).not.toBe('F42');
255
+ expect(dependency.definition_formal).toContain('S2');
256
+ expect(plan.items.at(-1)!.definition_formal).toContain(`${dependency.alias}[`);
257
+ expect(plan.items.at(-1)!.definition_formal).not.toContain('F42[');
258
+ });
259
+
260
+ it('reuses template dependency when target has matching substituted definition', () => {
261
+ const userArgs: ArgumentValue[] = [{ alias: 'σ', typification: 'ℬ((R1×R1)×R1)', value: 'S2' }];
262
+
263
+ const baseline = planTemplateInstantiation({
264
+ targetSchema,
265
+ templateItems,
266
+ prototype: p30,
267
+ userArgs,
268
+ mainItem: {
269
+ alias: 'A2',
270
+ cst_type: CstType.PREDICATE,
271
+ crucial: false,
272
+ convention: '',
273
+ definition_formal: p30.definition_formal,
274
+ definition_raw: '',
275
+ term_raw: p30.term_raw,
276
+ term_forms: [],
277
+ typification_manual: '',
278
+ value_is_property: false
279
+ }
280
+ });
281
+
282
+ const equivalentFunction = baseline.items[0];
283
+ const schemaWithF42 = mockSchema([
284
+ ...targetSchema.items,
285
+ mockCst({
286
+ id: 12,
287
+ alias: 'F42',
288
+ cst_type: equivalentFunction.cst_type,
289
+ definition_formal: equivalentFunction.definition_formal
290
+ })
291
+ ]);
292
+
293
+ const plan = planTemplateInstantiation({
294
+ targetSchema: schemaWithF42,
295
+ templateItems,
296
+ prototype: p30,
297
+ userArgs,
298
+ mainItem: {
299
+ alias: 'A2',
300
+ cst_type: CstType.PREDICATE,
301
+ crucial: false,
302
+ convention: '',
303
+ definition_formal: p30.definition_formal,
304
+ definition_raw: '',
305
+ term_raw: p30.term_raw,
306
+ term_forms: [],
307
+ typification_manual: '',
308
+ value_is_property: false
309
+ }
310
+ });
311
+
312
+ expect(plan.items).toHaveLength(1);
313
+ expect(plan.items[0].alias).toBe('A2');
314
+ expect(plan.items[0].definition_formal).toContain('F42[');
315
+ });
316
+
317
+ it('reports duplicate alias when the selected expression already exists in the schema', () => {
318
+ const userArgs: ArgumentValue[] = [
319
+ { alias: 'α', typification: 'ℬ(R1)', value: 'S1' },
320
+ { alias: 'σ', typification: 'ℬ((R1×R1)×R1)', value: 'S2' }
321
+ ];
322
+
323
+ const baseline = planTemplateInstantiation({
324
+ targetSchema,
325
+ templateItems,
326
+ prototype: p35,
327
+ userArgs,
328
+ mainItem: {
329
+ alias: 'A1',
330
+ cst_type: CstType.PREDICATE,
331
+ crucial: false,
332
+ convention: '',
333
+ definition_formal: p35.definition_formal,
334
+ definition_raw: p35.definition_raw,
335
+ term_raw: p35.term_raw,
336
+ term_forms: [],
337
+ typification_manual: '',
338
+ value_is_property: false
339
+ }
340
+ });
341
+
342
+ const existingMain = baseline.items.at(-1)!;
343
+ const plan = planTemplateInstantiation({
344
+ targetSchema: mockSchema([
345
+ ...targetSchema.items,
346
+ mockCst({
347
+ id: 20,
348
+ alias: 'A9',
349
+ cst_type: existingMain.cst_type,
350
+ definition_formal: existingMain.definition_formal
351
+ })
352
+ ]),
353
+ templateItems,
354
+ prototype: p35,
355
+ userArgs,
356
+ mainItem: {
357
+ alias: 'A1',
358
+ cst_type: CstType.PREDICATE,
359
+ crucial: false,
360
+ convention: '',
361
+ definition_formal: p35.definition_formal,
362
+ definition_raw: p35.definition_raw,
363
+ term_raw: p35.term_raw,
364
+ term_forms: [],
365
+ typification_manual: '',
366
+ value_is_property: false
367
+ }
368
+ });
369
+
370
+ expect(plan.mainDuplicateAlias).toBe('A9');
371
+ expect(plan.items.some(item => item.term_raw === p35.term_raw)).toBe(false);
372
+ });
373
+
374
+ it('reports binding conflict when the same template parameter is bound to different aliases', () => {
375
+ const f10 = mockCst({
376
+ id: 5,
377
+ alias: 'F10',
378
+ cst_type: CstType.FUNCTION,
379
+ term_raw: 'g',
380
+ definition_formal: '[x∈R1] x'
381
+ });
382
+ const p11 = mockCst({
383
+ id: 6,
384
+ alias: 'P11',
385
+ cst_type: CstType.PREDICATE,
386
+ term_raw: 'h',
387
+ definition_formal: '[y∈R1] F10[y]'
388
+ });
389
+ const mainTemplate = mockCst({
390
+ id: 7,
391
+ alias: 'P12',
392
+ cst_type: CstType.PREDICATE,
393
+ term_raw: 'main',
394
+ definition_formal: '[a∈R1, b∈R1] P11[a] & P11[b]'
395
+ });
396
+
397
+ const plan = planTemplateInstantiation({
398
+ targetSchema,
399
+ templateItems: [f10, p11],
400
+ prototype: mainTemplate,
401
+ userArgs: [
402
+ { alias: 'a', typification: 'R1', value: 'S1' },
403
+ { alias: 'b', typification: 'R1', value: 'S2' }
404
+ ],
405
+ mainItem: {
406
+ alias: 'A1',
407
+ cst_type: CstType.PREDICATE,
408
+ crucial: false,
409
+ convention: '',
410
+ definition_formal: mainTemplate.definition_formal,
411
+ definition_raw: '',
412
+ term_raw: mainTemplate.term_raw,
413
+ term_forms: [],
414
+ typification_manual: '',
415
+ value_is_property: false
416
+ }
417
+ });
418
+
419
+ expect(plan.bindingConflict).toEqual({
420
+ templateAlias: 'P11',
421
+ paramAlias: 'y',
422
+ existing: 'S1',
423
+ incoming: 'S2'
424
+ });
425
+ expect(plan.items).toHaveLength(0);
426
+ });
427
+ });