Have you tried running it with verbose_logging on (see
http://www.puzzlescript.net/Documentation/prelude.html )? That may tell you your answer.
The first rule
late [ sprite | ... | player ] -> [ player | ... | sprite]
is broken down by the compiler into a group of four rules, for each direction - let's look at two of them
left [ sprite | ... | player ] -> [ player | ... | sprite]
left [ player | ... | sprite ] -> [ sprite | ... | player]
if the first rule is applied, the second will be applied to swap the sprite and the player back - so the rule group has no effect, but it (and I could perhaps make the engine smarter so it doesn't do this) has noted that one of its rules did something, so it tries to apply it again.
Rule groups as a whole are applied until none of the subrules can be applied. However, if two subrules cancel eachother out, it gets stuck in a loop.