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
false
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).