import { AnySort } from 'z3-solver';
import { Arith } from 'z3-solver';
import { Bool } from 'z3-solver';
import { Context } from 'z3-solver';
import { Expr } from 'z3-solver';
import { Optimize } from 'z3-solver';
import { Solver } from 'z3-solver';
import { Z3LowLevel } from 'z3-solver';

export declare function combinations<T>(choices: T[], length: number): Generator<T[]>;

export declare type Constructor<T extends abstract new (...args: any) => any> = new (...args: ConstructorParameters<T>) => T;

/**
 * Returns a count of cells along a sightline through a grid.
 * @param context The context in which to construct the constraints.
 * @param symbolGrid The grid to check against.
 * @param start The location of the cell where the sightline should begin.
 * This is the first cell checked.
 * @param direction The direction to advance to reach the next cell in the
 * sightline.
 * @param count A function that accepts a symbol as an argument and returns the
 * integer value to add to the count when this symbol is encountered. By
 * default, each symbol will count with a value of one.
 * @param stop A function that accepts a symbol as an argument and returns True
 * if we should stop following the sightline when this symbol is
 * encountered. By default, the sightline will continue to the edge of the
 * grid.
 * @returns An `Arith` for the count of cells along the sightline through the
 * grid.
 */
export declare function countCells<Name extends string>(context: GrilopsContext<Name>, symbolGrid: SymbolGrid<Name>, start: Point, direction: Direction, count?: (c: Arith<Name>) => Arith<Name>, stop?: (c: Arith<Name>) => Bool<Name>): Arith<Name>;

export declare function createDefualtMap<T>(base: KeyedMapConstructor<T>): DefaultKeyedMapConstructor<T>;

export declare function createDefualtMap(base: MapConstructor): DefaultMapConstructor;

export declare function createStringMap<T, Key extends string>(toString: (item: T) => Key, fromString: (key: Key) => T): KeyedMapConstructor<T>;

export declare function createStringSet<T, Key extends string>(toString: (item: T) => Key, fromString: (key: Key) => T): KeyedSetConstructor<T>;

export declare const DefaultDirectionMap: DefaultKeyedMapConstructor<Direction>;

export declare interface DefaultKeyedMapConstructor<T> extends DefaultMapConstructor, KeyedMapConstructor<T> {
    new <V>(defaultFunc: () => V, entries?: readonly (readonly [T, V])[] | null): DefaultMap<T, V>;
    readonly prototype: DefaultMap<T, any>;
}

export declare interface DefaultMap<K, V> extends Map<K, V> {
    get(key: K): V;
}

export declare interface DefaultMapConstructor {
    new <K, V>(defaultFunc: () => V, entries?: readonly (readonly [K, V])[] | null): DefaultMap<K, V>;
    readonly prototype: DefaultMap<any, any>;
}

export declare const DefaultPointMap: DefaultKeyedMapConstructor<Point>;

export declare const DefaultVectorMap: DefaultKeyedMapConstructor<Vector>;

/**
 * A named direction vector that offsets by one space in the grid.
 */
export declare class Direction {
    /**
     * The name of the direction.
     */
    name: DirectionKey;
    /**
     * The vector of the direction.
     */
    vector: Vector;
    constructor(name: DirectionKey, vector: Vector);
    toString(): DirectionString;
    static fromString(s: DirectionString): Direction;
}

export declare type DirectionKey = 'N' | 'S' | 'E' | 'W' | 'NE' | 'NW' | 'SE' | 'SW';

export declare const DirectionMap: KeyedMapConstructor<Direction>;

export declare const DirectionSet: KeyedSetConstructor<Direction>;

export declare type DirectionString = `D(${DirectionKey},${VectorString})`;

/**
 * A quadtree for caching and aggregating z3 expressions.
 *
 * This class builds a quadtree data structure from a list of points, and
 * provides the ability to lazily construct and cache z3 expressions that
 * reference these points.
 */
export declare class ExpressionQuadTree<Name extends string, ExprKey extends string | number | symbol> {
    readonly ctx: GrilopsContext<Name>;
    private _exprs;
    private _exprFuncs;
    private _point;
    private _yMin;
    private _yMax;
    private _xMin;
    private _xMax;
    private _yMid;
    private _xMid;
    private _tl;
    private _tr;
    private _bl;
    private _br;
    private _quads;
    constructor(context: GrilopsContext<Name>, points: Point[], exprFuncs?: ExprFuncMap<Name, ExprKey> | undefined);
    /**
     * Returns true if the given point is within this tree node's bounds.
     */
    coversPoint(p: Point): boolean;
    /**
     * Registers an expression constructor, to be called for each point.
     */
    addExpr(key: ExprKey, exprFunc: (point: Point) => Bool<Name>): void;
    /**
     * Returns expressions for all points covered by this tree node.
     */
    getExprs(key: ExprKey): Bool<Name>[];
    /**
     * Returns the expression for the given point.
     */
    getPointExpr(key: ExprKey, p: Point): Bool<Name>;
    /**
     * Returns the conjunction of all expressions, excluding given points.
     */
    getOtherPointsExpr(key: ExprKey, points: Point[]): Bool<Name> | undefined;
}

export declare type ExprFuncMap<Name extends string, ExprKey> = Map<ExprKey, (point: Point) => Bool<Name>>;

/**
 * A set of points forming a flat-topped hexagonal lattice.
 *
 * All points must lie on a hexagonal lattice in which each hexagon has
 * a flat top. We use the doubled coordinates scheme described at
 * https://www.redblobgames.com/grids/hexagons/. That is, y describes
 * the row and x describes the column, so hexagons that are vertically
 * adjacent have their y coordinates differ by 2.
 */
