GAMS has an enormous number of features and options which allow it to support the most sophisticated mathematical programming and econometric applications. Fortunately, what a beginner needs to know to use the language in solving standard mathematical programs is much less.
These Notes are Professor Ron Rardin's overview of the features most often needed in coding and solving optimization models.
In the interest of simplicity and good style, many features of the language are presented in a much more limited and rigid form than actually allowed by the full GAMS. Users with more complicated questions should download the manual (about 250 pages) GAMS: A User's Guide which is available online in .pdf format.
Professor Rardin retains all copyrights to these Notes. Reproduction of any part of them for sale is prohibited without his expressed written consent, but noncommercial use or reproduction is authorized as long as the original source and author are acknowledged. (Accessed 3586 times from 1714 different hosts since 18Jan98)
filename.gmsinput (text) file using a modeling language which parallels the standard mathematical programming format of books and research papers. Several examples are provided below.
When the input file is ready, the system is invoked to solve one or more versions of the model, with output (including any error messages) sent to corresponding file
filename.lstMany output options are available in GAMS (see Part IV), but the default produced in the .lst file by each run is usually sufficient for student use.
Default output begins with an echo of the input like the following. If syntax errors were detected, GAMS includes numbered messages within the echo output and provides a key at the end of the listing.
1 * Echo print example with an error 2 positive variable x1 "product 1", x2 "product 2"; 3 free variable p "profit"; 4 equations objective, capacity; 5 objective.. z =e= 10*x1 + 20*x2; **** $140 6 capacity.. x1 + x2 =l= 100; 7 model tiny /all/; 8 solve tiny using lp maximizing z; **** $257 Error Messages 140 Unknown symbol 257 Solve statement not checked because of previous errors 
Once all errors are corrected, the SOLVE SUMMARY part of the .lst file details results of the optimization.
S O L V E S U M M A R Y MODEL TINY OBJECTIVE Z TYPE LP DIRECTION MAXIMIZE SOLVER CPLEX FROM LINE 8 **** SOLVER STATUS 1 NORMAL COMPLETION **** MODEL STATUS 1 OPTIMAL **** OBJECTIVE VALUE 2000.0000 LOWER LEVEL UPPER MARGINAL  EQU OBJECTIVE . . . 1.000  EQU CAPACITY INF 100.000 100.000 20.000 LOWER LEVEL UPPER MARGINAL  VAR X1 . . +INF 10.000  VAR X2 . 100.000 +INF .  VAR Z INF 2000.000 +INF . X1 product 1 X2 product 2 Z profit 
The first main part of each SOLVE SUMMARY reviews results for model equations. Values are given for each objective and constraint, with the LEVEL of each constraint providing the amount of the associated resource used in the final solution and MARGINAL showing the corresponding dual variable (Lagrange multiplier) value. Any value having only a decimal point is = 0.
The second part of each SOLVE SUMMARY details results for all decision variables. These reports show the final LEVEL for each variable along with any upper and lower bounds and a MARGINAL value corresponding to the variable's reduced cost. Again, values having only a decimal point = 0.
Errors may also be reported during solving. Such execution errors usually result from an infeasible or unbounded model, program limits being exceeded, or improper computations such as taking the logarithm of a nonpositive number.
gams filenameResults and any error messages can be seen by editing or printing the resulting filename.lst output file stored in the current directory.
When running in commandline mode, it is recommended that each .gms file begin with the commands
$offsymxref offsymlistwhich turn off all output except an echo of the input file and a SOLVE SUMMARY for each solve command of the input. These options are the default in the Windows IDE version.
option limrow=0, limcol=0;
To run the IDE version of GAMS, users must first launch the system by selecting Gams and gamside on the Programs menu (accessible from Start).
The result should be a screen similar to many other Windows applications, with a menu bar along the top and a main Edit Window for GAMS applications. As with most such systems, input and output operations are controlled by the File pulldown menu, with other menu items used in edit operations, and in running the GAMS system.
Users should begin each session by selecting a "project". A project is a system file you save but never have to touch. Still, its location is important because the folder (directory) of the current project file is where .gms input and .lst output files are saved by default. This allows you to easily keep all the input and output files for any task together in the same directory, and use different directories for different projects. The starting project file (if any) shows at the top of the main GAMS window. To select another, or create a new one, use the Project item on the File menu.
The IDE version provides for standard, mousedriven editing of .gms files in the main GAMS Edit Window. If the appropriate file is not already displayed, use the New or Open commands on the File menu to activate one. Then create or correct the file with the mouse and tools provided on the Edit and Search menus. The Matching Parenthesis button helps with the many parentheses in GAMS by skipping the cursor to the parenthesis that corresponds to the one it is now positioned in front of.
Once a .gms file is ready to run, the Run item on the main menu bar invokes GAMS. In addition, it automatically causes a .lst output to be stored in the current project directory (but not displayed).
The .lst output file can be activated using the Open command on the File menu. However, it is usually easier to first survey an IDE run by examining the separate Process Window, which is automatically displayed. A brief log of the run appears there, and clicking on any of the boldface lines (including run error messages) will activate the entire .lst output file and position you on that message. In particular, clicking on Reading solution for model will open the .lst and position the window at the SOLVE SUMMARY.
Syntax errors in GAMS input show in red in the Process Window. Clicking on any such red error message brings up the corresponding .gms file in the main GAMS window and positions the cursor at the point where the error was detected.
Formulation  GAMS Input 

