2014-02-12 74 views
1

过去几个小时我一直在篡改此代码。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)). 

我想知道是否有办法告诉序言如果它是假的跳过谓词,并转到下一个。或者这是不可实现的,我正在处理完全错误的问题?我不明白裁员是否正确,但我不认为他们会对我有用,在这种情况下,还是他们?

回答

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. 
... 
+0

我不知道有一个findall方法!我在无尽的时间尝试不同类型的递归,以不同的方式定义规则,这最终有效:) 谢谢。 它说我没有足够的声望投票给你,但我希望滴答作用帮助:) – zsawaf