@mark1russell7/coeval 0.24.0 → 0.25.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.js CHANGED
@@ -1353,6 +1353,61 @@ function narrowAt(type, path, at, narrowed, domains) {
1353
1353
  ...form.closed ? { closed: true } : {}
1354
1354
  };
1355
1355
  }
1356
+ /** This function gives the type of a value that is a member of both types. The result is the narrower known type. */
1357
+ function meetOf(type, proved, domains) {
1358
+ if (isUnknown(proved, domains)) return type;
1359
+ const form = formOf(type, domains);
1360
+ if (form.t === "one") return { one: form.values.filter((value) => member(value, proved, domains)) };
1361
+ return !isUnknown(type, domains) && isPrecise(type, domains) && fits(type, proved, domains) ? type : proved;
1362
+ }
1363
+ /** This function gives the type of a value of the first type that is not a member of the second type. */
1364
+ function withoutOf(type, removed, domains) {
1365
+ if (isUnknown(removed, domains)) return type;
1366
+ const form = formOf(type, domains);
1367
+ if (form.t === "one") return { one: form.values.filter((value) => !member(value, removed, domains)) };
1368
+ if (form.t === "union") {
1369
+ const members = form.members.map((each) => withoutOf(each, removed, domains)).filter((each) => each !== "never");
1370
+ return members.length === 0 ? "never" : members.length === 1 ? members[0] : { union: members };
1371
+ }
1372
+ return isPrecise(type, domains) && fits(type, removed, domains) ? "never" : type;
1373
+ }
1374
+ /**
1375
+ * This function gives a type with one proof at a path (STATIC.OCCURRENCE). A path that leaves the records of the type
1376
+ * gives the type back. A fact about a field also tells if the field exists. A value of a type without `undefined`
1377
+ * exists. An optional field without a remaining type does not.
1378
+ *
1379
+ * @param type - The type of the value at the first `at` keys of the path.
1380
+ * @param proof - The proof.
1381
+ * @param at - The number of keys of the path that the type already holds.
1382
+ * @param domains - The domains of the machine.
1383
+ * @returns The narrowed type.
1384
+ */
1385
+ function narrowType(type, proof, at, domains) {
1386
+ if (at === proof.path.length) {
1387
+ if (proof.fact === "is") return meetOf(type, proof.type, domains);
1388
+ return proof.fact === "not" ? withoutOf(type, proof.type, domains) : type;
1389
+ }
1390
+ const form = formOf(type, domains);
1391
+ const key = proof.path[at];
1392
+ if (form.t !== "record" || !Object.hasOwn(form.fields, key)) return type;
1393
+ const before = form.fields[key];
1394
+ const optional = new Set(form.optional);
1395
+ let after = narrowType(before, proof, at + 1, domains);
1396
+ if (at + 1 === proof.path.length && optional.has(key)) {
1397
+ if (proof.fact === "present" || proof.fact === "is" && !member(void 0, proof.type, domains)) optional.delete(key);
1398
+ else if (proof.fact === "absent" || after === "never") after = void 0;
1399
+ }
1400
+ const fields = {};
1401
+ for (const name of Object.keys(form.fields)) if (name !== key) setOwn$6(fields, name, form.fields[name]);
1402
+ if (after !== void 0) setOwn$6(fields, key, after);
1403
+ else if (form.closed) optional.delete(key);
1404
+ else setOwn$6(fields, key, "never");
1405
+ return {
1406
+ record: fields,
1407
+ ...optional.size === 0 ? {} : { optional: [...optional] },
1408
+ ...form.closed ? { closed: true } : {}
1409
+ };
1410
+ }
1356
1411
  /**
1357
1412
  * This function is the split rule of `fits` (TYPE.FITS-FINITE, D84, TYPE.FITS-PATH, D89). A record type fits when each
1358
1413
  * record of its split fits. A split takes the first field in the order of `splitsOf`. Each member of the field gives a
@@ -1568,7 +1623,7 @@ const MAX_TEXT_VALUES = 8;
1568
1623
  /** The most characters of one JSON value in the text of a type. */
1569
1624
  const MAX_TEXT_VALUE = 40;
1570
1625
  /** This function gives a short text of a JSON value for the text of a type. */
