-1

我正在使用的知识库:

connected(1,2). 
connected(3,4). 
connected(5,6). 
connected(7,8).
connected(9,10). 
connected(12,13). 
connected(13,14). 
connected(15,16).
connected(17,18). 
connected(19,20). 
connected(4,1). 
connected(6,3).
connected(4,7). 
connected(6,11). 
connected(14,9). 
connected(11,15).
connected(16,12). 
connected(14,17). 
connected(16,19).

我试图解决的问题:

假设您在事实“connected(3,4)”的正下方添加“connected(4,3)”。运行查询 ?- path(3,2) 会导致一个循环并且不会终止。使用累加器修改 path/2 以存储已经访问过的点,以便在计算路径时永远不会重新访问同一点。然后再次运行查询 ?- path(3,2)。

我在这里遇到的麻烦是我对 Prolog 很陌生,我之前实际上没有使用过累加器(据我所知),因此我不确定如何继续。如果有人可以向我解释我必须采取的步骤,那就太好了。

另外,我看到很多后面带有“/ 2”的东西 - 关于这通常意味着什么的任何解释?

干杯。

4

2 回答 2

0

/符号用于每个谓词的元数。例如,path/2表示path需要 2 个参数,例如

path(EdgeA, EdgeB) :- connected(EdgeA, EdgeB).
path(EdgeA, EdgeB) :- connected(EdgeA, Other), connected(Other, EdgeB).

累加器只是一个额外的参数,在满足目标后更新,作为中间步骤。它通常是一个列表。假设您要构建一个range/2谓词,它接受一个参数X并生成一个从1to的整数列表X(不使用内置between谓词)。

在这里,您将使用累加器来存储[1..X]运行查询时在范围内生成的每个数字。例如:

range(X, Y) :- range(X, [], Y).

range(X, Acc, Z) :- X > 0, NewX is X - 1, range(NewX, [X|Acc], Z).
range(X, Acc, Acc) :- X = 0.

Acc调用辅助谓词时,生成的新数字会被添加到前面range/3Acc是列表形式的经典累加器,您可以在其上“累积”内容。您可以在每次解决connected目标时从图表中累积边,而不是数字,并在每一步检查您要遵循的边是否已经在累加器中。

于 2015-02-09T13:16:13.860 回答
0

您没有显示 的​​定义path/2。然而,这个练习最有可能要求你保留一个connected/2你已经访问过的节点列表(由定义的连接隐式定义)(可能在一个列表中,你的“累加器”)。每当您考虑是否应该遵循连接时,您应该检查到目前为止的路径(您的累加器)是否已经包含该节点。这样,您将避免(无限)循环。

这几乎就是你的作业声明已经说的。

没有代码,这个答案不是很有用,但您也不提供任何代码。

于 2015-02-09T13:12:33.037 回答