%%%%%%%%%%%%%%%%%%%%%%%
%                     %
% AND/OR Hanoi Tower. %
%                     %
%%%%%%%%%%%%%%%%%%%%%%%

:- set_prolog_flag(toplevel_print_options,
                   [quoted(true), portray(true), max_depth(0)]).

:- use_module(andor).



hanoi(N) :-
    hanoi(N, _).

hanoi(N, Path) :-
    enum2(N, 1, Start),
    solve([Start, 1, 3], Path),
    nl, showHanoiSol(Path), nl.




goal([[_], _, _]).



[[P1, P2|Ps], X, Y] ---> and:[
                               [[P2|Ps], X, Z],
                               [[P1], X, Y],
                               [[P2|Ps], Z, Y]
                             ] :-
    aux(X, Y, Z).



% aux(X, Y, Z)
% Number of the auxiliary peg Z.
aux(1, 2, 3).
aux(1, 3, 2).
aux(2, 1, 3).
aux(2, 3, 1).
aux(3, 1, 2).
aux(3, 2, 1).

% aux(X1, X2, X3) :-
%     select(X1, [1,2,3], L),
%     select(X2, L, [X3]).



% enum2(A, B, L).
% enum A to B with A > B
enum2(A, A, [A]).
enum2(A, B, [A|Ls]) :-
    A > B,
    A1 is A - 1,
    enum2(A1, B, Ls).



% Show solution
showHanoiSol(_ ---> Tree) :- !,
    showHanoiSol(Tree).

showHanoiSol(and:[T]) :- !,
    showHanoiSol(T).

showHanoiSol(and:[T|Ts]) :- !,
    showHanoiSol(T),
    showHanoiSol(and:Ts).

showHanoiSol([[X], Y, Z]) :-
    write('Move disk '), write(X),
    write(' from '),
    write(Y), write(' to '), write(Z), nl.

