Prolog中对两列表按二元函数合并是否存在内置系统函数?
问题描述
假设我们有两个列表 [1, 2, 3]、[3, 2, 1],需要生成第三个列表,其每个元素为对原两个列表对应位置元素应用二元函数的计算结果。
使用的二元函数定义如下:
f(x, y) = -1, if x < y; 0, if x = y; 1 if x > y.
按上述规则,示例输入对应的输出为 [-1, 0, 1]。
自行实现的代码如下:
f(A, B, C) :- ( A < B -> C = -1 ; A =:= B -> C = 0 ; C = 1 ). zip([A], [B], [C]) :- f(A, B, C). zip([A | T1], [B | T2], [C | T]) :- f(A, B, C), zip(T1, T2, T).
测试运行结果符合预期:
?- zip([1,2,3], [3,2,1], X). X = [-1, 0, 1] .
提问:这类通用操作属于重复造轮子,请问Prolog中是否存在对应的系统内置函数可以直接实现该功能?
解答
主流Prolog实现(如SWI-Prolog)都内置了maplist/N系列高阶谓词,可以直接替代你自行实现的zip逻辑,无需重复造轮子。
maplist/3 正好接收一个三元谓词作为第一个入参,后跟两个等长的输入列表、一个输出列表,会自动对两个输入列表的对应位置元素调用传入的三元谓词,将输出结果存入输出列表的对应位置,逻辑和你手写的zip完全一致。
你可以直接用如下代码实现需求:
f(A, B, C) :- ( A < B -> C = -1 ; A =:= B -> C = 0 ; C = 1 ). % 直接调用内置maplist即可 ?- maplist(f, [1,2,3], [3,2,1], X). X = [-1, 0, 1] .
补充说明:
- 如果你使用的Prolog版本支持lambda表达式,甚至可以不用单独定义f谓词,直接在maplist中写入匿名函数实现对应逻辑,进一步简化代码
maplist有多个变种,包含maplist/2、maplist/4等,可以适配不同参数数量的谓词,支持更多列表同时映射的场景
内容的提问来源于stack exchange,提问作者user4035
相关产品推荐
相关产品推荐

