如何用Prolog生成包含元素前后项的三元组嵌套列表?
Prolog生成三元组邻接列表的实现问题
需求是从输入列表生成由三元组子列表组成的列表:每个三元组包含当前元素的前一个元素、当前元素、后一个元素。边界情况处理:第一个元素的前一个元素为null,最后一个元素的后一个元素为null。例如输入[1,2,3,4],期望输出:
[[null,1,2],[1,2,3],[2,3,4],[3,4,null]]
现有两个Prolog谓词均存在问题:
- 第一个谓词缺失开头的
[null,1,2]; - 第二个谓词结尾结果错误,返回
[...,6,null]而非[5,6,null]。
原谓词代码
第一个谓词
take_with_neighbors([X|Xs], Result) :- take_with_neighbors(Xs, X, Result). take_with_neighbors([X|Xs], Prev, [[Prev,X,Next]|Result]) :- take_with_neighbors(Xs, X, Result), ( Xs = [Next|_] ; Next = null ). take_with_neighbors([], _, []).
第二个谓词
get_adjacent_elements_helper([Primero|T], Result) :- get_adjacent_elements_helper(null, Primero, T, Result). get_adjacent_elements_helper(_, Primero, [], [Primero, null]) :- !. get_adjacent_elements_helper(Prev, Primero, [Next|T], Result) :- Result = [[Prev, Primero, Next] | Rest], get_adjacent_elements_helper(Primero, Next, T, Rest).
问题分析与修正
第一个谓词修正
问题根源:初始调用未处理第一个元素的前导null,直接从第二个元素开始生成三元组,漏掉了第一个边界三元组。
修正后的代码:
take_with_neighbors([X|Xs], Result) :- % 先生成第一个边界三元组:null + 当前元素 + 下一个元素(无则为null) (Xs = [Next|_] ; Next = null), Result = [[null, X, Next] | Rest], take_with_neighbors(Xs, X, Rest). take_with_neighbors([X|Xs], Prev, [[Prev,X,Next]|Result]) :- (Xs = [Next|_] ; Next = null), take_with_neighbors(Xs, X, Result). take_with_neighbors([], _, []).
第二个谓词修正
问题根源:递归终止子句错误返回二元组[Primero, null],而不是符合要求的三元组[Prev, Primero, null]。
修正后的代码:
get_adjacent_elements_helper([Primero|T], Result) :- get_adjacent_elements_helper(null, Primero, T, Result). % 终止时生成最后一个边界三元组:前元素 + 当前元素 + null get_adjacent_elements_helper(Prev, Primero, [], [[Prev, Primero, null]]) :- !. get_adjacent_elements_helper(Prev, Primero, [Next|T], Result) :- Result = [[Prev, Primero, Next] | Rest], get_adjacent_elements_helper(Primero, Next, T, Rest).
测试验证
调用修正后的谓词,输入[1,2,3,4],均会返回期望的输出:
[[null,1,2],[1,2,3],[2,3,4],[3,4,null]]
内容的提问来源于stack exchange,提问作者Lucas Rus Gallego
相关产品推荐
相关产品推荐

