%* gmpl.texi *%

\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename gmpl.info
@settitle Modeling Language GNU MathProg
@c %**end of header

@copying
The GLPK package is part of the GNU Project released under the aegis of
GNU.

Copyright @copyright{} 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
2008, 2009, 2010 Andrew Makhorin, Department for Applied Informatics,
Moscow Aviation Institute, Moscow, Russia. All rights reserved.

Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
02110-1301, USA.

Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
entire resulting derived work is distributed under the terms of
a permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end copying

@dircategory Scientific software
@direntry
* gmpl: (gmpl).                 GNU MathProg Language Reference
@end direntry

@titlepage
@title Modeling Language GNU MathProg
@subtitle Language Reference
@subtitle Draft Edition, for GLPK Version 4.42
@subtitle January 2010
@author Andrew Makhorin
Moscow Aviation Institute, Moscow, Russia
@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage

@contents

@ifnottex
@node Top
@top GNU MathProg Language Reference
@end ifnottex

@menu
* Introduction::
* Coding model description::
* Expressions::
* Statements::
* Model data::
* Date and time functions::
* Solving models with glpsol::
* Example model description::
* Acknowledgements::
@end menu

@node Introduction
@chapter Introduction

@menu
* Linear programming problem::
* Model objects::
* Structure of model description::
@end menu

@dfn{GNU MathProg} is a modeling language intended for describing linear
mathematical programming models.@footnote{The GNU MathProg language is a
subset of the AMPL language. Its GLPK implementation is mainly based on
the paper: @emph{Robert@tie{}Fourer}, @emph{David@tie{}M.@tie{}Gay},
and @emph{Brian@tie{}W.@tie{}Kernighan}, ``A Modeling Language for
Mathematical Programming.'' @emph{Management Science} 36 (1990)
pp.@tie{}519-54.}

@indent
Model descriptions written in the GNU MathProg language consist of a set
of statements and data blocks constructed by the user from the language
elements described in this document.

In a process called translation, a program called the model translator
analyzes the model description and translates it into internal data
structures, which may be then used either for generating mathematical
programming problem instance or directly by a program called the solver
to obtain numeric solution of the problem.

@node Linear programming problem
@section Linear programming problem

In MathProg it is assumed that the linear programming (LP) problem has
the following statement:

@iftex
@quotation
@quotation
@quotation
minimize (or maximize)
@tex
$$z=c_1x_1+c_2x_2+\dots+c_nx_n+c_0\eqno(1)$$
@end tex
subject to linear constraints
@tex
$$\matrix{
L_1\leq a_{11}x_1+a_{12}x_2+\dots+a_{1n}x_n\leq U_1\cr
L_2\leq a_{21}x_1+a_{22}x_2+\dots+a_{2n}x_n\leq U_2\cr
.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\cr
L_m\leq a_{m1}x_1+a_{m2}x_2+\dots+a_{mn}x_n\leq U_m\cr
}\eqno(2)$$
@end tex
and bounds of variables
@tex
$$\matrix{
l_1\leq x_1\leq u_1\cr
l_2\leq x_2\leq u_2\cr
.\ \ .\ \ .\ \ .\cr
l_n\leq x_n\leq u_n\cr
}\eqno(3)$$
@end tex
@end quotation
@end quotation
@end quotation

@noindent
where:
@multitable @columnfractions .20 .80
@item @math{x_1}, @math{x_2}, @dots, @math{x_n} @tab are variables;
@item @math{z} @tab is the objective function;
@item @math{c_1}, @math{c_2}, @dots, @math{c_n} @tab are coefficients of
the objective function;
@item @math{c_0} @tab is the constant term (``shift'') of the objective
function;
@item @math{a_{11}}, @math{a_{12}}, @dots, @math{a_{mn}} @tab are
constraint coefficients;
@item @math{L_1}, @math{L_2}, @dots, @math{L_m} @tab are lower
constraint bounds;
@item @math{U_1}, @math{U_2}, @dots, @math{U_m} @tab are upper
constraint bounds;
@item @math{l_1}, @math{l_2}, @dots, @math{l_n} @tab are lower bounds of
variables;
@item @math{u_1}, @math{u_2}, @dots, @math{u_n} @tab are upper bounds of
variables.
@end multitable
@end iftex

@ifnottex
@quotation
Minimize (or maximize)

@quotation
@i{z} = @i{c}1 @i{x}1 + @i{c}2 @i{x}2 + @dots{} + @i{cn xn} + @i{c}0
@end quotation

subject to linear constraints

@quotation
@i{L}1 <= @i{a}11 @i{x}1 + @i{a}12 @i{x}2 + @dots{} + @i{a}1@i{n} @i{xn}
<= @i{U}1 @*
@i{L}2 <= @i{a}21 @i{x}1 + @i{a}22 @i{x}2 + @dots{} + @i{a}2@i{n} @i{xn}
<= @i{U}2 @*
. . . . . @*
@i{Lm} <= @i{am}1 @i{x}1 + @i{am}2 @i{x}2 + @dots{} + @i{amn} @i{xn} <=
@i{Um}
@end quotation

and bounds of variables

@quotation
@i{l}1 <= @i{x}1 <= @i{u}1 @*
@i{l}2 <= @i{x}2 <= @i{u}2 @*
. . . . . @*
@i{ln} <= @i{xn} <= @i{un}
@end quotation
@end quotation

@multitable @columnfractions .30 .70
@item where:
@item @i{x}1, @i{x}2, @dots{}, @i{xn} @tab are variables;
@item @i{z} @tab is the objective function;
@item @i{c}1, @i{c}2, @dots{}, @i{cn} @tab are coefficients of the
objective function;
@item @i{c}0 @tab is the constant term (``shift'') of the objective
function;
@item @i{a}11, @i{a}12, @dots{}, @i{amn} @tab are constraint
coefficients;
@item @i{L}1, @i{L}2, @dots{}, @i{Lm} @tab are lower constraint bounds;
@item @i{U}1, @i{U}2, @dots{}, @i{Um} @tab are upper constraint bounds;
@item @i{l}1, @i{l}2, @dots{}, @i{ln} @tab are lower bounds of
variables;
@item @i{u}1, @i{u}2, @dots{}, @i{un} @tab are upper bounds of
variables.
@end multitable
@end ifnottex

@page

Bounds of variables and constraint bounds can be finite as well as
infinite. Besides, lower bounds can be equal to corresponding upper
bounds. Thus, the following types of variables and constraints are
allowed:

@iftex
@quotation
@multitable @columnfractions .25 .75
@item @math{-@infty<x<+@infty} @tab Free (unbounded) variable
@item @math{x@geq l} @tab Variable with lower bound
@item @math{x@leq u} @tab Variable with upper bound
@item @math{l@leq x@leq u} @tab Double-bounded variable
@item @math{x=l@ (=u)} @tab Fixed variable
@end multitable

@multitable @columnfractions .25 .75
@item @math{-@infty<@sum a_jx_j<+@infty} @tab Free (unbounded) linear
form
@item @math{@sum a_jx_j@geq L} @tab Inequality constraint ``greater than
or equal to''
@item @math{@sum a_jx_j@leq U} @tab Inequality constraint ``less than or
equal to''
@item @math{L@leq@sum a_jx_j@leq U} @tab Double-bounded inequality
constraint
@item @math{@sum a_jx_j=L@ (=U)} @tab Equality constraint
@end multitable
@end quotation
@end iftex

@ifnottex
@quotation
@multitable @columnfractions .40 .60
@item @minus{}inf < @i{x} < +inf @tab Free (unbounded) variable
@item @i{x} >= @i{l} @tab Variable with lower bound
@item @i{x} <= @i{u} @tab Variable with upper bound
@item @i{l} <= @i{x} <= @i{u} @tab Double-bounded variable
@item @i{x} = @i{l} (= @i{u}) @tab Fixed variable
@item @tab
@item @minus{}inf < sum @i{aj} @i{xj} < +inf @tab Free (unbounded)
linear form
@item sum @i{aj} @i{xj} >= @i{L} @tab Inequality constraint ``greater
than or equal to''
@item sum @i{aj} @i{xj} <= @i{U} @tab Inequality constraint ``less than
or equal to''
@item @i{L} <= sum @i{aj} @i{xj} <= @i{U} @tab Double-bounded inequality
constraint
@item sum @i{aj} @i{xj} = @i{L} (= @i{U}) @tab Equality constraint
@end multitable
@end quotation
@end ifnottex

In addition to pure LP problems MathProg allows mixed integer linear
programming (MIP) problems, where some (or all) structural variables are
restricted to be integer.

@node Model objects
@section Model objects

In MathProg the model is described in terms of sets, parameters,
variables, constraints, and objectives, which are called @dfn{model
objects}.

The user introduces particular model objects using the language
statements. Each model object is provided with a symbolic name that
uniquely identifies the object and is intended for referencing purposes.

Model objects, including sets, can be multidimensional arrays built
over indexing sets. Formally, @i{n}-dimensional array @i{A} is the
mapping:
@iftex
@tex
$$A:\Delta\rightarrow\Xi,\eqno(4)$$
@end tex
where @math{@Delta@subseteq S_1@times S_2@times@dots@times S_n} is a
subset of the Cartesian product of indexing sets, @math{@Xi} is a set of
the array members. In MathProg the set @math{@Delta} is called
@dfn{subscript domain}. Its members are @math{n}-tuples
@math{(i_1,i_2,@dots,i_n)}, where @math{i_1@in S_1}, @math{i_2@in S_2},
@dots, @math{i_n@in S_n}.
@end iftex

@ifnottex
@quotation
@i{A} : D @minus{}> X,
@end quotation

@noindent
where D within
@i{S}1@tie{}x@tie{}@i{S}2@tie{}x@tie{}@dots{}@tie{}x@tie{}@i{Sn} is a
subset of the Cartesian product of indexing sets, X is a set of the
array members. In MathProg the set D is called @dfn{subscript domain}.
Its members are @i{n}-tuples
(@i{i}1,@tie{}@i{i}2,@tie{}@dots{},@tie{}@i{in}), where
@i{i}1@tie{}in@tie{}@i{S}1, @i{i}2@tie{}in@tie{}@i{S}2, @dots{},
@i{in}@tie{}in@tie{}@i{Sn}.
@end ifnottex

If @i{n} = 0, the Cartesian product above has exactly one element
(namely, 0-tuple), so it is convenient to think scalar objects as
0-dimensional arrays which have one member.

The type of array members is determined by the type of corresponding
model object as follows:

@quotation
@multitable @columnfractions .20 .80
@item @i{Model object} @tab @i{Array member}
@item Set @tab Elemental plain set
@item Parameter @tab Number or symbol
@item Variable @tab Elemental variable
@item Constraint @tab Elemental constraint
@item Objective @tab Elemental objective
@end multitable
@end quotation

In order to refer to a particular object member the object should be
provided with subscripts. For example, if @i{a} is 2-dimensional
parameter built over
@iftex
@math{I@times J},
@end iftex
@ifnottex
@i{I}@tie{}x@tie{}@i{J},
@end ifnottex
a reference to its particular
member can be written as @i{a}[@i{i},@tie{}@i{j}], where
@iftex
@math{i@in I} and @math{j@in J}.
@end iftex
@ifnottex
@i{i}@tie{}in@tie{}@i{I} and @i{j}@tie{}in@tie{}@i{J}.
@end ifnottex
It is understood that scalar objects being 0-dimensional need no
subscripts.

@node Structure of model description
@section Structure of model description

It is sometimes desirable to write a model which, at various points,
may require different data for each problem to be solved using that
model. For this reason in MathProg the model description consists of
two parts: model section and data section.

@dfn{Model section} is a main part of the model description that
contains declarations of model objects and is common for all problems
based on the corresponding model.

@dfn{Data section} is an optional part of the model description that
contains data specific for a particular problem.

Depending on what is more convenient model and data sections can be
placed either in one file or in two separate files. The latter feature
allows to have arbitrary number of different data sections to be used
with the same model section.

@node Coding model description
@chapter Coding model description

@menu
* Symbolic names::
* Numeric literals::
* String literals::
* Keywords::
* Delimiters::
* Comments::
@end menu

Model description is coded in plain text format using ASCII character
set. Valid characters acceptable in the model description are the
following:

@itemize @bullet
@item alphabetic characters:

@quotation
@verb{|A B C D E F G H I J K L M N O P Q R S T U V W X Y Z|}@*
@verb{|a b c d e f g h i j k l m n o p q r s t u v w x y z _|}
@end quotation

@item numeric characters:

@quotation
@verb{|0 1 2 3 4 5 6 7 8 9|}
@end quotation

@item special characters:

