Prolog编写事实规则查询为何仅返回true不返回变量绑定值
问题原因
你的代码只返回true不返回X的绑定值,核心是两个错误:
- 滥用匿名变量
_切断了值传递路径
Prolog里的匿名变量_是不参与统一绑定的特殊变量,每个位置的_都是独立的,不会和其他位置的变量建立关联。你写的两个子句头部第一个参数全是_,意味着递归过程中哪怕算出了最后一个元素是d,这个值也没法和最外层查询传入的X做绑定,值在回溯阶段根本传不回顶层查询。 - 边界条件逻辑错误
你写的边界子句my_last(_, []).用来匹配空列表,但空列表本身不存在最后一个元素,这个子句逻辑本身就不成立。也正是因为这个错误的边界,你的递归会一直拆分到空列表才停止,比正确的递归终止时机多走了一步。
你trace时观察到执行到my_last(d, [])就返回true,本质是这个错误的边界子句直接让查询成立了,但因为全程没有用统一的变量把d和顶层的X关联起来,Prolog自然只会返回true,不会给出变量绑定结果。
正确实现
正确的代码需要做两处调整:一是把边界条件改为匹配单元素列表,二是全程用同一个变量贯穿递归过程,保证绑定值可以逐层传递回来:
% 边界条件:列表仅包含一个元素时,该元素就是列表的最后一个元素 my_last(X, [X]). % 递归规则:长度大于1的列表,最后一个元素和它的表尾的最后一个元素相同 my_last(X, [_|T]) :- my_last(X, T).
加载上述代码后执行示例查询?- my_last(X, [a,b,c,d]).,就会得到预期输出X = d。
内容的提问来源于stack exchange,提问作者Andrew Lubrino
相关产品推荐
相关产品推荐

