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:

  1. The position filter is evaluated in the current position to get a position p.
  2. The current position is set to p
  3. filter is evaluated
  4. 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.