我可以为变量分配可能值的域,即:
Object.keys(this.state.days).filter(day => this.state.days[day])
是否有办法添加约束,以便变量可以接受值列表 在指定的域名? 对于最大3个元素列表的约束怎么样,其值在1..5范围内?
最后一个问题: 一个变量Y,它可以接受最多3个元素的列表,这些元素位于接受的值域中 变量X(为了它恰好是1..5)?
任何示例或提示如何开始构建这样的约束?
根据潜伏者:
?- X in 1..3, X #= 3.
X = 3.
只有最后一个关闭,应该是真的..让我改进其中一个约束:)
哈,这很有效:列出1到3个元素,而不只是3个元素。
?- 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.
CLP有多酷:)
现在又一个改进。如何使列表中的元素不重复?
答案 0 :(得分:2)
在CLP中,将约束与非确定性分开是很重要的 (搜索)。在基于Prolog的框架中,这种区别不是 在语言中很明显,这常常使初学者感到困惑。
采用像Prolog的 length / 2 这样的谓词:虽然逻辑上可以这样做 在CLP中被视为其参数值的“约束” 术语我们通常不称之为约束,因为它会 每当这些参数时,不确定地为其参数生成值 没有充分实例化。
我们对约束的期望行为更为被动:它 应该禁止其参数采用约束的值 语义不允许,但不主动生成任意有效 值。原因是我们通常想要建立一个整体 我们开始之前的约束网络(约束设置阶段) 探索不同的变量分配(搜索阶段)。
现在,约束求解器带有许多预定义约束 在一个特定的变量域上(最广泛使用的是约束 整数变量)。但是你想约束一个变量 来自列表的值。你没有现成的 实现,所以你可能想写自己的。 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)
根据潜伏者的说法,这似乎是一个List的解决方案,其中包含1个最多3个不可重复数字的元素,范围为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.
答案 2 :(得分:0)
这段代码毫无意义,实际上并没有使用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.