@rsconcept/domain 1.2.0 → 1.4.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.
- package/dist/{analyzer-DlSq3Y3r.d.ts → analyzer-BliNe3pV.d.ts} +2 -2
- package/dist/{ast-annotations-BiMjkKvz.d.ts → ast-annotations-GOkbNN8F.d.ts} +2 -2
- package/dist/{calculator-C9W2jkSx.d.ts → calculator-DFevxZyV.d.ts} +3 -3
- package/dist/{error-E1LVq_3w.d.ts → error-deey7EiC.d.ts} +2 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +1 -1
- package/dist/library/rsengine.d.ts +2 -3
- package/dist/library/rsengine.js +15 -43
- package/dist/library/rsengine.js.map +1 -1
- package/dist/library/rsform-api.d.ts +1 -1
- package/dist/library/rsform.d.ts +1 -1
- package/dist/library/rsmodel-api.d.ts +1 -1
- package/dist/library/rsmodel-api.js +1 -1
- package/dist/library/rsmodel.d.ts +1 -1
- package/dist/rslang/ast-annotations.d.ts +1 -1
- package/dist/rslang/error.d.ts +1 -1
- package/dist/rslang/error.js +1 -0
- package/dist/rslang/error.js.map +1 -1
- package/dist/rslang/eval/calculator.d.ts +1 -1
- package/dist/rslang/eval/calculator.js +1 -1
- package/dist/rslang/eval/evaluation-cache.d.ts +1 -1
- package/dist/rslang/eval/evaluator.d.ts +2 -2
- package/dist/rslang/eval/evaluator.js +17 -11
- package/dist/rslang/eval/evaluator.js.map +1 -1
- package/dist/rslang/eval/value-api.d.ts +1 -1
- package/dist/rslang/eval/value-api.js +1 -1
- package/dist/rslang/eval/value.d.ts +2 -2
- package/dist/rslang/eval/value.js +2 -2
- package/dist/rslang/index.d.ts +6 -6
- package/dist/rslang/index.js +1 -1
- package/dist/rslang/parser/syntax-errors.d.ts +1 -1
- package/dist/rslang/semantic/analyzer.d.ts +1 -1
- package/dist/rslang/semantic/type-auditor.d.ts +1 -1
- package/dist/rslang/semantic/type-auditor.js +2 -1
- package/dist/rslang/semantic/type-auditor.js.map +1 -1
- package/dist/rslang/semantic/typification-api.js +1 -1
- package/dist/rslang/semantic/typification-api.js.map +1 -1
- package/dist/rslang/semantic/value-auditor.d.ts +1 -1
- package/dist/{value-CTjX6825.d.ts → value-BduA_ZGp.d.ts} +8 -2
- package/dist/{value-api-Bw-SgaYY.d.ts → value-api-B6T6f4Ia.d.ts} +2 -2
- package/dist/{value-B8UtCqaK.js → value-ybFBRuz6.js} +14 -3
- package/dist/{value-B8UtCqaK.js.map → value-ybFBRuz6.js.map} +1 -1
- package/package.json +2 -2
- package/src/library/rsengine.ts +14 -59
- package/src/rslang/error.ts +1 -0
- package/src/rslang/eval/calculator.test.ts +8 -0
- package/src/rslang/eval/evaluator.test.ts +5 -1
- package/src/rslang/eval/evaluator.ts +22 -13
- package/src/rslang/eval/value.ts +14 -1
- package/src/rslang/semantic/type-auditor.test.ts +21 -1
- package/src/rslang/semantic/type-auditor.ts +2 -1
- package/src/rslang/semantic/typification-api.test.ts +11 -2
- package/src/rslang/semantic/typification-api.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typification-api.js","names":[],"sources":["../../../src/rslang/semantic/typification-api.ts"],"sourcesContent":["/**\n * Module: Typification API for RSLang.\n */\n\nimport {\n bool,\n component,\n type EchelonBase,\n type EchelonCollection,\n type EchelonTuple,\n type ExpressionType,\n IntegerT,\n isRadical,\n isTypification,\n tuple,\n TypeClass,\n TypeID,\n type TypePath,\n type Typification\n} from './typification';\n\n/** Record map from typeID to typeClass. */\nconst TypeIDToClass: Record<TypeID, TypeClass> = {\n [TypeID.anyTypification]: TypeClass.typification,\n [TypeID.integer]: TypeClass.typification,\n [TypeID.basic]: TypeClass.typification,\n [TypeID.tuple]: TypeClass.typification,\n [TypeID.collection]: TypeClass.typification,\n [TypeID.logic]: TypeClass.logic,\n [TypeID.function]: TypeClass.function,\n [TypeID.predicate]: TypeClass.predicate\n};\n\n/** Returns the TypeClass associated with the given TypeID. */\nexport function getTypeClass(typeID: TypeID): TypeClass {\n return TypeIDToClass[typeID];\n}\n\n/** Returns true if the given typification is generic. */\nexport function hasGenerics(type: Typification): boolean {\n switch (type.typeID) {\n case TypeID.anyTypification:\n return true;\n case TypeID.integer:\n return false;\n case TypeID.basic:\n return isRadical(type.baseID);\n case TypeID.collection:\n return hasGenerics(type.base);\n case TypeID.tuple:\n for (const factor of type.factors) {\n if (hasGenerics(factor)) {\n return true;\n }\n }\n return false;\n }\n}\n\n/** Checks if two typifications are equal. */\nexport function checkEquality(type1: Typification, type2: Typification): boolean {\n if (type1 === type2) {\n return true;\n }\n if (type1.typeID !== type2.typeID) {\n return false;\n }\n switch (type1.typeID) {\n case TypeID.integer:\n case TypeID.anyTypification:\n return true;\n case TypeID.basic:\n return type1.baseID === (type2 as EchelonBase).baseID;\n case TypeID.collection:\n return checkEquality(type1.base, (type2 as EchelonCollection).base);\n case TypeID.tuple: {\n if (type1.factors.length !== (type2 as EchelonTuple).factors.length) {\n return false;\n }\n for (let index = 0; index < type1.factors.length; ++index) {\n if (!checkEquality(type1.factors[index], (type2 as EchelonTuple).factors[index])) {\n return false;\n }\n }\n return true;\n }\n }\n}\n\n/** Merge two types to get result of binary operation. */\nexport function mergeTypifications(type1: Typification, type2: Typification): Typification | null {\n if (type1 === type2) {\n return type1;\n }\n if (type1.typeID === TypeID.anyTypification) {\n return isTypification(type2) ? type2 : null;\n }\n if (type2.typeID === TypeID.anyTypification) {\n return isTypification(type1) ? type1 : null;\n }\n\n switch (type1.typeID) {\n case TypeID.integer:\n case TypeID.basic:\n return commonType(type1, type2);\n case TypeID.collection:\n if (type2.typeID !== TypeID.collection) {\n return null;\n }\n const base = mergeTypifications(type1.base, type2.base);\n return base ? bool(base) : null;\n case TypeID.tuple:\n if (type2.typeID !== TypeID.tuple) {\n return null;\n }\n if (type1.factors.length !== type2.factors.length) {\n return null;\n }\n const components: Typification[] = [];\n for (let index = 0; index < type1.factors.length; ++index) {\n const component = mergeTypifications(type1.factors[index], type2.factors[index]);\n if (component === null) {\n return null;\n }\n components.push(component);\n }\n return tuple(components);\n }\n}\n\n/** Check compatibility of typifications. */\nexport function checkCompatibility(type1: ExpressionType, type2: ExpressionType): boolean {\n if (type1 === type2) {\n return true;\n }\n if (type1.typeID === TypeID.anyTypification) {\n return isTypification(type2);\n }\n if (type2.typeID === TypeID.anyTypification) {\n return isTypification(type1);\n }\n if (isTypification(type1) !== isTypification(type2)) {\n return false;\n }\n if (\n type1.typeID === TypeID.integer ||\n type1.typeID === TypeID.basic ||\n type2.typeID === TypeID.integer ||\n type2.typeID === TypeID.basic\n ) {\n return commonType(type1 as Typification, type2 as Typification) !== null;\n }\n\n if (type1.typeID !== type2.typeID) {\n return false;\n }\n switch (type1.typeID) {\n case TypeID.collection:\n return checkCompatibility(type1.base, (type2 as EchelonCollection).base);\n case TypeID.tuple:\n if (type1.factors.length !== (type2 as EchelonTuple).factors.length) {\n return false;\n }\n for (let index = 0; index < type1.factors.length; ++index) {\n if (!checkCompatibility(type1.factors[index], (type2 as EchelonTuple).factors[index])) {\n return false;\n }\n }\n return true;\n case TypeID.logic:\n case TypeID.predicate:\n case TypeID.function:\n return false;\n }\n}\n\n/** Compare typification with substitutions. */\nexport function compareTemplated(\n substitutes: Map<string, Typification>,\n arg: Typification,\n value: Typification\n): boolean {\n if (arg === value) {\n return true;\n }\n if (arg.typeID === TypeID.basic && isRadical(arg.baseID)) {\n if (!substitutes.has(arg.baseID)) {\n substitutes.set(arg.baseID, value);\n return true;\n } else {\n const mergeType = mergeTypifications(substitutes.get(arg.baseID)!, value);\n if (mergeType === null) {\n return false;\n }\n substitutes.set(arg.baseID, mergeType);\n return true;\n }\n }\n if (value.typeID === TypeID.anyTypification) {\n return true;\n }\n if (\n arg.typeID === TypeID.integer ||\n arg.typeID === TypeID.basic ||\n value.typeID === TypeID.integer ||\n value.typeID === TypeID.basic\n ) {\n return commonType(arg, value) !== null;\n }\n if (arg.typeID !== value.typeID) {\n return false;\n }\n switch (arg.typeID) {\n case TypeID.collection:\n return compareTemplated(substitutes, arg.base, (value as EchelonCollection).base);\n case TypeID.tuple: {\n if (arg.factors.length !== (value as EchelonTuple).factors.length) {\n return false;\n }\n for (let index = 0; index < arg.factors.length; ++index) {\n if (!compareTemplated(substitutes, arg.factors[index], (value as EchelonTuple).factors[index])) {\n return false;\n }\n }\n return true;\n }\n }\n}\n\n/** Apply substitutions to typification. */\nexport function substituteBase(target: Typification, substitutes: Map<string, Typification>): void {\n switch (target.typeID) {\n case TypeID.basic: {\n if (substitutes.has(target.baseID)) {\n Object.assign(target, substitutes.get(target.baseID)!);\n }\n return;\n }\n case TypeID.collection: {\n substituteBase(target.base, substitutes);\n return;\n }\n case TypeID.tuple: {\n for (const factor of target.factors) {\n substituteBase(factor, substitutes);\n }\n return;\n }\n }\n}\n\n/** Extract bases from typification. */\nexport function extractBases(target: ExpressionType): Set<string> {\n return new Set(extractBasesImpl(target));\n}\n\n/** Apply type path to typification. */\nexport function applyPath(target: Typification, path: TypePath, index = 0): Typification | null {\n let current: Typification | null = target;\n let i = index;\n while (i < path.length && current) {\n switch (current.typeID) {\n case TypeID.anyTypification:\n case TypeID.integer:\n case TypeID.basic:\n return null;\n case TypeID.collection:\n current = current.base;\n i++;\n break;\n case TypeID.tuple:\n current = component(current, path[i]);\n if (current === null) {\n return null;\n }\n i++;\n break;\n }\n }\n return current;\n}\n\n// ===== Internals =====\nfunction commonType(type1: Typification, type2: Typification): Typification | null {\n if (type1 === type2) {\n return type1;\n }\n const int1 = 'isIntegerCompatible' in type1 && type1.isIntegerCompatible;\n const int2 = 'isIntegerCompatible' in type2 && type2.isIntegerCompatible;\n if (!int1 || !int2) {\n if (type1.typeID === TypeID.basic && type2.typeID === TypeID.basic) {\n return type1.baseID === type2.baseID ? type1 : null;\n }\n return null;\n }\n if (type1.typeID === TypeID.integer) {\n return type2;\n } else if (type2.typeID === TypeID.integer) {\n return type1;\n } else {\n return IntegerT;\n }\n}\n\nfunction extractBasesImpl(target: ExpressionType): string[] {\n switch (target.typeID) {\n case TypeID.basic:\n return [target.baseID];\n case TypeID.collection:\n return extractBasesImpl(target.base);\n case TypeID.tuple:\n return target.factors.reduce((result, factor) => result.concat(extractBasesImpl(factor)), [] as string[]);\n case TypeID.function:\n const result = extractBasesImpl(target.result);\n return target.args.reduce((result, arg) => result.concat(extractBasesImpl(arg.type)), result);\n case TypeID.predicate:\n return target.args.reduce((result, arg) => result.concat(extractBasesImpl(arg.type)), [] as string[]);\n default:\n return [];\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"typification-api.js","names":[],"sources":["../../../src/rslang/semantic/typification-api.ts"],"sourcesContent":["/**\n * Module: Typification API for RSLang.\n */\n\nimport {\n bool,\n component,\n type EchelonBase,\n type EchelonCollection,\n type EchelonTuple,\n type ExpressionType,\n IntegerT,\n isRadical,\n isTypification,\n tuple,\n TypeClass,\n TypeID,\n type TypePath,\n type Typification\n} from './typification';\n\n/** Record map from typeID to typeClass. */\nconst TypeIDToClass: Record<TypeID, TypeClass> = {\n [TypeID.anyTypification]: TypeClass.typification,\n [TypeID.integer]: TypeClass.typification,\n [TypeID.basic]: TypeClass.typification,\n [TypeID.tuple]: TypeClass.typification,\n [TypeID.collection]: TypeClass.typification,\n [TypeID.logic]: TypeClass.logic,\n [TypeID.function]: TypeClass.function,\n [TypeID.predicate]: TypeClass.predicate\n};\n\n/** Returns the TypeClass associated with the given TypeID. */\nexport function getTypeClass(typeID: TypeID): TypeClass {\n return TypeIDToClass[typeID];\n}\n\n/** Returns true if the given typification is generic. */\nexport function hasGenerics(type: Typification): boolean {\n switch (type.typeID) {\n case TypeID.anyTypification:\n return true;\n case TypeID.integer:\n return false;\n case TypeID.basic:\n return isRadical(type.baseID);\n case TypeID.collection:\n return hasGenerics(type.base);\n case TypeID.tuple:\n for (const factor of type.factors) {\n if (hasGenerics(factor)) {\n return true;\n }\n }\n return false;\n }\n}\n\n/** Checks if two typifications are equal. */\nexport function checkEquality(type1: Typification, type2: Typification): boolean {\n if (type1 === type2) {\n return true;\n }\n if (type1.typeID !== type2.typeID) {\n return false;\n }\n switch (type1.typeID) {\n case TypeID.integer:\n case TypeID.anyTypification:\n return true;\n case TypeID.basic:\n return type1.baseID === (type2 as EchelonBase).baseID;\n case TypeID.collection:\n return checkEquality(type1.base, (type2 as EchelonCollection).base);\n case TypeID.tuple: {\n if (type1.factors.length !== (type2 as EchelonTuple).factors.length) {\n return false;\n }\n for (let index = 0; index < type1.factors.length; ++index) {\n if (!checkEquality(type1.factors[index], (type2 as EchelonTuple).factors[index])) {\n return false;\n }\n }\n return true;\n }\n }\n}\n\n/** Merge two types to get result of binary operation. */\nexport function mergeTypifications(type1: Typification, type2: Typification): Typification | null {\n if (type1 === type2) {\n return type1;\n }\n if (type1.typeID === TypeID.anyTypification) {\n return isTypification(type2) ? type2 : null;\n }\n if (type2.typeID === TypeID.anyTypification) {\n return isTypification(type1) ? type1 : null;\n }\n\n switch (type1.typeID) {\n case TypeID.integer:\n case TypeID.basic:\n return commonType(type1, type2);\n case TypeID.collection:\n if (type2.typeID !== TypeID.collection) {\n return null;\n }\n const base = mergeTypifications(type1.base, type2.base);\n return base ? bool(base) : null;\n case TypeID.tuple:\n if (type2.typeID !== TypeID.tuple) {\n return null;\n }\n if (type1.factors.length !== type2.factors.length) {\n return null;\n }\n const components: Typification[] = [];\n for (let index = 0; index < type1.factors.length; ++index) {\n const component = mergeTypifications(type1.factors[index], type2.factors[index]);\n if (component === null) {\n return null;\n }\n components.push(component);\n }\n return tuple(components);\n }\n}\n\n/** Check compatibility of typifications. */\nexport function checkCompatibility(type1: ExpressionType, type2: ExpressionType): boolean {\n if (type1 === type2) {\n return true;\n }\n if (type1.typeID === TypeID.anyTypification) {\n return isTypification(type2);\n }\n if (type2.typeID === TypeID.anyTypification) {\n return isTypification(type1);\n }\n if (isTypification(type1) !== isTypification(type2)) {\n return false;\n }\n if (\n type1.typeID === TypeID.integer ||\n type1.typeID === TypeID.basic ||\n type2.typeID === TypeID.integer ||\n type2.typeID === TypeID.basic\n ) {\n return commonType(type1 as Typification, type2 as Typification) !== null;\n }\n\n if (type1.typeID !== type2.typeID) {\n return false;\n }\n switch (type1.typeID) {\n case TypeID.collection:\n return checkCompatibility(type1.base, (type2 as EchelonCollection).base);\n case TypeID.tuple:\n if (type1.factors.length !== (type2 as EchelonTuple).factors.length) {\n return false;\n }\n for (let index = 0; index < type1.factors.length; ++index) {\n if (!checkCompatibility(type1.factors[index], (type2 as EchelonTuple).factors[index])) {\n return false;\n }\n }\n return true;\n case TypeID.logic:\n case TypeID.predicate:\n case TypeID.function:\n return false;\n }\n}\n\n/** Compare typification with substitutions. */\nexport function compareTemplated(\n substitutes: Map<string, Typification>,\n arg: Typification,\n value: Typification\n): boolean {\n if (arg === value) {\n return true;\n }\n if (arg.typeID === TypeID.basic && isRadical(arg.baseID)) {\n if (!substitutes.has(arg.baseID)) {\n substitutes.set(arg.baseID, value);\n return true;\n } else {\n const mergeType = mergeTypifications(substitutes.get(arg.baseID)!, value);\n if (mergeType === null) {\n return false;\n }\n substitutes.set(arg.baseID, mergeType);\n return true;\n }\n }\n if (arg.typeID === TypeID.anyTypification || value.typeID === TypeID.anyTypification) {\n return true;\n }\n if (\n arg.typeID === TypeID.integer ||\n arg.typeID === TypeID.basic ||\n value.typeID === TypeID.integer ||\n value.typeID === TypeID.basic\n ) {\n return commonType(arg, value) !== null;\n }\n if (arg.typeID !== value.typeID) {\n return false;\n }\n switch (arg.typeID) {\n case TypeID.collection:\n return compareTemplated(substitutes, arg.base, (value as EchelonCollection).base);\n case TypeID.tuple: {\n if (arg.factors.length !== (value as EchelonTuple).factors.length) {\n return false;\n }\n for (let index = 0; index < arg.factors.length; ++index) {\n if (!compareTemplated(substitutes, arg.factors[index], (value as EchelonTuple).factors[index])) {\n return false;\n }\n }\n return true;\n }\n }\n}\n\n/** Apply substitutions to typification. */\nexport function substituteBase(target: Typification, substitutes: Map<string, Typification>): void {\n switch (target.typeID) {\n case TypeID.basic: {\n if (substitutes.has(target.baseID)) {\n Object.assign(target, substitutes.get(target.baseID)!);\n }\n return;\n }\n case TypeID.collection: {\n substituteBase(target.base, substitutes);\n return;\n }\n case TypeID.tuple: {\n for (const factor of target.factors) {\n substituteBase(factor, substitutes);\n }\n return;\n }\n }\n}\n\n/** Extract bases from typification. */\nexport function extractBases(target: ExpressionType): Set<string> {\n return new Set(extractBasesImpl(target));\n}\n\n/** Apply type path to typification. */\nexport function applyPath(target: Typification, path: TypePath, index = 0): Typification | null {\n let current: Typification | null = target;\n let i = index;\n while (i < path.length && current) {\n switch (current.typeID) {\n case TypeID.anyTypification:\n case TypeID.integer:\n case TypeID.basic:\n return null;\n case TypeID.collection:\n current = current.base;\n i++;\n break;\n case TypeID.tuple:\n current = component(current, path[i]);\n if (current === null) {\n return null;\n }\n i++;\n break;\n }\n }\n return current;\n}\n\n// ===== Internals =====\nfunction commonType(type1: Typification, type2: Typification): Typification | null {\n if (type1 === type2) {\n return type1;\n }\n const int1 = 'isIntegerCompatible' in type1 && type1.isIntegerCompatible;\n const int2 = 'isIntegerCompatible' in type2 && type2.isIntegerCompatible;\n if (!int1 || !int2) {\n if (type1.typeID === TypeID.basic && type2.typeID === TypeID.basic) {\n return type1.baseID === type2.baseID ? type1 : null;\n }\n return null;\n }\n if (type1.typeID === TypeID.integer) {\n return type2;\n } else if (type2.typeID === TypeID.integer) {\n return type1;\n } else {\n return IntegerT;\n }\n}\n\nfunction extractBasesImpl(target: ExpressionType): string[] {\n switch (target.typeID) {\n case TypeID.basic:\n return [target.baseID];\n case TypeID.collection:\n return extractBasesImpl(target.base);\n case TypeID.tuple:\n return target.factors.reduce((result, factor) => result.concat(extractBasesImpl(factor)), [] as string[]);\n case TypeID.function:\n const result = extractBasesImpl(target.result);\n return target.args.reduce((result, arg) => result.concat(extractBasesImpl(arg.type)), result);\n case TypeID.predicate:\n return target.args.reduce((result, arg) => result.concat(extractBasesImpl(arg.type)), [] as string[]);\n default:\n return [];\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as AstNode } from "../../ast-C8sIpKdL.js";
|
|
2
|
-
import { t as ErrorReporter } from "../../error-
|
|
2
|
+
import { t as ErrorReporter } from "../../error-deey7EiC.js";
|
|
3
3
|
import { n as ValueClassContext, t as ValueClass } from "../../value-class-CNI-lqXJ.js";
|
|
4
4
|
|
|
5
5
|
//#region src/rslang/semantic/value-auditor.d.ts
|
|
@@ -22,6 +22,12 @@ type ValuePath = Branded<number[], 'ValuePath'>;
|
|
|
22
22
|
declare function makeValuePath(path: number[]): ValuePath;
|
|
23
23
|
/** Empty set ∅. */
|
|
24
24
|
declare const EmptySetV: never[];
|
|
25
|
+
/** Thrown when a runtime value operation cannot be applied to the given operands. */
|
|
26
|
+
declare class CalcInvalidDataError extends Error {
|
|
27
|
+
readonly left: string;
|
|
28
|
+
readonly right: string;
|
|
29
|
+
constructor(left: string, right: string);
|
|
30
|
+
}
|
|
25
31
|
/** Compare two structured data without recursive calls. */
|
|
26
32
|
declare function compare(v1: Value, v2: Value): number;
|
|
27
33
|
/** Tuple from components. */
|
|
@@ -29,5 +35,5 @@ declare function tuple(components: Value[]): Value;
|
|
|
29
35
|
/** Set from elements (unique). Value[] - materialized. */
|
|
30
36
|
declare function set(elements: Value[]): Value[];
|
|
31
37
|
//#endregion
|
|
32
|
-
export {
|
|
33
|
-
//# sourceMappingURL=value-
|
|
38
|
+
export { SET_INFINITY as a, VALUE_TRUE as c, ValuePath as d, compare as f, tuple as h, INVALID_ELEMENT as i, Value as l, set as m, CalcInvalidDataError as n, TUPLE_ID as o, makeValuePath as p, EmptySetV as r, VALUE_FALSE as s, BOOL_INFINITY as t, ValueContext as u };
|
|
39
|
+
//# sourceMappingURL=value-BduA_ZGp.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { b as Typification, f as ExpressionType, y as TypePath } from "./typification-Dk-fisgO.js";
|
|
2
|
-
import {
|
|
2
|
+
import { d as ValuePath, l as Value, u as ValueContext } from "./value-BduA_ZGp.js";
|
|
3
3
|
|
|
4
4
|
//#region src/rslang/eval/value-api.d.ts
|
|
5
5
|
/** Cartesian product of factor sets. */
|
|
@@ -46,4 +46,4 @@ declare function setNestedValue(target: Value | null, path: ValuePath, newVal: V
|
|
|
46
46
|
declare function testInvalid(value: Value): boolean;
|
|
47
47
|
//#endregion
|
|
48
48
|
export { setSymDiff as _, extractValue as a, validateValue as b, isTupleValue as c, printValue as d, projection as f, setNestedValue as g, setIntersection as h, convertPathToType as i, makeDefaultValue as l, setDiff as m, cartesianProduct as n, isSetValue as o, reduce as p, contains as r, isSubsetOrEq as s, boolean as t, normalizeValue as u, setUnion as v, valueStub as x, testInvalid as y };
|
|
49
|
-
//# sourceMappingURL=value-api-
|
|
49
|
+
//# sourceMappingURL=value-api-B6T6f4Ia.d.ts.map
|
|
@@ -323,6 +323,17 @@ function makeValuePath(path) {
|
|
|
323
323
|
}
|
|
324
324
|
/** Empty set ∅. */
|
|
325
325
|
const EmptySetV = [];
|
|
326
|
+
/** Thrown when a runtime value operation cannot be applied to the given operands. */
|
|
327
|
+
var CalcInvalidDataError = class extends Error {
|
|
328
|
+
left;
|
|
329
|
+
right;
|
|
330
|
+
constructor(left, right) {
|
|
331
|
+
super(`Cannot compare different types ${left} and ${right}`);
|
|
332
|
+
this.name = "CalcInvalidDataError";
|
|
333
|
+
this.left = left;
|
|
334
|
+
this.right = right;
|
|
335
|
+
}
|
|
336
|
+
};
|
|
326
337
|
/** Compare two structured data without recursive calls. */
|
|
327
338
|
function compare(v1, v2) {
|
|
328
339
|
const stack1 = [v1];
|
|
@@ -336,7 +347,7 @@ function compare(v1, v2) {
|
|
|
336
347
|
if (numDiff !== 0) return numDiff;
|
|
337
348
|
continue;
|
|
338
349
|
}
|
|
339
|
-
if (!Array.isArray(el1) || !Array.isArray(el2)) throw new
|
|
350
|
+
if (!Array.isArray(el1) || !Array.isArray(el2)) throw new CalcInvalidDataError(printValue(el1), printValue(el2));
|
|
340
351
|
const arr1 = el1;
|
|
341
352
|
const arr2 = el2;
|
|
342
353
|
const len1 = arr1.length;
|
|
@@ -361,6 +372,6 @@ function set(elements) {
|
|
|
361
372
|
return sorted;
|
|
362
373
|
}
|
|
363
374
|
//#endregion
|
|
364
|
-
export {
|
|
375
|
+
export { setUnion as A, printValue as C, setIntersection as D, setDiff as E, validateValue as M, valueStub as N, setNestedValue as O, normalizeValue as S, reduce as T, extractValue as _, SET_INFINITY as a, isTupleValue as b, VALUE_TRUE as c, set as d, tuple as f, convertPathToType as g, contains as h, INVALID_ELEMENT as i, testInvalid as j, setSymDiff as k, compare as l, cartesianProduct as m, CalcInvalidDataError as n, TUPLE_ID as o, boolean as p, EmptySetV as r, VALUE_FALSE as s, BOOL_INFINITY as t, makeValuePath as u, isSetValue as v, projection as w, makeDefaultValue as x, isSubsetOrEq as y };
|
|
365
376
|
|
|
366
|
-
//# sourceMappingURL=value-
|
|
377
|
+
//# sourceMappingURL=value-ybFBRuz6.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"value-B8UtCqaK.js","names":[],"sources":["../src/rslang/eval/value-api.ts","../src/rslang/eval/value.ts"],"sourcesContent":["import { generateStub } from '../../shared';\nimport { type ExpressionType, TypeID, type TypePath, type Typification } from '../semantic/typification';\n\nimport {\n BOOL_INFINITY,\n compare,\n EmptySetV,\n INVALID_ELEMENT,\n makeValuePath,\n set,\n SET_INFINITY,\n tuple,\n TUPLE_ID,\n type Value,\n VALUE_FALSE,\n VALUE_TRUE,\n type ValueContext,\n type ValuePath\n} from './value';\n\n/** Cartesian product of factor sets. */\nexport function cartesianProduct(factors: Value[][]): Value[] | null {\n const cardinality = factors.reduce((acc, f) => acc * f.length, 1);\n if (cardinality > SET_INFINITY) {\n return null;\n }\n if (cardinality === 0 || factors.length === 0) {\n return EmptySetV;\n }\n\n let accumulator: Value[][] = [[]];\n for (const factor of factors) {\n const next: Value[][] = [];\n for (const prefix of accumulator) {\n for (const value of factor) {\n next.push([...prefix, value]);\n }\n }\n accumulator = next;\n }\n return accumulator.map(tuple);\n}\n\n/** Boolean power set ℬ(X). No cache - materialized. */\nexport function boolean(base: Value[]): Value[] | null {\n if (base.length > BOOL_INFINITY) {\n return null;\n }\n return powerset(base);\n}\n\n/** Powerset of array. */\nfunction powerset(arr: readonly Value[]): Value[][] {\n const result: Value[][] = [[]];\n if (arr.length === 0) {\n return result;\n }\n\n let current: Value[][] = [[]];\n let maxIndex: number[] = [-1];\n while (current.length > 0) {\n const next: Value[][] = [];\n const nextMaxIndex: number[] = [];\n for (let i = 0; i < current.length; i++) {\n for (let j = maxIndex[i] + 1; j < arr.length; j++) {\n const subset = [...current[i], arr[j]];\n result.push(subset);\n if (j < arr.length - 1) {\n next.push(subset);\n nextMaxIndex.push(j);\n }\n }\n }\n current = next;\n maxIndex = nextMaxIndex;\n }\n return result;\n}\n\n/** Check if set contains element. */\nexport function contains(setData: Value[], element: Value): boolean {\n let left = 0;\n let right = setData.length - 1;\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n const cmp = compare(setData[mid], element);\n if (cmp === 0) {\n return true;\n } else if (cmp < 0) {\n left = mid + 1;\n } else {\n right = mid - 1;\n }\n }\n return false;\n}\n\n/** Is A ⊆ B. */\nexport function isSubsetOrEq(a: Value[], b: Value[]): boolean {\n let i = 0,\n j = 0;\n while (i < a.length && j < b.length) {\n const cmp = compare(a[i], b[j]);\n if (cmp === 0) {\n i++;\n j++;\n } else if (cmp > 0) {\n j++;\n } else {\n return false;\n }\n }\n return i === a.length;\n}\n\n/** Reduce: flatten double boolean to single boolean. */\nexport function reduce(target: Value[][]): Value[] {\n const result: Value[] = [];\n for (const element of target) {\n result.push(...element);\n }\n return set(result);\n}\n\n/** Union A ∪ B. */\nexport function setUnion(set1: Value[], set2: Value[]): Value[] {\n const result: Value[] = [];\n let i = 0,\n j = 0;\n while (i < set1.length && j < set2.length) {\n const cmp = compare(set1[i], set2[j]);\n if (cmp < 0) {\n result.push(set1[i]);\n i++;\n } else if (cmp > 0) {\n result.push(set2[j]);\n j++;\n } else {\n result.push(set1[i]);\n i++;\n j++;\n }\n }\n while (i < set1.length) {\n result.push(set1[i]);\n i++;\n }\n while (j < set2.length) {\n result.push(set2[j]);\n j++;\n }\n return result;\n}\n\n/** Intersection A ∩ B. */\nexport function setIntersection(set1: Value[], set2: Value[]): Value[] {\n const result: Value[] = [];\n for (let i = 0, j = 0; i < set1.length && j < set2.length; ) {\n const cmp = compare(set1[i], set2[j]);\n if (cmp < 0) {\n i++;\n } else if (cmp > 0) {\n j++;\n } else {\n result.push(set1[i]);\n i++;\n j++;\n }\n }\n return result;\n}\n\n/** Difference A \\ B. */\nexport function setDiff(set1: Value[], set2: Value[]): Value[] {\n const result: Value[] = [];\n let i = 0,\n j = 0;\n while (i < set1.length && j < set2.length) {\n const cmp = compare(set1[i], set2[j]);\n if (cmp < 0) {\n result.push(set1[i]);\n i++;\n } else if (cmp > 0) {\n j++;\n } else {\n i++;\n j++;\n }\n }\n while (i < set1.length) {\n result.push(set1[i]);\n i++;\n }\n return result;\n}\n\n/** Symmetric difference A ∆ B. */\nexport function setSymDiff(set1: Value[], set2: Value[]): Value[] {\n const result: Value[] = [];\n let i = 0,\n j = 0;\n while (i < set1.length && j < set2.length) {\n const cmp = compare(set1[i], set2[j]);\n if (cmp < 0) {\n result.push(set1[i]);\n i++;\n } else if (cmp > 0) {\n result.push(set2[j]);\n j++;\n } else {\n i++;\n j++;\n }\n }\n while (i < set1.length) {\n result.push(set1[i]);\n i++;\n }\n while (j < set2.length) {\n result.push(set2[j]);\n j++;\n }\n return result;\n}\n\n/** Projection of set by indices (BigPr). */\nexport function projection(target: Value[][], indices: number[]): Value[] {\n const projectedElements: Value[] = target.map(element => {\n const newComponents = indices.map(idx => element[idx]);\n return indices.length === 1 ? newComponents[0] : tuple(newComponents);\n });\n return set(projectedElements);\n}\n\n/** Condensed string representation. */\nexport function printValue(data: Value | null): string {\n if (!Array.isArray(data)) {\n return String(data);\n }\n const len = data.length;\n if (data.length === 0) {\n return '{}';\n }\n\n const isTuple = data[0] === TUPLE_ID;\n const start = isTuple ? 1 : 0;\n\n let result = isTuple ? '(' : '{';\n for (let i = start; i < len; i++) {\n if (i > start) result += ', ';\n result += printValue(data[i]);\n }\n result += isTuple ? ')' : '}';\n return result;\n}\n\n/** Generates stub ID for value. */\nexport function valueStub(value: Value | null): string {\n if (value == null) {\n return '';\n }\n const str = printValue(value);\n return generateStub(str);\n}\n\n/** Checks if value is a set representation, not a tuple representation. */\nexport function isSetValue(data: Value | null): data is Value[] {\n return Array.isArray(data) && (data.length === 0 || data[0] !== TUPLE_ID);\n}\n\n/** Checks if value is a tuple representation. */\nexport function isTupleValue(data: Value | null): data is Value[] {\n return Array.isArray(data) && data.length > 1 && data[0] === TUPLE_ID;\n}\n\n/** Normalize unsorted array of values. */\nexport function normalizeValue(data: Value): void {\n if (!Array.isArray(data) || data.length === 0) {\n return;\n }\n\n if (data[0] === TUPLE_ID) {\n for (let i = 1; i < data.length; i++) {\n normalizeValue(data[i]);\n }\n return;\n }\n\n for (const item of data) {\n normalizeValue(item);\n }\n\n data.sort((a, b) => compare(a, b));\n let i = 1;\n while (i < data.length) {\n if (compare(data[i - 1], data[i]) === 0) {\n data.splice(i, 1);\n } else {\n i++;\n }\n }\n}\n\n/** Validates value for {@link ExpressionType} and value of basic sets. */\nexport function validateValue(value: Value, type: ExpressionType, basics: ValueContext): boolean {\n switch (type.typeID) {\n case TypeID.integer:\n return typeof value === 'number';\n case TypeID.logic: {\n if (typeof value !== 'number') {\n return false;\n }\n return value === VALUE_TRUE || value === VALUE_FALSE;\n }\n case TypeID.basic: {\n if (typeof value !== 'number') {\n return false;\n }\n const domain = basics.get(type.baseID);\n return !!domain && Array.isArray(domain) && domain.includes(value);\n }\n\n case TypeID.tuple: {\n if (!Array.isArray(value) || value.length !== type.factors.length + 1 || value[0] !== TUPLE_ID) {\n return false;\n }\n for (let i = 0; i < type.factors.length; i++) {\n if (!validateValue(value[i + 1], type.factors[i], basics)) {\n return false;\n }\n }\n return true;\n }\n\n case TypeID.collection: {\n if (!isSetValue(value)) {\n return false;\n }\n for (const item of value) {\n if (!validateValue(item, type.base, basics)) {\n return false;\n }\n }\n return true;\n }\n\n case TypeID.anyTypification:\n case TypeID.predicate:\n case TypeID.function:\n return false;\n }\n}\n\n/** Converts value path to type path. */\nexport function convertPathToType(path: ValuePath, type: Typification): TypePath | null {\n const result: number[] = [];\n if (path.length === 0) {\n return result as TypePath;\n }\n\n let curType = type;\n let index = 0;\n while (index < path.length) {\n switch (curType.typeID) {\n case TypeID.collection: {\n result.push(0);\n curType = curType.base;\n index++;\n break;\n }\n case TypeID.tuple: {\n const tupleIdx = path[index];\n if (typeof tupleIdx !== 'number' || tupleIdx < 1 || tupleIdx > curType.factors.length) {\n return null;\n }\n result.push(tupleIdx);\n curType = curType.factors[tupleIdx - 1];\n index++;\n break;\n }\n case TypeID.basic:\n case TypeID.integer:\n case TypeID.anyTypification:\n return null;\n }\n }\n return result as TypePath;\n}\n\n/** Extracts value from a target by path. */\nexport function extractValue(target: Value, path: ValuePath): Value | null {\n let current: Value = target;\n let i = 0;\n while (i < path.length) {\n if (!Array.isArray(current) || current.length <= path[i]) {\n return null;\n }\n current = current[path[i]];\n i++;\n }\n return current;\n}\n\n/** Makes default value for a type. */\nexport function makeDefaultValue(type: Typification): Value {\n switch (type.typeID) {\n case TypeID.anyTypification:\n case TypeID.integer:\n case TypeID.basic:\n return INVALID_ELEMENT;\n case TypeID.collection:\n return [];\n case TypeID.tuple:\n return tuple(type.factors.map(item => makeDefaultValue(item)));\n }\n}\n\n/** Perform immutable deep copy update. */\nexport function setNestedValue(target: Value | null, path: ValuePath, newVal: Value): Value {\n if (path.length === 0) {\n return newVal;\n }\n const [head, ...rest] = path;\n const arr = Array.isArray(target) ? [...target] : [];\n arr[head] = setNestedValue(arr[head], makeValuePath(rest), newVal);\n return arr;\n}\n\n/** Test if value contains invalid elements. */\nexport function testInvalid(value: Value): boolean {\n const stack = [value];\n while (stack.length > 0) {\n const current = stack.pop();\n if (current === INVALID_ELEMENT) {\n return true;\n }\n if (Array.isArray(current)) {\n for (const element of current) {\n stack.push(element);\n }\n }\n }\n return false;\n}\n","/**\n * Module: Structured data for RSLang expression evaluation.\n */\n\nimport { type Branded } from '../../shared';\n\nimport { printValue } from './value-api';\n\n/** Tuple ID for array distinction. */\nexport const TUPLE_ID = -111;\n\n/** Invalid value for structured data. */\nexport const INVALID_ELEMENT = -1;\n\n/** Boolean values: true. */\nexport const VALUE_TRUE = 1;\n\n/** Boolean values: false. */\nexport const VALUE_FALSE = 0;\n\n/** Cardinality threshold for \"infinite\" sets (e.g. Z). */\nexport const SET_INFINITY = 10_000_000;\n\n/** Cardinality threshold for Boolean power set. */\nexport const BOOL_INFINITY = 18;\n\n/** Expression evaluation result: structured data. */\nexport type Value = number | Value[];\n\n/** Values context. */\nexport type ValueContext = Map<string, Value>;\n\n/** Value extraction path. */\nexport type ValuePath = Branded<number[], 'ValuePath'>;\n\n/** Creates value path. */\nexport function makeValuePath(path: number[]): ValuePath {\n return path as ValuePath;\n}\n\n/** Empty set ∅. */\nexport const EmptySetV = [];\n\n/** Compare two structured data without recursive calls. */\nexport function compare(v1: Value, v2: Value): number {\n const stack1: Value[] = [v1];\n const stack2: Value[] = [v2];\n\n while (stack1.length > 0 && stack2.length > 0) {\n const el1 = stack1.pop();\n const el2 = stack2.pop();\n if (el1 === el2) {\n continue;\n }\n\n const type1 = typeof el1;\n const type2 = typeof el2;\n if (type1 === 'number' && type2 === 'number') {\n const numDiff = (el1 as number) - (el2 as number);\n if (numDiff !== 0) return numDiff;\n continue;\n }\n\n const isArray1 = Array.isArray(el1);\n const isArray2 = Array.isArray(el2);\n if (!isArray1 || !isArray2) {\n throw new Error(`Cannot compare different types ${printValue(el1!)} and ${printValue(el2!)}`);\n }\n\n const arr1 = el1;\n const arr2 = el2;\n const len1 = arr1.length;\n const len2 = arr2.length;\n if (len1 !== len2) {\n return len1 - len2;\n }\n\n for (let i = len1 - 1; i >= 0; i--) {\n stack1.push(arr1[i]);\n stack2.push(arr2[i]);\n }\n }\n return 0;\n}\n\n/** Tuple from components. */\nexport function tuple(components: Value[]): Value {\n return [TUPLE_ID, ...components];\n}\n\n/** Set from elements (unique). Value[] - materialized. */\nexport function set(elements: Value[]): Value[] {\n const sorted = [...elements].sort(compare);\n for (let i = 1; i < sorted.length; ) {\n if (compare(sorted[i - 1], sorted[i]) === 0) {\n sorted.splice(i, 1);\n } else {\n i++;\n }\n }\n return sorted;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"value-ybFBRuz6.js","names":[],"sources":["../src/rslang/eval/value-api.ts","../src/rslang/eval/value.ts"],"sourcesContent":["import { generateStub } from '../../shared';\nimport { type ExpressionType, TypeID, type TypePath, type Typification } from '../semantic/typification';\n\nimport {\n BOOL_INFINITY,\n compare,\n EmptySetV,\n INVALID_ELEMENT,\n makeValuePath,\n set,\n SET_INFINITY,\n tuple,\n TUPLE_ID,\n type Value,\n VALUE_FALSE,\n VALUE_TRUE,\n type ValueContext,\n type ValuePath\n} from './value';\n\n/** Cartesian product of factor sets. */\nexport function cartesianProduct(factors: Value[][]): Value[] | null {\n const cardinality = factors.reduce((acc, f) => acc * f.length, 1);\n if (cardinality > SET_INFINITY) {\n return null;\n }\n if (cardinality === 0 || factors.length === 0) {\n return EmptySetV;\n }\n\n let accumulator: Value[][] = [[]];\n for (const factor of factors) {\n const next: Value[][] = [];\n for (const prefix of accumulator) {\n for (const value of factor) {\n next.push([...prefix, value]);\n }\n }\n accumulator = next;\n }\n return accumulator.map(tuple);\n}\n\n/** Boolean power set ℬ(X). No cache - materialized. */\nexport function boolean(base: Value[]): Value[] | null {\n if (base.length > BOOL_INFINITY) {\n return null;\n }\n return powerset(base);\n}\n\n/** Powerset of array. */\nfunction powerset(arr: readonly Value[]): Value[][] {\n const result: Value[][] = [[]];\n if (arr.length === 0) {\n return result;\n }\n\n let current: Value[][] = [[]];\n let maxIndex: number[] = [-1];\n while (current.length > 0) {\n const next: Value[][] = [];\n const nextMaxIndex: number[] = [];\n for (let i = 0; i < current.length; i++) {\n for (let j = maxIndex[i] + 1; j < arr.length; j++) {\n const subset = [...current[i], arr[j]];\n result.push(subset);\n if (j < arr.length - 1) {\n next.push(subset);\n nextMaxIndex.push(j);\n }\n }\n }\n current = next;\n maxIndex = nextMaxIndex;\n }\n return result;\n}\n\n/** Check if set contains element. */\nexport function contains(setData: Value[], element: Value): boolean {\n let left = 0;\n let right = setData.length - 1;\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n const cmp = compare(setData[mid], element);\n if (cmp === 0) {\n return true;\n } else if (cmp < 0) {\n left = mid + 1;\n } else {\n right = mid - 1;\n }\n }\n return false;\n}\n\n/** Is A ⊆ B. */\nexport function isSubsetOrEq(a: Value[], b: Value[]): boolean {\n let i = 0,\n j = 0;\n while (i < a.length && j < b.length) {\n const cmp = compare(a[i], b[j]);\n if (cmp === 0) {\n i++;\n j++;\n } else if (cmp > 0) {\n j++;\n } else {\n return false;\n }\n }\n return i === a.length;\n}\n\n/** Reduce: flatten double boolean to single boolean. */\nexport function reduce(target: Value[][]): Value[] {\n const result: Value[] = [];\n for (const element of target) {\n result.push(...element);\n }\n return set(result);\n}\n\n/** Union A ∪ B. */\nexport function setUnion(set1: Value[], set2: Value[]): Value[] {\n const result: Value[] = [];\n let i = 0,\n j = 0;\n while (i < set1.length && j < set2.length) {\n const cmp = compare(set1[i], set2[j]);\n if (cmp < 0) {\n result.push(set1[i]);\n i++;\n } else if (cmp > 0) {\n result.push(set2[j]);\n j++;\n } else {\n result.push(set1[i]);\n i++;\n j++;\n }\n }\n while (i < set1.length) {\n result.push(set1[i]);\n i++;\n }\n while (j < set2.length) {\n result.push(set2[j]);\n j++;\n }\n return result;\n}\n\n/** Intersection A ∩ B. */\nexport function setIntersection(set1: Value[], set2: Value[]): Value[] {\n const result: Value[] = [];\n for (let i = 0, j = 0; i < set1.length && j < set2.length; ) {\n const cmp = compare(set1[i], set2[j]);\n if (cmp < 0) {\n i++;\n } else if (cmp > 0) {\n j++;\n } else {\n result.push(set1[i]);\n i++;\n j++;\n }\n }\n return result;\n}\n\n/** Difference A \\ B. */\nexport function setDiff(set1: Value[], set2: Value[]): Value[] {\n const result: Value[] = [];\n let i = 0,\n j = 0;\n while (i < set1.length && j < set2.length) {\n const cmp = compare(set1[i], set2[j]);\n if (cmp < 0) {\n result.push(set1[i]);\n i++;\n } else if (cmp > 0) {\n j++;\n } else {\n i++;\n j++;\n }\n }\n while (i < set1.length) {\n result.push(set1[i]);\n i++;\n }\n return result;\n}\n\n/** Symmetric difference A ∆ B. */\nexport function setSymDiff(set1: Value[], set2: Value[]): Value[] {\n const result: Value[] = [];\n let i = 0,\n j = 0;\n while (i < set1.length && j < set2.length) {\n const cmp = compare(set1[i], set2[j]);\n if (cmp < 0) {\n result.push(set1[i]);\n i++;\n } else if (cmp > 0) {\n result.push(set2[j]);\n j++;\n } else {\n i++;\n j++;\n }\n }\n while (i < set1.length) {\n result.push(set1[i]);\n i++;\n }\n while (j < set2.length) {\n result.push(set2[j]);\n j++;\n }\n return result;\n}\n\n/** Projection of set by indices (BigPr). */\nexport function projection(target: Value[][], indices: number[]): Value[] {\n const projectedElements: Value[] = target.map(element => {\n const newComponents = indices.map(idx => element[idx]);\n return indices.length === 1 ? newComponents[0] : tuple(newComponents);\n });\n return set(projectedElements);\n}\n\n/** Condensed string representation. */\nexport function printValue(data: Value | null): string {\n if (!Array.isArray(data)) {\n return String(data);\n }\n const len = data.length;\n if (data.length === 0) {\n return '{}';\n }\n\n const isTuple = data[0] === TUPLE_ID;\n const start = isTuple ? 1 : 0;\n\n let result = isTuple ? '(' : '{';\n for (let i = start; i < len; i++) {\n if (i > start) result += ', ';\n result += printValue(data[i]);\n }\n result += isTuple ? ')' : '}';\n return result;\n}\n\n/** Generates stub ID for value. */\nexport function valueStub(value: Value | null): string {\n if (value == null) {\n return '';\n }\n const str = printValue(value);\n return generateStub(str);\n}\n\n/** Checks if value is a set representation, not a tuple representation. */\nexport function isSetValue(data: Value | null): data is Value[] {\n return Array.isArray(data) && (data.length === 0 || data[0] !== TUPLE_ID);\n}\n\n/** Checks if value is a tuple representation. */\nexport function isTupleValue(data: Value | null): data is Value[] {\n return Array.isArray(data) && data.length > 1 && data[0] === TUPLE_ID;\n}\n\n/** Normalize unsorted array of values. */\nexport function normalizeValue(data: Value): void {\n if (!Array.isArray(data) || data.length === 0) {\n return;\n }\n\n if (data[0] === TUPLE_ID) {\n for (let i = 1; i < data.length; i++) {\n normalizeValue(data[i]);\n }\n return;\n }\n\n for (const item of data) {\n normalizeValue(item);\n }\n\n data.sort((a, b) => compare(a, b));\n let i = 1;\n while (i < data.length) {\n if (compare(data[i - 1], data[i]) === 0) {\n data.splice(i, 1);\n } else {\n i++;\n }\n }\n}\n\n/** Validates value for {@link ExpressionType} and value of basic sets. */\nexport function validateValue(value: Value, type: ExpressionType, basics: ValueContext): boolean {\n switch (type.typeID) {\n case TypeID.integer:\n return typeof value === 'number';\n case TypeID.logic: {\n if (typeof value !== 'number') {\n return false;\n }\n return value === VALUE_TRUE || value === VALUE_FALSE;\n }\n case TypeID.basic: {\n if (typeof value !== 'number') {\n return false;\n }\n const domain = basics.get(type.baseID);\n return !!domain && Array.isArray(domain) && domain.includes(value);\n }\n\n case TypeID.tuple: {\n if (!Array.isArray(value) || value.length !== type.factors.length + 1 || value[0] !== TUPLE_ID) {\n return false;\n }\n for (let i = 0; i < type.factors.length; i++) {\n if (!validateValue(value[i + 1], type.factors[i], basics)) {\n return false;\n }\n }\n return true;\n }\n\n case TypeID.collection: {\n if (!isSetValue(value)) {\n return false;\n }\n for (const item of value) {\n if (!validateValue(item, type.base, basics)) {\n return false;\n }\n }\n return true;\n }\n\n case TypeID.anyTypification:\n case TypeID.predicate:\n case TypeID.function:\n return false;\n }\n}\n\n/** Converts value path to type path. */\nexport function convertPathToType(path: ValuePath, type: Typification): TypePath | null {\n const result: number[] = [];\n if (path.length === 0) {\n return result as TypePath;\n }\n\n let curType = type;\n let index = 0;\n while (index < path.length) {\n switch (curType.typeID) {\n case TypeID.collection: {\n result.push(0);\n curType = curType.base;\n index++;\n break;\n }\n case TypeID.tuple: {\n const tupleIdx = path[index];\n if (typeof tupleIdx !== 'number' || tupleIdx < 1 || tupleIdx > curType.factors.length) {\n return null;\n }\n result.push(tupleIdx);\n curType = curType.factors[tupleIdx - 1];\n index++;\n break;\n }\n case TypeID.basic:\n case TypeID.integer:\n case TypeID.anyTypification:\n return null;\n }\n }\n return result as TypePath;\n}\n\n/** Extracts value from a target by path. */\nexport function extractValue(target: Value, path: ValuePath): Value | null {\n let current: Value = target;\n let i = 0;\n while (i < path.length) {\n if (!Array.isArray(current) || current.length <= path[i]) {\n return null;\n }\n current = current[path[i]];\n i++;\n }\n return current;\n}\n\n/** Makes default value for a type. */\nexport function makeDefaultValue(type: Typification): Value {\n switch (type.typeID) {\n case TypeID.anyTypification:\n case TypeID.integer:\n case TypeID.basic:\n return INVALID_ELEMENT;\n case TypeID.collection:\n return [];\n case TypeID.tuple:\n return tuple(type.factors.map(item => makeDefaultValue(item)));\n }\n}\n\n/** Perform immutable deep copy update. */\nexport function setNestedValue(target: Value | null, path: ValuePath, newVal: Value): Value {\n if (path.length === 0) {\n return newVal;\n }\n const [head, ...rest] = path;\n const arr = Array.isArray(target) ? [...target] : [];\n arr[head] = setNestedValue(arr[head], makeValuePath(rest), newVal);\n return arr;\n}\n\n/** Test if value contains invalid elements. */\nexport function testInvalid(value: Value): boolean {\n const stack = [value];\n while (stack.length > 0) {\n const current = stack.pop();\n if (current === INVALID_ELEMENT) {\n return true;\n }\n if (Array.isArray(current)) {\n for (const element of current) {\n stack.push(element);\n }\n }\n }\n return false;\n}\n","/**\n * Module: Structured data for RSLang expression evaluation.\n */\n\nimport { type Branded } from '../../shared';\n\nimport { printValue } from './value-api';\n\n/** Tuple ID for array distinction. */\nexport const TUPLE_ID = -111;\n\n/** Invalid value for structured data. */\nexport const INVALID_ELEMENT = -1;\n\n/** Boolean values: true. */\nexport const VALUE_TRUE = 1;\n\n/** Boolean values: false. */\nexport const VALUE_FALSE = 0;\n\n/** Cardinality threshold for \"infinite\" sets (e.g. Z). */\nexport const SET_INFINITY = 10_000_000;\n\n/** Cardinality threshold for Boolean power set. */\nexport const BOOL_INFINITY = 18;\n\n/** Expression evaluation result: structured data. */\nexport type Value = number | Value[];\n\n/** Values context. */\nexport type ValueContext = Map<string, Value>;\n\n/** Value extraction path. */\nexport type ValuePath = Branded<number[], 'ValuePath'>;\n\n/** Creates value path. */\nexport function makeValuePath(path: number[]): ValuePath {\n return path as ValuePath;\n}\n\n/** Empty set ∅. */\nexport const EmptySetV = [];\n\n/** Thrown when a runtime value operation cannot be applied to the given operands. */\nexport class CalcInvalidDataError extends Error {\n readonly left: string;\n readonly right: string;\n\n constructor(left: string, right: string) {\n super(`Cannot compare different types ${left} and ${right}`);\n this.name = 'CalcInvalidDataError';\n this.left = left;\n this.right = right;\n }\n}\n\n/** Compare two structured data without recursive calls. */\nexport function compare(v1: Value, v2: Value): number {\n const stack1: Value[] = [v1];\n const stack2: Value[] = [v2];\n\n while (stack1.length > 0 && stack2.length > 0) {\n const el1 = stack1.pop();\n const el2 = stack2.pop();\n if (el1 === el2) {\n continue;\n }\n\n const type1 = typeof el1;\n const type2 = typeof el2;\n if (type1 === 'number' && type2 === 'number') {\n const numDiff = (el1 as number) - (el2 as number);\n if (numDiff !== 0) return numDiff;\n continue;\n }\n\n const isArray1 = Array.isArray(el1);\n const isArray2 = Array.isArray(el2);\n if (!isArray1 || !isArray2) {\n throw new CalcInvalidDataError(printValue(el1!), printValue(el2!));\n }\n\n const arr1 = el1;\n const arr2 = el2;\n const len1 = arr1.length;\n const len2 = arr2.length;\n if (len1 !== len2) {\n return len1 - len2;\n }\n\n for (let i = len1 - 1; i >= 0; i--) {\n stack1.push(arr1[i]);\n stack2.push(arr2[i]);\n }\n }\n return 0;\n}\n\n/** Tuple from components. */\nexport function tuple(components: Value[]): Value {\n return [TUPLE_ID, ...components];\n}\n\n/** Set from elements (unique). Value[] - materialized. */\nexport function set(elements: Value[]): Value[] {\n const sorted = [...elements].sort(compare);\n for (let i = 1; i < sorted.length; ) {\n if (compare(sorted[i - 1], sorted[i]) === 0) {\n sorted.splice(i, 1);\n } else {\n i++;\n }\n }\n return sorted;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rsconcept/domain",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Shared TypeScript domain for RS language, RSForm, RSModel, RSEngine, OSS, and concept-text helpers.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "IRBorisov",
|
|
@@ -176,7 +176,7 @@
|
|
|
176
176
|
"tsdown": "^0.22.2",
|
|
177
177
|
"typescript": "^6.0.3",
|
|
178
178
|
"typescript-eslint": "^8.61.0",
|
|
179
|
-
"vitest": "^4.1.
|
|
179
|
+
"vitest": "^4.1.9"
|
|
180
180
|
},
|
|
181
181
|
"publishConfig": {
|
|
182
182
|
"access": "public"
|
package/src/library/rsengine.ts
CHANGED
|
@@ -23,7 +23,6 @@ export interface RSEngineServices {
|
|
|
23
23
|
export interface RSEngineNotifications {
|
|
24
24
|
onInvalidSetValue: () => void;
|
|
25
25
|
onCalculationSuccess: (timeSpent: string) => void;
|
|
26
|
-
onEvaluationError: (message: string) => void;
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
/** Calculation engine for {@link RSModel}. */
|
|
@@ -274,26 +273,12 @@ export class RSEngine {
|
|
|
274
273
|
|
|
275
274
|
/** Evaluates expression for {@link RSEngine}. */
|
|
276
275
|
public evaluateExpression(expression: string, cstType: CstType): CalculatorResult {
|
|
277
|
-
return getEvaluationFor(expression, cstType, this.schema!, this.calculator
|
|
278
|
-
this.notifications?.onEvaluationError(message)
|
|
279
|
-
);
|
|
276
|
+
return getEvaluationFor(expression, cstType, this.schema!, this.calculator);
|
|
280
277
|
}
|
|
281
278
|
|
|
282
279
|
/** Evaluates AST for {@link RSEngine}. */
|
|
283
280
|
public evaluateAst(ast: AstNode, options?: CalculatorEvaluateOptions): CalculatorResult {
|
|
284
|
-
|
|
285
|
-
const evaluation = this.calculator.evaluateFull(ast, options);
|
|
286
|
-
return evaluation;
|
|
287
|
-
} catch (error) {
|
|
288
|
-
this.notifications?.onEvaluationError((error as Error).message);
|
|
289
|
-
console.error(error);
|
|
290
|
-
return {
|
|
291
|
-
value: null,
|
|
292
|
-
iterations: 0,
|
|
293
|
-
cacheHits: 0,
|
|
294
|
-
errors: []
|
|
295
|
-
};
|
|
296
|
-
}
|
|
281
|
+
return this.calculator.evaluateFull(ast, options);
|
|
297
282
|
}
|
|
298
283
|
|
|
299
284
|
/** Calculates value for {@link Constituenta}. */
|
|
@@ -307,9 +292,7 @@ export class RSEngine {
|
|
|
307
292
|
const predecessors = this.schema.graph.expandAllInputs([cstID]);
|
|
308
293
|
this.prepareEvaluation(predecessors);
|
|
309
294
|
}
|
|
310
|
-
const result = getEvaluationFor(cst.definition_formal, cst.cst_type, this.schema, this.calculator
|
|
311
|
-
this.notifications?.onEvaluationError(message)
|
|
312
|
-
);
|
|
295
|
+
const result = getEvaluationFor(cst.definition_formal, cst.cst_type, this.schema, this.calculator);
|
|
313
296
|
|
|
314
297
|
if (result.value === null) {
|
|
315
298
|
this.calculator.resetValue(cst.alias);
|
|
@@ -492,9 +475,7 @@ export class RSEngine {
|
|
|
492
475
|
if (dependencies.includes(cstID)) {
|
|
493
476
|
const cst = this.schema!.cstByID.get(cstID)!;
|
|
494
477
|
if (isInferrable(cst.cst_type)) {
|
|
495
|
-
const value = fastEvaluation(cst.definition_formal, cst.cst_type, this.schema!, this.calculator
|
|
496
|
-
this.notifications?.onEvaluationError(message)
|
|
497
|
-
);
|
|
478
|
+
const value = fastEvaluation(cst.definition_formal, cst.cst_type, this.schema!, this.calculator);
|
|
498
479
|
if (value !== null) {
|
|
499
480
|
this.calculator.setValue(cst.alias, value);
|
|
500
481
|
} else {
|
|
@@ -537,8 +518,7 @@ function getEvaluationFor(
|
|
|
537
518
|
expression: string,
|
|
538
519
|
cstType: CstType,
|
|
539
520
|
schema: RSForm,
|
|
540
|
-
calculator: RSCalculator
|
|
541
|
-
onEvaluationError?: (message: string) => void
|
|
521
|
+
calculator: RSCalculator
|
|
542
522
|
): CalculatorResult {
|
|
543
523
|
const parse = getAnalysisFor(expression, cstType, schema);
|
|
544
524
|
if (!parse.success || !parse.ast) {
|
|
@@ -548,46 +528,21 @@ function getEvaluationFor(
|
|
|
548
528
|
cacheHits: 0,
|
|
549
529
|
errors: parse.errors
|
|
550
530
|
};
|
|
551
|
-
} else {
|
|
552
|
-
try {
|
|
553
|
-
const result = calculator.evaluateFull(parse.ast);
|
|
554
|
-
return {
|
|
555
|
-
value: result.value,
|
|
556
|
-
iterations: result.iterations,
|
|
557
|
-
cacheHits: result.cacheHits,
|
|
558
|
-
errors: [...parse.errors, ...result.errors]
|
|
559
|
-
};
|
|
560
|
-
} catch (error) {
|
|
561
|
-
onEvaluationError?.((error as Error).message);
|
|
562
|
-
console.error(expression, error);
|
|
563
|
-
return {
|
|
564
|
-
value: null,
|
|
565
|
-
iterations: 0,
|
|
566
|
-
cacheHits: 0,
|
|
567
|
-
errors: []
|
|
568
|
-
};
|
|
569
|
-
}
|
|
570
531
|
}
|
|
532
|
+
const result = calculator.evaluateFull(parse.ast);
|
|
533
|
+
return {
|
|
534
|
+
value: result.value,
|
|
535
|
+
iterations: result.iterations,
|
|
536
|
+
cacheHits: result.cacheHits,
|
|
537
|
+
errors: [...parse.errors, ...result.errors]
|
|
538
|
+
};
|
|
571
539
|
}
|
|
572
540
|
|
|
573
541
|
/** Evaluates expression for {@link RSModel}. */
|
|
574
|
-
function fastEvaluation(
|
|
575
|
-
expression: string,
|
|
576
|
-
cstType: CstType,
|
|
577
|
-
schema: RSForm,
|
|
578
|
-
calculator: RSCalculator,
|
|
579
|
-
onEvaluationError?: (message: string) => void
|
|
580
|
-
): Value | null {
|
|
542
|
+
function fastEvaluation(expression: string, cstType: CstType, schema: RSForm, calculator: RSCalculator): Value | null {
|
|
581
543
|
const parse = getAnalysisFor(expression, cstType, schema);
|
|
582
544
|
if (!parse.success || !parse.ast) {
|
|
583
545
|
return null;
|
|
584
|
-
} else {
|
|
585
|
-
try {
|
|
586
|
-
return calculator.evaluateFast(parse.ast);
|
|
587
|
-
} catch (error) {
|
|
588
|
-
onEvaluationError?.((error as Error).message);
|
|
589
|
-
console.error(expression, error);
|
|
590
|
-
return null;
|
|
591
|
-
}
|
|
592
546
|
}
|
|
547
|
+
return calculator.evaluateFast(parse.ast);
|
|
593
548
|
}
|
package/src/rslang/error.ts
CHANGED
|
@@ -84,6 +84,7 @@ export const RSErrorCode = {
|
|
|
84
84
|
calcInvalidDebool: 0x8105, // 35333
|
|
85
85
|
iterateInfinity: 0x8106, // 35334
|
|
86
86
|
calculationNotSupported: 0x8107, // 35335
|
|
87
|
+
calcInvalidData: 0x8108, // 35336
|
|
87
88
|
|
|
88
89
|
cstEmptyDerived: 0x8861, // 34913
|
|
89
90
|
definitionNotAllowed: 0x8862 // 34914
|
|
@@ -73,6 +73,14 @@ describe('RSCalculator', () => {
|
|
|
73
73
|
expectCalcFull('X11', { expectErrorCode: RSErrorCode.calcGlobalMissing });
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
+
it('returns error for undeclared local variable', () => {
|
|
77
|
+
expectCalcFull('∀a∈X1 b=b', { expectErrorCode: RSErrorCode.localUndeclared });
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('returns error for incompatible value comparison', () => {
|
|
81
|
+
expectCalcFull('X1=1', { expectErrorCode: RSErrorCode.calcInvalidData });
|
|
82
|
+
});
|
|
83
|
+
|
|
76
84
|
it('returns error for infinite quantifier', () => {
|
|
77
85
|
expectCalcFull('∀a∈Z a=a', { expectErrorCode: RSErrorCode.iterateInfinity });
|
|
78
86
|
});
|
|
@@ -192,6 +192,7 @@ const correctValuesData = [
|
|
|
192
192
|
const errorData = [
|
|
193
193
|
['[a∈ℬ(R1)] a=a', { code: RSErrorCode.calculationNotSupported, from: 0, to: 13 }],
|
|
194
194
|
['debool(X1)', { code: RSErrorCode.calcInvalidDebool, from: 7, to: 9 }],
|
|
195
|
+
['Pr1(1)', { code: RSErrorCode.calcUnknownError, from: 0, to: 6 }],
|
|
195
196
|
['∀a∈Z a=a', { code: RSErrorCode.iterateInfinity, from: 3, to: 4 }],
|
|
196
197
|
['ℬℬ({1,2,3,4,5})', { code: RSErrorCode.booleanBaseLimit, from: 1, to: 15, params: [String(BOOL_INFINITY)] }],
|
|
197
198
|
['X1\\D1', { code: RSErrorCode.calcGlobalMissing, from: 3, to: 5, params: ['D1'] }],
|
|
@@ -227,7 +228,10 @@ const errorData = [
|
|
|
227
228
|
['R{a:=X1 | D1=D1 | a∪X1}', { code: RSErrorCode.calcGlobalMissing, from: 10, to: 12, params: ['D1'] }],
|
|
228
229
|
['I{(a,b) | a:∈D1; b:=a; b≠a}', { code: RSErrorCode.calcGlobalMissing, from: 13, to: 15, params: ['D1'] }],
|
|
229
230
|
['I{(a,b) | a:∈X1; b:=a; b≠D1}', { code: RSErrorCode.calcGlobalMissing, from: 25, to: 27, params: ['D1'] }],
|
|
230
|
-
['I{(a,b) | a:∈X1; b:=D1; b≠a}', { code: RSErrorCode.calcGlobalMissing, from: 20, to: 22, params: ['D1'] }]
|
|
231
|
+
['I{(a,b) | a:∈X1; b:=D1; b≠a}', { code: RSErrorCode.calcGlobalMissing, from: 20, to: 22, params: ['D1'] }],
|
|
232
|
+
['∀a∈X1 b=b', { code: RSErrorCode.localUndeclared, from: 6, to: 7, params: ['b'] }],
|
|
233
|
+
['X1=1', { code: RSErrorCode.calcInvalidData, from: 0, to: 4, params: ['{1, 2, 3}', '1'] }],
|
|
234
|
+
['X1=1 & 1=1', { code: RSErrorCode.calcInvalidData, from: 0, to: 4, params: ['{1, 2, 3}', '1'] }]
|
|
231
235
|
];
|
|
232
236
|
|
|
233
237
|
describe('Calculator', () => {
|
|
@@ -10,6 +10,7 @@ import { TokenID } from '../parser/token';
|
|
|
10
10
|
import { EvaluationCache, EvaluationMetadata } from './evaluation-cache';
|
|
11
11
|
import {
|
|
12
12
|
BOOL_INFINITY,
|
|
13
|
+
CalcInvalidDataError,
|
|
13
14
|
compare,
|
|
14
15
|
EmptySetV,
|
|
15
16
|
set,
|
|
@@ -153,11 +154,19 @@ export class Evaluator {
|
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
156
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
this.
|
|
157
|
+
try {
|
|
158
|
+
const result = this.dispatchVisitImpl(node);
|
|
159
|
+
if (!this.disableCache && result !== null && info.cacheable && stamp !== null) {
|
|
160
|
+
this.evalCache.store(info.structuralKey, stamp, result);
|
|
161
|
+
}
|
|
162
|
+
return result;
|
|
163
|
+
} catch (error) {
|
|
164
|
+
if (error instanceof CalcInvalidDataError) {
|
|
165
|
+
return this.onError(RSErrorCode.calcInvalidData, node, [error.left, error.right]);
|
|
166
|
+
}
|
|
167
|
+
this.onError(RSErrorCode.calcUnknownError, node);
|
|
168
|
+
return null;
|
|
159
169
|
}
|
|
160
|
-
return result;
|
|
161
170
|
}
|
|
162
171
|
|
|
163
172
|
private dispatchVisitImpl(node: AstNode): Value | null {
|
|
@@ -280,8 +289,8 @@ export class Evaluator {
|
|
|
280
289
|
|
|
281
290
|
private visitGlobal(node: AstNode): Value | null {
|
|
282
291
|
const alias = getNodeText(node);
|
|
283
|
-
const value = this.context.get(alias);
|
|
284
|
-
if (value ===
|
|
292
|
+
const value = this.context.get(alias) ?? null;
|
|
293
|
+
if (value === null) {
|
|
285
294
|
return this.onError(RSErrorCode.calcGlobalMissing, node, [alias]);
|
|
286
295
|
}
|
|
287
296
|
return value;
|
|
@@ -289,7 +298,11 @@ export class Evaluator {
|
|
|
289
298
|
|
|
290
299
|
private visitLocal(node: AstNode): Value | null {
|
|
291
300
|
const alias = getNodeText(node);
|
|
292
|
-
|
|
301
|
+
const value = this.locals.findLocal(alias);
|
|
302
|
+
if (value === null) {
|
|
303
|
+
return this.onError(RSErrorCode.localUndeclared, node, [alias]);
|
|
304
|
+
}
|
|
305
|
+
return value;
|
|
293
306
|
}
|
|
294
307
|
|
|
295
308
|
private visitFunctionCall(node: AstNode): Value | null {
|
|
@@ -910,12 +923,8 @@ class LocalContext {
|
|
|
910
923
|
}
|
|
911
924
|
}
|
|
912
925
|
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
if (binding === undefined) {
|
|
916
|
-
throw new Error(`Local variable "${alias}" not found`);
|
|
917
|
-
}
|
|
918
|
-
return binding.value;
|
|
926
|
+
findLocal(alias: string): Value | null {
|
|
927
|
+
return this.data.get(alias)?.value ?? null;
|
|
919
928
|
}
|
|
920
929
|
|
|
921
930
|
buildDependencyStamp(reads: ReadonlySet<string>): string | null {
|
package/src/rslang/eval/value.ts
CHANGED
|
@@ -41,6 +41,19 @@ export function makeValuePath(path: number[]): ValuePath {
|
|
|
41
41
|
/** Empty set ∅. */
|
|
42
42
|
export const EmptySetV = [];
|
|
43
43
|
|
|
44
|
+
/** Thrown when a runtime value operation cannot be applied to the given operands. */
|
|
45
|
+
export class CalcInvalidDataError extends Error {
|
|
46
|
+
readonly left: string;
|
|
47
|
+
readonly right: string;
|
|
48
|
+
|
|
49
|
+
constructor(left: string, right: string) {
|
|
50
|
+
super(`Cannot compare different types ${left} and ${right}`);
|
|
51
|
+
this.name = 'CalcInvalidDataError';
|
|
52
|
+
this.left = left;
|
|
53
|
+
this.right = right;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
44
57
|
/** Compare two structured data without recursive calls. */
|
|
45
58
|
export function compare(v1: Value, v2: Value): number {
|
|
46
59
|
const stack1: Value[] = [v1];
|
|
@@ -64,7 +77,7 @@ export function compare(v1: Value, v2: Value): number {
|
|
|
64
77
|
const isArray1 = Array.isArray(el1);
|
|
65
78
|
const isArray2 = Array.isArray(el2);
|
|
66
79
|
if (!isArray1 || !isArray2) {
|
|
67
|
-
throw new
|
|
80
|
+
throw new CalcInvalidDataError(printValue(el1!), printValue(el2!));
|
|
68
81
|
}
|
|
69
82
|
|
|
70
83
|
const arr1 = el1;
|
|
@@ -7,7 +7,7 @@ import { normalizeAST } from '../parser/normalize';
|
|
|
7
7
|
import { parser as rslangParser } from '../parser/parser';
|
|
8
8
|
|
|
9
9
|
import { TypeAuditor } from './type-auditor';
|
|
10
|
-
import { basic, bool, constant, LogicT, tuple, type TypeContext, TypeID } from './typification';
|
|
10
|
+
import { AnyTypificationT, basic, bool, constant, LogicT, tuple, type TypeContext, TypeID } from './typification';
|
|
11
11
|
|
|
12
12
|
// Helper to build AST
|
|
13
13
|
function buildAST(expression: string) {
|
|
@@ -299,6 +299,26 @@ describe('TypeAuditor', () => {
|
|
|
299
299
|
});
|
|
300
300
|
});
|
|
301
301
|
|
|
302
|
+
it('Templated function with R0 typification', () => {
|
|
303
|
+
typeContext.set('F3', {
|
|
304
|
+
typeID: TypeID.function,
|
|
305
|
+
result: bool(AnyTypificationT),
|
|
306
|
+
args: [{ alias: 'a', type: bool(AnyTypificationT) }]
|
|
307
|
+
});
|
|
308
|
+
expectType('F3[∅]', 'ℬ(R0)');
|
|
309
|
+
expectType('F3[X1]', 'ℬ(R0)');
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
it('Templated function with bare R0 argument', () => {
|
|
313
|
+
typeContext.set('F4', {
|
|
314
|
+
typeID: TypeID.function,
|
|
315
|
+
result: bool(basic('X1')),
|
|
316
|
+
args: [{ alias: 'a', type: AnyTypificationT }]
|
|
317
|
+
});
|
|
318
|
+
expectType('F4[X1]', 'ℬ(X1)');
|
|
319
|
+
expectType('F4[Z]', 'ℬ(X1)');
|
|
320
|
+
});
|
|
321
|
+
|
|
302
322
|
it('Templated nesting', () => {
|
|
303
323
|
typeContext.set('F2', {
|
|
304
324
|
typeID: TypeID.function,
|
|
@@ -943,7 +943,8 @@ export class TypeAuditor {
|
|
|
943
943
|
function mangleRadicals(funcName: string, type: Typification): Typification {
|
|
944
944
|
switch (type.typeID) {
|
|
945
945
|
default:
|
|
946
|
-
throw new Error(`Unexpected type: ${type
|
|
946
|
+
throw new Error(`Unexpected type for ${funcName}: ${JSON.stringify(type)}`);
|
|
947
|
+
case TypeID.anyTypification:
|
|
947
948
|
case TypeID.integer:
|
|
948
949
|
return type;
|
|
949
950
|
case TypeID.basic: {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
|
|
3
3
|
import type { TypePath } from './typification';
|
|
4
|
-
import { AnyTypificationT, basic, bool, IntegerT, tuple } from './typification';
|
|
5
|
-
import { applyPath } from './typification-api';
|
|
4
|
+
import { AnyTypificationT, basic, bool, IntegerT, tuple, type Typification } from './typification';
|
|
5
|
+
import { applyPath, compareTemplated } from './typification-api';
|
|
6
6
|
|
|
7
7
|
describe('applyPath', () => {
|
|
8
8
|
function typePath(path: number[]): TypePath {
|
|
@@ -44,3 +44,12 @@ describe('applyPath', () => {
|
|
|
44
44
|
expect(applyPath(nested, typePath([2, 1]))).toBeNull();
|
|
45
45
|
});
|
|
46
46
|
});
|
|
47
|
+
|
|
48
|
+
describe('compareTemplated', () => {
|
|
49
|
+
it('accepts R0 on either side', () => {
|
|
50
|
+
const substitutes = new Map<string, Typification>();
|
|
51
|
+
expect(compareTemplated(substitutes, AnyTypificationT, basic('X1'))).toBe(true);
|
|
52
|
+
expect(compareTemplated(substitutes, bool(basic('X1')), AnyTypificationT)).toBe(true);
|
|
53
|
+
expect(compareTemplated(substitutes, AnyTypificationT, AnyTypificationT)).toBe(true);
|
|
54
|
+
});
|
|
55
|
+
});
|