您可以使用member/2 和maplist/2 轻松生成4 种颜色的所有可能性:
% give me a list of 4 fresh variables
% select a member of [red,blue,green] for each item of L, backtrackably
length(L,4),
maplist([I]>>(member(I,[red,blue,green])),L).
上面其实是一样的
L=[L0,L1,L2,L3],
member(L0,[red,blue,green]),
member(L1,[red,blue,green]),
member(L2,[red,blue,green]),
member(L3,[red,blue,green]).
注意组合爆炸。
如果首选“无状态下一个”。
我们想从现有的组合中推导出下一个红-绿-蓝组合!
让我们使用 CLP(FD) 来实现颜色列表和数字之间的双射映射。
:- use_module(library(clpfd)).
rgbnumber(red,0).
rgbnumber(blue,1).
rgbnumber(green,2).
rgbnumberlist([L0,L1,L2],N) :-
rgbnumber(L0,N0), N0 in 0..2,
rgbnumber(L1,N1), N1 in 0..2,
rgbnumber(L2,N2), N2 in 0..2,
N #= N0+N1*3+N2*3*3.
rgbnext(Current,Next,Wrap) :-
rgbnumberlist(Current,N),
succ(N,Nx),
Nxm is (Nx mod (3*3*3)), % Beware precedence: mod is as strong as *
(Nx > Nxm -> Wrap = true ; Wrap = false),
rgbnumberlist(Next,Nxm).
因此:
?- rgbnext([red,red,red],A,Wrap).
A = [blue, red, red],
Wrap = false ;
false.
?- rgbnext([blue,red,red],A,Wrap).
A = [green, red, red],
Wrap = false ;
false.
?- rgbnext([green,red,red],A,Wrap).
A = [red, blue, red],
Wrap = false ;
false.
?- rgbnext([green,green,green],A,Wrap).
A = [red, red, red],
Wrap = true ;
false.
现在您可以使用它从当前状态中查找下一个状态。