在 CLP(FD) 中,我们经常需要声明:“这是整数和有限域变量的列表(有时:strictly) 升序/降序。”
是否有任何 CLP(FD) 系统为此任务提供通用(可参数化)内置约束?
SWI-Prolog 提供了一个称为chain/2
,这与我正在寻找的类似。然而,这个名称有点过于具体,无法涵盖约束可以描述的所有关系(例如:#<
不是部分命令,但可以接受chain/2
,导致序列(视为一组整数)不再算作数学顺序理论中定义的链)。因此,该名称并没有完全描述约束实际实现的内容。
请给出最一般的相对于通常的二元 CLP(FD) 约束的定义 — 或至少包含的合适子集#<
, #>
, #=<
and #>=
— 包括根据约束定义的代数结构的专有名称。施加的条件是约束描述actual在文献中具有适当名称的数学结构。
首先,考虑使用 SICStus Prolog 或 SWI:
:- use_module(library(clpfd)).
connex(Relation_2, List) :-
connex_relation(Relation_2),
connex_(List, Relation_2).
connex_relation(#=).
connex_relation(#<).
connex_relation(#=<).
connex_relation(#>).
connex_relation(#>=).
connex_([], _).
connex_([L|Ls], Relation_2) :-
foldl(adjacent(Relation_2), Ls, L, _).
adjacent(Relation_2, X, Prev, X) :- call(Relation_2, Prev, X).
案例示例:
?- connex(#<, [A,B,C]).
A#=<B+-1,
B#=<C+-1.
?- connex(#=, [A,B,C]).
A = B, B = C,
C in inf..sup.
?- maplist(connex(#<), [[A,B],[C,D]]).
A#=<B+-1,
C#=<D+-1.
请注意,甚至可以允许#\=
,因为该关系将still描述数学顺序理论中已知的连接。因此,上面的代码对于通常的二进制 CLP(FD) 约束来说并不是最通用的。