@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,180 @@
1
+ /*
2
+ * Module: Typification for RSLang.
3
+ */
4
+
5
+ import { type Branded } from '../../shared';
6
+
7
+ /** Typification structure enumeration. */
8
+ export const TypeID = {
9
+ anyTypification: 1,
10
+ integer: 2,
11
+ basic: 3,
12
+ tuple: 4,
13
+ collection: 5,
14
+ logic: 6,
15
+ function: 7,
16
+ predicate: 8
17
+ } as const;
18
+ export type TypeID = (typeof TypeID)[keyof typeof TypeID];
19
+
20
+ /** Represents type class. */
21
+ export const TypeClass = {
22
+ logic: 1,
23
+ typification: 2,
24
+ function: 3,
25
+ predicate: 4
26
+ } as const;
27
+ export type TypeClass = (typeof TypeClass)[keyof typeof TypeClass];
28
+
29
+ /** Logic type object. */
30
+ export const LogicT = { typeID: TypeID.logic } as const;
31
+
32
+ /** Integer type object. */
33
+ export const IntegerT = {
34
+ typeID: TypeID.integer,
35
+ isOrdered: true,
36
+ isArithmetic: true,
37
+ isIntegerCompatible: true
38
+ } as const;
39
+
40
+ /** Type transformation path. */
41
+ export type TypePath = Branded<number[], 'TypePath'>;
42
+
43
+ /** Creates type path. */
44
+ export function makeTypePath(path: number[]): TypePath {
45
+ return path as TypePath;
46
+ }
47
+
48
+ /** AnyTyped type object. */
49
+ export const AnyTypificationT = { typeID: TypeID.anyTypification } as const;
50
+
51
+ /** Empty set typification. */
52
+ export const EmptySetT = bool(AnyTypificationT);
53
+
54
+ /** Parametrized typification. */
55
+ export type Parametrized = EchelonFunctional | EchelonPredicate;
56
+
57
+ /** General expression types. */
58
+ export type ExpressionType =
59
+ | EchelonLogic
60
+ | EchelonBase
61
+ | EchelonTuple
62
+ | EchelonCollection
63
+ | EchelonFunctional
64
+ | EchelonPredicate
65
+ | EchelonAnyTyped
66
+ | EchelonInteger;
67
+
68
+ /** Setexpr type. */
69
+ export type Typification = EchelonBase | EchelonAnyTyped | EchelonInteger | EchelonCollection | EchelonTuple;
70
+
71
+ /** Typification context. */
72
+ export type TypeContext = Map<string, ExpressionType>;
73
+
74
+ /** Functional argument. */
75
+ export interface Argument {
76
+ readonly alias: string;
77
+ readonly type: Typification;
78
+ }
79
+
80
+ /** Type: Logic. */
81
+ export interface EchelonLogic {
82
+ readonly typeID: typeof TypeID.logic;
83
+ }
84
+
85
+ /** Type: AnyTyped. */
86
+ export interface EchelonAnyTyped {
87
+ readonly typeID: typeof TypeID.anyTypification;
88
+ }
89
+
90
+ /** Type: Integer. */
91
+ export interface EchelonInteger {
92
+ readonly typeID: typeof TypeID.integer;
93
+ readonly isOrdered: true;
94
+ readonly isArithmetic: true;
95
+ readonly isIntegerCompatible: true;
96
+ }
97
+
98
+ /** Type: Element of basic set. */
99
+ export interface EchelonBase {
100
+ readonly typeID: typeof TypeID.basic;
101
+ readonly baseID: string;
102
+ readonly isOrdered?: boolean;
103
+ readonly isArithmetic?: boolean;
104
+ readonly isIntegerCompatible?: boolean;
105
+ }
106
+
107
+ /** Type: Tuple. */
108
+ export interface EchelonTuple {
109
+ readonly typeID: typeof TypeID.tuple;
110
+ readonly factors: readonly Typification[];
111
+ }
112
+
113
+ /** Type: Collection. */
114
+ export interface EchelonCollection {
115
+ readonly typeID: typeof TypeID.collection;
116
+ readonly base: Typification;
117
+ }
118
+
119
+ /** Type: Functional. */
120
+ export interface EchelonFunctional {
121
+ readonly typeID: typeof TypeID.function;
122
+ readonly result: Typification;
123
+ readonly args: readonly Argument[];
124
+ }
125
+
126
+ /** Type: Predicate. */
127
+ export interface EchelonPredicate {
128
+ readonly typeID: typeof TypeID.predicate;
129
+ readonly result: EchelonLogic;
130
+ readonly args: readonly Argument[];
131
+ }
132
+
133
+ /** Create basic element typification. */
134
+ export function basic(alias: string): EchelonBase {
135
+ return { typeID: TypeID.basic, baseID: alias };
136
+ }
137
+
138
+ /** Create constant element typification. */
139
+ export function constant(alias: string): EchelonBase {
140
+ return { typeID: TypeID.basic, baseID: alias, isOrdered: true, isArithmetic: true, isIntegerCompatible: true };
141
+ }
142
+
143
+ /** Create boolean typification. */
144
+ export function bool(base: Typification): EchelonCollection {
145
+ return { typeID: TypeID.collection, base };
146
+ }
147
+
148
+ /** Create tuple typification. */
149
+ export function tuple(factors: Typification[]): EchelonTuple {
150
+ if (factors.length < 2) {
151
+ throw new Error('Tuple with less than two factors is not allowed');
152
+ }
153
+ return { typeID: TypeID.tuple, factors };
154
+ }
155
+
156
+ /** Remove boolean from typification. */
157
+ export function debool(target: EchelonCollection): Typification {
158
+ return target.base;
159
+ }
160
+
161
+ /** Extract component from tuple. */
162
+ export function component(target: EchelonTuple, index: number): Typification | null {
163
+ return target.factors[index - 1] ?? null;
164
+ }
165
+
166
+ /** Checks if given type is typification. */
167
+ export function isTypification(type: ExpressionType | null): boolean {
168
+ return (
169
+ type?.typeID === TypeID.basic ||
170
+ type?.typeID === TypeID.anyTypification ||
171
+ type?.typeID === TypeID.integer ||
172
+ type?.typeID === TypeID.collection ||
173
+ type?.typeID === TypeID.tuple
174
+ );
175
+ }
176
+
177
+ /** Checks if given type is radical. */
178
+ export function isRadical(alias: string): boolean {
179
+ return alias.length > 0 && alias.startsWith('R') && alias[1] !== '0';
180
+ }
@@ -0,0 +1,206 @@
1
+ import { beforeEach, describe, expect, it } from 'vitest';
2
+
3
+ import { buildTree } from '../../parsing';
4
+ import { RSErrorCode, type RSErrorDescription } from '../error';
5
+ import { normalizeAST } from '../parser/normalize';
6
+ import { parser as rslangParser } from '../parser/parser';
7
+
8
+ import { ValueAuditor } from './value-auditor';
9
+ import { ValueClass, type ValueClassContext } from './value-class';
10
+
11
+ // Helper to build AST
12
+ function buildAST(expression: string) {
13
+ const tree = rslangParser.parse(expression);
14
+ const ast = buildTree(tree.cursor());
15
+ normalizeAST(ast, expression);
16
+ return ast;
17
+ }
18
+
19
+ function setupValueContext(): ValueClassContext {
20
+ const context: ValueClassContext = new Map();
21
+ context.set('X1', ValueClass.VALUE);
22
+ context.set('D1', ValueClass.VALUE);
23
+ context.set('D2', ValueClass.PROPERTY);
24
+ context.set('F1', ValueClass.VALUE);
25
+ context.set('F2', ValueClass.PROPERTY);
26
+ return context;
27
+ }
28
+
29
+ const correctValuesData = [
30
+ // Literals and global identifiers
31
+ ['1', ValueClass.VALUE],
32
+ ['Z', ValueClass.PROPERTY],
33
+ ['X1', ValueClass.VALUE],
34
+ ['D1', ValueClass.VALUE],
35
+ ['D2', ValueClass.PROPERTY],
36
+ // Functions
37
+ ['F1[X1, D1]', ValueClass.VALUE],
38
+ ['F2[X1, D1]', ValueClass.PROPERTY],
39
+ ['[a∈ℬ(R1), b∈ℬ(R2)] a⊆Pr1(b) & card(a)=card(b)', ValueClass.VALUE],
40
+ ['[a∈ℬ(R1)] ℬ(a)', ValueClass.PROPERTY],
41
+ // Integral
42
+ ['1+2', ValueClass.VALUE],
43
+ ['1*2', ValueClass.VALUE],
44
+ ['card(X1)', ValueClass.VALUE],
45
+ ['card(D1)', ValueClass.VALUE],
46
+ // Logical
47
+ ['1<1', ValueClass.VALUE],
48
+ ['1=1', ValueClass.VALUE],
49
+ ['1≠1', ValueClass.VALUE],
50
+ ['¬1=1', ValueClass.VALUE],
51
+ ['1=1 & 1=1', ValueClass.VALUE],
52
+ ['X1=X1', ValueClass.VALUE],
53
+ ['X1=∅', ValueClass.VALUE],
54
+ ['∃a∈X1 a=a', ValueClass.VALUE],
55
+ ['∃a∈D1 a=a', ValueClass.VALUE],
56
+ ['∀a∈X1 a=a', ValueClass.VALUE],
57
+ ['∀a∈D1 a=a', ValueClass.VALUE],
58
+ ['∀a,b∈D1 a=a', ValueClass.VALUE],
59
+ ['∀(a,b)∈D1 a=b', ValueClass.VALUE],
60
+ // Set predicates
61
+ ['X1 ∈ D1', ValueClass.VALUE],
62
+ ['X1 ∈ D2', ValueClass.VALUE],
63
+ ['X1 ∉ D1', ValueClass.VALUE],
64
+ ['X1 ⊂ X1', ValueClass.VALUE],
65
+ ['X1 ⊆ D2', ValueClass.VALUE],
66
+ // Constructors
67
+ ['ℬ(X1)', ValueClass.PROPERTY],
68
+ ['ℬ(D2)', ValueClass.PROPERTY],
69
+ ['X1×X1', ValueClass.VALUE],
70
+ ['X1×D2', ValueClass.PROPERTY],
71
+ ['D2×X1', ValueClass.PROPERTY],
72
+ ['(X1, D1)', ValueClass.VALUE],
73
+ ['{D1, X1}', ValueClass.VALUE],
74
+ ['D{t∈X1 | t=t}', ValueClass.VALUE],
75
+ ['D{t∈X1 | t∈D2}', ValueClass.VALUE],
76
+ ['D{t∈D2 | t=t}', ValueClass.PROPERTY],
77
+ ['R{a:=X1 | a\\a}', ValueClass.VALUE],
78
+ ['R{(a,b):=(0,1) | a<3 | (a+1, b+1)}', ValueClass.VALUE],
79
+ ['I{(a, b) | a:∈X1; X1\\X1=∅; b:=D1}', ValueClass.VALUE],
80
+ // Set operations
81
+ ['X1∩X1', ValueClass.VALUE],
82
+ ['D2∩X1', ValueClass.VALUE],
83
+ ['X1∩D2', ValueClass.VALUE],
84
+ ['D2∩D2', ValueClass.PROPERTY],
85
+ ['X1\\X1', ValueClass.VALUE],
86
+ ['D2\\X1', ValueClass.PROPERTY],
87
+ ['X1\\D2', ValueClass.VALUE],
88
+ ['D2\\D2', ValueClass.PROPERTY],
89
+ ['X1∪X1', ValueClass.VALUE],
90
+ ['D2∪X1', ValueClass.PROPERTY],
91
+ ['X1∪D2', ValueClass.PROPERTY],
92
+ ['D2∪D2', ValueClass.PROPERTY],
93
+ ['pr1(D1)', ValueClass.VALUE],
94
+ ['Pr1(D1)', ValueClass.VALUE],
95
+ ['Pr1,2(D1)', ValueClass.VALUE],
96
+ ['Fi1[X1](D1)', ValueClass.VALUE],
97
+ ['Fi1,2[X1,D2](D1)', ValueClass.VALUE],
98
+ ['Fi1[X1](D2)', ValueClass.PROPERTY],
99
+ ['Fi1[D2](X1)', ValueClass.VALUE],
100
+ ['Fi1[D2](D2)', ValueClass.PROPERTY],
101
+ ['bool(X1)', ValueClass.VALUE],
102
+ ['bool(D1)', ValueClass.VALUE],
103
+ ['debool(D1)', ValueClass.VALUE],
104
+ ['red(D1)', ValueClass.VALUE]
105
+ ];
106
+
107
+ const errorData = [
108
+ // Identifiers
109
+ ['X42', { code: RSErrorCode.globalNoValue, from: 0, to: 3, params: ['X42'] }],
110
+ // Functions
111
+ ['F1[D2]', { code: RSErrorCode.invalidPropertyUsage, from: 3, to: 5 }],
112
+ ['F42[D2]', { code: RSErrorCode.globalNoValue, from: 0, to: 3, params: ['F42'] }],
113
+ // Integral
114
+ ['card(D2)', { code: RSErrorCode.invalidPropertyUsage, from: 5, to: 7 }],
115
+ ['card(D3)', { code: RSErrorCode.globalNoValue, from: 5, to: 7, params: ['D3'] }],
116
+ // Logical
117
+ ['D2=X1', { code: RSErrorCode.invalidPropertyUsage, from: 0, to: 2 }],
118
+ ['X1=D2', { code: RSErrorCode.invalidPropertyUsage, from: 3, to: 5 }],
119
+ ['∃a∈ℬ(X1) a=a', { code: RSErrorCode.invalidPropertyUsage, from: 3, to: 8 }],
120
+ ['∃a∈D2 a=a', { code: RSErrorCode.invalidPropertyUsage, from: 3, to: 5 }],
121
+ ['∀a∈D3 a=a', { code: RSErrorCode.globalNoValue, from: 3, to: 5, params: ['D3'] }],
122
+ ['∃a∈D3 a=a', { code: RSErrorCode.globalNoValue, from: 3, to: 5, params: ['D3'] }],
123
+ // Set predicates
124
+ ['X1∈D3', { code: RSErrorCode.globalNoValue, from: 3, to: 5, params: ['D3'] }],
125
+ ['D2∈X1', { code: RSErrorCode.invalidPropertyUsage, from: 0, to: 2 }],
126
+ ['X1⊂D2', { code: RSErrorCode.invalidPropertyUsage, from: 3, to: 5 }],
127
+ ['X1⊄D2', { code: RSErrorCode.invalidPropertyUsage, from: 3, to: 5 }],
128
+ // Constructors
129
+ ['ℬ(D3)', { code: RSErrorCode.globalNoValue, from: 2, to: 4, params: ['D3'] }],
130
+ ['X1×D3', { code: RSErrorCode.globalNoValue, from: 3, to: 5, params: ['D3'] }],
131
+ ['D3×X1', { code: RSErrorCode.globalNoValue, from: 0, to: 2, params: ['D3'] }],
132
+ ['(X1, D2)', { code: RSErrorCode.invalidPropertyUsage, from: 5, to: 7 }],
133
+ ['(D2, X1)', { code: RSErrorCode.invalidPropertyUsage, from: 1, to: 3 }],
134
+ ['(X1, D3)', { code: RSErrorCode.globalNoValue, from: 5, to: 7, params: ['D3'] }],
135
+ ['{X1, D2}', { code: RSErrorCode.invalidPropertyUsage, from: 5, to: 7 }],
136
+ ['{D2, X1}', { code: RSErrorCode.invalidPropertyUsage, from: 1, to: 3 }],
137
+ ['{X1, D3}', { code: RSErrorCode.globalNoValue, from: 5, to: 7, params: ['D3'] }],
138
+ ['D{t ∈ D3 | t=t}', { code: RSErrorCode.globalNoValue, from: 6, to: 8, params: ['D3'] }],
139
+ ['R{a := X1 | D2\\a}', { code: RSErrorCode.invalidPropertyUsage, from: 12, to: 16 }],
140
+ ['R{a := X1 | D3\\a}', { code: RSErrorCode.globalNoValue, from: 12, to: 14, params: ['D3'] }],
141
+ ['R{a := D2 | a\\a}', { code: RSErrorCode.invalidPropertyUsage, from: 7, to: 9 }],
142
+ ['R{a := D3 | a\\a}', { code: RSErrorCode.globalNoValue, from: 7, to: 9, params: ['D3'] }],
143
+ ['I{(a,b) | a:∈D2; X1\\X1=∅; b:=D1}', { code: RSErrorCode.invalidPropertyUsage, from: 13, to: 15 }],
144
+ ['I{(a,b) | a:∈D3; X1\\X1=∅; b:=D1}', { code: RSErrorCode.globalNoValue, from: 13, to: 15, params: ['D3'] }],
145
+ ['I{(a,b) | a:∈X1; D2\\X1=∅; b:=D1}', { code: RSErrorCode.invalidPropertyUsage, from: 17, to: 22 }],
146
+ ['I{(a,b) | a:∈X1; D3\\X1=∅; b:=D1}', { code: RSErrorCode.globalNoValue, from: 17, to: 19, params: ['D3'] }],
147
+ ['I{(a,b) | a:∈X1; X1\\X1=∅; b:=D2}', { code: RSErrorCode.invalidPropertyUsage, from: 29, to: 31 }],
148
+ ['I{(a,b) | a:∈X1; X1\\X1=∅; b:=D3}', { code: RSErrorCode.globalNoValue, from: 29, to: 31, params: ['D3'] }],
149
+ // Set operations
150
+ ['pr1(D2)', { code: RSErrorCode.invalidPropertyUsage, from: 4, to: 6 }],
151
+ ['pr1(D3)', { code: RSErrorCode.globalNoValue, from: 4, to: 6, params: ['D3'] }],
152
+ ['Pr1(D2)', { code: RSErrorCode.invalidPropertyUsage, from: 4, to: 6 }],
153
+ ['Pr1(D3)', { code: RSErrorCode.globalNoValue, from: 4, to: 6, params: ['D3'] }],
154
+ ['Fi1[D3](X1)', { code: RSErrorCode.globalNoValue, from: 4, to: 6, params: ['D3'] }],
155
+ ['Fi1[X1](D3)', { code: RSErrorCode.globalNoValue, from: 8, to: 10, params: ['D3'] }],
156
+ ['bool(D2)', { code: RSErrorCode.invalidPropertyUsage, from: 5, to: 7 }],
157
+ ['bool(D3)', { code: RSErrorCode.globalNoValue, from: 5, to: 7, params: ['D3'] }],
158
+ ['debool(D2)', { code: RSErrorCode.invalidPropertyUsage, from: 7, to: 9 }],
159
+ ['debool(D3)', { code: RSErrorCode.globalNoValue, from: 7, to: 9, params: ['D3'] }],
160
+ ['red(D2)', { code: RSErrorCode.invalidPropertyUsage, from: 4, to: 6 }],
161
+ ['red(D3)', { code: RSErrorCode.globalNoValue, from: 4, to: 6, params: ['D3'] }]
162
+ ];
163
+
164
+ describe('ValueAuditor', () => {
165
+ let valueContext: ValueClassContext;
166
+ let valueAuditor: ValueAuditor;
167
+ let errors: RSErrorDescription[];
168
+
169
+ beforeEach(() => {
170
+ valueContext = setupValueContext();
171
+ valueAuditor = new ValueAuditor(valueContext);
172
+ errors = [];
173
+ });
174
+
175
+ function expectValue(input: string, expectedValue: string) {
176
+ const ast = buildAST(input);
177
+ expect(ast.hasError).toBe(false);
178
+ const result = valueAuditor.run(ast, error => errors.push(error));
179
+ expect(result).toBe(expectedValue);
180
+ }
181
+
182
+ function expectError(input: string, expectedError: RSErrorDescription) {
183
+ const ast = buildAST(input);
184
+ expect(ast.hasError).toBe(false);
185
+ expect(errors.length).toBe(0);
186
+
187
+ valueAuditor.run(ast, error => errors.push(error));
188
+ expect(errors.length).toBe(1);
189
+ expect(errors[0]).toMatchObject(expectedError);
190
+ }
191
+
192
+ // .filter(([input]) => input === '[α∈ℬ(R1), β∈ℬ(R1×R2)] α⊆Pr1(β) & card(α)=card(β)')
193
+ correctValuesData.forEach(([input, expectedValue]) => {
194
+ it(`Correct type for "${input}"`, () => expectValue(input, expectedValue));
195
+ });
196
+
197
+ errorData.forEach(([input, expectedError]) => {
198
+ it(`Error for "${input as string}"`, () => expectError(input as string, expectedError as RSErrorDescription));
199
+ });
200
+
201
+ it('Reports token end positions for value errors', () => {
202
+ const ast = buildAST('X42');
203
+ valueAuditor.run(ast, error => errors.push(error));
204
+ expect(errors[0]).toMatchObject({ code: RSErrorCode.globalNoValue, from: 0, to: 3 });
205
+ });
206
+ });