Minizinc: Trivial equality unsatisfiable - constraints

I have the following minizinc model:
include "globals.mzn";
var 0..9: A_1_1;
var 0..9: A_2_1;
var 0..9: A_3_1;
constraint (A_3_1+A_2_1+A_1_1) = A_1_1;
solve satisfy;
The model should have the trivial solution 0=A_1_1=A_2_1=A_3_1. However, Gecode and other solvers report this as unsatisfiable.
What am I overlooking?

It seems to be a bug in MiniZinc when it translates the model to FlatZinc format. The message given is from MiniZinc:
WARNING: model inconsistency detected
test66.mzn:6:
in binary '=' operator expression
The generated FlatZinc file contains just this:
constraint bool_eq(false,true);
solve satisfy;
and that's why the FlatZinc solvers yield UNSATISFIABLE.
Interestingly, the following model works, using a temporary decision variable, T:
var 0..9: A_1_1;
var 0..9: A_2_1;
var 0..9: A_3_1;
var 0..9: T;
constraint
T = A_3_1 + A_2_1 + A_1_1 /\
T = A_1_1
;
solve satisfy;
The model then yield all 10 solutions with A_1_1 is assigned values from 0 to 9, A_2_1 = A_3_1 = 0, and T is assigned to same value as A_1_1.
However, if T is initialized with A_1_1 then UNSAT is thrown again:
var 0..9: T = A_1_1;
Update: One can note that the following constraint works, i.e. 2 * A_1_1 at the right side:
constraint A_3_1 + A_2_1 + A_1_1 = 2 * A_1_1;

Your constraint seems to be attempting to use assignment operator but the operation maynot be valid. You may try a = b+ c but b+c=a may not be allowed. Alternately you can try to use equality == operator to define your constraint which should work. I don't have program installed to validate but hope it gives you bit more insight to the issue. I would not be surprised if there is bug too, I would be keen to know.

Related

add constraint rule pyomo

I have been trying to create a constraint based on a certain condition that is the binary output of my function ('Check_Condition'). The type of constraint is just a basic "conflicting" constraint to avoid that two conflicting variables are chosen. The constraint seems to be ignored (I included the print statement as a check), although I do not get any error. Here is the code. I do not want to use nested loops as they considerably slow down the code. Thanks!
model.n = RangeSet(n_operations)
model.triangular = Set(within=model.n * model.n, filter=lambda i, j: j < i)
def con(model, i, j):
if Check_Condition(operations[i],operations[j])==1:
print('added constraint')
return model.x[i] + model.x[j] <= 1
else:
return Constraint.Skip
model.OverlapConst = Constraint(model.triangular, rule=con)

How to use predicate exactly in MiniZinc

New MiniZinc user here ... I'm having a problem understanding the syntax of the counting constraint:
predicate exactly(int: n, array[int] of var int: x, int: v)
"Requires exactly n variables in x to take the value v."
I want to make sure each column in my 10r x 30c array has at least one each of 1,2 and 3, with the remaining 7 rows equal to zero.
If i declare my array as
array[1..10,1..30] of var 0..3: s;
how can I use predicate exactly to populate it as I need? Thanks!
Well, the "exactly" constraint is not so useful here since you want at least one occurrence of 1, 2, and 3. It's better to use for example the count function:
include "globals.mzn";
array[1..10,1..30] of var 0..3: s;
solve satisfy;
constraint
forall(j in 1..30) (
forall(c in 1..3) (
count([s[i,j] | i in 1..10],c) >= 1
)
)
;
output [
if j = 1 then "\n" else " " endif ++
show(s[i,j])
| i in 1..10, j in 1..30
];
You don't have do to anything about 0 since the domain is 0..3 and all values that are not 1, 2, or 3 must be 0.
Another constraint is "at_least", see https://www.minizinc.org/2.0/doc-lib/doc-globals-counting.html .
If you don't have read the MiniZinc tutorial (https://www.minizinc.org/downloads/doc-latest/minizinc-tute.pdf), I strongly advice you to. The tutorial teaches you how to think Constraint Programming and - of course - MiniZinc.

power-of (pow) constraints in minizinc

