【发布时间】:2017-10-09 04:33:10
【问题描述】:
有没有办法将列表的元素限制在一个范围内,看起来更像1-6,而不是使用between(1, 6, X)?
【问题讨论】:
-
我们讨论的是整数还是浮点数?
标签: prolog range constraint-programming clpfd
有没有办法将列表的元素限制在一个范围内,看起来更像1-6,而不是使用between(1, 6, X)?
【问题讨论】:
标签: prolog range constraint-programming clpfd
clpfd 库有一个 ins/2 谓词,您可以在其中指定 - 对于变量列表 - 元素的范围。
喜欢:
all_between(Low, High, Vars) :-
Vars ins Low..High.
当调用all_between(1,6,[X1,X2,X3]). 时,我们得到:
X1 in 1..6,
X2 in 1..6,
X3 in 1..6.
如果我们想枚举元素,我们也可以使用label(L). 来赋值:
all_between_enumerate(Low, High, Vars) :-
Vars ins Low..High,
label(Vars).
对于all_between_enumerate(1,2,[X1,X2,X3]).,这会生成:
?- all_between_enumerate(1,2,[X1,X2,X3]).
X1 = X2, X2 = X3, X3 = 1 ;
X1 = X2, X2 = 1,
X3 = 2 ;
X1 = X3, X3 = 1,
X2 = 2 ;
X1 = 1,
X2 = X3, X3 = 2 ;
X1 = 2,
X2 = X3, X3 = 1 ;
X1 = X3, X3 = 2,
X2 = 1 ;
X1 = X2, X2 = 2,
X3 = 1 ;
X1 = X2, X2 = X3, X3 = 2.
如果您已经为变量添加了约束,例如X1 #< X3,这些也会被考虑在内:
?- X1 #< X3, all_between_enumerate(1,2,[X1,X2,X3]).
X1 = X2, X2 = 1,
X3 = 2 ;
X1 = 1,
X3 = X2, X2 = 2.
【讨论】:
您可以使用库 CLPFD:
:- use_module(library(clpfd)).
constraint_list([]).
constraint_list([H|T]):-H in 1..6 ,label([H]),constraint_list(T).
例子:
?- constraint_list([X1,X2]).
X1 = X2, X2 = 2 ;
X1 = 2,
X2 = 3 ;
X1 = 2,
X2 = 4 ;
X1 = 2,
X2 = 5 ;
X1 = 3,
X2 = 2 ;
X1 = X2, X2 = 3 ;
X1 = 3,
X2 = 4 ;
X1 = 3,
X2 = 5 ;
X1 = 4,
X2 = 2 ;
X1 = 4,
X2 = 3 ;
X1 = X2, X2 = 4 ;
X1 = 4,
X2 = 5 ;
X1 = 5,
X2 = 2 ;
X1 = 5,
X2 = 3 ;
X1 = 5,
X2 = 4 ;
X1 = X2, X2 = 5.
?- L=[1,2,3] ,constraint_list(L).
false.
?- L=[2,2,3] ,constraint_list(L).
L = [2, 2, 3].
?- constraint_list(L).
L = [] ;
L = [2] ;
L = [2, 2] ;
L = [2, 2, 2] ;
L = [2, 2, 2, 2] ;
L = [2, 2, 2, 2, 2] ;
L = [2, 2, 2, 2, 2, 2] ;
L = [2, 2, 2, 2, 2, 2, 2] ;
L = [2, 2, 2, 2, 2, 2, 2, 2] ;
L = [2, 2, 2, 2, 2, 2, 2, 2, 2] ;
L = [2, 2, 2, 2, 2, 2, 2, 2, 2|...] ;
L = [2, 2, 2, 2, 2, 2, 2, 2, 2|...] ;
L = [2, 2, 2, 2, 2, 2, 2, 2, 2|...] ;
L = [2, 2, 2, 2, 2, 2, 2, 2, 2|...] ;
L = [2, 2, 2, 2, 2, 2, 2, 2, 2|...] .
... (and goes on)
【讨论】: