Documentation

The sort Filter

Sort matching games by computed values, control tie handling, and understand best-value selection behavior in CQLi.

sort [quiet] [min|max] [description] target-filter

The sort filter takes a single target-filter which may have String, Numeric, or Set type. If target-filter is a Set filter, the value is implicitly converted to the Numeric value that represents the set’s cardinality. The result of the sort filter is the String or Numeric value resulting from evaluating the target filter. The best value of the target filter across all evaluations of the sort filter for each game is articulated by a sort comment at the beginning of each matching game. Description is an optional string literal used to form the sort comment, a unique identifier is used if no description is provided.

Any comments generated as a result of evaluating the target filter are suppressed except for the evaluation that produced the best value (unless Smart Comments are disabled using the --nosmartcomments option). The best value is the one that compares smaller than any other value encountered if min is specified or the value that compares larger than any other value if either max is specified or neither of min or max is specified.

Finally, matching games in the output PGN file are sorted by the best value encountered in each game (ascending order if min is specified, descending order otherwise). Multiple games with the same sort value are further ordered by their position within the input PGN file (i.e. the game number).

Multiple sort Filters

If multiple sort filters appear in a query, a separate sort comment will be generated for each sort filter in the order in which the corresponding sort filters appeared. Games in the output PGN file will be ordered by each sort filter with the first sort filter providing the primary ordering, the second sort filter provided a secondary ordering, etc. with the game number providing a final ordering.

Smart Comments are applied to each sort filter independently of other sort filters. In particular, a sort filter enclosing another sort filter does not influence the best value of the nested filter. For example the query:

sort "max-ply" {
    comment("greatest ply: " ply)
    sort min "min-ply" { comment("smallest ply: " ply) ply }
}

will result in the first sort filter having a best value that corresponds to the position with the largest ply and the nested sort filter having a best value of zero (the smallest ply). The comment smallest ply will be inserted at the initial position and the comment greatest ply will be added to the position with the largest ply. The inner sort is not affected by the outer sort, e.g. the outer sort does not limit the values seen by the inner sort or affect the comment enclosed by the inner sort.

Conjunction of sort Filters

Multiple sort filters having the same description string form a single conjoined sort ordering in which the best value from the evaluations of all the corresponding sort filters is used to determine the sort order and the application of Smart Comments. A single sort comment representing the best value of the conjoined filters is emitted. sort filters appearing within transform filters are treated similarly even if no description string is provided, the corresponding sort filter from each transformation is part of a conjoined set of sort filters.

While multiple sort filters with the same description string may have different target-filters, the sort order (specified with the min or max parameters) and type (String or Numeric) must be the same across all sort filters that share the same description.

sort Comments

Every sort filter will be represented by a corresponding sort comment at the beginning of each matching game, this comment will include the provided description (or generated identifier) followed by a colon (:), a space, and the best value encountered for the sort filter within that game. If the sort filter was never evaluated or never matched, the articulated value will be none. If the quiet keyword parameter is provided or the –silent command line option is used, a sort comment is not emitted. If there are multiple sort filters with the same description string, the quiet parameter is ignored on all but the first of them.

Unmatched sort Filters

It is possible for a game to match a CQL query without matching a contained sort filter, either because the sort filter was not reached or because it appeared as part of a larger expression that did match. For example, the query:

terminal
if movenumber > 100 then sort min date

will match all games with a Date tag but the sort filter will only be reached for games with more than 100 moves. In the following query, the sort filter is always reached but its target filter will not match every game:

terminal
if sort (movenumber > 100) then comment "Long game"

A sort filter that never matches has an empty best value which sorts after any non-empty value, regardless of sort direction. For example, in the first query above, games with more than 100 moves will appear first in the output PGN file sorted in ascending order by date while the remaining games will appear in game number order (the default output sort order). In the second example, games with more than 100 moves will appear first, sorted in descending order by number of moves, followed by remaining games appearing in the default sort order.

Multiple Best Values

If multiple evaluations of the sort filter yield the same best value, only the comments generated during the first evaluation of the best value will be retained by default. The –keepallbest option may be used to retain the comments associated with every evaluation producing the best value.

Examples

The sort filter may be used with any Numeric or String filter but is often used with the echo, line, and find filters. For example, the following query will find games where one side was subjected to check 10 or more times in a row. If there are multiple sequences of 10 or more checks in a game, only the longest sequence will be considered. Matching games will be ordered in the output PGN file with the games having longer sequences appearing first.

sort "Consecutive checks"
    { line singlecolor nestban --> check + } >= 10

Below is an example of a game found by the above query:

{Game number 1711785} {Consecutive checks: 32} 1.d4 e6 2.c4 Nf6 3.Nc3 Bb4 4.Nf3
c5 5.Qb3 Ne4 6.Nd2 Nxd2 7.Bxd2 Nc6 8.dxc5 Bxc5 9.Ne4 Be7 10.Qg3 O-O 11.Bc3 f6
12.O-O-O d5 13.e3 Nb4 14.a3 a5 15.Be2 Bd7 16.axb4 axb4 17.Nxf6+ Bxf6 18.Bxb4
Ra1+ 19.Kd2 Ra2 20.Rb1 Bxb2 21.Ke1 Rf5 22.h4 Be5 23.f4 Bf6 24.Qf3 d4 25.e4 Bc6
26.g3 Rfa5 27.Bxa5 Qxa5+ 28.Kf2 d3 29.Qxd3 Rd2 30.Qf3 Qc5+ 31.Ke1 Qd4 32.Qg4
Kf7 33.Qh5+ g6 34.Qxh7+ Bg7 35.h5 Rxe2+ {CQL} {Start line that ends at move
67(wtm)} 36.Kxe2 Qxe4+ 37.Kd2 Qd4+ 38.Ke2 Qe4+ 39.Kd2 Qg2+ 40.Ke3 Qxg3+ 41.Kd2
Qc3+ 42.Ke2 Qxc4+ 43.Kd2 Qxf4+ 44.Kc2 Be4+ 45.Kb3 Bd5+ 46.Kc2 Be4+ 47.Kb3 Qe3+
48.Kb4 Qb6+ 49.Kc4 Qd4+ 50.Kb3 Qc3+ 51.Ka4 Bc2+ 52.Kb5 Qc6+ 53.Kb4 Qb6+ 54.Kc4
Qd4+ 55.Kb5 Bd3+ 56.Ka5 Qc5+ 57.Ka4 Bc2+ 58.Rb3 Qa7+ 59.Kb5 Qa6+ 60.Kc5 Qc6+
61.Kb4 Qb6+ 62.Ka4 Qxb3+ 63.Ka5 b6+ 64.Ka6 Qa4+ 65.Kxb6 Qb4+ 66.Kc7 Qc4+ {End
line of length 32 that starts at move 36(wtm)} 67.Kd8 g5 68.Rf1+ Qxf1 69.Qxc2
Bf6+ 70.Kc7 Qf5 71.Qa4 Qd5 72.h6 Qd8+ 73.Kb7 Kg6 74.Qe4+ Kxh6 0-1

The below query will find decisive games with more than 100 moves (by each side), sorted by the number of moves:

terminal
flipcolor result 1-0
sort "Total moves: " movenumber > 100

To find all games played by Viswanathan Anand, ordered in ascending order by date played, the following query may be used:

cql(silent)
initial
player "Viswanathan"
sort min tag "Date"

The silent parameter in the CQL header suppresses both the matching position comments and the sort comments, neither of which are likely to be desired here.