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)
表示,D
eparture 和 A
rival 通过 waypoints Xs
的 list 连接,使用传输类型Ts
。那么如果 D
和 A
仅由一个 traject(D,A,Transport)
弧直接连接,那么 waypoints 的列表是什么?运输类型列表是什么? --- 否则,如果我们可以使用一种传输类型 T
从 D
一步到 X
,并且 X
和 A
与waypoints Xs2
使用传输类型 Ts2
的列表,waypoints 的完整列表是什么?传输类型的完整列表是什么?
完成此操作后,您将能够非常轻松地定义您要求的两个谓词,因为信息已经存在,在这个 connect/4
谓词中(.../4
意味着,它有 4 个参数)。
我有这样一个数据库:
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)
表示,D
eparture 和 A
rival 通过 waypoints Xs
的 list 连接,使用传输类型Ts
。那么如果 D
和 A
仅由一个 traject(D,A,Transport)
弧直接连接,那么 waypoints 的列表是什么?运输类型列表是什么? --- 否则,如果我们可以使用一种传输类型 T
从 D
一步到 X
,并且 X
和 A
与waypoints Xs2
使用传输类型 Ts2
的列表,waypoints 的完整列表是什么?传输类型的完整列表是什么?
完成此操作后,您将能够非常轻松地定义您要求的两个谓词,因为信息已经存在,在这个 connect/4
谓词中(.../4
意味着,它有 4 个参数)。