我有三种可能的颜色:红色,绿色,蓝色。
我有一个初始列表:[蓝色,蓝色,蓝色,蓝色]。
我本质上需要创建一种搜索算法,以找到给定的列表Find
(也是一个包含四种颜色的列表)。这就是搜索算法的基本框架:
look(Find):- search([red, red, red, red], Find).
search([A,B,C,D], [A,B,C,D]):- do-something(A,B,C,D).
search(Node, Find):-
successor(Node, Next),
search(Next, Find).
我的问题是定义successor
。我如何才能找到一个继任者,在我找到一个等于列表Find
的继承人之前,我肯定从未访问过它-尤其是当我不在谓词中使用域({red,blue,green})时。任何帮助表示赞赏。谢谢!
您可以轻松地使用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.
现在,您可以使用它从当前状态中查找下一个状态。