我有一个这样的数据库:
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)
答案应该来了:马德里
答案 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
。因此,如果D
和A
仅由一个traject(D,A,Transport)
弧直接连接,那么航点列表是什么?什么是运输类型? ---否则,如果我们可以使用某种类型的传输D
一步从X
转到T
,并且X
和A
与使用传输类型Xs2
的航点Ts2
列表,完整的航点列表是什么?什么是传输类型的完整列表?
完成此操作后,您将能够非常轻松地定义您要求的两个谓词,因为信息已存在,在此connect/4
谓词中.../4
表示,它具有4个论点)。