The Position List

A position list (or position filter) is applied to a position and it either matches or it does not. The keywords in the position list determine how the match is performed, and the piece designators define what is matched.

Some keywords themselves take arguments that are lists of positions. Some keywords modify the way other options work perform their matching.

By default, when a position filter matches a position in a game, if the game itself matches then the game is printed out with the word MATCH preceding the position that matches.

Piece designators inside a position

The major work in a position is usually done by its piece designators. Any position list can have 0 or more piece designators. Without any keywords, a position filter matches a position if and only if each piece designator matches that position.

For example, the position list:

(position Ra3 )

will match any position with a white rook on a3. The position list

(position [RQ][a1-8])

will match any position with a white major piece on the a file.

The position list

(position [RQ][a1-8] q[h1-8])

will match any position with a white major piece on the a file and a black queen on the h file.

The position list

(position .d4 id3 U[a1,h1,a8,h8])

will match any position with an empty square on d4, a black minor piece on d3, and a piece 
on one of the corners.

Note that in consequence of this repeating piece designators has no effect. The position lists:

(position R Q)

and

(position R R Q Q)

each match any position with a white rook and a white queen.

Simple keywords in a position list

Some keywords take no arguments. These are called simple keywords. Transform keywords will be discussed in the next section. They are:

:mate

Match only if the position is a mate.

:stalemate

Match only if the position is a stalemate

:wtm

Match only if white is to move

:btm

Match only if black is to move

:variations

Look in the variations to find matches

:variationsonly

Look only in the variations to find matches, not in the main line

:initial

This is the first position in the game or study

:terminal

This is the last position in the game or study

:markall

Do not stop after the first match is found, but keep looking.

:check

One side is in check

:nocheck

Neither side is in check

:noannotate

Do not print "MATCH" when this position list matches a position in the game.

Examples using simple keywords

This position list


(position R Q :mate)

matches a position with a white rook and a white queen in which one side is in mate.

We can force white to be in mate:

(position R Q :mate :wtm)

Now white must be mated.

This

(position R Q :initial)

only matches if White has a rook and queen in the first move (of the study, presumably). We can force white to be incheck on the first move:

(position R Q :initial :check :wtm)

Transformation keywords in a position list

Certain keywords within a position list specify that the position list should match a position if some transformation of the position list matches the position. For example, the :fliphorizontal keyword specifies that the position list matches a position if either the original position list matches the position, or if the position list, when flipped about the horizontal bisector, matches the position.

To apply a transformation to a position list we apply the transformation to each piece designator that occurs in the position, and we recursively apply the transformation to any other position lists contained in that position list. If the transformation is a color flip translation, then we also flip interchange any :btm keywords with :wtm ones, and we flip the :result keyword arguments appropriately.

For example, consider the position list

(position Rc2 Bh8 :wtm)

This matches any position with white to move that has a white rook on c2 and a white bishop on h8. The result of applying a unit left shift transformation to this position list is the new position list:

(position Rb2 Bg8 :wtm)

that matches any position with white rook on b2 and white bishop on g8 with white to move.

Similarly, the result of applying a horizontal flip to this position list is the position list:

(position Rb8 Bg1 :wtm)

The result of applying a color flip transformation to the

(position Rb2 Bg8 :wtm)
is thus
(position Rb8 Bg1 :btm)

Remember that shifts interact specially with certain squares on the edge. For example the result of applying a unit up shift to this position list:

(position R[a1,a8,h1,a8])

is the position list:

(position R[a1,a2,h1,h2])

A transformation set is any set of transformations. A transformation set applied to a position list is the set of all position lists that result from applying any transformation in the transformation set to the position list.

