使用SWI-Prolog(多线程,64 位,版本 7.3.5),我们一步一步进行:
在模块中定义dcg非终结符(发音:“ di-SEE-goh ”):
a//1
dcgAux
:- 模块(dcgAux,[a//1])。 一(0)-> []。 a(s(N)) --> [a], a(N)。
运行以下查询 - 使用
phrase/2
andapply:foldl/4
:?- 使用模块([库(应用),dcgAux])。 真的。 ?- 短语( foldl( a,[s(0),s(s(0))]),[a,a,a])。 真的。 ?- 短语( foldl(dcgAux:a,[s(0),s(s(0))]),[a,a,a])。 真的。 ?- 短语(应用:折叠(dcgAux:a,[s(0),s(s(0))]),[a,a,a])。 真的。 ?- 短语(应用:折叠(a,[s(0),s(s(0))]),[a,a,a])。 错误:应用:foldl_/4:未定义的过程:应用:a/3
нет!相当惊喜——而且不是一个好惊喜。我们是否错过了一些未知的未知数?
为了摆脱上述恼人的行为,我们必须首先找出导致它的原因:
?- import_module(apply,M), M=user。 假的。 ?- 短语(应用:折叠(a,[s(0),s(s(0))]),[a,a,a])。 错误:应用:foldl_/4:未定义的过程:应用:a/3 ?- add_import_module(应用,用户,结束)。 真的。 ?- import_module(apply,M), M=user。%sic! M = 用户。% `?- import_module(apply,user).` 失败! ?- 短语(应用:折叠(a,[s(0),s(s(0))]),[a,a,a])。 真的。
这是怎么回事?我的看法是这样的:
- 传递给目标的模块扩展
foldl/4
是有限的。 引用SWI-Prolog 手册页
import_module/2
:所有普通模块仅从用户导入,从系统导入。
SWI 的
library(apply)
唯一“继承”自system
,但不是user
。如果我们将模块克隆
apply
到applY
(并传播新的模块名称),我们观察到:?- 使用模块(应用)。 真的。 ?- 短语(应用 : foldl (a,[s(0),s(s(0))]),[a,a,a])。% 是:错误为 真。% 现在好了!
请分享您对我可以/应该如何进行的想法!
(我还没有对其他 Prolog 处理器进行过类似的实验。)