@dallaylaen/ski-interpreter 2.7.0 → 2.8.1
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/CHANGELOG.md +39 -0
- package/bin/ski.js +24 -10
- package/lib/ski-interpreter.cjs.js +150 -119
- package/lib/ski-interpreter.cjs.js.map +3 -3
- package/lib/ski-interpreter.min.js +5 -5
- package/lib/ski-interpreter.min.js.map +4 -4
- package/lib/ski-interpreter.mjs +150 -119
- package/lib/ski-interpreter.mjs.map +3 -3
- package/lib/ski-quest.min.js +5 -5
- package/lib/ski-quest.min.js.map +4 -4
- package/lib/types/expr.d.ts +33 -6
- package/lib/types/extras.d.ts +41 -23
- package/lib/types/index.d.ts +3 -5
- package/lib/types/parser.d.ts +11 -13
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/internal.ts", "../src/expr.ts", "../src/
|
|
4
|
-
"sourcesContent": ["import {\n classes, native, control, FreeVar, Church,\n} from './expr';\nimport { Parser } from './parser';\n\nimport { Quest } from './quest';\nimport { toposort } from './toposort';\nimport { extras } from './extras';\nextras.toposort = toposort;\n\nexport class SKI extends Parser {\n static native = native;\n static control = control;\n static classes = classes;\n // TODO declare in a loop?\n static B = native.B;\n static C = native.C;\n static I = native.I;\n static K = native.K;\n static S = native.S;\n static W = native.W;\n\n /**\n * Create a proxy object that generates variables on demand,\n * with names corresponding to the property accessed.\n * Different invocations will return distinct variables,\n * even if with the same name.\n *\n * @example const {x, y, z} = SKI.vars();\n * x.name; // 'x'\n * x instanceof FreeVar; // true\n * x.apply(y).apply(z); // x(y)(z)\n */\n static vars (scope: object = {}): { [key: string]: FreeVar } {\n const vars: { [key: string]: FreeVar } = {};\n return new Proxy(vars, {\n get (target, prop: string) {\n if (!(prop in target))\n target[prop] = new FreeVar(prop, scope);\n\n return target[prop];\n }\n });\n }\n\n static church (n: number): Church {\n return new Church(n);\n }\n\n static extras = extras;\n static Quest = Quest;\n}\n\ndeclare global {\n interface Window { SKI: typeof SKI }\n}\n\ntype AnyGlobal = typeof globalThis & {\n SKI: typeof SKI;\n process?: { env: Record<string, string | undefined> };\n};\n\nconst g = globalThis as AnyGlobal;\n\n// SKI_REPL=1 node -r ./index.js\nif (g.process?.env.SKI_REPL) {\n g.SKI = SKI;\n console.log('SKI_REPL activated, try `new SKI();`');\n}\n\n// we're in a browser\nif (typeof window !== 'undefined')\n window.SKI = SKI;\n", "/* utility types */\n\nexport class Tokenizer {\n /**\n * Create a tokenizer that splits strings into tokens according to the given terms.\n * The terms are interpreted as regular expressions, and are sorted by length\n * to ensure that longer matches are preferred over shorter ones.\n * @param {...string|RegExp} terms\n */\n rex: RegExp;\n constructor (...terms: (string | RegExp)[]) {\n const src = '$|(\\\\s+)|' + terms\n .map(s => '(?:' + s + ')')\n .sort((a, b) => b.length - a.length)\n .join('|');\n this.rex = new RegExp(src, 'gys');\n }\n\n /**\n * Split the given string into tokens according to the terms specified in the constructor.\n * @param {string} str\n * @return {string[]}\n */\n split (str: string): string[] {\n this.rex.lastIndex = 0;\n const list = [...str.matchAll(this.rex)];\n\n // did we parse everything?\n const eol = list.pop();\n const last = eol?.index ?? 0;\n\n if (last !== str.length) {\n throw new Error('Unknown tokens at pos ' + last + '/' + str.length\n + ' starting with ' + str.substring(last));\n }\n\n // skip whitespace\n return list.filter(x => x[1] === undefined).map(x => x[0]);\n }\n}\n\nconst tokRestrict = new Tokenizer('[-=+]', '[A-Z]', '\\\\b[a-z_][a-z_0-9]*\\\\b');\n\n/**\n * Add ot remove tokens from a set according to a spec string.\n * The spec string is a sequence of tokens, with each group optionally prefixed\n * by one of the operators '=', '+', or '-'.\n * The '=' operator resets the set to contain only the following token(s).\n * @param {Set<string>} set\n * @param {string} [spec]\n * @returns {Set<string>}\n */\nexport function restrict (set:Set<string>, spec?: string) {\n if (!spec)\n return set;\n let out = new Set([...set]);\n let mode = '=';\n const act : {[key: string]: (s: string) => void} = {\n '=': sym => { out = new Set([sym]); mode = '+'; },\n '+': sym => { out.add(sym); },\n '-': sym => { out.delete(sym); },\n };\n\n for (const sym of tokRestrict.split(spec)) {\n if (act[sym])\n mode = sym;\n else\n act[mode](sym);\n }\n return out;\n}\n\nexport type TraverseDecorator = <T>(value?: T) => TraverseControl<T>;\nexport type TraverseValue<T> = TraverseControl<T | null | undefined | void> | T | null | undefined | void;\n\nexport class TraverseControl<T> {\n /**\n * A wrapper for values returned by fold/traverse callbacks\n * which instructs the traversal to alter its behavior while\n * retaining the value in question.\n *\n * This class is instantiated internally be `SKI.control.*` functions,\n * and is not intended to be used directly by client code.\n *\n * @template T\n * @param {T} value\n * @param {function(T): TraverseControl<T>} decoration\n */\n value?: T;\n decoration: TraverseDecorator;\n constructor (value: T | undefined, decoration: TraverseDecorator) {\n this.value = value;\n this.decoration = decoration;\n }\n}\n\n/**\n * @private\n * @template T\n * @param {T|TraverseControl<T>|null} value\n * @returns {[T?, function|undefined]}\n */\nexport function unwrap<T> (value: TraverseValue<T>): [T?, TraverseDecorator?] {\n // `?? undefined` so that null is not 'an object'\n if (value instanceof TraverseControl)\n return [value.value ?? undefined, value.decoration];\n return [value ?? undefined, undefined];\n}\n\n/**\n * Prepare a self-referencing wrapper function for use as a fold/traverse control decorator.\n *\n * If `fun` is created by `prepareWrapper`, then\n * unwrap(fun(x)) will always return exactly [x, fun], and the second value can be checked with ===.\n *\n * An optional label can be provided for debugging purposes.\n *\n * @private\n * @template T\n * @param {string} [label]\n * @returns {function(T): TraverseControl<T>}\n */\nexport function prepareWrapper (label?: string): <T>(value?: T) => TraverseControl<T> {\n const fun: TraverseDecorator = <T>(value: T|undefined) => new TraverseControl<T>(value, fun);\n (fun as { label?: string }).label = label;\n fun.toString = () => 'TraverseControl::' + label;\n return fun;\n}\n", "'use strict';\n\nimport { unwrap, prepareWrapper, TraverseValue } from './internal';\n\nconst DEFAULTS = {\n max: 1000,\n maxArgs: 32,\n maxSize: 1_000_000,\n};\n\n// canonize traverse order aliases\nconst ORDER: Record<string, 'LI' | 'LO'> = {\n 'leftmost-outermost': 'LO',\n 'leftmost-innermost': 'LI',\n LO: 'LO',\n LI: 'LI',\n};\n\n/**\n * Control primitives for fold() and traverse() methods.\n */\nexport const control = {\n descend: prepareWrapper('descend'),\n prune: prepareWrapper('prune'),\n redo: prepareWrapper('redo'),\n stop: prepareWrapper('stop'),\n};\n\n/**\n * List of predefined native combinators.\n * This is required for toSKI() to work, otherwise could as well have been in parser.js.\n */\nexport const native: Record<string, Native> = {};\n\nexport type TermInfo = {\n normal: boolean, // whether the term becomes irreducible after receiving a number of arguments.\n proper: boolean, // whether the irreducible form is only contains its arguments. implies normal.\n arity?: number, // the number of arguments that is enough to reach the irreducible form\n discard?: boolean, // whether the term (or subterms, unless proper) can discard arguments.\n duplicate?: boolean, // whether the term (or subterms, unless proper) can duplicate arguments.\n skip?: Set<number>, // indices of arguments that are discarded. nonempty implies discard.\n dup?: Set<number>, // indices of arguments that are duplicated. nonempty implies duplicate.\n expr?: Expr, // canonical form containing only lambdas, applications, and variables, if one exists\n steps?: number, // number of reduction steps taken to obtain the aforementioned information, if applicable\n}\n\nexport type Invocation = Expr | ((arg: Expr) => Invocation);\nexport type Step = { expr: Expr, steps: number, changed: boolean };\nexport type Run = { expr: Expr, steps: number, final: boolean };\nexport type RunOptions = { max?: number, steps?: number, throw?: boolean, maxSize?: number };\n\nexport type FormatOptions = {\n terse?: boolean,\n html?: boolean,\n brackets?: [string, string],\n space?: string,\n var?: [string, string],\n lambda?: [string, string, string],\n around?: [string, string],\n redex?: [string, string],\n inventory?: Record<string, Expr>,\n};\n\n/**\n * A version of FormatOptions with defaults plugged in,\n * use for mandatory formatImpl implementation in Expr subclasses.\n */\nexport type RefinedFormatOptions = { // ditto but with defaults plugged in\n terse?: boolean,\n html?: boolean,\n brackets: [string, string],\n space: string,\n var: [string, string],\n lambda: [string, string, string],\n around: [string, string],\n redex: [string, string],\n inventory?: Record<string, Expr>,\n}\n\nexport type TraverseOptions = {order?: 'LO' | 'LI' | 'leftmost-outermost' | 'leftmost-innermost'};\nexport type TraverseCallback = (e:Expr) => TraverseValue<Expr>;\n\n/**\n * A combinatory logic expression.\n *\n * Applications, variables, lambdas, combinators per se,\n * and other expression subtypes all extend this class.\n *\n * Expr itself cannot (or at least should not) be instantiated.\n *\n * @abstract\n */\nexport abstract class Expr {\n /** optional context for the term. Is set by the parser with addContext: true */\n context?: {\n scope?: object,\n env?: Record<string, Expr>,\n src?: string,\n parser: object,\n }\n\n /** number of arguments the term is waiting for (if known) */\n arity?: number;\n /** a brief description what the term does */\n note?: string;\n /** the properties of the term, typically inferred from its behavior.\n * This is used internally when declaring Native / Alias terms.\n */\n props?: TermInfo;\n /** An estimated number of nodes in the expression tree.\n * Used to prevent runaway computations.\n */\n size?: number;\n\n /**\n *\n * Define properties of the term based on user supplied options and/or inference results.\n * Typically useful for declaring Native and Alias terms.\n * @protected\n * @param {Object} options\n * @param {string} [options.note] - a brief description what the term does\n * @param {number} [options.arity] - number of arguments the term is waiting for (if known)\n * @param {string} [options.fancy] - how to display in html mode, e.g. φ instead of 'f'\n * @param {boolean} [options.canonize] - whether to try to infer the properties\n * @param {number} [options.max] - maximum number of steps for inference, if canonize is true\n * @param {number} [options.maxArgs] - maximum number of arguments for inference, if canonize is true\n * @return {this}\n */\n _setup (options: { note?: string, arity?: number, fancy?: string, canonize?: boolean, max?: number, maxArgs?: number, } = {}) {\n // TODO better name\n\n if (options.fancy !== undefined && this instanceof Named)\n this.fancyName = options.fancy;\n\n if (options.note !== undefined)\n this.note = options.note;\n\n if (options.arity !== undefined)\n this.arity = options.arity;\n\n if (options.canonize) {\n const guess = this.infer(options);\n if (guess.normal) {\n this.arity = this.arity ?? guess.arity;\n this.note = this.note ?? guess.expr!.format({ html: true, lambda: ['', ' ↦ ', ''] });\n delete guess.steps;\n this.props = guess;\n }\n }\n return this;\n }\n\n /**\n * apply self to zero or more terms and return the resulting term,\n * without performing any calculations whatsoever\n * @param {Expr} args\n * @return {Expr}\n */\n apply (...args: Expr[]): Expr {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let expr: Expr = this;\n for (const arg of args)\n expr = new App(expr, arg);\n return expr;\n }\n\n /**\n * Replace all aliases in the expression with their definitions, recursively.\n * @return {Expr}\n */\n expand (): Expr {\n return this.traverse(e => {\n if (e instanceof Alias)\n return e.impl.expand();\n }) ?? this;\n }\n\n /**\n * Traverse the expression tree, applying change() to each node.\n * If change() returns an Expr, the node is replaced with that value.\n * A null/undefined value is interpreted as\n * \"descend further if applicable, or leave the node unchanged\".\n *\n * Returned values may be decorated:\n *\n * SKI.control.prune will suppress further descending even if nothing was returned\n * SKI.control.stop will terminate further changes.\n * SKI.control.redo will apply the callback to the returned subtree, recursively.\n *\n * Note that if redo was applied at least once to a subtree, a null return from the same subtree\n * will be replaced by the last non-null value returned.\n *\n * The traversal order is leftmost-outermost, unless options.order = 'leftmost-innermost' is specified.\n * Short aliases 'LO' and 'LI' (case-sensitive) are also accepted.\n *\n * Returns null if no changes were made, or the new expression otherwise.\n *\n * @param {{\n * order?: 'LO' | 'LI' | 'leftmost-outermost' | 'leftmost-innermost',\n * }} [options]\n * @param {(e:Expr) => TraverseValue<Expr>} change\n * @returns {Expr|null}\n * @sealed\n */\n traverse (\n options: TraverseOptions | TraverseCallback,\n change?: TraverseCallback\n ): Expr | null {\n if (typeof options === 'function') {\n change = options;\n options = {};\n }\n const order = ORDER[options.order ?? 'LO'];\n if (order === undefined)\n throw new Error('Unknown traversal order: ' + options.order);\n const [expr] = unwrap(this._traverse_redo({ order }, change!));\n return expr ?? null;\n }\n\n /**\n *\n *\n * @protected\n *\n * @param {Object} options\n * @param {(e:Expr) => TraverseValue<Expr>} change\n * @returns {TraverseValue<Expr>}\n */\n _traverse_redo (options: TraverseOptions, change: TraverseCallback): TraverseValue<Expr> {\n let action;\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let expr: Expr | undefined = this;\n let prev;\n do {\n prev = expr;\n const next: TraverseValue<Expr> = options.order === 'LI'\n ? expr._traverse_descend(options, change) ?? change(expr)\n : change(expr) ?? expr._traverse_descend(options, change);\n [expr, action] = unwrap(next);\n } while (expr && action === control.redo);\n if (!expr && prev !== this)\n expr = prev; // we were in redo at least once\n return action ? action(expr!) : expr;\n }\n\n /**\n * Apply a {@link traverse} callback to the subterms of the expression, without changing the expression itself.\n *\n * @protected\n * @param {Object} options\n * @param {(e:Expr) => TraverseValue<Expr>} change\n * @returns {TraverseValue<Expr>}\n */\n _traverse_descend (options: TraverseOptions, change: TraverseCallback): TraverseValue<Expr> {\n return null;\n }\n\n /**\n * Returns true if predicate() is true for any subterm of the expression, false otherwise.\n *\n * @param {(e: Expr) => boolean} predicate\n * @returns {boolean}\n */\n any (predicate: (e: Expr) => boolean): boolean {\n return predicate(this);\n }\n\n /**\n * Fold the expression into a single value by recursively applying combine() to its subterms.\n * Nodes are traversed in leftmost-outermost order, i.e. the same order as reduction steps are taken.\n *\n * null or undefined return value from combine() means \"keep current value and descend further\".\n *\n * SKI.control provides primitives to control the folding flow:\n * - SKI.control.prune(value) means \"use value and don't descend further into this branch\";\n * - SKI.control.stop(value) means \"stop folding immediately and return value\".\n * - SKI.control.descend(value) is the default behavior, meaning \"use value and descend further\".\n *\n * This method is experimental and may change in the future.\n *\n * @example // count the number of nodes in the expression tree\n * expr.fold(0, (acc, e) => acc + 1);\n *\n * @experimental\n *\n * @template T\n * @param {T} initial\n * @param {(acc: T, expr: Expr) => TraverseValue<T>} combine\n * @returns {T}\n */\n fold<T> (initial: T, combine: (acc: T, expr: Expr) => TraverseValue<T>): T {\n const [value] = unwrap(this._fold(initial, combine));\n return value ?? initial;\n }\n\n /**\n * Internal method for fold(), which performs the actual folding.\n * Should be implemented in subclasses having any internal structure.\n *\n * @protected\n * @param initial\n * @param combine\n */\n _fold<T> (initial:T, combine: (acc: T, expr: Expr) => TraverseValue<T>): TraverseValue<T> {\n return combine(initial, this);\n }\n\n /**\n * @experimental\n * Fold an application tree bottom to top.\n * For each subtree, the function is given the term in the root position and\n * a list of the results of folding its arguments.\n *\n * E.g. fold('x y (z t)', f) results in f(x, [f(y, []), f(z, [f(t, [])])])\n *\n * @example expr.foldBottomUp((head, tail) => {\n * if (head.arity && head.arity <= tail.length) {\n * return '(<span class=\"redex\">'\n * + head + ' '\n * + tail.slice(0, head.arity).join(' ')\n * + '</span>'\n * + tail.slice(head.arity).join(' ')\n * + ')';\n * } else {\n * return '(' + head + ' ' + tail.join(' ') + ')';\n * }\n * });\n * @template T\n * @param {(head: Expr, tail: T[]) => T} fun\n * @return {T}\n */\n foldBottomUp<T> (fun: (head: Expr, tail: T[]) => T): T {\n const [head, ...tail] = this.unroll();\n return fun(head, tail.map(e => e.foldBottomUp(fun)));\n }\n\n /**\n * Try to empirically find an equivalent lambda term for the expression,\n * returning also the term's arity and some other properties.\n *\n * This is used internally when declaring a Native / Alias term,\n * unless {canonize: false} is used.\n *\n * As of current it only recognizes terms that have a normal form,\n * perhaps after adding some variables. This may change in the future.\n *\n * Use toLambda() if you want to get a lambda term in any case.\n *\n * @sealed\n * @param {{max?: number, maxArgs?: number}} options\n * @return {TermInfo}\n */\n infer (options : {max?: number, maxArgs?: number, maxSize?: number } = {}): TermInfo {\n const skipNames: Record<string, boolean> = {};\n const skipSkip: Set<Expr> = new Set();\n this.traverse(e => {\n if (e instanceof Named && !skipSkip.has(e))\n skipNames[e.name] = true;\n if (e instanceof Lambda)\n skipSkip.add(e.arg);\n });\n return this._infer({\n max: options.max ?? DEFAULTS.max,\n maxArgs: options.maxArgs ?? DEFAULTS.maxArgs,\n maxSize: options.maxSize ?? DEFAULTS.maxSize,\n skipNames,\n }, 0);\n // TODO maybe traverse() if no normal form was found\n }\n\n /**\n * Internal method for infer(), which performs the actual inference.\n * @param {{max: number, maxArgs: number}} options\n * @param {number} nargs - var index to avoid name clashes\n * @returns {TermInfo}\n * @private\n */\n _infer (options:{max: number, maxArgs: number, maxSize: number, skipNames: Record<string, boolean>}, nargs: number): TermInfo {\n const probe: FreeVar[] = [];\n let steps = 0;\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let expr: Expr = this;\n // eslint-disable-next-line no-labels\n main: for (let i = 0; i < options.maxArgs; i++) {\n const next = expr.run({ max: options.max - steps, maxSize: options.maxSize });\n // console.log(`infer step ${i}, expr = ${expr}, probe = [${probe}]: `, next);\n steps += next.steps;\n if (!next.final)\n break;\n if (firstVar(next.expr)) {\n // can't append more variables, return or recurse\n expr = next.expr;\n if (!expr.any(e => !(e instanceof FreeVar || e instanceof App)))\n return maybeLambda(probe, expr, { steps });\n const list = expr.unroll();\n let discard = false;\n let duplicate = false;\n const acc = [];\n for (let j = 1; j < list.length; j++) {\n const sub = list[j]._infer(\n { maxArgs: options.maxArgs - nargs, max: options.max - steps, maxSize: options.maxSize, skipNames: options.skipNames }, // limit recursion\n nargs + i // avoid variable name clashes\n );\n steps += sub.steps ?? 0;\n if (!sub.expr)\n // eslint-disable-next-line no-labels\n break main; // press f to pay respects\n if (sub.discard)\n discard = true;\n if (sub.duplicate)\n duplicate = true;\n acc.push(sub.expr);\n }\n return maybeLambda(probe, list[0].apply(...acc), { discard, duplicate, steps });\n }\n while (options.skipNames[nthvar(nargs + i).name])\n nargs++;\n const push = nthvar(nargs + i);\n probe.push(push);\n expr = next.expr.apply(push);\n }\n return { normal: false, proper: false, steps };\n }\n\n /**\n * Expand an expression into a list of terms\n * that give the initial expression when applied from left to right:\n * ((a, b), (c, d)) => [a, b, (c, d)]\n *\n * This can be thought of as an opposite of apply:\n * fun.apply(...arg).unroll() is exactly [fun, ...args]\n * (even if ...arg is in fact empty).\n *\n * @returns {Expr[]}\n */\n unroll (): Expr[] {\n // currently only used by infer() but may be useful\n // to convert binary App trees to n-ary or smth\n return [this];\n }\n\n /**\n * Returns a series of lambda terms equivalent to the given expression,\n * up to the provided computation steps limit.\n *\n * Unlike infer(), this method will always return something,\n * even if the expression has no normal form.\n *\n * See also Expr.walk() and Expr.toSKI().\n *\n * @sealed\n * @param {{\n * max?: number,\n * maxArgs?: number,\n * varGen?: function(void): FreeVar,\n * steps?: number,\n * html?: boolean,\n * latin?: number,\n * }} options\n * @return {IterableIterator<{expr: Expr, steps?: number, comment?: string}>}\n */\n * toLambda (options: { max?: number, maxArgs?: number } = {}) {\n let expr:Expr | null = this.traverse(e => {\n if (e instanceof FreeVar || e instanceof App || e instanceof Lambda || e instanceof Alias)\n return null; // no change\n const guess = e.infer({ max: options.max, maxArgs: options.maxArgs });\n if (!guess.normal)\n throw new Error('Failed to infer an equivalent lambda term for ' + e);\n return guess.expr;\n }) ?? this;\n const seen = new Set(); // prune irreducible\n let steps = 0;\n while (expr) {\n const next = expr.traverse({ order: 'LI' }, e => {\n if (seen.has(e))\n return null;\n if (e instanceof App && e.fun instanceof Lambda) {\n const guess = e.infer({ max: options.max, maxArgs: options.maxArgs });\n steps += guess.steps ?? 0;\n if (!guess.normal) {\n seen.add(e);\n return null;\n }\n return control.stop(guess.expr);\n }\n });\n yield { expr, steps };\n expr = next;\n }\n }\n\n /**\n * Rewrite the expression into S, K, and I combinators step by step.\n * Returns an iterator yielding the intermediate expressions,\n * along with the number of steps taken to reach them.\n *\n * See also Expr.walk() and Expr.toLambda().\n *\n * @sealed\n * @param {{max?: number}} [options]\n * @return {IterableIterator<{final: boolean, expr: Expr, steps: number}>}\n */\n * toSKI (options: {max?: number, maxArgs?: number} = {}) {\n // options are ignored completely, TODO remove\n // get rid of non-lambdas\n let expr:Expr|null = this.traverse(e => {\n if (e instanceof FreeVar || e instanceof App || e instanceof Lambda || e instanceof Alias)\n return null;\n // TODO infer failed for atomic term? die...\n return e.infer(options).expr;\n }) ?? this;\n\n let steps = 0;\n while (expr) {\n const next = expr.traverse({ order: 'LI' }, e => {\n if (!(e instanceof Lambda) || (e.impl instanceof Lambda))\n return null; // continue\n if (e.impl === e.arg)\n return control.stop(native.I);\n if (!e.impl.any(t => t === e.arg))\n return control.stop(native.K.apply(e.impl));\n // TODO use real assert here. e.impl contains e.arg and also isn't e.arg, in MUST be App.\n if (!(e.impl instanceof App))\n throw new Error('toSKI: assert failed: lambda body is of unexpected type ' + e.impl.constructor.name );\n // eta-reduction: body === (not e.arg) (e.arg)\n if (e.impl.arg === e.arg && !e.impl.fun.any(t => t === e.arg))\n return control.stop(e.impl.fun);\n // last resort, go S\n return control.stop(native.S.apply(new Lambda(e.arg, e.impl.fun), new Lambda(e.arg, e.impl.arg)));\n })\n yield { expr, steps, final: !next };\n steps++;\n expr = next;\n }\n }\n\n /**\n * Replace all instances of `search` in the expression with `replace` and return the resulting expression,\n * or null if no changes could be made.\n *\n * Lambda terms and applications will never match if used as plug\n * as they are impossible to compare without extensive computations.\n *\n * Typically used on variables but can also be applied to other terms, e.g. aliases.\n * See also Expr.traverse() for more flexible replacement of subterms.\n *\n * @param {Expr} search\n * @param {Expr} replace\n * @return {Expr|null}\n */\n subst (search:Expr, replace:Expr): Expr|null {\n return this === search ? replace : null;\n }\n\n /**\n * Apply term reduction rules, if any, to the given argument.\n * A returned value of null means no reduction is possible.\n * A returned value of Expr means the reduction is complete and the application\n * of this and arg can be replaced with the result.\n * A returned value of a function means that further arguments are needed,\n * and can be cached for when they arrive.\n *\n * This method is between apply() which merely glues terms together,\n * and step() which reduces the whole expression.\n *\n * foo.invoke(bar) is what happens inside foo.apply(bar).step() before\n * reduction of either foo or bar is attempted.\n *\n * The name 'invoke' was chosen to avoid confusion with either 'apply' or 'reduce'.\n *\n * @param {Expr} arg\n * @returns {Partial | null}\n */\n invoke (arg:Expr): Invocation | null {\n return null;\n }\n\n /**\n * iterate one step of a calculation.\n * @return {{expr: Expr, steps: number, changed: boolean}}\n */\n step (): Step { return { expr: this, steps: 0, changed: false } }\n\n /**\n * Iteratively apply {@link step} to the expression until it's irreducible,\n * or until the provided limits are reached.\n *\n * Returns { expr: Expr, steps: number, final: boolean }.\n *\n * If { throw: true } is given and no irreducible form was reached within the limits, an error is thrown.\n *\n * @sealed\n * @param {{max?: number, steps?: number, throw?: boolean}|Expr} [opt]\n * @param {Expr} args\n * @return {{expr: Expr, steps: number, final: boolean}}\n */\n run (opt : RunOptions|Expr = {}, ...args: Expr[]): Run {\n if (opt instanceof Expr) {\n args.unshift(opt);\n opt = {};\n }\n let expr = args ? this.apply(...args) : this;\n let steps = opt.steps ?? 0;\n // make sure we make at least 1 step, to tell whether we've reached the normal form\n const max = Math.max(opt.max ?? DEFAULTS.max, 1) + steps;\n let final = false;\n for (; steps < max; ) {\n const next = expr.step();\n if (!next.changed) {\n final = true;\n break;\n }\n if ((next.expr.size ?? 1) > (opt.maxSize ?? DEFAULTS.maxSize))\n break;\n steps += next.steps;\n expr = next.expr;\n }\n if (opt.throw && !final)\n throw new Error('Failed to compute expression in ' + max + ' steps');\n return { final, steps, expr };\n }\n\n /**\n * Returns an iterator of reduction steps of the expression, up to the provided limits.\n * Each step is an object of { expr, steps, final }, same as in {@link run}.\n *\n * Mnemonics: like {@link run} but slower.\n *\n * @remarks\n * This method is final. Do not override, override {@link step} instead.\n *\n * @param {{max?: number}} options\n * @return {IterableIterator<{final: boolean, expr: Expr, steps: number}>}\n */\n * walk (options : { max?: number, maxSize?: number } = {}): IterableIterator<Run> {\n const max = options.max ?? Infinity;\n let steps = 0;\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let expr:Expr = this;\n let final = false;\n\n while (steps < max && (expr.size ?? 1) < (options.maxSize ?? DEFAULTS.maxSize)) {\n // 1. calculate\n // 2. yield _unchanged_ expression\n // 3. either advance or stop\n const next = expr.step();\n if (!next.changed)\n final = true;\n yield { expr, steps, final };\n if (final)\n break;\n steps += next.steps;\n expr = next.expr;\n }\n }\n\n /**\n * True is the expressions are identical, false otherwise.\n * Aliases are expanded.\n * Bound variables in lambda terms are renamed consistently.\n * However, no reductions are attempted.\n *\n * E.g. a->b->a == x->y->x is true, but a->b->a == K is false.\n *\n * @remarks Final. Current implementation is a frontend to {@link diff}.\n *\n * @param {Expr} other\n * @return {boolean}\n */\n equals (other:Expr):boolean {\n return !this.diff(other);\n }\n\n /**\n * Recursively compare two expressions and return a string\n * describing the first point of difference.\n * Returns null if expressions are identical.\n *\n * Aliases are expanded.\n * Bound variables in lambda terms are renamed consistently.\n * However, no reductions are attempted.\n *\n * Members of the FreeVar class are considered different\n * even if they have the same name, unless they are the same object.\n * To somewhat alleviate confusion, the output will include\n * the internal id of the variable in square brackets.\n *\n * Do not rely on the exact format of the output as it may change in the future.\n *\n * @example \"K(S != I)\" is the result of comparing \"KS\" and \"KI\"\n * @example \"S(K([x[13] != x[14]]))K\"\n *\n * @param {Expr} other\n * @param {boolean} [swap] If true, the order of expressions is reversed in the output.\n * @returns {string|null}\n */\n diff (other:Expr, swap: boolean = false): string | null {\n if (this === other)\n return null;\n if (other instanceof Alias)\n return other.impl.diff(this, !swap);\n return swap\n ? '[' + other + ' != ' + this + ']'\n : '[' + this + ' != ' + other + ']';\n }\n\n /**\n * Assert expression equality. Can be used in tests.\n *\n * `this` is the expected value and the argument is the actual one.\n * Mnemonic: the expected value is always a combinator, the actual one may be anything.\n *\n * In case of failure, an error is thrown with a message describing the first point of difference\n * and `expected` and `actual` properties like in AssertionError.\n * AssertionError is not used directly because browsers don't recognize it.\n *\n * @sealed\n * @param {Expr} actual\n * @param {string} comment\n */\n expect (actual:Expr|object, comment = ''):void {\n comment = comment ? comment + ': ' : '';\n if (!(actual instanceof Expr)) {\n throw new Error(comment + 'Expected a combinator but found '\n + (actual?.constructor?.name ?? typeof actual));\n }\n const diff = this.diff(actual);\n if (!diff)\n return; // all good\n\n // TODO wanna use AssertionError but browser doesn't recognize it\n // still the below hack works for mocha-based tests.\n const poorMans = new Error(comment + diff) as Error & { expected?: string, actual?: string };\n poorMans.expected = this.diag();\n poorMans.actual = actual.diag();\n throw poorMans;\n }\n\n /**\n * Returns string representation of the expression.\n * Same as format() without options.\n *\n * Use formatImpl() to override in subclasses.\n * @return {string}\n * @sealed\n */\n toString (): string {\n return this.format();\n }\n\n /**\n * Whether the expression needs to be parenthesized when printed in terse mode.\n * (see {@link format})\n * @param isFirst whether this is the first term in a sequence\n * @return {boolean}\n * @protected\n */\n _braced (isFirst?:boolean): boolean {\n return false;\n }\n\n /**\n * Whether the expression can be printed without a space when followed by arg.\n * @param {Expr} arg\n * @returns {boolean}\n * @protected\n */\n _unspaced (arg: Expr): boolean {\n return this._braced(true);\n }\n\n /**\n * Stringify the expression with fancy formatting options.\n * Said options mostly include wrappers around various constructs in form of ['(', ')'],\n * as well as `terse` and `html` flags that fill in appropriate defaults.\n * Format without options is equivalent to toString() and can be parsed back.\n *\n * @sealed\n *\n * @param {Object} [options] - formatting options\n * @param {boolean} [options.terse] - whether to use terse formatting (omitting unnecessary spaces and parentheses)\n * @param {boolean} [options.html] - whether to default to HTML tags & entities.\n * If a named term has fancyName property set, it will be used instead of name in this mode.\n * @param {[string, string]} [options.brackets] - wrappers for application arguments, typically ['(', ')']\n * @param {[string, string]} [options.var] - wrappers for variable names\n * (will default to <var> and </var> in html mode).\n * @param {[string, string, string]} [options.lambda] - wrappers for lambda abstractions, e.g. ['λ', '.', '']\n * where the middle string is placed between argument and body\n * default is ['', '->', ''] or ['', '->', ''] for html\n * @param {[string, string]} [options.around] - wrappers around (sub-)expressions.\n * individual applications will not be wrapped, i.e. (a b c) but not ((a b) c)\n * @param {[string, string]} [options.redex] - wrappers around the starting term(s) that have enough arguments to be reduced\n * @param {Object<string, Expr>} [options.inventory] - if given, output aliases in the set as their names\n * and any other aliases as the expansion of their definitions.\n * The default is a cryptic and fragile mechanism dependent on a hidden mutable property.\n * @returns {string}\n *\n * @example foo.format() // equivalent to foo.toString()\n * @example foo.format({terse: false}) // spell out all parentheses\n * @example foo.format({html: true}) // use HTML tags and entities\n * @example foo.format({ around: ['(', ')'], brackets: ['', ''], lambda: ['(', '->', ')'] }) // lisp style, still back-parsable\n * @example foo.format({ lambda: ['λ', '.', ''] }) // pretty-print for the math department\n * @example foo.format({ lambda: ['', '=>', ''], terse: false }) // make it javascript\n * @example foo.format({ inventory: { T } }) // use T as a named term, expand all others\n *\n */\n format (options: FormatOptions = {}): string {\n const fallback: RefinedFormatOptions = options.html\n ? {\n brackets: ['(', ')'],\n space: ' ',\n var: ['<var>', '</var>'],\n lambda: ['', '->', ''],\n around: ['', ''],\n redex: ['', ''],\n }\n : {\n brackets: ['(', ')'],\n space: ' ',\n var: ['', ''],\n lambda: ['', '->', ''],\n around: ['', ''],\n redex: ['', ''],\n }\n return this.formatImpl({\n terse: options.terse ?? true,\n brackets: options.brackets ?? fallback.brackets,\n space: options.space ?? fallback.space,\n var: options.var ?? fallback.var,\n lambda: options.lambda ?? fallback.lambda,\n around: options.around ?? fallback.around,\n redex: options.redex ?? fallback.redex,\n inventory: options.inventory, // TODO better name\n html: options.html ?? false,\n }, 0);\n }\n\n /**\n * Internal method for format(), which performs the actual formatting.\n * @param {Object} options\n * @param {number} nargs\n * @returns {string}\n * @protected\n * @abstract\n */\n abstract formatImpl (options: RefinedFormatOptions, nargs: number): string;\n\n /**\n * Returns a string representation of the expression tree, with indentation to show structure.\n *\n * Applications are flattened to avoid excessive nesting.\n * Variables include ids to distinguish different instances of the same variable name.\n *\n * May be useful for debugging.\n *\n * @returns {string}\n *\n * @example\n * > console.log(ski.parse('C 5 x (x->x x)').diag())\n * App:\n * Native: C\n * Church: 5\n * FreeVar: x[53]\n * Lambda (x[54]):\n * App:\n * FreeVar: x[54]\n * FreeVar: x[54]\n */\n diag (indent: string = ''): string {\n return indent + this.constructor.name + ': ' + this;\n }\n\n /**\n * Convert the expression to a JSON-serializable format.\n * Sadly the format is not yet finalized and may change in the future.\n *\n * @experimental\n * @returns {string}\n * @sealed\n */\n toJSON (): string | object {\n return this.format();\n }\n}\n\n/**\n * Application of two {@link Expr} terms.\n *\n * Never ever call `new App(fun, arg)` directly, use `fun.apply(...args)` instead.\n */\nexport class App extends Expr {\n fun: Expr;\n arg: Expr;\n\n /** If irreducible, cache it and don't try anymore */\n final?: boolean;\n\n /**\n * @param fun\n * @param arg\n */\n constructor (fun:Expr, arg:Expr) {\n super();\n\n this.arg = arg;\n this.fun = fun;\n this.size = (fun.size ?? 1) + (arg.size ?? 1);\n }\n\n _traverse_descend (options: TraverseOptions, change: TraverseCallback): TraverseValue<Expr> {\n const [fun, fAction] = unwrap(this.fun._traverse_redo(options, change));\n if (fAction === control.stop)\n return control.stop(fun ? fun.apply(this.arg) : null);\n\n const [arg, aAction] = unwrap(this.arg._traverse_redo(options, change));\n\n const final:Expr|null = (fun || arg) ? (fun ?? this.fun).apply(arg ?? this.arg) : null;\n if (aAction === control.stop)\n return control.stop(final);\n return final;\n }\n\n any (predicate: (e: Expr) => boolean): boolean {\n return predicate(this) || this.fun.any(predicate) || this.arg.any(predicate);\n }\n\n _fold<T> (initial:T, combine: (acc: T, expr: Expr) => TraverseValue<T>): TraverseValue<T> {\n const [value = initial, action = 'descend'] = unwrap(combine(initial, this));\n if (action === control.prune)\n return value;\n if (action === control.stop)\n return control.stop(value);\n const [fValue = value, fAction = 'descend'] = unwrap(this.fun._fold(value, combine));\n if (fAction === control.stop)\n return control.stop(fValue);\n const [aValue = fValue, aAction = 'descend'] = unwrap(this.arg._fold(fValue, combine));\n if (aAction === control.stop)\n return control.stop(aValue);\n return aValue;\n }\n\n subst (search: Expr, replace:Expr): Expr | null {\n const fun = this.fun.subst(search, replace);\n const arg = this.arg.subst(search, replace);\n\n return (fun || arg) ? (fun ?? this.fun).apply(arg ?? this.arg) : null;\n }\n\n /**\n * @return {{expr: Expr, steps: number}}\n */\n\n step (): Step {\n // normal reduction order: first try root, then at most 1 step\n if (!this.final) {\n // try to apply rewriting rules, if applicable, at first\n const partial = this.fun.invoke(this.arg);\n if (partial instanceof Expr)\n return { expr: partial, steps: 1, changed: true };\n else if (typeof partial === 'function')\n this.invoke = partial; // cache for next time\n\n // descend into the leftmost term\n const fun = this.fun.step();\n if (fun.changed)\n return { expr: fun.expr.apply(this.arg), steps: fun.steps, changed: true };\n\n // descend into arg\n const arg = this.arg.step();\n if (arg.changed)\n return { expr: this.fun.apply(arg.expr), steps: arg.steps, changed: true };\n\n // mark as irreducible\n this.final = true; // mark as irreducible at root\n }\n\n return { expr: this, steps: 0, changed: false };\n }\n\n invoke (arg:Expr): Invocation | null {\n // propagate invocation towards the root term,\n // caching partial applications as we go\n const partial = this.fun.invoke(this.arg);\n if (partial instanceof Expr)\n return partial.apply(arg);\n else if (typeof partial === 'function') {\n this.invoke = partial;\n return partial(arg);\n } else {\n // invoke = null => we're uncomputable, cache for next time\n this.invoke = (arg: Expr) => null;\n return null;\n }\n }\n\n unroll (): Expr[] {\n return [...this.fun.unroll(), this.arg];\n }\n\n diff (other: Expr, swap = false) {\n if (!(other instanceof App))\n return super.diff(other, swap);\n\n const fun = this.fun.diff(other.fun, swap);\n if (fun)\n return fun + '(...)';\n const arg = this.arg.diff(other.arg, swap);\n if (arg)\n return this.fun + '(' + arg + ')';\n return null;\n }\n\n _braced (isFirst?: boolean): boolean {\n return !isFirst;\n }\n\n formatImpl (options:RefinedFormatOptions, nargs: number): string {\n const fun = this.fun.formatImpl(options, nargs + 1);\n const arg = this.arg.formatImpl(options, 0);\n const wrap = nargs ? ['', ''] : options.around!;\n // TODO ignore terse for now\n if (options.terse && !this.arg._braced(false))\n return wrap[0] + fun + (this.fun._unspaced(this.arg) ? '' : options.space) + arg + wrap[1];\n else\n return wrap[0] + fun + options.brackets![0] + arg + options.brackets![1] + wrap[1];\n }\n\n diag (indent: string = ''): string {\n return indent + 'App:\\n' + this.unroll().map(e => e.diag(indent + ' ')).join('\\n');\n }\n\n _unspaced (arg: Expr): boolean {\n return this.arg._braced(false) ? true : this.arg._unspaced(arg);\n }\n}\n\n/**\n * An abstract class representing a named term.\n *\n * @param {String} name\n */\nexport class Named extends Expr {\n name: string;\n fancyName?: string;\n\n constructor (name: string) {\n super();\n if (typeof name !== 'string' || name.length === 0)\n throw new Error('Attempt to create a named term with improper name');\n this.name = name;\n }\n\n _unspaced (arg: Expr): boolean {\n return !!(\n (arg instanceof Named) && (\n (this.name.match(/^[A-Z+]$/) && arg.name.match(/^[a-z+]/i))\n || (this.name.match(/^[a-z+]/i) && arg.name.match(/^[A-Z+]$/))\n )\n );\n }\n\n formatImpl (options: RefinedFormatOptions, nargs: number): string {\n // NOTE fancyName is not yet official and may change name or meaning\n const name = options.html ? this.fancyName ?? this.name : this.name;\n return this.arity !== undefined && this.arity > 0 && this.arity <= nargs\n ? options.redex![0] + name + options.redex![1]\n : name;\n }\n}\n\n/** A synthetic key for debugging/distinguishing variables. */\nlet freeId = 0;\n\n/**\n * A named variable.\n *\n * Given the functional nature of combinatory logic, variables are treated\n * as functions that we don't know how to evaluate just yet.\n *\n * Two variables are considered the same iff they have the same `name` and `scope` properties.\n * If `scope` is not given, the variable is only equal to itself.\n *\n * By convention, FreeVar.global is a constant denoting a global unbound variable.\n */\nexport class FreeVar extends Named {\n /**\n * @param name - name of the variable\n * @param scope - an object representing where the variable belongs to.\n */\n scope?: object;\n id: number;\n constructor (name:string, scope?: object ) {\n super(name);\n this.id = ++freeId;\n // TODO replace with null and scope??[notmatching] everywhere, but later\n this.scope = scope === undefined ? this : scope;\n }\n\n diff (other:Expr, swap = false): string | null {\n if (!(other instanceof FreeVar))\n return super.diff(other, swap);\n if (this.name === other.name && this.scope === other.scope)\n return null;\n const lhs = this.name + '[' + this.id + ']';\n const rhs = other.name + '[' + other.id + ']';\n return swap\n ? '[' + rhs + ' != ' + lhs + ']'\n : '[' + lhs + ' != ' + rhs + ']';\n }\n\n subst (search: Expr, replace: Expr): Expr | null {\n if (search instanceof FreeVar && search.name === this.name && search.scope === this.scope)\n return replace;\n return null;\n }\n\n formatImpl (options: RefinedFormatOptions, nargs: number): string {\n const name = options.html ? this.fancyName ?? this.name : this.name;\n return options.var![0] + name + options.var![1];\n }\n\n diag (indent: string = ''): string {\n // include variable id for disambiguation\n return `${indent}FreeVar: ${this.name}[${this.id}]`;\n }\n\n static global = ['global'];\n}\n\n/**\n * A named term with a known rewriting rule.\n * 'impl' is a function with signature Expr => Expr => ... => Expr\n * (see typedef Partial).\n * This is how S, K, I, and company are implemented.\n *\n * Note that as of current something like a=>b=>b(a) is not possible,\n * use full form instead: a=>b=>b.apply(a).\n *\n * @example new Native('K', x => y => x); // constant\n * @example new Native('Y', function(f) { return f.apply(this.apply(f)); }); // self-application\n */\nexport class Native extends Named {\n /**\n * @param name Name of the term\n * @param impl A javascript implementation of the term's rewriting rule.\n * @param opt Optional settings.\n */\n constructor (name: string, impl: (e: Expr) => Invocation,\n opt: {note?: string, arity?: number, canonize?: boolean } = {}) {\n super(name);\n // setup essentials\n this.invoke = impl;\n\n this._setup({ canonize: true, ...opt });\n }\n}\n\n/**\n * A lambda abstraction.\n *\n * Takes an arg: {@link FreeVar} and an impl: {@link Expr}.\n * Upon evaluation, all occurrences of `arg` within `impl`\n * will be replaced by the given term.\n *\n * Note that 'arg' will be replaced by a localized placeholder,\n * so the original variable can be used elsewhere without interference.\n */\nexport class Lambda extends Expr {\n arg: FreeVar;\n impl: Expr;\n /**\n * @param {FreeVar} arg\n * @param {Expr} impl\n */\n constructor (arg: FreeVar, impl: Expr) {\n super();\n\n if (!(arg instanceof FreeVar))\n throw new Error('Lambda argument must be a FreeVar');\n\n // localize argument variable and bind it to oneself\n const local = new FreeVar(arg.name, this);\n this.arg = local;\n this.impl = impl.subst(arg, local) ?? impl;\n this.arity = 1;\n this.size = (impl.size ?? 1) + 1;\n }\n\n invoke (arg: Expr): Expr {\n return this.impl.subst(this.arg, arg) ?? this.impl;\n }\n\n _traverse_descend (options: TraverseOptions, change: TraverseCallback): TraverseValue<Expr> {\n // alas no proper shielding of self.arg is possible\n const [impl, iAction] = unwrap(this.impl._traverse_redo(options, change));\n\n const final = impl ? new Lambda(this.arg, impl) : null;\n\n return iAction === control.stop ? control.stop(final) : final;\n }\n\n any (predicate: (e: Expr) => boolean): boolean {\n return predicate(this) || this.impl.any(predicate);\n }\n\n _fold<T> (initial:T, combine: (acc: T, expr: Expr) => TraverseValue<T>): TraverseValue<T> {\n const [value = initial, action = 'descend'] = unwrap(combine(initial, this));\n if (action === control.prune)\n return value;\n if (action === control.stop)\n return control.stop(value);\n const [iValue, iAction] = unwrap(this.impl._fold(value, combine));\n if (iAction === control.stop)\n return control.stop(iValue);\n return iValue ?? value;\n }\n\n subst (search: Expr, replace:Expr): Expr | null {\n if (search === this.arg)\n return null;\n const change = this.impl.subst(search, replace);\n return change ? new Lambda(this.arg, change) : null;\n }\n\n diff (other: Expr, swap = false): string | null {\n if (!(other instanceof Lambda))\n return super.diff(other, swap);\n\n const t = new FreeVar('t'); // TODO better placeholder name\n\n const diff = this.invoke(t).diff(other.invoke(t), swap);\n if (diff)\n return '(t->' + diff + ')'; // parentheses required to avoid ambiguity\n return null;\n }\n\n formatImpl (options: RefinedFormatOptions, nargs: number): string {\n return (nargs > 0 ? options.brackets![0] : '')\n + options.lambda![0]\n + this.arg.formatImpl(options, 0) // TODO highlight redex if nargs > 0\n + options.lambda![1]\n + this.impl.formatImpl(options, 0) + options.lambda![2]\n + (nargs > 0 ? options.brackets![1] : '');\n }\n\n diag (indent: string = ''): string {\n return `${indent}Lambda (${this.arg.name}[${this.arg.id}]):\\n`\n + this.impl.diag(indent + ' ');\n }\n\n _braced (isFirst: boolean): boolean {\n return true;\n }\n}\n\n/**\n * Church numeral representing non-negative integer `n`:\n * `n f x = f(f(...(f x)...))` with `f` applied `n` times.\n */\nexport class Church extends Expr {\n n: number;\n /**\n * @param {number} n\n */\n constructor (n: number) {\n n = Number.parseInt(String(n));\n if (!(n >= 0))\n throw new Error('Church number must be a non-negative integer');\n super();\n this.invoke = x => y => {\n let expr = y;\n for (let i = n; i-- > 0; )\n expr = x.apply(expr);\n return expr;\n };\n\n /** @type {number} */\n this.n = n;\n this.arity = 2;\n }\n\n diff (other:Expr, swap = false): string | null {\n if (!(other instanceof Church))\n return super.diff(other, swap);\n if (this.n === other.n)\n return null;\n return swap\n ? '[' + other.n + ' != ' + this.n + ']'\n : '[' + this.n + ' != ' + other.n + ']';\n }\n\n _unspaced (arg: Expr): boolean {\n return false;\n }\n\n formatImpl (options: RefinedFormatOptions, nargs: number): string {\n return nargs >= 2\n ? options.redex![0] + this.n + options.redex![1]\n : this.n + '';\n }\n}\n\nfunction waitn (n: number): (e : Expr) => (arg: Expr) => Invocation {\n return n <= 1\n ? (e: Expr) => (arg: Expr) => e.apply(arg)\n : (e: Expr) => (arg: Expr) => waitn(n - 1)(e.apply(arg));\n}\n\n/**\n * A named alias for an existing expression.\n *\n * Aliasing allows declaring new terms without a native implementation.\n * This is what happens when one writes `B = S(KS)K` in the interpreter.\n *\n * Aliases are transparent in terms of `equals` and `expect`;\n * for that reason, Alias.diag() in not adding to the indentation.\n *\n * Aliases have an `inline` property. Tf true, the alias will be replaced with its implementation\n * everywhere, unless specifically told otherwise e.g. by { inventory: { ... } } option of format().\n *\n * Upon creation, the aliases arity is calculated (unless `canonize` is false).\n *\n * Upon evaluation, the alias will be replaced with its implementation,\n * _unless_ it's not inline and has positive arity,\n * in which case it will wait for the required number of arguments before such replacement.\n */\nexport class Alias extends Named {\n /**\n * @param name\n * @param impl\n * @param options\n */\n impl: Expr;\n inline?: boolean;\n\n constructor (\n name: string,\n impl: Expr,\n options : {canonize?: boolean, max?: number, maxArgs?: number, note?: string, inline?: boolean, arity?: number} = {}\n ) {\n super(name);\n if (!(impl instanceof Expr))\n throw new Error('Attempt to create an alias for a non-expression: ' + impl);\n this.impl = impl;\n\n this._setup(options);\n this.invoke = waitn(options.inline ? 0 : this.arity ?? 0)(impl);\n this.size = impl.size;\n if (options.inline)\n this.inline = true;\n }\n\n /**\n * Make the alias inline, i.e. replace it with its implementation everywhere.\n *\n * Replaces the old `outdated` attribute.\n * Used by the parser when a term definition is removed or updated.\n *\n *\n *\n * May change in future versions, use with caution.\n *\n * @experimental\n * @returns {this}\n */\n makeInline (): this {\n this.invoke = waitn(0)(this.impl);\n this.inline = true;\n return this;\n }\n\n /**\n * @property {boolean} [proper] - whether the alias is a proper combinator (i.e. contains no free variables or constants)\n * @property {number} [arity] - the number of arguments the alias waits for before expanding\n * @property {Expr} [canonical] - equivalent lambda term.\n */\n\n _traverse_descend (options: TraverseOptions, change: TraverseCallback): TraverseValue<Expr> {\n return this.impl._traverse_redo(options, change);\n }\n\n any (predicate: (e: Expr) => boolean): boolean {\n return predicate(this) || this.impl.any(predicate);\n }\n\n _fold<T> (initial:T, combine: (acc: T, expr: Expr) => TraverseValue<T>): TraverseValue<T> {\n const [value = initial, action] = unwrap(combine(initial, this));\n if (action === control.prune)\n return value;\n if (action === control.stop)\n return control.stop(value);\n const [iValue, iAction] = unwrap(this.impl._fold(value, combine));\n if (iAction === control.stop)\n return control.stop(iValue);\n return iValue ?? value;\n }\n\n subst (search: Expr, replace: Expr): Expr | null {\n if (this === search)\n return replace;\n return this.impl.subst(search, replace);\n }\n\n // DO NOT REMOVE TYPE or tsc chokes with\n // TS2527: The inferred type of 'Alias' references an inaccessible 'this' type.\n /**\n * @return {{expr: Expr, steps: number, changed: boolean}}\n */\n step (): Step {\n // arity known = waiting for args to expand\n if ((this.arity ?? 0) > 0)\n return { expr: this, steps: 0, changed: false };\n // expanding is a change but it takes 0 steps\n return { expr: this.impl, steps: 0, changed: true };\n }\n\n diff (other: Expr, swap = false): string | null {\n if (this === other)\n return null;\n return other.diff(this.impl, !swap);\n }\n\n _braced (isFirst: boolean): boolean {\n return this.inline ? this.impl._braced(isFirst) : false;\n }\n\n formatImpl (options: RefinedFormatOptions, nargs: number): string {\n const inline = options.inventory\n ? options.inventory[this.name] !== this\n : this.inline;\n return inline ? this.impl.formatImpl(options, nargs) : super.formatImpl(options, nargs);\n }\n\n diag (indent: string = ''): string {\n // no indent increase so that a diff between diags is consistent with how `equals` works.\n return `${indent}Alias (${this.name}): \\\\\\n` + this.impl.diag(indent);\n }\n}\n\n// ----- Expr* classes end here -----\n\n// declare native combinators\n\n// redeclare `native` type with `Native` class\n\nfunction addNative (name: string, impl: (arg: Expr) => Invocation, opt : {note?: string} = {}): void {\n native[name] = new Native(name, impl, opt);\n}\naddNative('I', x => x);\naddNative('K', x => _y => x);\naddNative('S', x => y => z => x.apply(z, y.apply(z)));\naddNative('B', x => y => z => x.apply(y.apply(z)));\naddNative('C', x => y => z => x.apply(z).apply(y));\naddNative('W', x => y => x.apply(y).apply(y));\n\naddNative(\n '+',\n n => n instanceof Church\n ? new Church(n.n + 1)\n : f => x => f.apply(n.apply(f, x)),\n {\n note: 'Increase a Church numeral argument by 1, otherwise n => f => x => f(n f x)',\n }\n);\n\n// utility functions dependent on Expr* classes, in alphabetical order\n\nfunction firstVar (expr: Expr) {\n // yay premature optimization\n while (expr instanceof App)\n expr = expr.fun;\n return expr instanceof FreeVar;\n}\n\n/**\n * @private\n * Given a list of free variables, an expression, and some capabilities of the context,\n * return either a lambda term, or the original expression if no lambda abstraction is needed,\n * plus some metadata about the term and the context.\n *\n * Used by infer() internally.\n *\n * @param {FreeVar[]} args\n * @param {Expr} expr\n * @param {object} caps\n * @returns {TermInfo}\n */\nfunction maybeLambda (args: FreeVar[], expr: Expr, caps : {discard?: boolean, duplicate?: boolean, steps: number}): TermInfo {\n const count = new Array(args.length).fill(0);\n let proper = true;\n expr.traverse(e => {\n if (e instanceof FreeVar) {\n const index = args.findIndex(a => a.name === e.name);\n if (index >= 0) {\n count[index]++;\n return;\n }\n }\n if (!(e instanceof App))\n proper = false;\n });\n\n const skip : Set<number> = new Set();\n const dup : Set<number> = new Set();\n for (let i = 0; i < args.length; i++) {\n if (count[i] === 0)\n skip.add(i);\n else if (count[i] > 1)\n dup.add(i);\n }\n\n for (let i = args.length; i-- > 0; )\n expr = new Lambda(args[i], expr);\n\n return {\n normal: true,\n steps: caps.steps,\n expr,\n arity: args.length,\n ...(skip.size ? { skip } : {}),\n ...(dup.size ? { dup } : {}),\n duplicate: !!dup.size || caps.duplicate || false,\n discard: !!skip.size || caps.discard || false,\n proper,\n };\n}\n\nfunction nthvar (n: number): FreeVar {\n return new FreeVar('abcdefgh'[n] ?? 'x' + n);\n}\n\nexport const classes = { Expr, App, Named, FreeVar, Native, Lambda, Church, Alias };\n", "import { Expr, Named, control } from './expr';\nimport { TraverseValue } from './internal';\n\n/**\n * Sort a list in such a way that dependent terms come after the (named) terms they depend on.\n * If env is given, only terms listed there are taken into account.\n * If env is omitted, it will be implied from the list.\n * If list is omitted, it will default to values of env.\n * If just one term is given instead of a list, it will be coerced into a list.\n *\n * No terms outside env + list may ever appear in the result.\n *\n * The terms in env must be named and their names must match their keys.\n *\n * @param {Expr|Expr[]} list\n * @param {{[s:string]: Named}} env\n * @returns {{list: Expr[], env: {[s:string]: Named}}}\n *\n * @example\n * const expr = ski.parse(src);\n * toposort([expr], ski.getTerms()); // returns all terms appearing in Expr in correct order\n */\nexport type ToposortResult = { list: Expr[], env: { [s: string]: Named } };\nexport function toposort (list:Expr[]|Expr|undefined, env: { [s: string]: Named } | undefined): ToposortResult {\n if (list instanceof Expr)\n list = [list];\n if (env) {\n // TODO check in[name].name === name\n if (!list)\n list = Object.keys(env).sort().map(k => env![k]); // ensure deterministic order\n } else {\n if (!list)\n return { list: [], env: {} };\n env = {};\n for (const item of list) {\n if (!(item instanceof Named))\n continue;\n if (env[item.name])\n throw new Error('duplicate name ' + item);\n env[item.name] = item;\n }\n }\n\n const out: Expr[] = [];\n const seen = new Set();\n const rec = (term: Expr) => {\n if (seen.has(term))\n return;\n term.fold(false, (acc:boolean, e:Expr):TraverseValue<boolean> => {\n if (e !== term && e instanceof Named && env![e.name] === e) {\n rec(e);\n return control.prune(false);\n }\n });\n out.push(term);\n seen.add(term);\n };\n\n for (const term of list)\n rec(term);\n\n return {\n list: out,\n env,\n };\n}\n", "/**\n * Combinatory logic simulator\n */\n'use strict';\n\nimport { Tokenizer, restrict } from './internal';\nimport { Expr, FreeVar, Lambda, Church, Alias, Native, Named, native, Invocation, RefinedFormatOptions } from './expr';\nimport { toposort } from './toposort';\n\nclass Empty extends Expr {\n apply (...args: Expr[]):Expr {\n return args.length > 0 ? args.shift()!.apply(...args) : this;\n }\n\n postParse (): Expr {\n throw new Error('Attempt to use empty expression () as a term');\n }\n\n formatImpl (options: RefinedFormatOptions, nargs: number): string {\n return '()';\n }\n}\n\nclass PartialLambda extends Empty {\n impl: Expr;\n terms: FreeVar[];\n // TODO mutable! rewrite ro when have time\n constructor (term: Expr, _known = {}) {\n super();\n this.impl = new Empty();\n if (term instanceof FreeVar)\n this.terms = [term];\n else if (term instanceof PartialLambda) {\n if (!(term.impl instanceof FreeVar))\n throw new Error('Expected FreeVar->...->FreeVar->Expr');\n this.terms = [...term.terms, term.impl];\n } else\n throw new Error('Expected FreeVar or PartialLambda');\n }\n\n apply (term: Expr, ...tail:Expr[]) {\n if (term === null || tail.length !== 0 )\n throw new Error('bad syntax in partial lambda expr');\n this.impl = this.impl.apply(term);\n return this;\n }\n\n postParse (): Expr {\n let expr = this.impl;\n for (let i = this.terms.length; i-- > 0; )\n expr = new Lambda(this.terms[i], expr);\n return expr;\n }\n\n // uncomment if debugging with prints\n /* toString () {\n return this.terms.join('->') + '->' + (this.impl ?? '???');\n } */\n}\n\nfunction postParse (expr: Expr): Expr {\n return (expr as Empty).postParse ? (expr as Empty).postParse() : expr;\n}\n\nconst combChars = new Tokenizer(\n '[()]', '[A-Z]', '[a-z_][a-z_0-9]*', '\\\\b[0-9]+\\\\b', '->', '\\\\+'\n);\n\nexport type ParserOptions = {\n allow?: string,\n numbers?: boolean,\n lambdas?: boolean,\n terms?: { [key: string]: Expr | string } | string[],\n annotate?: boolean,\n addContext?: boolean,\n};\n\nexport type ParseOptions = {\n env?: { [key: string]: Expr },\n scope?: object,\n numbers?: boolean,\n lambdas?: boolean,\n allow?: string,\n};\n\nexport type AddOptions = {\n note?: string,\n canonize?: boolean,\n fancy?: string,\n arity?: number,\n};\n\nexport class Parser {\n /**\n *\n * @param {{\n * allow?: string,\n * numbers?: boolean,\n * lambdas?: boolean,\n * terms?: { [key: string]: Expr|string} | string[],\n * annotate?: boolean,\n * }} [options]\n */\n\n addContext: boolean;\n annotate: boolean;\n known: {[name: string]: Expr};\n allow: Set<string>;\n\n hasNumbers: boolean;\n hasLambdas: boolean;\n\n constructor (options: ParserOptions = {}) {\n this.annotate = !!options.annotate;\n this.addContext = !!options.addContext;\n this.known = { ...native };\n this.hasNumbers = true;\n this.hasLambdas = true;\n /** @type {Set<string>} */\n this.allow = new Set(Object.keys(this.known));\n\n // Import terms, if any. Omit native ones\n if (Array.isArray(options.terms))\n this.bulkAdd(options.terms);\n else if (options.terms) {\n for (const name in options.terms) {\n // Native terms already handled by allow\n if (typeof options.terms[name] !== 'string' || !options.terms[name].match(/^Native:/))\n this.add(name, options.terms[name]);\n }\n }\n\n // Finally, impose restrictions\n // We must do it after recreating terms, or else terms reliant on forbidden terms will fail\n this.hasNumbers = options.numbers ?? true;\n this.hasLambdas = options.lambdas ?? true;\n if (options.allow)\n this.restrict(options.allow);\n }\n\n /**\n * Declare a new term\n * If the first argument is an Alias, it is added as is.\n * Otherwise, a new Alias or Native term (depending on impl type) is created.\n * If note is not provided and this.annotate is true, an automatic note is generated.\n *\n * If impl is a function, it should have signature (Expr) => ... => Expr\n * (see typedef Partial at top of expr.js)\n *\n * @example ski.add('T', 'S(K(SI))K', 'swap combinator')\n * @example ski.add( ski.parse('T = S(K(SI))K') ) // ditto but one-arg form\n * @example ski.add('T', x => y => y.apply(x), 'swap combinator') // heavy artillery\n * @example ski.add('Y', function (f) { return f.apply(this.apply(f)); }, 'Y combinator')\n *\n * @param {Alias|String} term\n * @param {String|Expr|function(Expr):Partial} [impl]\n * @param {object|string} [options]\n * @param {string} [options.note] - optional annotation for the term, default is auto-generated if this.annotate is true\n * @param {boolean} [options.canonize] - whether to canonize the term's implementation, default is this.annotate\n * @param {boolean} [options.fancy] - alternative HTML-friendly name for the term\n * @param {number} [options.arity] - custom arity for the term, default is inferred from the implementation\n * @return {SKI} chainable\n */\n add (term: Alias | string, impl?: Expr | string | ((arg: Expr) => Invocation), options?: AddOptions | string): this {\n const named = this._named(term, impl);\n\n // backward compat\n const opts: AddOptions = typeof options === 'string' ? { note: options, canonize: false } : (options ?? {});\n named._setup({ canonize: this.annotate, ...opts });\n\n const old = this.known[named.name];\n if (old instanceof Alias)\n old.makeInline();\n\n this.known[named.name] = named;\n this.allow.add(named.name);\n\n return this;\n }\n\n /**\n * Internal helper for add() that creates an Alias or Native term from the given arguments.\n * @param {Alias|string} term\n * @param {string|Expr|function(Expr):Partial} impl\n * @returns {Native|Alias}\n * @private\n */\n _named (term: Alias | string, impl?: Expr | string | ((arg: Expr) => Invocation)): Native | Alias {\n if (term instanceof Named)\n return maybeAlias(term.name, term);\n if (typeof term !== 'string')\n throw new Error('add(): term must be an Alias or a string');\n if (impl === undefined)\n throw new Error('add(): impl must be provided when term is a string');\n if (typeof impl === 'string')\n return maybeAlias(term, this.parse(impl));\n if (impl instanceof Expr)\n return maybeAlias(term, impl);\n if (typeof impl === 'function')\n return new Native(term, impl);\n // idk what this is\n throw new Error('add(): impl must be an Expr, a string, or a function with a signature Expr => ... => Expr');\n }\n\n /**\n * Declare a new term if it is not known, otherwise just allow it.\n * Currently only used by quests.\n * Use with caution, this function may change its signature, behavior, or even be removed in the future.\n *\n * @experimental\n * @param {string|Alias} name\n * @param {string|Expr|function(Expr):Partial} impl\n * @returns {SKI}\n */\n maybeAdd (name: string, impl: Expr | string | ((arg: Expr) => Invocation)): this {\n if (this.known[name])\n this.allow.add(name);\n else\n this.add(name, impl);\n return this;\n }\n\n /**\n * Declare and remove multiple terms at once\n * term=impl adds term\n * term= removes term\n * @param {string[]} list\n * @return {SKI} chainable\n */\n bulkAdd (list: string[]): this {\n for (const item of list) {\n const m = item.match(/^([A-Z]|[a-z][a-z_0-9]*)\\s*=\\s*(.*)$/s);\n // TODO check all declarations before applying any (but we might need earlier terms for parsing later ones)\n if (!m)\n throw new Error('bulkAdd: invalid declaration: ' + item);\n if (m[2] === '')\n this.remove(m[1]);\n else\n this.add(m[1], this.parse(m[2]));\n }\n\n return this;\n }\n\n /**\n * Restrict the interpreter to given terms. Terms prepended with '+' will be added\n * and terms preceeded with '-' will be removed.\n * @example ski.restrict('SK') // use the basis\n * @example ski.restrict('+I') // allow I now\n * @example ski.restrict('-SKI +BCKW' ); // switch basis\n * @example ski.restrict('-foo -bar'); // forbid some user functions\n * @param {string} spec\n * @return {SKI} chainable\n */\n restrict (spec: string): this {\n this.allow = restrict(this.allow, spec);\n return this;\n }\n\n /**\n *\n * @param {string} spec\n * @return {string}\n */\n showRestrict (spec = '+') {\n const out = [];\n let prevShort: boolean = true;\n for (const term of [...restrict(this.allow, spec)].sort()) {\n const nextShort = !!term.match(/^[A-Z]$/);\n if (out.length && !(prevShort && nextShort))\n out.push(' ');\n out.push(term);\n prevShort = nextShort;\n }\n return out.join('');\n }\n\n /**\n *\n * @param {String} name\n * @return {SKI}\n */\n remove (name: string): this {\n const old = this.known[name];\n if (old instanceof Alias)\n old.makeInline();\n delete this.known[name];\n this.allow.delete(name);\n return this;\n }\n\n /**\n *\n * @return {{[key:string]: Native|Alias}}\n */\n getTerms (): { [key: string]: Expr } {\n const out: { [key: string]: Expr } = {};\n for (const name of Object.keys(this.known)) {\n if (this.allow.has(name))\n out[name] = this.known[name];\n }\n return out;\n }\n\n /**\n * Export term declarations for use in bulkAdd().\n * Currently only Alias terms are serialized.\n * @returns {string[]}\n */\n declare (): string[] {\n // TODO accept argument to declare specific terms only\n const env: { [key: string]: Alias } = {};\n for (const [name, term] of Object.entries(this.getTerms())) {\n if (term instanceof Alias)\n env[name] = term;\n }\n\n // avert conflicts if native terms were redefined:\n // create a temporary alias for each native term that was redefined;\n // replace usage of redefined term in subexpressions;\n // finally, remove the temporary aliases from the output\n const needDetour: { [key: string]: Alias } = {};\n let i = 1;\n for (const name in native) {\n if (!(env[name] instanceof Alias))\n continue;\n while ('tmp' + i in env)\n i++;\n const temp = new Alias('tmp' + i, env[name]);\n needDetour[temp.name] = env[name];\n env[temp.name] = temp;\n delete env[name];\n }\n\n // console.log(env);\n\n const list = toposort(undefined, env).list;\n\n const detour = new Map<Alias, Alias>();\n if (Object.keys(needDetour).length) {\n // replace aliases with their detoured counterparts.\n // we have to go recursive, otherwise an unrelated alias may be expanded to its impl\n // and name infos will be erased\n const rework = (expr: Expr): Expr => {\n return expr.traverse((e: Expr) => {\n if (!(e instanceof Alias))\n return null; // continue\n const newAlias = detour.get(e);\n if (newAlias)\n return newAlias;\n return new Alias(e.name, rework(e.impl));\n }) ?? expr;\n };\n\n for (let j = 0; j < list.length; j++) {\n // upon processing list[j], only terms declared before it may be detoured\n list[j] = rework(list[j]);\n detour.set(needDetour[(list[j] as Alias).name], list[j] as Alias);\n env[(list[j] as Alias).name] = list[j] as Alias;\n // console.log(`list[${j}] = ${(list[j] as Alias).name}=${(list[j] as Alias).impl};`);\n }\n // console.log('detour:', detour);\n }\n\n // console.log(res);\n const out = list.map(e => needDetour[(e as Alias).name]\n ? (e as Alias).name + '=' + needDetour[(e as Alias).name].name + '=' + (e as Alias).impl.format({ inventory: env })\n : (e as Alias).name + '=' + (e as Alias).impl.format({ inventory: env })\n );\n\n for (const [name, temp] of detour)\n out.push((name as Alias).name + '=' + temp, temp + '=');\n\n return out;\n }\n\n /**\n * @template T\n * @param {string} source\n * @param {Object} [options]\n * @param {{[keys: string]: Expr}} [options.env]\n * @param {T} [options.scope]\n * @param {boolean} [options.numbers]\n * @param {boolean} [options.lambdas]\n * @param {string} [options.allow]\n * @return {Expr}\n */\n parse (source: string, options: ParseOptions = {}): Expr {\n if (typeof source !== 'string')\n throw new Error('parse: source must be a string, got ' + typeof source);\n\n const lines = source.replace(/\\/\\/[^\\n]*$/gm, ' ')\n .replace(/\\/\\*.*?\\*\\//gs, ' ')\n .trim()\n .split(/\\s*;[\\s;]*/).filter( s => s.match(/\\S/));\n\n const jar = { ...options.env };\n\n let expr: Expr = new Empty();\n for (const item of lines) {\n if (expr instanceof Alias)\n expr.makeInline();\n\n const def = item.match(/^([A-Z]|[a-z][a-z_0-9]*)\\s*=(.*)$/s);\n if (def && def[2] === '')\n expr = new FreeVar(def[1], options.scope ?? FreeVar.global);\n else\n expr = this.parseLine(item, jar, options);\n\n if (def) {\n if (jar[def[1]] !== undefined)\n throw new Error('Attempt to redefine a known term: ' + def[1]);\n jar[def[1]] = expr;\n }\n\n // console.log('parsed line:', item, '; got:', expr,'; jar now: ', jar);\n }\n\n if (this.addContext) {\n // create a transparent alias to avoid mutating the original term\n if (expr instanceof Named)\n expr = new Alias(expr.name, expr, { inline: true });\n expr.context = {\n env: { ...this.getTerms(), ...jar }, // also contains pre-parsed terms\n scope: options.scope,\n src: source,\n parser: this,\n };\n }\n return expr;\n }\n\n /**\n * Parse a single line of source code, without splitting it into declarations.\n * Internal, always use parse() instead.\n * @template T\n * @param {String} source S(KI)I\n * @param {{[keys: string]: Expr}} env\n * @param {Object} [options]\n * @param {{[keys: string]: Expr}} [options.env] - unused, see 'env' argument\n * @param {T} [options.scope]\n * @param {boolean} [options.numbers]\n * @param {boolean} [options.lambdas]\n * @param {string} [options.allow]\n * @return {Expr} parsed expression\n */\n parseLine (source: string, env: { [key: string]: Expr } = {}, options: ParseOptions = {}): Expr {\n const aliased = source.match(/^\\s*([A-Z]|[a-z][a-z_0-9]*)\\s*=\\s*(.*)$/s);\n if (aliased)\n return new Alias(aliased[1], this.parseLine(aliased[2], env, options));\n\n const opt = {\n numbers: options.numbers ?? this.hasNumbers,\n lambdas: options.lambdas ?? this.hasLambdas,\n allow: restrict(this.allow, options.allow),\n };\n // make sure '+' usage is in sync with numerals\n if (opt.numbers) opt.allow.add('+'); else opt.allow.delete('+');\n\n const tokens = combChars.split(source);\n\n const empty = new Empty();\n /** @type {Expr[]} */\n const stack: Expr[] = [empty];\n const context = options.scope || FreeVar.global; // default is global unbound vars\n\n // TODO each token should carry along its position in source\n for (const c of tokens) {\n // console.log(\"parseLine: found \"+c+\"; stack =\", stack.join(\", \"));\n if (c === '(')\n stack.push(empty);\n else if (c === ')') {\n if (stack.length < 2)\n throw new Error('unbalanced input: extra closing parenthesis' + source);\n const x = postParse(stack.pop()!);\n const f = stack.pop()!;\n stack.push(f.apply(x));\n } else if (c === '->') {\n if (!opt.lambdas)\n throw new Error('Lambdas not supported, allow them explicitly');\n stack.push(new PartialLambda(stack.pop()!));\n } else if (c.match(/^[0-9]+$/)) {\n if (!opt.numbers)\n throw new Error('Church numbers not supported, allow them explicitly');\n const f = stack.pop()!;\n stack.push(f.apply(new Church(Number.parseInt(c))));\n } else {\n const f = stack.pop()!;\n if (!env[c] && this.known[c] && !opt.allow.has(c)) {\n throw new Error('Term \\'' + c + '\\' is not in the restricted set '\n + [...opt.allow].sort().join(' '));\n }\n // look in temp vars first, then in known terms, then fallback to creating free var\n const x = env[c] ?? this.known[c] ?? (env[c] = new FreeVar(c, context));\n stack.push(f.apply(x));\n }\n }\n\n if (stack.length !== 1) {\n throw new Error('unbalanced input: missing '\n + (stack.length - 1) + ' closing parenthesis:' + source);\n }\n\n return postParse(stack.pop()!);\n }\n\n toJSON () {\n return {\n version: '1.1.1', // set to incremented package.json version whenever SKI serialization changes\n allow: this.showRestrict('+'),\n numbers: this.hasNumbers,\n lambdas: this.hasLambdas,\n annotate: this.annotate,\n terms: this.declare(),\n }\n }\n\n /**\n * Public static shortcuts to common functions (see also ./extras.js)\n */\n}\n\nfunction maybeAlias (name: string, impl: Expr): Named {\n // Remove unnecessary extra aliases with the same name\n while (impl instanceof Alias && impl.name === name)\n impl = impl.impl;\n if (impl instanceof Named && impl.name === name)\n return impl;\n return new Alias(name, impl, { canonize: true });\n}\n", "import { Parser } from './parser';\nimport { Expr, FreeVar, Alias, Named, control, TermInfo, App } from './expr';\n\nexport type CaseResult = {\n pass: boolean,\n reason?: string,\n steps: number,\n start: Expr,\n found: Expr,\n expected?: Expr,\n note?: string,\n args: Expr[],\n case: Case\n};\n\nexport type Capability = {\n linear?: boolean,\n affine?: boolean,\n normal?: boolean,\n proper?: boolean,\n discard?: boolean,\n duplicate?: boolean,\n arity?: number,\n};\n\nexport type TestCase =\n [string, string]\n | [{max?: number}, string, string]\n | [{caps: Capability, max?: number}, string];\n\nexport type InputSpec = {\n name: string,\n fancy?: string,\n allow?: string,\n numbers?: boolean,\n lambdas?: boolean\n};\n\nexport type SolEntry = { input: string[], result: QuestResult };\n\nexport type QuestResult = {\n pass: boolean,\n details: CaseResult[],\n expr?: Expr,\n input: Expr[]|string[],\n exception?: Error,\n steps: number,\n weight?: number\n};\n\nexport type QuestSpec = {\n input: string | InputSpec | (string | InputSpec)[],\n cases: TestCase[],\n\n // the rest is optional\n\n allow?: string,\n numbers?: boolean,\n lambdas?: boolean,\n env?: string[],\n engine?: Parser,\n engineFull?: Parser,\n\n // metadata, also any fields not listed here will go to quest.meta.???\n id?: string | number,\n name?: string,\n intro?: string | string[], // multiple strings will be concatenated with spaces\n} & Record<string, unknown>; // allow any extra fields in the spec, they will be copied to quest.meta\n\nexport type SelfCheck = { accepted?: string[][], rejected?: string[][] };\n\nexport type AddCaseOptions = {\n engine?: Parser,\n env?: { [key: string]: Expr },\n max?: number,\n note?: string,\n caps?: Capability,\n canonize?: {\n max?: number,\n maxSize?: number,\n maxArgs?: number,\n },\n};\n\n/**\n * A combinator problem with a set of test cases for the proposed solution.\n * @param {QuestSpec} options\n * @example const quest = new Quest({\n * input: 'identity',\n * cases: [\n * ['identity x', 'x'],\n * ],\n * allow: 'SK',\n * intro: 'Find a combinator that behaves like the identity function.',\n * });\n * quest.check('S K K'); // { pass: true, details: [...], ... }\n * quest.check('K S'); // { pass: false, details: [...], ... }\n * quest.check('K x'); // fail! internal variable x is not equal to free variable x,\n * // despite having the same name.\n * quest.check('I'); // fail! I not in the allowed list.\n */\nexport class Quest {\n input: (InputSpec & {placeholder: FreeVar})[];\n cases: Case[];\n\n engineFull: Parser;\n engine: Parser;\n restrict: { allow?: string, numbers?: boolean, lambdas?: boolean };\n env: { [key: string]: Expr };\n envFull: { [key: string]: Expr };\n id?: string | number;\n name?: string\n intro?: string;\n // yes allow any\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n meta?: Record<string, unknown>;\n\n constructor (options: QuestSpec) {\n const { input, cases, allow, numbers, lambdas, engine, engineFull, ...meta } = options;\n const env = options.env ?? []; // backwards compatibility\n\n //\n this.engineFull = engineFull ?? new Parser();\n this.engine = engine ?? this.engineFull;\n this.restrict = { allow, numbers: numbers ?? false, lambdas: lambdas ?? false };\n this.env = {};\n\n const jar = {};\n\n // option.env is a list of expressions.\n // we suck all free variables + all term declarations from there into this.env\n // to feed it later to every case's parser.\n for (const term of env ?? []) {\n const expr: Expr = this.engineFull.parse(term, { env: jar, scope: this });\n if (expr instanceof Alias)\n this.env[expr.name] = new Alias(expr.name, expr.impl, { canonize: false });\n // Canonized aliases won't expand with insufficient arguments,\n // causing correct solutions to fail, so alas...\n else if (expr instanceof FreeVar)\n this.env[expr.name] = expr;\n else\n throw new Error('Unsupported given variable type: ' + term);\n }\n\n this.input = [];\n for (const term of Array.isArray(input) ? input : [input])\n this.addInput(term);\n if (!this.input.length)\n throw new Error('Quest needs at least one input placeholder');\n\n this.envFull = { ...this.env, ...jar };\n for (const term of this.input) {\n if (term.name in this.envFull)\n throw new Error('input placeholder name is duplicated or clashes with env: ' + term.name);\n this.envFull[term.name] = term.placeholder;\n }\n\n // NOTE meta is a local variable, can mutate\n // TODO title/descr are old name/intro respectively, do smth about it (or forget)\n this.cases = [];\n this.name = options.name;\n this.intro = list2str(options.intro);\n this.id = options.id;\n this.meta = meta;\n\n for (const c of cases ?? [])\n (this.add as (...args: unknown[]) => void)(...c);\n }\n\n /**\n * Display allowed terms based on what engine thinks of this.env + this.restrict.allow\n * @return {string}\n */\n allowed () {\n const allow = this.restrict.allow ?? '';\n const env = Object.keys(this.env).sort();\n // In case vars are present and restrictions aren't, don't clutter the output with all the known terms\n return allow\n ? this.engine.showRestrict(allow + '+' + env.join(' '))\n : env.map( s => '+' + s).join(' ');\n }\n\n addInput (term: string | InputSpec): void {\n if (typeof term !== 'object')\n term = { name: term };\n if (typeof term.name !== 'string')\n throw new Error(\"quest 'input' field must be a string or a {name: string, ...} object\");\n\n const full = term as InputSpec & { placeholder: FreeVar };\n full.placeholder = new FreeVar(term.name);\n // TODO more checks\n this.input.push(full);\n }\n\n /**\n *\n * @param {{} | string} opt\n * @param {string} terms\n * @return {Quest}\n */\n add (opt: AddCaseOptions | string, ...terms: string[]) {\n let o: AddCaseOptions;\n if (typeof opt === 'string') {\n terms.unshift(opt);\n o = {};\n } else\n o = { ...opt };\n\n o.engine = o.engine ?? this.engineFull;\n o.env = o.env ?? this.envFull;\n\n const input = this.input.map( t => t.placeholder );\n this.cases.push(\n o.caps\n ? new PropertyCase(input, o, terms)\n : new ExprCase(input, o, terms)\n );\n return this;\n }\n\n /**\n * Statefully parse a list of strings into expressions or fancy aliases thereof.\n * @param {string[]} input\n * @return {{terms: Expr[], weight: number}}\n */\n prepare (...input: string[]) {\n if (input.length !== this.input.length)\n throw new Error('Solutions provided ' + input.length + ' terms where ' + this.input.length + ' are expected');\n\n let weight = 0;\n const prepared = [];\n const jar = { ...this.env };\n for (let i = 0; i < input.length; i++) {\n const spec = this.input[i];\n const impl = this.engine.parse(input[i], {\n env: jar,\n allow: spec.allow ?? this.restrict.allow,\n numbers: spec.numbers ?? this.restrict.numbers,\n lambdas: spec.lambdas ?? this.restrict.lambdas,\n });\n const arsenal = { ...this.engine.getTerms(), ...jar };\n weight += impl.fold(0, (a, e) => {\n if (e instanceof Named && arsenal[e.name] === e)\n return control.prune( a + 1);\n });\n const expr = impl instanceof FreeVar\n ? impl\n : new Alias(spec.fancy ?? spec.name, impl, { canonize: false });\n jar[spec.name] = expr;\n prepared.push(expr);\n }\n return {\n prepared,\n weight,\n };\n }\n\n /**\n *\n * @param input\n * @return {QuestResult}\n */\n check (...input: string[]): QuestResult {\n try {\n const { prepared, weight } = this.prepare(...input);\n const details = this.cases.map( c => c.check(...prepared) ) as unknown as CaseResult[];\n const pass = details.reduce((acc, val) => acc && val.pass, true);\n const steps = details.reduce((acc, val) => acc + val.steps, 0);\n return {\n expr: prepared[0],\n input: prepared,\n pass,\n steps,\n details,\n weight,\n };\n } catch (e) {\n return { pass: false, details: [], exception: e as Error, steps: 0, input };\n }\n }\n\n verify (options: { solutions?: SelfCheck | { [key: string | number]: SelfCheck }, seen?: Set<string | number>, date?: boolean }) {\n const findings: { [key: string]: unknown } = this.verifyMeta(options);\n if (options.solutions) {\n const solCheck = this.verifySolutions(options.solutions);\n if (solCheck)\n findings.solutions = solCheck;\n }\n if (options.seen) {\n if (!this.id)\n findings.seen = 'No id in quest ' + (this.name ?? '(unnamed)');\n if (options.seen.has(this.id!))\n findings.seen = 'Duplicate quest id ' + this.id;\n options.seen.add(this.id!); // mutating but who cares\n }\n return Object.keys(findings).length ? findings : null;\n }\n\n /**\n * Verify that solutions that are expected to pass/fail do so.\n * @param {SelfCheck|{[key: string]: SelfCheck}} dataset\n * @return {{shouldPass: {input: string[], result: QuestResult}[], shouldFail: {input: string[], result: QuestResult}[]} | null}\n */\n verifySolutions (dataset: SelfCheck | { [key: string | number]: SelfCheck }) {\n // dataset is either a SelfCheck object or a hash of { quest_id: SelfCheck }\n if (typeof dataset === 'object' && !Array.isArray((dataset as SelfCheck).accepted) && !Array.isArray((dataset as SelfCheck).rejected)) {\n // dataset is a hash of { quest_id: SelfCheck } so extract data\n if (!this.id || !(dataset as { [key: string | number]: SelfCheck })[this.id])\n return null; // no self-check data for this quest, skip\n }\n\n const byId = this.id !== undefined ? (dataset as { [key: string | number]: SelfCheck })[this.id] : undefined;\n const { accepted = [], rejected = [] } = byId ?? (dataset as SelfCheck);\n\n const ret: { shouldPass: SolEntry[], shouldFail: SolEntry[] } = { shouldPass: [], shouldFail: [] };\n for (const input of accepted) {\n const result = this.check(...input);\n if (!result.pass)\n ret.shouldPass.push({ input, result });\n }\n for (const input of rejected) {\n const result = this.check(...input);\n if (result.pass)\n ret.shouldFail.push({ input, result });\n }\n return (ret.shouldFail.length + ret.shouldPass.length) ? ret : null; // return null if all good\n }\n\n verifyMeta (options: { date?: boolean } = {}): { [key: string]: unknown } {\n const findings: { [key: string]: unknown } = {};\n\n for (const field of ['name', 'intro']) {\n const found = checkHtml((this as unknown as { [key: string]: string })[field]);\n if (found)\n findings[field] = found;\n }\n if (options.date) {\n const date = new Date(this.meta?.created_at as string);\n if (isNaN(date.getTime()))\n findings.date = 'invalid date format: ' + this.meta?.created_at;\n else if (date.getTime() < new Date('2024-07-15').getTime() || date.getTime() > new Date().getTime())\n findings.date = 'date out of range: ' + this.meta?.created_at;\n }\n\n return findings;\n }\n\n /**\n *\n * @return {TestCase[]}\n */\n show ():Case[] {\n return [...this.cases];\n }\n\n static Group: new (options: { name?: string, intro?: string | string[], id?: string | number, content?: (Quest | QuestSpec)[] }) => { verify: (options: { seen?: Set<string | number>, date?: boolean }) => { [key: string]: unknown } };\n static Case: abstract new (input: FreeVar[], options: AddCaseOptions) => Case;\n}\n\nexport abstract class Case {\n /**\n * @param {FreeVar[]} input\n * @param {{\n * max?: number,\n * note?: string,\n * env?: {[key:string]: Expr},\n * engine: Parser\n * }} options\n */\n max: number;\n note: string;\n env: { [key: string]: Expr };\n input: FreeVar[];\n engine: Parser;\n constructor (input: FreeVar[], options: AddCaseOptions) {\n this.max = options.max ?? 1000;\n this.note = options.note!;\n this.env = { ...(options.env ?? {}) }; // note: env already contains input placeholders\n this.input = input;\n this.engine = options.engine!;\n }\n\n parse (src: string) {\n return new Subst(this.engine.parse(src, { env: this.env, scope: this }), this.input);\n }\n\n /**\n * @param input\n * @return {CaseResult}\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n abstract check ( ...input: Expr[] ): CaseResult;\n}\n\nexport class ExprCase extends Case {\n e1: Subst;\n e2: Subst;\n canonize?: {\n max?: number,\n maxSize?: number,\n maxArgs?: number,\n };\n\n /**\n * @param {FreeVar[]} input\n * @param {{\n * max?: number,\n * note?: string,\n * env?: {string: Expr},\n * canonize?: { max?: number, maxSize?: number, maxArgs?: number },\n * engine?: Parser\n * }} options\n * @param {[e1: string, e2: string]} terms\n */\n constructor (input: FreeVar[], options: AddCaseOptions, terms: string[]) {\n if (terms.length !== 2)\n throw new Error('Case accepts exactly 2 strings');\n\n super(input, options);\n\n this.canonize = options.canonize;\n [this.e1, this.e2] = terms.map( (s: string) => this.parse(s) );\n }\n\n check (...input: Expr[]): CaseResult {\n const e1 = this.e1.apply(input);\n const r1 = e1.run({ max: this.max });\n const e2 = this.e2.apply(input);\n const r2 = e2.run({ max: this.max });\n\n // TODO monads, monads everywhere\n let reason: string | null = null;\n if (!r1.final || !r2.final)\n reason = 'failed to reach normal form in ' + this.max + ' steps';\n else {\n reason = this.canonize\n ? canonize(r1.expr, this.canonize).diff(canonize(r2.expr, this.canonize))\n : r1.expr.diff(r2.expr);\n }\n\n return {\n pass: !reason,\n reason: reason ?? undefined,\n steps: r1.steps,\n start: e1,\n found: r1.expr,\n expected: r2.expr,\n note: this.note,\n args: input,\n case: this,\n };\n }\n}\n\nconst knownCaps: { [key: string]: boolean } = {\n normal: true,\n proper: true,\n discard: true,\n duplicate: true,\n linear: true,\n affine: true,\n arity: true,\n}\n\nexport class PropertyCase extends Case {\n expr: Subst;\n caps: Capability;\n isAffine?: boolean;\n // test that an expression uses all of its inputs exactly once\n constructor (input: FreeVar[], options: AddCaseOptions, terms: string[]) {\n super(input, options);\n if (terms.length > 1)\n throw new Error('PropertyCase accepts exactly 1 string');\n if (!options.caps || typeof options.caps !== 'object' || !Object.keys(options.caps).length)\n throw new Error('PropertyCase requires a caps object with at least one capability');\n const unknown = Object.keys(options.caps).filter( c => !knownCaps[c] );\n if (unknown.length)\n throw new Error('PropertyCase: don\\'t know how to test these capabilities: ' + unknown.join(', '));\n\n this.expr = this.parse(terms[0]);\n this.caps = { ...options.caps };\n\n if (this.caps.linear) {\n delete this.caps.linear;\n this.caps.duplicate = false;\n this.caps.discard = false;\n this.caps.normal = true;\n }\n\n if (this.caps.affine) {\n delete this.caps.affine;\n this.isAffine = true;\n }\n }\n\n check (...input: Expr[]): CaseResult {\n const start = this.expr.apply(input);\n const r = start.run({ max: this.max });\n const guess = r.expr.infer({ max: this.max });\n\n const reason: string[] = [];\n for (const cap in this.caps) {\n if ((guess as unknown as { [key: string]: unknown })[cap] !== (this.caps as unknown as { [key: string]: unknown })[cap])\n reason.push('expected property ' + cap + ' to be ' + (this.caps as unknown as { [key: string]: unknown })[cap] + ', found ' + (guess as unknown as { [key: string]: unknown })[cap]);\n }\n\n if (this.isAffine) {\n // const initial: MaybeTerm|undefined = undefined;\n const badGuy = start.fold<{ expr: Expr, props: TermInfo }|undefined>(\n undefined, (acc, expr) => {\n if (expr instanceof App || expr instanceof FreeVar)\n return;\n const props = expr.infer({ max: this.max });\n if (!props.expr || props.duplicate)\n return control.stop({ expr, props });\n\n // don't descend into aliases EXCEPT that input is aliases too and we definitely descend into them\n // so B=S(KS)K; B is affine (which it is) but S(KS)K alone isn't\n if (expr instanceof Alias && input.indexOf(expr) < 0)\n return control.prune(acc);\n }\n );\n if (badGuy) {\n reason.push(\n 'found unexpected subterm ' + badGuy.expr + (badGuy.props.expr\n ? ' that duplicates arguments'\n : ' without a normal form'\n )\n );\n }\n }\n\n return {\n pass: !reason.length,\n reason: reason.length ? reason.join('\\n') : undefined,\n steps: r.steps,\n start,\n found: r.expr,\n case: this,\n note: this.note,\n args: input,\n };\n }\n}\n\n/**\n * A placeholder object with exactly n free variables to be substituted later.\n * Basically a poor man's n-fold lambda.\n *\n * @remarks Internal. Do not rely on name, meaning, or structure. It's only in the docs for completeness sake.\n *\n * @experimental\n *\n * @param {Expr} expr\n * @param {FreeVar[]} env\n */\nexport class Subst {\n expr: Expr;\n // TODO rename env => args wtf?\n env: FreeVar[];\n constructor (expr: Expr, env: FreeVar[]) {\n this.expr = expr;\n this.env = env;\n }\n\n apply (list:Expr[]):Expr {\n if (list.length !== this.env.length)\n throw new Error('Subst: expected ' + this.env.length + ' terms, got ' + list.length);\n\n let expr = this.expr;\n for (let i = 0; i < this.env.length; i++)\n expr = expr.subst(this.env[i], list[i]) ?? expr;\n\n return expr;\n }\n}\n\n// corresponds to \"chapter\" in the quest page\nclass Group {\n name?: string;\n intro?: string;\n id?: string|number;\n content?: Quest[];\n\n constructor (options: { name?: string, intro?: string | string[], id?: string | number, content?: (Quest | QuestSpec)[] }) {\n this.name = options.name;\n this.intro = list2str(options.intro);\n this.id = options.id;\n\n // TODO don't die on failed quests\n if (options.content)\n this.content = options.content.map( c => c instanceof Quest ? c : new Quest(c) );\n }\n\n verify (options: { seen?: Set<string | number>, date?: boolean }): { [key: string]: unknown } {\n const findings: { [key: string]: unknown } = {};\n const id = checkId(this.id!, options.seen!);\n if (id)\n findings.id = id;\n for (const field of ['name', 'intro']) {\n const found = checkHtml((this as unknown as { [key: string]: string })[field]);\n if (found)\n findings[field] = found;\n }\n\n findings.content = this.content!.map(q => q.verify(options));\n return findings;\n }\n}\n\n/**\n * Concatenate long strings represented as arrays, or just pass along if already string or undefined.\n * @param {string|Array<string>|undefined} str\n * @returns {string|undefined}\n */\nfunction list2str (str: string|string[]|undefined):string|undefined {\n // TODO better arg validation\n if (str === undefined || typeof str === 'string')\n return str;\n return Array.isArray(str) ? str.join(' ') : '' + str;\n}\n\nfunction checkId (id:string|number, seen:Set<string|number>) {\n if (id === undefined)\n return 'missing';\n if (typeof id !== 'string' && typeof id !== 'number' )\n return 'is a ' + typeof id;\n if (seen) {\n if (seen.has(id))\n return 'duplicate id ' + id;\n seen.add(id);\n }\n // return nothing = success\n}\n\nfunction checkHtml (str: string): string | null {\n if (str === undefined)\n return 'missing';\n if (typeof str !== 'string')\n return 'not a string but ' + typeof str;\n\n // very basic check for unclosed tags, just to catch common mistakes in the quest text\n const tagStack = [];\n const tagRegex = /<\\/?([a-z]+)(?:\\s[^>]*)?>/gi;\n let match;\n while ((match = tagRegex.exec(str)) !== null) {\n const [fullTag, tagName] = match;\n if (fullTag.startsWith('</')) {\n // Closing tag\n if (tagStack.length === 0 || tagStack.pop() !== tagName)\n return (`Unmatched closing tag: </${tagName}>`);\n } else {\n // Opening tag\n tagStack.push(tagName);\n }\n }\n if (tagStack.length > 0)\n return (`Unclosed tags: ${tagStack.join(', ')}`);\n\n return null; // No issues found\n}\n\nQuest.Group = Group;\nQuest.Case = Case;\n\nfunction canonize (term: Expr, options = {}): Expr {\n return term.traverse({}, e => {\n return e.infer(options).expr;\n }) ?? term;\n}\n", "'use strict';\n\nimport { Expr, Alias, FreeVar, Named, FormatOptions, TermInfo } from './expr';\nimport { Quest } from './quest';\nimport { toposort } from './toposort';\n\n/**\n * Extra utilities that do not belong in the core.\n */\n\n/**\n * @experimental\n * Look for an expression that matches the predicate,\n * starting with the seed and applying the terms to one another.\n *\n * A predicate returning 0 (or nothing) means \"keep looking\",\n * a positive number stands for \"found\",\n * and a negative means \"discard this term from further applications\".\n *\n * The order of search is from shortest to longest expressions.\n *\n * @param {Expr[]} seed\n * @param {object} options\n * @param {number} [options.depth] - maximum generation to search for\n * @param {number} [options.tries] - maximum number of tries before giving up\n * @param {boolean} [options.infer] - whether to call infer(), default true.\n * @param {number} [options.maxArgs] - arguments in infer()\n * @param {number} [options.max] - step limit in infer()\n * @param {boolean} [options.noskip] - prevents skipping equivalent terms. Always true if infer is false.\n * @param {boolean} [retain] - if true. also add the whole cache to returned value\n * @param {({gen: number, total: number, probed: number, step: boolean}) => void} [options.progress]\n * @param {number} [options.progressInterval] - minimum number of tries between calls to options.progress, default 1000.\n * @param {(e: Expr, props: {}) => number?} predicate\n * @return {{expr?: Expr, total: number, probed: number, gen: number, cache?: Expr[][]}}\n */\nexport type SearchOptions = {\n depth?: number;\n tries?: number;\n infer?: boolean;\n maxArgs?: number;\n max?: number;\n noskip?: boolean;\n retain?: boolean;\n progress?: (info: { gen: number, total: number, probed: number, step: boolean }) => void;\n progressInterval?: number;\n};\nexport type SearchCallback = (e: Expr, props: TermInfo) => (number | undefined);\nexport type SearchResult = { expr?: Expr, total: number, probed: number, gen: number, cache?: Expr[][] };\n\nfunction search (seed: Expr[], options: SearchOptions, predicate: SearchCallback): SearchResult {\n const {\n depth = 16,\n infer = true,\n progressInterval = 1000,\n } = options;\n const hasSeen = infer && !options.noskip;\n\n // cache[i] = ith generation, 0 is empty\n const cache: Expr[][] = [[]];\n let total = 0;\n let probed = 0;\n const seen: {[s: string]: boolean} = {};\n\n const maybeProbe = (term: Expr) => {\n total++;\n const props = infer ? term.infer({ max: options.max, maxArgs: options.maxArgs }) : null;\n if (hasSeen && props && props.expr) {\n const key = String(props.expr);\n if (seen[key])\n return { res: -1 as number | undefined, props };\n seen[key] = true;\n }\n probed++;\n const res = predicate(term, props!);\n return { res, props };\n };\n\n // sieve through the seed\n for (const term of seed) {\n const { res = 0 } = maybeProbe(term);\n if (res > 0)\n return { expr: term, total, probed, gen: 1 };\n else if (res < 0)\n continue;\n\n cache[0].push(term);\n }\n\n let lastProgress = 0;\n\n for (let gen = 1; gen < depth; gen++) {\n if (options.progress) {\n options.progress({ gen, total, probed, step: true });\n lastProgress = total;\n }\n for (let i = 0; i < gen; i++) {\n for (const a of cache[gen - i - 1] || []) {\n for (const b of cache[i] || []) {\n if (total >= (options.tries ?? Infinity))\n return { total, probed, gen, ...(options.retain ? { cache } : {}) };\n if (options.progress && total - lastProgress >= progressInterval) {\n options.progress({ gen, total, probed, step: false });\n lastProgress = total;\n }\n const term = a.apply(b);\n const { res, props } = maybeProbe(term);\n\n if ((res ?? 0) > 0)\n return { expr: term, total, probed, gen, ...(options.retain ? { cache } : {}) };\n else if ((res ?? 0) < 0)\n continue;\n\n // if the term is not reducible, it is more likely to be a dead end, so we push it further away\n const offset = infer && props\n ? ((props.expr ? 0 : 3) + (props.dup ? 1 : 0) + (props.proper ? 0 : 1))\n : 0;\n if (!cache[gen + offset])\n cache[gen + offset] = [];\n cache[gen + offset].push(term);\n }\n }\n }\n }\n\n return { total, probed, gen: depth, ...(options.retain ? { cache } : {}) };\n}\n\n/**\n * Recursively replace all instances of Expr in a data structure with\n * respective string representation using the format() options.\n * Objects of other types and primitive values are eft as is.\n *\n * May be useful for debugging or diagnostic output.\n *\n * @experimental\n */\n// yes allow any in this function, it's pattern matched into correct classes during traverse\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction deepFormat (obj: any, options : FormatOptions = {}): any {\n if (obj instanceof Expr)\n return obj.format(options);\n // TODO for quests, use toJSON when it's ready\n if (obj instanceof Quest)\n return 'Quest(' + obj.name + ')';\n if (obj instanceof Quest.Case)\n return 'Quest.Case';\n if (Array.isArray(obj))\n return obj.map(item => deepFormat(item, options));\n if (typeof obj !== 'object' || obj === null || obj.constructor !== Object)\n return obj;\n\n // default = plain object\n const out: { [key: string]: unknown } = {};\n for (const key in obj)\n out[key] = deepFormat(obj[key], options);\n\n return out;\n}\n\n/**\n * Given an expression and a hash of named terms,\n * return a semicolon-separated string that declares said expression\n * unambiguously.\n *\n * @example\n * var expr = ski.parse(\"T=CI; V=BCT; V x y\");\n * SKI.extras.declare(expr, expr.context.env);\n * // 'B; C; I; T=CI; V=BC(T); x=; y=; Vx y'\n *\n * @param {Expr} expr\n * @param {{[s: string]: Named}} [env]\n * @returns {string}\n */\nfunction declare (expr: Expr, env: { [s: string]: Named } = {}): string {\n const res = toposort([expr], env);\n\n return res.list.map(s => {\n if (s instanceof Alias)\n return s.name + '=' + s.impl.format({ inventory: res.env });\n if (s instanceof FreeVar)\n return s.name + '=';\n return s.format({ inventory: res.env });\n }).join('; ');\n}\n\nconst isStringPair = (x: unknown) =>\n Array.isArray(x) && x.length === 2 && typeof x[0] === 'string' && typeof x[1] === 'string'\n ? undefined\n : 'must be a pair of strings';\nconst isStringTriple = (x: unknown) =>\n Array.isArray(x) && x.length === 3 && typeof x[0] === 'string' && typeof x[1] === 'string' && typeof x[2] === 'string'\n ? undefined\n : 'must be a triplet of strings';\n\nconst schema: Record<string, (arg0: unknown) => string | undefined> = {\n html: x => typeof x === 'boolean' ? undefined : 'must be a boolean',\n terse: x => typeof x === 'boolean' ? undefined : 'must be a boolean',\n space: x => typeof x === 'string' ? undefined : 'must be a string',\n brackets: isStringPair,\n var: isStringPair,\n around: isStringPair,\n redex: isStringPair,\n lambda: isStringTriple,\n inventory: x => {\n if (typeof x !== 'object' || x === null || x.constructor !== Object)\n return 'must be an object, not ' + (x?.constructor?.name ?? typeof x);\n const refined = x as Record<string, unknown>;\n for (const key of Object.keys(refined)) {\n if (!(refined[key] instanceof Expr))\n return 'key ' + key + 'is not an Expr';\n }\n return undefined;\n }\n}\n\n/**\n * Converts an unknown object into a FormatOptions, or returns an error it it is not valid.\n * A null/undefined counts as an empty options object (and is thus valid).\n */\nfunction checkFormatOptions (raw: unknown): { value: FormatOptions } | { error: Record<string, string> } {\n if (raw === null || raw === undefined)\n return { value: {} };\n\n if (typeof raw !== 'object' || Array.isArray(raw) || raw.constructor !== Object)\n return { error: { object: 'Format options must be an object, not ' + (raw?.constructor?.name ?? typeof raw) } };\n\n const rec = raw as Record<string, unknown>;\n const error: Record<string, string> = {};\n\n for (const key in rec) {\n if (schema[key]) {\n const err = schema[key](rec[key]);\n if (err)\n error[key] = err;\n } else\n error[key] = 'unknown option';\n }\n\n return Object.keys(error).length > 0 ? { error } : { value: rec as FormatOptions };\n}\n\nexport const extras = { search, deepFormat, declare, toposort, checkFormatOptions };\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAM,YAAN,MAAgB;AAAA,EAQrB,eAAgB,OAA4B;AAC1C,UAAM,MAAM,cAAc,MACvB,IAAI,OAAK,QAAQ,IAAI,GAAG,EACxB,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,EAClC,KAAK,GAAG;AACX,SAAK,MAAM,IAAI,OAAO,KAAK,KAAK;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAO,KAAuB;AAC5B,SAAK,IAAI,YAAY;AACrB,UAAM,OAAO,CAAC,GAAG,IAAI,SAAS,KAAK,GAAG,CAAC;AAGvC,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,OAAO,KAAK,SAAS;AAE3B,QAAI,SAAS,IAAI,QAAQ;AACvB,YAAM,IAAI,MAAM,2BAA2B,OAAO,MAAM,IAAI,SAChD,oBAAoB,IAAI,UAAU,IAAI,CAAC;AAAA,IACrD;AAGA,WAAO,KAAK,OAAO,OAAK,EAAE,CAAC,MAAM,MAAS,EAAE,IAAI,OAAK,EAAE,CAAC,CAAC;AAAA,EAC3D;AACF;AAEA,IAAM,cAAc,IAAI,UAAU,SAAS,SAAS,wBAAwB;AAWrE,SAAS,SAAU,KAAiB,MAAe;AACxD,MAAI,CAAC;AACH,WAAO;AACT,MAAI,MAAM,oBAAI,IAAI,CAAC,GAAG,GAAG,CAAC;AAC1B,MAAI,OAAO;AACX,QAAM,MAA6C;AAAA,IACjD,KAAK,SAAO;AAAE,YAAM,oBAAI,IAAI,CAAC,GAAG,CAAC;AAAG,aAAO;AAAA,IAAK;AAAA,IAChD,KAAK,SAAO;AAAE,UAAI,IAAI,GAAG;AAAA,IAAG;AAAA,IAC5B,KAAK,SAAO;AAAE,UAAI,OAAO,GAAG;AAAA,IAAG;AAAA,EACjC;AAEA,aAAW,OAAO,YAAY,MAAM,IAAI,GAAG;AACzC,QAAI,IAAI,GAAG;AACT,aAAO;AAAA;AAEP,UAAI,IAAI,EAAE,GAAG;AAAA,EACjB;AACA,SAAO;AACT;AAKO,IAAM,kBAAN,MAAyB;AAAA,EAe9B,YAAa,OAAsB,YAA+B;AAChE,SAAK,QAAQ;AACb,SAAK,aAAa;AAAA,EACpB;AACF;AAQO,SAAS,OAAW,OAAmD;AAE5E,MAAI,iBAAiB;AACnB,WAAO,CAAC,MAAM,SAAS,QAAW,MAAM,UAAU;AACpD,SAAO,CAAC,SAAS,QAAW,MAAS;AACvC;AAeO,SAAS,eAAgB,OAAsD;AACpF,QAAM,MAAyB,CAAI,UAAuB,IAAI,gBAAmB,OAAO,GAAG;AAC3F,EAAC,IAA2B,QAAQ;AACpC,MAAI,WAAW,MAAM,sBAAsB;AAC3C,SAAO;AACT;;;AC3HA,IAAM,WAAW;AAAA,EACf,KAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AACX;AAGA,IAAM,QAAqC;AAAA,EACzC,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,IAAsB;AAAA,EACtB,IAAsB;AACxB;AAKO,IAAM,UAAU;AAAA,EACrB,SAAS,eAAe,SAAS;AAAA,EACjC,OAAS,eAAe,OAAO;AAAA,EAC/B,MAAS,eAAe,MAAM;AAAA,EAC9B,MAAS,eAAe,MAAM;AAChC;AAMO,IAAM,SAAiC,CAAC;AA4DxC,IAAe,OAAf,MAAe,MAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoCzB,OAAQ,UAAkH,CAAC,GAAG;AAG5H,QAAI,QAAQ,UAAU,UAAa,gBAAgB;AACjD,WAAK,YAAY,QAAQ;AAE3B,QAAI,QAAQ,SAAS;AACnB,WAAK,OAAO,QAAQ;AAEtB,QAAI,QAAQ,UAAU;AACpB,WAAK,QAAQ,QAAQ;AAEvB,QAAI,QAAQ,UAAU;AACpB,YAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,UAAI,MAAM,QAAQ;AAChB,aAAK,QAAQ,KAAK,SAAS,MAAM;AACjC,aAAK,OAAO,KAAK,QAAQ,MAAM,KAAM,OAAO,EAAE,MAAM,MAAM,QAAQ,CAAC,IAAI,cAAc,EAAE,EAAE,CAAC;AAC1F,eAAO,MAAM;AACb,aAAK,QAAQ;AAAA,MACf;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,SAAU,MAAoB;AAE5B,QAAI,OAAa;AACjB,eAAW,OAAO;AAChB,aAAO,IAAI,IAAI,MAAM,GAAG;AAC1B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAgB;AACd,WAAO,KAAK,SAAS,OAAK;AACxB,UAAI,aAAa;AACf,eAAO,EAAE,KAAK,OAAO;AAAA,IACzB,CAAC,KAAK;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6BA,SACE,SACA,QACa;AACb,QAAI,OAAO,YAAY,YAAY;AACjC,eAAS;AACT,gBAAU,CAAC;AAAA,IACb;AACA,UAAM,QAAQ,MAAM,QAAQ,SAAS,IAAI;AACzC,QAAI,UAAU;AACZ,YAAM,IAAI,MAAM,8BAA8B,QAAQ,KAAK;AAC7D,UAAM,CAAC,IAAI,IAAI,OAAO,KAAK,eAAe,EAAE,MAAM,GAAG,MAAO,CAAC;AAC7D,WAAO,QAAQ;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,eAAgB,SAA0B,QAA+C;AACvF,QAAI;AAEJ,QAAI,OAAyB;AAC7B,QAAI;AACJ,OAAG;AACD,aAAO;AACP,YAAM,OAA4B,QAAQ,UAAU,OAChD,KAAK,kBAAkB,SAAS,MAAM,KAAK,OAAO,IAAI,IACtD,OAAO,IAAI,KAAK,KAAK,kBAAkB,SAAS,MAAM;AAC1D,OAAC,MAAM,MAAM,IAAI,OAAO,IAAI;AAAA,IAC9B,SAAS,QAAQ,WAAW,QAAQ;AACpC,QAAI,CAAC,QAAQ,SAAS;AACpB,aAAO;AACT,WAAO,SAAS,OAAO,IAAK,IAAI;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,kBAAmB,SAA0B,QAA+C;AAC1F,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAK,WAA0C;AAC7C,WAAO,UAAU,IAAI;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyBA,KAAS,SAAY,SAAsD;AACzE,UAAM,CAAC,KAAK,IAAI,OAAO,KAAK,MAAM,SAAS,OAAO,CAAC;AACnD,WAAO,SAAS;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAU,SAAW,SAAqE;AACxF,WAAO,QAAQ,SAAS,IAAI;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BA,aAAiB,KAAsC;AACrD,UAAM,CAAC,MAAM,GAAG,IAAI,IAAI,KAAK,OAAO;AACpC,WAAO,IAAI,MAAM,KAAK,IAAI,OAAK,EAAE,aAAa,GAAG,CAAC,CAAC;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAO,UAAgE,CAAC,GAAa;AACnF,UAAM,YAAqC,CAAC;AAC5C,UAAM,WAAsB,oBAAI,IAAI;AACpC,SAAK,SAAS,OAAK;AACjB,UAAI,aAAa,SAAS,CAAC,SAAS,IAAI,CAAC;AACvC,kBAAU,EAAE,IAAI,IAAI;AACtB,UAAI,aAAa;AACf,iBAAS,IAAI,EAAE,GAAG;AAAA,IACtB,CAAC;AACD,WAAO,KAAK,OAAO;AAAA,MACjB,KAAS,QAAQ,OAAO,SAAS;AAAA,MACjC,SAAS,QAAQ,WAAW,SAAS;AAAA,MACrC,SAAS,QAAQ,WAAW,SAAS;AAAA,MACrC;AAAA,IACF,GAAG,CAAC;AAAA,EAEN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAQ,SAA6F,OAAyB;AAC5H,UAAM,QAAmB,CAAC;AAC1B,QAAI,QAAQ;AAEZ,QAAI,OAAa;AAEjB,SAAM,UAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,KAAK;AAC9C,YAAM,OAAO,KAAK,IAAI,EAAE,KAAK,QAAQ,MAAM,OAAO,SAAS,QAAQ,QAAQ,CAAC;AAE5E,eAAS,KAAK;AACd,UAAI,CAAC,KAAK;AACR;AACF,UAAI,SAAS,KAAK,IAAI,GAAG;AAEvB,eAAO,KAAK;AACZ,YAAI,CAAC,KAAK,IAAI,OAAK,EAAE,aAAa,WAAW,aAAa,IAAI;AAC5D,iBAAO,YAAY,OAAO,MAAM,EAAE,MAAM,CAAC;AAC3C,cAAM,OAAO,KAAK,OAAO;AACzB,YAAI,UAAU;AACd,YAAI,YAAY;AAChB,cAAM,MAAM,CAAC;AACb,iBAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,gBAAM,MAAM,KAAK,CAAC,EAAE;AAAA,YAClB,EAAE,SAAS,QAAQ,UAAU,OAAO,KAAK,QAAQ,MAAM,OAAO,SAAS,QAAQ,SAAS,WAAW,QAAQ,UAAU;AAAA;AAAA,YACrH,QAAQ;AAAA;AAAA,UACV;AACA,mBAAS,IAAI,SAAS;AACtB,cAAI,CAAC,IAAI;AAEP,kBAAM;AACR,cAAI,IAAI;AACN,sBAAU;AACZ,cAAI,IAAI;AACN,wBAAY;AACd,cAAI,KAAK,IAAI,IAAI;AAAA,QACnB;AACA,eAAO,YAAY,OAAO,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,EAAE,SAAS,WAAW,MAAM,CAAC;AAAA,MAChF;AACA,aAAO,QAAQ,UAAU,OAAO,QAAQ,CAAC,EAAE,IAAI;AAC7C;AACF,YAAM,OAAO,OAAO,QAAQ,CAAC;AAC7B,YAAM,KAAK,IAAI;AACf,aAAO,KAAK,KAAK,MAAM,IAAI;AAAA,IAC7B;AACA,WAAO,EAAE,QAAQ,OAAO,QAAQ,OAAO,MAAM;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,SAAkB;AAGhB,WAAO,CAAC,IAAI;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,CAAE,SAAU,UAA8C,CAAC,GAAG;AAC5D,QAAI,OAAmB,KAAK,SAAS,OAAK;AACxC,UAAI,aAAa,WAAW,aAAa,OAAO,aAAa,UAAU,aAAa;AAClF,eAAO;AACT,YAAM,QAAQ,EAAE,MAAM,EAAE,KAAK,QAAQ,KAAK,SAAS,QAAQ,QAAQ,CAAC;AACpE,UAAI,CAAC,MAAM;AACT,cAAM,IAAI,MAAM,mDAAmD,CAAC;AACtE,aAAO,MAAM;AAAA,IACf,CAAC,KAAK;AACN,UAAM,OAAO,oBAAI,IAAI;AACrB,QAAI,QAAQ;AACZ,WAAO,MAAM;AACX,YAAM,OAAO,KAAK,SAAS,EAAE,OAAO,KAAK,GAAG,OAAK;AAC/C,YAAI,KAAK,IAAI,CAAC;AACZ,iBAAO;AACT,YAAI,aAAa,OAAO,EAAE,eAAe,QAAQ;AAC/C,gBAAM,QAAQ,EAAE,MAAM,EAAE,KAAK,QAAQ,KAAK,SAAS,QAAQ,QAAQ,CAAC;AACpE,mBAAS,MAAM,SAAS;AACxB,cAAI,CAAC,MAAM,QAAQ;AACjB,iBAAK,IAAI,CAAC;AACV,mBAAO;AAAA,UACT;AACA,iBAAO,QAAQ,KAAK,MAAM,IAAI;AAAA,QAChC;AAAA,MACF,CAAC;AACD,YAAM,EAAE,MAAM,MAAM;AACpB,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,CAAE,MAAO,UAA4C,CAAC,GAAG;AAGvD,QAAI,OAAiB,KAAK,SAAS,OAAK;AACtC,UAAI,aAAa,WAAW,aAAa,OAAO,aAAa,UAAU,aAAa;AAClF,eAAO;AAET,aAAO,EAAE,MAAM,OAAO,EAAE;AAAA,IAC1B,CAAC,KAAK;AAEN,QAAI,QAAQ;AACZ,WAAO,MAAM;AACX,YAAM,OAAO,KAAK,SAAS,EAAE,OAAO,KAAK,GAAG,OAAK;AAC/C,YAAI,EAAE,aAAa,WAAY,EAAE,gBAAgB;AAC/C,iBAAO;AACT,YAAI,EAAE,SAAS,EAAE;AACf,iBAAO,QAAQ,KAAK,OAAO,CAAC;AAC9B,YAAI,CAAC,EAAE,KAAK,IAAI,OAAK,MAAM,EAAE,GAAG;AAC9B,iBAAO,QAAQ,KAAK,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC;AAE5C,YAAI,EAAE,EAAE,gBAAgB;AACtB,gBAAM,IAAI,MAAM,6DAA6D,EAAE,KAAK,YAAY,IAAK;AAEvG,YAAI,EAAE,KAAK,QAAQ,EAAE,OAAO,CAAC,EAAE,KAAK,IAAI,IAAI,OAAK,MAAM,EAAE,GAAG;AAC1D,iBAAO,QAAQ,KAAK,EAAE,KAAK,GAAG;AAEhC,eAAO,QAAQ,KAAK,OAAO,EAAE,MAAM,IAAI,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,GAAG,IAAI,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC;AAAA,MAClG,CAAC;AACD,YAAM,EAAE,MAAM,OAAO,OAAO,CAAC,KAAK;AAClC;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAOA,SAAa,SAAyB;AAC3C,WAAO,SAASA,UAAS,UAAU;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,OAAQ,KAA6B;AACnC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAc;AAAE,WAAO,EAAE,MAAM,MAAM,OAAO,GAAG,SAAS,MAAM;AAAA,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAehE,IAAK,MAAwB,CAAC,MAAM,MAAmB;AACrD,QAAI,eAAe,OAAM;AACvB,WAAK,QAAQ,GAAG;AAChB,YAAM,CAAC;AAAA,IACT;AACA,QAAI,OAAO,OAAO,KAAK,MAAM,GAAG,IAAI,IAAI;AACxC,QAAI,QAAQ,IAAI,SAAS;AAEzB,UAAM,MAAM,KAAK,IAAI,IAAI,OAAO,SAAS,KAAK,CAAC,IAAI;AACnD,QAAI,QAAQ;AACZ,WAAO,QAAQ,OAAO;AACpB,YAAM,OAAO,KAAK,KAAK;AACvB,UAAI,CAAC,KAAK,SAAS;AACjB,gBAAQ;AACR;AAAA,MACF;AACA,WAAK,KAAK,KAAK,QAAQ,MAAM,IAAI,WAAW,SAAS;AACnD;AACF,eAAS,KAAK;AACd,aAAO,KAAK;AAAA,IACd;AACA,QAAI,IAAI,SAAS,CAAC;AAChB,YAAM,IAAI,MAAM,qCAAqC,MAAM,QAAQ;AACrE,WAAO,EAAE,OAAO,OAAO,KAAK;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,CAAE,KAAM,UAA+C,CAAC,GAA0B;AAChF,UAAM,MAAM,QAAQ,OAAO;AAC3B,QAAI,QAAQ;AAEZ,QAAI,OAAY;AAChB,QAAI,QAAQ;AAEZ,WAAO,QAAQ,QAAQ,KAAK,QAAQ,MAAM,QAAQ,WAAW,SAAS,UAAU;AAI9E,YAAM,OAAO,KAAK,KAAK;AACvB,UAAI,CAAC,KAAK;AACR,gBAAQ;AACV,YAAM,EAAE,MAAM,OAAO,MAAM;AAC3B,UAAI;AACF;AACF,eAAS,KAAK;AACd,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,OAAQ,OAAoB;AAC1B,WAAO,CAAC,KAAK,KAAK,KAAK;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyBA,KAAM,OAAY,OAAgB,OAAsB;AACtD,QAAI,SAAS;AACX,aAAO;AACT,QAAI,iBAAiB;AACnB,aAAO,MAAM,KAAK,KAAK,MAAM,CAAC,IAAI;AACpC,WAAO,OACH,MAAM,QAAQ,SAAS,OAAQ,MAC/B,MAAM,OAAQ,SAAS,QAAQ;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,OAAQ,QAAoB,UAAU,IAAS;AAC7C,cAAU,UAAU,UAAU,OAAO;AACrC,QAAI,EAAE,kBAAkB,QAAO;AAC7B,YAAM,IAAI,MAAM,UAAU,sCACrB,QAAQ,aAAa,QAAQ,OAAO,OAAO;AAAA,IAClD;AACA,UAAM,OAAO,KAAK,KAAK,MAAM;AAC7B,QAAI,CAAC;AACH;AAIF,UAAM,WAAW,IAAI,MAAM,UAAU,IAAI;AACzC,aAAS,WAAW,KAAK,KAAK;AAC9B,aAAS,SAAS,OAAO,KAAK;AAC9B,UAAM;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,WAAoB;AAClB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,QAAS,SAA2B;AAClC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,UAAW,KAAoB;AAC7B,WAAO,KAAK,QAAQ,IAAI;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqCA,OAAQ,UAAyB,CAAC,GAAW;AAC3C,UAAM,WAAiC,QAAQ,OAC3C;AAAA,MACA,UAAU,CAAC,KAAK,GAAG;AAAA,MACnB,OAAU;AAAA,MACV,KAAU,CAAC,SAAS,QAAQ;AAAA,MAC5B,QAAU,CAAC,IAAI,SAAS,EAAE;AAAA,MAC1B,QAAU,CAAC,IAAI,EAAE;AAAA,MACjB,OAAU,CAAC,IAAI,EAAE;AAAA,IACnB,IACE;AAAA,MACA,UAAU,CAAC,KAAK,GAAG;AAAA,MACnB,OAAU;AAAA,MACV,KAAU,CAAC,IAAI,EAAE;AAAA,MACjB,QAAU,CAAC,IAAI,MAAM,EAAE;AAAA,MACvB,QAAU,CAAC,IAAI,EAAE;AAAA,MACjB,OAAU,CAAC,IAAI,EAAE;AAAA,IACnB;AACF,WAAO,KAAK,WAAW;AAAA,MACrB,OAAW,QAAQ,SAAY;AAAA,MAC/B,UAAW,QAAQ,YAAY,SAAS;AAAA,MACxC,OAAW,QAAQ,SAAY,SAAS;AAAA,MACxC,KAAW,QAAQ,OAAY,SAAS;AAAA,MACxC,QAAW,QAAQ,UAAY,SAAS;AAAA,MACxC,QAAW,QAAQ,UAAY,SAAS;AAAA,MACxC,OAAW,QAAQ,SAAY,SAAS;AAAA,MACxC,WAAW,QAAQ;AAAA;AAAA,MACnB,MAAW,QAAQ,QAAY;AAAA,IACjC,GAAG,CAAC;AAAA,EACN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiCA,KAAM,SAAiB,IAAY;AACjC,WAAO,SAAS,KAAK,YAAY,OAAO,OAAO;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,SAA2B;AACzB,WAAO,KAAK,OAAO;AAAA,EACrB;AACF;AAOO,IAAM,MAAN,MAAM,aAAY,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAW5B,YAAa,KAAU,KAAU;AAC/B,UAAM;AAEN,SAAK,MAAM;AACX,SAAK,MAAM;AACX,SAAK,QAAQ,IAAI,QAAQ,MAAM,IAAI,QAAQ;AAAA,EAC7C;AAAA,EAEA,kBAAmB,SAA0B,QAA+C;AAC1F,UAAM,CAAC,KAAK,OAAO,IAAI,OAAO,KAAK,IAAI,eAAe,SAAS,MAAM,CAAC;AACtE,QAAI,YAAY,QAAQ;AACtB,aAAO,QAAQ,KAAK,MAAM,IAAI,MAAM,KAAK,GAAG,IAAI,IAAI;AAEtD,UAAM,CAAC,KAAK,OAAO,IAAI,OAAO,KAAK,IAAI,eAAe,SAAS,MAAM,CAAC;AAEtE,UAAM,QAAmB,OAAO,OAAQ,OAAO,KAAK,KAAK,MAAM,OAAO,KAAK,GAAG,IAAI;AAClF,QAAI,YAAY,QAAQ;AACtB,aAAO,QAAQ,KAAK,KAAK;AAC3B,WAAO;AAAA,EACT;AAAA,EAEA,IAAK,WAA0C;AAC7C,WAAO,UAAU,IAAI,KAAK,KAAK,IAAI,IAAI,SAAS,KAAK,KAAK,IAAI,IAAI,SAAS;AAAA,EAC7E;AAAA,EAEA,MAAU,SAAW,SAAqE;AACxF,UAAM,CAAC,QAAQ,SAAS,SAAS,SAAS,IAAI,OAAO,QAAQ,SAAS,IAAI,CAAC;AAC3E,QAAI,WAAW,QAAQ;AACrB,aAAO;AACT,QAAI,WAAW,QAAQ;AACrB,aAAO,QAAQ,KAAK,KAAK;AAC3B,UAAM,CAAC,SAAS,OAAO,UAAU,SAAS,IAAI,OAAO,KAAK,IAAI,MAAM,OAAO,OAAO,CAAC;AACnF,QAAI,YAAY,QAAQ;AACtB,aAAO,QAAQ,KAAK,MAAM;AAC5B,UAAM,CAAC,SAAS,QAAQ,UAAU,SAAS,IAAI,OAAO,KAAK,IAAI,MAAM,QAAQ,OAAO,CAAC;AACrF,QAAI,YAAY,QAAQ;AACtB,aAAO,QAAQ,KAAK,MAAM;AAC5B,WAAO;AAAA,EACT;AAAA,EAEA,MAAOA,SAAc,SAA2B;AAC9C,UAAM,MAAM,KAAK,IAAI,MAAMA,SAAQ,OAAO;AAC1C,UAAM,MAAM,KAAK,IAAI,MAAMA,SAAQ,OAAO;AAE1C,WAAQ,OAAO,OAAQ,OAAO,KAAK,KAAK,MAAM,OAAO,KAAK,GAAG,IAAI;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA,EAMA,OAAc;AAEZ,QAAI,CAAC,KAAK,OAAO;AAEf,YAAM,UAAU,KAAK,IAAI,OAAO,KAAK,GAAG;AACxC,UAAI,mBAAmB;AACrB,eAAO,EAAE,MAAM,SAAS,OAAO,GAAG,SAAS,KAAK;AAAA,eACzC,OAAO,YAAY;AAC1B,aAAK,SAAS;AAGhB,YAAM,MAAM,KAAK,IAAI,KAAK;AAC1B,UAAI,IAAI;AACN,eAAO,EAAE,MAAM,IAAI,KAAK,MAAM,KAAK,GAAG,GAAG,OAAO,IAAI,OAAO,SAAS,KAAK;AAG3E,YAAM,MAAM,KAAK,IAAI,KAAK;AAC1B,UAAI,IAAI;AACN,eAAO,EAAE,MAAM,KAAK,IAAI,MAAM,IAAI,IAAI,GAAG,OAAO,IAAI,OAAO,SAAS,KAAK;AAG3E,WAAK,QAAQ;AAAA,IACf;AAEA,WAAO,EAAE,MAAM,MAAM,OAAO,GAAG,SAAS,MAAM;AAAA,EAChD;AAAA,EAEA,OAAQ,KAA6B;AAGnC,UAAM,UAAU,KAAK,IAAI,OAAO,KAAK,GAAG;AACxC,QAAI,mBAAmB;AACrB,aAAO,QAAQ,MAAM,GAAG;AAAA,aACjB,OAAO,YAAY,YAAY;AACtC,WAAK,SAAS;AACd,aAAO,QAAQ,GAAG;AAAA,IACpB,OAAO;AAEL,WAAK,SAAS,CAACC,SAAc;AAC7B,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,SAAkB;AAChB,WAAO,CAAC,GAAG,KAAK,IAAI,OAAO,GAAG,KAAK,GAAG;AAAA,EACxC;AAAA,EAEA,KAAM,OAAa,OAAO,OAAO;AAC/B,QAAI,EAAE,iBAAiB;AACrB,aAAO,MAAM,KAAK,OAAO,IAAI;AAE/B,UAAM,MAAM,KAAK,IAAI,KAAK,MAAM,KAAK,IAAI;AACzC,QAAI;AACF,aAAO,MAAM;AACf,UAAM,MAAM,KAAK,IAAI,KAAK,MAAM,KAAK,IAAI;AACzC,QAAI;AACF,aAAO,KAAK,MAAM,MAAM,MAAM;AAChC,WAAO;AAAA,EACT;AAAA,EAEA,QAAS,SAA4B;AACnC,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,WAAY,SAA8B,OAAuB;AAC/D,UAAM,MAAM,KAAK,IAAI,WAAW,SAAS,QAAQ,CAAC;AAClD,UAAM,MAAM,KAAK,IAAI,WAAW,SAAS,CAAC;AAC1C,UAAM,OAAO,QAAQ,CAAC,IAAI,EAAE,IAAI,QAAQ;AAExC,QAAI,QAAQ,SAAS,CAAC,KAAK,IAAI,QAAQ,KAAK;AAC1C,aAAO,KAAK,CAAC,IAAI,OAAO,KAAK,IAAI,UAAU,KAAK,GAAG,IAAI,KAAK,QAAQ,SAAS,MAAM,KAAK,CAAC;AAAA;AAEzF,aAAO,KAAK,CAAC,IAAI,MAAM,QAAQ,SAAU,CAAC,IAAI,MAAM,QAAQ,SAAU,CAAC,IAAI,KAAK,CAAC;AAAA,EACrF;AAAA,EAEA,KAAM,SAAiB,IAAY;AACjC,WAAO,SAAS,WAAW,KAAK,OAAO,EAAE,IAAI,OAAK,EAAE,KAAK,SAAS,IAAI,CAAC,EAAE,KAAK,IAAI;AAAA,EACpF;AAAA,EAEA,UAAW,KAAoB;AAC7B,WAAO,KAAK,IAAI,QAAQ,KAAK,IAAI,OAAO,KAAK,IAAI,UAAU,GAAG;AAAA,EAChE;AACF;AAOO,IAAM,QAAN,MAAM,eAAc,KAAK;AAAA,EAI9B,YAAa,MAAc;AACzB,UAAM;AACN,QAAI,OAAO,SAAS,YAAY,KAAK,WAAW;AAC9C,YAAM,IAAI,MAAM,mDAAmD;AACrE,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,UAAW,KAAoB;AAC7B,WAAO,CAAC,EACL,eAAe,WACb,KAAK,KAAK,MAAM,UAAU,KAAK,IAAI,KAAK,MAAM,UAAU,KACnD,KAAK,KAAK,MAAM,UAAU,KAAK,IAAI,KAAK,MAAM,UAAU;AAAA,EAGpE;AAAA,EAEA,WAAY,SAA+B,OAAuB;AAEhE,UAAM,OAAO,QAAQ,OAAO,KAAK,aAAa,KAAK,OAAO,KAAK;AAC/D,WAAO,KAAK,UAAU,UAAa,KAAK,QAAQ,KAAK,KAAK,SAAS,QAC/D,QAAQ,MAAO,CAAC,IAAI,OAAO,QAAQ,MAAO,CAAC,IAC3C;AAAA,EACN;AACF;AAGA,IAAI,SAAS;AAaN,IAAM,UAAN,MAAM,iBAAgB,MAAM;AAAA,EAOjC,YAAa,MAAa,OAAiB;AACzC,UAAM,IAAI;AACV,SAAK,KAAK,EAAE;AAEZ,SAAK,QAAQ,UAAU,SAAY,OAAO;AAAA,EAC5C;AAAA,EAEA,KAAM,OAAY,OAAO,OAAsB;AAC7C,QAAI,EAAE,iBAAiB;AACrB,aAAO,MAAM,KAAK,OAAO,IAAI;AAC/B,QAAI,KAAK,SAAS,MAAM,QAAQ,KAAK,UAAU,MAAM;AACnD,aAAO;AACT,UAAM,MAAM,KAAK,OAAO,MAAM,KAAK,KAAK;AACxC,UAAM,MAAM,MAAM,OAAO,MAAM,MAAM,KAAK;AAC1C,WAAO,OACH,MAAM,MAAM,SAAS,MAAM,MAC3B,MAAM,MAAM,SAAS,MAAM;AAAA,EACjC;AAAA,EAEA,MAAOD,SAAc,SAA4B;AAC/C,QAAIA,mBAAkB,YAAWA,QAAO,SAAS,KAAK,QAAQA,QAAO,UAAU,KAAK;AAClF,aAAO;AACT,WAAO;AAAA,EACT;AAAA,EAEA,WAAY,SAA+B,OAAuB;AAChE,UAAM,OAAO,QAAQ,OAAO,KAAK,aAAa,KAAK,OAAO,KAAK;AAC/D,WAAO,QAAQ,IAAK,CAAC,IAAI,OAAO,QAAQ,IAAK,CAAC;AAAA,EAChD;AAAA,EAEA,KAAM,SAAiB,IAAY;AAEjC,WAAO,GAAG,MAAM,YAAY,KAAK,IAAI,IAAI,KAAK,EAAE;AAAA,EAClD;AAAA,EAEA;AAAA,SAAO,SAAS,CAAC,QAAQ;AAAA;AAC3B;AAcO,IAAM,SAAN,cAAqB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMhC,YAAa,MAAc,MACzB,MAA4D,CAAC,GAAG;AAChE,UAAM,IAAI;AAEV,SAAK,SAAU;AAEf,SAAK,OAAO,EAAE,UAAU,MAAM,GAAG,IAAI,CAAC;AAAA,EACxC;AACF;AAYO,IAAM,SAAN,MAAM,gBAAe,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAO/B,YAAa,KAAc,MAAY;AACrC,UAAM;AAEN,QAAI,EAAE,eAAe;AACnB,YAAM,IAAI,MAAM,mCAAmC;AAGrD,UAAM,QAAQ,IAAI,QAAQ,IAAI,MAAM,IAAI;AACxC,SAAK,MAAM;AACX,SAAK,OAAO,KAAK,MAAM,KAAK,KAAK,KAAK;AACtC,SAAK,QAAQ;AACb,SAAK,QAAQ,KAAK,QAAQ,KAAK;AAAA,EACjC;AAAA,EAEA,OAAQ,KAAiB;AACvB,WAAO,KAAK,KAAK,MAAM,KAAK,KAAK,GAAG,KAAK,KAAK;AAAA,EAChD;AAAA,EAEA,kBAAmB,SAA0B,QAA+C;AAE1F,UAAM,CAAC,MAAM,OAAO,IAAI,OAAO,KAAK,KAAK,eAAe,SAAS,MAAM,CAAC;AAExE,UAAM,QAAQ,OAAO,IAAI,QAAO,KAAK,KAAK,IAAI,IAAI;AAElD,WAAO,YAAY,QAAQ,OAAO,QAAQ,KAAK,KAAK,IAAI;AAAA,EAC1D;AAAA,EAEA,IAAK,WAA0C;AAC7C,WAAO,UAAU,IAAI,KAAK,KAAK,KAAK,IAAI,SAAS;AAAA,EACnD;AAAA,EAEA,MAAU,SAAW,SAAqE;AACxF,UAAM,CAAC,QAAQ,SAAS,SAAS,SAAS,IAAI,OAAO,QAAQ,SAAS,IAAI,CAAC;AAC3E,QAAI,WAAW,QAAQ;AACrB,aAAO;AACT,QAAI,WAAW,QAAQ;AACrB,aAAO,QAAQ,KAAK,KAAK;AAC3B,UAAM,CAAC,QAAQ,OAAO,IAAI,OAAO,KAAK,KAAK,MAAM,OAAO,OAAO,CAAC;AAChE,QAAI,YAAY,QAAQ;AACtB,aAAO,QAAQ,KAAK,MAAM;AAC5B,WAAO,UAAU;AAAA,EACnB;AAAA,EAEA,MAAOA,SAAc,SAA2B;AAC9C,QAAIA,YAAW,KAAK;AAClB,aAAO;AACT,UAAM,SAAS,KAAK,KAAK,MAAMA,SAAQ,OAAO;AAC9C,WAAO,SAAS,IAAI,QAAO,KAAK,KAAK,MAAM,IAAI;AAAA,EACjD;AAAA,EAEA,KAAM,OAAa,OAAO,OAAsB;AAC9C,QAAI,EAAE,iBAAiB;AACrB,aAAO,MAAM,KAAK,OAAO,IAAI;AAE/B,UAAM,IAAI,IAAI,QAAQ,GAAG;AAEzB,UAAM,OAAO,KAAK,OAAO,CAAC,EAAE,KAAK,MAAM,OAAO,CAAC,GAAG,IAAI;AACtD,QAAI;AACF,aAAO,SAAS,OAAO;AACzB,WAAO;AAAA,EACT;AAAA,EAEA,WAAY,SAA+B,OAAuB;AAChE,YAAQ,QAAQ,IAAI,QAAQ,SAAU,CAAC,IAAI,MACvC,QAAQ,OAAQ,CAAC,IACjB,KAAK,IAAI,WAAW,SAAS,CAAC,IAC9B,QAAQ,OAAQ,CAAC,IACjB,KAAK,KAAK,WAAW,SAAS,CAAC,IAAI,QAAQ,OAAQ,CAAC,KACnD,QAAQ,IAAI,QAAQ,SAAU,CAAC,IAAI;AAAA,EAC1C;AAAA,EAEA,KAAM,SAAiB,IAAY;AACjC,WAAO,GAAG,MAAM,WAAW,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE;AAAA,IACnD,KAAK,KAAK,KAAK,SAAS,IAAI;AAAA,EAClC;AAAA,EAEA,QAAS,SAA2B;AAClC,WAAO;AAAA,EACT;AACF;AAMO,IAAM,SAAN,MAAM,gBAAe,KAAK;AAAA;AAAA;AAAA;AAAA,EAK/B,YAAa,GAAW;AACtB,QAAI,OAAO,SAAS,OAAO,CAAC,CAAC;AAC7B,QAAI,EAAE,KAAK;AACT,YAAM,IAAI,MAAM,8CAA8C;AAChE,UAAM;AACN,SAAK,SAAS,OAAK,OAAK;AACtB,UAAI,OAAO;AACX,eAAS,IAAI,GAAG,MAAM;AACpB,eAAO,EAAE,MAAM,IAAI;AACrB,aAAO;AAAA,IACT;AAGA,SAAK,IAAI;AACT,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,KAAM,OAAY,OAAO,OAAsB;AAC7C,QAAI,EAAE,iBAAiB;AACrB,aAAO,MAAM,KAAK,OAAO,IAAI;AAC/B,QAAI,KAAK,MAAM,MAAM;AACnB,aAAO;AACT,WAAO,OACH,MAAM,MAAM,IAAI,SAAS,KAAK,IAAI,MAClC,MAAM,KAAK,IAAI,SAAS,MAAM,IAAI;AAAA,EACxC;AAAA,EAEA,UAAW,KAAoB;AAC7B,WAAO;AAAA,EACT;AAAA,EAEA,WAAY,SAA+B,OAAuB;AAChE,WAAO,SAAS,IACZ,QAAQ,MAAO,CAAC,IAAI,KAAK,IAAI,QAAQ,MAAO,CAAC,IAC7C,KAAK,IAAI;AAAA,EACf;AACF;AAEA,SAAS,MAAO,GAAoD;AAClE,SAAO,KAAK,IACR,CAAC,MAAY,CAAC,QAAc,EAAE,MAAM,GAAG,IACvC,CAAC,MAAY,CAAC,QAAc,MAAM,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC;AAC3D;AAoBO,IAAM,QAAN,cAAoB,MAAM;AAAA,EAS/B,YACE,MACA,MACA,UAAkH,CAAC,GACnH;AACA,UAAM,IAAI;AACV,QAAI,EAAE,gBAAgB;AACpB,YAAM,IAAI,MAAM,sDAAsD,IAAI;AAC5E,SAAK,OAAO;AAEZ,SAAK,OAAO,OAAO;AACnB,SAAK,SAAS,MAAM,QAAQ,SAAS,IAAI,KAAK,SAAS,CAAC,EAAE,IAAI;AAC9D,SAAK,OAAO,KAAK;AACjB,QAAI,QAAQ;AACV,WAAK,SAAS;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,aAAoB;AAClB,SAAK,SAAS,MAAM,CAAC,EAAE,KAAK,IAAI;AAChC,SAAK,SAAS;AACd,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,kBAAmB,SAA0B,QAA+C;AAC1F,WAAO,KAAK,KAAK,eAAe,SAAS,MAAM;AAAA,EACjD;AAAA,EAEA,IAAK,WAA0C;AAC7C,WAAO,UAAU,IAAI,KAAK,KAAK,KAAK,IAAI,SAAS;AAAA,EACnD;AAAA,EAEA,MAAU,SAAW,SAAqE;AACxF,UAAM,CAAC,QAAQ,SAAS,MAAM,IAAI,OAAO,QAAQ,SAAS,IAAI,CAAC;AAC/D,QAAI,WAAW,QAAQ;AACrB,aAAO;AACT,QAAI,WAAW,QAAQ;AACrB,aAAO,QAAQ,KAAK,KAAK;AAC3B,UAAM,CAAC,QAAQ,OAAO,IAAI,OAAO,KAAK,KAAK,MAAM,OAAO,OAAO,CAAC;AAChE,QAAI,YAAY,QAAQ;AACtB,aAAO,QAAQ,KAAK,MAAM;AAC5B,WAAO,UAAU;AAAA,EACnB;AAAA,EAEA,MAAOA,SAAc,SAA4B;AAC/C,QAAI,SAASA;AACX,aAAO;AACT,WAAO,KAAK,KAAK,MAAMA,SAAQ,OAAO;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAc;AAEZ,SAAK,KAAK,SAAS,KAAK;AACtB,aAAO,EAAE,MAAM,MAAM,OAAO,GAAG,SAAS,MAAM;AAEhD,WAAO,EAAE,MAAM,KAAK,MAAM,OAAO,GAAG,SAAS,KAAK;AAAA,EACpD;AAAA,EAEA,KAAM,OAAa,OAAO,OAAsB;AAC9C,QAAI,SAAS;AACX,aAAO;AACT,WAAO,MAAM,KAAK,KAAK,MAAM,CAAC,IAAI;AAAA,EACpC;AAAA,EAEA,QAAS,SAA2B;AAClC,WAAO,KAAK,SAAS,KAAK,KAAK,QAAQ,OAAO,IAAI;AAAA,EACpD;AAAA,EAEA,WAAY,SAA+B,OAAuB;AAChE,UAAM,SAAS,QAAQ,YACnB,QAAQ,UAAU,KAAK,IAAI,MAAM,OACjC,KAAK;AACT,WAAO,SAAS,KAAK,KAAK,WAAW,SAAS,KAAK,IAAI,MAAM,WAAW,SAAS,KAAK;AAAA,EACxF;AAAA,EAEA,KAAM,SAAiB,IAAY;AAEjC,WAAO,GAAG,MAAM,UAAU,KAAK,IAAI;AAAA,IAAY,KAAK,KAAK,KAAK,MAAM;AAAA,EACtE;AACF;AAQA,SAAS,UAAW,MAAc,MAAiC,MAAwB,CAAC,GAAS;AACnG,SAAO,IAAI,IAAI,IAAI,OAAO,MAAM,MAAM,GAAG;AAC3C;AACA,UAAU,KAAK,OAAK,CAAC;AACrB,UAAU,KAAK,OAAK,QAAM,CAAC;AAC3B,UAAU,KAAK,OAAK,OAAK,OAAK,EAAE,MAAM,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;AACpD,UAAU,KAAK,OAAK,OAAK,OAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AACjD,UAAU,KAAK,OAAK,OAAK,OAAK,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;AACjD,UAAU,KAAK,OAAK,OAAK,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;AAE5C;AAAA,EACE;AAAA,EACA,OAAK,aAAa,SACd,IAAI,OAAO,EAAE,IAAI,CAAC,IAClB,OAAK,OAAK,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,EACnC;AAAA,IACE,MAAM;AAAA,EACR;AACF;AAIA,SAAS,SAAU,MAAY;AAE7B,SAAO,gBAAgB;AACrB,WAAO,KAAK;AACd,SAAO,gBAAgB;AACzB;AAeA,SAAS,YAAa,MAAiB,MAAY,MAA0E;AAC3H,QAAM,QAAQ,IAAI,MAAM,KAAK,MAAM,EAAE,KAAK,CAAC;AAC3C,MAAI,SAAS;AACb,OAAK,SAAS,OAAK;AACjB,QAAI,aAAa,SAAS;AACxB,YAAM,QAAQ,KAAK,UAAU,OAAK,EAAE,SAAS,EAAE,IAAI;AACnD,UAAI,SAAS,GAAG;AACd,cAAM,KAAK;AACX;AAAA,MACF;AAAA,IACF;AACA,QAAI,EAAE,aAAa;AACjB,eAAS;AAAA,EACb,CAAC;AAED,QAAM,OAAqB,oBAAI,IAAI;AACnC,QAAM,MAAoB,oBAAI,IAAI;AAClC,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,MAAM,CAAC,MAAM;AACf,WAAK,IAAI,CAAC;AAAA,aACH,MAAM,CAAC,IAAI;AAClB,UAAI,IAAI,CAAC;AAAA,EACb;AAEA,WAAS,IAAI,KAAK,QAAQ,MAAM;AAC9B,WAAO,IAAI,OAAO,KAAK,CAAC,GAAG,IAAI;AAEjC,SAAO;AAAA,IACL,QAAW;AAAA,IACX,OAAW,KAAK;AAAA,IAChB;AAAA,IACA,OAAW,KAAK;AAAA,IAChB,GAAI,KAAK,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,IAC5B,GAAI,IAAI,OAAO,EAAE,IAAI,IAAI,CAAC;AAAA,IAC1B,WAAW,CAAC,CAAC,IAAI,QAAS,KAAK,aAAa;AAAA,IAC5C,SAAW,CAAC,CAAC,KAAK,QAAQ,KAAK,WAAa;AAAA,IAC5C;AAAA,EACF;AACF;AAEA,SAAS,OAAQ,GAAoB;AACnC,SAAO,IAAI,QAAQ,WAAW,CAAC,KAAK,MAAM,CAAC;AAC7C;AAEO,IAAM,UAAU,EAAE,MAAM,KAAK,OAAO,SAAS,QAAQ,QAAQ,QAAQ,MAAM;;;ACp+C3E,SAAS,SAAU,MAA4B,KAAyD;AAC7G,MAAI,gBAAgB;AAClB,WAAO,CAAC,IAAI;AACd,MAAI,KAAK;AAEP,QAAI,CAAC;AACH,aAAO,OAAO,KAAK,GAAG,EAAE,KAAK,EAAE,IAAI,OAAK,IAAK,CAAC,CAAC;AAAA,EACnD,OAAO;AACL,QAAI,CAAC;AACH,aAAO,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,EAAE;AAC7B,UAAM,CAAC;AACP,eAAW,QAAQ,MAAM;AACvB,UAAI,EAAE,gBAAgB;AACpB;AACF,UAAI,IAAI,KAAK,IAAI;AACf,cAAM,IAAI,MAAM,oBAAoB,IAAI;AAC1C,UAAI,KAAK,IAAI,IAAI;AAAA,IACnB;AAAA,EACF;AAEA,QAAM,MAAc,CAAC;AACrB,QAAM,OAAO,oBAAI,IAAI;AACrB,QAAM,MAAM,CAAC,SAAe;AAC1B,QAAI,KAAK,IAAI,IAAI;AACf;AACF,SAAK,KAAK,OAAO,CAAC,KAAa,MAAkC;AAC/D,UAAI,MAAM,QAAQ,aAAa,SAAS,IAAK,EAAE,IAAI,MAAM,GAAG;AAC1D,YAAI,CAAC;AACL,eAAO,QAAQ,MAAM,KAAK;AAAA,MAC5B;AAAA,IACF,CAAC;AACD,QAAI,KAAK,IAAI;AACb,SAAK,IAAI,IAAI;AAAA,EACf;AAEA,aAAW,QAAQ;AACjB,QAAI,IAAI;AAEV,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,EACF;AACF;;;ACxDA,IAAM,QAAN,cAAoB,KAAK;AAAA,EACvB,SAAU,MAAmB;AAC3B,WAAO,KAAK,SAAS,IAAI,KAAK,MAAM,EAAG,MAAM,GAAG,IAAI,IAAI;AAAA,EAC1D;AAAA,EAEA,YAAmB;AACjB,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAAA,EAEA,WAAY,SAA+B,OAAuB;AAChE,WAAO;AAAA,EACT;AACF;AAEA,IAAM,gBAAN,MAAM,uBAAsB,MAAM;AAAA;AAAA,EAIhC,YAAa,MAAY,SAAS,CAAC,GAAG;AACpC,UAAM;AACN,SAAK,OAAO,IAAI,MAAM;AACtB,QAAI,gBAAgB;AAClB,WAAK,QAAQ,CAAC,IAAI;AAAA,aACX,gBAAgB,gBAAe;AACtC,UAAI,EAAE,KAAK,gBAAgB;AACzB,cAAM,IAAI,MAAM,sCAAsC;AACxD,WAAK,QAAQ,CAAC,GAAG,KAAK,OAAO,KAAK,IAAI;AAAA,IACxC;AACE,YAAM,IAAI,MAAM,mCAAmC;AAAA,EACvD;AAAA,EAEA,MAAO,SAAe,MAAa;AACjC,QAAI,SAAS,QAAQ,KAAK,WAAW;AACnC,YAAM,IAAI,MAAM,mCAAmC;AACrD,SAAK,OAAO,KAAK,KAAK,MAAM,IAAI;AAChC,WAAO;AAAA,EACT;AAAA,EAEA,YAAmB;AACjB,QAAI,OAAO,KAAK;AAChB,aAAS,IAAI,KAAK,MAAM,QAAQ,MAAM;AACpC,aAAO,IAAI,OAAO,KAAK,MAAM,CAAC,GAAG,IAAI;AACvC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAMF;AAEA,SAAS,UAAW,MAAkB;AACpC,SAAQ,KAAe,YAAa,KAAe,UAAU,IAAI;AACnE;AAEA,IAAM,YAAY,IAAI;AAAA,EACpB;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAoB;AAAA,EAAgB;AAAA,EAAM;AAC7D;AA0BO,IAAM,SAAN,MAAa;AAAA,EAoBlB,YAAa,UAAyB,CAAC,GAAG;AACxC,SAAK,WAAW,CAAC,CAAC,QAAQ;AAC1B,SAAK,aAAa,CAAC,CAAC,QAAQ;AAC5B,SAAK,QAAQ,EAAE,GAAG,OAAO;AACzB,SAAK,aAAa;AAClB,SAAK,aAAa;AAElB,SAAK,QAAQ,IAAI,IAAI,OAAO,KAAK,KAAK,KAAK,CAAC;AAG5C,QAAI,MAAM,QAAQ,QAAQ,KAAK;AAC7B,WAAK,QAAQ,QAAQ,KAAK;AAAA,aACnB,QAAQ,OAAO;AACtB,iBAAW,QAAQ,QAAQ,OAAO;AAEhC,YAAI,OAAO,QAAQ,MAAM,IAAI,MAAM,YAAY,CAAC,QAAQ,MAAM,IAAI,EAAE,MAAM,UAAU;AAClF,eAAK,IAAI,MAAM,QAAQ,MAAM,IAAI,CAAC;AAAA,MACtC;AAAA,IACF;AAIA,SAAK,aAAa,QAAQ,WAAW;AACrC,SAAK,aAAa,QAAQ,WAAW;AACrC,QAAI,QAAQ;AACV,WAAK,SAAS,QAAQ,KAAK;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyBA,IAAK,MAAsB,MAAoD,SAAqC;AAClH,UAAM,QAAQ,KAAK,OAAO,MAAM,IAAI;AAGpC,UAAM,OAAmB,OAAO,YAAY,WAAW,EAAE,MAAM,SAAS,UAAU,MAAM,IAAK,WAAW,CAAC;AACzG,UAAM,OAAO,EAAE,UAAU,KAAK,UAAU,GAAG,KAAK,CAAC;AAEjD,UAAM,MAAM,KAAK,MAAM,MAAM,IAAI;AACjC,QAAI,eAAe;AACjB,UAAI,WAAW;AAEjB,SAAK,MAAM,MAAM,IAAI,IAAI;AACzB,SAAK,MAAM,IAAI,MAAM,IAAI;AAEzB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAQ,MAAsB,MAAoE;AAChG,QAAI,gBAAgB;AAClB,aAAO,WAAW,KAAK,MAAM,IAAI;AACnC,QAAI,OAAO,SAAS;AAClB,YAAM,IAAI,MAAM,0CAA0C;AAC5D,QAAI,SAAS;AACX,YAAM,IAAI,MAAM,oDAAoD;AACtE,QAAI,OAAO,SAAS;AAClB,aAAO,WAAW,MAAM,KAAK,MAAM,IAAI,CAAC;AAC1C,QAAI,gBAAgB;AAClB,aAAO,WAAW,MAAM,IAAI;AAC9B,QAAI,OAAO,SAAS;AAClB,aAAO,IAAI,OAAO,MAAM,IAAI;AAE9B,UAAM,IAAI,MAAM,2FAA2F;AAAA,EAC7G;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,SAAU,MAAc,MAAyD;AAC/E,QAAI,KAAK,MAAM,IAAI;AACjB,WAAK,MAAM,IAAI,IAAI;AAAA;AAEnB,WAAK,IAAI,MAAM,IAAI;AACrB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,QAAS,MAAsB;AAC7B,eAAW,QAAQ,MAAM;AACvB,YAAM,IAAI,KAAK,MAAM,uCAAuC;AAE5D,UAAI,CAAC;AACH,cAAM,IAAI,MAAM,mCAAmC,IAAI;AACzD,UAAI,EAAE,CAAC,MAAM;AACX,aAAK,OAAO,EAAE,CAAC,CAAC;AAAA;AAEhB,aAAK,IAAI,EAAE,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC;AAAA,IACnC;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,SAAU,MAAoB;AAC5B,SAAK,QAAQ,SAAS,KAAK,OAAO,IAAI;AACtC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAc,OAAO,KAAK;AACxB,UAAM,MAAM,CAAC;AACb,QAAI,YAAqB;AACzB,eAAW,QAAQ,CAAC,GAAG,SAAS,KAAK,OAAO,IAAI,CAAC,EAAE,KAAK,GAAG;AACzD,YAAM,YAAY,CAAC,CAAC,KAAK,MAAM,SAAS;AACxC,UAAI,IAAI,UAAU,EAAE,aAAa;AAC/B,YAAI,KAAK,GAAG;AACd,UAAI,KAAK,IAAI;AACb,kBAAY;AAAA,IACd;AACA,WAAO,IAAI,KAAK,EAAE;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAQ,MAAoB;AAC1B,UAAM,MAAM,KAAK,MAAM,IAAI;AAC3B,QAAI,eAAe;AACjB,UAAI,WAAW;AACjB,WAAO,KAAK,MAAM,IAAI;AACtB,SAAK,MAAM,OAAO,IAAI;AACtB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAqC;AACnC,UAAM,MAA+B,CAAC;AACtC,eAAW,QAAQ,OAAO,KAAK,KAAK,KAAK,GAAG;AAC1C,UAAI,KAAK,MAAM,IAAI,IAAI;AACrB,YAAI,IAAI,IAAI,KAAK,MAAM,IAAI;AAAA,IAC/B;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAqB;AAEnB,UAAM,MAAgC,CAAC;AACvC,eAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,KAAK,SAAS,CAAC,GAAG;AAC1D,UAAI,gBAAgB;AAClB,YAAI,IAAI,IAAI;AAAA,IAChB;AAMA,UAAM,aAAuC,CAAC;AAC9C,QAAI,IAAI;AACR,eAAW,QAAQ,QAAQ;AACzB,UAAI,EAAE,IAAI,IAAI,aAAa;AACzB;AACF,aAAO,QAAQ,KAAK;AAClB;AACF,YAAM,OAAO,IAAI,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC;AAC3C,iBAAW,KAAK,IAAI,IAAI,IAAI,IAAI;AAChC,UAAI,KAAK,IAAI,IAAI;AACjB,aAAO,IAAI,IAAI;AAAA,IACjB;AAIA,UAAM,OAAO,SAAS,QAAW,GAAG,EAAE;AAEtC,UAAM,SAAS,oBAAI,IAAkB;AACrC,QAAI,OAAO,KAAK,UAAU,EAAE,QAAQ;AAIlC,YAAM,SAAS,CAAC,SAAqB;AACnC,eAAO,KAAK,SAAS,CAAC,MAAY;AAChC,cAAI,EAAE,aAAa;AACjB,mBAAO;AACT,gBAAM,WAAW,OAAO,IAAI,CAAC;AAC7B,cAAI;AACF,mBAAO;AACT,iBAAO,IAAI,MAAM,EAAE,MAAM,OAAO,EAAE,IAAI,CAAC;AAAA,QACzC,CAAC,KAAK;AAAA,MACR;AAEA,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAEpC,aAAK,CAAC,IAAI,OAAO,KAAK,CAAC,CAAC;AACxB,eAAO,IAAI,WAAY,KAAK,CAAC,EAAY,IAAI,GAAG,KAAK,CAAC,CAAU;AAChE,YAAK,KAAK,CAAC,EAAY,IAAI,IAAI,KAAK,CAAC;AAAA,MAEvC;AAAA,IAEF;AAGA,UAAM,MAAM,KAAK;AAAA,MAAI,OAAK,WAAY,EAAY,IAAI,IACjD,EAAY,OAAO,MAAM,WAAY,EAAY,IAAI,EAAE,OAAO,MAAO,EAAY,KAAK,OAAO,EAAE,WAAW,IAAI,CAAC,IAC/G,EAAY,OAAO,MAAO,EAAY,KAAK,OAAO,EAAE,WAAW,IAAI,CAAC;AAAA,IACzE;AAEA,eAAW,CAAC,MAAM,IAAI,KAAK;AACzB,UAAI,KAAM,KAAe,OAAO,MAAM,MAAM,OAAO,GAAG;AAExD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAO,QAAgB,UAAwB,CAAC,GAAS;AACvD,QAAI,OAAO,WAAW;AACpB,YAAM,IAAI,MAAM,yCAAyC,OAAO,MAAM;AAExE,UAAM,QAAQ,OAAO,QAAQ,iBAAiB,GAAG,EAC9C,QAAQ,iBAAiB,GAAG,EAC5B,KAAK,EACL,MAAM,YAAY,EAAE,OAAQ,OAAK,EAAE,MAAM,IAAI,CAAC;AAEjD,UAAM,MAAM,EAAE,GAAG,QAAQ,IAAI;AAE7B,QAAI,OAAa,IAAI,MAAM;AAC3B,eAAW,QAAQ,OAAO;AACxB,UAAI,gBAAgB;AAClB,aAAK,WAAW;AAElB,YAAM,MAAM,KAAK,MAAM,oCAAoC;AAC3D,UAAI,OAAO,IAAI,CAAC,MAAM;AACpB,eAAO,IAAI,QAAQ,IAAI,CAAC,GAAG,QAAQ,SAAS,QAAQ,MAAM;AAAA;AAE1D,eAAO,KAAK,UAAU,MAAM,KAAK,OAAO;AAE1C,UAAI,KAAK;AACP,YAAI,IAAI,IAAI,CAAC,CAAC,MAAM;AAClB,gBAAM,IAAI,MAAM,uCAAuC,IAAI,CAAC,CAAC;AAC/D,YAAI,IAAI,CAAC,CAAC,IAAI;AAAA,MAChB;AAAA,IAGF;AAEA,QAAI,KAAK,YAAY;AAEnB,UAAI,gBAAgB;AAClB,eAAO,IAAI,MAAM,KAAK,MAAM,MAAM,EAAE,QAAQ,KAAK,CAAC;AACpD,WAAK,UAAU;AAAA,QACb,KAAQ,EAAE,GAAG,KAAK,SAAS,GAAG,GAAG,IAAI;AAAA;AAAA,QACrC,OAAQ,QAAQ;AAAA,QAChB,KAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,UAAW,QAAgB,MAA+B,CAAC,GAAG,UAAwB,CAAC,GAAS;AAC9F,UAAM,UAAU,OAAO,MAAM,0CAA0C;AACvE,QAAI;AACF,aAAO,IAAI,MAAM,QAAQ,CAAC,GAAG,KAAK,UAAU,QAAQ,CAAC,GAAG,KAAK,OAAO,CAAC;AAEvE,UAAM,MAAM;AAAA,MACV,SAAS,QAAQ,WAAW,KAAK;AAAA,MACjC,SAAS,QAAQ,WAAW,KAAK;AAAA,MACjC,OAAS,SAAS,KAAK,OAAO,QAAQ,KAAK;AAAA,IAC7C;AAEA,QAAI,IAAI,QAAS,KAAI,MAAM,IAAI,GAAG;AAAA,QAAQ,KAAI,MAAM,OAAO,GAAG;AAE9D,UAAM,SAAS,UAAU,MAAM,MAAM;AAErC,UAAM,QAAQ,IAAI,MAAM;AAExB,UAAM,QAAgB,CAAC,KAAK;AAC5B,UAAM,UAAU,QAAQ,SAAS,QAAQ;AAGzC,eAAW,KAAK,QAAQ;AAEtB,UAAI,MAAM;AACR,cAAM,KAAK,KAAK;AAAA,eACT,MAAM,KAAK;AAClB,YAAI,MAAM,SAAS;AACjB,gBAAM,IAAI,MAAM,gDAAgD,MAAM;AACxE,cAAM,IAAI,UAAU,MAAM,IAAI,CAAE;AAChC,cAAM,IAAI,MAAM,IAAI;AACpB,cAAM,KAAK,EAAE,MAAM,CAAC,CAAC;AAAA,MACvB,WAAW,MAAM,MAAM;AACrB,YAAI,CAAC,IAAI;AACP,gBAAM,IAAI,MAAM,8CAA8C;AAChE,cAAM,KAAK,IAAI,cAAc,MAAM,IAAI,CAAE,CAAC;AAAA,MAC5C,WAAW,EAAE,MAAM,UAAU,GAAG;AAC9B,YAAI,CAAC,IAAI;AACP,gBAAM,IAAI,MAAM,qDAAqD;AACvE,cAAM,IAAI,MAAM,IAAI;AACpB,cAAM,KAAK,EAAE,MAAM,IAAI,OAAO,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;AAAA,MACpD,OAAO;AACL,cAAM,IAAI,MAAM,IAAI;AACpB,YAAI,CAAC,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,IAAI,CAAC,GAAG;AACjD,gBAAM,IAAI,MAAM,WAAY,IAAI,oCAC5B,CAAC,GAAG,IAAI,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC;AAAA,QACrC;AAEA,cAAM,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,QAAQ,GAAG,OAAO;AACrE,cAAM,KAAK,EAAE,MAAM,CAAC,CAAC;AAAA,MACvB;AAAA,IACF;AAEA,QAAI,MAAM,WAAW,GAAG;AACtB,YAAM,IAAI,MAAM,gCACT,MAAM,SAAS,KAAK,0BAA0B,MAAM;AAAA,IAC7D;AAEA,WAAO,UAAU,MAAM,IAAI,CAAE;AAAA,EAC/B;AAAA,EAEA,SAAU;AACR,WAAO;AAAA,MACL,SAAU;AAAA;AAAA,MACV,OAAU,KAAK,aAAa,GAAG;AAAA,MAC/B,SAAU,KAAK;AAAA,MACf,SAAU,KAAK;AAAA,MACf,UAAU,KAAK;AAAA,MACf,OAAU,KAAK,QAAQ;AAAA,IACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAKF;AAEA,SAAS,WAAY,MAAc,MAAmB;AAEpD,SAAO,gBAAgB,SAAS,KAAK,SAAS;AAC5C,WAAO,KAAK;AACd,MAAI,gBAAgB,SAAS,KAAK,SAAS;AACzC,WAAO;AACT,SAAO,IAAI,MAAM,MAAM,MAAM,EAAE,UAAU,KAAK,CAAC;AACjD;;;AC5aO,IAAM,QAAN,MAAY;AAAA,EAgBjB,YAAa,SAAoB;AAC/B,UAAM,EAAE,OAAO,OAAO,OAAO,SAAS,SAAS,QAAQ,YAAY,GAAG,KAAK,IAAI;AAC/E,UAAM,MAAM,QAAQ,OAAO,CAAC;AAG5B,SAAK,aAAa,cAAc,IAAI,OAAO;AAC3C,SAAK,SAAS,UAAU,KAAK;AAC7B,SAAK,WAAW,EAAE,OAAO,SAAS,WAAW,OAAO,SAAS,WAAW,MAAM;AAC9E,SAAK,MAAM,CAAC;AAEZ,UAAM,MAAM,CAAC;AAKb,eAAW,QAAQ,OAAO,CAAC,GAAG;AAC5B,YAAM,OAAa,KAAK,WAAW,MAAM,MAAM,EAAE,KAAK,KAAK,OAAO,KAAK,CAAC;AACxE,UAAI,gBAAgB;AAClB,aAAK,IAAI,KAAK,IAAI,IAAI,IAAI,MAAM,KAAK,MAAM,KAAK,MAAM,EAAE,UAAU,MAAM,CAAC;AAAA,eAGlE,gBAAgB;AACvB,aAAK,IAAI,KAAK,IAAI,IAAI;AAAA;AAEtB,cAAM,IAAI,MAAM,sCAAsC,IAAI;AAAA,IAC9D;AAEA,SAAK,QAAQ,CAAC;AACd,eAAW,QAAQ,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AACtD,WAAK,SAAS,IAAI;AACpB,QAAI,CAAC,KAAK,MAAM;AACd,YAAM,IAAI,MAAM,4CAA4C;AAE9D,SAAK,UAAU,EAAE,GAAG,KAAK,KAAK,GAAG,IAAI;AACrC,eAAW,QAAQ,KAAK,OAAO;AAC7B,UAAI,KAAK,QAAQ,KAAK;AACpB,cAAM,IAAI,MAAM,+DAA+D,KAAK,IAAI;AAC1F,WAAK,QAAQ,KAAK,IAAI,IAAI,KAAK;AAAA,IACjC;AAIA,SAAK,QAAQ,CAAC;AACd,SAAK,OAAO,QAAQ;AACpB,SAAK,QAAQ,SAAS,QAAQ,KAAK;AACnC,SAAK,KAAK,QAAQ;AAClB,SAAK,OAAO;AAEZ,eAAW,KAAK,SAAS,CAAC;AACxB,MAAC,KAAK,IAAqC,GAAG,CAAC;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAW;AACT,UAAM,QAAQ,KAAK,SAAS,SAAS;AACrC,UAAM,MAAO,OAAO,KAAK,KAAK,GAAG,EAAE,KAAK;AAExC,WAAO,QACH,KAAK,OAAO,aAAa,QAAQ,MAAM,IAAI,KAAK,GAAG,CAAC,IACpD,IAAI,IAAK,OAAK,MAAM,CAAC,EAAE,KAAK,GAAG;AAAA,EACrC;AAAA,EAEA,SAAU,MAAgC;AACxC,QAAI,OAAO,SAAS;AAClB,aAAO,EAAE,MAAM,KAAK;AACtB,QAAI,OAAO,KAAK,SAAS;AACvB,YAAM,IAAI,MAAM,sEAAsE;AAExF,UAAM,OAAO;AACb,SAAK,cAAc,IAAI,QAAQ,KAAK,IAAI;AAExC,SAAK,MAAM,KAAK,IAAI;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAK,QAAiC,OAAiB;AACrD,QAAI;AACJ,QAAI,OAAO,QAAQ,UAAU;AAC3B,YAAM,QAAQ,GAAG;AACjB,UAAI,CAAC;AAAA,IACP;AACE,UAAI,EAAE,GAAG,IAAI;AAEf,MAAE,SAAS,EAAE,UAAW,KAAK;AAC7B,MAAE,MAAM,EAAE,OAAO,KAAK;AAEtB,UAAM,QAAQ,KAAK,MAAM,IAAK,OAAK,EAAE,WAAY;AACjD,SAAK,MAAM;AAAA,MACT,EAAE,OACE,IAAI,aAAa,OAAO,GAAG,KAAK,IAChC,IAAI,SAAS,OAAO,GAAG,KAAK;AAAA,IAClC;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAY,OAAiB;AAC3B,QAAI,MAAM,WAAW,KAAK,MAAM;AAC9B,YAAM,IAAI,MAAM,wBAAwB,MAAM,SAAS,kBAAkB,KAAK,MAAM,SAAS,eAAe;AAE9G,QAAI,SAAS;AACb,UAAM,WAAW,CAAC;AAClB,UAAM,MAAM,EAAE,GAAG,KAAK,IAAI;AAC1B,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,OAAO,KAAK,MAAM,CAAC;AACzB,YAAM,OAAO,KAAK,OAAO,MAAM,MAAM,CAAC,GAAG;AAAA,QACvC,KAAS;AAAA,QACT,OAAS,KAAK,SAAS,KAAK,SAAS;AAAA,QACrC,SAAS,KAAK,WAAW,KAAK,SAAS;AAAA,QACvC,SAAS,KAAK,WAAW,KAAK,SAAS;AAAA,MACzC,CAAC;AACD,YAAM,UAAU,EAAE,GAAG,KAAK,OAAO,SAAS,GAAG,GAAG,IAAI;AACpD,gBAAU,KAAK,KAAK,GAAG,CAAC,GAAG,MAAM;AAC/B,YAAI,aAAa,SAAS,QAAQ,EAAE,IAAI,MAAM;AAC5C,iBAAO,QAAQ,MAAO,IAAI,CAAC;AAAA,MAC/B,CAAC;AACD,YAAM,OAAO,gBAAgB,UACzB,OACA,IAAI,MAAM,KAAK,SAAS,KAAK,MAAM,MAAM,EAAE,UAAU,MAAM,CAAC;AAChE,UAAI,KAAK,IAAI,IAAI;AACjB,eAAS,KAAK,IAAI;AAAA,IACpB;AACA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAU,OAA8B;AACtC,QAAI;AACF,YAAM,EAAE,UAAU,OAAO,IAAI,KAAK,QAAQ,GAAG,KAAK;AAClD,YAAM,UAAU,KAAK,MAAM,IAAK,OAAK,EAAE,MAAM,GAAG,QAAQ,CAAE;AAC1D,YAAM,OAAO,QAAQ,OAAO,CAAC,KAAK,QAAQ,OAAO,IAAI,MAAM,IAAI;AAC/D,YAAM,QAAQ,QAAQ,OAAO,CAAC,KAAK,QAAQ,MAAM,IAAI,OAAO,CAAC;AAC7D,aAAO;AAAA,QACL,MAAO,SAAS,CAAC;AAAA,QACjB,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,SAAS,GAAG;AACV,aAAO,EAAE,MAAM,OAAO,SAAS,CAAC,GAAG,WAAW,GAAY,OAAO,GAAG,MAAM;AAAA,IAC5E;AAAA,EACF;AAAA,EAEA,OAAQ,SAAyH;AAC/H,UAAM,WAAuC,KAAK,WAAW,OAAO;AACpE,QAAI,QAAQ,WAAW;AACrB,YAAM,WAAW,KAAK,gBAAgB,QAAQ,SAAS;AACvD,UAAI;AACF,iBAAS,YAAY;AAAA,IACzB;AACA,QAAI,QAAQ,MAAM;AAChB,UAAI,CAAC,KAAK;AACR,iBAAS,OAAO,qBAAqB,KAAK,QAAQ;AACpD,UAAI,QAAQ,KAAK,IAAI,KAAK,EAAG;AAC3B,iBAAS,OAAO,wBAAwB,KAAK;AAC/C,cAAQ,KAAK,IAAI,KAAK,EAAG;AAAA,IAC3B;AACA,WAAO,OAAO,KAAK,QAAQ,EAAE,SAAS,WAAW;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,gBAAiB,SAA4D;AAE3E,QAAI,OAAO,YAAY,YAAY,CAAC,MAAM,QAAS,QAAsB,QAAQ,KAAK,CAAC,MAAM,QAAS,QAAsB,QAAQ,GAAG;AAErI,UAAI,CAAC,KAAK,MAAM,CAAE,QAAkD,KAAK,EAAE;AACzE,eAAO;AAAA,IACX;AAEA,UAAM,OAAO,KAAK,OAAO,SAAa,QAAkD,KAAK,EAAE,IAAI;AACnG,UAAM,EAAE,WAAW,CAAC,GAAG,WAAW,CAAC,EAAE,IAAI,QAAS;AAElD,UAAM,MAA0D,EAAE,YAAY,CAAC,GAAG,YAAY,CAAC,EAAE;AACjG,eAAW,SAAS,UAAU;AAC5B,YAAM,SAAS,KAAK,MAAM,GAAG,KAAK;AAClC,UAAI,CAAC,OAAO;AACV,YAAI,WAAW,KAAK,EAAE,OAAO,OAAO,CAAC;AAAA,IACzC;AACA,eAAW,SAAS,UAAU;AAC5B,YAAM,SAAS,KAAK,MAAM,GAAG,KAAK;AAClC,UAAI,OAAO;AACT,YAAI,WAAW,KAAK,EAAE,OAAO,OAAO,CAAC;AAAA,IACzC;AACA,WAAQ,IAAI,WAAW,SAAS,IAAI,WAAW,SAAU,MAAM;AAAA,EACjE;AAAA,EAEA,WAAY,UAA8B,CAAC,GAA+B;AACxE,UAAM,WAAuC,CAAC;AAE9C,eAAW,SAAS,CAAC,QAAQ,OAAO,GAAG;AACrC,YAAM,QAAQ,UAAW,KAA8C,KAAK,CAAC;AAC7E,UAAI;AACF,iBAAS,KAAK,IAAI;AAAA,IACtB;AACA,QAAI,QAAQ,MAAM;AAChB,YAAM,OAAO,IAAI,KAAK,KAAK,MAAM,UAAoB;AACrD,UAAI,MAAM,KAAK,QAAQ,CAAC;AACtB,iBAAS,OAAO,0BAA0B,KAAK,MAAM;AAAA,eAC9C,KAAK,QAAQ,KAAI,oBAAI,KAAK,YAAY,GAAE,QAAQ,KAAK,KAAK,QAAQ,KAAI,oBAAI,KAAK,GAAE,QAAQ;AAChG,iBAAS,OAAO,wBAAwB,KAAK,MAAM;AAAA,IACvD;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAe;AACb,WAAO,CAAC,GAAG,KAAK,KAAK;AAAA,EACvB;AAIF;AAEO,IAAe,OAAf,MAAoB;AAAA,EAezB,YAAa,OAAkB,SAAyB;AACtD,SAAK,MAAM,QAAQ,OAAO;AAC1B,SAAK,OAAO,QAAQ;AACpB,SAAK,MAAM,EAAE,GAAI,QAAQ,OAAO,CAAC,EAAG;AACpC,SAAK,QAAQ;AACb,SAAK,SAAS,QAAQ;AAAA,EACxB;AAAA,EAEA,MAAO,KAAa;AAClB,WAAO,IAAI,MAAM,KAAK,OAAO,MAAM,KAAK,EAAE,KAAK,KAAK,KAAK,OAAO,KAAM,CAAC,GAAG,KAAK,KAAK;AAAA,EACtF;AAQF;AAEO,IAAM,WAAN,cAAuB,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBjC,YAAa,OAAkB,SAAyB,OAAiB;AACvE,QAAI,MAAM,WAAW;AACnB,YAAM,IAAI,MAAM,gCAAgC;AAElD,UAAM,OAAO,OAAO;AAEpB,SAAK,WAAW,QAAQ;AACxB,KAAC,KAAK,IAAI,KAAK,EAAE,IAAI,MAAM,IAAK,CAAC,MAAc,KAAK,MAAM,CAAC,CAAE;AAAA,EAC/D;AAAA,EAEA,SAAU,OAA2B;AACnC,UAAM,KAAK,KAAK,GAAG,MAAM,KAAK;AAC9B,UAAM,KAAK,GAAG,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC;AACnC,UAAM,KAAK,KAAK,GAAG,MAAM,KAAK;AAC9B,UAAM,KAAK,GAAG,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC;AAGnC,QAAI,SAAwB;AAC5B,QAAI,CAAC,GAAG,SAAS,CAAC,GAAG;AACnB,eAAS,oCAAoC,KAAK,MAAM;AAAA,SACrD;AACH,eAAS,KAAK,WACV,SAAS,GAAG,MAAM,KAAK,QAAQ,EAAE,KAAK,SAAS,GAAG,MAAM,KAAK,QAAQ,CAAC,IACtE,GAAG,KAAK,KAAK,GAAG,IAAI;AAAA,IAC1B;AAEA,WAAO;AAAA,MACL,MAAU,CAAC;AAAA,MACX,QAAU,UAAU;AAAA,MACpB,OAAU,GAAG;AAAA,MACb,OAAU;AAAA,MACV,OAAU,GAAG;AAAA,MACb,UAAU,GAAG;AAAA,MACb,MAAU,KAAK;AAAA,MACf,MAAU;AAAA,MACV,MAAU;AAAA,IACZ;AAAA,EACF;AACF;AAEA,IAAM,YAAwC;AAAA,EAC5C,QAAW;AAAA,EACX,QAAW;AAAA,EACX,SAAW;AAAA,EACX,WAAW;AAAA,EACX,QAAW;AAAA,EACX,QAAW;AAAA,EACX,OAAW;AACb;AAEO,IAAM,eAAN,cAA2B,KAAK;AAAA;AAAA,EAKrC,YAAa,OAAkB,SAAyB,OAAiB;AACvE,UAAM,OAAO,OAAO;AACpB,QAAI,MAAM,SAAS;AACjB,YAAM,IAAI,MAAM,uCAAuC;AACzD,QAAI,CAAC,QAAQ,QAAQ,OAAO,QAAQ,SAAS,YAAY,CAAC,OAAO,KAAK,QAAQ,IAAI,EAAE;AAClF,YAAM,IAAI,MAAM,kEAAkE;AACpF,UAAM,UAAU,OAAO,KAAK,QAAQ,IAAI,EAAE,OAAQ,OAAK,CAAC,UAAU,CAAC,CAAE;AACrE,QAAI,QAAQ;AACV,YAAM,IAAI,MAAM,8DAA+D,QAAQ,KAAK,IAAI,CAAC;AAEnG,SAAK,OAAO,KAAK,MAAM,MAAM,CAAC,CAAC;AAC/B,SAAK,OAAO,EAAE,GAAG,QAAQ,KAAK;AAE9B,QAAI,KAAK,KAAK,QAAQ;AACpB,aAAO,KAAK,KAAK;AACjB,WAAK,KAAK,YAAY;AACtB,WAAK,KAAK,UAAU;AACpB,WAAK,KAAK,SAAS;AAAA,IACrB;AAEA,QAAI,KAAK,KAAK,QAAQ;AACpB,aAAO,KAAK,KAAK;AACjB,WAAK,WAAW;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,SAAU,OAA2B;AACnC,UAAM,QAAQ,KAAK,KAAK,MAAM,KAAK;AACnC,UAAM,IAAI,MAAM,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC;AACrC,UAAM,QAAQ,EAAE,KAAK,MAAM,EAAE,KAAK,KAAK,IAAI,CAAC;AAE5C,UAAM,SAAmB,CAAC;AAC1B,eAAW,OAAO,KAAK,MAAM;AAC3B,UAAK,MAAgD,GAAG,MAAO,KAAK,KAA+C,GAAG;AACpH,eAAO,KAAK,uBAAuB,MAAM,YAAa,KAAK,KAA+C,GAAG,IAAI,aAAc,MAAgD,GAAG,CAAC;AAAA,IACvL;AAEA,QAAI,KAAK,UAAU;AAEjB,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,QAAW,CAAC,KAAK,SAAS;AACxB,cAAI,gBAAgB,OAAO,gBAAgB;AACzC;AACF,gBAAM,QAAQ,KAAK,MAAM,EAAE,KAAK,KAAK,IAAI,CAAC;AAC1C,cAAI,CAAC,MAAM,QAAQ,MAAM;AACvB,mBAAO,QAAQ,KAAK,EAAE,MAAM,MAAM,CAAC;AAIrC,cAAI,gBAAgB,SAAS,MAAM,QAAQ,IAAI,IAAI;AACjD,mBAAO,QAAQ,MAAM,GAAG;AAAA,QAC5B;AAAA,MACF;AACA,UAAI,QAAQ;AACV,eAAO;AAAA,UACL,8BAA8B,OAAO,QAAQ,OAAO,MAAM,OACtD,+BACA;AAAA,QAEN;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAQ,CAAC,OAAO;AAAA,MAChB,QAAQ,OAAO,SAAS,OAAO,KAAK,IAAI,IAAI;AAAA,MAC5C,OAAQ,EAAE;AAAA,MACV;AAAA,MACA,OAAQ,EAAE;AAAA,MACV,MAAQ;AAAA,MACR,MAAQ,KAAK;AAAA,MACb,MAAQ;AAAA,IACV;AAAA,EACF;AACF;AAaO,IAAM,QAAN,MAAY;AAAA,EAIjB,YAAa,MAAY,KAAgB;AACvC,SAAK,OAAO;AACZ,SAAK,MAAM;AAAA,EACb;AAAA,EAEA,MAAO,MAAkB;AACvB,QAAI,KAAK,WAAW,KAAK,IAAI;AAC3B,YAAM,IAAI,MAAM,qBAAqB,KAAK,IAAI,SAAS,iBAAiB,KAAK,MAAM;AAErF,QAAI,OAAO,KAAK;AAChB,aAAS,IAAI,GAAG,IAAI,KAAK,IAAI,QAAQ;AACnC,aAAO,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK;AAE7C,WAAO;AAAA,EACT;AACF;AAGA,IAAM,QAAN,MAAY;AAAA,EAMV,YAAa,SAA8G;AACzH,SAAK,OAAO,QAAQ;AACpB,SAAK,QAAQ,SAAS,QAAQ,KAAK;AACnC,SAAK,KAAK,QAAQ;AAGlB,QAAI,QAAQ;AACV,WAAK,UAAU,QAAQ,QAAQ,IAAK,OAAK,aAAa,QAAQ,IAAI,IAAI,MAAM,CAAC,CAAE;AAAA,EACnF;AAAA,EAEA,OAAQ,SAAsF;AAC5F,UAAM,WAAuC,CAAC;AAC9C,UAAM,KAAK,QAAQ,KAAK,IAAK,QAAQ,IAAK;AAC1C,QAAI;AACF,eAAS,KAAK;AAChB,eAAW,SAAS,CAAC,QAAQ,OAAO,GAAG;AACrC,YAAM,QAAQ,UAAW,KAA8C,KAAK,CAAC;AAC7E,UAAI;AACF,iBAAS,KAAK,IAAI;AAAA,IACtB;AAEA,aAAS,UAAU,KAAK,QAAS,IAAI,OAAK,EAAE,OAAO,OAAO,CAAC;AAC3D,WAAO;AAAA,EACT;AACF;AAOA,SAAS,SAAU,KAAiD;AAElE,MAAI,QAAQ,UAAa,OAAO,QAAQ;AACtC,WAAO;AACT,SAAO,MAAM,QAAQ,GAAG,IAAI,IAAI,KAAK,GAAG,IAAI,KAAK;AACnD;AAEA,SAAS,QAAS,IAAkB,MAAyB;AAC3D,MAAI,OAAO;AACT,WAAO;AACT,MAAI,OAAO,OAAO,YAAY,OAAO,OAAO;AAC1C,WAAO,UAAU,OAAO;AAC1B,MAAI,MAAM;AACR,QAAI,KAAK,IAAI,EAAE;AACb,aAAO,kBAAkB;AAC3B,SAAK,IAAI,EAAE;AAAA,EACb;AAEF;AAEA,SAAS,UAAW,KAA4B;AAC9C,MAAI,QAAQ;AACV,WAAO;AACT,MAAI,OAAO,QAAQ;AACjB,WAAO,sBAAsB,OAAO;AAGtC,QAAM,WAAW,CAAC;AAClB,QAAM,WAAW;AACjB,MAAI;AACJ,UAAQ,QAAQ,SAAS,KAAK,GAAG,OAAO,MAAM;AAC5C,UAAM,CAAC,SAAS,OAAO,IAAI;AAC3B,QAAI,QAAQ,WAAW,IAAI,GAAG;AAE5B,UAAI,SAAS,WAAW,KAAK,SAAS,IAAI,MAAM;AAC9C,eAAQ,4BAA4B,OAAO;AAAA,IAC/C,OAAO;AAEL,eAAS,KAAK,OAAO;AAAA,IACvB;AAAA,EACF;AACA,MAAI,SAAS,SAAS;AACpB,WAAQ,kBAAkB,SAAS,KAAK,IAAI,CAAC;AAE/C,SAAO;AACT;AAEA,MAAM,QAAQ;AACd,MAAM,OAAO;AAEb,SAAS,SAAU,MAAY,UAAU,CAAC,GAAS;AACjD,SAAO,KAAK,SAAS,CAAC,GAAG,OAAK;AAC5B,WAAO,EAAE,MAAM,OAAO,EAAE;AAAA,EAC1B,CAAC,KAAK;AACR;;;AC5mBA,SAAS,OAAQ,MAAc,SAAwB,WAAyC;AAC9F,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,mBAAmB;AAAA,EACrB,IAAI;AACJ,QAAM,UAAU,SAAS,CAAC,QAAQ;AAGlC,QAAM,QAAkB,CAAC,CAAC,CAAC;AAC3B,MAAI,QAAQ;AACZ,MAAI,SAAS;AACb,QAAM,OAA+B,CAAC;AAEtC,QAAM,aAAa,CAAC,SAAe;AACjC;AACA,UAAM,QAAQ,QAAQ,KAAK,MAAM,EAAE,KAAK,QAAQ,KAAK,SAAS,QAAQ,QAAQ,CAAC,IAAI;AACnF,QAAI,WAAW,SAAS,MAAM,MAAM;AAClC,YAAM,MAAM,OAAO,MAAM,IAAI;AAC7B,UAAI,KAAK,GAAG;AACV,eAAO,EAAE,KAAK,IAA0B,MAAM;AAChD,WAAK,GAAG,IAAI;AAAA,IACd;AACA;AACA,UAAM,MAAM,UAAU,MAAM,KAAM;AAClC,WAAO,EAAE,KAAK,MAAM;AAAA,EACtB;AAGA,aAAW,QAAQ,MAAM;AACvB,UAAM,EAAE,MAAM,EAAE,IAAI,WAAW,IAAI;AACnC,QAAI,MAAM;AACR,aAAO,EAAE,MAAM,MAAM,OAAO,QAAQ,KAAK,EAAE;AAAA,aACpC,MAAM;AACb;AAEF,UAAM,CAAC,EAAE,KAAK,IAAI;AAAA,EACpB;AAEA,MAAI,eAAe;AAEnB,WAAS,MAAM,GAAG,MAAM,OAAO,OAAO;AACpC,QAAI,QAAQ,UAAU;AACpB,cAAQ,SAAS,EAAE,KAAK,OAAO,QAAQ,MAAM,KAAK,CAAC;AACnD,qBAAe;AAAA,IACjB;AACA,aAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC5B,iBAAW,KAAK,MAAM,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG;AACxC,mBAAW,KAAK,MAAM,CAAC,KAAK,CAAC,GAAG;AAC9B,cAAI,UAAU,QAAQ,SAAS;AAC7B,mBAAO,EAAE,OAAO,QAAQ,KAAK,GAAI,QAAQ,SAAS,EAAE,MAAM,IAAI,CAAC,EAAG;AACpE,cAAI,QAAQ,YAAY,QAAQ,gBAAgB,kBAAkB;AAChE,oBAAQ,SAAS,EAAE,KAAK,OAAO,QAAQ,MAAM,MAAM,CAAC;AACpD,2BAAe;AAAA,UACjB;AACA,gBAAM,OAAO,EAAE,MAAM,CAAC;AACtB,gBAAM,EAAE,KAAK,MAAM,IAAI,WAAW,IAAI;AAEtC,eAAK,OAAO,KAAK;AACf,mBAAO,EAAE,MAAM,MAAM,OAAO,QAAQ,KAAK,GAAI,QAAQ,SAAS,EAAE,MAAM,IAAI,CAAC,EAAG;AAAA,oBACtE,OAAO,KAAK;AACpB;AAGF,gBAAM,SAAS,SAAS,SAClB,MAAM,OAAO,IAAI,MAAM,MAAM,MAAM,IAAI,MAAM,MAAM,SAAS,IAAI,KAClE;AACJ,cAAI,CAAC,MAAM,MAAM,MAAM;AACrB,kBAAM,MAAM,MAAM,IAAI,CAAC;AACzB,gBAAM,MAAM,MAAM,EAAE,KAAK,IAAI;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,QAAQ,KAAK,OAAO,GAAI,QAAQ,SAAS,EAAE,MAAM,IAAI,CAAC,EAAG;AAC3E;AAaA,SAAS,WAAY,KAAU,UAA0B,CAAC,GAAQ;AAChE,MAAI,eAAe;AACjB,WAAO,IAAI,OAAO,OAAO;AAE3B,MAAI,eAAe;AACjB,WAAO,WAAW,IAAI,OAAO;AAC/B,MAAI,eAAe,MAAM;AACvB,WAAO;AACT,MAAI,MAAM,QAAQ,GAAG;AACnB,WAAO,IAAI,IAAI,UAAQ,WAAW,MAAM,OAAO,CAAC;AAClD,MAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,IAAI,gBAAgB;AACjE,WAAO;AAGT,QAAM,MAAkC,CAAC;AACzC,aAAW,OAAO;AAChB,QAAI,GAAG,IAAI,WAAW,IAAI,GAAG,GAAG,OAAO;AAEzC,SAAO;AACT;AAgBA,SAAS,QAAS,MAAY,MAA8B,CAAC,GAAW;AACtE,QAAM,MAAM,SAAS,CAAC,IAAI,GAAG,GAAG;AAEhC,SAAO,IAAI,KAAK,IAAI,OAAK;AACvB,QAAI,aAAa;AACf,aAAO,EAAE,OAAO,MAAM,EAAE,KAAK,OAAO,EAAE,WAAW,IAAI,IAAI,CAAC;AAC5D,QAAI,aAAa;AACf,aAAO,EAAE,OAAO;AAClB,WAAO,EAAE,OAAO,EAAE,WAAW,IAAI,IAAI,CAAC;AAAA,EACxC,CAAC,EAAE,KAAK,IAAI;AACd;AAEA,IAAM,eAAkB,CAAC,MACvB,MAAM,QAAQ,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,EAAE,CAAC,MAAM,YAAY,OAAO,EAAE,CAAC,MAAM,WAC9E,SACA;AACN,IAAM,iBAAkB,CAAC,MACvB,MAAM,QAAQ,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,EAAE,CAAC,MAAM,YAAY,OAAO,EAAE,CAAC,MAAM,YAAY,OAAO,EAAE,CAAC,MAAM,WAC1G,SACA;AAEN,IAAM,SAAgE;AAAA,EACpE,MAAW,OAAK,OAAO,MAAM,YAAY,SAAY;AAAA,EACrD,OAAW,OAAK,OAAO,MAAM,YAAY,SAAY;AAAA,EACrD,OAAW,OAAK,OAAO,MAAM,WAAW,SAAY;AAAA,EACpD,UAAW;AAAA,EACX,KAAW;AAAA,EACX,QAAW;AAAA,EACX,OAAW;AAAA,EACX,QAAW;AAAA,EACX,WAAW,OAAK;AACd,QAAI,OAAO,MAAM,YAAY,MAAM,QAAQ,EAAE,gBAAgB;AAC3D,aAAO,6BAA6B,GAAG,aAAa,QAAQ,OAAO;AACrE,UAAM,UAAU;AAChB,eAAW,OAAO,OAAO,KAAK,OAAO,GAAG;AACtC,UAAI,EAAE,QAAQ,GAAG,aAAa;AAC5B,eAAO,SAAS,MAAM;AAAA,IAC1B;AACA,WAAO;AAAA,EACT;AACF;AAMA,SAAS,mBAAoB,KAA4E;AACvG,MAAI,QAAQ,QAAQ,QAAQ;AAC1B,WAAO,EAAE,OAAO,CAAC,EAAE;AAErB,MAAI,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,KAAK,IAAI,gBAAgB;AACvE,WAAO,EAAE,OAAO,EAAE,QAAQ,4CAA4C,KAAK,aAAa,QAAQ,OAAO,KAAK,EAAE;AAEhH,QAAM,MAAM;AACZ,QAAM,QAAgC,CAAC;AAEvC,aAAW,OAAO,KAAK;AACrB,QAAI,OAAO,GAAG,GAAG;AACf,YAAM,MAAM,OAAO,GAAG,EAAE,IAAI,GAAG,CAAC;AAChC,UAAI;AACF,cAAM,GAAG,IAAI;AAAA,IACjB;AACE,YAAM,GAAG,IAAI;AAAA,EACjB;AAEA,SAAO,OAAO,KAAK,KAAK,EAAE,SAAS,IAAI,EAAE,MAAM,IAAI,EAAE,OAAO,IAAqB;AACnF;AAEO,IAAM,SAAS,EAAE,QAAQ,YAAY,SAAS,UAAU,mBAAmB;;;ANzOlF,OAAO,WAAW;AAEX,IAAM,MAAN,cAAkB,OAAO;AAAA,EAC9B;AAAA,SAAO,SAAS;AAAA;AAAA,EAChB;AAAA,SAAO,UAAU;AAAA;AAAA,EACjB;AAAA,SAAO,UAAU;AAAA;AAAA,EAEjB;AAAA;AAAA,SAAO,IAAI,OAAO;AAAA;AAAA,EAClB;AAAA,SAAO,IAAI,OAAO;AAAA;AAAA,EAClB;AAAA,SAAO,IAAI,OAAO;AAAA;AAAA,EAClB;AAAA,SAAO,IAAI,OAAO;AAAA;AAAA,EAClB;AAAA,SAAO,IAAI,OAAO;AAAA;AAAA,EAClB;AAAA,SAAO,IAAI,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAalB,OAAO,KAAM,QAAgB,CAAC,GAA+B;AAC3D,UAAM,OAAmC,CAAC;AAC1C,WAAO,IAAI,MAAM,MAAM;AAAA,MACrB,IAAK,QAAQ,MAAc;AACzB,YAAI,EAAE,QAAQ;AACZ,iBAAO,IAAI,IAAI,IAAI,QAAQ,MAAM,KAAK;AAExC,eAAO,OAAO,IAAI;AAAA,MACpB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,OAAQ,GAAmB;AAChC,WAAO,IAAI,OAAO,CAAC;AAAA,EACrB;AAAA,EAEA;AAAA,SAAO,SAAS;AAAA;AAAA,EAChB;AAAA,SAAO,QAAQ;AAAA;AACjB;AAWA,IAAM,IAAI;AAGV,IAAI,EAAE,SAAS,IAAI,UAAU;AAC3B,IAAE,MAAM;AACR,UAAQ,IAAI,sCAAsC;AACpD;AAGA,IAAI,OAAO,WAAW;AACpB,SAAO,MAAM;",
|
|
3
|
+
"sources": ["../src/index.ts", "../src/internal.ts", "../src/expr.ts", "../src/parser.ts", "../src/quest.ts", "../src/extras.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n classes, native, control, FreeVar, Church, toposort,\n} from './expr';\nimport { Parser } from './parser';\n\nimport { Quest } from './quest';\nimport { extras } from './extras';\nextras.toposort = toposort;\n\nexport class SKI extends Parser {\n static native = native;\n static control = control;\n static classes = classes;\n // TODO declare in a loop?\n static B = native.B;\n static C = native.C;\n static I = native.I;\n static K = native.K;\n static S = native.S;\n static W = native.W;\n\n /**\n * Create a proxy object that generates variables on demand,\n * with names corresponding to the property accessed.\n * Different invocations will return distinct variables,\n * even if with the same name.\n *\n * @example const {x, y, z} = SKI.vars();\n * x.name; // 'x'\n * x instanceof FreeVar; // true\n * x.apply(y).apply(z); // x(y)(z)\n */\n static vars (scope: object = {}): { [key: string]: FreeVar } {\n const vars: { [key: string]: FreeVar } = {};\n return new Proxy(vars, {\n get (target, prop: string) {\n if (!(prop in target))\n target[prop] = new FreeVar(prop, scope);\n\n return target[prop];\n }\n });\n }\n\n static church (n: number): Church {\n return new Church(n);\n }\n\n static extras = extras;\n static Quest = Quest;\n}\n\ndeclare global {\n interface Window { SKI: typeof SKI }\n}\n\ntype AnyGlobal = typeof globalThis & {\n SKI: typeof SKI;\n process?: { env: Record<string, string | undefined> };\n};\n\nconst g = globalThis as AnyGlobal;\n\n// SKI_REPL=1 node -r ./index.js\nif (g.process?.env.SKI_REPL) {\n g.SKI = SKI;\n console.log('SKI_REPL activated, try `new SKI();`');\n}\n\n// we're in a browser\nif (typeof window !== 'undefined')\n window.SKI = SKI;\n", "/* utility types */\n\nexport class Tokenizer {\n /**\n * Create a tokenizer that splits strings into tokens according to the given terms.\n * The terms are interpreted as regular expressions, and are sorted by length\n * to ensure that longer matches are preferred over shorter ones.\n * @param {...string|RegExp} terms\n */\n rex: RegExp;\n constructor (...terms: (string | RegExp)[]) {\n const src = '$|(\\\\s+)|' + terms\n .map(s => '(?:' + s + ')')\n .sort((a, b) => b.length - a.length)\n .join('|');\n this.rex = new RegExp(src, 'gys');\n }\n\n /**\n * Split the given string into tokens according to the terms specified in the constructor.\n * @param {string} str\n * @return {string[]}\n */\n split (str: string): string[] {\n this.rex.lastIndex = 0;\n const list = [...str.matchAll(this.rex)];\n\n // did we parse everything?\n const eol = list.pop();\n const last = eol?.index ?? 0;\n\n if (last !== str.length) {\n throw new Error('Unknown tokens at pos ' + last + '/' + str.length\n + ' starting with ' + str.substring(last));\n }\n\n // skip whitespace\n return list.filter(x => x[1] === undefined).map(x => x[0]);\n }\n}\n\nconst tokRestrict = new Tokenizer('[-=+]', '[A-Z]', '\\\\b[a-z_][a-z_0-9]*\\\\b');\n\n/**\n * Add ot remove tokens from a set according to a spec string.\n * The spec string is a sequence of tokens, with each group optionally prefixed\n * by one of the operators '=', '+', or '-'.\n * The '=' operator resets the set to contain only the following token(s).\n * @param {Set<string>} set\n * @param {string} [spec]\n * @returns {Set<string>}\n */\nexport function restrict (set:Set<string>, spec?: string) {\n if (!spec)\n return set;\n let out = new Set([...set]);\n let mode = '=';\n const act : {[key: string]: (s: string) => void} = {\n '=': sym => { out = new Set([sym]); mode = '+'; },\n '+': sym => { out.add(sym); },\n '-': sym => { out.delete(sym); },\n };\n\n for (const sym of tokRestrict.split(spec)) {\n if (act[sym])\n mode = sym;\n else\n act[mode](sym);\n }\n return out;\n}\n\nexport type TraverseDecorator = <T>(value?: T) => TraverseControl<T>;\nexport type TraverseValue<T> = TraverseControl<T | null | undefined | void> | T | null | undefined | void;\n\nexport class TraverseControl<T> {\n /**\n * A wrapper for values returned by fold/traverse callbacks\n * which instructs the traversal to alter its behavior while\n * retaining the value in question.\n *\n * This class is instantiated internally be `SKI.control.*` functions,\n * and is not intended to be used directly by client code.\n *\n * @template T\n * @param {T} value\n * @param {function(T): TraverseControl<T>} decoration\n */\n value?: T;\n decoration: TraverseDecorator;\n constructor (value: T | undefined, decoration: TraverseDecorator) {\n this.value = value;\n this.decoration = decoration;\n }\n}\n\n/**\n * @private\n * @template T\n * @param {T|TraverseControl<T>|null} value\n * @returns {[T?, function|undefined]}\n */\nexport function unwrap<T> (value: TraverseValue<T>): [T?, TraverseDecorator?] {\n // `?? undefined` so that null is not 'an object'\n if (value instanceof TraverseControl)\n return [value.value ?? undefined, value.decoration];\n return [value ?? undefined, undefined];\n}\n\n/**\n * Prepare a self-referencing wrapper function for use as a fold/traverse control decorator.\n *\n * If `fun` is created by `prepareWrapper`, then\n * unwrap(fun(x)) will always return exactly [x, fun], and the second value can be checked with ===.\n *\n * An optional label can be provided for debugging purposes.\n *\n * @private\n * @template T\n * @param {string} [label]\n * @returns {function(T): TraverseControl<T>}\n */\nexport function prepareWrapper (label?: string): <T>(value?: T) => TraverseControl<T> {\n const fun: TraverseDecorator = <T>(value: T|undefined) => new TraverseControl<T>(value, fun);\n (fun as { label?: string }).label = label;\n fun.toString = () => 'TraverseControl::' + label;\n return fun;\n}\n", "'use strict';\n\nimport { unwrap, prepareWrapper, TraverseValue } from './internal';\n\nconst DEFAULTS = {\n max: 1000,\n maxArgs: 32,\n maxSize: 1_000_000,\n};\n\n// canonize traverse order aliases\nconst ORDER: Record<string, 'LI' | 'LO'> = {\n 'leftmost-outermost': 'LO',\n 'leftmost-innermost': 'LI',\n LO: 'LO',\n LI: 'LI',\n};\n\n/**\n * Control primitives for fold() and traverse() methods.\n */\nexport const control = {\n descend: prepareWrapper('descend'),\n prune: prepareWrapper('prune'),\n redo: prepareWrapper('redo'),\n stop: prepareWrapper('stop'),\n};\n\n/**\n * List of predefined native combinators.\n * This is required for toSKI() to work, otherwise could as well have been in parser.js.\n */\nexport const native: Record<string, Native> = {};\n\nexport type TermInfo = {\n normal: boolean, // whether the term becomes irreducible after receiving a number of arguments.\n proper: boolean, // whether the irreducible form is only contains its arguments. implies normal.\n arity?: number, // the number of arguments that is enough to reach the irreducible form\n discard?: boolean, // whether the term (or subterms, unless proper) can discard arguments.\n duplicate?: boolean, // whether the term (or subterms, unless proper) can duplicate arguments.\n skip?: Set<number>, // indices of arguments that are discarded. nonempty implies discard.\n dup?: Set<number>, // indices of arguments that are duplicated. nonempty implies duplicate.\n expr?: Expr, // canonical form containing only lambdas, applications, and variables, if one exists\n steps?: number, // number of reduction steps taken to obtain the aforementioned information, if applicable\n}\n\nexport type Invocation = Expr | ((arg: Expr) => Invocation);\nexport type Step = { expr: Expr, steps: number, changed: boolean };\nexport type Run = { expr: Expr, steps: number, final: boolean };\nexport type RunOptions = { max?: number, steps?: number, throw?: boolean, maxSize?: number };\n\nexport type FormatOptions = {\n terse?: boolean,\n html?: boolean,\n brackets?: [string, string],\n space?: string,\n var?: [string, string],\n lambda?: [string, string, string],\n around?: [string, string],\n redex?: [string, string],\n inventory?: Record<string, Named>,\n};\n\n/**\n * A version of FormatOptions with defaults plugged in,\n * use for mandatory formatImpl implementation in Expr subclasses.\n */\nexport type RefinedFormatOptions = { // ditto but with defaults plugged in\n terse?: boolean,\n html?: boolean,\n brackets: [string, string],\n space: string,\n var: [string, string],\n lambda: [string, string, string],\n around: [string, string],\n redex: [string, string],\n inventory?: Record<string, Expr>,\n}\n\nexport type TraverseOptions = {order?: 'LO' | 'LI' | 'leftmost-outermost' | 'leftmost-innermost'};\nexport type TraverseCallback = (e:Expr) => TraverseValue<Expr>;\n\nexport type ToposortResult = { list: Expr[], env: Record<string, Named> };\n\n/**\n * A combinatory logic expression.\n *\n * Applications, variables, lambdas, combinators per se,\n * and other expression subtypes all extend this class.\n *\n * Expr itself cannot (or at least should not) be instantiated.\n *\n * @abstract\n */\nexport abstract class Expr {\n /** optional context for the term. Is set by the parser with addContext: true */\n context?: {\n scope?: object,\n env?: Record<string, Expr>,\n src?: string,\n parser: object,\n }\n\n /** number of arguments the term is waiting for (if known) */\n arity?: number;\n /** a brief description what the term does */\n note?: string;\n /** the properties of the term, typically inferred from its behavior.\n * This is used internally when declaring Native / Alias terms.\n */\n props?: TermInfo;\n /** An estimated number of nodes in the expression tree.\n * Used to prevent runaway computations.\n */\n size?: number;\n\n /**\n * Add metadata based on user-supplied values and/or the properties of the term itself.\n *\n * Typically applied to named terms shortly after instantiation.\n *\n * Experimental. Name and meaning may change in the future.\n *\n * @experimental\n * @param {Object} options\n * @param {string} [options.note] - a brief description what the term does\n * @param {number} [options.arity] - number of arguments the term is waiting for (if known)\n * @param {string} [options.fancy] - how to display in html mode, e.g. φ instead of 'f'\n * @param {boolean} [options.canonize] - whether to try to infer the properties\n * @param {number} [options.max] - maximum number of steps for inference, if canonize is true\n * @param {number} [options.maxArgs] - maximum number of arguments for inference, if canonize is true\n * @return {this}\n */\n annotate (options: { note?: string, arity?: number, fancy?: string, canonize?: boolean, max?: number, maxArgs?: number, } = {}) {\n // TODO better name\n\n if (options.fancy !== undefined && this instanceof Named)\n this.fancyName = options.fancy;\n\n if (options.note !== undefined)\n this.note = options.note;\n\n if (options.arity !== undefined)\n this.arity = options.arity;\n\n if (options.canonize) {\n const guess = this.infer(options);\n if (guess.normal) {\n this.arity = this.arity ?? guess.arity;\n this.note = this.note ?? guess.expr!.format({ html: true, lambda: ['', ' ↦ ', ''] });\n delete guess.steps;\n this.props = guess;\n }\n }\n return this;\n }\n\n /**\n * apply self to zero or more terms and return the resulting term,\n * without performing any calculations whatsoever\n * @param {Expr} args\n * @return {Expr}\n */\n apply (...args: Expr[]): Expr {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let expr: Expr = this;\n for (const arg of args)\n expr = new App(expr, arg);\n return expr;\n }\n\n /**\n * Replace all aliases in the expression with their definitions, recursively.\n * @return {Expr}\n */\n expand (): Expr {\n return this.traverse(e => {\n if (e instanceof Alias)\n return e.impl.expand();\n }) ?? this;\n }\n\n /**\n * Traverse the expression tree, applying change() to each node.\n * If change() returns an Expr, the node is replaced with that value.\n * A null/undefined value is interpreted as\n * \"descend further if applicable, or leave the node unchanged\".\n *\n * Returned values may be decorated:\n *\n * SKI.control.prune will suppress further descending even if nothing was returned\n * SKI.control.stop will terminate further changes.\n * SKI.control.redo will apply the callback to the returned subtree, recursively.\n *\n * Note that if redo was applied at least once to a subtree, a null return from the same subtree\n * will be replaced by the last non-null value returned.\n *\n * The traversal order is leftmost-outermost, unless options.order = 'leftmost-innermost' is specified.\n * Short aliases 'LO' and 'LI' (case-sensitive) are also accepted.\n *\n * Returns null if no changes were made, or the new expression otherwise.\n *\n * @param {{\n * order?: 'LO' | 'LI' | 'leftmost-outermost' | 'leftmost-innermost',\n * }} [options]\n * @param {(e:Expr) => TraverseValue<Expr>} change\n * @returns {Expr|null}\n * @sealed\n */\n traverse (\n options: TraverseOptions | TraverseCallback,\n change?: TraverseCallback\n ): Expr | null {\n if (typeof options === 'function') {\n change = options;\n options = {};\n }\n const order = ORDER[options.order ?? 'LO'];\n if (order === undefined)\n throw new Error('Unknown traversal order: ' + options.order);\n const [expr] = unwrap(this._traverse_redo({ order }, change!));\n return expr ?? null;\n }\n\n /**\n *\n *\n * @protected\n *\n * @param {Object} options\n * @param {(e:Expr) => TraverseValue<Expr>} change\n * @returns {TraverseValue<Expr>}\n */\n _traverse_redo (options: TraverseOptions, change: TraverseCallback): TraverseValue<Expr> {\n let action;\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let expr: Expr | undefined = this;\n let prev;\n do {\n prev = expr;\n const next: TraverseValue<Expr> = options.order === 'LI'\n ? expr._traverse_descend(options, change) ?? change(expr)\n : change(expr) ?? expr._traverse_descend(options, change);\n [expr, action] = unwrap(next);\n } while (expr && action === control.redo);\n if (!expr && prev !== this)\n expr = prev; // we were in redo at least once\n return action ? action(expr!) : expr;\n }\n\n /**\n * Apply a {@link traverse} callback to the subterms of the expression, without changing the expression itself.\n *\n * @protected\n * @param {Object} options\n * @param {(e:Expr) => TraverseValue<Expr>} change\n * @returns {TraverseValue<Expr>}\n */\n _traverse_descend (options: TraverseOptions, change: TraverseCallback): TraverseValue<Expr> {\n return null;\n }\n\n /**\n * Returns true if predicate() is true for any subterm of the expression, false otherwise.\n *\n * @param {(e: Expr) => boolean} predicate\n * @returns {boolean}\n */\n any (predicate: (e: Expr) => boolean): boolean {\n return predicate(this);\n }\n\n /**\n * Fold the expression into a single value by recursively applying combine() to its subterms.\n * Nodes are traversed in leftmost-outermost order, i.e. the same order as reduction steps are taken.\n *\n * null or undefined return value from combine() means \"keep current value and descend further\".\n *\n * SKI.control provides primitives to control the folding flow:\n * - SKI.control.prune(value) means \"use value and don't descend further into this branch\";\n * - SKI.control.stop(value) means \"stop folding immediately and return value\".\n * - SKI.control.descend(value) is the default behavior, meaning \"use value and descend further\".\n *\n * This method is experimental and may change in the future.\n *\n * @example // count the number of nodes in the expression tree\n * expr.fold(0, (acc, e) => acc + 1);\n *\n * @experimental\n *\n * @template T\n * @param {T} initial\n * @param {(acc: T, expr: Expr) => TraverseValue<T>} combine\n * @returns {T}\n */\n fold<T> (initial: T, combine: (acc: T, expr: Expr) => TraverseValue<T>): T {\n const [value] = unwrap(this._fold(initial, combine));\n return value ?? initial;\n }\n\n /**\n * Internal method for fold(), which performs the actual folding.\n * Should be implemented in subclasses having any internal structure.\n *\n * @protected\n * @param initial\n * @param combine\n */\n _fold<T> (initial:T, combine: (acc: T, expr: Expr) => TraverseValue<T>): TraverseValue<T> {\n return combine(initial, this);\n }\n\n /**\n * @experimental\n * Fold an application tree bottom to top.\n * For each subtree, the function is given the term in the root position and\n * a list of the results of folding its arguments.\n *\n * E.g. fold('x y (z t)', f) results in f(x, [f(y, []), f(z, [f(t, [])])])\n *\n * @example expr.foldBottomUp((head, tail) => {\n * if (head.arity && head.arity <= tail.length) {\n * return '(<span class=\"redex\">'\n * + head + ' '\n * + tail.slice(0, head.arity).join(' ')\n * + '</span>'\n * + tail.slice(head.arity).join(' ')\n * + ')';\n * } else {\n * return '(' + head + ' ' + tail.join(' ') + ')';\n * }\n * });\n * @template T\n * @param {(head: Expr, tail: T[]) => T} fun\n * @return {T}\n */\n foldBottomUp<T> (fun: (head: Expr, tail: T[]) => T): T {\n const [head, ...tail] = this.unroll();\n return fun(head, tail.map(e => e.foldBottomUp(fun)));\n }\n\n /**\n * Try to empirically find an equivalent lambda term for the expression,\n * returning also the term's arity and some other properties.\n *\n * This is used internally when declaring a Native / Alias term,\n * unless {canonize: false} is used.\n *\n * As of current it only recognizes terms that have a normal form,\n * perhaps after adding some variables. This may change in the future.\n *\n * Use toLambda() if you want to get a lambda term in any case.\n *\n * @sealed\n * @param {{max?: number, maxArgs?: number}} options\n * @return {TermInfo}\n */\n infer (options : {max?: number, maxArgs?: number, maxSize?: number } = {}): TermInfo {\n // First gather the names which can collide with generated variables and forbid them.\n // TODO confusing naming, rewrite.\n const skipNames: Record<string, boolean> = {};\n const skipSkip: Set<Expr> = new Set();\n this.traverse(e => {\n if (e instanceof Named && !skipSkip.has(e))\n skipNames[e.name] = true;\n if (e instanceof Lambda)\n skipSkip.add(e.arg);\n });\n return this._infer({\n max: options.max ?? DEFAULTS.max,\n maxArgs: options.maxArgs ?? DEFAULTS.maxArgs,\n maxSize: options.maxSize ?? DEFAULTS.maxSize,\n skipNames,\n }, 0);\n // TODO maybe traverse() if no normal form was found\n }\n\n /**\n * Internal method for infer(), which performs the actual inference.\n * @param {{max: number, maxArgs: number}} options\n * @param {number} nargs - var index to avoid name clashes\n * @returns {TermInfo}\n * @private\n */\n _infer (options:{max: number, maxArgs: number, maxSize: number, skipNames: Record<string, boolean>}, nargs: number): TermInfo {\n const probe: FreeVar[] = [];\n let steps = 0;\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let expr: Expr = this;\n // eslint-disable-next-line no-labels\n main: for (let i = 0; i < options.maxArgs; i++) {\n // keep reduction budget at bay.\n // ideally should be increased with more args but that (predictably) causes very long test runs\n const next = expr.run({ max: Math.max((options.max - steps) / 2, 10), maxSize: options.maxSize });\n // console.log(`infer step ${i}, expr = ${expr}, probe = [${probe}]: `, next);\n steps += next.steps;\n\n // if !final, still append more args, e.g. CK(WWW) is a->a, not CK(omega)\n if (next.final && firstVar(next.expr)) {\n // can't append more variables, return or recurse\n expr = next.expr;\n if (!expr.any(e => !(e instanceof FreeVar || e instanceof App)))\n return maybeLambda(probe, expr, { steps });\n const list = expr.unroll();\n let discard = false;\n let duplicate = false;\n const acc = [];\n for (let j = 1; j < list.length; j++) {\n const sub = list[j]._infer(\n { maxArgs: options.maxArgs - nargs, max: options.max - steps, maxSize: options.maxSize, skipNames: options.skipNames }, // limit recursion\n nargs + i // avoid variable name clashes\n );\n steps += sub.steps ?? 0;\n if (!sub.expr)\n // eslint-disable-next-line no-labels\n break main; // press f to pay respects\n if (sub.discard)\n discard = true;\n if (sub.duplicate)\n duplicate = true;\n acc.push(sub.expr);\n }\n return maybeLambda(probe, list[0].apply(...acc), { discard, duplicate, steps });\n }\n while (options.skipNames[nthvar(nargs + i).name])\n nargs++;\n const push = nthvar(nargs + i);\n probe.push(push);\n expr = next.expr.apply(push);\n }\n return { normal: false, proper: false, steps };\n }\n\n /**\n * Expand an expression into a list of terms\n * that give the initial expression when applied from left to right:\n * ((a, b), (c, d)) => [a, b, (c, d)]\n *\n * This can be thought of as an opposite of apply:\n * fun.apply(...arg).unroll() is exactly [fun, ...args]\n * (even if ...arg is in fact empty).\n *\n * @returns {Expr[]}\n */\n unroll (): Expr[] {\n // currently only used by infer() but may be useful\n // to convert binary App trees to n-ary or smth\n return [this];\n }\n\n /**\n * Returns a series of lambda terms equivalent to the given expression,\n * up to the provided computation steps limit.\n *\n * Unlike infer(), this method will always return something,\n * even if the expression has no normal form.\n *\n * See also Expr.walk() and Expr.toSKI().\n *\n * @sealed\n * @param {{\n * max?: number,\n * maxArgs?: number,\n * varGen?: function(void): FreeVar,\n * steps?: number,\n * html?: boolean,\n * latin?: number,\n * }} options\n * @return {IterableIterator<{expr: Expr, steps?: number, comment?: string}>}\n */\n * toLambda (options: { max?: number, maxArgs?: number } = {}) {\n let expr:Expr | null = this.traverse(e => {\n // free var => self, don't bother\n if (e instanceof FreeVar)\n return e;\n // compound => fall through\n if (e instanceof App || e instanceof Lambda || e instanceof Alias)\n return null;\n // all other => infer\n const guess = e.infer({ max: options.max, maxArgs: options.maxArgs });\n // TODO just return the term itself? Not sure if assertion obligate.\n if (!guess.normal)\n throw new Error('Failed to infer an equivalent lambda term for ' + e);\n return guess.expr;\n }) ?? this;\n const seen = new Set(); // prune irreducible\n let steps = 0;\n while (expr) {\n const next = expr.traverse({ order: 'LI' }, e => {\n if (seen.has(e))\n return null;\n if (e instanceof App && e.fun instanceof Lambda) {\n const guess = e.infer({ max: options.max, maxArgs: options.maxArgs });\n steps += guess.steps ?? 0;\n if (!guess.normal) {\n seen.add(e);\n return null;\n }\n return control.stop(guess.expr);\n }\n });\n yield { expr, steps };\n expr = next;\n }\n }\n\n /**\n * Rewrite the expression into S, K, and I combinators step by step.\n * Returns an iterator yielding the intermediate expressions,\n * along with the number of steps taken to reach them.\n *\n * See also Expr.walk() and Expr.toLambda().\n *\n * @sealed\n * @param {{max?: number}} [options]\n * @return {IterableIterator<{final: boolean, expr: Expr, steps: number}>}\n */\n * toSKI (options: {max?: number, maxArgs?: number} = {}) {\n // options are ignored completely, TODO remove\n // get rid of non-lambdas\n let expr:Expr|null = this.traverse(e => {\n if (e instanceof FreeVar || e instanceof App || e instanceof Lambda || e instanceof Alias)\n return null;\n // TODO infer failed for atomic term? die...\n return e.infer(options).expr;\n }) ?? this;\n\n let steps = 0;\n while (expr) {\n const next = expr.traverse({ order: 'LI' }, e => {\n if (!(e instanceof Lambda) || (e.impl instanceof Lambda))\n return null; // continue\n if (e.impl === e.arg)\n return control.stop(native.I);\n if (!e.impl.any(t => t === e.arg))\n return control.stop(native.K.apply(e.impl));\n // TODO use real assert here. e.impl contains e.arg and also isn't e.arg, in MUST be App.\n if (!(e.impl instanceof App))\n throw new Error('toSKI: assert failed: lambda body is of unexpected type ' + e.impl.constructor.name );\n // eta-reduction: body === (not e.arg) (e.arg)\n if (e.impl.arg === e.arg && !e.impl.fun.any(t => t === e.arg))\n return control.stop(e.impl.fun);\n // last resort, go S\n return control.stop(native.S.apply(new Lambda(e.arg, e.impl.fun), new Lambda(e.arg, e.impl.arg)));\n })\n yield { expr, steps, final: !next };\n steps++;\n expr = next;\n }\n }\n\n /**\n * Replace all instances of `search` in the expression with `replace` and return the resulting expression,\n * or null if no changes could be made.\n *\n * Lambda terms and applications will never match if used as plug\n * as they are impossible to compare without extensive computations.\n *\n * Typically used on variables but can also be applied to other terms, e.g. aliases.\n * See also Expr.traverse() for more flexible replacement of subterms.\n *\n * @param {Expr} search\n * @param {Expr} replace\n * @return {Expr|null}\n */\n subst (search:Expr, replace:Expr): Expr|null {\n return this === search ? replace : null;\n }\n\n /**\n * Apply term reduction rules, if any, to the given argument.\n * A returned value of null means no reduction is possible.\n * A returned value of Expr means the reduction is complete and the application\n * of this and arg can be replaced with the result.\n * A returned value of a function means that further arguments are needed,\n * and can be cached for when they arrive.\n *\n * This method is between apply() which merely glues terms together,\n * and step() which reduces the whole expression.\n *\n * foo.invoke(bar) is what happens inside foo.apply(bar).step() before\n * reduction of either foo or bar is attempted.\n *\n * The name 'invoke' was chosen to avoid confusion with either 'apply' or 'reduce'.\n *\n * @param {Expr} arg\n * @returns {Partial | null}\n */\n invoke (arg:Expr): Invocation | null {\n return null;\n }\n\n /**\n * iterate one step of a calculation.\n * @return {{expr: Expr, steps: number, changed: boolean}}\n */\n step (): Step { return { expr: this, steps: 0, changed: false } }\n\n /**\n * Iteratively apply {@link step} to the expression until it's irreducible,\n * or until the provided limits are reached.\n *\n * Returns { expr: Expr, steps: number, final: boolean }.\n *\n * If { throw: true } is given and no irreducible form was reached within the limits, an error is thrown.\n *\n * @sealed\n * @param {{max?: number, steps?: number, throw?: boolean}|Expr} [opt]\n * @param {Expr} args\n * @return {{expr: Expr, steps: number, final: boolean}}\n */\n run (opt : RunOptions|Expr = {}, ...args: Expr[]): Run {\n if (opt instanceof Expr) {\n args.unshift(opt);\n opt = {};\n }\n let expr = args ? this.apply(...args) : this;\n let steps = opt.steps ?? 0;\n // make sure we make at least 1 step, to tell whether we've reached the normal form\n const max = Math.max(opt.max ?? DEFAULTS.max, 1) + steps;\n let final = false;\n for (; steps < max; ) {\n const next = expr.step();\n if (!next.changed) {\n final = true;\n break;\n }\n if ((next.expr.size ?? 1) > (opt.maxSize ?? DEFAULTS.maxSize))\n break;\n steps += next.steps;\n expr = next.expr;\n }\n if (opt.throw && !final)\n throw new Error('Failed to compute expression in ' + max + ' steps');\n return { final, steps, expr };\n }\n\n /**\n * Returns an iterator of reduction steps of the expression, up to the provided limits.\n * Each step is an object of { expr, steps, final }, same as in {@link run}.\n *\n * Mnemonics: like {@link run} but slower.\n *\n * @remarks\n * This method is final. Do not override, override {@link step} instead.\n *\n * @param {{max?: number}} options\n * @return {IterableIterator<{final: boolean, expr: Expr, steps: number}>}\n */\n * walk (options : { max?: number, maxSize?: number } = {}): IterableIterator<Run> {\n const max = options.max ?? Infinity;\n let steps = 0;\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let expr:Expr = this;\n let final = false;\n\n while (steps < max && (expr.size ?? 1) < (options.maxSize ?? DEFAULTS.maxSize)) {\n // 1. calculate\n // 2. yield _unchanged_ expression\n // 3. either advance or stop\n const next = expr.step();\n if (!next.changed)\n final = true;\n yield { expr, steps, final };\n if (final)\n break;\n steps += next.steps;\n expr = next.expr;\n }\n }\n\n /**\n * True is the expressions are identical, false otherwise.\n * Aliases are expanded.\n * Bound variables in lambda terms are renamed consistently.\n * However, no reductions are attempted.\n *\n * E.g. a->b->a == x->y->x is true, but a->b->a == K is false.\n *\n * @remarks Final. Current implementation is a frontend to {@link diff}.\n *\n * @param {Expr} other\n * @return {boolean}\n */\n equals (other:Expr):boolean {\n return !this.diff(other);\n }\n\n /**\n * Recursively compare two expressions and return a string\n * describing the first point of difference.\n * Returns null if expressions are identical.\n *\n * Aliases are expanded.\n * Bound variables in lambda terms are renamed consistently.\n * However, no reductions are attempted.\n *\n * Members of the FreeVar class are considered different\n * even if they have the same name, unless they are the same object.\n * To somewhat alleviate confusion, the output will include\n * the internal id of the variable in square brackets.\n *\n * Do not rely on the exact format of the output as it may change in the future.\n *\n * @example \"K(S != I)\" is the result of comparing \"KS\" and \"KI\"\n * @example \"S(K([x[13] != x[14]]))K\"\n *\n * @param {Expr} other\n * @param {boolean} [swap] If true, the order of expressions is reversed in the output.\n * @returns {string|null}\n */\n diff (other:Expr, swap: boolean = false): string | null {\n if (this === other)\n return null;\n if (other instanceof Alias)\n return other.impl.diff(this, !swap);\n return swap\n ? '[' + other + ' != ' + this + ']'\n : '[' + this + ' != ' + other + ']';\n }\n\n /**\n * Assert expression equality. Can be used in tests.\n *\n * `this` is the expected value and the argument is the actual one.\n * Mnemonic: the expected value is always a combinator, the actual one may be anything.\n *\n * In case of failure, an error is thrown with a message describing the first point of difference\n * and `expected` and `actual` properties like in AssertionError.\n * AssertionError is not used directly because browsers don't recognize it.\n *\n * @sealed\n * @param {Expr} actual\n * @param {string} comment\n */\n expect (actual:Expr|object, comment = ''):void {\n comment = comment ? comment + ': ' : '';\n if (!(actual instanceof Expr)) {\n throw new Error(comment + 'Expected a combinator but found '\n + (actual?.constructor?.name ?? typeof actual));\n }\n const diff = this.diff(actual);\n if (!diff)\n return; // all good\n\n // TODO wanna use AssertionError but browser doesn't recognize it\n // still the below hack works for mocha-based tests.\n const poorMans = new Error(comment + diff) as Error & { expected?: string, actual?: string };\n poorMans.expected = this.diag();\n poorMans.actual = actual.diag();\n throw poorMans;\n }\n\n /**\n * Returns string representation of the expression.\n * Same as format() without options.\n *\n * Use formatImpl() to override in subclasses.\n * @return {string}\n * @sealed\n */\n toString (): string {\n return this.format();\n }\n\n /**\n * Whether the expression needs to be parenthesized when printed in terse mode.\n * (see {@link format})\n * @param isFirst whether this is the first term in a sequence\n * @return {boolean}\n * @protected\n */\n _braced (isFirst?:boolean): boolean {\n return false;\n }\n\n /**\n * Whether the expression can be printed without a space when followed by arg.\n * @param {Expr} arg\n * @returns {boolean}\n * @protected\n */\n _unspaced (arg: Expr): boolean {\n return this._braced(true);\n }\n\n /**\n * Stringify the expression with fancy formatting options.\n * Said options mostly include wrappers around various constructs in form of ['(', ')'],\n * as well as `terse` and `html` flags that fill in appropriate defaults.\n * Format without options is equivalent to toString() and can be parsed back.\n *\n * @sealed\n *\n * @param {Object} [options] - formatting options\n * @param {boolean} [options.terse] - whether to use terse formatting (omitting unnecessary spaces and parentheses)\n * @param {boolean} [options.html] - whether to default to HTML tags & entities.\n * If a named term has fancyName property set, it will be used instead of name in this mode.\n * @param {[string, string]} [options.brackets] - wrappers for application arguments, typically ['(', ')']\n * @param {[string, string]} [options.var] - wrappers for variable names\n * (will default to <var> and </var> in html mode).\n * @param {[string, string, string]} [options.lambda] - wrappers for lambda abstractions, e.g. ['λ', '.', '']\n * where the middle string is placed between argument and body\n * default is ['', '->', ''] or ['', '->', ''] for html\n * @param {[string, string]} [options.around] - wrappers around (sub-)expressions.\n * individual applications will not be wrapped, i.e. (a b c) but not ((a b) c)\n * @param {[string, string]} [options.redex] - wrappers around the starting term(s) that have enough arguments to be reduced\n * @param {Object<string, Expr>} [options.inventory] - if given, output aliases in the set as their names\n * and any other aliases as the expansion of their definitions.\n * The default is a cryptic and fragile mechanism dependent on a hidden mutable property.\n * @returns {string}\n *\n * @example foo.format() // equivalent to foo.toString()\n * @example foo.format({terse: false}) // spell out all parentheses\n * @example foo.format({html: true}) // use HTML tags and entities\n * @example foo.format({ around: ['(', ')'], brackets: ['', ''], lambda: ['(', '->', ')'] }) // lisp style, still back-parsable\n * @example foo.format({ lambda: ['λ', '.', ''] }) // pretty-print for the math department\n * @example foo.format({ lambda: ['', '=>', ''], terse: false }) // make it javascript\n * @example foo.format({ inventory: { T } }) // use T as a named term, expand all others\n *\n */\n format (options: FormatOptions = {}): string {\n const fallback: RefinedFormatOptions = options.html\n ? {\n brackets: ['(', ')'],\n space: ' ',\n var: ['<var>', '</var>'],\n lambda: ['', '->', ''],\n around: ['', ''],\n redex: ['', ''],\n }\n : {\n brackets: ['(', ')'],\n space: ' ',\n var: ['', ''],\n lambda: ['', '->', ''],\n around: ['', ''],\n redex: ['', ''],\n }\n return this.formatImpl({\n terse: options.terse ?? true,\n brackets: options.brackets ?? fallback.brackets,\n space: options.space ?? fallback.space,\n var: options.var ?? fallback.var,\n lambda: options.lambda ?? fallback.lambda,\n around: options.around ?? fallback.around,\n redex: options.redex ?? fallback.redex,\n inventory: options.inventory, // TODO better name\n html: options.html ?? false,\n }, 0);\n }\n\n /**\n * Internal method for format(), which performs the actual formatting.\n * @param {Object} options\n * @param {number} nargs\n * @returns {string}\n * @protected\n * @abstract\n */\n abstract formatImpl (options: RefinedFormatOptions, nargs: number): string;\n\n /**\n * Returns a string representation of the expression tree, with indentation to show structure.\n *\n * Applications are flattened to avoid excessive nesting.\n * Variables include ids to distinguish different instances of the same variable name.\n *\n * May be useful for debugging.\n *\n * @returns {string}\n *\n * @example\n * > console.log(ski.parse('C 5 x (x->x x)').diag())\n * App:\n * Native: C\n * Church: 5\n * FreeVar: x[53]\n * Lambda (x[54]):\n * App:\n * FreeVar: x[54]\n * FreeVar: x[54]\n */\n diag (indent: string = ''): string {\n return indent + this.constructor.name + ': ' + this;\n }\n\n declare (options: FormatOptions & { declaration?: [string, string, string] } = {}): string {\n // TODO also make declaration syntax configurable\n const { declaration : d = ['', '=', '; '], ...format } = options;\n\n const res = toposort({ list: [this], env: format.inventory });\n\n return res.list.map(s => {\n if (s instanceof Alias)\n return d[0] + s.name + d[1] + s.impl.format({ ...format, inventory: res.env });\n if (s instanceof FreeVar)\n return d[0] + s.name + d[1];\n return s.format({ ...format, inventory: res.env });\n }).join(d[2]);\n }\n\n /**\n * Convert the expression to a JSON-serializable format.\n * Sadly the format is not yet finalized and may change in the future.\n *\n * @experimental\n * @sealed\n */\n toJSON (): string | object {\n return this.declare();\n }\n}\n\n/**\n * Application of two {@link Expr} terms.\n *\n * Never ever call `new App(fun, arg)` directly, use `fun.apply(...args)` instead.\n */\nexport class App extends Expr {\n fun: Expr;\n arg: Expr;\n\n /** If irreducible, cache it and don't try anymore */\n final?: boolean;\n\n /**\n * @param fun\n * @param arg\n */\n constructor (fun:Expr, arg:Expr) {\n super();\n\n this.arg = arg;\n this.fun = fun;\n this.size = (fun.size ?? 1) + (arg.size ?? 1);\n }\n\n _traverse_descend (options: TraverseOptions, change: TraverseCallback): TraverseValue<Expr> {\n const [fun, fAction] = unwrap(this.fun._traverse_redo(options, change));\n if (fAction === control.stop)\n return control.stop(fun ? fun.apply(this.arg) : null);\n\n const [arg, aAction] = unwrap(this.arg._traverse_redo(options, change));\n\n const final:Expr|null = (fun || arg) ? (fun ?? this.fun).apply(arg ?? this.arg) : null;\n if (aAction === control.stop)\n return control.stop(final);\n return final;\n }\n\n any (predicate: (e: Expr) => boolean): boolean {\n return predicate(this) || this.fun.any(predicate) || this.arg.any(predicate);\n }\n\n _fold<T> (initial:T, combine: (acc: T, expr: Expr) => TraverseValue<T>): TraverseValue<T> {\n const [value = initial, action = 'descend'] = unwrap(combine(initial, this));\n if (action === control.prune)\n return value;\n if (action === control.stop)\n return control.stop(value);\n const [fValue = value, fAction = 'descend'] = unwrap(this.fun._fold(value, combine));\n if (fAction === control.stop)\n return control.stop(fValue);\n const [aValue = fValue, aAction = 'descend'] = unwrap(this.arg._fold(fValue, combine));\n if (aAction === control.stop)\n return control.stop(aValue);\n return aValue;\n }\n\n subst (search: Expr, replace:Expr): Expr | null {\n const fun = this.fun.subst(search, replace);\n const arg = this.arg.subst(search, replace);\n\n return (fun || arg) ? (fun ?? this.fun).apply(arg ?? this.arg) : null;\n }\n\n /**\n * @return {{expr: Expr, steps: number}}\n */\n\n step (): Step {\n // normal reduction order: first try root, then at most 1 step\n if (!this.final) {\n // try to apply rewriting rules, if applicable, at first\n const partial = this.fun.invoke(this.arg);\n if (partial instanceof Expr)\n return { expr: partial, steps: 1, changed: true };\n else if (typeof partial === 'function')\n this.invoke = partial; // cache for next time\n\n // descend into the leftmost term\n const fun = this.fun.step();\n if (fun.changed)\n return { expr: fun.expr.apply(this.arg), steps: fun.steps, changed: true };\n\n // descend into arg\n const arg = this.arg.step();\n if (arg.changed)\n return { expr: this.fun.apply(arg.expr), steps: arg.steps, changed: true };\n\n // mark as irreducible\n this.final = true; // mark as irreducible at root\n }\n\n return { expr: this, steps: 0, changed: false };\n }\n\n invoke (arg:Expr): Invocation | null {\n // propagate invocation towards the root term,\n // caching partial applications as we go\n const partial = this.fun.invoke(this.arg);\n if (partial instanceof Expr)\n return partial.apply(arg);\n else if (typeof partial === 'function') {\n this.invoke = partial;\n return partial(arg);\n } else {\n // invoke = null => we're uncomputable, cache for next time\n this.invoke = (arg: Expr) => null;\n return null;\n }\n }\n\n unroll (): Expr[] {\n return [...this.fun.unroll(), this.arg];\n }\n\n diff (other: Expr, swap = false) {\n if (!(other instanceof App))\n return super.diff(other, swap);\n\n const fun = this.fun.diff(other.fun, swap);\n if (fun)\n return fun + '(...)';\n const arg = this.arg.diff(other.arg, swap);\n if (arg)\n return this.fun + '(' + arg + ')';\n return null;\n }\n\n _braced (isFirst?: boolean): boolean {\n return !isFirst;\n }\n\n formatImpl (options:RefinedFormatOptions, nargs: number): string {\n const fun = this.fun.formatImpl(options, nargs + 1);\n const arg = this.arg.formatImpl(options, 0);\n const wrap = nargs ? ['', ''] : options.around!;\n // TODO ignore terse for now\n if (options.terse && !this.arg._braced(false))\n return wrap[0] + fun + (this.fun._unspaced(this.arg) ? '' : options.space) + arg + wrap[1];\n else\n return wrap[0] + fun + options.brackets![0] + arg + options.brackets![1] + wrap[1];\n }\n\n diag (indent: string = ''): string {\n return indent + 'App:\\n' + this.unroll().map(e => e.diag(indent + ' ')).join('\\n');\n }\n\n _unspaced (arg: Expr): boolean {\n return this.arg._braced(false) ? true : this.arg._unspaced(arg);\n }\n}\n\n/**\n * An abstract class representing a named term.\n *\n * @param {String} name\n */\nexport class Named extends Expr {\n name: string;\n fancyName?: string;\n\n constructor (name: string) {\n super();\n if (typeof name !== 'string' || name.length === 0)\n throw new Error('Attempt to create a named term with improper name');\n this.name = name;\n }\n\n _unspaced (arg: Expr): boolean {\n return !!(\n (arg instanceof Named) && (\n (this.name.match(/^[A-Z+]$/) && arg.name.match(/^[a-z+]/i))\n || (this.name.match(/^[a-z+]/i) && arg.name.match(/^[A-Z+]$/))\n )\n );\n }\n\n formatImpl (options: RefinedFormatOptions, nargs: number): string {\n // NOTE fancyName is not yet official and may change name or meaning\n const name = options.html ? this.fancyName ?? this.name : this.name;\n return this.arity !== undefined && this.arity > 0 && this.arity <= nargs\n ? options.redex![0] + name + options.redex![1]\n : name;\n }\n}\n\n/** A synthetic key for debugging/distinguishing variables. */\nlet freeId = 0;\n\n/**\n * A named variable.\n *\n * Given the functional nature of combinatory logic, variables are treated\n * as functions that we don't know how to evaluate just yet.\n *\n * Two variables are considered the same iff they have the same `name` and `scope` properties.\n * If `scope` is not given, the variable is only equal to itself.\n *\n * By convention, FreeVar.global is a constant denoting a global unbound variable.\n */\nexport class FreeVar extends Named {\n /**\n * @param name - name of the variable\n * @param scope - an object representing where the variable belongs to.\n */\n scope?: object;\n id: number;\n constructor (name:string, scope?: object ) {\n super(name);\n this.id = ++freeId;\n // TODO replace with null and scope??[notmatching] everywhere, but later\n this.scope = scope === undefined ? this : scope;\n }\n\n diff (other:Expr, swap = false): string | null {\n if (!(other instanceof FreeVar))\n return super.diff(other, swap);\n if (this.name === other.name && this.scope === other.scope)\n return null;\n const lhs = this.name + '[' + this.id + ']';\n const rhs = other.name + '[' + other.id + ']';\n return swap\n ? '[' + rhs + ' != ' + lhs + ']'\n : '[' + lhs + ' != ' + rhs + ']';\n }\n\n subst (search: Expr, replace: Expr): Expr | null {\n if (search instanceof FreeVar && search.name === this.name && search.scope === this.scope)\n return replace;\n return null;\n }\n\n formatImpl (options: RefinedFormatOptions, nargs: number): string {\n const name = options.html ? this.fancyName ?? this.name : this.name;\n return options.var![0] + name + options.var![1];\n }\n\n diag (indent: string = ''): string {\n // include variable id for disambiguation\n return `${indent}FreeVar: ${this.name}[${this.id}]`;\n }\n\n static global = ['global'];\n}\n\n/**\n * A named term with a known rewriting rule.\n * 'impl' is a function with signature Expr => Expr => ... => Expr\n * (see typedef Partial).\n * This is how S, K, I, and company are implemented.\n *\n * Note that as of current something like a=>b=>b(a) is not possible,\n * use full form instead: a=>b=>b.apply(a).\n *\n * @example new Native('K', x => y => x); // constant\n * @example new Native('Y', function(f) { return f.apply(this.apply(f)); }); // self-application\n */\nexport class Native extends Named {\n /**\n * @param name Name of the term\n * @param impl A javascript implementation of the term's rewriting rule.\n * @param opt Optional settings.\n */\n constructor (name: string, impl: (e: Expr) => Invocation,\n opt: {note?: string, arity?: number, canonize?: boolean } = {}) {\n super(name);\n // setup essentials\n this.invoke = impl;\n\n this.annotate({ canonize: true, ...opt });\n }\n}\n\n/**\n * A lambda abstraction.\n *\n * Takes an arg: {@link FreeVar} and an impl: {@link Expr}.\n * Upon evaluation, all occurrences of `arg` within `impl`\n * will be replaced by the given term.\n *\n * Note that 'arg' will be replaced by a localized placeholder,\n * so the original variable can be used elsewhere without interference.\n */\nexport class Lambda extends Expr {\n arg: FreeVar;\n impl: Expr;\n /**\n * @param {FreeVar} arg\n * @param {Expr} impl\n */\n constructor (arg: FreeVar, impl: Expr) {\n super();\n\n if (!(arg instanceof FreeVar))\n throw new Error('Lambda argument must be a FreeVar');\n\n // localize argument variable and bind it to oneself\n const local = new FreeVar(arg.name, this);\n this.arg = local;\n this.impl = impl.subst(arg, local) ?? impl;\n this.arity = 1;\n this.size = (impl.size ?? 1) + 1;\n }\n\n invoke (arg: Expr): Expr {\n return this.impl.subst(this.arg, arg) ?? this.impl;\n }\n\n _traverse_descend (options: TraverseOptions, change: TraverseCallback): TraverseValue<Expr> {\n // alas no proper shielding of self.arg is possible\n const [impl, iAction] = unwrap(this.impl._traverse_redo(options, change));\n\n const final = impl ? new Lambda(this.arg, impl) : null;\n\n return iAction === control.stop ? control.stop(final) : final;\n }\n\n any (predicate: (e: Expr) => boolean): boolean {\n return predicate(this) || this.impl.any(predicate);\n }\n\n _fold<T> (initial:T, combine: (acc: T, expr: Expr) => TraverseValue<T>): TraverseValue<T> {\n const [value = initial, action = 'descend'] = unwrap(combine(initial, this));\n if (action === control.prune)\n return value;\n if (action === control.stop)\n return control.stop(value);\n const [iValue, iAction] = unwrap(this.impl._fold(value, combine));\n if (iAction === control.stop)\n return control.stop(iValue);\n return iValue ?? value;\n }\n\n subst (search: Expr, replace:Expr): Expr | null {\n if (search === this.arg)\n return null;\n const change = this.impl.subst(search, replace);\n return change ? new Lambda(this.arg, change) : null;\n }\n\n diff (other: Expr, swap = false): string | null {\n if (!(other instanceof Lambda))\n return super.diff(other, swap);\n\n const t = new FreeVar('t'); // TODO better placeholder name\n\n const diff = this.invoke(t).diff(other.invoke(t), swap);\n if (diff)\n return '(t->' + diff + ')'; // parentheses required to avoid ambiguity\n return null;\n }\n\n formatImpl (options: RefinedFormatOptions, nargs: number): string {\n return (nargs > 0 ? options.brackets![0] : '')\n + options.lambda![0]\n + this.arg.formatImpl(options, 0) // TODO highlight redex if nargs > 0\n + options.lambda![1]\n + this.impl.formatImpl(options, 0) + options.lambda![2]\n + (nargs > 0 ? options.brackets![1] : '');\n }\n\n diag (indent: string = ''): string {\n return `${indent}Lambda (${this.arg.name}[${this.arg.id}]):\\n`\n + this.impl.diag(indent + ' ');\n }\n\n _braced (isFirst: boolean): boolean {\n return true;\n }\n}\n\n/**\n * Church numeral representing non-negative integer `n`:\n * `n f x = f(f(...(f x)...))` with `f` applied `n` times.\n */\nexport class Church extends Expr {\n n: number;\n /**\n * @param {number} n\n */\n constructor (n: number) {\n n = Number.parseInt(String(n));\n if (!(n >= 0))\n throw new Error('Church number must be a non-negative integer');\n super();\n this.invoke = x => y => {\n let expr = y;\n for (let i = n; i-- > 0; )\n expr = x.apply(expr);\n return expr;\n };\n\n /** @type {number} */\n this.n = n;\n this.arity = 2;\n }\n\n diff (other:Expr, swap = false): string | null {\n if (!(other instanceof Church))\n return super.diff(other, swap);\n if (this.n === other.n)\n return null;\n return swap\n ? '[' + other.n + ' != ' + this.n + ']'\n : '[' + this.n + ' != ' + other.n + ']';\n }\n\n _unspaced (arg: Expr): boolean {\n return false;\n }\n\n formatImpl (options: RefinedFormatOptions, nargs: number): string {\n return nargs >= 2\n ? options.redex![0] + this.n + options.redex![1]\n : this.n + '';\n }\n}\n\nfunction waitn (n: number): (e : Expr) => (arg: Expr) => Invocation {\n return n <= 1\n ? (e: Expr) => (arg: Expr) => e.apply(arg)\n : (e: Expr) => (arg: Expr) => waitn(n - 1)(e.apply(arg));\n}\n\n/**\n * A named alias for an existing expression.\n *\n * Aliasing allows declaring new terms without a native implementation.\n * This is what happens when one writes `B = S(KS)K` in the interpreter.\n *\n * Aliases are transparent in terms of `equals` and `expect`;\n * for that reason, Alias.diag() in not adding to the indentation.\n *\n * Aliases have an `inline` property. Tf true, the alias will be replaced with its implementation\n * everywhere, unless specifically told otherwise e.g. by { inventory: { ... } } option of format().\n *\n * Upon creation, the aliases arity is calculated (unless `canonize` is false).\n *\n * Upon evaluation, the alias will be replaced with its implementation,\n * _unless_ it's not inline and has positive arity,\n * in which case it will wait for the required number of arguments before such replacement.\n */\nexport class Alias extends Named {\n /**\n * @param name\n * @param impl\n * @param options\n */\n impl: Expr;\n inline?: boolean;\n\n constructor (\n name: string,\n impl: Expr,\n options : {canonize?: boolean, max?: number, maxArgs?: number, note?: string, inline?: boolean, arity?: number} = {}\n ) {\n super(name);\n if (!(impl instanceof Expr))\n throw new Error('Attempt to create an alias for a non-expression: ' + impl);\n this.impl = impl;\n\n this.annotate(options);\n this.invoke = waitn(options.inline ? 0 : this.arity ?? 0)(impl);\n this.size = impl.size;\n if (options.inline)\n this.inline = true;\n }\n\n /**\n * Make the alias inline, i.e. replace it with its implementation everywhere.\n *\n * Replaces the old `outdated` attribute.\n * Used by the parser when a term definition is removed or updated.\n *\n *\n *\n * May change in future versions, use with caution.\n *\n * @experimental\n * @returns {this}\n */\n makeInline (): this {\n this.invoke = waitn(0)(this.impl);\n this.inline = true;\n return this;\n }\n\n /**\n * @property {boolean} [proper] - whether the alias is a proper combinator (i.e. contains no free variables or constants)\n * @property {number} [arity] - the number of arguments the alias waits for before expanding\n * @property {Expr} [canonical] - equivalent lambda term.\n */\n\n _traverse_descend (options: TraverseOptions, change: TraverseCallback): TraverseValue<Expr> {\n return this.impl._traverse_redo(options, change);\n }\n\n any (predicate: (e: Expr) => boolean): boolean {\n return predicate(this) || this.impl.any(predicate);\n }\n\n _fold<T> (initial:T, combine: (acc: T, expr: Expr) => TraverseValue<T>): TraverseValue<T> {\n const [value = initial, action] = unwrap(combine(initial, this));\n if (action === control.prune)\n return value;\n if (action === control.stop)\n return control.stop(value);\n const [iValue, iAction] = unwrap(this.impl._fold(value, combine));\n if (iAction === control.stop)\n return control.stop(iValue);\n return iValue ?? value;\n }\n\n subst (search: Expr, replace: Expr): Expr | null {\n if (this === search)\n return replace;\n return this.impl.subst(search, replace);\n }\n\n // DO NOT REMOVE TYPE or tsc chokes with\n // TS2527: The inferred type of 'Alias' references an inaccessible 'this' type.\n /**\n * @return {{expr: Expr, steps: number, changed: boolean}}\n */\n step (): Step {\n // arity known = waiting for args to expand\n if ((this.arity ?? 0) > 0)\n return { expr: this, steps: 0, changed: false };\n // expanding is a change but it takes 0 steps\n return { expr: this.impl, steps: 0, changed: true };\n }\n\n diff (other: Expr, swap = false): string | null {\n if (this === other)\n return null;\n return other.diff(this.impl, !swap);\n }\n\n _braced (isFirst: boolean): boolean {\n return this.inline ? this.impl._braced(isFirst) : false;\n }\n\n formatImpl (options: RefinedFormatOptions, nargs: number): string {\n const inline = options.inventory\n ? options.inventory[this.name] !== this\n : this.inline;\n return inline ? this.impl.formatImpl(options, nargs) : super.formatImpl(options, nargs);\n }\n\n diag (indent: string = ''): string {\n // no indent increase so that a diff between diags is consistent with how `equals` works.\n return `${indent}Alias (${this.name}): \\\\\\n` + this.impl.diag(indent);\n }\n}\n\n// ----- Expr* classes end here -----\n\n// declare native combinators\n\n// redeclare `native` type with `Native` class\n\nfunction addNative (name: string, impl: (arg: Expr) => Invocation, opt : {note?: string} = {}): void {\n native[name] = new Native(name, impl, opt);\n}\naddNative('I', x => x);\naddNative('K', x => _y => x);\naddNative('S', x => y => z => x.apply(z, y.apply(z)));\naddNative('B', x => y => z => x.apply(y.apply(z)));\naddNative('C', x => y => z => x.apply(z).apply(y));\naddNative('W', x => y => x.apply(y).apply(y));\n\naddNative(\n '+',\n n => n instanceof Church\n ? new Church(n.n + 1)\n : f => x => f.apply(n.apply(f, x)),\n {\n note: 'Increase a Church numeral argument by 1, otherwise n => f => x => f(n f x)',\n }\n);\n\n// utility functions dependent on Expr* classes, in alphabetical order\n\nfunction firstVar (expr: Expr) {\n // yay premature optimization\n while (expr instanceof App)\n expr = expr.fun;\n return expr instanceof FreeVar;\n}\n\n/**\n * @private\n * Given a list of free variables, an expression, and some capabilities of the context,\n * return either a lambda term, or the original expression if no lambda abstraction is needed,\n * plus some metadata about the term and the context.\n *\n * Used by infer() internally.\n *\n * @param {FreeVar[]} args\n * @param {Expr} expr\n * @param {object} caps\n * @returns {TermInfo}\n */\nfunction maybeLambda (args: FreeVar[], expr: Expr, caps : {discard?: boolean, duplicate?: boolean, steps: number}): TermInfo {\n const count = new Array(args.length).fill(0);\n let proper = true;\n expr.traverse(e => {\n if (e instanceof FreeVar) {\n const index = args.findIndex(a => a.name === e.name);\n if (index >= 0) {\n count[index]++;\n return;\n }\n }\n if (!(e instanceof App))\n proper = false;\n });\n\n const skip : Set<number> = new Set();\n const dup : Set<number> = new Set();\n for (let i = 0; i < args.length; i++) {\n if (count[i] === 0)\n skip.add(i);\n else if (count[i] > 1)\n dup.add(i);\n }\n\n for (let i = args.length; i-- > 0; )\n expr = new Lambda(args[i], expr);\n\n return {\n normal: true,\n steps: caps.steps,\n expr,\n arity: args.length,\n ...(skip.size ? { skip } : {}),\n ...(dup.size ? { dup } : {}),\n duplicate: !!dup.size || caps.duplicate || false,\n discard: !!skip.size || caps.discard || false,\n proper,\n };\n}\n\nfunction nthvar (n: number): FreeVar {\n return new FreeVar('abcdefgh'[n] ?? 'x' + n);\n}\n\n/**\n * Topologically sort a list of terms, extending it with any missing dependency terms,\n * if necessary. The output list is guaranteed to contain at least the input terms.\n *\n * @param options\n * @param [options.list] - a single expression or a list of expressions to sort.\n * @param [options.env] - a set of terms assumed to be known (and thus not required in the output list).\n * @param [options.allow] - a set of terms that are allowed in the returned list (aside from the input list).\n *\n * @example\n * const expr = ski.parse(src);\n * toposort([expr], ski.getTerms()); // returns all terms appearing in Expr in correct order\n */\n// TODO the docs suck. You know it and I know it. Fix when have time.\nexport function toposort (options: {list?: Expr|Expr[], env?: Record<string, Named>, allow?: Record<string, Named>}): ToposortResult {\n if (typeof options !== 'object' || options === null || Array.isArray(options) || options instanceof Expr)\n throw new Error('positional arguments to toposort are deprecated, use { list: ..., env: ... } instead');\n\n // TODO enforce both `env` and `allow` to have foo[key].name === key\n\n const allow = options.allow ? { ...options.allow } : null;\n const env = { ...options.env ?? {} };\n const list = options.list instanceof Expr\n ? [options.list]\n : options.list ?? []; // TODO imply default from allow\n\n if (allow) {\n // terms from `list` are automatically allowed and trump existing values\n for (const term of list) {\n if (term instanceof Named)\n allow[term.name] = term;\n }\n }\n\n // env masks terms from being in output, but the terms that were in the list\n // to begin with should stay in the list.\n for (const term of list) {\n if (term instanceof Named && env[term.name] === term)\n delete env[term.name];\n }\n\n const out: Expr[] = [];\n // assume all terms in env seen, too\n const seen: Set<Expr> = new Set(Object.values(env));\n const rec = (term: Expr) => {\n if (seen.has(term))\n return;\n term.fold(undefined, (_:undefined, e:Expr):TraverseValue<undefined> => {\n if (!(e instanceof Named))\n return;\n // not allowed => fall through\n if (allow && allow[e.name] !== e)\n return;\n\n // inlined alias => skip, unless explicitly allowed\n if (!allow && e instanceof Alias && e.inline)\n return;\n\n // recurse. values in `env` will be auto-skipped because they're \"seen\"\n if (e !== term) {\n rec(e);\n return control.prune();\n }\n });\n out.push(term);\n seen.add(term); // TODO unify with env\n if (term instanceof Named)\n env[term.name] ||= term;\n };\n\n for (const term of list)\n rec(term);\n\n return {\n list: out,\n env,\n };\n}\n\nexport const classes = { Expr, App, Named, FreeVar, Native, Lambda, Church, Alias };\n", "/**\n * Combinatory logic simulator\n */\n'use strict';\n\nimport { Tokenizer, restrict } from './internal';\nimport { Expr, FreeVar, Lambda, Church, Alias, Native, Named, native, Invocation, RefinedFormatOptions, toposort } from './expr';\n\nclass Empty extends Expr {\n apply (...args: Expr[]):Expr {\n return args.length > 0 ? args.shift()!.apply(...args) : this;\n }\n\n postParse (): Expr {\n throw new Error('Attempt to use empty expression () as a term');\n }\n\n formatImpl (options: RefinedFormatOptions, nargs: number): string {\n return '()';\n }\n}\n\nclass PartialLambda extends Empty {\n impl: Expr;\n terms: FreeVar[];\n // TODO mutable! rewrite ro when have time\n constructor (term: Expr, _known = {}) {\n super();\n this.impl = new Empty();\n if (term instanceof FreeVar)\n this.terms = [term];\n else if (term instanceof PartialLambda) {\n if (!(term.impl instanceof FreeVar))\n throw new Error('Expected FreeVar->...->FreeVar->Expr');\n this.terms = [...term.terms, term.impl];\n } else\n throw new Error('Expected FreeVar or PartialLambda');\n }\n\n apply (term: Expr, ...tail:Expr[]) {\n if (term === null || tail.length !== 0 )\n throw new Error('bad syntax in partial lambda expr');\n this.impl = this.impl.apply(term);\n return this;\n }\n\n postParse (): Expr {\n let expr = this.impl;\n for (let i = this.terms.length; i-- > 0; )\n expr = new Lambda(this.terms[i], expr);\n return expr;\n }\n\n // uncomment if debugging with prints\n /* toString () {\n return this.terms.join('->') + '->' + (this.impl ?? '???');\n } */\n}\n\nfunction postParse (expr: Expr): Expr {\n return (expr as Empty).postParse ? (expr as Empty).postParse() : expr;\n}\n\nconst combChars = new Tokenizer(\n '[()]', '[A-Z]', '[a-z_][a-z_0-9]*', '\\\\b[0-9]+\\\\b', '->', '\\\\+'\n);\n\n// TODO names too similar, rename one\nexport type ParserOptions = {\n allow?: string,\n numbers?: boolean,\n lambdas?: boolean,\n terms?: { [key: string]: Expr | string } | string[],\n annotate?: boolean,\n addContext?: boolean,\n};\n\nexport type ParseOptions = {\n env?: { [key: string]: Expr },\n scope?: object,\n numbers?: boolean,\n lambdas?: boolean,\n allow?: string,\n canonize?: boolean,\n};\n\nexport type AddOptions = {\n note?: string,\n canonize?: boolean,\n fancy?: string,\n arity?: number,\n};\n\nexport class Parser {\n /**\n *\n * @param {{\n * allow?: string,\n * numbers?: boolean,\n * lambdas?: boolean,\n * terms?: { [key: string]: Expr|string} | string[],\n * annotate?: boolean,\n * }} [options]\n */\n\n addContext: boolean;\n annotate: boolean;\n known: Record<string, Named>;\n allow: Set<string>;\n\n hasNumbers: boolean;\n hasLambdas: boolean;\n\n constructor (options: ParserOptions = {}) {\n this.annotate = !!options.annotate;\n this.addContext = !!options.addContext;\n this.known = { ...native };\n this.hasNumbers = true;\n this.hasLambdas = true;\n /** @type {Set<string>} */\n this.allow = new Set(Object.keys(this.known));\n\n // Import terms, if any. Omit native ones\n if (Array.isArray(options.terms))\n this.bulkAdd(options.terms);\n else if (options.terms) {\n for (const name in options.terms) {\n // Native terms already handled by allow\n if (typeof options.terms[name] !== 'string' || !options.terms[name].match(/^Native:/))\n this.add(name, options.terms[name]);\n }\n }\n\n // Finally, impose restrictions\n // We must do it after recreating terms, or else terms reliant on forbidden terms will fail\n this.hasNumbers = options.numbers ?? true;\n this.hasLambdas = options.lambdas ?? true;\n if (options.allow)\n this.restrict(options.allow);\n }\n\n /**\n * Declare a new term\n * If the first argument is an Alias, it is added as is.\n * Otherwise, a new Alias or Native term (depending on impl type) is created.\n * If note is not provided and this.annotate is true, an automatic note is generated.\n *\n * If impl is a function, it should have signature (Expr) => ... => Expr\n * (see typedef Partial at top of expr.js)\n *\n * @example ski.add('T', 'S(K(SI))K', 'swap combinator')\n * @example ski.add( ski.parse('T = S(K(SI))K') ) // ditto but one-arg form\n * @example ski.add('T', x => y => y.apply(x), 'swap combinator') // heavy artillery\n * @example ski.add('Y', function (f) { return f.apply(this.apply(f)); }, 'Y combinator')\n *\n * @param {Alias|String} term\n * @param {String|Expr|function(Expr):Partial} [impl]\n * @param {object|string} [options]\n * @param {string} [options.note] - optional annotation for the term, default is auto-generated if this.annotate is true\n * @param {boolean} [options.canonize] - whether to canonize the term's implementation, default is this.annotate\n * @param {boolean} [options.fancy] - alternative HTML-friendly name for the term\n * @param {number} [options.arity] - custom arity for the term, default is inferred from the implementation\n * @return {SKI} chainable\n */\n add (term: Alias | string, impl?: Expr | string | ((arg: Expr) => Invocation), options?: AddOptions | string): this {\n const named = this._named(term, impl);\n\n // backward compat\n const opts: AddOptions = typeof options === 'string' ? { note: options, canonize: false } : (options ?? {});\n named.annotate({ canonize: this.annotate, ...opts });\n\n const old = this.known[named.name];\n if (old instanceof Alias)\n old.makeInline();\n\n this.known[named.name] = named;\n this.allow.add(named.name);\n\n return this;\n }\n\n /**\n * Internal helper for add() that creates an Alias or Native term from the given arguments.\n * @param {Alias|string} term\n * @param {string|Expr|function(Expr):Partial} impl\n * @returns {Native|Alias}\n * @private\n */\n _named (term: Alias | string, impl?: Expr | string | ((arg: Expr) => Invocation)): Native | Alias {\n if (term instanceof Named)\n return maybeAlias(term.name, term);\n if (typeof term !== 'string')\n throw new Error('add(): term must be an Alias or a string');\n if (impl === undefined)\n throw new Error('add(): impl must be provided when term is a string');\n if (typeof impl === 'string')\n return maybeAlias(term, this.parse(impl));\n if (impl instanceof Expr)\n return maybeAlias(term, impl);\n if (typeof impl === 'function')\n return new Native(term, impl);\n // idk what this is\n throw new Error('add(): impl must be an Expr, a string, or a function with a signature Expr => ... => Expr');\n }\n\n /**\n * Declare a new term if it is not known, otherwise just allow it.\n * Currently only used by quests.\n * Use with caution, this function may change its signature, behavior, or even be removed in the future.\n *\n * @experimental\n * @param {string|Alias} name\n * @param {string|Expr|function(Expr):Partial} impl\n * @returns {SKI}\n */\n maybeAdd (name: string, impl: Expr | string | ((arg: Expr) => Invocation)): this {\n if (this.known[name])\n this.allow.add(name);\n else\n this.add(name, impl);\n return this;\n }\n\n /**\n * Declare and remove multiple terms at once\n * term=impl adds term\n * term= removes term\n * @param {string[]} list\n * @return {SKI} chainable\n */\n bulkAdd (list: string[]): this {\n for (const item of list) {\n const m = item.match(/^([A-Z]|[a-z][a-z_0-9]*)\\s*=\\s*(.*)$/s);\n // TODO check all declarations before applying any (but we might need earlier terms for parsing later ones)\n if (!m)\n throw new Error('bulkAdd: invalid declaration: ' + item);\n if (m[2] === '')\n this.remove(m[1]);\n else\n this.add(m[1], this.parse(m[2]));\n }\n\n return this;\n }\n\n /**\n * Restrict the interpreter to given terms. Terms prepended with '+' will be added\n * and terms preceeded with '-' will be removed.\n * @example ski.restrict('SK') // use the basis\n * @example ski.restrict('+I') // allow I now\n * @example ski.restrict('-SKI +BCKW' ); // switch basis\n * @example ski.restrict('-foo -bar'); // forbid some user functions\n * @param {string} spec\n * @return {SKI} chainable\n */\n restrict (spec: string): this {\n this.allow = restrict(this.allow, spec);\n return this;\n }\n\n /**\n *\n * @param {string} spec\n * @return {string}\n */\n showRestrict (spec = '+') {\n const out = [];\n let prevShort: boolean = true;\n for (const term of [...restrict(this.allow, spec)].sort()) {\n const nextShort = !!term.match(/^[A-Z]$/);\n if (out.length && !(prevShort && nextShort))\n out.push(' ');\n out.push(term);\n prevShort = nextShort;\n }\n return out.join('');\n }\n\n /**\n *\n * @param {String} name\n * @return {SKI}\n */\n remove (name: string): this {\n const old = this.known[name];\n if (old instanceof Alias)\n old.makeInline();\n delete this.known[name];\n this.allow.delete(name);\n return this;\n }\n\n /**\n *\n * @return {{[key:string]: Native|Alias}}\n */\n getTerms (): Record<string, Named> {\n const out: Record<string, Named> = {};\n for (const name of Object.keys(this.known)) {\n if (this.allow.has(name))\n out[name] = this.known[name];\n }\n return out;\n }\n\n /**\n * Export term declarations for use in bulkAdd().\n * Currently only Alias terms are serialized.\n * @returns {string[]}\n */\n declare (): string[] {\n // TODO accept argument to declare specific terms only\n const env: { [key: string]: Alias } = {};\n for (const [name, term] of Object.entries(this.getTerms())) {\n if (term instanceof Alias)\n env[name] = term;\n }\n\n // avert conflicts if native terms were redefined:\n // create a temporary alias for each native term that was redefined;\n // replace usage of redefined term in subexpressions;\n // finally, remove the temporary aliases from the output\n const needDetour: { [key: string]: Alias } = {};\n let i = 1;\n for (const name in native) {\n if (!(env[name] instanceof Alias))\n continue;\n while ('tmp' + i in env)\n i++;\n const temp = new Alias('tmp' + i, env[name]);\n needDetour[temp.name] = env[name];\n env[temp.name] = temp;\n delete env[name];\n }\n\n // console.log(env);\n\n const list = toposort({ list: Object.values(env), allow: {} }).list;\n\n const detour = new Map<Alias, Alias>();\n if (Object.keys(needDetour).length) {\n // replace aliases with their detoured counterparts.\n // we have to go recursive, otherwise an unrelated alias may be expanded to its impl\n // and name infos will be erased\n const rework = (expr: Expr): Expr => {\n return expr.traverse((e: Expr) => {\n if (!(e instanceof Alias))\n return null; // continue\n const newAlias = detour.get(e);\n if (newAlias)\n return newAlias;\n return new Alias(e.name, rework(e.impl));\n }) ?? expr;\n };\n\n for (let j = 0; j < list.length; j++) {\n // upon processing list[j], only terms declared before it may be detoured\n list[j] = rework(list[j]);\n detour.set(needDetour[(list[j] as Alias).name], list[j] as Alias);\n env[(list[j] as Alias).name] = list[j] as Alias;\n // console.log(`list[${j}] = ${(list[j] as Alias).name}=${(list[j] as Alias).impl};`);\n }\n // console.log('detour:', detour);\n }\n\n // console.log(res);\n const out = list.map(e => needDetour[(e as Alias).name]\n ? (e as Alias).name + '=' + needDetour[(e as Alias).name].name + '=' + (e as Alias).impl.format({ inventory: env })\n : (e as Alias).name + '=' + (e as Alias).impl.format({ inventory: env })\n );\n\n for (const [name, temp] of detour)\n out.push((name as Alias).name + '=' + temp, temp + '=');\n\n return out;\n }\n\n /**\n * @param {string} source\n * @param {Object} [options]\n * @param [options.env] - additional\n * @param [options.scope] - assign this scope to unknown free variables\n * @param {boolean} [options.numbers] - whether numbers are allowed\n * @param {boolean} [options.lambdas] - whether lambdas are allowed\n * @param {string} [options.allow] - restrict known terms\n * @param [options.canonize] - whether to calculate canonical form, arity, and properties\n * of intermediate aliases\n * @return {Expr}\n */\n parse (source: string, options: ParseOptions = {}): Expr {\n if (typeof source !== 'string')\n throw new Error('parse: source must be a string, got ' + typeof source);\n\n const lines = source.replace(/\\/\\/[^\\n]*$/gm, ' ')\n .replace(/\\/\\*.*?\\*\\//gs, ' ')\n .trim()\n .split(/\\s*;[\\s;]*/).filter( s => s.match(/\\S/));\n\n const jar = { ...options.env };\n\n let expr: Expr = new Empty();\n for (const item of lines) {\n const [_, name, def] = item.match(/^([A-Z]|[a-z][a-z_0-9]*)\\s*=(.*)$/s) || [];\n\n if (name !== undefined) {\n if (jar[name] instanceof Alias && jar[name] !== options.env?.[name]) {\n // locally defined alias => demote\n jar[name].makeInline();\n }\n delete jar[name];\n }\n\n if (def === '')\n expr = new FreeVar(name, options.scope ?? FreeVar.global);\n else\n expr = this.parseLine(item, jar, options);\n\n if (name)\n jar[name] = expr;\n\n // console.log('parsed line:', item, '; got:', expr,'; jar now: ', jar);\n }\n\n if (this.addContext) {\n // create a transparent alias to avoid mutating the original term\n if (expr instanceof Named)\n expr = new Alias(expr.name, expr, { inline: true });\n expr.context = {\n env: { ...this.getTerms(), ...jar }, // also contains pre-parsed terms\n scope: options.scope,\n src: source,\n parser: this,\n };\n }\n return expr;\n }\n\n /**\n * Parse a single line of source code, without splitting it into declarations.\n * Internal, always use parse() instead.\n * @template T\n * @param {String} source S(KI)I\n * @param {{[keys: string]: Expr}} env\n * @param {Object} [options]\n * @param {{[keys: string]: Expr}} [options.env] - unused, see 'env' argument\n * @param {T} [options.scope]\n * @param {boolean} [options.numbers]\n * @param {boolean} [options.lambdas]\n * @param {string} [options.allow]\n * @return {Expr} parsed expression\n */\n parseLine (source: string, env: { [key: string]: Expr } = {}, options: ParseOptions = {}): Expr {\n const aliased = source.match(/^\\s*([A-Z]|[a-z][a-z_0-9]*)\\s*=\\s*(.*)$/s);\n if (aliased)\n return new Alias(aliased[1], this.parseLine(aliased[2], env, options), { canonize: options.canonize });\n\n const opt = {\n numbers: options.numbers ?? this.hasNumbers,\n lambdas: options.lambdas ?? this.hasLambdas,\n allow: restrict(this.allow, options.allow),\n };\n // make sure '+' usage is in sync with numerals\n if (opt.numbers) opt.allow.add('+'); else opt.allow.delete('+');\n\n const tokens = combChars.split(source);\n\n const empty = new Empty();\n /** @type {Expr[]} */\n const stack: Expr[] = [empty];\n const context = options.scope || FreeVar.global; // default is global unbound vars\n\n // TODO each token should carry along its position in source\n for (const c of tokens) {\n // console.log(\"parseLine: found \"+c+\"; stack =\", stack.join(\", \"));\n if (c === '(')\n stack.push(empty);\n else if (c === ')') {\n if (stack.length < 2)\n throw new Error('unbalanced input: extra closing parenthesis' + source);\n const x = postParse(stack.pop()!);\n const f = stack.pop()!;\n stack.push(f.apply(x));\n } else if (c === '->') {\n if (!opt.lambdas)\n throw new Error('Lambdas not supported, allow them explicitly');\n stack.push(new PartialLambda(stack.pop()!));\n } else if (c.match(/^[0-9]+$/)) {\n if (!opt.numbers)\n throw new Error('Church numbers not supported, allow them explicitly');\n const f = stack.pop()!;\n stack.push(f.apply(new Church(Number.parseInt(c))));\n } else {\n const f = stack.pop()!;\n if (!env[c] && this.known[c] && !opt.allow.has(c)) {\n throw new Error('Term \\'' + c + '\\' is not in the restricted set '\n + [...opt.allow].sort().join(' '));\n }\n // look in temp vars first, then in known terms, then fallback to creating free var\n const x = env[c] ?? this.known[c] ?? (env[c] = new FreeVar(c, context));\n stack.push(f.apply(x));\n }\n }\n\n if (stack.length !== 1) {\n throw new Error('unbalanced input: missing '\n + (stack.length - 1) + ' closing parenthesis:' + source);\n }\n\n return postParse(stack.pop()!);\n }\n\n toJSON () {\n return {\n version: '1.1.1', // set to incremented package.json version whenever SKI serialization changes\n allow: this.showRestrict('+'),\n numbers: this.hasNumbers,\n lambdas: this.hasLambdas,\n annotate: this.annotate,\n terms: this.declare(),\n }\n }\n\n /**\n * Public static shortcuts to common functions (see also ./extras.js)\n */\n}\n\nfunction maybeAlias (name: string, impl: Expr): Named {\n // Remove unnecessary extra aliases with the same name\n while (impl instanceof Alias && impl.name === name)\n impl = impl.impl;\n if (impl instanceof Named && impl.name === name)\n return impl;\n return new Alias(name, impl, { canonize: true });\n}\n", "import { Parser } from './parser';\nimport { Expr, FreeVar, Alias, Named, control, TermInfo, App } from './expr';\n\nexport type CaseResult = {\n pass: boolean,\n reason?: string,\n steps: number,\n start: Expr,\n found: Expr,\n expected?: Expr,\n note?: string,\n args: Expr[],\n case: Case\n};\n\nexport type Capability = {\n linear?: boolean,\n affine?: boolean,\n normal?: boolean,\n proper?: boolean,\n discard?: boolean,\n duplicate?: boolean,\n arity?: number,\n};\n\nexport type TestCase =\n [string, string]\n | [{max?: number}, string, string]\n | [{caps: Capability, max?: number}, string];\n\nexport type InputSpec = {\n name: string,\n fancy?: string,\n allow?: string,\n numbers?: boolean,\n lambdas?: boolean\n};\n\nexport type SolEntry = { input: string[], result: QuestResult };\n\nexport type QuestResult = {\n pass: boolean,\n details: CaseResult[],\n expr?: Expr,\n input: Expr[]|string[],\n exception?: Error,\n steps: number,\n weight?: number\n};\n\nexport type QuestSpec = {\n input: string | InputSpec | (string | InputSpec)[],\n cases: TestCase[],\n\n // the rest is optional\n\n allow?: string,\n numbers?: boolean,\n lambdas?: boolean,\n env?: string[],\n engine?: Parser,\n engineFull?: Parser,\n\n // metadata, also any fields not listed here will go to quest.meta.???\n id?: string | number,\n name?: string,\n intro?: string | string[], // multiple strings will be concatenated with spaces\n} & Record<string, unknown>; // allow any extra fields in the spec, they will be copied to quest.meta\n\nexport type SelfCheck = { accepted?: string[][], rejected?: string[][] };\n\nexport type AddCaseOptions = {\n engine?: Parser,\n env?: { [key: string]: Expr },\n max?: number,\n note?: string,\n caps?: Capability,\n canonize?: {\n max?: number,\n maxSize?: number,\n maxArgs?: number,\n },\n};\n\n/**\n * A combinator problem with a set of test cases for the proposed solution.\n * @param {QuestSpec} options\n * @example const quest = new Quest({\n * input: 'identity',\n * cases: [\n * ['identity x', 'x'],\n * ],\n * allow: 'SK',\n * intro: 'Find a combinator that behaves like the identity function.',\n * });\n * quest.check('S K K'); // { pass: true, details: [...], ... }\n * quest.check('K S'); // { pass: false, details: [...], ... }\n * quest.check('K x'); // fail! internal variable x is not equal to free variable x,\n * // despite having the same name.\n * quest.check('I'); // fail! I not in the allowed list.\n */\nexport class Quest {\n input: (InputSpec & {placeholder: FreeVar})[];\n cases: Case[];\n\n engineFull: Parser;\n engine: Parser;\n restrict: { allow?: string, numbers?: boolean, lambdas?: boolean };\n env: { [key: string]: Expr };\n envFull: { [key: string]: Expr };\n id?: string | number;\n name?: string\n intro?: string;\n // yes allow any\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n meta?: Record<string, unknown>;\n\n constructor (options: QuestSpec) {\n const { input, cases, allow, numbers, lambdas, engine, engineFull, ...meta } = options;\n const env = options.env ?? []; // backwards compatibility\n\n //\n this.engineFull = engineFull ?? new Parser();\n this.engine = engine ?? this.engineFull;\n this.restrict = { allow, numbers: numbers ?? false, lambdas: lambdas ?? false };\n this.env = {};\n\n const jar = {};\n\n // option.env is a list of expressions.\n // we suck all free variables + all term declarations from there into this.env\n // to feed it later to every case's parser.\n for (const term of env ?? []) {\n const expr: Expr = this.engineFull.parse(term, { env: jar, scope: this });\n if (expr instanceof Alias)\n this.env[expr.name] = new Alias(expr.name, expr.impl, { canonize: false });\n // Canonized aliases won't expand with insufficient arguments,\n // causing correct solutions to fail, so alas...\n else if (expr instanceof FreeVar)\n this.env[expr.name] = expr;\n else\n throw new Error('Unsupported given variable type: ' + term);\n }\n\n this.input = [];\n for (const term of Array.isArray(input) ? input : [input])\n this.addInput(term);\n if (!this.input.length)\n throw new Error('Quest needs at least one input placeholder');\n\n this.envFull = { ...this.env, ...jar };\n for (const term of this.input) {\n if (term.name in this.envFull)\n throw new Error('input placeholder name is duplicated or clashes with env: ' + term.name);\n this.envFull[term.name] = term.placeholder;\n }\n\n // NOTE meta is a local variable, can mutate\n // TODO title/descr are old name/intro respectively, do smth about it (or forget)\n this.cases = [];\n this.name = options.name;\n this.intro = list2str(options.intro);\n this.id = options.id;\n this.meta = meta;\n\n for (const c of cases ?? [])\n (this.add as (...args: unknown[]) => void)(...c);\n }\n\n /**\n * Display allowed terms based on what engine thinks of this.env + this.restrict.allow\n * @return {string}\n */\n allowed () {\n const allow = this.restrict.allow ?? '';\n const env = Object.keys(this.env).sort();\n // In case vars are present and restrictions aren't, don't clutter the output with all the known terms\n return allow\n ? this.engine.showRestrict(allow + '+' + env.join(' '))\n : env.map( s => '+' + s).join(' ');\n }\n\n addInput (term: string | InputSpec): void {\n if (typeof term !== 'object')\n term = { name: term };\n if (typeof term.name !== 'string')\n throw new Error(\"quest 'input' field must be a string or a {name: string, ...} object\");\n\n const full = term as InputSpec & { placeholder: FreeVar };\n full.placeholder = new FreeVar(term.name);\n // TODO more checks\n this.input.push(full);\n }\n\n /**\n *\n * @param {{} | string} opt\n * @param {string} terms\n * @return {Quest}\n */\n add (opt: AddCaseOptions | string, ...terms: string[]) {\n let o: AddCaseOptions;\n if (typeof opt === 'string') {\n terms.unshift(opt);\n o = {};\n } else\n o = { ...opt };\n\n o.engine = o.engine ?? this.engineFull;\n o.env = o.env ?? this.envFull;\n\n const input = this.input.map( t => t.placeholder );\n this.cases.push(\n o.caps\n ? new PropertyCase(input, o, terms)\n : new ExprCase(input, o, terms)\n );\n return this;\n }\n\n /**\n * Statefully parse a list of strings into expressions or fancy aliases thereof.\n * @param {string[]} input\n * @return {{terms: Expr[], weight: number}}\n */\n prepare (...input: string[]) {\n if (input.length !== this.input.length)\n throw new Error('Solutions provided ' + input.length + ' terms where ' + this.input.length + ' are expected');\n\n let weight = 0;\n const prepared = [];\n const jar = { ...this.env };\n for (let i = 0; i < input.length; i++) {\n const spec = this.input[i];\n const impl = this.engine.parse(input[i], {\n env: jar,\n allow: spec.allow ?? this.restrict.allow,\n numbers: spec.numbers ?? this.restrict.numbers,\n lambdas: spec.lambdas ?? this.restrict.lambdas,\n });\n const arsenal = { ...this.engine.getTerms(), ...jar };\n weight += impl.fold(0, (a, e) => {\n if (e instanceof Named && arsenal[e.name] === e)\n return control.prune( a + 1);\n });\n const expr = impl instanceof FreeVar\n ? impl\n : new Alias(spec.fancy ?? spec.name, impl, { canonize: false });\n jar[spec.name] = expr;\n prepared.push(expr);\n }\n return {\n prepared,\n weight,\n };\n }\n\n /**\n *\n * @param input\n * @return {QuestResult}\n */\n check (...input: string[]): QuestResult {\n try {\n const { prepared, weight } = this.prepare(...input);\n const details = this.cases.map( c => c.check(...prepared) ) as unknown as CaseResult[];\n const pass = details.reduce((acc, val) => acc && val.pass, true);\n const steps = details.reduce((acc, val) => acc + val.steps, 0);\n return {\n expr: prepared[0],\n input: prepared,\n pass,\n steps,\n details,\n weight,\n };\n } catch (e) {\n return { pass: false, details: [], exception: e as Error, steps: 0, input };\n }\n }\n\n verify (options: { solutions?: SelfCheck | { [key: string | number]: SelfCheck }, seen?: Set<string | number>, date?: boolean }) {\n const findings: { [key: string]: unknown } = this.verifyMeta(options);\n if (options.solutions) {\n const solCheck = this.verifySolutions(options.solutions);\n if (solCheck)\n findings.solutions = solCheck;\n }\n if (options.seen) {\n if (!this.id)\n findings.seen = 'No id in quest ' + (this.name ?? '(unnamed)');\n if (options.seen.has(this.id!))\n findings.seen = 'Duplicate quest id ' + this.id;\n options.seen.add(this.id!); // mutating but who cares\n }\n return Object.keys(findings).length ? findings : null;\n }\n\n /**\n * Verify that solutions that are expected to pass/fail do so.\n * @param {SelfCheck|{[key: string]: SelfCheck}} dataset\n * @return {{shouldPass: {input: string[], result: QuestResult}[], shouldFail: {input: string[], result: QuestResult}[]} | null}\n */\n verifySolutions (dataset: SelfCheck | { [key: string | number]: SelfCheck }) {\n // dataset is either a SelfCheck object or a hash of { quest_id: SelfCheck }\n if (typeof dataset === 'object' && !Array.isArray((dataset as SelfCheck).accepted) && !Array.isArray((dataset as SelfCheck).rejected)) {\n // dataset is a hash of { quest_id: SelfCheck } so extract data\n if (!this.id || !(dataset as { [key: string | number]: SelfCheck })[this.id])\n return null; // no self-check data for this quest, skip\n }\n\n const byId = this.id !== undefined ? (dataset as { [key: string | number]: SelfCheck })[this.id] : undefined;\n const { accepted = [], rejected = [] } = byId ?? (dataset as SelfCheck);\n\n const ret: { shouldPass: SolEntry[], shouldFail: SolEntry[] } = { shouldPass: [], shouldFail: [] };\n for (const input of accepted) {\n const result = this.check(...input);\n if (!result.pass)\n ret.shouldPass.push({ input, result });\n }\n for (const input of rejected) {\n const result = this.check(...input);\n if (result.pass)\n ret.shouldFail.push({ input, result });\n }\n return (ret.shouldFail.length + ret.shouldPass.length) ? ret : null; // return null if all good\n }\n\n verifyMeta (options: { date?: boolean } = {}): { [key: string]: unknown } {\n const findings: { [key: string]: unknown } = {};\n\n for (const field of ['name', 'intro']) {\n const found = checkHtml((this as unknown as { [key: string]: string })[field]);\n if (found)\n findings[field] = found;\n }\n if (options.date) {\n const date = new Date(this.meta?.created_at as string);\n if (isNaN(date.getTime()))\n findings.date = 'invalid date format: ' + this.meta?.created_at;\n else if (date.getTime() < new Date('2024-07-15').getTime() || date.getTime() > new Date().getTime())\n findings.date = 'date out of range: ' + this.meta?.created_at;\n }\n\n return findings;\n }\n\n /**\n *\n * @return {TestCase[]}\n */\n show ():Case[] {\n return [...this.cases];\n }\n\n static Group: new (options: { name?: string, intro?: string | string[], id?: string | number, content?: (Quest | QuestSpec)[] }) => { verify: (options: { seen?: Set<string | number>, date?: boolean }) => { [key: string]: unknown } };\n static Case: abstract new (input: FreeVar[], options: AddCaseOptions) => Case;\n}\n\nexport abstract class Case {\n /**\n * @param {FreeVar[]} input\n * @param {{\n * max?: number,\n * note?: string,\n * env?: {[key:string]: Expr},\n * engine: Parser\n * }} options\n */\n max: number;\n note: string;\n env: { [key: string]: Expr };\n input: FreeVar[];\n engine: Parser;\n constructor (input: FreeVar[], options: AddCaseOptions) {\n this.max = options.max ?? 1000;\n this.note = options.note!;\n this.env = { ...(options.env ?? {}) }; // note: env already contains input placeholders\n this.input = input;\n this.engine = options.engine!;\n }\n\n parse (src: string) {\n return new Subst(this.engine.parse(src, { env: this.env, scope: this }), this.input);\n }\n\n /**\n * @param input\n * @return {CaseResult}\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n abstract check ( ...input: Expr[] ): CaseResult;\n}\n\nexport class ExprCase extends Case {\n e1: Subst;\n e2: Subst;\n canonize?: {\n max?: number,\n maxSize?: number,\n maxArgs?: number,\n };\n\n /**\n * @param {FreeVar[]} input\n * @param {{\n * max?: number,\n * note?: string,\n * env?: {string: Expr},\n * canonize?: { max?: number, maxSize?: number, maxArgs?: number },\n * engine?: Parser\n * }} options\n * @param {[e1: string, e2: string]} terms\n */\n constructor (input: FreeVar[], options: AddCaseOptions, terms: string[]) {\n if (terms.length !== 2)\n throw new Error('Case accepts exactly 2 strings');\n\n super(input, options);\n\n this.canonize = options.canonize;\n [this.e1, this.e2] = terms.map( (s: string) => this.parse(s) );\n }\n\n check (...input: Expr[]): CaseResult {\n const e1 = this.e1.apply(input);\n const r1 = e1.run({ max: this.max });\n const e2 = this.e2.apply(input);\n const r2 = e2.run({ max: this.max });\n\n // TODO monads, monads everywhere\n let reason: string | null = null;\n if (!r1.final || !r2.final)\n reason = 'failed to reach normal form in ' + this.max + ' steps';\n else {\n reason = this.canonize\n ? canonize(r1.expr, this.canonize).diff(canonize(r2.expr, this.canonize))\n : r1.expr.diff(r2.expr);\n }\n\n return {\n pass: !reason,\n reason: reason ?? undefined,\n steps: r1.steps,\n start: e1,\n found: r1.expr,\n expected: r2.expr,\n note: this.note,\n args: input,\n case: this,\n };\n }\n}\n\nconst knownCaps: { [key: string]: boolean } = {\n normal: true,\n proper: true,\n discard: true,\n duplicate: true,\n linear: true,\n affine: true,\n arity: true,\n}\n\nexport class PropertyCase extends Case {\n expr: Subst;\n caps: Capability;\n isAffine?: boolean;\n // test that an expression uses all of its inputs exactly once\n constructor (input: FreeVar[], options: AddCaseOptions, terms: string[]) {\n super(input, options);\n if (terms.length > 1)\n throw new Error('PropertyCase accepts exactly 1 string');\n if (!options.caps || typeof options.caps !== 'object' || !Object.keys(options.caps).length)\n throw new Error('PropertyCase requires a caps object with at least one capability');\n const unknown = Object.keys(options.caps).filter( c => !knownCaps[c] );\n if (unknown.length)\n throw new Error('PropertyCase: don\\'t know how to test these capabilities: ' + unknown.join(', '));\n\n this.expr = this.parse(terms[0]);\n this.caps = { ...options.caps };\n\n if (this.caps.linear) {\n delete this.caps.linear;\n this.caps.duplicate = false;\n this.caps.discard = false;\n this.caps.normal = true;\n }\n\n if (this.caps.affine) {\n delete this.caps.affine;\n this.isAffine = true;\n }\n }\n\n check (...input: Expr[]): CaseResult {\n const start = this.expr.apply(input);\n const r = start.run({ max: this.max });\n const guess = r.expr.infer({ max: this.max });\n\n const reason: string[] = [];\n for (const cap in this.caps) {\n if ((guess as unknown as { [key: string]: unknown })[cap] !== (this.caps as unknown as { [key: string]: unknown })[cap])\n reason.push('expected property ' + cap + ' to be ' + (this.caps as unknown as { [key: string]: unknown })[cap] + ', found ' + (guess as unknown as { [key: string]: unknown })[cap]);\n }\n\n if (this.isAffine) {\n // const initial: MaybeTerm|undefined = undefined;\n const badGuy = start.fold<{ expr: Expr, props: TermInfo }|undefined>(\n undefined, (acc, expr) => {\n if (expr instanceof App || expr instanceof FreeVar)\n return;\n const props = expr.infer({ max: this.max });\n if (!props.expr || props.duplicate)\n return control.stop({ expr, props });\n\n // don't descend into aliases EXCEPT that input is aliases too and we definitely descend into them\n // so B=S(KS)K; B is affine (which it is) but S(KS)K alone isn't\n if (expr instanceof Alias && input.indexOf(expr) < 0)\n return control.prune(acc);\n }\n );\n if (badGuy) {\n reason.push(\n 'found unexpected subterm ' + badGuy.expr + (badGuy.props.expr\n ? ' that duplicates arguments'\n : ' without a normal form'\n )\n );\n }\n }\n\n return {\n pass: !reason.length,\n reason: reason.length ? reason.join('\\n') : undefined,\n steps: r.steps,\n start,\n found: r.expr,\n case: this,\n note: this.note,\n args: input,\n };\n }\n}\n\n/**\n * A placeholder object with exactly n free variables to be substituted later.\n * Basically a poor man's n-fold lambda.\n *\n * @remarks Internal. Do not rely on name, meaning, or structure. It's only in the docs for completeness sake.\n *\n * @experimental\n *\n * @param {Expr} expr\n * @param {FreeVar[]} env\n */\nexport class Subst {\n expr: Expr;\n // TODO rename env => args wtf?\n env: FreeVar[];\n constructor (expr: Expr, env: FreeVar[]) {\n this.expr = expr;\n this.env = env;\n }\n\n apply (list:Expr[]):Expr {\n if (list.length !== this.env.length)\n throw new Error('Subst: expected ' + this.env.length + ' terms, got ' + list.length);\n\n let expr = this.expr;\n for (let i = 0; i < this.env.length; i++)\n expr = expr.subst(this.env[i], list[i]) ?? expr;\n\n return expr;\n }\n}\n\n// corresponds to \"chapter\" in the quest page\nclass Group {\n name?: string;\n intro?: string;\n id?: string|number;\n content?: Quest[];\n\n constructor (options: { name?: string, intro?: string | string[], id?: string | number, content?: (Quest | QuestSpec)[] }) {\n this.name = options.name;\n this.intro = list2str(options.intro);\n this.id = options.id;\n\n // TODO don't die on failed quests\n if (options.content)\n this.content = options.content.map( c => c instanceof Quest ? c : new Quest(c) );\n }\n\n verify (options: { seen?: Set<string | number>, date?: boolean }): { [key: string]: unknown } {\n const findings: { [key: string]: unknown } = {};\n const id = checkId(this.id!, options.seen!);\n if (id)\n findings.id = id;\n for (const field of ['name', 'intro']) {\n const found = checkHtml((this as unknown as { [key: string]: string })[field]);\n if (found)\n findings[field] = found;\n }\n\n findings.content = this.content!.map(q => q.verify(options));\n return findings;\n }\n}\n\n/**\n * Concatenate long strings represented as arrays, or just pass along if already string or undefined.\n * @param {string|Array<string>|undefined} str\n * @returns {string|undefined}\n */\nfunction list2str (str: string|string[]|undefined):string|undefined {\n // TODO better arg validation\n if (str === undefined || typeof str === 'string')\n return str;\n return Array.isArray(str) ? str.join(' ') : '' + str;\n}\n\nfunction checkId (id:string|number, seen:Set<string|number>) {\n if (id === undefined)\n return 'missing';\n if (typeof id !== 'string' && typeof id !== 'number' )\n return 'is a ' + typeof id;\n if (seen) {\n if (seen.has(id))\n return 'duplicate id ' + id;\n seen.add(id);\n }\n // return nothing = success\n}\n\nfunction checkHtml (str: string): string | null {\n if (str === undefined)\n return 'missing';\n if (typeof str !== 'string')\n return 'not a string but ' + typeof str;\n\n // very basic check for unclosed tags, just to catch common mistakes in the quest text\n const tagStack = [];\n const tagRegex = /<\\/?([a-z]+)(?:\\s[^>]*)?>/gi;\n let match;\n while ((match = tagRegex.exec(str)) !== null) {\n const [fullTag, tagName] = match;\n if (fullTag.startsWith('</')) {\n // Closing tag\n if (tagStack.length === 0 || tagStack.pop() !== tagName)\n return (`Unmatched closing tag: </${tagName}>`);\n } else {\n // Opening tag\n tagStack.push(tagName);\n }\n }\n if (tagStack.length > 0)\n return (`Unclosed tags: ${tagStack.join(', ')}`);\n\n return null; // No issues found\n}\n\nQuest.Group = Group;\nQuest.Case = Case;\n\nfunction canonize (term: Expr, options = {}): Expr {\n return term.traverse({}, e => {\n return e.infer(options).expr;\n }) ?? term;\n}\n", "'use strict';\n\nimport { Expr, Named, FormatOptions, TermInfo, toposort } from './expr';\nimport { Quest } from './quest';\n\n/**\n * Extra utilities that do not belong in the core.\n */\n\n// --- Types ---\n\n/**\n * @experimental\n * Look for an expression that matches the predicate,\n * starting with the seed and applying the terms to one another.\n *\n * A predicate returning 0 (or nothing) means \"keep looking\",\n * a positive number stands for \"found\",\n * and a negative means \"discard this term from further applications\".\n *\n * The order of search is from shortest to longest expressions.\n *\n * @param {Expr[]} seed\n * @param {object} options\n * @param {number} [options.depth] - maximum generation to search for\n * @param {number} [options.tries] - maximum number of tries before giving up\n * @param {boolean} [options.infer] - whether to call infer(), default true.\n * @param {number} [options.maxArgs] - arguments in infer()\n * @param {number} [options.max] - step limit in infer()\n * @param {boolean} [options.noskip] - prevents skipping equivalent terms. Always true if infer is false.\n * @param {boolean} [retain] - if true. also add the whole cache to returned value\n * @param {({gen: number, total: number, probed: number, step: boolean}) => void} [options.progress]\n * @param {number} [options.progressInterval] - minimum number of tries between calls to options.progress, default 1000.\n * @param {(e: Expr, props: {}) => number?} predicate\n * @return {{expr?: Expr, total: number, probed: number, gen: number, cache?: Expr[][]}}\n */\nexport type SearchOptions = {\n depth?: number;\n tries?: number;\n infer?: boolean;\n maxArgs?: number;\n max?: number;\n noskip?: boolean;\n retain?: boolean;\n progress?: (info: { gen: number, total: number, probed: number, step: boolean }) => void;\n progressInterval?: number;\n};\nexport type SearchCallback = (e: Expr, props: TermInfo) => (number | undefined);\nexport type SearchResult = { expr?: Expr, total: number, probed: number, gen: number, cache?: Expr[][] };\n\nexport type EquivResult = {\n steps: number,\n equal: boolean,\n normal: boolean,\n canonical: [Expr | null, Expr | null],\n};\n\n// poor man's zod\nconst formatSchema: Record<string, (arg0: unknown) => string | undefined> = {\n html: x => typeof x === 'boolean' ? undefined : 'must be a boolean',\n terse: x => typeof x === 'boolean' ? undefined : 'must be a boolean',\n space: x => typeof x === 'string' ? undefined : 'must be a string',\n brackets: isStringPair,\n var: isStringPair,\n around: isStringPair,\n redex: isStringPair,\n lambda: isStringTriple,\n inventory: x => {\n if (typeof x !== 'object' || x === null || x.constructor !== Object)\n return 'must be an object, not ' + (x?.constructor?.name ?? typeof x);\n const refined = x as Record<string, unknown>;\n for (const key of Object.keys(refined)) {\n if (!(refined[key] instanceof Expr))\n return 'key ' + key + 'is not an Expr';\n }\n return undefined;\n }\n}\n\n// --- Exported functions (alphabetical) ---\n\n/**\n * Converts an unknown object into a FormatOptions, or returns an error it it is not valid.\n * A null/undefined counts as an empty options object (and is thus valid).\n */\nfunction checkFormatOptions (raw: unknown): { value: FormatOptions } | { error: Record<string, string> } {\n if (raw === null || raw === undefined)\n return { value: {} };\n\n if (typeof raw !== 'object' || Array.isArray(raw) || raw.constructor !== Object)\n return { error: { object: 'Format options must be an object, not ' + (raw?.constructor?.name ?? typeof raw) } };\n\n const rec = raw as Record<string, unknown>;\n const error: Record<string, string> = {};\n\n for (const key in rec) {\n if (formatSchema[key]) {\n const err = formatSchema[key](rec[key]);\n if (err)\n error[key] = err;\n } else\n error[key] = 'unknown option';\n }\n\n return Object.keys(error).length > 0 ? { error } : { value: rec as FormatOptions };\n}\n\n/**\n * Find out if two expressions are computationally equivalent.\n *\n * Unlike equals(), this function will attempt to normalize both expressions\n * before comparing.\n *\n * @experimental\n * @param e1\n * @param e2\n * @param options\n */\nfunction equiv (e1: Expr, e2: Expr, options = {}): EquivResult {\n let steps = 0;\n const [n1, n2] = [e1, e2].map( x => x.traverse(e => {\n const props = e.infer(options);\n steps += props.steps ?? 0;\n return props.expr;\n }));\n const normal = !!(n1 && n2);\n return {\n steps,\n normal,\n equal: normal ? n1.equals(n2) : false,\n canonical: [n1, n2],\n }\n}\n\n/**\n * Given an expression and a hash of named terms,\n * return a semicolon-separated string that declares said expression\n * unambiguously.\n *\n * @example\n * var expr = ski.parse(\"T=CI; V=BCT; V x y\");\n * SKI.extras.declare(expr, expr.context.env);\n * // 'B; C; I; T=CI; V=BC(T); x=; y=; Vx y'\n *\n */\nfunction declare (expr: Expr, env?: Record<string, Named>): string {\n return expr.declare({ inventory: env });\n}\n\n/**\n * Recursively replace all instances of Expr in a data structure with\n * respective string representation using the format() options.\n * Objects of other types and primitive values are eft as is.\n *\n * May be useful for debugging or diagnostic output.\n *\n * @experimental\n */\n// yes allow any in this function, it's pattern matched into correct classes during traverse\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction deepFormat (obj: any, options : FormatOptions = {}): any {\n if (obj instanceof Expr)\n return obj.format(options);\n // TODO for quests, use toJSON when it's ready\n if (obj instanceof Quest)\n return 'Quest(' + obj.name + ')';\n if (obj instanceof Quest.Case)\n return 'Quest.Case';\n if (Array.isArray(obj))\n return obj.map(item => deepFormat(item, options));\n if (typeof obj !== 'object' || obj === null || obj.constructor !== Object)\n return obj;\n\n // default = plain object\n const out: { [key: string]: unknown } = {};\n for (const key in obj)\n out[key] = deepFormat(obj[key], options);\n\n return out;\n}\n\n/**\n * @experimental\n * Look for an expression that matches the predicate,\n * starting with the seed and applying the terms to one another.\n */\nfunction search (seed: Expr[], options: SearchOptions, predicate: SearchCallback): SearchResult {\n const {\n depth = 16,\n infer = true,\n progressInterval = 1000,\n } = options;\n const hasSeen = infer && !options.noskip;\n\n // cache[i] = ith generation, 0 is empty\n const cache: Expr[][] = [[]];\n let total = 0;\n let probed = 0;\n const seen: {[s: string]: boolean} = {};\n\n const maybeProbe = (term: Expr) => {\n total++;\n const props = infer ? term.infer({ max: options.max, maxArgs: options.maxArgs }) : null;\n if (hasSeen && props && props.expr) {\n const key = String(props.expr);\n if (seen[key])\n return { res: -1 as number | undefined, props };\n seen[key] = true;\n }\n probed++;\n const res = predicate(term, props!);\n return { res, props };\n };\n\n // sieve through the seed\n for (const term of seed) {\n const { res = 0 } = maybeProbe(term);\n if (res > 0)\n return { expr: term, total, probed, gen: 1 };\n else if (res < 0)\n continue;\n\n cache[0].push(term);\n }\n\n let lastProgress = 0;\n\n for (let gen = 1; gen < depth; gen++) {\n if (options.progress) {\n options.progress({ gen, total, probed, step: true });\n lastProgress = total;\n }\n for (let i = 0; i < gen; i++) {\n for (const a of cache[gen - i - 1] || []) {\n for (const b of cache[i] || []) {\n if (total >= (options.tries ?? Infinity))\n return { total, probed, gen, ...(options.retain ? { cache } : {}) };\n if (options.progress && total - lastProgress >= progressInterval) {\n options.progress({ gen, total, probed, step: false });\n lastProgress = total;\n }\n const term = a.apply(b);\n const { res, props } = maybeProbe(term);\n\n if ((res ?? 0) > 0)\n return { expr: term, total, probed, gen, ...(options.retain ? { cache } : {}) };\n else if ((res ?? 0) < 0)\n continue;\n\n // if the term is not reducible, it is more likely to be a dead end, so we push it further away\n const offset = infer && props\n ? ((props.expr ? 0 : 3) + (props.dup ? 1 : 0) + (props.proper ? 0 : 1))\n : 0;\n if (!cache[gen + offset])\n cache[gen + offset] = [];\n cache[gen + offset].push(term);\n }\n }\n }\n }\n\n return { total, probed, gen: depth, ...(options.retain ? { cache } : {}) };\n}\n\n// --- Utility functions ---\n\nfunction isStringPair (x: unknown): string | undefined {\n return Array.isArray(x) && x.length === 2 && typeof x[0] === 'string' && typeof x[1] === 'string'\n ? undefined\n : 'must be a pair of strings';\n}\nfunction isStringTriple (x: unknown): string | undefined {\n return Array.isArray(x) && x.length === 3 && typeof x[0] === 'string' && typeof x[1] === 'string' && typeof x[2] === 'string'\n ? undefined\n : 'must be a triplet of strings';\n}\n\n// --- Namespace export ---\n\nexport const extras = { search, deepFormat, declare, toposort, checkFormatOptions, equiv };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["search", "arg"]
|
|
7
7
|
}
|