You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 23:48:21