Prolog中按第三参数升序、第二参数降序排序谓词的方法
Prolog 自定义排序实现你的需求
Prolog 确实有内置的排序功能,但要实现你需要的按第三个参数升序,相同则按第二个参数降序的自定义排序规则,得用 predsort/3 这个谓词——它允许你传入自定义的比较逻辑。
步骤1:定义自定义比较谓词
先写一个比较两个 pN 项的规则:
% 自定义比较规则:先按第三个参数升序,再按第二个参数降序 compare_terms(Order, p(_, B1, C1), p(_, B2, C2)) :- % 先比较第三个参数 compare(Cmp, C1, C2), ( % 如果第三个参数不同,直接用这个顺序 Cmp \= = -> Order = Cmp ; % 如果第三个参数相同,反转第二个参数的比较顺序(实现降序) compare(Order, B2, B1) ).
这里的 compare/3 是 Prolog 内置谓词,用来判断两个值的大小关系(返回 <、> 或 =)。当第三个参数相同时,我们通过比较 B2 和 B1 来实现第二个参数的降序排列。
步骤2:整理待排序列表并排序
把你的所有 pN 谓词放到一个列表里,然后用 predsort/3 排序:
% 待排序的原始列表 unsorted_list([p1(301, 1, 2), p2(201, 5, 2), p3(501, 1, 5), p4(401, 1, 4)]). % 执行排序 sorted_list(Sorted) :- unsorted_list(Unsorted), predsort(compare_terms, Unsorted, Sorted).
测试查询
在 Prolog 解释器里运行以下查询:
?- sorted_list(Sorted).
会得到你期望的结果:
Sorted = [p2(201, 5, 2), p1(301, 1, 2), p4(401, 1, 4), p3(501, 1, 5)].
动态收集谓词(可选)
如果你的 pN 谓词是动态添加的,不想硬编码列表,可以用 findall/3 自动收集所有符合条件的项:
% 自动收集所有 p1-p4 的事实 collect_terms(Terms) :- findall(Term, (member(Functor, [p1, p2, p3, p4]), Term =.. [Functor, A, B, C], call(Functor, A, B, C)), Terms). % 基于动态收集的列表排序 sorted_list_dynamic(Sorted) :- collect_terms(Unsorted), predsort(compare_terms, Unsorted, Sorted).
内容的提问来源于stack exchange,提问作者elfii
相关产品推荐
相关产品推荐

