仅显示陈述中的差异

时间:2017-12-26 21:11:25

标签: prolog

reservation("8V32EU", "John", "Doe", "27B", "YYZ", "CPH", "SAS").
reservation("8V32EU2", "Jane", "Doe", "27B", "YYZ", "CPH", "SAS").
reservation("94ISCU", "John", "Doe", "2C", "CPH", "YYZ", "SAS").
reservation("FDSDD3", "John", "Doe", "12D", "YYZ", "ROU", "SAS").

说我有这些陈述。

有一个小故障,约翰和简在同一航班上预订了同一个座位。 (前两个陈述)。 如何编写返回双重预留席位预订代码的程序? (在这种情况下为“8V32EU”和“8V32EU2”)。我需要计算所有双重预订的预订代码

到目前为止我的尝试:

double_reservations(BookingCode, SeatNo, Fname, Lname) :-
   reservation(BookingCode, Fname, Lname, SeatNo, _, _, _).

然而,只有当你给它所讨论的座位时,这才有效:

double_reservations(BookingCode, "27B", _, _).

没有它有办法吗?仅double_reservations(BookingCode, _, _, _).

2 个答案:

答案 0 :(得分:1)

您可以使用findall/3setof/3解决此问题。这是使用findall/3的解决方案:

getDouble([]).
getDouble([HS|TS]):-
    findall(C,reservation(C,_,_,HS,_,_,_),LC),
    length(LC,N),
    (   N > 1 ->  
        writeln(LC) 
    ; true),
    getDouble(TS).

solve:-
    findall(S,reservation(_,_,_,S,_,_,_),LS),
    sort(LS,L),
    getDouble(L).

查询:

?- solve.
[8V32EU, 8V32EU2]
true

我使用findall/3sort/2删除了重复项(read this),而不是setof/3,因为如果目标没有,findall/3将返回一个空列表解决方案,而setof/3(和bagof/3)在这种情况下会失败(link)。如果您不想删除重复项,可以使用msort/2

答案 1 :(得分:1)

我认为你应该将有问题的预订代码的识别分开,然后从预订/ 7表中恢复所需的任何细节:

double_reservations(BookingCode1, BookingCode2) :-
   reservation(BookingCode1, _Fname1, _Lname1, SeatNo, OAir, DAir, Airline),
   reservation(BookingCode2, _Fname2, _Lname2, SeatNo, OAir, DAir, Airline),
   BookingCode1 \= BookingCode2.