I would like to get the non-discontinued intervals of variable domains in a prolog environment.
For example, I have a variable X which is constrained to take some values in its domain. Let's say X has an initial domain [0..20]
and it is constrained to (not) have 5
, 8
, 9
as values. So X has the new domain [0..4, 6, 7, 10..20]
. I would like to get non-discontinued intervals in this domain as a list [[0..4], [6,7], [10..20]]
.
In SWI-Prolog, using clpfd library when I run the following goal:
X in 0..20, X #\= 5, X #\= 8, X #\= 9.
Answer is:
X in 0..4\/6..7\/10..20.
So far so good. But I don't know how I can get this domain as a list of intervals. Is there a way to do it?
Solutions with other Prolog implementations and their respective CLP/FD libraries are also welcome.
Using fd_dom/2
, it is possible to get the domain of the variable. Then a DCG rule can be used to parse the domain which is in form of L1..U1\/L2..U2\/...
.
An example DCG rule for getting domain as a list of integers is given in SWI-Prolog manual (link). With a little modification it can be used to get the intervals:
dom_intervals(Dom, Intervals) :- phrase(dom_intervals1(Dom), Intervals).
dom_intervals1(I) --> {integer(I)}, [I].
dom_intervals1(L..U) --> [L..U].
dom_intervals1(D1 \/ D2) --> dom_intervals1(D1), dom_intervals1(D2).
Finally this query can be used:
X in 0..20, X #\= 5, X #\= 8, X #\= 9, fd_dom(X, D), dom_intervals(D, Intervals).
Though clpfd is not mentioned in YAP-prolog manual, it is possible to do the same with YAP-prolog too.