export declare class FlatToppedHexagonalLattice extends HexagonalLattice {
    static DIRECTIONS: {
        N: Direction;
        S: Direction;
        NE: Direction;
        NW: Direction;
        SE: Direction;
        SW: Direction;
    };
    edgeSharingDirections(): Direction[];
    transformationFunctions(allowRotations: boolean, allowReflections: boolean): ((vector: Vector) => Vector)[];
    getInsideOutsideCheckDirections(): [Direction, Direction[]];
}

declare namespace geometry {
    export {
        getRectangleLattice,
        getSquareLattice,
        VectorString,
        Vector,
        VectorMap,
        VectorSet,
        DefaultVectorMap,
        DirectionKey,
        DirectionString,
        Direction,
        DirectionMap,
        DirectionSet,
        DefaultDirectionMap,
        PointString,
        Point,
        PointMap,
        PointSet,
        DefaultPointMap,
        HookFunction,
        Neighbor,
        Lattice,
        RectangularLattice,
        HexagonalLattice,
        FlatToppedHexagonalLattice,
        PointyToppedHexagonalLattice
    }
}

/**
 * Returns a lattice of all points in a rectangle of the given dimensions.
 * @param height Height of the lattice.
 * @param width Width of the lattice.
 * @returns The lattice.
 */
export declare function getRectangleLattice(height: number, width: number): RectangularLattice;

/**
 * Returns a lattice of all points in a square of the given height.
 * @param height Height of the lattice.
 * @returns The lattice.
 */
export declare function getSquareLattice(height: number): RectangularLattice;

export declare function grilops<Name extends string>(context: GrilopsContext<Name>): {
    PathSymbolSet: typeof paths.PathSymbolSet;
    PathConstrainer: typeof paths.PathConstrainer;
    RegionConstrainer: new <const Core extends Solver<Name> | Optimize<Name> = Solver<Name> | Optimize<Name>>(lattice: geometry.Lattice, solver: Core | undefined, complete?: boolean | undefined, rectangular?: boolean | undefined, minRegionSize?: number | undefined, maxRegionSize?: number | undefined) => RegionConstrainer<Name, Core>;
    Shape: new <Payload extends Expr<Name, AnySort<Name>, unknown>>(offsets: Offset<Name, Payload>[]) => Shape<Name, Payload>;
    ShapeConstrainer: new <Payload_1 extends Expr<Name, AnySort<Name>, unknown>, const Core_1 extends Solver<Name> | Optimize<Name> = Solver<Name> | Optimize<Name>>(lattice: geometry.Lattice, shapes: Shape<Name, Payload_1>[], solver: Core_1 | undefined, complete: boolean, allowRotations: boolean, allowReflections: boolean, allowCopies: boolean) => ShapeConstrainer<Name, Payload_1, Core_1>;
    reduceCells: <Accumulator extends Arith<Name>>(symbolGrid: SymbolGrid<Name, Solver<Name> | Optimize<Name>>, start: geometry.Point, direction: geometry.Direction, initializer: Accumulator, accumulate: (a: Accumulator, c: Arith<Name>, p: geometry.Point) => Accumulator, stop?: (a: Accumulator, c: Arith<Name>, p: geometry.Point) => Bool<Name>) => Accumulator;
    countCells: (symbolGrid: SymbolGrid<Name, Solver<Name> | Optimize<Name>>, start: geometry.Point, direction: geometry.Direction, count?: (c: Arith<Name>) => Arith<Name>, stop?: (c: Arith<Name>) => Bool<Name>) => Arith<Name>;
    makeLetterRangeSymbolSet(minLetter: string, maxLetter: string): symbols.SymbolSet;
    makeNumberRangeSymbolSet(minNumber: number, maxNumber: number): symbols.SymbolSet;
    Symbol: typeof symbols.Symbol;
    SymbolSet: typeof symbols.SymbolSet;
    ExpressionQuadTree: new <ExprKey extends string | number | symbol>(points: geometry.Point[], exprFuncs?: ExprFuncMap<Name, ExprKey> | undefined) => ExpressionQuadTree<Name, ExprKey>;
    SymbolGrid: new <Core_2 extends Solver<Name> | Optimize<Name> = Solver<Name>>(lattice: geometry.Lattice, symbolSet: symbols.SymbolSet, solver?: Core_2 | undefined) => SymbolGrid<Name, Core_2>;
    getRectangleLattice(height: number, width: number): geometry.RectangularLattice;
    getSquareLattice(height: number): geometry.RectangularLattice;
    Vector: typeof geometry.Vector;
    VectorMap: KeyedMapConstructor<geometry.Vector>;
    VectorSet: KeyedSetConstructor<geometry.Vector>;
    DefaultVectorMap: DefaultKeyedMapConstructor<geometry.Vector>;
    Direction: typeof geometry.Direction;
    DirectionMap: KeyedMapConstructor<geometry.Direction>;
    DirectionSet: KeyedSetConstructor<geometry.Direction>;
    DefaultDirectionMap: DefaultKeyedMapConstructor<geometry.Direction>;
    Point: typeof geometry.Point;
    PointMap: KeyedMapConstructor<geometry.Point>;
    PointSet: KeyedSetConstructor<geometry.Point>;
    DefaultPointMap: DefaultKeyedMapConstructor<geometry.Point>;
    Neighbor: typeof geometry.Neighbor;
    Lattice: typeof geometry.Lattice;
    RectangularLattice: typeof geometry.RectangularLattice;
    HexagonalLattice: typeof geometry.HexagonalLattice;
    FlatToppedHexagonalLattice: typeof geometry.FlatToppedHexagonalLattice;
    PointyToppedHexagonalLattice: typeof geometry.PointyToppedHexagonalLattice;
};

