export { $ };
export function select(selector: API.Select): Select;
export function rule<Match extends API.Proposition>(source: API.DeductiveRule<Match>): DeductiveRule<Match>;
export function formula<Operator extends API.SystemOperator["operator"]>(operator: Operator): Formula<API.SystemOperator & {
    operator: Operator;
}>;
export function recur<Match extends API.Proposition = API.Proposition>(terms: API.RuleBindings<Match>): RuleRecursion<Match>;
export function from(source: API.Conjunct | API.Recur): Select | FormulaApplication | Negation | RuleApplication<any> | RuleRecursion<any>;
/**
 * @template {API.Proposition} [Match=API.Proposition]
 * @implements {API.MatchRule<Match>}
 * @implements {API.RuleApplicationSyntax<Match>}
 */
export class RuleApplication<Match extends API.Proposition = API.Proposition> implements API.MatchRule<Match>, API.RuleApplicationSyntax<Match> {
    /**
     * @template {API.Proposition} [Match=API.Proposition]
     * @param {API.MatchRule<Match>} source
     * @returns {RuleApplication<Match>}
     */
    static from<Match_1 extends API.Proposition = API.Proposition>(source: API.MatchRule<Match_1>): RuleApplication<Match_1>;
    /**
     * Creates a rule application with a given `rule` and set of `terms`.
     *
     * @template {API.Proposition} Match
     * @param {DeductiveRule<Match>} rule
     * @param {Partial<API.RuleBindings<Match>>} terms
     */
    static "new"<Match_1 extends API.Proposition>(rule: DeductiveRule<Match_1>, terms: Partial<API.RuleBindings<Match_1>>): RuleApplication<Match_1>;
    /**
     * @param {Partial<API.RuleBindings<Match>> & {}} match
     * @param {DeductiveRule<Match>} rule
     * @param {API.Cursor} references
     * @param {API.MatchFrame} bindings
     * @param {Map<API.Variable, number>} cells
     */
    constructor(match: Partial<API.RuleBindings<Match>> & {}, rule: DeductiveRule<Match>, references?: API.Cursor, bindings?: API.MatchFrame, cells?: Map<API.Variable, number>);
    match: Partial<API.RuleBindings<Match>>;
    rule: DeductiveRule<Match>;
    /**
     * Mapping between variables inside the rule and variables that they were
     * bound to via rule application. Given below example we will have mapping
     * `$.name → $.q`.
     *
     * ```js
     * {
     *    match: { name: $.q },
     *    rule: {
     *      match: { name: $.name },
     *      when: {
     *        where: [{ match: { the: "person/name", is: $.name } }]
     *      }
     *    }
     * }
     * ```
     */
    references: API.Cursor;
    /**
     * Mapping between variables inside the rule and constants that they were
     * bound to via rule application. Given below example we will have a mapping
     * `$.name → "Irakli"`.
     *
     * ```js
     * {
     *    match: { name: "Irakli", address: $.q },
     *    rule: {
     *      match: { name: $.name, $.address },
     *      when: {
     *        where: [
     *          { match: { the: "person/name", of: $.person, is: $.name } },
     *          { match: { the: "person/address", of: $.person, is: $.address } }
     *        ]
     *      }
     *    }
     * }
     * ```
     */
    bindings: API.MatchFrame;
    /**
     * Mapping between variables that were bound in the application and the
     * cost estimate for them staying unbound.
     */
    cells: Map<API.Variable<API.Scalar>, number>;
    get recurs(): null;
    /**
     * Base cost of the rule application is the base cost of the rule itself.
     */
    get cost(): number;
    /**
     * Plans the rule execution in the given scope. `RuleApplication` links rule
     * variables (`this.rule.match`) to the variables passed in an application
     * (`this.match`). However rule application itself may be nested inside some
     * rule where terms (`this.match`) gets linked in this planning phase.
     *
     * @param {API.Scope} scope
     */
    plan(scope: API.Scope): Plan.RuleApplication<Match>;
    prepare(): API.RuleApplicationPlan<Match>;
    /**
     * Runs this rule application as a query in on a given `input`.
     *
     * @param {object} input
     * @param {API.Querier} input.from
     */
    query(input: {
        from: API.Querier;
    }): API.Task<API.MatchFrame[], Error, typeof import("./task.js").SUSPEND | import("./task.js").Join | import("./task.js").Throw<Error>>;
    toDebugString(): string;
    toJSON(): {
        match: object | API.Scalar;
        rule: {
            match: object | API.Scalar;
            when: {
                [k: string]: Conjunct[];
            };
        };
    };
    negate(): Negation;
    #private;
}
/**
 * @template {API.Proposition} [Match=API.Proposition]
 * @implements {API.DeductiveRuleSyntax<Match>}
 */
