创建列表以返回日期

时间:2014-01-04 02:21:57

标签: prolog

我目前有一个数据库,其中包含一个人员列表,他们发送邮件的人以及邮件发送的日期。请参阅以下内容:

message(allan, steve, 2013-09-03). 
message(nayna, jane, 2013-09-03). 
message(steve, jane, 2013-09-04). 
message(steve, allan, 2013-09-04). 
message(mark, martin, 2013-09-04). 
message(martin, steve, 2013-09-04). 
message(allan, martin, 2013-09-05).

对于我的一个任务,我需要创建一个规则,该规则返回人1(P1)和人2(P2)交换消息的所有日期的列表,直到日期(D)。

到目前为止,我有以下内容:

message(P1,P2,Date),D=Date,print([D]); message(P2,P1,Date),D=Date,print([D]).

我需要一条规则,只返回所有日期的列表,而不必每次都输入;

我知道这条规则需要修复,所以我们非常感谢任何帮助/建议!

1 个答案:

答案 0 :(得分:1)

您可能希望显示的代码是您规则的主体,

my_rule(P1,P2,D):-
  message(P1,P2,Date),D=Date,print([D]); message(P2,P1,Date),D=Date,print([D]).

当然,对于之前的日期,我们需要@<代替=

my_rule(P1,P2,D):-
  message(P1,P2,Date),D@<Date,print([D]); message(P2,P1,Date),D@<Date,print([D]).

但那里有很多代码复制;我们需要抽象出某些东西,显然:

my_rule(P1,P2,D):-
  message_between(P1,P2,Date),D@<Date,print([D]).

message_between(P1,P2,Date):- message(P1,P2,Date) ; message(P2,P1,Date).

此代码仍有错误。哪个日期给我们?我们找到哪个日期?我们要打印出哪个?

my_rule(P1,P2,D):-
  message_between(P1,P2,Date),D @>= Date,print([Date]).

这是对的。现在我们可以进入问题的第二部分 - 您不希望一直“按;”,逐一获得解决方案。

首先,请注意,您现在不会从谓词获取解决方案,而是由它打印。修复:

my_rule(P1,P2,Dtop,Date):-
  message_between(P1,P2,Date),Dtop @>= Date.

现在,当my_rule/4成功时,它将第四个参数实例化为两个给定人之间的消息交换日期,如果它不晚于Dtop date(第三个参数)。

要全部收集它们,您需要使用内置谓词setof,正如mbratch在评论中向您暗示的那样。

all_dates(P1,P2,Dtop,DatesList):-
   setof( Date, my_rule(P1,P2,Dtop,Date), .... ).

如果谓词all_dates的所有三个第一个参数都被完全给定(即被实例化为基础术语),则它将起作用。用有意义的条目替换点。要么猜测,要么 - 更好 - 阅读setoffindall的文档。

这里仍存在一个差异。如果在给定的人和日期组合中根本没有交换消息怎么办?上面给出的规则将失败。也许您希望以空列表作为解决方案来取得成功。你能做出必要的调整吗?使用以下骨架:

rule_suceeds( ..., DatesList):-
   /*... a rule that instantiates `DatesList` ...*/ -> true ; ... = [] .