Prolog中为何不能在事实后添加cut?咨询原因及回溯阻止方法
为什么你不能在Prolog事实后直接加cut?
这个问题核心是没搞清楚Prolog中子句的语法规则和cut的使用位置,我来给你理明白:
首先,你写的likes(mary,juice).是一个事实,在Prolog的语法里,事实其实是一种简化的子句——它等价于likes(mary,juice) :- true.,也就是没有自定义体(体是内置的true目标)的规则。
而!(cut)是一个目标,它必须出现在子句的体部分(也就是:-符号后面的内容里),不能直接用逗号跟在事实后面。你写的likes(mary,juice),!.既不符合事实的语法(事实只能是谓词(参数).的形式),也不符合规则的语法(规则需要:-来分隔头和体),所以编译器肯定会报错。
满足你需求的正确写法
如果想要实现「当这个匹配成功后阻止回溯」的需求,你需要把事实改写成带体的规则,把cut放在体里:
likes(mary,juice) :- !.
这样当这个子句被匹配成功并执行到!时,就会切断回溯:后续如果程序尝试回溯寻找其他likes(mary, _)的子句,会直接终止,不会再去尝试其他可能的匹配。
举个实际的例子,假设你还有其他同谓词的子句:
likes(mary,juice) :- !. likes(mary,coffee). likes(mary,tea).
当你查询likes(mary, X).时,只会得到X = juice这一个结果——因为第一个子句里的cut已经冻结了之前的选择点,回溯时不会再去尝试后面的coffee和tea选项。
内容的提问来源于stack exchange,提问作者Qwerto
相关产品推荐
相关产品推荐

