The move filter

The move filter provides information about the set of moves that match a given set of criteria:
      move to _ from K // K moves to empty square
      move from P legal // white can move a pawn
      move promote B // bishop promotion next move
      move to . from N // destination squares of N
      move enpassant // enpassant move
      move capture P // P is captured
      move null // null move
      move o-o // kingside castle
      move o-o-o // queenside castle
      move to _ previous // previous move was to an empty square
      move from Pa-d7 promote [BRN] //Underpromotion from Pa-d7
      move pseudolegal from P // pseudolegal to move a P
      move from K to _ //White king moves to empty square
      move from k      //Black king moves
      move previous from R //Previous move was of a white Rook
      move previous null // Previous move was a null move
      move promote N     // Next move is a knight promotion
      move legal enpassant // en passant is legal
      move legal from K castle // White castle is legal
      move from N to a-h8 //white moves to 8th rank
      move previous from [nb] to Q //black minor piece captures queen on previous move
      move promote [RBN] //the next move is underpromotion 
      move from A promote [RBN] // the next move is a white underpromtion
      move promote N captures A // black underpromotes to a knight with capture

As can be seen from the above examples, the move filter has a number of parameters which overall make it the most complex filter in CQL.

Fortunately, most of these parameters are rarely used. The important parameters to know are from and to. Sometimes previous and promote are useful as well.

A move is just a standard chess move: from a square; to a square.

The move filter matches a position if there are any moves that match each parameter to the move filter.

By default, only the moves from the current position that occur in the PGN file itself are considered. This can be modified by using the previous, legal, or pseudolegal parameters.

For example, consider the filter

      move to _ from N

This move filter has two parameters: a to parameter with value _; and a from parameter with value N. A move matches the to _ parameter if the destination of its moving piece is an empty square. A move matches the from N parameter if the moving piece is a white knight. Therefore, the filter will match positions such that the next move is of a white knight to an empty square. In addition, a move filter can return a value.

All the parameters of a move filter are collected together and form the criteria for the move filter. Then, if some move matches the criteria of the move filter, the move filter itself matches the position.

There are four kinds of move filters, each of which examine different classes of moves: ordinary move filters; previous move filters; legal move filters, and pseudolegal move filters.

Kind of move filter Meaning syntax
Ordinary move filter Moves from the current position occuring in the PGN file move
Previous move filter previous move from the current position move previous
Legal move filter legal moves from the current position move legal
Pseudolegal move filter pseudolegal (legal except possibly for check) moves from the current position move pseudolegal

The other parameters determine which of the moves from the class of moves considered match the criteria. The following rules are used:
Parameter nameargumentmeaningexample
from set filter from square move from R
to set filter to square move to a-h8
promote piece designator piece type of promotion move promote B
enpassant none move is enpassant move legal enpassant
enpassantsquare set filter enpassant move captures on specified square move enpassantsquare d1-8
capture set filter move captures on specified square move capture P
primary none move does not start a new variation move primary
secondary none move starts a new variation move secondary
null none null move move null
castle none move is castling move castle
o-o none move is kingside castling move o-o
o-o-o none move is queenside castling move o-o-o

Parameters may be combined in any way, but capture, primary, secondary and promote cannot be used with legal or pseudolegal.

from parameter

Any move in a game has an associated from square attribute which is the square from which the moving piece moved. For example, the move 1.e4 from the start position of a chess game has a from square attribute of e2.

The from square attribute of a castling move is the square from which the moving king moved. The from square attribute of a null move is the square on which the king of the side to move stands.

The from parameter is followed by a set filter denoting a set of squares S . Only moves whose from square attribute lies within S are considered in evaluating the move filter.

For example, move from Kd4 would match any move from a white king on d4.

If from is the first parameter following the keyword move, then the move filter is a set filter whose value is the set of from square attributes of all moves matching the move filter.

to parameter

Any move in a game has an associated to square attribute which is the square to which the moving moved. For example, the move 1.e4 from the start position of a chess game has a to square attribute of e4.

The to square attribute of a castling move is the square to which the moving king moved. The to square attribute of a null move is the square on which the king of the side to move stands.

The to parameter is followed by a set filter denoting a set of squares S . Only moves whose to square attribute lies within S are considered in evaluating the move filter.

For example, move to d4 would match any move to d4.

If to is the first parameter following the keyword move, then the move filter is a set filter whose value is the set of to square attributes of all moves matching the move filter.

capture parameter

Any move in a game has an associated capture square attribute which is the square of a piece that was captured by the move, or the empty set if no piece was capture by the move.

If a move is a capture, the capture square attribute of that move is the same as as the to square attribute of that move unless the move is an enpassant capture.

If capture is the first parameter following the keyword move, then the move filter is a set filter whose value is the set of capture square attributes of all moves matching the move filter.

promote parameter

The argument to the promote parameter must be a piece designator that does not specify any squares explicitly, like R or A or [RBN]. A piece designator like Ra8 is not allowed (use the to paremeter to specify destination squares).

Color is ignored in a promotion parameter: only the piece types of the argument are considered. That is move promote R and move promote r mean the same thing.

Thus, to specify any promotion, use

move promote A

Using move as a set filter

If one of the following three parameters:
  from
  to
  capture
is the first parameter following the keyword move, then the move filter is a set filter. The set that is returned depends on this first parameter.

If the first parameter following move is from, then the value of the move filter is the set of from squares of all moves matching the move filter. If the first parameter following move is to, then the value of the move filter is the set of all to squares of moves matching the move filter. If the first parameter following move is capture, then the value of the move filter is the set of all capture squares of moves matching the move filter.