1571
- function valueText$1(value) {
1626
+ function valueText$2(value) {
1572
1627
  let text;
1573
1628
  try {
1574
1629
  text = JSON.stringify(value) ?? String(value);
@@ -1590,7 +1645,7 @@ function textAt(type, depth, wrap) {
1590
1645
  if (term === "one") {
1591
1646
  if (!Array.isArray(type["one"])) return "unknown";
1592
1647
  const values = type["one"];
1593
- const shown = values.slice(0, MAX_TEXT_VALUES).map(valueText$1);
1648
+ const shown = values.slice(0, MAX_TEXT_VALUES).map(valueText$2);
1594
1649
  return group(values.length > MAX_TEXT_VALUES ? [...shown, `… ${values.length - MAX_TEXT_VALUES} more`] : shown);
1595
1650
  }
1596
1651
  if (term === "fn") {
@@ -1882,6 +1937,12 @@ var MergeError = class extends Error {
1882
1937
  }
1883
1938
  };
1884
1939
  const NONE$2 = /* @__PURE__ */ new Set();
1940
+ /** The verbs that the kernel reads. Thus no language owns them (COMPOSE.PIRACY). */
1941
+ const KERNEL_VERBS = /* @__PURE__ */ new Set([
1942
+ "eval",
1943
+ "deref",
1944
+ "step"
1945
+ ]);
1885
1946
  function keyOf(path) {
1886
1947
  return JSON.stringify(path.map(String));
1887
1948
  }
@@ -2072,16 +2133,123 @@ function mergeEntry(m, earlier, later, path, part, replaces) {
2072
2133
  m.clash(path, part, a === b ? `Two parts give two different ${a === "an alias" ? "aliases" : "kinds"}.` : `One part gives ${a}, and the other part gives ${b}.`);
2073
2134
  return earlier;
2074
2135
  }
2075
- function worldOf(draft) {
2136
+ function worldDraft() {
2137
+ return {
2138
+ kinds: {},
2139
+ defaults: {},
2140
+ owners: /* @__PURE__ */ new Map(),
2141
+ entries: []
2142
+ };
2143
+ }
2144
+ /**
2145
+ * This function gives a copy of a table with a change to the kind at a path, as `replaces` names the path. It gives
2146
+ * `undefined` when no kind is at the path. An alias is not a kind.
2147
+ */
2148
+ function changeKind(table, path, change) {
2149
+ const [first, key, ...rest] = path;
2150
+ if (String(first) === "fallback" && key === void 0) return table.fallback === void 0 ? void 0 : {
2151
+ ...table,
2152
+ fallback: change(table.fallback)
2153
+ };
2154
+ if (String(first) !== "kinds" || key === void 0) return void 0;
2155
+ const entry = own$2(table.kinds, String(key));
2156
+ const next = rest.length === 0 ? isKind(entry) ? change(entry) : void 0 : isNamespace(entry) ? changeKind(entry, rest, change) : void 0;
2157
+ if (next === void 0) return void 0;
2158
+ const kinds = { ...table.kinds };
2159
+ setOwn$5(kinds, String(key), next);
2160
+ return {
2161
+ ...table,
2162
+ kinds
2163
+ };
2164
+ }
2165
+ /**
2166
+ * This function adds the entries of `extends` to the kinds of a draft. A later part can give the kind, thus this step
2167
+ * reads the whole draft. Without `m`, it reports no conflict: a function part sees the entries of the parts before it.
2168
+ */
2169
+ function addVerbs(draft, m) {
2170
+ let table = draft.fallback === void 0 ? { kinds: draft.kinds } : {
2171
+ kinds: draft.kinds,
2172
+ fallback: draft.fallback
2173
+ };
2174
+ for (const entry of draft.entries) {
2175
+ if (!entry.allowed && !entry.replaced) {
2176
+ m?.clash(entry.path, entry.part, "A part adds a verb that it does not own to a kind that it does not give.");
2177
+ continue;
2178
+ }
2179
+ const next = changeKind(table, entry.kind, (kind) => {
2180
+ const verbs = { ...kind.verbs };
2181
+ const earlier = own$2(verbs, entry.verb);
2182
+ if (earlier === void 0) m?.give(entry.path, entry.part);
2183
+ else if (entry.replaced) m?.replace(entry.path, entry.part);
2184
+ else if (earlier !== entry.code) m?.clash(entry.path, entry.part, "Two parts give two different evaluators for this verb of this kind.");
2185
+ if (earlier === void 0 || entry.replaced) setOwn$5(verbs, entry.verb, entry.code);
2186
+ return {
2187
+ ...kind,
2188
+ verbs
2189
+ };
2190
+ });
2191
+ if (next !== void 0) table = next;
2192
+ else if (!entry.replaced) m?.clash(entry.path, entry.part, "A part adds a verb to a path without a kind.");
2193
+ }
2194
+ return table;
2195
+ }
2196
+ function worldOf(draft, m) {
2197
+ const table = addVerbs(draft, m);
2076
2198
  const world = {
2077
- kinds: { ...draft.kinds },
2199
+ kinds: { ...table.kinds },
2078
2200
  defaults: { ...draft.defaults }
2079
2201
  };
2080
- return draft.fallback === void 0 ? world : {
2202
+ return table.fallback === void 0 ? world : {
2081
2203
  ...world,
2082
- fallback: draft.fallback
2204
+ fallback: table.fallback
2083
2205
  };
2084
2206
  }
2207
+ /** This function records the verbs that a part owns, and the entries that it adds to kinds. */
2208
+ function mergeVerbs(m, draft, part, index, replaces, base) {
2209
+ const owned = part.verbs ?? [];
2210
+ for (const verb of owned) {
2211
+ const path = [
2212
+ ...base,
2213
+ "verbs",
2214
+ verb
2215
+ ];
2216
+ const owner = draft.owners.get(verb);
2217
+ if (replaces.has(keyOf(path))) {
2218
+ draft.owners.set(verb, part);
2219
+ m.replace(path, index);
2220
+ } else if (KERNEL_VERBS.has(verb)) m.clash(path, index, "The kernel owns this verb.");
2221
+ else if (owner === void 0) {
2222
+ draft.owners.set(verb, part);
2223
+ m.give(path, index);
2224
+ } else if (!same(owner, part)) m.clash(path, index, "Two parts own this verb.");
2225
+ }
2226
+ const table = part.fallback === void 0 ? { kinds: part.kinds ?? {} } : {
2227
+ kinds: part.kinds ?? {},
2228
+ fallback: part.fallback
2229
+ };
2230
+ for (const { kind, verbs } of part.extends ?? []) {
2231
+ const gives = changeKind(table, kind, (found) => found) !== void 0;
2232
+ for (const verb of Object.keys(verbs)) {
2233
+ const code = verbs[verb];
2234
+ if (code === void 0) continue;
2235
+ const path = [
2236
+ ...base,
2237
+ ...kind,
2238
+ "verbs",
2239
+ verb
2240
+ ];
2241
+ draft.entries.push({
2242
+ kind,
2243
+ verb,
2244
+ code,
2245
+ path,
2246
+ part: index,
2247
+ allowed: gives || owned.includes(verb),
2248
+ replaced: replaces.has(keyOf(path))
2249
+ });
2250
+ }
2251
+ }
2252
+ }
2085
2253
  function mergeWorldInto(m, draft, part, index, replaces, base) {
2086
2254
  if (part === void 0) return;
2087
2255
  if (part.kinds !== void 0) mergeEntries(m, draft.kinds, part.kinds, [...base, "kinds"], index, replaces);
@@ -2093,6 +2261,7 @@ function mergeWorldInto(m, draft, part, index, replaces, base) {
2093
2261
  ], index, replaces, Object.is, "Two parts give two different defaults for this verb.");
2094
2262
  const fallback = mergeFallback(m, draft.fallback, part.fallback, [...base, "fallback"], index, replaces);
2095
2263
  if (fallback !== void 0) draft.fallback = fallback;
2264
+ mergeVerbs(m, draft, part, index, replaces, base);
2096
2265
  }
2097
2266
  /**
2098
2267
  * This function merges worlds into one world, in the order of the parts. It does not change a part.
@@ -2102,6 +2271,8 @@ function mergeWorldInto(m, draft, part, index, replaces, base) {
2102
2271
  * - The defaults merge verb by verb, and the world keeps one fallback.
2103
2272
  * - Each other pair of entries at one path is a conflict, unless the later part names the path in `replaces`.
2104
2273
  * Then the later entry wins, with no merge below it.
2274
+ * - The entries of `extends` join their kinds after each part, thus the order of the parts does not change them. A
2275
+ * verb that a part does not own on a kind that it does not give is a conflict (COMPOSE.PIRACY).
2105
2276
  *
2106
2277
  * A part can be a function of the merge of the parts before it (`prev`, as an overlay of Nix). Thus a part can read
2107
2278
  * the entry that it replaces.
@@ -2112,16 +2283,14 @@ function mergeWorldInto(m, draft, part, index, replaces, base) {
2112
2283
  */
2113
2284
  function mergeWorlds(...parts) {
2114
2285
  const m = new Merger();
2115
- const draft = {
2116
- kinds: {},
2117
- defaults: {}
2118
- };
2286
+ const draft = worldDraft();
2119
2287
  parts.forEach((input, index) => {
2120
2288
  const part = typeof input === "function" ? input(worldOf(draft)) : input;
2121
2289
  mergeWorldInto(m, draft, part, index, new Set((part.replaces ?? []).map(keyOf)), []);
2122
2290
  });
2291
+ const world = worldOf(draft, m);
2123
2292
  if (m.conflicts.length > 0) throw new MergeError(m.conflicts);
2124
- return worldOf(draft);
2293
+ return world;
2125
2294
  }
2126
2295
  /** The fields of a machine that merge by their own rules. Each other field is one value, or a conflict. */
2127
2296
  const TABLES = /* @__PURE__ */ new Set([
@@ -2174,12 +2343,12 @@ function composeFacts(hooks, replaced) {
2174
2343
  }
2175
2344
  };
2176
2345
  }
2177
- function machineOf(draft) {
2346
+ function machineOf(draft, m) {
2178
2347
  const known = composeKnown(draft.hooks, draft.replaced);
2179
2348
  const facts = composeFacts(draft.factHooks, draft.replaced);
2180
2349
  return {
2181
2350
  ...draft.rest,
2182
- world: worldOf(draft.world),
2351
+ world: worldOf(draft.world, m),
2183
2352
  evaluators: { ...draft.evaluators },
2184
2353
  ...draft.runners === void 0 ? {} : { runners: { ...draft.runners } },
2185
2354
  ...draft.derefs === void 0 ? {} : { derefs: { ...draft.derefs } },
@@ -2253,10 +2422,7 @@ function checkHidden(m, draft) {
2253
2422
  function mergeMachines(...parts) {
2254
2423
  const m = new Merger();
2255
2424
  const draft = {
2256
- world: {
2257
- kinds: {},
2258
- defaults: {}
2259
- },
2425
+ world: worldDraft(),
2260
2426
  evaluators: {},
2261
2427
  hooks: [],
2262
2428
  factHooks: [],
@@ -2297,8 +2463,9 @@ function mergeMachines(...parts) {
2297
2463
  }
2298
2464
  });
2299
2465
  checkHidden(m, draft);
2466
+ const machine = machineOf(draft, m);
2300
2467
  if (m.conflicts.length > 0) throw new MergeError(m.conflicts);
2301
- return machineOf(draft);
2468
+ return machine;
2302
2469
  }
2303
2470
  /** This function removes the entry at a path from a table of entries. It gives the same table when no entry is there. */
2304
2471
  function removeEntry(entries, path) {
@@ -4812,7 +4979,8 @@ function compileNode(c, value, place, declared, depth, address = false) {
4812
4979
  } catch (error) {
4813
4980
  return failingWith(c, meta, placed(thrown(error, `the runner ${name}`), place));
4814
4981
  }
4815
- const run = placedRun(inner, place, name);
4982
+ const guard = guardOf(c, place);
4983
+ const run = placedRun(guard === void 0 ? inner : guardRun(inner, guard, c.machine.domains), place, name);
4816
4984
  return finish$1(c, meta, runnerCode(run, place, kindText), run);
4817
4985
  }
4818
4986
  let inner;
@@ -4821,7 +4989,8 @@ function compileNode(c, value, place, declared, depth, address = false) {
4821
4989
  } catch (error) {
4822
4990
  return failingWith(c, meta, placed(thrown(error, `the evaluator ${name}`), place));
4823
4991
  }
4824
- const done = finish$1(c, meta, TOTAL.has(inner) ? inner : placedCode(inner, place, name), void 0);
4992
+ const guard = guardOf(c, place);
4993
+ const done = finish$1(c, meta, guard !== void 0 ? placedCode(guardCode(inner, guard, c.machine.domains), place, name) : TOTAL.has(inner) ? inner : placedCode(inner, place, name), void 0);
4825
4994
  if (frees === void 0 || kind === void 0 || !pureCode(c, envelope, kind, typePath, name, quick)) return done;
4826
4995
  const free = freeOf(doc, kind, split.parts, frees);
4827
4996
  if (free === void 0) return done;
@@ -5217,6 +5386,29 @@ function gated(rules, part) {
5217
5386
  * This function gives the steps of a runner, with the place of each error and of each exception. The steps get the
5218
5387
  * context that its grant permits (CAP.NARROW-CODE).
5219
5388
  */
5389
+ /** This function gives the key of a place in the guards of a plan. */
5390
+ function guardKey(place) {
5391
+ return JSON.stringify(place.map(String));
5392
+ }
5393
+ /** This function gives the type of the boundary at a place, when the plan has one (PLAN.GUARD). */
5394
+ function guardOf(c, place) {
5395
+ return c.guards?.get(guardKey(place));
5396
+ }
5397
+ /** This function gives the result of a part of a boundary: a value that is not a member gives `#VALUE!` (PLAN.GUARD). */
5398
+ function guarded(result, type, domains) {
5399
+ if (!result.ok || member(result.value, type, domains)) return result;
5400
+ return fail("#VALUE!", `The value is not a member of ${typeText(type)}, the type of its boundary.`);
5401
+ }
5402
+ /** This function adds the test of a boundary to the code of a part. */
5403
+ function guardCode(inner, type, domains) {
5404
+ return (ctx, rt) => guarded(inner(ctx, rt), type, domains);
5405
+ }
5406
+ /** This function adds the test of a boundary to the steps of a part. */
5407
+ function guardRun(inner, type, domains) {
5408
+ return function* (ctx, rt) {
5409
+ return guarded(yield* inner(ctx, rt), type, domains);
5410
+ };
5411
+ }
5220
5412
  function placedRun(inner, place, name) {
5221
5413
  return function* (ctx, rt) {
5222
5414
  try {
@@ -5417,6 +5609,7 @@ function prepare(machine, doc, options = {}) {
5417
5609
  const traced = options.trace === true;
5418
5610
  const fold = !traced && options.fold !== false;
5419
5611
  const fixed = fold ? fixedNamesOf(options.fixed?.names) : void 0;
5612
+ const guards = options.guards === void 0 || options.guards.length === 0 ? void 0 : new Map(options.guards.map((each) => [guardKey(each.place), each.type]));
5420
5613
  const c = {
5421
5614
  machine,
5422
5615
  traced,
@@ -5424,7 +5617,8 @@ function prepare(machine, doc, options = {}) {
5424
5617
  verb,
5425
5618
  noAnswer,
5426
5619
  fold,
5427
- fixed
5620
+ fixed,
5621
+ guards
5428
5622
  };
5429
5623
  let root;
5430
5624
  try {
@@ -5537,7 +5731,8 @@ function evaluate(machine, doc, context = makeContext(), options) {
5537
5731
  const plan = prepare(machine, doc, {
5538
5732
  trace: true,
5539
5733
  ...declaredType === void 0 ? {} : { declaredType },
5540
- ...given.verb === void 0 ? {} : { verb: given.verb }
5734
+ ...given.verb === void 0 ? {} : { verb: given.verb },
5735
+ ...given.guards === void 0 ? {} : { guards: given.guards }
5541
5736
  });
5542
5737
  const ctx = rootContext(machine, context);
5543
5738
  const s = new Session(machine, ctx.caps, false, true, given.perform, void 0, void 0, readingOf(given.reads, ctx));
@@ -5558,6 +5753,7 @@ async function run(machine, doc, context = makeContext(), options = {}) {
5558
5753
  const plan = prepare(machine, doc, {
5559
5754
  trace: true,
5560
5755
  ...options.declaredType === void 0 ? {} : { declaredType: options.declaredType },
5756
+ ...options.guards === void 0 ? {} : { guards: options.guards },
5561
5757
  ...options.verb === void 0 ? {} : { verb: options.verb }
5562
5758
  });
5563
5759
  const ctx = rootContext(machine, context);
@@ -5928,7 +6124,8 @@ const STD_WORLD = {
5928
6124
  * A literal in a place that takes a document gets its data envelope (K159, D65). Such a place is a part of `if`,
5929
6125
  * `list`, `seq` or `pure`, the value of `write`, or the whole text. The document after a header name is such a place
5930
6126
  * too. Thus `list(1, "a")` evaluates to `[1, "a"]`. The forms `add`, `multiply` and `greater` write an operator document that its operator
5931
- * does not write, for example `add(5)` (K163).
6127
+ * does not write, for example `add(5)` (K163). The field `with` of `handle` is a field of data, thus each clause is a
6128
+ * record between braces in a list between brackets (D177).
5932
6129
  *
5933
6130
  * A host with more kinds spreads this profile and adds its forms to `calls.forms`. `STD_SYNTAX` stays the profile of
5934
6131
  * the formula kit.
@@ -6068,6 +6265,18 @@ const WORLD_SYNTAX = /* @__PURE__ */ Object.freeze({
6068
6265
  kind: "tree.quote",
6069
6266
  args: "literal"
6070
6267
  },
6268
+ {
6269
+ name: "handle",
6270
+ kind: "handle",
6271
+ args: "named",
6272
+ fields: [
6273
+ "with",
6274
+ "return",
6275
+ "body"
6276
+ ],
6277
+ data: ["with"],
6278
+ wrap: ["return", "body"]
6279
+ },
6071
6280
  {
6072
6281
  name: "add",
6073
6282
  kind: "add"
@@ -6135,11 +6344,17 @@ const STD_EVALUATORS = {
6135
6344
  const [a, b] = values;
6136
6345
  return ok((a ?? 0) > (b ?? 0));
6137
6346
  },
6138
- "ref.resolve": ({ data, resolve }) => {
6139
- if (!Array.isArray(data) || data.length === 0) return fail("#VALUE!", "The value of ref is a path: a list that starts with a root, for example [\"names\", \"a\"].");
6140
- const found = resolve(data);
6141
- return found.ok ? ok(valueOfThing(found.thing)) : fail(found.code, found.reason);
6142
- },
6347
+ "ref.resolve": { compile: ({ data, machine }) => {
6348
+ if (!Array.isArray(data) || data.length === 0) {
6349
+ const bad = fail("#VALUE!", "The value of ref is a path: a list that starts with a root, for example [\"names\", \"a\"].");
6350
+ return () => bad;
6351
+ }
6352
+ const path = compilePath(machine, data);
6353
+ return (ctx, rt) => {
6354
+ const found = resolveCompiled(rt, ctx, path);
6355
+ return found.ok ? ok(valueOfThing(found.thing)) : fail(found.code, found.reason);
6356
+ };
6357
+ } },
6143
6358
  "tree.node": (input) => treeNode(input, void 0)
6144
6359
  };
6145
6360
  /** The brand of a node of the decorated tree. Its value is the state that the kit reads. */
@@ -6524,6 +6739,7 @@ function leaderOnHost(n, key, rule, host) {
6524
6739
  /**
6525
6740
  * This function gives an attribute of a node with circular attributes, or an attribute in an open fixed point (D113).
6526
6741
  * The memo and the marks of the node do not hold the attribute. An open fixed point does not use the cells of the host.
6742
+ * With the cells of a host, only a circular attribute comes here outside a fixed point. A plain attribute takes its cell.
6527
6743
  */
6528
6744
  function circularRead(n, key) {
6529
6745
  const rule = circularRule(n.tree, key);
@@ -6938,7 +7154,7 @@ function treeThing(input, place, build, outer, host) {
6938
7154
  const text = attributeText(key, type, place);
6939
7155
  if (marks.has(key)) return busyAt(state, key);
6940
7156
  if (tree === void 0 && up?.tree === void 0 && !parts.some((item) => item.key === key)) return void 0;
6941
- if (circular || openPoint !== void 0) return circularRead(state, key);
7157
+ if (openPoint !== void 0 || circular && circularRule(tree, key) !== void 0) return circularRead(state, key);
6942
7158
  marks.set(key, BUSY);
6943
7159
  demands.push({
6944
7160
  cells: marks,
@@ -7270,6 +7486,26 @@ function isOp(value) {
7270
7486
  return typeof value === "string" || Array.isArray(value) && value.every(isKey);
7271
7487
  }
7272
7488
  /**
7489
+ * This function gives the runner of an `if` with its own truth (RUN.IF-TRUTH). A branch can wait for the host, thus a
7490
+ * language with the function `truthy` of a profile does not need a copy of `if`. A missing test and a test without a
7491
+ * truth give `#VALUE!`, a failed test gives its failure, and a missing branch gives `null`.
7492
+ *
7493
+ * @param truth - The function that gives the truth of a value, or `undefined` for a value without a truth.
7494
+ * @returns The runner.
7495
+ */
7496
+ function ifRunner(truth) {
7497
+ return function* ({ parts }) {
7498
+ const test = parts.find((part) => part.key === "test");
7499
+ if (test === void 0) return fail("#VALUE!", "if needs a test.");
7500
+ const chosen = yield* test.evaluate();
7501
+ if (!chosen.ok) return chosen;
7502
+ const held = truth(chosen.value);
7503
+ if (held === void 0) return fail("#VALUE!", "The test of if must give a truth value.");
7504
+ const branch = parts.find((part) => part.key === (held ? "then" : "else"));
7505
+ return branch === void 0 ? ok(null) : yield* branch.evaluate();
7506
+ };
7507
+ }
7508
+ /**
7273
7509
  * The runners of the standard world, by name: the kinds that can hold effects. Each one evaluates its parts in
7274
7510
  * order. In a run, an effect ends before the next step starts.
7275
7511
  */
@@ -7337,15 +7573,7 @@ const STD_RUNNERS = {
7337
7573
  }
7338
7574
  });
7339
7575
  },
7340
- "control.if": function* ({ parts }) {
7341
- const test = parts.find((part) => part.key === "test");
7342
- if (test === void 0) return fail("#VALUE!", "if needs a test.");
7343
- const chosen = yield* test.evaluate();
7344
- if (!chosen.ok) return chosen;
7345
- if (typeof chosen.value !== "boolean") return fail("#VALUE!", "The test of if must give a truth value.");
7346
- const branch = parts.find((part) => part.key === (chosen.value === true ? "then" : "else"));
7347
- return branch === void 0 ? ok(null) : yield* branch.evaluate();
7348
- },
7576
+ "control.if": /* @__PURE__ */ ifRunner((value) => typeof value === "boolean" ? value : void 0),
7349
7577
  "list.all": function* ({ parts }) {
7350
7578
  const all = yield* inOrder(parts);
7351
7579
  return "error" in all ? all.error : ok(all.values);
@@ -7768,6 +7996,31 @@ const CONSTRUCTS = [
7768
7996
  * narrows the capabilities for each part, thus the host does not give this type.
7769
7997
  */
7770
7998
  const CAPS_TYPE = { list: { union: ["text", { list: { union: ["text", "number"] } }] } };
7999
+ /**
8000
+ * This function gives the boundaries of a check. A part with an imprecise type at a position that needs a type is a
8001
+ * boundary. A read of a known type is a boundary too, because the check trusts the root types (PLAN.GUARD-BOUNDARY).
8002
+ *
8003
+ * @param typing - The places of a check of types.
8004
+ * @param domains - The domains of the machine.
8005
+ * @returns The boundaries, in the order of the document.
8006
+ */
8007
+ function boundariesOf(typing, domains) {
8008
+ const found = [];
8009
+ for (const item of typing.places) if (item.expected !== void 0 && item.expected !== "unknown" && !isPrecise(item.type, domains)) found.push({
8010
+ place: item.place,
8011
+ type: item.expected
8012
+ });
8013
+ else if (item.read === true && item.type !== "unknown") found.push({
8014
+ place: item.place,
8015
+ type: item.type
8016
+ });
8017
+ return found;
8018
+ }
8019
+ /** The result of a test that proves nothing. */
8020
+ const NO_PROOFS$1 = {
8021
+ yes: [],
8022
+ no: []
8023
+ };
7771
8024
  /** The roots that can change, as a rule gives them in `PartType.roots`. */
7772
8025
  const CHANGING = [
7773
8026
  "self",
@@ -7787,11 +8040,15 @@ function pathKey(path) {
7787
8040
  function ruleOf(machine, name) {
7788
8041
  if (name === void 0 || machine.runners !== void 0 && Object.hasOwn(machine.runners, name)) return void 0;
7789
8042
  const evaluator = Object.hasOwn(machine.evaluators, name) ? machine.evaluators[name] : void 0;
7790
- const rule = typeof evaluator === "object" && evaluator !== null ? evaluator.type : void 0;
8043
+ const rule = typeof evaluator === "object" && evaluator !== null || typeof evaluator === "function" ? evaluator.type : void 0;
7791
8044
  return typeof rule === "object" && rule !== null && typeof rule.synth === "function" ? rule : void 0;
7792
8045
  }
7793
- /** This function gives the order of the parts of a document: first the parts that give the names of a rule `keysAt`. */
7794
- function orderOf(node, nodes) {
8046
+ /** This function gives the order of the parts of a document. The part `first` of the rule comes first, or else the parts that give the names of a rule `keysAt`. */
8047
+ function orderOf(node, nodes, first) {
8048
+ if (first !== void 0) {
8049
+ const isFirst = (index) => String(nodes[index].visit.slot[0]) === first;
8050
+ return [...node.children.filter(isFirst), ...node.children.filter((index) => !isFirst(index))];
8051
+ }
7795
8052
  const sources = (node.visit.kind?.scope ?? []).flatMap((rule) => "keysAt" in rule.names ? [rule.names.keysAt] : []);
7796
8053
  if (sources.length === 0 || node.children.length < 2) return node.children;
7797
8054
  const gives = (index) => {
@@ -7815,7 +8072,7 @@ function message(error) {
7815
8072
  * @param rootTypes - The types of the roots and of the names of the host.
7816
8073
  * @returns The type of the root, the type issues in the order of the document, and the type of each document.
7817
8074
  */
7818
- function typePass(machine, nodes, verb, expect, rootTypes = {}) {
8075
+ function typePass(machine, nodes, verb, expect, rootTypes = {}, hasEffect = () => false) {
7819
8076
  if (nodes.length === 0) return {
7820
8077
  type: "unknown",
7821
8078
  issues: [],
@@ -7827,6 +8084,29 @@ function typePass(machine, nodes, verb, expect, rootTypes = {}) {
7827
8084
  const types = new Array(nodes.length);
7828
8085
  const needed = new Array(nodes.length);
7829
8086
  const seen = /* @__PURE__ */ new Set();
8087
+ const inputs = new Array(nodes.length);
8088
+ let changes;
8089
+ const rootsChange = () => changes ??= nodes.some(hasEffect);
8090
+ const narrowed = (names, roots, proofs) => {
8091
+ let nextNames = names;
8092
+ let nextRoots = roots;
8093
+ for (const proof of proofs) {
8094
+ const head = proof.path[0];
8095
+ if (head === "names") {
8096
+ const name = proof.path[1];
8097
+ if (name === void 0) continue;
8098
+ if (nextNames === names) nextNames = new Map(names);
8099
+ nextNames.set(name, narrowType(nextNames.get(name) ?? "unknown", proof, 2, domains));
8100
+ } else if ((head === "self" || head === "world" || head === "event") && !rootsChange()) nextRoots = {
8101
+ ...nextRoots,
8102
+ [head]: narrowType(nextRoots[head], proof, 1, domains)
8103
+ };
8104
+ }
8105
+ return {
8106
+ names: nextNames,
8107
+ roots: nextRoots
8108
+ };
8109
+ };
7830
8110
  const issueAt = (index, problem) => {
7831
8111
  const visit = nodes[index].visit;
7832
8112
  const issue = {
@@ -7864,19 +8144,30 @@ function typePass(machine, nodes, verb, expect, rootTypes = {}) {
7864
8144
  typeOf: (path) => typed.get(pathKey(path)) ?? "unknown",
7865
8145
  nameType: (name) => names.get(name),
7866
8146
  rootType: (root) => root === "caps" ? CAPS_TYPE : root === "self" || root === "world" || root === "event" ? roots[root] : "unknown",
7867
- contract: (type, what) => contract(index, type, what)
8147
+ contract: (type, what) => contract(index, type, what),
8148
+ readOf: (path) => {
8149
+ const key = pathKey(path);
8150
+ const part = node.children.find((child) => pathKey(nodes[child].visit.slot) === key);
8151
+ const read = part === void 0 ? void 0 : ruleOf(machine, nodes[part].evaluator)?.reads;
8152
+ return read === void 0 || nodes[part].marked ? void 0 : read(inputs[part]);
8153
+ },
8154
+ provenBy: (path) => frame.proven?.get(pathKey(path)) ?? NO_PROOFS$1
7868
8155
  };
7869
- return {
8156
+ inputs[index] = input;
8157
+ const rule = node.marked ? void 0 : ruleOf(machine, node.evaluator);
8158
+ const frame = {
7870
8159
  index,
7871
- rule: node.marked ? void 0 : ruleOf(machine, node.evaluator),
8160
+ rule,
7872
8161
  input,
7873
- order: orderOf(node, nodes),
8162
+ order: orderOf(node, nodes, rule?.first),
7874
8163
  next: 0,
7875
8164
  typed,
7876
8165
  needs,
7877
8166
  names,
7878
- roots
8167
+ roots,
8168
+ proven: void 0
7879
8169
  };
8170
+ return frame;
7880
8171
  };
7881
8172
  const ruleFailed = (frame, error) => {
7882
8173
  issueAt(frame.index, { reason: `The type rule of ${nodes[frame.index].evaluator ?? "the evaluator"} fails: ${message(error)}` });
@@ -7924,12 +8215,22 @@ function typePass(machine, nodes, verb, expect, rootTypes = {}) {
7924
8215
  if (contracts && node.expect !== void 0) need(contract(child, node.expect, `expected type of the ${what}`), what);
7925
8216
  if (part.expect !== void 0) need(part.expect, part.what ?? what);
7926
8217
  let names = frame.names;
8218
+ let kept = frame.roots;
8219
+ if (part.narrow !== void 0 && part.narrow.length > 0) {
8220
+ const after = narrowed(names, kept, part.narrow);
8221
+ names = after.names;
8222
+ kept = after.roots;
8223
+ if (part.keep === true) {
8224
+ frame.names = names;
8225
+ frame.roots = kept;
8226
+ }
8227
+ }
7927
8228
  if (node.bound.length > 0) {
7928
8229
  const copy = new Map(names);
7929
8230
  for (const name of node.bound) copy.set(name, part.names !== void 0 && Object.hasOwn(part.names, name) ? part.names[name] : "unknown");
7930
8231
  names = copy;
7931
8232
  }
7932
- let roots = frame.rule === void 0 ? UNKNOWN_ROOTS : frame.roots;
8233
+ let roots = frame.rule === void 0 ? UNKNOWN_ROOTS : kept;
7933
8234
  const changes = part.roots;
7934
8235
  if (typeof changes === "object" && changes !== null) {
7935
8236
  const copy = { ...roots };
@@ -7964,13 +8265,23 @@ function typePass(machine, nodes, verb, expect, rootTypes = {}) {
7964
8265
  }
7965
8266
  types[frame.index] = type;
7966
8267
  needed[frame.index] = frame.needs.length === 0 ? void 0 : frame.needs[frame.needs.length - 1].type;
7967
- stack[stack.length - 1]?.typed.set(pathKey(node.visit.slot), type);
8268
+ const parent = stack[stack.length - 1];
8269
+ if (parent === void 0) continue;
8270
+ const key = pathKey(node.visit.slot);
8271
+ parent.typed.set(key, type);
8272
+ if (parent.rule?.usesProofs === true && frame.rule?.proves !== void 0) try {
8273
+ (parent.proven ??= /* @__PURE__ */ new Map()).set(key, frame.rule.proves(frame.input));
8274
+ } catch (error) {
8275
+ ruleFailed(frame, error);
8276
+ }
7968
8277
  }
7969
8278
  const places = nodes.map((node, index) => {
7970
8279
  const want = needed[index];
8280
+ const read = !node.marked && ruleOf(machine, node.evaluator)?.read === true;
7971
8281
  const entry = {
7972
8282
  type: types[index] ?? "unknown",
7973
- ...want === void 0 ? {} : { expected: want }
8283
+ ...want === void 0 ? {} : { expected: want },
8284
+ ...read ? { read } : {}
7974
8285
  };
7975
8286
  Object.defineProperty(entry, "place", {
7976
8287
  enumerable: true,
@@ -9482,11 +9793,13 @@ function walk(world, doc, visit, options = {}) {
9482
9793
  continue;
9483
9794
  }
9484
9795
  const { sees, later } = scopesOf(kind.scope, doc.value, split.parts);
9796
+ const grantRules = kind.caps !== void 0 && kind.caps.some((rule) => rule.rule === "grant") ? kind.caps : void 0;
9485
9797
  for (let index = split.parts.length - 1; index >= 0; index -= 1) {
9486
9798
  const slot = split.parts[index];
9487
9799
  const extra = sees[index] ?? [];
9488
9800
  const hidden = later[index] ?? [];
9489
- const grants = partGrants(kind.caps, slot.path, doc.value);
9801
+ const grants = grantRules === void 0 ? void 0 : partGrants(grantRules, slot.path, doc.value);
9802
+ const granted = grants !== void 0 && grants.length > 0 ? grants : void 0;
9490
9803
  stack.push({
9491
9804
  value: slot.item,
9492
9805
  place: slot.path.length === 0 ? item.place : {
@@ -9504,8 +9817,8 @@ function walk(world, doc, visit, options = {}) {
9504
9817
  address: slot.address === true,
9505
9818
  slot: slot.path,
9506
9819
  parent: here,
9507
- caps: item.caps === void 0 || kind.caps === void 0 ? item.caps : [...partCaps(kind.caps, slot.path, item.caps), ...grants],
9508
- handled: grants.length === 0 ? item.handled : [...item.handled ?? [], ...grants],
9820
+ caps: item.caps === void 0 || kind.caps === void 0 ? item.caps : granted === void 0 ? partCaps(kind.caps, slot.path, item.caps) : [...partCaps(kind.caps, slot.path, item.caps), ...granted],
9821
+ handled: granted === void 0 ? item.handled : [...item.handled ?? [], ...granted],
9509
9822
  bound: extra,
9510
9823
  expect: slot.expect
9511
9824
  });
@@ -9595,6 +9908,28 @@ function mapRefs(world, doc, change, options = {}) {
9595
9908
  return out;
9596
9909
  }
9597
9910
  /**
9911
+ * This function changes the documents of a document, from the root to the parts (STATIC.MAPDOCS). The function
9912
+ * `change` reads only the original documents. It decides at each node, and it can stop at a node. The kinds of a
9913
+ * position come from the world, thus this function names no kind. The document is not changed: the function gives a
9914
+ * new document that shares each part without a change.
9915
+ *
9916
+ * @param world - The world of the kinds.
9917
+ * @param doc - The document, as JSON.
9918
+ * @param change - The function that gives the answer for each visit. See `DocChange`.
9919
+ * @param options - The type of a bare root value, and the names that the host binds at the root.
9920
+ * @returns The new document, or `doc` itself when no document changes.
9921
+ */
9922
+ function mapDocs(world, doc, change, options = {}) {
9923
+ let out = doc;
9924
+ walk(world, doc, (visit) => {
9925
+ const next = change(visit);
9926
+ if (next === void 0 || next === "skip") return next;
9927
+ out = setAt(out, visit.at, next.to);
9928
+ return next.into === true ? void 0 : "skip";
9929
+ }, options);
9930
+ return out;
9931
+ }
9932
+ /**
9598
9933
  * This function gives the parts that the code of a runner evaluates itself, without a wait (RUN.DRIVES, D119). The
9599
9934
  * answer of the hook `facts` for the code wins over the contract. The contract describes only the code of its kind for
9600
9935
  * `eval`. Without a declaration, the runner passes each wait of its parts through.
@@ -9737,7 +10072,8 @@ function check(machine, doc, options = {}) {
9737
10072
  function typeCheck(machine, doc, options = {}) {
9738
10073
  const nodes = [];
9739
10074
  const issues = checkAll(machine, doc, options, nodes);
9740
- const pass = typePass(machine, nodes, options.verb ?? "eval", options.expect, options.rootTypes);
10075
+ const verb = options.verb ?? "eval";
10076
+ const pass = typePass(machine, nodes, verb, options.expect, options.rootTypes, (node) => declaredEffects(node.visit, verb, machine, node.evaluator).length > 0);
9741
10077
  return {
9742
10078
  type: pass.type,
9743
10079
  issues: pass.issues.length === 0 ? issues : [...issues, ...pass.issues],
@@ -10742,6 +11078,13 @@ function decodeValue(machine, doc) {
10742
11078
  return prepare(machine, doc, { declaredType: "lit" }).evaluate(makeContext());
10743
11079
  }
10744
11080
  // src/formula.ts
11081
+ /** The most proofs that one test keeps. A proof only adds knowledge, thus the check can leave one out. */
11082
+ const MAX_PROOFS = 32;
11083
+ /** The result of a test that proves nothing. */
11084
+ const NO_PROOFS = {
11085
+ yes: [],
11086
+ no: []
11087
+ };
10745
11088
  /** The mark of a field that the profile leaves out of a record. */
10746
11089
  const SKIPPED = /* @__PURE__ */ Symbol("skipped");
10747
11090
  /** The value of a name whose binding failed. A reference to the name gives the error. */
@@ -11142,6 +11485,11 @@ function formulaTypes(profile) {
11142
11485
  type: sig.to,
11143
11486
  what: `result of a signature of ops.${name}`
11144
11487
  });
11488
+ if (sig.proves !== void 0) out.push({
11489
+ at: [...at, "proves"],
11490
+ type: sig.proves,
11491
+ what: `proved type of a signature of ops.${name}`
11492
+ });
11145
11493
  const earlier = list.slice(0, index).findIndex((other) => isSignature(other) && sameParams(other, sig));
11146
11494
  if (earlier >= 0) out.push({
11147
11495
  at,
@@ -11152,7 +11500,30 @@ function formulaTypes(profile) {
11152
11500
  return out;
11153
11501
  };
11154
11502
  const logic = (word) => ({
11155
- part: (input, path) => truthPart(input, `term ${Number(path[0]) + 1} of ${word}`),
11503
+ usesProofs: true,
11504
+ part: (input, path) => {
11505
+ const index = Number(path[0]);
11506
+ const part = truthPart(input, `term ${index + 1} of ${word}`);
11507
+ if (index === 0) return part;
11508
+ const before = input.provenBy([index - 1]);
11509
+ return {
11510
+ ...part,
11511
+ narrow: word === "and" ? before.yes : before.no,
11512
+ keep: true
11513
+ };
11514
+ },
11515
+ proves: (input) => {
11516
+ const each = input.paths.map((path) => input.provenBy(path));
11517
+ const all = (side) => each.flatMap((proven) => proven[side]).slice(0, MAX_PROOFS);
11518
+ const one = each.length === 1 ? each[0] : void 0;
11519
+ return word === "and" ? {
11520
+ yes: all("yes"),
11521
+ no: one?.no ?? []
11522
+ } : {
11523
+ yes: one?.yes ?? [],
11524
+ no: all("no")
11525
+ };
11526
+ },
11156
11527
  synth: (input) => {
11157
11528
  if (!logicValue) return "bool";
11158
11529
  if (input.paths.length === 0) return { one: [word === "and"] };
@@ -11161,39 +11532,47 @@ function formulaTypes(profile) {
11161
11532
  });
11162
11533
  return {
11163
11534
  "formula.lit": { synth: (input) => valueType(input.doc.value) },
11164
- "formula.ref": { synth: (input, report) => {
11165
- const path = input.doc.value;
11166
- if (input.address || !Array.isArray(path) || path.length === 0) return "unknown";
11167
- const domains = input.machine.domains;
11168
- const plain = input.machine.plain === true;
11169
- let type;
11170
- let start;
11171
- if (path[0] === "names") {
11172
- const name = path[1];
11173
- if (!isKey(name) || !plain && HEADER_KEYS.has(String(name))) return "unknown";
11174
- type = input.nameType(String(name)) ?? "unknown";
11175
- start = 2;
11176
- } else {
11177
- type = input.rootType(String(path[0]));
11178
- start = 1;
11179
- }
11180
- for (let index = start;; index += 1) {
11181
- if (isUnknown(type, domains) || !plain && holdsEnvelope(type, domains)) return "unknown";
11182
- if (index >= path.length) return type;
11183
- const step = path[index];
11184
- if (!isKey(step)) {
11185
- type = walkType(input, step, type);
11186
- continue;
11535
+ "formula.ref": {
11536
+ read: true,
11537
+ reads: (input) => {
11538
+ const path = input.doc.value;
11539
+ if (input.address || !Array.isArray(path) || path.length === 0) return void 0;
11540
+ return path.every((step) => typeof step === "string") ? path : void 0;
11541
+ },
11542
+ synth: (input, report) => {
11543
+ const path = input.doc.value;
11544
+ if (input.address || !Array.isArray(path) || path.length === 0) return "unknown";
11545
+ const domains = input.machine.domains;
11546
+ const plain = input.machine.plain === true;
11547
+ let type;
11548
+ let start;
11549
+ if (path[0] === "names") {
11550
+ const name = path[1];
11551
+ if (!isKey(name) || !plain && HEADER_KEYS.has(String(name))) return "unknown";
11552
+ type = input.nameType(String(name)) ?? "unknown";
11553
+ start = 2;
11554
+ } else {
11555
+ type = input.rootType(String(path[0]));
11556
+ start = 1;
11187
11557
  }
11188
- const next = stepType(type, step, domains, input.contract);
11189
- if ("missing" in next) {
11190
- const fields = next.missing.length === 0 ? "" : ` Its fields are ${listText(next.missing)}.`;
11191
- report({ reason: `The value at ${path.slice(0, index).map(stepText).join(".")} has no field ${String(step)}.${fields}` });
11192
- return "unknown";
11558
+ for (let index = start;; index += 1) {
11559
+ if (isUnknown(type, domains) || !plain && holdsEnvelope(type, domains)) return "unknown";
11560
+ if (index >= path.length) return type;
11561
+ const step = path[index];
11562
+ if (!isKey(step)) {
11563
+ type = walkType(input, step, type);
11564
+ continue;
11565
+ }
11566
+ const next = stepType(type, step, domains, input.contract);
11567
+ if ("missing" in next) {
11568
+ const fields = next.missing.length === 0 ? "" : ` Its fields are ${listText(next.missing)}.`;
11569
+ report({ reason: `The value at ${path.slice(0, index).map(stepText).join(".")} has no field ${String(step)}.${fields}` });
11570
+ return "unknown";
11571
+ }
11572
+ type = next.type;
11193
11573
  }
11194
- type = next.type;
11195
11574
  }
11196
- } },
11575
+ },
11197
11576
  "formula.record": {
11198
11577
  part: (input, path) => {
11199
11578
  const want = fieldOf(input.expected, String(path[0]), input.machine.domains);
@@ -11303,11 +11682,16 @@ function formulaTypes(profile) {
11303
11682
  type: truth,
11304
11683
  what: "truth type of the profile"
11305
11684
  }] : [],
11685
+ first: "test",
11686
+ usesProofs: true,
11306
11687
  part: (input, path) => {
11307
11688
  if (path[0] === "test") return truthPart(input, "test of if");
11308
- return isUnknown(input.expected, input.machine.domains) ? {} : {
11689
+ const proven = input.provenBy(["test"]);
11690
+ const narrow = path[0] === "then" ? proven.yes : proven.no;
11691
+ return isUnknown(input.expected, input.machine.domains) ? { narrow } : {
11309
11692
  expect: input.expected,
11310
- what: `${String(path[0])} branch of if`
11693
+ what: `${String(path[0])} branch of if`,
11694
+ narrow
11311
11695
  };
11312
11696
  },
11313
11697
  synth: (input) => {
@@ -11320,6 +11704,41 @@ function formulaTypes(profile) {
11320
11704
  "formula.or": logic("or"),
11321
11705
  "formula.op": {
11322
11706
  declared: sigsDeclared,
11707
+ proves: (input) => {
11708
+ const sigs = signatures(input)?.sigs;
11709
+ const sig = sigs?.length === 1 ? sigs[0] : void 0;
11710
+ if (sig === void 0 || sig.proves === void 0 && sig.present !== true || input.paths.length === 0) return NO_PROOFS;
11711
+ const path = input.readOf(input.paths[0]);
11712
+ if (path === void 0) return NO_PROOFS;
11713
+ const yes = [];
11714
+ const no = [];
11715
+ if (sig.proves !== void 0 && typeIssues(input.contract(sig.proves, `proved type of ops.${nameOf(input)}`), input.machine.domains).length === 0) {
11716
+ yes.push({
11717
+ path,
11718
+ fact: "is",
11719
+ type: sig.proves
11720
+ });
11721
+ no.push({
11722
+ path,
11723
+ fact: "not",
11724
+ type: sig.proves
11725
+ });
11726
+ }
11727
+ if (sig.present === true) {
11728
+ yes.push({
11729
+ path,
11730
+ fact: "present"
11731
+ });
11732
+ no.push({
11733
+ path,
11734
+ fact: "absent"
11735
+ });
11736
+ }
11737
+ return {
11738
+ yes,
11739
+ no
11740
+ };
11741
+ },
11323
11742
  part: (input, path) => {
11324
11743
  const read = signatures(input);
11325
11744
  if (read === void 0 || read.sigs.length !== 1) return {};
@@ -13107,10 +13526,23 @@ const treeDefinition = ({ parts, context, kind, place, machine, typePath, resolv
13107
13526
  }
13108
13527
  };
13109
13528
  /**
13529
+ * The definition of the standard evaluator `ref.resolve` (REF.RESOLVE, D133). It resolves the steps of the path at each
13530
+ * evaluation. The plan compiles the same path one time.
13531
+ */
13532
+ const refDefinition = ({ data, resolve: walk }) => {
13533
+ if (!Array.isArray(data) || data.length === 0) return fail("#VALUE!", "The value of ref is a path: a list that starts with a root, for example [\"names\", \"a\"].");
13534
+ const found = walk(data);
13535
+ return found.ok ? ok(valueOfThing(found.thing)) : fail(found.code, found.reason);
13536
+ };
13537
+ /**
13110
13538
  * The definitions of the reference for the evaluators of the standard machine that need their own reading. The
13111
- * reference uses them for the standard evaluators, also without the option `definitions`. It holds `tree.node`.
13539
+ * reference uses them for the standard evaluators, also without the option `definitions`. It holds `tree.node` and
13540
+ * `ref.resolve`. A host that wraps `ref.resolve` wraps this function, because the standard evaluator is compiled.
13112
13541
  */
13113
- const STD_DEFINITIONS = { evaluators: { "tree.node": treeDefinition } };
13542
+ const STD_DEFINITIONS = { evaluators: {
13543
+ "tree.node": treeDefinition,
13544
+ "ref.resolve": refDefinition
13545
+ } };
13114
13546
  const CLOSURE$1 = /* @__PURE__ */ Symbol.for("coeval.closure");
13115
13547
  /** This function sets an own field, also the field `__proto__` (SHAPE.PROTO). */
13116
13548
  function setField$1(target, key, value) {
@@ -14702,6 +15134,14 @@ function readsUnknown(reads) {
14702
15134
  function resolutions(reads) {
14703
15135
  return reads.filter((read) => read.free && read.kept !== true);
14704
15136
  }
15137
+ /** This function gives the text of a value of a trace. It does not throw for a bigint or a record with a cycle. */
15138
+ function valueText$1(value) {
15139
+ try {
15140
+ return JSON.stringify(value) ?? describe(value);
15141
+ } catch {
15142
+ return describe(value);
15143
+ }
15144
+ }
14705
15145
  function pathText(path) {
14706
15146
  if (path === void 0) return "no read";
14707
15147
  try {
@@ -14857,6 +15297,96 @@ async function agreeRun(machine, doc, context = makeContext(), options = {}) {
14857
15297
  reads: compared
14858
15298
  };
14859
15299
  }
15300
+ /** The type errors of the kernel, by the evaluator that gives them (STATIC.TYPES-AGREE). */
15301
+ const TYPE_ERRORS = {
15302
+ "formula.op": "#NAME?",
15303
+ "formula.if": "#VALUE!",
15304
+ "formula.and": "#VALUE!",
15305
+ "formula.or": "#VALUE!"
15306
+ };
15307
+ /**
15308
+ * This function examines the agreement rule for types (STATIC.TYPES-AGREE, D148). A document with no issue evaluates
15309
+ * with a trace. Each value of the trace is a member of the type of its place. A value of a precise type is also a member
15310
+ * of the type that its position needs. No document with precise parts gives a type error of the kernel.
15311
+ *
15312
+ * A language imports this function for its own property tests, with `agree`. A failure tells that a signature, a type
15313
+ * rule, a cover or a root type does not hold. A value that breaks a position of an imprecise type ends the promise, and
15314
+ * the result then has `checked: false` (TYPE.GRADUAL).
15315
+ *
15316
+ * @param machine - The world and the code of the evaluators, with their type rules.
15317
+ * @param doc - The document.
15318
+ * @param context - The context. Its roots are members of the root types.
15319
+ * @param options - The options of `check`, with the root types, and `guards`.
15320
+ * @returns The agreement, or the first place that breaks it.
15321
+ */
15322
+ function agreeTypes(machine, doc, context = makeContext(), options = {}) {
15323
+ const typing = typeCheck(machine, doc, options);
15324
+ if (typing.issues.length > 0) return {
15325
+ ok: true,
15326
+ checked: false,
15327
+ values: 0
15328
+ };
15329
+ const keyOf = (path) => JSON.stringify(path.map(String));
15330
+ const places = new Map(typing.places.map((item) => [keyOf(item.place), item]));
15331
+ const domains = machine.domains;
15332
+ const guards = options.guards === true ? boundariesOf(typing, domains) : void 0;
15333
+ const stack = [evaluate(machine, doc, context, {
15334
+ ...options.declaredType === void 0 ? {} : { declaredType: options.declaredType },
15335
+ ...guards === void 0 ? {} : { guards }
15336
+ }).trace];
15337
+ const nodes = [];
15338
+ while (stack.length > 0) {
15339
+ const node = stack.pop();
15340
+ nodes.push(node);
15341
+ stack.push(...node.children);
15342
+ }
15343
+ for (const node of nodes) {
15344
+ const place = places.get(keyOf(node.path));
15345
+ if (place?.expected === void 0 || !node.result.ok || isPrecise(place.type, domains)) continue;
15346
+ if (!member(node.result.value, place.expected, domains)) return {
15347
+ ok: true,
15348
+ checked: false,
15349
+ values: 0
15350
+ };
15351
+ }
15352
+ let values = 0;
15353
+ for (const node of nodes.reverse()) {
15354
+ const place = places.get(keyOf(node.path));
15355
+ if (place === void 0) continue;
15356
+ const at = node.path.map(String);
15357
+ if (!node.result.ok) {
15358
+ const parts = node.children.map((child) => places.get(keyOf(child.path)));
15359
+ const decided = node.children.every((child) => child.result.ok) && parts.every((part) => part?.expected !== void 0 && isPrecise(part.type, domains));
15360
+ const code = TYPE_ERRORS[node.answer.evaluator ?? ""];
15361
+ if (decided && node.result.error.code === code) return {
15362
+ ok: false,
15363
+ clause: "error",
15364
+ place: at,
15365
+ reason: `The document gives ${code}, but it checks with no issue.`
15366
+ };
15367
+ continue;
15368
+ }
15369
+ const value = node.result.value;
15370
+ values += 1;
15371
+ if (!member(value, place.type, domains)) return {
15372
+ ok: false,
15373
+ clause: "value",
15374
+ place: at,
15375
+ reason: `The value ${valueText$1(value)} is not a member of ${typeText(place.type)}.`
15376
+ };
15377
+ if (place.expected !== void 0 && !member(value, place.expected, domains)) return {
15378
+ ok: false,
15379
+ clause: "argument",
15380
+ place: at,
15381
+ reason: `The value ${valueText$1(value)} is not a member of the needed type ${typeText(place.expected)}.`
15382
+ };
15383
+ }
15384
+ return {
15385
+ ok: true,
15386
+ checked: true,
15387
+ values
15388
+ };
15389
+ }
14860
15390
  // src/codec-laws.ts
14861
15391
  /** The order of the laws in the list of findings. */
14862
15392
  const ORDER$1 = [
@@ -15280,6 +15810,13 @@ function compileConstructs(given, ops) {
15280
15810
  constructKinds
15281
15811
  };
15282
15812
  }
15813
+ /** This function examines the field `domain` of a call form (D141). A form `literal` of `ext.domain` needs a name, and each other form refuses it. */
15814
+ function compileDomain(given, args) {
15815
+ const writes = args === "literal" && given.kind === "ext.domain";
15816
+ if (writes && (typeof given.domain !== "string" || given.domain === "")) throw new TypeError(`The call form "${given.name}" of ext.domain needs the name of its domain.`);
15817
+ if (!writes && given.domain !== void 0) throw new TypeError(`The call form "${given.name}" takes no domain: only a form literal of ext.domain has one.`);
15818
+ return given.domain;
15819
+ }
15283
15820
  /** This function examines the field `wrap` of a call form (K159). A name that is not a field of the form throws. */
15284
15821
  function compileWrap(given, args) {
15285
15822
  const wrap = given.wrap;
@@ -15291,6 +15828,16 @@ function compileWrap(given, args) {
15291
15828
  return new Set(wrap);
15292
15829
  }
15293
15830
  /** This function gives the types of the data envelopes of a profile (K159), or `undefined` without them. */
15831
+ /** This function examines the field `data` of a call form (D177). Each name is a field of the form, and no name is in `wrap`. */
15832
+ function compileData(given, wrap) {
15833
+ const data = given.data ?? [];
15834
+ if (data.length > 0 && given.fields === void 0) throw new TypeError(`The call form "${given.name}" takes data only with fields.`);
15835
+ for (const name of data) {
15836
+ if (given.fields?.includes(name) !== true) throw new TypeError(`The call form "${given.name}" has no field ${name} for its data.`);
15837
+ if (wrap === true || wrap !== false && wrap.has(name)) throw new TypeError(`The call form "${given.name}" has the field ${name} in wrap and in data.`);
15838
+ }
15839
+ return new Set(data);
15840
+ }
15294
15841
  function compileEnvelopes(given) {
15295
15842
  if (given === void 0) return void 0;
15296
15843
  const out = {};
@@ -15327,17 +15874,22 @@ function compileProfile(profile) {
15327
15874
  if (!FORM_ARGS.includes(args)) throw new TypeError(`The call form "${given.name}" has the unknown arguments ${String(args)}.`);
15328
15875
  if (args === "fields" !== (given.fields !== void 0) && args !== "named") throw new TypeError(`The call form "${given.name}" with the arguments ${args} ${args === "fields" ? "needs" : "takes no"} fields.`);
15329
15876
  if (given.min !== void 0 && (args === "named" || args === "literal")) throw new TypeError(`The call form "${given.name}" with the arguments ${args} takes no min.`);
15877
+ const wrap = compileWrap(given, args);
15330
15878
  const form = {
15331
15879
  name: given.name,
15332
15880
  type,
15333
15881
  args,
15334
15882
  fields: given.fields,
15335
15883
  min: given.min ?? given.fields?.length ?? 0,
15336
- wrap: compileWrap(given, args)
15884
+ wrap,
15885
+ domain: compileDomain(given, args),
15886
+ data: compileData(given, wrap)
15337
15887
  };
15338
15888
  forms.set(form.name, form);
15339
15889
  addTo(formsByKind, key, form);
15340
15890
  }
15891
+ const brackets = [...forms.values()].some((form) => form.data.size > 0);
15892
+ for (const symbol of brackets ? [...ops.prefixSymbols, ...ops.binarySymbols] : []) if (/^[[\]{}]/.test(symbol)) throw new TypeError(`The operator "${symbol}" reads the text of a field of data.`);
15341
15893
  const compiled = {
15342
15894
  ...ops,
15343
15895
  numbers: literals.numbers ?? true,
@@ -15369,7 +15921,8 @@ function compileProfile(profile) {
15369
15921
  ...ops.opWords,
15370
15922
  ...roots
15371
15923
  ]),
15372
- maxDepth: profile.maxDepth ?? 256
15924
+ maxDepth: profile.maxDepth ?? 256,
15925
+ brackets
15373
15926
  };
15374
15927
  compiledProfiles.set(profile, compiled);
15375
15928
  return compiled;
@@ -15828,7 +16381,7 @@ var Parser = class {
15828
16381
  }
15829
16382
  /** This method stops at a token where a group or a list must end. A list can also continue with its separator. */
15830
16383
  noEnd(close, list) {
15831
- const closer = close === ")" ? "parenthesis" : "brace";
16384
+ const closer = closerName(close);
15832
16385
  const before = list ? `"${this.syn.separator}" or a ` : "";
15833
16386
  return this.stop(`A ${before}closing ${closer} is missing.`, this.pos, this.tokenLength());
15834
16387
  }
@@ -15853,16 +16406,31 @@ var Parser = class {
15853
16406
  this.pos += 1;
15854
16407
  return args;
15855
16408
  }
15856
- if (this.pos >= this.text.length) this.stop(`A closing ${close === ")" ? "parenthesis" : "brace"} is missing.`, open, 1);
16409
+ if (this.pos >= this.text.length) this.stop(`A closing ${closerName(close)} is missing.`, open, 1);
15857
16410
  this.noEnd(close, true);
15858
16411
  }
15859
16412
  }
15860
16413
  /**
15861
- * This method reads the entries `key: expr` into a record: the arguments of a form `named` (SYNTAX.RECORD), or the
15862
- * entries between braces without a form (SYNTAX.RECORD-TEXT).
16414
+ * This method reads the argument of a field of data (D177): a list between brackets, a record between braces, or a
16415
+ * document. A literal in it stays its data.
15863
16416
  */
15864
- entries(form) {
15865
- const owner = form === void 0 ? "record" : `form ${form.name}`;
16417
+ data() {
16418
+ this.skip();
16419
+ const start = this.pos;
16420
+ const c = this.text[start];
16421
+ if (c !== "[" && c !== "{") return this.bound();
16422
+ this.depth += 1;
16423
+ if (this.depth > this.syn.maxDepth) this.stop(`The text is deeper than ${String(this.syn.maxDepth)} levels.`, start, 0);
16424
+ const value = c === "[" ? this.argumentsOf(() => this.data(), "]") : this.entries(void 0, true);
16425
+ this.depth -= 1;
16426
+ return value;
16427
+ }
16428
+ /**
16429
+ * This method reads the entries `key: expr` into a record. The record is the arguments of a form `named`
16430
+ * (SYNTAX.RECORD), or the entries between braces (SYNTAX.RECORD-TEXT). It is also a record of data (D177).
16431
+ */
16432
+ entries(form, data = false) {
16433
+ const owner = data ? "record of data" : form === void 0 ? "record" : `form ${form.name}`;
15866
16434
  const value = {};
15867
16435
  const entry = () => {
15868
16436
  this.skip();
@@ -15872,9 +16440,10 @@ var Parser = class {
15872
16440
  this.skip();
15873
16441
  if (key === void 0 || this.text[this.pos] !== ":") this.stop(`Each ${form === void 0 ? "entry" : "argument"} of the ${owner} is a key, a ":" and a document.`, at, Math.max(end - at, this.tokenLength()));
15874
16442
  if (form?.fields !== void 0 && !form.fields.includes(key)) this.stop(`The form ${form.name} has no field ${key}.`, at, end - at);
16443
+ if (data && key === "type") this.stop("A record of data has no key type, because the key type makes a document.", at, end - at);
15875
16444
  if (Object.hasOwn(value, key)) this.stop(`The ${owner} has the field ${key} two times.`, at, end - at);
15876
16445
  this.pos += 1;
15877
- const arg = this.bound();
16446
+ const arg = data || form?.data.has(key) === true ? this.data() : this.bound();
15878
16447
  setOwn$1(value, key, form !== void 0 && wraps(form, key) ? envelop(this.syn, arg) : arg);
15879
16448
  };
15880
16449
  this.argumentsOf(entry, form === void 0 ? "}" : ")");
@@ -15883,11 +16452,19 @@ var Parser = class {
15883
16452
  call(name, start, nameLength) {
15884
16453
  const form = this.syn.forms.get(name);
15885
16454
  if (form?.args === "named") return opDoc(form, this.entries(form));
15886
- const args = this.argumentsOf(() => this.bound());
16455
+ let index = 0;
16456
+ const args = this.argumentsOf(() => {
16457
+ const key = form?.fields?.[index];
16458
+ index += 1;
16459
+ return key !== void 0 && form?.data.has(key) === true ? this.data() : this.bound();
16460
+ });
15887
16461
  if (form?.args === "literal") {
15888
16462
  const [only] = args;
15889
16463
  if (args.length !== 1 || !isScalar(only)) this.stop(`The form ${name} takes one literal that JSON writes.`, start, this.pos - start);
15890
- return opDoc(form, only);
16464
+ return opDoc(form, form.domain === void 0 ? only : {
16465
+ domain: form.domain,
16466
+ data: only
16467
+ });
15891
16468
  }
15892
16469
  if (form !== void 0) {
15893
16470
  const most = form.fields?.length ?? Number.POSITIVE_INFINITY;
@@ -15913,15 +16490,20 @@ var Parser = class {
15913
16490
  /** The end of a recovery. The class `Recovery` throws it, and its method `run` catches it. */
15914
16491
  var End = class {};
15915
16492
  function hasBraces(syn) {
15916
- return syn.constructs.record !== void 0 || syn.constructs.let !== void 0;
16493
+ return syn.constructs.record !== void 0 || syn.constructs.let !== void 0 || syn.brackets;
16494
+ }
16495
+ /** This function gives the name of a closer in a message. */
16496
+ function closerName(close) {
16497
+ return close === ")" ? "parenthesis" : close === "]" ? "bracket" : "brace";
15917
16498
  }
15918
16499
  /** This function gives the closer of an opening bracket of a profile, or `undefined` for each other character. */
15919
16500
  function closerOf(syn, c) {
15920
16501
  if (c === "(") return ")";
16502
+ if (c === "[" && syn.brackets) return "]";
15921
16503
  return c === "{" && hasBraces(syn) ? "}" : void 0;
15922
16504
  }
15923
16505
  function isCloser(syn, c) {
15924
- return c === ")" || c === "}" && hasBraces(syn);
16506
+ return c === ")" || c === "]" && syn.brackets || c === "}" && hasBraces(syn);
15925
16507
  }
15926
16508
  /** This function gives the position after a quoted text at `at`, or after one other character. An open quote gives `Infinity`. */
15927
16509
  function pastToken(syn, text, at) {
@@ -16164,6 +16746,7 @@ function refShape(syn, value) {
16164
16746
  }
16165
16747
  function callName(syn, keys) {
16166
16748
  if (keys.length === 0 || !keys.every((key) => typeof key === "string" && NAME.test(key))) return void 0;
16749
+ if (keys.length > 1 && !syn.fields) return void 0;
16167
16750
  const name = keys.join(".");
16168
16751
  if (syn.forms.has(name) || syn.opWords.has(keys[0])) return void 0;
16169
16752
  return syn.ops === true || syn.ops.has(name) ? name : void 0;
@@ -16186,10 +16769,16 @@ function wrappedShape(syn, doc) {
16186
16769
  const literal = literalShape(syn, doc.value);
16187
16770
  return literal.tag === "text" ? literal : void 0;
16188
16771
  }
16772
+ /** This function tells if a value of `ext.domain` is a record with this domain and its data, and no other key. */
16773
+ function holdsDomain(value, domain) {
16774
+ return isRecord(value) && value["domain"] === domain && Object.hasOwn(value, "data") && Object.keys(value).length === 2;
16775
+ }
16189
16776
  function formShape(syn, form, value) {
16190
16777
  if (form.args === "literal") {
16191
- if (!isScalar(value)) return void 0;
16192
- const literal = literalShape(syn, value);
16778
+ if (form.domain !== void 0 && !holdsDomain(value, form.domain)) return void 0;
16779
+ const data = form.domain === void 0 ? value : value["data"];
16780
+ if (!isScalar(data)) return void 0;
16781
+ const literal = literalShape(syn, data);
16193
16782
  return literal.tag === "text" ? {
16194
16783
  tag: "text",
16195
16784
  text: `${form.name}(${literal.text})`
@@ -16205,7 +16794,8 @@ function formShape(syn, form, value) {
16205
16794
  args: keys.map((key) => [
16206
16795
  key,
16207
16796
  value[key],
16208
- wraps(form, key)
16797
+ wraps(form, key),
16798
+ form.data.has(key)
16209
16799
  ]),
16210
16800
  named: true
16211
16801
  };
@@ -16232,7 +16822,8 @@ function formShape(syn, form, value) {
16232
16822
  args: present.map((key) => [
16233
16823
  key,
16234
16824
  value[key],
16235
- wraps(form, key)
16825
+ wraps(form, key),
16826
+ form.data.has(key)
16236
16827
  ])
16237
16828
  };
16238
16829
  }
@@ -16368,6 +16959,18 @@ function bracesText(syn, record, path, sub) {
16368
16959
  if (!texts.ok) return texts;
16369
16960
  return ok(`{${texts.value.map((text, index) => `${keyText(keys[index])}: ${text}`).join(`${syn.separator} `)}}`);
16370
16961
  }
16962
+ /**
16963
+ * This function writes the argument of a field of data (D177): a list between brackets, or a record between braces.
16964
+ * The function `sub` writes a literal and a document. A record that is an envelope is a document.
16965
+ */
16966
+ function dataText(syn, value, path, sub) {
16967
+ const each = (child, at) => dataText(syn, child, at, sub);
16968
+ if (Array.isArray(value)) {
16969
+ const texts = partTexts(value.map((item, index) => [index, item]), path, each);
16970
+ return texts.ok ? ok(`[${texts.value.join(`${syn.separator} `)}]`) : texts;
16971
+ }
16972
+ return isRecord(value) && !isEnvelope(value) && !Object.hasOwn(value, "type") ? bracesText(syn, value, path, each) : sub(value, path);
16973
+ }
16371
16974
  /** This function writes a construct form (K145). */
16372
16975
  function constructText(syn, shape, sub) {
16373
16976
  if (shape.tag === "record") return bracesText(syn, shape.entries, [], sub);
@@ -16410,8 +17013,8 @@ function printNode(syn, doc, sub) {
16410
17013
  return ok(texts.join("."));
16411
17014
  }
16412
17015
  const texts = [];
16413
- for (const [key, arg, wrapped] of shape.args) {
16414
- const result = sub(arg, [key], wrapped);
17016
+ for (const [key, arg, wrapped, data] of shape.args) {
17017
+ const result = data === true ? dataText(syn, arg, [key], sub) : sub(arg, [key], wrapped);
16415
17018
  if (!result.ok) return result;
16416
17019
  texts.push(shape.named === true ? `${keyText(String(key))}: ${result.value}` : result.value);
16417
17020
  }
@@ -19286,6 +19889,7 @@ function schedule(machine, options = {}) {
19286
19889
  let keptAt = -1;
19287
19890
  const keptNodes = [];
19288
19891
  let keptMet = false;
19892
+ let keptFrom = 0;
19289
19893
  let count = 0;
19290
19894
  let ahead = 0;
19291
19895
  let wanted;
@@ -19356,7 +19960,10 @@ function schedule(machine, options = {}) {
19356
19960
  const reader = stack[stack.length - 1];
19357
19961
  const known = epoch.values.get(id);
19358
19962
  if (known !== void 0) {
19359
- if (reader !== void 0 && onOpen.has(id)) lower(reader, order.get(id));
19963
+ if (reader !== void 0 && onOpen.has(id)) {
19964
+ if (keptAt >= 0 && order.get(id) < keptFrom) keptMet = true;
19965
+ else lower(reader, order.get(id));
19966
+ }
19360
19967
  return known;
19361
19968
  }
19362
19969
  if (busy.has(id)) {
@@ -19560,9 +20167,11 @@ function schedule(machine, options = {}) {
19560
20167
  keeping(read) {
19561
20168
  const outer = keptAt;
19562
20169
  const outerMet = keptMet;
20170
+ const outerFrom = keptFrom;
19563
20171
  const from = keptNodes.length;
19564
20172
  keptAt = stack.length;
19565
20173
  keptMet = false;
20174
+ keptFrom = count;
19566
20175
  try {
19567
20176
  return read();
19568
20177
  } finally {
@@ -19573,6 +20182,7 @@ function schedule(machine, options = {}) {
19573
20182
  }
19574
20183
  keptAt = outer;
19575
20184
  keptMet = outerMet;
20185
+ keptFrom = outerFrom;
19576
20186
  }
19577
20187
  }
19578
20188
  });
@@ -20556,6 +21166,6 @@ function samplesAt(values, closed, depth) {
20556
21166
  function typeFromSamples(values, options = {}) {
20557
21167
  return samplesAt(values, options.closed === true, 0);
20558
21168
  }
20559
- export { ATTRIBUTE_RUNGS, CAPS_TYPE, CIRCULAR_LIMIT, CONSTRUCTS, ENVELOPE_KEYS, Failure, GENERATION_LIMIT, Held, JOURNAL, MAX_SYNTAX_ISSUES, 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, argsKey, ask, atArgsOf, atRuleOf, attributeGraph, attributeTrace, attributeVertexId, capKeys, check, checkCycles, checkLatent, checkStep, checkSteps, checkSyntax, checkWorld, circularOf, classify, codecLaws, collectOf, compilePath, components, conforms, context, cycles, dataEdges, decodeDomain, decodeLog, decodeValue, derefStep, describe, docEquals, documentKey, 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, isStep, isTypeRef, join, jsTruthy, kindDocument, kindNamed, kindOf, layers, looksLikeKind, lookupKind, makeContext, mapRefs, member, mergeMachines, mergeWorlds, narrow, nearestWalker, necessary, nodeAt, nodeLayers, ok, parse, partCaps, partGrants, partsOf, pathMatches, permits, placeOf, placed, planner, prepare, print, printReads, random, recorder, ref, reference, referenceRun, refsOf, replayer, resolve, resolveCompiled, restrictMachine, restrictWorld, run, sameResult, sameValue, schedule, splitParts, stepLadder, stepOf, stepRank, stored, syntaxFormat, tag, thrown, toJson, treeNodeEvaluator, typeCheck, typeFromSamples, typeFromSchema, typeIssues, typeName, typePath, typeText, typed, typesOf, valueOfThing, verifyReads, walk, worldThing };
21169
+ export { ATTRIBUTE_RUNGS, CAPS_TYPE, CIRCULAR_LIMIT, CONSTRUCTS, ENVELOPE_KEYS, Failure, GENERATION_LIMIT, Held, JOURNAL, MAX_SYNTAX_ISSUES, 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, agreeTypes, argsKey, ask, atArgsOf, atRuleOf, attributeGraph, attributeTrace, attributeVertexId, boundariesOf, capKeys, check, checkCycles, checkLatent, checkStep, checkSteps, checkSyntax, checkWorld, circularOf, classify, codecLaws, collectOf, compilePath, components, conforms, context, cycles, dataEdges, decodeDomain, decodeLog, decodeValue, derefStep, describe, docEquals, documentKey, 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, ifRunner, intersectCaps, isAlias, isAllowedOrder, isClosure, isEnvelope, isHostThing, isKey, isKind, isNamespace, isRecord, isRef, isStackOverflow, isStep, isTypeRef, join, jsTruthy, kindDocument, kindNamed, kindOf, layers, looksLikeKind, lookupKind, makeContext, mapDocs, mapRefs, member, mergeMachines, mergeWorlds, narrow, nearestWalker, necessary, nodeAt, nodeLayers, ok, parse, partCaps, partGrants, partsOf, pathMatches, permits, placeOf, placed, planner, prepare, print, printReads, random, recorder, ref, reference, referenceRun, refsOf, replayer, resolve, resolveCompiled, restrictMachine, restrictWorld, run, sameResult, sameValue, schedule, splitParts, stepLadder, stepOf, stepRank, stored, syntaxFormat, tag, thrown, toJson, treeNodeEvaluator, typeCheck, typeFromSamples, typeFromSchema, typeIssues, typeName, typePath, typeText, typed, typesOf, valueOfThing, verifyReads, walk, worldThing };
20560
21170
 
20561
21171
  //# sourceMappingURL=index.js.map