Prolog递归处理列表时如何获取初始原始列表的未修改副本?
核心问题根源
你现在的写法无法拿到递归启动前原始列表的原因有两点:
- 你在每层递归调用内部做的
copy_term只能拿到当前递归层的输入子列表,而非最顶层启动递归时的完整原始列表 - 如果你拷贝时
List未完全实例化,后续对List的合一操作如果存在变量共享,也可能导致拷贝结果不符合预期
可行实现方案
通过新增辅助谓词的方式将顶层原始列表作为固定参数全程透传即可,Prolog变量具备不可变特性,透传的原始列表不会受到递归过程中拆分、合并操作的影响,修改后代码如下:
% 顶层调用谓词,对外接口保持和原有逻辑一致 mSort(Sorted, List) :- % 调用递归辅助谓词,传入最顶层的原始列表 mSort_aux(Sorted, List, List). % 递归终止条件1:空列表直接返回 mSort_aux([], [], _OriginalList). % 递归终止条件2:单元素列表直接返回 mSort_aux([X], [X], _OriginalList). % 递归辅助谓词,第三个参数固定为最顶层原始列表,全程透传不修改 mSort_aux(Sorted, List, OriginalList) :- length(List, N), N > 1, FLength is N // 2, SLength is N - FLength, length(FUnsorted, FLength), length(SUnsorted, SLength), append(FUnsorted, SUnsorted, List), % 递归调用时继续传递原始列表 mSort_aux(FSorted, FUnsorted, OriginalList), mSort_aux(SSorted, SUnsorted, OriginalList), combine(Sorted, FSorted, SSorted), % 直接使用透传的原始列表调用打印方法 printPerMerge(Sorted, OriginalList), write('Sorted '), tab(1), format('~w ',[Sorted]), nl.
补充说明
如果你的需求是打印当前合并步骤对应的父层级未排序列表,而非全局最原始列表,可以调整辅助谓词的透传逻辑,将每层拆分前的列表作为参数传递到当前层的合并步骤即可。
内容的提问来源于stack exchange,提问作者ina
相关产品推荐
相关产品推荐