Each transformation keyword is associated to a transformation set, each of which also includes the identity transformation. The transformation keywords and their associated transformation sets are:

    :flipdihedral

    all dihedral transformations.

    :flip

    same as :flipdihedral

    :fliphorizontal

    the horizontal flip transformation.

    :flipvertical

    the vertical flip transformation.

    :flipcolor

    the color flip transformation.

    :flipdiagonal

    the diagonal flip transformation.

    :shifthorizontal

    the horizontal shift transformations.

    :shiftvertical

    the vertical shift transformations.

    :shiftmaindiagonal

    the main-diagonal shift transformations.

    :shiftoffdiagonal

    the off-diagonal shift transformations.

    :shiftdiagonal

    the off-diagonal and main-diagonal shift transformations.

    :flipcolor

    the color flip transformation.

    :shift

    the shift transformations.

Examples of transformation keyword uses

Consider this position list:

(position Rc3 qg3)

which matches any position with a white rook on c3 and a black queen on g3. We can add a :shifthorizontal keyword:

(position Rc3 qg3 :shifthorizontal)

The set of transformed position lists is:

(position Rc3 qg3)
(position Rb3 qf3)
(position Ra3 qe3)
(position Rd3 qh3)

A position will match the new position list, if there is a white Rook and black queen on the third rank and the white rook is four squares to the left of the black queen.

Similarly, the position list:

(position Rc3 qg3 :shiftvertical)

will match any position in which there is a white rook on the same rank as a black queen such that the rook is on the c file and the queen on the g file.

The position list:

(position Rc3 qg3 :shift)

will match any position with a white Rook and a black queen on the same rank, in which the white rook is four squares to the left of the black queen. The position list:

(position Rc3 qg3 :fliphorizontal)

will match any position in which either the white rook is on c3 and the black queen is on g3, or the white rook is on c6 and the black queen on g6.

The position list:

(position Rc3 qg3 :flipdiagonal)

will match a position in which either a white rook is on c3 and a black queen on g3, or in which a white rook is on c3 and a black queen is on c7.

The position list:
(position Rc3 qg3 :flip)

The following position list matches any position in which a white rook is somewhere behind a white pawn on the c file:

(position Pc2 Rc1 :shiftvertical)

Because of the way edge squares are treated, this will match a position in which, say, the white rook is on c2 and the white pawn on c7.

To match any position in which a white rook is behind a white pawn on the same file, use:

(position Pc2 Rc1 :shift)

Multiple transformation keywords

When multiple transformation keywords occur, the associated transformation set is any transformation that can be expressed as a composition of transformations from the corresponding transformation sets. This feature is most often used when looking for a piece configuration that can occur anywhere on the board, possibly rotated or reflected: adding :shift :flip to the position specifier does this.

For example, this position list

(position Nd4 kf3 :shift :flip)

matches any position in which a white knight attacks a black King, while

(position Nd4 kf3 :shift :flip :flipcolor)

matches any position in which a knight attacks a king of the opposite color.

Note: This example can be written much more efficiently as

 (position :attackcount N k 1 100 :flipcolor)

however.

Piece configuration keywords