LP Example 5.1: Top Brass Trophy 
* Rardin Example 5.1 file topbrass.gms 
Formulation  GAMS Input 

ILP Example 12.2: River Power 
* Rardin Example 12.2 file rivpower.gms 
Formulation  GAMS Input 

NLP Example 14.7: Service Desk Design 
* Rardin Example 14.7 file servdesk.gms 
$offsymxref offsymlistat the top. This eliminates lengthy debug print that is usually not needed.
option limrow=0, limcol=0;
Allowed types and corresponding GAMS keywords are as follows:
Type  GAMS Keyword 

unrestricted (continuous) variable(s)  free variable(s) 
nonnegative (continuous) variable(s)  positive variable(s) 
nonpositive (continuous) variable(s)  negative variable(s) 
01 variable(s)  binary variable(s) 
nonnegative integer variable(s)  integer variable(s) 
Any type can also be indexed over one or more subscript sets (see Part II).
In addition to the usual decision variables of the model, there must always be free variable(s) defined to represent the objective function value(s). For example, free variable profit plays this role in the Top Brass Trophy illustration above.
equation dem "annual demand";declares an equation named dem and notes that it corresponds to annual demand.
The second part of defining an equation is to add detail on each declared equation name in a separate statement beginning
equationname..and continuing with lefthand side and righthand side expressions separated by one of the following operators
Equation Type  Operator 

equals  =e= 
less than or equal to  =l= 
greater than or equal to  =g= 
For example, the annual demand equation declared above might be detailed as
dem .. x1 + x2 + x3 =g= 120  x0;
One such equation always sets the objective function equal to the (free) objective value variable. Any equation can be indexed over one or more subscript sets to define a whole system of similar constraints (see Part II).
The syntax of equation detail statements follows the pattern of C and similar languages with + for addition,  for subtraction, * for multiplication, / for division, and ** for exponentiation. Terms need not be collected, and they may appear on either side of the relational operator. Parentheses may be added to group quantities or aid readability.
A variety of standard functions may also be included:



