The consecutivemoves filter takes two position filters in parentheses as arguments, optionally preceded by a range:
  consecutivemoves (x y)
  consecutivemoves 5 1000 (x y)

Suppose the arguments to the consecutivemoves filter are the two position filters whose values are x and y.

The consecutivemoves filter first finds the latest common ancestor L of the position arguments x and y.

Let S be the sequence of moves from L to x. Let T be the sequence of moves from L to y. S and T are the exact moves, in order, played to reach x from L and to reach y from L respectively. Thus, the length of S is equal to the ply value of x minus the ply value of L. Similarly the length of T is the ply value of y minus the ply value of L.

The consecutivemoves(x y) gives the length of the longest sequence of consecutives moves in S that is identical to a sequence of consecutive moves in T.

If a range is specified, the consecutivemoves filter only matches if that length lies with the range. If either of its argument filters do not match, then neither does the consecutivemoves filter.

The consecutivemoves filter adds comments to the longest pair of subsequences of consecutivemoves that it located (unless the quiet or silent was specified in the CQL header). These comments indicate which move in one subsequence matched which move in the other subsequence.

The consecutivemoves filter is used in locating so-called "logical" studies, where one key move (the move in the LCA position) has a small difference that only becomes apparent much later.

< id="quiet">If the parameter quiet is included, the consecutivemoves filter does not output any comments. (The filter also does not output comments if the quiet is specified in the CQL header):

    consecutivemoves quiet 15 100 (source target)


The consecutivemoves filter is used in zugzwang2.cql and movedblackpieceecho.cql . In zugzwang2.cql, the consecutivemoves filters is used to find a zugzwang position where the positions differing only in side to move are reached by a series of identical moves.

In the following position from a Didukh study, White can play either 2. Kf3! or 2. Kf2:

Didukh 2011, mainline after Black's 1...Nf5
(found from CQL file: zugzwang2.cql)

If White plays 2. Kf3 the position leads to the following position, which is winning for White:

Didukh 2011, mainline after 10. Kf2

If on the other hand, white plays 2. Kf2, then Black reaches the following the position, which is identical to the position above except that it is white to move instead of black to move:

Didukh 2011, variation after 9...Bb7

The sequences of moves to reach the two positions above are the same for 15 consecutive individual moves. For example, from the PGN output for the Didukh study, we see that if White were to play 2. Kf2 then Black would respond 2...Ne7.

Note the comments of the form: target-move or source-move. The comments were generated as a consequence of the filter:

    consecutivemoves (source target)>= 5

in the CQL file zugzwang2.cql. It was called when the source was set to the mainline black-to-move position (diagrammed above) after 10. Kf2, and target was set to the variation white-to-move position (diagrammed above) after 9...Bb7.

The comment target-move[1] means that this is the first (because of the [1]) move of the sequence of moves leading to target . There is a corresponding sequence of moves leading to source, and the first move of that sequence, which is 2...Ne7 in the mainline, is annotated source-move[1]. Both these moves are the same: ...Ne7.

Reading down the moves in the variation and mainline, one can see the correspondence of identical moves between the variation and the mainline.