I am asking this question in context of sat solver.
Lets suppose I have 100 integer variables x1, x2, x3 ... x100 which are assigned a value randomly between 1 to N. I want to make sure that at least one variable of x1 to x100 should have each of value from 1 to N.
Now I would like to encode this problem in sat solver constraints. Since while writing the constraints I don’t know the value N, it is difficult to me to code as below –
(assert (x1 = 0 or x2 = 0 or ... x100 = 0))
(assert (x1 = 1 or x2 = 1 or ... x100 = 1))
(assert (x1 = 2 or x2 = 2 or ... x100 = 2))
...
(assert (x1 = N or x2 = N or ... x100 = N))
Lets say, that at the end, I assert the value of N to be 2, then the above constraints will not work. Further to that, I would not like to use arrays or un-interpreted functions for performance reasons.
Update :
In Short, the constraints are as follows –
- N < 100
- (Lets say N = 20), then there are 20 variables which maybe be any of them from x_1 to x_100 which are distinct. So this constraint will ensure that there will be assignment of at least one variable for each of values from 1 to N.
- The values of remaining variables (100-N) can overlap each other.
Can anyone give me some suggestions?
How about combining Kyle’s answer with distinct, for up to n of the x_i variables (randomly chosen)?
This will give a model like (for N = 50 and 100 x_i variables):
Here’s a Z3Py script accomplishing this, assuming the first N indices can be constrained, instead of random ones (and using a function for x instead of constants so it was faster to write): http://rise4fun.com/Z3Py/M3TG
Next is code for doing this for a random set of indices, but you can’t run this on Z3Py@Rise, because it does not allow using imports, so you’ll have to run it locally.
(Beware if you make this query unsat, it may timeout.)