如果要根据值对名称进行排序,则必须跟踪变量与其名称之间的关联。
这是因为您在源代码中看到的变量名称在 Prolog 程序中是不可访问的,因此您必须以在 Prolog 中可访问的方式跟踪名称。
一种方法是跟踪表单对Variable-Name
的列表。这样,当变量绑定到一个值时,您仍然知道它的预期 名称。
因此,我建议进行以下轻微的重写:
:- 使用模块(库(clpfd))。
解决方案(对):-
Vs = [L,M,O,R,S,_V],
名称 = [l,m,o,r,s,v],
pair_keys_values(Pairs, Vs, Names),
R #\= S+1,
R #\= S-1,
M #= L+1,
O #> M,
O #< S,
VS 1..6。
请注意,我现在使用atom l
、m
等o
来表示变量的名称,并且我现在对pair进行推理。此外,我冒昧地用约束来表达这一切,因此我们从约束传播中受益,而不必尝试每个排列。使用约束,Prolog 引擎可以修剪搜索空间的重要部分,甚至无需尝试。我_V
用来表示变量V
,因为在其他任何地方都没有提到这个变量, V
因此使用会导致单例警告。
我们已经可以尝试了:
?- 解决方案(对),
pair_keys_values(Pairs, Vs, Names),
标签(Vs)。
对 = [1-l, 2-m, 3-o, 1-r, 4-s, 1-v],
Vs = [1, 2, 3, 1, 4, 1],
名称 = [l, m, o, r, s, v] ;
对 = [1-l, 2-m, 3-o, 1-r, 4-s, 2-v],
Vs = [1, 2, 3, 1, 4, 2],
名称 = [l, m, o, r, s, v] ;
对 = [1-l, 2-m, 3-o, 1-r, 4-s, 3-v],
Vs = [1, 2, 3, 1, 4, 3],
名称 = [l, m, o, r, s, v] ;
等等
现在,要根据这些变量的值对名称进行排序keysort/2
,请使用 ISO 谓词,它根据 键对对进行排序,即它们的第一个组件:
?- 解决方案(Pairs0),
pair_keys_values(Pairs0, Vs0, Names0),
标签(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] ;
等等