GAMS Programs

Introduction

This chapter provides a look at the structure of the GAMS language and its components. It should be emphasized again that GAMS is a programming language, and that programs must be written in the language to use it. A GAMS program is contained in a disk file, which is usually constructed with a text editor of choice (e.g. GAMS Studio). When GAMS is 'run', the file containing the program (the input file) is submitted to be processed. After this processing has finished, the results, which are in the output file(s), can be inspected. By default the GAMS log appears on the screen while GAMS runs, keeping the user informed about progress and error detection. It is the responsibility of the user to inspect the output file(s) carefully to see the results and to diagnose any errors.

The Structure of GAMS Programs

GAMS programs consist of one or more statements (sentences) that define data structures, initial values, data modifications, and symbolic relationships (equations). While there is no fixed order in which statements have to be arranged, the order in which data modifications are carried out is important. Symbols must be declared as to type before they are used, and must have values assigned before they can be referenced in assignment statements. Each statement is followed by a semicolon except the last statement, where a semicolon is optional.

Note
The semicolon at the end of a statement can be omitted if a new GAMS keyword follows. However, to improve readability of the code, it is recommended to use the semicolon at the end of a statement anyway.

Format of GAMS Input

GAMS input is free format. A statement may be placed anywhere on a line, multiple statements may appear on a line, or a statement may be continued over any number of lines as follows:

statement;
statement;
statement; statement; statement;
the words that you are now reading is an example of a very
long statement which is stretched over two lines;

Blanks and end-of-lines may generally be used freely between individual symbols or words. GAMS is not case sensitive. This means that lower and upper case letters may be mixed freely but are treated identically. Up to 80,000 characters may be placed on a line and completely blank lines may be inserted for easier reading.

Not all lines are a part of the GAMS language. Two special symbols, the asterisk '*' and the dollar symbol '$' may be used in the first position on a line to indicate a non-language input line. An asterisk in column one means that the line will not be processed, but treated as a comment. For more on comments, see section Comments. A dollar symbol in the first position indicates that compiler options or directives are contained in the rest of the line (see chapter Dollar Control Options for more information).

For example, multiple files may be used as input through the use of the $include facility. In short, the statement

$include file1

inserts the contents of the specified file (file1 in this case) at the location of the call. A more complex versions of this is the option $batinclude. Both options are introduced and discussed in details in chapter Dollar Control Options.

Classification of GAMS Statements

Each statement in GAMS is classified into one of two groups:

  1. Declaration and definition statements.
  2. Execution statements.

A declaration statement describes the class of a symbol. Often initial values are provided in a declaration, then it may be called a definition. The specification of symbolic relationships for an equation is a definition. The declaration and definition statements are:

Execution statements are instructions to carry out actions such as data transformation, model solution, and report generation. The execution statements are:

Note
While an assignment is an execution statement, it also defines the symbol on the left hand side of the assignment.

Although there is great freedom about the order in which statements may be placed in a GAMS program, certain arrangements are commonly used. The two most common are discussed next.

Organization of GAMS Programs

One common style of organizing GAMS statements places the data first, followed by the model and the solution statements.

Style 1:

Data:

Set declarations and definitions

Parameter declarations and definitions

Assignments

Displays

Model:

Variable declarations

Equation declarations

Equation definitions

Model definition(s)

Solution:

Solve(s)

Displays

In this style of organization, the sets are placed first. Then the data is specified with parameter, scalar, and table statements. Next, the model is defined with the variable declarations, equation declarations, equation definitions and one or more model statements. Finally, the model is / models are solved and the results are displayed. One can refer to the model trnsport as an example for this style.

A second style emphasizes the model by placing it before the data. This is a particularly useful order when the model is to be solved repeatedly with different data sets.

Style 2:

Model:

Set declarations

Parameter declarations

Variable declarations

Equation declaration

Equation definition

Model definition

Data:

Set definitions

Parameter definitions

Assignments

Displays

Solution:

Solve

Displays

Here, there is a separation between declaration and definition. For example, sets and parameters may be declared first with the following statements:

Set       c         "crops" ;
Parameter yield(c)  "crop yield" ;

Later they may be defined with the statements:

Set        c        / wheat, clover, beans / ;
Parameter  yield(c) / wheat     1.5
                      clover    6.5
                      beans     1.0  / ;

The first statement declares that the identifier c is a set and the later statement defines the elements in this set. Similarly, in the second statement yield is declared to be a parameter and later the corresponding data is given.

Note
Sets and parameters that are used in equations must be declared before the equations are specified. However, they may be defined after the equation specifications but before the specific equation is used in a solve statement. This gives GAMS programs substantial organizational flexibility.

Data Types and Definitions

