这是我的问题: 一个小俱乐部决定建立一个紧急信息的电话网络 其中的成员。商定了以下安排: 安妮可以打电话给比尔和玛丽。比尔可以打电话给汤姆 和苏。汤姆可以打电话给利兹和弗兰克。丽兹还可以打电话 如有必要,弗兰克。
将此信息表达为表格中的七个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}}
我不明白如何在我的回答中实现这个列表。
答案 0 :(得分:3)
累积列表相对简单:首先,观察如果A
可以直接调用B
,则列表只是[A, B]
。因此,我们可以将您的第一条规则重写为
message_route(A,B,[A,B]) :- can_phone(A,B).
第二条规则有点棘手:您需要统一到由message_route
生成的列表,并在其头部插入A
。请注意,您无需插入X
或B
,因为它们将由返回的列表提供:
message_route(A,B,[A|Tail]) :- can_phone(A,X), message_route(X,B,Tail).
这是small demo that uses your data。
请注意,如果您呈现的数据表示带有循环的图形而不是树,则此代码将追逐自己的尾部。为避免这种情况,如果X
已成为Tail
列表的一部分,则可以避免选择{{1}}。