2015-02-09 81 views
-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). 

的问题,我试图解决:

假设你添加“连接(4,3)“紧接事实 ”连接(3,4)“。运行查询? - 路径(3,2)产生一个循环 并且不终止。使用累加器修改路径/ 2以存储 已经访问的点,以便在计算路径时不会再次访问相同点 。然后再次运行查询? - 路径(3,2)。

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

此外,我看到很多“/ 2”之后的东西 - 任何解释,这一般意味着什么?

干杯。

+1

你应该显示你的'path/2':它看起来是被定义的,但它不在你的问题中。 “'/ 2”代表仿函数的_arity_(参见这里:http:// www。swi-prolog.org/pldoc/man?section=glossary)。而且,如果你使用“prolog accumulator”,你会得到相当多的关于这个话题的信息。 – 2015-02-09 13:07:48

+0

请参阅[这些答案](http://stackoverflow.com/search?q=%5Btransitive-closure%5D+%5Bprolog%5D+closure0) – false 2015-02-09 17:36:55

回答

0

您没有显示path/2的定义。但是,练习中最常见的问题是,要保留已经访问过的节点列表(如connected/2中定义的连接所隐含定义的)(可能在列表中为您的“累加器”)。每当你考虑是否应该关注连接时,你应该检查迄今为止的路径(你的累加器)是否已经包含该节点。这样你将避免(无限)循环。

这几乎是你的家庭作业声明已经说了。

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

0

/表示法用于每个谓词的arity。例如,path/2指示path需要2个参数,例如,

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

累加器只是一个额外的参数,在满足目标后更新,作为中间步骤。这通常是一个列表。假设您要构建一个range/2谓词,其谓词参数为X,并生成一个从1X(不使用内置的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. 

生成调用辅助谓词range/3时预先计划Acc新号码。 Acc是一个经典的累加器,以列表的形式列出您“积累”的内容。您可以在每次解析目标时从图形中累积边数,并在每个步骤检查您要跟随的边是否已经在累加器中,而不是数字。