Some position list keywords apply the geometrical configuration of the pieces themselves. Most of these can take a range specifier argument as well which counts the number of times the configuration occurs in the position. These piece configuration keywords are:

    :piececount

    . This keyword takes a piece designator argument followed by a range specifier. It matches the position if and only the number of occurrences of the piece designator in the position is given by the range specifier.

    For example,

    (position :piececount R 2)
    will match any position with exactly two white rooks - a position with three white rooks would fail to match. The position list
    (position 
      :piececount [Rr][a1-8] 1 3 
      :piececount [Qq][a-h8] 4 
      Nd4)
    will match any position with a white knight on d4, between one and three rooks on the a file, and exactly four queens on the eight rank. Another way to write this position list is:
    (position 
      Nd4
      :piececount [Rr][a?] 1 3 
      :piececount [Qq][?8] 4 
      )
    

    :power

    This keyword takes as argument a piece designator followed by a range specifier. It matches positions for which the total power of all pieces in the position matching the piece designator lies within the range specifier. The power of a piece is their standard chess material power: Q=9, R=5, B=3, N=3, P=1, K=0.

    For example,

    (position :power a 6)
    
    will match positions in which the total power of the black pieces on the board equals 6.
    (position :power Aa-h1-4 10 25)
    
    will match positions in which the total power of the white pieces on the white half of the board is between 10 and 25 inclusive.

    :powerdifference

    This keyword takes as argument a piece designator followed by a range specifier. It matches positions in which the difference in power between the white and black pieces matching the piece designator (that is, the numeric value of the power of the matching black pieces subtracted from the power of the matching white pieces) lies within the range specifier.

    For example,

    (position :powerdifference U 4)
    
    matches positions in which the white pieces have power precisely 4 greater than the black pieces.
    (position :powerdifference [Rr] -5 10)
    
    matches positions in which white has between one fewer and two more rooks than black.
    (position :powerdifference [RrBbNn] -1000 -2)
    
    matches positions in which black is up at least an exchange.

    This example shows how to search for queen sacrifices using :powerdifference.

    :attackcount

    This keyword takes as arguments two piece designators followed by a range specifier. The first piece designator is the attacker piece designator. The second piece designator is the attacked piece designator. An attack by a piece to a square occurs if the piece could move to that square were it empty and disregarding any possible checks. A valid attack is an attack by a piece on a square that matches the attacker piece designator to a square on which is a piece that matches the attacking piece designator.

    The :attackcount keyword matches a position if the total number of valid attacks in the position lies with the range given by its range specifier.

    For example,

    (position :attackcount A k 2)
    
    matches any position in which white has a double attack on the black king.
    (position :attackcount A k 2 :flipcolor)
    matches any position in which a king is under double attack.
    (position :attackcount A .h3 1)
    matches a position in which exactly one white piece attacks an empty h3 square.
    (position :attackcount [RB][a-c8] ??1 5 9
    matches a position in which the number of times a white rook or white bishop on a8, b8, or c8 attacks a square on the first rank is between 5 and 9 inclusive.
    (position :attackcount n [KRQ] 3 100) 
    matches position for which the number of times a black knight attacks a white King or white major piece is at least 3.

    :ray

    A ray specifier is a list of piece designators. A ray is a contiguous set of squares on a straight line on the chessboard parallel to an axis, the a1-h1 diagonal, or the a8-h8 diagonal.

    Let R by a ray with ordered set of squares in a contiguous lineS1, S2,...,Sn. Suppose spec is a ray specifier (G1, G2,...,Gk) where each G1,...,Gk is a piece designator. The ray R is valid with respect to the ray specifier if G1 matches the piece on S1, and if Gk matches the piece on Sn, and if the remaining G's can be paired to some subset of the squares in the ray in an order-preserving way such that each G matches the piece on its corresponding square and such that all unpaired squares in the ray are empty.

    The :ray keyword takes a ray specifier and an optional range specifier. If the range specifier is absent, it is taken to be 1 1000. Otherwise, :ray matches a position if the number of rays in the position valid with respect to the ray specifier lies within the range specifier.

    :ray examples

    (position :ray (k Q)) 
    matches a position in which a white queen attacks the black king.
    (position :ray (Qa? n k[?4-8]))
    matches a position in which a white queen on the a file pins a black knight to the black king on the last four ranks.
    (position :ray (Qa? Qc? Qe? kg?))
    matches a position in which either three queens and the black king are on the same rank, with exactly one empty square between them, and one of the queens is on the a -file, or a position in which the three queens and king form a diagonal with one empty squares between successive pieces and the queens on the a, c, and e files.
    (position :ray (Q n k) 2 4)
    between two and for black knights are pinned to the black king.

    :raydiagonal, :rayhorizontal, :rayvertical, :rayorthogonal

    These keywords function exactly like :ray but the given rays are restricted to being diagonal, horizontal, vertical, and orthogonal respectively. A horizontal ray is a ray that is horizontal. A vertical ray is a ray that is vertical. A diagonal ray is a ray that is not vertical or horizontal. An orthogonal ray is a ray that is not diagonal.

    Thus

    (position :rayorthogonal (R b k)) 
    matches position in which a black bishop is pinned by a white rook against the black king.
    (position :raydiagonal (Q B n k))
    matches positions in which there is a white Queen-bishop battery pinning a black knight to the black king.
    (position :rayvertical (R[a1-8] b k))
    matches positions in which a white rook on the a file pins a black bishop to the black king on the a file.
    (position :rayhorizontal (K .  . k))
    matches positions in which the kings are on the same rank and separated by at least two empty squares.

    :rayattack

    has the same syntax as :ray. It has the semantics of :ray, except that only orthogonal rays that start on a square containing a rook or queen are included, and only diagonal rays starting on a square containing a bishop or queen are included.

    For example,

    (position :rayattack (A a k))
    matches a position in which a black piece is pinned to the black king.
    (position :rayattack (Ad5 a [rk][a-h1-4]) 3)
    matches positions in which there are three black pinned by a white piece on d5 against either a black rook or king in the first four ranks.
    (position :stalemate :rayattack (A a k) 2 8 :flipcolor)
    finds multiple-pin stalemates.

    Move keywords

    In a position, the next move is the move about to be played, if any. A move has three charactistics: its from designator, its to designator and its promotion designator. These refer respectively to the piece and square from which the piece moves; to the piece and square to which it is going to move (but before it actually moves there), and to the piece and square to which it promotes, if any.

    For example, the to designation of a white rook on a4 capturing a black knight on d4 is nd4, and its from designation is Ra4. The to designation of a move to e4 that is not a capture is .e4.

    :movefrom

    takes a single parameter, a piece designator. It matches a move whose from designator matches that piece designator. For example,
    (position :movefrom Ra3)
    
    matches a position in which the next move is of a white rook on a3.
    (position :movefrom U?8)
    
    matches a position in the next move is of some piece on the 8th rank.

    :moveto

    takes a single parameter, a piece designator. It matches a move whose to designator matches its parameter. For example,
    (position :moveto .a3)
    matches a position in which the next move is to an empty square on a3.
    (position :moveto R[b1-8])
    matches a position in which the next move is to capture a white rook on the b file. Note that this is quite different from the natural PGN interpration of its being a move of a white rook to the b file. That would be done via:
    (position :movefrom R :moveto ?b?)
    which matches a move of the white rook to the b file.

    :promote

    takes a single parameter, a piece designator. It matches a move if that move is a promotion whose promotion designator matches its parameter. For example,
    (position :promote [RBN])
    matches a position whose next move is a white underpromotion.
    (position :promote [BN]a8)
    matches a position whose next move is a white promotion to bishop or knight.
    (position :promote [Re8] :movefrom Pf7 :moveto q)
    matches a position in which the next move is of a pawn on f7 capturing a black queen on e8 and promoting to a rook. Castling is considered a move of the king two squares:
    (position :movefrom [Kk]e? :moveto .[c?,g?])
    matches any position in which the next move is castles. There are also some special keywords for handling en-passant:

    :enpassant

    The next move is an en-passant captue.

    :noenpassant

    The next move is not an en-passant capture.

    :movenumber

    :movenumber takes a range specifier as parameter and matches positions only if the current move number is within the specified range. The move number computation assumes white moves first, and might be one off otherwise. For example,
      (position :movenumber 10 20 :check)
    matches a position in which there is a check between moves 10 and 20.
    (position   :movenumber 35 :mate)
    matches a position in which move 35 is mate.

    Logical keywords

    There are three ways to combine position lists using logical operations: :and, :or, and not.

    :and

    takes a list of position lists and matches a position only if each of them match the position.

    :or

    takes a list of position lists and matches a position only if at least one of them matches the position.

    :not

    matches a position if the containing position list would not match the position without the :not.

    For example,

    (position 
      :wtm 
      :check
      :and 
       ((position Ke2 kg2 :shift :flip)
         (position Ne2)))
    
    matches positions in which the kings are in opposition, there is a white knight on e2, and white is in check.
    (position
    :wtm :check
     :or 
       ((position Ke1 kg1 :shift :flip)
        (position Ne2)))
    
    matches positions in which white is in check and either the kings are in opposition or there is a white knight on e2 (or both).
    (position Ra3 :not)
    
    is equivalent to
    (position [aQBNPK.]a3)
    .

    Sequence keywords

    Two keywords can be used to match sequences of positions that occur from a given position, :sequence and :gappedsequence.

    :sequence

    takes a single argument that is a list of position lists. It matches a given position if and only successive occurring positions, beginning with the current position, match each corresponding element in its argument.

    For example, the position list

    (position Re8 
      :sequence
       ((position Qf3 .g2)
        (position .f3 Qg2)))
    
    matches exactly those positions with a white rook on e8 such that:
    1. In that position, white has a queen on f3 and g2 is empty, and
    2. After the next move, f3 is empty and there is a white queen on g2.
    In consequence, this position list is identical in effect to
    (position Re8 :movefrom Qf3 :moveto .g2)
    
    The following more typical usage of :sequence will search for all queen staircase checking maneuvers by either side:
    (position 
      :shift :flip :flipcolor
      :sequence
       ((position :movefrom Qa2) 
        (position :check) 
        (position :movefrom Qb2) 
        (position :check) 
        (position :movefrom Qb3) 
        (position :check) 
        (position :movefrom Qc3)
        (position :check)
        (position :movefrom Qc4)
        ); end the sequence
      ); end the position
    
    This position list matches any position with a white queen on a2 for which there are successively moves by queens on the indicated squares giving check; the :shift, :flip, and flipcolor search for this variation reflected or rotated anywhere on the board.

    :gappedsequence

    takes one argument, a list of position lists. A position list A is said to be a refinement of a position list B if A may be formed from B by inserting 0 or more position lists of the form (position) into the top level of B. For example,
    ((position Na4) (position) (position Rb2))
    refines
    ((position Na4) (position Rb2))
    because it was formed by inserting a single position list into the latter list.

    A :gappedsequence with argument B matches a position if and only if there is a refinement A of B such that a :sequence with argument A would match that position. That is, :gappedsequence is like :sequence except that the sequence of matching positions may include intervening positions from the game.

    For example,

    (position 
     :gappedsequence
      ((position :movefrom Ra3)
       (position :movefrom Rb4)
      ); end the gappedsequence
    ); end the position
    
    will match any position for which the positions that occur successively in the game starting with that position comprise 0 or more positions, followed by a position from which a white rook on a3 moves, followed by 0 or more positions, followed by a position from which a white rook on b4 moves. In consequence the same effect can be obtained much more efficiently via:
    (position 
     :initial
     :gappedsequence
      ((position :movefrom Ra3)
       (position :movefrom Rb4)
      )
    )
    

    The following position list matches a position in which a knight is on d4 at some point in the game after that position:

    (position
      :gappedsequence
       ((position)
        (position Nd4)
       )
    ) 
    
    Note that the first element of the argument to :gappedsequence, (position), is used to ensure that only knights on d4 in positions that occur after the position to be matched are considered.

    This fragment is used here, to find all games in which some knight has visited at least twenty different squares.

    The total number of :sequence and :gappedsequence position lists that can occur at the top level of a position list cannot exceed 1. To get the effect of both a :gappedequence and :sequence keywords in one position list, use :and .

    Relations between positions

    :relation

    takes one argument, a relation specification. is used to search for games with pairs of positions P1 and P2 that satisfy certain properties. The relation specification keywords are described here.

    Game-related position list keywords

    Several keywords relate to the game parameters and are not affected by the contents of the position; they are included as position list keywords instead of match list keywords so the :flipcolor can be used with them. These are:

    :elo

    this parameter expects a range specifer; the ELO of at least one of the players must lie within the specified range

    :whiteelo

    this parameter takes a range specifer; the ELO of the white player must lie within its range

    :blackelo

    this parameter takes a range specifier; the ELO of the black player must lie within its range.

    :result

    this parameter takes one argument, the same as the argument to :result in a match list.

    For example,

    (position 
      :result 1-0 
      :whiteelo 0 2300
      :blackelo 2600 3000
      :flipcolor
    )
    
    searches for positions in which a 2300 player or below defeated a 2600 player or above.

    Matching count keywords

    Two keywords pertain to the number of positions which a position list matches. These each take a range specifier as parameter. They can only be used in a position list at the top level of a match list.

    :matchcount

    matches if and only if the number of times this position list matches a position in the current game lies within the range specifier.

    For example,

    (position :moveto [Qq] :matchcount 4 100)
    
    matches any game in which at least four queen captures have occurred.

    :pretransformmatchcount

    has the same syntax :matchcount. It matches a position if and only if there is some transform in the transformation set associated with the position list in which it occurs such that, were the position list replaced by a new position list formed from the first by deleting all transformation keywords, applying the transform to that position list, and changing this keyword to :matchcount, then the position list would match the position.

    For example,

    (position :moveto [Aa]d4 
              :pretransformmatchcount 12 1000 :shift)
    )
    
    would match any game in which at least 12 captures occur on the same square. Were the :pretransformmatchcount replaced by :matchcount , the position list would match games in which at least 12 captures occurred.

    The "MATCH" string is printed independent of any count keywords.

    Accumulator keywords

    (Note: this feature is experimental). There are two accumulator keywords, :accumulate and :sumrange . These are used to accumulate and to test the number of transforms of the enclosing position list that match the current position. Each time a transform of a position list matches a position, the accumulator associated with that position is incremented. Any position with a sum range can then test if the accumulator is within a certain range.

    :accumulate

    This takes one parameter, the name of an accumulator. Each time the application of some element of the transform set of the position list matches a position, the accumulator associated with this name is incremented. The accumulator is cleared when a new position is reached (and in consequence :accumulate should not be used inside of :not or the sequence keywords. This keyword inhibits short-circuiting of logical keywords :and and :or . Note that :flipcolor likely has unexpected results when used with :accumulate, because the accumulator is not cleared between color flips.

    :sumrange

    This takes a parameter the name of an accumulator and a range specifer. It matches a position if the value of the given accumulator lies within the range specifier.

    Using accumulators to count passed pawns

    We will show how to use :accumulate and :sumrange to look for games that have at least 3 white passed pawns in a position. First, we give a position filter that will match any position with a white passed pawn:
    (position ;match a position with a white passed pawn
     Pd2
     :piececount [pP][d3-7] 0
     :piececount p[c3-7,e3-7] 0
     :shift
    )
    
    Now, to find at least 3 white passed pawns, we add in some accumulation code:
    (position ;match a position with at least three white passed pawns
     Pd2
     :piececount [pP][d3-7] 0
     :piececount p[c3-7,e3-7] 0
     :shift
     :accumulate white_passer_counter
     :sumrange white_passer_counter 3 8
     :markall
    )
    

    Now suppose we want to find positions with at least two black passed pawns. We can use:

    (position ;match a position with at least two black passed pawns
      pd7	
      :piececount [pP][d2-6] 0
      :piececount P[c2-6,e2-6] 0
      :shift
      :accumulate black_passer_counter
      :sumrange black_passer_counter 2 8
      :markall
    )
    
    Finally, to find positions with at least two black passers and at least three white passers, we combine these lists:
    (position ; match a position with at least three white and at least two black passers
     :sumrange white_passer_counter 3 8 
     :sumrange black_passer_counter 2 8
     :markall
    	:and
    	((position
    	  Pd2	
    	  :piececount [pP][d3-7] 0
    	  :piececount p[c3-7,e3-7] 0
    	  :shift
    	  :accumulate white_passer_counter
    	  )
    	 (position
    	  pd7	
    	  :piececount [pP][d2-6] 0
    	  :piececount P[c2-6,e2-6] 0
    	  :shift
    	  :accumulate black_passer_counter
             )
            )
    )
    

    Tagging keywords

    The :tagmatch keyword takes two parameters, the name of a tag and a piece designator. It matches only if the piece corresonding to the named tag matches the given piece designator. For more information, see the section on tagging.


    ChessQuery Language Manual: http://www.rbnn.com/cql