@mark1russell7/coeval 0.17.0 → 0.18.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/build/index.d.ts +39 -78
- package/build/index.d.ts.map +1 -1
- package/build/index.js +313 -133
- package/build/index.js.map +1 -1
- package/package.json +3 -2
- package/src/conform.ts +35 -9
- package/src/evaluate.ts +38 -2
- package/src/formula.ts +14 -3
- package/src/merge.ts +6 -3
- package/src/reference.ts +20 -1
- package/src/replay.ts +123 -35
- package/src/types.ts +97 -21
package/build/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/doc.ts
|
|
2
2
|
/** The keys that an envelope can have. */
|
|
3
3
|
const ENVELOPE_KEYS = [
|
|
4
4
|
"type",
|
|
@@ -240,8 +240,7 @@ function equalWith(a, b, rule) {
|
|
|
240
240
|
}
|
|
241
241
|
return true;
|
|
242
242
|
}
|
|
243
|
-
|
|
244
|
-
//#region src/errors.ts
|
|
243
|
+
// src/errors.ts
|
|
245
244
|
/**
|
|
246
245
|
* This function makes a result with a value.
|
|
247
246
|
*
|
|
@@ -354,8 +353,7 @@ function describe(value) {
|
|
|
354
353
|
return "(a value without a text)";
|
|
355
354
|
}
|
|
356
355
|
}
|
|
357
|
-
|
|
358
|
-
//#region src/world.ts
|
|
356
|
+
// src/world.ts
|
|
359
357
|
/**
|
|
360
358
|
* This function gives the type of a bare equation of a kind (D42). It is the type `of` of the shape of its parts, or
|
|
361
359
|
* else the type `of` of the shape `rest` of a record. The plan, the reference and `check` read it with this one function.
|
|
@@ -568,8 +566,7 @@ function kindDocument(name, kind) {
|
|
|
568
566
|
function looksLikeKind(value) {
|
|
569
567
|
return isRecord(value) && isRecord(field(value, "verbs"));
|
|
570
568
|
}
|
|
571
|
-
|
|
572
|
-
//#region src/types.ts
|
|
569
|
+
// src/types.ts
|
|
573
570
|
/**
|
|
574
571
|
* The domains of the kernel. `unknown` and `never` are not domains: they are the top and the bottom of the types.
|
|
575
572
|
* A machine that does not name one of these domains gets it from this table.
|
|
@@ -592,6 +589,7 @@ const STD_DOMAINS = {
|
|
|
592
589
|
},
|
|
593
590
|
number: {
|
|
594
591
|
is: (value) => typeof value === "number",
|
|
592
|
+
samples: [0, -1],
|
|
595
593
|
summary: "A number of the host, also NaN, an infinity and -0."
|
|
596
594
|
},
|
|
597
595
|
text: {
|
|
@@ -860,7 +858,8 @@ function membersAt(type, domains, samples, depth) {
|
|
|
860
858
|
/**
|
|
861
859
|
* This function gives members of a type for a test of a declaration (D86). A type with at most 64 members gives each
|
|
862
860
|
* member, from the lists `values` of its domains (TYPE.FITS-FINITE). A union gives the members of each of its types.
|
|
863
|
-
* Each other type gives the samples that are its members. The
|
|
861
|
+
* Each other type gives the samples that are its members. The samples of the domains come after the given samples (D99).
|
|
862
|
+
* The kernel does not export the function.
|
|
864
863
|
*
|
|
865
864
|
* @param type - The type.
|
|
866
865
|
* @param domains - The domains of the machine.
|
|
@@ -868,7 +867,51 @@ function membersAt(type, domains, samples, depth) {
|
|
|
868
867
|
* @returns Distinct members of the type.
|
|
869
868
|
*/
|
|
870
869
|
function membersOf(type, domains, samples) {
|
|
871
|
-
return membersAt(type, domains, samples, 0);
|
|
870
|
+
return membersAt(type, domains, withDomainSamples(samples, domains), 0);
|
|
871
|
+
}
|
|
872
|
+
/**
|
|
873
|
+
* This function adds the samples of the domains to a palette (D99). It reads the list `samples` of each domain of the
|
|
874
|
+
* table and of each standard domain that the table does not replace. The result holds each value one time.
|
|
875
|
+
*/
|
|
876
|
+
function withDomainSamples(palette, domains) {
|
|
877
|
+
const out = [];
|
|
878
|
+
for (const value of palette) addValue(out, value);
|
|
879
|
+
const names = /* @__PURE__ */ new Set([...Object.keys(STD_DOMAINS), ...domains === void 0 ? [] : Object.keys(domains)]);
|
|
880
|
+
for (const name of names) {
|
|
881
|
+
const samples = domainOf(name, domains)?.samples;
|
|
882
|
+
if (Array.isArray(samples)) for (const value of samples) addValue(out, value);
|
|
883
|
+
}
|
|
884
|
+
return out;
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
887
|
+
* This function finds the false covers of a language from samples (D94). A cover is false when a sample of the covered
|
|
888
|
+
* domain is in no domain of the cover. The function tests each valid cover of each domain of the table. It ignores a
|
|
889
|
+
* cover that does not count by the line rule of D85, because `fits` ignores it too. It also ignores a sample outside
|
|
890
|
+
* the covered domain.
|
|
891
|
+
*
|
|
892
|
+
* The samples of the domains come after the given samples (D99). `conforms` and a test of `fits` use the function. The
|
|
893
|
+
* kernel does not export it.
|
|
894
|
+
*
|
|
895
|
+
* @param domains - The domains of the language, by their names.
|
|
896
|
+
* @param samples - The samples of each covered domain, by the name of the domain.
|
|
897
|
+
* @returns Each sample that breaks a cover, in the order of the domains, the covers and the samples.
|
|
898
|
+
*/
|
|
899
|
+
function falseCovers(domains, samples) {
|
|
900
|
+
const out = [];
|
|
901
|
+
for (const [name, domain] of Object.entries(domains)) {
|
|
902
|
+
const covers = domain.covers;
|
|
903
|
+
if (!Array.isArray(covers)) continue;
|
|
904
|
+
const values = withDomainSamples((Object.hasOwn(samples, name) ? samples[name] : void 0) ?? [], domains);
|
|
905
|
+
for (const cover of covers) {
|
|
906
|
+
if (!validCover(name, cover, domains)) continue;
|
|
907
|
+
for (const value of values) if (member(value, name, domains) && !cover.some((part) => member(value, part, domains))) out.push({
|
|
908
|
+
domain: name,
|
|
909
|
+
cover,
|
|
910
|
+
value
|
|
911
|
+
});
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
return out;
|
|
872
915
|
}
|
|
873
916
|
/** This function holds the rules of the shapes of `fits`: base types, lists, records and functions. */
|
|
874
917
|
function shapeFits(a, b, domains, next, gradual, budget) {
|
|
@@ -963,7 +1006,8 @@ function partFits(part, expected, domains, depth, gradual, state) {
|
|
|
963
1006
|
* cases is a split. An optional field also has the absent case.
|
|
964
1007
|
*
|
|
965
1008
|
* The type splits follow each value split, in the same order (D90). A base type with a valid cover in its line splits
|
|
966
|
-
* into the domains of
|
|
1009
|
+
* into the domains of a cover, and it tries each valid cover (D102). A union without a finite list splits into its
|
|
1010
|
+
* members. The prefix is the path of `a`.
|
|
967
1011
|
*/
|
|
968
1012
|
function splitsOf(a, domains, depth, prefix = []) {
|
|
969
1013
|
const out = [];
|
|
@@ -996,10 +1040,10 @@ function splitsOf(a, domains, depth, prefix = []) {
|
|
|
996
1040
|
optional
|
|
997
1041
|
});
|
|
998
1042
|
else if (inner.t === "base") {
|
|
999
|
-
const
|
|
1000
|
-
if (
|
|
1043
|
+
const covers = coversOf(inner.name, domains, false);
|
|
1044
|
+
if (covers.length > 0) later.push({
|
|
1001
1045
|
path: [...path, key],
|
|
1002
|
-
|
|
1046
|
+
covers,
|
|
1003
1047
|
optional
|
|
1004
1048
|
});
|
|
1005
1049
|
}
|
|
@@ -1013,16 +1057,17 @@ function validCover(name, cover, domains) {
|
|
|
1013
1057
|
return Array.isArray(cover) && cover.length > 0 && cover.every((part) => typeof part === "string" && part !== name && lineOf(part, domains).has(name));
|
|
1014
1058
|
}
|
|
1015
1059
|
/**
|
|
1016
|
-
* This function gives the
|
|
1017
|
-
*
|
|
1018
|
-
* `undefined`.
|
|
1060
|
+
* This function gives the valid covers of a base type for a type split (D90, D102). The order is the order of the line,
|
|
1061
|
+
* then the order of the covers of each domain. With `own`, only the domain of the type itself counts.
|
|
1019
1062
|
*/
|
|
1020
|
-
function
|
|
1063
|
+
function coversOf(name, domains, own) {
|
|
1064
|
+
const out = [];
|
|
1021
1065
|
for (const each of own ? [name] : lineOf(name, domains)) {
|
|
1022
1066
|
const covers = domainOf(each, domains)?.covers;
|
|
1023
1067
|
if (!Array.isArray(covers)) continue;
|
|
1024
|
-
for (const cover of covers) if (validCover(each, cover, domains))
|
|
1068
|
+
for (const cover of covers) if (validCover(each, cover, domains)) out.push(cover);
|
|
1025
1069
|
}
|
|
1070
|
+
return out;
|
|
1026
1071
|
}
|
|
1027
1072
|
/**
|
|
1028
1073
|
* This function gives the splits of a case of a type split, at the path of the case (D90). A case with a finite list
|
|
@@ -1044,10 +1089,10 @@ function againOf(type, path, domains, depth) {
|
|
|
1044
1089
|
types: form.members,
|
|
1045
1090
|
optional: false
|
|
1046
1091
|
}];
|
|
1047
|
-
const
|
|
1048
|
-
return
|
|
1092
|
+
const covers = form.t === "base" ? coversOf(form.name, domains, true) : [];
|
|
1093
|
+
return covers.length === 0 ? [] : [{
|
|
1049
1094
|
path,
|
|
1050
|
-
|
|
1095
|
+
covers,
|
|
1051
1096
|
optional: false
|
|
1052
1097
|
}];
|
|
1053
1098
|
}
|
|
@@ -1081,6 +1126,8 @@ function narrowAt(type, path, at, narrowed, domains) {
|
|
|
1081
1126
|
* A record of the split that does not fit splits the next such field. A record of a type split first splits its case
|
|
1082
1127
|
* again, at the same path. One budget of 64 records serves the outer split and each split inside its work, at each
|
|
1083
1128
|
* depth. Thus nested splits do not multiply the work.
|
|
1129
|
+
*
|
|
1130
|
+
* A cover split tries each valid cover of its field until one fits (D102). Each try takes from the same budget.
|
|
1084
1131
|
*/
|
|
1085
1132
|
function splitFits(found, a, expected, domains, depth, gradual, budget) {
|
|
1086
1133
|
const splits = splitsOf(a, domains, depth);
|
|
@@ -1091,6 +1138,18 @@ function splitFits(found, a, expected, domains, depth, gradual, budget) {
|
|
|
1091
1138
|
function casesFit(type, closed, splits, index, expected, domains, depth, gradual, budget) {
|
|
1092
1139
|
const split = splits[index];
|
|
1093
1140
|
if (split === void 0) return false;
|
|
1141
|
+
if (split.covers !== void 0) {
|
|
1142
|
+
for (const cover of split.covers) {
|
|
1143
|
+
const tried = [...splits];
|
|
1144
|
+
tried[index] = {
|
|
1145
|
+
path: split.path,
|
|
1146
|
+
types: cover,
|
|
1147
|
+
optional: split.optional
|
|
1148
|
+
};
|
|
1149
|
+
if (casesFit(type, closed, tried, index, expected, domains, depth, gradual, budget)) return true;
|
|
1150
|
+
}
|
|
1151
|
+
return false;
|
|
1152
|
+
}
|
|
1094
1153
|
const cases = (split.values?.map((value) => ({ one: [value] })) ?? split.types ?? []).map((each) => narrowAt(type, split.path, 0, each, domains));
|
|
1095
1154
|
if (split.optional) cases.push(narrowAt(type, split.path, 0, void 0, domains));
|
|
1096
1155
|
for (const [at, record] of cases.entries()) {
|
|
@@ -1137,16 +1196,18 @@ function casesFit(type, closed, splits, index, expected, domains, depth, gradual
|
|
|
1137
1196
|
* split first, then the paths of each next depth, in the order of the keys. A path goes into a record without a
|
|
1138
1197
|
* finite list. Thus `{a: {x: bool}}` fits the union of `{a: {x: true}}` and `{a: {x: false}}`.
|
|
1139
1198
|
* - A type split comes after each value split (TYPE.FITS-SPLIT-TYPE, D90). A field of a base type with a valid cover in
|
|
1140
|
-
* its line splits into the domains of
|
|
1141
|
-
* members. A case that does not fit splits again at its path, by the same rules. A base type there uses only
|
|
1142
|
-
*
|
|
1199
|
+
* its line splits into the domains of a cover. A field of a union without a finite list splits into its
|
|
1200
|
+
* members. A case that does not fit splits again at its path, by the same rules. A base type there uses only the
|
|
1201
|
+
* covers of its own domain. Thus `{a: number}` fits `{a: neg} | {a: nonneg}` when `neg` and `nonneg` cover `number`.
|
|
1202
|
+
* - A field with more than one valid cover tries each cover until one fits (TYPE.FITS-SPLIT-COVERS, D102). The order
|
|
1203
|
+
* is the order of the line, then the order of the covers of each domain.
|
|
1143
1204
|
*
|
|
1144
1205
|
* The relation is sound: a member of `found` is a member of `expected` when no `unknown` is in the types
|
|
1145
1206
|
* (TYPE.FITS-SOUND). The finite rule trusts `values`, and the cover rule trusts `covers`. Thus a list without a member
|
|
1146
1207
|
* or a false cover makes the relation unsound for that domain.
|
|
1147
1208
|
*
|
|
1148
|
-
* The relation is not complete. A split builds at most 64 records, with each split inside its work at each depth.
|
|
1149
|
-
*
|
|
1209
|
+
* The relation is not complete. A split builds at most 64 records, with each split inside its work at each depth. The
|
|
1210
|
+
* failed tries of covers take from these 64 records too. A domain without `values` gets no finite rule, and
|
|
1150
1211
|
* neither does a type with more than 64 members that is not a record. The cover rule tests at most 64 domains of
|
|
1151
1212
|
* covers. The function does not throw.
|
|
1152
1213
|
*
|
|
@@ -1563,8 +1624,7 @@ function typeIssues(type, domains) {
|
|
|
1563
1624
|
}
|
|
1564
1625
|
return issues;
|
|
1565
1626
|
}
|
|
1566
|
-
|
|
1567
|
-
//#region src/merge.ts
|
|
1627
|
+
// src/merge.ts
|
|
1568
1628
|
/** The exception of a merge with conflicts. It lists each conflict of the merge, not only the first. */
|
|
1569
1629
|
var MergeError = class extends Error {
|
|
1570
1630
|
conflicts;
|
|
@@ -1611,7 +1671,7 @@ function same(a, b) {
|
|
|
1611
1671
|
}
|
|
1612
1672
|
/**
|
|
1613
1673
|
* Two domains are the same when they are one object. They are also the same when they have the same test `is`,
|
|
1614
|
-
* parents, summary, steps, codec, list of values and covers. Thus two languages that give one test under one name give one
|
|
1674
|
+
* parents, summary, steps, codec, list of values, samples and covers. Thus two languages that give one test under one name give one
|
|
1615
1675
|
* domain. Two codecs are the same when they have the same functions `encode` and `decode` (D80).
|
|
1616
1676
|
*/
|
|
1617
1677
|
function sameDomain(a, b) {
|
|
@@ -1623,6 +1683,7 @@ function sameDomain(a, b) {
|
|
|
1623
1683
|
steps: same(a.steps ?? {}, b.steps ?? {}),
|
|
1624
1684
|
codec: same(a.codec ?? null, b.codec ?? null),
|
|
1625
1685
|
values: same(a.values ?? null, b.values ?? null),
|
|
1686
|
+
samples: same(a.samples ?? null, b.samples ?? null),
|
|
1626
1687
|
covers: same(a.covers ?? [], b.covers ?? [])
|
|
1627
1688
|
};
|
|
1628
1689
|
return Object.values(fields).every(Boolean);
|
|
@@ -1630,8 +1691,8 @@ function sameDomain(a, b) {
|
|
|
1630
1691
|
/**
|
|
1631
1692
|
* This function makes a part of a merge that adds parents, steps or covers to a domain of an earlier part
|
|
1632
1693
|
* (TYPE.PARENTS). An example is a domain of another language. The part reads the domain from the merge before it
|
|
1633
|
-
* (`prev`). It gives a copy with the same test, summary, codec
|
|
1634
|
-
* in `replaces` (D17).
|
|
1694
|
+
* (`prev`). It gives a copy with the same test, summary, codec, list of values and samples, and it names
|
|
1695
|
+
* `["domains", name]` in `replaces` (D17).
|
|
1635
1696
|
* A domain of the kernel that the earlier parts do not name comes from `STD_DOMAINS`.
|
|
1636
1697
|
*
|
|
1637
1698
|
* An extension does not change the codec. Thus each member keeps its document (D80).
|
|
@@ -1664,6 +1725,7 @@ function extendDomain(name, more) {
|
|
|
1664
1725
|
steps: Object.keys(steps).length === 0 ? void 0 : steps,
|
|
1665
1726
|
codec: found.codec,
|
|
1666
1727
|
values: found.values,
|
|
1728
|
+
samples: found.samples,
|
|
1667
1729
|
covers: covers.length === 0 ? void 0 : covers
|
|
1668
1730
|
};
|
|
1669
1731
|
const domain = {};
|
|
@@ -2108,8 +2170,7 @@ function restrictMachine(machine, paths) {
|
|
|
2108
2170
|
...tables.domains === void 0 ? {} : { domains: tables.domains }
|
|
2109
2171
|
};
|
|
2110
2172
|
}
|
|
2111
|
-
|
|
2112
|
-
//#region src/ladder.ts
|
|
2173
|
+
// src/ladder.ts
|
|
2113
2174
|
/** The rungs of the ladder, in the order that a question visits them. */
|
|
2114
2175
|
const RUNGS = [
|
|
2115
2176
|
"own",
|
|
@@ -2277,8 +2338,7 @@ function ask(world, doc, verb, options = {}) {
|
|
|
2277
2338
|
steps
|
|
2278
2339
|
};
|
|
2279
2340
|
}
|
|
2280
|
-
|
|
2281
|
-
//#region src/deref.ts
|
|
2341
|
+
// src/deref.ts
|
|
2282
2342
|
/**
|
|
2283
2343
|
* The brand of a host thing: an object of the host that answers the steps of a path itself. The brand is a
|
|
2284
2344
|
* global symbol, thus two copies of the kernel in one program know the things of each other.
|
|
@@ -2822,8 +2882,7 @@ function resolveFully$1(nav, ctx, path, hops, known) {
|
|
|
2822
2882
|
function valueOfThing(thing) {
|
|
2823
2883
|
return isHostThing(thing) ? thing.toJson() : thing;
|
|
2824
2884
|
}
|
|
2825
|
-
|
|
2826
|
-
//#region src/classify.ts
|
|
2885
|
+
// src/classify.ts
|
|
2827
2886
|
function isStrictSuperset(larger, smaller) {
|
|
2828
2887
|
return larger.length > smaller.length && smaller.every((name) => larger.includes(name));
|
|
2829
2888
|
}
|
|
@@ -2861,8 +2920,7 @@ function classify(shapes, value) {
|
|
|
2861
2920
|
function tag(value, kind) {
|
|
2862
2921
|
return typed(kind, value);
|
|
2863
2922
|
}
|
|
2864
|
-
|
|
2865
|
-
//#region src/parts.ts
|
|
2923
|
+
// src/parts.ts
|
|
2866
2924
|
var Bad = class {
|
|
2867
2925
|
reason;
|
|
2868
2926
|
at;
|
|
@@ -3196,8 +3254,7 @@ function scopesOf(rules, value, slots) {
|
|
|
3196
3254
|
later
|
|
3197
3255
|
};
|
|
3198
3256
|
}
|
|
3199
|
-
|
|
3200
|
-
//#region src/evaluate.ts
|
|
3257
|
+
// src/evaluate.ts
|
|
3201
3258
|
/**
|
|
3202
3259
|
* This function makes a context with names and capabilities. The other roots are empty, and an evaluation sets
|
|
3203
3260
|
* the world.
|
|
@@ -3635,6 +3692,11 @@ var Session = class {
|
|
|
3635
3692
|
list;
|
|
3636
3693
|
tick = 0;
|
|
3637
3694
|
nextId = 0;
|
|
3695
|
+
/**
|
|
3696
|
+
* The count of the drives without a wait that are active at this time. In a run, an effect under such a drive does
|
|
3697
|
+
* not reach the host (RUN.HELD).
|
|
3698
|
+
*/
|
|
3699
|
+
held = 0;
|
|
3638
3700
|
current;
|
|
3639
3701
|
holder;
|
|
3640
3702
|
/**
|
|
@@ -3842,6 +3904,11 @@ var Session = class {
|
|
|
3842
3904
|
if ("ok" in made) return made;
|
|
3843
3905
|
const perform = this.perform;
|
|
3844
3906
|
if (!this.running || perform === void 0) return this.answer(made, place);
|
|
3907
|
+
if (this.held > 0) {
|
|
3908
|
+
made.outcome = fail("#CALC!", heldReason(made.kind), { place });
|
|
3909
|
+
yield HELD;
|
|
3910
|
+
return made.outcome;
|
|
3911
|
+
}
|
|
3845
3912
|
let done;
|
|
3846
3913
|
try {
|
|
3847
3914
|
done = perform(made);
|
|
@@ -4021,6 +4088,18 @@ function holderNode() {
|
|
|
4021
4088
|
function waitedReason(kindText) {
|
|
4022
4089
|
return `${kindText} waits for effects, and its parent cannot wait. Give the parent a runner.`;
|
|
4023
4090
|
}
|
|
4091
|
+
/**
|
|
4092
|
+
* This function gives the reason of an effect that a run does not give to the host: the parent of its runner cannot
|
|
4093
|
+
* wait (RUN.HELD). The plan and the reference give the same reason.
|
|
4094
|
+
*
|
|
4095
|
+
* @param kind - The kind of the effect.
|
|
4096
|
+
* @returns The reason.
|
|
4097
|
+
*/
|
|
4098
|
+
function heldReason(kind) {
|
|
4099
|
+
return `The parent of the runner cannot wait, thus the host does not get the effect ${typeof kind === "string" ? kind : kind.join(".")}.`;
|
|
4100
|
+
}
|
|
4101
|
+
/** The wait of an effect that a run does not give to the host. A drive without a wait stops at it (RUN.HELD). */
|
|
4102
|
+
const HELD = /* @__PURE__ */ Promise.resolve(void 0);
|
|
4024
4103
|
/** This function drives steps that cannot wait. A step that waits stops the steps, and gives `#CALC!`. */
|
|
4025
4104
|
function drive$2(steps, kindText) {
|
|
4026
4105
|
const step = steps.next();
|
|
@@ -4649,10 +4728,19 @@ function placedRun(inner, place, name) {
|
|
|
4649
4728
|
/**
|
|
4650
4729
|
* This function gives the code of a runner under a parent that cannot wait: its steps, driven without a wait. An
|
|
4651
4730
|
* evaluation and a run both drive them (RUN.DRIVE-NESTED). Only a step that really waits gives `#CALC!`, at the place
|
|
4652
|
-
* of the runner, where the error started (RUN.WAIT).
|
|
4731
|
+
* of the runner, where the error started (RUN.WAIT). In a run, an effect under the runner does not reach the host,
|
|
4732
|
+
* because the parent cannot wait for its answer (RUN.HELD).
|
|
4653
4733
|
*/
|
|
4654
4734
|
function runnerCode(run, place, kindText) {
|
|
4655
|
-
return (ctx, rt) =>
|
|
4735
|
+
return (ctx, rt) => {
|
|
4736
|
+
if (!rt.running || !(rt instanceof Session)) return placed(drive$2(run(ctx, rt), kindText), place);
|
|
4737
|
+
rt.held += 1;
|
|
4738
|
+
try {
|
|
4739
|
+
return placed(drive$2(run(ctx, rt), kindText), place);
|
|
4740
|
+
} finally {
|
|
4741
|
+
rt.held -= 1;
|
|
4742
|
+
}
|
|
4743
|
+
};
|
|
4656
4744
|
}
|
|
4657
4745
|
/** This function gives the steps of a run of an evaluator. The code runs at the first step, and it does not wait. */
|
|
4658
4746
|
function runOf(code) {
|
|
@@ -4993,8 +5081,7 @@ function flatten(trace) {
|
|
|
4993
5081
|
function failures(trace) {
|
|
4994
5082
|
return flatten(trace).filter((node) => !node.result.ok && !node.children.some((child) => !child.result.ok && child.result.error === node.result.error)).map((node) => node.result.error);
|
|
4995
5083
|
}
|
|
4996
|
-
|
|
4997
|
-
//#region src/stdlib.ts
|
|
5084
|
+
// src/stdlib.ts
|
|
4998
5085
|
/**
|
|
4999
5086
|
* The world of the examples: small kinds for numbers, lists, conditions, names, sequences and effects.
|
|
5000
5087
|
* Each kind names an evaluator for `eval` and a view for `view`. The site draws each document with its view.
|
|
@@ -5895,8 +5982,7 @@ const STD_MACHINE = {
|
|
|
5895
5982
|
};
|
|
5896
5983
|
/** The capabilities of the examples at the root: the two effects of the standard world. */
|
|
5897
5984
|
const STD_CAPS = ["log", "write"];
|
|
5898
|
-
|
|
5899
|
-
//#region src/order.ts
|
|
5985
|
+
// src/order.ts
|
|
5900
5986
|
/**
|
|
5901
5987
|
* This function finds the references that a sequence cannot resolve. A step can read only the steps before it.
|
|
5902
5988
|
*
|
|
@@ -5992,8 +6078,7 @@ function layers(steps) {
|
|
|
5992
6078
|
}
|
|
5993
6079
|
return result;
|
|
5994
6080
|
}
|
|
5995
|
-
|
|
5996
|
-
//#region src/context.ts
|
|
6081
|
+
// src/context.ts
|
|
5997
6082
|
/** The parts of a context. A term can reach outside itself only through these parts. */
|
|
5998
6083
|
const PARTS = [
|
|
5999
6084
|
"self",
|
|
@@ -6281,8 +6366,7 @@ const CONSTRUCTS = [
|
|
|
6281
6366
|
}
|
|
6282
6367
|
}
|
|
6283
6368
|
];
|
|
6284
|
-
|
|
6285
|
-
//#region src/typing.ts
|
|
6369
|
+
// src/typing.ts
|
|
6286
6370
|
/**
|
|
6287
6371
|
* The value type of the root `caps`: a list of capabilities. A capability is a text, or a list of keys. The kernel
|
|
6288
6372
|
* narrows the capabilities for each part, thus the host does not give this type.
|
|
@@ -6509,8 +6593,7 @@ function typePass(machine, nodes, verb, expect, rootTypes = {}) {
|
|
|
6509
6593
|
places
|
|
6510
6594
|
};
|
|
6511
6595
|
}
|
|
6512
|
-
|
|
6513
|
-
//#region src/static.ts
|
|
6596
|
+
// src/static.ts
|
|
6514
6597
|
/** The names of a walk without names. A walk does not change a set at any time: it makes a new set to add names. */
|
|
6515
6598
|
const NO_NAMES = /* @__PURE__ */ new Set();
|
|
6516
6599
|
/** This function gives the options of a walk without the names of the host. */
|
|
@@ -7192,8 +7275,7 @@ function checkAll(machine, doc, options, nodes, seen = /* @__PURE__ */ new Set()
|
|
|
7192
7275
|
}
|
|
7193
7276
|
return issues;
|
|
7194
7277
|
}
|
|
7195
|
-
|
|
7196
|
-
//#region src/facts.ts
|
|
7278
|
+
// src/facts.ts
|
|
7197
7279
|
/** The lazy rules that cover each part: the rules of a document whose evaluator the contract does not describe. */
|
|
7198
7280
|
const EACH$1 = "each";
|
|
7199
7281
|
/** An empty list. One frozen list serves each empty list of the facts, thus a store of many facts keeps less (PLAN.LEAN). */
|
|
@@ -7422,8 +7504,7 @@ function factsOf(machine, doc, options = {}) {
|
|
|
7422
7504
|
size
|
|
7423
7505
|
};
|
|
7424
7506
|
}
|
|
7425
|
-
|
|
7426
|
-
//#region src/effects.ts
|
|
7507
|
+
// src/effects.ts
|
|
7427
7508
|
/** Each capability: one capability with no keys. It permits each effect, because each kind starts with no keys (CAP.KEYS). */
|
|
7428
7509
|
const EACH = /* @__PURE__ */ Object.freeze([[]]);
|
|
7429
7510
|
/**
|
|
@@ -7503,8 +7584,7 @@ function checkLatent(machine, declared, body, options = {}) {
|
|
|
7503
7584
|
}
|
|
7504
7585
|
return issues;
|
|
7505
7586
|
}
|
|
7506
|
-
|
|
7507
|
-
//#region src/codec.ts
|
|
7587
|
+
// src/codec.ts
|
|
7508
7588
|
/** This function gives the codec of a domain, or `undefined` when the domain has no codec. */
|
|
7509
7589
|
function codecOf(domain) {
|
|
7510
7590
|
const codec = domain.codec;
|
|
@@ -7675,8 +7755,7 @@ function encodeValue(machine, value) {
|
|
|
7675
7755
|
function decodeValue(machine, doc) {
|
|
7676
7756
|
return prepare(machine, doc, { declaredType: "lit" }).evaluate(makeContext());
|
|
7677
7757
|
}
|
|
7678
|
-
|
|
7679
|
-
//#region src/formula.ts
|
|
7758
|
+
// src/formula.ts
|
|
7680
7759
|
/** The mark of a field that the profile leaves out of a record. */
|
|
7681
7760
|
const SKIPPED = /* @__PURE__ */ Symbol("skipped");
|
|
7682
7761
|
/** The value of a name whose binding failed. A reference to the name gives the error. */
|
|
@@ -7937,7 +8016,7 @@ function paramsOf(value) {
|
|
|
7937
8016
|
/**
|
|
7938
8017
|
* This function makes the type rules of the formula kit for one profile (TYPE.SYNTH, D25). Each evaluator of the kit
|
|
7939
8018
|
* holds its rule. The rules read the rules of the profile that change a type: `truthy`, `truthType`, `logic`,
|
|
7940
|
-
* `otherwise`, `omit` and `
|
|
8019
|
+
* `otherwise`, `omit`, `sigs` and `extTypes`.
|
|
7941
8020
|
*/
|
|
7942
8021
|
function formulaTypes(profile) {
|
|
7943
8022
|
const declared = profile.truthy !== void 0 && profile.truthType !== void 0;
|
|
@@ -8191,7 +8270,13 @@ function formulaTypes(profile) {
|
|
|
8191
8270
|
},
|
|
8192
8271
|
"formula.ext": { synth: (input) => {
|
|
8193
8272
|
const name = nameOf(input);
|
|
8194
|
-
if (profile.ext !== void 0 && Object.hasOwn(profile.ext, name))
|
|
8273
|
+
if (profile.ext !== void 0 && Object.hasOwn(profile.ext, name)) {
|
|
8274
|
+
const types = profile.extTypes;
|
|
8275
|
+
const declared = types !== void 0 && Object.hasOwn(types, name) ? types[name] : void 0;
|
|
8276
|
+
if (declared === void 0) return "unknown";
|
|
8277
|
+
const type = input.contract(declared, `type of ext.${name} in extTypes`);
|
|
8278
|
+
return typeIssues(type, input.machine.domains).length > 0 ? "unknown" : type;
|
|
8279
|
+
}
|
|
8195
8280
|
if (name === "undefined") return "undefined";
|
|
8196
8281
|
if (name === "number") return "number";
|
|
8197
8282
|
return name === "domain" ? domainTypeOf(input.doc.value, input.machine.domains) : "unknown";
|
|
@@ -8257,6 +8342,7 @@ const PROFILE_KEYS = /* @__PURE__ */ Object.freeze([
|
|
|
8257
8342
|
"ops",
|
|
8258
8343
|
"lazy",
|
|
8259
8344
|
"ext",
|
|
8345
|
+
"extTypes",
|
|
8260
8346
|
"truthy",
|
|
8261
8347
|
"truthType",
|
|
8262
8348
|
"otherwise",
|
|
@@ -8772,8 +8858,7 @@ function formulaMachine(profile = {}, more = {}) {
|
|
|
8772
8858
|
facts: kit.facts
|
|
8773
8859
|
}, more);
|
|
8774
8860
|
}
|
|
8775
|
-
|
|
8776
|
-
//#region src/syntax.ts
|
|
8861
|
+
// src/syntax.ts
|
|
8777
8862
|
/**
|
|
8778
8863
|
* The standard syntax of the formula kit. It gives the site and the playground a text form. The operators are
|
|
8779
8864
|
* `or`, `and`, `not`, the comparisons, `+ - * / %`, a minus sign and `^`, from the loosest to the tightest. A call
|
|
@@ -9869,8 +9954,7 @@ function syntaxFormat(profile) {
|
|
|
9869
9954
|
evaluators: { "syntax.format": code }
|
|
9870
9955
|
};
|
|
9871
9956
|
}
|
|
9872
|
-
|
|
9873
|
-
//#region src/reference.ts
|
|
9957
|
+
// src/reference.ts
|
|
9874
9958
|
function own$1(table, name) {
|
|
9875
9959
|
return table !== void 0 && Object.hasOwn(table, name) ? table[name] : void 0;
|
|
9876
9960
|
}
|
|
@@ -10056,6 +10140,11 @@ function* causeAndWait(env, ctx, kind, payload, place) {
|
|
|
10056
10140
|
if ("ok" in effect) return effect;
|
|
10057
10141
|
const perform = env.perform;
|
|
10058
10142
|
if (perform === void 0) return effect.outcome = ok(payload);
|
|
10143
|
+
if (env.held > 0) {
|
|
10144
|
+
effect.outcome = fail("#CALC!", heldReason(kind), { place });
|
|
10145
|
+
yield Promise.resolve(void 0);
|
|
10146
|
+
return effect.outcome;
|
|
10147
|
+
}
|
|
10059
10148
|
let given;
|
|
10060
10149
|
try {
|
|
10061
10150
|
given = perform(effect);
|
|
@@ -10125,7 +10214,15 @@ function evaluateSeen(env, seen, at) {
|
|
|
10125
10214
|
const { chosen } = seen;
|
|
10126
10215
|
const { place } = at;
|
|
10127
10216
|
if ("gap" in chosen) return fail("#NOEVAL", chosen.gap, { place });
|
|
10128
|
-
if ("runner" in chosen)
|
|
10217
|
+
if ("runner" in chosen) {
|
|
10218
|
+
if (!env.running) return drive$1(runSeen(env, seen, at, chosen.runner), place, seen.kindText);
|
|
10219
|
+
env.held += 1;
|
|
10220
|
+
try {
|
|
10221
|
+
return drive$1(runSeen(env, seen, at, chosen.runner), place, seen.kindText);
|
|
10222
|
+
} finally {
|
|
10223
|
+
env.held -= 1;
|
|
10224
|
+
}
|
|
10225
|
+
}
|
|
10129
10226
|
const input = evalInput(env, seen, at);
|
|
10130
10227
|
try {
|
|
10131
10228
|
return placed(chosen.evaluator(input), place);
|
|
@@ -10385,6 +10482,7 @@ function envOf(machine, options, running, root, outer) {
|
|
|
10385
10482
|
counts: /* @__PURE__ */ new Map(),
|
|
10386
10483
|
alls: 0
|
|
10387
10484
|
},
|
|
10485
|
+
held: 0,
|
|
10388
10486
|
reading: outer ?? (options.reads === void 0 ? void 0 : {
|
|
10389
10487
|
list: options.reads,
|
|
10390
10488
|
root
|
|
@@ -10886,8 +10984,7 @@ function valuesOfStrict(parts) {
|
|
|
10886
10984
|
}
|
|
10887
10985
|
return { values };
|
|
10888
10986
|
}
|
|
10889
|
-
|
|
10890
|
-
//#region src/replay.ts
|
|
10987
|
+
// src/replay.ts
|
|
10891
10988
|
/**
|
|
10892
10989
|
* This function makes a recorder (RUN.RECORD). The recorder gives each effect to the function `perform` of the host.
|
|
10893
10990
|
* Its log keeps each effect with its address, its kind, its payload and the outcome that the kernel gives it. The log
|
|
@@ -11053,8 +11150,60 @@ function holdsHole(value) {
|
|
|
11053
11150
|
return false;
|
|
11054
11151
|
}
|
|
11055
11152
|
/**
|
|
11153
|
+
* This function gives the lists and the plain records that the walk of `causeJson` keeps as containers of parts, also
|
|
11154
|
+
* with a term document (D101). Such a container is at two places of the walk, or it holds such a container at some depth.
|
|
11155
|
+
* It reads the values as the walk does: the fields of an exception, its hidden fields and its cause, and the items of a
|
|
11156
|
+
* container. A term document gives a copy at each place, thus a shared container cannot be one.
|
|
11157
|
+
*/
|
|
11158
|
+
function sharedOf(root) {
|
|
11159
|
+
const seen = /* @__PURE__ */ new Set();
|
|
11160
|
+
const twice = [];
|
|
11161
|
+
const owners = /* @__PURE__ */ new Map();
|
|
11162
|
+
const stack = [[root, void 0]];
|
|
11163
|
+
for (let next = stack.pop(); next !== void 0; next = stack.pop()) {
|
|
11164
|
+
const [at, owner] = next;
|
|
11165
|
+
if (typeof at !== "object" || at === null) continue;
|
|
11166
|
+
const container = Array.isArray(at) || isRecord(at);
|
|
11167
|
+
if (!container && !(at instanceof Error)) continue;
|
|
11168
|
+
if (container && owner !== void 0) {
|
|
11169
|
+
const list = owners.get(at);
|
|
11170
|
+
if (list === void 0) owners.set(at, [owner]);
|
|
11171
|
+
else list.push(owner);
|
|
11172
|
+
}
|
|
11173
|
+
if (seen.has(at)) {
|
|
11174
|
+
if (container) twice.push(at);
|
|
11175
|
+
continue;
|
|
11176
|
+
}
|
|
11177
|
+
seen.add(at);
|
|
11178
|
+
if (Array.isArray(at)) {
|
|
11179
|
+
for (let item = 0; item < at.length; item += 1) if (Object.hasOwn(at, item)) stack.push([readField(at, item), at]);
|
|
11180
|
+
} else if (container) for (const key of Object.keys(at)) stack.push([readField(at, key), at]);
|
|
11181
|
+
else {
|
|
11182
|
+
for (const key of Object.keys(at)) if (!ownField(key)) stack.push([readField(at, key), void 0]);
|
|
11183
|
+
for (const key of HIDDEN) if (Object.getOwnPropertyDescriptor(at, key)?.enumerable === false) stack.push([readField(at, key), void 0]);
|
|
11184
|
+
if (Object.hasOwn(at, "cause")) stack.push([readField(at, "cause"), void 0]);
|
|
11185
|
+
}
|
|
11186
|
+
}
|
|
11187
|
+
const shared = /* @__PURE__ */ new Set();
|
|
11188
|
+
for (let at = twice.pop(); at !== void 0; at = twice.pop()) {
|
|
11189
|
+
if (shared.has(at)) continue;
|
|
11190
|
+
shared.add(at);
|
|
11191
|
+
for (const owner of owners.get(at) ?? []) twice.push(owner);
|
|
11192
|
+
}
|
|
11193
|
+
return shared;
|
|
11194
|
+
}
|
|
11195
|
+
/**
|
|
11196
|
+
* This function tells if the walk of `causeJson` keeps a value with a term document as a container of parts (D101). The
|
|
11197
|
+
* value is in the set of `sharedOf`. A member of a domain stays a term document, because its codec makes it again.
|
|
11198
|
+
*/
|
|
11199
|
+
function wholeOf(shared, value, term) {
|
|
11200
|
+
if (typeof value !== "object" || value === null || !shared.has(value)) return false;
|
|
11201
|
+
const type = isRecord(term) ? term["type"] : void 0;
|
|
11202
|
+
return !(Array.isArray(type) && type[0] === "ext" && type[1] === "domain");
|
|
11203
|
+
}
|
|
11204
|
+
/**
|
|
11056
11205
|
* This function tells if a list or a plain record holds an exception at some depth (D87). It reads the items as the
|
|
11057
|
-
* walk of `causeJson` does, thus a cause
|
|
11206
|
+
* walk of `causeJson` does, thus a container cause of an error value with an exception gets a form.
|
|
11058
11207
|
*/
|
|
11059
11208
|
function holdsException(value) {
|
|
11060
11209
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -11116,13 +11265,15 @@ function keptOf(keys, built) {
|
|
|
11116
11265
|
*
|
|
11117
11266
|
* The walk gives each exception an index in the order of a depth-first walk. It takes the fields in `parts` in the
|
|
11118
11267
|
* order of their keys, the hidden fields in the order of `HIDDEN`, then the cause (D78). A list or a plain record
|
|
11119
|
-
* without a term document is a container of parts, with its items in their order (D82).
|
|
11120
|
-
* when it holds an exception (D87).
|
|
11268
|
+
* without a term document is a container of parts, with its items in their order (D82). The cause of an error value
|
|
11269
|
+
* is a container only when it holds an exception (D87). The cause of an exception is a container as a field is (D100).
|
|
11270
|
+
* A value that is an earlier exception of the walk is its index in `loop` (D77).
|
|
11121
11271
|
*
|
|
11122
|
-
* A container that an earlier place holds is its index in `share`, also a container that holds itself (D88).
|
|
11123
|
-
* a
|
|
11272
|
+
* A container that an earlier place holds is its index in `share`, also a container that holds itself (D88). A container
|
|
11273
|
+
* of `sharedOf` is a container of parts also with a term document, thus each share gives one object (D101). The value
|
|
11274
|
+
* `tried` marks a root that `encodeValue` cannot write. The walk is a loop, thus a long chain does not overflow the stack.
|
|
11124
11275
|
*/
|
|
11125
|
-
function causeJson(machine, root) {
|
|
11276
|
+
function causeJson(machine, root, shared, tried) {
|
|
11126
11277
|
const items = [];
|
|
11127
11278
|
const index = /* @__PURE__ */ new Map();
|
|
11128
11279
|
const holders = /* @__PURE__ */ new Map();
|
|
@@ -11170,7 +11321,16 @@ function causeJson(machine, root) {
|
|
|
11170
11321
|
if (ownField(key)) continue;
|
|
11171
11322
|
const value = readField(current, key);
|
|
11172
11323
|
const term = value === MISSING ? void 0 : termOrNothing(machine, value);
|
|
11173
|
-
if (term === void 0) linked.push([
|
|
11324
|
+
if (term === void 0) linked.push([
|
|
11325
|
+
key,
|
|
11326
|
+
value,
|
|
11327
|
+
true
|
|
11328
|
+
]);
|
|
11329
|
+
else if (wholeOf(shared, value, term)) linked.push([
|
|
11330
|
+
key,
|
|
11331
|
+
value,
|
|
11332
|
+
false
|
|
11333
|
+
]);
|
|
11174
11334
|
else fields.push([key, term]);
|
|
11175
11335
|
}
|
|
11176
11336
|
const node = {
|
|
@@ -11187,14 +11347,14 @@ function causeJson(machine, root) {
|
|
|
11187
11347
|
items.push(node);
|
|
11188
11348
|
const children = [];
|
|
11189
11349
|
for (let place = 0; place < linked.length; place += 1) {
|
|
11190
|
-
const [key, value] = linked[place];
|
|
11350
|
+
const [key, value, without] = linked[place];
|
|
11191
11351
|
const put = (part) => {
|
|
11192
11352
|
node.parts[place] = part;
|
|
11193
11353
|
};
|
|
11194
11354
|
children.push({
|
|
11195
11355
|
value,
|
|
11196
11356
|
name: key,
|
|
11197
|
-
tried:
|
|
11357
|
+
tried: without,
|
|
11198
11358
|
nest: true,
|
|
11199
11359
|
keep: false,
|
|
11200
11360
|
put
|
|
@@ -11225,7 +11385,7 @@ function causeJson(machine, root) {
|
|
|
11225
11385
|
value: current.cause,
|
|
11226
11386
|
name: "cause",
|
|
11227
11387
|
tried: false,
|
|
11228
|
-
nest:
|
|
11388
|
+
nest: true,
|
|
11229
11389
|
keep: false,
|
|
11230
11390
|
put
|
|
11231
11391
|
});
|
|
@@ -11237,7 +11397,7 @@ function causeJson(machine, root) {
|
|
|
11237
11397
|
tasks.push({
|
|
11238
11398
|
value: root,
|
|
11239
11399
|
name: "cause",
|
|
11240
|
-
tried
|
|
11400
|
+
tried,
|
|
11241
11401
|
nest: false,
|
|
11242
11402
|
keep: false,
|
|
11243
11403
|
put: (part) => {
|
|
@@ -11255,22 +11415,24 @@ function causeJson(machine, root) {
|
|
|
11255
11415
|
task.put({ loop });
|
|
11256
11416
|
continue;
|
|
11257
11417
|
}
|
|
11418
|
+
const container = Array.isArray(value) || isRecord(value);
|
|
11419
|
+
const held = container ? holders.get(value) : void 0;
|
|
11420
|
+
if (held !== void 0) {
|
|
11421
|
+
if (task.keep) items[held].keep = true;
|
|
11422
|
+
task.put({
|
|
11423
|
+
same: held,
|
|
11424
|
+
name: task.name
|
|
11425
|
+
});
|
|
11426
|
+
continue;
|
|
11427
|
+
}
|
|
11258
11428
|
const term = task.tried || task.keep ? void 0 : termOrNothing(machine, value);
|
|
11259
|
-
|
|
11429
|
+
const whole = term !== void 0 && wholeOf(shared, value, term);
|
|
11430
|
+
if (term !== void 0 && !whole) task.put({ value: term });
|
|
11260
11431
|
else if (value instanceof Error) task.put({ node: open(value) });
|
|
11261
|
-
else if (
|
|
11262
|
-
const
|
|
11263
|
-
|
|
11264
|
-
|
|
11265
|
-
task.put({ holder: hold(task.name, value, task.keep, children) });
|
|
11266
|
-
later(children);
|
|
11267
|
-
} else {
|
|
11268
|
-
if (task.keep) items[held].keep = true;
|
|
11269
|
-
task.put({
|
|
11270
|
-
same: held,
|
|
11271
|
-
name: task.name
|
|
11272
|
-
});
|
|
11273
|
-
}
|
|
11432
|
+
else if (container && (whole || task.nest || holdsException(value))) {
|
|
11433
|
+
const children = [];
|
|
11434
|
+
task.put({ holder: hold(task.name, value, task.keep || whole, children) });
|
|
11435
|
+
later(children);
|
|
11274
11436
|
} else task.put({ none: task.name });
|
|
11275
11437
|
}
|
|
11276
11438
|
const { formed, shares } = formsOf(items);
|
|
@@ -11394,20 +11556,25 @@ function errorJson(machine, error, what) {
|
|
|
11394
11556
|
};
|
|
11395
11557
|
if (!Object.hasOwn(error, "cause")) return base;
|
|
11396
11558
|
const cause = error.cause;
|
|
11559
|
+
const shared = sharedOf(cause);
|
|
11560
|
+
let term;
|
|
11561
|
+
let failure;
|
|
11397
11562
|
try {
|
|
11398
|
-
|
|
11399
|
-
|
|
11400
|
-
|
|
11401
|
-
};
|
|
11402
|
-
} catch (failure) {
|
|
11403
|
-
const { link, names } = causeJson(machine, cause);
|
|
11404
|
-
if (link === void 0) throw new TypeError(`encodeLog cannot write the cause of ${what()}: ${messageOf(failure)}`);
|
|
11405
|
-
return {
|
|
11406
|
-
...base,
|
|
11407
|
-
...link,
|
|
11408
|
-
...names.length === 0 ? {} : { dropped: names }
|
|
11409
|
-
};
|
|
11563
|
+
term = encodeValue(machine, cause);
|
|
11564
|
+
} catch (thrown) {
|
|
11565
|
+
failure = thrown;
|
|
11410
11566
|
}
|
|
11567
|
+
if (term !== void 0 && !wholeOf(shared, cause, term)) return {
|
|
11568
|
+
...base,
|
|
11569
|
+
cause: term
|
|
11570
|
+
};
|
|
11571
|
+
const { link, names } = causeJson(machine, cause, shared, term === void 0);
|
|
11572
|
+
if (link === void 0) throw new TypeError(`encodeLog cannot write the cause of ${what()}: ${messageOf(failure)}`);
|
|
11573
|
+
return {
|
|
11574
|
+
...base,
|
|
11575
|
+
...link,
|
|
11576
|
+
...names.length === 0 ? {} : { dropped: names }
|
|
11577
|
+
};
|
|
11411
11578
|
}
|
|
11412
11579
|
/**
|
|
11413
11580
|
* This function writes a log as JSON (RUN.REPLAY-JSON, D75). Then `JSON.stringify` gives the text of a golden file.
|
|
@@ -11424,8 +11591,12 @@ function errorJson(machine, error, what) {
|
|
|
11424
11591
|
* (RUN.REPLAY-FIELDS, D78, D82). An item of a list without a form is the mark `dropped` at its place.
|
|
11425
11592
|
* - A cause without a term document that is a list or a plain record with an exception is in `causeParts`
|
|
11426
11593
|
* (RUN.REPLAY-CAUSE-PARTS, D87). The rule is the same for the cause of an exception and of an error value.
|
|
11594
|
+
* - The cause of an exception is also in `causeParts` without an exception in it, when an item has a form
|
|
11595
|
+
* (RUN.REPLAY-CAUSE-ITEMS, D100). Each item without a form is a name in `dropped`, for example `cause.send`.
|
|
11427
11596
|
* - A list or a record of parts that an earlier place of one error holds is the part `share` with its index
|
|
11428
11597
|
* (RUN.REPLAY-SHARED, D88). This rule also covers a container that holds itself.
|
|
11598
|
+
* - A list or a plain record with a term document that two places of one error share is a container of parts
|
|
11599
|
+
* (RUN.REPLAY-SHARED-VALUES, D101). Each later place is a share. A member of a domain stays a term document.
|
|
11429
11600
|
* - An outcome that the log does not have stays absent.
|
|
11430
11601
|
*
|
|
11431
11602
|
* @param machine - The machine of the run, or only its domains.
|
|
@@ -11856,8 +12027,7 @@ function decodeLog(machine, data) {
|
|
|
11856
12027
|
settles
|
|
11857
12028
|
});
|
|
11858
12029
|
}
|
|
11859
|
-
|
|
11860
|
-
//#region src/agree.ts
|
|
12030
|
+
// src/agree.ts
|
|
11861
12031
|
/** The tiers that `agree` compares when its options name none. */
|
|
11862
12032
|
const DEFAULT_TIERS = /* @__PURE__ */ Object.freeze([
|
|
11863
12033
|
"reference",
|
|
@@ -12330,8 +12500,7 @@ async function agreeRun(machine, doc, context = makeContext(), options = {}) {
|
|
|
12330
12500
|
reads: compared
|
|
12331
12501
|
};
|
|
12332
12502
|
}
|
|
12333
|
-
|
|
12334
|
-
//#region src/generate.ts
|
|
12503
|
+
// src/generate.ts
|
|
12335
12504
|
/**
|
|
12336
12505
|
* This function makes a source of random numbers with a seed (the algorithm mulberry32). It needs no package.
|
|
12337
12506
|
*
|
|
@@ -12733,8 +12902,7 @@ function generate(world, options) {
|
|
|
12733
12902
|
hint: void 0
|
|
12734
12903
|
});
|
|
12735
12904
|
}
|
|
12736
|
-
|
|
12737
|
-
//#region src/conform.ts
|
|
12905
|
+
// src/conform.ts
|
|
12738
12906
|
/** The order of the obligations in the list of findings. */
|
|
12739
12907
|
const ORDER = [
|
|
12740
12908
|
"C1",
|
|
@@ -12747,7 +12915,8 @@ const ORDER = [
|
|
|
12747
12915
|
"C8",
|
|
12748
12916
|
"local",
|
|
12749
12917
|
"agree",
|
|
12750
|
-
"truth"
|
|
12918
|
+
"truth",
|
|
12919
|
+
"cover"
|
|
12751
12920
|
];
|
|
12752
12921
|
/** A function in the results of the probe parts. It gives the count of its arguments. */
|
|
12753
12922
|
const PROBE_FN = (...args) => args.length;
|
|
@@ -13627,7 +13796,8 @@ function examine(env, sample, contract) {
|
|
|
13627
13796
|
/**
|
|
13628
13797
|
* This function checks the declared truth of a profile (D86). The function `truthy` must give `true` or `false` for
|
|
13629
13798
|
* each member of `truthType`, and it must not throw. The members come from the lists `values` of the domains of the
|
|
13630
|
-
* type. A type without such a list gets
|
|
13799
|
+
* type. A type without such a list gets its members from the results of the palette and from the samples of the
|
|
13800
|
+
* domains (D99).
|
|
13631
13801
|
*/
|
|
13632
13802
|
function checkTruth(env, code, probe) {
|
|
13633
13803
|
const truth = declaredTruthOf(code);
|
|
@@ -13650,6 +13820,21 @@ function checkTruth(env, code, probe) {
|
|
|
13650
13820
|
}
|
|
13651
13821
|
}
|
|
13652
13822
|
/**
|
|
13823
|
+
* This function checks the covers of the domains of the machine from samples (D94). Each sample of a covered domain
|
|
13824
|
+
* must be in one domain of each valid cover. The samples of a domain come from its list `values`. A domain without
|
|
13825
|
+
* that list gets its members from the palette and from the samples of the domains, as for the check `truth`.
|
|
13826
|
+
*/
|
|
13827
|
+
function checkCovers(env, probe) {
|
|
13828
|
+
const domains = env.machine.domains;
|
|
13829
|
+
if (domains === void 0) return;
|
|
13830
|
+
const palette = env.results.flatMap((result) => result.ok ? [result.value] : []);
|
|
13831
|
+
const samples = {};
|
|
13832
|
+
for (const [name, domain] of Object.entries(domains)) if (domain.covers !== void 0) samples[name] = membersOf(name, domains, palette);
|
|
13833
|
+
const found = falseCovers(domains, samples)[0];
|
|
13834
|
+
if (found === void 0) return;
|
|
13835
|
+
report(env, "cover", `The member ${valueText(found.value)} of the domain ${found.domain} is in no domain of its cover ${found.cover.join(", ")}. The check of types trusts the cover, thus it is unsound for ${found.domain}.`, () => probe(found.value));
|
|
13836
|
+
}
|
|
13837
|
+
/**
|
|
13653
13838
|
* This function examines one evaluator or runner of a machine against the obligations of host code (K92, D36). It
|
|
13654
13839
|
* starts the code directly, without the kernel, with probe parts and a probe runtime. It generates probe documents from
|
|
13655
13840
|
* the contract of each kind that names the code, and it gives the probe parts chosen and random results.
|
|
@@ -13659,7 +13844,8 @@ function checkTruth(env, code, probe) {
|
|
|
13659
13844
|
* compiled code with its definition. The finding of an obligation names the first probe that breaks it. An empty list
|
|
13660
13845
|
* means that each probe conforms.
|
|
13661
13846
|
*
|
|
13662
|
-
* The check `truth` tests the declared truth of a formula profile (D86).
|
|
13847
|
+
* The check `truth` tests the declared truth of a formula profile (D86). The check `cover` tests the covers of the
|
|
13848
|
+
* domains of the machine from samples (D94).
|
|
13663
13849
|
*
|
|
13664
13850
|
* @param machine - The machine with the code and the world of the kinds.
|
|
13665
13851
|
* @param name - The name of the evaluator or of the runner. A runner wins over an evaluator of the same name.
|
|
@@ -13702,7 +13888,7 @@ function conforms(machine, name, options = {}) {
|
|
|
13702
13888
|
examine(env, sample, contract);
|
|
13703
13889
|
}
|
|
13704
13890
|
}
|
|
13705
|
-
|
|
13891
|
+
const probeWith = (value) => first === void 0 ? {
|
|
13706
13892
|
type: typeName(types[0]),
|
|
13707
13893
|
doc: {
|
|
13708
13894
|
type: types[0],
|
|
@@ -13717,11 +13903,12 @@ function conforms(machine, name, options = {}) {
|
|
|
13717
13903
|
waits: [],
|
|
13718
13904
|
caps: NO_CAPS,
|
|
13719
13905
|
running: runner
|
|
13720
|
-
})
|
|
13906
|
+
});
|
|
13907
|
+
checkTruth(env, code, probeWith);
|
|
13908
|
+
checkCovers(env, probeWith);
|
|
13721
13909
|
return ORDER.filter((obligation) => env.found.has(obligation)).map((obligation) => env.found.get(obligation));
|
|
13722
13910
|
}
|
|
13723
|
-
|
|
13724
|
-
//#region src/same.ts
|
|
13911
|
+
// src/same.ts
|
|
13725
13912
|
/**
|
|
13726
13913
|
* This function tells if two results are the same for an early cutoff (RESULT.SAME). A schedule uses it to stop the
|
|
13727
13914
|
* work when a part that evaluates again gives the same result. A wrong `true` keeps a stale value, but a wrong `false`
|
|
@@ -13757,8 +13944,7 @@ function sameError(a, b) {
|
|
|
13757
13944
|
if (a.place === void 0 || b.place === void 0) return a.place === b.place;
|
|
13758
13945
|
return docEquals(a.place, b.place);
|
|
13759
13946
|
}
|
|
13760
|
-
|
|
13761
|
-
//#region src/reads.ts
|
|
13947
|
+
// src/reads.ts
|
|
13762
13948
|
/** One answer serves each list whose reads are all the same. */
|
|
13763
13949
|
const SAME = /* @__PURE__ */ Object.freeze({ same: true });
|
|
13764
13950
|
/** This function tells if two lists of hops are the same: the same steps, rungs and things, in order. */
|
|
@@ -13849,8 +14035,7 @@ function verifyReads(target, reads, context, options = {}) {
|
|
|
13849
14035
|
}
|
|
13850
14036
|
return SAME;
|
|
13851
14037
|
}
|
|
13852
|
-
|
|
13853
|
-
//#region src/durable.ts
|
|
14038
|
+
// src/durable.ts
|
|
13854
14039
|
/** The most values that a cache of value documents keeps, as in `planner`. */
|
|
13855
14040
|
const MAX_VALUES = 1e3;
|
|
13856
14041
|
/** No reads. One frozen list serves each result of a pure document without reads. */
|
|
@@ -13990,8 +14175,7 @@ function durable(machine, options = {}) {
|
|
|
13990
14175
|
}
|
|
13991
14176
|
};
|
|
13992
14177
|
}
|
|
13993
|
-
|
|
13994
|
-
//#region src/graph.ts
|
|
14178
|
+
// src/graph.ts
|
|
13995
14179
|
/** This function gives the indexed form of a graph, with the edges that the options keep. */
|
|
13996
14180
|
function indexed(graph, options) {
|
|
13997
14181
|
const eager = options.eager === true;
|
|
@@ -14321,8 +14505,7 @@ function deepestFirst(from, edgesOf) {
|
|
|
14321
14505
|
}
|
|
14322
14506
|
return out;
|
|
14323
14507
|
}
|
|
14324
|
-
|
|
14325
|
-
//#region src/schedule.ts
|
|
14508
|
+
// src/schedule.ts
|
|
14326
14509
|
/**
|
|
14327
14510
|
* This function gives the edges of a node from the static facts of its document (SCHED.EDGES). Each read of the root
|
|
14328
14511
|
* `world` is an edge to the node of its first key. The keys after that key are the field of the edge (SCHED.GRAIN).
|
|
@@ -14616,8 +14799,7 @@ function schedule(machine, options = {}) {
|
|
|
14616
14799
|
}
|
|
14617
14800
|
};
|
|
14618
14801
|
}
|
|
14619
|
-
|
|
14620
|
-
//#region src/meaning.ts
|
|
14802
|
+
// src/meaning.ts
|
|
14621
14803
|
/** A list of eight reference types. The generator then gives more references, thus more reads of nodes. */
|
|
14622
14804
|
function moreRefs() {
|
|
14623
14805
|
return Array.from({ length: 8 }, () => ["ref"]);
|
|
@@ -15016,8 +15198,7 @@ function agreeSchedule(engine, options = {}) {
|
|
|
15016
15198
|
counts
|
|
15017
15199
|
};
|
|
15018
15200
|
}
|
|
15019
|
-
|
|
15020
|
-
//#region src/providers.ts
|
|
15201
|
+
// src/providers.ts
|
|
15021
15202
|
/** The deepest schema that `typeFromSchema` reads. A deeper schema reads as `unknown`. */
|
|
15022
15203
|
const MAX_SCHEMA_DEPTH = 256;
|
|
15023
15204
|
/** The keywords that describe a schema and do not test a value. The reading ignores them without an issue. */
|
|
@@ -15326,7 +15507,6 @@ function samplesAt(values, closed, depth) {
|
|
|
15326
15507
|
function typeFromSamples(values, options = {}) {
|
|
15327
15508
|
return samplesAt(values, options.closed === true, 0);
|
|
15328
15509
|
}
|
|
15329
|
-
//#endregion
|
|
15330
15510
|
export { ATTRIBUTE_RUNGS, CAPS_TYPE, CONSTRUCTS, ENVELOPE_KEYS, Failure, Held, JOURNAL, MergeError, PARTS, PART_INFO, ROOTS, RUNGS, STD_CAPS, STD_DEFINITIONS, STD_DOMAINS, STD_EVALUATORS, STD_EXT, STD_MACHINE, STD_RUNNERS, STD_SYNTAX, STD_WALKERS, STD_WORLD, THING, WORLD_SYNTAX, agree, agreeRun, agreeSchedule, ask, attributeTrace, capKeys, check, checkLatent, checkSteps, checkWorld, classify, components, conforms, context, cycles, dataEdges, decodeDomain, decodeLog, decodeValue, derefStep, describe, docEquals, durable, edgesOf, effectEdges, effectsOf, effectsOfVerb, encodeLog, encodeValue, entriesAsJson, equationType, evaluate, extendDomain, factsOf, fail, failures, field, fits, flatten, formulaDefinitions, formulaEvaluators, formulaFacts, formulaKinds, formulaKnown, formulaMachine, fromJson, generate, heights, intersectCaps, isAlias, isAllowedOrder, isClosure, isEnvelope, isHostThing, isKey, isKind, isNamespace, isRecord, isRef, isStackOverflow, isTypeRef, join, jsTruthy, kindDocument, kindNamed, kindOf, layers, looksLikeKind, lookupKind, makeContext, mapRefs, member, mergeMachines, mergeWorlds, narrow, nearestWalker, necessary, nodeAt, nodeLayers, ok, parse, partCaps, partsOf, pathMatches, permits, placeOf, placed, planner, prepare, print, random, recorder, ref, reference, referenceRun, refsOf, replayer, resolve, restrictMachine, restrictWorld, run, sameResult, sameValue, schedule, splitParts, stored, syntaxFormat, tag, thrown, toJson, typeCheck, typeFromSamples, typeFromSchema, typeIssues, typeName, typePath, typeText, typed, typesOf, valueOfThing, verifyReads, walk, worldThing };
|
|
15331
15511
|
|
|
15332
15512
|
//# sourceMappingURL=index.js.map
|