export declare interface GrilopsContext<Name extends string> {
    z3: Z3LowLevel['Z3'];
    context: Context<Name>;
}

export declare abstract class HexagonalLattice extends Lattice {
    private _points;
    private _pointIndices;
    private static _DIRECTION_LABELS;
    /**
     * A set of points forming a hexagonal lattice.
     *
     * This abstract class implements functions identical between
     * FlatToppedHexagonalLattice and PointyToppedHexagonalLattice.
     *
     * We use the doubled coordinates scheme described at
     * https://www.redblobgames.com/grids/hexagons/. That is, y describes
     * the row and x describes the column, so x + y is always even.
     */
    constructor(points: Point[]);
    get points(): Point[];
    pointToIndex(point: Point): number | undefined;
    vertexSharingDirections(): Direction[];
    labelForDirection(direction: Direction): string;
    labelForDirectionPair(dir1: Direction, dir2: Direction): string;
}

export declare type HookFunction = (point: Point) => string | undefined;

export declare interface KeyedMapConstructor<T> extends MapConstructor {
    new (): Map<T, any>;
    new <V>(entries?: readonly (readonly [T, V])[] | null): Map<T, V>;
    readonly prototype: Map<T, any>;
    readonly [KeyedMapContructorSymbol]?: undefined;
}

declare const KeyedMapContructorSymbol: unique symbol;

export declare interface KeyedSetConstructor<T> {
    new (values?: readonly T[] | null): Set<T>;
    readonly prototype: Set<any>;
}

/**
 * A base class for defining the structure of a grid.
 */
export declare abstract class Lattice {
    private _vectorDirection;
    constructor();
    /**
     * The points in the lattice, sorted.
     */
    abstract get points(): Point[];
    /**
     * Returns the index of a point in the lattice's ordered list.
     * @param point The `Point` to get the index of.
     * @returns The index of the point in the ordered list, or None if the point
     * is not in the list.
     */
    abstract pointToIndex(point: Point): number | undefined;
    /**
     * A list of edge-sharing directions.
     * @returns A list of `Direction`s, each including the name of an edge-sharing
     * direction and the vector representing that direction. Edge sharing (also
     * known as orthogonal adjacency) is the relationship between grid cells
     * that share an edge.
     */
    abstract edgeSharingDirections(): Direction[];
    /**
     * A list of vertex-sharing directions.
     * @returns A list of `Direction`s, each including the name of a
     * vertex-sharing direction and the vector representing that
     * direction. Vertex sharing (also known as touching adjacency) is the
     * relationship between grid cells that share a vertex.
     */
    abstract vertexSharingDirections(): Direction[];
    /**
     * Given a direction, return the opposite direction.
     * @param direction The given `Direction`.
     * @returns The `Direction` opposite the given direction.
     */
    oppositeDirection(direction: Direction): Direction;
    /**
     * Returns a list of points that share an edge with the given cell.
     * @param point The point of the given cell.
     * @returns A list of `Point`s in the lattice that correspond to cells that
     * share an edge with the given cell.
     */
    edgeSharingPoints(point: Point): Point[];
    /**
     * Returns a list of points that share a vertex with the given cell.
     * @param point The point of the given cell.
     * @returns A list of `Point`s in the lattice corresponding to cells that
     * share a vertex with the given cell.
     */
    vertexSharingPoints(point: Point): Point[];
    /**
     * Returns a list of neighbors in the given directions of the given cell.
     * @param cellMap A dictionary mapping points in the lattice to z3 constants.
     * @param p Point of the given cell.
     * @param directions The given list of directions to find neighbors with.
     * @returns A list of `Neighbor`s corresponding to the cells that are in the
     * given directions from the given cell.
     */
    private static _getNeighbors;
    /**
     * Returns a list of neighbors sharing an edge with the given cell.
     * @param cellMap A dictionary mapping points in the lattice to z3 constants.
     * @param p Point of the given cell.
     * @returns A list of `Neighbor`s corresponding to the cells that share an
     * edge with the given cell.
     */
    edgeSharingNeighbors<Name extends string>(cellMap: Map<Point, Arith<Name>>, p: Point): Neighbor<Name>[];
    /**
     * Returns a list of neighbors sharing a vertex with the given cell.
     * @param cellMap A dictionary mapping points in the lattice to z3 constants.
     * @param p Point of the given cell.
     * @returns A list of `Neighbor`s corresponding to the cells that share a
     * vertex with the given cell.
     */
    vertexSharingNeighbors<Name extends string>(cellMap: Map<Point, Arith<Name>>, p: Point): Neighbor<Name>[];
    /**
     * Returns the label for a direction.
     * @param direction The direction to label.
     * @returns A label representing the direction.
     * @throws An error if there's no character defined for the direction.
     */
    abstract labelForDirection(direction: Direction): string;
    /**
     * Returns the label for a pair of edge-sharing directions.
     * @param dir1 The first direction.
     * @param dir2 The second direction.
     * @returns A label representing both directions.
     * @throws An error if there's no character defined for the direction pair.
     */
    abstract labelForDirectionPair(dir1: Direction, dir2: Direction): string;
    /**
     * Returns a list of `Vector` transformations.
     *
     * Each returned transformation is a function that transforms a
     * `Vector` into a `Vector`. The returned list always contains at least
     * one transformation: the identity function.  The transformations
     * returned are all transformations satisfying the given constraints.
     *
     * @param allowRotations Whether rotation is an allowed transformation.
     * @param allowReflections Whether reflection is an allowed transformation.
     * @returns A list of `Vector` transformation functions.
     */
    abstract transformationFunctions(allowRotations: boolean, allowReflections: boolean): ((vector: Vector) => Vector)[];
    /**
     * Returns directions for use in a loop inside-outside check.
     *
     * The first direction returned is the direction to look, and the
     * remaining directions are the directions to check for crossings.
     *
     * For instance, on a rectangular grid, a valid return value would
     * be (north, [west]). This means that if you look north and count how many
     * west-going lines you cross, you can tell from its parity if you're inside
     * or outside the loop.
     *
     * @returns A tuple, the first component of which indicates the direction to
     * look, and the second component of which indicates what types of crossings
     * to count.
     */
    abstract getInsideOutsideCheckDirections(): [Direction, Direction[]];
    /**
     * Prints something for each of the given points.
     * @param hookFunction A function implementing per-location display
     * behavior. It will be called for each `Point` in the lattice. If the
     * returned string has embedded newlines, it will be treated as a multi-line
     * element.  For best results, all elements should have the same number of
     * lines as each other and as blank (below).
     * @param ps The `Point`s to print something for.
     * @param blank What to print for `Point`s not in the lattice, or for when
     * the hook function returns None. Defaults to one space.  If it has
     * embedded newlines, it will be treated as a multi-line element.
     */
    private _pointsToString;
    /**
     * Prints something for each space in the lattice.
     *
     * Printing is done from top to bottom and left to right.
     *
     * @param hookFunction A function implementing per-location display
     * behavior. It will be called for each `Point` in the lattice. If the
     * returned string has embedded newlines, it will be treated as a multi-line
     * element.  For best results, all elements should have the same number of
     * lines as each other and as blank (below).
     * @param blank What to print for `Point`s not in the lattice, or for when
     * the hook function returns None. Defaults to one space.  If it has
     * embedded newlines, it will be treated as a multi-line element.
     */
    toString(hookFunction: HookFunction, blank?: string): string;
}

