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 nonvar/1.8号/ 1.9可赎回/ 1.10地/ 1.11 acyclic_term/1.
在这一组中有那些目的只是为了测试某种实例,即8.3.1 var/1,8.3.7 nonvar/1,8.3.10 ground/1,而那些假设长期充分实例化使得型式试验是安全的.不幸的是,它们与测试具体实例相结合.
考虑目标integer(X),其失败,如果X是一个nonvar术语,不是一个整数,并当X是一个变量.这破坏了许多理想的声明属性:
?- X = 1, integer(X).
true.
?- integer(X), X = 1.
false.
Run Code Online (Sandbox Code Playgroud)
理想情况下,第二个查询将使用某种形式的coroutining成功; 或者根据错误分类发出实例化错误1.毕竟:
7.12.2错误分类
错误根据Error_term的形式分类:
a)当
参数或其中一个组件是变量并且需要
实例化的参数或组件时,应该存在实例化错误.它有
形式instantiation_error....
请注意,实例化测试和类型测试的这种隐式组合会导致Prolog程序中的许多错误,并且也会出现在SO上.
对这种情况的快速解决方法是在内置的每个测试之前添加一个显式测试,或者详细说明
( var(T) -> throw(error(instantiation_error,_)) ; true),
integer(T), ....
Run Code Online (Sandbox Code Playgroud)
或更紧凑
functor(T, _,_),
integer(T), ....
Run Code Online (Sandbox Code Playgroud)
它甚至可以
T =.. _,
integer(T), …Run Code Online (Sandbox Code Playgroud) 查看Prolog文档,谓词签名有时写成如下:
foo(:Bar, +Baz, -Qux, ?Mop)
Run Code Online (Sandbox Code Playgroud)
什么是:,+,-和?为以及如何解读?此外,这些是唯一存在的还是更多?
任何在Prolog有一定经验的程序员都知道使用一元符号表示数字的优点.例如,如果我们将数字表示为1"("4"是列表"[1,1,1,1]"等等)的列表,我们可以定义:
unary_succ(X,[1|X]).
Run Code Online (Sandbox Code Playgroud)
以下查询执行预期的操作:
?- X=[1,1],unary_succ(X,Y).
X = [1, 1],
Y = [1, 1, 1].
?- unary_succ(X,Y),X=[1,1].
X = [1, 1],
Y = [1, 1, 1].
?- unary_succ(X,Y),Y=[1,1].
X = [1],
Y = [1, 1].
Run Code Online (Sandbox Code Playgroud)
通过这种方式,语句unary_succ(X,Y)以一种方式"绑定"X和Y,如果在声明事实之后,这些变量中的一个绑定到一个值,另一个绑定到一个值.
但是,如果我们使用内部数字表示,则无法执行此操作:
?- X=2,succ(X,Y).
X = 2,
Y = 3.
?- succ(X,Y),X=2.
ERROR: succ/2: Arguments are not sufficiently instantiated
?- succ(X,Y),Y=2.
ERROR: succ/2: Arguments are not sufficiently instantiated
Run Code Online (Sandbox Code Playgroud)
在我看来,先前的陈述和类似的陈述是预期的,这将是非常有用的.也就是说,我们需要以一种方式链接两个变量,当其中一个变量绑定到一个值时,另一个变量遵循先前建立的规则.
我的问题是:
a)在Prolog中做一些简单的方法.
b)如果不可能,支持此功能的任何其他编程语言?
欢迎任何评论.
感谢大家.
*附录I*
另一个例子是:
user_id(john,1234).
user_id(tom,5678).
Run Code Online (Sandbox Code Playgroud)
和查询:
X=john,user_id(X,Y).
user_id(X,Y),X=john
Run Code Online (Sandbox Code Playgroud)
目前通过回溯解决.