@quotation
@verb{$! " # & ' ( ) * + , - . / : ; < = > [ ] ^ { | }$}
@end quotation

@item white-space characters:

@quotation
@verb{|SP HT CR NL VT FF|}
@end quotation
@end itemize

Within string literals and comments any ASCII characters (except control
characters) are valid.

White-space characters are non-significant. They can be used freely
between lexical units to improve readability of the model description.
They are also used to separate lexical units from each other if there
is no other way to do that.

Syntactically model description is a sequence of lexical units in the
following categories:

@itemize @bullet
@item symbolic names;
@item numeric literals;
@item string literals;
@item keywords;
@item delimiters;
@item comments.
@end itemize

The lexical units of the language are discussed below.

@node Symbolic names
@section Symbolic names

@dfn{Symbolic name} consists of alphabetic and numeric characters, the
first of which must be alphabetic. All symbolic names are distinct (case
sensitive).

@strong{Examples}

@example
alpha123
This_is_a_name
_P123_abc_321
@end example

Symbolic names are used to identify model objects (sets, parameters,
variables, constraints, objectives) and dummy indices.

All symbolic names (except names of dummy indices) must be unique,
i.e. the model description must have no objects with the same name.
Symbolic names of dummy indices must be unique within the scope, where
they are valid.

@node Numeric literals
@section Numeric literals

@dfn{Numeric literal} has the form @i{xx}@code{E}@i{syy}, where @i{xx}
is a real number with optional decimal point, @i{s} is the sign @code{+}
or @code{-}, @i{yy} is an integer decimal exponent. The letter @code{E}
is case insensitive and can be coded as @code{e}.

@strong{Examples}

@example
123
3.14159
56.E+5
.78
123.456e-7
@end example

Numeric literals are used to represent numeric quantities. They have
obvious fixed meaning.

@node String literals
@section String literals

@dfn{String literal} is a sequence of arbitrary characters enclosed
either in single quotes or in double quotes. Both these forms are
equivalent.

If the single quote is a part of a string literal enclosed in single
quotes, it must be coded twice. Analogously, if the double quote is
a part of string literal enclosed in double quotes, it must be coded
twice.

@strong{Examples}

@example
'This is a string'
"This is another string"
'1 + 2 = 3'
'That''s all'
"She said: ""No"""
@end example

String literals are used to represent symbolic quantities.

@node Keywords
@section Keywords

@dfn{Keyword} is a sequence of alphabetic characters and possibly some
special characters. All keywords fall into two categories: reserved
keywords, which cannot be used as symbolic names, and non-reserved
keywords, which being recognized by context can be used as symbolic
names.

Reserved keywords are the following:

@example
and      else     mod      union
by       if       not      within
cross    in       or
diff     inter    symdiff
div      less     then
@end example

Non-reserved keywords are described in following sections.

All the keywords have fixed meaning, which will be explained on
discussion of corresponding syntactic constructions, where the keywords
are used.

@node Delimiters
@section Delimiters

@dfn{Delimiter} is either a single special character or a sequence of
two special characters as follows:

@example
+    ^    ==   !    :    )
-    &    >=   &&   ;    [
*    <    >    ||   :=   |
/    <=   <>   .    ..   @{
**   =    !=   ,    (    @}
@end example

If delimiter consists of two characters, there must be no spaces between
the characters.

All the delimiters have fixed meaning, which will be explained on
discussion corresponding syntactic constructions, where the delimiters
are used.

@node Comments
@section Comments

For documenting purposes the model description can be provided with
@dfn{comments}, which have two different forms. The first form is
a single-line comment, which begins with the character @code{#} and
extends until end of line. The second form is a comment sequence,
which is a sequence of any characters enclosed between @code{/*} and
@code{*/}.

@strong{Examples}

@example
set s@{1..10@}; # This is a comment
/* This is another comment */
@end example

Comments are ignored by the model translator and can appear anywhere in
the model description, where white-space characters are allowed.

@node Expressions
@chapter Expressions

@menu
* Numeric expressions::
* Symbolic expressions::
* Indexing expressions and dummy indices::
* Set expressions::
* Logical expressions::
* Linear expressions::
@end menu

@dfn{Expression} is a rule for computing a value. In model description
expressions are used as constituents of certain statements.

In general case expressions consist of operands and operators.

Depending on the type of the resultant value all expressions fall into
the following categories:

@itemize @bullet
@item numeric expressions;
@item symbolic expressions;
@item indexing expressions;
@item set expressions;
@item logical expressions;
@item linear expressions.
@end itemize

@node Numeric expressions
@section Numeric expressions

@dfn{Numeric expression} is a rule for computing a single numeric value
represented in the form of floating-point number.

The primary numeric expression may be a numeric literal, dummy index,
unsubscripted parameter, subscripted parameter, built-in function
reference, iterated numeric expression, conditional numeric expression,
or another numeric expression enclosed in parentheses.

@strong{Examples}

@quotation
@multitable @columnfractions .60 .40
@item @verb{|1.23|} @tab (numeric literal)
@item @verb{|j|} @tab (dummy index)
@item @verb{|time|} @tab (unsubscripted parameter)
@item @verb{|a['May 2003',j+1]|} @tab (subscripted parameter)
@item @verb{|abs(b[i,j])|} @tab (function reference)
@item @verb{|sum{i in S diff T} alpha[i] * b[i,j]|} @tab (iterated
expression)
@item @verb{|if i in I then 2 * p else q[i+1]|} @tab (conditional
expression)
@item @verb{|(b[i,j] + .5 * c)|} @tab (parenthesized expression)
@end multitable
@end quotation

More general numeric expressions containing two or more primary numeric
expressions may be constructed by using certain arithmetic operators.

@strong{Examples}

@example
j+1
2 * a[i-1,j+1] - b[i,j]
sum@{j in J@} a[i,j] * x[j] + sum@{k in K@} b[i,k] * x[k]
(if i in I then 2 * p else q[i+1]) / (a[i,j] + 1.5)
@end example

@subheading Numeric literals

If the primary numeric expression is a numeric literal, the resultant
value is obvious.

@subheading Dummy indices

If the primary numeric expression is a dummy index, the resultant value
is current value assigned to the dummy index.

@subheading Unsubscripted parameters

If the primary numeric expression is an unsubscripted parameter (which
must be 0-dimen@-sional), the resultant value is the value of the
parameter.

@subheading Subscripted parameters

The primary numeric expression, which refers to a subscripted parameter,
has the following syntactic form:

@iftex
@quotation
@math{name[i_1,i_2,@dots,i_n],}
@end quotation

@noindent
where @math{name} is the symbolic name of the parameter, @math{i_1},
@math{i_2}, @dots, @math{i_n} are subscripts.
@end iftex

@ifnottex
@quotation
@i{name}[@i{i}1, @i{i}2, @dots{}, @i{in}],
@end quotation

@noindent
where @i{name} is the symbolic name of the parameter, @i{i}1, @i{i}2,
@dots{}, @i{in} are subscripts.
@end ifnottex

Each subscript must be a numeric or symbolic expression. The number of
subscripts in the subscript list must be the same as the dimension of
the parameter with which the subscript list is associated.

Actual values of subscript expressions are used to identify a particular
member of the parameter that determines the resultant value of the
primary expression.

@subheading Function references

In MathProg there are the following built-in functions which may be used
in numeric expressions:

@quotation
@multitable @columnfractions .25 .75
@item @verb{|abs|}(@i{x}) @tab absolute value
@item @verb{|atan|}(@i{x}) @tab trigonometric arctangent
arctan@tie{}@i{x} (in radians)
@item @verb{|atan|}(@i{y},@tie{}@i{x}) @tab trigonometric arctangent
arctan@tie{}@i{y}/@i{x} (in radians)
@item @verb{|card|}(@i{x}) @tab cardinality (the number of elements)
of set @i{x}
@item @verb{|ceil|}(@i{x}) @tab smallest integer not less than @i{x}
(``ceiling of @i{x}'')
@item @verb{|cos|}(@i{x}) @tab trigonometric cosine cos@tie{}@i{x}
(in radians)
@item @verb{|exp|}(@i{x}) @tab base-@i{e} exponential
@iftex
@math{e^x}
@end iftex
@ifnottex
@i{e}^@i{x}
@end ifnottex
@item @verb{|floor|}(@i{x}) @tab largest integer not greater than @i{x}
(``floor of @i{x}'')
@item @verb{|gmtime|}() @tab the number of seconds elapsed since
00:00:00 Jan 1, 1970,
@item @tab Coordinated Universal Time@footnote{For details
@xref{Obtaining current calendar time}.}
@item @verb{|length|}(@i{x}) @tab length of character string @i{x}
@item @verb{|log|}(@i{x}) @tab natural logarithm log@tie{}@i{x}
@item @verb{|log10|}(@i{x}) @tab common (decimal) logarithm
@iftex
@math{@log_{10}x}
@end iftex
@ifnottex
log10@tie{}@i{x}
@end ifnottex
@iftex
@item @verb{|max|}@math{(x_1,x_2,@dots,x_n)} @tab the largest of values
@math{x_1}, @math{x_2}, @dots, @math{x_n}
@item @verb{|min|}@math{(x_1,x_2,@dots,x_n)} @tab the smallest of values
@math{x_1}, @math{x_2}, @dots, @math{x_n}
@end iftex
@ifnottex
@item @verb{|max|}(@i{x}1, @dots{}, @i{xn}) @tab the largest of values
@i{x}1, @dots{}, @i{xn}
@item @verb{|min|}(@i{x}1, @dots{}, @i{xn}) @tab the smallest of values
@i{x}1, @dots{}, @i{xn}
@end ifnottex
@item @verb{|round|}(@i{x}) @tab rounding @i{x} to nearest integer
@item @verb{|round|}(@i{x},@tie{}@i{n}) @tab rounding @i{x} to @i{n}
fractional decimal digits
@item @verb{|sin|}(@i{x}) @tab trigonometric sine sin@tie{}@i{x} (in
radians)
@item @verb{|sqrt|}(@i{x}) @tab square root
@iftex
@math{@sqrt{x}}
@end iftex
@ifnottex
of @i{x}
@end ifnottex
@item @verb{|str2time|}(@i{s},@tie{}@i{f}) @tab converting character
string @i{s} to calendar time@footnote{For details @xref{Converting
character string to calendar time}.}
@item @verb{|trunc|}(@i{x}) @tab truncating @i{x} to nearest integer
@item @verb{|trunc|}(@i{x},@tie{}@i{n}) @tab truncating @i{x} to @i{n}
fractional decimal digits
@item @verb{|Irand224|}() @tab pseudo-random integer uniformly
distributed in @math{[0,2^{24})}
@item @verb{|Uniform01|}() @tab pseudo-random number uniformly
distributed in @math{[0,1)}
@item @verb{|Uniform|}(@i{a},@tie{}@i{b}) @tab pseudo-random number
uniformly distributed in [@i{a},@tie{}@i{b})
@item @verb{|Normal01|}@math{()} @tab Gaussian pseudo-random variate
with
@iftex
@math{@mu=0} and @math{@sigma=1}
@end iftex
@ifnottex
mu@tie{}=@tie{}0 and sigma@tie{}=@tie{}1
@end ifnottex
@item
@iftex
@verb{|Normal|}@math{(@mu,@sigma)}
@end iftex
@ifnottex
@verb{|Normal|}(mu,@tie{}sigma)
@end ifnottex
@tab Gaussian pseudo-random
variate with given
@iftex
@math{@mu} and @math{@sigma}
@end iftex
@ifnottex
mu and sigma
@end ifnottex
@end multitable
@end quotation

Arguments of all built-in functions, except @code{card}, @code{length},
and @code{str2time}, must be numeric expressions. The argument of
@code{card} must be a set expression. The argument of @code{length} and
both arguments of @code{str2time} must be symbolic expressions.

The resultant value of the numeric expression, which is a function
reference, is the result of applying the function to its argument(s).

Note that each pseudo-random generator function have a latent argument
(i.e. some internal state), which is changed whenever the function has
been applied. Thus, if the function is applied repeatedly even to
identical arguments, due to the side effect different resultant values
are always produced.

@subheading Iterated expressions

Iterated numeric expression is a primary numeric expression, which has
the following syntactic form:

@quotation
@var{iterated-operator} @var{indexing-expression} @var{integrand}
@end quotation

@noindent
where @var{iterated-operator} is the symbolic name of the iterated
operator to be performed (see below), @var{indexing expression} is an
indexing expression which introduces dummy indices and controls
iterating, @var{integrand} is a numeric expression that participates in
the operation.

In MathProg there are four iterated operators, which may be used in
numeric expressions:

@iftex
@quotation
@multitable @columnfractions .10 .15 .75
@item @verb{|sum|} @tab summation @tab
@math{@displaystyle@sum_{(i_1,@dots,i_n)@in@Delta}x(i_1,@dots,i_n)}
@item @verb{|prod|} @tab production @tab
@math{@displaystyle@prod_{(i_1,@dots,i_n)@in@Delta}x(i_1,@dots,i_n)}
@item @verb{|min|} @tab minimum @tab
@math{@displaystyle@min_{(i_1,@dots,i_n)@in@Delta}x(i_1,@dots,i_n)}
@item @verb{|max|} @tab maximum @tab
@math{@displaystyle@max_{(i_1,@dots,i_n)@in@Delta}x(i_1,@dots,i_n)}
@end multitable
@end quotation

@noindent
where @math{i_1}, @dots, @math{i_n} are dummy indices introduced in the
indexing expression, @math{@Delta} is the domain, a set of
@math{n}-tuples specified by the indexing expression which defines
particular values assigned to the dummy indices on performing the
iterated operation, @math{x(i_1,@dots,i_n)} is the integrand, a numeric
expression whose resultant value depends on the dummy indices.
@end iftex

@ifnottex
@quotation
@multitable @columnfractions .10 .15 .75
@item @verb{|sum|} @tab summation @tab
of @i{x}(@i{i}1,@tie{}@dots{},@tie{}@i{in}) for all
(@i{i}1,@tie{}@dots{},@tie{}@i{in})@tie{}in@tie{}D
@item @verb{|prod|} @tab production @tab
of @i{x}(@i{i}1,@tie{}@dots{},@tie{}@i{in}) for all
(@i{i}1,@tie{}@dots{},@tie{}@i{in})@tie{}in@tie{}D
@item @verb{|min|} @tab minimum @tab
of @i{x}(@i{i}1,@tie{}@dots{},@tie{}@i{in}) for all
(@i{i}1,@tie{}@dots{},@tie{}@i{in})@tie{}in@tie{}D
@item @verb{|max|} @tab maximum @tab
of @i{x}(@i{i}1,@tie{}@dots{},@tie{}@i{in}) for all
(@i{i}1,@tie{}@dots{},@tie{}@i{in})@tie{}in@tie{}D
@end multitable
@end quotation

@noindent
where @i{i}1, @dots{}, @i{in} are dummy indices introduced in the
indexing expression, D is the domain, a set of @i{n}-tuples specified
by the indexing expression which defines particular values assigned to
the dummy indices on performing the iterated operation,
@i{x}(@i{i}1,@tie{}@dots{},@tie{}@i{in}) is the integrand, a numeric
expression whose resultant value depends on the dummy indices.
@end ifnottex

The resultant value of an iterated numeric expression is the result of
applying of the iterated operator to its integrand over all @i{n}-tuples
contained in the domain.

@subheading Conditional expressions

Conditional numeric expression is a primary numeric expression, which
has one of the following two syntactic forms:

@quotation
@verb{|if|} @i{b} @verb{|then|} @i{x} @verb{|else|} @i{y}

@verb{|if|} @i{b} @verb{|then|} @i{x}
@end quotation

@noindent
where @i{b} is an logical expression, @i{x} and @i{y} are numeric
expressions.

The resultant value of the conditional expression depends on the value
of the logical expression that follows the keyword @code{if}. If it
takes on the value @i{true}, the value of the conditional expression is
the value of the expression that follows the keyword @code{then}.
Otherwise, if the logical expression takes on the value @i{false}, the
value of the conditional expression is the value of the expression that
follows the keyword @code{else}. If the reduced form of the conditional
expression is used and the logical expression takes on the value
@i{false}, the resultant value of the conditional expression is zero.

@subheading Parenthesized expressions

Any numeric expression may be enclosed in parentheses that syntactically
makes it primary numeric expression.

Parentheses may be used in numeric expressions, as in algebra, to
specify the desired order in which operations are to be performed. Where
parentheses are used, the expression within the parentheses is evaluated
before the resultant value is used.

The resultant value of the parenthesized expression is the same as the
value of the expression enclosed within parentheses.

@subheading Arithmetic operators

In MathProg there are the following arithmetic operators, which may be
used in numeric expressions:

@quotation
@multitable @columnfractions .25 .75
@item @verb{|+|} @i{x} @tab unary plus
@item @verb{|-|} @i{x} @tab unary minus
@item @i{x} @verb{|+|} @i{y} @tab addition
@item @i{x} @verb{|-|} @i{y} @tab subtraction
@item @i{x} @verb{|less|} @i{y} @tab positive difference (if
@i{x}@tie{}<@tie{}@i{y} then 0 else @i{x}@tie{}@minus{}@tie{}@i{y})
@item @i{x} @verb{|*|} @i{y} @tab multiplication
@item @i{x} @verb{|/|} @i{y} @tab division
@item @i{x} @verb{|div|} @i{y} @tab quotient of exact division
@item @i{x} @verb{|mod|} @i{y} @tab remainder of exact division
@item @i{x} @verb{|**|} @i{y}, @i{x} @verb{|^|} @i{y} @tab
exponentiation (raise to power)
@end multitable
@end quotation

@noindent
where @i{x} and @i{y} are numeric expressions.

If the expression includes more than one arithmetic operator, all
operators are performed from left to right according to the hierarchy
of operations (see below) with the only exception that the exponentiaion
operators are performed from right to left.

The resultant value of the expression, which contains arithmetic
operators, is the result of applying the operators to their operands.

@subheading Hierarchy of operations

The following list shows the hierarchy of operations in numeric
expressions:

@quotation
@multitable @columnfractions .70 .30
@item @i{Operation} @tab @i{Hierarchy}
@item Evaluation of functions (@verb{|abs|}, @verb{|ceil|}, etc.) @tab
1st
@item Exponentiation (@verb{|**|}, @verb{|^|}) @tab 2nd
@item Unary plus and minus (@verb{|+|}, @verb{|-|}) @tab 3rd
@item Multiplication and division (@verb{|*|}, @verb{|/|}, @verb{|div|},
@verb{|mod|}) @tab 4th
@item Iterated operations (@verb{|sum|}, @verb{|prod|}, @verb{|min|},
@verb{|max|}) @tab 5th
@item Addition and subtraction (@verb{|+|}, @verb{|-|}, @verb{|less|})
@tab 6th
@item Conditional evaluation (@verb{|if|} @dots{} @verb{|then|} @dots{}
@verb{|else|}) @tab 7th
@end multitable
@end quotation

This hierarchy is used to determine which of two consecutive operations
is performed first. If the first operator is higher than or equal to the
second, the first operation is performed. If it is not, the second
operator is compared to the third, etc. When the end of the expression
is reached, all of the remaining operations are performed in the reverse
order.

@node Symbolic expressions
@section Symbolic expressions

@dfn{Symbolic expression} is a rule for computing a single symbolic
value represented in the form of character string.

The primary symbolic expression may be a string literal, dummy index,
unsubscripted parameter, subscripted parameter, built-in function
reference, conditional symbolic expression, or another symbolic
expression enclosed in parentheses.

It is also allowed to use a numeric expression as the primary symbolic
expression, in which case the resultant value of the numeric expression
is automatically converted to the symbolic type.

@strong{Examples}

@quotation
@multitable @columnfractions .60 .40
@item @verb{|'May 2003'|} @tab (string literal)
@item @verb{|j|} @tab (dummy index)
@item @verb{|p|} @tab (unsubscripted parameter)
@item @verb{|s['abc',j+1]|} @tab (subscripted parameter)
@item @verb{|substr(name[i],k+1,3)|} @tab (function reference)
@item @verb{|if i in I then s[i,j] else t[i+1]|} @tab (conditional
expression)
@item @verb{|((10 * b[i,j]) & '.bis')|} @tab (parenthesized expression)
@end multitable
@end quotation

More general symbolic expressions containing two or more primary
symbolic expressions may be constructed by using the concatenation
operator.

@strong{Examples}

@example
'abc[' & i & ',' & j & ']'
"from " & city[i] & " to " & city[j]
@end example

The principles of evaluation of symbolic expressions are completely
analogous to that ones given for numeric expressions (see above).

@subheading Function references

In MathProg there are the following built-in functions which may be used
in symbolic expressions:

@quotation
@multitable @columnfractions .25 .75
@item @verb{|substr|}(@i{x},@tie{}@i{y}) @tab substring of @i{x}
starting from position @i{y}
@item @verb{|substr|}(@i{x}, @i{y}, @i{z}) @tab substring of @i{x}
starting from position @i{y} and having length @i{z}
@item @verb{|time2str|}(@i{t}, @i{f}) @tab converting calendar time to
character string@footnote{For details see @xref{Converting calendar time
to character string}.}
@end multitable
@end quotation

The first argument of @code{substr} must be a symbolic expression while
its second and optional third arguments must be numeric expressions.

The first argument of @code{time2str} must be a numeric expression, and
its second argument must be a symbolic expression.

The resultant value of the symbolic expression, which is a function
reference, is the result of applying the function to its arguments.

@subheading Symbolic operators

Currently in MathProg there is the only symbolic operator:

@quotation
@i{x} @verb{|&|} @i{y}
@end quotation

@noindent
where @i{x} and @i{y} are symbolic expressions. This operator means
concatenation of its two symbolic operands, which are character strings.

@subheading Hierarchy of operations

The following list shows the hierarchy of operations in symbolic
expressions:

@quotation
@multitable @columnfractions .70 .30
@item @i{Operation} @tab @i{Hierarchy}
@item Evaluation of numeric operations @tab 1st-7th
@item Concatenation (@verb{|&|}) @tab 8th
@item Conditional evaluation (@verb{|if|} @dots{} @verb{|then|} @dots{}
@verb{|else|}) @tab 9th
@end multitable
@end quotation

This hierarchy has the same meaning as explained in Section ``Numeric
expressions''.

@node Indexing expressions and dummy indices
@section Indexing expressions and dummy indices

@dfn{Indexing expression} is an auxiliary construction, which specifies
a plain set of @math{n}-tuples and introduces dummy indices. It has two
syntactic forms:

@iftex
@quotation
@verb{|{|} @math{entry_1,entry_2,@dots,entry_m} @verb{|}|}

@verb{|{|} @math{entry_1,entry_2,@dots,entry_m} : @math{predicate}
@verb{|}|}
@end quotation

@noindent
where @math{entry_1,entry_2,@dots,entry_m} are indexing entries,
@math{predicate} is a logical expression which specifies an optional
predicate.
@end iftex

@ifnottex
@quotation
@verb{|{|} @var{entry}-1, @var{entry}-2, @dots{}, @var{entry}-@i{m}
@verb{|}|}

@verb{|{|} @var{entry}-1, @var{entry}-2, @dots{}, @var{entry}-@i{m} :
@var{predicate} @verb{|}|}
@end quotation

@noindent
where @var{entry}-1, @var{entry}-2, @dots{}, @var{entry}-@i{m} are
indexing entries, @var{predicate} is a logical expression which
specifies an optional predicate.
@end ifnottex

Each indexing entry in the indexing expression has one of the following
three forms:

@quotation
@i{t} @verb{|in|} @i{S}

@iftex
@math{(t_1,t_2,@dots,t_k)} @verb{|in|} @math{S}
@end iftex

@ifnottex
(@i{t}1, @i{t}2, @dots{}, @i{tk}) @verb{|in|} @math{S}
@end ifnottex

@i{S}
@end quotation

@noindent
where
@iftex
@math{t_1,t_2,@dots,t_k}
@end iftex
@ifnottex
@i{t}1, @i{t}2, @dots{}, @i{tk}
@end ifnottex
are indices, @i{S} is a set expression (discussed in the next section),
which specifies the basic set.

The number of indices in the indexing entry must be the same as the
dimension of the basic set @i{S}, i.e. if @i{S} consists of 1-tuples,
the first form must be used, and if @i{S} consists of @i{n}-tuples,
where @i{n}@tie{}>@tie{}1, the second form must be used.

If the first form of the indexing entry is used, the index @i{t} can
be a dummy index only. If the second form is used, the indices
@iftex
@math{t_1,t_2,@dots,t_k}
@end iftex
@ifnottex
@i{t}1, @i{t}2, @dots{}, @i{tk}
@end ifnottex
can be either dummy indices or some numeric or symbolic expressions,
where at least one index must be a dummy index. The third, reduced form
of the indexing entry has the same effect as if there were @i{t}
(if @i{S} is 1-dimensional) or
@iftex
@math{t_1,t_2,@dots,t_k}
@end iftex
@ifnottex
@i{t}1, @i{t}2, @dots{}, @i{tk}
@end ifnottex
(if @math{S} is @math{n}-dimensional) all specified as dummy indices.

@dfn{Dummy index} is an auxiliary model object, which acts like an
individual variable. Values assigned to dummy indices are components
of @i{n}-tuples from basic sets, i.e. some numeric and symbolic
quantities.

For referencing purposes dummy indices can be provided with symbolic
names. However, unlike other model objects (sets, parameters, etc.)
dummy indices do not need to be explicitly declared. Each
@emph{undeclared} symbolic name being used in the indexing position of
an indexing entry is recognized as the symbolic name of corresponding
dummy index.

Symbolic names of dummy indices are valid only within the scope of the
indexing expression, where the dummy indices were introduced. Beyond
the scope the dummy indices are completely inaccessible, so the same
symbolic names may be used for other purposes, in particular, to
represent dummy indices in other indexing expressions.

The scope of indexing expression, where implicit declarations of dummy
indices are valid, depends on the context, in which the indexing
expression is used:

@enumerate
@item If the indexing expression is used in iterated operator, its
scope extends until the end of the integrand.
@item If the indexing expression is used as a primary set expression,
its scope extends until the end of this indexing expression.
@item If the indexing expression is used to define the subscript domain
in declarations of some model objects, its scope extends until the end
of the corresponding statement.
@end enumerate

The indexing mechanism implemented by means of indexing expressions is
best explained by some examples discussed below.

Let there be three sets:

@quotation
@i{A} = @{4, 7, 9@}

@i{B} = @{(1,@i{Jan}), (1,@i{Feb}), (2,@i{Mar}), (2,@i{Apr}),
(3,@i{May}), (3,@i{Jun})@}

@i{C} = @{@i{a}, @i{b}, @i{c}@}
@end quotation

@noindent
where @i{A} and @i{C} consist of 1-tuples (singles), @i{B} consists of
2-tuples (doubles). And consider the following indexing expression:

@example
@{i in A, (j,k) in B, l in C@}
@end example

@noindent
where @i{i}, @i{j}, @i{k}, and @i{l} are dummy indices.

Although MathProg is not a procedural language, for any indexing
expression an equivalent algorithmic description could be given. In
particular, the algorithmic description of the indexing expression
above is the following:

@iftex
@quotation
@b{for all} @math{i@in A} @b{do}

@ @ @ @b{for all} @math{(j,k)@in B} @b{do}

@ @ @ @ @ @ @b{for all} @math{l@in C} @b{do}

@ @ @ @ @ @ @ @ @ @i{action};
@end quotation
@end iftex

@ifnottex
@example
for all i in A do
   for all (j,k) in B do
      for all l in C do
         action;
@end example
@end ifnottex

@noindent
where the dummy indices @i{i}, @i{j}, @i{k}, @i{l} are consecutively
assigned corresponding components of @i{n}-tuples from the basic sets
@i{A}, @i{B}, @i{C}, and @code{action} is some action that depends on
the context, where the indexing expression is used. For example, if the
@code{action} were printing current values of dummy indices, the output
would look like follows:

@iftex
@quotation
@tex
$\matrix{
i = 4 & j = 1 & k = Jan & l = a \cr
i = 4 & j = 1 & k = Jan & l = b \cr
i = 4 & j = 1 & k = Jan & l = c \cr
i = 4 & j = 1 & k = Feb & l = a \cr
i = 4 & j = 1 & k = Feb & l = b \cr
\dots & \dots & \dots   & \dots \cr
i = 9 & j = 3 & k = Jun & l = b \cr
i = 9 & j = 3 & k = Jun & l = c \cr
}$
@end tex
@end quotation
@end iftex

@ifnottex
@quotation
@multitable @columnfractions .15 .15 .15 .15
@item @i{i} = 4 @tab @i{j} = 1 @tab @i{k} = @i{Jan} @tab @i{l} = @i{a}
@item @i{i} = 4 @tab @i{j} = 1 @tab @i{k} = @i{Jan} @tab @i{l} = @i{b}
@item @i{i} = 4 @tab @i{j} = 1 @tab @i{k} = @i{Jan} @tab @i{l} = @i{c}
@item @i{i} = 4 @tab @i{j} = 1 @tab @i{k} = @i{Feb} @tab @i{l} = @i{a}
@item @i{i} = 4 @tab @i{j} = 1 @tab @i{k} = @i{Feb} @tab @i{l} = @i{b}
@item @dots{} @tab @dots{} @tab @dots{} @tab @dots{}
@item @i{i} = 9 @tab @i{j} = 3 @tab @i{k} = @i{Jun} @tab @i{l} = @i{b}
@item @i{i} = 9 @tab @i{j} = 3 @tab @i{k} = @i{Jun} @tab @i{l} = @i{c}
@end multitable
@end quotation
@end ifnottex

@page

Let the example indexing expression be used in the following iterated
operation:

@example
sum@{i in A, (j,k) in B, l in C@} p[i,j,k,l]
@end example

@noindent
where @i{p}[@i{i}, @i{j}, @i{k}, @i{l}] may be a 4-dimensional numeric
parameter or some numeric expression whose resultant value depends on
@i{i}, @i{j}, @i{k}, and @i{l}. In this case the action is summation,
so the resultant value of the primary numeric expression
@iftex
is:

@quotation
@math{@displaystyle@sum_{i@in A,(j,k)@in B,l@in C}(p_{ijkl}).}
@end quotation
@end iftex
@ifnottex
is the sum of @i{p}[@i{i}, @i{j}, @i{k}, @i{l}], where summation is
performed over all @i{i}@tie{}in@tie{}@i{A},
(@i{j},@i{k})@tie{}in@tie{}@i{B}, and @i{l}@tie{}in@tie{}@i{C}.
@end ifnottex

Now let the example indexing expression be used as a primary set
expression. In this case the action is gathering all 4-tuples
(quadruples) of the form (@i{i}, @i{j}, @i{k}, @i{l}) in one set, so the
resultant value of such operation is simply the Cartesian product of the
basic sets:

@iftex
@quotation
@math{A@times B@times C=@{(i,j,k,l):i@in A,(j,k)@in B,l@in C@}.}
@end quotation
@end iftex

@ifnottex
@quotation
@i{A} x @i{B} x @i{C} = @{(@i{i},@i{j},@i{k},@i{l}) :
@i{i}@tie{}in@tie{}@i{A}, (@i{j},@i{k})@tie{}in@tie{}@i{B},
@i{l}@tie{}in@tie{}@i{C}@}
@end quotation
@end ifnottex

@noindent
Note that in this case the same indexing expression might be written
in the reduced form:

@example
@{A, B, C@}
@end example

@noindent
because the dummy indices @i{i}, @i{j}, @i{k}, and @i{l} are not
referenced and therefore their symbolic names are not needed.

Finally, let the example indexing expression be used as the subscript
domain in the declaration of a 4-dimensional model object, say, a
numeric parameter:

@example
par p@{i in A, (j,k) in B, l in C@} ... ;
@end example

@noindent
In this case the action is generating the parameter members, where each
member has the form @i{p}[@i{i},@tie{}@i{j},@tie{}@i{k},@tie{}@i{l}].

As was said above, some indices in the second form of indexing entries
may be numeric or symbolic expressions, not only dummy indices. In this
case resultant values of such expressions play role of some logical
conditions to select only that @i{n}-tuples from the Cartesian product
of basic sets, which satisfy these conditions.

Consider, for example, the following indexing expression:

@example
@{i in A, (i-1,k) in B, l in C@}
@end example

@noindent
where @i{i}, @i{k}, @i{l} are dummy indices, and @i{i}@minus{}1 is
a numeric expression. The algorithmic decsription of this indexing
expression is the following:

@iftex
@quotation
@b{for all} @math{i@in A} @b{do}

@ @ @ @b{for all} @math{(j,k)@in B} @b{and} @math{j=i-1} @b{do}

@ @ @ @ @ @ @b{for all} @math{l@in C} @b{do}

@ @ @ @ @ @ @ @ @ @i{action};
@end quotation
@end iftex

@ifnottex
@example
for all i in A do
   for all (j,k) in B and j = i-1 do
      for all l in C do
         action;
@end example
@end ifnottex

@noindent
Thus, if this indexing expression were used as a primary set expression,
the resultant set would be the following:

@quotation
@{(4,@i{May},@i{a}), (4,@i{May},@i{b}), (4,@i{May},@i{c}),
(4,@i{Jun},@i{a}), (4,@i{Jun},@i{b}), (4,@i{Jun},@i{c})@}.
@end quotation

@noindent
Should note that in this case the resultant set consists of 3-tuples,
not of 4-tuples, because in the indexing expression there is no dummy
index that corresponds to the first component of 2-tuples from the set
@i{B}.

The general rule is: the number of components of @i{n}-tuples defined
by an indexing expression is the same as the number of dummy indices in
that indexing expression, where the correspondence between dummy indices
and components on @math{n}-tuples in the resultant set is positional,
i.e. the first dummy index corresponds to the first component, the
second dummy index corresponds to the second component, etc.

In many cases it is needed to select a subset from the Cartesian
product of some sets. This may be attained by using an optional logical
predicate, which is specified in indexing expression after the last or
the only indexing entry.

Consider, for another example, the following indexing expression:

@example
@{i in A, (j,k) in B, l in C: i <= 5 and k <> 'Mar'@}
@end example

@noindent
where the logical expression following the colon is a predicate. The
algorithmic description of this indexing expression is the following:

@iftex
@quotation
@b{for all} @math{i@in A} @b{do}

@ @ @ @b{for all} @math{(j,k)@in B} @b{do}

@ @ @ @ @ @ @b{for all} @math{l@in C} @b{do}

@ @ @ @ @ @ @ @ @ @b{if} @math{i@leq 5} @b{and} @math{k@neq} `@i{Mar}'
@b{then}

@ @ @ @ @ @ @ @ @ @ @ @ @i{action};
@end quotation
@end iftex

@ifnottex
@example
for all i in A do
   for all (j,k) in B do
      for all l in C do
         if i <= 5 and k != 'Mar' then
            action;
@end example
@end ifnottex

@noindent
Thus, if this indexing expression were used as a primary set expression,
the resultant set would be the following:

@quotation
@{(4,1,@i{Jan},@i{a}), (4,1,@i{Feb},@i{a}), (4,2,@i{Apr},@i{a}),
@dots{}, (4,3,@i{Jun},@i{c})@}.
@end quotation

If no predicate is specified in the indexing expression, the one, which
takes on the value @i{true}, is assumed.

@node Set expressions
@section Set expressions

@dfn{Set expression} is a rule for computing an elemental set, i.e.
a collection of @i{n}-tuples, where components of @i{n}-tuples are
numeric and symbolic quantities.

The primary set expression may be a literal set, unsubscripted set,
subscripted set, ``arithmetic'' set, indexing expression, iterated set
expression, conditional set expression, or another set expression
enclosed in parentheses.

@strong{Examples}

@quotation
@multitable @columnfractions .60 .40
@item @verb{|{(123,'aa'), (i,'bb'), (j-1,'cc')}|} @tab (literal set)
@item @verb{|I|} @tab (unsubscripted set)
@item @verb{|S[i-1,j+1]|} @tab (subscripted set)
@item @verb{|1..t-1 by 2|} @tab (``arithmetic'' set)
@item @verb{|{t in 1..T, (t+1,j) in S: (t,j) in F}|} @tab (indexing
expression)
@item @verb{|setof{i in I, j in J}(i+1,j-1)|} @tab (iterated expression)
@item @verb{|if i < j then S[i] else F diff S[j]|} @tab (conditional
expression)
@item @verb{|(1..10 union 21..30)|} @tab (parenthesized expression)
@end multitable
@end quotation

More general set expressions containing two or more primary set
expressions may be constructed by using certain set operators.

@strong{Examples}

@example
(A union B) inter (I cross J)
1..10 cross (if i < j then @{'a', 'b', 'c'@} else @{'d', 'e', 'f'@})
@end example

@subheading Literal sets

Literal set is a primary set expression, which has the following two
syntactic forms:

@iftex
@quotation
@math{@{e_1,e_2,@dots,e_m@}}

@math{@{(e_{11},@dots,e_{1n}),(e_{21},@dots,e_{2n}),@dots,(e_{m1},@dots,
e_{mn})@}}
@end quotation

@noindent
where @math{e_1}, @dots, @math{e_m}, @math{e_{11}}, @dots, @math{e_{mn}}
are numeric or symbolic expressions.
@end iftex

@ifnottex
@quotation
@{@i{e}1, @i{e}2, @dots{}, @i{em}@}

@{(@i{e}11, @dots{}, @i{e}1@i{n}), (@i{e}21, @dots{}, @i{e}2@i{n}),
@dots{}, (@i{em}1, @dots{}, @i{emn})@}
@end quotation

@noindent
where @i{e}1, @dots{}, @i{em}, @i{e}11, @dots{}, @i{emn} are numeric or
symbolic expressions.
@end ifnottex

If the first form is used, the resultant set consists of 1-tuples
(singles) enumerated within the curly braces. It is allowed to specify
an empty set, which has no 1-tuples.

If the second form is used, the resultant set consists of @i{n}-tuples
enumerated within the curly braces, where a particular @i{n}-tuple
consists of corresponding components enumerated within the parentheses.
All @i{n}-tuples must have the same number of components.

@subheading Unsubscripted sets

If the primary set expression is an unsubscripted set (which must be
0-dimensional), the resultant set is an elemental set associated with
the corresponding set object.

@subheading Subscripted sets

The primary set expression, which refers to a subscripted set, has the
following syntactic form:

@iftex
@quotation
@math{name[i_1,i_2,@dots,i_n],}
@end quotation

@noindent
where @math{name} is the symbolic name of the set object, @math{i_1},
@math{i_2}, @dots, @math{i_n} are subscripts.
@end iftex

@ifnottex
@quotation
@i{name}[@i{i}1, @i{i}2, @dots{}, @i{in}],
@end quotation

@noindent
where @i{name} is the symbolic name of the set object, @i{i}1, @i{i}2,
@dots{}, @i{in} are subscripts.
@end ifnottex

Each subscript must be a numeric or symbolic expression. The number of
subscripts in the subscript list must be the same as the dimension of
the set object with which the subscript list is associated.

Actual values of subscript expressions are used to identify a particular
member of the set object that determines the resultant set.

@subheading ``Arithmetic'' set

The primary set expression, which is an ``arithmetic'' set, has the
following two syntactic forms:

@iftex
@quotation
@math{t_0} @verb{|..|} @math{t_f} @verb{|by|} @math{@delta t}

@math{t_0} @verb{|..|} @math{t_f}
@end quotation

@noindent
where @math{t_0}, @math{t_1}, and @math{@delta t} are numeric
expressions (the value of @math{@delta t} must not be zero). The second
form is equivalent to the first form, where @math{@delta t=1}.

If @math{@delta t>0}, the resultant set is determined as follows:

@quotation
@math{@{t:@exists k@in{@cal Z}(t=t_0+k@delta t,@ t_0@leq t@leq t_f)@}}
@end quotation

@noindent
Otherwise, if @math{@delta t<0}, the resultant set is determined as
follows:

@quotation
@math{@{t:@exists k@in{@cal Z}(t=t_0+k@delta t,@ t_f@leq t@leq t_0)@}}
@end quotation
@end iftex

@ifnottex
@quotation
@i{t}0 @verb{|..|} @i{tf} @verb{|by|} @i{dt}

@i{t}0 @verb{|..|} @i{tf}
@end quotation

@noindent
where @i{t}0, @i{t}1, and @i{dt} are numeric expressions (the value of
@i{dt} must not be zero). The second form is equivalent to the first
form, where @i{dt}@tie{}=@tie{}1.

If @i{dt}@tie{}>@tie{}0, the resultant set is determined as follows:

@quotation
@{@i{t}: exists @i{k} in Z (@i{t} = @i{t}0 + @i{k} @i{dt}, @i{t}0 <=
@i{t} <= @i{tf})@}
@end quotation

@noindent
Otherwise, if @i{dt}@tie{}<@tie{}0, the resultant set is determined as
follows:

@quotation
@{@i{t}: exists @i{k} in Z (@i{t} = @i{t}0 + @i{k} @i{dt}, @i{tf} <=
@i{t} <= @i{t}0)@}
@end quotation
@end ifnottex

@subheading Indexing expressions

If the primary set expression is an indexing expression, the resultant
set is determined as described in Section ``Indexing expressions and
dummy indices'' (see above).

@subheading Iterated expressions

Iterated set expression is a primary set expression, which has the
following syntactic form:

@quotation
@verb{|setof|} @var{indexing-expression} @var{integrand}
@end quotation

@noindent
where @var{indexing-expression} is an indexing expression which
introduces dummy indices and controls iterating, @var{integrand} is
either a single numeric or symbolic expression or a list of numeric and
symbolic expressions separated by commae and enclosed in parentheses.

If the integrand is a single numeric or symbolic expression, the
resultant set consists of 1-tuples and is determined as follows:

@iftex
@quotation
@math{@{x:(i_1,@dots,i_n)@in@Delta@},}
@end quotation

@noindent
where @math{x} is a value of the integrand, @math{i_1}, @dots,
@math{i_n} are dummy indices introduced in the indexing expression,
@math{@Delta}
@end iftex
@ifnottex
@quotation
@{@i{x}: (@i{i}1, @dots{}, @i{in}) in D@},
@end quotation

@noindent
where @i{x} is a value of the integrand, @i{i1}, @dots{}, @i{in} are
dummy indices introduced in the indexing expression, D
@end ifnottex
is the domain, a set of @i{n}-tuples specified by the indexing
expression which defines particular values assigned to the dummy indices
on performing the iterated operation.

If the integrand is a list containing @i{m} numeric and symbolic
expressions, the resultant set consists of @i{m}-tuples and is
determined as follows:

@iftex
@quotation
@math{@{(x_1,@dots,x_m):(i_1,@dots,i_n)@in@Delta@},}
@end quotation

@noindent
where @math{x_1}, @dots, @math{x_m} are values of the expressions in the
integrand list, @math{i_1}, @dots, @math{i_n} and @math{@Delta}
@end iftex
@ifnottex
@quotation
@{(@i{x}1, @dots{}, @i{xm}): (@i{i}1, @dots{}, @i{in}) in D@},
@end quotation

@noindent
where @i{x}1, @dots{}, @i{xm} are values of the expressions in the
integrand list, @i{i}1, @dots{}, @i{in} and D
@end ifnottex
have the same meaning as above.

@subheading Conditional expressions

Conditional set expression is a primary set expression that has the
following syntactic form:

@quotation
@verb{|if|} @i{b} @verb{|then|} @i{X} @verb{|else|} @i{Y}
@end quotation

@noindent
where @i{b} is an logical expression, @i{X} and @i{Y} are set
expressions, which must define sets of the same dimension.

The resultant value of the conditional expression depends on the value
of the logical expression that follows the keyword @verb{|if|}. If it
takes on the value @i{true}, the resultant set is the value of the
expression that follows the keyword @verb{|then|}. Otherwise, if the
logical expression takes on the value @i{false}, the resultant set is
the value of the expression that follows the keyword @verb{|else|}.

@subheading Parenthesized expressions

Any set expression may be enclosed in parentheses that syntactically
makes it primary set expression.

Parentheses may be used in set expressions, as in algebra, to specify
the desired order in which operations are to be performed. Where
parentheses are used, the expression within the parentheses is evaluated
before the resultant value is used.

The resultant value of the parenthesized expression is the same as the
value of the expression enclosed within parentheses.

@subheading Set operators

In MathProg there are the following set operators, which may be used in
set expressions:

@quotation
@multitable @columnfractions .20 .80
@item @i{X} @verb{|union|} @i{Y} @tab union
@iftex
@math{X@cup Y}
@end iftex
@item @i{X} @verb{|diff|} @i{Y} @tab difference
@iftex
@math{X@backslash Y}
@end iftex
@item @i{X} @verb{|symdiff|} @i{Y} @tab symmetric difference
@iftex
@math{X@oplus Y}
@end iftex
@item @i{X} @verb{|inter|} @i{Y} @tab intersection
@iftex
@math{X@cap Y}
@end iftex
@item @i{X} @verb{|cross|} @i{Y} @tab cross (Cartesian) product
@iftex
@math{X@times Y}
@end iftex
@end multitable
@end quotation

@noindent
where @i{X} and @i{Y} are set expressions, which must define sets of the
identical dimension (except for the Cartesian product).

If the expression includes more than one set operator, all operators are
performed from left to right according to the hierarchy of operations
(see below).

The resultant value of the expression, which contains set operators, is
the result of applying the operators to their operands.

The dimension of the resultant set, i.e. the dimension of @i{n}-tuples,
of which the resultant set consists of, is the same as the dimension of
the operands, except the Cartesian product, where the dimension of the
resultant set is the sum of dimensions of the operands.

@subheading Hierarchy of operations

The following list shows the hierarchy of operations in set expressions:

@quotation
@multitable @columnfractions .70 .30
@item @i{Operation} @tab @i{Hierarchy}
@item Evaluation of numeric operations @tab 1st-7th
@item Evaluation of symbolic operations @tab 8th-9th
@item Evaluation of iterated or ``arithmetic'' set (@verb{|setof|},
@verb{|..|}) @tab 10th
@item Cartesian product (@verb{|cross|}) @tab 11th
@item Intersection (@verb{|inter|}) @tab 12th
@item Union and difference (@verb{|union|}, @verb{|diff|},
@verb{|symdiff|}) @tab 13th
@item Conditional evaluation (@verb{|if|} @dots{} @verb{|then|} @dots{}
@verb{|else|}) @tab 14th
@end multitable
@end quotation

This hierarchy is used to determine which of two consecutive operations
is performed first. If the first operator is higher than or equal to the
second, the first operation is performed. If it is not, the second
operator is compared to the third, etc. When the end of the expression
is reached, all of the remaining operations are performed in the reverse
order.

@node Logical expressions
@section Logical expressions

@dfn{Logical expression} is a rule for computing a single logical value,
which can be either @i{true} or @i{false}.

The primary logical expression may be a numeric expression, relational
expression, iterated logical expression, or another logical expression
enclosed in parentheses.

@strong{Examples}

@quotation
@multitable @columnfractions .60 .40
@item @verb{|i+1|} @tab (numeric expression)
@item @verb{|a[i,j] < 1.5|} @tab (relational expression)
@item @verb{|s[i+1,j-1] <> 'Mar' & year|} @tab (relational expression)
@item @verb{|(i+1,'Jan') not in I cross J|} @tab (relational expression)
@item @verb{|S union T within A[i] inter B[j]|} @tab (relational
expression)
@item @verb{|forall{i in I, j in J} a[i,j] < .5 * b|} @tab (iterated
expression)
@item @verb{|(a[i,j] < 1.5 or b[i] >= a[i,j])|} @tab (parenthesized
expression)
@end multitable
@end quotation

More general logical expressions containing two or more primary logical
expressions may be constructed by using certain logical operators.

@strong{Examples}

@example
not (a[i,j] < 1.5 or b[i] >= a[i,j]) and (i,j) in S
(i,j) in S or (i,j) not in T diff U
@end example

@subheading Numeric expressions

The resultant value of the primary logical expression, which is a
numeric expression, is @i{true}, if the resultant value of the numeric
expression is non-zero. Otherwise the resultant value of the logical
expression is @i{false}.

@subheading Relational expressions

In MathProg there are the following relational operators, which may be
used in logical expressions:

@quotation
@multitable @columnfractions .50 .50
@item @i{x} @verb{|<|} @i{y} @tab test on @i{x} < @i{y}
@item @i{x} @verb{|<=|} @i{y} @tab test on
@iftex
@math{x@leq y}
@end iftex
@ifnottex
@i{x} <= @i{y}
@end ifnottex
@item @i{x} @verb{|=|} @i{y}, @i{x} @verb{|==|} @i{y} @tab test on
@i{x} = @i{y}
@item @i{x} @verb{|>=|} @i{y} @tab test on
@iftex
@math{x@geq y}
@end iftex
@ifnottex
@i{x} >= @i{y}
@end ifnottex
@item @i{x} @verb{|<>|} @i{y}, @i{x} @verb{|!=|} @i{y} @tab test on
@iftex
@math{x@neq y}
@end iftex
@ifnottex
@i{x} != @i{y}
@end ifnottex
@item @i{x} @verb{|in|} @i{Y} @tab test on
@iftex
@math{x@in Y}
@end iftex
@ifnottex
@i{x} in @i{Y}
@end ifnottex
@iftex
@item @math{(x_1,@dots,x_n)} @verb{|in|} @math{Y} @tab test on
@math{(x_1,@dots,x_n)@in Y}
@end iftex
@ifnottex
@item (@i{x}1,@dots{},@i{xn}) @verb{|in|} @i{Y} @tab test on
(@i{x}1,@dots{},@i{xn}) in @i{Y}
@end ifnottex
@item @i{x} @verb{|not in|} @i{Y}, @i{x} @verb{|!in|} @i{Y} @tab test on
@iftex
@math{x@not@in Y}
@end iftex
@ifnottex
@i{x} not in @i{Y}
@end ifnottex
@iftex
@item @math{(x_1,@dots,x_n)} @verb{|not in|} @math{Y},
@math{(x_1,@dots,x_n)} @verb{|!in|} @math{Y} @tab test on
@math{(x_1,@dots,x_n)@not@in Y}
@end iftex
@ifnottex
@item (@i{x}1,@dots{},@i{xn}) @verb{|not in|} @i{Y}, @tab
@item (@i{x}1,@dots{},@i{xn}) @verb{|!in|} @i{Y} @tab test on
(@i{x}1,@dots{},@i{xn}) not in @i{Y}
@end ifnottex
@item @i{X} @verb{|within|} @i{Y} @tab test on
@iftex
@math{X@subseteq Y}
@end iftex
@ifnottex
@i{X} within @i{Y}
@end ifnottex
@item @i{X} @verb{|not within|} @i{Y}, @i{X} @verb{|!within|} @i{Y}
@tab test on
@iftex
@math{X@not@subseteq Y}
@end iftex
@ifnottex
@i{X} not within @i{Y}
@end ifnottex
@end multitable
@end quotation

@noindent
where @i{x},
@iftex
@math{x_1}, @dots, @math{x_n},
@end iftex
@ifnottex
@i{x}1, @dots{}, @i{xn},
@end ifnottex
@i{y} are numeric or symbolic expressions, @i{X} and @i{Y} are set
expression.

@i{Note:}

@quotation
@enumerate
@item In the operations @verb{|in|}, @verb{|not in|}, and @verb{|!in|}
the number of components in the first operands must be the same as the
dimension of the second operand.
@item In the operations @verb{|within|}, @verb{|not within|}, and
@verb{|!within|} both operands must have identical dimension.
@end enumerate
@end quotation

All the relational operators listed above have their conventional
mathematical meaning. The resultant value is @i{true}, if the
corresponding relation is satisfied for its operands, otherwise
@i{false}. (Note that symbolic values are ordered lexicographically,
and any numeric value precedes any symbolic value.)

@subheading Iterated expressions

Iterated logical expression is a primary logical expression, which has
the following syntactic form:

@quotation
@var{iterated-operator} @var{indexing-expression} @var{integrand}
@end quotation

@noindent
where @var{iterated-operator} is the symbolic name of the iterated
operator to be performed (see below), @var{indexing expression} is an
indexing expression which introduces dummy indices and controls
iterating, @var{integrand} is a logical expression that participates in
the operation.

In MathProg there are two iterated operators, which may be used in
logical expressions:

@iftex
@quotation
@multitable @columnfractions .10 .25 .65
@item @verb{|forall|} @tab @math{@forall}-quantification @tab
@math{@forall(i_1,@dots,i_n)_{@in@Delta}[x(i_1,@dots,i_n)]}
@item @verb{|exists|} @tab @math{@exists}-quantification @tab
@math{@exists(i_1,@dots,i_n)_{@in@Delta}[x(i_1,@dots,i_n)]}
@end multitable
@end quotation
@end iftex

@ifnottex
@quotation
@multitable @columnfractions .10 .25 .65
@item @verb{|forall|} @tab A-quantification @tab
for all (@i{i}1,@dots{},@i{in}) in D: @i{x}(@i{i}1,@dots{},@i{in})
@item @verb{|exists|} @tab E-quantification @tab
exists @ (@i{i}1,@dots{},@i{in}) in D: @i{x}(@i{i}1,@dots{},@i{in})
@end multitable
@end quotation
@end ifnottex

@noindent
where
@iftex
@math{i_1}, @dots, @math{i_n}
@end iftex
@ifnottex
@i{i}1, @dots{}, @i{in}
@end ifnottex
are dummy indices introduced in the
indexing expression,
@iftex
@math{@Delta}
@end iftex
@ifnottex
D
@end ifnottex
is the domain, a set of
@i{n}-tuples specified by the indexing expression which defines
particular values assigned to the dummy indices on performing the
iterated operation,
@iftex
@math{x(i_1,@dots,i_n)}
@end iftex
@ifnottex
@i{x}(@i{i}1,@dots{},@i{in})
@end ifnottex
is the integrand, a logical expression whose resultant value depends on
the dummy indices.

For
@iftex
@math{@forall}-quantification
@end iftex
@ifnottex
A-quantification
@end ifnottex
the resultant value of the iterated logical expression is @i{true}, if
the value of the integrand is @i{true} for all @i{n}-tuples contained in
the domain, otherwise @i{false}.

For
@iftex
@math{@exists}-quantification
@end iftex
@ifnottex
E-quantification
@end ifnottex
the resultant value of the iterated logical expression is @i{false}, if
the value of the integrand is @i{false} for all @i{n}-tuples contained
in the domain, otherwise @i{true}.

@subheading Parenthesized expressions

Any logical expression may be enclosed in parentheses that syntactically
makes it primary logical expression.

Parentheses may be used in logical expressions, as in algebra, to
specify the desired order in which operations are to be performed. Where
parentheses are used, the expression within the parentheses is evaluated
before the resultant value is used.

The resultant value of the parenthesized expression is the same as the
value of the expression enclosed within parentheses.

@subheading Logical operators

In MathProg there are the following logical operators, which may be used
in logical expressions:

@quotation
@multitable @columnfractions .30 .70
@item @verb{|not|} @i{x}, @verb{|!|} @i{x} @tab negation
@item @i{x} @verb{|and|} @i{y}, @i{x} @verb{|&&|} @i{y} @tab
conjunction (logical ``and'')
@item @i{x} @verb{|or|} @i{y}, @i{x} @verb{$||$} @i{y} @tab
disjunction (logical ``or'')
@end multitable
@end quotation

@noindent
where @i{x} and @i{y} are logical expressions.

If the expression includes more than one logical operator, all
operators are performed from left to right according to the hierarchy
of operations (see below).

The resultant value of the expression, which contains logical
operators, is the result of applying the operators to their operands.

@subheading Hierarchy of operations

The following list shows the hierarchy of operations in logical
expressions:

@quotation
@multitable @columnfractions .70 .30
@item @i{Operation} @tab @i{Hierarchy}
@item Evaluation of numeric operations @tab 1st-7th
@item Evaluation of symbolic operations @tab 8th-9th
@item Evaluation of set operations @tab 10th-14th
@item Relational operations (@verb{|<|}, @verb{|<=|}, etc.) @tab 15th
@item Negation (@verb{|not|}, @verb{|!|}) @tab 16th
@item Conjunction (@verb{|and|}, @verb{|&&|}) @tab 17th
@item
@iftex
@math{@forall}- and @math{@exists}-quantification
@end iftex
@ifnottex
A- and E-quantification
@end ifnottex
(@verb{|forall|}, @verb{|exists|}) @tab 18th
@item Disjunction (@verb{|or|}, @verb{$||$}) @tab 19th
@end multitable
@end quotation

This hierarchy has the same meaning as explained in Section ``Numeric
expressions''.

@node Linear expressions
@section Linear expressions

@dfn{Linear expression} is a rule for computing so called @dfn{linear
form} or simply @dfn{formula}, which is a linear (or affine) function of
elemental variables.

The primary linear expression may be an unsubscripted variable,
subscripted variable, iterated linear expression, conditional linear
expression, or another linear expression enclosed in parentheses.

It is also allowed to use a numeric expression as the primary linear
expression, in which case the resultant value of the numeric expression
is automatically converted to the formula that includes the only
constant term.

@strong{Examples}

@quotation
@multitable @columnfractions .60 .40
@item @verb{|z|} @tab (unsubscripted variable)
@item @verb{|x[i,j]|} @tab (subscripted variable)
@item @verb{|sum{j in J} (a[i] * x[i,j] + 3 * y)|} @tab (iterated
expression)
@item @verb{|if i in I then x[i,j] else 1.5 * z + 3|} @tab
(conditional expression)
@item @verb{|(a[i,j] * x[i,j] + y[i-1] + .1)|} @tab (parenthesized
expression)
@end multitable
@end quotation

More general linear expressions containing two or more primary linear
expressions may be constructed by using certain arithmetic operators.

@strong{Examples}

@example
2 * x[i-1,j+1] + 3.5 * y[k] + .5 * z
(- x[i,j] + 3.5 * y[k]) / sum@{t in T@} abs(d[i,j,t])
@end example

@subheading Unsubscripted variables

If the primary linear expression is an unsubscripted variable (which
must be 0-dimensional), the resultant formula is that unsubscripted
variable.

@subheading Subscripted variables

The primary linear expression, which refers to a subscripted variable,
has the following syntactic form:

@iftex
@quotation
@math{name[i_1,i_2,@dots,i_n],}
@end quotation

@noindent
where @math{name} is the symbolic name of the variable, @math{i_1},
@math{i_2}, @dots, @math{i_n} are subscripts.
@end iftex

@ifnottex
@quotation
@i{name}[@i{i}1, @i{i}2, @dots{}, @i{in}],
@end quotation

@noindent
where @i{name} is the symbolic name of the variable, @i{i}1, @i{i}2,
@dots{}, @i{in} are subscripts.
@end ifnottex

Each subscript must be a numeric or symbolic expression. The number of
subscripts in the subscript list must be the same as the dimension of
the variable with which the subscript list is associated.

Actual values of subscript expressions are used to identify
a particular member of the model variable that determines the resultant
formula, which is an elemental variable associated with the
corresponding member.

@subheading Iterated expressions

Iterated linear expression is a primary linear expression, which has the
following syntactic form:

@verb{|sum|} @var{indexing-expression} @var{integrand}

@noindent
where @var{indexing-expression} is an indexing expression which
introduces dummy indices and controls iterating, @var{integrand} is a
linear expression that participates in the operation.

The iterated linear expression is evaluated exactly in the same way as
the iterated numeric expression (see Section ``Numeric expressions''
above) with the exception that the integrand participated in the
summation is a formula, not a numeric value.

@subheading Conditional expressions

Conditional linear expression is a primary linear expression, which has
one of the following two syntactic forms:

@quotation
@verb{|if|} @i{b} @verb{|then|} @i{f} @verb{|else|} @i{g}

@verb{|if|} @i{b} @verb{|then|} @i{f}
@end quotation

@noindent
where @i{b} is an logical expression, @i{f} and @i{g} are linear
expressions.

The conditional linear expression is evaluated exactly in the same way
as the conditional numeric expression (see Section ``Numeric
expressions'' above) with the exception that operands participated in
the operation are formulae, not numeric values.

@subheading Parenthesized expressions

Any linear expression may be enclosed in parentheses that syntactically
makes it primary linear expression.

Parentheses may be used in linear expressions, as in algebra, to
specify the desired order in which operations are to be performed. Where
parentheses are used, the expression within the parentheses is evaluated
before the resultant formula is used.

The resultant value of the parenthesized expression is the same as the
value of the expression enclosed within parentheses.

@subheading Arithmetic operators

In MathProg there are the following arithmetic operators, which may be
used in linear expressions:

@quotation
@multitable @columnfractions .20 .80
@item @verb{|+|} @i{f} @tab unary plus
@item @verb{|-|} @i{f} @tab unary minus
@item @i{f} @verb{|+|} @i{g} @tab addition
@item @i{f} @verb{|-|} @i{g} @tab subtraction
@item @i{x} @verb{|*|} @i{f}, @i{f} @verb{|*|} @i{x} @tab multiplication
@item @i{f} @verb{|/|} @i{x} @tab division
@end multitable
@end quotation

@noindent
where @i{f} and @i{g} are linear expressions, @i{x} is a numeric
expression (more precisely, a linear expression containing the constant
term only).

If the expression includes more than one arithmetic operator, all
operators are performed from left to right according to the hierarchy
of operations (see below).

The resultant value of the expression, which contains arithmetic
operators, is the result of applying the operators to their operands.

@subheading Hierarchy of operations

The hierarchy of arithmetic operations used in linear expressions is
the same as for numeric expressions (for details see Section ``Numeric
expressions'' above).

@node Statements
@chapter Statements

@menu
* Set statement::
* Parameter statement::
* Variable statement::
* Constraint statement::
* Objective statement::
* Solve statement::
* Check statement::
* Display statement::
* Printf statement::
* For statement::
@end menu

@dfn{Statements} are basic units of the model description. In MathProg
all statements are divided into two categories: declaration statements
and functional statements.

@dfn{Declaration statements} (set statement, parameter statement,
variable statement, constraint statement, and objective statement) are
used to declare model objects of certain kinds and define certain
properties of that objects.

@dfn{Functional statements} (solve statement, check statement, display
statement, printf statement, loop statement) are intended for performing
some specific actions.

Note that declaration statements may follow in arbitrary order which
does not affect the result of translation. However, any model object
must be declared before it is referenced in other statements.

@node Set statement
@section Set statement

@cartouche
@verb{| set|} @var{name} @var{alias} @var{domain} @verb{|,|}
@var{attrib} @verb{|,|} @dots{} @verb{|,|} @var{attrib} @verb{|;|}
@end cartouche

@table @asis
@item Where:
@var{name} is the symbolic name of the set;
@item
@var{alias} is an optional string literal which specifies the alias of
the set;
@item
@var{domain} is an optional indexing expression which specifies the
subscript domain of the set;
@item
@var{attrib}, @dots{}, @var{attrib} are optional attributes of the set.
(Commae preceding attributes may be omitted.)
@end table

@noindent
Optional attributes:

@table @asis
@item @t{dimen} @i{n}
specifies dimension of @i{n}-tuples, which the set consists of;
@item @t{within} @i{expression}
specifies a superset which restricts the set or all its members
(elemental sets) to be within this superset;
@item @t{:=} @i{expression}
specifies an elemental set assigned to the set or its members;
@item @t{default} @i{expression}
specifies an elemental set assigned to the set or its members whenever
no appropriate data are available in the data section.
@end table

@strong{Examples}

@example
set V;
set E within V cross V;
set step@{s in 1..maxiter@} dimen 2 := if s = 1 then E else step[s-1]
   union setof@{k in V, (i,k) in step[s-1], (k,j) in step[s-1]@}(i,j);
set A@{i in I, j in J@}, within B[i+1] cross C[j-1], within D diff E,
   default @{('abc',123), (321,'cba')@};
@end example

The set statement declares a set. If the subscript domain is not
specified, the set is a simple set, otherwise it is an array of
elemental sets.

The @code{dimen} attribute specifies dimension of @i{n}-tuples, which
the set (if it is a simple set) or its members (if the set is an array
of elemental sets) consist of, where @i{n} must be unsigned integer from
1 to 20. At most one @code{dimen} attribute can be specified. If the
@code{dimen} attribute is not specified, dimension of @i{n}-tuples is
implicitly determined by other attributes (for example, if there is a
set expression that follows @code{:=} or the keyword @code{default}, the
dimension of @i{n}-tuples of the corresponding elemental set is used).
If no dimension information is available, @code{dimen 1} is assumed.

The @code{within} attribute specifies a set expression whose resultant
value is a superset used to restrict the set (if it is a simple set) or
its members (if the set is an array of elemental sets) to be within this
superset. Arbitrary number of @code{within} attributes may be specified
in the same set statement.

The assign (@code{:=}) attribute specifies a set expression used to
evaluate elemental set(s) assigned to the set (if it is a simple set) or
its members (if the set is an array of elemental sets). If the assign
attribute is specified, the set is @emph{computable} and therefore needs
no data to be provided in the data section. If the assign attribute is
not specified, the set must be provided with data in the data section.
At most one assign or @code{default} attribute can be specified for the
same set.

The @code{default} attribute specifies a set expression used to
evaluate elemental set(s) assigned to the set (if it is a simple set) or
its members (if the set is an array of elemental sets) whenever
no appropriate data are available in the data section. If neither assign
nor @code{default} attribute is specified, missing data will cause an
error.

@node Parameter statement
@section Parameter statement

@cartouche
@verb{| param|} @var{name} @var{alias} @var{domain} @verb{|,|}
@var{attrib} @verb{|,|} @dots{} @verb{|,|} @var{attrib} @verb{|;|}
@end cartouche

@table @asis
@item Where:
@var{name} is the symbolic name of the parameter;
@item
@var{alias} is an optional string literal which specifies the alias of
the parameter;
@item
@var{domain} is an optional indexing expression which specifies the
subscript domain of the parameter;
@item
@var{attrib}, @dots{}, @var{attrib} are optional attributes of the
parameter. (Commae preceding attributes may be omitted.)
@end table

@noindent
Optional attributes:

@table @asis
@item @t{integer}
specifies that the parameter is integer;
@item @t{binary}
specifies that the parameter is binary;
@item @t{symbolic}
specifies that the parameter is symbolic;
@item @var{relation} @var{expression}
(where @var{relation} is one of: @t{< <= = == >= > <> !=})@*
specifies a condition that restricts the parameter or its members to
satisfy this condition;
@item @t{in} @var{expression}
specifies a superset that restricts the parameter or its members to be
in this superset;
@item @t{:=} @var{expression}
specifies a value assigned to the parameter or its members;
@item @t{default} @var{expression}
specifies a value assigned to the parameter or its members whenever no
appropriate data are available in the data section.
@end table

@strong{Examples}

@example
param units@{raw, prd@} >= 0;
param profit@{prd, 1..T+1@};
param N := 20, integer, >= 0, <= 100;
param comb 'n choose k' @{n in 0..N, k in 0..n@} :=
   if k = 0 or k = n then 1 else comb[n-1,k-1] + comb[n-1,k];
param p@{i in I, j in J@}, integer, >= 0, <= i+j, in A[i] symdiff B[j],
   in C[i,j], default 0.5 * (i + j);
param month symbolic default 'May' in @{'Mar', 'Apr', 'May'@};
@end example

The parameter statement declares a parameter. If the subscript domain
is not specified, the parameter is a simple (scalar) parameter,
otherwise it is a @i{n}-dimensional array.

The type attributes @code{integer}, @code{binary}, and @code{symbolic}
qualify the type values which can be assigned to the parameter as shown
below:

@quotation
@multitable @columnfractions .25 .75
@item @i{Type attribute} @tab @i{Assigned values}
@item not specified @tab Any numeric values
@item @verb{|integer|} @tab Only integer numeric values
@item @verb{|binary|} @tab Either 0 or 1
@item @verb{|symbolic|} @tab Any numeric and symbolic values
@end multitable
@end quotation

The @code{symbolic} attribute cannot be specified along with other
type attributes. Being specified it must precede all other attributes.

The condition attribute specifies an optional condition that restricts
values assigned to the parameter to satisfy this condition. This
attribute has the following syntactic forms:

@quotation
@multitable @columnfractions .25 .75
@item @verb{|<|} @i{v} @tab Check for @i{x} < @i{v}
@item @verb{|<=|} @i{v} @tab Check for
@iftex
@math{x@leq v}
@end iftex
@ifnottex
@i{x} <= @i{v}
@end ifnottex
@item @verb{|=|} @i{v}, @verb{|==|} @i{v} @tab Check for @i{x} = @i{v}
@item @verb{|>=|} @i{v} @tab Check for
@iftex
@math{x@geq v}
@end iftex
@ifnottex
@i{x} >= @i{v}
@end ifnottex
@item @verb{|>|} @i{v} @tab Check for @i{x} > @i{v}
@item @verb{|<>|} @i{v}, @verb{|!=|} @i{v} @tab Check for
@iftex
@math{x@neq v}
@end iftex
@ifnottex
@i{x} != @i{v}
@end ifnottex
@end multitable
@end quotation

@noindent
where @i{x} is a value assigned to the parameter, @i{v} is the
resultant value of a numeric or symbolic expression specified in the
condition attribute. Arbitrary number of condition attributes can be
specified for the same parameter. If a value being assigned to the
parameter during model evaluation violates at least one specified
condition, an error is raised. (Note that symbolic values are ordered
lexicographically, and any numeric value precedes any symbolic value.)

The @code{in} attribute is similar to the condition attribute and
specifies a set expression whose resultant value is a superset used
to restrict numeric or symbolic values assigned to the parameter to be
in this superset. Arbitrary number of the @code{in} attributes can be
specified for the same parameter. If a value being assigned to the
parameter during model evaluation is not in at least one specified
superset, an error is raised.

The assign (@code{:=}) attribute specifies a numeric or symbolic
expression used to compute a value assigned to the parameter (if it is
a simple parameter) or its member (if the parameter is an array). If the
assign attribute is specified, the parameter is @emph{computable} and
therefore needs no data to be provided in the data section. If the
assign attribute is not specified, the parameter must be provided with
data in the data section. At most one assign or @code{default}
attribute can be specified for the same parameter.

The @code{default} attribute specifies a numeric or symbolic
expression used to compute a value assigned to the parameter or its
member whenever no appropriate data are available in the data section.
If neither assign nor @code{default} attribute is specified, missing
data will cause an error.

@node Variable statement
@section Variable statement

@cartouche
@verb{| var|} @var{name} @var{alias} @var{domain} @verb{|,|}
@var{attrib} @verb{|,|} @dots{} @verb{|,|} @var{attrib} @verb{|;|}
@end cartouche

@table @asis
@item Where:
@var{name} is the symbolic name of the variable;
@item
@var{alias} is an optional string literal which specifies the alias of
the variable;
@item
@var{domain} is an optional indexing expression which specifies the
subscript domain of the variable;
@item
@var{attrib}, @dots{}, @var{attrib} are optional attributes of the
variable. (Commae preceding attributes may be omitted.)
@end table

@noindent
Optional attributes:

@table @asis
@item @t{integer}
restricts the variable to be integer;
@item @t{binary}
restricts the variable to be binary;
@item @t{>=} @var{expression}
specifies an lower bound of the variable;
@item @t{<=} @var{expression}
specifies an upper bound of the variable;
@item @t{=} @var{expression}, @t{==} @var{expression}
specifies a fixed value of the variable;
@end table

@strong{Examples}

@example
var x >= 0;
var y@{I,J@};
var make@{p in prd@}, integer, >= commit[p], <= market[p];
var store@{raw, 1..T+1@} >= 0;
var z@{i in I, j in J@} >= i+j;
@end example

The variable statement declares a variable. If the subscript domain
is not specified, the variable is a simple (scalar) variable,
otherwise it is a @i{n}-dimensional array of elemental variables.

Elemental variable(s) associated with the model variable (if it is
a simple variable) or its members (if it is an array) correspond to
the variables in the LP/MIP problem formulation (see Section ``Linear
programming problem''). Note that only the elemental variables actually
referenced in some constraints and/or objectives are included in the
LP/MIP problem instance to be generated.

The type attributes @code{integer} and @code{binary} restrict the
variable to be integer or binary, respectively. If no type attribute
is specified, the variable is continuous. If all variables in the model
are continuous, the corresponding problem is of LP class. If there is
at least one integer or binary variable, the problem is of MIP class.

The lower bound (@code{>=}) attribute specifies a numeric expression
for computing the lower bound of the variable. At most one lower bound
can be specified. By default all variables (except binary ones) have
no lower bounds, so if a variable is required to be non-negative, its
zero lower bound should be explicitly specified.

The upper bound (@code{<=}) attribute specifies a numeric expression
for computing the upper bound of the variable. At most one upper bound
attribute can be specified.

The fixed value (@code{=}) attribute specifies a numeric expression
for computing the value, at which the variable is fixed. This attribute
cannot be specified along with lower/upper bound attributes.

@node Constraint statement
@section Constraint statement

@cartouche
@verb{| subject to|} @var{name} @var{alias} @var{domain} @verb{|:|}
@var{expression} @verb{|,|} @verb{|=|} @var{expression} @verb{|;|}

@noindent
@verb{| subject to|} @var{name} @var{alias} @var{domain} @verb{|:|}
@var{expression} @verb{|,|} @verb{|<=|} @var{expression} @verb{|;|}

@noindent
@verb{| subject to|} @var{name} @var{alias} @var{domain} @verb{|:|}
@var{expression} @verb{|,|} @verb{|>=|} @var{expression} @verb{|;|}

@noindent
@verb{| subject to|} @var{name} @var{alias} @var{domain} @verb{|:|}
@var{expression} @verb{|,|} @verb{|<=|} @var{expression} @verb{|,|}
@verb{|<=|} @var{expression} @verb{|;|}

@noindent
@verb{| subject to|} @var{name} @var{alias} @var{domain} @verb{|:|}
@var{expression} @verb{|,|} @verb{|>=|} @var{expression} @verb{|,|}
@verb{|>=|} @var{expression} @verb{|;|}
@end cartouche

@table @asis
@item Where:
@var{name} is the symbolic name of the constraint;
@item
@var{alias} is an optional string literal which specifies the alias of
the constraint;
@item
@var{domain} is an optional indexing expression which specifies the
subscript domain of the constraint;
@item
@var{expressions} are linear expressions for computing components of the
constraint. (Commae following expressions may be omitted.)
@end table

@table @asis
@item Note:
The keyword @code{subject to} may be reduced to @code{subj to}, or to
@code{s.t.}, or be omitted at all.
@end table

@strong{Examples}

@example
s.t. r: x + y + z, >= 0, <= 1;
limit@{t in 1..T@}: sum@{j in prd@} make[j,t] <= max_prd;
subject to balance@{i in raw, t in 1..T@}:
   store[i,t+1] - store[i,t] - sum@{j in prd@} units[i,j] * make[j,t];
subject to rlim 'regular-time limit' @{t in time@}:
   sum@{p in prd@} pt[p] * rprd[p,t] <= 1.3 * dpp[t] * crews[t];
@end example

The constraint statement declares a constraint. If the subscript domain
is not specified, the constraint is a simple (scalar) constraint,
otherwise it is a @i{n}-dimensional array of elemental constraints.

Elemental constraint(s) associated with the model constraint (if it is
a simple constraint) or its members (if it is an array) correspond to
the linear constraints in the LP/MIP problem formulation (see Section
``Linear programming problem'').

If the constraint has the form of equality or single inequality, i.e.
includes two expressions, one of which follows the colon and other
follows the relation sign @code{=}, @code{<=}, or @code{>=}, both
expressions in the statement can be linear expressions. If the
constraint has the form of double inequality, i.e. includes three
expressions, the middle expression can be a linear expression while the
leftmost and rightmost ones can be only numeric expressions.

Generating the model is, generally speaking, generating its constraints,
which are always evaluated for the entire subscript domain. Evaluating
constraints leads, in turn, to evaluating other model objects such as
sets, parameters, and variables.

Constructing the actual linear constraint included in the problem
instantce, which (constraint) corresponds to a particular elemental
constraint, is performed as follows.

If the constraint has the form of equality or single inequality,
evaluation of both linear expressions gives two resultant linear forms:
@iftex
@tex
$$\matrix{
f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,\cr
g=b_1x_1+b_2x_2+\dots+b_nx_n+b_0,\cr
}$$
where @math{x_1}, @math{x_2}, @dots, @math{x_n} are elemental variables,
@math{a_1}, @math{a_2}, @dots, @math{a_n}, @math{b_1}, @math{b_2},
@dots, @math{b_n} are numeric coefficients, @math{a_0} and @math{b_0}
are constant terms.
@end tex
@end iftex
@ifnottex

@quotation
@i{f} = @i{a}1 @i{x}1 + @i{a}2 @i{x}2 + @dots{} + @i{an} @i{xn} +
@i{a}0,

@i{g} = @i{b}1 @i{x}1 + @i{b}2 @i{x}2 + @dots{} + @i{bn} @i{xn} +
@i{b}0,
@end quotation

@noindent
where @i{x}1, @i{x}2, @dots{}, @i{xn} are elemental variables, @i{a}1,
@i{a}2, @dots{}, @i{an}, @i{b}1, @i{b}2, @dots{}, @i{bn} are numeric
coefficients, @i{a}0 and @i{b}0 are constant terms.
@end ifnottex
Then all linear terms of @i{f} and @i{g} are carried to the left-hand
side, and the constant terms are carried to the right-hand side that
gives the final elemental constraint in the standard form:
@iftex
@tex
$$
(a_1-b_1)x_1+(a_2-b_2)x_2+\dots+(a_n-b_n)x_n
\left\{ \matrix{=\cr\leq\cr\geq\cr}\right\}b_0-a_0.
$$
@end tex
@end iftex
@ifnottex

@quotation
(@i{a}1 @minus{} @i{b}1) @i{x}1 + (@i{a}2 @minus{} @i{b}2) @i{x}2 +
@dots{} + (@i{an} @minus{} @i{bn}) @i{xn} @{= | <= | =>@} @i{b}0
@minus{} @i{a}0
@end quotation
@end ifnottex

If the constraint has the form of double inequality, evaluation of the
middle linear expression gives the resultant linear form:
@iftex
@tex
$$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$
@end tex
@end iftex
@ifnottex

@quotation
@i{f} = @i{a}1 @i{x}1 + @i{a}2 @i{x}2 + @dots{} + @i{an} @i{xn} +
@i{a}0,
@end quotation

@end ifnottex
@noindent
and evaluation of the leftmost and rightmost numeric expressions gives
two numeric values @i{l} and @i{u}. Then the constant term of the linear
form is carried to both left-hand and right-hand sides that gives the
final elemental constraint in the standard form:
@iftex
@tex
$$l-a_0\leq a_1x_1+a_2x_2+\dots+a_nx_n\leq u-a_0.$$
@end tex
@end iftex
@ifnottex

@quotation
@i{l} @minus{} @i{a}0 <= @i{a}1 @i{x}1 + @i{a}2 @i{x}2 + @dots{} +
@i{an} @i{xn} <= @i{u} @minus{} @i{a}0.
@end quotation
@end ifnottex

@node Objective statement
@section Objective statement

@cartouche
@verb{| minimize|} @var{name} @var{alias} @var{domain} @verb{|:|}
@var{expression} @verb{|;|}

@noindent
@verb{| maximize|} @var{name} @var{alias} @var{domain} @verb{|:|}
@var{expression} @verb{|;|}
@end cartouche

@table @asis
@item Where:
@var{name} is the symbolic name of the objective;
@item
@var{alias} is an optional string literal which specifies the alias of
the objective;
@item
@var{domain} is an optional indexing expression which specifies the
subscript domain of the objective;
@item
@var{expression} is an linear expression for computing the linear form
of the objective
@end table

@strong{Examples}

@example
minimize obj: x + 1.5 * (y + z);
maximize total_profit: sum@{p in prd@} profit[p] * make[p];
@end example

The objective statement declares an objective. If the subscript domain
is not specified, the objective is a simple (scalar) objective.
Otherwise it is a @i{n}-dimensional array of elemental objectives.

Elemental objective(s) associated with the model objective (if it is
a simple objective) or its members (if it is an array) correspond to
general linear constraints in the LP/MIP problem formulation (see
Section ``Linear programming problem''). However, unlike constraints
the corresponding linear forms are free (unbounded).

Constructing the actual linear constraint included in the problem
instance, which (constraint) corresponds to a particular elemental
objective, is performed as follows. The linear expression specified in
the objective statement is evaluated that gives the resultant linear
form:
@iftex
@tex
$$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$
@end tex
where @math{x_1}, @math{x_2}, @dots, @math{x_n} are elemental variables,
@math{a_1}, @math{a_2}, @dots, @math{a_n} are numeric coefficients,
@math{a_0} is the constant term. Then the linear form is used to
construct the final elemental constraint in the standard form:
@tex
$$-\infty<a_1x_1+a_2x_2+\dots+a_nx_n+a_0<+\infty.$$
@end tex
@end iftex
@ifnottex

@quotation
@i{f} = @i{a}1 @i{x}1 + @i{a}2 @i{x}2 + @dots{} + @i{an} @i{xn} +
@i{a}0,
@end quotation

@noindent
where @i{x}1, @i{x}2, @dots{}, @i{xn} are elemental variables, @i{a}1,
@i{a}2, @dots{}, @i{an} are numeric coefficients, @i{a}0 is the constant
term. Then the linear form is used to construct the final elemental
constraint in the standard form:

@quotation
@minus{}inf < @i{a}1 @i{x}1 + @i{a}2 @i{x}2 + @dots{} + @i{an} @i{xn} +
@i{a}0 < +inf.
@end quotation
@end ifnottex

As a rule the model description contains only one objective statement
that defines the objective function (1) used in the problem instance.
However, it is allowed to declare arbitrary number of objectives, in
which case the actual objective function is the @emph{first} objective
encountered in the model description. Other objectives are also included
in the problem instance, but they do not affect the objective function.

@node Solve statement
@section Solve statement

@cartouche
@verb{| solve ;|}
@end cartouche

@table @asis
@item Note:
The solve statement is optional and can be used only once. If no solve
statement is used, one is assumed at the end of the model section.
@end table

The solve statement causes solving the model, i.e. computing numeric
values of all model variables. This allows using variables in statements
below the solve statement in the same way as if they were numeric
parameters.

Note that variable, constraint, and objective statements cannot be used
below the solve statement, i.e. all principal components of the model
must be described above the solve statement.

@node Check statement
@section Check statement

@cartouche
@verb{| check|} @var{domain} @verb{|:|} @var{expression} @verb{|;|}
@end cartouche

@table @asis
@item Where:
@var{domain} is an optional indexing expression which specifies the
subscript domain of the check statement;
@item
@var{expression} is an logical expression which specifies the logical
condition to be checked. (The colon preceding @var{expression} may be
omitted.)
@end table

@strong{Examples}

@example
check: x + y <= 1 and x >= 0 and y >= 0;
check sum@{i in ORIG@} supply[i] = sum@{j in DEST@} demand[j];
check@{i in I, j in 1..10@}: S[i,j] in U[i] union V[j];
@end example

The check statement allows checking the resultant value of an logical
expression specified in the statement. If the value is @i{false}, the
model translator reports an error.

If the subscript domain is not specified, the check is performed only
once. Specifying the subscript domain allows performing multiple checks
for every @i{n}-tuple in the domain set. In the latter case the logical
expression may include dummy indices introduced in the corresponding
indexing expression.

@node Display statement
@section Display statement

@cartouche
@verb{| display|} @var{domain} @verb{|:|} @var{item} @verb{|,|}
@dots{} @verb{|,|} @var{item} @verb{|;|}
@end cartouche

@table @asis
@item Where:
@var{domain} is an optional indexing expression which specifies the
subscript domain of the display statement;
@item
@var{item}, @dots{}, @var{item} are items to be displayed. (The colon
preceding the first item may be omitted.)
@end table

@strong{Examples}

@example
display: 'x =', x, 'y =', y, 'z =', z;
display sqrt(x ** 2 + y ** 2 + z ** 2);
display@{i in I, j in J@}: i, j, a[i,j], b[i,j];
@end example

The display statement evaluates all items specified in the statement
and writes their values to the terminal in plain text format.

If the subscript domain is not specified, items are evaluated and
then displayed only once. Specifying the subscript domain causes
evaluating and displaying items for every @i{n}-tuple in the domain
set. In the latter case items may include dummy indices introduced in
the corresponding indexing expression.

Item to be displayed can be a model object (set, parameter, variable,
constraint, objective) or an expression.

If the item is a computable object (i.e. a set or parameter provided
with the assign attribute), the object is evaluated over the entire
domain and then its content (i.e. the content of the object array) is
displayed. Otherwise, if the item is not a computable object, only its
current content (i.e. the members actually generated during the model
evaluation) is displayed. Note that if the display statement is used
above the solve statement and the item is a variable, its displayed
``value'' means ``elemental variable'', not a numeric value, which the
variable could have in some solution obtained by the solver. To display
a numeric value of a variable the display statement should be used
below the solve statement. Analogously, if the item is a constraint or
objective, its ``value'' means ``elemental constraint'' or ``elemental
objective'', not a numeric value.

If the item is an expression, the expression is evaluated and its
resultant value is displayed.

@node Printf statement
@section Printf statement

@cartouche
@verb{| printf|} @var{domain} @verb{|:|} @var{format} @verb{|,|}
@var{expression} @verb{|,|} @dots{} @verb{|,|} @var{expression}
@verb{|;|}

@noindent
@verb{| printf|} @var{domain} @verb{|:|} @var{format} @verb{|,|}
@var{expression} @verb{|,|} @dots{} @verb{|,|} @var{expression}
@verb{|>|} @var{filename} @verb{|;|}

@noindent
@verb{| printf|} @var{domain} @verb{|:|} @var{format} @verb{|,|}
@var{expression} @verb{|,|} @dots{} @verb{|,|} @var{expression}
@verb{|>>|} @var{filename} @verb{|;|}
@end cartouche

@table @asis
@item Where:
@var{domain} is an optional indexing expression which specifies the
subscript domain of the printf statement;
@item
@var{format} is a symbolic expression whose value specifies a format
control string. (The colon preceding the format expression may be
omitted.)
@item
@var{expression}, @dots{}, @var{expression} are zero or more expressions
whose values have to be formatted and printed. Each expression must be
of numeric, symbolic, or logical type.
@item
@var{filename} is a symbolic expression whose value specifies the name
of a text file, to which the printf output should be redirected. The
flag @code{>} means creating a new empty file while the flag @code{>>}
means appending the output to an existing file. If no file name is
specified, the output is written to the terminal.
@end table

@strong{Examples}

@example
printf 'Hello, world!\n';
printf: "x = %.3f; y = %.3f; z = %.3f\n", x, y, z > "result.txt";
printf@{i in I, j in J@}: "flow from %s to %s is %d\n", i, j, x[i,j];
printf@{i in I@} 'total flow from %s is %g\n', i, sum@{j in J@} x[i,j];
printf@{k in K@} "x[%s] = " & (if x[k] < 0 then "?" else "%g"), k, x[k];
@end example

The printf statement is similar to the display statement, however, it
allows formatting the data to be written.

If the subscript domain is not specified, the printf statement is
executed only once. Specifying the subscript domain causes executing
the printf statement for every @i{n}-tuple in the domain set. In the
latter case @var{format} and @var{expressions} may include dummy indices
introduced in the corresponding indexing expression.

The format control string is a value of the symbolic expression
@var{format} specified in the printf statement. It is composed of zero
or more directives as follows: ordinary characters (not @code{%}), which
are copied unchanged to the output stream, and conversion
specifications, each of which causes evaluating corresponding
@var{expression} specified in the printf statement, formatting it, and
writing the resultant value to the output stream.

Conversion specifications which may be used in the format control
string are the following: @code{d}, @code{i}, @code{f}, @code{F},
@code{e}, @code{E}, @code{g}, @code{G}, and @code{s}. These
specifications have the same syntax and semantics as in the C
programming language.

@node For statement
@section For statement

@cartouche
@verb{| for|} @var{domain} @verb{|:|} @var{statement}

@noindent
@verb{| for|} @var{domain} @verb{|:|} @verb{|{|} @var{statement}
@dots{} @var{statement} @verb{|}|}
@end cartouche

@table @asis
@item Where:
@var{domain} is an indexing expression which specifies the subscript
domain of the for statement. (The colon following the indexing
expression may be omitted.)
@item
@var{statement} is a statement which should be executed under control of
the for statement;
@item
@var{statement}, @dots{}, @var{statement} is a sequence of statements
(enclosed in curly braces) which should be executed under control of the
for statement.
@end table

@table @asis
@item Note:
Only the following statements are allowed within the for statement:
check, display, printf, and another for.
@end table

@strong{Examples}

@example
for @{(i,j) in E: i != j@}
@{  printf "flow from %s to %s is %g\n", i, j, x[i,j];
   check x[i,j] >= 0;
@}
for @{i in 1..n@}
@{  for @{j in 1..n@} printf " %s", if x[i,j] then "Q" else ".";
   printf("\n");
@}
for @{1..72@} printf("*");
@end example

The for statement causes executing a statement or a sequence of
statements specified as part of the for statement for every @i{n}-tuple
in the domain set. Thus, statements within the for statement may refer
to dummy indices introduced in the corresponding indexing expression.

@node Model data
@chapter Model data

@menu
* Coding data section::
* Set data block::
* Parameter data block::
@end menu

@dfn{Model data} include elemental sets, which are ``values'' of model
sets, and numeric and symbolic values of model parameters.

In MathProg there are two different ways to saturate model sets and
parameters with data. One way is simply providing necessary data using
the assign attribute. However, in many cases it is more practical to
separate the model itself and particular data needed for the model.
For the latter reason in MathProg there is other way, when the model
description is divided into two parts: model section and data section.

@i{Model section} is a main part of the model description that contains
declarations of all model objects and is common for all problems based
on that model.

@i{Data section} is an optional part of the model description that
contains model data specific for a particular problem.

In MathProg model and data sections can be placed either in one text
file or in two separate text files.

If both model and data sections are placed in one file, the file is
composed as follows:

@example
+------------+
| statement  |
| statement  |
| . . .      |
| statement  |
| data;      |
| data block |
| data block |
| . . .      |
| data block |
| end;       |
+------------+
@end example

If the model and data sections are placed in two separate files, the
files are composed as follows:

@example
+------------+   +------------+
| statement  |   | data;      |
| statement  |   | data block |
| . . .      |   | data block |
| statement  |   | . . .      |
| end;       |   | data block |
|            |   | end;       |
+------------+   +------------+
  Model file       Data file
@end example

@table @asis
@item Note:
If the data section is placed in a separate file, the keyword
@code{data} is optional and may be omitted along with the semicolon
that follows it.
@end table

@node Coding data section
@section Coding data section

The data section is a sequence of data blocks in various formats, which
are discussed in following subsections. The order, in which data blocks
follow in the data section, may be arbitrary, not necessarily the same
as in which the corresponding model objects follow in the model section.

The rules of coding the data section are commonly the same as the rules
of coding the model description (for details see Section ``Coding model
description''), i.e. data blocks are composed from basic lexical units
such as symbolic names, numeric and string literals, keywords,
delimiters, and comments. However, for the sake of convenience and
improving readability there is one deviation from the common rule: if
a string literal consists of only alphanumeric characters (including the
underscore character), the signs @code{+} and @code{-}, and/or the
decimal point, it may be coded @emph{without} bordering (single or
double) quotes.

All numeric and symbolic material provided in the data section is coded
in the form of numbers and symbols, i.e. unlike the model section
no expressions are allowed in the data section. Nevertheless the signs
@code{+} and @code{-} can precede numeric literals to allow coding
signed numeric quantities, in which case there must be no white-space
characters between the sign and following numeric literal (if there is
at least one white-space, the sign and following numeric literal are
recognized as @emph{two} different lexical units).

@node Set data block
@section Set data block

@cartouche
@verb{| set|} @var{name} @verb{|,|} @var{record} @verb{|,|}
@dots{} @verb{|,|} @var{record} @verb{|;|}

@noindent
@verb{| set|} @var{name} @verb{|[|} @var{symbol} @verb{|,|}
@dots{} @verb{|,|} @var{symbol} @verb{|]|} @verb{|,|} @var{record}
@verb{|,|} @dots{} @verb{|,|} @var{record} @verb{|;|}
@end cartouche

@table @asis
@item Where:
@var{name} is a symbolic name of the set;
@item
@var{symbol}, @dots{}, @var{symbol} are subscripts which specify a
particular member of the set (if the set is an array, i.e. a set of
sets);
@item
@var{record}, @dots{}, @var{record} are data records.
@end table

@table @asis
@item Note:
Commae preceding data records may be omitted.
@end table

@noindent
Data records:

@table @asis
@item @t{:=}
is a non-significant data record which may be used freely to improve
readability;
@item @t{(} @var{slice} @t{)}
specifies a slice;
@item @var{simple-data}
specifies set data in the simple format;
@item @t{:} @var{matrix-data}
specifies set data in the matrix format;
@item @t{(tr) :} @var{matrix-data}
specifies set data in the transposed matrix format. (In this case the
colon following the keyword @t{(tr)} may be omitted.)
@end table

@page

@strong{Examples}

@example
set month := Jan Feb Mar Apr May Jun;
set month "Jan", "Feb", "Mar", "Apr", "May", "Jun";
set A[3,Mar] := (1,2) (2,3) (4,2) (3,1) (2,2) (4,4) (3,4);
set A[3,'Mar'] := 1 2 2 3 4 2 3 1 2 2 4 4 2 4;
set A[3,'Mar'] : 1 2 3 4 :=
               1 - + - -
               2 - + + -
               3 + - - +
               4 - + - + ;
set B := (1,2,3) (1,3,2) (2,3,1) (2,1,3) (1,2,2) (1,1,1) (2,1,1);
set B := (*,*,*) 1 2 3, 1 3 2, 2 3 1, 2 1 3, 1 2 2, 1 1 1, 2 1 1;
set B := (1,*,2) 3 2 (2,*,1) 3 1 (1,2,3) (2,1,3) (1,1,1);
set B := (1,*,*) : 1 2 3 :=
                 1 + - -
                 2 - + +
                 3 - + -
         (2,*,*) : 1 2 3 :=
                 1 + - +
                 2 - - -
                 3 + - - ;
@end example

@noindent
(In these examples the set @code{month} is a simple set of singles,
@code{A} is a 2-dimensional array of doubles, and @code{B} is a simple
set of triples. Data blocks for the same set are equivalent in the sense
that they specify the same data in different formats.)

The set data block is used to specify a complete elemental set, which
is assigned to a set (if it is a simple set) or one of its members (if
the set is an array of sets).@footnote{There is another way to specify
data for a simple set along with data for parameters. This feature is
discussed in the next section.}

Data blocks can be specified only for non-computable sets, i.e. sets
which have no assign attribute in the corresponding set statements.

If the set is a simple set, only its symbolic name should be given in
the header of the data block. Otherwise, if the set is a
@i{n}-dimensional array, its symbolic name should be provided with a
complete list of subscripts separated by commae and enclosed in square
brackets to specify a particular member of the set array. The number of
subscripts must be the same as the dimension of the set array, where
each subscript must be a number or symbol.

The elemental set defined in the set data block is coded as a sequence
of data records described below.@footnote{@dfn{Data record} is simply a
technical term. It @emph{does not mean} that data records have any
special formatting.}

@subheading Assign data record

The assign (@code{:=}) data record is a non-signficant element. It may
be used for improving readability of data blocks.

@subheading Slice data record

The slice data record is a control record which specifies a slice of
the elemental set defined in the data block. It has the following
syntactic form:

@iftex
@quotation
@verb{|(|} @math{s_1} @verb{|,|} @math{s_2} @verb{|,|} @dots@ @verb{|,|}
@math{s_n} @verb{|)|}
@end quotation

@noindent
where @math{s_1}, @math{s_2}, @dots, @math{s_n} are components of the
slice.
@end iftex

@ifnottex
@quotation
@verb{|(|} @i{s}1 @verb{|,|} @i{s}2 @verb{|,|} @dots{} @verb{|,|}
@i{sn} @verb{|)|}
@end quotation

@noindent
where @i{s}1, @i{s}2, @dots{}, @i{sn} are components of the slice.
@end ifnottex

Each component of the slice can be a number or symbol or the asterisk
(@verb{|*|}). The number of components in the slice must be the same as
the dimension of @i{n}-tuples in the elemental set to be defined. For
instance, if the elemental set contains 4-tuples (quadruples), the slice
must have four components. The number of asterisks in the slice is
called @dfn{slice dimension}.

The effect of using slices is the following. If a @i{m}-dimensional
slice (i.e. a slice which has @math{m} asterisks) is specified in the
data block, all subsequent data records must specifiy tuples of the
dimension @i{m}. Whenever a @math{m}-tuple is encountered, each
asterisk in the slice is replaced by corresponding components of the
@math{m}-tuple that gives the resultant @i{n}-tuple, which is included
in the elemental set to be defined. For example, if the slice
@t{(a,*,1,2,*)} is in effect, and 2-tuple @t{(3,b)} is encountered
in a subsequent data record, the resultant 5-tuple included in the
elemental set is @t{(a,3,1,2,b)}.

The slice that has no asterisks itself defines a complete @i{n}-tuple,
which is included in the elemental set.

Being once specified the slice effects until either a new slice or the
end of data block has been encountered. Note that if there is no slice
specified in the data block, a dummy one, components of which are all
asterisks, is assumed.

@subheading Simple data record

The simple data record defines one @i{n}-tuple in simple format and has
the following syntactic form:

@iftex
@quotation
@math{t_1} @verb{|,|} @math{t_2} @verb{|,|} @dots@ @verb{|,|} @math{t_n}
@end quotation

@noindent
where @math{t_1}, @math{t_2}, @dots, @math{t_n} are components of the
@i{n}-tuple. Each component can be a number or symbol. Commae between
components are optional and may be omitted.
@end iftex

@ifnottex
@quotation
@i{t}1 @verb{|,|} @i{t}2 @verb{|,|} @dots{} @verb{|,|} @i{tn}
@end quotation

@noindent
where @i{t}1, @i{t}2, @dots{}, @i{tn} are components of the @i{n}-tuple.
Each component can be a number or symbol. Commae between components are
optional and may be omitted.
@end ifnottex

@subheading Matrix data record

The matrix data record defines several 2-tuples (doubles) in matrix
format and has the following syntactic form:

@iftex
@quotation
@tex
$\matrix{
{\tt :} & c_1 & c_2 & \dots & c_n & {\tt :=} \cr
r_1 & a_{11} & a_{12} & \dots & a_{1n} & \cr
r_2 & a_{21} & a_{22} & \dots & a_{2n} & \cr
\dots & \dots & \dots & \dots & \dots & \cr
r_m & a_{m1} & a_{m2} & \dots & a_{mn} & \cr
}$
@end tex
@end quotation

@noindent
where @math{r_1}, @math{r_2}, @dots, @math{r_m} are numbers and/or
symbols which correspond to rows of the matrix, @math{c_1}, @math{c_2},
@dots, @math{c_n} are numbers and/or symbols which correspond to columns
of the matrix, @math{a_{11}}, @math{a_{12}}, @dots, @math{a_{mn}} are
the matrix elements, which can be either the sign @code{+} or the sign
@code{-}. (In this data record the delimiter @code{:} preceding the
column list and the delimiter @code{:=} following the column list cannot
be omitted.)

Each element @math{a_{ij}} of the matrix data block (where
@math{1@leq i@leq m}, @math{1@leq j@leq n}) corresponds to 2-tuple
@math{(r_i, c_j)}. If @math{a_{ij}} is the plus sign (@code{+}), the
corresponding 2-tuple (or a longer @i{n}-tuple, if a slice is used)
is included in the elemental set. Otherwise, if @math{a_{ij}} is the
minus sign (@code{-}) sign, the corresponding 2-tuple is not included
in the elemental set.
@end iftex

@ifnottex
@quotation
@multitable @columnfractions .06 .06 .06 .06 .06 .06
@item @t{:} @tab @i{c}1 @tab @i{c}2 @tab @dots{} @tab @i{cn} @tab @t{:=}
@item @i{r}1 @tab @i{a}11 @tab @i{a}12 @tab @dots{} @tab @i{a}1@i{n}
@item @i{r}2 @tab @i{a}21 @tab @i{a}22 @tab @dots{} @tab @i{a}2@i{n}
@item @dots{} @tab @dots{} @tab @dots{} @tab @dots{} @tab @dots{}
@item @i{rm} @tab @i{am}1 @tab @i{am}2 @tab @dots{} @tab @i{amn}
@end multitable
@end quotation

@noindent
where @i{r}1, @i{r}2, @dots{}, @i{rm} are numbers and/or symbols which
correspond to rows of the matrix, @i{c}1, @i{c}2, @dots{}, @i{cn} are
numbers and/or symbols which correspond to columns of the matrix,
@i{a}11, @i{a}12, @dots{}, @i{amn} are the matrix elements, which can be
either the sign @code{+} or the sign @code{-}. (In this data record the
delimiter @code{:} preceding the column list and the delimiter @code{:=}
following the column list cannot be omitted.)

Each element @i{aij} of the matrix data block (where
1@tie{}<=@tie{}i@tie{}<=@tie{}@i{m},
1@tie{}<=@tie{}j@tie{}<=@tie{}@i{n}) corresponds to 2-tuple
(@i{ri},@tie{}@i{cj}). If @i{aij} is the plus sign (@code{+}), the
corresponding 2-tuple (or a longer @i{n}-tuple, if a slice is used)
is included in the elemental set. Otherwise, if @i{aij} is the minus
sign (@code{-}) sign, the corresponding 2-tuple is not included in the
elemental set.
@end ifnottex

Since the matrix data record defines 2-tuples, either the elemental
set must consist of 2-tuples or the slice currently used must be
2-dimensional.

@subheading Transposed matrix data record

The transposed matrix data record has the following syntactic form:

@iftex
@quotation
@tex
$\matrix{
{\tt (tr)\ :} & c_1 & c_2 & \dots & c_n & {\tt :=} \cr
r_1 & a_{11} & a_{12} & \dots & a_{1n} & \cr
r_2 & a_{21} & a_{22} & \dots & a_{2n} & \cr
\dots & \dots & \dots & \dots & \dots & \cr
r_m & a_{m1} & a_{m2} & \dots & a_{mn} & \cr
}$
@end tex
@end quotation
@end iftex

@ifnottex
@quotation
@multitable @columnfractions .10 .06 .06 .06 .06 .06
@item @t{(tr) :} @tab @i{c}1 @tab @i{c}2 @tab @dots{} @tab @i{cn} @tab
@t{:=}
@item @i{r}1 @tab @i{a}11 @tab @i{a}12 @tab @dots{} @tab @i{a}1@i{n}
@item @i{r}2 @tab @i{a}21 @tab @i{a}22 @tab @dots{} @tab @i{a}2@i{n}
@item @dots{} @tab @dots{} @tab @dots{} @tab @dots{} @tab @dots{}
@item @i{rm} @tab @i{am}1 @tab @i{am}2 @tab @dots{} @tab @i{amn}
@end multitable
@end quotation
@end ifnottex

@noindent
(In this case the delimiter @code{:} following the keyword @code{(tr)}
is optional and may be omitted.)

This data record is completely analogous to the matrix data record (see
above) with the only exception that each element
@iftex
@math{a_{ij}} of the matrix corresponds to 2-tuple @math{(c_j,r_i)}.
@end iftex
@ifnottex
@i{aij} of the matrix corresponds to 2-tuple (@i{cj},@tie{}@i{ri}).
@end ifnottex

Being once specified the @code{(tr)} indicator effects on @emph{all}
subsequent data records until either a slice or the end of data block
has been encountered.

@node Parameter data block
@section Parameter data block

@cartouche
@verb{| param|} @var{name} @verb{|,|} @var{record} @verb{|,|} @dots{}
@verb{|,|} @var{record} @verb{|;|}

@noindent
@verb{| param|} @var{name} @verb{|default|} @var{value} @verb{|,|}
@var{record} @verb{|,|} @dots{} @verb{|,|} @var{record} @verb{|;|}

@noindent
@verb{| param|} @verb{|:|} @var{tabbing-data} @verb{|;|}

@noindent
@verb{| param|} @verb{|default|} @var{value} @verb{|:|}
@var{tabbing-data} @verb{|;|}
@end cartouche

@table @asis
@item Where:
@var{name} is a symbolic name of the parameter;
@item
@var{value} is an optional default value of the parameter;
@item
@var{record}, @dots{}, @var{record} are data records.
@item
@var{tabbing-data} specifies parameter data in the tabbing format.
@end table

@table @asis
@item Note:
Commae preceding data records may be omitted.
@end table

@noindent
Data records:

@table @asis
@item @t{:=}
is a non-significant data record which may be used freely to improve
readability;
@item @t{[} @var{slice} @t{]}
specifies a slice;
@item @var{plain-data}
specifies parameter data in the plain format;
@item @t{:} @var{tabular-data}
specifies parameter data in the tabular format;
@item @t{(tr) :} @var{tabular-data}
specifies parameter data in the transposed tabular format. (In this case
the colon following the keyword @verb{|(tr)|} may be omitted.)
@end table

@page

@strong{Examples}

@example
param T := 4;
param month := 1 Jan 2 Feb 3 Mar 4 Apr 5 May;
param month := [1] 'Jan', [2] 'Feb', [3] 'Mar', [4] 'Apr', [5] 'May';
param init_stock := iron 7.32 nickel 35.8;
param init_stock [*] iron 7.32, nickel 35.8;
param cost [iron] .025 [nickel] .03;
param value := iron -.1, nickel .02;
param       : init_stock  cost  value :=
      iron       7.32     .025   -.1
      nickel    35.8      .03     .02 ;
param : raw : init stock  cost  value :=
        iron     7.32     .025   -.1
        nickel  35.8      .03     .02 ;
param demand default 0 (tr)
       :  FRA  DET  LAN  WIN  STL  FRE  LAF :=
   bands  300   .   100   75   .   225  250
   coils  500  750  400  250   .   850  500
   plate  100   .    .    50  200   .   250 ;
param trans_cost :=
   [*,*,bands]:  FRA  DET  LAN  WIN  STL  FRE  LAF :=
         GARY     30   10    8   10   11   71    6
         CLEV     22    7   10    7   21   82   13
         PITT     19   11   12   10   25   83   15
   [*,*,coils]:  FRA  DET  LAN  WIN  STL  FRE  LAF :=
         GARY     39   14   11   14   16   82    8
         CLEV     27    9   12    9   26   95   17
         PITT     24   14   17   13   28   99   20
   [*,*,plate]:  FRA  DET  LAN  WIN  STL  FRE  LAF :=
         GARY     41   15   12   16   17   86    8
         CLEV     29    9   13    9   28   99   18
         PITT     26   14   17   13   31  104   20 ;
@end example

The parameter data block is used to specify complete data for a
parameter (or parameters, if data are specified in the tabbing format)
whose name is given in the block.

Data blocks can be specified only for the parameters, which are
non-computable, i.e. which have no assign attribute in the corresponding
parameter statements.

Data defined in the parameter data block are coded as a sequence of
data records described below. Additionally the data block can be
provided with the optional @code{default} attribute, which specifies
a default numeric or symbolic value of the parameter (parameters). This
default value is assigned to the parameter or its members, if
no appropriate value is defined in the parameter data block. The
@code{default} attribute cannot be used, if it is already specified in
the corresponding parameter statement(s).

@subheading Assign data record

The assign (@code{:=}) data record is a non-signficant element. It may
be used for improving readability of data blocks.

@subheading Slice data record

The slice data record is a control record which specifies a slice of
the parameter array. It has the following syntactic form:

@iftex
@quotation
@verb{|[|} @math{s_1} @verb{|,|} @math{s_2} @verb{|,|} @dots@ @verb{|,|}
@math{s_n} @verb{|]|}
@end quotation

@noindent
where @math{s_1}, @math{s_2}, @dots, @math{s_n} are components of the
slice.
@end iftex

@ifnottex
@quotation
@verb{|[|} @i{s}1 @verb{|,|} @i{s}2 @verb{|,|} @dots{} @verb{|,|}
@i{sn} @verb{|]|}
@end quotation

@noindent
where @i{s}1, @i{s}2, @dots{}, @i{sn} are components of the slice.
@end ifnottex

Each component of the slice can be a number or symbol or the asterisk
(@code{|*|}). The number of components in the slice must be the same as
the dimension of the parameter. For instance, if the parameter is a
4-dimensional array, the slice must have four components. The number of
asterisks in the slice is called @dfn{slice dimension}.

The effect of using slices is the following. If a @i{m}-dimensional
slice (i.e. a slice which has @i{m} asterisks) is specified in the
data block, all subsequent data records must specify subscripts of the
parameter members as if the parameter were @i{m}-dimensional, not
@i{n}-dimensional.

Whenever @i{m} subscripts are encountered, each asterisk in the slice is
replaced by corresponding subscript that gives @i{n} subscripts, which
define the actual parameter member. For example, if the slice
@t{[a,*,1,2,*]} is in effect, and the subscripts @t{3} and @t{b} are
encountered in a subsequent data record, the complete subscript list
used to choose a parameter member is @t{[a,3,1,2,b]}.

It is allowed to specify a slice that has no asterisks. Such slice
itself defines a complete subscript list, in which case the next data
record can define only a single value of the corresponding parameter
member.

Being once specified the slice effects until either a new slice or the
end of data block has been encountered. Note that if there is no slice
specified in the data block, a dummy one, components of which are all
asterisks, is assumed.

@subheading Plain data record

The plain data record defines the subscript list and a single value in
plain format. This record has the following syntactic form:

@iftex
@quotation
@math{t_1} @verb{|,|} @math{t_2} @verb{|,|} @dots@ @verb{|,|} @math{t_n}
@verb{|,|} @math{v}
@end quotation

@noindent
where @math{t_1}, @math{t_2}, @dots, @math{t_n} are subscripts, @math{v}
@end iftex
@ifnottex
@quotation
@i{t}1 @verb{|,|} @i{t}2 @verb{|,|} @dots{} @verb{|,|} @i{tn} @verb{|,|}
@i{v}
@end quotation

@noindent
where @i{t}1, @i{t}2, @dots{}, @i{tn} are subscripts, @i{v}
@end ifnottex
is a value. Each subscript as well as the value can be a number or
symbol. Commae following subscripts are optional and may be omitted.

In case of 0-dimensional parameter or slice the plain data record have
no subscripts and consists of a single value only.

@subheading Tabular data record

The tabular data record defines several values, where each value is
provided with two subscripts. This record has the following syntactic
form:

@iftex
@quotation
@tex
$\matrix{
{\tt :} & c_1 & c_2 & \dots & c_n & {\tt :=} \cr
r_1 & a_{11} & a_{12} & \dots & a_{1n} & \cr
r_2 & a_{21} & a_{22} & \dots & a_{2n} & \cr
\dots & \dots & \dots & \dots & \dots & \cr
r_m & a_{m1} & a_{m2} & \dots & a_{mn} & \cr
}$
@end tex
@end quotation

@noindent
where @math{r_1}, @math{r_2}, @dots, @math{r_m} are numbers and/or
symbols which correspond to rows of the table, @math{c_1}, @math{c_2},
@dots, @math{c_n} are numbers and/or symbols which correspond to columns
of the table, @math{a_{11}}, @math{a_{12}}, @dots, @math{a_{mn}} are the
table elements. Each element can be a number or symbol or the single
decimal point. (In this data record the delimiter @verb{|:|} preceding
the column list and the delimiter @verb{|:=|} following the column list
cannot be omitted.)

Each element @math{a_{ij}} of the tabular data block
(@math{1@leq i@leq m}, @math{1@leq j@leq n}) defines two subscripts,
where the first subscript is @math{r_i}, and the second one is
@math{c_j}. These subscripts are used in conjunction with the current
slice to form the complete subscript list which identifies a particular
member of the parameter array. If @math{a_{ij}} is a number or symbol,
this value is assigned to the parameter member. However, if
@math{a_{ij}} is the single decimal point, the member is assigned
a default value specified either in the parameter data block or in the
parameter statement, or, if no default value is specified, the member
remains undefined.
@end iftex

@ifnottex
@quotation
@multitable @columnfractions .06 .06 .06 .06 .06 .06
@item @t{:} @tab @i{c}1 @tab @i{c}2 @tab @dots{} @tab @i{cn} @tab @t{:=}
@item @i{r}1 @tab @i{a}11 @tab @i{a}12 @tab @dots{} @tab @i{a}1@i{n}
@item @i{r}2 @tab @i{a}21 @tab @i{a}22 @tab @dots{} @tab @i{a}2@i{n}
@item @dots{} @tab @dots{} @tab @dots{} @tab @dots{} @tab @dots{}
@item @i{rm} @tab @i{am}1 @tab @i{am}2 @tab @dots{} @tab @i{amn}
@end multitable
@end quotation

@noindent
where @i{r}1, @i{r}2, @dots{}, @i{rm} are numbers and/or symbols which
correspond to rows of the table, @i{c}1, @i{c}2, @dots{}, @i{cn} are
numbers and/or symbols which correspond to columns of the table,
@i{a}11, @i{a}12, @dots{}, @i{amn} are the table elements. Each element
can be a number or symbol or the single decimal point. (In this data
record the delimiter @code{:} preceding the column list and the
delimiter @code{:=} following the column list cannot be omitted.)

Each element @i{aij} of the tabular data block
(1@tie{}<=@tie{}i@tie{}<=@tie{}@i{m},
1@tie{}<=@tie{}j@tie{}<=@tie{}@i{n}) defines two subscripts, where the
first subscript is @i{ri}, and the second one is @i{cj}. These
subscripts are used in conjunction with the current slice to form the
complete subscript list which identifies a particular member of the
parameter array. If @i{aij} is a number or symbol, this value is
assigned to the parameter member. However, if @i{aij} is the single
decimal point, the member is assigned a default value specified either
in the parameter data block or in the parameter statement, or, if
no default value is specified, the member remains undefined.
@end ifnottex

Since the tabular data record provides two subscripts for each value,
either the parameter or the slice currently used must be 2-dimensional.

@subheading Transposed tabular data record

The transposed tabular data record has the following syntactic form:

@iftex
@quotation
@tex
$\matrix{
{\tt (tr)\ :} & c_1 & c_2 & \dots & c_n & {\tt :=} \cr
r_1 & a_{11} & a_{12} & \dots & a_{1n} & \cr
r_2 & a_{21} & a_{22} & \dots & a_{2n} & \cr
\dots & \dots & \dots & \dots & \dots & \cr
r_m & a_{m1} & a_{m2} & \dots & a_{mn} & \cr
}$
@end tex
@end quotation
@end iftex

@ifnottex
@quotation
@multitable @columnfractions .10 .06 .06 .06 .06 .06
@item @t{(tr) :} @tab @i{c}1 @tab @i{c}2 @tab @dots{} @tab @i{cn} @tab
@t{:=}
@item @i{r}1 @tab @i{a}11 @tab @i{a}12 @tab @dots{} @tab @i{a}1@i{n}
@item @i{r}2 @tab @i{a}21 @tab @i{a}22 @tab @dots{} @tab @i{a}2@i{n}
@item @dots{} @tab @dots{} @tab @dots{} @tab @dots{} @tab @dots{}
@item @i{rm} @tab @i{am}1 @tab @i{am}2 @tab @dots{} @tab @i{amn}
@end multitable
@end quotation
@end ifnottex

@noindent
(In this case the delimiter @code{:} following the keyword @code{(tr)}
is optional and may be omitted.)

This data record is completely analogous to the tabular data record (see
above) with the only exception that the first subscript defined by the
element
@iftex
@math{a_{ij}} is @math{c_j} while the second one is @math{r_i}.
@end iftex
@ifnottex
@i{aij} is @i{cj} while the second one is @i{ri}.
@end ifnottex

Being once specified the @code{(tr)} indicator effects on all subsequent
data records until either a slice or the end of data block has been
encountered.

@subheading Tabbing data format

The parameter data block in the tabbing format has the following
syntactic form:

@iftex
@quotation
@tex
$\matrix{
{\tt param\ default}\ {\it value} : s :&p_1\ ,&p_2\ ,&\dots\ ,&p_k
\ :=\cr
\hfill t_{11}\ ,\ t_{12}\ ,\ \dots\ ,\ t_{1n}\ ,&a_{11}\ ,&a_{12}\ ,&
\dots\ ,&a_{1k}\hfill\cr
\hfill t_{21}\ ,\ t_{22}\ ,\ \dots\ ,\ t_{2n}\ ,&a_{21}\ ,&a_{22}\ ,&
\dots\ ,&a_{2k}\hfill\cr
\ \ \ \ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .&
\dots&\dots&\dots\ \ &\dots\ \ \ \cr
\hfill t_{m1}\ ,\ t_{m2}\ ,\ \dots\ ,\ t_{mn}\ ,&a_{m1}\ ,&a_{m2}\ ,&
\dots\ ,&a_{mk}\ ;\hfill\cr
}$
@end tex
@end quotation
@end iftex

@ifnottex
@example
param default value : s :  p1 ,  p2 , ...,  pk :=
t11 , t12 , ... , t1n ,   a11 , a12 , ..., a1k
t21 , t22 , ... , t2n ,   a21 , a22 , ..., a2k
  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
tm1 , tm2 , ... , tmn ,   am1 , am2 , ..., amk ;
@end example
@end ifnottex

@table @asis
@item Note:
The keyword @verb{|default|} may be omitted along with a value
following it.
@item
The symbolic name @math{s} of a set may be omitted along with the
colon following it.
@item
All comae are optional and may be omitted.
@end table

The data block in the tabbing format shown above is exactly equivalent
to the following data blocks:

@iftex
@quotation
@verb{|set|} @math{s:=(t_{11},t_{12},@dots,t_{1n})@ (t_{21},t_{22},
@dots,t_{2n})@ @dots@ (t_{m1},t_{m2},@dots,t_{mn})}@ ;

@verb{|param|} @math{p_j} @verb{|default|} @i{value} :=

@ @ @ @ @ @ @ @ @ @ @ @ @math{[t_{11},t_{12},@dots,t_{1n}]@ a_{1j}
@ [t_{21},t_{22},@dots,t_{2n}]@ a_{2j}@ @dots@ [t_{m1},t_{m2},@dots,
t_{mn}]@ a_{mj}}@ ;
@end quotation
@end iftex

@ifnottex
@example
set s := (t11,...,t1n) (t21,...,t2n) ... (tm1,...,tmn)

param pj default value :=
         [t11,...,t1n] a1j [t21,...,t2n] a2j ... [tm1,...,tmn] amj;
@end example
@end ifnottex

@noindent
where @i{j} = 1, 2, @dots{}, @i{k}.

@node Date and time functions
@appendix Date and time functions

@center by Andrew Makhorin @t{<mao@@mai2.rcnet.ru>}
@center and Heinrich Schuchardt @t{<heinrich.schuchardt@@gmx.de>} 

@menu
* Obtaining current calendar time::
* Converting character string to calendar time::
* Converting calendar time to character string::
@end menu

@node Obtaining current calendar time
@section Obtaining current calendar time

To obtain the current calendar time there is the function
@verb{|gmtime|}. It has no arguments and returns the number of seconds
elapsed since 00:00:00 on January 1, 1970, Coordinated Universal Time
(UTC). For example:

@example
param utc := gmtime();
@end example

GNU MathProg has no functions to convert UTC time returned by the
function @verb{|gmtime|} to @emph{local} calendar times. Thus, if you
need to determine the current local calendar time, you have to add to
the UTC time returned the time offset from UTC expressed in seconds.
For example, the time in Berlin during the winter is one hour ahead of
UTC that corresponds to the time offset +1 hour = +3600 secs, so the
current winter calendar time in Berlin may be determined as follows:

@example
param now := gmtime() + 3600;
@end example

@noindent
Similarly, the summer time in Chicago (Central Daylight Time) is five
hours behind UTC, so the corresponding current local calendar time may
be determined as follows:

@example
param now := gmtime() - 5 * 3600;
@end example

Note that the value returned by @verb{|gmtime|} is volatile, i.e.
being called several times this function may return different values.

@node Converting character string to calendar time
@section Converting character string to calendar time

The function @verb{|str2time|}(@i{s},@tie{}@i{f}) converts a character
string (timestamp) specified by its first argument @i{s}, which must be
a symbolic expression, to the calendar time suitable for arithmetic
calculations. The conversion is controlled by the specified format
string @i{f} (the second argument), which also must be a symbolic
expression.

The result of conversion returned by @verb{|str2time|} has the same
meaning as the value returned by the function @verb{|gmtime|}
(@xref{Obtaining current calendar time}). Note that @verb{|str2time|}
does @emph{not} correct the calendar time returned for the local
timezone, i.e. being applied to 00:00:00 on January 1, 1970 it always
returns 0.

For example, the model statements:

@example
param s, symbolic, := "07/14/98 13:47";
param t := str2time(s, "%m/%d/%y %H:%M");
display t;
@end example

@noindent
produce the following printout:

@example
t = 900424020
@end example

@noindent
where the calendar time printed corresponds to 13:47:00 on July 14,
1998.

The format string passed to the function @verb{|str2time|} consists of
conversion specifiers and ordinary characters. Each conversion specifier
begins with a `@t{%}' character followed by a letter.

@page

The following conversion specifiers may be used in the format string:

@table @asis
@item @t{%b}
The abbreviated month name (case insensitive). At least three first
letters of the month name must appear in the input string.
@item @t{%d}
The day of the month as a decimal number (range 1 to 31). Leading zero
is permitted, but not required.
@item @t{%h}
The same as @t{%b}.
@item @t{%H}
The hour as a decimal number, using a 24-hour clock (range 0 to 23).
Leading zero is permitted, but not required.
@item @t{%m}
The month as a decimal number (range 1 to 12). Leading zero is
permitted, but not required.
@item @t{%M}
The minute as a decimal number (range 0 to 59). Leading zero is
permitted, but not required.
@item @t{%S}
The second as a decimal number (range 0 to 60). Leading zero is
permitted, but not required.
@item @t{%y}
The year without a century as a decimal number (range 0 to 99). Leading
zero is permitted, but not required. Input values in the range 0 to 68
are considered as the years 2000 to 2068 while the values 69 to 99 as
the years 1969 to 1999.
@item @t{%z}
The offset from GMT in ISO 8601 format.
@item @t{%%}
A literal `@t{%}' character.
@end table

All other (ordinary) characters in the format string must have
a matching character in the input string to be converted. Exceptions
are spaces in the input string which can match zero or more space
characters in the format string.

If some date and/or time component(s) are missing in the format and,
therefore, in the input string, the function @verb{|str2time|} uses
their default values corresponding to 00:00:00 on January 1, 1970, that
is, the default value of the year is 1970, the default value of the
month is January, etc.

The function @verb{|str2time|} is applicable to all calendar times in
the range 00:00:00 on January 1, 0001 to 23:59:59 on December 31, 4000
of the Gregorian calendar.

@node Converting calendar time to character string
@section Converting calendar time to character string

The function @verb{|time2str|}(@i{t},@tie{}@i{f}) converts the calendar
time specified by its first argument @i{t}, which must be a numeric
expression, to a character string (symbolic value). The conversion is
controlled by the specified format string @i{f} (the second argument),
which must be a symbolic expression.

The calendar time passed to @verb{|time2str|} has the same meaning as
the value returned by the function @verb{|gmtime|} (@xref{Obtaining
current calendar time}). Note that @t{time2str} does @emph{not} correct
the specified calendar time for the local timezone, i.e. the calendar
time 0 always corresponds to 00:00:00 on January 1, 1970.

@page

For example, the model statements:

@example
param s, symbolic, := time2str(gmtime(), "%FT%TZ");
display s;
@end example

@noindent
may produce the following printout:

@example
s = '2008-12-04T00:23:45Z'
@end example

@noindent
which is a timestamp in the ISO format.

The format string passed to the function @verb{|time2str|} consists of
conversion specifiers and ordinary characters. Each conversion specifier
begins with a `@t{%}' character followed by a letter.

The following conversion specifiers may be used in the format string:

@table @asis
@item @t{%a}
The abbreviated (2-character) weekday name.
@item @t{%A}
The full weekday name.
@item @t{%b}
The abbreviated (3-character) month name.
@item @t{%B}
The full month name.
@item @t{%C}
The century of the year, that is the greatest integer not greater than
the year divided by 100.
@item @t{%d}
The day of the month as a decimal number (range 01 to 31).
@item @t{%D}
The date using the format @t{%m/%d/%y}.
@item @t{%e}
The day of the month like with @t{%d}, but padded with blank rather
than zero.
@item @t{%F}
The date using the format @t{%Y-%m-%d}.
@item @t{%g}
The year corresponding to the ISO week number, but without the century
(range 00 to 99). This has the same format and value as @t{%y}, except
that if the ISO week number (see @t{%V}) belongs to the previous or next
year, that year is used instead.
@item @t{%G}
The year corresponding to the ISO week number. This has the same format
and value as @t{%Y}, except that if the ISO week number (see @t{%V})
belongs to the previous or next year, that year is used instead.
@item @t{%h}
The same as @t{%b}.
@item @t{%H}
The hour as a decimal number, using a 24-hour clock (range 00 to 23).
@item @t{%I}
The hour as a decimal number, using a 12-hour clock (range 01 to 12).
@item @t{%j}
The day of the year as a decimal number (range 001 to 366).
@item @t{%k}
The hour as a decimal number, using a 24-hour clock like @t{%H}, but
padded with blank rather than zero.
@item @t{%l}
The hour as a decimal number, using a 12-hour clock like @t{%I}, but
padded with blank rather than zero.
@item @t{%m}
The month as a decimal number (range 01 to 12).
@item @t{%M}
The minute as a decimal number (range 00 to 59).
@item @t{%p}
Either `@t{AM}' or `@t{PM}', according to the given time value.
Midnight is treated as `@t{AM}' and noon as `@t{PM}'.
@item @t{%P}
Either `@t{am}' or `@t{pm}', according to the given time value.
Midnight is treated as `@t{am}' and noon as `@t{pm}'.
@item @t{%R}
The hour and minute in decimal numbers using the format @t{%H:%M}.
@item @t{%S}
The second as a decimal number (range 00 to 59).
@item @t{%T}
The time of day in decimal numbers using the format @t{%H:%M:%S}.
@item @t{%u}
The day of the week as a decimal number (range 1 to 7), Monday being 1.
@item @t{%U}
The week number of the current year as a decimal number (range 00 to
53), starting with the first Sunday as the first day of the first week.
Days preceding the first Sunday in the year are considered to be in
week 00.
@item @t{%V}
The ISO week number as a decimal number (range 01 to 53). ISO weeks
start with Monday and end with Sunday. Week 01 of a year is the first
week which has the majority of its days in that year; this is equivalent
to the week containing January 4. Week 01 of a year can contain days
from the previous year. The week before week 01 of a year is the last
week (52 or 53) of the previous year even if it contains days from the
new year. In other word, if 1 January is Monday, Tuesday, Wednesday or
Thursday, it is in week 01; if 1 January is Friday, Saturday or Sunday,
it is in week 52 or 53 of the previous year.
@item @t{%w}
The day of the week as a decimal number (range 0 to 6), Sunday being 0.
@item @t{%W}
The week number of the current year as a decimal number (range 00 to
53), starting with the first Monday as the first day of the first week.
Days preceding the first Monday in the year are considered to be in
week 00.
@item @t{%y}
The year without a century as a decimal number (range 00 to 99), that
is the year modulo 100.
@item @t{%Y}
The year as a decimal number, using the Gregorian calendar.
@item @t{%%}
A literal `@t{%}' character.
@end table

All other (ordinary) characters in the format string are simply copied
to the resultant string.

The first argument (calendar time) passed to the function @t{time2str}
must be in the range from --62135596800 to +64092211199 that corresponds
to the period from 00:00:00 on January 1, 0001 to 23:59:59 on December
31, 4000 of the Gregorian calendar.

@node Solving models with glpsol
@appendix Solving models with @code{glpsol}

The GLPK
package@footnote{@indicateurl{http://www.gnu.org/software/glpk/}}
includes the program @verb{|glpsol|}, which is a stand-alone LP/MIP
solver. This program can be launched from the command line or from the
shell to solve models written in the GNU MathProg modeling language.

In order to tell the solver that the input file contains a model
description, you should specify the option @verb{|--model|} in the
command line. For example:

@example
glpsol --model foo.mod
@end example

Sometimes it is necessary to use the data section placed in a separate
file, in which case you may use the following command:

@example
glpsol --model foo.mod --data foo.dat
@end example

@noindent
Note that if the model file also contains the data section, that
section is ignored.

If the model description contains some display and/or print statements,
by default the output sends to the terminal. In order to redirect the
output to a file you may use the following command:

@example
glpsol --model foo.mod --display foo.out
@end example

If you need to look at the problem which has been generated by the
model translator, you may use the option @verb{|--wcpxlp|} as follows:

@example
glpsol --model foo.mod --wcpxlp foo.lp
@end example

@noindent
in which case the problem data is written to file @verb{|foo.lp|} in
CPLEX LP format suitable for visual analysis.

Sometimes it is needed merely to check the model description not
solving the generated problem. In this case you may specify the option
@verb{|--check|}, for example:

@example
glpsol --check --model foo.mod --wcpxlp foo.lp
@end example

In order to write a numeric solution obtained by the solver you may use
the following command:

@example
glpsol --model foo.mod --output foo.sol
@end example

@noindent
in which case the solution is written to the file @verb{|foo.sol|} in
plain text format.

Complete list of the @verb{|glpsol|} options can be found in the
reference manual included in the GLPK distribution.

@node Example model description
@appendix Example model description

@subheading Model description written in GNU MathProg

Below here is a complete example of the model description written in
the GNU MathProg modeling language.

@iftex
@sp
@end iftex

@verbatim
# A TRANSPORTATION PROBLEM
#
# This problem finds a least cost shipping schedule that meets
# requirements at markets and supplies at factories.
#
#  References:
#              Dantzig G B, "Linear Programming and Extensions."
#              Princeton University Press, Princeton, New Jersey, 1963,
#              Chapter 3-3.

set I;
/* canning plants */

set J;
/* markets */

param a{i in I};
/* capacity of plant i in cases */

param b{j in J};
/* demand at market j in cases */

param d{i in I, j in J};
/* distance in thousands of miles */

param f;
/* freight in dollars per case per thousand miles */

param c{i in I, j in J} := f * d[i,j] / 1000;
/* transport cost in thousands of dollars per case */

var x{i in I, j in J} >= 0;
/* shipment quantities in cases */

minimize cost: sum{i in I, j in J} c[i,j] * x[i,j];
/* total transportation costs in thousands of dollars */

s.t. supply{i in I}: sum{j in J} x[i,j] <= a[i];
/* observe supply limit at plant i */

s.t. demand{j in J}: sum{i in I} x[i,j] >= b[j];
/* satisfy demand at market j */

data;

set I := Seattle San-Diego;

set J := New-York Chicago Topeka;

param a := Seattle     350
           San-Diego   600;

param b := New-York    325
           Chicago     300
           Topeka      275;

param d :              New-York   Chicago   Topeka :=
           Seattle     2.5        1.7       1.8
           San-Diego   2.5        1.8       1.4  ;

param f := 90;

end;
@end verbatim

@subheading Generated LP problem

Below here is the result of the translation of the example model
produced by the solver @verb{|glpsol|} and written in the CPLEX LP
format with the option @verb{|--wcpxlp|}.

@iftex
@sp
@end iftex

@verbatim
\* Problem: transp *\

Minimize
 cost: + 0.225 x(Seattle,New~York) + 0.153 x(Seattle,Chicago)
 + 0.162 x(Seattle,Topeka) + 0.225 x(San~Diego,New~York)
 + 0.162 x(San~Diego,Chicago) + 0.126 x(San~Diego,Topeka)

Subject To
 supply(Seattle): + x(Seattle,New~York) + x(Seattle,Chicago)
 + x(Seattle,Topeka) <= 350
 supply(San~Diego): + x(San~Diego,New~York) + x(San~Diego,Chicago)
 + x(San~Diego,Topeka) <= 600
 demand(New~York): + x(Seattle,New~York) + x(San~Diego,New~York) >= 325
 demand(Chicago): + x(Seattle,Chicago) + x(San~Diego,Chicago) >= 300
 demand(Topeka): + x(Seattle,Topeka) + x(San~Diego,Topeka) >= 275

End
@end verbatim

@subheading Optimal LP solution

Below here is the optimal solution of the generated LP problem found by
the solver @verb{|glpsol|} and written in plain text format with the
option @verb{|--output|}.

@iftex
@sp
@end iftex

@smalldisplay
@verbatim
Problem:    transp
Rows:       6
Columns:    6
Non-zeros:  18
Status:     OPTIMAL
Objective:  cost = 153.675 (MINimum)

   No.   Row name   St   Activity     Lower bound   Upper bound    Marginal
------ ------------ -- ------------- ------------- ------------- -------------
     1 cost         B        153.675
     2 supply[Seattle]
                    B            300                         350
     3 supply[San-Diego]
                    NU           600                         600         < eps
     4 demand[New-York]
                    NL           325           325                       0.225
     5 demand[Chicago]
                    NL           300           300                       0.153
     6 demand[Topeka]
                    NL           275           275                       0.126

   No. Column name  St   Activity     Lower bound   Upper bound    Marginal
------ ------------ -- ------------- ------------- ------------- -------------
     1 x[Seattle,New-York]
                    B              0             0               
     2 x[Seattle,Chicago]
                    B            300             0               
     3 x[Seattle,Topeka]
                    NL             0             0                       0.036
     4 x[San-Diego,New-York]
                    B            325             0               
     5 x[San-Diego,Chicago]
                    NL             0             0                       0.009
     6 x[San-Diego,Topeka]
                    B            275             0               

End of output
@end verbatim
@end smalldisplay

@page

@headings off
@everyheading Acknowledgements @| @| @thispage

@node Acknowledgements
@chapheading Acknowledgements

The author would like to thank the following people, who kindly read,
commented, and corrected the draft of this manual:

@noindent
Juan Carlos Borras @verb{|<borras@cs.helsinki.fi>|}

@noindent
Harley Mackenzie @verb{|<hjm@bigpond.com>|}

@noindent
Robbie Morrison @verb{|<robbie@actrix.co.nz>|}

@bye
