Prolog 关于解决意外情况的方法;“未定义的程序”;错误
NB:我想澄清一下,我提出以下问题的动机是学习如何处理Prolog和SWI Prolog,而不是越过特定的错误消息。事实上,我已经知道一种克服这个错误的方法。我的问题是,是否还有其他几种选择Prolog 关于解决意外情况的方法;“未定义的程序”;错误,prolog,Prolog,NB:我想澄清一下,我提出以下问题的动机是学习如何处理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勇敢地将
在我的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.
?-
…或者至少对于一个合适的
我可以给SWI Prolog,这样它就可以得出结论false
。瞧,那么
?- w(x).
ERROR: w/1: Undefined procedure: y/1
Exception: (7) y(x) ? <ONE-LETTER RESPONSE>
false.
?-
我想知道其他可能的解决办法,例如,我刚才提到的“适当”办法
另一种可能是一些SWI Prolog全局配置,这将导致上述交互更改为
?- w(x).
false.
?-
第三种可能是以某种最小的方式“定义”y
。我能想出的唯一办法就是加上这个事实
y(dummy).
到知识库。有没有一种更简单的方法来定义
y
,一种不需要在论述域中引入无关常量的方法?未定义的过程错误会引发异常,因此,如果您不想更改y/1谓词(删除或定义它),则希望引发异常您需要捕获异常,然后返回false,如下所示:
x(a).
z(b).
z(c).
z(d).
w(V) :- x(V).
w(V) :- catch(y(V), error(Err,_Context),my_handler(Err)).
w(V) :- z(V).
my_handler(Err):- write(Err),fail.
例如:
?- w(x).
existence_error(procedure,y/1)
false.
(这不是针对SWI的)
20世纪70年代的第一个Prolog系统实际上是按照您描述的方式运行的。很快,很明显,这是一个常见的错误来源。简单的拼写错误在很长一段时间内都没有被发现。当前的实现会产生一个干净的存在错误。这是自1995年以来的标准行为
但是,您可以使用ISO Prolog标志unknown
返回到旧版本,该标志有三个值error
(默认值)、fail
和warning
?- 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建议使用动态
声明来代替-这反过来也有其自身的问题。。。最好是声明:
:- discontiguous(y/1).
您可以使用指令
:-dynamic y/1将y/1
声明为动态。
这会导致调用它的目标在不存在任何子句时失败。
:- discontiguous(y/1).