# Filters

Every CQL file is built from*filters*.

A *filter* is a CQL construct which can either *match the current position* or *fail to match the current position*.

If a filter matches the current position, we say the filter is *true* in the current position. Otherwise, we say the filter is *false* in the current position.

We sometimes just say a filter *matches* as shorthand for "matches the current position". Or we might say a filter *matches a position X* if, when the current position is set to the value of *X*, the filter matches the current position.

A filter is *evaluated* at the current position. This evaluation determines two things about the filter:

- Whether the filter matches the current position
- If it does match the current position, what the
*value*of the filter is

A filter is only ever applied to the current position. But
it can be applied to many different positions in a game as the current
position is updated by the CQL main loop. Some filters, like `line`

and `find`

can themselves temporarily modify the current position.

For example, one filter is the `check`

filter. This will match the current position if one
of the Kings is in check in that position. The name of the
`check`

filter is simply `check`

Many filters include other filters as constituents. For example, an
`or`

filter has two constituents: the filter to its left and the filter to its right.

check or Ra3is a single filter with two constituents. The filter matches a position when

*either*there is a check

*or*the White rook is on a3 (or both).

## value of a filter

Some filters can have a*value*. This means that when the filter is evaluated in the current position, the filter computes an associated value. Sometimes we say the filter

*returns*this value or that it

*represents*this value.

A value can be either:

- a set of squares (sometimes abbreviated to just
*set*) - a number (32-bit integer)
- a position

These are the only values a filter can represent. Some filters never have a value, even if they
match a position. These filters are called *logical* filters. Examples are check, mate, hascomment.

### Numeric Filters

A filter that represents a number is called a*numeric filter*.

A numeric filter only has a value if it matches the current position.

Numeric filters include rank, file, sort, line and +. Examples of numeric filters are:

34 #R + #q rank R

Here, `34`

is a numeric filter whose value is, not surprisingly, 34.

`#R+#q`

is a numeric filter whose value in the current position is the sum of the
number of white rooks and the number of black queens in the position. More exactly, `R`

is a filter whose value is the set of squares on which there is a white rook. `#R`

is a filter whose value is the cardinality of this set of squares, which is to say the number of white rooks. Likewise `#q`

is a filter whose value in the current position is the cardinality of the set of squares on which there is a black queen. `+`

is a filter whose value is the sum of the values of its left and right arguments, which in this case are the number of white rooks and the number of black queens respectively.

The last filter, `rank R`

is more complicated. It only matches the position if there is exactly one white rook in the position. In that case its value is the
rank of the square of that white rook. But if there are no white rooks, or more than one white rook, the `rank`

filter does not match.

### Set Filters

A filter that represents a set of squares is called a*set filter*. Set filters include attacks, between, piece designators like

`Pa-h2`

, square, piece and the direction filters (like up or vertical).
Unlike numeric filters and position filters, a set filter has a value no matter what: if a set filter does not match a position, its value is the empty set.

Examples of set filters are

move from Q to n pin

The value of `move from Q to n`

is the set of squares on which there is a white queen which captures a black knight on the next move. The value of `pin`

is the set of squares on which there is a piece pinned against its own king by a piece of the opposing color. Each of these filters will only match a position
if the associated set is nonempty.

A piece variable is a set filter even though it stores the value of a piece. When a piece variable is used, its value is the square on which the piece it represents lies.

### Position filters

A filter that represents a position is called a*position filter*. Position filters include child, parent, position, find and currentposition.

A position filter only has a value if it matches the current position.

Examples of position filters are:

parent find move promote R

Here, `parent`

is a position filter whose value is the position that is the parent of the current position. The `find`

filter takes a single filter
as argument, and returns the next position in which that filter is true.

In this case the argument is `move promote R`

. The `move`

filter here matches a position if the next move is a rook underpromotion. Thus,
`find move promote R`

will have as value the position from which the next rook underpromotion occurs, if it exists. If there is no such next
rook underpromotion, then the `find`

filter will not match.

## arguments to filters

Some filters take one or more *arguments*. An *argument* is another filter that the filter applies to.

For example, the *power* filter takes one argument a *set filter*. A set filter is a particular type of filter whose value is a set of squares.
The *power* filter has a value equal to the total material of all the pieces on a square in the set given by its argument.

power R

Here, the argument to `power`

is the filter `R`

.
Here, `R`

is a set filter that is equal to the set of squares that have a white rook on them. If the start position of a chess game, for instance, its value
is the set of two squares: `a1`

and `h1`

. The *power* filter then computes the material on those squares (which would be 10 in that position).

When a filter takes only one argument, the argument just follows the filter:

sort R not Q #P

Some filters have multiple arguments.

In the case of *prefix filters*, where the name of the filter precedes the arguments, the arguments are enclosed in parentheses:

