type IntVal = number | bigint; /** A bigint that fits the safe-integer range collapses to a number; everything else stays bigint. */ declare function canonInt(n: IntVal): IntVal; declare function addInt(x: IntVal, y: IntVal): IntVal; declare function subInt(x: IntVal, y: IntVal): IntVal; declare function mulInt(x: IntVal, y: IntVal): IntVal; /** Integer division truncating toward zero (matches the existing `Math.trunc(a/b)` semantics). */ declare function intDiv(x: IntVal, y: IntVal): IntVal; declare function intMod(x: IntVal, y: IntVal): IntVal; declare function intAbs(n: IntVal): IntVal; declare function isZero(n: IntVal): boolean; /** Coerce either representation to a double for the f64 math ops (precision loss is acceptable there). */ declare function toF64(n: IntVal): number; /** Three-way compare of two integer values, exact (promotes to bigint when needed). Value-level * analogue of `compareNumbers`, used by the deterministic-core compiler on unwrapped ints. */ declare function cmpIntVal(a: IntVal, b: IntVal): number; /** * The MeTTa term model. A discriminated union on `kind` (convention C1). * Every variant declares ALL nine fields in the SAME order so V8 keeps one * hidden class across atoms (monomorphic property access on the hot path). * Unused fields are `undefined`, never absent, never deleted (C1). */ type MetaType = "Symbol" | "Variable" | "Expression" | "Grounded"; interface SymAtom { readonly kind: "sym"; readonly name: string; readonly items: undefined; readonly value: undefined; readonly typ: undefined; readonly exec: undefined; readonly match: undefined; readonly ground: true; vars: readonly string[] | undefined; } interface VarAtom { readonly kind: "var"; readonly name: string; readonly items: undefined; readonly value: undefined; readonly typ: undefined; readonly exec: undefined; readonly match: undefined; readonly ground: false; vars: readonly string[] | undefined; } interface ExprAtom { readonly kind: "expr"; readonly name: undefined; readonly items: readonly Atom[]; readonly value: undefined; readonly typ: undefined; readonly exec: undefined; readonly match: undefined; /** True iff no variable occurs anywhere inside (a precomputed ground flag): lets `applySubst`, * `atomVars`, and `occurs` short-circuit instantly on closed terms. Computed once at construction. */ readonly ground: boolean; vars: readonly string[] | undefined; } /** A grounded value (LeaTTa `Ground`). Numbers track int vs float so `3` and `3.0` stay distinct. */ type Ground = { readonly g: "int"; readonly n: number | bigint; } | { readonly g: "float"; readonly n: number; } | { readonly g: "str"; readonly s: string; } | { readonly g: "bool"; readonly b: boolean; } | { readonly g: "unit"; } | { readonly g: "error"; readonly msg: string; } | { readonly g: "ext"; readonly kind: string; readonly id: string; }; /** A grounded atom: a structured `Ground` value with a derived type atom, plus optional executor * and custom matcher (used by DAS-style grounded atoms; core built-in ops dispatch by symbol). */ interface GndAtom { readonly kind: "gnd"; readonly name: undefined; readonly items: undefined; readonly value: Ground; readonly typ: Atom; readonly exec: GroundedExec | undefined; readonly match: GroundedMatch | undefined; readonly ground: true; vars: readonly string[] | undefined; } type Atom = SymAtom | VarAtom | ExprAtom | GndAtom; /** A grounded atom's executor: applied when the atom heads an expression `( arg...)`. Receives * the evaluated argument atoms and returns the result atoms, either directly or as a Promise. A * Promise suspends the async runner (as a named async op does) and is refused by the sync runner; * it never widens the atom record, since `exec` stays a single slot. May throw / reject for a * runtime error. */ type GroundedExec = (args: readonly Atom[]) => readonly Atom[] | Promise; type GroundedMatch = (other: Atom) => readonly unknown[]; declare function groundEq(a: Ground, b: Ground): boolean; declare function canInternExprItems(items: readonly Atom[]): boolean; /** Interned symbol atom: equal names share one object (reference equality, low allocation). */ declare function sym(name: string): SymAtom; /** Variable atom. Not interned: freshening needs distinct identities. */ declare function variable(name: string): VarAtom; declare function expr(items: readonly Atom[]): ExprAtom; interface InternTable { readonly buckets: Map; readonly variables: Map; readonly expressions: WeakSet; readonly hasUnsafeGrounded: WeakMap; } declare function createInternTable(): InternTable; declare function internAtom(table: InternTable | undefined, a: Atom): Atom; declare function internExpr(table: InternTable | undefined, a: ExprAtom): ExprAtom; declare function internBuiltExpr(table: InternTable | undefined, a: ExprAtom): ExprAtom; /** The built-in type atom for a grounded value (LeaTTa `getTypes` on grounded). */ declare function groundType(v: Ground): Atom; declare function gnd(value: Ground, typ?: Atom, exec?: GroundedExec, match?: GroundedMatch): GndAtom; /** Grounded literal constructors. */ declare const gint: (n: IntVal) => GndAtom; declare const gfloat: (n: number) => GndAtom; declare const gstr: (s: string) => GndAtom; declare const gbool: (b: boolean) => GndAtom; declare const gunit: GndAtom; declare function metaType(a: Atom): MetaType; declare const mixHash: (h: number, x: number) => number; declare const strHash: (s: string) => number; /** A 32-bit structural hash: equal structures hash equal. O(1) amortised for a fresh atom whose subterms * are already hashed. Collisions are possible, so callers verify a match with `atomEq`. */ declare function hashOf(a: Atom): number; /** Total term size (LeaTTa `Atom.size`): leaves are 1, an expression is 1 + sum of parts. */ declare function atomSize(a: Atom): number; /** All variable names occurring in an atom (LeaTTa `Atom.vars`), in first-seen order, deduped. */ declare function atomVars(a: Atom, out?: string[]): string[]; /** Past this many distinct variables, deduplicating a cache entry by scanning the accumulated list * costs more than hashing it. Below it the scan wins outright and allocates nothing: an expression * carries 5.9 distinct variables on average through a MeTTaSpeak schema registration, and the `Set` * a general dedupe needs was being allocated 4.4M times for that handful of names. */ declare const VARS_SCAN_LIMIT = 16; /** Collect an atom's variable names into `out`, deduping via the shared `seen` set (O(1) membership instead * of a linear `out.includes`). Hot accumulation loops (scopeVars/frameVars) reuse one `seen` across many * atoms so the whole walk stays linear; `atomVars` is the one-shot wrapper that seeds `seen` from `out`. */ declare function collectVars(a: Atom, out: string[], seen: Set): void; /** The distinct variable names of `a`, first-seen order, straight from the shared cache. Do not mutate * the result: it is the cache entry itself, shared with every other caller. `atomVars` returns a copy. * Callers testing a property of a term's variables use this to avoid rebuilding the list. */ declare function varNamesOf(a: Atom): readonly string[]; /** The names a filtered collection is looking for: a list while it is short enough that scanning beats * hashing, a set once it is not. A rewrite-heavy program spans both — a schema registration carries 3 * binding names, a forward-chaining saturation carries 108 over a live set of 436. */ type VarProbe = readonly string[] | ReadonlySet; /** Append the variables of `a` that occur in `want`, in `collectVars` order and without duplicates. * `want` and `out` hold a binding's variables, which stay small (3.0 on average through a MeTTaSpeak * schema registration), so a linear scan beats the `Set` that `collectVars` needs for its unbounded * live set — and nothing is allocated per call. */ declare function collectVarsAmong(a: Atom, want: VarProbe, out: string[]): void; /** `collectSubstitutedVars` filtered to `want`, in the same order. */ declare function collectSubstitutedVarsAmong(template: Atom, name: string, value: Atom, want: VarProbe, out: string[]): void; /** Collect the variable order produced by replacing `name` with `value` in `template` once. */ declare function collectSubstitutedVars(template: Atom, name: string, value: Atom, out: string[], seen: Set): void; /** The empty expression `()` (LeaTTa `Atom.empty`), the success marker used by `assert*`. */ declare const emptyExpr: ExprAtom; /** Type names the engine treats as one numeric family. `Number` is Hyperon's numeric type; * `Int`/`Integer`/`Double`/`Float` are annotations common in other MeTTa dialects, accepted as `Number` * aliases by the type checker (`matchType`) and the scalar compiler (`scalarDeclaredReturn`) so typed * numeric programs from those dialects run. Hyperon itself knows only `Number` and rejects the aliases. */ declare const NUMBER_FAMILY_TYPE_NAMES: ReadonlySet; /** Is this atom an `(Error ...)` expression? */ declare function isErrorAtom(a: Atom): boolean; declare const isExpr: (a: Atom) => a is ExprAtom; declare const isVar: (a: Atom) => a is VarAtom; declare const isSym: (a: Atom) => a is SymAtom; declare const isGnd: (a: Atom) => a is GndAtom; /** Structural equality. Interned symbols short-circuit to reference identity. The recursive `atomEqRec` * is the fast, memoised common path (no per-call allocation); a term deep enough to exhaust the native * stack throws, and the catch re-runs the comparison iteratively (`atomEqIter`) after its frames unwind. * The wrapper adds one try/catch per top-level call — the recursion itself stays raw. */ declare function atomEq(a: Atom, b: Atom): boolean; interface BitmapNode { readonly datamap: number; readonly nodemap: number; /** Payload pairs first (`[k0, v0, k1, v1, ...]` in datamap bit order), then child nodes in nodemap bit * order. */ readonly slots: ReadonlyArray; } /** Keys sharing one full 32-bit hash. `datamap: -1` is the discriminant (a real datamap is >= 0). */ interface CollisionNode { readonly datamap: -1; readonly keys: ReadonlyArray; readonly vals: ReadonlyArray; } type PNode = BitmapNode | CollisionNode; /** A persistent string -> V map. `null` is the empty map. */ type PMap = PNode | null; declare const emptyPMap: null; /** The value for `key`, or `undefined` if absent. */ declare function pmGet(map: PMap, key: string): V | undefined; /** Set `key` to `val`, or remove it when `val` is `undefined`. Returns a new map sharing untouched nodes. */ declare function pmSet(map: PMap, key: string, val: V | undefined): PMap; interface KeyStackNode { readonly key: string; readonly prev: KeyStack; } type KeyStack = KeyStackNode | null; interface PTable { readonly root: PMap; readonly size: number; /** Keys in reverse first-insertion order. May contain dead keys after a delete. */ readonly keys: KeyStack; } declare function emptyPTable(): PTable; declare function ptGet(t: PTable, key: string): V | undefined; declare function ptHas(t: PTable, key: string): boolean; /** Set `key` to `val` (`undefined` values are not representable; use `ptDelete`). */ declare function ptSet(t: PTable, key: string, val: V): PTable; declare function ptDelete(t: PTable, key: string): PTable; /** Entries in first-insertion order (JS Map order for delete-free histories). */ declare function ptEntries(t: PTable): Array<[string, V]>; /** Keys in first-insertion order (live keys only). */ declare function ptKeys(t: PTable): string[]; /** One key that differs between two maps. `before`/`after` are `undefined` where the key is absent. */ interface PMapChange { readonly key: string; readonly before: V | undefined; readonly after: V | undefined; } /** Every key whose value differs between two maps, in no particular order. * * Costs what CHANGED, not what is stored, whenever the two share structure — which two versions of the * same map always do. Comparing two maps built independently is the worst case and walks both. */ declare function pmDiff(before: PMap, after: PMap): Array>; /** {@link pmDiff} over two tables. */ declare function ptDiff(before: PTable, after: PTable): Array>; interface LogNode { readonly atom: Atom; readonly prev: AtomLog; readonly size: number; /** Count of non-ground atoms in this log; the index fast path is valid only when this is 0. */ readonly nonGround: number; } /** An atom log: `null` is empty; otherwise the most recently appended atom and the rest. */ type AtomLog = LogNode | null; interface ValRel { readonly tag: "val"; readonly x: string; readonly a: Atom; readonly y: undefined; } interface EqRel { readonly tag: "eq"; readonly x: string; readonly a: undefined; readonly y: string; } type BindingRel = ValRel | EqRel; type Bindings = readonly BindingRel[]; declare const emptyBindings: Bindings; /** The atom bound to `$x` by a direct `val` relation, if any (eq aliases are not followed). */ declare function lookupVal(b: Bindings, x: string): Atom | undefined; /** Remove direct value bindings for `x`; equality relations remain. */ declare function removeVal(b: Bindings, x: string): Bindings; /** True if the binding set carries a variable loop: some variable is reachable from itself by following * value bindings (`$x ← (.. $y ..)`, `$y ← (.. $x ..)`), so the set has no finite instantiation. Deep and * transitive, mirroring Hyperon `Bindings::has_loops` (a DFS over variable→value edges) and CeTTa * `bindings_atom_has_loop`. Every matcher call site drops a looping set (`if (!hasLoop(m))`), the same * boundary at which Hyperon's `match_atoms` filters `!binding.has_loops()`, so a cyclic unification that a * direct match admits (`matchAtomsWith` has no occurs check, faithfully — LeaTTa's occurs check lives only * in reconcile) never reaches the evaluator. * * Was shallow, catching only the one-hop self relations `$x ← $x` / `$x = $x`, which let an indirect cycle * like `$x ← (→ $x A)` through. That is a first-bind cycle (each variable bound once); the occurs check in * `reconcile`/`addVarBinding` only fires on a SECOND bind of a variable, so it never sees such a cycle, and * the fixpoint resolver then unrolled it to depth `size(b)` and overflowed the native stack — Nil * Geisweiller's bfc-xp `obc` proof search at size ≥ 7. Deep detection is exactly the guard that makes * resolution terminate (Alloy model MT1: a binding graph is loop-free iff every variable resolves to a * finite normal form; a first-bind-only cycle is reachable, so the check must run here at the match * boundary, not only on reconcile). A variable bound directly to itself (`$x ← $x`) is an identity, not a * loop, matching Hyperon's short-circuit; it is caught above and treated as a loop only in that trivial * self form to preserve the previous behaviour exactly. * * The DFS is iterative (an explicit stack, never native recursion) so detecting a loop can never itself * overflow, and 3-colours each variable so it is visited once: O(vars + total value size), like Hyperon's * bitset walk. `atomVars` is cached by object identity, so a DAG-shared value is scanned once. */ declare function hasLoop(b: Bindings): boolean; /** `hasLoop` for a `merge` result whose base was already loop-free. * * `merge` builds every output by prepending relations onto its base: `addVarBinding` prepends a value * relation only for a variable the current set leaves unbound (a bound variable either no-ops or goes * through `reconcile`, whose own extensions bottom out in the same prepend-or-no-op steps), and * `addVarEquality` prepends an equality. The base is therefore a reference-identical suffix of the * result, no prepend can shadow a base variable's first value, and the base's first-value graph embeds * unchanged in the result's. A cycle in the result must then pass through a prepended value binding, * so running the colour DFS only from the prepended variables is answer-equivalent to the full scan. * The self-relation quick checks run on the prepended prefix alone for the same reason. Anything that * is not a reference-identical suffix extension falls back to the full `hasLoop`. * * Callers must pass the exact base the result was merged from, and that base must itself be loop-free; * the equivalence fuzz in match.test.ts pins this predicate to `hasLoop` over merge outputs. */ declare function hasLoopFromBase(merged: Bindings, base: Bindings): boolean; /** Bind `$x ← a`, dropping any previous value binding for `$x`. Raw: no consistency check. */ declare function addValRaw(b: Bindings, x: string, a: Atom): Bindings; /** Prepend `$x ← a` when the caller has already proved `$x` has no direct value binding. */ declare function prependValRaw(b: Bindings, x: string, a: Atom): Bindings; /** Add the alias `$x = $y` (a no-op when `x = y`). Raw: no consistency check. */ declare function addEqRaw(b: Bindings, x: string, y: string): Bindings; /** Build a single value relation. The canonical `ValRel` constructor for callers outside this module. */ declare function makeValRel(x: string, a: Atom): ValRel; /** Build a single variable-equality relation. */ declare function makeEqRel(x: string, y: string): EqRel; /** Build a binding set from an explicit list of relations (newest-first). */ declare function fromRelations(rels: readonly BindingRel[]): Bindings; /** Number of relations in the set. */ declare function size(b: Bindings): number; /** Whether the set has no relations. */ declare function isEmpty(b: Bindings): boolean; /** Every relation, newest-first (the order `merge` folds them in). */ declare function relations(b: Bindings): Iterable; /** Each current value binding as `[var, atom]`. */ declare function valEntries(b: Bindings): Iterable; /** Whether any value binding satisfies `pred`. */ declare function someVal(b: Bindings, pred: (x: string, a: Atom) => boolean): boolean; /** Whether the set carries any `eq` alias. */ declare function hasEq(b: Bindings): boolean; /** Every variable name the set mentions: each relation's subject plus an `eq`'s other endpoint. A name * outside this list misses in `lookupVal` and cannot be an `eq` endpoint, so restricting a binding to a * set of live variables reads that set only through its intersection with these names. Callers holding an * expensive live set can therefore intersect first and skip building the rest of it. * * Returned as a list while it is short enough that scanning beats hashing, and as a set once it is not. * The caller probes it once per live variable, so it wants the set anyway at that size — and deduplicating * a few hundred names by scanning the accumulated list is quadratic on its own. */ declare function bindingNames(b: Bindings): VarProbe; /** How many distinct names a probe holds. */ declare function probeSize(w: VarProbe): number; /** Each `eq` alias relation, newest-first. */ declare function eqRelations(b: Bindings): Iterable; interface Space { add(atom: Atom): void; /** Remove the first structurally-equal atom; returns whether one was removed. */ remove(atom: Atom): boolean; /** All binding sets under which `pattern` matches a stored atom. `freshen`, if given, is applied * to each stored atom before matching (rule-variable freshening). */ query(pattern: Atom, freshen?: (a: Atom) => Atom): Bindings[]; atoms(): readonly Atom[]; /** Remove every atom, when the backend can do it in one pass. Optional so a backend that cannot * (a remote store, say) is unaffected; the caller falls back to removing one at a time. */ clear?(): void; } /** In-memory space with a symbol-head index for ordinary expression queries. */ declare class InMemorySpace implements Space { private readonly store; private readonly byHead; private readonly unindexed; add(atom: Atom): void; remove(atom: Atom): boolean; private indexedCandidates; query(pattern: Atom, freshen?: (a: Atom) => Atom): Bindings[]; atoms(): readonly Atom[]; clear(): void; } type ReduceEffect = { readonly kind: "addAtom"; readonly space: Atom; readonly atom: Atom; } | { readonly kind: "removeAtom"; readonly space: Atom; readonly atom: Atom; } | { readonly kind: "bindToken"; readonly name: string; readonly atom: Atom; }; type ReduceResult = { readonly tag: "ok"; readonly results: readonly Atom[]; readonly effects?: readonly ReduceEffect[]; } | { readonly tag: "runtimeError"; readonly msg: string; } | { readonly tag: "incorrectArgument"; readonly msg: string; } | { readonly tag: "noReduce"; }; type GroundFn = (args: readonly Atom[]) => ReduceResult; type GroundingTable = Map; /** Return the type carried by a grounded operation, if it has one. */ declare function groundedOperationType(op: GroundFn): Atom | undefined; /** Replace the line-output sink used by `println!`/`trace!` (returns the previous sink). */ declare function setOutputSink(fn: (line: string) => void): (line: string) => void; /** Replace the raw (no-newline) sink used by `print!` (returns the previous sink). */ declare function setRawSink(fn: (text: string) => void): (text: string) => void; /** Enable or disable host effects such as file IO and git imports for this process. */ declare function setHostEffectsEnabled(enabled: boolean): void; /** Three-way compare: exact for two Ints (promoting to bigint as needed), f64 otherwise. */ declare function compareNumbers(a: Atom, b: Atom): number | undefined; /** Names of the PeTTa-compat grounded ops. They yield to user `=` rules (PeTTa is rules-first, builtins as * fallback), so a program that defines its own e.g. `sort`/`length` is not shadowed by the stdlib one. */ declare const pettaOpNames: ReadonlySet; /** Every name the interpreter grounds to a built-in function. Some are also declared in MeTTa source and * some are not, so this is the only complete list of what a program can call without defining it — which * is what a tool documenting or completing the language needs. `pettaOpNames` is the PeTTa-compat subset. */ declare const builtinOpNames: ReadonlySet; /** True only for the unchanged built-in function registered under this name. */ declare function isTableSafeGroundedOp(name: string, fn: GroundFn): boolean; /** The arithmetic / boolean / list-surgery / math grounding core every KB starts with. */ declare function baseTable(): GroundingTable; /** The full standard-library grounding table (base + stdlib grounded ops + PeTTa-compat). Later entries do * not override earlier ones (Map keeps the first), so Hyperon ops win any name shared with PeTTa-compat. */ declare function stdTable(): GroundingTable; /** Dispatch `op` through the grounding table, or `noReduce` if unknown. */ declare function callGrounded(gt: GroundingTable, op: string, args: readonly Atom[]): ReduceResult; /** Native recursion stays on the fast path below this logical user-call depth. */ declare const EVALUATION_TRAMPOLINE_DEPTH = 32; /** Hard cap on natively nested evaluation frames. Logical depth misses tail transfers (they * reuse their level), so a long tail chain nests one native generator quartet per step; at * roughly 340 bytes a frame the default Node stack fits about 250 of them. Handing off to the * heap continuation driver at half that keeps headroom for grounded-op internals while leaving * ordinary deep evaluation on the fast native path. */ declare const NATIVE_EVALUATION_NESTING_LIMIT = 128; /** The default language-level call bound. Explicit `max-stack-depth 0` remains unlimited. */ declare const DEFAULT_MAX_STACK_DEPTH = 320; interface EvaluationDepthSpan { base: number; peak: number; } type EvaluationDepthBoundary = "overflow" | "handoff"; /** A depth-bound branch cut raised inside compiled evaluation. The compiler unwinds to its evaluator * boundary, which turns the attempted call and the state immediately before it into the normal * `(Error StackOverflow)` branch result. */ declare class EvaluationDepthOverflow extends Error { readonly atom: Atom; readonly state?: unknown | undefined; constructor(atom: Atom, state?: unknown | undefined); } /** A compiled nested call reached the heap-evaluation boundary. The compiled attempt is abandoned before * the call runs, then the evaluator replays the original application through its explicit driver. */ declare class EvaluationDepthHandoff extends Error { readonly atom: Atom; readonly state?: unknown | undefined; constructor(atom: Atom, state?: unknown | undefined); } /** The active user-equation call lineage for one evaluation branch. Tail transfers reuse the current * level. Nested calls enter one level and leave it in `finally`, so host frames do not define the value. * A positive bound N is exclusive: attempting level N is the StackOverflow cut, matching Hyperon's * `depth >= max-stack-depth` check. Zero remains the explicit unlimited setting. */ declare class EvaluationDepth { private level; private observed; private readonly floor; private marker; /** Native evaluation-frame nesting. Unlike `level`, this counts every frame descent, so a chain * of tail transfers (which reuse their logical level) still raises it. The evaluator hands a * branch to the heap continuation driver when this crosses the trampoline threshold, which is * what keeps arbitrarily long tail loops off the JS stack. */ private nativeLevel; constructor(level?: number); get current(): number; get native(): number; enterNative(): void; leaveNative(): void; get maximum(): number; private observe; tryEnter(limit: number): boolean; /** Enter without constructing an error atom. The common path returns `undefined`; callers materialize * boundary diagnostics only for the one attempted call that cannot enter. */ enterBoundary(limit: number, handoffDepth?: number): EvaluationDepthBoundary | undefined; enter(atom: Atom, limit: number, state?: unknown, handoffDepth?: number): void; leave(): void; beginSpan(): EvaluationDepthSpan; span(marker: EvaluationDepthSpan): number; rebase(marker: EvaluationDepthSpan): void; endSpan(marker: EvaluationDepthSpan): number; canReplay(span: number, limit: number): boolean; replay(span: number): void; fork(): EvaluationDepth; absorb(branch: EvaluationDepth): void; } /** Thrown by a compiled node when it meets a case it cannot handle faithfully (division by zero); * the caller catches it (along with a native stack `RangeError`) and re-runs the call in the * interpreter, which is sound because the compiled subset is side-effect-free. */ declare const BAIL: unique symbol; declare class Tup { readonly v: readonly IntVal[]; constructor(v: readonly IntVal[]); } /** A boxed f64 inside the native frame. Integers remain bare `IntVal`; the wrapper keeps `3` distinct * from `3.0` even though both use a JavaScript number. */ declare class FloatVal { readonly n: number; constructor(n: number); } type FrameVal = IntVal | FloatVal | Tup | Atom; type Ty = "int" | "float" | "number" | "bool" | "atom" | "sym" | `tuple${number}` | `symtuple${number}`; /** A compiled pure function. `run` is filled after the whole dependency group is compiled, so mutual * recursion resolves through the holder object. */ interface FunctionalHolder { kind: "functional"; name: string; arity: number; retType: Ty; paramTypes: Ty[]; /** The run memoises, so its step accounting is the cost of the first computation replayed on every hit, * which is not what the interpreter would spend recomputing. Only a holder without a memo reports its * steps back to the evaluator. */ memoized: boolean; run: (vals: FrameVal[], runtime?: FunctionalRuntime, entered?: boolean) => FrameVal | boolean; } /** A deterministic constructor dispatch with at least one native value- or atom-returning clause. Clauses * outside the subset remain interpreter fallbacks, so exclusivity is proved over all clauses. */ interface ScalarHolder { kind: "scalar"; name: string; arity: number; retType: "number" | "atom"; paramTypes: Ty[]; clauseCount: number; run: (vals: FrameVal[], runtime?: FunctionalRuntime, entered?: boolean) => FrameVal | boolean; } interface FunctionalRuntime { readonly depth: EvaluationDepth; readonly limit: number; readonly counterBase: number; readonly counterLimit: number | undefined; counterDelta: number; freshSuffix: string; } interface CompiledAtomResult { readonly atom: Atom; readonly bnd: Bindings; } interface CompiledRunResult { readonly results: readonly CompiledAtomResult[]; readonly counterDelta: number; readonly state?: St; /** The holder reduced each result fully and checked that the current world cannot change that result. * The evaluator may skip the ordinary RHS reduction for this call. */ readonly resultsFinal?: boolean; } interface RewriteHolder { kind: "rewrite"; arity: number; retType: Ty; paramTypes: Ty[]; ruleCount: number; run: (partAtoms: readonly Atom[]) => CompiledRunResult | undefined; } interface SymbolicHolder { kind: "symbolic"; arity: number; clauseCount: number; run: (partAtoms: readonly Atom[], counter: number) => CompiledRunResult | undefined; } interface CompiledImpureOps { /** Per-evaluation logical call lineage. The evaluator supplies it at the compiled boundary; recursive * holders enter it before invoking another user equation. */ readonly evaluationDepth?: EvaluationDepth; readonly maxStackDepth?: number; /** Remaining evaluator fuel at the compiled boundary. Bounds the imperative tail-call driver: each * tail transfer debits one unit, mirroring the interpreter's per-transfer cost, so a runaway impure * tail cycle cuts with the same StackOverflow atom instead of spinning. */ readonly fuel?: number | undefined; readonly addAtom: (env: MinEnv, st: St, space: Atom, atom: Atom) => St | undefined; /** Solutions of a `(match space pattern template)` under the current world: the instantiated * template plus that solution's bindings, in the interpreter's own candidate order, and the * fresh-variable counter advance the interpreted match would have cost. Undefined = not a space. */ readonly matchSolutions?: (env: MinEnv, st: St, space: Atom, pattern: Atom, template: Atom) => { readonly pairs: ReadonlyArray; readonly counterDelta: number; } | undefined; /** The add-if-absent idiom on a ground atom: exact-membership probe, then append when absent. * Undefined when the fast probe is unsound for this space (non-ground facts, static facts of the * same head, state handles), sending the caller back to the interpreter. */ readonly addIfAbsent?: (env: MinEnv, st: St, space: Atom, atom: Atom) => { readonly added: boolean; readonly state: St; } | undefined; } type ImpEval = { readonly value: Atom; readonly st: St; } | typeof BAIL; /** A tail call another (or the same) imperative holder should continue. Produced only by a call in * tail position; the holder-entry driver loops on it, so a tail-recursive impure chain (`build`, * a saturation walk) runs iteratively instead of growing the host stack one `run` frame per step. */ interface ImpTail { readonly tail: true; readonly op: string; readonly holder: ImperativeHolder; readonly vals: readonly Atom[]; readonly st: St; } type ImpStep = ImpEval | ImpTail; type ImpEmit = (value: Atom, st: St) => St | typeof BAIL; type ImpForEach = (slots: readonly Atom[], st: St, ops: CompiledImpureOps, discard: boolean | undefined, emit: ImpEmit) => St | typeof BAIL; interface ImperativeHolder { kind: "imperative"; arity: number; clauseCount: number; run: (partAtoms: readonly Atom[], st: St, ops: CompiledImpureOps, discard?: boolean) => ImpEval; runForEach?: ImpForEach; /** The compiled body, exposed so the tail-call driver can continue a chain without re-entering * `run` (which would rebuild the loop and recurse). */ body?: ImpCompiled; } interface NondetHolder { kind: "nondet"; arity: number; clauseCount: number; /** Prefer direct depth-first search when a later recursive call consumes a clause-local field * produced by an earlier answer. Independent overlapping calls retain table-first evaluation. */ preferDirectForModed: boolean; run: (env: MinEnv, partAtoms: readonly Atom[], st: St, ops: CompiledImpureOps, fuel?: number) => CompiledRunResult | undefined; } type CompiledHolder = FunctionalHolder | ScalarHolder | RewriteHolder | SymbolicHolder | ImperativeHolder | NondetHolder; type CompiledFns = Map; /** Compile a single-tail-call numeric functor to one JS source function replacing `makeRun`'s loop. * * The closure nodes evaluate the same body as a tree of `node(frame, runtime)` calls, which V8 cannot * inline through, and every self-call allocates an argument frame. Emitting the loop as source lets the * JIT unbox the whole body into machine arithmetic: the trial-division loop this targets measured 16x * faster hand-written than through the closures, answers identical. * * Faithfulness is the whole design: * - Ints run as plain numbers with a `Number.isSafeInteger` guard after each `+`/`-`/`*`, which is * exactly `addInt`'s own fast path; the guard failing is the case where `addInt` promotes to bigint, * and it throws `EMIT_RERUN` so the closures take the call instead. `%` and `/` of safe ints are * always safe, so they carry no guard, and both check the divisor first and throw `BAIL` on zero, * in the closure nodes' own evaluation order. * - Fuel is charged where the closures charge it and nowhere else: +1 per loop iteration after the * first with the same limit check, +2 after an `if` condition, +1 after a `let` value. A body that * declines emission anywhere keeps the closures, so a decline is always safe. * - Anything outside the proven subset declines: float or atom types, tuple parameters, any call * (including a non-tail self-call), `unify`, symbols. The subset is what the profile showed the time * in, and every widening is another differential surface. */ declare function emitNumericTailLoop(params: readonly ParamPat[], paramTypes: readonly Ty[], retType: Ty, body: Atom, self: string): ((vals: FrameVal[], runtime: FunctionalRuntime) => FrameVal | boolean) | undefined; type ParamPat = string | string[]; type Skel = { readonly t: 0; readonly a: Atom; } | { readonly t: 1; readonly i: number; } | { readonly t: 2; readonly items: readonly Skel[]; readonly arith: string | undefined; }; interface SkelGoal { readonly pat: Skel; /** Empty string when `match` is set: a space-match goal has no dispatched function. */ readonly fn: string; readonly args: readonly Skel[]; /** A `(match space pattern template)` goal, served by the injected immutable matcher with the * solutions bound back onto the cells. The JIT declines any group carrying one, so only the * skeleton interpreter and the immutable engine ever see it. */ readonly match?: { readonly space: Skel; readonly pattern: Skel; readonly template: Skel; }; } type SkelTail = { readonly tag: "tpl"; readonly tpl: Skel; } | { readonly tag: "empty"; } | { readonly tag: "call"; readonly fn: string; readonly args: readonly Skel[]; } | { readonly tag: "match"; readonly space: Skel; readonly pattern: Skel; readonly template: Skel; }; type SkelBody = { readonly tag: "seq"; readonly goals: readonly SkelGoal[]; readonly tail: SkelTail; } | { readonly tag: "if"; readonly op: string; readonly x: Skel; readonly y: Skel; readonly then: SkelBody; readonly els: SkelBody; }; interface SkelClause { /** Number of clause-variable slots (the dispatch frame's length). */ readonly n: number; /** Head argument skeletons (the head symbol is implied by the dispatch table). */ readonly lhsArgs: readonly Skel[]; readonly body: SkelBody; } /** Compile one answer-dependent recursive search group for query-directed dispatch. Independent * overlapping recursion stays on moded tabling and returns undefined, so the caller can use the full * compiler when the query needs another compiled fragment. */ declare function compileDependentNondetGroup(env: MinEnv, root: string): CompiledFns | undefined; interface ImpCompiled { readonly node: ImpNode; readonly forEach?: ImpForEach; readonly directEffect: boolean; readonly callees: ReadonlySet; } type ImpNode = (slots: readonly Atom[], st: St, ops: CompiledImpureOps, discard?: boolean) => ImpStep; /** Compile every compilable pure single-clause function in `env` to a memoised native closure. * Phase 1 infers return types (fixpoint, optimistic over recursion). Phase 2 compiles bodies with * those types and drops any that fail end-to-end (a call to an uncompilable function fails too). */ declare function compileEnv(env: MinEnv): CompiledFns; /** Run a compiled function, returning an ordered result bag, or `undefined` to fall back to the interpreter * when the call falls outside the proven subset. */ declare function runCompiled(env: MinEnv, op: string, partAtoms: readonly Atom[], st: St, ops?: CompiledImpureOps, discard?: boolean, fuel?: number, depth?: EvaluationDepth): CompiledRunResult | undefined; declare function runCompiledEffectCount(env: MinEnv, op: string, partAtoms: readonly Atom[], st: St, ops: CompiledImpureOps, depth?: EvaluationDepth): { readonly count: number; readonly state: St; } | undefined; type TermId = number; type FactId = number; declare class Int32Chunks { private readonly chunks; private tail; length: number; push(value: number): number; get(index: number): number; } declare function canCompactAtom(a: Atom): boolean; declare class FlatAtomSpaceTable { readonly termKind: Int32Chunks; readonly termStart: Int32Chunks; readonly termLen: Int32Chunks; readonly termHash: Int32Chunks; readonly termGround: Int32Chunks; readonly termData: Int32Chunks; readonly factRoot: Int32Chunks; readonly factHeadSym: Int32Chunks; suspectScanUpTo: number; readonly suspectHeads: Set; suspectTokenA: number; suspectTokenB: number; /** Per-term verdicts under the current tokens: 0 unknown, 1 clean, 2 suspect. */ termSuspect: Int8Array; /** Per-symbol `isDefinedSym` answers under the current tokens: 0 unknown, 1 no, 2 yes. */ symDefined: Int8Array; /** The encoded mirror of the deep normal-form walk: a term is suspect when it is a defined symbol, * an expression whose head is not a symbol, an expression with a defined head symbol, or an * expression with a suspect child. Iterative so a deep numeral cannot overflow the host stack. */ termIsSuspect(root: TermId, isDefinedSym: (name: string) => boolean): boolean; private symIsDefined; private slots; private slotCount; private missSlot; private missHash; private readonly symByName; private readonly intNumberGrounds; private readonly floatGrounds; private readonly groundByKey; private readonly varByName; private readonly termFacts; private readonly nestedHeadFacts; private readonly symbols; private readonly grounds; private readonly vars; private readonly decoded; private readonly termIdOf; get factCount(): number; insertFact(atom: Atom): FactId; factsForTerm(term: TermId): readonly FactId[]; insertAtom(atom: Atom): TermId; private insertAtomUncached; lookupAtom(atom: Atom): TermId | undefined; private lookupAtomUncached; decodeTerm(term: TermId): Atom; private decodeTermUncached; isTermGround(term: TermId): boolean; headSymOf(term: TermId): number; lookupHeadSym(name: string): number | undefined; factsForNestedPattern(pattern: Atom): readonly FactId[] | undefined; private internSym; private internGround; private lookupGround; private internNumericGround; private internGroundByKey; private internVar; private internLeaf; private lookupLeaf; private internExpr; private lookupExpr; private pushTerm; private recordMiss; private growSlots; } declare class FlatAtomSpace { private readonly table; private readonly ranges; private readonly dead; readonly liveCount: number; readonly nonGroundCount: number; private arr; private constructor(); static empty(): FlatAtomSpace; static fromAtoms(atoms: readonly Atom[]): FlatAtomSpace | undefined; get size(): number; /** Append a batch as new visible facts. Returns undefined when some atom is not flat-storable (a * grounded executor/matcher); the caller keeps such a batch on the plain log instead. */ appendAll(atoms: readonly Atom[]): FlatAtomSpace | undefined; removeOne(atom: Atom): FlatAtomSpace; exactCount(atom: Atom): number; candidatesFor(patternHead: string | undefined, pattern?: Atom): Iterable; toArray(): Atom[]; /** Columnar mirror of the `&self` direct tally in eval.ts: over the visible facts the head filter * admits (head symbol `patternHead` or no symbol head, same filter as `candidatesFor`), count the * ones an all-distinct-variable pattern `(k $v..)` of `arity` items unifies with, without decoding * any fact. `iterated` is the admitted total (it advances the candidate counter). */ countHeadArity(patternHead: string, arity: number): { count: number; iterated: number; }; /** Whether some stored fact the head filter admits contains a defined symbol or a non-symbol * expression head anywhere — the deep normal-form question, answered on the encoded terms with no * decode. Each distinct term is judged once per token state (the shared table is append-only; * repeated calls only visit facts inserted since the last call) and a suspect fact pins its head * symbol. `tokenA`/`tokenB` version `isDefinedSym`: when either moves the scan restarts, because * a new rule or grounded registration can make an old fact suspect. Dead and version-invisible * facts are included on purpose: a stale positive only widens a conservative caller's answer, * never narrows it. */ anySuspectFactFor(head: string | undefined, isDefinedSym: (name: string) => boolean, tokenA: number, tokenB: number): boolean; roundTrip(atom: Atom): Atom; private decodeFact; private visibleFactIds; private factVisible; } /** Observable effects an evaluator operation may perform. */ type GroundedOperationEffect = "Pure" | "World" | "Host" | "AsyncHost"; interface BuiltinGroundedOperation { readonly name: string; readonly operation: GroundFn; readonly effect: GroundedOperationEffect; } /** Attach an effect declaration to an operation so environments rebuilt from its grounding table retain it. */ declare function declareGroundedOperationEffect(operation: GroundFn, effect: GroundedOperationEffect): void; /** Return the effect declaration attached to an operation, if one was supplied. */ declare function groundedOperationEffect(operation: GroundFn): GroundedOperationEffect | undefined; /** Register a grounded operation that is installed in each subsequently created environment. * * Repeating the same registration is a no-op. A package cannot silently replace another package's * operation or change its declared effect. */ declare function registerBuiltinGroundedOperation(name: string, operation: GroundFn, effect?: GroundedOperationEffect): void; /** A stable snapshot of globally registered grounded operations in registration order. */ declare function registeredBuiltinGroundedOperations(): readonly BuiltinGroundedOperation[]; interface RangeEntry { readonly value: Atom; readonly occurrence: number; readonly atom: Atom; } interface ArityColumn { readonly total: number; readonly entries: readonly RangeEntry[]; } interface SortedColumn { readonly functor: string; readonly argPosition: number; readonly totalCandidates: number; readonly arities: ReadonlyMap; } interface FactIdView { readonly count: number; ids(): Iterable; } /** Compact storage for static symbol-headed expression facts. * * Fact ids are the source positions passed to `fromAtoms`. Head keys use the evaluator's `headKey` * format for the supported fact shape: the symbol name at expression position 0. */ declare class StaticCompactBase { private readonly table; private readonly headFacts; readonly size: number; private readonly columnCache; private readonly factMemo; private memoizeFactDecode; private constructor(); /** Encode all atoms as facts 0..n-1. The batch is rejected if any fact is not compactable or is * not a symbol-headed expression. */ static fromAtoms(atoms: readonly Atom[]): StaticCompactBase | undefined; factAtom(id: number): Atom; /** Switch `factAtom` to per-fact memoized decoding: repeated reads of a fact return the identical * object. The evaluator wiring requires this (its evaluated-atoms and freshen caches key on object * identity); the unmemoized default keeps the standalone store's steady heap flat. */ enableDecodeMemo(): void; /** Structural membership without decoding: whether some stored fact equals `atom`. The interned term * table gives each distinct term one id, so equality is an id lookup plus a per-term fact check. */ hasFact(atom: Atom): boolean; /** Whether the functor stores two structurally identical facts. Interning makes duplicate facts share * one root term id, so this is a Set scan over the bucket's root ids, never a decode. */ hasDuplicateFacts(headKey: string): boolean; factsForHead(headKey: string): FactIdView; equalRange(headKey: string, argPos: number, value: Atom): readonly number[]; bucketSize(headKey: string, argPos: number, value: Atom): number; numericRange(headKey: string, argPos: number, low: Atom | undefined, high: Atom | undefined, incLow: boolean, incHigh: boolean): readonly number[] | undefined; private column; private buildColumn; private buildNumericColumn; private buildKeyColumn; private argumentTerm; private termValue; private equalNumeric; private countEqualNumeric; private filteredNumericIds; private equalKeyed; private countEqualKeyed; private keyBounds; private decodeTermFresh; } declare class StaticAtomStore { private readonly slots; private ids; private base; private arr; get length(): number; /** The compact base, when a compaction sweep installed one. */ get compactBase(): StaticCompactBase | undefined; push(atom: Atom): void; get(index: number): Atom; /** Install the compaction result: `factIds[slot]` is the base fact id for compacted slots and * OBJECT_SLOT elsewhere. Compacted slots release their object references. */ adoptCompact(base: StaticCompactBase, factIds: Int32Array): void; /** De-compaction for one functor: restore the given slots to plain object storage (the atoms are * decoded through the memoized base, so identity stays stable for anything already handed out). */ restoreSlots(slots: Int32Array): void; /** Membership by structural equality. Object slots compare directly; compacted facts resolve through * the base's interned term table without decoding. */ hasAtom(atom: Atom): boolean; /** `some` over the OBJECT slots only. Used by the custom-matcher scan: a compacted fact passed * `canCompactAtom`, so it cannot contain a custom grounded matcher and never satisfies that scan. */ someObject(predicate: (atom: Atom) => boolean): boolean; [Symbol.iterator](): Iterator; /** Materialize the full slot-order list (the `get-atoms` / variable-headed-pattern enumeration). * Memoized until the store changes; callers must not mutate the result. */ toArray(): Atom[]; } type TraceEvent = { readonly kind: "reduce"; readonly atom: string; } | { readonly kind: "grounded"; readonly op: string; } | { readonly kind: "specialize"; readonly from: string; readonly to: string; } | { readonly kind: "overflow"; readonly atom: string; } | { readonly kind: "compiled"; readonly op: string; readonly holder: string; }; type TraceSink = (event: TraceEvent) => void; declare const TAG_ARITY = 0; declare const TAG_SYMBOL = 1; declare const TAG_NEWVAR = 2; declare const TAG_VARREF = 3; /** Interns symbols and grounded values to dense integer ids, with a reverse map so a flat atom decodes * back exactly. Symbols and grounds share the id space (a ground's id reconstructs the ground). */ declare class Interner { private readonly byKey; private readonly entries; private add; internSym(name: string): number; internGround(value: Ground): number; /** The id for a symbol/ground if already interned, else undefined (a pattern symbol absent from the * KB can never match, so its lookup short-circuits). */ lookupSym(name: string): number | undefined; lookupGround(value: Ground): number | undefined; /** Reconstruct the atom for a leaf id. */ decodeLeaf(id: number): Atom; get size(): number; } /** Encode an atom into the token array `out`, interning leaves. `varMap` assigns de Bruijn indices to * variable names (shared across one atom so repeated variables become VARREF). */ declare function encodeInto(a: Atom, out: number[], it: Interner, varMap: Map): void; /** Encode a single atom to a token array. */ declare function encodeAtom(a: Atom, it: Interner): number[]; /** Decode the token at `pos`, returning the atom and the position after it. Variables are reconstructed * with de Bruijn names `$0`, `$1`, … (so a decoded atom is alpha-equivalent to the original). */ declare function decodeAt(tokens: Int32Array | number[], pos: number, it: Interner): [Atom, number]; /** Decode a full token array to an atom. */ declare function decodeAtom(tokens: Int32Array | number[], it: Interner): Atom; /** The number of tokens in the subterm starting at `pos`. */ declare function subtermLen(tokens: Int32Array | number[], pos: number): number; /** Encode a query pattern using lookup (not interning): returns the tokens and the variable names in de * Bruijn order, or `null` if a pattern symbol/ground is absent from the interner (fast fail; it can * never match any stored fact). */ declare function encodePattern(a: Atom, it: Interner): { tokens: number[]; varNames: string[]; } | null; /** One-sided match of an encoded pattern against an encoded ground fact in a (possibly shared) token * array. Returns the variable bindings (de Bruijn index -> the matched fact subterm's [start, end) * token range), or `null` on mismatch. Pure integer work over the token array, so a worker can run it * against a `SharedArrayBuffer`-backed `Int32Array` with no copying. */ declare function matchFlatAt(pat: ArrayLike, fact: Int32Array | number[], factStart: number): Map | null; /** A flat, interned knowledge base: facts are appended as token runs into one array, indexed by head * functor id, and matched against an encoded pattern by integer scan. */ declare class FlatKB { readonly interner: Interner; private readonly tokens; private readonly byFunctor; private readonly other; private readonly offsets; /** The token array (for packing into a SharedArrayBuffer). */ get tokenArray(): readonly number[]; /** Every fact's start offset, in insertion order (for sharding across workers). */ get factOffsets(): readonly number[]; /** Add a (typically ground) atom to the KB. */ add(a: Atom): void; /** Candidate fact offsets for a pattern, using the functor index when the pattern head is a known * symbol; otherwise every fact. */ private candidates; /** Match `pattern` against the KB, returning a binding map (variable name -> matched atom) per match. */ match(pattern: Atom): Array>; get size(): number; } declare const _internals: { tok: (tag: number, payload?: number) => number; tagOf: (tok: number) => number; payloadOf: (tok: number) => number; subtermLen: typeof subtermLen; }; interface TableKey { readonly tokens: readonly number[]; readonly generation: number; /** Head functor of the tabled call, so utility is attributed per functor. A chain of keys * remembered together can span several functors, which is why the key carries its own. */ readonly functor?: string | undefined; } interface VariantAtomKey { readonly tokens: readonly number[]; readonly varNames: readonly string[]; readonly canonicalMap: Map; } interface EncodedAtomKey extends TableKey, VariantAtomKey { } /** Encode an atom for variant lookup without printing it. Variables are canonicalized by first occurrence. */ declare function encodeVariantKey(a: Atom, interner: Interner): VariantAtomKey; declare class TokenTrie { private readonly root; get(tokens: readonly number[]): V | undefined; set(tokens: readonly number[], value: V): void; delete(tokens: readonly number[]): boolean; clear(): void; } interface CompletedTableEntry { readonly numCallVars: number; readonly results: readonly Atom[]; readonly depthSpan: number; readonly answerCount: number; readonly approxCells: number; } interface ActiveTableEntry { readonly tokens: readonly number[]; readonly numCallVars: number; readonly results: readonly Atom[]; readonly answerCount: number; readonly approxCells: number; depthSpan: number; cyclic: boolean; overBudget: boolean; } interface TableBudget { readonly maxCompletedEntries: number; readonly maxCompletedAnswers: number; readonly maxApproxCells: number; readonly maxEntryCells: number; readonly maxInternerLeaves: number; } declare const DEFAULT_TABLE_BUDGET: TableBudget; type TableKeyKind = "ground" | "ground-distinct" | "ground-space-read" | "ground-space-read-distinct" | "moded"; type TableVersion = number | readonly [ruleVersion: number, spaceVersion: number]; declare class TableSpace { private readonly budget; interner: Interner; private generation; private readonly completed; private readonly active; private readonly activeStack; private head; private tail; private entries; private answers; private cells; private activeCount; private activeAnswers; private activeCells; /** Measured utility per functor: how many entries it stored, and how many were ever read back. * A memo that never hits is pure overhead, so admission revokes it (see `admitsFunctor`). */ private readonly functorUtility; constructor(budget?: TableBudget); key(kind: TableKeyKind, call: Atom, version: TableVersion): EncodedAtomKey; isCurrentKey(key: TableKey): boolean; getCompleted(key: TableKey): CompletedTableEntry | undefined; /** Whether this functor's memo has earned its keep. A table is a pure memo, so refusing one can * only cost time, never change a result; that is what makes measured revocation safe. The static * profitability analysis (`analyzeTableWorth`) can only guess from the call graph, and a wrong * guess is expensive: a functor that threads an accumulator stores one large key per iteration * and hits none of them. So admission also watches the outcome, and once a functor has stored * `UTILITY_REVOKE_AFTER` entries without a single read it stops being tabled for the rest of the * run. The threshold sits far above any plausible warm-up (a memo that pays starts hitting * within a few dozen entries) and far below the millions of tokens a runaway table burns. */ admitsFunctor(functor: string): boolean; /** Measured per-functor table utility, for tests and diagnostics. */ functorUtilityOf(functor: string): { inserts: number; hits: number; } | undefined; rememberCompleted(key: TableKey, numCallVars: number, results: readonly Atom[], depthSpan?: number): void; beginActive(key: TableKey, numCallVars: number): ActiveTableEntry | null | undefined; getActive(key: TableKey): ActiveTableEntry | undefined; isTopActive(entry: ActiveTableEntry): boolean; markCyclic(entry: ActiveTableEntry): void; observeActiveDepth(entry: ActiveTableEntry, depthSpan: number): void; addActiveAnswers(entry: ActiveTableEntry, results: readonly Atom[]): number; endActive(key: TableKey): void; clear(): void; private resetTables; stats(): { entries: number; answers: number; approxCells: number; }; entryCellLimit(): number; resourceBudget(): TableBudget; private entryCost; private touch; private insertHead; private unlink; private remove; private evict; private makeRoomForActive; private resetInternerAndTables; private maybeResetInterner; } /** A grounded operation that runs asynchronously, for the async runner. */ type AsyncGroundFn = (args: readonly Atom[]) => Promise; type HostImportFn = (space: Atom, file: Atom) => ReduceResult | Promise; /** Thrown when synchronous evaluation reaches an async grounded operation. Use the async runner. */ declare class AsyncInSyncError extends Error { constructor(op: string); } type Ret = "none" | "chain" | "function"; interface Frame { readonly atom: Atom; readonly ret: Ret; readonly vars: readonly string[]; readonly fin: boolean; } interface StackCons { readonly head: Frame; readonly tail: Stack; } type Stack = StackCons | null; interface Item { readonly stack: Stack; readonly bnd: Bindings; } /** A literal `import!` target: a symbol, string, or PeTTa `(library ...)` wrapper. */ declare function literalImportName(atom: Atom): string | undefined; /** Return the literal target of an `(import! )` atom. */ declare function literalImportTarget(atom: Atom): string | undefined; /** Whether `a` is headed by an embedded instruction. Exported because the compiler asks the same question: * a right-hand side of that shape re-enters evaluation by a different route than the rule it stands for. */ declare function isEmbeddedOp(a: Atom): boolean; interface ImportModule { readonly id: string; readonly defs: Atom[]; readonly imports: string[]; } type ImportEntry = Atom[] | ImportModule; type ImportMap = Map; interface MinEnv { ruleIndex: Map>; /** The `&self` equations an `import!` added, as of the last compile. * * A module's equations land in the space, so the evaluator finds them through the world's rule index and * `ruleIndex` never hears about them. The compiler has no world, so `ensureCompiled` hands it this * snapshot and rebuilds whenever the world's `selfRuleVersion` moves off `compiledRuleVersion`. Without * it a multi-file program could not be compiled at all, which cost a corpus Peano saturation 27x and a * corpus Fibonacci 276x purely for living in two files. */ compileSelfRules?: ReadonlyMap> | undefined; /** The `selfRuleVersion` `compileSelfRules` was taken at; `undefined` before the first query. */ compiledRuleVersion?: number | undefined; /** Pure functors over the rules the COMPILER can see, which is the static ones plus `compileSelfRules`. * `pureFunctors` answers the same question for tabling, which a runtime rule addition deliberately * switches off in favour of its own versioned gates; compilation stays on. Only built when a module * actually contributed equations, so a single-file program reuses `pureFunctors` untouched. */ compilePureFunctors?: Set | undefined; /** The rule source a parallel-hyperpose worker re-evaluates branches from: the program's own non-`!` * atoms, extended by import promotion with each promoted module's definitions, so a worker sees the * same static rules the main evaluation does. Read at call time by the `parEval` closures. */ parRulesSrc?: string | undefined; varRules: Array<[Atom, Atom]>; varRulesVar: Array<[Atom, Atom]>; sigs: Map; /** Custom {@link Space} backends by space name. Absent by default, and every named-space read and * write falls through to the World's own log when a name has none. */ spaceBackends?: Map | undefined; /** Called for each atom added to or removed from a space, if a host installs it. * * The atom is passed as an ATOM, not formatted: the caller that wants text can format it, and the one * that wants to undo the write needs the value. Absent by default, so every emit site is one `if` that * allocates nothing — the same bargain {@link trace} makes. */ onSpaceChange?: ((op: "add" | "remove", space: string, atom: Atom) => void) | undefined; gt: GroundingTable; /** Static `&self` atoms in insertion (occurrence) order. Slot-stable: the nested match index refers * to slots by occurrence id and `get-atoms` order is observable, so the compaction sweep swaps a * slot's storage without renumbering. */ atoms: StaticAtomStore; /** How many leading `atoms` are the preloaded prelude/stdlib base. `get-atoms &self` enumerates the * atoms AFTER this point: Hyperon keeps its standard library in a separate space reachable through an * embedded space atom, so enumerating `&self` there yields the program's own atoms, not thousands of * library definitions (and each enumerated atom is reduced, so enumerating the library here meant * reducing every open library rule body, which overflowed or hung on any real program). Matching and * reduction still see the whole store; only the enumeration boundary moves. */ preloadBase?: number | undefined; types: Map; imports: ImportMap; /** Canonical module ids loaded into each space during this evaluator run. */ loadedModules: Map>; exprTypes: Array<[Atom, Atom]>; /** `exprTypes` bucketed by the subject's structural hash. Both the dedupe on insert and the lookup * walked the whole list with `atomEq`, so a program declaring N expression types cost O(N^2) to load: * measured 46ms at 1,000 declarations and 1,305ms at 4,000. */ exprTypesByHash?: Map> | undefined; /** How many leading `exprTypes` are in the buckets. */ exprTypesIndexed?: number | undefined; /** Async grounded operations, dispatched by the async runner; empty for pure synchronous evaluation. */ agt: Map; /** Effect declarations for named sync and async grounded operations. Missing sync declarations are * treated as Host and missing async declarations as AsyncHost by the fuzz sandbox. */ groundedEffects: Map; asyncGroundedEffects: Map; /** Active case-local effect policy. Undefined during ordinary evaluation. */ fuzzEffectPolicy?: "Sandboxed" | "ExternalEffects" | undefined; /** Optional host-language import hook used by async `import!` for files outside the MeTTa import map. */ hostImport?: HostImportFn; /** Optional opt-in execution trace sink. `undefined` when tracing is off, so emit sites cost one branch. * Always present (as `undefined` when off) to keep the env object's shape monomorphic on the hot path. */ trace?: TraceSink | undefined; /** Which compiled holders to leave unbuilt, asked once per holder after each compile. A differential * debugging switch rather than a tuning knob: running a program as-is and again with one functor's * holder declined says whether compiling THAT functor is what changed the answer, and diffing the two * traces says where. `undefined` builds every holder, which is the normal path. */ declineCompiled?: ((functor: string, kind: string) => boolean) | undefined; /** Per-runner `with-mutex` locks (a Promise chain per key), so mutexes do not leak across runners. */ mutexes: Map>; /** Optional per-run hash-cons table for immutable terms. */ intern?: InternTable; /** Ground expressions already observed to reduce to themselves for the current rule set. */ evaluatedAtoms: WeakSet; factIndex: Map; argIndex: Map; nonGroundAtPos: Map; /** Internal static nested-head index. Optional so existing structural `MinEnv` values stay compatible. */ nestedMatchIndex?: StaticNestedMatchIndex | undefined; /** Argument columns over the static atoms, for a pattern whose head is a variable. Every index above is * keyed by head, so `($rel 500000 $y)` names no bucket and falls back to reading the space; a column * keys on one argument position instead, so the ground argument selects even though the head does not. * Keyed by `arity|position`, built for a position a query actually asks about and only when a sample * says the key is selective enough to be worth it, then extended per added atom. A program that never * writes such a pattern never pays for one. Occurrence ids stay valid across a compaction sweep, which * swaps a slot's storage without renumbering. */ varHeadPosIndex?: Map | undefined; /** Per column site, what the selectivity sample has been deciding, so a site it keeps refusing stops * paying for the sample that refuses it. */ varHeadPosPredict?: Map | undefined; varHeadedFacts: Atom[]; /** Automatic tabling storage: structural variant keys over token tries and bounded completed entries. * `undefined` when tabling is disabled. */ tableSpace?: TableSpace | undefined; /** Positive only while an idempotent unique(collapse ...) consumer evaluates a proven-pure ground call. */ distinctGroundDepth?: number | undefined; /** Functor names proven tabling-safe by `analyzePurity`; recomputed when equations change. */ pureFunctors?: Set | undefined; /** Functor names proven safe for MODED tabling by `analyzePurity(env, MODED_IMPURE_OPS)` — a superset of * `pureFunctors` (only `empty`, which is genuinely pure, is treated more permissively); recomputed * alongside it. */ modedPureFunctors?: Set | undefined; /** Functor names whose only permitted atom-space dependency is `match`; their table keys include the * current space-content version. */ spaceReadPureFunctors?: Set | undefined; /** Pure functors whose rule SCC has branching recursion, so ground tabling is likely useful. */ tableWorth?: Set | undefined; /** Pure functors whose rule SCC has branching recursion under the moded purity rules. */ modedTableWorth?: Set | undefined; /** Space-read-pure functors whose rule SCC has branching recursion. */ spaceReadTableWorth?: Set | undefined; /** Set when equations changed and the purity/profitability analysis must be refreshed before evaluation. */ tablingDirty?: boolean | undefined; /** Memo for `getTypes` of ground atoms: a ground atom's type is a pure function of the env's type tables, * which only change via `addAtomToEnv` (where this is reset). Keyed by atom identity, so the recursion * reuses the type of every shared subterm (a growing Peano/list term is the worst case otherwise). */ typeCache?: WeakMap | undefined; /** Optional parallel branch evaluator for `hyperpose` (set by a host worker pool). Given the formatted * branch atoms and whether to stop at the first result, returns each branch's result atoms, or `null` for * a branch that errored or (under firstOnly) lost the race. It re-evaluates each branch from the program's * rules in a worker, so it is only used when a branch is pure and the space carries no runtime additions, * so it is identical to evaluating in line. */ parEval?: ((branchSrcs: string[], firstOnly: boolean) => (Atom[] | null)[]) | undefined; /** Async host-worker equivalent, used by browser Web Workers and other non-blocking hosts. */ parEvalAsync?: ((branchSrcs: string[], firstOnly: boolean) => Promise<(Atom[] | null)[]>) | undefined; /** Bumped whenever a grounded operation is registered onto this env, so identity-keyed caches that * read `gt`/`agt` (the normal-form verdict cache) can tell a mutated table from the one they saw. */ groundedEpoch: number; /** Compiled pure deterministic functions (the int/bool functional core); undefined when disabled. */ compiled?: CompiledFns | undefined; /** Set when an equation changed, so the compiler re-runs before the next query. */ compileDirty?: boolean | undefined; /** False when `compiled` contains only query-directed dependent search groups. Undefined retains the * historical meaning for structural environments whose map was produced by `compileEnv`. */ compiledComplete?: boolean | undefined; /** Internal differential switch for handing a pure compiled tail continuation back to the evaluator loop. * Enabled by default. `false` keeps the former recursive normalization path for equivalence tests. */ useCompiledTailContinuation?: boolean; /** Opt-in trail-based matching (`experimental.trail`): the conjunctive `match` enumerates on a WAM-style * trail (zero per-solution allocation) instead of the immutable `Bindings`/`merge` threading. Off by * default; byte-identical to the reference matcher (differential-gated), falling back to it per query for * cases the trail cannot reproduce (custom grounded matchers). */ useTrail?: boolean; /** Compact runtime `&self` atomspace. When on, runtime additions are stored as flat term ids and decoded * only when a query or observable operation needs tree atoms. */ useFlatAtomspace?: boolean; /** Anchored-acyclic conjunctive matching (`experimental.conjNested`, on by default): a `(, ...)` whose * first goal is anchored by a ground argument and whose later goals are connected over a ground, * duplicate-free candidate domain runs through the source-ordered binding-aware nested loop (matchConj), * which probes the argument index per bound join variable instead of materializing every goal's full * relation for matchConjJoin's WCO. Differential-gated to matchConjJoin: same solution multiset and * multiplicity. Enumeration order can interleave differently when the anchor bucket is not grouped by * the join variable (MeTTa leaves query order unspecified — the MOPS workspace is a multiset); on * unique-entity-per-goal shapes the orders coincide, asserted by the differential suite. * Cyclic, unanchored, non-ground-fact, or duplicate-fact conjunctions stay on matchConjJoin. */ useConjNested?: boolean; /** Ordered numeric single-column range matching (`experimental.rangeIndex`, on by default): a single * functor-headed all-variable pattern whose template is a pure nested `if` numeric range filter enumerates * the sorted numeric column slice instead of scanning the whole functor bucket. The selected slice is * restored to source order before yielding. */ useRangeIndex?: boolean; /** Argument-column candidate selection for a `match` whose head is a variable * (`experimental.varHeadIndex`, on by default). Cached conjuncts freshen each selected fact once and may * choose a head bucket, argument column, or full scan independently for each incoming solution. */ useVarHeadIndex?: boolean; /** Emit a single-tail-call numeric functor's loop as JS source (`experimental.emitNumericLoop`, on by * default) instead of running it through the closure nodes. Byte-identical including fuel boundaries: * the emitted loop charges the counter exactly where the closures do, and bails back to them on any * value its unboxed arithmetic cannot carry. */ useEmitLoop?: boolean; /** Mark normal-form ground `match` results as already evaluated (`experimental.matchEvalMark`, on by * default) so the first consumer visit takes the existing evaluatedAtoms short-circuit. */ useMatchEvalMark?: boolean; /** Answer a public-entry bare `(match &self pat templ)` straight from its match plan * (`experimental.directMatch`, on by default), skipping the generator driver, the worklist, and the * per-result reduce probe those would run. Guarded to the exact cases where that machinery is a * provable no-op; anything else declines to the general path. */ useDirectMatch?: boolean; /** Lazily-computed set of head functors that have a duplicate ground fact. matchConjJoin's WCO trie dedups * duplicate relation tuples, so it collapses a conjunction over duplicate facts to one solution; the nested * loop preserves multiplicity. Only functors with no duplicate facts route to the nested loop, so the two * paths stay byte-identical. Computed once (conjNested only) from factIndex and cached here. */ duplicateFactHeadsCache?: Set | undefined; /** Per-head "every stored static fact is a normal form" verdicts for the collapse-count gate * (matchCountsSolutionsAsResults). Valid only for the stamped rule/removal/grounded state — the * same validity axes as the normal-form cache — and reset wherever the fact buckets change, * alongside duplicateFactHeadsCache. */ normalFactHeadsCache?: { selfRuleVersion: number; removedStatic: unknown; groundedEpoch: number; byHead: Map; } | undefined; /** Compact static fact storage (`experimental.staticCompact`, on by default for buildEnv loads): large * all-ground flat-fact functors are swept into one shared StaticCompactBase; their slots, factIndex * buckets, and argIndex postings release the object forest, and candidates decode on demand through the * base's memoized decoder with sorted-column equality/range probes standing in for argIndex. */ staticBase?: StaticCompactBase; /** Per-functor compaction metadata for `staticBase` (functors currently served by the compact base). */ compactHeads?: Map; /** Lazy ordered numeric column indexes for `experimental.rangeIndex`. Keyed by functor and argument * position; a `null` cache entry records a column that is not safely numeric, so later declined queries do * not rescan the fact bucket. */ numericRangeIndexCache?: Map | undefined; } interface StaticNestedMatchIndex { /** Occurrence ids by functor, argument position, and nested expression head. */ readonly byHead: Map; /** Occurrence ids whose argument or argument head has a custom grounded matcher. */ readonly wildcardAtPos: Map; /** Root functors with a non-ground static fact. */ readonly nonGroundFactHeads: Set; } /** Compaction metadata for one functor served by the shared StaticCompactBase. */ interface CompactHeadMeta { /** Fact count (the whole bucket, every arity). */ readonly count: number; /** The facts' env.atoms slots, ascending (bucket insertion order). */ readonly slots: Int32Array; /** The uniform expression arity (item count), or -1 when the bucket mixes arities. */ readonly arity: number; /** Fact count per expression arity (the all-distinct-variable tally reads these without decoding). */ readonly arityCounts: ReadonlyMap; /** Distinct leaf symbol names across all argument positions; with the functor itself, these decide * whether a decoded fact is in normal form without decoding (isNormalForm on a flat ground fact * reduces to isDefinedHead over the head and its symbol leaves). */ readonly leafSyms: readonly string[]; /** Whether the bucket stores two structurally identical facts (the conjNested routing guard). */ readonly hasDup: boolean; } declare function setStaticCompactThresholdForTests(n: number): number; /** An empty environment for grounding table `gt`. Grow it with `addAtomToEnv`. */ declare function emptyEnv(gt: GroundingTable): MinEnv; /** Register a sync grounded operation and invalidate analyses that may have classified its name. */ declare function registerGroundedOperation(env: MinEnv, name: string, op: GroundFn, effect?: GroundedOperationEffect): void; /** Register an async grounded operation and invalidate analyses that may have classified its name. */ declare function registerAsyncGroundedOperation(env: MinEnv, name: string, op: AsyncGroundFn, effect?: GroundedOperationEffect): void; declare function addAtomToEnv(env: MinEnv, x: Atom): void; declare function buildEnv(atoms: Atom[], gt: GroundingTable, staticCompact?: boolean): MinEnv; /** The atoms a runtime `(add-atom space …)` put into `&self` while evaluating. * * These live in the World, not in the env, so a host that keeps its own list of added atoms has to ask * for them separately or it will disagree with what `(match &self …)` sees over the very same space. */ declare function runtimeSelfAtoms(w: World): readonly Atom[]; /** Remove an atom a runtime `(add-atom &self …)` put in the World, exactly as `(remove-atom &self …)` * does. Answers the new World, or `undefined` when the atom was not a runtime addition. * * A host reading the space through {@link runtimeSelfAtoms} sees those atoms, so it must be able to * remove one too, or the space disagrees with itself: `getAtoms()` would list an atom that `remove` * refused. The static half stays the caller's, since only it knows what it loaded. */ declare function removeRuntimeSelfAtom(w0: World, a: Atom): World | undefined; /** Empty `&self` of everything the World holds: every runtime addition goes, and a retraction is kept * only while `env` still holds the atom it refers to. * * Both halves are needed. Dropping the additions is the point. Filtering the retractions against what * `env` still holds is what stops a later re-add of a previously retracted atom from coming back * already retracted, while a program that retracted a STDLIB rule keeps that retraction, which * clearing a space has no business undoing. */ declare function clearSelfSpace(env: MinEnv, w0: World): World; /** Whether a statically loaded atom has been retracted by a runtime `(remove-atom …)`. */ declare function selfAtomRetracted(w: World, a: Atom): boolean; /** Whether any static atom has been retracted at runtime. Cheap, so a reader can skip the per-atom * filter in the usual case where nothing was removed. */ declare function selfHasRetractions(w: World): boolean; /** Whether a runtime `add-atom` has put anything into `&self`, WITHOUT materialising it. * * `runtimeSelfAtoms` builds an array, and a host that reads the space on every query would pay that * allocation on every read just to discover there was nothing to add. Both sides answer their size in * constant time, so the emptiness question is asked separately from the contents. */ declare function hasRuntimeSelfAtoms(w: World): boolean; type NamedSpace = AtomLog; interface World { spaces: PTable; /** State cells keyed by `String(handle)`. */ store: PTable; tokens: PTable; selfExtra: AtomLog; flatSelfExtra: FlatAtomSpace | undefined; selfRules: Map>; selfVarRules: ReadonlyArray<[Atom, Atom]>; selfRuleVersion: number; spaceVersion: number; typeVersion: number; removedStatic: AtomLog; removedStaticHeads: ReadonlySet; removedStaticVarRules: boolean; maxStackDepth: number; maxSteps: number; stepStart: number; logLevel: number; typeCheckAuto: boolean; } interface St { counter: number; world: World; } declare const initSt: () => St; declare function freshenRule(counter: number, lhs: Atom, rhs: Atom): [Atom, Atom]; declare function getTypes(env: MinEnv, a: Atom): Atom[]; declare function checkApplication(env: MinEnv, w: World, op: string, args: readonly Atom[], opSig?: Atom[] | undefined): Atom | null; /** Occurrence ids of the static atoms holding each ground leaf at one (arity, argument position). * Argument columns rather than a feature index over whole terms: a path index costs about six times as * much to build here, which is more than the scan it replaces, so it lost on the query it was meant to * win. */ interface VarHeadPosIndex { /** Ids per leaf bucket, ascending. A bucket held by exactly one atom stores that id unboxed, because a * selective position has nearly as many distinct buckets as there are atoms and boxing every one of * them is a large part of what the build costs. */ readonly exact: Map; /** Ids that cannot be discriminated at this position and are admitted against any query leaf: an atom * that is itself a variable, and a grounded value whose own matcher decides what it accepts. */ readonly residual: number[]; /** How many leading `atoms` are indexed; the column extends rather than rebuilds. */ indexed: number; /** Ids stored, across the postings and the residual: what this column costs, in budget units. */ entries: number; } /** What the sample has been deciding about one `(arity, position)` site. */ interface VarHeadSitePrediction { /** Saturating confidence that the site is worth indexing: 0 means keep refusing it. */ score: number; /** Queries refused on the prediction alone since the site was last sampled. */ since: number; } /** Test hook: the chain flatten's routing decision, so tests pin which spellings flatten without * depending on fuel or wall time. */ declare function flattenMatchChainForTests(env: MinEnv, w: World, match: ExprAtom, bnd: Bindings, context?: "count" | "result"): ExprAtom | undefined; /** Consult semantics for a completed top-level import: move the module closure a literal * `!(import! &self "mod")` directive appended to the world into the env's static tables, through the * same `addAtomToEnvPlanned` path a single-file program's own definitions take, and hand back a world * whose runtime side is empty again. * * Runs only between directives (the caller threads exactly one world there, and the interpretation plan * is empty), and only over a world that held no runtime additions before the import, so the move cannot * be observed by any program construct: the `&self` multiset and its candidate order are unchanged. * What it buys is that every static-state fast path, index, purity analysis, tabling admission, and * compiled dispatch guard now sees the imported program exactly as it would a single-file one, instead * of each of them separately declining on "there are runtime rules". Imports evaluated anywhere else * (computed targets, nested in a body, non-`&self` spaces) keep the world-local path untouched. * * Type declarations are NOT re-registered: `registerImportedTypes` already applied them under the * import contract (a module may add a signature but never override one), which promotion must preserve. * Returns the promoted state, `post` itself when the import brought nothing new (dedup, missing module), * or `undefined` when the directive or the pre-state disqualifies promotion. */ declare function promoteCompletedSelfImport(env: MinEnv, directive: Atom, preWorld: World, post: St): St | undefined; declare function mettaEval(env: MinEnv, fuel: number, st: St, bnd: Bindings, a: Atom, depth?: EvaluationDepth): [Array<[Atom, Bindings]>, St]; /** Async type-directed evaluation: awaits async grounded operations (`env.agt`). */ declare function mettaEvalAsync(env: MinEnv, fuel: number, st: St, bnd: Bindings, a: Atom, signal?: AbortSignal, depth?: EvaluationDepth): Promise<[Array<[Atom, Bindings]>, St]>; /** Evaluate `atom` (i.e. interpret `(eval atom)`) under `env`, returning the result atoms. */ declare function evalAtom(env: MinEnv, atom: Atom, st?: St, fuel?: number): [Atom[], St]; interface HostInterop { readonly name: string; readonly prelude?: string; readonly asyncOps?: ReadonlyMap; readonly hostImport?: HostImportFn; dispose?(): Promise | void; } type HostTextLoader = (path: string, from?: string) => Promise; interface ComposeHostInteropsOptions { readonly allowDuplicateAsyncOps?: boolean; } declare function composeHostInterops(interops: readonly HostInterop[], options?: ComposeHostInteropsOptions): HostInterop; export { type MetaType as $, type Atom as A, type Bindings as B, type CompiledFns as C, DEFAULT_MAX_STACK_DEPTH as D, EvaluationDepth as E, FlatKB as F, type GndAtom as G, type HostImportFn as H, type InternTable as I, type Ground as J, type GroundFn as K, type GroundedExec as L, type MinEnv as M, type GroundedMatch as N, type GroundedOperationEffect as O, type PTable as P, type GroundingTable as Q, type HostInterop as R, type Space as S, type TraceSink as T, type HostTextLoader as U, type ImportEntry as V, type ImportModule as W, InMemorySpace as X, type IntVal as Y, Interner as Z, type Item as _, type ImportMap as a, decodeAtom as a$, NATIVE_EVALUATION_NESTING_LIMIT as a0, NUMBER_FAMILY_TYPE_NAMES as a1, type PMapChange as a2, type ParamPat as a3, type ReduceEffect as a4, type ReduceResult as a5, type Ret as a6, type Skel as a7, type SkelBody as a8, type SkelClause as a9, addInt as aA, addValRaw as aB, atomEq as aC, atomSize as aD, atomVars as aE, baseTable as aF, bindingNames as aG, buildEnv as aH, builtinOpNames as aI, callGrounded as aJ, canCompactAtom as aK, canInternExprItems as aL, canonInt as aM, checkApplication as aN, clearSelfSpace as aO, cmpIntVal as aP, collectSubstitutedVars as aQ, collectSubstitutedVarsAmong as aR, collectVars as aS, collectVarsAmong as aT, compareNumbers as aU, compileDependentNondetGroup as aV, compileEnv as aW, composeHostInterops as aX, createInternTable as aY, declareGroundedOperationEffect as aZ, decodeAt as a_, type SkelGoal as aa, type SkelTail as ab, type St as ac, type Stack as ad, type StackCons as ae, type SymAtom as af, TAG_ARITY as ag, TAG_NEWVAR as ah, TAG_SYMBOL as ai, TAG_VARREF as aj, type TableBudget as ak, type TableKey as al, type TableKeyKind as am, TableSpace as an, type TableVersion as ao, TokenTrie as ap, type TraceEvent as aq, VARS_SCAN_LIMIT as ar, type ValRel as as, type VarAtom as at, type VarProbe as au, type VariantAtomKey as av, type World as aw, _internals as ax, addAtomToEnv as ay, addEqRaw as az, type AsyncGroundFn as b, prependValRaw as b$, emitNumericTailLoop as b0, emptyBindings as b1, emptyEnv as b2, emptyExpr as b3, emptyPMap as b4, emptyPTable as b5, encodeAtom as b6, encodeInto as b7, encodePattern as b8, encodeVariantKey as b9, internAtom as bA, internBuiltExpr as bB, internExpr as bC, isEmbeddedOp as bD, isEmpty as bE, isErrorAtom as bF, isExpr as bG, isGnd as bH, isSym as bI, isTableSafeGroundedOp as bJ, isVar as bK, isZero as bL, literalImportName as bM, literalImportTarget as bN, lookupVal as bO, makeEqRel as bP, makeValRel as bQ, matchFlatAt as bR, metaType as bS, mettaEval as bT, mettaEvalAsync as bU, mixHash as bV, mulInt as bW, pettaOpNames as bX, pmDiff as bY, pmGet as bZ, pmSet as b_, eqRelations as ba, evalAtom as bb, expr as bc, flattenMatchChainForTests as bd, freshenRule as be, fromRelations as bf, gbool as bg, getTypes as bh, gfloat as bi, gint as bj, gnd as bk, groundEq as bl, groundType as bm, groundedOperationEffect as bn, groundedOperationType as bo, gstr as bp, gunit as bq, hasEq as br, hasLoop as bs, hasLoopFromBase as bt, hasRuntimeSelfAtoms as bu, hashOf as bv, initSt as bw, intAbs as bx, intDiv as by, intMod as bz, type PMap as c, probeSize as c0, promoteCompletedSelfImport as c1, ptDelete as c2, ptDiff as c3, ptEntries as c4, ptGet as c5, ptHas as c6, ptKeys as c7, ptSet as c8, registerAsyncGroundedOperation as c9, registerBuiltinGroundedOperation as ca, registerGroundedOperation as cb, registeredBuiltinGroundedOperations as cc, relations as cd, removeRuntimeSelfAtom as ce, removeVal as cf, runCompiled as cg, runCompiledEffectCount as ch, runtimeSelfAtoms as ci, selfAtomRetracted as cj, selfHasRetractions as ck, setHostEffectsEnabled as cl, setOutputSink as cm, setRawSink as cn, setStaticCompactThresholdForTests as co, size as cp, someVal as cq, stdTable as cr, strHash as cs, subInt as ct, sym as cu, toF64 as cv, valEntries as cw, varNamesOf as cx, variable as cy, type ActiveTableEntry as d, AsyncInSyncError as e, BAIL as f, type BindingRel as g, type BuiltinGroundedOperation as h, type CompiledHolder as i, type CompiledImpureOps as j, type CompiledRunResult as k, type CompletedTableEntry as l, type ComposeHostInteropsOptions as m, DEFAULT_TABLE_BUDGET as n, EVALUATION_TRAMPOLINE_DEPTH as o, type EncodedAtomKey as p, type EqRel as q, type EvaluationDepthBoundary as r, EvaluationDepthHandoff as s, EvaluationDepthOverflow as t, type EvaluationDepthSpan as u, type ExprAtom as v, FlatAtomSpace as w, FlatAtomSpaceTable as x, type Frame as y, type FunctionalRuntime as z };