Prolog统一清单

时间:2014-02-12 22:43:47

标签: prolog

过去几个小时我一直在篡改这段代码。

该函数应该做的是从当前状态(X / Y)返回下一个可达状态的列表。 Obs是无法访问的状态列表,N是行数,M是列数。

因此successors(2/2, X)的典型回复答案为:X = [ (1, [3/2]), (1, [1/2]), (1, [2/3])| (1, [2/1])].

到目前为止,如果所有谓词都为真,我的代码就可以正常工作,并返回正确的输出。但是,如果任何后继辅助谓词错误,则失败。

succesors(X/Y, Succs):-
   loadMazeInfo(maze1), %loading the maze info
   maze(_, M, N, Obs, _, _), %obtaining the S and G states.
   successorsRight(X/Y, Succs, Obs, M, N).

successorsRight(X/Y, [(1, [S1/Y])|T], Obs, M, N):-
   successorsLeft(X/Y, T, Obs, _, N), S1 is X + 1, M >= S1, not(member(S1/Y, Obs)).
successorsLeft(X/Y, [(1, [S1/Y])|T], Obs, _, N):-
   successorsUp(X/Y, T, Obs, _, N), S1 is X - 1, S1 >= 1, not(member(S1/Y, Obs)).
successorsUp(X/Y, [(1, [X/S2])|T], Obs, _, N):-
   successorsDown(X/Y, T, Obs, _, _), S2 is Y + 1, N >= S2, not(member(X/S2, Obs)).
successorsDown(X/Y, (1, [X/S2]), Obs, _, _):-
   S2 is Y - 1, S2 >= 1, not(member(X/S2, Obs)).

我想知道是否有办法告诉prolog跳过谓词,如果它是假的,并转到下一个。或者这是无法实现的,我正在完全解决这个问题?我不理解切割,但在这种情况下我不认为它们对我有用,或者它们是不是?

1 个答案:

答案 0 :(得分:3)

我认为你'过度指定'逻辑。您应该简化程序,分解重复的代码,并让Prolog搜索可用的步骤。然后findall / 3将帮助您构建结果列表

succesors(X/Y, Succs):-
  loadMazeInfo(maze1), %loading the maze info
  maze(_, M, N, Obs, _, _), %obtaining the S and G states.
  findall((1,SX/SY), (successor(X, Y, SX, SY, M, N), not(member(SX/SY, Obs))), Succs).

successor(X, Y, S1, Y, M, _):-
  S1 is X + 1, M >= S1.
successor(X, Y, S1, Y, _, _):-
  S1 is X - 1, S1 >= 1.
...