使用SWI-Prolog(多线程,64位,版本7.3.5), 我们一步一步地进行:
在模块a//1
中定义dcg非终结dcgAux
(发音为:“ di-SEE-goh ”):
:- module(dcgAux,[a//1]). a(0) --> []. a(s(N)) --> [a], a(N).
使用phrase/2
和apply:foldl/4
运行以下查询:
?- use_module([library(apply),dcgAux]). true. ?- phrase( foldl( a,[s(0),s(s(0))]),[a,a,a]). true. ?- phrase( foldl(dcgAux:a,[s(0),s(s(0))]),[a,a,a]). true. ?- phrase(apply:foldl(dcgAux:a,[s(0),s(s(0))]),[a,a,a]). true. ?- phrase(apply:foldl( a,[s(0),s(s(0))]),[a,a,a]). ERROR: apply:foldl_/4: Undefined procedure: apply:a/3
нет!非常惊喜 - 而不是一个好的。我们是否遗漏了一些未知的未知数?
为了摆脱上述恼人的行为,我们必须先找出导致它的原因:
?- import_module(apply,M), M=user. false. ?- phrase(apply:foldl(a,[s(0),s(s(0))]),[a,a,a]). ERROR: apply:foldl_/4: Undefined procedure: apply:a/3 ?- add_import_module(apply,user,end). true. ?- import_module(apply,M), M=user. % sic! M = user. % `?- import_module(apply,user).` fails! ?- phrase(apply:foldl(a,[s(0),s(s(0))]),[a,a,a]). true.
发生了什么事?我看到它的方式是:
foldl/4
的目标的模块扩展是有限的。引自SWI-Prolog manual page on import_module/2
:
所有普通模块仅从用户导入,从用户导入。
SWI的library(apply)
仅“{继承”来自system
,而不是user
。
如果我们将模块apply
克隆到applY
(并传播新的模块名称),我们会观察:
?- use_module(applY). true. ?- phrase(applY:foldl(a,[s(0),s(s(0))]),[a,a,a]). % was: ERROR true. % now: OK!
请分享您对我如何/应该如何进行的想法!
(我还没有与其他Prolog处理器进行类似的实验。)
答案 0 :(得分:6)
这是Quintus传统中基于谓词的模块系统的固有特征/错误。也就是说,这个模块系统最初是为Quintus Prolog开发的。它随后由SICStus采用(在0.7 1 之后),然后(或多或少)由13211-2采用,然后由YAP采用,并且(经过一些修改)由SWI采用。
这里的问题是一个明确的资格意味着什么。只要目标不是元谓词,事情就可以轻易解决:采用最内层资格的模块。但是,一旦有了元谓词,就需要将元参数告知该模块;或不。如果通知了元参数,我们说冒号设置调用上下文,如果没有,那么为此目的需要一些其他方法。
在Quintus传统中,元参数被考虑在内。结果你看到了。因此,您无法直接在同一模块中比较同一元谓词的两个实现。还有其他方法,尤其是IF和ECLiPSe,它们不会通过冒号更改调用上下文。这有利有弊。最好的是逐个比较它们。
这是最近的案例。取lambdas以及如何将它们放入模块中 在SICStus中,in SWI和in ECLiPSe。
对于Quintus / SICStus / YAP / SWI模块系统,我宁愿以最保守的方式使用它。那就是:
没有明确的资格,将中缀:
视为内部内容
干净,可检查的元声明 - 故意插入未定义的谓词,以查看交叉引用是否能够检测到问题(在SWI中check
或{{ 1}})。
使用公共子集,避免许多花里胡哨 - 有很多很好的扩展......
在行人方式做更多功能:通过添加适当的模块并添加虚拟定义来重新导出。同样,不是重命名,而是从接口模块导入内容。
始终注意模块系统固有某些限制。无论你如何扭曲或扭转它。没有完全无缝的模块系统,因为模块的目的是分离代码和关注点。
1:确切地说,SICStus'对于make
声明中的模块敏感参数,Quintus模块的调整仅包含:
。对基于meta_predicate
的高阶编程非常重要的整数0..9
仅在大约20年后才被引入
4.2.0 released 2011-03-08