/**
 * Returns a `SymbolSet` consisting of consecutive letters.
 * @param minLetter The lowest letter to include in the set.
 * @param maxLetter The highest letter to include in the set.
 * @returns A `SymbolSet` consisting of consecutive letters.
 */
export declare function makeLetterRangeSymbolSet(minLetter: string, maxLetter: string): SymbolSet;

/**
 * Returns a `SymbolSet` consisting of consecutive numbers.
 *
 * The names of the symbols will be prefixed with S to be consistent with the
 * Python implementation.
 *
 * @param minNumber The lowest number to include in the set.
 * @param maxNumber The highest number to include in the set.
 * @returns A `SymbolSet` consisting of consecutive numbers.
 */
export declare function makeNumberRangeSymbolSet(minNumber: number, maxNumber: number): SymbolSet;

/**
 * Properties of a cell that is a neighbor of another.
 */
export declare class Neighbor<Name extends string> {
    /**
     * The location of the cell.
     */
    location: Point;
    /**
     * The direction from the original cell.
     */
    direction: Direction;
    /**
     * The symbol constant of the cell.
     */
    symbol: Arith<Name>;
    constructor(location: Point, direction: Direction, symbol: Arith<Name>);
}

export declare type Offset<Name extends string, Payload extends Expr<Name>> = Vector | [Vector, Payload?];

/**
 * Creates constraints for ensuring symbols form connected paths.
 */
export declare class PathConstrainer<Name extends string> {
    private static _instanceIndex;
    private readonly _symbolGrid;
    private readonly _complete;
    private readonly _allowTerminatedPaths;
    private readonly _allowLoops;
    private readonly _pathInstanceGrid;
    private readonly _pathOrderGrid;
    private _numPaths;
    /**
     * @param symbolGrid The grid to constrain.
     * @param complete If true, every cell must be part of a path. Defaults to
     * false.
     * @param allowTerminatedPaths If true, finds paths that are terminated
     * (not loops). Defaults to true.
     * @param allowLoops If true, finds paths that are loops. Defaults to true.
     */
    constructor(symbolGrid: SymbolGrid<Name>, complete?: boolean, allowTerminatedPaths?: boolean, allowLoops?: boolean);
    private _addPathEdgeConstraints;
    private _addPathInstanceGridConstraints;
    private _allDirectionPairs;
    private _addPathOrderGridConstraints;
    private _addAllowTerminatedPathsConstraints;
    /**
     * A constant representing the number of distinct paths found.
     */
    get numPaths(): Arith<Name>;
    /**
     * Constants of path instance identification.
     *
     * Each separate path will have a distinct instance number. The instance number
     * is -1 if the cell does not contain a path segment or terminal.
     */
    get pathInstanceGrid(): Map<Point, Arith<Name>>;
    /**
     * Constants of path traversal orders.
     *
     * Each segment or terminal of a path will have a distinct order number. The
     * order number is -1 if the cell does not contain a path segment or terminal.
     */
    get pathOrderGrid(): Map<Point, Arith<Name>>;
    /**
     * Prints the path instance and order for each path cell.
     *
     * Should be called only after the solver has been checked.
     */
    pathNumberingToString(): string;
}

declare namespace paths {
    export {
        PathSymbolSet,
        PathConstrainer
    }
}

