ISO-Prolog(ISO/IEC 13211-1:1995,包括Cor.1:2007,Cor.2:2012)提供了用于测试术语类型的以下内置谓词:
8.3 类型测试
1 var/1. 2 atom/1. 3 integer/1. 4 float/1. 5 atomic/1. 6 compound/1. 7 nonvar/1. 8 number/1. 9 callable/1. 10 ground/1. 11 acyclic_term/1.
在这个组中,有些谓词的目的仅仅是为了测试特定的实例化,即8.3.1 var/1,8.3.7 nonvar/1,8.3.10 ground/1,以及那些假设术语已经被充分实例化以使类型测试安全的谓词。不幸的是,它们与对具体实例化的测试结合在一起。
考虑目标
更简洁地说,可以表示为
它甚至可能更好。
我的问题有两个方面:
其他不太理想的选择是循环或产生资源错误。但仍然比得到错误结果要好。
8.3 类型测试
1 var/1. 2 atom/1. 3 integer/1. 4 float/1. 5 atomic/1. 6 compound/1. 7 nonvar/1. 8 number/1. 9 callable/1. 10 ground/1. 11 acyclic_term/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.
理想情况下,第二个查询要么通过某种协程形式成功执行;要么根据error classification发出实例化错误1。毕竟:
7.12.2 错误分类
错误按照Error_term的形式进行分类:
a) 当参数或其组件为变量且需要已实例化的参数或组件时,会出现实例化错误。它的形式为
instantiation_error
。...
请注意,这种隐含的实例化测试和类型测试的组合会导致Prolog程序中的许多错误,也会在此处发生。
对这种情况的快速修复是在每个测试内置之前添加显式测试,可以如下详细描述:
( nonvar(T) -> true ; throw(error(instantiation_error,_)) ),
integer(T), ....
更简洁地说,可以表示为
functor(T, _,_),
integer(T), ....
它甚至可能更好。
T =.. _,
integer(T), ...
我的问题有两个方面:
如何在用户级别提供此功能?
以及,为了使其更具挑战性:
什么是使用ISO-Prolog编写的更紧凑的、更安全的
atomic/1
实现?
其他不太理想的选择是循环或产生资源错误。但仍然比得到错误结果要好。
must_be(integer, X)
如何适用于此(只是举个例子)? - user1812457must_be(integer, a)
会产生一个type_error(integer,a)
- 它应该失败。 - falsemust_be(integer,a)
应该失败?根据手册页面,must_be
从不失败。可能是其他谓词会失败。(如has_type/2
,如果我没记错的话) - repeatcatch/3
捕获错误。如果有替代方案,类型错误是无用的,只有在您说TINA时才有用。 - falseinteger(X)
的回答为false
意味着没有整数。integer(X)
失败的原因是DEC10没有错误,而它的前身(马赛)Prolog I有错误,但是没有人读过(法国)论文。 - false