像这样对地下管道的停靠点进行建模:
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)
表示S
是N
行的第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的新手,所以我可能会缺少一些基本知识。但是,我真的不明白为什么它可以验证给定的路径正确,但是在尝试查找所有路径时却找不到该路径。
答案 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中找到几个相关的答案。但是,请先尝试自行解决。