(This convention is consistent with how the values returned from the pin filter are handled). For example

  #move to K legal>4

is true if there are more than 4 legal moves of the white king in a position.

These values are often used when variations is not set in the CQL header, so that only mainline moves are considered, and thus there is at most one move from the current position. In this case,

 x=move from .

sets the variable x to be the square from which the next move is made. If there is no such move (so that the current position is terminal), x will be set to the empty set.

Likewise,

  y=move to .

sets the variable y to be the destination of the next move, or to the empty set if the current position is terminal.

  k attacks move to . from Q
means that the next move is of the white queen to a square next to the black king.

previous parameter

The previous parameter indicates that only the previous move (the move that reached the current position) is to be considered. Note that there is always exactly one previous move in any position, unless the position is the initial position, in which case there are no previous moves.

When the previous parameter is present, any set filter values of other parameters to the move filter are evaluted in the previous position, not the current position.

Thus, the following filter matches positions that were reached by moving a major piece to an empty square:

    move previous from [QRqr] to _

null moves

A null move is a move that only changes the color to move. It is listed in the PGN as -- and is considered a move by the king of the side to move from and to the same square. A null move matches a parameter with the null parameter.

As an example, the following CQL code matches a white discovered check:

 (A&~move to . previous) attacks k

Here,

move to . previous
is the set of destinations of any move from the previous position. Thus,
~ move to . previous
is the set of squares that were not the destination of the previous move. If any of these squares are a white piece giving check, then that must be a discovered check, which is what the filter checks for.

This technique is used in multiple-discovered-checks.cql, where it finds the following position from a Korolkov study, which contains 12 discovered checks:

Korolkov 1975, after 1. Ba4+
(found from CQL file: multiple-discovered-checks.cql)

Here, the previous move was 1. Bc2-a4. Therefore, the value of move to . previous in the diagrammed position is the single square a4. Thus, the white Rc3 is not in that set, and is giving check, which is why the position matches the filter.

If the legal parameter is specified, all legal moves from a position are considered, subject to the following:
  • In the initial position of the PGN file, en passant is not considered legal by move legal.
  • The King and Rook are considered not to have moved before the initial position when evaluating whether castling is legal move legal

count parameter

The count parameter can only be present if either the legal or the pseudolegal parameter is also present. If the count parameter is present, then:
  • The move filter always matches the position
  • The value of the move filter is the number of matching moves from the position

For example

    move legal count == 1 // only one legal move
    2<=move legal count  // at least 2 legal moves
    move legal from K count == 0 //K cannot move

The last example is equivalent to

    not move legal from K

When counting legal moves, move legal considers two promotion moves that differ only in the type of promoted piece to be identical (because if one of four possible promotions is legal, they all are).

Castling

Castling can be specified with move o-o, move o-o-o or move castle (for kingside or queenside castling). The from and to squares associated to castling are those of the moving king.

An example of the use of the castling move parameters is in castleecho.cql, which seeks games in which two positions differ only in the legality of the same kind of castling. This finds the following study:

Pervakov 1996 after 3...Bg6
(found from CQL file: castleecho.cql)

In the diagrammed position, the natural move for White is 4. a7? which, however fails to 4...B:h7 5. a8Q, leading to the following position

Pervakov 1996, after 5. a8Q (5...o-o!)
(found from CQL file: castleecho.cql)

Black wins with 5...o-o!.

To prevent this defense, instead of 4. a7?, white plays 4. Bg8! Kf8 5. Bh7 Ke8 6. a7 B:h7 7. a8Q leading to an position that looks identical, except that Black's o-o defense is no longer possible:

Pervakov 1996, after 7. a8Q (7...o-o illegal)
(found from CQL file: castleecho.cql)

That the two above diagrammed positions are the same except for castling is expressed in the CQL file as

 source:move legal o-o
  and not move legal o-o

Here, source is a variable bound to the position after 5.a8Q.

source:move legal o-o evaluates the filter move legal o-o at the position source, where it matches because o-o is legal (this uses the colon operator).

The current position, however, is the position after the variation 7. a8Q, and there we see that o-o is not legal.

The comment in the PGN file, target -> move 5(btm)[47] indicates that the current position is bound to the target variable and that it matched when the source variable was the position before black's move 5 in the position indicated by an ID of 47. That position is indeed annotated by id:47 and source, as well as a pointer back to this target position.

comment with move

If a comment filter immediately follows a move filter (unless legal or pseudolegal are specified) then the comment associated with the comment filter is located after each move in the PGN file matching the the move filter. Technically, the associated comment filter is evaluated in the position that is reached after the move is made. See the documentation for comment for more information.

Examples

The move filter is of course used throughout the examples: in averagedistance.cql (with from and to); in bristol-universal.cql, bristol1.cql, and bristol2.cql (with from); in castleecho.cql (with legal and castle); in clearance-delayed.cql (with from and to); in enpassantecho.cql (with legal and enpassant); in excelsior-comment.cql, excelsior-multiple.cql, excelsior-return.cql, excelsior-simple.cql (with from and promote); in forced-moves-both-sides.cql, forced-moves-either-side.cql, forced-moves-white.cql (with legal and count); in idealmate.cql and modelmate.cql (with pseudolegal); in immured.cql (with legal and from); in multiple-discovered-checks.cql (with to and previous); in persistent.cql (with previous, promote, enpassant and castle); in queenpawnpinecho.cql (with primary) among others.