Is there any way (direct or indirect) by which pow constraints can be supported in minizinc. Gecode supports the pow constraint with float and int variables, however Minizinc and FlatZinc does not support pow for variables. Minizinc and Flatzinc supports pow only for parameters to the model.
Any pointers on where to look to add support in MiniZinc to Flatzinc (mzn2fzn) parser to do this.
I want to have a constraint such as - " pow( 4, x ) == y " , i.e. 4^x == y .
What I know it's not possible in current version of MiniZinc to use pow/2 with decision variables.
Perhaps it would be enough to emulate it with "exists"? Here's a simple example (the domain of "i" is too large in this example).
var 0..10000: x;
var 0..10000: y;
solve satisfy;
constraint
exists(i in lb(x)..ub(x)) (
i = x /\
pow(4,i) = y
)
;
output [ show([x,y]) ];

Using solve and/or linsolve with the symbolic toolbox in R2010b

I asked a question a few days ago here and got an answer that seems like it would work- it involves using linsolve to find the solutions to a system of equations that are all modulo p, where p is a non-prime integer.
However, when I try to run the commands from the provided answer, or the linsolve help page, I get an error saying linsolve doesn't support arguments of type 'sym'. Is using linsolve with sym variables only possible in R2013b? I've also tried it with my school's copy, which is R2012b. Here is the code I'm attempting to execute (from the answer at the above link):
A = [0 5 4 1;1 7 0 2;8 1 0 2;10 5 1 0];
b = [2946321;5851213;2563617;10670279];
s = mod(linsolve(sym(A),sym(b)),8)
And the output is:
??? Undefined function or method linsolve' for input arguments of type 'sym'.
I've also tried to use the function solve for this, however even if I construct the equations represented by the matrices A and b above, I'm having issues. Here's what I'm attempting:
syms x y z q;
solve(5*y + 4*z + q == 2946321, x + 7*y + 2*q == 5851213, 8*x + y + 2*q == 2563617, 10*x + 5*y + z == 10670279,x,y,z,q)
And the output is:
??? Error using ==> char
Conversion to char from logical is not possible.
Error in ==> solve>getEqns at 169
vc = char(v);
Error in ==> solve at 67
[eqns,vars] = getEqns(varargin{:});
Am I using solve wrong? Should I just try to execute my code in R2013b to use linsolve with symbolic data types?
The Symbolic Math toolbox math toolbox has changed a lot (for the better) over the years. You might not have sym/linsolve, but does this work?:
s = mod(sym(A)\sym(b),8)
That will basically do the same thing. sym/linsolve just does some extra input checking and and rank calculation to mirror the capabilities of linsolve.
You're using solve correctly for current versions, but it looks like R2010b may not understand the == operator (sym/eq) in this context. You can use the old string format to specify your equations:
eqs = {'5*y + 4*z + q = 2946321',...
'x + 7*y + 2*q = 5851213',...
'8*x + y + 2*q = 2563617',...
'10*x + 5*y + z = 10670279'};
vars = {'x','y','z','q'};
[x,y,z,q] = solve(eqs{:},vars{:})

How to define a parameter recursively in GAMS?

I need to define a set of parameters that have a natural recursive relation.
Here is a MWE where I try to define the factorial function over a set of (nine) parameters S:
$title TitleOfProblem
set S / s1*s9 /;
alias(S, S1, S2);
set delta1(S1,S2);
delta1(S1,S2) = yes$(ord(S1) + 1 = ord(S2));
parameter f(S);
f(S) = 1$(ord(S) = 1) + (ord(S) * sum(S1$(delta1(S1, S)), f(S1)))$(ord(S) > 1);
display f;
"delta1" is a relation containing pairs of elements in sorted order that differ by 1. Logically, the definition of f matches the definition of the factorial function (for inputs 1 to 9), but GAMS doesn't seem to like that f is defined recursively. The output of GAMS compilation looks something like this:
f(S) = 1$(ord(S) = 1) + (ord(S) * sum(S1$(delta1(S1, S)), f(S1)))$(ord(S) > 1);
$141
141 Symbol neither initialized nor assigned
A wild shot: You may have spurious commas in the explanatory
text of a declaration. Check symbol reference list.
Question:
Is it possible to recursively define a parameter in GAMS? If not, what is a work-around?
(P.S. Someone with enough rep should create a tag "GAMS" and add it to this question.)
Someone showed me a solution for my example using a while loop. However, this solution is specific to factorial and does not generalize to an arbitrary recursive function.
$title factorial
set S / s1*s9 /;
parameter f(S);
parameter temp;
Loop(S,
temp=ord(s);
f(S)=ord(s);
While(temp > 1,
f(S) = f(S) * (temp-1);
temp = temp - 1;
);
);
display f;

Resources