I am building a CPLEX OPL model. I found error: Decision variable (or expression) "x" not allowed.
Here x is a decision variable and shown below:
dvar boolean x[N][CR];
Constraint:
forall(i in N, j in CR :x[i][j]==1) {
(j%2 == 0) => r[i] == 1;
(j%2 == 1) => r[i] == 0;
}
How I write this constraint correctly. Thanks in advance
range N=1..2;
range CR=1..3;
dvar boolean x[N][CR];
dvar boolean r[N];
subject to
{
forall(i in N, j in CR ) {
((j%2 == 0) && (x[i][j]==1)) => (r[i] == 1);
((j%2 == 1) && (x[i][j]==1)) => (r[i] == 0);
}
}
works fine
Related
I am learning Dafny, attempting to write a specification for the hamming weight problem, aka the number of 1 bits in a number. I believe I have gotten the specification correct, but it still doesn't verify. For speed of verification I limited it to 8 bit numbers;
problem definition: https://leetcode.com/problems/number-of-1-bits/
function method twoPow(x: bv16): bv16
requires 0 <= x <= 16
{
1 << x
}
function method oneMask(n: bv16): bv16
requires 0 <= n <= 16
ensures oneMask(n) == twoPow(n)-1
{
twoPow(n)-1
}
function countOneBits(n:bv8): bv8 {
if n == 0 then 0 else (n & 1) + countOneBits(n >> 1)
}
method hammingWeight(n: bv8) returns (count: bv8 )
ensures count == countOneBits(n)
{
count := 0;
var i := 0;
var n' := n;
assert oneMask(8) as bv8 == 255; //passes
while i < 8
invariant 0 <= i <= 8
invariant n' == n >> i
invariant count == countOneBits(n & oneMask(i) as bv8);
{
count := count + n' & 1;
n' := n' >> 1;
i := i + 1;
}
}
I have written the same code in javascript to test the behavior and example the invariant values before and after the loop. I don't seen any problems.
function twoPow(x) {
return 1 << x;
}
function oneMask(n) {
return twoPow(n)-1;
}
function countOneBits(n) {
return n === 0 ? 0 : (n & 1) + countOneBits(n >> 1)
}
function hammingWeight(n) {
if(n < 0 || n > 256) throw new Error("out of range")
console.log(`n: ${n} also ${n.toString(2)}`)
let count = 0;
let i = 0;
let nprime = n;
console.log("beforeloop",`i: ${i}`, `n' = ${nprime}`, `count: ${count}`, `oneMask: ${oneMask(i)}`, `cb: ${countOneBits(n & oneMask(i))}`)
console.log("invariants", i >= 0 && i <= 8, nprime == n >> i, count == countOneBits(n & oneMask(i)));
while (i < 8) {
console.log("");
console.log('before',`i: ${i}`, `n' = ${nprime}`, `count: ${count}`, `oneMask: ${oneMask(i)}`, `cb: ${countOneBits(n & oneMask(i))}`)
console.log("invariants", i >= 0 && i <= 8, nprime == n >> i, count == countOneBits(n & oneMask(i)));
count += nprime & 1;
nprime = nprime >> 1;
i++;
console.log('Afterloop',`i: ${i}`, `n' = ${nprime}`, `count: ${count}`, `oneMask: ${oneMask(i)}`, `cb: ${countOneBits(n & oneMask(i))}`)
console.log("invariants", i >= 0 && i <= 8, nprime == n >> i, count == countOneBits(n & oneMask(i)));
}
return count;
};
hammingWeight(128);
All invariants evaluate as true. I must be missing something. it says invariant count == countOneBits(n & oneMask(i) as bv8); might not be maintained by the loop. Running the javascript shows that they are all true. Is it due to the cast of oneMask to bv8?
edit:
I replaced the mask function with one that didn't require casting and that still not resolve the problem.
function method oneMaskOr(n: bv8): bv8
requires 0 <= n <= 8
ensures oneMaskOr(n) as bv16 == oneMask(n as bv16)
{
if n == 0 then 0 else (1 << (n-1)) | oneMaskOr(n-1)
}
One interesting thing I found is that it shows me a counter example where it has reached the end of the loop and the final bit of the input variable n is set, so values 128 or greater. But when I add an assertion above the loop that value equals the count at the end of the loop it then shows me the another value of n.
assert 1 == countOneBits(128 & OneMaskOr(8)); //counterexample -> 192
assert 2 == countOneBits(192 & OneMaskOr(8)); //counterexample -> 160
So it seems like it isn't evaluating the loop invariant after the end of loop? I thought the whole point of the invariants was to evaluate after the end of loop.
Edit 2:
I figured it out, apparently adding the explicit decreases clause to the while loop fixed it. I don't get it though. I thought Dafny could figure this out.
while i < 8
invariant 0 <= i <= 8
invariant n' == n >> i
invariant count == countOneBits(n & oneMask(i) as bv8);
decreases 8 - i
{
I see one line in the docs for loop termination saying
If the decreases clause of a loop specifies *, then no termination check will be performed. Use of this feature is sound only with respect to partial correctness.
So is if the decreases clause is missing does it default to *?
After playing around, I did find a version which passes though it required reworking countOneBits() so that its recursion followed the order of iteration:
function countOneBits(n:bv8, i: int, j:int): bv8
requires i ≥ 0 ∧ i ≤ j ∧ j ≤ 8
decreases 8-i {
if i == j then 0
else (n&1) + countOneBits(n >> 1, i+1, j)
}
method hammingWeight(n: bv8) returns (count: bv8 )
ensures count == countOneBits(n,0,8)
{
count ≔ 0;
var i ≔ 0;
var n' ≔ n;
//
assert count == countOneBits(n,0,i);
//
while i < 8
invariant 0 ≤ i ≤ 8;
invariant n' == n >> i;
invariant count == countOneBits(n,0,i);
{
count ≔ (n' & 1) + count;
n' ≔ n' >> 1;
i ≔ i + 1;
}
}
The intuition here is that countOneBits(n,i,j) returns the number of 1 bits between i (inclusive) and j (exclusive). This then reflects what the loop is doing as we increase i.
How to invoke lemma as the reasoning for equality to be true. Consider the following example in dafny where I've created a lemma to say that the sum from 0 to n is n choose 2. Dafny seems to have no problem justifying this lemma. I want to use that lemma to say that the number of swaps in bubblesort has an upper bound of the sum from 0 to n which is equivalent to n choose 2. That being the case, I currently have an error when I try to say it's true by the lemma. Why is this happening and how can I say that equality is true given a lemma?
method BubbleSort(a: array?<int>) returns (n: nat)
modifies a
requires a != null
ensures n <= (a.Length * (a.Length - 1))/2
{
var i := a.Length - 1;
n := 0;
while (i > 0)
invariant 0 <= i < a.Length
{
var j := 0;
while (j < i)
invariant j <= i
invariant n <= SumRange(i, a.Length)
{
if(a[j] > a[j+1])
{
a[j], a[j+1] := a[j+1], a[j];
n := n + 1;
}
j := j + 1;
}
i := i -1;
}
assert n <= SumRange(i, a.Length) == (a.Length * (a.Length - 1))/2 by {SumRangeNChoose2(a.Length)};
assert n <= (a.Length * (a.Length - 1))/2
}
function SumRange(lo: int, hi: int): int
decreases hi - lo
{
if lo == hi then hi
else if lo >= hi then 0
else SumRange(lo, hi - 1) + hi
}
lemma SumRangeNChoose2(n: nat)
ensures SumRange(0, n) == (n * (n - 1))/2
{}
You just have a syntax error. There should be no semicolon after the } on the second to last line of BubbleSort. Also, there should be a semicolon after the assertion on the following line.
After you fix the syntax errors, there are several deeper errors in the code about missing invariants, etc. But they can all be fixed using the annotations from my answer to your other question.
here is a part of my cplex code. i defined the PreReq as boolean variable but in the constraint i get the error for PreReq that "expression must have bool type" what am i doing wrong?
IloBoolVarArray2 PreReq(env), CoRec(env), Offered(env);
//Constraint 6: if course d is taken and course c is its pre-req, then course c must be taken before d
IloExpr constraint6a(env);
IloExpr constraint6b(env);
IloExpr constraint6c(env);
IloExpr constraint6d(env);
for (c = 0; c < NumberOfCourses; c++) {
for (d = 0; d < NumberOfCourses; d++) {
if (PreReq[c][d] == 1 ) {
for (s = 0; s < NumberOfSemesters; s++) {
constraint6a += X[d][s];
constraint6b += X[c][s];
constraint6c += s*X[c][s];
constraint6d += s*X[d][s];
}
}
}
mod.add(constraint6a <= constraint6b);
mod.add(constraint6c <= constraint6d + (NumberOfSemesters)*(1 - onstraint6a) );
constraint6a.end();
constraint6b.end();
constraint6c.end();
constraint6d.end();
}
You'd rather use IloIfThen (logical constraints)
The example in CPLEX documentation:
IloIfThen(env, (x >= y && x >= z), IloNot(x <= 300 || y >= 700))
Expanding on Alex's answer: your problem is that you are mixing constraints with constraint generation: In the statement if ( PreReq[c][d] == 1 ) the operator== is overloaded to generate a constraint that requires PreReq[c][d] to take the value 1. So the result in this expression is of type IloConstraint, which is not a boolean type (it is a constraint object instead). That is why you get the error message. What you want instead is to add a constraint to your model that requires additional constraints in case PreReq[c][d] is 1.
So you probably want something like this:
for (d = 0; d < NumberOfCourses; d++) {
for (s = 0; s < NumberOfSemesters; s++) {
mod.add(IloIfThen(PreReq[c][d] == 1, constraint6a + X[d][s] <= constraint6b + X[c][s]));
mod.add(IloIfThen(PreReq[c][d] == 0, constraint6a <= constraint6b));
}
}
Which adds two variants of the constraint, only one of which will ever be active (depending on the value of PreReq[c][d]). Also see the reference documentation of class IloIfThen.
The model is optimizing the costs of Machines in Cell layout design
regarding the duplication and subcontracting.
Mod Const. is,
forall (k in 1..Cells, i in 1..nbMachines, j in 1..nbComps)
{
if (U[i][j][k] == 1 && A[k][i] < ((D[k][j]*S[k][j])*52))
DN[i][j][k] == 1;
SC[i][j][k] == 0;
INT[i][j][k] == 0;
}
forall (k in 1..Cells, i in 1..nbMachines, j in 1..nbComps)
{
if (V[i][j][k] == 1 && A[k][i] >= ((D[k][j]*S[k][j])*52))
DN[i][j][k] == 0;
SC[i][j][k] == 1;
INT[i][j][k] == 1;}
U , V are extracted in previous steps, A, D, S are input data.
The variables reqd. are DN, SC and INT.
Errors are those expressions are cannot be extracted, U, V are unbounded,
Please help in this regard,
Since U and V are decision variables, you should not write:
if (U[i][j][k] == 1 && A[k][i] < ((D[k][j]*S[k][j])*52))
DN[i][j][k] == 1;
Instead write:
((U[i][j][k] == 1) && (A[k][i] <= -1+((D[k][j]*S[k][j])*52)))
=> (DN[i][j][k] == 1);
Hi I have these two separate if statements, when put like so ;
if (powerlevel <= 0) // <--- ends up having no effect
if (src.health <= 0)
the_thing_to_do();
How do I combine these two if statements into one? is it possible? If so how?
If you want both statements to be true use logical AND
if(powerlevel <= 0 && src.health <= 0)
If you want either of the statements to be true use logical OR
if(powerlevel <= 0 || src.health <= 0)
Both of the above operators are logical operators
Use operator&& if you want both of them to be met (logical AND)
if(powerlevel <= 0 && src.health <= 0) { .. }
or operator|| if you want just one to be met (logical OR)
if(powerlevel <= 0 || src.health <= 0) { .. }
It depends if you want both to evaluate to true...
if ((powerlevel <= 0) && (src.health <= 0)) {
// do stuff
}
... or at least one ...
if ((powerlevel <= 0) || (src.health <= 0)) {
// do stuff
}
The difference being logical AND (&&) or logical OR (||)
Just an aternative if it is meaningful(sometimes).
Both true:
if (!(src.health > 0 || powerlevel > 0)) {}
at least one is true:
if (!(src.health > 0 && powerlevel > 0)) {}
Or if you don't want to use && you can use a Ternary Operator
#include <iostream>
int main (int argc, char* argv[])
{
struct
{
int health;
} src;
int powerlevel = 1;
src.health = 1;
bool result((powerlevel <= 0) ? ((src.health <=0) ? true : false) : false);
std::cout << "Result: " << result << std::endl;
}