use*_*956 5 module swi-prolog meta-predicate
?- 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>
Run Code Online (Sandbox Code Playgroud)
我感觉合理。但是然后(从头开始)......
?- 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!
Run Code Online (Sandbox Code Playgroud)
但是之后...
?- foo2:assertz(f(1)).
true.
?- foo2:f(1).
true.
?- frobnoz:f(1).
ERROR: Undefined procedure: frobnoz:f/1
Run Code Online (Sandbox Code Playgroud)
如何F取得加入到foo2时候我不提foo2。为什么frobnoz:f在第二个例子中成功,而在第三个例子中失败?
什么是模块?我以为它们是命名空间,但现在很困惑。
当我没有提到 foo2 时,f 如何被添加到 foo2 中?
SWI-Prolog 默认支持从其标准库自动加载。自动加载意味着当在执行期间发现谓词丢失时,将搜索库并使用 use_module/2 延迟导入谓词。
你可以更深入,但基本上,当模块没有明确定义时,prolog 搜索它并静默加载它。这是默认行为。您可以使用autoload flag更改它。
为什么 frobnoz:f 在第二个例子中成功,但在第三个例子中失败?
可能这frobnoz:f可以作为foo1模块的依赖项找到,您在第三个示例中没有引用它。
什么是模块?我以为它们是命名空间,但现在很困惑。
正如SWI-Prolog 参考手册所写:
Prolog 模块是谓词的集合,它通过一组提供的谓词和运算符定义了一个公共接口。Prolog 模块由 ISO 标准定义。不幸的是,该标准被认为是失败的,据我们所知,没有被任何具体的 Prolog 实现实现。SWI-Prolog 模块系统语法源自 Quintus Prolog 模块系统。Quintus模块系统已经成为SICStus、Ciao、YAP等多个主流Prolog系统的模块系统的起点。SWI-Prolog 模块系统的底层原语与上述系统不同。这些原语允许在一个文件中使用多个模块、分层模块、其他模块接口的仿真等(源)
在经典的 Prolog 系统中,所有谓词都组织在一个命名空间中,任何谓词都可以调用任何谓词。[...] Prolog 模块封装了一组谓词并定义了一个接口。模块可以导入其他模块,这使得依赖关系显式。给定显式依赖项和定义良好的接口,在不破坏整个应用程序的情况下更改模块的内部组织变得更加容易。(来源)
通常,模块的名称与定义它的文件的名称相同,但不带文件扩展名,但不强制执行此命名。模块被组织在一个单一的平面命名空间中,因此必须谨慎选择模块名称以避免冲突。正如我们将看到的,模块系统的典型应用程序很少在源文本中明确使用模块的名称。(来源)
| 归档时间: |
|
| 查看次数: |
121 次 |
| 最近记录: |