我可以将可能值的域分配给变量,即:
?- X in 1..3, X #= 3.
X = 3.
是否有一种方法来添加约束,以便变量可以接受值列表在指定的域中?限制最大3个要素的列表又如何,值在1..5?
范围内。最后一个问题:可以接受最多3个元素列表的可变y由变量x(为此,恰好是1..5(?
有任何例子或提示如何开始建立这样的约束?
根据Lurker:
?- L=[1,2,3], length(L, 3), L ins 1..5.
L = [1, 2, 3].
?- L=[1,2,3,4], length(L, 3), L ins 1..5.
false.
?- L=[1,2,6], length(L, 3), L ins 1..5.
false.
?- L=[1,2,5], length(L, 3), L ins 1..5.
L = [1, 2, 5].
?- L=[4,5], length(L, 3), L ins 1..5.
false.
只有最后一个是关闭的,应该是真的..让我完善其中一个约束:)
列表具有1到3个元素,而不是仅3个元素。
ha,这有效:
?- L=[4,5], X in 1..3, length(L, X), L ins 1..5.
L = [4, 5],
X = 2.
clp :(
有多酷现在再进行了一项完善。如何做到这一点,以使列表的元素不重复?
在CLP中(搜索(。在基于原始的框架中,这种区别不是在语言上很明显,这通常会使初学者感到困惑。
以prolog's length/2 之类的谓词:虽然从逻辑上讲可以在CLP中被视为对其参数值的"约束"术语我们通常不称其为约束,因为它会每当这些参数时,无确定地生成价值不够实例化。
我们期望从A 约束的行为更加被动:它应该禁止其参数以约束为价值语义不允许,但不能主动生成任意有效的值。这样做的原因是我们通常想设置一个整体启动之前,约束网络(约束设置阶段(探索不同的变量分配(搜索阶段(。
现在,约束求解器带有许多预定义的约束在某个变量域上(最广泛使用的是约束整数变量(。但是您想限制一个变量来自列表的域的值。您没有现成的为此实施,因此您可能需要编写自己的文章。Clp系统的支持使您有所不同,让您定义您的自己的约束。在以下示例中,我使用Eclipse的延迟条款功能,因为这可能是最可读的(免责声明:我个人参与了Eclipse(。
这是一个简单的长度约束。注意"延迟条款"如果任何参数都没有实验性,则导致谓词等待:
delay c_len(Xs, N) if var(Xs) ; var(N).
c_len([], 0).
c_len([_|Xs], N) :-
N1 is N-1,
c_len(Xs, N1).
这可以确保变量仅列出一定长度的列表:
?- c_len(Xs, 3), Xs = [_,_].
No (0.00s cpu)
?- c_len(Xs, 3), Xs = [_,_,_].
Xs = [_76, _78, _80]
Yes (0.00s cpu)
?- c_len(Xs, 3), Xs = [_,_,_,_].
No (0.00s cpu)
但是当没有足够的信息时,它会等待(如"延迟目标"消息(:
?- c_len(Xs, 3), Xs = [_,_|Tail].
Xs = [_64, _66|Tail]
There is 1 delayed goal.
Yes (0.00s cpu)
在最后一个示例中,我们看到了,尽管约束是正确的(在它不允许其参数无效的实例化的感觉,实际上可能会更聪明,并推断Tail
必须是长度1的列表。这是相当典型的:约束的操作行为(通常在实施之间被称为其繁殖强度(可能会有所不同。通常它反映了传播强度和计算复杂性。
这是一个更好的实现。它利用有限的域变量,还实现了您约束的要求列表元素的域:
:- use_module(library(ic)). % provides finite domain solver
delay bounded_list(Xs,_Lo,_Hi,Len) if var(Xs), var(Len).
bounded_list([],_Lo,_Hi, 0).
bounded_list([X|Xs], Lo, Hi, Len) :-
Len #> 0,
Lo #=< X, X #=< Hi,
Len1 #= Len-1,
bounded_list(Xs, Lo, Hi, Len1).
这可以强制执行您所需的列表属性(在此处长度1到3和值1至5之间:
?- N #:: 1..3, bounded_list(Xs,1,5,N), Xs = [1,2,3].
N = 3
Xs = [1, 2, 3]
Yes (0.00s cpu)
?- N #:: 1..3, bounded_list(Xs,1,5,N), Xs = [1,2,3,4].
No (0.00s cpu)
?- N #:: 1..3, bounded_list(Xs,1,5,N), Xs = [1].
N = 1
Xs = [1]
?- N #:: 1..3, bounded_list(Xs,1,5,N), Xs = [1,9].
No (0.00s cpu)
它也做了一些早期推论,例如用适当的整数域:
?- bounded_list(Xs, 1, 5, 3).
Xs = [_319{1..5}, _472{1..5}, _625{1..5}]
Yes (0.00s cpu, ...)
根据潜伏者,这似乎是列表的解决方案,其中1个最新的不可重复数字在1 .. 5:
范围内的元素。 ?- L=[4,1,Z], X in 1..3, length(L, X), L ins 1..5, all_distinct(L).
L = [4, 1, Z],
X = 3,
Z in 2..3/5,
all_distinct([4, 1, Z]).
?- L=[4,1,1], X in 1..3, length(L, X), L ins 1..5, all_distinct(L).
false.
?- L=[4,1,2], X in 1..3, length(L, X), L ins 1..5, all_distinct(L).
L = [4, 1, 2],
X = 3.
?- Lst=[3,1,5], Length in 1..3, length(Lst, Length), Lst ins 1..5, all_distinct(Lst).
Lst = [3, 1, 5],
Length = 3.
此代码没有任何意义,而实际上也没有使用CLPFD。
?- L=[4,5], X in 1..3, length(L, X), L ins 1..5.
L = [4, 5],
X = 2.
删除 X in 1..3
和 L ins 1..5
后,它可以轻松工作。
?- L=[4,5],length(L,X).
L = [4, 5],
X = 2.