tla-ts 0.0.3-dev.79f7ed7 → 0.0.3-dev.b74f28c
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/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/transfer.cjs +2 -2
- package/dist/transfer.js +2 -2
- package/package.json +1 -1
- package/src/symmetry.ts +14 -2
- package/src/values.ts +7 -4
package/package.json
CHANGED
package/src/symmetry.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
isEnumerable,
|
|
10
10
|
isFunctionValue,
|
|
11
11
|
isModelValue,
|
|
12
|
+
isSameValue,
|
|
12
13
|
isSetValue,
|
|
13
14
|
toFiniteFunction,
|
|
14
15
|
toFiniteSet,
|
|
@@ -163,7 +164,10 @@ const permuteValue = (value: Value, permutation: Permutation): Value => {
|
|
|
163
164
|
if (size === 0 || size > CACHED_SIZE_LIMIT) return computePermutedValue(value, permutation);
|
|
164
165
|
const cached = permutation.cache.get(value);
|
|
165
166
|
if (cached !== undefined) return cached;
|
|
166
|
-
const
|
|
167
|
+
const computed = computePermutedValue(value, permutation);
|
|
168
|
+
// A permutation often maps a value to an equal one. Keeping the original lets the comparison
|
|
169
|
+
// with the smallest state so far stop at identity.
|
|
170
|
+
const permuted = computed !== value && isSameValue(computed, value) ? value : computed;
|
|
167
171
|
if (permutation.cacheSize >= permutation.cacheLimit) {
|
|
168
172
|
permutation.cache = new WeakMap();
|
|
169
173
|
permutation.cacheSize = 0;
|
|
@@ -184,7 +188,15 @@ const computePermutedValue = (value: ObjectValue, permutation: Permutation) => {
|
|
|
184
188
|
const domain = permuteElements(functionValue.domain, permutation);
|
|
185
189
|
const range = permuteElements(functionValue.range, permutation) ?? functionValue.range;
|
|
186
190
|
if (domain) {
|
|
187
|
-
|
|
191
|
+
const permuted = createFunction(
|
|
192
|
+
domain.map((key, index): [Value, Value] => [key, range[index]]),
|
|
193
|
+
);
|
|
194
|
+
// A permutation often maps the domain to itself, such as a function over the symmetric set.
|
|
195
|
+
// Sharing the original domain array lets comparisons with other images skip the domain.
|
|
196
|
+
const isSameDomain = permuted.domain.every(
|
|
197
|
+
(key, index) => key === functionValue.domain[index],
|
|
198
|
+
);
|
|
199
|
+
return isSameDomain ? createSortedFunction(functionValue.domain, permuted.range) : permuted;
|
|
188
200
|
}
|
|
189
201
|
return range === functionValue.range
|
|
190
202
|
? functionValue
|
package/src/values.ts
CHANGED
|
@@ -5,6 +5,7 @@ export interface ModelValue {
|
|
|
5
5
|
kind: "ModelValue";
|
|
6
6
|
name: string;
|
|
7
7
|
type: string | undefined;
|
|
8
|
+
rank: number;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export interface SetValue {
|
|
@@ -264,6 +265,7 @@ const stringOrder = { ranks: Object.create(null) as Record<string, number>, size
|
|
|
264
265
|
export const setStringOrder = (texts: Iterable<string>) => {
|
|
265
266
|
stringOrder.ranks = Object.create(null);
|
|
266
267
|
stringOrder.size = 0;
|
|
268
|
+
modelValues.clear();
|
|
267
269
|
for (const text of texts) rankString(text);
|
|
268
270
|
};
|
|
269
271
|
|
|
@@ -353,7 +355,7 @@ export const compareValues = (left: Value, right: Value): number => {
|
|
|
353
355
|
if (left.type !== undefined && right.type !== undefined) {
|
|
354
356
|
checkModelValueTypes(left, right, false);
|
|
355
357
|
}
|
|
356
|
-
return
|
|
358
|
+
return left.rank - right.rank;
|
|
357
359
|
}
|
|
358
360
|
if (leftKind === "ModelValue" || rightKind === "ModelValue") {
|
|
359
361
|
checkModelValueTypes(left, right, false);
|
|
@@ -385,14 +387,15 @@ export const compareValues = (left: Value, right: Value): number => {
|
|
|
385
387
|
|
|
386
388
|
const modelValues = new Map<string, ModelValue>();
|
|
387
389
|
|
|
390
|
+
// A check ranks every model value's name when it creates the value, and creates its own values.
|
|
388
391
|
export const createModelValue = (name: string): ModelValue => {
|
|
389
|
-
rankString(name);
|
|
390
392
|
const known = modelValues.get(name);
|
|
391
393
|
if (known) return known;
|
|
392
394
|
const value: ModelValue = {
|
|
393
395
|
kind: "ModelValue",
|
|
394
396
|
name,
|
|
395
397
|
type: name.length > 2 && name[1] === "_" ? name[0] : undefined,
|
|
398
|
+
rank: getStringRank(name),
|
|
396
399
|
};
|
|
397
400
|
modelValues.set(name, value);
|
|
398
401
|
return value;
|
|
@@ -562,7 +565,7 @@ const equalsModelValueWith = (modelValue: ModelValue, other: Value) => {
|
|
|
562
565
|
|
|
563
566
|
const compareModelValue = (left: ModelValue, right: Value) => {
|
|
564
567
|
const type = getModelValueType(left);
|
|
565
|
-
if (type === undefined) return isModelValue(right) ?
|
|
568
|
+
if (type === undefined) return isModelValue(right) ? left.rank - right.rank : -1;
|
|
566
569
|
if (!isModelValue(right)) {
|
|
567
570
|
throw new TlaEvaluationError(
|
|
568
571
|
`Attempted to compare the typed model value ${formatValue(left)} and non-model value\n${formatValue(right)}`,
|
|
@@ -574,7 +577,7 @@ const compareModelValue = (left: ModelValue, right: Value) => {
|
|
|
574
577
|
`Attempted to compare the differently-typed model values ${formatValue(left)} and ${formatValue(right)}`,
|
|
575
578
|
);
|
|
576
579
|
}
|
|
577
|
-
return
|
|
580
|
+
return left.rank - right.rank;
|
|
578
581
|
};
|
|
579
582
|
|
|
580
583
|
const equalsModelValue = (left: ModelValue, right: Value) => {
|