%u(+, 1, 1).
%u(+,-1,-1).
%u(-, 1,-1).
%u(-,-1, 1).
%
%opp(1,-1).
%opp(-1,1).
%
%s(X,S) :- e(X,Y,U), s(Y,S1), u(U,S0,S).
%s(X,0) :- s(X,1), s(X,-1),

node(1,8,A0,A,t(A0,B,C,D,E,F,G,H),t(A,B,C,D,E,F,G,H)).
node(2,8,B0,B,t(A,B0,C,D,E,F,G,H),t(A,B,C,D,E,F,G,H)).
node(3,8,C0,C,t(A,B,C0,D,E,F,G,H),t(A,B,C,D,E,F,G,H)).
node(4,8,D0,D,t(A,B,C,D0,E,F,G,H),t(A,B,C,D,E,F,G,H)).
node(5,8,E0,E,t(A,B,C,D,E0,F,G,H),t(A,B,C,D,E,F,G,H)).
node(6,8,F0,F,t(A,B,C,D,E,F0,G,H),t(A,B,C,D,E,F,G,H)).
node(7,8,G0,G,t(A,B,C,D,E,F,G0,H),t(A,B,C,D,E,F,G,H)).
node(8,8,H0,H,t(A,B,C,D,E,F,G,H0),t(A,B,C,D,E,F,G,H)).

portray(X) :- once(node(_,N,_,_,X,_)), write(n/N).

place(This=That,T0,T) :- 
	once(node(_,N,_,_,_,_)),
	hash_term(This,Hash), 
	place0(Hash mod N^4,N,[Place|Places]),
	place1(Places,Place,This=That,T0,T).

place1([],Place,This=That,T0,T) :- 
	node(Place,_,Old,New,T0,T),
	placed(Old,This=That,New).
place1([Places2|Places],Place1,This=That,T0,T) :-
	node(Place1,_,Old,New,T0,T),
	place1(Places,Places2,This=That,Old,New).
	
place0(M,N,[M]) :- M < N,!.
place0(M,N,[Pos|Rest]) :-
	Level is floor(log(M) / log(N)),
	Pos   is floor(M/(N^Level)),
	Less  is M - Pos*(N^Level),
	place0(Less,N,Rest).

placed(L0,X=Y,L) :- 
	var(L0) -> L = [X=Y] ; within(L0,X=Y,L).	

within([],        X=Y,[X=Y]).
within([X=Y|T],   X=Y,[X=Y|T]).
within([X0=Y0|T0],X=Y,[X0=Y0|T]) :- not(X0=X), within(T0,X=Y,T).
	

