无条件断言会给什么模块增加一个术语?

问题描述 投票:3回答:1
?- assertz(:- module(foo1, [f/1])).
true.

?- foo1:assertz(f(1)).
true.

?- foo1:f(1).
true.

?- foo2:f(1).
Correct to: "foo1:f(1)"? no
ERROR: Undefined procedure: foo2:f/1
ERROR: In:
ERROR:    [8] foo2:f(1)
ERROR:    [7] <user>

我觉得很有道理。但是后来(从头开始)......。

?- assertz(:- module(foo1, [f/1])).
true.

?- assertz(f(1)).
true.

?- foo1:f(1).
true.

?- foo2:f(1).
true.    # Wait, what? foo2 doesn't appear in my program. Should fail?

?- frobnoz:f(1).
true.    # Also odd!

但是,然后....

?- foo2:assertz(f(1)).
true.

?- foo2:f(1).
true.

?- frobnoz:f(1).
ERROR: Undefined procedure: frobnoz:f/1

f怎么会被添加到 foo2 当我不说 foo2.为什么 frobnoz:f 在第二个例子中成功,但在第三个例子中失败?

模块是什么?我以为它们是命名空间,但现在很困惑。

module swi-prolog meta-predicate
1个回答
7
投票

第1个问题:如何将f添加到foo2:f1中?

当我没有提到foo2时,f怎么会被添加到foo2中。

来自 SWI-Prolog手册 - 模块自动加载部分:

SWI-Prolog默认支持从标准库中自动加载。自动加载意味着当在执行过程中发现一个谓词缺失时,库会被搜索,并使用use_module2懒惰地导入该谓词。

你可以去 更深 但是,基本上,当模块没有被明确定义时,prolog会搜索它并默默地加载它。这是默认的行为。你可以用 自动加载旗.

第2个问题。

为什么frobnoz:f在第二个例子中成功了,而在第三个例子中失败了?

可能是这样的 frobnoz:f 的依赖关系,可以从 foo1 模块,你在第三个例子中没有引用。

第三个问题。

模块是什么?我以为它们是命名空间,但现在很困惑。

SWI-Prolog参考手册 读。

Prolog模块是一个谓词的集合,它通过一组提供的谓词和运算符来定义一个公共接口。Prolog模块是由一个ISO标准定义的。遗憾的是,这个标准被认为是失败的,据我们所知,没有任何具体的Prolog实现来实现。SWI-Prolog模块系统语法来源于Quintus Prolog模块系统。Quintus模块系统一直是一些主流Prolog系统的模块系统的起点,如SICStus、Ciao和YAP等。SWI-Prolog模块系统的底层基元与上述系统不同。这些基元允许在一个文件中使用多个模块,分层模块,模拟其他模块的接口等。源码)

在经典的Prolog系统中,所有的谓词都被组织在一个单一的命名空间中,任何谓词都可以调用任何谓词。[...]一个Prolog模块封装了一组谓词并定义了一个接口。模块可以导入其他模块,这使得依赖关系显式化。鉴于明确的依赖关系和定义良好的接口,改变模块的内部组织结构而不破坏整个应用程序会变得更加容易。(源头)

通常情况下,一个模块的名称和它所定义的文件名称是一样的,没有文件名的扩展名,但是这种命名方式并不强制执行。模块被组织在一个单一的、扁平的命名空间中,因此模块名称的选择必须谨慎,以避免冲突。正如我们将看到的,模块系统的典型应用很少在源代码中明确使用模块的名称。(源头)

© www.soinside.com 2019 - 2024. All rights reserved.