export class DeductiveRule<Match extends API.Proposition = API.Proposition> implements API.DeductiveRuleSyntax<Match> {
    /**
     * @template {API.Proposition} Case
     * @param {API.DeductiveRule<Case>} source
     */
    static from<Case extends API.Proposition>(source: API.DeductiveRule<Case>): DeductiveRule<Case>;
    /**
     * @param {Match} match - Pattern to match against
     * @param {Map<API.Variable, number>} cells - Cost per variable when not bound
     * @param {number} cost - Base execution cost
     * @param {boolean} recurs
     * @param {Record<string, Join>} when - Named deductive branches that must be evaluated
     */
    constructor(match: Match, cells: Map<API.Variable, number>, cost: number, recurs: boolean, when: Record<string, Join>);
    match: Match;
    cells: Map<API.Variable<API.Scalar>, number>;
    cost: number;
    recurs: boolean;
    when: Record<string, Join>;
    /**
     * @param {API.RuleBindings<Match>} terms
     * @returns {RuleApplication<Match>}
     */
    apply(terms?: API.RuleBindings<Match>): RuleApplication<Match>;
    /**
     * @param {API.Scope} application
     */
    plan(application: API.Scope): Plan.DeductiveRule<Match>;
    toDebugString(): string;
    toJSON(): {
        match: object | API.Scalar;
        when: {
            [k: string]: Conjunct[];
        };
    };
}
/**
 * @template {API.Proposition} [Match=API.Proposition]
 * @implements {API.RuleRecursionSyntax<Match>}
 */
export class RuleRecursion<Match extends API.Proposition = API.Proposition> implements API.RuleRecursionSyntax<Match> {
    /**
     * @template {API.Proposition} [Match=API.Proposition]
     * @param {API.Recur<Match>} source
     */
    static from<Match_1 extends API.Proposition = API.Proposition>({ recur: terms }: API.Recur<Match_1>): RuleRecursion<Match_1>;
    /**
     * @param {API.RuleBindings<Match>} terms
     * @param {Map<API.Variable, number>} cells
     */
    constructor(terms: API.RuleBindings<Match>, cells: Map<API.Variable, number>);
    get recurs(): this;
    get references(): Map<any, any>;
    terms: API.RuleBindings<Match>;
    cells: Map<API.Variable<API.Scalar>, number>;
    get recur(): API.RuleBindings<Match>;
    get cost(): number;
    /**
     * @param {API.Scope} scope
     */
    plan(scope: API.Scope): this;
    toJSON(): {
        recur: API.RuleBindings<Match>;
    };
    toDebugString(): string;
    /**
     * Instead of direct recursion, we collect bindings to be processed later
     * in a breadth-first fixed-point iteration.
     *
     * @param {API.EvaluationContext} context
     */
    evaluate({ self, selection, recur }: API.EvaluationContext): Generator<never, never[], unknown>;
}
/**
 * @implements {API.Every<API.Conjunct|API.Recur>}
 */
