【问题标题】:Prolog Unifying ListProlog 统一列表
【发布时间】:2014-02-13 15:34:57
【问题描述】:

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

函数应该做的是从当前状态(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 如果它是假的就跳过谓词,然后转到下一个。或者这是无法实现的,我正在解决这个问题完全错误?我不能正确理解削减,但我认为在这种情况下它们对我没有用,或者是吗?

【问题讨论】:

    标签: prolog


    【解决方案1】:

    我认为您“过度指定”了逻辑。你应该简化你的程序,分解重复的代码,让 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.
    ...
    

    【讨论】:

    • 我不知道有 findall 方法!我花了无数个小时尝试不同类型的递归,以不同的方式定义规则,这终于奏效了:) 谢谢。它说我没有足够的声誉来投票给你,但我希望对勾有帮助:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多