/* 0.26.0-alpha2 */import type { BoxedExpression } from './public';
/***
 * ### THEORY OF OPERATIONS
 *
 * A `["Function"]` expression has its own scope.
 * This scope includes the parameters and local variables.
 *
 * Some expressions with anonymous parameters (e.g. `["Add", "_", 1]`)
 * are rewritten to a `["Function"]` expression with anonymous parameters
 * (e.g. `["Function", ["Add", "_", 1], "_"]`).
 *
 * The **body** of a `["Function"]` expression may have its own scope
 * (for example if it's a `["Block"]` expression) or may not have a scope
 * at all (if it's a number, i.e. `["Function", 1]`). the function body may
 * be a number, a symbol or (more commonly) an function expression.
 *
 *
 * #### DURING BOXING (in makeLambda())
 *
 * During the boxing/canonicalization phase of a function
 * (`["Function"]` expression or operator of expression):
 *
 * 1/ If not a `["Function"]` expression, the expression is rewritten
 *    to a `["Function"]` expression with anonymous parameters
 * 2/ A new scope is created
 * 3/ The function parameters are declared in the scope
 * 4/ The function body is boxed in the context of the scope and the scope
 *    is associated with the function
 *
 *
 * #### DURING EVALUATION (executing the result of makeLambda())
 *
 * 1/ The arguments are evaluated in the current scope
 * 2/ The context is swapped to the function scope
 * 3/ The values of all the ids in this scope are reset
 * 4/ The parameters are set to the value of the arguments
 * 5/ The function body is evaluated in the context of the function scope
 * 6/ The context is swapped back to the current scope
 * 7/ The result of the function body is returned
 *
 */
/**
 * From an expression, return a predicate function, which can be used to filter.
 */
export declare function predicate(_expr: BoxedExpression): (...args: BoxedExpression[]) => boolean;
/**
 * From an expression, create an ordering function, which can be used to sort.
 */
export declare function order(_expr: BoxedExpression): (a: BoxedExpression, b: BoxedExpression) => -1 | 0 | 1;
/**
 * Given an expression, rewrite it to a canonical Function form.
 *
 * - explicit parameters (no change)
 *      ["Function", ["Add, "x", 1], "x"]
 *      -> ["Function", ["Add, "x", 1], "x"]
 *
 * - single anonymous parameters:
 *      ["Add", "_", 1]
 *      -> ["Function", ["Add", "_", 1], "_"]
 *
 * - multiple anonymous parameters:
 *      ["Add", "_1", "_2"]
 *      -> ["Function", ["Add", "_1", "_2"], "_1", "_2"]
 *
 *
 */
export declare function canonicalFunctionExpression(body: BoxedExpression, args?: BoxedExpression[]): [body: BoxedExpression, ...params: string[]];
/**
 * Apply arguments to an expression which is either
 * - a '["Function"]' expression
 * - an expression with anonymous parameters, e.g. ["Add", "_", 1]
 * - the identifier for a function, e.g. "Sin".
 */
export declare function apply(fn: BoxedExpression, args: ReadonlyArray<BoxedExpression>): BoxedExpression;
/**
 * Return a lambda function, assuming a scoped environment has been
 * created and there is a single numeric argument
 */
export declare function makeLambdaN1(expr: BoxedExpression): ((arg: number) => number) | undefined;
/**
 * Given an expression such as:
 * - ["Function", ["Add", 1, "x"], "x"]
 * - ["Function", ["Divide", "_", 2]]
 * - ["Multiply, "_", 3]
 * - ["Add, "_1", "_2"]
 * - "Sin"
 *
 * return a JS function that can be called with arguments.
 */
export declare function applicable(fn: BoxedExpression): (xs: ReadonlyArray<BoxedExpression>) => BoxedExpression | undefined;
/**
 * Use applicableN when the function is known to be a function of a single
 * variable and the argument is a number.
 *
 * Unlike "apply", applicable returns a function  that can be called
 * with an argument.
 *
 */
export declare function applicableN1(fn: BoxedExpression): (x: number) => number;
/**
 * Give a string like "f(x,y)" return, ["f", ["x", "y"]]
 */
export declare function parseFunctionSignature(s: string): [id: string, args: string[] | undefined];
