Prolog 查询中的递归

Recursion in Prolog Query

我有这样一个数据库:

traject(departure,arrive,transport).

traject(London,Paris,train).
traject(Paris,Madrid,train).
traject(Madrid,Lisbon,bus).
traject(Madrid,Berlin,plane).
traject(Berlin,Prague,bus).

我有规则:

connection(Departure,Arrrive):-traject(Departure,Arrive,Transport).
connection(Departure,Arrrive):-traject(Departure,X,Transport),traject(X,Arrive).

根据该规则,我可以知道如果我询问查询连接(巴黎、里斯本),例如,答案将是肯定的。

如何制定规则 and/or 可以回答以下问题的查询:

A) transport(Paris,Lisbon)

答案应该是:火车和公共汽车

B) traject_between(Paris,Lisbon)

答案应该是:马德里

要让原子名称以大写字母开头,请使用单引号:traject( 'London', 'Paris', train).

我更喜欢在代码中使用简短的、暗示性的变量名,这样更容易在精神上和视觉上进行跟踪(当然是 YMMV):

connect(D,A):- traject(D,A,T).

后面你说要看交通工具,为什么在这里忽略了呢?将其更改为

connect(D,A,T):- traject(D,A,T).
connect(D,A,T):- traject(D,X,T1), traject(X,A,T2).

在第二种情况下,您现在有两个传输。以某种方式将它们组合在一起!提示:什么类型的数据可以包含两个条目和一个条目?为了保持一致,您还必须更改第一个子句。

现在新的问题是,你忽略了航路点,X。另一个相关的是,你在旅途中只走两条腿,但如果你需要三条或更多怎么办?

递归将有助于解决这两个问题:

connect(D,A, Xs,Ts):- traject(D,A,T), Xs = ... , Ts = ... .
connect(D,A, Xs,Ts):- traject(D,X,T), 
                      connect(X,A, Xs2,Ts2),  % <---- recursion!
                      Xs = ... ,
                      Ts = ... .

而不是...,必须出现一些明智的事情。 connect(D,A, Xs,Ts) 表示,Departure 和 Arival 通过 waypoints Xslist 连接,使用传输类型Ts。那么如果 DA 仅由一个 traject(D,A,Transport) 弧直接连接,那么 waypoints 的列表是什么?运输类型列表是什么? --- 否则,如果我们可以使用一种传输类型 TD 一步到 X,并且 XA 与waypoints Xs2 使用传输类型 Ts2 的列表,waypoints 的完整列表是什么?传输类型的完整列表是什么?

完成此操作后,您将能够非常轻松地定义您要求的两个谓词,因为信息已经存在,在这个 connect/4 谓词中(.../4 意味着,它有 4 个参数)。