Each symbol or identifier has exactly one of the following basic GAMS data types:

Note

Declarations have common characteristics. The following example has a typical structure:

Parameter    a(i,j)        "input-output matrix" ;

The structure is:

Keyword for data type - identifier (with index list) - explanatory text ;.

Note that the index list (or domain list) and the explanatory text are always optional characteristics. However, we recommend to specify the index list if the data type is defined over a domain; the advantages of this practice are outlined in section Domain Checking.

Note
Variables, sets, parameters and equations may be declared and defined over one or more indices or dimensions. Currently the maximum number of dimensions for all these data types is 20.

It is also recommend to add an explanatory text for reasons of clarity. For more on explanatory texts, see section Text below. Other examples for declarations follow:

Set         time     "time periods" ;
Model       turkey   "turkish fertilizer model" ;
Variables   x,y,z ;

Observe that in the last example a number of identifiers (separated by commas) is declared in one statement.

Language Items

Before proceeding with more language details, a few basic symbols need to be defined and the rules for recognizing and writing them in GAMS established. These basic symbols are often called lexical elements and form the building blocks of the language. They are:

Each of these items is discussed in detail in the following subsections.

Attention
As noted previously, GAMS is not case sensitive, so we may use any mix of lower and upper case.

Characters

A few characters are not allowed in a GAMS program, because they are illegal or ambiguous on some machines. Generally, all unprintable and control characters are illegal. The only place where any character is legal, is in an $ontext-$offtext block as illustrated in section Block Comments below. For completeness, the full set of legal characters are listed in Table 1. Note that most of the uncommon punctuation characters are not part of the language, but they may be used freely in the context of explanatory texts, comments, and labels (if quoted). Similarly, special language specific characters (e.g. ä, ß, à, é, ç, ț, ș) may also be used freely in explanatory texts, comments, and labels (if quoted).

Table 1: Legal Characters

Legal Characters Description
A to Z alphabet
a to z alphabet
0 to 9 numerals
+ plus
- minus
= equals
< less than
> greater than
( ) parenthesis
[ ] square brackets
{ } braces
' single quote
" double quote
\ back slash
/ slash
, comma
: colon
; semicolon
. dot
? question mark
! exclamation mark
space
_ underscore
& ampersand
^ circumflex
# pound sign
* asterisk
% percent
@ at
$ dollar
Note
Not every character listed above is allowed to be used in every place (for example, identifiers have certain limitations).

Reserved Words

GAMS, like other programming languages such as C and Java, uses reserved words (often also called keywords) that have predefined meanings. Users are in general not permitted to use these for their own definitions, neither as identifiers nor labels. The complete list of reserved words is given below. In addition, a small number of symbols constructed from non-alphanumeric characters have a meaning in GAMS.

Note
While it is not allowed to use reserved words as identifiers and labels in general, it is still possible (put not recommended) in certain cases which are explained in more detail further below.
Attention
Some of the keywords above can actually be used as an identifier (e.g. sameas). But if they get used as identifier, their built-in meaning as part of the GAMS language can not be accessed anymore.
Note
The words marked with * in the list above are no reserved words by default. However, they get a special meaning if the dollar control option $onEnd is set.

The following list shows words which have a special meaning in GAMS (e.g. they are part of the solve statement), but can be used as identifiers anyway:

The reserved non-alphanumeric symbols are:

Identifiers

Identifiers are the names given to sets, parameters, variables, models, etc. GAMS requires an identifier to start with a letter followed by more letters or digits. The length of an identifier is currently limited to 63 characters. Identifiers may only contain alphanumeric characters (letters or numbers) or underscores (_). Examples of legal identifiers are:

a   a15   revenue   x0051

Note that the following identifiers are incorrect:

15   $casg      milk&meat
Attention
A name used for one data type cannot be reused for another.

Labels

Labels are set elements. They may be up to 63 characters long and may be used in quoted or unquoted form.

The unquoted form is simpler to use but places restrictions on characters allowed, in that any unquoted label must start with a letter or digit and can only be followed by letters, digits, underscores (_) or the sign characters + and -. Examples of valid unquoted labels are:

Phos-Acid      1986      1952-53   A
September      H2S04      Line-1

Quotes can be used to delimit labels. Quoted labels may begin with and include any legal character. Either single or double quotes may be used but the closing quote has to match the opening quote. A label quoted with double quotes may contain a single quote (and vice versa). Most experienced users avoid quoted labels because they can be tedious to enter and confusing to read. There are a couple of special circumstances though. If we want to make a label stand out, we could put asterisks in it and indent it. A more subtle example is that GAMS keywords may be used as labels if they are quoted. So labels like parameter, put or while may be used if they are quoted. Some examples of quoted labels follow:

