Prolog - 递归列表

3
这里是我的问题: 一个小俱乐部决定为其成员建立一个紧急信息电话网络。达成了以下安排: Anne可以给Bill和Mary打电话。Bill可以给Tom和Sue打电话。Tom可以给Liz和Frank打电话。如果必要,Liz也可以给Frank打电话。
将此信息表示为七个Prolog事实的形式can_phone(anne,bill)。现在编写递归的Prolog规则,用于谓词message_route,使得当A可以通过列表R中的人使用俱乐部的电话安排向B传递消息时,message_route(A,B,R)为真。例如,message_route(anne,frank,[anne,bill,tom,liz,frank])将为真(因为anne可以给bill打电话,who可以给tom打电话,who可以给liz打电话,who可以给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个回答

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).

这里有一个使用您的数据的小演示

请注意,如果您呈现的数据代表带有循环的图形而不是树形结构,则此代码将会陷入循环。为了避免这种情况,您可以避免选择X,如果它已经是Tail列表的一部分。


can_phone 不需要第三个变量。 - Vincent Ramdhanie
@VincentRamdhanie 谢谢!我尝试了这段代码,发现了同样的错误。 - Sergey Kalinichenko
@dasblinkenlight 我尝试对R进行统一。我做得对吗。 message_route(A,B,[A,B]) :- can_phone(A,B). message_route(A,B,[A|Tail]) :- can_phone(A,X), message_route(X,B,Tail)。 % message_route(A,B,R):- can_phone(A,B,R),R = [A,B]。 % message_route(A,B,R):- can_phone(A,B,R),can_phone(A,X),message_route(X,B,Tail),R = [A | Tail]。 - Danny Rancher
@DannyRancher请查看修改后的演示:链接 - Sergey Kalinichenko
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/25795/discussion-between-danny-rancher-and-dasblinkenlight - Danny Rancher
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接