If statement 在prolog中返回布尔值的嵌套if语句

If statement 在prolog中返回布尔值的嵌套if语句,if-statement,prolog,If Statement,Prolog,我想比较两个date结构,如果第一个日期早于第二个日期,则返回true,否则返回false 逻辑很简单 第一个日期为D1,第二个日期为D2 如果D1年>D2年,则返回false 如果D1年=D2年,比较月份 如果D1年

我想比较两个
date
结构,如果第一个日期早于第二个日期,则返回
true
,否则返回
false

逻辑很简单

第一个日期为D1,第二个日期为D2

  • 如果D1年>D2年,则返回
    false
  • 如果D1年=D2年,比较月份
  • 如果D1年true
  • 重复此过程,直到比较秒

    我尝试过的示例代码:

    date_earlier_than(date(SY, SM, SD, SH, SMm, SS, _, _, _),
                      date(EY, EM, ED, EH, EMm, ES, _, _, _)) :-
        (   SY > EY ->
            fail
        ;
            SY =:= EY ->
                (   SM > EM ->
                    fail
                ;
                    SM =:= EM ->
                        (   SD > ED ->
                            fail
                        ;
                            SD =:= ED ->
                                (   SH > EH ->
                                    fail
                                ;
                                    SH =:= EH ->
                                        (   SMm > EMm ->
                                            fail
                                        ;
                                            SMm =:= EMm ->
                                                (   SS >= ES ->
                                                    fail
                                                ;
                                                    true
                                                )
                                        ;
                                            true
                                        )
                                ;
                                    true
                                )
                        ;
                            true
                        )
                ;
                    true
                )
        ;
            true
        ).
    
    此谓词始终返回作为参数传递的任何日期

    我不知道哪里出错了,即使我使用
    trace
    跟踪流程,谓词在执行后也会立即返回
    false

    更新

    示例代码按预期工作,但在测试时没有使用
    date/9
    ,导致失败

    这是修改后的表格:

    date_earlier_than(date(SY, SM, SD, SH, SMm, SS, SOff, STZ, SDST),
                      date(EY, EM, ED, EH, EMm, ES, EOff, ETZ, EDST)) :-
        Start = date(SY, SM, SD, SH, SMm, SS, SOff, STZ, SDST),
        End = date(EY, EM, ED, EH, EMm, ES, EOff, ETZ, EDST),
        Start @< End, !.
    
    
    日期早于(日期(SY、SM、SD、SH、SMm、SS、SOff、STZ、SDST),
    日期(EY、EM、ED、EH、EMm、ES、EOff、ETZ、EDST):-
    开始=日期(SY、SM、SD、SH、SMm、SS、SOff、STZ、SDST),
    结束=日期(EY、EM、ED、EH、EMm、ES、EOff、ETZ、EDST),
    开始@<结束!。
    
    这完全没有必要

    如果将日期表示为复合术语,则可以使用内置的比较谓词和“术语的标准顺序”来正确比较。例如,请参见SWI Prolog文档:

    或GNU序言:

    试试看,例如:

    ?- date(2020, 10, 26, 10, 34, 43) @< date(2020, 10, 26, 6, 34, 43).
    
    但这也不是必要的。只需将您的时间表示为时间戳(例如,自1970-01-01T0:0:0Z起的秒数),并将其作为数字进行比较(可能是浮点数)。请参见此处的示例:

    无论作为参数传递的日期是什么,该谓词始终返回false

    不适合我:

    ?- Today = date(2020, 10, 26, 12, 13, 14, _, _, _), Agincourt = date(1415, 10, 25, 09, 10, 11, _, _, _), date_earlier_than(Today, Agincourt).
    false.
    
    ?- Today = date(2020, 10, 26, 12, 13, 14, _, _, _), Agincourt = date(1415, 10, 25, 09, 10, 11, _, _, _), date_earlier_than(Agincourt, Today).
    Today = date(2020, 10, 26, 12, 13, 14, _2890, _2892, _2894),
    Agincourt = date(1415, 10, 25, 9, 10, 11, _2916, _2918, _2920).
    
    阿金库尔战役确实发生在今天之前,所以你的断言似乎是有效的,至少在某种程度上是有效的。这是一个很好的论据,支持在问题中始终(始终)包含测试数据


    除此之外,我同意另一个答案的建议,将数据设置为只需使用
    @我也尝试过使用
    @,当然有办法生成嵌套if。但不确定你现在到底在问什么。也许你只能在你的问题中嵌套两次,这样就很明显错误在哪里了。我也不明白你所说的“未能以变量形式评估日期”是什么意思。你能用代码表示吗?好的,我会缩小范围。对于评估失败,我指的是以下代码:
    get_time(TimeStamp),current_prolog_flag(timezone,TZ),stamp_date_time(TimeStamp,date,TZ),date@
    其评估结果为
    false
    。这可能是由于原子和复合词之间的比较造成的。@PHD您在注释中的查询与问题无关。无论如何,从查询中删除最后一个比较,以便查看
    Date
    的外观。我明白了:
    Date=Date(2020,10,26,14,36,58.586801052,-7200,--)
    所以,如果你试图用算术比较原子
    -
    ,这将失败。@PHD。。。但是在您在注释中显示的查询中,
    Date
    是一个带arity 9的复合词;它总是比算术为3的复合项“大”。从文档中(我回答中的链接:“复合术语首先检查其算术性…”我很傻。我使用了
    date/3
    作为参数。在我使用
    date/9
    进行测试后,谓词起作用了。答案就在那里,我没有在其中输入正确的值!即使你考虑了时区,也更容易将其作为一对世界时(某种格式)保存和一个时区。本地时间可以从中提取。在比较时使用自由变量是完全危险的。在我的计算机上,这是成功的:
    ?-X=date(2020,10,u),Y=date(2020,10,u),X@
    (什么?)而这失败了:
    ?-X=date(2020,10,u),Y=date(2020,10,u),X==Y.
    (什么?)关于变量,大家都同意,应该完全删除任何不需要的字段。
    ?- Today = date(2020, 10, 26, 12, 13, 14, _, _, _), Agincourt = date(1415, 10, 25, 09, 10, 11, _, _, _), date_earlier_than(Today, Agincourt).
    false.
    
    ?- Today = date(2020, 10, 26, 12, 13, 14, _, _, _), Agincourt = date(1415, 10, 25, 09, 10, 11, _, _, _), date_earlier_than(Agincourt, Today).
    Today = date(2020, 10, 26, 12, 13, 14, _2890, _2892, _2894),
    Agincourt = date(1415, 10, 25, 9, 10, 11, _2916, _2918, _2920).