API Reference¶
chess.board¶
Definitions and theorems about a chess board¶
Summary¶
The chess board is a set of indexed pieces 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¶
The
boarditself, which requires an indexed vector ofpieces, and theplayfieldwhich 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.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.
board.piece_at, which extracts the piece which sits on a given square.
Implementation notes¶
A
boardrequires finite dimensions for theplayfield, finite indices, and a finite piece set. Ideally, this should be generizable to potentially infinite types. However, sinceplayfields are usually provided bymatrix, which is restricted to finite dimensions, it is easiest to define the board as finite.The requirement of
decidable_eqon the dimensions and index allows use ofdec_trivialto automatically infer proofs for board constraint propositions. That means instantiation of aboardwill not require explicit proofs for the propositions.The board does not define what are valid position comparisons – the geometry of the space is not defined other than what the
playfieldprovides.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.
- constant chess.board
A board is axiomatized as a set of indexable (ergo distinguishable) pieces which are placed on distinct squares of a
playfield.No inhabited instance because the index type can be larger than the cardinality of the playfield dimensions.
Fields:
- field pieces
- field contents
- field contains
- field injects
- def board_repr
A board’s representation is just the concatentation of the representations of the
piecesandcontentsviaboard_repr_piecesandboard_repr_contents, respectively, with newlines inserted for clarity.
- def board_repr_contents
A board’s
contentscan be represented by reducing the board according to the indexed vector atpieces, and placing the pieces on theplayfield. We override the defaultoption Krepresentation by usingoption_wrap, and supply an underscore to represent empty positions.
- def board_repr_instance
A board’s representation is provided by
board_repr.
- def board_repr_pieces
A board’s
piecesis a “vector”, sovec_repris used to represent it.
- def contents_decidable
Explicitly state that the proposition that an index
ix : ιis in the board isdecidable, when theιis itselfdecidable_eq.
- def has_equiv
- def has_mem
- def height
The height of the board. Explicit argument for projection notation.
- theorem inj_iff
Given that the board is
occupied_atsomepos : m × n, then the index at somepos' : m × nis equal to the index atpos, iff thatpos'is equalpos' = pos.
- theorem no_superimposed
A board maps each index
ix : ιto a unique positionpos : m × n, stated explicitly. Uses theboard.injectsconstraint.
- def piece_at
The (colored)
pieceon a given square.
- def reduce
The state of the board, where pieces of the same type are equivalent
- theorem retains_pieces
A board contains all of the
ix : ιindices that it knows of, stated explicitly. Uses theboard.containsconstraint.
- def width
The width of the board. Explicit argument for projection notation.
chess.move¶
Definitions and theorems about chess board movements¶
Summary¶
A move on a particular board is a pair of squares whose start
square contains a piece and whose end square does not.
Moves may be combined into sequences of moves, which encapsulate
multiple sequential moves all iteratively satisfying the above
condition.
Main definitions¶
The
moveitself, which requires specifying the particularboardit will occur onperform_move, which yields theboardwhose playfield has the start and end squares of amovesuitably modifiedA move
sequence, rooted on a starting board, containing a sequence of start and end squares which can be treated as iterated moves.
Implementation notes¶
moveandsequenceare implemented independently of each other.sequence.movescan be used to extract amovefrom a particular index into asequence.sequences are also currently finite, and therefore also may automatically infer proofs of move conditions viadec_trivial.Currently, no legality checks or piece math whatsoever is performed, meaning
moves are not yet programmatically confirmed to be legal. Captures are similarly not yet supported.
- def chess.board.has_sequence_len
Assert the existence of a
sequenceof lengthofrom astart_boardto a given end board.
- def chess.board.has_sequence_to
Assert the existence of a
sequencefrom astart_boardto a given end board.
- constant chess.move
A move is a (distinct) start and end square whose start square is occupied and whose end square is not.
No inhabited instance because the board might be made up of a single occupied position.
(Captures are not implemented yet.)
Fields:
- field start_square
- field end_square
- field occupied_start
- field unoccupied_end
- theorem after_occupied_end
End squares are occupied after a move.
- theorem after_unoccupied_start
Start squares are unoccupied after a move.
- theorem before_after_same
Other squares are unchanged after a move.
- theorem before_after_same_occupied
Other occupation are unchanged after a move.
- theorem before_occupied_start
Start squares are occupied before a move.
- theorem before_unoccupied_end
End squares are unoccupied before a move.
- def decidable_eq
- theorem diff_squares
The start and end squares of a move are distinct.
- def fintype
- theorem no_superimposed
Pieces do not become superimposed after a move.
- def perform_move
A valid
moveon aboardretains a valid board state.
- def piece
The piece that is being moved.
- theorem retains_injectivity
A
moveretains accesing indices injectively on theboardit operates on.
- theorem retains_surjectivity
A
moveretains all indices, ignoring empty squares, present on theboardit operates on.
- def scan_contents
Define the mapping of
playfields after performing successivemove_pieces using the pairs of positions in the providedelements, starting from thestart_board.
- constant sequence
A move
sequencerepresents a sequential set of moves from a startingboard.No inhabited instance because boards do not have an inhabited instance.
Fields:
- field start_board
- field elements
- field all_occupied_start'
- field all_unoccupied_end'
- theorem sequence.all_occupied_start
Every scanned board is occupied at the start square of the upcoming move.
- theorem sequence.all_unoccupied_end
Every scanned board is unoccupied at the end square of the upcoming move.
- def sequence.boards
The board which results from applying the first
ix₀ + 1moves in thesequence.
- def sequence.contents_at
Shorthand for referring to the contents at a sequence index
ixₒ : fin (o + 1).
- theorem sequence.contents_at_def
Shorthand for referring to the contents at a sequence index
ixₒ : fin (o + 1).
- def sequence.end_board
The board which results from applying all
moves in thesequence.
- theorem sequence.fixes_unmentioned_squares
Any square which is not the
start_squareorend_squareof anymovein thesequenceis fixed across allmoves (i.e. contains the same piece or remains empty).
- def sequence.moves
The
ix₀’thmovein thesequence.
- theorem sequence.no_superimposed
Pieces do not become superimposed after any
movein asequence.
- theorem sequence.retains_injectivity
Every
playfieldin a sequence of moves injectively accesses the indices.
- theorem sequence.retains_pieces
Pieces do not disappear after any
move_piecein asequence.
- theorem sequence.retains_surjectivity
Every
playfieldin a sequence of moves contains all the indices it can.
- theorem sequence.sequence_step
Any
contents_ata step in thesequenceis the result of performing amove_pieceusing thesequence.elementsat that step.
- theorem sequence.sequence_zero
The first contents in a
scan_contentssequenceis of thestart_board.
chess.move.legal¶
Legal chess move definitions and theorems¶
Summary¶
Legal chess moves are moves which satisfy the legal rules of
chess. This includes both the mathematics of which squares a given
piece type can move to and the broader set of board conditions
that must be satisfied (e.g. not moving a king into check).
Only a subset of these rules are currently implemented below so far. Currently:
knight move math
are what is implemented.
(No chess variants are currently implemented either.)
Main definitions¶
move.is_legal, which can decide whether a givenmoveis legalmove.legal, which represents amovealong with the above proof that themove.is_legalboard.moves_from, which given a position on the providedboard, produces the set of legal moves which may be performed from that square.
Implementation notes¶
moves_fromis currently defined to return afinset, even though in theory topologically one could have boards with infinitely many immediate next squares. This finiteness assumption will eventually need fixing in other places, so it seems safe here for now.The requirement of
decidable_eqon the various types surroundingmove.legalmeans that againdec_trivialcan automatically infer proofs for move legality without them being explicitly provided.
- theorem chess.board.mem_moves_from
The
finsetoflegalmoves from a given square.
- def chess.board.moves_from
The
finsetoflegalmoves from a given square.
- def chess.board.moves_from.fintype
- theorem chess.board.moves_from_def
The
finsetoflegalmoves from a given square.
- def chess.move.adjacent
Two squares
posandpos'are adjacent (i.e. have no square between them).
- def chess.move.adjacent.decidable_pred
- def chess.move.between
The finite set of (presumably squares) between two elements of
m(orn).
- def chess.move.is_legal
A legal chess move.
- def chess.move.is_legal_decidable
- def chess.move.knight_move
A legal knight move moves 2 squares in one direction and 1 in the other.
- def chess.move.knight_move.decidable_pred
- constant chess.move.legal
A legal move is a
movealong with a proof that the move satisfies the rules of chess.Fields:
- field to_move
- field legality
- def fintype
- def chess.move.one_gap
Two squares
posandpos'have exactly one square between them.
- def chess.move.one_gap.decidable_pred
- constant chess.move.sequence.legal
Fields:
- field to_sequence
- field legality
- theorem chess.moves_from.unoccupied_zero
There are 0
legalmoves from an unoccupied square.
chess.piece¶
Chess piece implementation.
- def chess.black_bishop
- def chess.black_king
- def chess.black_knight
- def chess.black_pawn
- def chess.black_queen
- def chess.black_rook
- constant chess.color
- def chess.color.decidable_eq
- def chess.color.fintype
- constant chess.colored_piece
Fields:
- field piece
- field color
- def chess.colored_piece.decidable_eq
- def chess.colored_piece.fintype
- def chess.has_coe
“Forget” a piece’s color.
- def chess.has_repr
- constant chess.piece
- def decidable_eq
- def fintype
- def chess.piece_repr
- def chess.white_bishop
- def chess.white_king
- def chess.white_knight
- def chess.white_pawn
- def chess.white_queen
- def 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
matrixof (possibly) occupied spaces to aplayfieldMoving a piece by switching the indices at two specified positions using
move_pieceMaking a sequence of moves at once using
move_sequence
Implementation details¶
The
playfieldtype itself has no requirements to be finite in any dimension, or that the indices used are finite. We represent the actual index wrapped byoption, such that the empty square can be anoption.none. The playfield definition wraps the two types used to define the dimensions of the board into a pair.In the current implementation, the way to construct a
playfieldis to provide a matrix. This limits theplayfieldto 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-tiedmatrixdefinition makesplayfielda light type wrapper on top ofmatrix, i.e. a function of two variables.Currently,
move_piecejust swaps the (potentially absent) indices at two positions. This is done by using anequiv.swapas an updating function. For now, this means that moves that usemove_pieceare non-capturing. Additionally, no math or other requirements on the positions or their contents is required. This means thatmove_piecesupports a move from a position to itself. A separatemoveis defined inchess.movethat has more chess-like rule constraints.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
playfielditself. However, any given position can hold at-most-one index on it. The actual chess-like rule constraints are inchess.board.Sequences of moves are implemented on top of
moves, rather than vice versa (moves being defined as sequences of length one). This probably causes a bit of duplication, which may warrant flipping things later.
- def matrix_to_playfield
A conversion function to turn a bare
matrixinto aplayfield. Amatrixrequires 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)
- def playfield
A
playfield m n ιrepresents amatrix (m × n) option ι, which is a model for am × nshaped game board where not every square is occupied.
- theorem playfield.coe_occ_val
A
pos : pf.occupied_positionscan be used as apos : m × n.
- def playfield.decidable_pred
The predicate that
pf.occupied_at posfor some pos is decidable if the indicesix : ιare finite and decidably equal.
- theorem playfield.exists_of_occupied
A
pos : pf.occupied_positions' has the property that there is an not-necessarily-uniqueix : ιsuch thatpf pos = some ix`.
- theorem playfield.exists_unique_of_occupied
A
pos : pf.occupied_positions' has the property that there is a necessarily-uniqueix : ιsuch thatpf pos = some ix`.
- theorem playfield.finite_occupied
When the
playfielddimensions are all finite, theoccupied_positions_setof all positions that areoccupied_atis afintype.
- def playfield.fintype
- def playfield.fintype_occupied
When the
playfielddimensions are all finite, theoccupied_positions_setof all positions that areoccupied_atis finite.
- def playfield.has_coe
- def 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_meminstance allows usingix ∈ pfforix : ι, pf : playfield m n ι. This definition does not preclude duplicated indices on the playfield. See “Implementation details”.
- def playfield.index_at
Extract the
ix : ιthat is atpf pos = some ix.
- theorem playfield.index_at.implies_surjective
Index retrieval via
pfis known to be surjective, given an surjectivity condition viafunction.surjective pf.index_atand an unoccupied square somewhere.
- theorem playfield.index_at.injective
Index retrieval via
pf.index_atis known to be injective, given an injectivity condition viapf.some_injective.
- theorem playfield.index_at.surjective
Index retrieval via
pf.index_atis known to be surjective, given an surjectivity condition viafunction.surjective pf.
- theorem playfield.index_at_def
Extract the
ix : ιthat is atpf pos = some ix.
- theorem playfield.index_at_exists
The index retrieved via
pf.index_atis known to be in thepf, in existential format.
- theorem playfield.index_at_exists'
The index retrieved via
pf.index_atis known to be in thepf, in existential format, operating on thepf.occupied_positionssubtype.
- theorem playfield.index_at_iff
For a
pos : pf.occupied_positions, the wrapped indexix : ιgiven bypf.index_at posis preciselypf pos, in iff form.
- theorem playfield.index_at_in
The index retrieved via
pf.index_atis known to be in thepf.
- theorem playfield.index_at_inj
Index retrieval via
pf.index_atis known to be injective, given an injectivity condition viapf.some_injective.
- theorem playfield.index_at_inv_pos_from'
Given a surjectivity condition of
pf.index_at, and an injectivity condition ofpf.some_injective, the right inverse ofpf.index_atispf.pos_from'.
- theorem playfield.index_at_mk
For a
pos : m × n, and the hypothesis thath : pf pos = some ix, the index given bypf.index_at (occupied_positions.mk _ h)is preciselyix.
- theorem playfield.index_at_retains_surjectivity
If every index and the empty square is present in the
pf : playfield m n ι, as given by afunction.surjective pfproposition, then each index is present on the playfield after amove_piece.
- theorem playfield.index_at_some
For a
pos : pf.occupied_positions, the wrapped index given bypf.index_at posis preciselypf pos.
- def playfield.index_equiv
Given a surjectivity condition of
pf.index_at, and an injectivity condition ofpf.some_injective, there is an explicit equivalence from the indicesιto the type of positions inpf.occupied_positions.
- def playfield.inhabited
A
playfieldis by defaultinhabitedby empty squares everywhere.
- theorem playfield.inj_iff
When a
pf : playfield m n ιissome_injective, if it is occupied at somepos : m × n, then it is injective at thatpos.
- theorem playfield.inj_on_occupied
The injectivity of
some_injectiveis equivalent to theset.inj_onproposition.
- theorem playfield.injective
When a
pf : playfield m n ιissome_injective, if it is not empty at somepos : m × n, then it is injective at thatpos.
- def playfield.move_piece
Move an (optional) index from
start_squaretoend_squareon aplayfield, swapping the indices at those squares.Does not assume anything about occupancy.
- theorem playfield.move_piece_def
Equivalent to to
move_piece, but useful forrewriteing.
- theorem playfield.move_piece_diff
Moving an (optional) index retains whatever (optional) indices that were at other squares.
- theorem playfield.move_piece_end
Moving an (optional) index that was at
end_squareplaces it atstart_square
- theorem playfield.move_piece_occupied_diff
The
pf : playfield m n ιisoccupied_at other_squareafter amove_piece, for aposthat is neitherstart_squarenorend_square, iff it isoccupied_at other_squarebefore the piece move.
- theorem playfield.move_piece_occupied_end
The
pf : playfield m n ιisoccupied_at end_squareafter amove_pieceiff it isoccupied_at start_squarebefore the piece move.
- theorem playfield.move_piece_occupied_start
The
pf : playfield m n ιisoccupied_at start_squareafter amove_pieceiff it isoccupied_at end_squarebefore the piece move.
- theorem playfield.move_piece_start
Moving an (optional) index that was at
start_squareplaces it atend_square
- def playfield.move_sequence
Make a sequence of
moves all at once.
- theorem playfield.move_sequence_def
Equivalent to to
move_sequence, but useful forrewriteing.
- theorem playfield.move_sequence_diff
Throughout a sequence, moving an (optional) index retains whatever (optional) indices that were at other squares on the next board.
- theorem playfield.move_sequence_end
Throughout a sequence, moving an (optional) index that was at
end_squareplaces it atstart_squareon the next board.
- theorem playfield.move_sequence_start
Throughout a sequence, moving an (optional) index that was at
start_squareplaces it atend_squareon the next board.
- theorem playfield.nonempty_pos
Given a surjectivity condition of
pf.index_at, the type ofpos : pf.occupied_positionsthat identify a particular index is a nonempty.
- theorem playfield.not_occupied_at_iff
A
pos : m × nis unoccupied iff it isnone.
- theorem playfield.not_occupied_has_none
If for some
pf : playfield m n ι, atpos : m × n,pf pos = none, then that is equivalent to¬ pf.occupied_at pos.
- def playfield.occ_set_decidable
The predicate that
λ p, p ∈ pf.occupied_position_setfor some pos is decidable if the indicesix : ιare finite and decidably equal.
- def playfield.occupied_at
A wrapper to indicate that there is some
ix : ιsuch that for apf : playfield m n ι, atpos : m × n,pf pos = some ix.
- theorem playfield.occupied_at_def
A wrapper to indicate that there is some
ix : ιsuch that for apf : playfield m n ι, atpos : m × n,pf pos = some ix.
- theorem playfield.occupied_at_iff
A wrapper to indicate that there is some
ix : ιsuch that for apf : playfield m n ι, atpos : m × n,pf pos = some ix.
- theorem playfield.occupied_at_of_ne
If for some
pf : playfield m n ι, atpos : m × n,pf pos ≠ none, then that is equivalent topf.occupied_at pos.
- theorem playfield.occupied_at_of_some
If for some
pf : playfield m n ι, atpos : m × n,pf pos = some ix, then that is equivalent topf.occupied_at pos.
- theorem playfield.occupied_at_transfer
If for some
pf : playfield m n ι, atpos : m × n,pf.occupied_at pos, then for apos' : m × nsuch thatpf pos = pf pos', we have thatpf.occupied_at pos'.
- theorem playfield.occupied_at_unique
A
pf : playfield m n ιmaps any occupiedposuniquely.
- def playfield.occupied_fintype
The
occupied_positionsof apf : playfield m n ιare finite if the dimensions of the playfield and the indices are finite.
- theorem playfield.occupied_has_not_none
A wrapper API for converting between inequalities and existentials.
- theorem playfield.occupied_has_some
A wrapper API for underlying
option.is_somepropositions.
- theorem playfield.occupied_is_some
A
pos : pf.occupied_positions'has the property thatpf posis occupied.
- def playfield.occupied_position_finset
The
finsetof all positions that areoccupied_at, when all the dimensions of theplayfieldarefintype.
- def playfield.occupied_positions
The
setof all positions that areoccupied_at.
- def playfield.occupied_positions.mk
Given some
ix : ιsuch that forpf : playfield m n ιandpos : m × n,pf pos = some ix, we can subtype intopos : pf.occupied_positions.
- theorem playfield.occupied_positions_def
Given some
ix : ιsuch that forpf : playfield m n ιandpos : m × n,pf pos = some ix, we can subtype intopos : pf.occupied_positions.
- theorem playfield.occupied_positions_in
The
pos : m × nthat is inpf.occupied_positionsby definition is the proposition thatpf.occupied_at pos.
- theorem playfield.occupied_some_injective
The injectivity of
pf.some_injectiveextends to thepf.occupied_positionssubtype.
- theorem playfield.occupied_unique_of_injective
The index retrieved via
pf.index_atis known to be unique in thepf, given an injectivity condition viapf.some_injective.
- def playfield.playfield_decidable_in
- def playfield.playfield_repr_instance
- def playfield.pos_from
Given a surjectivity condition of
pf.index_at, and an injectivity condition ofpf.some_injective, the type there exists apos : m × n' such thatpf pos = some ix`.
- def playfield.pos_from'
Given a surjectivity condition of
pf.index_at, and an injectivity condition ofpf.some_injective, we can retrieve thepos : pf.occupied_positionssuch thatpf.index_at pos = ix.
- theorem playfield.pos_from.injective
Given a surjectivity condition of
pf.index_at, and an injectivity condition ofpf.some_injective, the functionpf.pos_fromis injective.
- theorem playfield.pos_from_at
Given a surjectivity condition of
pf.index_at, and an injectivity condition ofpf.some_injective, round-tripping to get thepf (pf.pos_from ix _ _)is exactlysome ix,
- theorem playfield.pos_from_at'
Given a surjectivity condition of
pf.index_at, and an injectivity condition ofpf.some_injective, round-tripping to get thepf (pf.pos_from' ix _ _)is exactlysome ix, which goes through the coercion down topos : m × n.
- def playfield.pos_from_aux
A helper subtype definition describing all the positions that match an index.
No inhabited instance exists because the type could be empty, if none of the positions of the playfield have this index.
- theorem playfield.pos_from_aux_subtype
A helper subtype definition describing all the positions that match an index.
- def playfield.pos_from_auxf
A helper finset definition describing all the positions that match an index.
- theorem playfield.pos_from_auxf_finset
A helper finset definition describing all the positions that match an index.
- theorem playfield.pos_from_auxf_in
A helper finset definition describing all the positions that match an index.
- theorem playfield.pos_from_auxf_set
A helper set definition describing all the positions that match an index.
- theorem playfield.pos_from_def
Given a surjectivity condition of
pf.index_at, and an injectivity condition ofpf.some_injective, the type there exists apos : m × n' such thatpf pos = some ix`.
- theorem playfield.pos_from_def'
Given a surjectivity condition of
pf.index_at, and an injectivity condition ofpf.some_injective, we can retrieve thepos : pf.occupied_positionssuch thatpf.index_at pos = ix.
- theorem playfield.pos_from_index_at'
Given a surjectivity condition of
pf.index_at, and an injectivity condition ofpf.some_injective, round-tripping to get thepf.index_at (pf.pos_from' ix _ _)is exactlyix.
- theorem playfield.pos_from_inv
Given a surjectivity condition of
pf.index_at, and an injectivity condition ofpf.some_injective, the partial inverse ofpf.pos_fromispfitself.
- theorem playfield.pos_from_inv_index_at'
Given a surjectivity condition of
pf.index_at, and an injectivity condition ofpf.some_injective, the left inverse ofpf.index_atispf.pos_from'.
- theorem playfield.pos_from_occupied
Given a surjectivity condition of
pf.index_at, and an injectivity condition ofpf.some_injective, the position retrieved viapf.pos_frommeans that thepfisoccupied_atit.
- theorem playfield.retains_injectivity
Each index that is present on the playfield and appears only once, appears only once after a
move_piece.
- theorem playfield.retains_pieces
Pieces do not disappear after a
move_piece.
- theorem playfield.retains_surjectivity
If every index and the empty square is present in the
pf : playfield m n ι, as given by afunction.surjective pfproposition, then each index is present on the playfield after amove_piece.
- def playfield.some_injective
A
playfieldon which every index that appears, appears only once.
- def playfield.some_injective_decidable
Explicitly state that the proposition that
pf.some_injectiveisdecidable, when theιis itselfdecidable_eq.
- theorem playfield.subsingleton_pos
Given an injectivity condition of
pf.some_injective, the type ofpos : pf.occupied_positionsthat identify a particular index is a subsingleton.
- theorem playfield.unique_of_injective
When a
pf : playfield m n ιissome_injective, every indexix : ι ∈ pfexists in thepfuniquely.
- theorem playfield.unique_of_occupied
When a
pf : playfield m n ιissome_injective, everypos : pf.occupied_positionsmaps to a unique index viapf pos.
- theorem playfield.unique_pos
Given a surjectivity condition of
pf.index_at, and an injectivity condition ofpf.some_injective, the type ofpos : pf.occupied_positionsthat identify a particular index is a unique.
chess.utils¶
Helpers that don’t currently fit elsewhere…
- def matrix_repr
For a
matrixX^(m' × n')where theXhas ahas_reprinstance itself, we can provide ahas_reprfor the matrix, usingvec_reprfor each of the rows of the matrix. This definition is used for displaying the playfield, when it is defined via amatrix, likely through notation.
- def matrix_repr_instance
- def option_wrap
Construct an
option_wrapperterm from a providedoption Xand thestringthat will override thehas_repr.reprfornone.
- constant option_wrapper
An auxiliary wrapper for
option Xthat allows for overriding thehas_reprinstance foroption, and rather, output just the value in thesomeand a custom providedstringfornone.Fields:
- field val
- field none_s
- def vec_repr
For a “vector”
X^n'represented by the typeΠ n' : ℕ, fin n' → X, where theXhas ahas_reprinstance itself, we can provide ahas_reprfor the “vector”. This definition is used for displaying rows of the playfield, when it is defined via amatrix, likely through notation.
- def vec_repr_instance
- def wrapped_option_repr
- theorem split_eq
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:
♞ _ ♞ ♞ _ ♞ ♞ _ _ ♞ _ ♘ _ _ ♘
_ _ _ → ♘ _ _ → ♘ _ _ → _ _ _ → _ _ ♞
♘ _ ♘ ♘ _ _ ♘ ♞ _ ♘ ♞ _ ♘ ♞ _
_ ♘ ♘ _ _ ♘ _ _ ♘ _ _ ♘
→ _ _ ♞ → _ _ ♞ → ♘ _ ♞ → ♘ _ _
_ ♞ _ _ ♞ ♘ _ ♞ _ ♞ ♞ _
_ ♞ ♘ ♞ ♞ ♘ _ ♞ ♘ _ ♞ _
→ ♘ _ _ → ♘ _ _ → ♘ _ ♞ → ♘ _ ♞
_ ♞ _ _ _ _ _ _ _ _ ♘ _
♘ ♞ _ ♘ ♞ ♘ ♘ ♞ ♘ ♘ _ ♘
→ ♘ _ ♞ → _ _ ♞ → _ _ _ → _ _ _
_ _ _ _ _ _ ♞ _ _ ♞ _ ♞
- def ending_position
- def first_move
- theorem guarini
- def guarini_seq
- def starting_position