Prolog查询中的递归

时间:2015-10-15 00:12:16

标签: prolog

我有一个这样的数据库:

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

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

如何制定规则和/或查询,我可以回答这些问题:

A)transport(Paris,Lisbon)

答案应该来了:火车和公共汽车

B)traject_between(Paris,Lisbon)

答案应该来了:马德里

1 个答案:

答案 0 :(得分:2)

要使用大写字母开头的原子名称,请使用单引号: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)表示D eparture和A到达航点通过航路点Xs列表连接,使用传输类型Ts。因此,如果DA仅由一个traject(D,A,Transport)弧直接连接,那么航点列表是什么?什么是运输类型? ---否则,如果我们可以使用某种类型的传输D一步从X转到T,并且XA与使用传输类型Xs2的航点Ts2列表,完整的航点列表是什么?什么是传输类型的完整列表?

完成此操作后,您将能够非常轻松地定义您要求的两个谓词,因为信息已存在,在此connect/4谓词中.../4表示,它具有4个论点)。