'  *TOTAL*'   "MATCH"   '10%-INCR'   '12" / FOOT'   "line 1"
Note
  • Labels do not have any numerical value. The label '1986' does not have the numerical value 1986 and the label '01' is different from the label '1'. One can access the numerical value of a label with the Set Attributes .val attribute.
  • Leading blanks in a label are significant and preserved while trailing blanks are trimmed. So ' label1' is different from 'label1', but 'label2 ' is identical to 'label2'.
  • Labels are, like the rest of the GAMS language, case insensitive. Note, however, that case insensitivity for labels applies only to ASCII characters. Labels with non-ASCII characters are case sensitive:
    * This defines two different labels
    Set i / "Ä", "ä" /; 
    display i;
    
    * This gives a compilation error
    Set j / "A", "a" /;
    

To summarize, set names are identifiers and set elements are labels. An overview of the rules for constructing identifiers and labels is given in the following table.

Identifiers Unquoted Labels Quoted Labels
Number of characters 63 63 63
Must begin with A letter A letter or a number Any character
Permitted special characters Underscore (_) Underscore (_) and the characters + and – Any but the starting quote

Table 2: Rules for constructing identifiers and labels

Text

Identifiers and set elements may also be associated with a line of descriptive text. This text is more than a comment: it is retained by GAMS and is displayed whenever results are written for the identifier.

Text may be quoted or unquoted. Quoted text may contain any character except the quote character used. Single or double quotes may be used but they must match. Text has to fit on one line and cannot exceed 255 characters in length. Text used in unquoted form must follow a number of mild restrictions. Unquoted text cannot start with a reserved word, '..' or '=' and must not include semicolons ';', commas ',', or slashes '/'. End of lines terminate a text. These restrictions are a direct consequence of the GAMS syntax and are usually followed naturally by the user. Some examples are:

this is text
final product shipment (tpy)
"quoted text containing otherwise illegal characters ; /,"
'use single quotes to put a "double" quote in text'

Numbers

Numeric values are entered in a style similar to that used in other computer languages

Attention
  • Blanks cannot be used in a number: GAMS treats a blank as a separator.
  • The common distinction between real and integer data types does not exist in GAMS. If a number is used without a decimal point it is still stored as a real number.

In addition, GAMS uses an extended range arithmetic that contains special symbols for infinity (INF), negative infinity (-INF), undefined (UNDF), epsilon (EPS), and not available (NA). The user cannot enter UNDF; it is only produced by an operation that does not have a proper result, such as division by zero. All the other special symbols may be entered and used as if they were ordinary numbers. For more details, see section Extended Range Arithmetic.

The following example shows various legal ways of entering numbers:

  0      156.70   -135      .095     1. 
  2e10   2e+10    15.e+10   .314e5   +1.7 
  0.0    .0       0.        INF      -INF 
  EPS    NA

The letter e denotes the well-known scientific notation allowing convenient representation of very large or small numbers. For example,

  1e-5 = 1 * 10^{-5} = 0.00001;
  3.56e6 = 3.56 * 10^6 = 3,560,000;
Note
  • GAMS uses a smaller range of numbers than many computers are able to handle. This has been done to ensure that GAMS programs will behave in the same way on a wide variety of machines, including personal computers. GAMS will create an error if a number with an absolute value greater or equal to 1.0e+300 is used.
  • A number may be entered with up to 16 significant digits. The dollar control option $offDigit can be used to control the behavior if this number is exceeded.

Delimiters

As mentioned before, statements are separated by a semicolon ';'. However, if the next statement begins with a reserved word (often called keyword in succeeding chapters), then GAMS does not require that the semicolon is used.

The characters comma ',' and slash '/' are used as delimiters in data lists, to be introduced later. The comma terminates a data element (as does an end-of-line) and the slash terminates a data list.

Comments

A comment is an explanatory text that is not processed or retained by the computer. There are several ways to include comments in a GAMS program.

Blank Lines

The user may freely enter blank lines to set off certain sections and enhance readability. For example, in trnsport there are blank lines between the different parameters:

  Sets
       i   "canning plants"   / seattle, san-diego /
       j   "markets"          / new-york, chicago, topeka / ;

  Parameters

       a(i)  "capacity of plant i in cases"
         /    seattle     350
              san-diego   600  /

       b(j)  "demand at market j in cases"
         /    new-york    325
              chicago     300
              topeka      275  / ;

Single Line Comments

Users may insert a single line comment on any line by placing an asterisk * in column 1. The text that follows the asterisk is the comment and may contain GAMS reserved words, messages or any other content. It is completely ignored by the GAMS compiler. Note that several successive lines may be single line comments as in the example below.

