lcafilter takes two arguments enclosed in parentheses. Each of these two argument is a position filter. The value of the
lcafilter is the position that is the latest common ancestor of the two positions.
Suppose x and y are two positions.
We begin by defining the term generalized ancestor. We say that a position x is a generalized ancestor of position y is either
x == y or x is an ancestor of y.
Then the position L is the latest common ancestor of x and y if the following conditions are met:
- L is a generalized ancestor of both x and y
- Suppose z is another position that is also a generalized ancestor of both x and y. Then the ply value of L is greater than the ply value of z.
Note that if
x == y then the LCA of x and y is x. Similarly, if x is an ancestor of y, then the LCA of x and y is just x.
The interesting case is when x and y are distinct positions and neither is an ancestor of the other. Their LCA in this case is a sort of decision point: it's the latest point in the game where one side can definitively avoid either one of them.
Suppose for instance that L is a white to move position. This means that from the position L, there are two moves white can make, say M1 and M2. If white choses to make move M1, then the game can reach position x, but the game cannot reach position y. But, if white makes move M2, then the position cannot reach position x but the game can reach position y. It's up to white which move to make.
The latest common ancestor is useful in understanding studies involving echoes (or more generally logical studies). It helps us understand the "key" move that white makes to choose of avoid one of a pair of related positions. The LCA position is commented by default in the
echo filter, except when it is trivial (when one of the source and target is an ancestor of the other).
lcafilter is used in fatamorgana.cql, queenpawnpinecho.cql, and underpromotionecho.cql.