Documentation

Synoptic Examples

Short practical recipes demonstrating common CQLi tasks for tags, comments, output files, and everyday filtering needs.

This section contains many short examples with little or no commentary. Many of the examples found here are also included in the section which discusses the relevant filters in more detail.

Illustrative Examples

This section contains queries for various types of positional constructs. Each query is accompanied by an illustrative diagram representing a position found by the query.

Pawn Attacks

2+ pieces attacked by pawns
2+ pieces attacked by pawns
flipcolor [bnrqk] attackedby P > 1
Pawn forks
Pawn forks
flipcolor piece Pawn in P {
    [bnrqk] attackedby Pawn > 1
}

Castling

Castling on opposite sides
Castling on opposite sides
initial
find move o-o
find move o-o-o
Check delivered via castling
Check delivered via castling
check
move previous castle

Castling pins undefended minor piece
Castling pins undefended minor piece
flipcolor {
    btm
    move previous castle
    $pin =? pin through [bn]
        from (R attackedby K)
    $pin attackedby a == []
}

Castling out of mate-in-1 threat
Castling out of mate-in-1 threat
move castle
child : not move legal : mate
imagine sidetomove reverse :
    move legal : mate

Pawn Structures

Advanced passed pawns
Advanced passed pawns
flipcolor Pa-h5-8 & passedpawns
Fixed pawns
Fixed pawns
flipcolor p & up 1 P

Pawn chains
Pawn chains
flipcolor P & diagonal 1 P

Bases of pawn chains
Bases of pawn chains
(flipcolor P & diagonal 1 P) &
(flipcolor P & ~ up horizontal 0 1 P)

Promotions

Both sides have promoted queens
Both sides have promoted queens
promotedpieces & Q
promotedpieces & q
Promotion to queen results in stalemate
Promotion to queen results in stalemate
stalemate
move previous promote Q

Underpromotions
Underpromotions
move promote [BNR]

Knight underpromotion forks major pieces
Knight underpromotion forks major pieces
flipcolor {
    btm
    piece $pid = move to . previous
        promote N
    [krq] attackedby $pid > 1
}

King Squares

King is surrounded by 8 empty squares
King is surrounded by 8 empty squares
flipcolor { _ attackedby K == 8 }
Mated king surrounded by 8 empty squares
Mated king surrounded by 8 empty squares
mate
flipcolor { wtm _ attackedby K == 8 }

King is surrounded by friendly pieces
King is surrounded by friendly pieces
flipcolor {
    [_a] attackedby K == []
}

Smothered mate
Smothered mate
mate
flipcolor {
    wtm
    [_a] attackedby K == []
}

Speculative move

More than 5 moves mate
More than 5 moves mate
move count legal : mate > 5
Discovered check via en passant
Discovered check via en passant
move legal enpassant : {
    check 
    flipcolor { [brq] attacks K }
}

Knight has move that forks K/Q
Knight has move that forks K/Q
flipcolor piece $knight in N {
    move from $knight legal : {
        [kq] attackedby $knight > 1
    }
}

Pawn can fork two pieces
Pawn can fork two pieces
flipcolor piece Pawn in P {
    move to . from Pawn legal : {
        [bnrqk] attackedby Pawn > 1
    }
}

Tactics

Check answered with mate
Check answered with mate
mate
parent : check
Rook battery pins queen to king
Rook battery pins queen to king
flipcolor ray orthogonal (R R q k)

Productive bishop skewer
Productive bishop skewer
flipcolor {
    xray(B k [qr])
    move from k to _
}

Knight exploits rook xray with check
Knight exploits rook xray with check
flipcolor
xray(R (move from N to
    ~(. attackedby a): check) q)

Miscellaneous

Every square is attacked by one side
Every square is attacked by one side
. attackedby A & . attackedby a == []
. attackedby A | . attackedby a == 64
All pieces reside on same color squares
All pieces reside on same color squares
flipcolor dark [Aa] == [Aa]

