序言未找到所有解决方案

时间:2018-11-11 06:44:35

标签: prolog

像这样对地下管道的停靠点进行建模:

stop(line1, 1, station1).
stop(line1, 2, station2).
stop(line1, 3, station3).
stop(line1, 4, station4).
stop(line1, 5, station5).
stop(line2, 1, station2).
stop(line2, 2, station4).

其中stop(L, N, S)表示SN行的第L个停靠点,我试图定义path(S1, S2, P)来计算{ {1}}和S1

此处的路径是“段”的列表,段是沿同一行的旅程,即S2代表从segment(L,S1,S2)S1沿行{{ 1}}。因此,对S2的可能解决方案是L,即从path(a,d,P)P=[segment(line1, a, b), segment(line2, b, d)]a,然后从b到{{1 }}在line1上。

另一个限制是,路径不应多次包含同一行。

我有以下内容:

b

但是发生一些奇怪的事情。如果我自己明确指定所有参数,它将识别为正确路径:

d

但是,如果我要求它计算所有路径,它只会找到一条路径,与刚刚验证为正确的路径不同:

line2

我必须承认我是Prolog的新手,所以我可能会缺少一些基本知识。但是,我真的不明白为什么它可以验证给定的路径正确,但是在尝试查找所有路径时却找不到该路径。

1 个答案:

答案 0 :(得分:1)

该错误位于path/3谓词的第二个子句中。为了清楚起见,将其重写:

path(S1, S2, [segment(L, S1, X)|T]) :-
    \+ line_present_in_path(L, T),
    path(X, S2, T).

对于诸如path(station1, station4, P)这样的目标,您可以在第二个参数中使用变量来调用line_present_in_path/2谓词。该调用始终成功,因此其否定始终失败。通常,您应该谨慎使用仅带有充分实例化参数的\+/1

提示:要解决该错误,请在路径谓词上使用一个附加参数来保存到目前为止找到的站点。例如

path(S1, S2, Path) :-
    path(S1, S2, Path, []).

path(S1, S2, Path, Visited) :-
    ...

您可以使用事实上的标准member/2谓词来检查路径中是否已存在站点,否则可以将其添加到访问列表中。路径查找是一个常见问题,您可以在StackOverflow中找到几个相关的答案。但是,请先尝试自行解决。