export class Join implements API.Every<API.Conjunct | API.Recur> {
    /**
     * @param {object} source
     * @param {Map<string, API.Variable>} source.bindings
     * @param {string} source.name
     * @param {API.Every<API.Conjunct|API.Recur>} source.conjuncts
     * @param {Set<API.Variable>} [source.variables]
     */
    static from({ bindings, name, conjuncts: forms, variables, }: {
        bindings: Map<string, API.Variable>;
        name: string;
        conjuncts: API.Every<API.Conjunct | API.Recur>;
        variables?: Set<API.Variable<API.Scalar>> | undefined;
    }): Join;
    /**
     * Ensures that given bindings are referenced from inside this join. Throws
     * a `ReferenceError` if there is a binding that is not referenced. The reason
     * if rule contains binding that is not used is in it's body it will either
     * not get bound or will not contribute to the rule in both cases rule is
     * likely not captures intended logic. Note that it theory rule may use some
     * variables only in some logic branches in which case those variables could
     * be considered as required input, but even then it is indicative of bad rule
     * design which could be broken apart into multiple rules which is why we
     * choose to error on side of caution. It is also always possible to consume
     * variable in cases where it really isn't needed.
     *
     * @param {Map<API.Variable, number>} cells
     * @param {Map<string, API.Variable>} bindings
     * @param {string} name
     */
    static ensureBindings(cells: Map<API.Variable, number>, bindings: Map<string, API.Variable>, name: string): typeof Join;
    /**
     * @param {Conjunct[]} conjuncts
     * @param {Map<API.Variable, number>} cells
     * @param {number} cost
     * @param {boolean} recurs
     * @param {string} name
     */
    constructor(conjuncts: Conjunct[], cells: Map<API.Variable, number>, cost: number, recurs: boolean, name: string);
    conjuncts: Conjunct[];
    cells: Map<API.Variable<API.Scalar>, number>;
    cost: number;
    name: string;
    recurs: boolean;
    /**
     * @param {API.Scope} scope
     * @returns {Plan.Join}
     */
    plan(scope: API.Scope): Plan.Join;
    toJSON(): Conjunct[];
    toDebugString(): string;
    /**
     * @returns {IterableIterator<API.Conjunct|API.Recur>}
     */
    [Symbol.iterator](): IterableIterator<API.Conjunct | API.Recur>;
}
/**
 * @typedef {Select|FormulaApplication|RuleApplication} Constraint
 * @typedef {Select|FormulaApplication|RuleApplication|Negation|RuleRecursion} Conjunct
 * @implements {API.NegationSyntax}
 */
export class Negation implements API.NegationSyntax {
    /**
     * @param {API.Negation} source
     * @returns {Negation}
     */
    static from({ not: constraint }: API.Negation): Negation;
    /**
     * @param {Constraint} constraint
     */
    static "new"(constraint: Constraint): Negation;
    /**
     * @param {Constraint} constraint
     * @param {Map<API.Variable, number>} cells
     */
    constructor(constraint: Constraint, cells: Map<API.Variable, number>);
    get recurs(): null;
    constraint: Constraint;
    cells: Map<API.Variable<API.Scalar>, number>;
    get references(): API.Cursor | Map<any, any>;
    get not(): API.Constraint;
    get cost(): number;
    /**
     * @param {API.Scope} scope
     * @returns {Plan.Negation}
     */
    plan(scope: API.Scope): Plan.Negation;
    toJSON(): {
        not: {
            match: API.Select;
        } | {
            match: API.FormulaMatch<{
                of: API.Numeric;
                by: API.Numeric;
            }, API.Numeric> | API.FormulaMatch<{
                of: API.Numeric;
                by: API.Numeric;
            }, API.Numeric> | API.FormulaMatch<{
                of: API.Numeric;
                by: API.Numeric;
            }, API.Numeric> | API.FormulaMatch<{
                of: API.Numeric;
                with: API.Numeric;
            }, API.Numeric> | API.FormulaMatch<{
                this: string | number;
                than: string | number;
            }, {}> | API.FormulaMatch<boolean, boolean> | API.FormulaMatch<{
                this: string | number;
                than: string | number;
            }, {}> | API.FormulaMatch<{
                this: string | number;
                than: string | number;
            }, {}> | API.FormulaMatch<{
                this: string | number;
                than: string | number;
            }, {}> | API.FormulaMatch<API.Scalar, API.TypeName> | API.FormulaMatch<Record<string, API.Scalar>, API.Link<Record<string, API.Scalar>, 113, 30>> | API.FormulaMatch<{
                text: string;
                pattern: string;
            }, string> | API.FormulaMatch<string, number> | API.FormulaMatch<string, string> | API.FormulaMatch<Uint8Array<ArrayBufferLike>, string> | API.FormulaMatch<string, Uint8Array<ArrayBufferLike>> | API.FormulaMatch<{
                this: string;
                slice: string;
            }, true> | API.FormulaMatch<{
                of: string;
                start: string;
                end: string;
            }, string> | API.FormulaMatch<{
                of: string;
                with: string;
            }, string> | API.FormulaMatch<{
                of: API.Numeric;
                by: API.Numeric;
            }, API.Numeric> | API.FormulaMatch<{
                of: API.Numeric;
                by: API.Numeric;
            }, number> | API.FormulaMatch<number, number> | API.FormulaMatch<API.Scalar, API.Scalar>;
            operator: "/" | "*" | "%" | "+" | "<" | "!" | "==" | ">" | ">=" | "<=" | "data/type" | "data/refer" | "text/like" | "text/length" | "text/words" | "text/lines" | "text/case/upper" | "text/case/lower" | "text/trim" | "text/trim/start" | "text/trim/end" | "utf8/to/text" | "text/to/utf8" | "text/includes" | "text/slice" | "text/concat" | "-" | "**" | "math/absolute";
        } | {
            match: object | API.Scalar;
            rule: {
                match: object | API.Scalar;
                when: {
                    [k: string]: Conjunct[];
                };
            };
        };
    };
    toDebugString(): string;
}
export type Constraint = Select | FormulaApplication | RuleApplication;
export type Conjunct = Select | FormulaApplication | RuleApplication | Negation | RuleRecursion;
import { $ } from './$.js';
import * as API from './api.js';
/**
 * @implements {API.SelectForm}
 * @implements {API.SelectSyntax}
 */