between (R n) ray (R between (N k) k) max (#R #Q)

The arguments to `between (R n)`

for example are the two filters `R`

and `N`

.

The `ray`

filter above, however, has three arguments: `R`

, `between (N k)`

and `k`

.

Some filters are *infix filters*, where the name of the filter is between the two arguments to the filter. The infix filters are mostly symbols (like `>`

, `+`

, `==`

, `:`

and so on) with the exceptions of `and`

, `or`

, `attacks`

, and `attackedby`

. Thus in the example

A attacks k

the `attacks`

filter has two arguments: `A`

and `k`

. We call `A`

the *left* argument` of the filter `

attacks` and we call `

k` the `

of the filter *right* argument`attacks`

.

## parameters to filters

Some filters also have*parameters*. A parameter is a keyword, or a keyword followed by a value, that controls how the filter acts on its arguments.

For example, the `move`

filter has many parameters (and no arguments). The filter:

move legal from R to _is a

`move`

filter with three parameters:
- The
`legal`

parameter, which has no value. The`legal`

parameter specifies that all legal moves are considered, rather than just the moves that occur in the PGN file - The
`from`

parameter, whose value is the filter`R`

. It specifies that only moves of a white rook are to be considered - The
`to`

parameter, whose value is the filter`_`

. It specifies the only moves to an empty square are to be considered

The filter will match the current position if there is a legal move of a white rook to an empty square.

Some filters have an optional unnamed parameter: an *optional range*. A *range* is specified by listing one or two numbers. It represents all integers
between its these values, inclusively. For example the range `1 3`

represents the numbers `1,2,3`

.

## Precedence and Parsing

Sometimes it can seem difficult to parse an expression using filters. For example, what does this mean?not Ra3 or check

It might mean either of the two possibilities below:

{not Ra3} or check not {Ra3 or check}

The first possibility would match a position in which either there is no white rook on `a3`

or
one side is in check. The second possibility would match a position in which there is neither
a white rook on `a3`

nor is there a check.

CQL in this case chooses the first interpretation. The reason has to do with *precedence*: the
*not* filter has a higher precedence than the *or* filter.

Precedence is discussed in more detail in the precedence section. See also the precedence table, concisely summarizing the precedence rules.

## reading argument lists

Sometimes reading CQL code can be confusing because an argument list might contain more than one filter. An argument list is a series of one or more filters separated by white space and enclosed in parentheses.For example, the argument list

(Ra3 check)is an argument list with two filters in it . Similarly

(Ra3 or Nb2 check or stalemate)is another argument list with two filters. The first filter is the or filter

Ra3 or Nb2which matches a position if there is a white rook on a3 or a white knight on b2. The second filter is

check or stalematewhich is true if either the position is stalemate or check

This could be written equivalently as

({Ra3 or Nb2} {check or stalemate})If it's clearer to you, always enclose filters in braces.

You might be tempted to think that

(Ra3 or Nb2 check or stalemate)Might be parsed as

(Ra3 or {Nb2 check} or stalemate)but this would be incorrect, because

Nb2 checkis not the same as

{Nb2 check}

Note that there is no filter

Nb2 checkThe rule to remember here is this:

*Two filters next to one other separated by white space is never a single filter*

## More parsing examples

Likewise,{not Ra3 check}matches positions where the R is not on a3

*and*the position is a check. It is equivalent to

{ {not Ra3} check}

This is because there is no such single filter

Ra3 checkso that

Ra3 checkcannot be an argument to

`not,`

which takes only a single filter as its argument.
This rule is most commonly applied to transform filters (`shift`

,
`flip`

and so on). All of these take a single filter argument, but it is common to want to apply these to multiple filters at once. Remember to enclose their bodies in braces if you want to apply them to multiple filters at once. For instance, use

{rotate90 Ka1 kh8}would be parsed as

{{rotate90 Ka1} kh8}which would match a position with the white King on a corner and the black on h8.

By contrast,

{rotate90 {Ka1 kh8}}

would match positions with the kings on diagonally opposite corners.

However, since a transform filter is itself one filter, they can be chained:

flipcolor rotate90 {Ka1 kh8}would apply

`flipcolor`

to the result of applying `rotate90`

to `{K1 kh8}`

(which in point of fact would not change anything semantically here).

## combining filters

One of the most powerful features of CQL is that filters can be combined. Any time a filter takes an argument, or a parameter takes a value, that argument or value can be another filter.
For example, `#`

is a filter whose value is the number of squares of its argument, which must be a set filter.
Thus, `#R`

is the number of white rooks in a position.

`A attacks k`

is a filter whose value is the set of squares on which there is a white piece giving check.

`>`

is a filter which is true if its left argument is greater than its right argument. Therefore,

#{A attacks k}>1will be true of a position where White is giving double check. In the above, we don't actually need the braces.

In fact, we can just write

A attacks k>1

here because `>`

converts a set argument to a cardinality in this case.