1

I would like to shorten the following program. Just imaging there are tens of variables instead of just X and Y. The problem is that I need to define domain for each variable separately. I don't like it because it makes my program much longer and less transparent.

Input:

?- Dom1 in 0..2, Dom2 in 0..2, global_cardinality([X,Y], [0-Dom1,1-Dom2]), labeling([],[X,Y]).

Results:

X = 0,
Y = 0,
Dom1 = 2,
Dom2 = 0 ? ;
X = 0,
Y = 1,
Dom1 = 1,
Dom2 = 1 ? ;
X = 1,
Y = 0,
Dom1 = 1,
Dom2 = 1 ? ;
X = 1,
Y = 1,
Dom1 = 0,
Dom2 = 2 ? ;
no

At first I thought that I would solve it simply by writing:

?- Dom1 in 0..2, global_cardinality([X,Y], [0-Dom1,1-Dom1]), labeling([],[X,Y]).  

but it does not work because Dom1 unifies (is this the proper term for what happens in clpfd?) with one value and therefore the only results are:

X = 0,      
Y = 1,
Dom1 = 1 ? ;
X = 1,
Y = 0,
Dom1 = 1 ? ;
no

Thanks!

MartyIX
  • 27,828
  • 29
  • 136
  • 207

2 Answers2

3

Suppose that L = [X1,...,Xn] and you want every variable to be in 1..10.

Alternative 1, works for intervals only:

?- domain(L, 1, 10).

Alternative 2, works for domains that are not intervals too:

?- (foreach(X,L) do X in 1..10).
MartyIX
  • 27,828
  • 29
  • 136
  • 207
Mats Carlsson
  • 1,426
  • 7
  • 3
2

I can't understand your use case. The result you're after seems to be the same of

?- [X,Y] ins 0..1, labeling([], [X,Y]).
X = Y, Y = 0 ;
X = 0,
Y = 1 ;
X = 1,
Y = 0 ;
X = Y, Y = 1.

Your explanation

it does not work because Dom1 unifies (...) with one value

seems clear to me. Since Dom1 means 'number of occurrences' of key and there are 2 variables with 2 possible values (the 'keys' 0, 1), Dom1 must be 1.

CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • aha, `ins` shortens the program considerably but still I need many `Dom` variables. I guess it cannot be shorten further. I'm solving a timetabling problem and I need `global_cardinality` constrain to say that a time slot may contain either no lesson or one lesson at most. – MartyIX May 12 '13 at 19:19
  • 1
    Regarding time tabling, it may be better to use one finite domain variable for each lesson that is scheduled, and then require that these variables (which hold the time slot for each lesson) be `all_different/1`. This may reduce the number of variables, since empty time slots are then simply not assigned to any lesson, without requiring their own variables. – mat May 12 '13 at 21:24