In CLP(FD), we frequently need to state: "This is a list of integers and finite domain variables in (sometimes: strictly) ascending/descending order."
Is there any CLP(FD) system that provides a general (parametrisable) built-in constraint for this task?
SWI-Prolog provides a constraint called chain/2
, which is similar to what I am looking for. However, the name is slightly too specific to encompass all relations that the constraint can describe (example: #<
is not a partial order but admissible in chain/2
, leading to the sequence — taken as a set of integers — no longer counting as a chain as defined in mathematical order-theory). Hence, the name does not fully describe what the constraint actually implements.
Please give the most general definition with respect to the usual binary CLP(FD) constraints — or a suitable subset that contains at least #<
, #>
, #=<
and #>=
— including the proper name according to the algebraic structure the constraint defines. The condition imposed is that the constraint describe an actual mathematical structure that has a proper name in the literature.
As a start, consider with SICStus Prolog or 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).
Sample cases:
?- 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.
Notice that it would even be admissible to allow #\=
, because the relation would still describe a connex as known in mathematical order-theory. Hence, the code above is not most general with respect to the usual binary CLP(FD) constraints.
Hoogle was not very useful, but Hayoo is!
foldcmpl
so this is a special form of fold for a list, but it does not apply
length list
times but one time less.isSortedBy
is not entirely general in its name, but in its signature. Maybe insisting on the most general name is not that helpful. Otherwise we just have entities all over?
The definition reads:
Maybe:
all_adjacent_pairs(R_2, Xs)
. which sounds a bit after having a looping construct that hasadjacent_pair
as some modifier.