AMPL error "is not a set" "is not a param (or var or constraint or objective)""No variables declared" - ampl

I'm super new to AMPL and now struggling to solve the error.
I created both dat.file and mod.file separately, and wrote codes as exactly as the same as my teacher mentioned but it keeps showing below errors. I asked the teacher but seems it's properly shown on his PC, but not on mine (I'm Mac user).
Dat file:
`set PRODUCTION := P1 P2;
set RESOURCES := C W; # C W
param max_res := C 3000 W 1440;
param profit := P1 3.5 P2 1.5;
param param_res : C W :=
P1 1.5 5
P2 2 4.5;`
Mod file:
`reset;
option solver cplex;
set PRODUCTION;
set RESOURCES;
param profit {PRODUCTION};
param max_res {RESOURCES};
param param_res {PRODUCTION, RESOURCES};
var x {PRODUCTION} >= 0;
maximize profit: sum {i in PRODUCTION} profit[i] * x[i];
s.t. c_res {j in RESOURCES}: sum {i in production} param_res[i,j]*x[i] <= max_res[j];
s.t. c_minp2 {i in PRODUCTION]: sum {i in production} P2[i] >=30;
data PRODUCTION_REV.dat;`
Error:
ampl: data '/Users/XXX/Desktop/PRODUCTION_REV.dat';
/Users/XXX/Desktop/PRODUCTION_REV.dat, line 4 (offset 37):
PRODUCTION is not a set
context: set >>> PRODUCTION <<< := P1 P2;
/Users/XXX/Desktop/PRODUCTION_REV.dat, line 5 (offset 62):
RESOURCES is not a set
context: set >>> RESOURCES <<< := C W; # C W
/Users/XXX/Desktop/PRODUCTION_REV.dat, line 8 (offset 120):
max_res is not a param (or var or constraint or objective)
context: param >>> max_res <<< := C 3000 W 1440;
/Users/XXX/Desktop/PRODUCTION_REV.dat, line 9 (offset 152):
profit is not a param (or var or constraint or objective)
context: param >>> profit <<< := P1 3.5 P2 1.5;
/Users/XXX/Desktop/PRODUCTION_REV.dat, line 12 (offset 209):
param_res is not a param (or var or constraint or objective)
context: param >>> param_res <<< : C W :=
ampl: solve;
No variables declared.
ampl:
Anyone has a clue for this? The teacher's reply is slow and my assignment due is tomorrow night, can't wait for another reply from him...

Related

Dafny question: How to sort the Dutch Flag problem with four colors?