/**
 * A `SymbolSet` consisting of symbols that may form paths.
 *
 * Additional symbols (e.g. a `Symbol` representing an empty
 * space) may be added to this `SymbolSet` by calling
 * `SymbolSet.append` after it's constructed.
 */
export declare class PathSymbolSet extends SymbolSet {
    private readonly _includeTerminals;
    private readonly _symbolsForDirection;
    private readonly _symbolForDirectionPair;
    private readonly _terminalForDirection;
    private _maxPathSegmentSymbolIndex;
    private _maxPathTerminalSymbolIndex;
    /**
     * @param lattice The structure of the grid.
     * @param includeTerminals If true, create symbols for path terminals.
     * Defaults to true.
     */
    constructor(lattice: Lattice, includeTerminals?: boolean);
    /**
     * Returns true if the given symbol represents part of a path.
     * @param symbol An `Arith` expression representing a symbol.
     * @returns A true `Bool` if the symbol represents part of a path.
     */
    isPath<Name extends string>(symbol: Arith<Name>): Bool<Name>;
    /**
     * Returns true if the given symbol represents a non-terminal path segment.
     * @param symbol An `Arith` expression representing a symbol.
     * @returns A true `Bool` if the symbol represents a non-terminal path segment.
     */
    isPathSegment<Name extends string>(symbol: Arith<Name>): Bool<Name>;
    /**
     * Returns true if the given symbol represents a path terminal.
     * @param symbol An `Arith` expression representing a symbol.
     * @returns A true `Bool` if the symbol represents a path terminal.
     */
    isTerminal<Name extends string>(symbol: Arith<Name>): Bool<Name>;
    /**
     * Returns the symbols with one arm going in the given direction.
     * @param d The given direction.
     * @returns A `number[]` of symbol indices corresponding to symbols with one
     * arm going in the given direction.
     */
    symbolsForDirection(d: Direction): number[];
    /**
     * Returns the symbol with arms going in the two given directions.
     * @param d1 The first given direction.
     * @param d2 The second given direction.
     * @returns The symbol index for the symbol with one arm going in each of the
     * two given directions.
     */
    symbolForDirectionPair(d1: Direction, d2: Direction): number;
    /**
     * Returns the symbol that terminates the path from the given direction.
     * @param d The given direction.
     * @returns The symbol index for the symbol that terminates the path from the
     * given direction.
     */
    terminalForDirection(d: Direction): number | undefined;
}

/**
 * A point, generally corresponding to the center of a grid cell.
 */
export declare class Point {
    /**
     * The location in the y dimension.
     */
    y: number;
    /**
     * The location in the x dimension.
     */
    x: number;
    constructor(y: number, x: number);
    /**
     * Translates this point by the given `Vector` or `Direction`.
     */
    translate(other: Vector | Direction): Point;
    toString(): PointString;
    static fromString(s: PointString): Point;
    equals(other: Point): boolean;
    static comparator(a: Point, b: Point): number;
}

export declare const PointMap: KeyedMapConstructor<Point>;

export declare const PointSet: KeyedSetConstructor<Point>;

export declare type PointString = `P(${string},${string})`;

/**
 * A set of points forming a pointy-topped hexagonal lattice.
 *
 * All points must lie on a hexagonal lattice in which each hexagon has
 * a pointy top. We use the doubled coordinates scheme described at
 * https://www.redblobgames.com/grids/hexagons/. That is, y describes
 * the row and x describes the column, so hexagons that are horizontally
 * adjacent have their x coordinates differ by 2.
 */
export declare class PointyToppedHexagonalLattice extends HexagonalLattice {
    static DIRECTIONS: {
        E: Direction;
        W: Direction;
        NE: Direction;
        NW: Direction;
        SE: Direction;
        SW: Direction;
    };
    edgeSharingDirections(): Direction[];
    transformationFunctions(allowRotations: boolean, allowReflections: boolean): ((vector: Vector) => Vector)[];
    getInsideOutsideCheckDirections(): [Direction, Direction[]];
}

export declare class RectangularLattice extends Lattice {
    private _points;
    private _pointIndices;
    static EDGE_DIRECTIONS: {
        N: Direction;
        S: Direction;
        E: Direction;
        W: Direction;
    };
    static VERTEX_DIRECTIONS: {
        NE: Direction;
        NW: Direction;
        SE: Direction;
        SW: Direction;
        N: Direction;
        S: Direction;
        E: Direction;
        W: Direction;
    };
    /**
     * @param points A set of points corresponding to a rectangular lattice.
     * Note that these points need not fill a complete rectangle.
     */
    constructor(points: Point[]);
    get points(): Point[];
    pointToIndex(point: Point): number | undefined;
    edgeSharingDirections(): Direction[];
    vertexSharingDirections(): Direction[];
    labelForDirection(direction: Direction): string;
    labelForDirectionPair(dir1: Direction, dir2: Direction): string;
    transformationFunctions(allowRotations: boolean, allowReflections: boolean): ((vector: Vector) => Vector)[];
    getInsideOutsideCheckDirections(): [Direction, Direction[]];
}

/**
 * Returns a computation of a sightline through a grid.
 * @param context The context in which to construct the constraints.
 * @param symbolGrid The grid to check against.
 * @param start The location of the cell where the sightline should begin.
 * This is the first cell checked.
 * @param direction The direction to advance to reach the next cell in the
 * sightline.
 * @param initializer The initial value for the accumulator.
 * @param accumulate A function that accepts an accumulated value, a symbol,
 * and (optionally) a point as arguments, and returns a new accumulated
 * value. This function is used to determine a new accumulated value for
 * each cell along the sightline, based on the accumulated value from the
 * previously encountered cells as well as the point and/or symbol of the
 * current cell.
 * @param stop A function that accepts an accumulated value, a symbol, and
 * (optionally) a point as arguments, and returns True if we should stop
 * following the sightline when this symbol or point is encountered. By
 * default, the sightline will continue to the edge of the grid.
 * @returns The accumulated value.
 */
