In this co-recursive Prolog solution we need two building blocks.
One building block is a way to enumerate a search tree co-recursively in Prolog. We adopt the idea that the Prolog closure term should carry an agenda with the paths and thus nodes that should be expanded. We can then start with an agenda that only contains the root:
% tree(-Path, -LazyPaths)
tree(H, T) :-
tree([[]], H, T).
To archive breadth first enumeration we will append the new expanded paths and thus nodes at the end of the agenda. This can be done by a simple list append predicate call, so that the missing definition reads as follows. In the full binary tree paths and thus nodes are always expanded twice:
% tree(+Paths, -Path, -LazyPaths)
tree([X|Y], X, tree(Z)) :-
append(Y, [[0|X],[1|X]], Z).
Here is an example run:
?- take(5, tree, L).
L = [[],[0],[1],[0,0],[1,0]]
?- take(10, tree, L).
L = [[],[0],[1],[0,0],[1,0],[0,1],[1,1],[0,0,0],[1,0,0],[0,1,0]]
In case of the evaluator problem we will have a path and thus node expansion that will not always lead to two successors. If we are at a level k, the elevator can go to a level k+2 or k-3, only provided the elevator stays inside the building. So we readly arrive at a co-recursive predicate steps that does simulate all possible paths of the elevator:
?- take(5, steps(7,[[2]]), L).
L = [[2],[4,2],[1,4,2],[6,4,2],[3,1,4,2]]
?- take(10, steps(7,[[2]]), L).
L = [[2],[4,2],[1,4,2],[6,4,2],[3,1,4,2],[3,6,4,2],
[5,3,1,4,2],[5,3,6,4,2],[2,5,3,1,4,2],[7,5,3,1,4,2]]
The last hurdle and second building block is to get a Haskell dropWhile in Prolog. We didn't aim at a predicate that takes a Prolog closure term argument for the boolean condition, but instead only provide a predicate that enumerates the lazy list elements, and the user of the predicate can filter in the Prolog continuation.
% drop_while(+LazyList, -Element)
drop_while(C, P) :-
call(C, Q, T),
(P = Q; drop_while(T, P)).
If we put everything together we get a co-recusive Prolog solution, that can even potentially enumerate all infinite solutions to the evaluator problem via backtracking besides calculating the results in breadth first order:
?- elevator(7,2,6,L), length(L,N).
L = [6,4,2],
N = 3 ;
L = [6,4,2,5,3,1,4,2],
N = 8 ;
L = [6,4,7,5,3,1,4,2],
N = 8