I'm trying to sort the Dutch Flag problem with 4 colors instead of 3, it seems that Dafny does not really verify and I could not fix it as well. This is my code:
datatype Colour = RED | WHITE | PINK | BLUE
method FlagSort(flag: array<Colour>) returns (w:int, p:int, b:int)
ensures 0 <= w <= p <= b < flag.Length
ensures forall i :: 0 <= i < w ==> flag[i] == RED
ensures forall i :: w <= i < p ==> flag[i] == WHITE
ensures forall i :: p <= i < b ==> flag[i] == PINK
ensures forall i :: b <= i < flag.Length ==> flag[i] == BLUE
ensures multiset(flag[..]) == multiset(old(flag[..]))
modifies flag
{
var next := 0;
w, p := 0, 0;
b := flag.Length;
while next <= b
invariant 0 <= w <= p <= next <= b <= flag.Length
invariant forall i :: 0 <= i < w ==> flag[i] == RED
invariant forall i :: w <= i < p ==> flag[i] == WHITE
invariant forall i :: p <= i < next ==> flag[i] == PINK
invariant forall i :: b <= i < flag.Length ==> flag[i] == BLUE
invariant multiset(flag[..]) == multiset(old(flag[..]))
{
if flag[next] == RED {
flag[next], flag[w] := flag[w], flag[next];
w := w + 1;
if p < w {
p := p + 1;
}
if next < w {
next := next + 1;
}
} else if flag[next] == WHITE {
flag[next], flag[p] := flag[p], flag[next];
p := p + 1;
next := next + 1;
} else if flag[next] == PINK {
next := next + 1;
} else if flag[next] == BLUE {
b := b - 1;
flag[next], flag[b] := flag[b], flag[next];
}
}
}
Can anyone help me with this please, thank you!
I don't know the solution to this problem (you might be solving a hard problem !), but here is some relevant advice for each of the three errors Dafny found in your code.
Error 1
When you see this:
flag[next], flag[b] := flag[b], flag[next];
^^^ index out of range
you can add an assertion before like this:
assert 0 <= b;
assert b < |flags|;
flag[next], flag[b] := flag[b], flag[next];
Magically, the index out of range will go away, and in your case, the first assertion will fail. You can then apply verification debugging techniques to move the assertion up..
Error 2
while next <= b
^^^^^ cannot prove termination, try supplying a decreases clause
the problem is that it tried to insert the decrease clause b - next, which should always be decreasing and bounded below by zero. If you make it explicit, and hover the decreases expression, it will tell you "the decreases expression is always bounded below by zero", but you get a new error:
while next <= b
^^^^^ decreases expression might not decrease
decreases b - next
What you can do is add this line at the beginning of your while loop.
ghost var b_saved,next_saved := b, next;
and at the end of your while loop, add the decreases check explicitly:
assert b - next < b_saved-next_saved;
You'll see that now the decreases clause is verified, and you have an error on an assert, on which you can apply regular verification debugging techniques.
Error 3
if flag[next] == RED {
^^^^^^^^^^ index out of range.
Similarly, you can insert the implicit assertions there:
assert 0 <= next < flag.Length;
if flag[next] == RED { // No error there
You'll see an underline on next < flag.Length. What can you do to ensure this? Perhaps change an invariant?

What will be the decreases value for multiply two integer in Dafny

Basically, my target is to learn dafny basics. But I am confused about invariant and decreases. In this code, my first while loop decreases by one so I have set decreases b but in my inner loop it is divided by 10, so when I was trying to set up b%10 as a decreases value, it always showed me an error. here I need some expert suggestions. What will be the decreases value for the second while loop in this code in this code invariant and decreases values are right?
method MultiplyTheory(N: int, M: nat) returns (Res: int)
ensures Res == M*N;
requires N>=0 && M>=0;
{
var a := N;
var b := M;
var x := 0;
var i :=0;
while (b > 0)
invariant M * N == a * b + x
decreases b
{
while (b % 10 != 0)
invariant M * N == a * b + x
decreases ?? // what will be the value here ??
{
x := x + a;
b := b - 1;
}
a := 10 * a;
b := b / 10;
}
Res := x;
}
Here is a verification debugging technique: you should first write the assertion that, if proven, would make your previous failing assertions to verify. Since you have two errors, one on the postcondition, and one on the outer decrease clause, here are two assertions you could insert.
If you want to see the solution, skip the steps and go to the end of this post.
Steps to solution
method MultiplyTheory(N: int, M: nat) returns (Res: int)
ensures Res == M*N;
requires N>=0 && M>=0;
{
var a := N;
var b := M;
var x := 0;
var i :=0;
while (b > 0)
invariant M * N == a * b + x
decreases b
{
var oldB := b;
while (b % 10 != 0)
invariant M * N == a * b + x
{
x := x + a;
b := b - 1;
}
a := 10 * a;
b := b / 10;
assert b < oldB; // Just added: If proven, the decreases condition holds
}
Res := x;
assert Res == M*N; // Just added: If proven, the postcondition would be ok
}
Now you see the two errors are on these assert. It's time to "move the asserts up" by applying weakest precondition rules. That means we keep the assert, but we write assert before their preceding statement such that, if these new assertions held, the old assertions would be verified:
method MultiplyTheory(N: int, M: nat) returns (Res: int)
ensures Res == M*N;
requires N>=0 && M>=0;
{
var a := N;
var b := M;
var x := 0;
var i :=0;
while (b > 0)
invariant M * N == a * b + x
decreases b
{
var oldB := b;
while (b % 10 != 0)
invariant M * N == a * b + x
{
x := x + a;
b := b - 1;
}
a := 10 * a;
assert b / 10 < oldB; // Just added. The next assert conditionally verify
b := b / 10;
assert b < oldB;
}
assert x == M * N; // Just added. The next assert conditionally verify.
Res := x;
assert Res == M*N;
}
See in your IDE how the error is now on the two most recent asserts.
Let's consider the second assert x == M * N;. Why is it wrong? There is an invariant that says M * N == a * b + x. So, if x == M * N;, it probably means that b should be equal to zero.
However, when we exit the while loop, we only know the negation of the guard, which is !(b > 0), or b <= 0. That's why we could not conclude!
Since we never intended b to be non-positive, we either need to add the invariant b >= 0 to the outer loop, or simply change the guard to b != 0 - but if you do that, then it will complain that with decreases b, b is not bounded by zero anymore. So the invariant is better.
method MultiplyTheory(N: int, M: nat) returns (Res: int)
ensures Res == M*N;
requires N>=0 && M>=0;
{
var a := N;
var b := M;
var x := 0;
var i :=0;
while (b > 0)
invariant M * N == a * b + x
invariant b >= 0 // Just added
decreases b
{
var oldB := b;
while (b % 10 != 0)
invariant M * N == a * b + x
{
x := x + a;
b := b - 1;
}
a := 10 * a;
assert b / 10 < oldB;
b := b / 10;
assert b < oldB;
}
assert x == M * N;
Res := x;
assert Res == M*N;
}
Now the invariant b >= 0 might not be maintained by the loop. This is because the inner while loop modifies b and does not give invariant on the value of b. Of course, we want b >= 0. So we add the invariant in the inner loop.
method MultiplyTheory(N: int, M: nat) returns (Res: int)
ensures Res == M*N;
requires N>=0 && M>=0;
{
var a := N;
var b := M;
var x := 0;
var i :=0;
while (b > 0)
invariant M * N == a * b + x
invariant b >= 0
decreases b
{
var oldB := b;
while (b % 10 != 0)
invariant M * N == a * b + x
invariant b >= 0 // Just added
{
x := x + a;
b := b - 1;
}
a := 10 * a;
assert b / 10 < oldB;
b := b / 10;
assert b < oldB;
}
assert x == M * N;
Res := x;
assert Res == M*N;
}
Ok, now the only assertion remaining is assert b / 10 < oldB;
Note that you don't need to write decreases in the inner clause because the default decreases for E > 0 is inferred to be decreases E, and in this case, Dafny can prove that b % 10 decreases.
However, knowing that b%10 == 0 at the end is not useful to prove that b itself decreased. If b was 7, it could be that the inner loop was increasing b to 10 before exiting...
The most basic strategy would be to convert the assertion b / 10 < oldB as an invariant. If you add it like that, everything verifies!
Solution
method MultiplyTheory(N: int, M: nat) returns (Res: int)
ensures Res == M*N;
requires N>=0 && M>=0;
{
var a := N;
var b := M;
var x := 0;
var i :=0;
while (b > 0)
invariant M * N == a * b + x
invariant b >= 0
decreases b
{
var oldB := b;
while (b % 10 != 0)
invariant M * N == a * b + x
invariant b >= 0
invariant b / 10 < oldB
{
x := x + a;
b := b - 1;
}
a := 10 * a;
assert b / 10 < oldB;
b := b / 10;
assert b < oldB;
}
assert x == M * N;
Res := x;
assert Res == M*N;
}
Now, you can experiment a bit about other invariant and observe that the following clauses would solve this last problem as well:
invariant b <= oldB
decreases b
Take some time to remove the asserts now because they were only used for scaffolding, but keep the invariant :-)

Is there a way to make a specific variable from a set an integer in Ampl?

set P;
set K;
set I:= {i in K};
set J:={j in P};
param C {P} >=0;
param A {K,P} >=0;
param B {K} >=0;
var X{j in P} >=0;
P consists of 4 set values, namely sweatshirt-f, sweatshirtB/F, tshirtf and tshirtBF, but I would like sweatshirt-f only to return an integer:
maximize f: sum{j in P} C[j]*X[j];
s.t. Constraint {i in K}:
sum{j in P} A[i,j]*X[j]<=B[i];
Option 1: declare all of them as integer, then relax integer constraints for the others:
var X{j in P} >=0 integer;
let {i in P: i <> "sweatshirt-f"} X[i].relax := 1;
Option 2: declare a dummy variable as integer, then constrain relevant value to match it:
var X{j in P} >=0;
var int_dummy integer;
s.t. force_integer: X["sweatshirt-f"] = int_dummy;
I'm not able to test those right now, so you may have to do a little debugging, but that should get you in the neighbourhood of a solution.

Is this an issue with pre-solve or how AMPL uses arrays?

I am modeling a production problem in AMPL with start and end inventories to be zero.
Simple 3 products being produced over 4 day span, on a single machine.
however my model keeps having problems with the bigM constraint and no inventory is allocated.Model is infeasible per AMPL presolve.
I would really appreciate if someone could point whats wrong or what i should try. Thanks in advance!
HERE IS THE CODE -
param n;
param m;
param M;
param T;
set I := {1..n};
set J := {1..m};
param r {I} integer; #productionrate
param stp {I} integer; #setuptime
param rev {I} integer; #sellingprice
param h {I} integer; #inventorycost
param d {I,J} integer; #demand
var t {I,J} integer >= 0, <=480 default 50; #production time allocated for product i on day j
var s {I,J} integer >= 0 default 50; #inventory of product i on day j
var z {I,J} binary default 1; #setup for product i done on day j or not
#sum of revenue - sum of inventory cost
maximize K: sum {i in I,j in J}(rev[i] * t[i,j] * r[i] * z[i,j]) - sum {i in I,j in J}(h[i] * s[i,j]);
#inventory equation
s.t. c2 {i in I,j in 2..4}: s[i,j] = s[i,j-1] + t[i,j]*r[i] - d[i,j];
s.t. c14 {i in I}: s[i,1] = t[i,1]*r[i] - d[i,1];
#initial and end inventories
s.t. c3 {i in I}: s[i,1] = 0;
s.t. c4 {i in I}: s[i,4] = 0;
#ensuring time allocation only when setup
s.t. c5 {i in I,j in J}: t[i,j] <= M*z[i,j];
#ensuring demand is satisfied
s.t. c6 {i in I,j in 2..4}: s[i,j-1] + t[i,j]*r[i] = d[i,j];
s.t. c11 {i in I}: t[i,1]*r[i] = d[i,1];
#production time constraint
s.t. c7 {j in J}: sum{i in I}(z[i,j]*stp[i]) + sum{i in I}(t[i,j]) <= T;
#other non-negativity constraints
s.t. c12 {i in I,j in J}: s[i,j] >= 0;
#s.t. c13 {i in I,j in J}: t[i,j] >= 0;
end;
HERE IS THE DATA -
param n :=3;
param m :=4;
param T :=480;
param M :=480;
#param o :=2;
param d: 1 2 3 4 :=
1 400 600 200 800
2 240 440 100 660
3 80 120 40 100;
param r:=
1 5
2 4
3 2;
param stp:=
1 45
2 60
3 100;
param rev:=
1 50
2 70
3 120;
param h:=
1 2
2 1
3 3;
end;
RUN FILE -
#RESET THE AMPL ENVIROMENT
reset;
#LOAD THE MODEL
model 'EDX 15.053 Production problem.mod';
#LOAD THE DATA
data 'EDX 15.053 Production problem.dat';
#DISPLAY THE PROBLEM FORMULATION
expand K;
expand c2;
#expand c3;
expand c4;
expand c5;
expand c6;
expand c7;
expand c11;
#let s[3,3] := 20;
#CHANGE THE SOLVER (optional)
#option solver CBC;
option solver cplex, cplex_options ’presolve 0’;
option show_stats 1;
option send_statuses 0;
#option presolve 0;
#SOLVE
solve;
print {j in 1.._nvars:_var[j].status = "pre"}: _varname[j];
print {i in 1.._ncons:_con[i].status = "pre"}: _conname[i];
display solve_message;
display solve_result_num, solve_result;
#SHOW RESULTS
display t,s,z,K;
end;

AMPL Variables in subscripts are not yet allowed

I really hope someone can help with this...
This is what i have in the .mod file
set I := 1..10;
set J := 1..10;
set K := 1..2;
set W := 1..20;
param v{K, W};
param d{I, J};
var x1, integer;
var y1, integer;
var x2, integer;
var y2, integer;
var assist{W}, binary;
and this is the code generating error:
minimize nome: sum{w in W} (if (assist[w] == 0) then
(if (x1 >= v[1,w]) then
(if (y1 >= v[2,w]) then
(d[x1 - v[1,w],y1 - v[2,w]])....
where the error regards the last line and says:
Variables in subscripts are not yet allowed.
context: (d[x1 - v[1,w],y1 - >>> v[2,w]] <<< )
this is one of constraints (others are just the same):
subject to rangex1:
x1 > 0 && x1 <= 10;
As the error message says, you can't use decision variables within a subscript in AMPL. In this case x1 and y1 are decision variables, so d[x1 - v[1,w],y1 - v[2,w]] is not allowed. You'll need to reformulate the problem in a way that avoids this issue.