export declare function reduceCells<Name extends string, Accumulator extends Arith<Name>>(context: GrilopsContext<Name>, symbolGrid: SymbolGrid<Name>, start: Point, direction: Direction, initializer: Accumulator, accumulate: (a: Accumulator, c: Arith<Name>, p: Point) => Accumulator, stop?: (a: Accumulator, c: Arith<Name>, p: Point) => Bool<Name>): Accumulator;

/**
 * Creates constraints for grouping cells into contiguous regions.
 */
export declare class RegionConstrainer<Name extends string, const Core extends Solver<Name> | Optimize<Name> = Solver<Name> | Optimize<Name>> {
    private static _instanceIndex;
    readonly ctx: GrilopsContext<Name>;
    private readonly _solver;
    private readonly _lattice;
    private readonly _complete;
    private readonly _minRegionSize;
    private readonly _maxRegionSize;
    private _edgeSharingDirectionToIndex;
    private _parentTypeToIndex;
    private _parentTypes;
    private _parentGrid;
    private _subtreeSizeGrid;
    private _regionIdGrid;
    private _regionSizeGrid;
    /**
     * @param lattice The structure of the grid.
     * @param solver A `Solver` object. If None, a `Solver` will be constructed.
     * @param complete If true, every cell must be part of a region. Defaults to
     * true.
     * @param rectangular If true, every region must be "rectangular"; for each
     * cell in a region, ensure that pairs of its neighbors that are part of
     * the same region each share an additional neighbor that's part of the
     * same region when possible.
     * @param minRegionSize The minimum possible size of a region.
     * @param maxRegionSize The maximum possible size of a region.
     */
    constructor(context: GrilopsContext<Name>, lattice: Lattice, solver?: Core | undefined, complete?: boolean, rectangular?: boolean, minRegionSize?: number | undefined, maxRegionSize?: number | undefined);
    /**
     * Creates the structures used for managing edge-sharing directions.
     *
     * Creates the mapping between edge-sharing directions and the parent
     * indices corresponding to them.
     */
    private _manageEdgeSharingDirections;
    /**
     * Create the grids used to model region constraints.
     */
    private _createGrids;
    /**
     * Add constraints to the region modeling grids.
     */
    private _addConstraints;
    private _addRectangularConstraints;
    /**
     * Returns the `RegionConstrainer.parent_grid` value for the direction.
     *
     * For instance, if direction is (-1, 0), return the index for N.
     *
     * @param direction The direction to an edge-sharing cell.
     * @returns The `RegionConstrainer.parent_grid` value that means that the
     * parent in its region's subtree is the cell offset by that direction.
     */
    edgeSharingDirectionToIndex(direction: Direction): number;
    /**
     * Returns the `RegionConstrainer.parent_grid` value for the parent type.
     *
     * The parent_type may be a direction name (like "N") or name of a special
     * value like "R" or "X".
     *
     * @param parentType The parent type.
     * @returns The corresponding `RegionConstrainer.parent_grid` value.
     */
    parentTypeToIndex(parentType: string): number;
    /**
     * The `Solver` associated with this `RegionConstrainer`.
     */
    get solver(): Core;
    /**
     * A dictionary of numbers identifying regions.
     *
     * A region's identifier is the position in the grid (going in order from left
     * to right, top to bottom) of the root of that region's subtree. It is the
     * same as the index of the point in the lattice.
     */
    get regionIdGrid(): Map<Point, Arith<Name>>;
    /**
     * A dictionary of region sizes.
     */
    get regionSizeGrid(): Map<Point, Arith<Name>>;
    /**
     * A dictionary of region subtree parent pointers.
     */
    get parentGrid(): Map<Point, Arith<Name>>;
    /**
     * A dictionary of cell subtree sizes.
     *
     * A cell's subtree size is one plus the number of cells that are descendents
     * of the cell in its region's subtree.
     */
    get subtreeSizeGrid(): Map<Point, Arith<Name>>;
    /**
     * Prints the region parent assigned to each cell.
     *
     * Should be called only after the solver has been checked.
     */
    treesToString(): string;
    /**
     * Prints the region subtree size of each cell.
     *
     * Should be called only after the solver has been checked.
     */
    subtreeSizesToString(): string;
    /**
     * Prints a number identifying the region that owns each cell.
     *
     * Should be called only after the solver has been checked.
     */
    regionIdsToString(): string;
    /**
     * Prints the size of the region that contains each cell.
     *
     * Should be called only after the solver has been checked.
     */
    regionSizesToString(): string;
}

/**
 * A shape defined by a list of `Vector` offsets.
 *
 * Each offset may optionally have an associated payload value.
 */
