List 创建和打印日期列表

List 创建和打印日期列表,list,date,prolog,List,Date,Prolog,这就是我到目前为止所做的: daycompare(D,D1):- parse_time(D,iso_8601,DateCode) @< parse_time(D1,iso_8601,DateCode1). listdates(P1,P2,D1) :- message(P1,P2,D), daycompare(D,D1), print(D) ; message(P2,P1,D), daycompare(D,D1), print(D). 因此,如果我称之为规则,它将

这就是我到目前为止所做的:

daycompare(D,D1):-
    parse_time(D,iso_8601,DateCode) @< parse_time(D1,iso_8601,DateCode1).

listdates(P1,P2,D1) :-
    message(P1,P2,D), daycompare(D,D1), print(D) ;
    message(P2,P1,D), daycompare(D,D1), print(D).
因此,如果我称之为规则,它将是:

listdates(jessica,steve,'2013-08-30').
以下是此查询的输出:

2013-03-15
true ;
2013-03-15
true ;
2013-03-23
true ;
2013-03-23
true ;
2013-07-23
true ;
2013-07-23
true ;
2012-05-17
true ;
2012-05-17
true ;
2012-08-05
true ;
2012-08-05
true ;
false.
另一件我不明白的事是为什么日期要打印两次

提前谢谢

  • findall
    是获取结果列表所需的工具

  • 每种不同的解决方案都会打印出一个日期,因此必须有两种不同的方法来确定每个日期


    • 您不希望打印日期,而是希望将其作为查询结果返回
    • 当您使用'parse_time'时,第三个参数是结果,这些是您想要比较的结果
    • 您可以使用'findall/3'将所有查询结果收集到一个列表中(正如@ScottHunter所指出的)
    然后使用
    findall/3

    ?- findall(D, listdates(jessica,steve,'2013-08-30',D), DateList).
    DateList = ['2013-03-15', '2013-03-23', '2013-07-23', '2012-08-05', '2012-05-17'].
    

    在Prolog中,谓词不是返回可分配或使用的值的函数。所以
    parse_time(D,iso_8601,DateCode)@
    没有意义。你想单独调用它们,然后
    DateCode@
    或者你想比较的任何东西。像这样?daycompare(D,D1):-parse_time(D,iso_8601,DateCode),parse_time(D1,iso_8601,DateCode1),DateCodeYes。顺便说一下,我按原样运行了代码,日期没有重复。因此,在获得这些结果时运行的代码必须与显示的代码不同。此外,如果您具有一致的日期格式,如
    YYYY-MM-DD
    ,其中日期和月份被零填充为两位数字,则可以正确比较两个日期字符串,如
    D@
    ,并获得预期结果。在这种情况下,它将比较每个字符排序序列的字符串。真的很奇怪,我使用的代码和给出的代码完全相同。你知道为什么我的会重复吗?我该如何实现findall函数?它或类似的东西应该是语言的一部分,这取决于你使用的是哪种Prolog方言。我很清楚我使用的是SWI-Prolog。它是否类似于listdates(P1,P2,D1):-message(P1,P2,D)、daycompare(D,D1)、findall(D);消息(P2、P1、D)、日期比较(D、D1)、findall(D)。还是错了?@Steglas
    findall/3
    为您做的是,如果您有一个谓词提供多个解决方案,它会将它们全部收集到一个列表中。但是您的谓词中至少需要一个自由变量才能返回查询结果,而不是让谓词使用
    print
    将它们打印出来。哇,您让它看起来很简单,至少离我不远了。谢谢大家的帮助,我真的很感激@Steglas你离得不远了。我认为关键的收获是:(1)不要像在其他语言中那样将prolog谓词视为“函数”。(2)prolog生成输出,作为解决未实例化(未绑定)参数的一部分,因此您不必
    编写
    ,除非在某些情况下;(3)findall
    (或
    bagof
    setof
    )是一个很好的工具,可以收集通过回溯给定谓词生成的许多解决方案。最后一个问题。是否可以将findall/3也作为规则?这将如何阐述?listdates2(P1,P2,D1,D):-findall(D,listdates(P1,P2,D1,D),DateList)。但我只明白了。是的,我正在学习Java和Prolog,我发现Java更容易。这是有点难得到的概念,但我相信我最终会。是的,我听说这三种工具非常方便-bagof是我记忆中更详细的findall版本吗?@Steglas是的,你可以在谓词中包含
    findall/3
    。没有什么特别的东西可以阻止这一点。我发现Prolog实际上是由一组简单的规则定义的,但是可能性很大。我认为Prolog和Java就像比较围棋和国际象棋一样。
    daycompare(D,D1):-
        parse_time(D,iso_8601,DateCode),
        parse_time(D1,iso_8601,DateCode1),
        DateCode < DateCode1.
    
    listdates(P1, P2, D1, D) :-
        message(P1, P2, D), daycompare(D, D1) ;
        message(P2, P1, D), daycompare(D, D1).
    
    ?- listdates(jessica, steve, '2013-08-30', D).
    
    D = '2013-03-15' ;
    D = '2013-03-23' ;
    D = '2013-07-23' ;
    D = '2012-08-05' ;
    D = '2012-05-17'.
    
    listdates(P1, P2, D1, D) :-
        message(P1, P2, D), D @< D1 ;
        message(P2, P1, D), D @< D1.
    
    ?- findall(D, listdates(jessica,steve,'2013-08-30',D), DateList).
    DateList = ['2013-03-15', '2013-03-23', '2013-07-23', '2012-08-05', '2012-05-17'].