API Reference¶
chess.board
¶
# Definitions and theorems about a chess board
## Summary
The chess board is a set of indexed piece`s on a `playfield. A board is valid, and can only be constructed, if all the pieces are present on the board, and no two distinct (by index) pieces share the same position on the board.
## Main definitions
1. The board itself, which requires an indexed vector of piece`s, and the `playfield which will serve as the where those pieces are placed. Additionally, all pieces must be present on the playfield, and no two distinct (by index) pieces can share a position on the playfield.
2. A way to reduce the board, following the indices to just the pieces. This allows comparison of boards that are equivalent modulo permutation of indices that point to equivalent pieces.
## Implementation notes
1. A board requires finite dimensions for the playfield, finite indices, and a finite piece set. Ideally, this should be generizable to potentially infinite types. However, since playfield`s are usually provided by `matrix, which is restricted to finite dimensions, it is easiest to define the board as finite. Additionally, to perform position math, more constraints on the dimension types will likely be necessary, like decidable_linear_order.
2. The requirement of decidable_eq on the dimensions and index allows use of dec_trivial to automatically infer proofs for board constraint propositions. That means instantiation of a board will not require explicit proofs for the propositions.
3. The board does not define what are valid position comparisons – the geometry of the space is not defined other than what the playfield provides.
4. Currently, all pieces are constrained by the definition of a board to be present on the playfield. That means no capturing moves and no piece introduction moves are possible.
-
chess.board
A board is axiomatized as a set of indexable (ergo distinguishable) pieces which are placed on distinct squares of a playfield.
-
chess.board.board_repr
A board’s representation is just the concatentation of the representations of the pieces and contents via board_repr_pieces and board_repr_contents, respectively, with newlines inserted for clarity.
-
chess.board.board_repr_contents
A board’s contents can be represented by reducing the board according to the indexed vector at pieces, and placing the pieces on the playfield. We override the default option K representation by using option_wrap, and supply an underscore to represent empty positions.
-
chess.board.board_repr_instance
-
chess.board.board_repr_pieces
A board’s pieces is a “vector”, so vec_repr is used to represent it.
-
chess.board.has_equiv
-
chess.board.has_mem
-
chess.board.height
The height of the board.
-
chess.board.reduce
The state of the board, where pieces of the same type are equivalent
-
chess.board.width
The width of the board.
-
chess.option_wrap
Construct an option_wrapper term from a provided option K and the string that will override the has_repr.repr for none.
-
chess.option_wrapper
An auxiliary wrapper for option K that allows for overriding the has_repr instance for option, and rather, output just the value in the some and a custom provided string for none.
-
chess.wrapped_option_repr
chess.move
¶
-
chess.move
A move is a (distinct) start and end square whose start square is occupied and whose end square is not.
(Captures are not implemented yet.)
-
chess.move.after_occupied_end
End squares are occupied after a move.
-
chess.move.after_unoccupied_start
Start squares are unoccupied after a move.
-
chess.move.before_after_same
Other squares are unchanged after a move.
-
chess.move.before_occupied_start
Start squares are occupied before a move.
-
chess.move.before_unoccupied_end
End squares are unoccupied before a move.
-
chess.move.no_superimpose
Pieces do not become superimposed after a move.
-
chess.move.perform_move
A valid move on a board retains a valid board state.
-
chess.move.piece
The piece that is being moved.
-
chess.move.retains_pieces
Pieces do not disappear after a move.
-
chess.move.start_square_is_some
-
chess.split_eq
chess.piece
¶
Chess piece implementation.
-
chess.black_bishop
-
chess.black_king
-
chess.black_knight
-
chess.black_pawn
-
chess.black_queen
-
chess.black_rook
-
chess.color
-
chess.color.decidable_eq
-
chess.colored_pieces
-
chess.colored_pieces.decidable_eq
-
chess.has_repr
-
chess.piece_repr
-
chess.pieces
-
chess.pieces.decidable_eq
-
chess.white_bishop
-
chess.white_king
-
chess.white_knight
-
chess.white_pawn
-
chess.white_queen
-
chess.white_rook
chess.playfield
¶
# Definitions and theorems about the chess board field
## Summary
The field on which chess pieces are placed is a 2D plane, where each position corresponds to a piece index. This is because we think of defining pieces and moves, usually, by indicating which position they are at, and which position they are moved to.
## Main definitions
The playfield itself (playfield)
Conversion from a matrix of (possibly) occupied spaces to a playfield
Moving a piece by switching the indices at two specified positions using move_piece
## Implementation details
1. The playfield type itself has no requirements to be finite in any dimension, or that the indices used are finite. We represent the actual index wrapped by option, such that the empty square can be an option.none. The playfield definition wraps the two types used to define the dimensions of the board into a pair.
2. In the current implementation, the way to construct a playfield is to provide a matrix. This limits the playfield to a finite 2D plane. Another possible implementation is of a “sparse matrix”, where for each index, we can look up where the piece is. This now allows for an infinite playfield, but still complicates using infinite pieces. For now, the closely-tied matrix definition makes playfield a light type wrapper on top of matrix, i.e. a function of two variables.
3. Currently, move_piece just swaps the (potentially absent) indices at two positions. This is done by using an equiv.swap as an updating function. For now, this means that moves that use move_piece are non-capturing. Additionally, no math or other requirements on the positions or their contents is required. This means that move_piece supports a move from a position to itself. A separate move is defined in chess.move that has more chess-like rule constraints.
4. Index presence on the board is not limited to have each index on at-most-one position. Preventing duplication of indices is not enforced by the playfield itself. However, any given position can hold at-most-one index on it. The actual chess-like rule constraints are in chess.board.
-
matrix_to_playfield
A conversion function to turn a bare matrix into a playfield. A matrix requires the dimensions to be finite.
An example empty 3 × 3 playfield for 4 pieces could be generated by:
matrix_to_playfield (( ![![none, none, none], ![none, none, none], ![none, none, none]] : matrix (fin 3) (fin 3) (option (fin 4))
where the positions are 0-indexed, with the origin in the top-left, first dimension for the row, and second dimension for the column (0,0) (0,1) (0,2) (1,0) (1,1) (1,2) (2,0) (2,1) (2,2)
-
playfield
A playfield m n ι represents a matrix (m × n) option ι, which is a model for a m × n shaped game board where not every square is occupied.
-
playfield.has_mem
A piece, identified by an index, is on the board, if there is any position such that the index at that position is the one we’re inquiring about. Providing a has_mem instance allows using ix ∈ pf for ix : ι, pf : playfield m n ι. This definition does not preclude duplicated indices on the playfield. See “Implementation details”.
-
playfield.inhabited
A playfield is by default inhabited by empty squares everywhere.
-
playfield.matrix_repr
For a matrix ι^(m’ × n’) where the ι has a has_repr instance itself, we can provide a has_repr for the matrix, using vec_repr for each of the rows of the matrix. This definition is used for displaying the playfield, when it is defined via a matrix, likely through notation.
TODO: redefine using a fold + intercalate
-
playfield.matrix_repr_instance
-
playfield.move_piece
Move an (optional) index from start_square to end_square on a playfield, swapping the indices at those squares.
Does not assume anything about occupancy.
-
playfield.move_piece_def
Equivalent to to move_piece, but useful for rewriteing.
-
playfield.move_piece_diff
Moving an (optional) index retains whatever (optional) indices were at other squares.
-
playfield.move_piece_end
Moving an (optional) index that was at end_square places it at start_square
-
playfield.move_piece_start
Moving an (optional) index that was at start_square places it at end_square
-
playfield.playfield_repr_instance
-
playfield.vec_repr
For a “vector” ι^n’ represented by the type Π n’ : ℕ, fin n’ → ι, where the ι has a has_repr instance itself, we can provide a has_repr for the “vector”. This definition is used for displaying rows of the playfield, when it is defined via a matrix, likely through notation.
TODO: redefine using a fold + intercalate
-
playfield.vec_repr_instance
guarini
¶
“Proof” of Guarini’s Problem: swapping some knights.
Given a board like:
♞ _ ♞ _ _ _ ♘ _ ♘
Guarini’s problem asks for a sequence of moves that swaps the knights, producing:
♘ _ ♘ _ _ _ ♞ _ ♞
Solution:
♞ _ ♞ ♞ _ ♞ ♞ _ _ ♞ _ ♘ _ _ ♘
_ _ _ → ♘ _ _ → ♘ _ _ → _ _ _ → _ _ ♞
♘ _ ♘ ♘ _ _ ♘ ♞ _ ♘ ♞ _ ♘ ♞ _
_ ♘ ♘ _ _ ♘ _ _ ♘ _ _ ♘
→ _ _ ♞ → _ _ ♞ → ♘ _ ♞ → ♘ _ _
_ ♞ _ _ ♞ ♘ _ ♞ _ ♞ ♞ _
_ ♞ ♘ ♞ ♞ ♘ _ ♞ ♘ _ ♞ _
→ ♘ _ _ → ♘ _ _ → ♘ _ ♞ → ♘ _ ♞
_ ♞ _ _ _ _ _ _ _ _ ♘ _
♘ ♞ _ ♘ ♞ ♘ ♘ ♞ ♘ ♘ _ ♘
→ ♘ _ ♞ → _ _ ♞ → _ _ _ → _ _ _
_ _ _ _ _ _ ♞ _ _ ♞ _ ♞
-
ending_position
-
first_move
-
guarini_position
-
guarini_seq
-
guarini_seq.scan_contents
-
starting_position
-
vector.scanl
-
vector.scanr