如何在Prolog中对输出进行排序?

如何在Prolog中对输出进行排序?,prolog,prolog-toplevel,Prolog,Prolog Toplevel,我有以下谓词: soln(L,M,O,R,S,V) :- permutation([L,M,O,R,S,V],[1,2,3,4,5,6]), R=\=S+1, R=\=S-1, M=:=L+1, O>M, O<S. 然而,对我来说更有用的是输出,其中变量根据其值进行排序;使用上一个例子,像[L,M,O,R,V,S],…这样的东西是理想的 我希望能够在REPL和独立脚本中实现这一点。如果要根据名称的值对名称进行排序,必须跟踪变量与其名称

我有以下谓词:

soln(L,M,O,R,S,V) :-
    permutation([L,M,O,R,S,V],[1,2,3,4,5,6]),
    R=\=S+1,
    R=\=S-1,
    M=:=L+1,
    O>M,
    O<S.
然而,对我来说更有用的是输出,其中变量根据其值进行排序;使用上一个例子,像
[L,M,O,R,V,S],…
这样的东西是理想的


我希望能够在REPL和独立脚本中实现这一点。

如果要根据名称的值对名称进行排序,必须跟踪变量与其名称之间的关联

这是因为您在源代码中看到的变量名在Prolog程序中是不可访问的,因此您必须以在Prolog中可访问的方式跟踪这些名称

一种方法是跟踪
变量名
形式的列表。这样,当变量绑定到一个值时,您仍然知道它的预期名称

因此,我建议稍微重写以下内容:

:- use_module(library(clpfd)). solution(Pairs) :- Vs = [L,M,O,R,S,_V], Names = [l,m,o,r,s,v], pairs_keys_values(Pairs, Vs, Names), R #\= S+1, R #\= S-1, M #= L+1, O #> M, O #< S, Vs ins 1..6. 现在,要根据这些变量的值对名称进行排序,请使用ISOpredicate
keysort/2
,它根据标记(即它们的第一个组件)对配对进行排序:

?- solution(Pairs0), pairs_keys_values(Pairs0, Vs0, Names0), label(Vs0), keysort(Pairs0, Pairs), pairs_values(Pairs, Names). Pairs0 = [1-l, 2-m, 3-o, 1-r, 4-s, 1-v], Vs0 = [1, 2, 3, 1, 4, 1], Names0 = [l, m, o, r, s, v], Pairs = [1-l, 1-r, 1-v, 2-m, 3-o, 4-s], Names = [l, r, v, m, o, s] ; Pairs0 = [1-l, 2-m, 3-o, 1-r, 4-s, 2-v], Vs0 = [1, 2, 3, 1, 4, 2], Names0 = [l, m, o, r, s, v], Pairs = [1-l, 1-r, 2-m, 2-v, 3-o, 4-s], Names = [l, r, m, v, o, s] ; Pairs0 = [1-l, 2-m, 3-o, 1-r, 4-s, 3-v], Vs0 = [1, 2, 3, 1, 4, 3], Names0 = [l, m, o, r, s, v], Pairs = [1-l, 1-r, 2-m, 3-o, 3-v, 4-s], Names = [l, r, m, o, v, s] ; Pairs0 = [1-l, 2-m, 3-o, 1-r, 4-s, 4-v], Vs0 = [1, 2, 3, 1, 4, 4], Names0 = [l, m, o, r, s, v], Pairs = [1-l, 1-r, 2-m, 3-o, 4-s, 4-v], Names = [l, r, m, o, s, v] ; etc. ?溶液(Pairs0), 配对\u键\u值(配对0、Vs0、名称0), 标签(Vs0), 键端口(成对0,成对), 成对值(成对、名称)。 Pairs0=[1-l,2-m,3-o,1-r,4-s,1-v], Vs0=[1,2,3,1,4,1], 名称0=[l,m,o,r,s,v], 配对=[1-l,1-r,1-v,2-m,3-o,4-s], 名称=[l,r,v,m,o,s]; Pairs0=[1-l,2-m,3-o,1-r,4-s,2-v], Vs0=[1,2,3,1,4,2], 名称0=[l,m,o,r,s,v], 配对=[1-l,1-r,2-m,2-v,3-o,4-s], 名称=[l,r,m,v,o,s]; Pairs0=[1-l,2-m,3-o,1-r,4-s,3-v], Vs0=[1,2,3,1,4,3], 名称0=[l,m,o,r,s,v], 配对=[1-l,1-r,2-m,3-o,3-v,4-s], 名称=[l,r,m,o,v,s]; Pairs0=[1-l,2-m,3-o,1-r,4-s,4-v], Vs0=[1,2,3,1,4,4], 名称0=[l,m,o,r,s,v], 配对=[1-l,1-r,2-m,3-o,4-s,4-v], 名称=[l,r,m,o,s,v]; 等
如果要根据变量的值对名称进行排序,则必须跟踪变量与其名称之间的关联

