【发布时间】:2013-10-16 14:34:14
【问题描述】:
查看 Prolog 文档,谓词签名有时写成如下:
foo(:Bar, +Baz, -Qux, ?Mop)
:、+、- 和 ? 是什么,我该如何解释它们?另外,这些是唯一存在的还是还有更多?
【问题讨论】:
标签: prolog signature iso-prolog
查看 Prolog 文档,谓词签名有时写成如下:
foo(:Bar, +Baz, -Qux, ?Mop)
:、+、- 和 ? 是什么,我该如何解释它们?另外,这些是唯一存在的还是还有更多?
【问题讨论】:
标签: prolog signature iso-prolog
在这种情况下,这些前缀运算符表示实例化模式,即它们告诉您在调用谓词时哪些参数应该是变量或实例化。它们还告诉您调用是否会(可能进一步)实例化参数。它们也可以用来告诉你一个参数将被你调用的谓词以某种方式元解释。其中一些实例化模式是标准的,其他的则取决于系统。最常见的是:
- - 参数应该是未绑定的(可能是输出参数)
+ - 参数应该被绑定(输入参数)
? - 参数可以是绑定的或未绑定的
@ - 调用不会进一步实例化参数
: - 参数将以某种方式进行元解释(通常是模棱两可的)
0 - 参数将被解释为目标并被调用
N - 其中 N 是自然数;该参数将被解释为一个闭包,该闭包将与 N 附加参数组成,以构造一个将被调用的目标
不同的系统提供其他或不同的实例化模式。例如,在调用谓词时声明参数应该是基础,或者声明参数应该是谓词指示符或将被解释为语法规则体。有关详细信息,您需要参考您正在使用的 Prolog 系统的文档。
【讨论】:
:- mode(length(?list, ?integer), zero_or_more). 但这些字符也只能用于文档中,不能用于您可以编译的代码中。因此,更友好的标题可能是“Prolog 实例化模式字符”或“Prolog 实例化模式指示符”。
模式声明于 1970 年代末首次出现在 DECsystem-10 编译器中。 1978-09 的 DECsystem-10 用户指南是最早的描述之一。动机是1982-11-10:
此类信息使编译器能够生成更紧凑的代码 更好地利用运行时存储。节省运行时间 特别是存储空间通常非常大。模式 声明还可以帮助其他人了解您的 程序运行。
+ — 参数始终是非变量
- — 参数始终是变量
? — 没有限制
请注意,这些声明适用于每个目标。最值得注意的是,它们适用于递归目标。以这种方式,以下模式声明及其定义意味着第二个参数不是部分列表。因此,目标member(A, [c|_]) 将不符合要求。所以接口和实现在某种程度上是相互依赖的,当必须考虑到谓词本身执行的统一时,这可能会导致相当复杂的情况。
:- mode member(?, +).
member(X, [X|_]). % member(X, [X,.._]) in DEC10
member(X, [_|L]) :-
member(X, L).
如果模式声明被具体目标违反,则声明要么被忽略,要么会产生错误,这在当时意味着写出错误消息并失败。 DECsystem-10 解释器总是忽略声明。
在 1970 年代的深处,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。
以这种方式,程序员只需查看模板和模式子句即可预测许多错误,而无需阅读详细的错误条件。
与 ISO 不同的系统在对模式的精确解释方面也各不相同。许多执行静默失败,以防类型错误是合适的。他们将模式声明视为指示谓词预期以未定义含义工作的情况的一种手段。通常- 大致解释如下。由于没有定义含义的实际参考,这是我非正式收集的:
- — 参数是“输出参数”。这意味着它将在目标执行后与生成的术语统一。所以论据是坚定的。通常,这样的论点不会有任何错误。
【讨论】:
更现代的文档在这里: https://www.swi-prolog.org/pldoc/man?section=modes
元谓词也有类似的注解,它应该有meta_predicate 指令,以确保它们在被调用时正确添加模块。 https://www.swi-prolog.org/pldoc/doc_for?object=(meta_predicate)/1
【讨论】: