如何为Prolog简单元解释器添加cut(截断)处理能力?
让Prolog简单元解释器支持cut操作的方法
现有问题
很多教材里都会用到这个简单的Prolog元解释器:
prove(true) :- !. prove((A,B)):- !, prove(A), prove(B). prove(H) :- clause(H,B), prove(B), write(H), write(" <- "), writeln(B).
用下面这个带cut的测试程序运行时会出问题:
% 亲属关系事实 parent(john, jane). parent(john, james). parent(sally, jane). parent(martha, sally). parent(deirdre, martha). % 祖先关系定义(含cut截断) ancestor(X,Y) :- parent(X,Y), !. ancestor(X,Y) :- parent(X,A), ancestor(A,Y).
执行查询?- prove(ancestor(martha, jane)).会报错:
?- prove(ancestor(martha, jane)). parent(martha,sally) <- true parent(sally,jane) <- true No permission to access private_procedure `!/0' In: [6] clause(!,_692) [5] prove(!) at line 20 [3] prove(ancestor(sally,jane)) at line 20 [1] prove(ancestor(martha,jane)) at line 20
问题出在元解释器试图用clause/2解析cut(!),但cut是Prolog的内置私有过程,没法通过这种方式处理。
简单解决方法
和处理否定操作\+的思路一样,给元解释器加一条专门处理cut的规则就行。修改后的完整代码:
prove(true) :- !. prove((A,B)):- !, prove(A), prove(B). prove(\+ A) :- !, \+ prove(A). % 处理否定操作 prove(!) :- !. % 处理cut:直接执行内置的截断操作 prove(H) :- clause(H,B), prove(B), write(H), write(" <- "), writeln(B).
这条prove(!) :- !.规则的作用是:当元解释器遇到cut目标时,直接执行Prolog内置的cut操作(规则体里的!),既实现了cut的截断语义,又避免了调用clause/2访问私有过程的错误。
修改后再运行之前的查询,就能正常执行,cut的逻辑也能正确生效。
内容的提问来源于stack exchange,提问作者Penelope
相关产品推荐
相关产品推荐