8 pieces in a file
8 pieces in a file
shifthorizontal
up 0 7 a1 & [Aa] == 8

Quadrupled Pawns
Quadrupled Pawns
shifthorizontal flipcolor {
    QP = down a8 & P QP > 3 QP
}

Tag Operations

This section contains examples that manipulate PGN tags. The cql(silent) header is used to prevent new comments (such as game header comments or matching position comments) from being added to matching games (which is all of them if a CQL query is not provided).

Set the PlyCount tag to the number of plies in the mainline

cql(silent)
terminal
mainline
settag("PlyCount" str ply)

Populate an EndFEN tag with the FEN of the final position

cql(silent)
terminal
settag("EndFEN" standardfen)

Add missing 7-tag roster components

cql(silent)
initial
if not tag "Event" then settag("Event" "?")
if not tag "Site" then settag("Site" "?")
if not tag "Date" then settag("Date" "????.??.??")
if not tag "Round" then settag("Round" "?")
if not tag "White" then settag("White" "?")
if not tag "Black" then settag("Black" "?")
if not tag "Result" {
    $result = "*"
    if result "1-0" then $result = "1-0"
    if result "0-1" then $result = "0-1"
    if result "1/2-1/2" then $result = "1/2-1/2"
    settag("Result" $result)
}

Remove the Opening tag from all games

cql(silent)
removetag "Opening"

Change the name of a tag

cql(silent)
initial
settag("NewTagName" tag "OldTagName")
removetag "OldTagName"

Find games with inconsistent Result tag

cql(silent)
initial
tag "Result"
$expected_result = "*"
if result 1-0 then $expected_result = "1-0"
if result 0-1 then $expected_result = "0-1"
if result 1/2-1/2 then $expected_result = "1/2-1/2"
$expected_result != tag "Result"

Comment Operations

The queries in this section manipulate comments that appear in the move text portion of the PGN file. The header cql(quiet) prevents matching position comments from being added but game header comments will still be added. To suppress the game header comments, use the –noheader command line option.

Find all games containing comments

cql(quiet)
hascomment

Find all games with evaluation comments of the form [%eval ...]

cql(quiet)
hascomment "[%eval "

Remove all comments from every game

cql(quiet)
removecomment

Remove time clock comments having the form %[clk ...]

cql(quiet)
if hascomment {
    removecomment
    $newcomment = replace((originalcomment) "\[%clk .*?\]" "")
    if $newcomment != "" {
        comment $newcomment
    }
}

Add a comment to each position containing the position’s Zobrist Key

cql(quiet)
comment zobristkey

Output File Operations

This section provides examples of how to control various aspects of the output file. Since these aspects are handled by the CQL front-end (they are not part of the CQL language), the focus is on the CQLi command and relevant arguments instead of a CQL query. The commands below will match all games in the input file. To limit the operation to matching games, provide a .cql file argument or use the -cql option to supply a query.

The examples below use input.pgn as input file and output.pgn (or the output/ directory when using multiple output files) for the output file, these should be adjusted appropriately.

The –silent option is used to prevent new comments from being added to matching games which is usually the desired behavior. This option can be removed or replaced with any combination of –quiet, –noheader, and –matchstring to obtain an alternate behavior.

Split matching games into files named after a tag

cqli -i input.pgn -o 'output/%T{Event}.pgn' --silent

Use with:

Split matching games into files based on query

cqli -i input.pgn -o 'output/%Q{str gamenumber % 10}.pgn' --silent

See notes above.

Exclude NAGs from matching games

cqli -i input.pgn -o output.pgn --silent --elidenags

Exclude comments from matching games

cqli -i input.pgn -o output.pgn --silent --elidecomments

Exclude variations from matching games

cqli -i input.pgn -o output.pgn --silent --elidevariations

Include all PGN move text on a single line

cqli -i input.pgn -o output.pgn --silent --pgnlinewidth 0