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¶
The
board
itself, which requires an indexed vector ofpiece
s, and theplayfield
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.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
board
requires finite dimensions for theplayfield
, finite indices, and a finite piece set. Ideally, this should be generizable to potentially infinite types. However, sinceplayfield
s are usually provided bymatrix
, which is restricted to finite dimensions, it is easiest to define the board as finite.The requirement of
decidable_eq
on the dimensions and index allows use ofdec_trivial
to automatically infer proofs for board constraint propositions. That means instantiation of aboard
will 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
playfield
provides.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
pieces
andcontents
viaboard_repr_pieces
andboard_repr_contents
, respectively, with newlines inserted for clarity.
- def board_repr_contents
A board’s
contents
can be represented by reducing the board according to the indexed vector atpieces
, and placing the pieces on theplayfield
. We override the defaultoption K
representation 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
pieces
is a “vector”, sovec_repr
is 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_at
somepos : m × n
, then the index at somepos' : m × n
is 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.injects
constraint.
- def piece_at
The (colored)
piece
on 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.contains
constraint.
- 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 sequence
s of moves, which encapsulate
multiple sequential moves all iteratively satisfying the above
condition.
Main definitions¶
The
move
itself, which requires specifying the particularboard
it will occur onperform_move
, which yields theboard
whose playfield has the start and end squares of amove
suitably 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¶
move
andsequence
are implemented independently of each other.sequence.moves
can be used to extract amove
from a particular index into asequence
.sequence
s 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
move
s 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
sequence
of lengtho
from astart_board
to a given end board.
- def chess.board.has_sequence_to
Assert the existence of a
sequence
from astart_board
to 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
move
on aboard
retains a valid board state.
- def piece
The piece that is being moved.
- theorem retains_injectivity
A
move
retains accesing indices injectively on theboard
it operates on.
- theorem retains_surjectivity
A
move
retains all indices, ignoring empty squares, present on theboard
it operates on.
- def scan_contents
Define the mapping of
playfield
s after performing successivemove_piece
s using the pairs of positions in the providedelements
, starting from thestart_board
.
- constant sequence
A move
sequence
represents 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₀ + 1
move
s 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
move
s in thesequence
.
- theorem sequence.fixes_unmentioned_squares
Any square which is not the
start_square
orend_square
of anymove
in thesequence
is fixed across allmove
s (i.e. contains the same piece or remains empty).
- def sequence.moves
The
ix₀
’thmove
in thesequence
.
- theorem sequence.no_superimposed
Pieces do not become superimposed after any
move
in asequence
.
- theorem sequence.retains_injectivity
Every
playfield
in a sequence of moves injectively accesses the indices.
- theorem sequence.retains_pieces
Pieces do not disappear after any
move_piece
in asequence
.
- theorem sequence.retains_surjectivity
Every
playfield
in a sequence of moves contains all the indices it can.
- theorem sequence.sequence_step
Any
contents_at
a step in thesequence
is the result of performing amove_piece
using thesequence.elements
at that step.
- theorem sequence.sequence_zero
The first contents in a
scan_contents
sequence
is of thestart_board
.
chess.move.legal
¶
Legal chess move definitions and theorems¶
Summary¶
Legal chess move
s 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 givenmove
is legalmove.legal
, which represents amove
along with the above proof that themove.is_legal
board.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_from
is 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_eq
on the various types surroundingmove.legal
means that againdec_trivial
can automatically infer proofs for move legality without them being explicitly provided.
- theorem chess.board.mem_moves_from
The
finset
oflegal
moves from a given square.
- def chess.board.moves_from
The
finset
oflegal
moves from a given square.
- def chess.board.moves_from.fintype
- theorem chess.board.moves_from_def
The
finset
oflegal
moves from a given square.
- def chess.move.adjacent
Two squares
pos
andpos'
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
move
along 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
pos
andpos'
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
legal
moves 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
matrix
of (possibly) occupied spaces to aplayfield
Moving a piece by switching the indices at two specified positions using
move_piece
Making a sequence of moves at once using
move_sequence
Implementation details¶
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 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
playfield
is to provide a matrix. This limits theplayfield
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-tiedmatrix
definition makesplayfield
a light type wrapper on top ofmatrix
, i.e. a function of two variables.Currently,
move_piece
just swaps the (potentially absent) indices at two positions. This is done by using anequiv.swap
as an updating function. For now, this means that moves that usemove_piece
are non-capturing. Additionally, no math or other requirements on the positions or their contents is required. This means thatmove_piece
supports a move from a position to itself. A separatemove
is defined inchess.move
that 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
playfield
itself. 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
move
s, rather than vice versa (move
s 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
matrix
into aplayfield
. Amatrix
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)
- def playfield
A
playfield m n ι
represents amatrix (m × n) option ι
, which is a model for am × n
shaped game board where not every square is occupied.
- theorem playfield.coe_occ_val
A
pos : pf.occupied_positions
can be used as apos : m × n
.
- def playfield.decidable_pred
The predicate that
pf.occupied_at pos
for 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-unique
ix : ιsuch that
pf pos = some ix`.
- theorem playfield.exists_unique_of_occupied
A
pos : pf.occupied_positions' has the property that there is a necessarily-unique
ix : ιsuch that
pf pos = some ix`.
- theorem playfield.finite_occupied
When the
playfield
dimensions are all finite, theoccupied_positions_set
of all positions that areoccupied_at
is afintype
.
- def playfield.fintype
- def playfield.fintype_occupied
When the
playfield
dimensions are all finite, theoccupied_positions_set
of all positions that areoccupied_at
is 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_mem
instance allows usingix ∈ pf
forix : ι, 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
pf
is known to be surjective, given an surjectivity condition viafunction.surjective pf.index_at
and an unoccupied square somewhere.
- theorem playfield.index_at.injective
Index retrieval via
pf.index_at
is known to be injective, given an injectivity condition viapf.some_injective
.
- theorem playfield.index_at.surjective
Index retrieval via
pf.index_at
is 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_at
is known to be in thepf
, in existential format.
- theorem playfield.index_at_exists'
The index retrieved via
pf.index_at
is known to be in thepf
, in existential format, operating on thepf.occupied_positions
subtype.
- theorem playfield.index_at_iff
For a
pos : pf.occupied_positions
, the wrapped indexix : ι
given bypf.index_at pos
is preciselypf pos
, in iff form.
- theorem playfield.index_at_in
The index retrieved via
pf.index_at
is known to be in thepf
.
- theorem playfield.index_at_inj
Index retrieval via
pf.index_at
is 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_at
ispf.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 pf
proposition, 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 pos
is 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
playfield
is by defaultinhabited
by 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_injective
is equivalent to theset.inj_on
proposition.
- 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_square
toend_square
on 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 forrewrite
ing.
- 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_square
places it atstart_square
- theorem playfield.move_piece_occupied_diff
The
pf : playfield m n ι
isoccupied_at other_square
after amove_piece
, for apos
that is neitherstart_square
norend_square
, iff it isoccupied_at other_square
before the piece move.
- theorem playfield.move_piece_occupied_end
The
pf : playfield m n ι
isoccupied_at end_square
after amove_piece
iff it isoccupied_at start_square
before the piece move.
- theorem playfield.move_piece_occupied_start
The
pf : playfield m n ι
isoccupied_at start_square
after amove_piece
iff it isoccupied_at end_square
before the piece move.
- theorem playfield.move_piece_start
Moving an (optional) index that was at
start_square
places it atend_square
- def playfield.move_sequence
Make a sequence of
move
s all at once.
- theorem playfield.move_sequence_def
Equivalent to to
move_sequence
, but useful forrewrite
ing.
- 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_square
places it atstart_square
on the next board.
- theorem playfield.move_sequence_start
Throughout a sequence, moving an (optional) index that was at
start_square
places it atend_square
on the next board.
- theorem playfield.nonempty_pos
Given a surjectivity condition of
pf.index_at
, the type ofpos : pf.occupied_positions
that identify a particular index is a nonempty.
- theorem playfield.not_occupied_at_iff
A
pos : m × n
is 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_set
for 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 × n
such thatpf pos = pf pos'
, we have thatpf.occupied_at pos'
.
- theorem playfield.occupied_at_unique
A
pf : playfield m n ι
maps any occupiedpos
uniquely.
- def playfield.occupied_fintype
The
occupied_positions
of 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_some
propositions.
- theorem playfield.occupied_is_some
A
pos : pf.occupied_positions'
has the property thatpf pos
is occupied.
- def playfield.occupied_position_finset
The
finset
of all positions that areoccupied_at
, when all the dimensions of theplayfield
arefintype
.
- def playfield.occupied_positions
The
set
of 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 × n
that is inpf.occupied_positions
by definition is the proposition thatpf.occupied_at pos
.
- theorem playfield.occupied_some_injective
The injectivity of
pf.some_injective
extends to thepf.occupied_positions
subtype.
- theorem playfield.occupied_unique_of_injective
The index retrieved via
pf.index_at
is 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 that
pf 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_positions
such 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_from
is 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 that
pf 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_positions
such 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_from
ispf
itself.
- 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_at
ispf.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_from
means that thepf
isoccupied_at
it.
- 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 pf
proposition, then each index is present on the playfield after amove_piece
.
- def playfield.some_injective
A
playfield
on which every index that appears, appears only once.
- def playfield.some_injective_decidable
Explicitly state that the proposition that
pf.some_injective
isdecidable
, when theι
is itselfdecidable_eq
.
- theorem playfield.subsingleton_pos
Given an injectivity condition of
pf.some_injective
, the type ofpos : pf.occupied_positions
that identify a particular index is a subsingleton.
- theorem playfield.unique_of_injective
When a
pf : playfield m n ι
issome_injective
, every indexix : ι ∈ pf
exists in thepf
uniquely.
- theorem playfield.unique_of_occupied
When a
pf : playfield m n ι
issome_injective
, everypos : pf.occupied_positions
maps 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_positions
that identify a particular index is a unique.
chess.utils
¶
Helpers that don’t currently fit elsewhere…
- def matrix_repr
For a
matrix
X^(m' × n')
where theX
has ahas_repr
instance itself, we can provide ahas_repr
for the matrix, usingvec_repr
for 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_wrapper
term from a providedoption X
and thestring
that will override thehas_repr.repr
fornone
.
- constant option_wrapper
An auxiliary wrapper for
option X
that allows for overriding thehas_repr
instance foroption
, and rather, output just the value in thesome
and a custom providedstring
fornone
.Fields:
- field val
- field none_s
- def vec_repr
For a “vector”
X^n'
represented by the typeΠ n' : ℕ, fin n' → X
, where theX
has ahas_repr
instance itself, we can provide ahas_repr
for 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