Prolog - 递归列表

时间:2013-03-07 16:30:27

标签: list recursion prolog

这是我的问题: 一个小俱乐部决定建立一个紧急信息的电话网络 其中的成员。商定了以下安排: 安妮可以打电话给比尔和玛丽。比尔可以打电话给汤姆 和苏。汤姆可以打电话给利兹和弗兰克。丽兹还可以打电话 如有必要,弗兰克。

将此信息表达为表格中的七个Prolog事实 can_phone(anne,bill)。现在为谓词message_route编写递归的Prolog规则 message_route(A,B,R)如果A可以将邮件传递给B路由,则R为真 通过列表message_route(anne,frank,[anne,bill,tom,liz,frank])中的人,使用俱乐部的电话安排。对于 例如,anne 是真的(因为bill可以打电话tom,谁可以致电liz, 谁可以致电frank,谁可以致电can_phone(anne,bill). can_phone(anne,mary). can_phone(bill,tom). can_phone(bill,sue). can_phone(tom,liz). can_phone(tom,frank). can_phone(liz,frank). )。

到目前为止,我有这个:

message_route

有关我的R,我已经尝试与具有这方面的工作,让我完成了问题的第二部分,而不限制列表中的人的指定列表的要求(message_route(A,B) :- can_phone(A,B). message_route(A,B) :- can_phone(A,X), message_route(X,B). )。

{{1}}

我不明白如何在我的回答中实现这个列表。

1 个答案:

答案 0 :(得分:3)

累积列表相对简单:首先,观察如果A可以直接调用B,则列表只是[A, B]。因此,我们可以将您的第一条规则重写为

message_route(A,B,[A,B]) :- can_phone(A,B).

第二条规则有点棘手:您需要统一到由message_route生成的列表,并在其头部插入A。请注意,您无需插入XB,因为它们将由返回的列表提供:

message_route(A,B,[A|Tail]) :- can_phone(A,X), message_route(X,B,Tail).

这是small demo that uses your data

请注意,如果您呈现的数据表示带有循环的图形而不是树,则此代码将追逐自己的尾部。为避免这种情况,如果X已成为Tail列表的一部分,则可以避免选择{{1}}。