// Download lacny.cql
// PGN output when run on sample.pgn

cql(quiet variations)
 3-fold Lacny theme in mate-in-2
 After the key:
     black moves x, y, z
 are mated respectively by
       white moves X, Y, Z
 Set play: After initial null move by white,
      black moves x, y, z
 are mated respectively by
      white moves Z, X, Y

 Each move is represented by the position it leads to.
 Note that many of the compound filters are longer than they appear:
 they sometimes continue on the next line without indentation.

S(other) is true if the move represented by position other
 is the same as the move represented by the current position

function S(other){
   move from . previous == other:move from . previous
   move to . previous == other:move to . previous

D(other): shorthand for "not S(other)"

function D(other){
  not S(other)

initial start=currentposition wtm
line primary
    --> .
    --> {key=currentposition}
    --> {x=currentposition}
    --> {mate X=currentposition}

key:line firstmatch
         --> . //after the key move
         --> {y=currentposition D(x)}
         --> {mate Y=currentposition D(X) //note: compound filter continues...

key:line   --> .
           --> {z=currentposition D(x) D(y)}
	   --> {mate Z=currentposition D(X) D(Y)

start:line --> move null
           --> {set=currentposition}
	   --> {S(x) set_x=currentposition}
	   --> {mate set_Z=currentposition S(Z)

set:line   --> . //after the set move
	   -->{S(y) set_y=currentposition}
	   -->{mate S(X) set_X=currentposition

set:line   -->.
	   -->{S(z) set_z=currentposition}
	   -->{mate S(Y) set_Y=currentposition

X:comment("[X]") Y:comment("[Y]") Z:comment("[Z]")
x:comment("[x]") y:comment("[y]") z:comment("[z]")
set_x:comment("[set play: x]") set_y:comment("[set play: y]") set_z:comment("[set play: z]")
set_X:comment("[set play: X]") set_Y:comment("[set play: Y]") set_Z:comment("[set play: Z]")