【问题标题】:Prolog loop control not working as expectedProlog 循环控制未按预期工作
【发布时间】:2016-04-02 13:48:50
【问题描述】:

我有以下序言代码。链接谓词指的是另一个包含各种链接的文件,例如:

link(b,brown,j)

我正在使用成员谓词来尝试控制此路由程序中的循环。这个想法是,如果我以前去过某个职位,程序就不会尝试走那条路。

但是,当我尝试跟踪程序以查看哪里出错时,当它检查该职位是否是职位列表中的成员时,第一个职位已经在列表中,因此程序总是尝试另一个在不应该的那一点之后的路线。有谁知道如何解决这个问题?

member(X,[X|_]).
member(X,[_|Xs]):- member(X,Xs).

route(X,X,[X],_).
route(X,Z,[X|Path],Positions):- 
    link(X,Colour,Y),
    \+member([Y,Colour],Positions),             
    route(Y,Z,Path,[[Y,Colour]|Positions]),
    !.

【问题讨论】:

  • 请不要破坏您的问题。如果这篇文章有问题,您可以通过提高自定义标志来提醒版主。
  • 您无权删除自己发布的内容。请不要再尝试自我破坏。

标签: prolog


【解决方案1】:

首先是一些小的 cmets:你根本不需要那个剪辑。如果您真的想将谓词限制为一个答案,请使用once/1 在顶部执行此操作。这不仅在概念上更清洁,而且效率更高。

您遇到的另一个问题与 Prolog 的不安全否定有关。如果你不小心交出了一个过于笼统的目标,否定总是会失败。换句话说:否定在 Prolog 中是下一个被打破的。有两种方法:要么针对这种情况产生错误,要么只使用更好的定义,例如 non_member/2

让我们看看使用non_member/2 会发生什么:

link(b,brown,j).

route(X,X,[X],_).
route(X,Z,[X|Path],Positions):-
    link(X,Colour,Y),
    % \+member([Y,Colour],Positions),
    non_member([Y,Colour],Positions),
    route(Y,Z,Path,[[Y,Colour]|Positions]).

non_member(E, Es) :-
   maplist(dif(E), Es).

| ?- route(X,Y,Path,Rs).
     Y = X, Path = [X]
;    X = b, Y = j, Path = "bj", Rs = []
;    X = b, Y = j, Path = "bj", Rs = [_A],
     dif([j,brown],_A)
;    X = b, Y = j, Path = "bj", Rs = [_A,_B],
     dif([j,brown],_A),
     dif([j,brown],_B)
;    X = b, Y = j, Path = "bj", Rs = [_A,_B,_C],
     dif([j,brown],_A),
     dif([j,brown],_B),
     dif([j,brown],_C)
;    X = b, Y = j, Path = "bj", Rs = [_A,_B,_C,_D],
     dif([j,brown],_A),
     dif([j,brown],_B),
     dif([j,brown],_C),
     dif([j,brown],_D)
;    X = b, Y = j, Path = "bj", Rs = [_A,_B,_C,_D,_E],
     dif([j,brown],_A),
     dif([j,brown],_B),
     dif([j,brown],_C),
     dif([j,brown],_D),
     dif([j,brown],_E)
; ...

所以所有答案都描述了相同的Path = "bj"[b,j] 的缩写形式)。但是现在最后一个参数是一个元素列表,所有元素都必须不同于[j,brown]。所以最好的应该是:

route(X, Y, Path) :-
   route(X, Y, Path, []).

这是一个复用path/4 的替代定义。我不太确定这些颜色是什么意思。尽管如此:

clink(X-_, Y-Color) :-
   link(X, Color, Y).

route(X, Y, Path) :-
   path(clink, Path, X-none, Y-_).

使用library(lambda) 甚至更短:

route(X, Y, Path) :-
   path(\ (Xl,_)^(Yl^C)^clink(Xl,C,Yl), Path, X-none, Y-_).

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多