export declare class Shape<Name extends string, Payload extends Expr<Name>> {
    readonly ctx: GrilopsContext<Name>;
    private _offsetTuples;
    /**
     * @param offsets A list of offsets that define the shape. An offset may be a
     * `Vector`; or, to optionally associate a payload value with the offset, it
     * may be a `[Vector, Payload]`. A payload may be any z3 expression.
     */
    constructor(context: GrilopsContext<Name>, offsets: Offset<Name, Payload>[]);
    /**
     * The offset vectors that define this shape.
     */
    get offsetVectors(): Vector[];
    /**
     * The offset vector and payload value tuples for this shape.
     */
    get offsetsWithPayloads(): [Vector, Payload | undefined][];
    /**
     * Returns a new shape with each offset transformed by `f`.
     */
    transform(f: (vector: Vector) => Vector): Shape<Name, Payload>;
    /**
     * Returns a new shape that's canonicalized.
     *
     * A canonicalized shape is in sorted order and its first offset is
     * `Vector`(0, 0). This helps with deduplication, since equivalent shapes
     * will be canonicalized identically.
     *
     * @returns A `Shape` of offsets defining the canonicalized version of the
     * shape, i.e., in sorted order and with first offset equal to
     * `Vector`(0, 0).
     */
    canonicalize(): Shape<Name, Payload>;
    /**
     * Returns true iff the given shape is equivalent to this shape.
     */
    equivalent(shape: Shape<Name, Payload>): boolean;
}

/**
 * Creates constraints for placing fixed shape regions into the grid.
 */
export declare class ShapeConstrainer<Name extends string, Payload extends Expr<Name>, const Core extends Solver<Name> | Optimize<Name> = Solver<Name> | Optimize<Name>> {
    private static _instanceIndex;
    readonly ctx: GrilopsContext<Name>;
    private readonly _solver;
    private readonly _lattice;
    private readonly _complete;
    private readonly _allowCopies;
    private readonly _shapes;
    private _variants;
    private _shapeTypeGrid;
    private _shapeInstanceGrid;
    private _shapePayloadGrid;
    /**
     * @param lattice The structure of the grid.
     * @param shapes A list of region shape definitions. The same region shape
     * definition may be included multiple times to indicate the number of times
     * that shape may appear (if allowCopies is false).
     * @param solver A `Solver` object. If undefined, a `Solver` will be constructed.
     * @param complete If true, every cell must be part of a shape region.
     * Defaults to false.
     * @param allowRotations If true, allow rotations of the shapes to be placed
     * in the grid. Defaults to false.
     * @param allowReflections If true, allow reflections of the shapes to be
     * placed in the grid. Defaults to false.
     * @param allowCopies If true, allow any number of copies of the shapes to
     * be placed in the grid. Defaults to false.
     */
    constructor(context: GrilopsContext<Name>, lattice: Lattice, shapes: Shape<Name, Payload>[], solver?: Core | undefined, complete?: boolean, allowRotations?: boolean, allowReflections?: boolean, allowCopies?: boolean);
    private _makeVariants;
    /**
     * Create the grids used to model shape region constraints.
     */
    private _createGrids;
    private _addConstraints;
    private _addGridAgreementConstraints;
    private _addShapeInstanceConstraints;
    private _addSingleCopyConstraints;
    /**
     * The `Solver` associated with this `ShapeConstrainer`.
     */
    get solver(): Core;
    /**
     * A dictionary of z3 constants of shape types.
     *
     * Each cell contains the index of the shape type placed in that cell (as
     * indexed by the shapes list passed in to the `ShapeConstrainer`
     * constructor), or -1 if no shape is placed within that cell.
     */
    get shapeTypeGrid(): Map<Point, Arith<Name>>;
    getShapeTypeAt(p: Point): Arith<Name>;
    /**
     * z3 constants of shape instance IDs.
     *
     * Each cell contains a number shared among all cells containing the same
     * instance of the shape, or -1 if no shape is placed within that cell.
     */
    get shapeInstanceGrid(): Map<Point, Arith<Name>>;
    getShapeInstanceAt(p: Point): Arith<Name>;
    /**
     * z3 constants of the shape offset payloads initially provided.
     *
     * undefined if no payloads were provided during construction.
     */
    get shapePayloadGrid(): Map<Point, Payload> | undefined;
    getShapePayloadAt(p: Point): Payload;
    /**
     * Prints the shape type assigned to each cell.
     *
     * Should be called only after the solver has been checked.
     */
    shapeTypesToString(): string;
    /**
     * Prints the shape instance ID assigned to each cell.
     *
     * Should be called only after the solver has been checked.
     */
    shapeInstancesToString(): string;
}

export declare enum ShapeExprKey {
    HAS_INSTANCE_ID = 0,
    NOT_HAS_INSTANCE_ID = 1,
    HAS_SHAPE_TYPE = 2
}

/**
 * @module symbols This module supports defining symbols that may be filled into grid cells.
 */
/**
 * A marking that may be filled into a `grilops.grids.SymbolGrid` cell.
 */
declare class Symbol_2 {
    private _index;
    private _name;
    private _label;
    /**
     * @param index The index value assigned to the symbol.
     * @param name The code-safe name of the symbol.
     * @param label The printable label of the symbol.
     */
    constructor(index: number, name?: string, label?: string);
    /**
     * The index value assigned to the symbol.
     */
    get index(): number;
    /**
     * The code-safe name of the symbol.
     */
    get name(): string;
    /**
     * The printable label of the symbol.
     */
    get label(): string;
    toString(): string;
}
export { Symbol_2 as Symbol }

/**
 * A grid of cells that can be solved to contain specific symbols.
 */
