0

我有以下谓词:

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.

当我从 REPL 调用它时,它会打印出正确的答案:

?- soln(L,M,O,R,S,V).
L = 1,
M = 2,
O = 3,
R = 4,
S = 6,
V = 5 ;
L = 1,
M = 2,
O = 3,
R = 6,
S = 4,
V = 5 .

但是,对我来说更有用的是根据变量的值对变量进行排序的输出;使用前面的例子,类似的东西[L,M,O,R,V,S], [L,M,O,S,V,R], ...是理想的。

我希望能够在 REPL 和独立脚本中执行此操作。

4

1 回答 1

3

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

这是因为您在源代码中看到的变量名称在 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 lmo来表示变量的名称,并且我现在对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] ;
等等
于 2017-01-22T11:07:55.653 回答