prolog - 对于日期时间转换的极端情况,正确的错误是什么?
问题描述
TL;DR: 谓词datime/2
(由 SICStus Prolog 和 SWI-Prolog 提供)将UNIX 时间与包含年、月、日、小时、分钟和秒的记录相关联。
对于某些极端情况,我得到了奇怪的答案,这让我想知道: 在这些情况下,符合 ISO 标准的 Prolog 系统应该引发哪些错误?
首先,这里是datime/2
文档——SICStus Prolog 手册的一部分:
now(-When)
将当前日期和时间统一为 UNIX 时间戳When
。
datime(-Datime)
Datime
与当前日期时间 统一datime/6
为表格的记录datime(Year,Month,Day,Hour,Min,Sec)
。所有字段都是整数。
datime(+When,-Datime)
datime(-When,+Datime)
将通过 获得的时间戳转换为now/1
记录datime/6
。可以双向使用。
所以这里有一些虚假的 SICStus Prolog 4.6.0 输出:
| ?- use_module(library(system)).
yes
| ?- datime(X,Y).
no % expected: result | error
| ?- datime(-67768200000000000,X).
no % expected: result | error
| ?- datime(X,datime(19700000000000,1,1,1,0,0)).
X = -32029950380687608 ? ; % expected: X >= 0
no
SWI-Prolog 8.2.0 给出了一些奇怪的“答案”:
?- use_module(library(dialect/sicstus/system)).
true.
?- datime(X,datime(1970,1,1,1,0,0)).
ERROR: Arguments are not sufficiently instantiated
% expected: X = 0
?- datime(10000000000000000000000000,X).
X = datime(1901, 1461302465, 32753, 9, 35, 13).
?- datime(1000000000000000000000000000,X).
X = datime(1901, 1461302465, 32753, 9, 35, 13).
?- datime(100000000000000000000000000000,X).
X = datime(1901, 1461302465, 32753, 9, 35, 13).
% expected: different answers for different queries
那么: 在这些情况下,符合 ISO 标准的 Prolog 系统应该引发哪些错误?
解决方案
如果 Unix 时间戳值不合理地超出“预期”范围,您希望确定适当的错误。我不清楚负数是否有意义。但至少,它们似乎在 0..1972 年产生了合理的日期。第二个参数可能是一个正确的域,或者只是因为不可统一的术语而失败。
从 7.12.2 中现有的错误分类,我们有以下候选:
b) 类型错误。指定一个特殊类型似乎有点牵强。毕竟,即使是非负数也不值得一个单独的类型,而是它们是一个域not_less_than_zero
。
c) 域错误。这似乎是一个不错的候选人。所以域可能是 unix_timestamp
——如果它是一个定义良好的数据类型;或datime
。
f) 表示错误。虽然类型和域错误意味着语义失败(“这样的时间不存在”),但表示错误却没有。它只是指出当前的处理器不能代表那个日期,但没有给出关于这可能意味着什么的结论。
所以我倾向于支持 f,仅仅是因为时间的概念似乎没有限制,甚至没有年份(或时间戳)7^7^7
。我知道那是真正的乐观...
两种实现似乎都有一些实例化错误的问题,SWI 产生了太多的错误,而 SICStus 不够——这个库在 SICStus 和 Quintus 血统中相对较新。
作为实例化错误的一般规则,请考虑5.5.12中新选项的要求。因此,如果第二个参数的实例是有效日期,则必须存在实例化错误。但是,如果没有有效的实例但组件仍然是变量,也可能会产生实例化错误。想想datime(T, datime(noyear,_,_,_,_,_)).
你可能会为任何非基础术语产生实例化错误。
推荐阅读
- javascript - 如何在不四舍五入的情况下从长数中删除小数?
- python - Alpha-beta 修剪在完全实施时会做出更糟糕的决定
- python - 是否有根据其他列值过滤列值的功能?
- javascript - 如何在 div 中显示 javascript 列表中的所有项目?
- cron - 如何每小时和每分钟运行一次 cron 作业
- c# - 为什么这个循环最终会反转数组?
- mule-sdk - 为什么我会得到 org.apache.maven.plugins:maven-site-plugin:3.6.1:?
- python - 当使用python的值高于阈值时,突出显示谷歌电子表格中的列中的单元格
- python - Python循环未能检测到每个目录中某些文件的使用
- python - ttk 按钮不执行功能