clpfd - 约束域的上层绑定是元素列表的最大值

时间:2015-04-14 13:08:50

标签: prolog clpfd

给出以下代码:

solve(G,L) :-
    G = [A0,B0,C0,D0],
    L = [A1,B1,C1,D1,A2,B2,C2,D2,A3,B3,C3,D3,A4,B4,C4,D4],
    G ins 0..4,
    L ins 0..max(G).

我想约束L不包含高于G中包含的最大值的值,但是在使用此语法时我得到“域错误”。还有另一种表达方式吗?

1 个答案:

答案 0 :(得分:2)

基本上你是在正确的轨道上。但是L ins 0..max(G)不起作用,因为您传递给ins/2的边界必须是整数或infsup

SWI-Prolog clpfd manual page支持max 有限域算术表达式,因此我们首先声明MaxGA0B0C0D0的最大值。然后我们声明MaxG大于或等于列表L中的每个项目。

全部放在一起:

:- use_module(library(clpfd)).

gte_than(X,Y) :-
    X #>= Y.

solve(G,L) :-
    G = [A0,B0,C0,D0],
    L = [A1,B1,C1,D1,A2,B2,C2,D2,A3,B3,C3,D3,A4,B4,C4,D4],
    G ins 0..4,
    L ins 0..sup,
    MaxG #= max(max(A0,B0),max(C0,D0)),
    maplist(gte_than(MaxG),L).

以下是一些问题:

?- solve([0,1,2,1], [0,1,2,1,1,2,1,2,1,0,1,2,1,1,1,2]).
true.

?- solve([0,1,2,1], [0,3,2,1,1,2,1,2,1,0,1,2,1,1,1,2]).
false.

?- solve([0,3,2,1], [0,3,2,1,1,2,1,2,1,0,1,2,1,1,1,2]).
true.

?- solve([0,3,2,1], [0,3,2,1,1,2,4,4,1,0,1,2,1,1,1,2]).
false.

?- solve([4,3,2,1], [0,3,2,1,1,2,4,4,1,0,1,2,1,1,1,2]).
true.

附注:SICStus Prolog有一个我们可以在这里使用的名为maximum/2的专用arithmetic constraint,但是在带有SWI-Prolog的clpfd中,这个约束不可用。