数据:
%flight(FID, Start, Destination, Company, Seats).
%------------------------------------------------------
flight(1, 'Paris', 'Berlin', 'Lufthansa', 210).
flight(2, 'Frankfurt', 'Dubai', 'Lufthansa', 400).
flight(3, 'Rome', 'Barcelona', 'Eurowings', 350).
我想知道所有有超过200个座位的航班的公司。但是每个公司只能退货一次。
我试过了:
q1(Company) :- flight(_, _, _, Company, S), S > 200.
但这两次返回汉莎航空公司。我试过了:
q1(Company) :- flight(_, _, _, Company, S), S > 200,!.
但是,这在汉莎航空首次返回后就消失了。我想我必须将条件包装在子查询中:
q1(Company) :- flight(_, _, _, Company, S), q12(S).
q12(S) :- flight(_, _, _, _, S), S > 200,!.
但这在第一次返回之后就退出了。知道如何使用cut退回只匹配一次的公司吗?
FID是主键,只允许使用。,+ <> <=> =
这里的关键是唯一的ID。您最初的问题是:
哪些公司的航班座位超过200个?
查询很明显:
?- flight(_,_,_,C,S), S > 200.
C = 'Lufthansa',
S = 210 ;
C = 'Lufthansa',
S = 400 ;
C = 'Eurowings',
S = 350.
现在,由于ID是唯一的,因此在同一公司内的组中将有一个航班,且座位数大于200,且ID最高(或最低)。因此,您可以将问题重新表述为:
同一公司的航班组中,哪些航班的座位数超过200个且ID最高?
或者,如果要更接近我们在Prolog中提出查询的方式,
对于具有ID,公司和席位的航班,席位必须超过200,并且同一ID较高的公司不得有其他航班。
?- flight(ID,_,_,C,S), S > 200, \+ ( flight(IDX,_,_,C,_), IDX > ID ).
ID = 2,
C = 'Lufthansa',
S = 400 ;
ID = 3,
C = 'Eurowings',
S = 350.
如果将此查询放在谓词中,则可以避免报告ID和实际座位数。
顺便说一句,这种方法是对某些相关问题(无耻的自我提升)的回答。我真的不记得我的主意是什么:我确定我自己没有想到。如果有人可以在Stackoverflow或其他地方找到很好的参考,请发表评论。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句