For simple cases this is accomplished with the statement
model modelname /all/;In more complicated situations the all can be replaced by a list of relevant equation names such as
model small /obj,demand/;(see an actual example in http://www.ecn.purdue.edu/~rardin/oorbook/software/gams/hiwayptl.gms).
model big /obj,demand,detail/;
solve modelname using solvertype maximizing objectivevaluevariable;or
solve modelname using solvertype minimizing objectivevaluevariable;invokes a solver where modelname is the declared name of the model, objectivevaluevariable is the free variable representing the objective function value, and solvertype is one of the following:
GAMS Type  Description 

LP  exact solution of a linear program 
MIP  exact solution of an integer linear program 
RMIP  solution of the LP relaxation of an integer linear program 
NLP  local optimization of a nonlinear program over smooth functions 
DNLP  local optimization of a nonlinear program with nonsmooth functions 
MIDNLP  local optimization of an integer nonlinear program with nonlinearities all in the continuous variables 
RMIDNLP  local optimization of the continuous relaxation of an integer nonlinear program with nonlinearities all in the continuous variables 
There is a default solver for each of these model types. The defaults are detailed in online documentation, and, for the IDE version, under Options on the File menu. Default solvers can also be changed with an option command. For example,
option nlp=minos5;in a .gms file makes the default NLP solver MINOS5.
Input files often contain more than one solve statement, each optimizing a different case. For example, the following sequence solves a nonlinear programming model three times from different starting values of the decision variable x:
x.l=2.0;
solve nlmodel using nlp minimizing z;
x.l=20.0;
solve nlmodel using nlp minimizing z;
x.l=200.0;
solve nlmodel using nlp minimizing z;
Suffixed Form  Description 

variable.l  variable level or current value 
variable.lo  variable lower bound 
variable.up  variable upper bound 
variable.m  variable reduced cost 
constraint.m  constraint dual value 
Upper and lower bounds may be assigned values to impose constraints. For example the statements
x.lo=1e5;have the effect of enforcing constraints
x.up=92.0;
10^{5} <= x <= 92.0The small positive lower bound can be particularly useful in nonlinear programming where functions may not be defined at zero.
It is sometimes also necessary to set the current level of a variable. This is particularly true in nonlinear programming where it is advisable to pick starting solutions because results may depend on initial variable values. For example, the statement
x.l=56.2;before a solve statement will cause the algorithm to begin its search with x=56.2.
Note that the statement x=56.2; would not be allowed for a GAMS decision variable x because the variable name itself cannot be assigned a value. Add an appropriate suffix (usually .l) to correct the resulting error.
Error Keywords  Likely Problem 

unknown symbol  A set, variable, equation or parameter name is used without being previously declared. 
symbol redefined  A set, variable, equation or parameter name is declared more than once. Remember xx, XX and xX are the same name. 
unrecognized item skip to a new statement  An extra semicolon or comma has interrupted a part of a statement. May be due to a constant with a comma in it. 
=l=, =e=, or =g= operator expected  An equation lacks a suitable relational operator. Remember you cannot use =, <= or >=. 
suffix is missing  An operation on a decision variable or constraint does not indicate whether .l, .lo .up, or .m is intended. 
endog arguments endog operands  The model has nonlinear elements not consistent with the problem type in the solve statement. 
variable wrong type  The model has variable types not consistent with the problem type in the solve statement. 
log of negative number sqrt of a negative number  Argument of a function is outside range. Probably need a starting solution or bound on variables. 
division by zero gradient too big  A denominator is too close to zero. Probably need a starting solution or bound on variables. 
no solution  The model is infeasible or unbounded, or no solution was discovered before termination criteria were reached. 
set identifier or quoted element expected  An explicit subscript has been used without placing it in quotes. 
incompatible operands for relational operator  A subscript is probably being treated as numeric rather than string. Consider using the ord() function. 
domain violation  A subscript name used is not the same as the original declaration of the variable, equation or parameter. If your really need to do this, consider an alias. 
more/less indices  The number of subscripts is not the same as the original declaration of the variable, equation or parameter. 
uncontrolled set  A subscript is dangling, i.e. the index of neither that of a sum nor that of a system of constraints 
set under control already  A subscript is simultaneously used in two ways  probably as the index of both a sum and a system of constraints. If you really need to do this, consider an alias. 
licensing error  Your licenses do not permit solving the specified model, probably because you have exceeded the size limits of the student version 
If a review of the errors is not enough to find the problems in a GAMS model, consider the extensive debug print options outlined in Part IV.
Consider a facilities location problem in the form (SUM denotes the usual sigma for summations):
min SUM_{i} SUM_{j} d_{j}c_{i,j}x_{i,j} + s SUM_{i} f_{i}y_{i} s.t. SUM_{i} x_{i,j} = 1 SUM_{j} x_{i,j} <= 5y_{i} y_{LA} + y_{ATL} <= 1 x_{i,j} >= 0 y_{i} = 0 or 1 
for all j for all i for all i,j for all i 
where x_{i,j} and y_{i} are the decision variables for i=LA,CHI,ATL and j=1,...,5. The rest of the symbols in the model are constant parameters with s=100, and c_{i,j}, d_{j} and f_{i} as shown in the following table:
c_{i,j}  

j=1  j=2  j=3  j=4  j=5  f_{i}  
i=LA  2  4  9  3  8  3.1 
i=CHI  6  0  0  1  2  3.1 
i=ATL  1  4  2  0  3  3.1 
d_{j}  11  0  15  12  19 
The corresponding GAMS input would be
* Facilities location example with subscripts and symbolic constants option optcr=0.0; sets i "facilities" /LA, CHI, ATL/, j "customers" /1 * 5/; scalar s "scaling constant" /100/; parameter d(j) "demand at j" /1 11, 3 15, 4 12, 5 19/; parameter f(i) "fixed cost at i"; f(i) = 3.1; table c(i,j) "i to j transportation cost" 1 2 3 4 5 LA 2 4 9 3 8 CHI 6 1 2 ATL 1 4 2 0 3 ; free variable cost "total cost"; positive variable x(i,j) "fraction of j serviced by i"; binary variable y(i) "whether i is opened"; equations obj "min total cost", switch(i) "switching at i", sumone(j) "do customer all of j", laoratl "LA or ATL"; obj.. sum((i,j), d(j)*c(i,j)*x(i,j)) + s*sum(i, f(i)*y(i)) =e= cost; switch(i).. sum(j, x(i,j)) =l= card(j)*y(i); sumone(j).. sum(i, x(i,j)) =e= 1; laoratl.. y('LA') + y('ATL') =l= 1; model facloc /all/; solve facloc using mip minimizing cost; 
If the set is a sequence of consecutive integers, the shorthand
Elements of the set are still treated as strings even though they look like integers./ lowerlimit * upperlimit / gives lowerlimit,...,upperlimit
A handy function card( setname ) returns the number of elements in the specified set. Notice that switch(i) constraints in the above example use the value of this function as a model constant.
Once a set name has been associated with some a variable, that same index name must normally be used whenever the variable is referenced. Cases where more than one subscript name is needed are handled with aliases (see Domains and Aliases.)
The fact that elements of sets are taken as strings means they must be enclosed in quotes when called out explicitly. For example in the above model, a single side constraint
Leaving out quotes leads to a host of errors even though the 3 seems to be a number.x_{LA,3} <= y_{LA} would be expressed x('LA','3') =l= y('LA');
equation vub(i,j);has the effect of enforcing constraints
vub(i,j)..x(i,j) =l= y(i);
x_{i,j} <= y_{i} for all i and j
Sometimes indexing is desired over only part of the elements of an index set. For example an equation may exist for all i and all j> i. The $restriction feature of GAMS, which handles such cases, is outlined in Part III below.
sum( subscript range, expression )computes the sum of the specified expressions of subscripts over all combinations of their elements.
The objective function of the above example illustrates:
obj .. sum((i,j), d(j)*c(i,j)*x(i,j)) + s*sum(i, f(i)*y(i)) =e= cost;The first summation totals terms d_{j}c_{i,j}x_{i,j} for all combinations of i and j, and the second sums f_{i}y_{i} over all i.
A similar approach can be used to express indexed products. The operator
prod( subscript range, expression )returns the product of specified expressions.
Sometimes indexing is desired over only part of the elements of an index set. For example we may want to sum over all i and all j> i. The $restriction feature of GAMS, which handles such cases, is outlined in Part III below.
When the parameter has no subscripts, the scalar statement is used. For example, the statement
scalar s "scaling constant" /100/;in the above example defines a constant s=100. As usual, information between the double quotes is explanatory text, and the assigned value is placed between slashes.
Subscripted symbolic parameters may be defined in a similar way with parameter statements. For example the above statement
parameter d(j) "demand for j" /1 11, 3 15, 4 12, 5 19/;defines a constant d_{j} for each j and assigns values to elements j = 1, 3, 4 and 5. Values are assigned in subscriptvalue pairs separated by commas. Any unmentioned components are automatically set = 0.
When a parameter has more than one subscript, its nonzero elements can be defined in a similar way with subscript combinations concatinated with periods. For example the statement
parameter c(i,j) "i to j transportation cost" /LA.1 2, CHI.1 6, ATL.5 3/;would define all c_{i,j} constants in the above example and set values for three. Others would default to = 0. (See also the often easier table alternative of the next section.)
The /delimited value lists may be omitted in all these examples. Values must then be assigned after the declaration by placing parameter names on the left side of an = sign. Some examples include
scalar s; s = 100; 
gives scalar constant s the value 100 
parameter f(i); f(i)=3.1; 
makes all parameters f_{i} = 3.1 
parameter totc(i); totc(i) = sum( j, c(i,j) ); 
computes all parameters totc_{i} as sums over j of corresponding c_{i,j} 
Notice that, in contrast to decision variables, no suffix is required on parameters.
Subscript set elements are arranged around the borders and nonzero values aligned with them in a matrix. The above example model illustrates for two subscripts:
This statement both defines doublesubscripted parameter c_{i,j} and assigns nonzero values. For example, c_{LA,3} = 9. Unspecified values are taken =0.table c(i,j) "i to j transportation cost" 1 2 3 4 5 LA 2 4 9 3 8 CHI 6 1 2 ATL 1 4 2 0 3 ;
If a symbolic parameter has more than two subscripts, some must me concatenated by periods to reduce to a twodimensional table. For example, the sixteen components of a table yield_{i,j,k,l} over sets
sets i /A,B/, j /1,2/, k /90,95/, l /Y,Z/;could be inputed in a table by combining i and j along the vertical axis, and k and l along the horizontal as
Here yield_{A,1,95,Y} = 1.23, yield_{B,2,95,Z} = 45, and all other yield_{i,j,k,l}=0.table yield(i,j,k,l) "process yield" 90.Y 90.Z 95.Y 95.Z A.1 1.23 A.2 B.1 B.2 45 ;
GAMS accommodates such situations with a $operator read to mean "such that". Appending a $restriction to any subscript(s) makes the operation apply only to subscript combinations satisfying the specified condition. For example,
Statement  Meaning 

positive variable x(j)$(condition);  defines x_{j} for all j satisfying condition 
equation switch(i,j); switch(i,j)$(condition).. x(i,j) =l= y(i); 
defines an x_{i,j} <= y_{i} constraint for all (i,j) satisfying condition 
y.lo(i,j)$(condition) = 10;  sets the lower bound of y_{i,j} equal to 10 for all (i,j) satisfying condition 
sum( (i,j,k)$(condition), expression );  sums expression over all (i,j,k) satisfying condition 
The condition used in a $restriction can be any sort of logical expression using relational operators over model quantities
Operator  Meaning 

lt le eq ne ge gt  less than, less than or equal to, equal, not equal, greater than or equal to, greater than 
not and or  not, and, or 
For example the statement
parameter c(i,j)$( a(i) gt 0 and b(j) gt 0 );defines a parameter c_{i,j} for all (i,j) with both parameter a_{i} > 0 and parameter b_{j} > 0.
Because set elements are treated as strings in GAMS, it is often necessary to convert them to numbers in order to express $conditions. An ord( ) function is provided for this purpose which returns the ordinal position (beginning with 1) of an element of a set. For example if c_{i,j} are to be summed over all i and all j > i the natural coding sum( (i,j)$( j gt i ), c(i,j) ) produces errors because j and i are not numeric quantities. However, they can be converted with the ord() function (assuming elements of the sets were originally defined in sequence) to obtain correct form
sum( (i,j)$( ord(j) gt ord(i) ), c(i,j) );
i_{t} = i_{t1} + x_{t}  d_{t}where x_{t} is the production in period t, and d_{t} is the demand in period t.
Even though it stretches the principle that elements of sets are treated as strings rather than numbers, GAMS allows such equations to be coded
balance(t).. i(t) =e= i(t1) + x(t)  d(t);over set t /1*12/. The 1 simply means take the previous element of the set; 2 would mean the second previous; +1 would mean the next element; +2 would mean the element after next; etc.
Subscripted quantities outside the set in such + and  constructions are taken = 0. For example, in the above balance(t), i('1'1) is assumed =0.
An alternative is to wraparound indexing from one end of a set to another. Double operators ++ and  are used. Changing the above example in this way to
balance(t).. i(t) =e= i(t1) + x(t)  d(t);would make ('1'1) be 12.
GAMS provides an alias option to escape this limitation when, for example, a variable is defined as x(j) but later referred to as x(k). The statement
alias (j,k);makes k another name for the previously defined set j. Thereafter, they may be used interchangeably.
For example, consider a model posed on a network or graph, and let
set i /1 * 4/;define the list of nodes i,j=1,...4. Also assume only arcs (1,2), (1,3), (2,4), (3,2) and (3,4) are present in the digraph of interest.
alias (i,j);
Declaration
set arc(i,j) / 1.2, 1.3, 2.4, 3.2, 3.4 /;enumerates the existing arcs in a new subset arc(i,j) defined within the full range of i and j combinations. Then a subsequent
sum( (i,j)$arc(i,j), x(i,j) );sums only over (i,j) enumerated in the subset. The $arc(i,j) is taken to mean "such that the pair (i,j) belongs to the subset". (See a full example in http://www.ecn.purdue.edu/~rardin/oorbook/software/gams/optoven.gms).
Unlike underlying sets, which must remain "static" through all modeling and computation, subsets are "dynamic", i.e. their membership can be changed as processing evolves. The syntax is simply to assign the values yes or no to particular indices of the set. For example arc(i,j)=yes makes the arc set in the above example complete; all arcs belong to the subset. A later statement arc('3','2')=no would delete arc (3,2).
Dynamic (sub)sets can also be defined by classic set operations on other subsets.
Statement  Meaning 

sub3(i) = sub1(i) + sub2(i);  subset3 = the union of subset1 and subset2 
sub3(i) = sub1(i) * sub2(i);  subset3 = the intersection of subset1 and subset2 
sub3(i) = sub1(i)  sub2(i)  subset3 = the set difference of subset1 and subset 2 
sub3(i) = not sub1(i);  subset3 = the complement of subset1 
One case is where the user wants to print values not part of the standard output. The display statement is used for this purpose. For example the sequence
would compute a distance matrix using previously defined coordinates (h_{i},k_{i}) for points and then output the results for user information. Such listings of parameter values are not part of the default GAMS output.
parameter dist(i,j);
dist(i,j) = abs( h(i)h(j) ) + abs( k(i)  k(j) );
display dist;
Another common use of display statements is to replace for a voluminous default output. First, statement
option solprint = off;turns off all standard solution output. Then display statements are used to print only results of interest, e.g.
display x.l, budget.m;
option limrow = integer;calls for outputing the first integer rows from each equation (system) defined in the model. Nonzero coefficients are shown along with corresponding variable names. Similarly
option limcol = integer;causes outputing of nonzero coefficients for the first integer components of each variable defined in the model. These outputs will have terms fully collected and coefficients evaluated so that the user can see if there were errors.
$include 'includefile.gms'is encountered. Here includefile.gms (in single quotes) is the name of the .gms file with code to be inserted. Any sequence that would be correct within the main .gms file is acceptable from an included one. Notice that the $include statement does not end with a semicolon because it is a $command.
This include feature provides a convenient way to import parameter values from spreadsheet software. For example, the main file
sets i /1*2/, t /95*98/;could import the following spreadsheet output as included file sales.gms:
table sales(i,t)
$include 'sales.gms'
;
95 96 97 98 1 1.3 2.0 2.7 3.6 2 4.9 4.6 4.3 4.5
file soln /training.out/;opens a file soln as training.out, signifies that the next puts will be to that file, writes text "final x and y =" to the file, and then writes the current values of a variables x and y followed by an endofline.
put soln;
put "final x and y =";
put x.l, y.l;
put /;
Option  Description 

decimals  decimal places in standard outputs 
seed  pseudo random number seed 
limcol  columns displayed in diagnostic output 
limrow  rows displayed in diagnostic output 
iterlim  maximum iterations per solve 
domlim  maximum function domain violations per solve 
reslim  maximum time per solve 
optcr  maximum fraction suboptimal in MIPs 
optca  maximum absolute suboptimality in MIPs 
lp  LP solver 
nlp  NLP solver 
mip  MIP solver 
dnlp  DNLP solver 
midnlp  MIDNLP solver 
solprint  default print 'off' or 'on' 
All these parameters have default values that are usually satisfactory, but explicit option statements may be used to make a different choice. For example
option lp = cplex;resets the LP solver to CPLEX.
model dsgn /all/; option solprint = off; set t /1*20/; loop( t, x.l(j) = uniform( x.lo(j), x.up(j) ); solve dsgn using nlp minimizing cost; display x.l, cost.l; );
model dsgn /all/; option solprint = off; scalar t /1/; while( (t le 20), x.l(j) = uniform( x.lo(j), x.up(j) ); solve dsgn using nlp minimizing cost; display x.l, cost.l; t = t + 1; );
model dsgn /all/; option solprint = off; scalar t; for( t = 1 to 20, x.l(j) = uniform( x.lo(j), x.up(j) ); solve dsgn using nlp minimizing cost; display x.l, cost.l; );
if( x.l gt 0 ), s = 1; elseif( x.l lt 0 ), s = 1; else s = 0; );
modelstat value  Description 

1  optimal 
2  locally optimal 
3  unbounded 
4  infeasible 
5  locally infeasible 
6  incomplete solution, infeasible 
7  incomplete solution, feasible 
8  integer solution 
9  incomplete solution, noninteger 
10  integer infeasible 
Thus, for example, if some statements are to be executed only if the last solve terminated optimal, the following sequence would be appropriate:
model plan /all/; solve plan using lp minimizing cost; if( (plan.modelstat eq 1), statements );