binary4.gms : Tests that solvers evaluate logical expressions correctly

Description

In this test we attempt to solve a simple MINLP with logical functions
(bool_and, bool_or, etc) in equality equations and check whether the
returned solutions are feasible.
This is in particular interesting for solvers that do their own handling
of the model algebra.

Contributor: Stefan Vigerske, April 2022


Large Model of Type : MINLP


Category : GAMS Test library


Main file : binary4.gms

$Title 'tests that solvers evaluate logical expressions correctly'

$onText
In this test we attempt to solve a simple MINLP with logical functions
(bool_and, bool_or, etc) in equality equations and check whether the
returned solutions are feasible.
This is in particular interesting for solvers that do their own handling
of the model algebra.

Contributor: Stefan Vigerske, April 2022
$offText


$if not set TESTTOL $set TESTTOL 1e-6

$if not '%GAMS.minlp%' == '' $set solver %GAMS.minlp%
$if not set solver           $set solver dicopt

Set i / 1*50 /;
Binary Variables x, y, w(i);
Variables z1, z2, z3, z4, z5, z6, z7, z8, z9, objvar;
Equations e1, e2, e3, e4, e5, e6, e7, e8, e9, obj;

e1.. z1 =E= x and y;
e2.. z2 =E= x eqv y;
e3.. z3 =E= x imp y;
e4.. z4 =E= not x;
e5.. z5 =E= x or y;
e6.. z6 =E= x xor y;
* something longer to check also operator nesting and unusual constant
e7.. z7 =E= (x and y) or (not (x or y)) and (x eqv (y or 42)) imp not y;
e8.. z8 =E= sand(i,w(i));
e9.. z9 =E= sor(i,w(i));

* because GAMS doesn't allow to optimize binary variables
obj.. objvar =E= x;

Model m /all/;

$onEcho > examiner2.opt
subsolver %solver%
examineSoluPoint 0
examineInitPoint 0
fCheckAll 0
fCheckPCon 1
primalFeasTol %TESTTOL%
trace conviol.csv
$offEcho

$onEcho > conviol.csv
* Trace Record Definition
* GAMS/Examiner2 link
* DummyToMakeExaminer2Work,PrimalConInfeas
$offEcho

option minlp = examiner2;
m.optfile = 1;
* let GAMS replace fixed variables by values to check handling of constants in logic expression
m.holdfixed = 1;

* min x  should give 0
Solve m min objvar using minlp;
abort.noerror$(m.solvestat = %solvestat.CapabilityProblems%)  "Solver does not handle logical functions. Abort test.";
abort$(abs(m.objval)>%TESTTOL%) "objective value not 0";

* max x  should give 1
Solve m max objvar using minlp;
abort$(abs(m.objval-1)>%TESTTOL%) "objective value not 1";

* min x w.r.t. y = 0  should give 0
y.fx = 0;
Solve m min objvar using minlp;
abort$(abs(m.objval)>%TESTTOL%) "objective value not 0";

* min x w.r.t. y = 1  should give 0
y.fx = 1;
Solve m min objvar using minlp;
abort$(abs(m.objval)>%TESTTOL%) "objective value not 0";

* min x w.r.t. x = 0, y = 1
x.fx = 0;
Solve m min objvar using minlp;

* min x w.r.t. x = 0
y.lo = 0;
Solve m min objvar using minlp;

* min x w.r.t. x = 1
x.fx = 1;
Solve m min objvar using minlp;

m.holdfixed = 0;

* fix all w to 1
w.fx(i) = 1;
Solve m min objvar using minlp;

* fix first w to 1, all other to 0
w.fx(i) = 1$(ord(i)=1);
Solve m min objvar using minlp;

* check whether primal constraint violation was above test tolerance for every solve
* (the kludge with MSG is because we have no double-quotes available inside the execute command)
* (skip on windows because the spaces in the call are confusing cmd.exe)
$if %system.filesys% == UNIX execute.checkErrorLevel "awk -v FS=, -v MSG='Violation too large in solve ' 'NR>3 {if ($2 > %TESTTOL%) {print MSG NR-3 ; exit(1);} }' conviol.csv"