relation filterThe relation filter compares two different positions from the same game.
The position reached when the relation filter is first evaluated is called the source. Every time CQL evaluates a relation filter at a source position, it successively tries to match every other position in the game against the source. The other position that is matched against the source is called the target. The parameters and arguments of the relation filter itself tell CQL how the matching is to be performed.
Syntactically, a relation filter consists of the keyword 'relation' followed by a sequence of zero or more target filters followed by a sequence of one or more relation parameters. Each target filter is just an ordinary filter that will be applied to the target. Each relation parameter is a special kind of filter that matches a source and target at the same time.
It is easy to identify a relation parameter: they are always enclosed in parentheses, except for an
echo transform parameter, which consists of a keyword beginning with the string
echo followed by a square parameter.
relation := 'relation' targetfilters relationparameters targetfilters := filter* relationparameters := relation_parameter+A target is said to match a source according to the relation filter if:
- each filter in the targetfilters part of the relation_filter matches the target. Note that the current position is set to the target before this matching is done.
- each relation_parameter in the relationparameters part of the relation_filter matches the source and target together
There are four types of relation parameters, as described by the following table (click on parameter type for more information about a particular parameter type):
|Parameter type||Sample usage||Function|
||compare the contents of a set of squares in the source and target|
||compare the side to move in the source and target|
||compare the sequences of moves leading to the source and the target|
|echo transform parameter||
||transform the target before applying a square parameter|
wtmand the target is
cql(input i.pgn) wtm relation btm (mismatch 0)In the above code we get:
- targetfilters =
- relationparameters =
(mismatch 0). This is a square_parameter that specifies that the source and target positions are identical.
V. Dolgov & B. Sidorov
1.p Rubinstein MT Szachy
|position after 2..Rg8||position after 9.Ke1|
A more in-depth explanation:
wtm is a filter that is evaluated at the source. It is not part of the
relation filter, but the relation would not be evaluated at a position unless that position were also wtm because otherwise the
wtm filter would have already failed.
The relation has a single target filter,
btm. When the
relation filter is evaluated at the current position, every other position in the game will be tried as a target, that is, the current position will be successively set to every other position in the game. Only those positions
that match the target filters, in this case the single filter
btm will be considered.
This relation filter has a single relation parameter,
the square parameter
(mismatch 0). A relation parameter compares the source and target in various ways. In this example,
(mismatch 0) is a square parameter that compares the board positions of the source and target and is true only if they are equal.
The above code matches the Fata Morgana theme.
relation annotationsUnless preceded by silent the
relationfilter adds various comments indicating the source, the target, and where applicable the LCA and the matched longest common path. Each matched target is annotated with the word "TARGET" followed by a number followed by a list of numbers in brackets, like
TARGET 4 [2 3]
The first number, 4 here, is the number of the matched target, indicating that the position resulting from the move with that annotation is target 4. There will be other targets in the
PGN file annotated with
The brackets are the numbers of the sources, here indicating the target corresponds to sources 2 and 3. Likewise, each source will have similar annotations, with brackets indicating which targets they correspond to, e.g.
SOURCE 3 
indicating that the position resulting from the annotated move is source number 3 and is associated with target 4.
pitfalls in using relationThere are two things to keep in mind when using
- the rules for the position in which filters are evaluated can be confusing. Target filters are evaluated at the target. But in a square parameter, the
sourcesquaresfilter is evaluated at the source position, even though the
targetsquaresfilter is evaluated at the target position. This can be particularly confusing when the filter contains a piece variable: the variable looks the same but can represent different squares in the
targetsquaresor in the targetfilters.
relationcan be slow, because each possible target is checked at each possible source. The
echoshiftparameter is particularly slow because for each target, 224 shift transforms (the rank and file can each be shifted from -7 to 7, independently) must be compared. When a relation is also under the scope of another transform (like
shift flipor a
piecefilter, it is possible for tens of thousands of source/target position comparisons to be performed for every source/target pair, so that in a long game millions of comparisons - each requiring potentially full board comparisons - need to be performed.