declare class Select implements API.SelectForm, API.SelectSyntax {
    /**
     * @param {API.SelectForm} source
     */
    static from({ match }: API.SelectForm): Select;
    /**
     * @param {API.Select} selector
     * @param {Map<API.Variable, number>} cells
     */
    constructor(selector: API.Select, cells: Map<API.Variable, number>);
    cells: Map<API.Variable<API.Scalar>, number>;
    selector: API.Select;
    get references(): Map<any, any>;
    get recurs(): null;
    get match(): API.Select;
    /**
     * Base execution cost of the select operation.
     */
    get cost(): number;
    /**
     *
     * @param {API.Scope} scope
     */
    plan({ references, bindings }: API.Scope): Plan.Select;
    toJSON(): {
        match: API.Select;
    };
    toDebugString(): string;
}
/**
 * @template {API.SystemOperator} Operator
 */
declare class Formula<Operator extends API.SystemOperator> {
    /**
     *
     * @param {Operator['operator']} operator
     */
    constructor(operator: Operator["operator"]);
    operator: Operator["operator"];
    /**
     * @param {Operator['match']} terms
     */
    apply(terms: Operator["match"]): FormulaApplication;
}
declare class FormulaApplication {
    /**
     * @param {API.SystemOperator} source
     */
    static from(source: API.SystemOperator): FormulaApplication;
    /**
     * @param {API.SystemOperator} source
     * @param {Map<API.Variable, number>} cells
     * @param {Record<string, API.Term>|API.Term} from
     * @param {Record<string, API.Term>} to
     */
    constructor(source: API.SystemOperator, cells: Map<API.Variable, number>, from: Record<string, API.Term> | API.Term, to: Record<string, API.Term>);
    cells: Map<API.Variable<API.Scalar>, number>;
    source: API.SystemOperator;
    from: API.Term<API.Scalar> | Record<string, API.Term<API.Scalar>>;
    to: Record<string, API.Term<API.Scalar>>;
    get references(): Map<any, any>;
    get match(): API.FormulaMatch<{
        of: API.Numeric;
        by: API.Numeric;
    }, API.Numeric> | API.FormulaMatch<{
        of: API.Numeric;
        by: API.Numeric;
    }, API.Numeric> | API.FormulaMatch<{
        of: API.Numeric;
        by: API.Numeric;
    }, API.Numeric> | API.FormulaMatch<{
        of: API.Numeric;
        with: API.Numeric;
    }, API.Numeric> | API.FormulaMatch<{
        this: string | number;
        than: string | number;
    }, {}> | API.FormulaMatch<boolean, boolean> | API.FormulaMatch<API.Scalar, API.Scalar> | API.FormulaMatch<{
        this: string | number;
        than: string | number;
    }, {}> | API.FormulaMatch<{
        this: string | number;
        than: string | number;
    }, {}> | API.FormulaMatch<{
        this: string | number;
        than: string | number;
    }, {}> | API.FormulaMatch<API.Scalar, API.TypeName> | API.FormulaMatch<Record<string, API.Scalar>, API.Link<Record<string, API.Scalar>, 113, 30>> | API.FormulaMatch<{
        text: string;
        pattern: string;
    }, string> | API.FormulaMatch<string, number> | API.FormulaMatch<string, string> | API.FormulaMatch<Uint8Array<ArrayBufferLike>, string> | API.FormulaMatch<string, Uint8Array<ArrayBufferLike>> | API.FormulaMatch<{
        this: string;
        slice: string;
    }, true> | API.FormulaMatch<{
        of: string;
        start: string;
        end: string;
    }, string> | API.FormulaMatch<{
        of: string;
        with: string;
    }, string> | API.FormulaMatch<{
        of: API.Numeric;
        by: API.Numeric;
    }, API.Numeric> | API.FormulaMatch<{
        of: API.Numeric;
        by: API.Numeric;
    }, number> | API.FormulaMatch<number, number>;
    get operator(): "/" | "*" | "%" | "+" | "<" | "!" | "==" | ">" | ">=" | "<=" | "data/type" | "data/refer" | "text/like" | "text/length" | "text/words" | "text/lines" | "text/case/upper" | "text/case/lower" | "text/trim" | "text/trim/start" | "text/trim/end" | "utf8/to/text" | "text/to/utf8" | "text/includes" | "text/slice" | "text/concat" | "-" | "**" | "math/absolute";
    get recurs(): null;
    /**
     * Base execution cost of the formula application operation.
     */
    get cost(): number;
    /**
     * @param {API.Scope} scope
     */
    plan(scope: API.Scope): Plan.FormulaApplication;
    toJSON(): {
        match: API.FormulaMatch<{
            of: API.Numeric;
            by: API.Numeric;
        }, API.Numeric> | API.FormulaMatch<{
            of: API.Numeric;
            by: API.Numeric;
        }, API.Numeric> | API.FormulaMatch<{
            of: API.Numeric;
            by: API.Numeric;
        }, API.Numeric> | API.FormulaMatch<{
            of: API.Numeric;
            with: API.Numeric;
        }, API.Numeric> | API.FormulaMatch<{
            this: string | number;
            than: string | number;
        }, {}> | API.FormulaMatch<boolean, boolean> | API.FormulaMatch<API.Scalar, API.Scalar> | API.FormulaMatch<{
            this: string | number;
            than: string | number;
        }, {}> | API.FormulaMatch<{
            this: string | number;
            than: string | number;
        }, {}> | API.FormulaMatch<{
            this: string | number;
            than: string | number;
        }, {}> | API.FormulaMatch<API.Scalar, API.TypeName> | API.FormulaMatch<Record<string, API.Scalar>, API.Link<Record<string, API.Scalar>, 113, 30>> | API.FormulaMatch<{
            text: string;
            pattern: string;
        }, string> | API.FormulaMatch<string, number> | API.FormulaMatch<string, string> | API.FormulaMatch<Uint8Array<ArrayBufferLike>, string> | API.FormulaMatch<string, Uint8Array<ArrayBufferLike>> | API.FormulaMatch<{
            this: string;
            slice: string;
        }, true> | API.FormulaMatch<{
            of: string;
            start: string;
            end: string;
        }, string> | API.FormulaMatch<{
            of: string;
            with: string;
        }, string> | API.FormulaMatch<{
            of: API.Numeric;
            by: API.Numeric;
        }, API.Numeric> | API.FormulaMatch<{
            of: API.Numeric;
            by: API.Numeric;
        }, number> | API.FormulaMatch<number, number>;
        operator: "/" | "*" | "%" | "+" | "<" | "!" | "==" | ">" | ">=" | "<=" | "data/type" | "data/refer" | "text/like" | "text/length" | "text/words" | "text/lines" | "text/case/upper" | "text/case/lower" | "text/trim" | "text/trim/start" | "text/trim/end" | "utf8/to/text" | "text/to/utf8" | "text/includes" | "text/slice" | "text/concat" | "-" | "**" | "math/absolute";
    };
    toDebugString(): string;
}
import * as Plan from './plan.js';
//# sourceMappingURL=syntax.d.ts.map