注意:需要明确的是,我提出以下问题的动机是学习 Prolog 和 SWI-Prolog 的方法,而不是为了忽略特定的错误消息。事实上,我已经知道一种方法来克服这个错误。我的问题是询问是否还有其他几种替代方案。
<小时/>我的 Prolog 教科书中的一个练习要求人们描述从多个查询中应该期望的结果,假设人们事先查阅了以下知识库:
x(a).
z(b).
z(c).
z(d).
w(V) :- x(V).
w(V) :- y(V).
w(V) :- z(V).
至少在 SWI-Prolog 上,大多数查询都会失败,因为 SWI-Prolog 解释 y
未定义。
从书末的习题解答可以看出,这不是作者想要的结果。也许有一个 Prolog 实现,练习将在解决方案呈现时转向。
尽管如此,我还是想了解解决该问题的好方法。
例如,考虑查询 w(x).
。该书的解决方案声称查询 w(x).
应评估为 false.
。事实上,事情是这样的:
?- w(x).
ERROR: w/1: Undefined procedure: y/1
Exception: (7) y(x) ?
(此时,SWI-Prolog 期望我输入一些字母来指示如何响应异常。稍后会详细介绍。)
我正在寻找将上面的交互转变为的方法
?- w(x).
false.
?-
...或者至少对于合适的 <ONE-LETTER RESPONSE>
我可以给SWI-Prolog,以便它得出结论false
。 IOW,这样
?- w(x).
ERROR: w/1: Undefined procedure: y/1
Exception: (7) y(x) ? <ONE-LETTER RESPONSE>
false.
?-
我知道我的问题至少有一个答案,即简单地删除或注释掉该行:
w(V) :- y(V).
我想知道其他可能的解决方案,例如我之前提到的“合适的”。
另一种可能性是某些 SWI-Prolog 全局配置,这将导致上述交互更改为
?- w(x).
false.
?-
第三种可能性是“定义”y
以某种最小的方式。我能想到的唯一方法就是添加事实
y(dummy).
到知识库。有没有更简单的方法来定义 y
,不需要在讨论域中引入无关常量的一个?
最佳答案
(这并非特定于 SWI)
早在 20 世纪 70 年代的第一个 Prolog 系统实际上就按照您所描述的方式运行。很快我们就发现这是一个常见的错误来源。简单的拼写错误很长时间都没有被发现。当前的实现会产生一个干净的存在错误。这是自 1995 年以来的标准行为。
但是,您可以使用 ISO Prolog 标志 unknown
回到旧时代,它具有三个值 error
(默认)、fail
和警告
。
?- inex.
ERROR: Undefined procedure: inex/0 (DWIM could not correct goal)
?- set_prolog_flag(unknown, fail).
Warning: Using a non-error value for unknown in the global module
Warning: causes most of the development environment to stop working.
Warning: Please use :- dynamic or limit usage of unknown to a module.
Warning: See http://www.swi-prolog.org/howto/database.html
true.
?- inex.
false.
?- set_prolog_flag(unknown, warning).
Warning: Using a non-error value for unknown in the global module
Warning: causes most of the development environment to stop working.
Warning: Please use :- dynamic or limit usage of unknown to a module.
Warning: See http://www.swi-prolog.org/howto/database.html
true.
?- inex.
Warning: toplevel: Undefined procedure: inex/0 (DWIM could not correct goal)
false.
正如您在上面所读到的,SWI 建议使用 dynamic
声明来代替 - 这反过来又存在其自身的问题......最好是声明:
:- discontiguous(y/1).
关于prolog - 关于解决意外 "Undefined procedure"错误的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42468128/