不合格的断言会向哪些模块添加术语?

What modules does an unqualified assert add a term to?

?- 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

当我没有提到 foo2 时,f 如何添加到 foo2。 为什么 frobnoz:f 在第二个示例中成功,但在第三个示例中失败?

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

第一个问题:

How does f get added to foo2 when I don't mention foo2.

来自SWI-Prolog Manual - Module autoload section

SWI-Prolog by default support autoloading from its standard library. Autoloading implies that when a predicate is found missing during execution the library is searched and the predicate is imported lazily using use_module/2.

你可以去deeper but, basically, when the module is not explicitly defined, prolog search for it and silently loads it. It's the default behavior. You can change it with autoload flag.

第二题:

Why does frobnoz:f succeed in the second example, but fail in the third?

可能这个 frobnoz:f 可以作为 foo1 模块的依赖项找到,您在第三个示例中没有引用它。

第三题:

What are modules? I thought they were namespaces, but am now confused.

SWI-Prolog Reference Manual 所示:

A Prolog module is a collection of predicates which defines a public interface by means of a set of provided predicates and operators. Prolog modules are defined by an ISO standard. Unfortunately, the standard is considered a failure and, as far as we are aware, not implemented by any concrete Prolog implementation. The SWI-Prolog module system syntax is derived from the Quintus Prolog module system. The Quintus module system has been the starting point for the module systems of a number of mainstream Prolog systems, such as SICStus, Ciao and YAP. The underlying primitives of the SWI-Prolog module system differ from the mentioned systems. These primitives allow for multiple modules in a file, hierarchical modules, emulation of other modules interfaces, etc. (source)

In classic Prolog systems, all predicates are organised in a single namespace and any predicate can call any predicate. [...] A Prolog module encapsulates a set of predicates and defines an interface. Modules can import other modules, which makes the dependencies explicit. Given explicit dependencies and a well-defined interface, it becomes much easier to change the internal organisation of a module without breaking the overall application. (source)

Typically, the name of a module is the same as the name of the file by which it is defined without the filename extension, but this naming is not enforced. Modules are organised in a single and flat namespace and therefore module names must be chosen with some care to avoid conflicts. As we will see, typical applications of the module system rarely use the name of a module explicitly in the source text. (source)