查看Prolog文档,谓词签名有时写成如下:
foo(:Bar, +Baz, -Qux, ?Mop)
Run Code Online (Sandbox Code Playgroud)
什么是:,+,-和?为以及如何解读?此外,这些是唯一存在的还是更多?
在此上下文中,这些前缀运算符表示实例化模式,即它们告诉您哪些参数应该是变量或在调用谓词时实例化.他们还会告诉您参数是否(可能进一步)被调用实例化.它们也可以用来告诉你一个参数将以某种方式被你正在调用的谓词进行元解释.其中一些实例化模式是标准的,其他模式取决于系统.最常见的是:
- - 参数应该是未绑定的(可能是输出参数)
+ - 参数应该绑定(输入参数)
? - 参数可以是绑定的也可以是非绑定的
@ - 该调用不会进一步实例化该参数
: - 论证将以某种方式进行元解释(通常含糊不清)
0 - 参数将被解释为目标并被称为目标
N - 其中N是自然数; 该参数将被解释为一个闭包,它将与N其他参数一起构成一个将被调用的目标
不同的系统提供其他或不同的实例化模式.例如,用于声明在调用谓词时应该参数,或者声明参数应该是谓词指示符或者将被解释为语法规则体.您需要参考您正在使用的Prolog系统的文档以获取详细信息.
模式声明最初出现在20世纪70年代末的DECsystem-10编译器中.DECMSystem-10 1978-09用户指南是最早的描述之一.动机是1982-11-10:
这些信息使编译器能够生成更紧凑的代码,从而更好地利用运行时存储.特别是节省运行时存储通常非常大.模式声明还可以帮助其他人了解您的程序如何运作.
+ - 参数永远是一个非变量
- - 参数将始终是一个变量
? - 没有限制
请注意,这些声明适用于每个目标.最值得注意的是,它们适用于递归目标.以这种方式,以下模式声明及其定义意味着第二个参数不是部分列表.因此,目标member(A, [c|_])不符合要求.因此,当谓词本身执行的统一必须被考虑时,接口和实现在某种程度上是相互依赖的,这可能导致非常复杂的情况.
:- mode member(?, +).
member(X, [X|_]). % member(X, [X,.._]) in DEC10
member(X, [_|L]) :-
member(X, L).
Run Code Online (Sandbox Code Playgroud)
如果某个具体目标违反了模式声明,则该声明将被忽略,或者将产生一个错误,该错误在此时意味着写出错误消息并失败.DECsystem-10解释器总是忽略声明.
在20世纪70年代的深层次,DEC 10用户指南因此对模式声明产生了两种解释:第一种是规定性的,在调用者不满足模式的情况下确实产生错误.第二个是完全非正式的,忽略了运行时的模式声明.前者用于Prolog标准,后者可以在一些Prolog系统的文档中找到.
Prolog标准(ISO/IEC 13211-1:1995,2007,2012)使用以下格式来定义内置谓词.它从子条款.1描述,.2模板和模式,.3错误开始,并且可选地继续.4示例,.5自举内置谓词.
8.1.2模板和模式
参数类型的规范以及哪些参数
应该被实例化以满足内置谓词
.案件形成互相排斥的集合.
...
混凝土模式是:
+ - 论证应该被实例化.
@- 喜欢+和论点保持不变.
- - 如果目标成功,参数应为将被实例化的变量.
? - 没有模式要求,参数可以是变量或实例化.
如果使用不同的模式调用谓词,则生成instantiation_error或uninstantiation_error生成谓词.如果类型不匹配,type_error则生成a.通过这种方式,程序员只需查看模板和模式子条款就可以预见到许多错误,而无需阅读详细的错误条件.
与ISO不同的系统在模式的精确解释方面也彼此不同.如果类型错误合适,许多人会执行静默失败.他们将模式声明视为一种手段,用于指示谓词预期与未定义含义一起工作的情况.通常-大致解释如下.由于没有定义含义的实际参考,这是我非正式收集的内容:
- - 参数是"输出参数".这意味着在目标执行后它将与结果术语统一.所以这个论点是坚定的.通常,没有错误与这样的论证相关联.