CQL Language Differences
New Features in CQLi
Variant Support
CQLi provides comprehensive support for several chess variants including Chess 960, Atomic, Crazyhouse, King of the Hill, Three-check, Antichess, Horde, and Racing Kings which includes the ability to correctly parse such games and perform legal and pseudolegal move generation for these variants via the move filter. CQLi also provides the new variant, variantwin, variantloss, variantend, and variantdraw filters to inspect variant-specific ending conditions. Finally, the move filter supports the new drop parameter to support dropped-piece moves in the Crazyhouse variant.
CQL 6.1 does not provide explicit support for variants but can parse PGN files containing King of the Hill and Three-check games as these variants do not introduce any changes to game mechanics aside from alternate winning conditions. Of course CQL 6.1 does not understand the alternate winning conditions of these variants but they can still be evaluated using CQL 6.1 without loss of move text as a result of game parse errors.
Other variants cannot be correctly parsed by CQL 6.1 for various reasons and will result in loss of move text as games will be truncated at the first move that cannot be processed by CQL 6.1. In particular, CQL 6.1 does not support positions without both a black and white king on the board such as occur in the Horde variant, does not support the capture explosions or king adjacency rules of Atomic chess, does not understand piece drops employed in Crazyhouse, does not enforce compulsory captures or the non-royal kings (which are not subject to check and may be captured) of Antichess, and does not support Chess 960 style castling or the notation needed to specify Chess 960 castling rights. Racing Kings games cannot be reliably parsed by CQL 6.1 since it is necessary to consider the fact that checking is forbidden to disambiguate certain moves.
Imaginary Position Support
The ability to modify board state within games using the imagine filter and the speculative move filter, as well as the currentmutation filter used to articulate board modifications and the saveposition filter used to save modified positions, are CQLi-specific features. CQL 6.1 does not provide a mechanism to explore positions not actually reached within a game.
Unicode Support
CQLi provides full support for Unicode and properly handles UTF-8 characters within PGN tags, in-game comments, and CQL query strings. This results in several noticeable behavior changes:
- Preservation of Unicode characters in these locations.
- The cardinality operator (
#) applied to a String yields the number of code points in CQLi instead of the number of bytes as it does in CQL 6.1. - The indices used with string slicing represent the positions of code points, not bytes.
- CQLi supports values between 0 and 127 with the
asciifilter whereas CQL 6.1 supports values up to 255. CQLi assumes UTF-8 encoding and values larger than 127 are always part of a non-ASCII multi-byte character when appearing in a UTF-8 encoded file. - Unicode string collation is employed by CQLi to support the
sortfilter and comparison filters applied to string filters. Language-specific collation tailorings are supported based on the user’s locale settings. Regular expression matching conforms to Level 1 of the Unicode Technical Standard #18 with some support for Level 2.
Command Pipe
CQLi provides a generalized extensibility mechanism via the commandpipe filter that allows CQL queries to interact with external programs during query evaluation. Command-pipe programs may be written in any programming language and may perform tasks such as database lookups, obtaining positional evaluations from local or remote chess engines, writing statistic information to a file, etc.
Other Filters
The following additional CQLi filters not referenced above do not exist in CQL 6.1.
CQLi Extensions
CQLi-specific enhancements to existing CQL features.
- Persistent variable and dictionary merge strategy specification to support multi-threaded execution of queries employing them.
- CQLi supports dictionaries with keys and values having Numeric and Set types in addition to String type.
- Conditional set assignment and compound assignment for dictionary members.
- Multi-threaded execution support for queries employing the
readfileandwritefilefilters. - Reverse move generation using the
reversekeyword parameter with themovefilter. - The optional
restrictkeyword parameter for shift transforms. - Atomic evaluation of nodes involving variable modifications in
lineconstituents. - Optional
nolinearizeandnonatomickeyword parameters for thelinefilter. - CQLi allows
{?}to be used as an alias for the?quantifier inlineconstituents. - The string
"*"as an argument to theresultfilter to indicate an unfinished or incomplete game. - The
movefilter allows combiningcaptureandpromotewithlegalandpseudolegal. - The
movefilter allows thecountparameter to be used with all forms of themovefilter, not justlegalorpseudolegal. - Extended Smart Comments which suppresses comments whenever the enclosing expression does not match including many cases not covered by CQL 6.
- Commit Logging for
sortandconsecutivemoveswhich suppresses best-value updates and associated comments when an enclosing expression does not match. - The
yearfilter will attempt to extract the year from theUTCDatetag in the absence of aDatetag. - Variables declared in loops and functions have block scope.
- The
sortfilter does not require the use of a doc-string forsort min. - The
consecutivemovesfilter allows any position filter for its arguments, CQL 6.1 requires arguments to be position variables. - The
currentfenfilter may be used as an alias for the version of thefenfilter that does not receive a string literal argument. - CQLi supports up to 1000 regular expression backreferences in a pattern, CQL 6.1 supports 100.
- The CQLi-specific
noclobberkeyword parameter may be used with awritefilefilter to append to an existing file. - CQLi supports multiple comments at a position, CQL 6.1 removes all comments except the last.
- CQLi supports the following string regular expression features not supported by CQL 6.1: named capture groups (including extraction via
\{name}and\-{name}), lookbehind assertions, in-pattern comments, possessive matches, optional case-insensitive matching, and the backslash sequences\a,\A,\e,\E,\h,\H,\k,\N,\p,\P,\Q,\R,\U,\V,\X,\z, and\Z. - The
nonspecialandsortableparameters of thehhdbfilter.
Implementation Defined Behavior
Known differences in implementation-defined behaviors.
- The first and longest matching sequence reported by the
linefilter may be different between the implementations when there are multiple matching candidate sequences. - The portion matched by
lineconstituents involving multiple optional regex repetitions may be different between implementations.
Other Observable Differences
- If two transform keywords are followed by a range, the range applies to their composition in CQL 6.1 but to the most nested transform in CQLi. Thus,
shift flip count {a1 a7}yields64in CQL 6.1 and8in CQLi. cql()headers are always optional in CQLi, may appear anywhere a function definition is legal, and multiple headers are allowed (all but the last one is ignored).- In CQL 6.1
1/2-1/2,1-0and0-1are each individual tokens which means thatx = 1-0+1results in a parse error which can be rectified by placing whitespace on either side of the-. In CQLi these are not tokens which means that 1)x = 1-0is not a parse error and 2)result 1 - 0is treated the same asresult 1-0. - CQL 6.1 employs AST node transformations to accommodate certain filters such as
!=. The AST produced by CQLi always represents the query as written without performing such transformations. This difference is noticeable in error messages and when viewing the resulting AST via the--parseoption. - The
linefilter in CQL 6.1 utilizes a traditional backtracking algorithm for filter repetition which can result in extremely long evaluation times for certain combinations of games and patterns due to a phenomenon known as catastrophic backtracking. CQLi avoids this issue by employing a non-backtracking NFA search algorithm. - CQLi honors the enpassant square and castling rights specified in the FEN tag of a PGN game.
- Extraneous characters at the end of the FEN string in a
fenfilter result in an error at parse time. - CQLi honors the fullmove number specified in the FEN tag of a PGN game. The first move of a game with a FEN tag will start at the move number specified instead of
1. Themovenumberfilter, position portrayal in e.g.commentandmessagefilters, and the move number indicators in the output PGN file reflect this difference. - The
intfilter in CQLi will ignore leading whitespace and non-digit characters following a valid number, in CQL 6.1 theintfilter will not match the position for such strings. - CQL 6.1 allows a backslash literal (e.g.
\n) to be used in a context where a string literal is required (e.g. the implicit search string forplayer,site,event, etc.). CQLi does not support this usage. - CQLi allows dictionaries to be specified as
quietto indicate their values should not be emitted when using--showdictionaries. - The tag argument to the
settagfilter need not be a string literal in CQLi and there are no prohibitions on tags that may be modified with this filter. - CQLi does not require input or output files to have a prescribed file extension, including those operated on by the
readfileandwritefilefilters. - CQLi preserves one-line comments in PGN files (those that begin with a semicolon) and converts them to braced comments, CQL 6.1 removes one-line comments.
- CQLi recognizes
passas a null move in the move text of a PGN file. - When
countis used withlegalorpseudolegal, promotion moves that differ only in the type of the promoted piece are not counted separately in CQL 6.1 but are in CQLi. The CQL 6.1 behavior may be obtained by subtracting 3/4 of the generated promotions, e.g.move count legal - 3 * move count legal promote A / 4. - In CQLi, the
isboundfilter always returnsfalse, and theisunboundfilter always returnstrue, for a variable that does not exist in the lexical scope of the filter as identifier resolution is always performed at parse time. This behavior differs from CQL 6.1 where variables are resolved at run time and e.g.isbound Xwill returntrueif the variableXholds a value, even ifXis not declared until later. - In CQL 6.1 an
hhdbaward filter that does not specifyspecialwill only consider special awards if the result of the filter is not used in a numeric context. In CQLi, whether or how the result is used does not have any bearing on the behavior of a filter and anhhdbaward filter will always match both special and non-special awards unless one of thespecialornonspecialparameters are specified.
CQL Frontend Differences
New Features
- The
--limitrangeoption stops processing when the specified number of matching games are found. - The
--warnlevel/-woption accepts a value of 1, 2, or 3 and sets the warning level to the provided value. (1 = errors only, 2 = errors and warnings, 3 = errors, warnings, and infos). - The
--pgnlinewidthwidthoption specifies the maximum line width of output PGN files. - The
--coalescecomments/--nocoalescecommentsoptions specify whether multiple comments for a single position should be emitted as a single combined comment or as individual comments. - The
--compactmoves/--nocompactmovesoptions control whether space characters separate the move number indicator from the move in output files (e.g.1.e4vs1. e4). - The
--compactvariations/--nocompactvariationsoptions determine whether space characters appear between variation text and the enclosing parentheses in output files (e.g.1.e4 (1.d4)vs1.e4 ( 1.d4 )). - The
--compactcomments/--nocompactcommentsoptions specify if spaces should separate comments from the enclosing braces in output files (e.g.1.e4 {best by test}vs1.e4 { best by test }). - PGN and CQL files specified with relative paths on the command line are searched in the colon-separated list of directories in the
CL_PATHenvironment variable if the file cannot be found in the directory from which CQLi was invoked. - The
--showdictionariesoption may be used to cause dictionary values to be emitted at the end of processing with other persistent variable values. - The
--noremovetagoption suppresses tag removals via theremovetagfilter. - The
--secureoption rejects queries containingreadfile,writefile, orcommandpipefilters and causes theinputandoutputCQL header parameters to be ignored. - The
--keepallbestoption keeps comments associated with all best matches for theline,sort, andconsecutivemovesfilters. - The
--nosortoption reduces memory consumption by emitting matching games immediately. - The
--noclobberoption prevents overwriting existing output files. - The
--createdirectoriesoption automatically creates directories as needed for output files. - CQLi supports expressive diagnostics which include precise location information and query component highlighting in diagnostics and supports non-fatal warning and info messages.
- CQL 6.1 produces syntax errors for many valid, but suspicious, queries. CQLi accepts such queries after producing a non-fatal warning message.
Extensions
- The
--nosmartcommentsoption is an alias for--alwayscomment. - PGN files are not required to have a
.pgnextension and CQL files are not required to have a.cqlextension.
Missing Functionality
- The
-gui,-guipgnstdin, and-guipgnstdoutoptions are not supported.