export declare class SymbolGrid<Name extends string, const Core extends Solver<Name> | Optimize<Name> = Solver<Name> | Optimize<Name>> {
    private static _instanceIndex;
    readonly ctx: GrilopsContext<Name>;
    private _lattice;
    private _symbolSet;
    private _solver;
    private _grid;
    /**
     * @param context The context in which to construct the grid.
     * @param lattice The structure of the grid.
     * @param symbolSet The set of symbols to be filled into the grid.
     * @param solver A `Solver` object. If undefined, a `Solver` will be constructed.
     */
    constructor(context: GrilopsContext<Name>, lattice: Lattice, symbolSet: SymbolSet, solver?: Core | undefined);
    /**
     * The `Solver` object associated with this `SymbolGrid`.
     */
    get solver(): Core;
    /**
     * The `grilops.symbols.SymbolSet` associated with this `SymbolGrid`.
     */
    get symbolSet(): SymbolSet;
    /**
     * The grid of cells.
     */
    get grid(): Map<Point, Arith<Name>>;
    /**
     * The lattice of points in the grid.
     */
    get lattice(): Lattice;
    /**
     * Returns a list of cells that share an edge with the given cell.
     * @param p The location of the given cell.
     * @returns A `Neighbor[]` representing the cells sharing
     * an edge with the given cell.
     */
    edgeSharingNeighbors(p: Point): Neighbor<Name>[];
    /**
     * Returns the cells that share a vertex with the given cell.
     *
     * In other words, returns a list of cells orthogonally and diagonally
     * adjacent to the given cell.
     * @param p The location of the given cell.
     * @returns A `Neighbor[]` representing the cells sharing
     * a vertex with the given cell.
     */
    vertexSharingNeighbors(p: Point): Neighbor<Name>[];
    /**
     * Returns the cell at the given point.
     * @param p The location of the cell.
     * @returns The cell at the given point.
     */
    cellAt(p: Point): Arith<Name>;
    /**
     * Returns an expression for whether this cell contains this value.
     * @param p The location of the given cell.
     * @param value The value to satisfy the expression.
     * @returns An expression that's true if and only if the cell at p contains
     * this value.
     */
    cellIs(p: Point, value: number): Bool<Name>;
    /**
     * Returns an expression for whether this cell contains one of these values.
     * @param p The location of the given cell.
     * @param values The set of values to satisfy the expression.
     * @returns An expression that's true if and only if the cell at p contains
     * one of these values.
     */
    cellIsOneOf(p: Point, values: number[]): Bool<Name>;
    /**
     * Returns true if the puzzle has a solution, false otherwise.
     */
    solve(): Promise<boolean>;
    /**
     * Returns true if the solution to the puzzle is unique, false otherwise.
     *
     * Should be called only after `SymbolGrid.solve` has already completed
     * successfully.
     */
    isUnique(): Promise<boolean>;
    /**
     * Returns the solved symbol grid.
     *
     * Should be called only after `SymbolGrid.solve` has already completed
     * successfully.
     */
    solvedGrid(): Map<Point, number>;
    /**
     * Prints the solved grid using symbol labels.
     *
     * Should be called only after `SymbolGrid.solve` has already completed
     * successfully.
     * @param hookFunction A function implementing custom symbol display
     * behavior, or None. If this function is provided, it will be called for
     * each cell in the grid, with the arguments p (`Point`)
     * and the symbol index for that cell (`number`). It may return a string to
     * print for that cell, or None to keep the default behavior.
     */
    toString(hookFunction?: ((p: Point, i: number) => string) | undefined): string;
}

declare namespace symbols {
    export {
        makeLetterRangeSymbolSet,
        makeNumberRangeSymbolSet,
        Symbol_2 as Symbol,
        SymbolSet
    }
}

/**
 * A set of markings that may be filled into a `grilops.grids.SymbolGrid`.
 */
export declare class SymbolSet {
    private _indexToSymbol;
    private _labelToSymbolIndex;
    readonly indices: Record<string, number>;
    /**
     * @param symbols A list of specifications for the symbols. Each specification
     * may be a code-safe name, a (code-safe name, printable label) tuple, or
     * a (code-safe name, printable label, index value) tuple.
     */
    constructor(symbols: (string | [string, string] | [string, string, number])[]);
    private _nextUnusedIndex;
    /**
     * Appends an additional symbol to this symbol set.
     * @param name The code-safe name of the symbol.
     * @param label The printable label of the symbol.
     */
    append(name?: string | undefined, label?: string | undefined): void;
    /**
     * Returns the minimum index value of all of the symbols.
     */
    minIndex(): number;
    /**
     * Returns the maximum index value of all of the symbols.
     */
    maxIndex(): number;
    /**
     * The map of all symbols.
     */
    get symbols(): Map<number, Symbol_2>;
    toString(): string;
}

/**
 * A vector representing an offset in two dimensions.
 */
export declare class Vector {
    /**
     * The relative distance in the y dimension.
     */
    dy: number;
    /**
     * The relative distance in the x dimension.
     */
    dx: number;
    constructor(dy: number, dx: number);
    /**
     * Returns a vector that's the negation of this one.
     */
    negate(): Vector;
    /**
     * Translates this vector's endpoint in the given direction.
     */
    translate(other: Vector): Vector;
    toString(): VectorString;
    static fromString(s: VectorString): Vector;
    equals(other: Vector): boolean;
    static comparator(a: Vector, b: Vector): number;
}

export declare const VectorMap: KeyedMapConstructor<Vector>;

export declare const VectorSet: KeyedSetConstructor<Vector>;

export declare type VectorString = `V(${string},${string})`;

export declare function zip<T1, T2>(a: T1[], b: T2[]): [T1, T2][];

export declare function zip<T1, T2, T3>(a: T1[], b: T2[], c: T3[]): [T1, T2, T3][];

export declare function zip<T>(...args: T[][]): T[][];

export { }