这是因为您在源代码中看到的变量名在Prolog程序中是不可访问的,因此您必须以在Prolog中可访问的方式跟踪这些名称

一种方法是跟踪
变量名
形式的列表。这样,当变量绑定到一个值时,您仍然知道它的预期名称

因此,我建议稍微重写以下内容:

:- use_module(library(clpfd)). solution(Pairs) :- Vs = [L,M,O,R,S,_V], Names = [l,m,o,r,s,v], pairs_keys_values(Pairs, Vs, Names), R #\= S+1, R #\= S-1, M #= L+1, O #> M, O #< S, Vs ins 1..6. 现在,要根据这些变量的值对名称进行排序,请使用ISOpredicate
keysort/2
,它根据标记(即它们的第一个组件)对配对进行排序:

?- solution(Pairs0), pairs_keys_values(Pairs0, Vs0, Names0), label(Vs0), keysort(Pairs0, Pairs), pairs_values(Pairs, Names). Pairs0 = [1-l, 2-m, 3-o, 1-r, 4-s, 1-v], Vs0 = [1, 2, 3, 1, 4, 1], Names0 = [l, m, o, r, s, v], Pairs = [1-l, 1-r, 1-v, 2-m, 3-o, 4-s], Names = [l, r, v, m, o, s] ; Pairs0 = [1-l, 2-m, 3-o, 1-r, 4-s, 2-v], Vs0 = [1, 2, 3, 1, 4, 2], Names0 = [l, m, o, r, s, v], Pairs = [1-l, 1-r, 2-m, 2-v, 3-o, 4-s], Names = [l, r, m, v, o, s] ; Pairs0 = [1-l, 2-m, 3-o, 1-r, 4-s, 3-v], Vs0 = [1, 2, 3, 1, 4, 3], Names0 = [l, m, o, r, s, v], Pairs = [1-l, 1-r, 2-m, 3-o, 3-v, 4-s], Names = [l, r, m, o, v, s] ; Pairs0 = [1-l, 2-m, 3-o, 1-r, 4-s, 4-v], Vs0 = [1, 2, 3, 1, 4, 4], Names0 = [l, m, o, r, s, v], Pairs = [1-l, 1-r, 2-m, 3-o, 4-s, 4-v], Names = [l, r, m, o, s, v] ; etc. ?溶液(Pairs0), 配对\u键\u值(配对0、Vs0、名称0), 标签(Vs0), 键端口(成对0,成对), 成对值(成对、名称)。 Pairs0=[1-l,2-m,3-o,1-r,4-s,1-v], Vs0=[1,2,3,1,4,1], 名称0=[l,m,o,r,s,v], 配对=[1-l,1-r,1-v,2-m,3-o,4-s], 名称=[l,r,v,m,o,s]; Pairs0=[1-l,2-m,3-o,1-r,4-s,2-v], Vs0=[1,2,3,1,4,2], 名称0=[l,m,o,r,s,v], 配对=[1-l,1-r,2-m,2-v,3-o,4-s], 名称=[l,r,m,v,o,s]; Pairs0=[1-l,2-m,3-o,1-r,4-s,3-v], Vs0=[1,2,3,1,4,3], 名称0=[l,m,o,r,s,v], 配对=[1-l,1-r,2-m,3-o,3-v,4-s], 名称=[l,r,m,o,v,s]; Pairs0=[1-l,2-m,3-o,1-r,4-s,4-v], Vs0=[1,2,3,1,4,4], 名称0=[l,m,o,r,s,v], 配对=[1-l,1-r,2-m,3-o,4-s,4-v], 名称=[l,r,m,o,s,v]; 等