这是一个块世界问题,它将移动我们想要的块。
预测located_on
根据流量告诉我们块的位置。 goal_state
是我们想要块的地方。
located_on
的第三个参数是 情境(污水) ,表示 行动历史记录 。
流畅的 在 空列表 中启动 ,这意味着尚未执行任何操作。在每个动作之后,我们将动作添加到第三个参数fluent中。
例如,如果我们将a移动到b,然后将b移动到c,然后将c移到d,则流畅度为[move(c,d),move(b,c),move(a,b)]
。我们可以根据 流程(他们的行动历史) 了解每个街区的位置。
%Successor states
located_on(A,B,[move(A,B)|_]).
located_on(B,L,[_|S]) :- located_on(B,L,S).
%Goal state
goal_state(S):- located_on(a,b,S),located_on(d,area2,S).
问题在于,当我只有一个目标,比如说goal_state(S):- located_on(a,b,S)
时,我可以得到所有可能的污水S:
?- goal_state(X).
X = [] ;
X = [move(a, b)|_G4037] ;
X = [_G4036] ;
X = [_G4036, move(a, b)|_G4040] ;
X = [_G4036, _G4039] ;
X = [_G4036, _G4039, move(a, b)|_G4043] ;
X = [_G4036, _G4039, _G4042] ;
X = [_G4036, _G4039, _G4042, move(a, b)|_G4046] ;
X = [_G4036, _G4039, _G4042, _G4045] ;
X = [_G4036, _G4039, _G4042, _G4045, move(a, b)|_G4049]
但是当我有多个目标时,比如说goal_state(S):- located_on(a,b,S),located_on(d,area2,S).
,我得到的一些问题就陷入了其中一个目标:
?- goal_state(X).
X = [] ;
X = [move(a, b)] ;
X = [move(a, b), move(d, area2)|_G344] ;
X = [move(a, b), _G343] ;
X = [move(a, b), _G343, move(d, area2)|_G347] ;
X = [move(a, b), _G343, _G346] ;
X = [move(a, b), _G343, _G346, move(d, area2)|_G350] ;
X = [move(a, b), _G343, _G346, _G349] ;
X = [move(a, b), _G343, _G346, _G349, move(d, area2)|_G353] ;
X = [move(a, b), _G343, _G346, _G349, _G352] ;
X = [move(a, b), _G343, _G346, _G349, _G352, move(d, area2)|_G356] ;
X = [move(a, b), _G343, _G346, _G349, _G352, _G355] ;
X = [move(a, b), _G343, _G346, _G349, _G352, _G355, move(d, area2)|_G359]
这里的第一个元素是move(a,b)
,因为程序在满足move(d, area2)
时会得到无限循环。
有什么方法可以帮助我摆脱无限循环?
整个计划是这样的:
%Initial states
initial_state([]).
located_on(a,b,[]).
located_on(b,c,[]).
located_on(c,area1,[]).
located_on(d,area2,[]).
%Successor states
located_on(A,B,[move(A,B)|_]).
located_on(B,L,[_|S]) :- located_on(B,L,S).
%Goal state
goal_state(S):- located_on(a,b,S),located_on(d,area2,S),located_on(b,d,S),located_on(c,area1,S).
%Poss
poss(move(A,B),S) :- member(A,[a,b,c,d]),member(B,[a,b,c,d,area1,area2,area3]),
\+A=B,clear(A,S),clear(B,S).
clear(A,S) :- member(A,[a,b,c,d,area1,area2,area3]), \+located_on(_,A,S).
%Solve problem
legal_move(S,A,[A|S]):-poss(A,S).
plan(L) :- initial_state(I), goal_state(G), reachable(I,L,G).
reachable(S,[],S).
reachable(S1,[M|L],S3) :- legal_move(S1,M,S2), reachable(S2,L,S3).
我将plan(L) :- initial_state(I), goal_state(G), reachable(I,L,G).
替换为plan(L) :- initial_state(I), reachable(I,L,G), goal_state(G).
这意味着我们不是生成所有可能的goal_states,而是首先尝试每个可到达的位置,然后检查它们是否是目标状态。通过这种方式,我们在处理goal_state时得到统一的G.
以下是prolog的答案:
24 ?- plan([A,B,C]).
A = move(a, area3),
B = move(b, d),
C = move(a, b) ;
false.
答案 0 :(得分:4)
在这个公式中,你不能摆脱无限递归alltogther,因为在一个新状态和后面之间移动一个块会在图形中创建一个循环,它对应于一个无限列表。
您可以做的是通过首先使用任意列表解决方案来执行迭代深化搜索:
:- length(S,_), goal_state(S).
首先,S与一个长度为0的列表统一,在其上尝试了goal_state。在尝试了所有长度为a的列表之后,长度与长度为1的列表结合等等。
编辑:感谢mat用于识别正确的搜索策略!