Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prolog: Constraining the elements of a list to be within a range

Are there any ways to constrain the elements of a list to be within a range, something that would look more like 1-6, instead of using between(1, 6, X)?

like image 716
Liu Junhan Avatar asked Nov 21 '25 09:11

Liu Junhan


2 Answers

The clpfd library, has an ins/2 predicate, where you can specify - for a list of variables - the range of the elements.

Like:

all_between(Low, High, Vars) :-
    Vars ins Low..High.

When calling all_between(1,6,[X1,X2,X3]). we get:

X1 in 1..6,
X2 in 1..6,
X3 in 1..6.

In case we want to enumerate over the elements, we can use label(L). as well, to assign values:

all_between_enumerate(Low, High, Vars) :-
    Vars ins Low..High,
    label(Vars).

For all_between_enumerate(1,2,[X1,X2,X3]). this generates:

?- all_between_enumerate(1,2,[X1,X2,X3]).
X1 = X2, X2 = X3, X3 = 1 ;
X1 = X2, X2 = 1,
X3 = 2 ;
X1 = X3, X3 = 1,
X2 = 2 ;
X1 = 1,
X2 = X3, X3 = 2 ;
X1 = 2,
X2 = X3, X3 = 1 ;
X1 = X3, X3 = 2,
X2 = 1 ;
X1 = X2, X2 = 2,
X3 = 1 ;
X1 = X2, X2 = X3, X3 = 2.

In case you already added constraints to the variables, like X1 #< X3, these are taken into account as well:

?- X1 #< X3, all_between_enumerate(1,2,[X1,X2,X3]).
X1 = X2, X2 = 1,
X3 = 2 ;
X1 = 1,
X3 = X2, X2 = 2.
like image 188
Willem Van Onsem Avatar answered Nov 23 '25 00:11

Willem Van Onsem


You could use library CLPFD :

:- use_module(library(clpfd)).

constraint_list([]).
constraint_list([H|T]):-H in 1..6 ,label([H]),constraint_list(T).

Examples:

?- constraint_list([X1,X2]).
X1 = X2, X2 = 2 ;
X1 = 2,
X2 = 3 ;
X1 = 2,
X2 = 4 ;
X1 = 2,
X2 = 5 ;
X1 = 3,
X2 = 2 ;
X1 = X2, X2 = 3 ;
X1 = 3,
X2 = 4 ;
X1 = 3,
X2 = 5 ;
X1 = 4,
X2 = 2 ;
X1 = 4,
X2 = 3 ;
X1 = X2, X2 = 4 ;
X1 = 4,
X2 = 5 ;
X1 = 5,
X2 = 2 ;
X1 = 5,
X2 = 3 ;
X1 = 5,
X2 = 4 ;
X1 = X2, X2 = 5.

?- L=[1,2,3] ,constraint_list(L).
false.

?- L=[2,2,3] ,constraint_list(L).
L = [2, 2, 3].

?- constraint_list(L).
L = [] ;
L = [2] ;
L = [2, 2] ;
L = [2, 2, 2] ;
L = [2, 2, 2, 2] ;
L = [2, 2, 2, 2, 2] ;
L = [2, 2, 2, 2, 2, 2] ;
L = [2, 2, 2, 2, 2, 2, 2] ;
L = [2, 2, 2, 2, 2, 2, 2, 2] ;
L = [2, 2, 2, 2, 2, 2, 2, 2, 2] ;
L = [2, 2, 2, 2, 2, 2, 2, 2, 2|...] ;
L = [2, 2, 2, 2, 2, 2, 2, 2, 2|...] ;
L = [2, 2, 2, 2, 2, 2, 2, 2, 2|...] ;
L = [2, 2, 2, 2, 2, 2, 2, 2, 2|...] ;
L = [2, 2, 2, 2, 2, 2, 2, 2, 2|...] .
    ... (and goes on)
like image 45
coder Avatar answered Nov 22 '25 22:11

coder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!