The default asterisk * may be replaced by other symbols. GAMS provides the dollar control option $comment to customize the comment character (for more on dollar control options, see chapter Dollar Control Options). The new comment character cannot be used in column 1 as before, since now it has a special meaning. The change of comment character should be used with great care. An example can be seen here:

*normal comment
*next line is a deactivated GAMS statement
*  x=sum(I,z(i));
$comment !
!comment with new character
$comment *
*now we are back to how it should be

In the fourth line, the new comment character ! replaces the GAMS default * as the comment delimiter. Note that single line comments appear in the echo print of the GAMS output as numbered lines. For details see section The Echo Print of the Input File.

Block Comments

For longer comments special 'block' delimiters may be used that cause GAMS to ignore an entire section of the program. The dollar control option $ontext marks the beginning of the comment block and the option $offtext marks the end. Note that the $ symbol must be in the first character position. The example below illustrates the use of the block comment and also contains some useful information. For more on dollar control options, see chapter Dollar Control Options.

$ontext
Following a $ontext directive in column 1 all lines are
ignored by GAMS but printed on the output file until the matching $offtext is encountered, also
in column 1. This facility is often used to logically remove parts of programs
that are not used every time, such as statements producing voluminous reports.
Every $ontext must have a matching $offtext in the same file
$offtext

Note that block comments appear in the echo print without line numbers. For details see section The Echo Print of the Input File.

End-of-Line Comments

Comments may also be placed at the end of a line that contains GAMS code. The dollar control option $onEolCom activates end-of-line comments. The default symbol to indicate that the comment begins is a double exclamation mark !!. This symbol may be reset with the option $eolCom followed by the desired symbol which may be one character or a two-character sequence. The following example serves as illustration. For more on dollar control options, see chapter Dollar Control Options.

Scalar x /0/;
$onEolCom
x=x+1;       !! eol comment
x = x        !! eol comment in line of GAMS statement, where the GAMS statement continues  to the next line
   +1;
$eolCom &&
x=x+1;       && eol comment with new symbol

Note that the option to add end-of-line comments may be deactivated with the dollar control option $offEolCom. End-of-line comments appear in the echo print on the appropriate lines. For details see section The Echo Print of the Input File.

In-Line Comments

Comments may also appear in a line of GAMS code. The dollar control option $onInline activates in-line comments. By default, the in-line comment symbols are set to the two character pairs ' \(/*\)' and ' \(*/\)', where ' \(/*\)' indicates that the in-line comment begins and ' \(*/\)' indicates that the in-line comment ends. The comment may span lines till the end-of-comment characters are encountered. The in-line comment symbols may be reset with the option $inLineCom followed by the desired pair of characters. The following example serves as illustration. For more on dollar control options, see chapter Dollar Control Options.

Scalar x /0/;
$onInLine
x=x      /* in-line comment*/ +1;
x=x      /* in-line comment in line
            that continues to next line */
   +1;
$inLineCom /&  &/
x=x      /& in-line comment with new character &/ +1;

Note that the option to add in-line comments may be deactivated with the dollar control option $offInline. In-line comments appear in the echo print on the appropriate lines. For details see section The Echo Print of the Input File. Note that in-line comments may be allowed to be nested using the dollar control option $onNestCom.

Outside Margin Comments

GAMS provides the facility to define margins. The active code is within the margins, everything outside the set margins is ignored by the compiler and treated as comment. The dollar control option $onMargin activates margin marking and $offMargin deactivates it. The option $minCol is used to specify the first column, where GAMS code that is to be compiled may appear. Similarly, the option $maxCol is used to specify the last column for GAMS code. The following example shows how this works. For more on dollar control options, see chapter Dollar Control Options.

$ontext
         1         2         3         4         5         6
123456789012345678901234567890123456789012345678901234567890
$offtext

$onMargin minCol 20 maxCol 45
Now I have          Set i plant /US, UK/     This defines i
turned on the       Scalar x / 3.145 /       A scalar example.
margin marking.     Parameter a, b;          Define some
                                             parameters.
$offMargin

The text before column 20 and after column 45 is treated as a comment. Note that the full content of the lines is copied to the echo print, including everything outside the margins. For details see section The Echo Print of the Input File.

Hidden Comments

Finally, GAMS also allows hidden comments, that are not copied to the echo print of the GAMS output file. These comments contain information that is only relevant for the person manipulating the file. They are single line comments starting with the dollar control option $hidden. An example follows. For more on dollar control options, see chapter Dollar Control Options.

$hidden a comment I do not want in LST file
set a /a1,a2/;
set b /a2,c2/;
set c /a3,d3/;

Summary

This completes the discussion of the components of the GAMS language. Many unfamiliar terms used in this chapter are further explained in the Glossary.