# xray

The `xray` filter is a sort of generalized pin.

In a pin, the pinning piece would attack a target piece except for the presence of a pinned piece. But in a normal pin the colors of the pinning piece and the pinned piece are different.

In an xray, we allow any configuration of pieces in a line, in which the last piece in the line would be attacked by the first piece in the line except for the presence of the other pieces in th eline.

Examples of xrays are:

```  xray (R a k)
xray (Q A K)```

The first filter `xray (R a k)` matches a position where a black piece (the `a`) is pinned by a white rook (`R`) to the black king (`k`):

xray(b5 d5 g5)

It is an xray because without the bishop on `d5`, the `R` would attack the `k`.

However, this filter would not match the following position:

not xray(b3 d5 f7)

because even without the `bd5` the `R` does not attack the `k`.

The second filter `xray (Q A K)` matches a position where there is a single white piece (`A`) between a white queen (`Q`) and the white king (`K`), e.g.:

xray(b3 d5 f7)

## Specification

More formally, the `xray` filter takes any number of set filter arguments enclosed in parentheses. For simplicity we discuss the case of 3 arguments:
`  xray (x y z)`

Here x, y, and z are set filters. Suppose in the current position these set filters correspond to sets of squares X, Y, and Z respectively.

Then the above `xray` filter matches a position if there are distinct squares sx, sy, and sz in X, Y, and Z respectively such that

• sx contains a line piece (rook, bishop or queen)
• The piece on sx attacks sy
• If the square sy were empty, then sx would attack sz
• If the square sy were occupied by a piece, then sx would not attack sz

This is extended to more than three arguments exactly as in the case of `ray`. In fact, `xray` can be defined in terms of `ray`:

Any `xray` of the form

`  xray (x other_args)`
where other_args is a sequence of set filters, is equivalent to:
```  ray orthogonal ({x&[RrQq]} other_args)
| ray diagonal ({x&[BbQq]} other_args)```

# Examples

The `xray` filter is used in bristol-universal.cql, idealmate.cql, modelmate.cql, indian.cql, turton.cql and puremate.cql.

An unusual 4 argument `xray` filter is used in indian.cql, where if finds the following study:

Costeff 1996 after 1...e2
(found from CQL file: indian.cql)

In the diagrammed position, White has to be worried both about stalemating black if the pawns on `e2, a7, e7` disappear or run out of moves; and of course about the `ng1` moving and freeing the pawns `ph2,pg2`. White has two reasonable moves: `2.Ra1` and `2.Rb1`. It turns out that only `2.Rb1` wins, as the position after `2.Rb1 a6 3.Ra1` is zugzwang: black to move loses, white to move draws. If White had played immediately `2.Ra1?` then black responds `2...a6!` reaching the zugzang position with white to move.

One reason for this is an Indian theme. White promotes the `Pd5` to a bishop and interposes it to `b1`, preventing stalemate:

xray(a1 b1 g1 h1) from Costeff 1996, after 12.Bb1
(found from CQL file: indian.cql)

One of the elements of the Indian theme is that White moves to a critical square (here the move `12.Bb1`) in order to prevent stalemate. The CQL code in `indian.cql` is somewhat convoluted, but for our purposes the key filter is:

`  xray (rear critical x k)`

The goal of this filter is to express the concept that the piece on `x` would be pinned if not for the piece on `critical`. In the diagrammed position, `rear` has value `a1`; `critical` has value `b1`; `x` has value `g1`; and the `k` is on `h1`. The rook on `a1` would attack the `kh1` but for the pieces on `b1` and `g1`. Equivalently, the `ng1` is pinned but for the `Bb1`.

(This study actually expresses a double Indian, because at move 10 the bishop had moved to `d1`, also preventing stalemate, which explains the apparent duplicate comments in the PGN file).