ISO-Prolog(ISO/IEC 13211-1:1995 包括 Cor.1:2007、Cor.2:2012)提供以下内置谓词来测试术语的类型:
8.3 型式试验
1 var/1。2个原子/1。3 整数/1。4个浮子/1。5个原子/1。6化合物/1。7 无变量/1。8个数字/1。9个可调用/1。10地/1。11 非循环术语/1。
在这一组中,有些人的目的仅仅是测试某个实例化,即 8.3.1 var/1
、 8.3.7 nonvar/1
、 8.3.10 ground/1
,以及那些假设一个术语已充分实例化以使型式测试是安全的。不幸的是,它们与具体实例化的测试相结合。
考虑如果是非整数的非变量项并且何时是变量,则integer(X)
失败的目标。这会破坏许多理想的声明性属性:X
X
?- X = 1, integer(X).
true.
?- integer(X), X = 1.
false.
理想情况下,第二个查询要么使用某种形式的协程成功;要么 否则它会根据错误分类发出实例化错误1 。毕竟:
7.12.2 错误分类
错误按照Error_term的形式分类:
a) 当参数或其组件之一是变量并且需要
实例化参数或组件时,应存在实例化错误。它有
形式instantiation_error
。...
请注意,实例化测试和类型测试的这种隐式组合会导致 Prolog 程序以及 SO 中的许多错误。
解决这种情况的一个快速方法是在每个内置测试之前添加一个显式测试,或者详细地为
( nonvar(T) -> true ; throw(error(instantiation_error,_)) ),
integer(T), ....
或更紧凑地为
functor(T, _,_),
integer(T), ....
甚至可能
T =.. _,
integer(T), ...
我的问题是双重的:
如何在用户级别提供此功能?
而且,为了使这也有点挑战性:
atomic/1
用 ISO-Prolog 编写的更安全的最紧凑的实现是什么?
1 其他不太理想的选择是循环或产生资源错误。仍然比不正确的结果更可取。