Prolog 和无头的含义

Dav*_*fer 5 prolog

在 Prolog 代码中,可以通过使用“无头”Horn 子句向编译器传递指令,这些子句与左指材料蕴涵':-' (?) 的左侧没有头部关系。例如,要导入模块或声明单元测试代码

:- begin_tests(lists).
:- use_module(library(lists)).

test(reverse) :- reverse([a,b], [b,a]).

:- end_tests(lists).
Run Code Online (Sandbox Code Playgroud)

显然,无头 Horn 子句在源文件中的位置很重要。

喇叭条款

HEAD :- BODY1, BODY2, .... , BODYN
Run Code Online (Sandbox Code Playgroud)

被理解为等价于逻辑表达式

身体_1?身体_2?.... ? 身体_n ? 头

或者,因为这被理解为经典逻辑,使用布尔代数的等价规则:

¬body_1 ?¬body_2 ? .... ? ¬body_n ? 头

在无头子句的情况下,我们因此断言否定:

:- begin_tests(lists).
Run Code Online (Sandbox Code Playgroud)

原则上意味着我们断言这begin_tests(lists)不是真的。

(实际上,在Answer Set Programming 中,上述类型的子句用作“矛盾”以拒绝生成的解决方案::- move(D,P,T), blocked(D-1,P,T).意思是“ move(D,P,T) ?blocked(D-1,P,T)永远不是真的” ,相应地拒绝任何潜在的解决方案。)

我理解能够指定代码分隔符、源注释、文件元信息和其他编译器指令的实际需求。但是为什么指令使用:-. 使用一些与逻辑语法完全无关的其他符号,例如#C 宏传统上使用的符号,会不会更干净。

fal*_*lse 2

使用一些与逻辑语法完全无关的其他符号(例如 C 宏传统上使用的 #)会不会更简洁。

只要您使用 Prolog 的术语语法,与 Horn 子句的字面类比就不起作用,因为前缀运算符和后缀运算符都表示相同的术语。头部为空的子句 is:- p.和主体为空的子句 isp :- .使用适当的运算符都表示术语:-(p).由于您可以动态更改运算符,因此术语:-(p).非常不明确:它可能表示头部为空的事实或规则。

在 Prolog 文本中,读取术语:-(Dir).称为指令。自 Edinburgh Prolog 以来,即自 1977 年以来,情况都是如此。最初(并且仍然在许多当前的实现中),该术语Dir只是简单地视为要执行的目标,并在失败时发出警告。对于显示答案的查询,?-(Query).使用了该术语,后来成为提示?-。也就是说,顶层循环会?-为您打印。

在 ISO Prolog 中,仅定义了选定数量的指令。

7.4.2 指令 1 动态/1。2 多文件/1。3 不连续/1。4 操作/3。5 字符_转换/2。6 初始化/1。7 包括/1。8 确保_已加载/1。9 设置序言标志/2。

一般目标需要用 包裹起来initialization/1。它们在整个 Prolog 文本准备好执行后执行。将此与在许多实现中立即执行的指令与迄今为止读取的子句的当前状态进行对比。

我一直无法理解的是为什么系统对指令和?-问题执行单例变量检查。