% RUBIK PROGRAM
%
% Copyright 1996, David Lee Winston Miller.
%
% All rights reserved.  This software is not shareware or freeware.  The
% software may be used only to evaluate the research presented and may not
% be used for any commercial purpose.  The sofware may not be distributed to
% others.  (The only distribution allowed is from my Web site.)  The
% software may not be modified.  There is no warranty implied or given with
% this software.  Use it at your own risk.  The author assumes no liability
% for any damages resulting from the use of this software.  Portions of the
% software may be covered under other copyrights.
%
%
% Before using, first consult dcorn2.ari, dedge2.ari, bfast3.ari.  Also
% the file efile.txt must be in same directory that you started the API in.
% Before running, type makeehash.


%makeehash. This predicate uses a file called efile.txt to create a hash
% table.  The format of efile.txt is:
% e(Profile,EstimatedMovesAwayFromSolved),e(Profile,...
% and ends with a comma.
makeehash :-
  open(H,'efile.txt',r),
  removeallh(e),
  defineh(e,1018),
  repeat,
  read(H,Line),
  write(Line),
  ifthen(Line=e(P,M),
  		(recordh(e,P,e(P,M)),fail)),
  close(H).


%moves for corner mini-cubes:
gR(a,a). gR(b,b). gR(c,c). gR(d,d). gR(e,l). gR(f,j). gR(g,g). gR(h,h).
gR(i,i). gR(j,v). gR(k,k). gR(l,s). gR(m,f). gR(n,n). gR(o,e). gR(p,p).
gR(q,x). gR(r,w). gR(s,o). gR(t,t). gR(u,u). gR(v,m). gR(w,q). gR(x,r).

gL(a,a). gL(b,b). gL(c,c). gL(d,d). gL(e,o). gL(f,m). gL(g,g). gL(h,h). 
gL(i,i). gL(j,f). gL(k,k). gL(l,e). gL(m,v). gL(n,n). gL(o,s). gL(p,p). 
gL(q,w). gL(r,x). gL(s,l). gL(t,t). gL(u,u). gL(v,j). gL(w,r). gL(x,q). 

wR(a,a). wR(b,i). wR(c,c). wR(d,d). wR(e,e). wR(f,f). wR(g,p). wR(h,s). 
wR(i,w). wR(j,b). wR(k,k). wR(l,g). wR(m,m). wR(n,n). wR(o,o). wR(p,v). 
wR(q,q). wR(r,t). wR(s,r). wR(t,h). wR(u,u). wR(v,l). wR(w,j). wR(x,x). 

wL(a,a). wL(b,j). wL(c,c). wL(d,d). wL(e,e). wL(f,f). wL(g,l). wL(h,t). 
wL(i,b). wL(j,w). wL(k,k). wL(l,v). wL(m,m). wL(n,n). wL(o,o). wL(p,g). 
wL(q,q). wL(r,s). wL(s,h). wL(t,r). wL(u,u). wL(v,p). wL(w,i). wL(x,x). 

oR(a,g). oR(b,l). oR(c,c). oR(d,d). oR(e,n). oR(f,a). oR(g,r). oR(h,h). 
oR(i,i). oR(j,e). oR(k,b). oR(l,x). oR(m,m). oR(n,t). oR(o,o). oR(p,p). 
oR(q,q). oR(r,f). oR(s,s). oR(t,j). oR(u,u). oR(v,v). oR(w,w). oR(x,k). 

oL(a,f). oL(b,k). oL(c,c). oL(d,d). oL(e,j). oL(f,r). oL(g,a). oL(h,h). 
oL(i,i). oL(j,t). oL(k,x). oL(l,b). oL(m,m). oL(n,e). oL(o,o). oL(p,p). 
oL(q,q). oL(r,g). oL(s,s). oL(t,n). oL(u,u). oL(v,v). oL(w,w). oL(x,l). 

yR(a,c). yR(b,a). yR(c,h). yR(d,p). yR(e,e). yR(f,f). yR(g,n). yR(h,b). 
yR(i,g). yR(j,j). yR(k,d). yR(l,l). yR(m,m). yR(n,u). yR(o,o). yR(p,t). 
yR(q,q). yR(r,r). yR(s,s). yR(t,k). yR(u,i). yR(v,v). yR(w,w). yR(x,x). 

yL(a,b). yL(b,h). yL(c,a). yL(d,k). yL(e,e). yL(f,f). yL(g,i). yL(h,c). 
yL(i,u). yL(j,j). yL(k,t). yL(l,l). yL(m,m). yL(n,g). yL(o,o). yL(p,d). 
yL(q,q). yL(r,r). yL(s,s). yL(t,p). yL(u,n). yL(v,v). yL(w,w). yL(x,x). 

bR(a,e). bR(b,b). bR(c,n). bR(d,a). bR(e,q). bR(f,o). bR(g,g). bR(h,h). 
bR(i,i). bR(j,j). bR(k,f). bR(l,l). bR(m,c). bR(n,x). bR(o,u). bR(p,p). 
bR(q,d). bR(r,r). bR(s,s). bR(t,t). bR(u,k). bR(v,v). bR(w,w). bR(x,m). 

bL(a,d). bL(b,b). bL(c,m). bL(d,q). bL(e,a). bL(f,k). bL(g,g). bL(h,h). 
bL(i,i). bL(j,j). bL(k,u). bL(l,l). bL(m,x). bL(n,c). bL(o,f). bL(p,p). 
bL(q,e). bL(r,r). bL(s,s). bL(t,t). bL(u,o). bL(v,v). bL(w,w). bL(x,n). 

rR(a,a). rR(b,b). rR(c,o). rR(d,m). rR(e,e). rR(f,f). rR(g,g). rR(h,u). 
rR(i,d). rR(j,j). rR(k,k). rR(l,l). rR(m,s). rR(n,n). rR(o,w). rR(p,c). 
rR(q,v). rR(r,r). rR(s,i). rR(t,t). rR(u,q). rR(v,h). rR(w,p). rR(x,x). 

rL(a,a). rL(b,b). rL(c,p). rL(d,i). rL(e,e). rL(f,f). rL(g,g). rL(h,v). 
rL(i,s). rL(j,j). rL(k,k). rL(l,l). rL(m,d). rL(n,n). rL(o,c). rL(p,w). 
rL(q,u). rL(r,r). rL(s,m). rL(t,t). rL(u,h). rL(v,q). rL(w,o). rL(x,x). 
 


%moves for edge mini-cubes:
gr(a,a). gr(b,b). gr(c,c). gr(d,d). gr(e,e). gr(f,j). gr(g,g). gr(h,h).
gr(i,i). gr(j,v). gr(k,k). gr(l,l). gr(m,f). gr(n,n). gr(o,o). gr(p,p).
gr(q,x). gr(r,w). gr(s,s). gr(t,t). gr(u,u). gr(v,m). gr(w,q). gr(x,r).

gl(a,a). gl(b,b). gl(c,c). gl(d,d). gl(e,e). gl(f,m). gl(g,g). gl(h,h). 
gl(i,i). gl(j,f). gl(k,k). gl(l,l). gl(m,v). gl(n,n). gl(o,o). gl(p,p). 
gl(q,w). gl(r,x). gl(s,s). gl(t,t). gl(u,u). gl(v,j). gl(w,r). gl(x,q). 

wr(a,a). wr(b,b). wr(c,c). wr(d,d). wr(e,e). wr(f,f). wr(g,p). wr(h,s). 
wr(i,i). wr(j,j). wr(k,k). wr(l,g). wr(m,m). wr(n,n). wr(o,o). wr(p,v). 
wr(q,q). wr(r,t). wr(s,r). wr(t,h). wr(u,u). wr(v,l). wr(w,w). wr(x,x). 

wl(a,a). wl(b,b). wl(c,c). wl(d,d). wl(e,e). wl(f,f). wl(g,l). wl(h,t). 
wl(i,i). wl(j,j). wl(k,k). wl(l,v). wl(m,m). wl(n,n). wl(o,o). wl(p,g). 
wl(q,q). wl(r,s). wl(s,h). wl(t,r). wl(u,u). wl(v,p). wl(w,w). wl(x,x). 

or(a,a). or(b,l). or(c,c). or(d,d). or(e,n). or(f,f). or(g,g). or(h,h). 
or(i,i). or(j,e). or(k,b). or(l,x). or(m,m). or(n,t). or(o,o). or(p,p). 
or(q,q). or(r,r). or(s,s). or(t,j). or(u,u). or(v,v). or(w,w). or(x,k). 

ol(a,a). ol(b,k). ol(c,c). ol(d,d). ol(e,j). ol(f,f). ol(g,g). ol(h,h). 
ol(i,i). ol(j,t). ol(k,x). ol(l,b). ol(m,m). ol(n,e). ol(o,o). ol(p,p). 
ol(q,q). ol(r,r). ol(s,s). ol(t,n). ol(u,u). ol(v,v). ol(w,w). ol(x,l). 

yr(a,c). yr(b,a). yr(c,h). yr(d,d). yr(e,e). yr(f,f). yr(g,n). yr(h,b). 
yr(i,g). yr(j,j). yr(k,k). yr(l,l). yr(m,m). yr(n,u). yr(o,o). yr(p,p). 
yr(q,q). yr(r,r). yr(s,s). yr(t,t). yr(u,i). yr(v,v). yr(w,w). yr(x,x). 

yl(a,b). yl(b,h). yl(c,a). yl(d,d). yl(e,e). yl(f,f). yl(g,i). yl(h,c). 
yl(i,u). yl(j,j). yl(k,k). yl(l,l). yl(m,m). yl(n,g). yl(o,o). yl(p,p). 
yl(q,q). yl(r,r). yl(s,s). yl(t,t). yl(u,n). yl(v,v). yl(w,w). yl(x,x). 

br(a,e). br(b,b). br(c,c). br(d,a). br(e,q). br(f,o). br(g,g). br(h,h). 
br(i,i). br(j,j). br(k,f). br(l,l). br(m,m). br(n,n). br(o,u). br(p,p). 
br(q,d). br(r,r). br(s,s). br(t,t). br(u,k). br(v,v). br(w,w). br(x,x). 

bl(a,d). bl(b,b). bl(c,c). bl(d,q). bl(e,a). bl(f,k). bl(g,g). bl(h,h). 
bl(i,i). bl(j,j). bl(k,u). bl(l,l). bl(m,m). bl(n,n). bl(o,f). bl(p,p). 
bl(q,e). bl(r,r). bl(s,s). bl(t,t). bl(u,o). bl(v,v). bl(w,w). bl(x,x). 

rr(a,a). rr(b,b). rr(c,o). rr(d,m). rr(e,e). rr(f,f). rr(g,g). rr(h,h). 
rr(i,d). rr(j,j). rr(k,k). rr(l,l). rr(m,s). rr(n,n). rr(o,w). rr(p,c). 
rr(q,q). rr(r,r). rr(s,i). rr(t,t). rr(u,u). rr(v,v). rr(w,p). rr(x,x). 

rl(a,a). rl(b,b). rl(c,p). rl(d,i). rl(e,e). rl(f,f). rl(g,g). rl(h,h). 
rl(i,s). rl(j,j). rl(k,k). rl(l,l). rl(m,d). rl(n,n). rl(o,c). rl(p,w). 
rl(q,q). rl(r,r). rl(s,m). rl(t,t). rl(u,u). rl(v,v). rl(w,o). rl(x,x). 
 

goal(st(a,a,c,b,c,b,g,h,e,d,l,p,e,f,m,j,m,j,r,s)).

%s(Node, SuccessorNode, Cost)
s(st(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T),
  st(Aa,Bb,Cc,Dd,Ee,Ff,Gg,Hh,Ii,Jj,Kk,Ll,Mm,Nn,Oo,Pp,Qq,Rr,Ss,Tt),1):-
       (Z=gr,Y=gR;
	Z=gl,Y=gL;
	Z=wr,Y=wR;
	Z=wl,Y=wL;
	Z=or,Y=oR;
	Z=ol,Y=oL;
	Z=yr,Y=yR;
	Z=yl,Y=yL;
	Z=br,Y=bR;
	Z=bl,Y=bL;
	Z=rr,Y=rR;
	Z=rl,Y=rL),
      [!Xa=..[Y,A,Aa],call(Xa),
	Xb=..[Z,B,Bb],call(Xb),
	Xc=..[Y,C,Cc],call(Xc),
	Xd=..[Z,D,Dd],call(Xd),
	Xe=..[Z,E,Ee],call(Xe),
	Xf=..[Y,F,Ff],call(Xf),
	Xg=..[Z,G,Gg],call(Xg),
	Xh=..[Y,H,Hh],call(Xh),	%_____________
	Xi=..[Z,I,Ii],call(Xi),
	Xj=..[Z,J,Jj],call(Xj),
	Xk=..[Z,K,Kk],call(Xk),
	Xl=..[Z,L,Ll],call(Xl),	%_____________
	Xm=..[Y,M,Mm],call(Xm),
	Xn=..[Z,N,Nn],call(Xn),
	Xo=..[Y,O,Oo],call(Xo),
	Xp=..[Z,P,Pp],call(Xp),
	Xq=..[Z,Q,Qq],call(Xq),
	Xr=..[Y,R,Rr],call(Xr),
	Xs=..[Z,S,Ss],call(Xs),
	Xt=..[Y,T,Tt],call(Xt)!].
	     
%move(Node, Move, SuccessorNode,)
move(st(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T), Z,
  st(Aa,Bb,Cc,Dd,Ee,Ff,Gg,Hh,Ii,Jj,Kk,Ll,Mm,Nn,Oo,Pp,Qq,Rr,Ss,Tt)):-
	(Z=gr,Y=gR;Z=gl,Y=gL;Z=wr,Y=wR;Z=wl,Y=wL;Z=or,Y=oR;Z=ol,Y=oL;
	 Z=yr,Y=yR;Z=yl,Y=yL;Z=br,Y=bR;Z=bl,Y=bL;Z=rr,Y=rR;Z=rl,Y=rL),
      [!Xa=..[Y,A,Aa],call(Xa),
	Xb=..[Z,B,Bb],call(Xb),
	Xc=..[Y,C,Cc],call(Xc),
	Xd=..[Z,D,Dd],call(Xd),
	Xe=..[Z,E,Ee],call(Xe),
	Xf=..[Y,F,Ff],call(Xf),
	Xg=..[Z,G,Gg],call(Xg),
	Xh=..[Y,H,Hh],call(Xh), %__________
	Xi=..[Z,I,Ii],call(Xi),
	Xj=..[Z,J,Jj],call(Xj),
	Xk=..[Z,K,Kk],call(Xk),
	Xl=..[Z,L,Ll],call(Xl),	%__________
	Xm=..[Y,M,Mm],call(Xm),
	Xn=..[Z,N,Nn],call(Xn),
	Xo=..[Y,O,Oo],call(Xo),
	Xp=..[Z,P,Pp],call(Xp),
	Xq=..[Z,Q,Qq],call(Xq),
	Xr=..[Y,R,Rr],call(Xr),
	Xs=..[Z,S,Ss],call(Xs),
	Xt=..[Y,T,Tt],call(Xt)!].
	     

dx(A,B,V,D) :-	 			%Distance between states A & B is D
  d(A,B,D),				% V is profile of individual mini-c.
  case([D=0	->	V=0,
	D=1	->	V=1,
	D=2	->	V=169,
	D=3	->	V=28561]),!.

lx(A,B,V,D) :-
  l(A,B,D),
  case([D=0	->	V=0,
	D=1	->	V=13,
	D=2	->	V=2197,
	D=3	->	V=371293,
	D=4	->	V=4826809]),!.	

%totdist(State,Profile,TotalDistanceOfAllCubesFromSolutionPosition)
totdist(st(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T),Pf,Ds) :-  
	dx(a,A,Ap,Ad),
		lx(a,B,Bp,Bl),
	dx(c,C,Cp,Cd),	
		lx(b,D,Dp,Dl),
		lx(c,E,Ep,El),
	dx(b,F,Fp,Fd),
		lx(g,G,Gp,Gl),
	dx(h,H,Hp,Hd),	    
		lx(e,I,Ip,Il),			     
		lx(d,J,Jp,Jl),
		lx(l,K,Kp,Kl),
		lx(p,L,Lp,Ll),
	dx(e,M,Mp,Md),
		lx(f,N,Np,Nl),
	dx(m,O,Op,Od),
		lx(j,P,Pp,Pl),
		lx(m,Q,Qp,Ql),
	dx(j,R,Rp,Rd),
		lx(r,S,Sp,Sl),
	dx(s,T,Tp,Td),
	Pf is Ap+Bp+Cp+Dp+Ep+Fp+Gp+Hp+Ip+Jp+Kp+Lp+Mp+Np+Op+Pp+Qp+Rp+Sp+Tp,
	Ds is Ad+Bl+Cd+Dl+El+Fd+Gl+Hd+Il+Jl+Kl+Ll+Md+Nl+Od+Pl+Ql+Rd+Sl+Td,!.


showall([H|T]) :-
  show(H),
  ifthen(T\=[],(nl,
		[H2|T2]=T,
		move(H,MOVE,H2),
		write($Make following move, then press any key: $),
		write(MOVE),
		get0(_),
		showall(T)
	       )
	).  

show(st(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T)) :-
  define_window(first_window,Label,ULC,LRC,Att),
  current_window(_,first_window),
  tmove(0,0),
write($		
   +-----------+
   |   |   |   |
   |---+---+---|
   |   | R |   |
   |---+---+---|
   |   |   |   |	        
   +-----------+-----------+
   |   |   |   |   |   |   |
   |---+---+---|---+---+---|
   |   | B |   |   | Y |   |         
   |---+---+---|---+---+---|
   |   |   |   |   |   |   |      	         
   +-----------+-----------+-----------+
    	       |   |   |   |   |   |   |   
	       |---+---+---|---+---+---|
	       |   | O |   |   | W |   |
	       |---+---+---|---+---+---|
	       |   |   |   |   |   |   |	 
	       +-----------+-----------+
	       		   |   |   |   |
			   |---+---+---|
			   |   | G |   |
			   |---+---+---|
			   |   |   |   |
                           +-----------+$),
  smc(A,`O,`B,`Y),
  smc(B,`B,`Y),
  smc(C,`B,`R,`Y),
  smc(D,`O,`Y),
  smc(E,`R,`Y),
  smc(F,`W,`O,`Y),
  smc(G,`Y,`W),
  smc(H,`R,`W,`Y),
  smc(I,`B,`O),
  smc(J,`B,`R),
  smc(K,`O,`W),
  smc(L,`R,`W),
  smc(M,`G,`B,`O),
  smc(N,`G,`B),
  smc(O,`B,`G,`R),
  smc(P,`G,`O),
  smc(Q,`G,`R),
  smc(R,`W,`G,`O),
  smc(S,`W,`G),
  smc(T,`G,`W,`R),
  tmove(13,46),write($<<Press any key to continue>>$),
  get0(_),
  delete_window(_).

%faces(S,F2,F3):  %faces(State,showcoordinatesFace2,showcoordinatesFace3)
%1st grouping (3-tuple) is for edge mini-cubes
faces(a,9-13,9-17).
faces(b,13-21,11-21).
faces(c,3-13,7-21).
faces(d,7-9,5-9).
faces(e,11-9,15-17).
faces(f,23-33,9-5).
faces(g,9-25,13-33).
faces(h,13-33,9-25).
faces(i,7-21,3-13).
faces(j,21-29,17-21).
faces(k,15-17,11-9).
faces(l,15-25,15-29).
faces(m,21-37,3-5).
faces(n,11-21,13-21).
faces(o,5-9,7-9).
faces(p,1-9,15-37).
faces(q,9-5,23-33).
faces(r,17-33,19-33).
faces(s,15-37,1-9).
faces(t,15-29,15-25).
faces(u,9-17,9-13).
faces(v,19-33,17-33).
faces(w,3-5,21-37).
faces(x,17-21,21-29).

%2nd grouping (4-tuple) is for corner mini-cubes
faces(a,13-17,11-13,11-17).
faces(b,13-29,13-25,11-25).
faces(c,7-13,5-13,7-17).
faces(d,7-17,7-13,5-13).
faces(e,23-29,11-5,17-17).
faces(f,17-17,23-29,11-5).
faces(g,13-25,11-25,13-29).
faces(h,1-13,13-37,7-25).
faces(i,13-37,7-25,1-13).
faces(j,17-29,19-29,17-25).
faces(k,11-17,13-17,11-13).
faces(l,19-29,17-25,17-29).
faces(m,7-5,23-37,5-5).
faces(n,11-13,11-17,13-17).
faces(o,23-37,5-5,7-5).
faces(p,7-25,1-13,13-37).
faces(q,5-5,7-5,23-37).
faces(r,17-25,17-29,19-29).
faces(s,19-37,17-37,1-5).
faces(t,11-25,13-29,13-25).
faces(u,5-13,7-17,7-13).
faces(v,1-5,19-37,17-37).
faces(w,17-37,1-5,19-37).
faces(x,11-5,17-17,23-29).
      

%colorattribute(Color,ScreenAttribute)-
colorattribute(`R,4).
colorattribute(`B,9).
colorattribute(`Y,14).
colorattribute(`O,6).
colorattribute(`W,15).
colorattribute(`G,2).

%1st grouping (3-tuple) is for edge mini-cube
smc(S,Color2,Color3) :-	   %ShowMini-Cube(solvedface2Color,solvedface3Color)
  faces(S,R2-C2,R3-C3),    %face(State,coordinatesFace2,coordinatesFace3)
  colorattribute(Color2,Attrib2),
  tmove(R2,C2),		   %position cursor
  wca(1,Color2,Attrib2),   %write color of face 2 at cursor position
  colorattribute(Color3,Attrib3),
  tmove(R3,C3),		   %position cursor
  wca(1,Color3,Attrib3).   %write color of face 2 at cursor position

%2nd grouping (4-tuple) is for corner mini-cube
smc(S,Color1,Color2,Color3) :-
  faces(S,R1-C1,R2-C2,R3-C3),
  colorattribute(Color1,Attrib1),
  tmove(R1,C1),		   %position cursor
  wca(1,Color1,Attrib1),   %write color of face 2 at cursor position
  colorattribute(Color2,Attrib2),
  tmove(R2,C2),		   %position cursor
  wca(1,Color2,Attrib2),   %write color of face 2 at cursor position
  colorattribute(Color3,Attrib3),
  tmove(R3,C3),		   %position cursor
  wca(1,Color3,Attrib3).   %write color of face 2 at cursor position



%h(State,HeuristicEstimateOfMovesToSolveState)
h(S,H) :-
   totdist(S,P,TD),				%find profile for this State
   ifthenelse(setof(NM,retrieveh(e,P,e(P,NM)),[M|_]), %if profile is known
		H=M,				% then hueristic is Moves
		(ifthenelse(TD>=56,		% else if est >= 7 moves
				H is TD/8,	%       then huer is est
				H is 6 + TD/56	%       else let huer be < 7
			   )			%      	     but > 6
		)
	     ),		
!.

%getprofile(Profile,NumberOfMovesFromSolveState)
%getprofile(P,M) :-
%   setof(Moves,retrieveh(e,P,e(P,Moves)),[M|_]).

%	totdist(S,H1),
%	case([	H1=8 	-> H=8,
%		H1=16	-> H=16,
%		H1=24	-> H=24,
%		H1<24	-> H=25,
%		H1>24	-> H=H1]).


start1(B) :- goal(A),   move(A,wr,B).
start2(B) :- start1(A), move(A,ol,B).
start3(B) :- start2(A), move(A,rl,B).
start4(B) :- start3(A), move(A,gl,B).
start5(B) :- start4(A), move(A,yr,B).
start6(B) :- start5(A), move(A,or,B).
start7(B) :- start6(A), move(A,gl,B).
start8(B) :- start7(A), move(A,wl,B).
start9(B) :- start8(A), move(A,or,B).
start10(B) :- start9(A), move(A,gr,B).
start11(B) :- start10(A), move(A,br,B).
start12(B) :- start11(A), move(A,rl,B).
start13(B) :- start12(A), move(A,yr,B).
start14(B) :- start13(A), move(A,br,B).
start15(B) :- start14(A), move(A,wl,B).
start16(B) :- start15(A), move(A,gl,B).
start17(B) :- start16(A), move(A,ol,B).
start18(B) :- start17(A), move(A,bl,B).
start19(B) :- start18(A), move(A,bl,B).
start20(B) :- start19(A), move(A,yl,B).
start21(B) :- start20(A), move(A,br,B).
start22(B) :- start21(A), move(A,wr,B).
start23(B) :- start22(A), move(A,or,B).
		  
val(st(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T)) :-
 L1=[A,C,F,H,M,O,R,T],
 L2=[B,D,E,G,I,J,K,L,N,P,Q,S],
 nodups(L1), nodups(L2).

%               nodups(List) determines if every element in a list is unique.
%                                  All elements in List must be instantiated.
nodups([]).
nodups([H|T]) :-
	member(H,T),!,fail.
nodups([H|T]) :-
	nodups(T).

%               member(Element,List) determines if Element is listed in List.
member(X,[X|Tail]).
member(X,[Head|Tail]) :-
	member(X,Tail).
