the : operator
The:
operator has the form
position : filter
where position is a position filter and filter is any filter. It evaluates filter when the current position is set to the value of position. More exactly:
- The position filter is evaluated in the current position to get a position p.
- The current position is set to p
- filter is evaluated
- the current position is restored to its original value
The :
operator matches the current position if position matches the current position and if filter matches the position p. When the :
operator does match the current position, its value is whatever the value of filter at the position p was in step 2 above.
The :
operator has precedence higher than any other operator. Thus
x: f * g
is equivalent to
{x:f} * g
Examples of :
filters:
parent:check child:not check position 0 : child : comment ("first position")
The right argument to the :
filter can be arbitrarily complex, and can even include other :
filters.
Examples
The:
operator is often used in echo filters, where it is used to compare different positions, the "source" and the "target". Indeed, the :
operator is used in nearly every echo
filter in the examples: castleecho.cql, chameleon.cql, enpassantecho.cql, fatamorgana.cql, knightpawnforkecho.cql, zugzwang1.cql.
Often the :
operator is used to check the relation between the side to move in the source and target positions. In castleecho.cql, the :
operator is just used to check that side-to-move of the source or target positions are the same:
sidetomove==s:sidetomove
The filter is true if the current position (which is the target) has the same side to move as the position in the user variable s
, which is the source position of the echo
filter.
To check that kingside castling is legal in the source but not in the target, castleecho.cql uses the :
operator in this fragment:
s:move legal o-o and not move legal o-o
A more complex example is in movedblackpieceecho.cql. There, the source (which is now bound to a variable named source
) and the target need to be compared to see if one black piece has moved between them, and nothing else.
A piece variable Mover
is defined, which is bound to a black piece in the target that is in a different square (or nonexistent) in the source. Suppose x
is any square. Then the filter
x==Mover and source:(x&_)is true if the piece
Mover
is on x
in the current position (i.e., the target) and if x
is empty in source
.
Similarly,
x&_and source:(x==Mover)
is true if x
is empty in the current position but if the piece Mover
is on x
in the source. Note that the square on which Mover
can be different in the source and the current position.
Since x
must have different contents in the source and target, and since only a move of Mover
distinguishes source
and target
, exactly one of the two filters above must be true (if the target has the desired property with respect to the source).
The movedblackpieceecho.cql file puts this all together by making sure the two filters above are true at each square where the source
and target
positions differ. It loops over all the square in mismatches
and makes sure one of these two filters is true:
square all x in mismatches x==Mover and source:( x&_) or x&_and source:(x==Mover)
For an even more complex example of the :
filter, the see chameleon.cql, which seeks positions where the all the piece in the source have been shifted rigidly to a different color square in the target. This uses the filter
source:colortype up DeltaRank right DeltaFile Piece
Here, the variable Piece
is particular square . Despite its name, it is not a piece variable, but a set variable.
DeltaRank
and DeltaFile
are numeric variables that denote how much the target position
of the white King has shifted compared to the source. The filter above computes the colortype (a number representing the piece type and color of the contents of a square) of the square in the source that is reached by shifting the square Piece
by the specified amounts. This example illustrates how careful one must be in distinguishing piece variables and square variables when using the :
operator.