summaryrefslogtreecommitdiff
path: root/glpk-5.0/doc
diff options
context:
space:
mode:
Diffstat (limited to 'glpk-5.0/doc')
-rw-r--r--glpk-5.0/doc/cnfsat.pdfbin0 -> 59926 bytes
-rw-r--r--glpk-5.0/doc/cnfsat.tex413
-rw-r--r--glpk-5.0/doc/glpk.pdfbin0 -> 493213 bytes
-rw-r--r--glpk-5.0/doc/glpk.tex156
-rw-r--r--glpk-5.0/doc/glpk01.tex336
-rw-r--r--glpk-5.0/doc/glpk02.tex3480
-rw-r--r--glpk-5.0/doc/glpk03.tex1936
-rw-r--r--glpk-5.0/doc/glpk04.tex1392
-rw-r--r--glpk-5.0/doc/glpk05.tex1098
-rw-r--r--glpk-5.0/doc/glpk06.tex464
-rw-r--r--glpk-5.0/doc/glpk07.tex258
-rw-r--r--glpk-5.0/doc/glpk08.tex740
-rw-r--r--glpk-5.0/doc/glpk09.tex423
-rw-r--r--glpk-5.0/doc/glpk10.tex160
-rw-r--r--glpk-5.0/doc/glpk11.tex207
-rw-r--r--glpk-5.0/doc/glpk12.tex710
-rw-r--r--glpk-5.0/doc/gmpl.pdfbin0 -> 222661 bytes
-rw-r--r--glpk-5.0/doc/gmpl.tex4285
-rw-r--r--glpk-5.0/doc/gmpl_es.pdfbin0 -> 234471 bytes
-rw-r--r--glpk-5.0/doc/gmpl_es.tex3231
-rw-r--r--glpk-5.0/doc/gmpl_pt-BR.pdfbin0 -> 256626 bytes
-rw-r--r--glpk-5.0/doc/gmpl_pt-BR.tex7893
-rw-r--r--glpk-5.0/doc/graphs.pdfbin0 -> 210854 bytes
-rw-r--r--glpk-5.0/doc/graphs.tex4180
-rw-r--r--glpk-5.0/doc/miplib2.txt135
-rw-r--r--glpk-5.0/doc/miplib3.txt143
-rw-r--r--glpk-5.0/doc/netlib.txt103
-rw-r--r--glpk-5.0/doc/notes/gomory.pdfbin0 -> 75445 bytes
-rw-r--r--glpk-5.0/doc/notes/keller.pdfbin0 -> 85985 bytes
-rw-r--r--glpk-5.0/doc/notes/scf.pdfbin0 -> 123131 bytes
-rw-r--r--glpk-5.0/doc/notes/simplex1.pdfbin0 -> 385190 bytes
-rw-r--r--glpk-5.0/doc/notes/simplex2.pdfbin0 -> 264051 bytes
-rw-r--r--glpk-5.0/doc/npp.txt283
33 files changed, 32026 insertions, 0 deletions
diff --git a/glpk-5.0/doc/cnfsat.pdf b/glpk-5.0/doc/cnfsat.pdf
new file mode 100644
index 0000000..d7ff193
--- /dev/null
+++ b/glpk-5.0/doc/cnfsat.pdf
Binary files differ
diff --git a/glpk-5.0/doc/cnfsat.tex b/glpk-5.0/doc/cnfsat.tex
new file mode 100644
index 0000000..4a2c3bb
--- /dev/null
+++ b/glpk-5.0/doc/cnfsat.tex
@@ -0,0 +1,413 @@
+%* cnfsat.tex *%
+
+\documentclass[11pt,draft]{article}
+\usepackage{amssymb}
+\usepackage{indentfirst}
+
+\setlength{\textwidth}{6.5in}
+\setlength{\textheight}{8.5in}
+\setlength{\oddsidemargin}{0in}
+\setlength{\topmargin}{0in}
+\setlength{\headheight}{0in}
+\setlength{\headsep}{0in}
+\setlength{\footskip}{0.5in}
+\setlength{\parindent}{16pt}
+\setlength{\parskip}{5pt}
+\setlength{\topsep}{0pt}
+\setlength{\partopsep}{0pt}
+\setlength{\itemsep}{\parskip}
+\setlength{\parsep}{0pt}
+\setlength{\leftmargini}{\parindent}
+\renewcommand{\labelitemi}{---}
+
+\def\para#1{\noindent{\bf#1}}
+\def\synopsis{\para{Synopsis}}
+\def\description{\para{Description}}
+\def\returns{\para{Returns}}
+
+\newenvironment{retlist}
+{ \def\arraystretch{1.5}
+ \noindent
+ \begin{tabular}{@{}p{1in}@{}p{5.5in}@{}}
+}
+{\end{tabular}}
+
+\begin{document}
+
+\title{\bf CNF Satisfiability Problem}
+
+\author{Andrew Makhorin {\tt<mao@gnu.org>}}
+
+\date{August 2011}
+
+\maketitle
+
+\section{Introduction}
+
+The {\it Satisfiability Problem (SAT)} is a classic combinatorial
+problem. Given a Boolean formula of $n$ variables
+$$f(x_1,x_2,\dots,x_n),\eqno(1.1)$$
+this problem is to find such values of the variables, on which the
+formula takes on the value {\it true}.
+
+The {\it CNF Satisfiability Problem (CNF-SAT)} is a version of the
+Satisfiability Problem, where the Boolean formula (1.1) is specified
+in the {\it Conjunctive Normal Form (CNF)}, that means that it is a
+conjunction of {\it clauses}, where a clause is a disjunction of
+{\it literals}, and a literal is a variable or its negation.
+For example:
+$$(x_1\vee x_2)\;\&\;(\neg x_2\vee x_3\vee\neg x_4)\;\&\;(\neg
+x_1\vee x_4).\eqno(1.2)$$
+Here $x_1$, $x_2$, $x_3$, $x_4$ are Boolean variables to be assigned,
+$\neg$ means
+negation (logical {\it not}), $\vee$ means disjunction (logical
+{\it or}), and $\&$ means conjunction (logical {\it and}). One may
+note that the formula (1.2) is {\it satisfiable}, because on
+$x_1$ = {\it true}, $x_2$ = {\it false}, $x_3$ = {\it false}, and
+$x_4$ = {\it true} it takes on the value {\it true}. If a formula
+is not satisfiable, it is called {\it unsatisfiable}, that means that
+it takes on the value {\it false} on any values of its variables.
+
+Any CNF-SAT problem can be easily translated to a 0-1 programming
+problem as follows.\linebreak A Boolean variable $x$ can be modeled by
+a binary variable in a natural way: $x=1$ means that $x$ takes on the
+value {\it true}, and $x=0$ means that $x$ takes on the value
+{\it false}. Then, if a literal is a negated variable, i.e. $t=\neg x$,
+it can be expressed as $t=1-x$. Since a formula in CNF is a conjunction
+of clauses, to provide its satisfiability we should require all its
+clauses to take on the value {\it true}. A particular clause is
+a disjunction of literals:
+$$t\vee t'\vee t''\dots ,\eqno(1.3)$$
+so it takes on the value {\it true} iff at least one of its literals
+takes on the value {\it true}, that can be expressed as the following
+inequality constraint:
+$$t+t'+t''+\dots\geq 1.\eqno(1.4)$$
+Note that no objective function is used in this case, because only
+a feasible solution needs to be found.
+
+For example, the formula (1.2) can be translated to the following
+constraints:
+$$\begin{array}{c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c}
+x_1&+&x_2&&&&&\geq&1\\
+&&(1-x_2)&+&x_3&+&(1-x_4)&\geq&1\\
+(1-x_1)&&&&&+&x_4&\geq&1\\
+\end{array}$$
+$$x_1, x_2, x_3, x_4\in\{0,1\}$$
+Carrying out all constant terms to the right-hand side gives
+corresponding 0-1 programming problem in the standard format:
+$$\begin{array}{r@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }c@{\ }r}
+x_1&+&x_2&&&&&\geq&1\\
+&-&x_2&+&x_3&-&x_4&\geq&-1\\
+-x_1&&&&&+&x_4&\geq&0\\
+\end{array}$$
+$$x_1, x_2, x_3, x_4\in\{0,1\}$$
+
+In general case translation of a CNF-SAT problem results in the
+following 0-1 programming problem:
+$$\sum_{j\in J^+_i}x_j-\sum_{j\in J^-_i}x_j\geq 1-|J^-_i|,
+\ \ \ i=1,\dots,m\eqno(1.5)$$
+$$x_j\in\{0,1\},\ \ \ j=1,\dots,n\eqno(1.6)$$
+where $n$ is the number of variables, $m$ is the number of clauses
+(inequality constraints),\linebreak $J^+_i\subseteq\{1,\dots,n\}$ is
+a subset of variables, whose literals in $i$-th clause do not have
+negation, and $J^-_i\subseteq\{1,\dots,n\}$ is a subset of variables,
+whose literals in $i$-th clause are negations of that variables. It is
+assumed that $J^+_i\cap J^-_i=\varnothing$ for all $i$.
+
+\section{GLPK API Routines}
+
+\subsection{glp\_read\_cnfsat --- read CNF-SAT problem data in DIMACS
+format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_read_cnfsat(glp_prob *P, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_read_cnfsat| reads the CNF-SAT problem data from
+a text file in DIMACS format and automatically translates the data to
+corresponding 0-1 programming problem instance (1.5)--(1.6).
+
+The parameter \verb|P| specifies the problem object, to which the
+0-1 programming problem instance should be stored. Note that before
+reading data the current content of the problem object is completely
+erased with the routine \verb|glp_erase_prob|.
+
+The character string \verb|fname| specifies the name of a text file
+to be read in. (If the file name ends with the suffix `\verb|.gz|',
+the file is assumed to be compressed, in which case the routine
+decompresses it ``on the fly''.)
+
+\newpage
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+\para{DIMACS CNF-SAT problem format}\footnote{This material is based on
+the paper ``Satisfiability Suggested Format'', which is publicly
+available at {\tt http://dimacs.rutgers.edu/}.}
+
+The DIMACS input file is a plain ASCII text file. It contains lines of
+several types described below. A line is terminated with an end-of-line
+character. Fields in each line are separated by at least one blank
+space.
+
+\para{Comment lines.} Comment lines give human-readable information
+about the file and are ignored by programs. Comment lines can appear
+anywhere in the file. Each comment line begins with a lower-case
+character \verb|c|.
+
+\begin{verbatim}
+ c This is a comment line
+\end{verbatim}
+
+\para{Problem line.} There is one problem line per data file. The
+problem line must appear before any clause lines. It has the following
+format:
+
+\begin{verbatim}
+ p cnf VARIABLES CLAUSES
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|p| signifies that this is a problem
+line. The three character problem designator \verb|cnf| identifies the
+file as containing specification information for the CNF-SAT problem.
+The \verb|VARIABLES| field contains an integer value specifying $n$,
+the number of variables in the instance. The \verb|CLAUSES| field
+contains an integer value specifying $m$, the number of clauses in the
+instance.
+
+\para{Clauses.} The clauses appear immediately after the problem
+line. The variables are assumed to be numbered from 1 up to $n$. It is
+not necessary that every variable appears in the instance. Each clause
+is represented by a sequence of numbers separated by either a space,
+tab, or new-line character. The non-negated version of a variable $j$
+is represented by $j$; the negated version is represented by $-j$. Each
+clause is terminated by the value 0. Unlike many formats that represent
+the end of a clause by a new-line character, this format allows clauses
+to be on multiple lines.
+
+\para{Example.} Below here is an example of the data file in DIMACS
+format corresponding to the CNF-SAT problem (1.2).
+
+\begin{footnotesize}
+\begin{verbatim}
+c sample.cnf
+c
+c This is an example of the CNF-SAT problem data
+c in DIMACS format.
+c
+p cnf 4 3
+1 2 0
+-4 3
+-2 0
+-1 4 0
+c
+c eof
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+\subsection{glp\_check\_cnfsat --- check for CNF-SAT problem instance}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_check_cnfsat(glp\_prob *P);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_check_cnfsat| checks if the specified problem
+object \verb|P| contains a 0-1 programming problem instance in the
+format (1.5)--(1.6) and therefore encodes a CNF-SAT problem instance.
+
+\returns
+
+If the specified problem object has the format (1.5)--(1.6), the
+routine returns zero, otherwise non-zero.
+
+\subsection{glp\_write\_cnfsat --- write CNF-SAT problem data in DIMACS
+format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_write_cnfsat(glp_prob *P, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_write_cnfsat| automatically translates the
+specified 0-1 programming problem instance (1.5)--(1.6) to a CNF-SAT
+problem instance and writes the problem data to a text file in DIMACS
+format.
+
+The parameter \verb|P| is the problem object, which should specify
+a 0-1 programming problem instance in the format (1.5)--(1.6).
+
+The character string \verb|fname| specifies a name of the output text
+file to be written. (If the file name ends with suffix `\verb|.gz|',
+the file is assumed to be compressed, in which case the routine
+performs automatic compression on writing that file.)
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+\subsection{glp\_minisat1 --- solve CNF-SAT problem instance with
+MiniSat solver}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_minisat1(glp_prob *P);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_minisat1| is a driver to MiniSat, a CNF-SAT
+solver developed by Niklas E\'en and Niklas S\"orensson, Chalmers
+University of Technology, Sweden.\footnote{The MiniSat software module
+is {\it not} part of GLPK, but is used with GLPK and included in the
+distribution.}
+
+\newpage
+
+It is assumed that the specified problem object \verb|P| contains
+a 0-1 programming problem instance in the format (1.5)--(1.6) and
+therefore encodes a CNF-SAT problem instance.
+
+If the problem instance has been successfully solved to the end, the
+routine \verb|glp_minisat1| returns 0. In this case the routine
+\verb|glp_mip_status| can be used to determine the solution status:
+
+\begin{itemize}
+\item {\tt GLP\_OPT} means that the solver found an integer feasible
+solution and therefore the corresponding CNF-SAT instance is
+satisfiable;
+
+\item {\tt GLP\_NOFEAS} means that no integer feasible solution exists
+and therefore the corresponding CNF-SAT instance is unsatisfiable.
+\end{itemize}
+
+If an integer feasible solution was found, corresponding values of
+binary variables can be retrieved with the routine
+\verb|glp_mip_col_val|.
+
+\returns
+
+\begin{retlist}
+0 & The MIP problem instance has been successfully solved. (This code
+does {\it not} necessarily mean that the solver has found feasible
+solution. It only means that the solution process was successful.)\\
+
+{\tt GLP\_EDATA} & The specified problem object contains a MIP
+instance which does {\it not} have the format (1.5)--(1.6).\\
+
+{\tt GLP\_EFAIL} & The solution process was unsuccessful because of
+the solver failure.\\
+\end{retlist}
+
+\subsection{glp\_intfeas1 --- solve integer feasibility problem}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_intfeas1(glp_prob *P, int use_bound, int obj_bound);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_intfeas1| is a tentative implementation of
+an integer feasibility solver based on a CNF-SAT solver (currently
+it is MiniSat; see Subsection 2.4).
+
+If the parameter \verb|use_bound| is zero, the routine searches for
+{\it any} integer feasibile solution to the specified integer
+programming problem. Note that in this case the objective function is
+ignored.
+
+If the parameter \verb|use_bound| is non-zero, the routine searches for
+an integer feasible solution, which provides a value of the objective
+function not worse than \verb|obj_bound|. In other word, the parameter
+\verb|obj_bound| specifies an upper (in case of minimization) or lower
+(in case of maximization) bound to the objective function.
+
+If the specified problem has been successfully solved to the end, the
+routine \verb|glp_intfeas1| returns 0. In this case the routine
+\verb|glp_mip_status| can be used to determine the solution status:
+
+\begin{itemize}
+\item {\tt GLP\_FEAS} means that the solver found an integer feasible
+solution;
+
+\item {\tt GLP\_NOFEAS} means that the problem has no integer feasible
+solution (if {\tt use\_bound} is zero) or it has no integer feasible
+solution, which is not worse than {\tt obj\_bound} (if {\tt use\_bound}
+is non-zero).
+\end{itemize}
+
+\newpage
+
+If an integer feasible solution was found, corresponding values of
+variables (columns) can be retrieved with the routine
+\verb|glp_mip_col_val|.
+
+\para{Usage Notes}
+
+The integer programming problem specified by the parameter \verb|P|
+should satisfy to the following requirements:
+
+\begin{enumerate}
+\item All variables (columns) should be either binary ({\tt GLP\_BV})
+or fixed at integer values ({\tt GLP\_FX}).
+
+\item All constraint and objective coefficients should be integer
+numbers in the range\linebreak $[-2^{31},\ +2^{31}-1]$.
+\end{enumerate}
+
+Though there are no special requirements to the constraints,
+currently the routine \verb|glp_intfeas1| is efficient mainly for
+problems, where most constraints (rows) fall into the following three
+classes:
+
+\begin{enumerate}
+\item Covering inequalities
+$$\sum_{j}t_j\geq 1,$$
+where $t_j=x_j$ or $t_j=1-x_j$, $x_j$ is a binary variable.
+
+\item Packing inequalities
+$$\sum_{j}t_j\leq 1.$$
+
+\item Partitioning equalities (SOS1 constraints)
+$$\sum_{j}t_j=1.$$
+\end{enumerate}
+
+\returns
+
+\begin{retlist}
+0 & The problem has been successfully solved. (This code does
+{\it not} necessarily mean that the solver has found an integer
+feasible solution. It only means that the solution process was
+successful.) \\
+
+{\tt GLP\_EDATA} & The specified problem object does not satisfy
+to the requirements listed in Paragraph `Usage Notes'. \\
+
+{\tt GLP\_ERANGE} & An integer overflow occured on translating the
+specified problem to a CNF-SAT problem. \\
+
+{\tt GLP\_EFAIL} & The solution process was unsuccessful because of
+the solver failure. \\
+\end{retlist}
+
+\end{document}
diff --git a/glpk-5.0/doc/glpk.pdf b/glpk-5.0/doc/glpk.pdf
new file mode 100644
index 0000000..cca6086
--- /dev/null
+++ b/glpk-5.0/doc/glpk.pdf
Binary files differ
diff --git a/glpk-5.0/doc/glpk.tex b/glpk-5.0/doc/glpk.tex
new file mode 100644
index 0000000..6263773
--- /dev/null
+++ b/glpk-5.0/doc/glpk.tex
@@ -0,0 +1,156 @@
+% glpk.tex %
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% The GLPK package is part of the GNU Project released under the aegis
+% of GNU.
+%
+% Copyright (c) 2000-2020 Free Software Foundation, Inc.
+%
+% Author: Andrew Makhorin <mao@gnu.org>.
+%
+% Permission is granted to copy, distribute and/or modify this
+% document under the terms of the GNU Free Documentation License,
+% Version 1.3 or any later version published by the Free Software
+% Foundation.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% To produce glpk.pdf from glpk.tex run the following two commands:
+% latex glpk.tex
+% dvipdfm -p letter glpk.dvi
+% Note: You need TeX Live 2010 or later version.
+
+\documentclass[11pt]{report}
+\usepackage{amssymb}
+\usepackage[dvipdfm,linktocpage,colorlinks,linkcolor=blue,
+urlcolor=blue]{hyperref}
+\usepackage{indentfirst}
+\usepackage{lscape}
+\usepackage{niceframe}
+\usepackage[all]{xy}
+
+% US Letter = 8.5 x 11 in
+\setlength{\textwidth}{6.5in}
+\setlength{\textheight}{9in}
+\setlength{\oddsidemargin}{0in}
+\setlength{\topmargin}{0in}
+\setlength{\headheight}{0in}
+\setlength{\headsep}{0in}
+%\setlength{\footskip}{0.5in}
+\setlength{\parindent}{16pt}
+\setlength{\parskip}{5pt}
+\setlength{\topsep}{0pt}
+\setlength{\partopsep}{0pt}
+%\setlength{\itemsep}{\parskip}
+%\setlength{\parsep}{0pt}
+%\setlength{\leftmargini}{\parindent}
+%\renewcommand{\labelitemi}{---}
+
+\newcommand{\Item}[1]{\parbox[t]{\parindent}{#1}}
+\def\para#1{\noindent{\bf#1}}
+\def\synopsis{\para{Synopsis}}
+\def\description{\para{Description}}
+\def\note{\para{Note}}
+\def\returns{\para{Returns}}
+
+\renewcommand\contentsname{\sf\bfseries Contents}
+\renewcommand\chaptername{\sf\bfseries Chapter}
+\renewcommand\appendixname{\sf\bfseries Appendix}
+
+\newenvironment{retlist}
+{ \def\arraystretch{1.5}
+ \noindent
+ \begin{tabular}{@{}p{1in}@{}p{5.5in}@{}}
+}
+{\end{tabular}}
+
+\begin{document}
+
+\thispagestyle{empty}
+
+\artdecoframe{
+
+\begin{center}
+
+\vspace*{1.5in}
+
+\begin{huge}
+\sf\bfseries GNU Linear Programming Kit
+\end{huge}
+
+\vspace{0.5in}
+
+\begin{LARGE}
+\sf Reference Manual
+\end{LARGE}
+
+\vspace{0.5in}
+
+\begin{LARGE}
+\sf for GLPK Version 5.0
+\end{LARGE}
+
+\vspace{0.5in}
+\begin{Large}
+\sf (December 2020)
+\end{Large}
+\end{center}
+
+\vspace*{3.2in}
+}
+
+\newpage
+
+\vspace*{1in}
+
+\vfill
+
+\noindent
+The GLPK package is part of the GNU Project released under the aegis of
+GNU.
+
+\noindent
+Copyright \copyright{} 2000-2020 Free Software Foundation, Inc.
+
+\noindent
+Author: Andrew Makhorin $<$mao@gnu.org$>$.
+
+\noindent
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+{\setlength{\parskip}{0pt}\tableofcontents}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\include{glpk01}
+
+\include{glpk02}
+
+\include{glpk03}
+
+\include{glpk04}
+
+\include{glpk05}
+
+\include{glpk06}
+
+\appendix
+
+\include{glpk07}
+
+\include{glpk08}
+
+\include{glpk09}
+
+\include{glpk10}
+
+\include{glpk11}
+
+\include{glpk12}
+
+\end{document}
diff --git a/glpk-5.0/doc/glpk01.tex b/glpk-5.0/doc/glpk01.tex
new file mode 100644
index 0000000..3ffc587
--- /dev/null
+++ b/glpk-5.0/doc/glpk01.tex
@@ -0,0 +1,336 @@
+%* glpk01.tex *%
+
+\chapter{Introduction}
+
+GLPK (\underline{G}NU \underline{L}inear \underline{P}rogramming
+\underline{K}it) is a set of routines written in the ANSI C programming
+language and organized in the form of a callable library. It is
+intended for solving linear programming (LP), mixed integer programming
+(MIP), and other related problems.
+
+\section{LP problem}
+\label{seclp}
+
+GLPK assumes the following formulation of the {\it linear programming
+(LP)} problem:
+
+\noindent
+\hspace{.5in} minimize (or maximize)
+$$z = c_1x_{m+1} + c_2x_{m+2} + \dots + c_nx_{m+n} + c_0 \eqno (1.1)$$
+\hspace{.5in} subject to linear constraints
+$$
+\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r}
+x_1&=&a_{11}x_{m+1}&+&a_{12}x_{m+2}&+ \dots +&a_{1n}x_{m+n} \\
+x_2&=&a_{21}x_{m+1}&+&a_{22}x_{m+2}&+ \dots +&a_{2n}x_{m+n} \\
+\multicolumn{7}{c}
+{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .} \\
+x_m&=&a_{m1}x_{m+1}&+&a_{m2}x_{m+2}&+ \dots +&a_{mn}x_{m+n} \\
+\end{array} \eqno (1.2)
+$$
+\hspace{.5in} and bounds of variables
+$$
+\begin{array}{r@{\:}c@{\:}c@{\:}c@{\:}l}
+l_1&\leq&x_1&\leq&u_1 \\
+l_2&\leq&x_2&\leq&u_2 \\
+\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .}\\
+l_{m+n}&\leq&x_{m+n}&\leq&u_{m+n} \\
+\end{array} \eqno (1.3)
+$$
+where: $x_1, x_2, \dots, x_m$ are auxiliary variables;
+$x_{m+1}, x_{m+2}, \dots, x_{m+n}$ are structural variables;
+$z$ is the objective function;
+$c_1, c_2, \dots, c_n$ are objective coefficients;
+$c_0$ is the constant term (``shift'') of the objective function;
+$a_{11}, a_{12}, \dots, a_{mn}$ are constraint coefficients;
+$l_1, l_2, \dots, l_{m+n}$ are lower bounds of variables;
+$u_1, u_2, \dots, u_{m+n}$ are upper bounds of variables.
+
+Auxiliary variables are also called {\it rows}, because they correspond
+to rows of the constraint matrix (i.e. a matrix built of the constraint
+coefficients). Similarly, structural variables are also called
+{\it columns}, because they correspond to columns of the constraint
+matrix.
+
+Bounds of variables can be finite as well as infinite. Besides, lower
+and upper bounds can be equal to each other. Thus, the following types
+of variables are possible:
+
+\begin{center}
+\begin{tabular}{r@{}c@{}ll}
+\multicolumn{3}{c}{Bounds of variable} & Type of variable \\
+\hline
+$-\infty <$ &$\ x_k\ $& $< +\infty$ & Free (unbounded) variable \\
+$l_k \leq$ &$\ x_k\ $& $< +\infty$ & Variable with lower bound \\
+$-\infty <$ &$\ x_k\ $& $\leq u_k$ & Variable with upper bound \\
+$l_k \leq$ &$\ x_k\ $& $\leq u_k$ & Double-bounded variable \\
+$l_k =$ &$\ x_k\ $& $= u_k$ & Fixed variable \\
+\end{tabular}
+\end{center}
+
+\noindent
+Note that the types of variables shown above are applicable to
+structural as well as to auxiliary variables.
+
+To solve the LP problem (1.1)---(1.3) is to find such values of all
+structural and auxiliary variables, which:
+
+%\vspace*{-10pt}
+
+%\begin{itemize}\setlength{\itemsep}{0pt}
+\Item{---}satisfy to all the linear constraints (1.2), and
+
+\Item{---}are within their bounds (1.3), and
+
+\Item{---}provide smallest (in case of minimization) or largest (in
+case of maximization) value of the objective function (1.1).
+%\end{itemize}
+
+\section{MIP problem}
+
+{\it Mixed integer linear programming (MIP)} problem is an LP problem
+in which some variables are additionally required to be integer.
+
+GLPK assumes that MIP problem has the same formulation as ordinary
+(pure) LP problem (1.1)---(1.3), i.e. includes auxiliary and structural
+variables, which may have lower and/or upper bounds. However, in case
+of MIP problem some variables may be required to be integer. This
+additional constraint means that a value of each {\it integer variable}
+must be only integer number. (Should note that GLPK allows only
+structural variables to be of integer kind.)
+
+\section{Using the package}
+
+\subsection{Brief example}
+
+In order to understand what GLPK is from the user's standpoint,
+consider the following simple LP problem:
+
+\noindent
+\hspace{.5in} maximize
+$$z = 10 x_1 + 6 x_2 + 4 x_3$$
+\hspace{.5in} subject to
+$$
+\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r}
+x_1 &+&x_2 &+&x_3 &\leq 100 \\
+10 x_1 &+& 4 x_2 & +&5 x_3 & \leq 600 \\
+2 x_1 &+& 2 x_2 & +& 6 x_3 & \leq 300 \\
+\end{array}
+$$
+\hspace{.5in} where all variables are non-negative
+$$x_1 \geq 0, \ x_2 \geq 0, \ x_3 \geq 0$$
+
+At first, this LP problem should be transformed to the standard form
+(1.1)---(1.3). This can be easily done by introducing auxiliary
+variables, by one for each original inequality constraint. Thus, the
+problem can be reformulated as follows:
+
+\noindent
+\hspace{.5in} maximize
+$$z = 10 x_1 + 6 x_2 + 4 x_3$$
+\hspace{.5in} subject to
+$$
+\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r}
+p& = &x_1 &+&x_2 &+&x_3 \\
+q& = &10 x_1 &+& 4 x_2 &+& 5 x_3 \\
+r& = &2 x_1 &+& 2 x_2 &+& 6 x_3 \\
+\end{array}
+$$
+\hspace{.5in} and bounds of variables
+$$
+\begin{array}{ccc}
+\nonumber -\infty < p \leq 100 && 0 \leq x_1 < +\infty \\
+\nonumber -\infty < q \leq 600 && 0 \leq x_2 < +\infty \\
+\nonumber -\infty < r \leq 300 && 0 \leq x_3 < +\infty \\
+\end{array}
+$$
+where $p, q, r$ are auxiliary variables (rows), and $x_1, x_2, x_3$ are
+structural variables (columns).
+
+The example C program shown below uses GLPK API routines in order to
+solve this LP problem.\footnote{If you just need to solve LP or MIP
+instance, you may write it in MPS or CPLEX LP format and then use the
+GLPK stand-alone solver to obtain a solution. This is much less
+time-consuming than programming in C with GLPK API routines.}
+
+\begin{footnotesize}
+\begin{verbatim}
+/* sample.c */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+int main(void)
+{ glp_prob *lp;
+ int ia[1+1000], ja[1+1000];
+ double ar[1+1000], z, x1, x2, x3;
+s1: lp = glp_create_prob();
+s2: glp_set_prob_name(lp, "sample");
+s3: glp_set_obj_dir(lp, GLP_MAX);
+s4: glp_add_rows(lp, 3);
+s5: glp_set_row_name(lp, 1, "p");
+s6: glp_set_row_bnds(lp, 1, GLP_UP, 0.0, 100.0);
+s7: glp_set_row_name(lp, 2, "q");
+s8: glp_set_row_bnds(lp, 2, GLP_UP, 0.0, 600.0);
+s9: glp_set_row_name(lp, 3, "r");
+s10: glp_set_row_bnds(lp, 3, GLP_UP, 0.0, 300.0);
+s11: glp_add_cols(lp, 3);
+s12: glp_set_col_name(lp, 1, "x1");
+s13: glp_set_col_bnds(lp, 1, GLP_LO, 0.0, 0.0);
+s14: glp_set_obj_coef(lp, 1, 10.0);
+s15: glp_set_col_name(lp, 2, "x2");
+s16: glp_set_col_bnds(lp, 2, GLP_LO, 0.0, 0.0);
+s17: glp_set_obj_coef(lp, 2, 6.0);
+s18: glp_set_col_name(lp, 3, "x3");
+s19: glp_set_col_bnds(lp, 3, GLP_LO, 0.0, 0.0);
+s20: glp_set_obj_coef(lp, 3, 4.0);
+s21: ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */
+s22: ia[2] = 1, ja[2] = 2, ar[2] = 1.0; /* a[1,2] = 1 */
+s23: ia[3] = 1, ja[3] = 3, ar[3] = 1.0; /* a[1,3] = 1 */
+s24: ia[4] = 2, ja[4] = 1, ar[4] = 10.0; /* a[2,1] = 10 */
+s25: ia[5] = 3, ja[5] = 1, ar[5] = 2.0; /* a[3,1] = 2 */
+s26: ia[6] = 2, ja[6] = 2, ar[6] = 4.0; /* a[2,2] = 4 */
+s27: ia[7] = 3, ja[7] = 2, ar[7] = 2.0; /* a[3,2] = 2 */
+s28: ia[8] = 2, ja[8] = 3, ar[8] = 5.0; /* a[2,3] = 5 */
+s29: ia[9] = 3, ja[9] = 3, ar[9] = 6.0; /* a[3,3] = 6 */
+s30: glp_load_matrix(lp, 9, ia, ja, ar);
+s31: glp_simplex(lp, NULL);
+s32: z = glp_get_obj_val(lp);
+s33: x1 = glp_get_col_prim(lp, 1);
+s34: x2 = glp_get_col_prim(lp, 2);
+s35: x3 = glp_get_col_prim(lp, 3);
+s36: printf("\nz = %g; x1 = %g; x2 = %g; x3 = %g\n",
+ z, x1, x2, x3);
+s37: glp_delete_prob(lp);
+ return 0;
+}
+
+/* eof */
+\end{verbatim}
+\end{footnotesize}
+
+The statement \verb|s1| creates a problem object. Being created the
+object is initially empty. The statement \verb|s2| assigns a symbolic
+name to the problem object.
+
+The statement \verb|s3| calls the routine \verb|glp_set_obj_dir| in
+order to set the optimization direction flag, where \verb|GLP_MAX|
+means maximization.
+
+The statement \verb|s4| adds three rows to the problem object.
+
+The statement \verb|s5| assigns the symbolic name `\verb|p|' to the
+first row, and the statement \verb|s6| sets the type and bounds of the
+first row, where \verb|GLP_UP| means that the row has an upper bound.
+The statements \verb|s7|, \verb|s8|, \verb|s9|, \verb|s10| are used in
+the same way in order to assign the symbolic names `\verb|q|' and
+`\verb|r|' to the second and third rows and set their types and bounds.
+
+The statement \verb|s11| adds three columns to the problem object.
+
+The statement \verb|s12| assigns the symbolic name `\verb|x1|' to the
+first column, the statement \verb|s13| sets the type and bounds of the
+first column, where \verb|GLP_LO| means that the column has an lower
+bound, and the statement \verb|s14| sets the objective coefficient for
+the first column. The statements \verb|s15|---\verb|s20| are used in
+the same way in order to assign the symbolic names `\verb|x2|' and
+`\verb|x3|' to the second and third columns and set their types,
+bounds, and objective coefficients.
+
+The statements \verb|s21|---\verb|s29| prepare non-zero elements of the
+constraint matrix (i.e. constraint coefficients). Row indices of each
+element are stored in the array \verb|ia|, column indices are stored in
+the array \verb|ja|, and numerical values of corresponding elements are
+stored in the array \verb|ar|. Then the statement \verb|s30| calls
+the routine \verb|glp_load_matrix|, which loads information from these
+three arrays into the problem object.
+
+Now all data have been entered into the problem object, and therefore
+the statement \verb|s31| calls the routine \verb|glp_simplex|, which is
+a driver to the simplex method, in order to solve the LP problem. This
+routine finds an optimal solution and stores all relevant information
+back into the problem object.
+
+The statement \verb|s32| obtains a computed value of the objective
+function, and the statements \verb|s33|---\verb|s35| obtain computed
+values of structural variables (columns), which correspond to the
+optimal basic solution found by the solver.
+
+The statement \verb|s36| writes the optimal solution to the standard
+output. The printout may look like follows:
+
+\newpage
+
+\begin{footnotesize}
+\begin{verbatim}
+* 0: objval = 0.000000000e+00 infeas = 0.000000000e+00 (0)
+* 2: objval = 7.333333333e+02 infeas = 0.000000000e+00 (0)
+OPTIMAL SOLUTION FOUND
+
+z = 733.333; x1 = 33.3333; x2 = 66.6667; x3 = 0
+\end{verbatim}
+\end{footnotesize}
+
+Finally, the statement \verb|s37| calls the routine
+\verb|glp_delete_prob|, which frees all the memory allocated to the
+problem object.
+
+\subsection{Compiling}
+
+The GLPK package has the only header file \verb|glpk.h|, which should
+be available on compiling a C (or C++) program using GLPK API routines.
+
+If the header file is installed in the default location
+\verb|/usr/local/include|, the following typical command may be used to
+compile, say, the example C program described above with the GNU C
+compiler:
+
+\begin{verbatim}
+ $ gcc -c sample.c
+\end{verbatim}
+
+If \verb|glpk.h| is not in the default location, the corresponding
+directory containing it should be made known to the C compiler through
+\verb|-I| option, for example:
+
+\begin{verbatim}
+ $ gcc -I/foo/bar/glpk-4.15/include -c sample.c
+\end{verbatim}
+
+In any case the compilation results in an object file \verb|sample.o|.
+
+\subsection{Linking}
+
+The GLPK library is a single file \verb|libglpk.a|. (On systems which
+support shared libraries there may be also a shared version of the
+library \verb|libglpk.so|.)
+
+If the library is installed in the default
+location \verb|/usr/local/lib|, the following typical command may be
+used to link, say, the example C program described above against with
+the library:
+
+\begin{verbatim}
+ $ gcc sample.o -lglpk -lm
+\end{verbatim}
+
+If the GLPK library is not in the default location, the corresponding
+directory containing it should be made known to the linker through
+\verb|-L| option, for example:
+
+\begin{verbatim}
+ $ gcc -L/foo/bar/glpk-4.15 sample.o -lglpk -lm
+\end{verbatim}
+
+Depending on configuration of the package linking against with the GLPK
+library may require optional libraries, in which case these libraries
+should be also made known to the linker, for example:
+
+\begin{verbatim}
+ $ gcc sample.o -lglpk -lgmp -lm
+\end{verbatim}
+
+For more details about configuration options of the GLPK package see
+Appendix \ref{install}, page \pageref{install}.
+
+%* eof *%
diff --git a/glpk-5.0/doc/glpk02.tex b/glpk-5.0/doc/glpk02.tex
new file mode 100644
index 0000000..f49ae75
--- /dev/null
+++ b/glpk-5.0/doc/glpk02.tex
@@ -0,0 +1,3480 @@
+%* glpk02.tex *%
+
+\chapter{Basic API Routines}
+
+\section{General conventions}
+
+\subsection{Library header}
+
+All GLPK API data types and routines are defined in the header file
+\verb|glpk.h|. It should be included in all source files which use
+GLPK API, either directly or indirectly through some other header file
+as follows:
+
+\begin{verbatim}
+ #include <glpk.h>
+\end{verbatim}
+
+\subsection{Error handling}
+
+If some GLPK API routine detects erroneous or incorrect data passed by
+the application program, it writes appropriate diagnostic messages to
+the terminal and then abnormally terminates the application program.
+In most practical cases this allows to simplify programming by avoiding
+numerous checks of return codes. Thus, in order to prevent crashing the
+application program should check all data, which are suspected to be
+incorrect, before calling GLPK API routines.
+
+Should note that this kind of error handling is used only in cases of
+incorrect data passed by the application program. If, for example, the
+application program calls some GLPK API routine to read data from an
+input file and these data are incorrect, the GLPK API routine reports
+about error in the usual way by means of the return code.
+
+\subsection{Thread safety}
+
+The standard version of GLPK API is {\it not} thread safe and therefore
+should not be used in multi-threaded programs.
+
+\subsection{Array indexing}
+
+Normally all GLPK API routines start array indexing from 1, not from 0
+(except the specially stipulated cases). This means, for example, that
+if some vector $x$ of the length $n$ is passed as an array to some GLPK
+API routine, the latter expects vector components to be placed in
+locations \verb|x[1]|, \verb|x[2]|, \dots, \verb|x[n]|, and the
+location \verb|x[0]| normally is not used.
+
+To avoid indexing errors it is most convenient and most reliable to
+declare the array \verb|x| as follows:
+
+\begin{verbatim}
+ double x[1+n];
+\end{verbatim}
+
+\noindent
+or to allocate it as follows:
+
+\begin{verbatim}
+ double *x;
+ . . .
+ x = calloc(1+n, sizeof(double));
+ . . .
+\end{verbatim}
+
+\noindent
+In both cases one extra location \verb|x[0]| is reserved that allows
+passing the array to GLPK routines in a usual way.
+
+\section{Problem object}
+
+All GLPK API routines deal with so called {\it problem object}, which
+is a program object of type \verb|glp_prob| and intended to represent
+a particular LP or MIP instance.
+
+The type \verb|glp_prob| is a data structure declared in the header
+file \verb|glpk.h| as follows:
+
+\begin{verbatim}
+ typedef struct glp_prob glp_prob;
+\end{verbatim}
+
+Problem objects (i.e. program objects of the \verb|glp_prob| type) are
+allocated and managed internally by the GLPK API routines. The
+application program should never use any members of the \verb|glp_prob|
+structure directly and should deal only with pointers to these objects
+(that is, \verb|glp_prob *| values).
+
+The problem object consists of the following segments:
+
+%\vspace*{-8pt}
+
+%\begin{itemize}\setlength{\itemsep}{0pt}
+\Item{---}problem segment,
+
+\Item{---}basis segment,
+
+\Item{---}interior-point segment, and
+
+\Item{---}MIP segment.
+%\end{itemize}
+
+\subsection{Problem segment}
+
+The {\it problem segment} contains original LP/MIP data, which
+corresponds to the problem formulation (1.1)---(1.3) (see Section
+\ref{seclp}, page \pageref{seclp}). This segment includes the following
+components:
+
+%\vspace*{-8pt}
+
+%\begin{itemize}\setlength{\itemsep}{0pt}
+\Item{---}rows (auxiliary variables),
+
+\Item{---}columns (structural variables),
+
+\Item{---}objective function, and
+
+\Item{---}constraint matrix.
+%\end{itemize}
+
+%\vspace*{-7pt}
+
+Rows and columns have the same set of the following attributes:
+
+%\vspace*{-7pt}
+
+%\begin{itemize}\setlength{\itemsep}{0pt}
+\Item{---}ordinal number,
+
+\Item{---}symbolic name (1 up to 255 arbitrary graphic characters),
+
+\Item{---}type (free, lower bound, upper bound, double bound, fixed),
+
+\Item{---}numerical values of lower and upper bounds,
+
+\Item{---}scale factor.
+%\end{itemize}
+
+%\vspace*{-7pt}
+
+{\it Ordinal numbers} are intended for referencing rows and columns.
+Row ordinal numbers are integers $1, 2, \dots, m$, and column ordinal
+numbers are integers $1, 2, \dots, n$, where $m$ and $n$ are,
+respectively, the current number of rows and columns in the problem
+object.
+
+{\it Symbolic names} are intended for informational purposes. They also
+can be used for referencing rows and columns.
+
+{\it Types and bounds} of rows (auxiliary variables) and columns
+(structural variables) are explained above (see Section \ref{seclp},
+page \pageref{seclp}).
+
+{\it Scale factors} are used internally for scaling rows and columns of
+the constraint matrix.
+
+Information about the {\it objective function} includes numerical
+values of objective coefficients and a flag, which defines the
+optimization direction (i.e. minimization or maximization).
+
+The {\it constraint matrix} is a $m \times n$ rectangular matrix built
+of constraint coefficients $a_{ij}$, which defines the system of linear
+constraints (1.2) (see Section \ref{seclp}, page \pageref{seclp}). This
+matrix is stored in the problem object in both row-wise and column-wise
+sparse formats.
+
+Once the problem object has been created, the application program can
+access and modify any components of the problem segment in arbitrary
+order.
+
+\subsection{Basis segment}
+
+The {\it basis segment} of the problem object keeps information related
+to the current basic solution. It includes:
+
+%\vspace*{-8pt}
+
+%\begin{itemize}\setlength{\itemsep}{0pt}
+\Item{---}row and column statuses,
+
+\Item{---}basic solution statuses,
+
+\Item{---}factorization of the current basis matrix, and
+
+\Item{---}basic solution components.
+%\end{itemize}
+
+%\vspace*{-8pt}
+
+The {\it row and column statuses} define which rows and columns are
+basic and which are non-basic. These statuses may be assigned either by
+the application program of by some API routines. Note that these
+statuses are always defined independently on whether the corresponding
+basis is valid or not.
+
+The {\it basic solution statuses} include the {\it primal status} and
+the {\it dual status}, which are set by the simplex-based solver once
+the problem has been solved. The primal status shows whether a primal
+basic solution is feasible, infeasible, or undefined. The dual status
+shows the same for a dual basic solution.
+
+The {\it factorization of the basis matrix} is some factorized form
+(like {\it LU}-factorization) of the current basis matrix (defined by
+the current row and column statuses). The factorization is used by
+simplex-based solvers and kept when the solver terminates the search.
+This feature allows efficiently reoptimizing the problem after some
+modifications (for example, after changing some bounds or objective
+coefficients). It also allows performing the post-optimal analysis (for
+example, computing components of the simplex table, etc.).
+
+The {\it basic solution components} include primal and dual values of
+all auxiliary and structural variables for the most recently obtained
+basic solution.
+
+\subsection{Interior-point segment}
+
+The {\it interior-point segment} contains interior-point solution
+components, which include the solution status, and primal and dual
+values of all auxiliary and structural variables.
+
+\subsection{MIP segment}
+
+The {\it MIP segment} is used only for MIP problems. This segment
+includes:
+
+%\vspace*{-8pt}
+
+%\begin{itemize}\setlength{\itemsep}{0pt}
+\Item{---}column kinds,
+
+\Item{---}MIP solution status, and
+
+\Item{---}MIP solution components.
+%\end{itemize}
+
+%\vspace*{-8pt}
+
+The {\it column kinds} define which columns (i.e. structural variables)
+are integer and which are continuous.
+
+The {\it MIP solution status} is set by the MIP solver and shows whether
+a MIP solution is integer optimal, integer feasible (non-optimal), or
+undefined.
+
+The {\it MIP solution components} are computed by the MIP solver and
+include primal values of all auxiliary and structural variables for the
+most recently obtained MIP solution.
+
+Note that in case of MIP problem the basis segment corresponds to
+the optimal solution of LP relaxation, which is also available to the
+application program.
+
+Currently the search tree is not kept in the MIP segment, so if the
+search has been terminated, it cannot be continued.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Problem creating and modifying routines}
+
+\subsection{glp\_create\_prob --- create problem object}
+
+\synopsis
+
+\begin{verbatim}
+ glp_prob *glp_create_prob(void);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_create_prob| creates a new problem object, which
+initially is ``empty'', i.e. has no rows and columns.
+
+\returns
+
+The routine returns a pointer to the created object, which should be
+used in any subsequent operations on this object.
+
+\subsection{glp\_set\_prob\_name --- assign (change) problem name}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_prob_name(glp_prob *P, const char *name);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_prob_name| assigns a given symbolic
+\verb|name| (1 up to 255 characters) to the specified problem object.
+
+If the parameter \verb|name| is \verb|NULL| or empty string, the
+routine erases an existing symbolic name of the problem object.
+
+\subsection{glp\_set\_obj\_name --- assign (change) objective function
+name}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_obj_name(glp_prob *P, const char *name);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_obj_name| assigns a given symbolic
+\verb|name| (1 up to 255 characters) to the objective function of the
+specified problem object.
+
+If the parameter \verb|name| is \verb|NULL| or empty string, the
+routine erases an existing symbolic name of the objective function.
+
+\newpage
+
+\subsection{glp\_set\_obj\_dir --- set (change) optimization direction
+flag}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_obj_dir(glp_prob *P, int dir);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_obj_dir| sets (changes) the optimization
+direction flag (i.e. ``sense'' of the objective function) as specified
+by the parameter \verb|dir|:
+
+\verb|GLP_MIN| means minimization;
+
+\verb|GLP_MAX| means maximization.
+
+Note that by default the problem is minimization.
+
+\subsection{glp\_add\_rows --- add new rows to problem object}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_add_rows(glp_prob *P, int nrs);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_add_rows| adds \verb|nrs| rows (constraints) to
+the specified problem object. New rows are always added to the end of
+the row list, so the ordinal numbers of existing rows are not changed.
+
+Being added each new row is initially free (unbounded) and has empty
+list of the constraint coefficients.
+
+Each new row becomes a non-active (non-binding) constraint, i.e. the
+corresponding auxiliary variable is marked as basic.
+
+If the basis factorization exists, adding row(s) invalidates it.
+
+\returns
+
+The routine \verb|glp_add_rows| returns the ordinal number of the first
+new row added to the problem object.
+
+\subsection{glp\_add\_cols --- add new columns to problem object}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_add_cols(glp_prob *P, int ncs);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_add_cols| adds \verb|ncs| columns (structural
+variables) to the specified problem object. New columns are always
+added to the end of the column list, so the ordinal numbers of existing
+columns are not changed.
+
+Being added each new column is initially fixed at zero and has empty
+list of the constraint coefficients.
+
+Each new column is marked as non-basic, i.e. zero value of the
+corresponding structural variable becomes an active (binding) bound.
+
+If the basis factorization exists, it remains valid.
+
+\returns
+
+The routine \verb|glp_add_cols| returns the ordinal number of the first
+new column added to the problem object.
+
+\subsection{glp\_set\_row\_name --- assign (change) row name}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_row_name(glp_prob *P, int i, const char *name);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_row_name| assigns a given symbolic
+\verb|name| (1 up to 255 characters) to \verb|i|-th row (auxiliary
+variable) of the specified problem object.
+
+If the parameter \verb|name| is \verb|NULL| or empty string, the
+routine erases an existing name of $i$-th row.
+
+\subsection{glp\_set\_col\_name --- assign (change) column name}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_col_name(glp_prob *P, int j, const char *name);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_col_name| assigns a given symbolic
+\verb|name| (1 up to 255 characters) to \verb|j|-th column (structural
+variable) of the specified problem object.
+
+If the parameter \verb|name| is \verb|NULL| or empty string, the
+routine erases an existing name of $j$-th column.
+
+\subsection{glp\_set\_row\_bnds --- set (change) row bounds}
+
+\synopsis
+
+{\tt void glp\_set\_row\_bnds(glp\_prob *P, int i, int type,
+double lb, double ub);}
+
+\description
+
+The routine \verb|glp_set_row_bnds| sets (changes) the type and bounds
+of \verb|i|-th row (auxiliary variable) of the specified problem
+object.
+
+The parameters \verb|type|, \verb|lb|, and \verb|ub| specify the type,
+lower bound, and upper bound, respectively, as follows:
+
+\begin{center}
+\begin{tabular}{cr@{}c@{}ll}
+Type & \multicolumn{3}{c}{Bounds} & Comment \\
+\hline
+\verb|GLP_FR| & $-\infty <$ &$\ x\ $& $< +\infty$
+ & Free (unbounded) variable \\
+\verb|GLP_LO| & $lb \leq$ &$\ x\ $& $< +\infty$
+ & Variable with lower bound \\
+\verb|GLP_UP| & $-\infty <$ &$\ x\ $& $\leq ub$
+ & Variable with upper bound \\
+\verb|GLP_DB| & $lb \leq$ &$\ x\ $& $\leq ub$
+ & Double-bounded variable \\
+\verb|GLP_FX| & $lb =$ &$\ x\ $& $= ub$
+ & Fixed variable \\
+\end{tabular}
+\end{center}
+
+\noindent
+where $x$ is the auxiliary variable associated with $i$-th row.
+
+If the row has no lower bound, the parameter \verb|lb| is ignored. If
+the row has no upper bound, the parameter \verb|ub| is ignored. If the
+row is an equality constraint (i.e. the corresponding auxiliary
+variable is of fixed type), only the parameter \verb|lb| is used while
+the parameter \verb|ub| is ignored.
+
+Being added to the problem object each row is initially free, i.e. its
+type is \verb|GLP_FR|.
+
+\subsection{glp\_set\_col\_bnds --- set (change) column bounds}
+
+\synopsis
+
+{\tt void glp\_set\_col\_bnds(glp\_prob *P, int j, int type,
+double lb, double ub);}
+
+\description
+
+The routine \verb|glp_set_col_bnds| sets (changes) the type and bounds
+of \verb|j|-th column (structural variable) of the specified problem
+object.
+
+The parameters \verb|type|, \verb|lb|, and \verb|ub| specify the type,
+lower bound, and upper bound, respectively, as follows:
+
+\begin{center}
+\begin{tabular}{cr@{}c@{}ll}
+Type & \multicolumn{3}{c}{Bounds} & Comment \\
+\hline
+\verb|GLP_FR| & $-\infty <$ &$\ x\ $& $< +\infty$
+ & Free (unbounded) variable \\
+\verb|GLP_LO| & $lb \leq$ &$\ x\ $& $< +\infty$
+ & Variable with lower bound \\
+\verb|GLP_UP| & $-\infty <$ &$\ x\ $& $\leq ub$
+ & Variable with upper bound \\
+\verb|GLP_DB| & $lb \leq$ &$\ x\ $& $\leq ub$
+ & Double-bounded variable \\
+\verb|GLP_FX| & $lb =$ &$\ x\ $& $= ub$
+ & Fixed variable \\
+\end{tabular}
+\end{center}
+
+\noindent
+where $x$ is the structural variable associated with $j$-th column.
+
+If the column has no lower bound, the parameter \verb|lb| is ignored.
+If the column has no upper bound, the parameter \verb|ub| is ignored.
+If the column is of fixed type, only the parameter \verb|lb| is used
+while the parameter \verb|ub| is ignored.
+
+Being added to the problem object each column is initially fixed at
+zero, i.e. its type is \verb|GLP_FX| and both bounds are 0.
+
+%\newpage
+
+\subsection{glp\_set\_obj\_coef --- set (change) objective coefficient
+or constant term}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_obj_coef(glp_prob *P, int j, double coef);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_obj_coef| sets (changes) the objective
+coefficient at \verb|j|-th column (structural variable). A new value of
+the objective coefficient is specified by the parameter \verb|coef|.
+
+If the parameter \verb|j| is 0, the routine sets (changes) the constant
+term (``shift'') of the objective function.
+
+\newpage
+
+\subsection{glp\_set\_mat\_row --- set (replace) row of the constraint
+matrix}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_mat_row(glp_prob *P, int i, int len, const int ind[],
+ const double val[]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_mat_row| stores (replaces) the contents of
+\verb|i|-th row of the constraint matrix of the specified problem
+object.
+
+Column indices and numerical values of new row elements should be
+placed in locations\linebreak \verb|ind[1]|, \dots, \verb|ind[len]| and
+\verb|val[1]|, \dots, \verb|val[len]|, respectively, where
+$0 \leq$ \verb|len| $\leq n$ is the new length of $i$-th row, $n$ is
+the current number of columns in the problem object. Elements with
+identical column indices are not allowed. Zero elements are allowed,
+but they are not stored in the constraint matrix.
+
+If the parameter \verb|len| is 0, the parameters \verb|ind| and/or
+\verb|val| can be specified as \verb|NULL|.
+
+\note
+
+If the basis factorization exists and changing the row changes
+coefficients at basic column(s), the factorization is invalidated.
+
+\subsection{glp\_set\_mat\_col --- set (replace) column of the
+constr\-aint matrix}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_mat_col(glp_prob *P, int j, int len, const int ind[],
+ const double val[]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_mat_col| stores (replaces) the contents of
+\verb|j|-th column of the constraint matrix of the specified problem
+object.
+
+Row indices and numerical values of new column elements should be
+placed in locations\linebreak \verb|ind[1]|, \dots, \verb|ind[len]| and
+\verb|val[1]|, \dots, \verb|val[len]|, respectively, where
+$0 \leq$ \verb|len| $\leq m$ is the new length of $j$-th column, $m$ is
+the current number of rows in the problem object. Elements with
+identical row indices are not allowed. Zero elements are allowed, but
+they are not stored in the constraint matrix.
+
+If the parameter \verb|len| is 0, the parameters \verb|ind| and/or
+\verb|val| can be specified as \verb|NULL|.
+
+\note
+
+If the basis factorization exists, changing the column corresponding
+to a basic structural variable invalidates it.
+
+\newpage
+
+\subsection{glp\_load\_matrix --- load (replace) the whole constraint
+matrix}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_load_matrix(glp_prob *P, int ne, const int ia[],
+ const int ja[], const double ar[]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_load_matrix| loads the constraint matrix passed
+in the arrays \verb|ia|, \verb|ja|, and \verb|ar| into the specified
+problem object. Before loading the current contents of the constraint
+matrix is destroyed.
+
+Constraint coefficients (elements of the constraint matrix) should be
+specified as triplets (\verb|ia[k]|, \verb|ja[k]|, \verb|ar[k]|) for
+$k=1,\dots,ne$, where \verb|ia[k]| is the row index, \verb|ja[k]| is
+the column index, and \verb|ar[k]| is a numeric value of corresponding
+constraint coefficient. The parameter \verb|ne| specifies the total
+number of (non-zero) elements in the matrix to be loaded. Coefficients
+with identical indices are not allowed. Zero coefficients are allowed,
+however, they are not stored in the constraint matrix.
+
+If the parameter \verb|ne| is 0, the parameters \verb|ia|, \verb|ja|,
+and/or \verb|ar| can be specified as \verb|NULL|.
+
+\note
+
+If the basis factorization exists, this operation invalidates it.
+
+\subsection{glp\_check\_dup --- check for duplicate elements in sparse
+matrix}
+
+\synopsis
+
+{\tt int glp\_check\_dup(int m, int n, int ne, const int ia[],
+const int ja[]);}
+
+\description
+
+The routine \verb|glp_check_dup checks| for duplicate elements (that
+is, elements with identical indices) in a sparse matrix specified in
+the coordinate format.
+
+The parameters $m$ and $n$ specifies, respectively, the number of rows
+and columns in the matrix, $m\geq 0$, $n\geq 0$.
+
+The parameter {\it ne} specifies the number of (structurally) non-zero
+elements in the matrix,\linebreak {\it ne} $\geq 0$.
+
+Elements of the matrix are specified as doublets $(ia[k],ja[k])$ for
+$k=1,\dots,ne$, where $ia[k]$ is a row index, $ja[k]$ is a column
+index.
+
+The routine \verb|glp_check_dup| can be used prior to a call to the
+routine \verb|glp_load_matrix| to check that the constraint matrix to
+be loaded has no duplicate elements.
+
+\returns
+
+\begin{retlist}
+0& the matrix representation is correct;\\
+$-k$& indices $ia[k]$ or/and $ja[k]$ are out of range;\\
+$+k$& element $(ia[k],ja[k])$ is duplicate.\\
+\end{retlist}
+
+\subsection{glp\_sort\_matrix --- sort elements of the constraint
+matrix}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_sort_matrix(glp_prob *P);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_sort_matrix| sorts elements of the constraint
+matrix by rebuilding its row and column linked lists.
+
+On exit from the routine the constraint matrix is not changed, however,
+elements in the row linked lists become ordered by ascending column
+indices, and the elements in the column linked lists become ordered by
+ascending row indices.
+
+\subsection{glp\_del\_rows --- delete rows from problem object}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_del_rows(glp_prob *P, int nrs, const int num[]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_del_rows| deletes rows from the specified problem
+object. Ordinal numbers of rows to be deleted should be placed in
+locations \verb|num[1]|, \dots, \verb|num[nrs]|, where ${\tt nrs}>0$.
+
+Note that deleting rows involves changing ordinal numbers of other
+rows remaining in the problem object. New ordinal numbers of the
+remaining rows are assigned under the assumption that the original
+order of rows is not changed. Let, for example, before deletion there
+be five rows $a$, $b$, $c$, $d$, $e$ with ordinal numbers 1, 2, 3, 4,
+5, and let rows $b$ and $d$ have been deleted. Then after deletion the
+remaining rows $a$, $c$, $e$ are assigned new oridinal numbers 1, 2, 3.
+
+If the basis factorization exists, deleting active (binding) rows,
+i.e. whose auxiliary variables are marked as non-basic, invalidates it.
+
+%\newpage
+
+\subsection{glp\_del\_cols --- delete columns from problem object}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_del_cols(glp_prob *P, int ncs, const int num[]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_del_cols| deletes columns from the specified
+problem object. Ordinal numbers of columns to be deleted should be
+placed in locations \verb|num[1]|, \dots, \verb|num[ncs]|, where
+${\tt ncs}>0$.
+
+Note that deleting columns involves changing ordinal numbers of other
+columns remaining in\linebreak the problem object. New ordinal numbers
+of the remaining columns are assigned under the assumption that the
+original order of columns is not changed. Let, for example, before
+deletion there be six columns $p$, $q$, $r$, $s$, $t$, $u$ with
+ordinal numbers 1, 2, 3, 4, 5, 6, and let columns $p$, $q$, $s$ have
+been deleted. Then after deletion the remaining columns $r$, $t$, $u$
+are assigned new ordinal numbers 1, 2, 3.
+
+If the basis factorization exists, deleting basic columns invalidates
+it.
+
+\subsection{glp\_copy\_prob --- copy problem object content}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_copy_prob(glp_prob *dest, glp_prob *prob, int names);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_copy_prob| copies the content of the problem
+object \verb|prob| to the problem object \verb|dest|.
+
+The parameter \verb|names| is a flag. If it is \verb|GLP_ON|,
+the routine also copies all symbolic names; otherwise, if it is
+\verb|GLP_OFF|, no symbolic names are copied.
+
+\subsection{glp\_erase\_prob --- erase problem object content}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_erase_prob(glp_prob *P);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_erase_prob| erases the content of the specified
+problem object. The effect of this operation is the same as if the
+problem object would be deleted with the routine \verb|glp_delete_prob|
+and then created anew with the routine \verb|glp_create_prob|, with the
+only exception that the pointer to the problem object remains valid.
+
+%\newpage
+
+\subsection{glp\_delete\_prob --- delete problem object}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_delete_prob(glp_prob *P);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_delete_prob| deletes a problem object, which the
+parameter \verb|lp| points to, freeing all the memory allocated to this
+object.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Problem retrieving routines}
+
+\subsection{glp\_get\_prob\_name --- retrieve problem name}
+
+\synopsis
+
+\begin{verbatim}
+ const char *glp_get_prob_name(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_prob_name| returns a pointer to an internal
+buffer, which contains symbolic name of the problem. However, if the
+problem has no assigned name, the routine returns \verb|NULL|.
+
+\subsection{glp\_get\_obj\_name --- retrieve objective function name}
+
+\synopsis
+
+\begin{verbatim}
+ const char *glp_get_obj_name(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_obj_name| returns a pointer to an internal
+buffer, which contains symbolic name assigned to the objective
+function. However, if the objective function has no assigned name, the
+routine returns \verb|NULL|.
+
+\subsection{glp\_get\_obj\_dir --- retrieve optimization direction
+flag}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_obj_dir(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_obj_dir| returns the optimization direction
+flag (i.e. ``sense'' of the objective function):
+
+\verb|GLP_MIN| means minimization;
+
+\verb|GLP_MAX| means maximization.
+
+\subsection{glp\_get\_num\_rows --- retrieve number of rows}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_num_rows(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_num_rows| returns the current number of rows
+in the specified problem object.
+
+\newpage
+
+\subsection{glp\_get\_num\_cols --- retrieve number of columns}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_num_cols(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_num_cols| returns the current number of
+columns in the specified problem object.
+
+\subsection{glp\_get\_row\_name --- retrieve row name}
+
+\synopsis
+
+\begin{verbatim}
+ const char *glp_get_row_name(glp_prob *P, int i);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_row_name| returns a pointer to an internal
+buffer, which contains a symbolic name assigned to \verb|i|-th row.
+However, if the row has no assigned name, the routine returns
+\verb|NULL|.
+
+\subsection{glp\_get\_col\_name --- retrieve column name}
+
+\synopsis
+
+\begin{verbatim}
+ const char *glp_get_col_name(glp_prob *P, int j);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_col_name| returns a pointer to an internal
+buffer, which contains a symbolic name assigned to \verb|j|-th column.
+However, if the column has no assigned name, the routine returns
+\verb|NULL|.
+
+\subsection{glp\_get\_row\_type --- retrieve row type}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_row_type(glp_prob *P, int i);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_row_type| returns the type of \verb|i|-th
+row, i.e. the type of corresponding auxiliary variable, as follows:
+
+\verb|GLP_FR| --- free (unbounded) variable;
+
+\verb|GLP_LO| --- variable with lower bound;
+
+\verb|GLP_UP| --- variable with upper bound;
+
+\verb|GLP_DB| --- double-bounded variable;
+
+\verb|GLP_FX| --- fixed variable.
+
+\subsection{glp\_get\_row\_lb --- retrieve row lower bound}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_get_row_lb(glp_prob *P, int i);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_row_lb| returns the lower bound of
+\verb|i|-th row, i.e. the lower bound of corresponding auxiliary
+variable. However, if the row has no lower bound, the routine returns
+\verb|-DBL_MAX|.
+
+\vspace*{-4pt}
+
+\subsection{glp\_get\_row\_ub --- retrieve row upper bound}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_get_row_ub(glp_prob *P, int i);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_row_ub| returns the upper bound of
+\verb|i|-th row, i.e. the upper bound of corresponding auxiliary
+variable. However, if the row has no upper bound, the routine returns
+\verb|+DBL_MAX|.
+
+\vspace*{-4pt}
+
+\subsection{glp\_get\_col\_type --- retrieve column type}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_col_type(glp_prob *P, int j);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_col_type| returns the type of \verb|j|-th
+column, i.e. the type of corresponding structural variable, as follows:
+
+\verb|GLP_FR| --- free (unbounded) variable;
+
+\verb|GLP_LO| --- variable with lower bound;
+
+\verb|GLP_UP| --- variable with upper bound;
+
+\verb|GLP_DB| --- double-bounded variable;
+
+\verb|GLP_FX| --- fixed variable.
+
+\vspace*{-4pt}
+
+\subsection{glp\_get\_col\_lb --- retrieve column lower bound}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_get_col_lb(glp_prob *P, int j);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_col_lb| returns the lower bound of
+\verb|j|-th column, i.e. the lower bound of corresponding structural
+variable. However, if the column has no lower bound, the routine
+returns \verb|-DBL_MAX|.
+
+\subsection{glp\_get\_col\_ub --- retrieve column upper bound}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_get_col_ub(glp_prob *P, int j);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_col_ub| returns the upper bound of
+\verb|j|-th column, i.e. the upper bound of corresponding structural
+variable. However, if the column has no upper bound, the routine
+returns \verb|+DBL_MAX|.
+
+\subsection{glp\_get\_obj\_coef --- retrieve objective coefficient or
+constant term}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_get_obj_coef(glp_prob *P, int j);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_obj_coef| returns the objective coefficient
+at \verb|j|-th structural variable (column).
+
+If the parameter \verb|j| is 0, the routine returns the constant term
+(``shift'') of the objective function.
+
+\subsection{glp\_get\_num\_nz --- retrieve number of constraint
+coefficients}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_num_nz(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_num_nz| returns the number of non-zero
+elements in the constraint matrix of the specified problem object.
+
+\subsection{glp\_get\_mat\_row --- retrieve row of the constraint
+matrix}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_mat_row(glp_prob *P, int i, int ind[], double val[]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_get_mat_row| scans (non-zero) elements of
+\verb|i|-th row of the constraint matrix of the specified problem
+object and stores their column indices and numeric values to locations
+\verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|, \dots,
+\verb|val[len]|, respectively, where $0\leq{\tt len}\leq n$ is the
+number of elements in $i$-th row, $n$ is the number of columns.
+
+The parameter \verb|ind| and/or \verb|val| can be specified as
+\verb|NULL|, in which case corresponding information is not stored.
+
+%\newpage
+
+\returns
+
+The routine \verb|glp_get_mat_row| returns the length \verb|len|, i.e.
+the number of (non-zero) elements in \verb|i|-th row.
+
+\subsection{glp\_get\_mat\_col --- retrieve column of the constraint
+matrix}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_mat_col(glp_prob *P, int j, int ind[], double val[]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_get_mat_col| scans (non-zero) elements of
+\verb|j|-th column of the constraint matrix of the specified problem
+object and stores their row indices and numeric values to locations
+\linebreak \verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|,
+\dots, \verb|val[len]|, respectively, where $0\leq{\tt len}\leq m$ is
+the number of elements in $j$-th column, $m$ is the number of rows.
+
+The parameter \verb|ind| and/or \verb|val| can be specified as
+\verb|NULL|, in which case corresponding information is not stored.
+
+\returns
+
+The routine \verb|glp_get_mat_col| returns the length \verb|len|, i.e.
+the number of (non-zero) elements in \verb|j|-th column.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Row and column searching routines}
+
+Sometimes it may be necessary to find rows and/or columns by their
+names (assigned with the routines \verb|glp_set_row_name| and
+\verb|glp_set_col_name|). Though a particular row/column can be found
+by its name using simple enumeration of all rows/columns, in case of
+large instances such a {\it linear} search may take too long time.
+
+To significantly reduce the search time the application program may
+create the row/column name index, which is an auxiliary data structure
+implementing a {\it binary} search. Even in worst cases the search
+takes logarithmic time, i.e. the time needed to find a particular row
+(or column) by its name is $O(\log_2m)$ (or $O(\log_2n)$), where $m$
+and $n$ are, resp., the number of rows and columns in the problem
+object.
+
+It is important to note that:
+
+\Item{1.}On creating the problem object with the routine
+\verb|glp_create_prob| the name index is {\it not} created.
+
+\Item{2.}The name index can be created (destroyed) at any time with the
+routine \verb|glp_create_index| (\verb|glp_delete_index|). Having been
+created the name index becomes part of the corresponding problem
+object.
+
+\Item{3.}The time taken to create the name index is
+$O[(m+n)\log_2(m+n)]$, so it is recommended to create the index only
+once, for example, just after the problem object was created.
+
+\Item{4.}If the name index exists, it is automatically updated every
+time the name of a row/column is assigned/changed. The update operation
+takes logarithmic time.
+
+\Item{5.}If the name index does not exist, the application should not
+call the routines \verb|glp_find_row| and \verb|glp_find_col|.
+Otherwise, an error message will be issued and abnormal program
+termination will occur.
+
+\Item{6.}On destroying the problem object with the routine
+\verb|glp_delete_prob|, the name index, if exists, is automatically
+destroyed.
+
+\subsection{glp\_create\_index --- create the name index}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_create_index(glp_prob *P);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_create_index| creates the name index for the
+specified problem object. The name index is an auxiliary data
+structure, which is intended to quickly (i.e. for logarithmic time)
+find rows and columns by their names.
+
+This routine can be called at any time. If the name index already
+exists, the routine does nothing.
+
+\newpage
+
+\subsection{glp\_find\_row --- find row by its name}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_find_row(glp_prob *P, const char *name);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_find_row| returns the ordinal number of a row,
+which is assigned the specified symbolic \verb|name|. If no such row
+exists, the routine returns 0.
+
+\subsection{glp\_find\_col --- find column by its name}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_find_col(glp_prob *P, const char *name);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_find_col| returns the ordinal number of a column,
+which is assigned the specified symbolic \verb|name|. If no such column
+exists, the routine returns 0.
+
+\subsection{glp\_delete\_index --- delete the name index}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_delete_index(glp_prob *P);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_delete_index| deletes the name index previously
+created by the routine\linebreak \verb|glp_create_index| and frees the
+memory allocated to this auxiliary data structure.
+
+This routine can be called at any time. If the name index does not
+exist, the routine does nothing.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Problem scaling routines}
+
+\subsection{Background}
+
+In GLPK the {\it scaling} means a linear transformation applied to the
+constraint matrix to improve its numerical properties.\footnote{In many
+cases a proper scaling allows making the constraint matrix to be better
+conditioned, i.e. decreasing its condition number, that makes
+computations numerically more stable.}
+
+The main equality is the following:
+$$\widetilde{A}=RAS,\eqno(2.1)$$
+where $A=(a_{ij})$ is the original constraint matrix, $R=(r_{ii})>0$ is
+a diagonal matrix used to scale rows (constraints), $S=(s_{jj})>0$ is a
+diagonal matrix used to scale columns (variables), $\widetilde{A}$ is
+the scaled constraint matrix.
+
+From (2.1) it follows that in the {\it scaled} problem instance each
+original constraint coefficient $a_{ij}$ is replaced by corresponding
+scaled constraint coefficient:
+$$\widetilde{a}_{ij}=r_{ii}a_{ij}s_{jj}.\eqno(2.2)$$
+
+Note that the scaling is performed internally and therefore
+transparently to the user. This means that on API level the user always
+deal with unscaled data.
+
+Scale factors $r_{ii}$ and $s_{jj}$ can be set or changed at any time
+either directly by the application program in a problem specific way
+(with the routines \verb|glp_set_rii| and \verb|glp_set_sjj|), or by
+some API routines intended for automatic scaling.
+
+\subsection{glp\_set\_rii --- set (change) row scale factor}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_rii(glp_prob *P, int i, double rii);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_rii| sets (changes) the scale factor $r_{ii}$
+for $i$-th row of the specified problem object.
+
+\subsection{glp\_set\_sjj --- set (change) column scale factor}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_sjj(glp_prob *P, int j, double sjj);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_sjj| sets (changes) the scale factor $s_{jj}$
+for $j$-th column of the specified problem object.
+
+\newpage
+
+\subsection{glp\_get\_rii --- retrieve row scale factor}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_get_rii(glp_prob *P, int i);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_rii| returns current scale factor $r_{ii}$
+for $i$-th row of the specified problem object.
+
+\vspace*{-6pt}
+
+\subsection{glp\_get\_sjj --- retrieve column scale factor}
+
+\vspace*{-4pt}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_get_sjj(glp_prob *P, int j);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_sjj| returns current scale factor $s_{jj}$
+for $j$-th column of the specified problem object.
+
+\vspace*{-6pt}
+
+\subsection{glp\_scale\_prob --- scale problem data}
+
+\vspace*{-4pt}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_scale_prob(glp_prob *P, int flags);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_scale_prob| performs automatic scaling of problem
+data for the specified problem object.
+
+The parameter \verb|flags| specifies scaling options used by the
+routine. The options can be combined with the bitwise OR operator and
+may be the following:
+
+\verb|GLP_SF_GM | --- perform geometric mean scaling;
+
+\verb|GLP_SF_EQ | --- perform equilibration scaling;
+
+\verb|GLP_SF_2N | --- round scale factors to nearest power of two;
+
+\verb|GLP_SF_SKIP| --- skip scaling, if the problem is well scaled.
+
+The parameter \verb|flags| may be also specified as \verb|GLP_SF_AUTO|,
+in which case the routine chooses the scaling options automatically.
+
+\vspace*{-6pt}
+
+\subsection{glp\_unscale\_prob --- unscale problem data}
+
+\vspace*{-4pt}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_unscale_prob(glp_prob *P);
+\end{verbatim}
+
+The routine \verb|glp_unscale_prob| performs unscaling of problem data
+for the specified problem object.
+
+``Unscaling'' means replacing the current scaling matrices $R$ and $S$
+by unity matrices that cancels the scaling effect.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{LP basis constructing routines}
+
+\subsection{Background}
+
+To start the search the simplex method needs a valid initial basis.
+In GLPK the basis is completely defined by a set of {\it statuses}
+assigned to {\it all} (auxiliary and structural) variables, where the
+status may be one of the following:
+
+\verb|GLP_BS| --- basic variable;
+
+\verb|GLP_NL| --- non-basic variable having active lower bound;
+
+\verb|GLP_NU| --- non-basic variable having active upper bound;
+
+\verb|GLP_NF| --- non-basic free variable;
+
+\verb|GLP_NS| --- non-basic fixed variable.
+
+The basis is {\it valid}, if the basis matrix, which is a matrix built
+of columns of the augmented constraint matrix $(I\:|-A)$ corresponding
+to basic variables, is non-singular. This, in particular, means that
+the number of basic variables must be the same as the number of rows in
+the problem object. (For more details see Section \ref{lpbasis}, page
+\pageref{lpbasis}.)
+
+Any initial basis may be constructed (or restored) with the API
+routines \verb|glp_set_row_stat| and \verb|glp_set_col_stat| by
+assigning appropriate statuses to auxiliary and structural variables.
+Another way to construct an initial basis is to use API routines like
+\verb|glp_adv_basis|, which implement so called
+{\it crashing}.\footnote{This term is from early linear programming
+systems and means a heuristic to construct a valid initial basis.} Note
+that on normal exit the simplex solver remains the basis valid, so in
+case of re-optimization there is no need to construct an initial basis
+from scratch.
+
+\subsection{glp\_set\_row\_stat --- set (change) row status}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_row_stat(glp_prob *P, int i, int stat);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_row_stat| sets (changes) the current status
+of \verb|i|-th row (auxiliary variable) as specified by the parameter
+\verb|stat|:
+
+\verb|GLP_BS| --- make the row basic (make the constraint inactive);
+
+\verb|GLP_NL| --- make the row non-basic (make the constraint active);
+
+\verb|GLP_NU| --- make the row non-basic and set it to the upper bound;
+if the row is not double-bounded, this status is equivalent to
+\verb|GLP_NL| (only in case of this routine);
+
+\verb|GLP_NF| --- the same as \verb|GLP_NL| (only in case of this
+routine);
+
+\verb|GLP_NS| --- the same as \verb|GLP_NL| (only in case of this
+routine).
+
+\newpage
+
+\subsection{glp\_set\_col\_stat --- set (change) column status}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_col_stat(glp_prob *P, int j, int stat);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_col_stat sets| (changes) the current status
+of \verb|j|-th column (structural variable) as specified by the
+parameter \verb|stat|:
+
+\verb|GLP_BS| --- make the column basic;
+
+\verb|GLP_NL| --- make the column non-basic;
+
+\verb|GLP_NU| --- make the column non-basic and set it to the upper
+bound; if the column is not double-bounded, this status is equivalent
+to \verb|GLP_NL| (only in case of this routine);
+
+\verb|GLP_NF| --- the same as \verb|GLP_NL| (only in case of this
+routine);
+
+\verb|GLP_NS| --- the same as \verb|GLP_NL| (only in case of this
+routine).
+
+\subsection{glp\_std\_basis --- construct standard initial LP basis}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_std_basis(glp_prob *P);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_std_basis| constructs the ``standard'' (trivial)
+initial LP basis for the specified problem object.
+
+In the ``standard'' LP basis all auxiliary variables (rows) are basic,
+and all structural variables (columns) are non-basic (so the
+corresponding basis matrix is unity).
+
+\subsection{glp\_adv\_basis --- construct advanced initial LP basis}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_adv_basis(glp_prob *P, int flags);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_adv_basis| constructs an advanced initial LP
+basis for the specified problem object.
+
+The parameter \verb|flags| is reserved for use in the future and must
+be specified as zero.
+
+In order to construct the advanced initial LP basis the routine does
+the following:
+
+1) includes in the basis all non-fixed auxiliary variables;
+
+2) includes in the basis as many non-fixed structural variables as
+possible keeping the triangular form of the basis matrix;
+
+3) includes in the basis appropriate (fixed) auxiliary variables to
+complete the basis.
+
+As a result the initial LP basis has as few fixed variables as possible
+and the corresponding basis matrix is triangular.
+
+\subsection{glp\_cpx\_basis --- construct Bixby's initial LP basis}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_cpx_basis(glp_prob *P);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_cpx_basis| constructs an initial basis for the
+specified problem object with the algorithm proposed by
+R.~Bixby.\footnote{Robert E. Bixby, ``Implementing the Simplex Method:
+The Initial Basis.'' ORSA Journal on Computing, Vol. 4, No. 3, 1992,
+pp. 267-84.}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Simplex method routines}
+
+The {\it simplex method} is a well known efficient numerical procedure
+to solve LP problems.
+
+On each iteration the simplex method transforms the original system of
+equaility constraints (1.2) resolving them through different sets of
+variables to an equivalent system called {\it the simplex table} (or
+sometimes {\it the simplex tableau}), which has the following form:
+$$
+\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}r}
+z&=&d_1(x_N)_1&+&d_2(x_N)_2&+ \dots +&d_n(x_N)_n \\
+(x_B)_1&=&\xi_{11}(x_N)_1& +& \xi_{12}(x_N)_2& + \dots +&
+ \xi_{1n}(x_N)_n \\
+(x_B)_2&=& \xi_{21}(x_N)_1& +& \xi_{22}(x_N)_2& + \dots +&
+ \xi_{2n}(x_N)_n \\
+\multicolumn{7}{c}
+{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .} \\
+(x_B)_m&=&\xi_{m1}(x_N)_1& +& \xi_{m2}(x_N)_2& + \dots +&
+ \xi_{mn}(x_N)_n \\
+\end{array} \eqno (2.3)
+$$
+where: $(x_B)_1, (x_B)_2, \dots, (x_B)_m$ are basic variables;
+$(x_N)_1, (x_N)_2, \dots, (x_N)_n$ are non-basic variables;
+$d_1, d_2, \dots, d_n$ are reduced costs;
+$\xi_{11}, \xi_{12}, \dots, \xi_{mn}$ are coefficients of the
+simplex table. (May note that the original LP problem (1.1)---(1.3)
+also has the form of a simplex table, where all equalities are resolved
+through auxiliary variables.)
+
+From the linear programming theory it is known that if an optimal
+solution of the LP problem (1.1)---(1.3) exists, it can always be
+written in the form (2.3), where non-basic variables are set on their
+bounds while values of the objective function and basic variables are
+determined by the corresponding equalities of the simplex table.
+
+A set of values of all basic and non-basic variables determined by the
+simplex table is called {\it basic solution}. If all basic variables
+are within their bounds, the basic solution is called {\it (primal)
+feasible}, otherwise it is called {\it (primal) infeasible}. A feasible
+basic solution, which provides a smallest (in case of minimization) or
+a largest (in case of maximization) value of the objective function is
+called {\it optimal}. Therefore, for solving LP problem the simplex
+method tries to find its optimal basic solution.
+
+Primal feasibility of some basic solution may be stated by simple
+checking if all basic variables are within their bounds. Basic solution
+is optimal if additionally the following optimality conditions are
+satisfied for all non-basic variables:
+\begin{center}
+\begin{tabular}{lcc}
+Status of $(x_N)_j$ & Minimization & Maximization \\
+\hline
+$(x_N)_j$ is free & $d_j = 0$ & $d_j = 0$ \\
+$(x_N)_j$ is on its lower bound & $d_j \geq 0$ & $d_j \leq 0$ \\
+$(x_N)_j$ is on its upper bound & $d_j \leq 0$ & $d_j \geq 0$ \\
+\end{tabular}
+\end{center}
+In other words, basic solution is optimal if there is no non-basic
+variable, which changing in the feasible direction (i.e. increasing if
+it is free or on its lower bound, or decreasing if it is free or on its
+upper bound) can improve (i.e. decrease in case of minimization or
+increase in case of maximization) the objective function.
+
+If all non-basic variables satisfy to the optimality conditions shown
+above (independently on whether basic variables are within their bounds
+or not), the basic solution is called {\it dual feasible}, otherwise it
+is called {\it dual infeasible}.
+
+It may happen that some LP problem has no primal feasible solution due
+to incorrect\linebreak formulation --- this means that its constraints
+conflict with each other. It also may happen that some LP problem has
+unbounded solution again due to incorrect formulation --- this means
+that some non-basic variable can improve the objective function, i.e.
+the optimality conditions are violated, and at the same time this
+variable can infinitely change in the feasible direction meeting
+no resistance from basic variables. (May note that in the latter case
+the LP problem has no dual feasible solution.)
+
+\subsection{glp\_simplex --- solve LP problem with the primal or dual
+simplex method}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_simplex(glp_prob *P, const glp_smcp *parm);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_simplex| is a driver to the LP solver based on
+the simplex method. This routine retrieves problem data from the
+specified problem object, calls the solver to solve the problem
+instance, and stores results of computations back into the problem
+object.
+
+The simplex solver has a set of control parameters. Values of the
+control parameters can be passed in the structure \verb|glp_smcp|,
+which the parameter \verb|parm| points to. For detailed description of
+this structure see paragraph ``Control parameters'' below.
+Before specifying some control parameters the application program
+should initialize the structure \verb|glp_smcp| by default values of
+all control parameters using the routine \verb|glp_init_smcp| (see the
+next subsection). This is needed for backward compatibility, because in
+the future there may appear new members in the structure
+\verb|glp_smcp|.
+
+The parameter \verb|parm| can be specified as \verb|NULL|, in which
+case the solver uses default settings.
+
+\returns
+
+\begin{retlist}
+0 & The LP problem instance has been successfully solved. (This code
+does {\it not} necessarily mean that the solver has found optimal
+solution. It only means that the solution process was successful.) \\
+
+\verb|GLP_EBADB| & Unable to start the search, because the initial
+basis specified in the problem object is invalid---the number of basic
+(auxiliary and structural) variables is not the same as the number of
+rows in the problem object.\\
+
+\verb|GLP_ESING| & Unable to start the search, because the basis matrix
+corresponding to the initial basis is singular within the working
+precision.\\
+
+\verb|GLP_ECOND| & Unable to start the search, because the basis matrix
+corresponding to the initial basis is ill-conditioned, i.e. its
+condition number is too large.\\
+
+\verb|GLP_EBOUND| & Unable to start the search, because some
+double-bounded (auxiliary or structural) variables have incorrect
+bounds.\\
+
+\verb|GLP_EFAIL| & The search was prematurely terminated due to the
+solver failure.\\
+
+\verb|GLP_EOBJLL| & The search was prematurely terminated, because the
+objective function being maximized has reached its lower limit and
+continues decreasing (the dual simplex only).\\
+
+\verb|GLP_EOBJUL| & The search was prematurely terminated, because the
+objective function being minimized has reached its upper limit and
+continues increasing (the dual simplex only).\\
+
+\verb|GLP_EITLIM| & The search was prematurely terminated, because the
+simplex iteration limit has been exceeded.\\
+
+\verb|GLP_ETMLIM| & The search was prematurely terminated, because the
+time limit has been exceeded.\\
+\end{retlist}
+
+\begin{retlist}
+\verb|GLP_ENOPFS| & The LP problem instance has no primal feasible
+solution (only if the LP presolver is used).\\
+
+\verb|GLP_ENODFS| & The LP problem instance has no dual feasible
+solution (only if the LP presolver is used).\\
+\end{retlist}
+
+\para{Built-in LP presolver}
+
+The simplex solver has {\it built-in LP presolver}. It is a subprogram
+that transforms the original LP problem specified in the problem object
+to an equivalent LP problem, which may be easier for solving with the
+simplex method than the original one. This is attained mainly due to
+reducing the problem size and improving its numeric properties (for
+example, by removing some inactive constraints or by fixing some
+non-basic variables). Once the transformed LP problem has been solved,
+the presolver transforms its basic solution back to the corresponding
+basic solution of the original problem.
+
+Presolving is an optional feature of the routine \verb|glp_simplex|,
+and by default it is disabled. In order to enable the LP presolver the
+control parameter \verb|presolve| should be set to \verb|GLP_ON| (see
+paragraph ``Control parameters'' below). Presolving may be used when
+the problem instance is solved for the first time. However, on
+performing re-optimization the presolver should be disabled.
+
+The presolving procedure is transparent to the API user in the sense
+that all necessary processing is performed internally, and a basic
+solution of the original problem recovered by the presolver is the same
+as if it were computed directly, i.e. without presolving.
+
+Note that the presolver is able to recover only optimal solutions. If
+a computed solution is infeasible or non-optimal, the corresponding
+solution of the original problem cannot be recovered and therefore
+remains undefined. If you need to know a basic solution even if it is
+infeasible or non-optimal, the presolver should be disabled.
+
+\para{Terminal output}
+
+Solving large problem instances may take a long time, so the solver
+reports some information about the current basic solution, which is
+sent to the terminal. This information has the following format:
+
+\begin{verbatim}
+ nnn: obj = xxx infeas = yyy (num) cnt
+\end{verbatim}
+
+\noindent
+where: `\verb|nnn|' is the iteration number, `\verb|xxx|' is the
+current value of the objective function (it is unscaled and has correct
+sign); `\verb|yyy|' is the current sum of primal or dual
+infeasibilities (it is scaled and therefore may be used only for visual
+estimating), `\verb|num|' is the current number of primal or dual
+infeasibilities (phase I) or non-optimalities (phase II), `\verb|cnt|'
+is the number of basis factorizations since the last terminal output.
+
+The symbol preceding the iteration number indicates which phase of the
+simplex method is in effect:
+
+{\it Blank} means that the solver is searching for primal feasible
+solution using the primal simplex or for dual feasible solution using
+the dual simplex;
+
+{\it Asterisk} (\verb|*|) means that the solver is searching for
+optimal solution using the primal simplex;
+
+{\it Hash} (\verb|#|) means that the solver is searching for optimal
+solution using the dual simplex.
+
+\newpage
+
+\para{Control parameters}
+
+This paragraph describes all control parameters currently used in the
+simplex solver. Symbolic names of control parameters are names of
+corresponding members in the structure \verb|glp_smcp|.
+
+\bigskip
+
+{\tt int msg\_lev} (default: {\tt GLP\_MSG\_ALL})
+
+Message level for terminal output:
+
+\verb|GLP_MSG_OFF| --- no output;
+
+\verb|GLP_MSG_ERR| --- error and warning messages only;
+
+\verb|GLP_MSG_ON | --- normal output;
+
+\verb|GLP_MSG_ALL| --- full output (including informational messages).
+
+\bigskip
+
+{\tt int meth} (default: {\tt GLP\_PRIMAL})
+
+Simplex method option:
+
+\verb|GLP_PRIMAL| --- use two-phase primal simplex;
+
+\verb|GLP_DUAL | --- use two-phase dual simplex;
+
+\verb|GLP_DUALP | --- use two-phase dual simplex, and if it fails,
+switch to the primal simplex.
+
+\bigskip
+
+{\tt int pricing} (default: {\tt GLP\_PT\_PSE})
+
+Pricing technique:
+
+\verb|GLP_PT_STD| --- standard (``textbook'');
+
+\verb|GLP_PT_PSE| --- projected steepest edge.
+
+\bigskip
+
+{\tt int r\_test} (default: {\tt GLP\_RT\_HAR})
+
+Ratio test technique:
+
+\verb|GLP_RT_STD| --- standard (``textbook'');
+
+\verb|GLP_RT_HAR| --- Harris' two-pass ratio test.
+
+\bigskip
+
+{\tt double tol\_bnd} (default: {\tt 1e-7})
+
+Tolerance used to check if the basic solution is primal feasible.
+(Do not change this parameter without detailed understanding its
+purpose.)
+
+%\newpage
+\bigskip
+
+{\tt double tol\_dj} (default: {\tt 1e-7})
+
+Tolerance used to check if the basic solution is dual feasible.
+(Do not change this parameter without detailed understanding its
+purpose.)
+
+\bigskip
+
+{\tt double tol\_piv} (default: {\tt 1e-9})
+
+Tolerance used to choose eligble pivotal elements of the simplex table.
+(Do not change this parameter without detailed understanding its
+purpose.)
+
+%\bigskip
+\newpage
+
+{\tt double obj\_ll} (default: {\tt -DBL\_MAX})
+
+Lower limit of the objective function. If the objective function
+reaches this limit and continues decreasing, the solver terminates the
+search. (Used in the dual simplex only.)
+
+\bigskip
+
+{\tt double obj\_ul} (default: {\tt +DBL\_MAX})
+
+Upper limit of the objective function. If the objective function
+reaches this limit and continues increasing, the solver terminates the
+search. (Used in the dual simplex only.)
+
+\bigskip
+
+{\tt int it\_lim} (default: {\tt INT\_MAX})
+
+Simplex iteration limit.
+
+\bigskip
+
+{\tt int tm\_lim} (default: {\tt INT\_MAX})
+
+Searching time limit, in milliseconds.
+
+\bigskip
+
+{\tt int out\_frq} (default: {\tt 500})
+
+Output frequency, in iterations. This parameter specifies how
+frequently the solver sends information about the solution process to
+the terminal.
+
+\bigskip
+
+{\tt int out\_dly} (default: {\tt 0})
+
+Output delay, in milliseconds. This parameter specifies how long the
+solver should delay sending information about the solution process to
+the terminal.
+
+\bigskip
+
+{\tt int presolve} (default: {\tt GLP\_OFF})
+
+LP presolver option:
+
+\verb|GLP_ON | --- enable using the LP presolver;
+
+\verb|GLP_OFF| --- disable using the LP presolver.
+
+\newpage
+
+\para{Example 1}
+
+The following example main program reads LP problem instance in fixed
+MPS format from file \verb|25fv47.mps|,\footnote{This instance in fixed
+MPS format can be found in the Netlib LP collection; see
+{\tt ftp://ftp.netlib.org/lp/data/}.} constructs an advanced initial
+basis, solves the instance with the primal simplex method (by default),
+and writes the solution to file \verb|25fv47.txt|.
+
+\begin{footnotesize}
+\begin{verbatim}
+/* spxsamp1.c */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+int main(void)
+{ glp_prob *P;
+ P = glp_create_prob();
+ glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps");
+ glp_adv_basis(P, 0);
+ glp_simplex(P, NULL);
+ glp_print_sol(P, "25fv47.txt");
+ glp_delete_prob(P);
+ return 0;
+}
+
+/* eof */
+\end{verbatim}
+\end{footnotesize}
+
+Below here is shown the terminal output from this example program.
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading problem data from '25fv47.mps'...
+Problem: 25FV47
+Objective: R0000
+822 rows, 1571 columns, 11127 non-zeros
+6919 records were read
+One free row was removed
+Constructing initial basis...
+Size of triangular part is 812
+GLPK Simplex Optimizer, v4.57
+821 rows, 1571 columns, 10400 non-zeros
+ 0: obj = 7.131703290e+03 inf = 2.145e+05 (204)
+ 500: obj = 1.886711682e+04 inf = 8.273e+02 (36) 4
+ 741: obj = 1.846047936e+04 inf = 5.575e-14 (0) 2
+* 1000: obj = 9.220063473e+03 inf = 2.423e-14 (432) 2
+* 1500: obj = 6.187659664e+03 inf = 1.019e-13 (368) 4
+* 2000: obj = 5.503442062e+03 inf = 0.000e+00 (33) 5
+* 2052: obj = 5.501845888e+03 inf = 0.000e+00 (0)
+OPTIMAL LP SOLUTION FOUND
+Writing basic solution to '25fv47.txt'...
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+\para{Example 2}
+
+The following example main program solves the same LP problem instance
+as in Example 1 above, however, it uses the dual simplex method, which
+starts from the standard initial basis.
+
+\begin{footnotesize}
+\begin{verbatim}
+/* spxsamp2.c */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+int main(void)
+{ glp_prob *P;
+ glp_smcp parm;
+ P = glp_create_prob();
+ glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps");
+ glp_init_smcp(&parm);
+ parm.meth = GLP_DUAL;
+ glp_simplex(P, &parm);
+ glp_print_sol(P, "25fv47.txt");
+ glp_delete_prob(P);
+ return 0;
+}
+
+/* eof */
+\end{verbatim}
+\end{footnotesize}
+
+Below here is shown the terminal output from this example program.
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading problem data from '25fv47.mps'...
+Problem: 25FV47
+Objective: R0000
+822 rows, 1571 columns, 11127 non-zeros
+6919 records were read
+One free row was removed
+GLPK Simplex Optimizer, v4.57
+821 rows, 1571 columns, 10400 non-zeros
+ 0: inf = 1.223e+02 (41)
+ 258: inf = 3.091e-16 (0) 2
+# 500: obj = -5.071287080e+03 inf = 2.947e-15 (292) 2
+# 1000: obj = -1.352843873e+03 inf = 8.452e-15 (302) 5
+# 1500: obj = 7.985859737e+02 inf = 1.127e-14 (263) 5
+# 2000: obj = 3.059023029e+03 inf = 6.290e-11 (197) 4
+# 2500: obj = 5.354770966e+03 inf = 7.172e-13 (130) 5
+# 2673: obj = 5.501845888e+03 inf = 3.802e-16 (0) 2
+OPTIMAL LP SOLUTION FOUND
+Writing basic solution to '25fv47.txt'...
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+\subsection{glp\_exact --- solve LP problem in exact arithmetic}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_exact(glp_prob *P, const glp_smcp *parm);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_exact| is a tentative implementation of the
+primal two-phase simplex method based on exact (rational) arithmetic.
+It is similar to the routine \verb|glp_simplex|, however, for all
+internal computations it uses arithmetic of rational numbers, which is
+exact in mathematical sense, i.e. free of round-off errors unlike
+floating-point arithmetic.
+
+Note that the routine \verb|glp_exact| uses only three control
+parameters passed in the structure \verb|glp_smcp|, namely,
+\verb|msg_lev|, \verb|it_lim|, and \verb|tm_lim|.
+
+\returns
+
+\begin{retlist}
+0 & The LP problem instance has been successfully solved. (This code
+does {\it not} necessarily mean that the solver has found optimal
+solution. It only means that the solution process was successful.) \\
+
+\verb|GLP_EBADB| & Unable to start the search, because the initial basis
+specified in the problem object is invalid---the number of basic
+(auxiliary and structural) variables is not the same as the number of
+rows in the problem object.\\
+
+\verb|GLP_ESING| & Unable to start the search, because the basis matrix
+corresponding to the initial basis is exactly singular.\\
+
+\verb|GLP_EBOUND| & Unable to start the search, because some
+double-bounded (auxiliary or structural) variables have incorrect
+bounds.\\
+
+\verb|GLP_EFAIL| & The problem instance has no rows/columns.\\
+
+\verb|GLP_EITLIM| & The search was prematurely terminated, because the
+simplex iteration limit has been exceeded.\\
+
+\verb|GLP_ETMLIM| & The search was prematurely terminated, because the
+time limit has been exceeded.\\
+\end{retlist}
+
+\para{Note}
+
+Computations in exact arithmetic are very time-consuming, so solving
+LP problem with the routine \verb|glp_exact| from the very beginning is
+not a good idea. It is much better at first to find an optimal basis
+with the routine \verb|glp_simplex| and only then to call
+\verb|glp_exact|, in which case only a few simplex iterations need to
+be performed in exact arithmetic.
+
+\newpage
+
+\subsection{glp\_init\_smcp --- initialize simplex solver control
+parameters}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_init_smcp(glp_smcp *parm);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_init_smcp| initializes control parameters, which
+are used by the simplex solver, with default values.
+
+Default values of the control parameters are stored in
+a \verb|glp_smcp| structure, which the parameter \verb|parm| points to.
+
+\subsection{glp\_get\_status --- determine generic status of basic
+solution}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_status(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_status| reports the generic status of the
+current basic solution for the specified problem object as follows:
+
+\verb|GLP_OPT | --- solution is optimal;
+
+\verb|GLP_FEAS | --- solution is feasible;
+
+\verb|GLP_INFEAS| --- solution is infeasible;
+
+\verb|GLP_NOFEAS| --- problem has no feasible solution;
+
+\verb|GLP_UNBND | --- problem has unbounded solution;
+
+\verb|GLP_UNDEF | --- solution is undefined.
+
+More detailed information about the status of basic solution can be
+retrieved with the routines \verb|glp_get_prim_stat| and
+\verb|glp_get_dual_stat|.
+
+\subsection{glp\_get\_prim\_stat --- retrieve status of primal basic
+solution}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_prim_stat(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_prim_stat| reports the status of the primal
+basic solution for the specified problem object as follows:
+
+\verb|GLP_UNDEF | --- primal solution is undefined;
+
+\verb|GLP_FEAS | --- primal solution is feasible;
+
+\verb|GLP_INFEAS| --- primal solution is infeasible;
+
+\verb|GLP_NOFEAS| --- no primal feasible solution exists.
+
+\subsection{glp\_get\_dual\_stat --- retrieve status of dual basic
+solution}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_dual_stat(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_dual_stat| reports the status of the dual
+basic solution for the specified problem object as follows:
+
+\verb|GLP_UNDEF | --- dual solution is undefined;
+
+\verb|GLP_FEAS | --- dual solution is feasible;
+
+\verb|GLP_INFEAS| --- dual solution is infeasible;
+
+\verb|GLP_NOFEAS| --- no dual feasible solution exists.
+
+\subsection{glp\_get\_obj\_val --- retrieve objective value}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_get_obj_val(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_obj_val| returns current value of the
+objective function.
+
+\subsection{glp\_get\_row\_stat --- retrieve row status}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_row_stat(glp_prob *P, int i);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_row_stat| returns current status assigned to
+the auxiliary variable associated with \verb|i|-th row as follows:
+
+\verb|GLP_BS| --- basic variable;
+
+\verb|GLP_NL| --- non-basic variable on its lower bound;
+
+\verb|GLP_NU| --- non-basic variable on its upper bound;
+
+\verb|GLP_NF| --- non-basic free (unbounded) variable;
+
+\verb|GLP_NS| --- non-basic fixed variable.
+
+%\newpage
+
+\subsection{glp\_get\_row\_prim --- retrieve row primal value}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_get_row_prim(glp_prob *P, int i);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_row_prim| returns primal value of the
+auxiliary variable associated with \verb|i|-th row.
+
+\subsection{glp\_get\_row\_dual --- retrieve row dual value}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_get_row_dual(glp_prob *P, int i);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_row_dual| returns dual value (i.e. reduced
+cost) of the auxiliary variable associated with \verb|i|-th row.
+
+\subsection{glp\_get\_col\_stat --- retrieve column status}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_col_stat(glp_prob *P, int j);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_col_stat| returns current status assigned to
+the structural variable associated with \verb|j|-th column as follows:
+
+\verb|GLP_BS| --- basic variable;
+
+\verb|GLP_NL| --- non-basic variable on its lower bound;
+
+\verb|GLP_NU| --- non-basic variable on its upper bound;
+
+\verb|GLP_NF| --- non-basic free (unbounded) variable;
+
+\verb|GLP_NS| --- non-basic fixed variable.
+
+\subsection{glp\_get\_col\_prim --- retrieve column primal value}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_get_col_prim(glp_prob *P, int j);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_col_prim| returns primal value of the
+structural variable associated with \verb|j|-th column.
+
+%\newpage
+
+\subsection{glp\_get\_col\_dual --- retrieve column dual value}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_get_col_dual(glp_prob *P, int j);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_col_dual| returns dual value (i.e. reduced
+cost) of the structural variable associated with \verb|j|-th column.
+
+\newpage
+
+\subsection{glp\_get\_unbnd\_ray --- determine variable causing
+unboundedness}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_unbnd_ray(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_unbnd_ray| returns the number $k$ of
+a variable, which causes primal or dual unboundedness.
+If $1\leq k\leq m$, it is $k$-th auxiliary variable, and if
+$m+1\leq k\leq m+n$, it is $(k-m)$-th structural variable, where $m$ is
+the number of rows, $n$ is the number of columns in the problem object.
+If such variable is not defined, the routine returns 0.
+
+\para{Note}
+
+If it is not exactly known which version of the simplex solver
+detected unboundedness, i.e. whether the unboundedness is primal or
+dual, it is sufficient to check the status of the variable
+with the routine \verb|glp_get_row_stat| or \verb|glp_get_col_stat|.
+If the variable is non-basic, the unboundedness is primal, otherwise,
+if the variable is basic, the unboundedness is dual (the latter case
+means that the problem has no primal feasible dolution).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Interior-point method routines}
+
+{\it Interior-point methods} (also known as {\it barrier methods}) are
+more modern and powerful numerical methods for large-scale linear
+programming. Such methods are especially efficient for very sparse LP
+problems and allow solving such problems much faster than the simplex
+method.
+
+In brief, the GLPK interior-point solver works as follows.
+
+At first, the solver transforms the original LP to a {\it working} LP
+in the standard format:
+
+\medskip
+
+\noindent
+\hspace{.5in} minimize
+$$z = c_1x_{m+1} + c_2x_{m+2} + \dots + c_nx_{m+n} + c_0 \eqno (2.4)$$
+\hspace{.5in} subject to linear constraints
+$$
+\begin{array}{r@{\:}c@{\:}r@{\:}c@{\:}r@{\:}c@{\:}l}
+a_{11}x_{m+1}&+&a_{12}x_{m+2}&+ \dots +&a_{1n}x_{m+n}&=&b_1 \\
+a_{21}x_{m+1}&+&a_{22}x_{m+2}&+ \dots +&a_{2n}x_{m+n}&=&b_2 \\
+\multicolumn{7}{c}
+{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .} \\
+a_{m1}x_{m+1}&+&a_{m2}x_{m+2}&+ \dots +&a_{mn}x_{m+n}&=&b_m \\
+\end{array} \eqno (2.5)
+$$
+\hspace{.5in} and non-negative variables
+$$x_1\geq 0,\ \ x_2\geq 0,\ \ \dots,\ \ x_n\geq 0 \eqno(2.6)$$
+where: $z$ is the objective function; $x_1$, \dots, $x_n$ are variables;
+$c_1$, \dots, $c_n$ are objective coefficients; $c_0$ is a constant term
+of the objective function; $a_{11}$, \dots, $a_{mn}$ are constraint
+coefficients; $b_1$, \dots, $b_m$ are right-hand sides.
+
+Using vector and matrix notations the working LP (2.4)---(2.6) can be
+written as follows:
+$$z=c^Tx+c_0\ \rightarrow\ \min,\eqno(2.7)$$
+$$Ax=b,\eqno(2.8)$$
+$$x\geq 0,\eqno(2.9)$$
+where: $x=(x_j)$ is $n$-vector of variables, $c=(c_j)$ is $n$-vector of
+objective coefficients, $A=(a_{ij})$ is $m\times n$-matrix of
+constraint coefficients, and $b=(b_i)$ is $m$-vector of right-hand
+sides.
+
+Karush--Kuhn--Tucker optimality conditions for LP (2.7)---(2.9) are the
+following:
+$$Ax=b,\eqno(2.10)$$
+$$A^T\pi+\lambda=c,\eqno(2.11)$$
+$$\lambda^Tx=0,\eqno(2.12)$$
+$$x\geq 0,\ \ \lambda\geq 0,\eqno(2.13)$$
+where:
+$\pi$ is $m$-vector of Lagrange multipliers (dual variables) for
+equality constraints (2.8),\linebreak $\lambda$ is $n$-vector of
+Lagrange multipliers (dual variables) for non-negativity constraints
+(2.9),\linebreak (2.10) is the primal feasibility condition, (2.11) is
+the dual feasibility condition, (2.12) is the primal-dual
+complementarity condition, and (2.13) is the non-negativity conditions.
+
+The main idea of the primal-dual interior-point method is based on
+finding a point in the primal-dual space (i.e. in the space of all
+primal and dual variables $x$, $\pi$, and $\lambda$), which satisfies
+to all optimality conditions (2.10)---(2.13). Obviously, $x$-component
+of such point then provides an optimal solution to the working LP
+(2.7)---(2.9).
+
+To find the optimal point $(x^*,\pi^*,\lambda^*)$ the interior-point
+method attempts to solve the system of equations (2.10)---(2.12), which
+is closed in the sense that the number of variables $x_j$, $\pi_i$, and
+$\lambda_j$ and the number equations are the same and equal to $m+2n$.
+Due to condition (2.12) this system of equations is non-linear, so it
+can be solved with a version of {\it Newton's method} provided with
+additional rules to keep the current point within the positive orthant
+as required by the non-negativity conditions (2.13).
+
+Finally, once the optimal point $(x^*,\pi^*,\lambda^*)$ has been found,
+the solver performs inverse transformations to recover corresponding
+solution to the original LP passed to the solver from the application
+program.
+
+\subsection{glp\_interior --- solve LP problem with the interior-point
+method}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_interior(glp_prob *P, const glp_iptcp *parm);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_interior| is a driver to the LP solver based on
+the primal-dual interior-point method. This routine retrieves problem
+data from the specified problem object, calls the solver to solve the
+problem instance, and stores results of computations back into the
+problem object.
+
+The interior-point solver has a set of control parameters. Values of
+the control parameters can be passed in the structure \verb|glp_iptcp|,
+which the parameter \verb|parm| points to. For detailed description of
+this structure see paragraph ``Control parameters'' below. Before
+specifying some control parameters the application program should
+initialize the structure \verb|glp_iptcp| by default values of all
+control parameters using the routine \verb|glp_init_iptcp| (see the
+next subsection). This is needed for backward compatibility, because in
+the future there may appear new members in the structure
+\verb|glp_iptcp|.
+
+The parameter \verb|parm| can be specified as \verb|NULL|, in which
+case the solver uses default settings.
+
+\returns
+
+\begin{retlist}
+0 & The LP problem instance has been successfully solved. (This code
+does {\it not} necessarily mean that the solver has found optimal
+solution. It only means that the solution process was successful.) \\
+
+\verb|GLP_EFAIL| & The problem has no rows/columns.\\
+
+\verb|GLP_ENOCVG| & Very slow convergence or divergence.\\
+
+\verb|GLP_EITLIM| & Iteration limit exceeded.\\
+
+\verb|GLP_EINSTAB| & Numerical instability on solving Newtonian
+system.\\
+\end{retlist}
+
+\newpage
+
+\para{Comments}
+
+The routine \verb|glp_interior| implements an easy version of
+the primal-dual interior-point method based on Mehrotra's
+technique.\footnote{S. Mehrotra. On the implementation of a primal-dual
+interior point method. SIAM J. on Optim., 2(4), pp. 575-601, 1992.}
+
+Note that currently the GLPK interior-point solver does not include
+many important features, in particular:
+
+%\vspace*{-8pt}
+
+%\begin{itemize}
+\Item{---}it is not able to process dense columns. Thus, if the
+constraint matrix of the LP problem has dense columns, the solving
+process may be inefficient;
+
+\Item{---}it has no features against numerical instability. For some LP
+problems premature termination may happen if the matrix $ADA^T$ becomes
+singular or ill-conditioned;
+
+\Item{---}it is not able to identify the optimal basis, which
+corresponds to the interior-point solution found.
+%\end{itemize}
+
+%\vspace*{-8pt}
+
+\para{Terminal output}
+
+Solving large LP problems may take a long time, so the solver reports
+some information about every interior-point iteration,\footnote{Unlike
+the simplex method the interior point method usually needs 30---50
+iterations (independently on the problem size) in order to find an
+optimal solution.} which is sent to the terminal. This information has
+the following format:
+
+\begin{verbatim}
+nnn: obj = fff; rpi = ppp; rdi = ddd; gap = ggg
+\end{verbatim}
+
+\noindent where: \verb|nnn| is iteration number, \verb|fff| is the
+current value of the objective function (in the case of maximization it
+has wrong sign), \verb|ppp| is the current relative primal
+infeasibility (cf. (2.10)):
+$$\frac{\|Ax^{(k)}-b\|}{1+\|b\|},\eqno(2.14)$$
+\verb|ddd| is the current relative dual infeasibility (cf. (2.11)):
+$$\frac{\|A^T\pi^{(k)}+\lambda^{(k)}-c\|}{1+\|c\|},\eqno(2.15)$$
+\verb|ggg| is the current primal-dual gap (cf. (2.12)):
+$$\frac{|c^Tx^{(k)}-b^T\pi^{(k)}|}{1+|c^Tx^{(k)}|},\eqno(2.16)$$
+and $[x^{(k)},\pi^{(k)},\lambda^{(k)}]$ is the current point on $k$-th
+iteration, $k=0,1,2,\dots$\ . Note that all solution components are
+internally scaled, so information sent to the terminal is suitable only
+for visual inspection.
+
+\newpage
+
+\para{Control parameters}
+
+This paragraph describes all control parameters currently used in the
+interior-point solver. Symbolic names of control parameters are names of
+corresponding members in the structure \verb|glp_iptcp|.
+
+\bigskip
+
+{\tt int msg\_lev} (default: {\tt GLP\_MSG\_ALL})
+
+Message level for terminal output:
+
+\verb|GLP_MSG_OFF|---no output;
+
+\verb|GLP_MSG_ERR|---error and warning messages only;
+
+\verb|GLP_MSG_ON |---normal output;
+
+\verb|GLP_MSG_ALL|---full output (including informational messages).
+
+\bigskip
+
+{\tt int ord\_alg} (default: {\tt GLP\_ORD\_AMD})
+
+Ordering algorithm used prior to Cholesky factorization:
+
+\verb|GLP_ORD_NONE |---use natural (original) ordering;
+
+\verb|GLP_ORD_QMD |---quotient minimum degree (QMD);
+
+\verb|GLP_ORD_AMD |---approximate minimum degree (AMD);
+
+\verb|GLP_ORD_SYMAMD|---approximate minimum degree (SYMAMD).
+
+\bigskip
+
+\para{Example}
+
+The following main program reads LP problem instance in fixed MPS
+format from file\linebreak \verb|25fv47.mps|,\footnote{This instance in
+fixed MPS format can be found in the Netlib LP collection; see
+{\tt ftp://ftp.netlib.org/lp/data/}.} solves it with the interior-point
+solver, and writes the solution to file \verb|25fv47.txt|.
+
+\begin{footnotesize}
+\begin{verbatim}
+/* iptsamp.c */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+int main(void)
+{ glp_prob *P;
+ P = glp_create_prob();
+ glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps");
+ glp_interior(P, NULL);
+ glp_print_ipt(P, "25fv47.txt");
+ glp_delete_prob(P);
+ return 0;
+}
+
+/* eof */
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+Below here is shown the terminal output from this example program.
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading problem data from `25fv47.mps'...
+Problem: 25FV47
+Objective: R0000
+822 rows, 1571 columns, 11127 non-zeros
+6919 records were read
+Original LP has 822 row(s), 1571 column(s), and 11127 non-zero(s)
+Working LP has 821 row(s), 1876 column(s), and 10705 non-zero(s)
+Matrix A has 10705 non-zeros
+Matrix S = A*A' has 11895 non-zeros (upper triangle)
+Minimal degree ordering...
+Computing Cholesky factorization S = L'*L...
+Matrix L has 35411 non-zeros
+Guessing initial point...
+Optimization begins...
+ 0: obj = 1.823377629e+05; rpi = 1.3e+01; rdi = 1.4e+01; gap = 9.3e-01
+ 1: obj = 9.260045192e+04; rpi = 5.3e+00; rdi = 5.6e+00; gap = 6.8e+00
+ 2: obj = 3.596999742e+04; rpi = 1.5e+00; rdi = 1.2e+00; gap = 1.8e+01
+ 3: obj = 1.989627568e+04; rpi = 4.7e-01; rdi = 3.0e-01; gap = 1.9e+01
+ 4: obj = 1.430215557e+04; rpi = 1.1e-01; rdi = 8.6e-02; gap = 1.4e+01
+ 5: obj = 1.155716505e+04; rpi = 2.3e-02; rdi = 2.4e-02; gap = 6.8e+00
+ 6: obj = 9.660273208e+03; rpi = 6.7e-03; rdi = 4.6e-03; gap = 3.9e+00
+ 7: obj = 8.694348283e+03; rpi = 3.7e-03; rdi = 1.7e-03; gap = 2.0e+00
+ 8: obj = 8.019543639e+03; rpi = 2.4e-03; rdi = 3.9e-04; gap = 1.0e+00
+ 9: obj = 7.122676293e+03; rpi = 1.2e-03; rdi = 1.5e-04; gap = 6.6e-01
+ 10: obj = 6.514534518e+03; rpi = 6.1e-04; rdi = 4.3e-05; gap = 4.1e-01
+ 11: obj = 6.361572203e+03; rpi = 4.8e-04; rdi = 2.2e-05; gap = 3.0e-01
+ 12: obj = 6.203355508e+03; rpi = 3.2e-04; rdi = 1.7e-05; gap = 2.6e-01
+ 13: obj = 6.032943411e+03; rpi = 2.0e-04; rdi = 9.3e-06; gap = 2.1e-01
+ 14: obj = 5.796553021e+03; rpi = 9.8e-05; rdi = 3.2e-06; gap = 1.0e-01
+ 15: obj = 5.667032431e+03; rpi = 4.4e-05; rdi = 1.1e-06; gap = 5.6e-02
+ 16: obj = 5.613911867e+03; rpi = 2.5e-05; rdi = 4.1e-07; gap = 3.5e-02
+ 17: obj = 5.560572626e+03; rpi = 9.9e-06; rdi = 2.3e-07; gap = 2.1e-02
+ 18: obj = 5.537276001e+03; rpi = 5.5e-06; rdi = 8.4e-08; gap = 1.1e-02
+ 19: obj = 5.522746942e+03; rpi = 2.2e-06; rdi = 4.0e-08; gap = 6.7e-03
+ 20: obj = 5.509956679e+03; rpi = 7.5e-07; rdi = 1.8e-08; gap = 2.9e-03
+ 21: obj = 5.504571733e+03; rpi = 1.6e-07; rdi = 5.8e-09; gap = 1.1e-03
+ 22: obj = 5.502576367e+03; rpi = 3.4e-08; rdi = 1.0e-09; gap = 2.5e-04
+ 23: obj = 5.502057119e+03; rpi = 8.1e-09; rdi = 3.0e-10; gap = 7.7e-05
+ 24: obj = 5.501885996e+03; rpi = 9.4e-10; rdi = 1.2e-10; gap = 2.4e-05
+ 25: obj = 5.501852464e+03; rpi = 1.4e-10; rdi = 1.2e-11; gap = 3.0e-06
+ 26: obj = 5.501846549e+03; rpi = 1.4e-11; rdi = 1.2e-12; gap = 3.0e-07
+ 27: obj = 5.501845954e+03; rpi = 1.4e-12; rdi = 1.2e-13; gap = 3.0e-08
+ 28: obj = 5.501845895e+03; rpi = 1.5e-13; rdi = 1.2e-14; gap = 3.0e-09
+OPTIMAL SOLUTION FOUND
+Writing interior-point solution to `25fv47.txt'...
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+\subsection{glp\_init\_iptcp --- initialize interior-point solver
+control parameters}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_init_iptcp(glp_iptcp *parm);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_init_iptcp| initializes control parameters, which
+are used by the interior-point solver, with default values.
+
+Default values of the control parameters are stored in the structure
+\verb|glp_iptcp|, which the parameter \verb|parm| points to.
+
+\subsection{glp\_ipt\_status --- determine solution status}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_ipt_status(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_ipt_status| reports the status of a solution
+found by the interior-point solver as follows:
+
+\verb|GLP_UNDEF | --- interior-point solution is undefined;
+
+\verb|GLP_OPT | --- interior-point solution is optimal;
+
+\verb|GLP_INFEAS| --- interior-point solution is infeasible;
+
+\verb|GLP_NOFEAS| --- no feasible primal-dual solution exists.
+
+\subsection{glp\_ipt\_obj\_val --- retrieve objective value}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_ipt_obj_val(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_ipt_obj_val| returns value of the objective
+function for interior-point solution.
+
+\subsection{glp\_ipt\_row\_prim --- retrieve row primal value}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_ipt_row_prim(glp_prob *P, int i);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_ipt_row_prim| returns primal value of the
+auxiliary variable associated with \verb|i|-th row.
+
+\newpage
+
+\subsection{glp\_ipt\_row\_dual --- retrieve row dual value}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_ipt_row_dual(glp_prob *P, int i);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_ipt_row_dual| returns dual value (i.e. reduced
+cost) of the auxiliary variable associated with \verb|i|-th row.
+
+\subsection{glp\_ipt\_col\_prim --- retrieve column primal value}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_ipt_col_prim(glp_prob *P, int j);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_ipt_col_prim| returns primal value of the
+structural variable associated with \verb|j|-th column.
+
+\subsection{glp\_ipt\_col\_dual --- retrieve column dual value}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_ipt_col_dual(glp_prob *P, int j);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_ipt_col_dual| returns dual value (i.e. reduced
+cost) of the structural variable associated with \verb|j|-th column.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Mixed integer programming routines}
+
+\subsection{glp\_set\_col\_kind --- set (change) column kind}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_col_kind(glp_prob *P, int j, int kind);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_col_kind| sets (changes) the kind of
+\verb|j|-th column (structural variable) as specified by the parameter
+\verb|kind|:
+
+\verb|GLP_CV| --- continuous variable;
+
+\verb|GLP_IV| --- integer variable;
+
+\verb|GLP_BV| --- binary variable.
+
+Setting a column to \verb|GLP_BV| has the same effect as if it were
+set to \verb|GLP_IV|, its lower bound were set 0, and its upper bound
+were set to 1.
+
+\subsection{glp\_get\_col\_kind --- retrieve column kind}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_col_kind(glp_prob *P, int j);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_col_kind| returns the kind of \verb|j|-th
+column (structural variable) as follows:
+
+\verb|GLP_CV| --- continuous variable;
+
+\verb|GLP_IV| --- integer variable;
+
+\verb|GLP_BV| --- binary variable.
+
+\subsection{glp\_get\_num\_int --- retrieve number of integer columns}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_num_int(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_num_int| returns the number of columns
+(structural variables), which are marked as integer. Note that this
+number {\it does} include binary columns.
+
+\newpage
+
+\subsection{glp\_get\_num\_bin --- retrieve number of binary columns}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_num_bin(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_num_bin| returns the number of columns
+(structural variables), which are marked as integer and whose lower
+bound is zero and upper bound is one.
+
+\subsection{glp\_intopt --- solve MIP problem with the branch-and-cut
+method}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_intopt(glp_prob *P, const glp_iocp *parm);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_intopt| is a driver to the MIP solver based on
+the branch-and-cut method, which is a hybrid of branch-and-bound and
+cutting plane methods.
+
+If the presolver is disabled (see paragraph ``Control parameters''
+below), on entry to the routine \verb|glp_intopt| the problem object,
+which the parameter \verb|mip| points to, should contain optimal
+solution to LP relaxation (it can be obtained, for example, with the
+routine \verb|glp_simplex|). Otherwise, if the presolver is enabled, it
+is not necessary.
+
+The MIP solver has a set of control parameters. Values of the control
+parameters can be passed in the structure \verb|glp_iocp|, which the
+parameter \verb|parm| points to. For detailed description of this
+structure see paragraph ``Control parameters'' below. Before specifying
+some control parameters the application program should initialize the
+structure \verb|glp_iocp| by default values of all control parameters
+using the routine \verb|glp_init_iocp| (see the next subsection). This
+is needed for backward compatibility, because in the future there may
+appear new members in the structure \verb|glp_iocp|.
+
+The parameter \verb|parm| can be specified as \verb|NULL|, in which case
+the solver uses default settings.
+
+Note that the GLPK branch-and-cut solver is not perfect, so it is
+unable to solve hard or very large scale MIP instances for a reasonable
+time.
+
+\returns
+
+\begin{retlist}
+0 & The MIP problem instance has been successfully solved. (This code
+does {\it not} necessarily mean that the solver has found optimal
+solution. It only means that the solution process was successful.) \\
+
+\verb|GLP_EBOUND| & Unable to start the search, because some
+double-bounded variables have incorrect bounds or some integer
+variables have non-integer (fractional) bounds.\\
+
+\verb|GLP_EROOT| & Unable to start the search, because optimal basis
+for initial LP relaxation is not provided. (This code may appear only
+if the presolver is disabled.)\\
+
+\verb|GLP_ENOPFS| & Unable to start the search, because LP relaxation
+of the MIP problem instance has no primal feasible solution. (This code
+may appear only if the presolver is enabled.)\\
+\end{retlist}
+
+\newpage
+
+\begin{retlist}
+\verb|GLP_ENODFS| & Unable to start the search, because LP relaxation
+of the MIP problem instance has no dual feasible solution. In other
+word, this code means that if the LP relaxation has at least one primal
+feasible solution, its optimal solution is unbounded, so if the MIP
+problem has at least one integer feasible solution, its (integer)
+optimal solution is also unbounded. (This code may appear only if the
+presolver is enabled.)\\
+
+\verb|GLP_EFAIL| & The search was prematurely terminated due to the
+solver failure.\\
+
+\verb|GLP_EMIPGAP| & The search was prematurely terminated, because the
+relative mip gap tolerance has been reached.\\
+
+\verb|GLP_ETMLIM| & The search was prematurely terminated, because the
+time limit has been exceeded.\\
+
+\verb|GLP_ESTOP| & The search was prematurely terminated by application.
+(This code may appear only if the advanced solver interface is used.)\\
+\end{retlist}
+
+\para{Built-in MIP presolver}
+
+The branch-and-cut solver has {\it built-in MIP presolver}. It is
+a subprogram that transforms the original MIP problem specified in the
+problem object to an equivalent MIP problem, which may be easier for
+solving with the branch-and-cut method than the original one. For
+example, the presolver can remove redundant constraints and variables,
+whose optimal values are known, perform bound and coefficient reduction,
+etc. Once the transformed MIP problem has been solved, the presolver
+transforms its solution back to corresponding solution of the original
+problem.
+
+Presolving is an optional feature of the routine \verb|glp_intopt|, and
+by default it is disabled. In order to enable the MIP presolver, the
+control parameter \verb|presolve| should be set to \verb|GLP_ON| (see
+paragraph ``Control parameters'' below).
+
+\para{Advanced solver interface}
+
+The routine \verb|glp_intopt| allows the user to control the
+branch-and-cut search by passing to the solver a user-defined callback
+routine. For more details see Chapter ``Branch-and-Cut API Routines''.
+
+\para{Terminal output}
+
+Solving a MIP problem may take a long time, so the solver reports some
+information about best known solutions, which is sent to the terminal.
+This information has the following format:
+
+\begin{verbatim}
++nnn: mip = xxx <rho> yyy gap (ppp; qqq)
+\end{verbatim}
+
+\noindent
+where: `\verb|nnn|' is the simplex iteration number; `\verb|xxx|' is a
+value of the objective function for the best known integer feasible
+solution (if no integer feasible solution has been found yet,
+`\verb|xxx|' is the text `\verb|not found yet|'); `\verb|rho|' is the
+string `\verb|>=|' (in case of minimization) or `\verb|<=|' (in case of
+maximization); `\verb|yyy|' is a global bound for exact integer optimum
+(i.e. the exact integer optimum is always in the range from `\verb|xxx|'
+to `\verb|yyy|'); `\verb|gap|' is the relative mip gap, in percents,
+computed as $gap=|xxx-yyy|/(|xxx|+{\tt DBL\_EPSILON})\cdot 100\%$ (if
+$gap$ is greater than $999.9\%$, it is not printed); `\verb|ppp|' is the
+number of subproblems in the active list, `\verb|qqq|' is the number of
+subproblems which have been already fathomed and therefore removed from
+the branch-and-bound search tree.
+
+\newpage
+
+\subsubsection{Control parameters}
+
+This paragraph describes all control parameters currently used in the
+MIP solver. Symbolic names of control parameters are names of
+corresponding members in the structure \verb|glp_iocp|.
+
+\bigskip\vspace*{-2pt}
+
+{\tt int msg\_lev} (default: {\tt GLP\_MSG\_ALL})
+
+Message level for terminal output:
+
+\verb|GLP_MSG_OFF| --- no output;
+
+\verb|GLP_MSG_ERR| --- error and warning messages only;
+
+\verb|GLP_MSG_ON | --- normal output;
+
+\verb|GLP_MSG_ALL| --- full output (including informational messages).
+
+\bigskip\vspace*{-2pt}
+
+{\tt int br\_tech} (default: {\tt GLP\_BR\_DTH})
+
+Branching technique option:
+
+\verb|GLP_BR_FFV| --- first fractional variable;
+
+\verb|GLP_BR_LFV| --- last fractional variable;
+
+\verb|GLP_BR_MFV| --- most fractional variable;
+
+\verb|GLP_BR_DTH| --- heuristic by Driebeck and Tomlin;
+
+\verb|GLP_BR_PCH| --- hybrid pseudo-cost heuristic.
+
+\bigskip\vspace*{-2pt}
+
+{\tt int bt\_tech} (default: {\tt GLP\_BT\_BLB})
+
+Backtracking technique option:
+
+\verb|GLP_BT_DFS| --- depth first search;
+
+\verb|GLP_BT_BFS| --- breadth first search;
+
+\verb|GLP_BT_BLB| --- best local bound;
+
+\verb|GLP_BT_BPH| --- best projection heuristic.
+
+\bigskip\vspace*{-2pt}
+
+{\tt int pp\_tech} (default: {\tt GLP\_PP\_ALL})
+
+Preprocessing technique option:
+
+\verb|GLP_PP_NONE| --- disable preprocessing;
+
+\verb|GLP_PP_ROOT| --- perform preprocessing only on the root level;
+
+\verb|GLP_PP_ALL | --- perform preprocessing on all levels.
+
+\bigskip\vspace*{-2pt}
+
+{\tt int sr\_heur} (default: {\tt GLP\_ON})
+
+Simple rounding heuristic option:
+
+\verb|GLP_ON | --- enable applying the simple rounding heuristic;
+
+\verb|GLP_OFF| --- disable applying the simple rounding heuristic.
+
+\newpage
+
+{\tt int fp\_heur} (default: {\tt GLP\_OFF})
+
+Feasibility pump heuristic option:
+
+\verb|GLP_ON | --- enable applying the feasibility pump heuristic;
+
+\verb|GLP_OFF| --- disable applying the feasibility pump heuristic.
+
+\bigskip
+
+{\tt int ps\_heur} (default: {\tt GLP\_OFF})
+
+Proximity search heuristic\footnote{The Fischetti--Monaci Proximity
+Search (a.k.a. Proxy) heuristic. This algorithm is often capable of
+rapidly improving a feasible solution of a MIP problem with binary
+variables. It allows to quickly obtain suboptimal solutions in some
+problems which take too long time to be solved to optimality.} option:
+
+\verb|GLP_ON | --- enable applying the proximity search heuristic;
+
+\verb|GLP_OFF| --- disable applying the proximity search pump heuristic.
+
+\bigskip
+
+{\tt int ps\_tm\_lim} (default: {\tt 60000})
+
+Time limit, in milliseconds, for the proximity search heuristic (see
+above).
+
+\bigskip
+
+{\tt int gmi\_cuts} (default: {\tt GLP\_OFF})
+
+Gomory's mixed integer cut option:
+
+\verb|GLP_ON | --- enable generating Gomory's cuts;
+
+\verb|GLP_OFF| --- disable generating Gomory's cuts.
+
+\bigskip
+
+{\tt int mir\_cuts} (default: {\tt GLP\_OFF})
+
+Mixed integer rounding (MIR) cut option:
+
+\verb|GLP_ON | --- enable generating MIR cuts;
+
+\verb|GLP_OFF| --- disable generating MIR cuts.
+
+\bigskip
+
+{\tt int cov\_cuts} (default: {\tt GLP\_OFF})
+
+Mixed cover cut option:
+
+\verb|GLP_ON | --- enable generating mixed cover cuts;
+
+\verb|GLP_OFF| --- disable generating mixed cover cuts.
+
+\bigskip
+
+{\tt int clq\_cuts} (default: {\tt GLP\_OFF})
+
+Clique cut option:
+
+\verb|GLP_ON | --- enable generating clique cuts;
+
+\verb|GLP_OFF| --- disable generating clique cuts.
+
+\newpage
+
+{\tt double tol\_int} (default: {\tt 1e-5})
+
+Absolute tolerance used to check if optimal solution to the current LP
+relaxation is integer feasible. (Do not change this parameter without
+detailed understanding its purpose.)
+
+\bigskip
+
+{\tt double tol\_obj} (default: {\tt 1e-7})
+
+Relative tolerance used to check if the objective value in optimal
+solution to the current LP relaxation is not better than in the best
+known integer feasible solution. (Do not change this parameter without
+detailed understanding its purpose.)
+
+\bigskip
+
+{\tt double mip\_gap} (default: {\tt 0.0})
+
+The relative mip gap tolerance. If the relative mip gap for currently
+known best integer feasible solution falls below this tolerance, the
+solver terminates the search. This allows obtainig suboptimal integer
+feasible solutions if solving the problem to optimality takes too long
+time.
+
+\bigskip
+
+{\tt int tm\_lim} (default: {\tt INT\_MAX})
+
+Searching time limit, in milliseconds.
+
+\bigskip
+
+{\tt int out\_frq} (default: {\tt 5000})
+
+Output frequency, in milliseconds. This parameter specifies how
+frequently the solver sends information about the solution process to
+the terminal.
+
+\bigskip
+
+{\tt int out\_dly} (default: {\tt 10000})
+
+Output delay, in milliseconds. This parameter specifies how long the
+solver should delay sending information about solution of the current
+LP relaxation with the simplex method to the terminal.
+
+\bigskip
+
+{\tt void (*cb\_func)(glp\_tree *tree, void *info)}
+(default: {\tt NULL})
+
+Entry point to the user-defined callback routine. \verb|NULL| means
+the advanced solver interface is not used. For more details see Chapter
+``Branch-and-Cut API Routines''.
+
+\bigskip
+
+{\tt void *cb\_info} (default: {\tt NULL})
+
+Transit pointer passed to the routine \verb|cb_func| (see above).
+
+\bigskip
+
+{\tt int cb\_size} (default: {\tt 0})
+
+The number of extra (up to 256) bytes allocated for each node of the
+branch-and-bound tree to store application-specific data. On creating
+a node these bytes are initialized by binary zeros.
+
+\bigskip
+
+{\tt int presolve} (default: {\tt GLP\_OFF})
+
+MIP presolver option:
+
+\verb|GLP_ON | --- enable using the MIP presolver;
+
+\verb|GLP_OFF| --- disable using the MIP presolver.
+
+\newpage
+
+{\tt int binarize} (default: {\tt GLP\_OFF})
+
+Binarization option (used only if the presolver is enabled):
+
+\verb|GLP_ON | --- replace general integer variables by binary ones;
+
+\verb|GLP_OFF| --- do not use binarization.
+
+\subsection{glp\_init\_iocp --- initialize integer optimizer control
+parameters}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_init_iocp(glp_iocp *parm);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_init_iocp| initializes control parameters, which
+are used by the branch-and-cut solver, with default values.
+
+Default values of the control parameters are stored in
+a \verb|glp_iocp| structure, which the parameter \verb|parm| points to.
+
+\subsection{glp\_mip\_status --- determine status of MIP solution}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_mip_status(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_mip_status| reports the status of a MIP solution
+found by the MIP solver as follows:
+
+\verb|GLP_UNDEF | --- MIP solution is undefined;
+
+\verb|GLP_OPT | --- MIP solution is integer optimal;
+
+\verb|GLP_FEAS | --- MIP solution is integer feasible, however, its
+optimality (or non-optimality) has not been proven, perhaps due to
+premature termination of the search;
+
+\verb|GLP_NOFEAS| --- problem has no integer feasible solution (proven
+by the solver).
+
+\subsection{glp\_mip\_obj\_val --- retrieve objective value}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_mip_obj_val(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_mip_obj_val| returns value of the objective
+function for MIP solution.
+
+\newpage
+
+\subsection{glp\_mip\_row\_val --- retrieve row value}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_mip_row_val(glp_prob *P, int i);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_mip_row_val| returns value of the auxiliary
+variable associated with \verb|i|-th row for MIP solution.
+
+\subsection{glp\_mip\_col\_val --- retrieve column value}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_mip_col_val(glp_prob *P, int j);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_mip_col_val| returns value of the structural
+variable associated with \verb|j|-th column for MIP solution.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Additional routines}
+
+\subsection{glp\_check\_kkt --- check feasibility/optimality
+conditions}
+
+\synopsis
+
+{\parskip=0pt
+\tt void glp\_check\_kkt(glp\_prob *P, int sol, int cond,
+double *ae\_max, int *ae\_ind,
+
+\hspace{105pt}double *re\_max, int *re\_ind);}
+
+\description
+
+The routine \verb|glp_check_kkt| allows to check
+feasibility/optimality conditions for the current solution stored in
+the specified problem object. (For basic and interior-point solutions
+these conditions are known as {\it Karush--Kuhn--Tucker optimality
+conditions}.)
+
+The parameter \verb|sol| specifies which solution should be checked:
+
+\verb|GLP_SOL| --- basic solution;
+
+\verb|GLP_IPT| --- interior-point solution;
+
+\verb|GLP_MIP| --- mixed integer solution.
+
+The parameter \verb|cond| specifies which condition should be checked:
+
+\verb|GLP_KKT_PE| --- check primal equality constraints (KKT.PE);
+
+\verb|GLP_KKT_PB| --- check primal bound constraints (KKT.PB);
+
+\verb|GLP_KKT_DE| --- check dual equality constraints (KKT.DE). This
+conditions can be checked only for basic or interior-point solution;
+
+\verb|GLP_KKT_DB| --- check dual bound constraints (KKT.DB). This
+conditions can be checked only for basic or interior-point solution.
+
+Detailed explanations of these conditions are given below in paragraph
+``Background''.
+
+On exit the routine stores the following information to locations
+specified by parameters \verb|ae_max|, \verb|ae_ind|, \verb|re_max|,
+and \verb|re_ind| (if some parameter is a null pointer, corresponding
+information is not stored):
+
+\verb|ae_max| --- largest absolute error;
+
+\verb|ae_ind| --- number of row (KKT.PE), column (KKT.DE), or variable
+(KKT.PB, KKT.DB) with the largest absolute error;
+
+\verb|re_max| --- largest relative error;
+
+\verb|re_ind| --- number of row (KKT.PE), column (KKT.DE), or variable
+(KKT.PB, KKT.DB) with the largest relative error.
+
+Row (auxiliary variable) numbers are in the range 1 to $m$, where $m$
+is the number of rows in the problem object. Column (structural
+variable) numbers are in the range 1 to $n$, where $n$ is the number
+of columns in the problem object. Variable numbers are in the range
+1 to $m+n$, where variables with numbers 1 to $m$ correspond to rows,
+and variables with numbers $m+1$ to $m+n$ correspond to columns. If
+the error reported is exact zero, corresponding row, column or variable
+number is set to zero.
+
+\newpage
+
+\para{Background}
+
+\def\arraystretch{1.5}
+
+The first condition checked by the routine is the following:
+$$x_R - A x_S = 0, \eqno{\rm (KKT.PE)}$$
+where $x_R$ is the subvector of auxiliary variables (rows), $x_S$ is
+the subvector of structural variables (columns), $A$ is the constraint
+matrix. This condition expresses the requirement that all primal
+variables should satisfy to the system of equality constraints of the
+original LP problem. In case of exact arithmetic this condition would
+be satisfied for any basic solution; however, in case of inexact
+(floating-point) arithmetic, this condition shows how accurate the
+primal solution is, that depends on accuracy of a representation of the
+basis matrix used by the simplex method, or on accuracy provided by the
+interior-point method.
+
+To check the condition (KKT.PE) the routine computes the vector of
+residuals:
+$$g = x_R - A x_S,$$
+and determines component of this vector that correspond to largest
+absolute and relative errors:
+$${\tt ae\_max}=\max_{1\leq i\leq m}|g_i|,$$
+$${\tt re\_max}=\max_{1\leq i\leq m}\frac{|g_i|}{1+|(x_R)_i|}.$$
+
+The second condition checked by the routine is the following:
+$$l_k \leq x_k \leq u_k {\rm \ \ \ for\ all}\ k=1,\dots,m+n,
+\eqno{\rm (KKT.PB)}$$
+where $x_k$ is auxiliary ($1\leq k\leq m$) or structural
+($m+1\leq k\leq m+n$) variable, $l_k$ and $u_k$ are, respectively,
+lower and upper bounds of the variable $x_k$ (including cases of
+infinite bounds). This condition expresses the requirement that all
+primal variables shoudl satisfy to bound constraints of the original
+LP problem. In case of basic solution all non-basic variables are
+placed on their active bounds, so actually the condition (KKT.PB) needs
+to be checked for basic variables only. If the primal solution has
+sufficient accuracy, this condition shows its primal feasibility.
+
+To check the condition (KKT.PB) the routine computes a vector of
+residuals:
+$$
+h_k = \left\{
+\begin{array}{ll}
+0, & {\rm if}\ l_k \leq x_k \leq u_k \\
+x_k - l_k, & {\rm if}\ x_k < l_k \\
+x_k - u_k, & {\rm if}\ x_k > u_k \\
+\end{array}
+\right.
+$$
+for all $k=1,\dots,m+n$, and determines components of this vector that
+correspond to largest absolute and relative errors:
+$${\tt ae\_max}=\max_{1\leq k \leq m+n}|h_k|,$$
+$${\tt re\_max}=\max_{1\leq k \leq m+n}\frac{|h_k|}{1+|x_k|}.$$
+
+\newpage
+
+The third condition checked by the routine is:
+$${\rm grad}\;Z = c = (\tilde{A})^T \pi + d,$$
+where $Z$ is the objective function, $c$ is the vector of objective
+coefficients, $(\tilde{A})^T$ is a matrix transposed to the expanded
+constraint matrix $\tilde{A} = (I|-A)$, $\pi$ is a vector of Lagrange
+multipliers that correspond to equality constraints of the original LP
+problem, $d$ is a vector of Lagrange multipliers that correspond to
+bound constraints for all (auxiliary and structural) variables of the
+original LP problem. Geometrically the third condition expresses the
+requirement that the gradient of the objective function should belong
+to the orthogonal complement of a linear subspace defined by the
+equality and active bound constraints, i.e. that the gradient is
+a linear combination of normals to the constraint hyperplanes, where
+Lagrange multipliers $\pi$ and $d$ are coefficients of that linear
+combination.
+
+To eliminate the vector $\pi$ rewrite the third condition as:
+$$
+\left(\begin{array}{@{}c@{}}I \\ -A^T\end{array}\right) \pi =
+\left(\begin{array}{@{}c@{}}d_R \\ d_S\end{array}\right) +
+\left(\begin{array}{@{}c@{}}c_R \\ c_S\end{array}\right),
+$$
+or, equivalently,
+$$
+\left\{
+\begin{array}{r@{}c@{}c}
+\pi + d_R&\ =\ &c_R, \\
+-A^T\pi + d_S&\ =\ &c_S. \\
+\end{array}
+\right.
+$$
+
+Then substituting the vector $\pi$ from the first equation into the
+second we finally have:
+$$A^T (d_R - c_R) + (d_S - c_S) = 0, \eqno{\rm(KKT.DE)}$$
+where $d_R$ is the subvector of reduced costs of auxiliary variables
+(rows), $d_S$ is the subvector of reduced costs of structural variables
+(columns), $c_R$ and $c_S$ are subvectors of objective coefficients at,
+respectively, auxiliary and structural variables, $A^T$ is a matrix
+transposed to the constraint matrix of the original LP problem. In case
+of exact arithmetic this condition would be satisfied for any basic
+solution; however, in case of inexact (floating-point) arithmetic, this
+condition shows how accurate the dual solution is, that depends on
+accuracy of a representation of the basis matrix used by the simplex
+method, or on accuracy provided by the interior-point method.
+
+To check the condition (KKT.DE) the routine computes a vector of
+residuals:
+$$u = A^T (d_R - c_R) + (d_S - c_S),$$
+and determines components of this vector that correspond to largest
+absolute and relative errors:
+$${\tt ae\_max}=\max_{1\leq j\leq n}|u_j|,$$
+$${\tt re\_max}=\max_{1\leq j\leq n}\frac{|u_j|}{1+|(d_S)_j-(c_S)_j|}.$$
+
+\newpage
+
+The fourth condition checked by the routine is the following:
+$$
+\left\{
+\begin{array}{l@{\ }r@{\ }c@{\ }c@{\ }c@{\ }l@{\ }c@{\ }c@{\ }c@{\ }l}
+{\rm if} & -\infty & < & x_k & < & +\infty,
+& {\rm then} & d_k & = & 0 \\
+{\rm if} & l_k & \leq & x_k & < & +\infty,
+& {\rm then} & d_k & \geq & 0\ {\rm(minimization)} \\
+&&&&&& & d_k & \leq & 0\ {\rm(maximization)} \\
+{\rm if} & -\infty & < & x_k & \leq & u_k,
+& {\rm then} & d_k & \leq & 0\ {\rm(minimization)} \\
+&&&&&& & d_k & \geq & 0\ {\rm(maximization)} \\
+{\rm if} & l_k & \leq & x_k & \leq & u_k,
+& {\rm then} & d_k & {\rm is} & {\rm of\ any\ sign} \\
+\end{array}\right.\eqno{\rm(KKT.DB)}
+$$
+for all $k=1,\dots,m+n$, where $d_k$ is a reduced cost (Lagrange
+multiplier) of auxiliary ($1\leq k\leq m$) or structural
+($m+1\leq k\leq m+n$) variable $x_k$. Geometrically this condition
+expresses the requirement that constraints of the original problem must
+``hold'' the point preventing its movement along the anti-gradient (in
+case of minimization) or the gradient (in case of maximization) of the
+objective function. In case of basic solution reduced costs of all
+basic variables are placed on their active (zero) bounds, so actually
+the condition (KKT.DB) needs to be checked for non-basic variables
+only. If the dual solution has sufficient accuracy, this condition
+shows the dual feasibility of the solution.
+
+To check the condition (KKT.DB) the routine computes a vector of
+residuals:
+$$
+v_k = \left\{
+\begin{array}{ll}
+0, & {\rm if}\ d_k\ {\rm has\ correct\ sign} \\
+|d_k|, & {\rm if}\ d_k\ {\rm has\ wrong\ sign} \\
+\end{array}
+\right.
+$$
+for all $k=1,\dots,m+n$, and determines components of this vector that
+correspond to largest absolute and relative errors:
+$${\tt ae\_max}=\max_{1\leq k\leq m+n}|v_k|,$$
+$${\tt re\_max}=\max_{1\leq k\leq m+n}\frac{|v_k|}{1+|d_k - c_k|}.$$
+
+Note that the complete set of Karush-Kuhn-Tucker optimality conditions
+also includes the fifth, so called {\it complementary slackness
+condition}, which expresses the requirement that at least either
+a primal variable $x_k$ or its dual counterpart $d_k$ should be on its
+bound for all $k=1,\dots,m+n$. Currently checking this condition is
+not implemented yet.
+
+\def\arraystretch{1}
+
+%* eof *%
diff --git a/glpk-5.0/doc/glpk03.tex b/glpk-5.0/doc/glpk03.tex
new file mode 100644
index 0000000..6086c54
--- /dev/null
+++ b/glpk-5.0/doc/glpk03.tex
@@ -0,0 +1,1936 @@
+%* glpk03.tex *%
+
+\chapter{Utility API routines}
+
+\section{Problem data reading/writing routines}
+
+\subsection{glp\_read\_mps --- read problem data in MPS format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_read_mps(glp_prob *P, int fmt, const glp_mpscp *parm,
+ const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_read_mps| reads problem data in MPS format from a
+text file. (The MPS format is described in Appendix \ref{champs}, page
+\pageref{champs}.)
+
+The parameter \verb|fmt| specifies the MPS format version as follows:
+
+\verb|GLP_MPS_DECK| --- fixed (ancient) MPS format;
+
+\verb|GLP_MPS_FILE| --- free (modern) MPS format.
+
+The parameter \verb|parm| is reserved for use in the future and should
+be specified as \verb|NULL|.
+
+The character string \verb|fname| specifies a name of the text file to
+be read in. (If the file name ends with suffix `\verb|.gz|', the file
+is assumed to be compressed, in which case the routine
+\verb|glp_read_mps| decompresses it ``on the fly''.)
+
+Note that before reading data the current content of the problem object
+is completely erased with the routine \verb|glp_erase_prob|.
+
+\returns
+
+If the operation was successful, the routine \verb|glp_read_mps|
+returns zero. Otherwise, it prints an error message and returns
+non-zero.
+
+\newpage
+
+\subsection{glp\_write\_mps --- write problem data in MPS format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_write_mps(glp_prob *P, int fmt, const glp_mpscp *parm,
+ const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_write_mps| writes problem data in MPS format to
+a text file. (The MPS format is described in Appendix \ref{champs},
+page \pageref{champs}.)
+
+The parameter \verb|fmt| specifies the MPS format version as follows:
+
+\verb|GLP_MPS_DECK| --- fixed (ancient) MPS format;
+
+\verb|GLP_MPS_FILE| --- free (modern) MPS format.
+
+The parameter \verb|parm| is reserved for use in the future and should
+be specified as \verb|NULL|.
+
+The character string \verb|fname| specifies a name of the text file to
+be written out. (If the file name ends with suffix `\verb|.gz|', the
+file is assumed to be compressed, in which case the routine
+\verb|glp_write_mps| performs automatic compression on writing it.)
+
+\returns
+
+If the operation was successful, the routine \verb|glp_write_mps|
+returns zero. Otherwise, it prints an error message and returns
+non-zero.
+
+\subsection{glp\_read\_lp --- read problem data in CPLEX LP format}
+
+\synopsis
+
+{\tt int glp\_read\_lp(glp\_prob *P, const glp\_cpxcp *parm,
+const char *fname);}
+
+\description
+
+The routine \verb|glp_read_lp| reads problem data in CPLEX LP format
+from a text file. (The CPLEX LP format is described in Appendix
+\ref{chacplex}, page \pageref{chacplex}.)
+
+The parameter \verb|parm| is reserved for use in the future and should
+be specified as \verb|NULL|.
+
+The character string \verb|fname| specifies a name of the text file to
+be read in. (If the file name ends with suffix `\verb|.gz|', the file
+is assumed to be compressed, in which case the routine
+\verb|glp_read_lp| decompresses it ``on the fly''.)
+
+Note that before reading data the current content of the problem object
+is completely erased with the routine \verb|glp_erase_prob|.
+
+\returns
+
+If the operation was successful, the routine \verb|glp_read_lp| returns
+zero. Otherwise, it prints an error message and returns non-zero.
+
+\newpage
+
+\subsection{glp\_write\_lp --- write problem data in CPLEX LP format}
+
+\synopsis
+
+{\tt int glp\_write\_lp(glp\_prob *P, const glp\_cpxcp *parm,
+const char *fname);}
+
+\description
+
+The routine \verb|glp_write_lp| writes problem data in CPLEX LP format
+to a text file. (The CPLEX LP format is described in Appendix
+\ref{chacplex}, page \pageref{chacplex}.)
+
+The parameter \verb|parm| is reserved for use in the future and should
+be specified as \verb|NULL|.
+
+The character string \verb|fname| specifies a name of the text file to
+be written out. (If the file name ends with suffix `\verb|.gz|', the
+file is assumed to be compressed, in which case the routine
+\verb|glp_write_lp| performs automatic compression on writing it.)
+
+\returns
+
+If the operation was successful, the routine \verb|glp_write_lp|
+returns zero. Otherwise, it prints an error message and returns
+non-zero.
+
+\subsection{glp\_read\_prob --- read problem data in GLPK format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_read_prob(glp_prob *P, int flags, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_read_prob| reads problem data in the GLPK LP/MIP
+format from a text file. (For description of the GLPK LP/MIP format see
+below.)
+
+The parameter \verb|flags| is reserved for use in the future and should
+be specified as zero.
+
+The character string \verb|fname| specifies a name of the text file to
+be read in. (If the file name ends with suffix `\verb|.gz|', the file
+is assumed to be compressed, in which case the routine
+\verb|glp_read_prob| decompresses it ``on the fly''.)
+
+Note that before reading data the current content of the problem object
+is completely erased with the routine \verb|glp_erase_prob|.
+
+\returns
+
+If the operation was successful, the routine \verb|glp_read_prob|
+returns zero. Otherwise, it prints an error message and returns
+non-zero.
+
+%\newpage
+
+\para{GLPK LP/MIP format}
+
+The GLPK LP/MIP format is a DIMACS-like format.\footnote{The DIMACS
+formats were developed by the Center for Discrete Mathematics and
+Theoretical Computer Science (DIMACS) to facilitate exchange of problem
+data. For details see: {\tt <http://dimacs.rutgers.edu/Challenges/>}. }
+The file in this format is a plain ASCII text file containing lines of
+several types described below. A line is terminated with the
+end-of-line character. Fields in each line are separated by at least
+one blank space. Each line begins with a one-character designator to
+identify the line type.
+
+\newpage
+
+The first line of the data file must be the problem line (except
+optional comment lines, which may precede the problem line). The last
+line of the data file must be the end line. Other lines may follow in
+arbitrary order, however, duplicate lines are not allowed.
+
+\para{Comment lines.} Comment lines give human-readable
+information about the data file and are ignored by GLPK routines.
+Comment lines can appear anywhere in the data file. Each comment line
+begins with the lower-case character \verb|c|.
+
+\begin{verbatim}
+ c This is an example of comment line
+\end{verbatim}
+
+\para{Problem line.} There must be exactly one problem line in the
+data file. This line must appear before any other lines except comment
+lines and has the following format:
+
+\begin{verbatim}
+ p CLASS DIR ROWS COLS NONZ
+\end{verbatim}
+
+The lower-case letter \verb|p| specifies that this is the problem line.
+
+The \verb|CLASS| field defines the problem class and can contain either
+the keyword \verb|lp| (that means linear programming problem) or
+\verb|mip| (that means mixed integer programming problem).
+
+The \verb|DIR| field defines the optimization direction (that is, the
+objective function sense) and can contain either the keyword \verb|min|
+(that means minimization) or \verb|max| (that means maximization).
+
+The \verb|ROWS|, \verb|COLS|, and \verb|NONZ| fields contain
+non-negative integer values specifying, respectively, the number of
+rows (constraints), columns (variables), and non-zero constraint
+coefficients in the problem instance. Note that \verb|NONZ| value does
+not account objective coefficients.
+
+\para{Row descriptors.} There must be at most one row descriptor line
+in the data file for each row (constraint). This line has one of the
+following formats:
+
+\begin{verbatim}
+ i ROW f
+ i ROW l RHS
+ i ROW u RHS
+ i ROW d RHS1 RHS2
+ i ROW s RHS
+\end{verbatim}
+
+The lower-case letter \verb|i| specifies that this is the row
+descriptor line.
+
+The \verb|ROW| field specifies the row ordinal number, an integer
+between 1 and $m$, where $m$ is the number of rows in the problem
+instance.
+
+The next lower-case letter specifies the row type as follows:
+
+\verb|f| --- free (unbounded) row: $-\infty<\sum a_jx_j<+\infty$;
+
+\verb|l| --- inequality constraint of `$\geq$' type:
+$\sum a_jx_j\geq b$;
+
+\verb|u| --- inequality constraint of `$\leq$' type:
+$\sum a_jx_j\leq b$;
+
+\verb|d| --- double-sided inequality constraint:
+$b_1\leq\sum a_jx_j\leq b_2$;
+
+\verb|s| --- equality constraint: $\sum a_jx_j=b$.
+
+The \verb|RHS| field contains a floaing-point value specifying the
+row right-hand side. The \verb|RHS1| and \verb|RHS2| fields contain
+floating-point values specifying, respectively, the lower and upper
+right-hand sides for the double-sided row.
+
+If for some row its descriptor line does not appear in the data file,
+by default that row is assumed to be an equality constraint with zero
+right-hand side.
+
+\para{Column descriptors.} There must be at most one column descriptor
+line in the data file for each column (variable). This line has one of
+the following formats depending on the problem class specified in the
+problem line:
+
+\begin{tabular}{@{}l@{\hspace*{40pt}}l}
+LP class & MIP class \\
+\hline
+\verb|j COL f| & \verb|j COL KIND f| \\
+\verb|j COL l BND| & \verb|j COL KIND l BND| \\
+\verb|j COL u BND| & \verb|j COL KIND u BND| \\
+\verb|j COL d BND1 BND2| & \verb|j COL KIND d BND1 BND2| \\
+\verb|j COL s BND| & \verb|j COL KIND s BND| \\
+\end{tabular}
+
+The lower-case letter \verb|j| specifies that this is the column
+descriptor line.
+
+The \verb|COL| field specifies the column ordinal number, an integer
+between 1 and $n$, where $n$ is the number of columns in the problem
+instance.
+
+The \verb|KIND| field is used only for MIP problems and specifies the
+column kind as follows:
+
+\verb|c| --- continuous column;
+
+\verb|i| --- integer column;
+
+\verb|b| --- binary column (in this case all remaining fields must be
+omitted).
+
+The next lower-case letter specifies the column type as follows:
+
+\verb|f| --- free (unbounded) column: $-\infty<x<+\infty$;
+
+\verb|l| --- column with lower bound: $x\geq l$;
+
+\verb|u| --- column with upper bound: $x\leq u$;
+
+\verb|d| --- double-bounded column: $l\leq x\leq u$;
+
+\verb|s| --- fixed column: $x=s$.
+
+The \verb|BND| field contains a floating-point value that specifies the
+column bound. The \verb|BND1| and \verb|BND2| fields contain
+floating-point values specifying, respectively, the lower and upper
+bounds for the double-bounded column.
+
+If for some column its descriptor line does not appear in the file, by
+default that column is assumed to be non-negative (in case of LP class)
+or binary (in case of MIP class).
+
+\para{Coefficient descriptors.} There must be exactly one coefficient
+descriptor line in the data file for each non-zero objective or
+constraint coefficient. This line has the following format:
+
+\begin{verbatim}
+ a ROW COL VAL
+\end{verbatim}
+
+The lower-case letter \verb|a| specifies that this is the coefficient
+descriptor line.
+
+For objective coefficients the \verb|ROW| field must contain 0. For
+constraint coefficients the \verb|ROW| field specifies the row ordinal
+number, an integer between 1 and $m$, where $m$ is the number of rows
+in the problem instance.
+
+The \verb|COL| field specifies the column ordinal number, an integer
+between 1 and $n$, where $n$ is the number of columns in the problem
+instance.
+
+If both the \verb|ROW| and \verb|COL| fields contain 0, the line
+specifies the constant term (``shift'') of the objective function
+rather than objective coefficient.
+
+The \verb|VAL| field contains a floating-point coefficient value (it is
+allowed to specify zero value in this field).
+
+The number of constraint coefficient descriptor lines must be exactly
+the same as specified in the field \verb|NONZ| of the problem line.
+
+\para{Symbolic name descriptors.} There must be at most one symbolic
+name descriptor line for the problem instance, objective function, each
+row (constraint), and each column (variable). This line has one of the
+following formats:
+
+\begin{verbatim}
+ n p NAME
+ n z NAME
+ n i ROW NAME
+ n j COL NAME
+\end{verbatim}
+
+The lower-case letter \verb|n| specifies that this is the symbolic name
+descriptor line.
+
+The next lower-case letter specifies which object should be assigned a
+symbolic name:
+
+\verb|p| --- problem instance;
+
+\verb|z| --- objective function;
+
+\verb|i| --- row (constraint);
+
+\verb|j| --- column (variable).
+
+The \verb|ROW| field specifies the row ordinal number, an integer
+between 1 and $m$, where $m$ is the number of rows in the problem
+instance.
+
+The \verb|COL| field specifies the column ordinal number, an integer
+between 1 and $n$, where $n$ is the number of columns in the problem
+instance.
+
+The \verb|NAME| field contains the symbolic name, a sequence from 1 to
+255 arbitrary graphic ASCII characters, assigned to corresponding
+object.
+
+\para{End line.} There must be exactly one end line in the data file.
+This line must appear last in the file and has the following format:
+
+\begin{verbatim}
+ e
+\end{verbatim}
+
+The lower-case letter \verb|e| specifies that this is the end line.
+Anything that follows the end line is ignored by GLPK routines.
+
+\newpage
+
+\para{Example of data file in GLPK LP/MIP format}
+
+The following example of a data file in GLPK LP/MIP format specifies
+the same LP problem as in Subsection ``Example of MPS file''.
+
+\bigskip
+
+\begin{center}
+\footnotesize\tt
+\begin{tabular}{l@{\hspace*{50pt}}}
+p lp min 8 7 48 \\
+n p PLAN \\
+n z VALUE \\
+i 1 f \\
+n i 1 VALUE \\
+i 2 s 2000 \\
+n i 2 YIELD \\
+i 3 u 60 \\
+n i 3 FE \\
+i 4 u 100 \\
+n i 4 CU \\
+i 5 u 40 \\
+n i 5 MN \\
+i 6 u 30 \\
+n i 6 MG \\
+i 7 l 1500 \\
+n i 7 AL \\
+i 8 d 250 300 \\
+n i 8 SI \\
+j 1 d 0 200 \\
+n j 1 BIN1 \\
+j 2 d 0 2500 \\
+n j 2 BIN2 \\
+j 3 d 400 800 \\
+n j 3 BIN3 \\
+j 4 d 100 700 \\
+n j 4 BIN4 \\
+j 5 d 0 1500 \\
+n j 5 BIN5 \\
+n j 6 ALUM \\
+n j 7 SILICON \\
+a 0 1 0.03 \\
+a 0 2 0.08 \\
+a 0 3 0.17 \\
+a 0 4 0.12 \\
+a 0 5 0.15 \\
+a 0 6 0.21 \\
+a 0 7 0.38 \\
+a 1 1 0.03 \\
+a 1 2 0.08 \\
+a 1 3 0.17 \\
+a 1 4 0.12 \\
+a 1 5 0.15 \\
+a 1 6 0.21 \\
+\end{tabular}
+\begin{tabular}{|@{\hspace*{80pt}}l}
+a 1 7 0.38 \\
+a 2 1 1 \\
+a 2 2 1 \\
+a 2 3 1 \\
+a 2 4 1 \\
+a 2 5 1 \\
+a 2 6 1 \\
+a 2 7 1 \\
+a 3 1 0.15 \\
+a 3 2 0.04 \\
+a 3 3 0.02 \\
+a 3 4 0.04 \\
+a 3 5 0.02 \\
+a 3 6 0.01 \\
+a 3 7 0.03 \\
+a 4 1 0.03 \\
+a 4 2 0.05 \\
+a 4 3 0.08 \\
+a 4 4 0.02 \\
+a 4 5 0.06 \\
+a 4 6 0.01 \\
+a 5 1 0.02 \\
+a 5 2 0.04 \\
+a 5 3 0.01 \\
+a 5 4 0.02 \\
+a 5 5 0.02 \\
+a 6 1 0.02 \\
+a 6 2 0.03 \\
+a 6 5 0.01 \\
+a 7 1 0.7 \\
+a 7 2 0.75 \\
+a 7 3 0.8 \\
+a 7 4 0.75 \\
+a 7 5 0.8 \\
+a 7 6 0.97 \\
+a 8 1 0.02 \\
+a 8 2 0.06 \\
+a 8 3 0.08 \\
+a 8 4 0.12 \\
+a 8 5 0.02 \\
+a 8 6 0.01 \\
+a 8 7 0.97 \\
+e o f \\
+\\
+\end{tabular}
+\end{center}
+
+\newpage
+
+\subsection{glp\_write\_prob --- write problem data in GLPK format}
+
+\synopsis
+
+\begin{verbatim}
+int glp_write_prob(glp_prob *P, int flags, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_write_prob| writes problem data in the GLPK
+LP/MIP format to a text file. (For description of the GLPK LP/MIP
+format see Subsection ``Read problem data in GLPK format''.)
+
+The parameter \verb|flags| is reserved for use in the future and should
+be specified as zero.
+
+The character string \verb|fname| specifies a name of the text file to
+be written out. (If the file name ends with suffix `\verb|.gz|', the
+file is assumed to be compressed, in which case the routine
+\verb|glp_write_prob| performs automatic compression on writing it.)
+
+\returns
+
+If the operation was successful, the routine \verb|glp_read_prob|
+returns zero. Otherwise, it prints an error message and returns
+non-zero.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Routines for processing MathProg models}
+
+\subsection{Introduction}
+
+GLPK supports the {\it GNU MathProg modeling language}.\footnote{The
+GNU MathProg modeling language is a subset of the AMPL language. For
+its detailed description see the document ``Modeling Language GNU
+MathProg: Language Reference'' included in the GLPK distribution.}
+As a rule, models written in MathProg are solved with the GLPK LP/MIP
+stand-alone solver \verb|glpsol| (see Appendix D) and do not need any
+programming with API routines. However, for various reasons the user
+may need to process MathProg models directly in his/her application
+program, in which case he/she may use API routines described in this
+section. These routines provide an interface to the {\it MathProg
+translator}, a component of GLPK, which translates MathProg models into
+an internal code and then interprets (executes) this code.
+
+The processing of a model written in GNU MathProg includes several
+steps, which should be performed in the following order:
+
+%\vspace*{-8pt}
+
+%\begin{enumerate}
+\Item{1.}{\it Allocating the workspace.}
+The translator allocates the workspace, an internal data structure used
+on all subsequent steps.
+
+\Item{2.}{\it Reading model section.} The translator reads model
+section and, optionally, data section from a specified text file and
+translates them into the internal code. If necessary, on this step data
+section may be ignored.
+
+\Item{3.}{\it Reading data section(s).} The translator reads one or
+more data sections from specified text file(s) and translates them into
+the internal code.
+
+\Item{4.}{\it Generating the model.} The translator executes the
+internal code to evaluate the content of the model objects such as sets,
+parameters, variables, constraints, and objectives. On this step the
+execution is suspended at the solve statement.
+
+\Item{5.}{\it Building the problem object.} The translator obtains all
+necessary information from the workspace and builds the standard
+problem object (that is, the program object of type \verb|glp_prob|).
+
+\Item{6.}{\it Solving the problem.} On this step the problem object
+built on the previous step is passed to a solver, which solves the
+problem instance and stores its solution back to the problem object.
+
+\Item{7.}{\it Postsolving the model.} The translator copies the
+solution from the problem object to the workspace and then executes the
+internal code from the solve statement to the end of the model.
+(If model has no solve statement, the translator does nothing on this
+step.)
+
+\Item{8.}{\it Freeing the workspace.} The translator frees all the
+memory allocated to the workspace.
+%\end{enumerate}
+
+%\vspace*{-8pt}
+
+Note that the MathProg translator performs no error correction, so if
+any of steps 2 to 7 fails (due to errors in the model), the application
+program should terminate processing and go to\linebreak step 8.
+
+\newpage
+
+\para{Example 1}
+
+In this example the program reads model and data sections from input
+file \verb|egypt.mod|\footnote{This is an example model included in
+the GLPK distribution.} and writes the model to output file
+\verb|egypt.mps| in free MPS format (see Appendix B). No solution is
+performed.
+
+\bigskip
+
+\begin{small}
+\begin{verbatim}
+/* mplsamp1.c */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+int main(void)
+{ glp_prob *lp;
+ glp_tran *tran;
+ int ret;
+ lp = glp_create_prob();
+ tran = glp_mpl_alloc_wksp();
+ ret = glp_mpl_read_model(tran, "egypt.mod", 0);
+ if (ret != 0)
+ { fprintf(stderr, "Error on translating model\n");
+ goto skip;
+ }
+ ret = glp_mpl_generate(tran, NULL);
+ if (ret != 0)
+ { fprintf(stderr, "Error on generating model\n");
+ goto skip;
+ }
+ glp_mpl_build_prob(tran, lp);
+ ret = glp_write_mps(lp, GLP_MPS_FILE, NULL, "egypt.mps");
+ if (ret != 0)
+ fprintf(stderr, "Error on writing MPS file\n");
+skip: glp_mpl_free_wksp(tran);
+ glp_delete_prob(lp);
+ return 0;
+}
+
+/* eof */
+\end{verbatim}
+\end{small}
+
+\newpage
+
+\subsubsection*{Example 2}
+
+In this example the program reads model section from file
+\verb|sudoku.mod|\footnote{This is an example model which is included
+in the GLPK distribution along with alternative data file
+{\tt sudoku.dat}.} ignoring data section in this file, reads alternative
+data section from file \verb|sudoku.dat|, solves the problem instance
+and passes the solution found back to the model.
+
+\bigskip
+
+\begin{small}
+\begin{verbatim}
+/* mplsamp2.c */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+int main(void)
+{ glp_prob *mip;
+ glp_tran *tran;
+ int ret;
+ mip = glp_create_prob();
+ tran = glp_mpl_alloc_wksp();
+ ret = glp_mpl_read_model(tran, "sudoku.mod", 1);
+ if (ret != 0)
+ { fprintf(stderr, "Error on translating model\n");
+ goto skip;
+ }
+ ret = glp_mpl_read_data(tran, "sudoku.dat");
+ if (ret != 0)
+ { fprintf(stderr, "Error on translating data\n");
+ goto skip;
+ }
+ ret = glp_mpl_generate(tran, NULL);
+ if (ret != 0)
+ { fprintf(stderr, "Error on generating model\n");
+ goto skip;
+ }
+ glp_mpl_build_prob(tran, mip);
+ glp_simplex(mip, NULL);
+ glp_intopt(mip, NULL);
+ ret = glp_mpl_postsolve(tran, mip, GLP_MIP);
+ if (ret != 0)
+ fprintf(stderr, "Error on postsolving model\n");
+skip: glp_mpl_free_wksp(tran);
+ glp_delete_prob(mip);
+ return 0;
+}
+
+/* eof */
+\end{verbatim}
+\end{small}
+
+\newpage
+
+\subsection{glp\_mpl\_alloc\_wksp --- allocate the translator
+workspace}
+
+\synopsis
+
+\begin{verbatim}
+ glp_tran *glp_mpl_alloc_wksp(void);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mpl_alloc_wksp| allocates the MathProg translator
+work\-space. (Note that multiple instances of the workspace may be
+allocated, if necessary.)
+
+\returns
+
+The routine returns a pointer to the workspace, which should be used in
+all subsequent operations.
+
+\subsection{glp\_mpl\_init\_rand --- initialize pseudo-random number
+generator}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_mpl_init_rand(glp_tran *tran, int seed);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mpl_init_rand| initializes a pseudo-random number
+generator used by the MathProg translator, where the parameter
+\verb|seed| may be any integer number.
+
+A call to the routine \verb|glp_mpl_init_rand| should immediately
+follow the call to the routine \verb|glp_mpl_alloc_wksp|. However,
+using of this routine is optional. If it is not called, the effect is
+the same as if it were called with \verb|seed| equal to 1.
+
+\subsection{glp\_mpl\_read\_model --- read and translate model section}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_mpl_read_model(glp_tran *tran, const char *fname, int skip);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mpl_read_model| reads model section and,
+optionally, data section, which may follow the model section, from a
+text file, whose name is the character string \verb|fname|, performs
+translation of model statements and data blocks, and stores all the
+information in the workspace.
+
+The parameter \verb|skip| is a flag. If the input file contains the
+data section and this flag is non-zero, the data section is not read as
+if there were no data section and a warning message is printed. This
+allows reading data section(s) from other file(s).
+
+\returns
+
+If the operation is successful, the routine returns zero. Otherwise
+the routine prints an error message and returns non-zero.
+
+\newpage
+
+\subsection{glp\_mpl\_read\_data --- read and translate data section}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_mpl_read_data(glp_tran *tran, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mpl_read_data| reads data section from a text
+file, whose name is the character string \verb|fname|, performs
+translation of data blocks, and stores the data read in the translator
+workspace. If necessary, this routine may be called more than once.
+
+\returns
+
+If the operation is successful, the routine returns zero. Otherwise
+the routine prints an error message and returns non-zero.
+
+\subsection{glp\_mpl\_generate --- generate the model}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_mpl_generate(glp_tran *tran, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mpl_generate| generates the model using its
+description stored in the translator workspace. This operation means
+generating all variables, constraints, and objectives, executing check
+and display statements, which precede the solve statement (if it is
+presented).
+
+The character string \verb|fname| specifies the name of an output text
+file, to which output produced by display statements should be written.
+If \verb|fname| is \verb|NULL|, the output is sent to the terminal.
+
+\returns
+
+If the operation is successful, the routine returns zero. Otherwise
+the routine prints an error message and returns non-zero.
+
+\vspace*{-6pt}
+
+\subsection{glp\_mpl\_build\_prob --- build problem instance from the
+model}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_mpl_build_prob(glp_tran *tran, glp_prob *P);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mpl_build_prob| obtains all necessary information
+from the translator work\-space and stores it in the specified problem
+object \verb|P|. Note that before building the current content of the
+problem object is erased with the routine \verb|glp_erase_prob|.
+
+\newpage
+
+\subsection{glp\_mpl\_postsolve --- postsolve the model}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_mpl_postsolve(glp_tran *tran, glp_prob *P, int sol);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mpl_postsolve| copies the solution from the
+specified problem object \verb|prob| to the translator workspace and
+then executes all the remaining model statements, which follow the
+solve statement.
+
+The parameter \verb|sol| specifies which solution should be copied
+from the problem object to the workspace as follows:
+
+\verb|GLP_SOL| --- basic solution;
+
+\verb|GLP_IPT| --- interior-point solution;
+
+\verb|GLP_MIP| --- mixed integer solution.
+
+\returns
+
+If the operation is successful, the routine returns zero. Otherwise
+the routine prints an error message and returns non-zero.
+
+\subsection{glp\_mpl\_free\_wksp --- free the translator workspace}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_mpl_free_wksp(glp_tran *tran);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mpl_free_wksp| frees all the memory allocated to
+the translator workspace. It also frees all other resources, which are
+still used by the translator.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Problem solution reading/writing routines}
+
+\subsection{glp\_print\_sol --- write basic solution in printable
+format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_print_sol(glp_prob *P, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_print_sol writes| the current basic solution to
+an LP problem, which is specified by the pointer \verb|P|, to a text
+file, whose name is the character string \verb|fname|, in printable
+format.
+
+Information reported by the routine \verb|glp_print_sol| is intended
+mainly for visual analysis.
+
+\returns
+
+If no errors occurred, the routine returns zero. Otherwise the routine
+prints an error message and returns non-zero.
+
+\subsection{glp\_read\_sol --- read basic solution in GLPK format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_read_sol(glp_prob *P, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_read_sol| reads basic solution from a text file
+in the GLPK format. (For description of the format see below.)
+
+The character string \verb|fname| specifies the name of the text file
+to be read in. (If the file name ends with suffix `\verb|.gz|', the
+file is assumed to be compressed, in which case the routine
+\verb|glp_read_sol| decompresses it "on the fly".)
+
+\returns
+
+If the operation was successful, the routine \verb|glp_read_sol|
+returns zero. Otherwise, it prints an error message and returns
+non-zero.
+
+\para{GLPK basic solution format}
+
+The GLPK basic solution format is a DIMACS-like format.\footnote{The
+DIMACS formats were developed by the Center for Discrete Mathematics
+and Theoretical Computer Science (DIMACS) to facilitate exchange of
+problem data.
+For details see: {\tt <http://dimacs.rutgers.edu/Challenges/>}. }
+The file in this format is a plain ASCII text file containing lines of
+several types described below. A line is terminated with the
+end-of-line character. Fields in each line are separated by at least
+one blank space. Each line begins with a one-character designator to
+identify the line type.
+
+The first line of the solution file must be the solution line (except
+optional comment lines, which may precede the problem line). The last
+line of the data file must be the end line. Other lines may follow in
+arbitrary order, however, duplicate lines are not allowed.
+
+\newpage
+
+\para{Comment lines.} Comment lines give human-readable information
+about the solution file and are ignored by GLPK routines. Comment lines
+can appear anywhere in the data file. Each comment line begins with the
+lower-case character \verb|c|.
+
+\begin{verbatim}
+ c This is an example of comment line
+\end{verbatim}
+
+\para{Solution line.} There must be exactly one solution line in the
+solution file. This line must appear before any other lines except
+comment lines and has the following format:
+
+\begin{verbatim}
+ s bas ROWS COLS PST DST OBJ
+\end{verbatim}
+
+The lower-case letter \verb|s| specifies that this is the solution
+line.
+
+The three-character solution designator \verb|bas| identifies the file
+as containing a basic solution to the LP problem instance.
+
+The \verb|ROWS| and \verb|COLS| fields contain non-negative integer
+values that specify the number of rows (constraints) and columns
+(variables), resp., in the LP problem instance.
+
+The \verb|PST| and \verb|DST| fields contain lower-case letters that
+specify the primal and dual solution status, resp., as follows:
+
+\verb|u| --- solution is undefined;
+
+\verb|f| --- solution is feasible;
+
+\verb|i| --- solution is infeasible;
+
+\verb|n| --- no feasible solution exists.
+
+The \verb|OBJ| field contains a floating-point number that specifies
+the objective function value in the basic solution.
+
+\para{Row solution descriptors.} There must be exactly one row solution
+descriptor line in the solution file for each row (constraint). This
+line has the following format:
+
+\begin{verbatim}
+ i ROW ST PRIM DUAL
+\end{verbatim}
+
+The lower-case letter \verb|i| specifies that this is the row solution
+descriptor line.
+
+The \verb|ROW| field specifies the row ordinal number, an integer
+between 1 and $m$, where $m$ is the number of rows in the problem
+instance.
+
+The \verb|ST| field contains one of the following lower-case letters
+that specifies the row status in the basic solution:\footnote{The row
+status is the status of the associated auxiliary variable.}
+
+\verb|b| --- inactive constraint;
+
+\verb|l| --- inequality constraint active on its lower bound;
+
+\verb|u| --- inequality constraint active on its upper bound;
+
+\verb|f| --- active free (unounded) row;
+
+\verb|s| --- active equality constraint.
+
+The \verb|PRIM| field contains a floating-point number that specifies
+the row primal value (the value of the corresponding linear form).
+
+The \verb|DUAL| field contains a floating-point number that specifies
+the row dual value (the Lagrangian multiplier for active bound).
+
+\para{Column solution descriptors.} There must be exactly one column
+solution descriptor line in the solution file for each column
+(variable). This line has the following format:
+
+\begin{verbatim}
+ j COL ST PRIM DUAL
+\end{verbatim}
+
+The lower-case letter \verb|j| specifies that this is the column
+solution descriptor line.
+
+The \verb|COL| field specifies the column ordinal number, an integer
+between 1 and $n$, where $n$ is the number of columns in the problem
+instance.
+
+The \verb|ST| field contains one of the following lower-case letters
+that specifies the column status in the basic solution:
+
+\verb|b| --- basic variable;
+
+\verb|l| --- non-basic variable having its lower bound active;
+
+\verb|u| --- non-basic variable having its upper bound active;
+
+\verb|f| --- non-basic free (unounded) variable;
+
+\verb|s| --- non-basic fixed variable.
+
+The \verb|PRIM| field contains a floating-point number that specifies
+the column primal value.
+
+The \verb|DUAL| field contains a floating-point number that specifies
+the column dual value (the Lagrangian multiplier for active bound).
+
+\para{End line.} There must be exactly one end line in the solution
+file. This line must appear last in the file and has the following
+format:
+
+\begin{verbatim}
+ e
+\end{verbatim}
+
+The lower-case letter \verb|e| specifies that this is the end line.
+Anything that follows the end line is ignored by GLPK routines.
+
+\para{Example of solution file in GLPK basic solution format}
+
+The following example of a solution file in GLPK basic solution format
+specifies the optimal basic solution to the LP problem instance from
+Subsection ``Example of MPS file''.
+
+\bigskip
+
+\begin{center}
+\footnotesize\tt
+\begin{tabular}{l@{\hspace*{50pt}}}
+s bas 7 7 f f 296.216606498195 \\
+i 1 s 2000 -0.0135956678700369 \\
+i 2 u 60 -2.56823104693141 \\
+i 3 b 83.9675090252707 0 \\
+i 4 u 40 -0.544404332129962 \\
+i 5 b 19.9602888086643 0 \\
+i 6 l 1500 0.251985559566788 \\
+i 7 l 250 0.48519855595668 \\
+\end{tabular}
+\begin{tabular}{|@{\hspace*{50pt}}l}
+j 1 l 0 0.253624548736462 \\
+j 2 b 665.342960288809 0 \\
+j 3 b 490.252707581226 0 \\
+j 4 b 424.187725631769 0 \\
+j 5 l 0 0.0145559566787004 \\
+j 6 b 299.638989169676 0 \\
+j 7 b 120.57761732852 0 \\
+e o f \\
+\end{tabular}
+\end{center}
+
+\newpage
+
+\subsection{glp\_write\_sol --- write basic solution in GLPK format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_write_sol(glp_prob *P, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_write_sol| writes the current basic solution to
+a text file in the GLPK format. (For description of the GLPK basic
+solution format see Subsection ``Read basic solution in GLPK format.'')
+
+The character string \verb|fname| specifies the name of the text file
+to be written. (If the file name ends with suffix `\verb|.gz|', the
+routine \verb|glp_write_sol| compresses it "on the fly".)
+
+\returns
+
+If the operation was successful, the routine \verb|glp_write_sol|
+returns zero. Otherwise, it prints an error message and returns
+non-zero.
+
+\subsection{glp\_print\_ipt --- write interior-point solution in
+printable format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_print_ipt(glp_prob *P, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_print_ipt| writes the current interior point
+solution to an LP problem, which the parameter \verb|P| points to, to
+a text file, whose name is the character string \verb|fname|, in
+printable format.
+
+Information reported by the routine \verb|glp_print_ipt| is intended
+mainly for visual analysis.
+
+\returns
+
+If no errors occurred, the routine returns zero. Otherwise the routine
+prints an error message and returns non-zero.
+
+\subsection{glp\_read\_ipt --- read interior-point solution in GLPK
+format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_read_ipt(glp_prob *P, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_read_ipt| reads interior-point solution from
+a text file in the GLPK format. (For description of the format see
+below.)
+
+The character string \verb|fname| specifies the name of the text file
+to be read in. (If the file name ends with suffix `\verb|.gz|', the
+file is assumed to be compressed, in which case the routine
+\verb|glp_read_ipt| decompresses it "on the fly".)
+
+%\newpage
+
+\returns
+
+If the operation was successful, the routine \verb|glp_read_ipt|
+returns zero. Otherwise, it prints an error message and returns
+non-zero.
+
+\para{GLPK interior-point solution format}
+
+The GLPK interior-point solution format is a DIMACS-like
+format.\footnote{The DIMACS formats were developed by the Center for
+Discrete Mathematics and Theoretical Computer Science (DIMACS) to
+facilitate exchange of problem data. For details see:
+{\tt <http://dimacs.rutgers.edu/Challenges/>}. }
+The file in this format is a plain ASCII text file containing lines of
+several types described below. A line is terminated with the
+end-of-line character. Fields in each line are separated by at least
+one blank space. Each line begins with a one-character designator to
+identify the line type.
+
+The first line of the solution file must be the solution line (except
+optional comment lines, which may precede the problem line). The last
+line of the data file must be the end line. Other lines may follow in
+arbitrary order, however, duplicate lines are not allowed.
+
+\para{Comment lines.} Comment lines give human-readable information
+about the solution file and are ignored by GLPK routines. Comment lines
+can appear anywhere in the data file. Each comment line begins with the
+lower-case character \verb|c|.
+
+\begin{verbatim}
+ c This is an example of comment line
+\end{verbatim}
+
+\para{Solution line.} There must be exactly one solution line in the
+solution file. This line must appear before any other lines except
+comment lines and has the following format:
+
+\begin{verbatim}
+ s ipt ROWS COLS SST OBJ
+\end{verbatim}
+
+The lower-case letter \verb|s| specifies that this is the solution
+line.
+
+The three-character solution designator \verb|ipt| identifies the file
+as containing an interior-point solution to the LP problem instance.
+
+The \verb|ROWS| and \verb|COLS| fields contain non-negative integer
+values that specify the number of rows (constraints) and columns
+(variables), resp., in the LP problem instance.
+
+The \verb|SST| field contains one of the following lower-case letters
+that specifies the solution status:
+
+\verb|o| --- solution is optimal;
+
+\verb|i| --- solution is infeasible;
+
+\verb|n| --- no feasible solution exists;
+
+\verb|u| --- solution is undefined.
+
+The \verb|OBJ| field contains a floating-point number that specifies
+the objective function value in the interior-point solution.
+
+\para{Row solution descriptors.} There must be exactly one row solution
+descriptor line in the solution file for each row (constraint). This
+line has the following format:
+
+\begin{verbatim}
+ i ROW PRIM DUAL
+\end{verbatim}
+
+The lower-case letter \verb|i| specifies that this is the row solution
+descriptor line.
+
+%\newpage
+
+The \verb|ROW| field specifies the row ordinal number, an integer
+between 1 and $m$, where $m$ is the number of rows in the problem
+instance.
+
+The \verb|PRIM| field contains a floating-point number that specifies
+the row primal value (the value of the corresponding linear form).
+
+The \verb|DUAL| field contains a floating-point number that specifies
+the row dual value (the Lagrangian multiplier for active bound).
+
+\para{Column solution descriptors.} There must be exactly one column
+solution descriptor line in the solution file for each column
+(variable). This line has the following format:
+
+\begin{verbatim}
+ j COL PRIM DUAL
+\end{verbatim}
+
+The lower-case letter \verb|j| specifies that this is the column
+solution descriptor line.
+
+The \verb|COL| field specifies the column ordinal number, an integer
+between 1 and $n$, where $n$ is the number of columns in the problem
+instance.
+
+The \verb|PRIM| field contains a floating-point number that specifies
+the column primal value.
+
+The \verb|DUAL| field contains a floating-point number that specifies
+the column dual value (the Lagrangian multiplier for active bound).
+
+\para{End line.} There must be exactly one end line in the solution
+file. This line must appear last in the file and has the following
+format:
+
+\begin{verbatim}
+ e
+\end{verbatim}
+
+The lower-case letter \verb|e| specifies that this is the end line.
+Anything that follows the end line is ignored by GLPK routines.
+
+\para{Example of solution file in GLPK interior-point solution format}
+
+The following example of a solution file in GLPK interior-point
+solution format specifies the optimal interior-point solution to the LP
+problem instance from Subsection ``Example of MPS file''.
+
+\bigskip
+
+\begin{center}
+\footnotesize\tt
+\begin{tabular}{l@{\hspace*{10pt}}}
+s ipt 7 7 o 296.216606851403 \\
+i 1 2000.00000290369 -0.0135956757623443 \\
+i 2 60.0000001302903 -2.568231024875 \\
+i 3 83.9675094251819 -8.85591445202383e-10 \\
+i 4 39.9999999985064 -0.544404310443766 \\
+i 5 19.9602886941262 -2.24817803513554e-09 \\
+i 6 1500.00000199013 0.251985567257828 \\
+i 7 250.000000244896 0.48519856304979 \\
+\end{tabular}
+\begin{tabular}{|@{\hspace*{10pt}}l}
+j 1 3.3482079213784e-07 0.253624547432525 \\
+j 2 665.342955760768 6.04613825351601e-11 \\
+j 3 490.25271366802 5.8488360240978e-10 \\
+j 4 424.187729774275 -2.54144550490434e-11 \\
+j 5 1.46067738492801e-06 0.0145559574770786 \\
+j 6 299.638985053112 1.49359074902927e-10 \\
+j 7 120.577616852015 3.50297708781545e-10 \\
+e o f
+\end{tabular}
+\end{center}
+
+\subsection{glp\_write\_ipt --- write interior-point solution in GLPK
+format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_write_ipt(glp_prob *P, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_write_ipt| writes the current interior-point
+solution to a text file in the GLPK format. (For description of the
+GLPK interior-point solution format see Subsection ``Read
+interior-point solution in GLPK format.'')
+
+The character string \verb|fname| specifies the name of the text file
+to be written. (If the file name ends with suffix `\verb|.gz|', the
+routine \verb|glp_write_ipt| compresses it "on the fly".)
+
+\returns
+
+If the operation was successful, the routine \verb|glp_write_ipt|
+returns zero. Otherwise, it prints an error message and returns
+non-zero.
+
+\subsection{glp\_print\_mip --- write MIP solution in printable format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_print_mip(glp_prob *P, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_print_mip| writes the current solution to a MIP
+problem, which is specified by the pointer \verb|P|, to a text file,
+whose name is the character string \verb|fname|, in printable format.
+
+Information reported by the routine \verb|glp_print_mip| is intended
+mainly for visual analysis.
+
+\returns
+
+If no errors occurred, the routine returns zero. Otherwise the routine
+prints an error message and returns non-zero.
+
+\subsection{glp\_read\_mip --- read MIP solution in GLPK format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_read_mip(glp_prob *P, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_read_mip| reads MIP solution from a text file in
+the GLPK format. (For description of the format see below.)
+
+The character string \verb|fname| specifies the name of the text file
+to be read in. (If the file name ends with suffix `\verb|.gz|', the
+file is assumed to be compressed, in which case the routine
+\verb|glp_read_mip| decompresses it "on the fly".)
+
+\returns
+
+If the operation was successful, the routine \verb|glp_read_mip|
+returns zero. Otherwise, it prints an error message and returns
+non-zero.
+
+\para{GLPK MIP solution format}
+
+The GLPK MIP solution format is a DIMACS-like format.\footnote{The
+DIMACS formats were developed by the Center for Discrete Mathematics
+and Theoretical Computer Science (DIMACS) to facilitate exchange of
+problem data. For details see:
+{\tt <http://dimacs.rutgers.edu/Challenges/>}. }
+The file in this format is a plain ASCII text file containing lines of
+several types described below. A line is terminated with the
+end-of-line character. Fields in each line are separated by at least
+one blank space. Each line begins with a one-character designator to
+identify the line type.
+
+The first line of the solution file must be the solution line (except
+optional comment lines, which may precede the problem line). The last
+line of the data file must be the end line. Other lines may follow in
+arbitrary order, however, duplicate lines are not allowed.
+
+\para{Comment lines.} Comment lines give human-readable information
+about the solution file and are ignored by GLPK routines. Comment lines
+can appear anywhere in the data file. Each comment line begins with the
+lower-case character \verb|c|.
+
+\begin{verbatim}
+ c This is an example of comment line
+\end{verbatim}
+
+\para{Solution line.} There must be exactly one solution line in the
+solution file. This line must appear before any other lines except
+comment lines and has the following format:
+
+\begin{verbatim}
+ s mip ROWS COLS SST OBJ
+\end{verbatim}
+
+The lower-case letter \verb|s| specifies that this is the solution
+line.
+
+The three-character solution designator \verb|mip| identifies the file
+as containing a solution to the MIP problem instance.
+
+The \verb|ROWS| and \verb|COLS| fields contain non-negative integer
+values that specify the number of rows (constraints) and columns
+(variables), resp., in the LP problem instance.
+
+The \verb|SST| field contains one of the following lower-case letters
+that specifies the solution status:
+
+\verb|o| --- solution is integer optimal;
+
+\verb|f| --- solution is integer feasible (non-optimal);
+
+\verb|n| --- no integer feasible solution exists;
+
+\verb|u| --- solution is undefined.
+
+The \verb|OBJ| field contains a floating-point number that specifies
+the objective function value in the MIP solution.
+
+\para{Row solution descriptors.} There must be exactly one row solution
+descriptor line in the solution file for each row (constraint). This
+line has the following format:
+
+\begin{verbatim}
+ i ROW VAL
+\end{verbatim}
+
+The lower-case letter \verb|i| specifies that this is the row solution
+descriptor line.
+
+The \verb|ROW| field specifies the row ordinal number, an integer
+between 1 and $m$, where $m$ is the number of rows in the problem
+instance.
+
+The \verb|VAL| field contains a floating-point number that specifies
+the row value (the value of the corresponding linear form).
+
+\para{Column solution descriptors.} There must be exactly one column
+solution descriptor line in the solution file for each column
+(variable). This line has the following format:
+
+\begin{verbatim}
+ j COL VAL
+\end{verbatim}
+
+The lower-case letter \verb|j| specifies that this is the column
+solution descriptor line.
+
+The \verb|COL| field specifies the column ordinal number, an integer
+between 1 and $n$, where $n$ is the number of columns in the problem
+instance.
+
+The \verb|VAL| field contains a floating-point number that specifies
+the column value.
+
+\para{End line.} There must be exactly one end line in the solution
+file. This line must appear last in the file and has the following
+format:
+
+\begin{verbatim}
+ e
+\end{verbatim}
+
+The lower-case letter \verb|e| specifies that this is the end line.
+Anything that follows the end line is ignored by GLPK routines.
+
+\para{Example of solution file in GLPK MIP solution format}
+
+The following example of a solution file in GLPK MIP solution format
+specifies an optimal solution to a MIP problem instance.
+
+\bigskip
+
+\begin{center}
+\footnotesize\tt
+\begin{tabular}{l@{\hspace*{50pt}}}
+s mip 8 8 o 1201500 \\
+i 1 60 \\
+i 2 8400 \\
+i 3 -1200 \\
+i 4 0 \\
+i 5 9000 \\
+i 6 -600 \\
+i 7 0 \\
+i 8 8000 \\
+\end{tabular}
+\begin{tabular}{|@{\hspace*{80pt}}l}
+j 1 60 \\
+j 2 6 \\
+j 3 0 \\
+j 4 60 \\
+j 5 6 \\
+j 6 600 \\
+j 7 60 \\
+j 8 16 \\
+e o f \\
+\end{tabular}
+\end{center}
+
+\subsection{glp\_write\_mip --- write MIP solution in GLPK format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_write_mip(glp_prob *P, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_write_mip| writes the current MIP solution to
+a text file in the GLPK format. (For description of the GLPK MIP
+solution format see Subsection ``Read MIP solution in GLPK format.'')
+
+The character string \verb|fname| specifies the name of the text file
+to be written. (If the file name ends with suffix `\verb|.gz|', the
+routine \verb|glp_write_mip| compresses it "on the fly".)
+
+\returns
+
+If the operation was successful, the routine \verb|glp_write_mip|
+returns zero. Otherwise, it prints an error message and returns
+non-zero.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Post-optimal analysis routines}
+
+\subsection{glp\_print\_ranges --- print sensitivity analysis report}
+
+\synopsis
+
+{\tt int glp\_print\_ranges(glp\_prob *P, int len, const int list[],
+int flags,\\
+\hspace*{134pt}const char *fname);}
+
+\description
+
+The routine \verb|glp_print_ranges| performs sensitivity analysis of
+current optimal basic solution and writes the analysis report in
+human-readable format to a text file, whose name is the character
+string {\it fname}. (Detailed description of the report structure is
+given below.)
+
+The parameter {\it len} specifies the length of the row/column list.
+
+The array {\it list} specifies ordinal number of rows and columns to be
+analyzed. The ordinal numbers should be passed in locations
+{\it list}[1], {\it list}[2], \dots, {\it list}[{\it len}]. Ordinal
+numbers from 1 to $m$ refer to rows, and ordinal numbers from $m+1$ to
+$m+n$ refer to columns, where $m$ and $n$ are, resp., the total number
+of rows and columns in the problem object. Rows and columns appear in
+the analysis report in the same order as they follow in the array list.
+
+It is allowed to specify $len=0$, in which case the array {\it list} is
+not used (so it can be specified as \verb|NULL|), and the routine
+performs analysis for all rows and columns of the problem object.
+
+The parameter {\it flags} is reserved for use in the future and must be
+specified as zero.
+
+On entry to the routine \verb|glp_print_ranges| the current basic
+solution must be optimal and the basis factorization must exist.
+The application program can check that with the routine
+\verb|glp_bf_exists|, and if the factorization does
+not exist, compute it with the routine \verb|glp_factorize|. Note that
+if the LP preprocessor is not used, on normal exit from the simplex
+solver routine \verb|glp_simplex| the basis factorization always exists.
+
+\returns
+
+If the operation was successful, the routine \verb|glp_print_ranges|
+returns zero. Otherwise, it prints an error message and returns
+non-zero.
+
+\para{Analysis report example}
+
+An example of the sensitivity analysis report is shown on the next two
+pages. This example corresponds to the example of LP problem described
+in Subsection ``Example of MPS file''.
+
+\para{Structure of the analysis report}
+
+For each row and column specified in the array {\it list} the routine
+prints two lines containing generic information and analysis
+information, which depends on the status of corresponding row or column.
+
+Note that analysis of a row is analysis of its auxiliary variable,
+which is equal to the row linear form $\sum a_jx_j$, and analysis of
+a column is analysis of corresponding structural variable. Therefore,
+formally, on performing the sensitivity analysis there is no difference
+between rows and columns.
+
+\newpage
+
+\begin{landscape}
+\begin{footnotesize}
+\begin{verbatim}
+ GLPK 4.42 - SENSITIVITY ANALYSIS REPORT Page 1
+
+ Problem: PLAN
+ Objective: VALUE = 296.2166065 (MINimum)
+
+ No. Row name St Activity Slack Lower bound Activity Obj coef Obj value at Limiting
+ Marginal Upper bound range range break point variable
+ ------ ------------ -- ------------- ------------- ------------- ------------- ------------- ------------- ------------
+ 1 VALUE BS 296.21661 -296.21661 -Inf 299.25255 -1.00000 . MN
+ . +Inf 296.21661 +Inf +Inf
+
+ 2 YIELD NS 2000.00000 . 2000.00000 1995.06864 -Inf 296.28365 BIN3
+ -.01360 2000.00000 2014.03479 +Inf 296.02579 CU
+
+ 3 FE NU 60.00000 . -Inf 55.89016 -Inf 306.77162 BIN4
+ -2.56823 60.00000 62.69978 2.56823 289.28294 BIN3
+
+ 4 CU BS 83.96751 16.03249 -Inf 93.88467 -.30613 270.51157 MN
+ . 100.00000 79.98213 .21474 314.24798 BIN5
+
+ 5 MN NU 40.00000 . -Inf 34.42336 -Inf 299.25255 BIN4
+ -.54440 40.00000 41.68691 .54440 295.29825 BIN3
+
+ 6 MG BS 19.96029 10.03971 -Inf 24.74427 -1.79618 260.36433 BIN1
+ . 30.00000 9.40292 .28757 301.95652 MN
+
+ 7 AL NL 1500.00000 . 1500.00000 1485.78425 -.25199 292.63444 CU
+ .25199 +Inf 1504.92126 +Inf 297.45669 BIN3
+
+ 8 SI NL 250.00000 50.00000 250.00000 235.32871 -.48520 289.09812 CU
+ .48520 300.00000 255.06073 +Inf 298.67206 BIN3
+\end{verbatim}
+\end{footnotesize}
+\end{landscape}
+
+\newpage
+
+\begin{landscape}
+\begin{footnotesize}
+\begin{verbatim}
+ GLPK 4.42 - SENSITIVITY ANALYSIS REPORT Page 2
+
+ Problem: PLAN
+ Objective: VALUE = 296.2166065 (MINimum)
+
+ No. Column name St Activity Obj coef Lower bound Activity Obj coef Obj value at Limiting
+ Marginal Upper bound range range break point variable
+ ------ ------------ -- ------------- ------------- ------------- ------------- ------------- ------------- ------------
+ 1 BIN1 NL . .03000 . -28.82475 -.22362 288.90594 BIN4
+ .25362 200.00000 33.88040 +Inf 304.80951 BIN4
+
+ 2 BIN2 BS 665.34296 .08000 . 802.22222 .01722 254.44822 BIN1
+ . 2500.00000 313.43066 .08863 301.95652 MN
+
+ 3 BIN3 BS 490.25271 .17000 400.00000 788.61314 .15982 291.22807 MN
+ . 800.00000 -347.42857 .17948 300.86548 BIN5
+
+ 4 BIN4 BS 424.18773 .12000 100.00000 710.52632 .10899 291.54745 MN
+ . 700.00000 -256.15524 .14651 307.46010 BIN1
+
+ 5 BIN5 NL . .15000 . -201.78739 .13544 293.27940 BIN3
+ .01456 1500.00000 58.79586 +Inf 297.07244 BIN3
+
+ 6 ALUM BS 299.63899 .21000 . 358.26772 .18885 289.87879 AL
+ . +Inf 112.40876 .22622 301.07527 MN
+
+ 7 SILICON BS 120.57762 .38000 . 124.27093 .14828 268.27586 BIN5
+ . +Inf 85.54745 .46667 306.66667 MN
+
+ End of report
+\end{verbatim}
+\end{footnotesize}
+\end{landscape}
+
+\newpage
+
+\noindent
+{\it Generic information}
+
+{\tt No.} is the row or column ordinal number in the problem object.
+Rows are numbered from 1 to $m$, and columns are numbered from 1 to $n$,
+where $m$ and $n$ are, resp., the total number of rows and columns in
+the problem object.
+
+{\tt Row name} is the symbolic name assigned to the row. If the row has
+no name assigned, this field contains blanks.
+
+{\tt Column name} is the symbolic name assigned to the column. If the
+column has no name assigned, this field contains blanks.
+
+{\tt St} is the status of the row or column in the optimal solution:
+
+{\tt BS} --- non-active constraint (row), basic column;
+
+{\tt NL} --- inequality constraint having its lower right-hand side
+active (row), non-basic column having its lower bound active;
+
+{\tt NU} --- inequality constraint having its upper right-hand side
+active (row), non-basic column having its upper bound active;
+
+{\tt NS} --- active equality constraint (row), non-basic fixed column.
+
+{\tt NF} --- active free row, non-basic free (unbounded) column. (This
+case means that the optimal solution is dual degenerate.)
+
+{\tt Activity} is the (primal) value of the auxiliary variable (row) or
+structural variable (column) in the optimal solution.
+
+{\tt Slack} is the (primal) value of the row slack variable.
+
+{\tt Obj coef} is the objective coefficient of the column (structural
+variable).
+
+{\tt Marginal} is the reduced cost (dual activity) of the auxiliary
+variable (row) or structural variable (column).
+
+{\tt Lower bound} is the lower right-hand side (row) or lower bound
+(column). If the row or column has no lower bound, this field contains
+{\tt -Inf}.
+
+{\tt Upper bound} is the upper right-hand side (row) or upper bound
+(column). If the row or column has no upper bound, this field contains
+{\tt +Inf}.
+
+\noindent
+{\it Sensitivity analysis of active bounds}
+
+The sensitivity analysis of active bounds is performed only for rows,
+which are active constraints, and only for non-basic columns, because
+inactive constraints and basic columns have no active bounds.
+
+For every auxiliary (row) or structural (column) non-basic variable the
+routine starts changing its active bound in both direction. The first
+of the two lines in the report corresponds to decreasing, and the
+second line corresponds to increasing of the active bound. Since the
+variable being analyzed is non-basic, its activity, which is equal to
+its active bound, also starts changing. This changing leads to changing
+of basic (auxiliary and structural) variables, which depend on the
+non-basic variable. The current basis remains primal feasible and
+therefore optimal while values of all basic variables are primal
+feasible, i.e. are within their bounds. Therefore, if some basic
+variable called the {\it limiting variable} reaches its (lower or
+upper) bound first, before any other basic variables, it thereby limits
+further changing of the non-basic variable, because otherwise the
+current basis would become primal infeasible. The point, at which this
+happens, is called the {\it break point}. Note that there are two break
+points: the lower break point, which corresponds to decreasing of the
+non-basic variable, and the upper break point, which corresponds to
+increasing of the non-basic variable.
+
+In the analysis report values of the non-basic variable (i.e. of its
+active bound) being analyzed at both lower and upper break points are
+printed in the field `{\tt Activity range}'. Corresponding values of
+the objective function are printed in the field `{\tt Obj value at
+break point}', and symbolic names of corresponding limiting basic
+variables are printed in the field `{\tt Limiting variable}'.
+If the active bound can decrease or/and increase unlimitedly, the field
+`{\tt Activity range}' contains {\tt -Inf} or/and {\tt +Inf}, resp.
+
+For example (see the example report above), row SI is a double-sided
+constraint, which is active on its lower bound (right-hand side), and
+its activity in the optimal solution being equal to the lower bound is
+250. The activity range for this row is $[235.32871,255.06073]$. This
+means that the basis remains optimal while the lower bound is
+increasing up to 255.06073, and further increasing is limited by
+(structural) variable BIN3. If the lower bound reaches this upper break
+point, the objective value becomes equal to 298.67206.
+
+Note that if the basis does not change, the objective function depends
+on the non-basic variable linearly, and the per-unit change of the
+objective function is the reduced cost (marginal value) of the
+non-basic variable.
+
+\noindent
+{\it Sensitivity analysis of objective coefficients at non-basic
+variables}
+
+The sensitivity analysis of the objective coefficient at a non-basic
+variable is quite simple, because in this case change in the objective
+coefficient leads to equivalent change in the reduced cost (marginal
+value).
+
+For every auxiliary (row) or structural (column) non-basic variable the
+routine starts changing its objective coefficient in both direction.
+(Note that auxiliary variables are not included in the objective
+function and therefore always have zero objective coefficients.) The
+first of the two lines in the report corresponds to decreasing, and the
+second line corresponds to increasing of the objective coefficient.
+This changing leads to changing of the reduced cost of the non-basic
+variable to be analyzed and does affect reduced costs of all other
+non-basic variables. The current basis remains dual feasible and
+therefore optimal while the reduced cost keeps its sign. Therefore, if
+the reduced cost reaches zero, it limits further changing of the
+objective coefficient (if only the non-basic variable is non-fixed).
+
+In the analysis report minimal and maximal values of the objective
+coefficient, on which the basis remains optimal, are printed in the
+field `\verb|Obj coef range|'. If the objective coefficient can
+decrease or/and increase unlimitedly, this field contains {\tt -Inf}
+or/and {\tt +Inf}, resp.
+
+For example (see the example report above), column BIN5 is non-basic
+having its lower bound active. Its objective coefficient is 0.15, and
+reduced cost in the optimal solution 0.01456. The column lower bound
+remains active while the column reduced cost remains non-negative,
+thus, minimal value of the objective coefficient, on which the current
+basis still remains optimal, is $0.15-0.01456=0.13644$, that is
+indicated in the field `\verb|Obj coef range|'.
+
+%\newpage
+
+%{\parskip=0pt
+\noindent
+{\it Sensitivity analysis of objective coefficients at basic variables}
+
+%\medskip
+
+To perform sensitivity analysis for every auxiliary (row) or structural
+(column) variable the routine starts changing its objective coefficient
+in both direction. (Note that auxiliary variables are not included in
+the objective function and therefore always have zero objective
+coefficients.) The first of the two lines in the report corresponds to
+decreasing, and the second line corresponds to increasing of the
+objective coefficient. This changing leads to changing of reduced costs
+of non-basic variables. The current basis remains dual feasible and
+therefore optimal while reduced costs of all non-basic variables
+(except fixed variables) keep their signs. Therefore, if the reduced
+cost of some non-basic non-fixed variable called the {\it limiting
+variable} reaches zero first, before reduced cost of any other
+non-basic non-fixed variable, it thereby limits further changing of the
+objective coefficient, because otherwise the current basis would become
+dual infeasible (non-optimal). The point, at which this happens, is
+called the {\it break point}. Note that there are two break points: the
+lower break point, which corresponds to decreasing of the objective
+coefficient, and the upper break point, which corresponds to increasing
+of the objective coefficient. Let the objective coefficient reach its
+limit value and continue changing a bit further in the same direction
+that makes the current basis dual infeasible (non-optimal). Then the
+reduced cost of the non-basic limiting variable becomes ``a bit'' dual
+infeasible that forces the limiting variable to enter the basis
+replacing there some basic variable, which leaves the basis to keep its
+primal feasibility. It should be understood that if we change the
+current basis in this way exactly at the break point, both the current
+and adjacent bases will be optimal with the same objective value,
+because at the break point the limiting variable has zero reduced cost.
+On the other hand, in the adjacent basis the value of the limiting
+variable changes, because there it becomes basic, that leads to
+changing of the value of the basic variable being analyzed. Note that
+on determining the adjacent basis the bounds of the analyzed basic
+variable are ignored as if it were a free (unbounded) variable, so it
+cannot leave the current basis.
+
+In the analysis report lower and upper limits of the objective
+coefficient at the basic variable being analyzed, when the basis
+remains optimal, are printed in the field `{\tt Obj coef range}'.
+Corresponding values of the objective function at both lower and upper
+break points are printed in the field `{\tt Obj value at break point}',
+symbolic names of corresponding non-basic limiting variables are
+printed in the field `{\tt Limiting variable}', and values of the basic
+variable, which it would take on in the adjacent bases (as was
+explained above) are printed in the field `{\tt Activity range}'.
+If the objective coefficient can increase or/and decrease unlimitedly,
+the field `{\tt Obj coef range}' contains {\tt -Inf} and/or {\tt +Inf},
+resp. It also may happen that no dual feasible adjacent basis exists
+(i.e. on entering the basis the limiting variable can increase or
+decrease unlimitedly), in which case the field `{\tt Activity range}'
+contains {\tt -Inf} and/or {\tt +Inf}.
+
+For example (see the example report above), structural variable
+(column) BIN3 is basic, its optimal value is 490.25271, and its
+objective coefficient is 0.17. The objective coefficient range for this
+column is $[0.15982,0.17948]$. This means that the basis remains
+optimal while the objective coefficient is decreasing down to 0.15982,
+and further decreasing is limited by (auxiliary) variable MN. If we
+make the objective coefficient a bit less than 0.15982, the limiting
+variable MN will enter the basis, and in that adjacent basis the
+structural variable BIN3 will take on new optimal value 788.61314. At
+the lower break point, where the objective coefficient is exactly
+0.15982, the objective function takes on the value 291.22807 in both
+the current and adjacent bases.
+
+Note that if the basis does not change, the objective function depends
+on the objective coefficient at the basic variable linearly, and the
+per-unit change of the objective function is the value of the basic
+variable.
+%}
+
+%* eof *%
diff --git a/glpk-5.0/doc/glpk04.tex b/glpk-5.0/doc/glpk04.tex
new file mode 100644
index 0000000..0a981be
--- /dev/null
+++ b/glpk-5.0/doc/glpk04.tex
@@ -0,0 +1,1392 @@
+%* glpk04.tex *%
+
+\chapter{Advanced API Routines}
+
+\section{Background}
+\label{basbgd}
+
+Using vector and matrix notations the LP problem (1.1)---(1.3) (see
+Section \ref{seclp}, page \pageref{seclp}) can be stated as follows:
+
+\noindent
+\hspace{.5in} minimize (or maximize)
+$$z=c^Tx_S+c_0\eqno(3.1)$$
+\hspace{.5in} subject to linear constraints
+$$x_R=Ax_S\eqno(3.2)$$
+\hspace{.5in} and bounds of variables
+$$
+\begin{array}{l@{\ }c@{\ }l@{\ }c@{\ }l}
+l_R&\leq&x_R&\leq&u_R\\
+l_S&\leq&x_S&\leq&u_S\\
+\end{array}\eqno(3.3)
+$$
+where:
+
+$x_R=(x_1,\dots,x_m)$ is the vector of auxiliary variables;
+
+$x_S=(x_{m+1},\dots,x_{m+n})$ is the vector of structural variables;
+
+$z$ is the objective function;
+
+$c=(c_1,\dots,c_n)$ is the vector of objective coefficients;
+
+$c_0$ is the constant term (``shift'') of the objective function;
+
+$A=(a_{11},\dots,a_{mn})$ is the constraint matrix;
+
+$l_R=(l_1,\dots,l_m)$ is the vector of lower bounds of auxiliary
+variables;
+
+$u_R=(u_1,\dots,u_m)$ is the vector of upper bounds of auxiliary
+variables;
+
+$l_S=(l_{m+1},\dots,l_{m+n})$ is the vector of lower bounds of
+structural variables;
+
+$u_S=(u_{m+1},\dots,u_{m+n})$ is the vector of upper bounds of
+structural variables.
+
+From the simplex method's standpoint there is no difference between
+auxiliary and structural variables. This allows combining all these
+variables into one vector that leads to the following problem
+statement:
+
+\newpage
+
+\noindent
+\hspace{.5in} minimize (or maximize)
+$$z=(0\ |\ c)^Tx+c_0\eqno(3.4)$$
+\hspace{.5in} subject to linear constraints
+$$(I\ |-\!A)x=0\eqno(3.5)$$
+\hspace{.5in} and bounds of variables
+$$l\leq x\leq u\eqno(3.6)$$
+where:
+
+$x=(x_R\ |\ x_S)$ is the $(m+n)$-vector of (all) variables;
+
+$(0\ |\ c)$ is the $(m+n)$-vector of objective
+coefficients;\footnote{Subvector 0 corresponds to objective
+coefficients at auxiliary variables.}
+
+$(I\ |-\!A)$ is the {\it augmented} constraint
+$m\times(m+n)$-matrix;\footnote{Note that due to auxiliary variables
+matrix $(I\ |-\!A)$ contains the unity submatrix and therefore has full
+rank. This means, in particular, that the system (3.5) has no linearly
+dependent constraints.}
+
+$l=(l_R\ |\ l_S)$ is the $(m+n)$-vector of lower bounds of (all)
+variables;
+
+$u=(u_R\ |\ u_S)$ is the $(m+n)$-vector of upper bounds of (all)
+variables.
+
+By definition an {\it LP basic solution} geometrically is a point in
+the space of all variables, which is the intersection of hyperplanes
+corresponding to active constraints\footnote{A constraint is called
+{\it active} if at a given point it is satisfied as equality, otherwise
+it is called {\it inactive}.}. The space of all variables has the
+dimension $m+n$, therefore, to define some basic solution we have to
+define $m+n$ active constraints. Note that $m$ constraints (3.5) being
+linearly independent equalities are always active, so remaining $n$
+active constraints can be chosen only from bound constraints (3.6).
+
+A variable is called {\it non-basic}, if its (lower or upper) bound is
+active, otherwise it is called {\it basic}. Since, as was said above,
+exactly $n$ bound constraints must be active, in any basic solution
+there are always $n$ non-basic variables and $m$ basic variables.
+(Note that a free variable also can be non-basic. Although such
+variable has no bounds, we can think it as the difference between two
+non-negative variables, which both are non-basic in this case.)
+
+Now consider how to determine numeric values of all variables for a
+given basic solution.
+
+Let $\Pi$ be an appropriate permutation matrix of the order $(m+n)$.
+Then we can write:
+$$\left(\begin{array}{@{}c@{}}x_B\\x_N\\\end{array}\right)=
+\Pi\left(\begin{array}{@{}c@{}}x_R\\x_S\\\end{array}\right)=\Pi x,
+\eqno(3.7)$$
+where $x_B$ is the vector of basic variables, $x_N$ is the vector of
+non-basic variables, $x=(x_R\ |\ x_S)$ is the vector of all variables
+in the original order. In this case the system of linear constraints
+(3.5) can be rewritten as follows:
+$$(I\ |-\!A)\Pi^T\Pi x=0\ \ \ \Rightarrow\ \ \ (B\ |\ N)
+\left(\begin{array}{@{}c@{}}x_B\\x_N\\\end{array}\right)=0,\eqno(3.8)$$
+where
+$$(B\ |\ N)=(I\ |-\!A)\Pi^T.\eqno(3.9)$$
+
+%\newpage
+
+Matrix $B$ is a square non-singular $m\times m$-matrix, which is
+composed from columns of the augmented constraint matrix corresponding
+to basic variables. It is called the {\it basis matrix} or simply the
+{\it basis}. Matrix $N$ is a rectangular $m\times n$-matrix, which is
+composed from columns of the augmented constraint matrix corresponding
+to non-basic variables.
+
+From (3.8) it follows that:
+$$Bx_B+Nx_N=0,\eqno(3.10)$$
+therefore,
+$$x_B=-B^{-1}Nx_N.\eqno(3.11)$$
+Thus, the formula (3.11) shows how to determine numeric values of basic
+variables $x_B$ assuming that non-basic variables $x_N$ are fixed on
+their active bounds.
+
+The $m\times n$-matrix
+$$\Xi=-B^{-1}N,\eqno(3.12)$$
+which appears in (3.11), is called the {\it simplex
+tableau}.\footnote{This definition corresponds to the GLPK
+implementation.} It shows how basic variables depend on non-basic
+variables:
+$$x_B=\Xi x_N.\eqno(3.13)$$
+
+The system (3.13) is equivalent to the system (3.5) in the sense that
+they both define the same set of points in the space of (primal)
+variables, which satisfy to these systems. If, moreover, values of all
+basic variables satisfy to their bound constraints (3.3), the
+corresponding basic solution is called {\it (primal) feasible},
+otherwise {\it (primal) infeasible}. It is understood that any (primal)
+feasible basic solution satisfy to all constraints (3.2) and (3.3).
+
+The LP theory says that if LP has optimal solution, it has (at least
+one) basic feasible solution, which corresponds to the optimum. And the
+most natural way to determine whether a given basic solution is optimal
+or not is to use the Karush---Kuhn---Tucker optimality conditions.
+
+\def\arraystretch{1.5}
+
+For the problem statement (3.4)---(3.6) the optimality conditions are
+the following:\footnote{These conditions can be appiled to any solution,
+not only to a basic solution.}
+$$(I\ |-\!A)x=0\eqno(3.14)$$
+$$(I\ |-\!A)^T\pi+\lambda_l+\lambda_u=\nabla z=(0\ |\ c)^T\eqno(3.15)$$
+$$l\leq x\leq u\eqno(3.16)$$
+$$\lambda_l\geq 0,\ \ \lambda_u\leq 0\ \ \mbox{(minimization)}
+\eqno(3.17)$$
+$$\lambda_l\leq 0,\ \ \lambda_u\geq 0\ \ \mbox{(maximization)}
+\eqno(3.18)$$
+$$(\lambda_l)_k(x_k-l_k)=0,\ \ (\lambda_u)_k(x_k-u_k)=0,\ \ k=1,2,\dots,
+m+n\eqno(3.19)$$
+where:
+
+$\pi=(\pi_1,\dots,\pi_m)$ is a $m$-vector of Lagrange
+multipliers for equality constraints (3.5);
+
+$\lambda_l=[(\lambda_l)_1,\dots,(\lambda_l)_n]$ is a $n$-vector of
+Lagrange multipliers for lower bound constraints (3.6);
+
+$\lambda_u=[(\lambda_u)_1,\dots,(\lambda_u)_n]$ is a $n$-vector of
+Lagrange multipliers for upper bound constraints (3.6).
+
+%\newpage
+
+Condition (3.14) is the {\it primal} (original) system of equality
+constraints (3.5).
+
+Condition (3.15) is the {\it dual} system of equality constraints.
+It requires the gradient of the objective function to be a linear
+combination of normals to the planes defined by constraints of the
+original problem.
+
+Condition (3.16) is the primal (original) system of bound constraints
+(3.6).
+
+Condition (3.17) (or (3.18) in case of maximization) is the dual system
+of bound constraints.
+
+Condition (3.19) is the {\it complementary slackness condition}. It
+requires, for each original (auxiliary or structural) variable $x_k$,
+that either its (lower or upper) bound must be active, or zero bound of
+the corresponding Lagrange multiplier ($(\lambda_l)_k$ or
+$(\lambda_u)_k$) must be active.
+
+In GLPK two multipliers $(\lambda_l)_k$ and $(\lambda_u)_k$ for each
+primal variable $x_k$, $k=1,\dots,m+n$, are combined into one
+multiplier:
+$$\lambda_k=(\lambda_l)_k+(\lambda_u)_k,\eqno(3.20)$$
+which is called a {\it dual variable} for $x_k$. This {\it cannot} lead
+to an ambiguity, because both lower and upper bounds of $x_k$ cannot be
+active at the same time,\footnote{If $x_k$ is a fixed variable, we can
+think it as double-bounded variable $l_k\leq x_k\leq u_k$, where
+$l_k=u_k.$} so at least one of $(\lambda_l)_k$ and $(\lambda_u)_k$ must
+be equal to zero, and because these multipliers have different signs,
+the combined multiplier, which is their sum, uniquely defines each of
+them.
+
+\def\arraystretch{1}
+
+Using dual variables $\lambda_k$ the dual system of bound constraints
+(3.17) and (3.18) can be written in the form of so called {\it ``rule of
+signs''} as follows:
+
+\medskip
+
+\begin{center}
+\begin{tabular}{|@{\,}c@{$\,$}|@{$\,$}c@{$\,$}|@{$\,$}c@{$\,$}|
+@{$\,$}c|c@{$\,$}|@{$\,$}c@{$\,$}|@{$\,$}c@{$\,$}|}
+\hline
+Original bound&\multicolumn{3}{c|}{Minimization}&\multicolumn{3}{c|}
+{Maximization}\\
+\cline{2-7}
+constraint&$(\lambda_l)_k$&$(\lambda_u)_k$&$(\lambda_l)_k+
+(\lambda_u)_k$&$(\lambda_l)_k$&$(\lambda_u)_k$&$(\lambda_l)_k+
+(\lambda_u)_k$\\
+\hline
+$-\infty<x_k<+\infty$&$=0$&$=0$&$\lambda_k=0$&$=0$&$=0$&$\lambda_k=0$\\
+$x_k\geq l_k$&$\geq 0$&$=0$&$\lambda_k\geq 0$&$\leq 0$&$=0$&$\lambda_k
+\leq0$\\
+$x_k\leq u_k$&$=0$&$\leq 0$&$\lambda_k\leq 0$&$=0$&$\geq 0$&$\lambda_k
+\geq0$\\
+$l_k\leq x_k\leq u_k$&$\geq 0$& $\leq 0$& $-\infty\!<\!\lambda_k\!<
+\!+\infty$
+&$\leq 0$& $\geq 0$& $-\infty\!<\!\lambda_k\!<\!+\infty$\\
+$x_k=l_k=u_k$&$\geq 0$& $\leq 0$& $-\infty\!<\!\lambda_k\!<\!+\infty$&
+$\leq 0$&
+$\geq 0$& $-\infty\!<\!\lambda_k\!<\!+\infty$\\
+\hline
+\end{tabular}
+\end{center}
+
+\medskip
+
+May note that each primal variable $x_k$ has its dual counterpart
+$\lambda_k$ and vice versa. This allows applying the same partition for
+the vector of dual variables as (3.7):
+$$\left(\begin{array}{@{}c@{}}\lambda_B\\\lambda_N\\\end{array}\right)=
+\Pi\lambda,\eqno(3.21)$$
+where $\lambda_B$ is a vector of dual variables for basic variables
+$x_B$, $\lambda_N$ is a vector of dual variables for non-basic variables
+$x_N$.
+
+By definition, bounds of basic variables are inactive constraints, so in
+any basic solution $\lambda_B=0$. Corresponding values of dual variables
+$\lambda_N$ for non-basic variables $x_N$ can be determined in the
+following way. From the dual system (3.15) we have:
+$$(I\ |-\!A)^T\pi+\lambda=(0\ |\ c)^T,\eqno(3.22)$$
+so multiplying both sides of (3.22) by matrix $\Pi$ gives:
+$$\Pi(I\ |-\!A)^T\pi+\Pi\lambda=\Pi(0\ |\ c)^T.\eqno(3.23)$$
+From (3.9) it follows that
+$$\Pi(I\ |-\!A)^T=[(I\ |-\!A)\Pi^T]^T=(B\ |\ N)^T.\eqno(3.24)$$
+Further, we can apply the partition (3.7) also to the vector of
+objective coefficients (see (3.4)):
+$$\left(\begin{array}{@{}c@{}}c_B\\c_N\\\end{array}\right)=
+\Pi\left(\begin{array}{@{}c@{}}0\\c\\\end{array}\right),\eqno(3.25)$$
+where $c_B$ is a vector of objective coefficients at basic variables,
+$c_N$ is a vector of objective coefficients at non-basic variables.
+Now, substituting (3.24), (3.21), and (3.25) into (3.23), leads to:
+$$(B\ |\ N)^T\pi+(\lambda_B\ |\ \lambda_N)^T=(c_B\ |\ c_N)^T,
+\eqno(3.26)$$
+and transposing both sides of (3.26) gives the system:
+$$\left(\begin{array}{@{}c@{}}B^T\\N^T\\\end{array}\right)\pi+
+\left(\begin{array}{@{}c@{}}\lambda_B\\\lambda_N\\\end{array}\right)=
+\left(\begin{array}{@{}c@{}}c_B\\c_T\\\end{array}\right),\eqno(3.27)$$
+which can be written as follows:
+$$\left\{
+\begin{array}{@{\ }r@{\ }c@{\ }r@{\ }c@{\ }l@{\ }}
+B^T\pi&+&\lambda_B&=&c_B\\
+N^T\pi&+&\lambda_N&=&c_N\\
+\end{array}
+\right.\eqno(3.28)
+$$
+Lagrange multipliers $\pi=(\pi_i)$ correspond to equality constraints
+(3.5) and therefore can have any sign. This allows resolving the first
+subsystem of (3.28) as follows:\footnote{$B^{-T}$ means $(B^T)^{-1}=
+(B^{-1})^T$.}
+$$\pi=B^{-T}(c_B-\lambda_B)=-B^{-T}\lambda_B+B^{-T}c_B,\eqno(3.29)$$
+and substitution of $\pi$ from (3.29) into the second subsystem of
+(3.28) gives:
+$$\lambda_N=-N^T\pi+c_N=N^TB^{-T}\lambda_B+(c_N-N^TB^{-T}c_B).
+\eqno(3.30)$$
+The latter system can be written in the following final form:
+$$\lambda_N=-\Xi^T\lambda_B+d,\eqno(3.31)$$
+where $\Xi$ is the simplex tableau (see (3.12)), and
+$$d=c_N-N^TB^{-T}c_B=c_N+\Xi^Tc_B\eqno(3.32)$$
+is the vector of so called {\it reduced costs} of non-basic variables.
+
+Above it was said that in any basic solution $\lambda_B=0$, so
+$\lambda_N=d$ as it follows from (3.31).
+
+The system (3.31) is equivalent to the system (3.15) in the sense that
+they both define the same set of points in the space of dual variables
+$\lambda$, which satisfy to these systems. If, moreover, values of all
+dual variables $\lambda_N$ (i.e. reduced costs $d$) satisfy to their
+bound constraints (i.e. to the ``rule of signs''; see the table above),
+the corresponding basic solution is called {\it dual feasible},
+otherwise {\it dual infeasible}. It is understood that any dual feasible
+solution satisfy to all constraints (3.15) and (3.17) (or (3.18) in case
+of maximization).
+
+It can be easily shown that the complementary slackness condition
+(3.19) is always satisfied for {\it any} basic solution.\footnote{Until
+double-bounded variables appear.} Therefore, a basic
+solution\footnote{It is assumed that a complete basic solution has the
+form $(x,\lambda)$, i.e. it includes primal as well as dual variables.}
+is {\it optimal} if and only if it is primal and dual feasible, because
+in this case it satifies to all the optimality conditions
+(3.14)---(3.19).
+
+\def\arraystretch{1.5}
+
+The meaning of reduced costs $d=(d_j)$ of non-basic variables can be
+explained in the following way. From (3.4), (3.7), and (3.25) it follows
+that:
+$$z=c_B^Tx_B+c_N^Tx_N+c_0.\eqno(3.33)$$
+Substituting $x_B$ from (3.11) into (3.33) we can eliminate basic
+variables and express the objective only through non-basic variables:
+$$
+\begin{array}{r@{\ }c@{\ }l}
+z&=&c_B^T(-B^{-1}Nx_N)+c_N^Tx_N+c_0=\\
+&=&(c_N^T-c_B^TB^{-1}N)x_N+c_0=\\
+&=&(c_N-N^TB^{-T}c_B)^Tx_N+c_0=\\
+&=&d^Tx_N+c_0.
+\end{array}\eqno(3.34)
+$$
+From (3.34) it is seen that reduced cost $d_j$ shows how the objective
+function $z$ depends on non-basic variable $(x_N)_j$ in the neighborhood
+of the current basic solution, i.e. while the current basis remains
+unchanged.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{LP basis routines}
+\label{lpbasis}
+
+\subsection{glp\_bf\_exists --- check if the basis factorization
+exists}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_bf_exists(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+If the basis factorization for the current basis associated with the
+specified problem object exists and therefore is available for
+computations, the routine \verb|glp_bf_exists| returns non-zero.
+Otherwise the routine returns zero.
+
+\para{Comments}
+
+Let the problem object have $m$ rows and $n$ columns. In GLPK the
+{\it basis matrix} $B$ is a square non-singular matrix of the order $m$,
+whose columns correspond to basic (auxiliary and/or structural)
+variables. It is defined by the following main
+equality:\footnote{For more details see Subsection \ref{basbgd},
+page \pageref{basbgd}.}
+$$(B\ |\ N)=(I\ |-\!A)\Pi^T,$$
+where $I$ is the unity matrix of the order $m$, whose columns correspond
+to auxiliary variables; $A$ is the original constraint
+$m\times n$-matrix, whose columns correspond to structural variables;
+$(I\ |-\!A)$ is the augmented constraint $m\times(m+n)$-matrix, whose
+columns correspond to all (auxiliary and structural) variables
+following in the original order; $\Pi$ is a permutation matrix of the
+order $m+n$; and $N$ is a rectangular $m\times n$-matrix, whose columns
+correspond to non-basic (auxiliary and/or structural) variables.
+
+For various reasons it may be necessary to solve linear systems with
+matrix $B$. To provide this possibility the GLPK implementation
+maintains an invertable form of $B$ (that is, some representation of
+$B^{-1}$) called the {\it basis factorization}, which is an internal
+component of the problem object. Typically, the basis factorization is
+computed by the simplex solver, which keeps it in the problem object
+to be available for other computations.
+
+Should note that any changes in the problem object, which affects the
+basis matrix (e.g. changing the status of a row or column, changing
+a basic column of the constraint matrix, removing an active constraint,
+etc.), invalidates the basis factorization. So before calling any API
+routine, which uses the basis factorization, the application program
+must make sure (using the routine \verb|glp_bf_exists|) that the
+factorization exists and therefore available for computations.
+
+%\newpage
+
+\subsection{glp\_factorize --- compute the basis factorization}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_factorize(glp_prob *P);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_factorize| computes the basis factorization for
+the current basis associated with the specified problem
+object.\footnote{The current basis is defined by the current statuses
+of rows (auxiliary variables) and columns (structural variables).}
+
+The basis factorization is computed from ``scratch'' even if it exists,
+so the application program may use the routine \verb|glp_bf_exists|,
+and, if the basis factorization already exists, not to call the routine
+\verb|glp_factorize| to prevent an extra work.
+
+The routine \verb|glp_factorize| {\it does not} compute components of
+the basic solution (i.e. primal and dual values).
+
+\returns
+
+\begin{retlist}
+0 & The basis factorization has been successfully computed.\\
+\verb|GLP_EBADB| & The basis matrix is invalid, because the number of
+basic (auxiliary and structural) variables is not the same as the number
+of rows in the problem object.\\
+
+\verb|GLP_ESING| & The basis matrix is singular within the working
+precision.\\
+
+\verb|GLP_ECOND| & The basis matrix is ill-conditioned, i.e. its
+condition number is too large.\\
+\end{retlist}
+
+\subsection{glp\_bf\_updated --- check if the basis factorization has
+been updated}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_bf_updated(glp_prob *P);
+\end{verbatim}
+
+\returns
+
+If the basis factorization has been just computed from ``scratch'', the
+routine \verb|glp_bf_updated| returns zero. Otherwise, if the
+factorization has been updated at least once, the routine returns
+non-zero.
+
+\para{Comments}
+
+{\it Updating} the basis factorization means recomputing it to reflect
+changes in the basis matrix. For example, on every iteration of the
+simplex method some column of the current basis matrix is replaced by
+a new column that gives a new basis matrix corresponding to the
+adjacent basis. In this case computing the basis factorization for the
+adjacent basis from ``scratch'' (as the routine \verb|glp_factorize|
+does) would be too time-consuming.
+
+On the other hand, since the basis factorization update is a numeric
+computational procedure, applying it many times may lead to
+accumulating round-off errors. Therefore the basis is periodically
+refactorized (reinverted) from ``scratch'' (with the routine
+\verb|glp_factorize|) that allows improving its numerical properties.
+
+The routine \verb|glp_bf_updated| allows determining if the basis
+factorization has been updated at least once since it was computed from
+``scratch''.
+
+\subsection{glp\_get\_bfcp --- retrieve basis factorization control
+parameters}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_get_bfcp(glp_prob *P, glp_bfcp *parm);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_get_bfcp| retrieves control parameters, which are
+used on computing and updating the basis factorization associated with
+the specified problem object.
+
+Current values of the control parameters are stored in
+a \verb|glp_bfcp| structure, which the parameter \verb|parm| points to.
+For a detailed description of the structure \verb|glp_bfcp| see
+comments to the routine \verb|glp_set_bfcp| in the next subsection.
+
+\para{Comments}
+
+The purpose of the routine \verb|glp_get_bfcp| is two-fold. First, it
+allows the application program obtaining current values of control
+parameters used by internal GLPK routines, which compute and update the
+basis factorization.
+
+The second purpose of this routine is to provide proper values for all
+fields of the structure \verb|glp_bfcp| in the case when the
+application program needs to change some control parameters.
+
+\subsection{glp\_set\_bfcp --- change basis factorization control
+parameters}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_bfcp(glp_prob *P, const glp_bfcp *parm);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_bfcp| changes control parameters, which are
+used by internal GLPK routines on computing and updating the basis
+factorization associated with the specified problem object.
+
+New values of the control parameters should be passed in a structure
+\verb|glp_bfcp|, which the parameter \verb|parm| points to. For a
+detailed description of the structure \verb|glp_bfcp| see paragraph
+``Control parameters'' below.
+
+The parameter \verb|parm| can be specified as \verb|NULL|, in which
+case all control parameters are reset to their default values.
+
+\para{Comments}
+
+Before changing some control parameters with the routine
+\verb|glp_set_bfcp| the application program should retrieve current
+values of all control parameters with the routine \verb|glp_get_bfcp|.
+This is needed for backward compatibility, because in the future there
+may appear new members in the structure \verb|glp_bfcp|.
+
+Note that new values of control parameters come into effect on a next
+computation of the basis factorization, not immediately.
+
+\para{Example}
+
+\begin{footnotesize}
+\begin{verbatim}
+glp_prob *lp;
+glp_bfcp parm;
+. . .
+/* retrieve current values of control parameters */
+glp_get_bfcp(lp, &parm);
+/* change the threshold pivoting tolerance */
+parm.piv_tol = 0.05;
+/* set new values of control parameters */
+glp_set_bfcp(lp, &parm);
+. . .
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+\para{Control parameters}
+
+This paragraph describes all basis factorization control parameters
+currently used in the package. Symbolic names of control parameters are
+names of corresponding members in the structure \verb|glp_bfcp|.
+
+\medskip
+
+{\tt int type} (default: {\tt GLP\_BF\_LUF + GLP\_BF\_FT})
+
+Basis factorization type:
+
+\verb~GLP_BF_LUF + GLP_BF_FT~ --- $LUF$, Forrest--Tomlin update;
+
+\verb~GLP_BF_LUF + GLP_BF_BG~ --- $LUF$, Schur complement,
+Bartels--Golub update;
+
+\verb~GLP_BF_LUF + GLP_BF_GR~ --- $LUF$, Schur complement,
+Givens rotation update;
+
+\verb~GLP_BF_BTF + GLP_BF_BG~ --- $BTF$, Schur complement,
+Bartels--Golub update;
+
+\verb~GLP_BF_BTF + GLP_BF_GR~ --- $BTF$, Schur complement,
+Givens rotation update.
+
+In case of \verb|GLP_BF_FT| the update is applied to matrix $U$, while
+in cases of \verb|GLP_BF_BG| and \verb|GLP_BF_GR| the update is applied
+to the Schur complement.
+
+%\medskip
+%
+%{\tt int lu\_size} (default: {\tt 0})
+%
+%The initial size of the Sparse Vector Area, in non-zeros, used on
+%computing $LU$-factorization of the basis matrix for the first time.
+%If this parameter is set to 0, the initial SVA size is determined
+%automatically.
+
+\medskip
+
+{\tt double piv\_tol} (default: {\tt 0.10})
+
+Threshold pivoting (Markowitz) tolerance, 0 $<$ \verb|piv_tol| $<$ 1,
+used on computing $LU$-factoriza\-tion of the basis matrix. Element
+$u_{ij}$ of the active submatrix of factor $U$ fits to be pivot if it
+satisfies to the stability criterion
+$|u_{ij}| >= {\tt piv\_tol}\cdot\max|u_{i*}|$, i.e. if it is not very
+small in the magnitude among other elements in the same row. Decreasing
+this parameter may lead to better sparsity at the expense of numerical
+accuracy, and vice versa.
+
+\medskip
+
+{\tt int piv\_lim} (default: {\tt 4})
+
+This parameter is used on computing $LU$-factorization of the basis
+matrix and specifies how many pivot candidates needs to be considered
+on choosing a pivot element, \verb|piv_lim| $\geq$ 1. If \verb|piv_lim|
+candidates have been considered, the pivoting routine prematurely
+terminates the search with the best candidate found.
+
+\medskip
+
+{\tt int suhl} (default: {\tt GLP\_ON})
+
+This parameter is used on computing $LU$-factorization of the basis
+matrix. Being set to {\tt GLP\_ON} it enables applying the following
+heuristic proposed by Uwe Suhl: if a column of the active submatrix has
+no eligible pivot candidates, it is no more considered until it becomes
+a column singleton. In many cases this allows reducing the time needed
+for pivot searching. To disable this heuristic the parameter
+\verb|suhl| should be set to {\tt GLP\_OFF}.
+
+\medskip
+
+{\tt double eps\_tol} (default: {\tt 1e-15})
+
+Epsilon tolerance, \verb|eps_tol| $\geq$ 0, used on computing
+$LU$-factorization of the basis matrix. If an element of the active
+submatrix of factor $U$ is less than \verb|eps_tol| in the magnitude,
+it is replaced by exact zero.
+
+%\medskip
+%
+%{\tt double max\_gro} (default: {\tt 1e+10})
+%
+%Maximal growth of elements of factor $U$, \verb|max_gro| $\geq$ 1,
+%allowable on computing $LU$-factorization of the basis matrix. If on
+%some elimination step the ratio $u_{big}/b_{max}$ (where $u_{big}$ is
+%the largest magnitude of elements of factor $U$ appeared in its active
+%submatrix during all the factorization process, $b_{max}$ is the
+%largest magnitude of elements of the basis matrix to be factorized),
+%the basis matrix is considered as ill-conditioned.
+
+\medskip
+
+{\tt int nfs\_max} (default: {\tt 100})
+
+Maximal number of additional row-like factors (entries of the eta
+file), \verb|nfs_max| $\geq$ 1, which can be added to
+$LU$-factorization of the basis matrix on updating it with the
+Forrest--Tomlin technique. This parameter is used only once, before
+$LU$-factorization is computed for the first time, to allocate working
+arrays. As a rule, each update adds one new factor (however, some
+updates may need no addition), so this parameter limits the number of
+updates between refactorizations.
+
+\medskip
+
+{\tt double upd\_tol} (default: {\tt 1e-6})
+
+Update tolerance, 0 $<$ \verb|upd_tol| $<$ 1, used on updating
+$LU$-factorization of the basis matrix with the Forrest--Tomlin
+technique. If after updating the magnitude of some diagonal element
+$u_{kk}$ of factor $U$ becomes less than
+${\tt upd\_tol}\cdot\max(|u_{k*}|, |u_{*k}|)$, the factorization is
+considered as inaccurate.
+
+\medskip
+
+{\tt int nrs\_max} (default: {\tt 100})
+
+Maximal number of additional rows and columns, \verb|nrs_max| $\geq$ 1,
+which can be added to $LU$-factorization of the basis matrix on
+updating it with the Schur complement technique. This parameter is used
+only once, before $LU$-factorization is computed for the first time, to
+allocate working arrays. As a rule, each update adds one new row and
+column (however, some updates may need no addition), so this parameter
+limits the number of updates between refactorizations.
+
+%\medskip
+%
+%{\tt int rs\_size} (default: {\tt 0})
+%
+%The initial size of the Sparse Vector Area, in non-zeros, used to
+%store non-zero elements of additional rows and columns introduced on
+%updating $LU$-factorization of the basis matrix with the Schur
+%complement technique. If this parameter is set to 0, the initial SVA
+%size is determined automatically.
+
+\subsection{glp\_get\_bhead --- retrieve the basis header information}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_bhead(glp_prob *P, int k);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_get_bhead| returns the basis header information
+for the current basis associated with the specified problem object.
+
+\returns
+
+If basic variable $(x_B)_k$, $1\leq k\leq m$, is $i$-th auxiliary
+variable ($1\leq i\leq m$), the routine returns $i$. Otherwise, if
+$(x_B)_k$ is $j$-th structural variable ($1\leq j\leq n$), the routine
+returns $m+j$. Here $m$ is the number of rows and $n$ is the number of
+columns in the problem object.
+
+\para{Comments}
+
+Sometimes the application program may need to know which original
+(auxiliary and structural) variable correspond to a given basic
+variable, or, that is the same, which column of the augmented
+constraint matrix $(I\ |-\!A)$ correspond to a given column of the
+basis matrix $B$.
+
+\def\arraystretch{1}
+
+The correspondence is defined as follows:\footnote{For more details see
+Subsection \ref{basbgd}, page \pageref{basbgd}.}
+$$\left(\begin{array}{@{}c@{}}x_B\\x_N\\\end{array}\right)=
+\Pi\left(\begin{array}{@{}c@{}}x_R\\x_S\\\end{array}\right)
+\ \ \Leftrightarrow
+\ \ \left(\begin{array}{@{}c@{}}x_R\\x_S\\\end{array}\right)=
+\Pi^T\left(\begin{array}{@{}c@{}}x_B\\x_N\\\end{array}\right),$$
+where $x_B$ is the vector of basic variables, $x_N$ is the vector of
+non-basic variables, $x_R$ is the vector of auxiliary variables
+following in their original order,\footnote{The original order of
+auxiliary and structural variables is defined by the ordinal numbers
+of corresponding rows and columns in the problem object.} $x_S$ is the
+vector of structural variables following in their original order, $\Pi$
+is a permutation matrix (which is a component of the basis
+factorization).
+
+Thus, if $(x_B)_k=(x_R)_i$ is $i$-th auxiliary variable, the routine
+returns $i$, and if $(x_B)_k=(x_S)_j$ is $j$-th structural variable,
+the routine returns $m+j$, where $m$ is the number of rows in the
+problem object.
+
+\subsection{glp\_get\_row\_bind --- retrieve row index in the basis
+header}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_row_bind(glp_prob *P, int i);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_row_bind| returns the index $k$ of basic
+variable $(x_B)_k$, $1\leq k\leq m$, which is $i$-th auxiliary variable
+(that is, the auxiliary variable corresponding to $i$-th row),
+$1\leq i\leq m$, in the current basis associated with the specified
+problem object, where $m$ is the number of rows. However, if $i$-th
+auxiliary variable is non-basic, the routine returns zero.
+
+\para{Comments}
+
+The routine \verb|glp_get_row_bind| is an inversion of the routine
+\verb|glp_get_bhead|; that is, if \linebreak
+\verb|glp_get_bhead|$(P,k)$ returns $i$,
+\verb|glp_get_row_bind|$(P,i)$ returns $k$, and vice versa.
+
+\subsection{glp\_get\_col\_bind --- retrieve column index in the basis
+header}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_get_col_bind(glp_prob *P, int j);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_get_col_bind| returns the index $k$ of basic
+variable $(x_B)_k$, $1\leq k\leq m$, which is $j$-th structural
+variable (that is, the structural variable corresponding to $j$-th
+column), $1\leq j\leq n$, in the current basis associated with the
+specified problem object, where $m$ is the number of rows, $n$ is the
+number of columns. However, if $j$-th structural variable is non-basic,
+the routine returns zero.
+
+\para{Comments}
+
+The routine \verb|glp_get_col_bind| is an inversion of the routine
+\verb|glp_get_bhead|; that is, if \linebreak
+\verb|glp_get_bhead|$(P,k)$ returns $m+j$,
+\verb|glp_get_col_bind|$(P,j)$ returns $k$, and vice versa.
+
+\subsection{glp\_ftran --- perform forward transformation}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_ftran(glp_prob *P, double x[]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_ftran| performs forward transformation (FTRAN),
+i.e. it solves the system $Bx=b$, where $B$ is the basis matrix
+associated with the specified problem object, $x$ is the vector of
+unknowns to be computed, $b$ is the vector of right-hand sides.
+
+On entry to the routine elements of the vector $b$ should be stored in
+locations \verb|x[1]|, \dots, \verb|x[m]|, where $m$ is the number of
+rows. On exit the routine stores elements of the vector $x$ in the same
+locations.
+
+\subsection{glp\_btran --- perform backward transformation}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_btran(glp_prob *P, double x[]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_btran| performs backward transformation (BTRAN),
+i.e. it solves the system $B^Tx=b$, where $B^T$ is a matrix transposed
+to the basis matrix $B$ associated with the specified problem object,
+$x$ is the vector of unknowns to be computed, $b$ is the vector of
+right-hand sides.
+
+On entry to the routine elements of the vector $b$ should be stored in
+locations \verb|x[1]|, \dots, \verb|x[m]|, where $m$ is the number of
+rows. On exit the routine stores elements of the vector $x$ in the same
+locations.
+
+\subsection{glp\_warm\_up --- ``warm up'' LP basis}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_warm_up(glp_prob *P);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_warm_up| ``warms up'' the LP basis for the
+specified problem object using current statuses assigned to rows and
+columns (that is, to auxiliary and structural variables).
+
+This operation includes computing factorization of the basis matrix
+(if it does not exist), computing primal and dual components of basic
+solution, and determining the solution status.
+
+\returns
+
+\begin{retlist}
+0 & The operation has been successfully performed.\\
+
+\verb|GLP_EBADB| & The basis matrix is invalid, because the number of
+basic (auxiliary and structural) variables is not the same as the
+number of rows in the problem object.\\
+
+\verb|GLP_ESING| & The basis matrix is singular within the working
+precision.\\
+
+\verb|GLP_ECOND| & The basis matrix is ill-conditioned, i.e. its
+condition number is too large.\\
+\end{retlist}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Simplex tableau routines}
+
+\subsection{glp\_eval\_tab\_row --- compute row of the tableau}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_eval_tab_row(glp_prob *P, int k, int ind[], double val[]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_eval_tab_row| computes a row of the current
+simplex tableau (see Subsection 3.1.1, formula (3.12)), which (row)
+corresponds to some basic variable specified by the parameter $k$ as
+follows: if $1\leq k\leq m$, the basic variable is $k$-th auxiliary
+variable, and if $m+1\leq k\leq m+n$, the basic variable is $(k-m)$-th
+structural variable, where $m$ is the number of rows and $n$ is the
+number of columns in the specified problem object. The basis
+factorization must exist.
+
+The computed row shows how the specified basic variable depends on
+non-basic variables:
+$$x_k=(x_B)_i=\xi_{i1}(x_N)_1+\xi_{i2}(x_N)_2+\dots+\xi_{in}(x_N)_n,$$
+where $\xi_{i1}$, $\xi_{i2}$, \dots, $\xi_{in}$ are elements of the
+simplex table row, $(x_N)_1$, $(x_N)_2$, \dots, $(x_N)_n$ are non-basic
+(auxiliary and structural) variables.
+
+The routine stores column indices and corresponding numeric values of
+non-zero elements of the computed row in unordered sparse format in
+locations \verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|,
+\dots, \verb|val[len]|, respectively, where $0\leq{\tt len}\leq n$ is
+the number of non-zero elements in the row returned on exit.
+
+Element indices stored in the array \verb|ind| have the same sense as
+index $k$, i.e. indices 1 to $m$ denote auxiliary variables while
+indices $m+1$ to $m+n$ denote structural variables (all these variables
+are obviously non-basic by definition).
+
+\returns
+
+The routine \verb|glp_eval_tab_row| returns \verb|len|, which is the
+number of non-zero elements in the simplex table row stored in the
+arrays \verb|ind| and \verb|val|.
+
+\para{Comments}
+
+A row of the simplex table is computed as follows. At first, the
+routine checks that the specified variable $x_k$ is basic and uses the
+permutation matrix $\Pi$ (3.7) to determine index $i$ of basic variable
+$(x_B)_i$, which corresponds to $x_k$.
+
+The row to be computed is $i$-th row of the matrix $\Xi$ (3.12),
+therefore:
+$$\xi_i=e_i^T\Xi=-e_i^TB^{-1}N=-(B^{-T}e_i)^TN,$$
+where $e_i$ is $i$-th unity vector. So the routine performs BTRAN to
+obtain $i$-th row of the inverse $B^{-1}$:
+$$\varrho_i=B^{-T}e_i,$$
+and then computes elements of the simplex table row as inner products:
+$$\xi_{ij}=-\varrho_i^TN_j,\ \ j=1,2,\dots,n,$$
+where $N_j$ is $j$-th column of matrix $N$ (3.9), which (column)
+corresponds to non-basic variable $(x_N)_j$. The permutation matrix
+$\Pi$ is used again to convert indices $j$ of non-basic columns to
+original ordinal numbers of auxiliary and structural variables.
+
+\subsection{glp\_eval\_tab\_col --- compute column of the tableau}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_eval_tab_col(glp_prob *P, int k, int ind[], double val[]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_eval_tab_col| computes a column of the current
+simplex tableau (see Subsection 3.1.1, formula (3.12)), which (column)
+corresponds to some non-basic variable specified by the parameter $k$:
+if $1\leq k\leq m$, the non-basic variable is $k$-th auxiliary
+variable, and if $m+1\leq k\leq m+n$, the non-basic variable is
+$(k-m)$-th structural variable, where $m$ is the number of rows and $n$
+is the number of columns in the specified problem object. The basis
+factorization must exist.
+
+The computed column shows how basic variables depends on the specified
+non-basic variable $x_k=(x_N)_j$:
+$$
+\begin{array}{r@{\ }c@{\ }l@{\ }l}
+(x_B)_1&=&\dots+\xi_{1j}(x_N)_j&+\dots\\
+(x_B)_2&=&\dots+\xi_{2j}(x_N)_j&+\dots\\
+.\ \ .&.&.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\\
+(x_B)_m&=&\dots+\xi_{mj}(x_N)_j&+\dots\\
+\end{array}
+$$
+where $\xi_{1j}$, $\xi_{2j}$, \dots, $\xi_{mj}$ are elements of the
+simplex table column, $(x_B)_1$, $(x_B)_2$, \dots, $(x_B)_m$ are basic
+(auxiliary and structural) variables.
+
+The routine stores row indices and corresponding numeric values of
+non-zero elements of the computed column in unordered sparse format in
+locations \verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|,
+\dots, \verb|val[len]|, respectively, where $0\leq{\tt len}\leq m$ is
+the number of non-zero elements in the column returned on exit.
+
+Element indices stored in the array \verb|ind| have the same sense as
+index $k$, i.e. indices 1 to $m$ denote auxiliary variables while
+indices $m+1$ to $m+n$ denote structural variables (all these variables
+are obviously basic by definition).
+
+\returns
+
+The routine \verb|glp_eval_tab_col| returns \verb|len|, which is the
+number of non-zero elements in the simplex table column stored in the
+arrays \verb|ind| and \verb|val|.
+
+\para{Comments}
+
+A column of the simplex table is computed as follows. At first, the
+routine checks that the specified variable $x_k$ is non-basic and uses
+the permutation matrix $\Pi$ (3.7) to determine index $j$ of non-basic
+variable $(x_N)_j$, which corresponds to $x_k$.
+
+The column to be computed is $j$-th column of the matrix $\Xi$ (3.12),
+therefore:
+$$\Xi_j=\Xi e_j=-B^{-1}Ne_j=-B^{-1}N_j,$$
+where $e_j$ is $j$-th unity vector, $N_j$ is $j$-th column of matrix
+$N$ (3.9). So the routine performs FTRAN to transform $N_j$ to the
+simplex table column $\Xi_j=(\xi_{ij})$ and uses the permutation matrix
+$\Pi$ to convert row indices $i$ to original ordinal numbers of
+auxiliary and structural variables.
+
+\newpage
+
+\subsection{glp\_transform\_row --- transform explicitly specified row}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_transform_row(glp_prob *P, int len, int ind[], double val[]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_transform_row| performs the same operation as the
+routine \verb|glp_eval_tab_row| with exception that the row to be
+transformed is specified explicitly as a sparse vector.
+
+The explicitly specified row may be thought as a linear form:
+$$x=a_1x_{m+1}+a_2x_{m+2}+\dots+a_nx_{m+n},$$
+where $x$ is an auxiliary variable for this row, $a_j$ are coefficients
+of the linear form, $x_{m+j}$ are structural variables.
+
+On entry column indices and numerical values of non-zero coefficients
+$a_j$ of the specified row should be placed in locations \verb|ind[1]|,
+\dots, \verb|ind[len]| and \verb|val[1]|, \dots, \verb|val[len]|, where
+\verb|len| is number of non-zero coefficients.
+
+This routine uses the system of equality constraints and the current
+basis in order to express the auxiliary variable $x$ through the current
+non-basic variables (as if the transformed row were added to the problem
+object and the auxiliary variable $x$ were basic), i.e. the resultant
+row has the form:
+$$x=\xi_1(x_N)_1+\xi_2(x_N)_2+\dots+\xi_n(x_N)_n,$$
+where $\xi_j$ are influence coefficients, $(x_N)_j$ are non-basic
+(auxiliary and structural) variables, $n$ is the number of columns in
+the problem object.
+
+On exit the routine stores indices and numerical values of non-zero
+coefficients $\xi_j$ of the resultant row in locations \verb|ind[1]|,
+\dots, \verb|ind[len']| and \verb|val[1]|, \dots, \verb|val[len']|,
+where $0\leq{\tt len'}\leq n$ is the number of non-zero coefficients in
+the resultant row returned by the routine. Note that indices of
+non-basic variables stored in the array \verb|ind| correspond to
+original ordinal numbers of variables: indices 1 to $m$ mean auxiliary
+variables and indices $m+1$ to $m+n$ mean structural ones.
+
+\returns
+
+The routine \verb|glp_transform_row| returns \verb|len'|, the number of
+non-zero coefficients in the resultant row stored in the arrays
+\verb|ind| and \verb|val|.
+
+\newpage
+
+\subsection{glp\_transform\_col --- transform explicitly specified
+column}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_transform_col(glp_prob *P, int len, int ind[], double val[]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_transform_col| performs the same operation as the
+routine \verb|glp_eval_tab_col| with exception that the column to be
+transformed is specified explicitly as a sparse vector.
+
+The explicitly specified column may be thought as it were added to
+the original system of equality constraints:
+$$
+\begin{array}{l@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r}
+x_1&=&a_{11}x_{m+1}&+\dots+&a_{1n}x_{m+n}&+&a_1x \\
+x_2&=&a_{21}x_{m+1}&+\dots+&a_{2n}x_{m+n}&+&a_2x \\
+\multicolumn{7}{c}
+{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\
+x_m&=&a_{m1}x_{m+1}&+\dots+&a_{mn}x_{m+n}&+&a_mx \\
+\end{array}
+$$
+where $x_i$ are auxiliary variables, $x_{m+j}$ are structural variables
+(presented in the problem object), $x$ is a structural variable for the
+explicitly specified column, $a_i$ are constraint coefficients at $x$.
+
+On entry row indices and numerical values of non-zero coefficients
+$a_i$ of the specified column should be placed in locations
+\verb|ind[1]|, \dots, \verb|ind[len]| and \verb|val[1]|, \dots,
+\verb|val[len]|, where \verb|len| is number of non-zero coefficients.
+
+This routine uses the system of equality constraints and the current
+basis in order to express the current basic variables through the
+structural variable $x$ (as if the transformed column were added to the
+problem object and the variable $x$ were non-basic):
+$$
+\begin{array}{l@{\ }c@{\ }r}
+(x_B)_1&=\dots+&\xi_{1}x\\
+(x_B)_2&=\dots+&\xi_{2}x\\
+\multicolumn{3}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .}\\
+(x_B)_m&=\dots+&\xi_{m}x\\
+\end{array}
+$$
+where $\xi_i$ are influence coefficients, $x_B$ are basic (auxiliary
+and structural) variables, $m$ is the number of rows in the problem
+object.
+
+On exit the routine stores indices and numerical values of non-zero
+coefficients $\xi_i$ of the resultant column in locations \verb|ind[1]|,
+\dots, \verb|ind[len']| and \verb|val[1]|, \dots, \verb|val[len']|,
+where $0\leq{\tt len'}\leq m$ is the number of non-zero coefficients in
+the resultant column returned by the routine. Note that indices of basic
+variables stored in the array \verb|ind| correspond to original ordinal
+numbers of variables, i.e. indices 1 to $m$ mean auxiliary variables,
+indices $m+1$ to $m+n$ mean structural ones.
+
+\returns
+
+The routine \verb|glp_transform_col| returns \verb|len'|, the number of
+non-zero coefficients in the resultant column stored in the arrays
+\verb|ind| and \verb|val|.
+
+\newpage
+
+\subsection{glp\_prim\_rtest --- perform primal ratio test}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_prim_rtest(glp_prob *P, int len, const int ind[], const double val[],
+ int dir, double eps);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_prim_rtest| performs the primal ratio test using
+an explicitly specified column of the simplex table.
+
+The current basic solution associated with the LP problem object must
+be primal feasible.
+
+The explicitly specified column of the simplex table shows how the
+basic variables $x_B$ depend on some non-basic variable $x$ (which is
+not necessarily presented in the problem object):
+$$
+\begin{array}{l@{\ }c@{\ }r}
+(x_B)_1&=\dots+&\xi_{1}x\\
+(x_B)_2&=\dots+&\xi_{2}x\\
+\multicolumn{3}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .}\\
+(x_B)_m&=\dots+&\xi_{m}x\\
+\end{array}
+$$
+
+The column is specifed on entry to the routine in sparse format.
+Ordinal numbers of basic variables $(x_B)_i$ should be placed in
+locations \verb|ind[1]|, \dots, \verb|ind[len]|, where ordinal number
+1 to $m$ denote auxiliary variables, and ordinal numbers $m+1$ to $m+n$
+denote structural variables. The corresponding non-zero coefficients
+$\xi_i$ should be placed in locations
+\verb|val[1]|, \dots, \verb|val[len]|. The arrays \verb|ind| and
+\verb|val| are not changed by the routine.
+
+The parameter \verb|dir| specifies direction in which the variable $x$
+changes on entering the basis: $+1$ means increasing, $-1$ means
+decreasing.
+
+The parameter \verb|eps| is an absolute tolerance (small positive
+number, say, $10^{-9}$) used by the routine to skip $\xi_i$'s whose
+magnitude is less than \verb|eps|.
+
+The routine determines which basic variable (among those specified in
+\verb|ind[1]|, \dots, \verb|ind[len]|) reaches its (lower or upper)
+bound first before any other basic variables do, and which, therefore,
+should leave the basis in order to keep primal feasibility.
+
+\returns
+
+The routine \verb|glp_prim_rtest| returns the index, \verb|piv|, in the
+arrays \verb|ind| and \verb|val| corresponding to the pivot element
+chosen, $1\leq$ \verb|piv| $\leq$ \verb|len|. If the adjacent basic
+solution is primal unbounded, and therefore the choice cannot be made,
+the routine returns zero.
+
+\para{Comments}
+
+If the non-basic variable $x$ is presented in the LP problem object,
+the input column can be computed with the routine
+\verb|glp_eval_tab_col|; otherwise, it can be computed with the routine
+\verb|glp_transform_col|.
+
+\newpage
+
+\subsection{glp\_dual\_rtest --- perform dual ratio test}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_dual_rtest(glp_prob *P, int len, const int ind[], const double val[],
+ int dir, double eps);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_dual_rtest| performs the dual ratio test using
+an explicitly specified row of the simplex table.
+
+The current basic solution associated with the LP problem object must
+be dual feasible.
+
+The explicitly specified row of the simplex table is a linear form
+that shows how some basic variable $x$ (which is not necessarily
+presented in the problem object) depends on non-basic variables $x_N$:
+$$x=\xi_1(x_N)_1+\xi_2(x_N)_2+\dots+\xi_n(x_N)_n.$$
+
+The row is specified on entry to the routine in sparse format. Ordinal
+numbers of non-basic variables $(x_N)_j$ should be placed in locations
+\verb|ind[1]|, \dots, \verb|ind[len]|, where ordinal numbers 1 to $m$
+denote auxiliary variables, and ordinal numbers $m+1$ to $m+n$ denote
+structural variables. The corresponding non-zero coefficients $\xi_j$
+should be placed in locations \verb|val[1]|, \dots, \verb|val[len]|.
+The arrays \verb|ind| and \verb|val| are not changed by the routine.
+
+The parameter \verb|dir| specifies direction in which the variable $x$
+changes on leaving the basis: $+1$ means that $x$ goes on its lower
+bound, so its reduced cost (dual variable) is increasing (minimization)
+or decreasing (maximization); $-1$ means that $x$ goes on its upper
+bound, so its reduced cost is decreasing (minimization) or increasing
+(maximization).
+
+The parameter \verb|eps| is an absolute tolerance (small positive
+number, say, $10^{-9}$) used by the routine to skip $\xi_j$'s whose
+magnitude is less than \verb|eps|.
+
+The routine determines which non-basic variable (among those specified
+in \verb|ind[1]|, \dots,\linebreak \verb|ind[len]|) should enter the
+basis in order to keep dual feasibility, because its reduced cost
+reaches the (zero) bound first before this occurs for any other
+non-basic variables.
+
+\returns
+
+The routine \verb|glp_dual_rtest| returns the index, \verb|piv|, in the
+arrays \verb|ind| and \verb|val| corresponding to the pivot element
+chosen, $1\leq$ \verb|piv| $\leq$ \verb|len|. If the adjacent basic
+solution is dual unbounded, and therefore the choice cannot be made,
+the routine returns zero.
+
+\para{Comments}
+
+If the basic variable $x$ is presented in the LP problem object, the
+input row can be computed\linebreak with the routine
+\verb|glp_eval_tab_row|; otherwise, it can be computed with the routine
+\linebreak \verb|glp_transform_row|.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Post-optimal analysis routines}
+
+\subsection{glp\_analyze\_bound --- analyze active bound of non-basic
+variable}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_analyze_bound(glp_prob *P, int k, double *limit1, int *var1,
+ double *limit2, int *var2);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_analyze_bound| analyzes the effect of varying the
+active bound of specified non-basic variable.
+
+The non-basic variable is specified by the parameter $k$, where
+$1\leq k\leq m$ means auxiliary variable of corresponding row, and
+$m+1\leq k\leq m+n$ means structural variable (column).
+
+Note that the current basic solution must be optimal, and the basis
+factorization must exist.
+
+Results of the analysis have the following meaning.
+
+\verb|value1| is the minimal value of the active bound, at which the
+basis still remains primal feasible and thus optimal. \verb|-DBL_MAX|
+means that the active bound has no lower limit.
+
+\verb|var1| is the ordinal number of an auxiliary (1 to $m$) or
+structural ($m+1$ to $m+n$) basic variable, which reaches its bound
+first and thereby limits further decreasing the active bound being
+analyzed. if \verb|value1| = \verb|-DBL_MAX|, \verb|var1| is set to 0.
+
+\verb|value2| is the maximal value of the active bound, at which the
+basis still remains primal feasible and thus optimal. \verb|+DBL_MAX|
+means that the active bound has no upper limit.
+
+\verb|var2| is the ordinal number of an auxiliary (1 to $m$) or
+structural ($m+1$ to $m+n$) basic variable, which reaches its bound
+first and thereby limits further increasing the active bound being
+analyzed. if \verb|value2| = \verb|+DBL_MAX|, \verb|var2| is set to 0.
+
+The parameters \verb|value1|, \verb|var1|, \verb|value2|, \verb|var2|
+can be specified as \verb|NULL|, in which case corresponding information
+is not stored.
+
+\subsection{glp\_analyze\_coef --- analyze objective coefficient at
+basic variable}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_analyze_coef(glp_prob *P, int k,
+ double *coef1, int *var1, double *value1,
+ double *coef2, int *var2, double *value2);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_analyze_coef| analyzes the effect of varying the
+objective coefficient at specified basic variable.
+
+The basic variable is specified by the parameter $k$, where
+$1\leq k\leq m$ means auxiliary variable of corresponding row, and
+$m+1\leq k\leq m+n$ means structural variable (column).
+
+Note that the current basic solution must be optimal, and the basis
+factorization must exist.
+
+Results of the analysis have the following meaning.
+
+\verb|coef1| is the minimal value of the objective coefficient, at
+which the basis still remains dual feasible and thus optimal.
+\verb|-DBL_MAX| means that the objective coefficient has no lower
+limit.
+
+\verb|var1| is the ordinal number of an auxiliary (1 to $m$) or
+structural ($m+1$ to $m+n$) non-basic variable, whose reduced cost
+reaches its zero bound first and thereby limits further decreasing the
+objective coefficient being analyzed.
+If \verb|coef1| = \verb|-DBL_MAX|, \verb|var1| is set to 0.
+
+\verb|value1| is value of the basic variable being analyzed in an
+adjacent basis, which is defined as follows. Let the objective
+coefficient reach its minimal value (\verb|coef1|) and continue
+decreasing. Then the reduced cost of the limiting non-basic variable
+(\verb|var1|) becomes dual infeasible and the current basis becomes
+non-optimal that forces the limiting non-basic variable to enter the
+basis replacing there some basic variable that leaves the basis to keep
+primal feasibility. Should note that on determining the adjacent basis
+current bounds of the basic variable being analyzed are ignored as if
+it were free (unbounded) variable, so it cannot leave the basis. It may
+happen that no dual feasible adjacent basis exists, in which case
+\verb|value1| is set to \verb|-DBL_MAX| or \verb|+DBL_MAX|.
+
+\verb|coef2| is the maximal value of the objective coefficient, at
+which the basis still remains dual feasible and thus optimal.
+\verb|+DBL_MAX| means that the objective coefficient has no upper
+limit.
+
+\verb|var2| is the ordinal number of an auxiliary (1 to $m$) or
+structural ($m+1$ to $m+n$) non-basic variable, whose reduced cost
+reaches its zero bound first and thereby limits further increasing the
+objective coefficient being analyzed.
+If \verb|coef2| = \verb|+DBL_MAX|, \verb|var2| is set to 0.
+
+\verb|value2| is value of the basic variable being analyzed in an
+adjacent basis, which is defined exactly in the same way as
+\verb|value1| above with exception that now the objective coefficient
+is increasing.
+
+The parameters \verb|coef1|, \verb|var1|, \verb|value1|, \verb|coef2|,
+\verb|var2|, \verb|value2| can be specified as \verb|NULL|, in which
+case corresponding information is not stored.
+
+%* eof *%
diff --git a/glpk-5.0/doc/glpk05.tex b/glpk-5.0/doc/glpk05.tex
new file mode 100644
index 0000000..66e3c40
--- /dev/null
+++ b/glpk-5.0/doc/glpk05.tex
@@ -0,0 +1,1098 @@
+%* glpk05.tex *%
+
+\chapter{Branch-and-Cut API Routines}
+
+\section{Introduction}
+
+\subsection{Using the callback routine}
+
+The GLPK MIP solver based on the branch-and-cut method allows the
+application program to control the solution process. This is attained
+by means of the user-defined callback routine, which is called by the
+solver at various points of the branch-and-cut algorithm.
+
+The callback routine passed to the MIP solver should be written by the
+user and has the following specification:\footnote{The name
+{\tt foo\_bar} used here is a placeholder for the callback routine
+name.}
+
+\begin{verbatim}
+ void foo_bar(glp_tree *T, void *info);
+\end{verbatim}
+
+\noindent
+where \verb|tree| is a pointer to the data structure \verb|glp_tree|,
+which should be used on subsequent calls to branch-and-cut interface
+routines, and \verb|info| is a transit pointer passed to the routine
+\verb|glp_intopt|, which may be used by the application program to pass
+some external data to the callback routine.
+
+The callback routine is passed to the MIP solver through the control
+parameter structure \verb|glp_iocp| (see Chapter ``Basic API
+Routines'', Section ``Mixed integer programming routines'', Subsection
+``Solve MIP problem with the branch-and-cut method'') as follows:
+
+\begin{verbatim}
+ glp_prob *mip;
+ glp_iocp parm;
+ . . .
+ glp_init_iocp(&parm);
+ . . .
+ parm.cb_func = foo_bar;
+ parm.cb_info = ... ;
+ ret = glp_intopt(mip, &parm);
+ . . .
+\end{verbatim}
+
+To determine why it is being called by the MIP solver the callback
+routine should use the routine \verb|glp_ios_reason| (described in this
+section below), which returns a code indicating the reason for calling.
+Depending on the reason the callback routine may perform necessary
+actions to control the solution process.
+
+The reason codes, which correspond to various point of the
+branch-and-cut algorithm implemented in the MIP solver, are described
+in Subsection ``Reasons for calling the callback routine'' below.
+
+To ignore calls for reasons, which are not processed by the callback
+routine, it should simply return to the MIP solver doing nothing. For
+example:
+
+\begin{verbatim}
+void foo_bar(glp_tree *T, void *info)
+{ . . .
+ switch (glp_ios_reason(T))
+ { case GLP_IBRANCH:
+ . . .
+ break;
+ case GLP_ISELECT:
+ . . .
+ break;
+ default:
+ /* ignore call for other reasons */
+ break;
+ }
+ return;
+}
+\end{verbatim}
+
+To control the solution process as well as to obtain necessary
+information the callback routine may use the branch-and-cut API
+routines described in this chapter. Names of all these routines begin
+with `\verb|glp_ios_|'.
+
+\subsection{Branch-and-cut algorithm}
+
+This section gives a schematic description of the branch-and-cut
+algorithm as it is implemented in the GLPK MIP solver.
+
+{\it 1. Initialization}
+
+Set $L:=\{P_0\}$, where $L$ is the {\it active list} (i.e. the list of
+active subproblems), $P_0$ is the original MIP problem to be solved.
+
+Set $z^{\it best}:=+\infty$ (in case of minimization) or
+$z^{\it best}:=-\infty$ (in case of maximization), where $z^{\it best}$
+is {\it incumbent value}, i.e. an upper (minimization) or lower
+(maximization) global bound for $z^{\it opt}$, the optimal objective
+value for $P^0$.
+
+{\it 2. Subproblem selection}
+
+If $L=\varnothing$ then GO TO 9.
+
+Select $P\in L$, i.e. make active subproblem $P$ current.
+
+%\newpage
+
+{\it 3. Solving LP relaxation}
+
+Solve $P^{\it LP}$, which is LP relaxation of $P$.
+
+If $P^{\it LP}$ has no primal feasible solution then GO TO 8.
+
+Let $z^{\it LP}$ be the optimal objective value for $P^{\it LP}$.
+
+If $z^{\it LP}\geq z^{\it best}$ (minimization) or
+$z^{\it LP}\leq z^{\rm best}$ (), GO TO 8.
+
+{\it 4. Adding ``lazy'' constraints}
+
+Let $x^{\it LP}$ be the optimal solution to $P^{\it LP}$.
+
+If there are ``lazy'' constraints (i.e. essential constraints not
+included in the original MIP problem $P_0$), which are violated at the
+optimal point $x^{\it LP}$, add them to $P$, and GO TO 3.
+
+{\it 5. Check for integrality}
+
+Let $x_j$ be a variable, which is required to be integer, and let
+$x^{\it LP}_j\in x^{\it LP}$ be its value in the optimal solution to
+$P^{\it LP}$.
+
+If $x^{\it LP}_j$ are integral for all integer variables, then a better
+integer feasible solution is found. Store its components, set
+$z^{\it best}:=z^{\it LP}$, and GO TO 8.
+
+{\it 6. Adding cutting planes}
+
+If there are cutting planes (i.e. valid constraints for $P$),
+which are violated at the optimal point $x^{\it LP}$, add them to $P$,
+and GO TO 3.
+
+{\it 7. Branching}
+
+Select {\it branching variable} $x_j$, i.e. a variable, which is
+required to be integer, and whose value $x^{\it LP}_j\in x^{\it LP}$ is
+fractional in the optimal solution to $P^{\it LP}$.
+
+Create new subproblem $P^D$ (so called {\it down branch}), which is
+identical to the current subproblem $P$ with exception that the upper
+bound of $x_j$ is replaced by $\lfloor x^{\it LP}_j\rfloor$. (For
+example, if $x^{\it LP}_j=3.14$, the new upper bound of $x_j$ in the
+down branch will be $\lfloor 3.14\rfloor=3$.)
+
+Create new subproblem $P^U$ (so called {\it up branch}), which is
+identical to the current subproblem $P$ with exception that the lower
+bound of $x_j$ is replaced by $\lceil x^{\it LP}_j\rceil$. (For example,
+if $x^{\it LP}_j=3.14$, the new lower bound of $x_j$ in the up branch
+will be $\lceil 3.14\rceil=4$.)
+
+Set $L:=(L\backslash\{P\})\cup\{P^D,P^U\}$, i.e. remove the current
+subproblem $P$ from the active list $L$ and add two new subproblems
+$P^D$ and $P^U$ to it. Then GO TO 2.
+
+{\it 8. Pruning}
+
+Remove from the active list $L$ all subproblems (including the current
+one), whose local bound $\widetilde{z}$ is not better than the global
+bound $z^{\it best}$, i.e. set $L:=L\backslash\{P\}$ for all $P$, where
+$\widetilde{z}\geq z^{\it best}$ (in case of minimization) or
+$\widetilde{z}\leq z^{\it best}$ (in case of maximization), and then
+GO TO 2.
+
+The local bound $\widetilde{z}$ for subproblem $P$ is an lower
+(minimization) or upper (maximization) bound for integer optimal
+solution to {\it this} subproblem (not to the original problem). This
+bound is local in the sense that only subproblems in the subtree rooted
+at node $P$ cannot have better integer feasible solutions. Note that
+the local bound is not necessarily the optimal objective value to LP
+relaxation $P^{\it LP}$.
+
+{\it 9. Termination}
+
+If $z^{\it best}=+\infty$ (in case of minimization) or
+$z^{\it best}=-\infty$ (in case of maximization), the original problem
+$P_0$ has no integer feasible solution. Otherwise, the last integer
+feasible solution stored on step 5 is the integer optimal solution to
+the original problem $P_0$ with $z^{\it opt}=z^{\it best}$. STOP.
+
+\subsection{The search tree}
+
+On the branching step of the branch-and-cut algorithm the current
+subproblem is divided into two\footnote{In more general cases the
+current subproblem may be divided into more than two subproblems.
+However, currently such feature is not used in GLPK.} new subproblems,
+so the set of all subproblems can be represented in the form of a rooted
+tree, which is called the {\it search} or {\it branch-and-bound} tree.
+An example of the search tree is shown on Fig.~1. Each node of the
+search tree corresponds to a subproblem, so the terms `node' and
+`subproblem' may be used synonymously.
+
+\begin{figure}[t]
+\noindent\hfil
+\xymatrix @R=20pt @C=10pt
+{&&&&&&*+<14pt>[o][F=]{A}\ar@{-}[dllll]\ar@{-}[dr]\ar@{-}[drrrr]&&&&\\
+&&*+<14pt>[o][F=]{B}\ar@{-}[dl]\ar@{-}[dr]&&&&&*+<14pt>[o][F=]{C}
+\ar@{-}[dll]\ar@{-}[dr]\ar@{-}[drrr]&&&*+<14pt>[o][F-]{\times}\\
+&*+<14pt>[o][F-]{\times}\ar@{-}[dl]\ar@{-}[d]\ar@{-}[dr]&&
+*+<14pt>[o][F-]{D}&&*+<14pt>[o][F=]{E}\ar@{-}[dl]\ar@{-}[dr]&&&
+*+<14pt>[o][F=]{F}\ar@{-}[dl]\ar@{-}[dr]&&*+<14pt>[o][F-]{G}\\
+*+<14pt>[o][F-]{\times}&*+<14pt>[o][F-]{\times}&*+<14pt>[o][F-]{\times}
+&&*+<14pt>[][F-]{H}&&*+<14pt>[o][F-]{I}&*+<14pt>[o][F-]{\times}&&
+*+<14pt>[o][F-]{J}&\\}
+
+\bigskip
+
+\noindent\hspace{.8in}
+\xymatrix @R=11pt
+{*+<20pt>[][F-]{}&*\txt{\makebox[1in][l]{Current}}&&
+*+<20pt>[o][F-]{}&*\txt{\makebox[1in][l]{Active}}\\
+*+<20pt>[o][F=]{}&*\txt{\makebox[1in][l]{Non-active}}&&
+*+<14pt>[o][F-]{\times}&*\txt{\makebox[1in][l]{Fathomed}}\\
+}
+
+\bigskip
+
+\begin{center}
+Fig. 1. An example of the search tree.
+\end{center}
+\end{figure}
+
+In GLPK each node may have one of the following four statuses:
+
+%\vspace*{-8pt}
+
+%\begin{itemize}
+\Item{---}{\it current node} is the active node currently being
+processed;
+
+\Item{---}{\it active node} is a leaf node, which still has to be
+processed;
+
+\Item{---}{\it non-active node} is a node, which has been processed,
+but not fathomed;
+
+\Item{---}{\it fathomed node} is a node, which has been processed and
+fathomed.
+%\end{itemize}
+
+%\vspace*{-8pt}
+
+In the data structure representing the search tree GLPK keeps only
+current, active, and non-active nodes. Once a node has been fathomed,
+it is removed from the tree data structure.
+
+Being created each node of the search tree is assigned a distinct
+positive integer called the {\it subproblem reference number}, which
+may be used by the application program to specify a particular node of
+the tree. The root node corresponding to the original problem to be
+solved is always assigned the reference number 1.
+
+\subsection{Current subproblem}
+
+The current subproblem is a MIP problem corresponding to the current
+node of the search tree. It is represented as the GLPK problem object
+(\verb|glp_prob|) that allows the application program using API
+routines to access its content in the standard way. If the MIP
+presolver is not used, it is the original problem object passed to the
+routine \verb|glp_intopt|; otherwise, it is an internal problem object
+built by the MIP presolver.
+
+Note that the problem object is used by the MIP solver itself during
+the solution process for various purposes (to solve LP relaxations, to
+perfom branching, etc.), and even if the MIP presolver is not used, the
+current content of the problem object may differ from its original
+content. For example, it may have additional rows, bounds of some rows
+and columns may be changed, etc. In particular, LP segment of the
+problem object corresponds to LP relaxation of the current subproblem.
+However, on exit from the MIP solver the content of the problem object
+is restored to its original state.
+
+To obtain information from the problem object the application program
+may use any API routines, which do not change the object. Using API
+routines, which change the problem object, is restricted to stipulated
+cases.
+
+\subsection{The cut pool}
+
+The {\it cut pool} is a set of cutting plane constraints maintained by
+the MIP solver. It is used by the GLPK cut generation routines and may
+be used by the application program in the same way, i.e. rather than
+to add cutting plane constraints directly to the problem object the
+application program may store them to the cut pool. In the latter case
+the solver looks through the cut pool, selects efficient constraints,
+and adds them to the problem object.
+
+\subsection{Reasons for calling the callback routine}
+
+The callback routine may be called by the MIP solver for the following
+reasons.
+
+\para{Request for subproblem selection}
+
+The callback routine is called with the reason code \verb|GLP_ISELECT|
+if the current subproblem has been fathomed and therefore there is no
+current subproblem.
+
+In response the callback routine may select some subproblem from the
+active list and pass its reference number to the solver using the
+routine \verb|glp_ios_select_node|, in which case the solver continues
+the search from the specified active subproblem. If no selection is
+made by the callback routine, the solver uses a backtracking technique
+specified by the control parameter \verb|bt_tech|.
+
+To explore the active list (i.e. active nodes of the branch-and-bound
+tree) the callback routine may use the routines \verb|glp_ios_next_node|
+and \verb|glp_ios_prev_node|.
+
+\para{Request for preprocessing}
+
+The callback routine is called with the reason code \verb|GLP_IPREPRO|
+if the current subproblem has just been selected from the active list
+and its LP relaxation is not solved yet.
+
+In response the callback routine may perform some preprocessing of the
+current subproblem like tightening bounds of some variables or removing
+bounds of some redundant constraints.
+
+\para{Request for row generation}
+
+The callback routine is called with the reason code \verb|GLP_IROWGEN|
+if LP relaxation of the current subproblem has just been solved to
+optimality and its objective value is better than the best known
+integer feasible solution.
+
+In response the callback routine may add one or more ``lazy''
+constraints (rows), which are violated by the current optimal solution
+of LP relaxation, using API routines \verb|glp_add_rows|,
+\verb|glp_set_row_name|, \verb|glp_set_row_bnds|, and
+\verb|glp_set_mat_row|, in which case the solver will perform
+re-optimization of LP relaxation. If there are no violated constraints,
+the callback routine should just return.
+
+Note that components of optimal solution to LP relaxation can be
+obtained with API\linebreak routines \verb|glp_get_obj_val|,
+\verb|glp_get_row_prim|, \verb|glp_get_row_dual|,
+\verb|glp_get_col_prim|, and\linebreak \verb|glp_get_col_dual|.
+
+\para{Request for heuristic solution}
+
+The callback routine is called with the reason code \verb|GLP_IHEUR|
+if LP relaxation of the current subproblem being solved to optimality
+is integer infeasible (i.e. values of some structural variables of
+integer kind are fractional), though its objective value is better than
+the best known integer feasible solution.
+
+In response the callback routine may try applying a primal heuristic
+to find an integer feasible solution,\footnote{Integer feasible to the
+original MIP problem, not to the current subproblem.} which is better
+than the best known one. In case of success the callback routine may
+store such better solution in the problem object using the routine
+\verb|glp_ios_heur_sol|.
+
+\para{Request for cut generation}
+
+The callback routine is called with the reason code \verb|GLP_ICUTGEN|
+if LP relaxation of the current subproblem being solved to optimality
+is integer infeasible (i.e. values of some structural variables of
+integer kind are fractional), though its objective value is better than
+the best known integer feasible solution.
+
+In response the callback routine may reformulate the {\it current}
+subproblem (before it will be splitted up due to branching) by adding
+to the problem object one or more {\it cutting plane constraints},
+which cut off the fractional optimal point from the MIP
+polytope.\footnote{Since these constraints are added to the current
+subproblem, they may be globally as well as locally valid.}
+
+Adding cutting plane constraints may be performed in two ways.
+One way is the same as for the reason code \verb|GLP_IROWGEN| (see
+above), in which case the callback routine adds new rows corresponding
+to cutting plane constraints directly to the current subproblem.
+
+The other way is to add cutting plane constraints to the
+{\it cut pool}, a set of cutting plane constraints maintained by the
+solver, rather than directly to the current subproblem. In this case
+after return from the callback routine the solver looks through the
+cut pool, selects efficient cutting plane constraints, adds them to the
+current subproblem, drops other constraints, and then performs
+re-optimization.
+
+\para{Request for branching}
+
+The callback routine is called with the reason code \verb|GLP_IBRANCH|
+if LP relaxation of the current subproblem being solved to optimality
+is integer infeasible (i.e. values of some structural variables of
+integer kind are fractional), though its objective value is better than
+the best known integer feasible solution.
+
+In response the callback routine may choose some variable suitable for
+branching (i.e. integer variable, whose value in optimal solution to
+LP relaxation of the current subproblem is fractional) and pass its
+ordinal number to the solver using the routine
+\verb|glp_ios_branch_upon|, in which case the solver splits the current
+subproblem in two new subproblems and continues the search.
+If no choice is made by the callback routine, the solver uses
+a branching technique specified by the control parameter \verb|br_tech|.
+
+\para{Better integer solution found}
+
+The callback routine is called with the reason code \verb|GLP_IBINGO|
+if LP relaxation of the current subproblem being solved to optimality
+is integer feasible (i.e. values of all structural variables of integer
+kind are integral within the working precision) and its objective value
+is better than the best known integer feasible solution.
+
+Optimal solution components for LP relaxation can be obtained in the
+same way as for the reason code \verb|GLP_IROWGEN| (see above).
+
+Components of the new MIP solution can be obtained with API routines
+\verb|glp_mip_obj_val|, \verb|glp_mip_row_val|, and
+\verb|glp_mip_col_val|. Note, however, that due to row/cut generation
+there may be additional rows in the problem object.
+
+The difference between optimal solution to LP relaxation and
+corresponding MIP solution is that in the former case some structural
+variables of integer kind (namely, basic variables) may have values,
+which are close to nearest integers within the working precision, while
+in the latter case all such variables have exact integral values.
+
+The reason \verb|GLP_IBINGO| is intended only for informational
+purposes, so the callback routine should not modify the problem object
+in this case.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Basic routines}
+
+\subsection{glp\_ios\_reason --- determine reason for calling the
+callback routine}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_ios_reason(glp_tree *T);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_ios_reason| returns a code, which indicates why
+the user-defined callback routine is being called:
+
+\verb|GLP_ISELECT| --- request for subproblem selection;
+
+\verb|GLP_IPREPRO| --- request for preprocessing;
+
+\verb|GLP_IROWGEN| --- request for row generation;
+
+\verb|GLP_IHEUR | --- request for heuristic solution;
+
+\verb|GLP_ICUTGEN| --- request for cut generation;
+
+\verb|GLP_IBRANCH| --- request for branching;
+
+\verb|GLP_IBINGO | --- better integer solution found.
+
+\subsection{glp\_ios\_get\_prob --- access the problem object}
+
+\synopsis
+
+\begin{verbatim}
+ glp_prob *glp_ios_get_prob(glp_tree *T);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_ios_get_prob| can be called from the user-defined
+callback routine to access the problem object, which is used by the MIP
+solver. It is the original problem object passed to the routine
+\verb|glp_intopt| if the MIP presolver is not used; otherwise it is an
+internal problem object built by the presolver.
+
+\returns
+
+The routine \verb|glp_ios_get_prob| returns a pointer to the problem
+object used by the MIP solver.
+
+\para{Comments}
+
+To obtain various information about the problem instance the callback
+routine can access the problem object (i.e. the object of type
+\verb|glp_prob|) using the routine \verb|glp_ios_get_prob|. It is the
+original problem object passed to the routine \verb|glp_intopt| if the
+MIP presolver is not used; otherwise it is an internal problem object
+built by the presolver.
+
+\newpage
+
+\subsection{glp\_ios\_row\_attr --- determine additional row
+attributes}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_ios_row_attr(glp_tree *T, int i, glp_attr *attr);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_ios_row_attr| retrieves additional attributes of
+$i$-th row of the current subproblem and stores them in the structure
+\verb|glp_attr|, which the parameter \verb|attr| points to.
+
+The structure \verb|glp_attr| has the following fields:
+
+\medskip
+
+{\tt int level}
+
+Subproblem level at which the row was created. (If \verb|level| = 0,
+the row was added either to the original problem object passed to the
+routine \verb|glp_intopt| or to the root subproblem on generating
+``lazy'' or/and cutting plane constraints.)
+
+\medskip
+
+{\tt int origin}
+
+The row origin flag:
+
+\verb|GLP_RF_REG | --- regular constraint;
+
+\verb|GLP_RF_LAZY| --- ``lazy'' constraint;
+
+\verb|GLP_RF_CUT | --- cutting plane constraint.
+
+\medskip
+
+{\tt int klass}
+
+The row class descriptor, which is a number passed to the routine
+\verb|glp_ios_add_row| as its third parameter. If the row is a cutting
+plane constraint generated by the solver, its class may be the
+following:
+
+\verb|GLP_RF_GMI | --- Gomory's mixed integer cut;
+
+\verb|GLP_RF_MIR | --- mixed integer rounding cut;
+
+\verb|GLP_RF_COV | --- mixed cover cut;
+
+\verb|GLP_RF_CLQ | --- clique cut.
+
+\subsection{glp\_ios\_mip\_gap --- compute relative MIP gap}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_ios_mip_gap(glp_tree *T);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_ios_mip_gap| computes the relative MIP gap (also
+called {\it duality gap}) with the following formula:
+$${\tt gap} = \frac{|{\tt best\_mip} - {\tt best\_bnd}|}
+{|{\tt best\_mip}| + {\tt DBL\_EPSILON}}$$
+where \verb|best_mip| is the best integer feasible solution found so
+far, \verb|best_bnd| is the best (global) bound. If no integer feasible
+solution has been found yet, \verb|gap| is set to \verb|DBL_MAX|.
+
+\newpage
+
+\returns
+
+The routine \verb|glp_ios_mip_gap| returns the relative MIP gap.
+
+\para{Comments}
+
+The relative MIP gap is used to measure the quality of the best integer
+feasible solution found so far, because the optimal solution value
+$z^*$ for the original MIP problem always lies in the range
+$${\tt best\_bnd}\leq z^*\leq{\tt best\_mip}$$
+in case of minimization, or in the range
+$${\tt best\_mip}\leq z^*\leq{\tt best\_bnd}$$
+in case of maximization.
+
+To express the relative MIP gap in percents the value returned by the
+routine \verb|glp_ios_mip_gap| should be multiplied by 100\%.
+
+\subsection{glp\_ios\_node\_data --- access application-specific data}
+
+\synopsis
+
+\begin{verbatim}
+ void *glp_ios_node_data(glp_tree *T, int p);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_ios_node_data| allows the application accessing
+a memory block allocated for the subproblem (which may be active or
+inactive), whose reference number is $p$.
+
+The size of the block is defined by the control parameter
+\verb|cb_size| passed to the routine \verb|glp_intopt|. The block is
+initialized by binary zeros on creating corresponding subproblem, and
+its contents is kept until the subproblem will be removed from the
+tree.
+
+The application may use these memory blocks to store specific data for
+each subproblem.
+
+\returns
+
+The routine \verb|glp_ios_node_data| returns a pointer to the memory
+block for the specified subproblem. Note that if \verb|cb_size| = 0,
+the routine returns a null pointer.
+
+\subsection{glp\_ios\_select\_node --- select subproblem to continue
+the search}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_ios_select_node(glp_tree *T, int p);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_ios_select_node| can be called from the
+user-defined callback routine in response to the reason
+\verb|GLP_ISELECT| to select an active subproblem, whose reference
+number\linebreak is $p$. The search will be continued from the
+subproblem selected.
+
+\newpage
+
+\subsection{glp\_ios\_heur\_sol --- provide solution found by
+heuristic}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_ios_heur_sol(glp_tree *T, const double x[]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_ios_heur_sol| can be called from the user-defined
+callback routine in response to the reason \verb|GLP_IHEUR| to provide
+an integer feasible solution found by a primal heuristic.
+
+Primal values of {\it all} variables (columns) found by the heuristic
+should be placed in locations $x[1]$, \dots, $x[n]$, where $n$ is the
+number of columns in the original problem object. Note that the routine
+\verb|glp_ios_heur_sol| does {\it not} check primal feasibility of the
+solution provided.
+
+Using the solution passed in the array $x$ the routine computes value
+of the objective function. If the objective value is better than the
+best known integer feasible solution, the routine computes values of
+auxiliary variables (rows) and stores all solution components in the
+problem object.
+
+\returns
+
+If the provided solution is accepted, the routine
+\verb|glp_ios_heur_sol| returns zero. Otherwise, if the provided
+solution is rejected, the routine returns non-zero.
+
+\vspace*{-5pt}
+
+\subsection{glp\_ios\_can\_branch --- check if can branch upon
+specified variable}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_ios_can_branch(glp_tree *T, int j);
+\end{verbatim}
+
+\returns
+
+If $j$-th variable (column) can be used to branch upon, the routine
+returns non-zero, otherwise zero.
+
+\vspace*{-5pt}
+
+\subsection{glp\_ios\_branch\_upon --- choose variable to branch upon}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_ios_branch_upon(glp_tree *T, int j, int sel);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_ios_branch_upon| can be called from the
+user-defined callback routine in response to the reason
+\verb|GLP_IBRANCH| to choose a branching variable, whose ordinal number
+\linebreak is $j$. Should note that only variables, for which the
+routine \verb|glp_ios_can_branch| returns non-zero, can be used to
+branch upon.
+
+The parameter \verb|sel| is a flag that indicates which branch
+(subproblem) should be selected next to continue the search:
+
+\verb|GLP_DN_BRNCH| --- select down-branch;
+
+\verb|GLP_UP_BRNCH| --- select up-branch;
+
+\verb|GLP_NO_BRNCH| --- use general selection technique.
+
+\newpage
+
+\para{Comments}
+
+On branching the solver removes the current active subproblem from the
+active list and creates two new subproblems ({\it down-} and {\it
+up-branches}), which are added to the end of the active list. Note that
+the down-branch is created before the up-branch, so the last active
+subproblem will be the up-branch.
+
+The down- and up-branches are identical to the current subproblem with
+exception that in the down-branch the upper bound of $x_j$, the variable
+chosen to branch upon, is replaced by $\lfloor x_j^*\rfloor$, while in
+the up-branch the lower bound of $x_j$ is replaced by
+$\lceil x_j^*\rceil$, where $x_j^*$ is the value of $x_j$ in optimal
+solution to LP relaxation of the current subproblem. For example, if
+$x_j^*=3.14$, the new upper bound of $x_j$ in the down-branch is
+$\lfloor 3.14\rfloor=3$, and the new lower bound in the up-branch is
+$\lceil 3.14\rceil=4$.)
+
+Additionally the callback routine may select either down- or up-branch,
+from which the solver will continue the search. If none of the branches
+is selected, a general selection technique will be used.
+
+\subsection{glp\_ios\_terminate --- terminate the solution process}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_ios_terminate(glp_tree *T);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_ios_terminate| sets a flag indicating that the
+MIP solver should prematurely terminate the search.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{The search tree exploring routines}
+
+\subsection{glp\_ios\_tree\_size --- determine size of the search tree}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_ios_tree_size(glp_tree *T, int *a_cnt, int *n_cnt, int *t_cnt);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_ios_tree_size| stores the following three counts
+which characterize the current size of the search tree:
+
+\verb|a_cnt| is the current number of active nodes, i.e. the current
+size of the active list;
+
+\verb|n_cnt| is the current number of all (active and inactive) nodes;
+
+\verb|t_cnt| is the total number of nodes including those which have
+been already removed from the tree. This count is increased whenever
+a new node appears in the tree and never decreased.
+
+If some of the parameters \verb|a_cnt|, \verb|n_cnt|, \verb|t_cnt| is
+a null pointer, the corresponding count is not stored.
+
+\subsection{glp\_ios\_curr\_node --- determine current active
+subproblem}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_ios_curr_node(glp_tree *T);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_ios_curr_node| returns the reference number of
+the current active subproblem. However, if the current subproblem does
+not exist, the routine returns zero.
+
+\subsection{glp\_ios\_next\_node --- determine next active subproblem}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_ios_next_node(glp_tree *T, int p);
+\end{verbatim}
+
+\returns
+
+If the parameter $p$ is zero, the routine \verb|glp_ios_next_node|
+returns the reference number of the first active subproblem. However,
+if the tree is empty, zero is returned.
+
+If the parameter $p$ is not zero, it must specify the reference number
+of some active subproblem, in which case the routine returns the
+reference number of the next active subproblem. However, if there is
+no next active subproblem in the list, zero is returned.
+
+All subproblems in the active list are ordered chronologically, i.e.
+subproblem $A$ precedes subproblem $B$ if $A$ was created before $B$.
+
+\newpage
+
+\subsection{glp\_ios\_prev\_node --- determine previous active
+subproblem}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_ios_prev_node(glp_tree *T, int p);
+\end{verbatim}
+
+\returns
+
+If the parameter $p$ is zero, the routine \verb|glp_ios_prev_node|
+returns the reference number of the last active subproblem. However, if
+the tree is empty, zero is returned.
+
+If the parameter $p$ is not zero, it must specify the reference number
+of some active subproblem, in which case the routine returns the
+reference number of the previous active subproblem. However, if there
+is no previous active subproblem in the list, zero is returned.
+
+All subproblems in the active list are ordered chronologically, i.e.
+subproblem $A$ precedes subproblem $B$ if $A$ was created before $B$.
+
+\subsection{glp\_ios\_up\_node --- determine parent subproblem}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_ios_up_node(glp_tree *T, int p);
+\end{verbatim}
+
+\returns
+
+The parameter $p$ must specify the reference number of some (active or
+inactive) subproblem, in which case the routine \verb|iet_get_up_node|
+returns the reference number of its parent subproblem. However, if the
+specified subproblem is the root of the tree and, therefore, has
+no parent, the routine returns zero.
+
+\subsection{glp\_ios\_node\_level --- determine subproblem level}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_ios_node_level(glp_tree *T, int p);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_ios_node_level| returns the level of the
+subproblem, whose reference number is $p$, in the branch-and-bound
+tree. (The root subproblem has level 0, and the level of any other
+subproblem is the level of its parent plus one.)
+
+\subsection{glp\_ios\_node\_bound --- determine subproblem local bound}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_ios_node_bound(glp_tree *T, int p);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_ios_node_bound| returns the local bound for
+(active or inactive) subproblem, whose reference number is $p$.
+
+\newpage
+
+\para{Comments}
+
+The local bound for subproblem $p$ is an lower (minimization) or upper
+(maximization) bound for integer optimal solution to {\it this}
+subproblem (not to the original problem). This bound is local in the
+sense that only subproblems in the subtree rooted at node $p$ cannot
+have better integer feasible solutions.
+
+On creating a subproblem (due to the branching step) its local bound is
+inherited from its parent and then may get only stronger (never weaker).
+For the root subproblem its local bound is initially set to
+\verb|-DBL_MAX| (minimization) or \verb|+DBL_MAX| (maximization) and
+then improved as the root LP relaxation has been solved.
+
+Note that the local bound is not necessarily the optimal objective
+value to corresponding LP relaxation.
+
+\subsection{glp\_ios\_best\_node --- find active subproblem with best
+local bound}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_ios_best_node(glp_tree *T);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_ios_best_node| returns the reference number of
+the active subproblem, whose local bound is best (i.e. smallest in case
+of minimization or largest in case of maximization). However, if the
+tree is empty, the routine returns zero.
+
+\para{Comments}
+
+The best local bound is an lower (minimization) or upper (maximization)
+bound for integer optimal solution to the original MIP problem.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{The cut pool routines}
+
+\subsection{glp\_ios\_pool\_size --- determine current size of the cut
+pool}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_ios_pool_size(glp_tree *T);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_ios_pool_size| returns the current size of the
+cut pool, that is, the number of cutting plane constraints currently
+added to it.
+
+\subsection{glp\_ios\_add\_row --- add constraint to the cut pool}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_ios_add_row(glp_tree *T, const char *name, int klass, int flags,
+ int len, const int ind[], const double val[], int type, double rhs);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_ios_add_row| adds specified row (cutting plane
+constraint) to the cut pool.
+
+The cutting plane constraint should have the following format:
+$$\sum_{j\in J}a_jx_j\left\{\begin{array}{@{}c@{}}\geq\\\leq\\
+\end{array}\right\}b,$$
+where $J$ is a set of indices (ordinal numbers) of structural
+variables, $a_j$ are constraint coefficients, $x_j$ are structural
+variables, $b$ is the right-hand side.
+
+The parameter \verb|name| specifies a symbolic name assigned to the
+constraint (1 up to 255 characters). If it is \verb|NULL| or an empty
+string, no name is assigned.
+
+The parameter \verb|klass| specifies the constraint class, which must
+be either zero or a number in the range from 101 to 200.
+The application may use this attribute to distinguish between cutting
+plane constraints of different classes.\footnote{Constraint classes
+numbered from 1 to 100 are reserved for GLPK cutting plane generators.}
+
+The parameter \verb|flags| currently is not used and must be zero.
+
+Ordinal numbers of structural variables (i.e. column indices) $j\in J$
+and numerical values of corresponding constraint coefficients $a_j$
+should be placed in locations \verb|ind[1]|, \dots, \verb|ind[len]| and
+\verb|val[1]|, \dots, \verb|val[len]|, respectively, where
+${\tt len}=|J|$ is the number of constraint coefficients,
+$0\leq{\tt len}\leq n$, and $n$ is the number of columns in the problem
+object. Coefficients with identical column indices are not allowed.
+Zero coefficients are allowed, however, they are ignored.
+
+The parameter \verb|type| specifies the constraint type as follows:
+
+\verb|GLP_LO| means inequality constraint $\Sigma a_jx_j\geq b$;
+
+\verb|GLP_UP| means inequality constraint $\Sigma a_jx_j\leq b$;
+
+\newpage
+
+The parameter \verb|rhs| specifies the right-hand side $b$.
+
+All cutting plane constraints in the cut pool are identified by their
+ordinal numbers 1, 2, \dots, $size$, where $size$ is the current size
+of the cut pool. New constraints are always added to the end of the cut
+pool, thus, ordinal numbers of previously added constraints are not
+changed.
+
+\returns
+
+The routine \verb|glp_ios_add_row| returns the ordinal number of the
+cutting plane constraint added, which is the new size of the cut pool.
+
+\para{Example}
+
+\begin{verbatim}
+/* generate triangle cutting plane:
+ x[i] + x[j] + x[k] <= 1 */
+. . .
+/* add the constraint to the cut pool */
+ind[1] = i, val[1] = 1.0;
+ind[2] = j, val[2] = 1.0;
+ind[3] = k, val[3] = 1.0;
+glp_ios_add_row(tree, NULL, TRIANGLE_CUT, 0, 3, ind, val, GLP_UP, 1.0);
+\end{verbatim}
+
+\para{Comments}
+
+Cutting plane constraints added to the cut pool are intended to be then
+added only to the {\it current} subproblem, so these constraints can be
+globally as well as locally valid. However, adding a constraint to the
+cut pool does not mean that it will be added to the current
+subproblem---it depends on the solver's decision: if the constraint
+seems to be efficient, it is moved from the pool to the current
+subproblem, otherwise it is simply dropped.\footnote{Globally valid
+constraints could be saved and then re-used for other subproblems, but
+currently such feature is not implemented.}
+
+Normally, every time the callback routine is called for cut generation,
+the cut pool is empty. On the other hand, the solver itself can
+generate cutting plane constraints (like Gomory's or mixed integer
+rounding cuts), in which case the cut pool may be non-empty.
+
+\subsection{glp\_ios\_del\_row --- remove constraint from the cut pool}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_ios_del_row(glp_tree *T, int i);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_ios_del_row| deletes $i$-th row (cutting plane
+constraint) from the cut pool, where $1\leq i\leq size$ is the ordinal
+number of the constraint in the pool, $size$ is the current size of the
+cut pool.
+
+Note that deleting a constraint from the cut pool leads to changing
+ordinal numbers of other constraints remaining in the pool. New ordinal
+numbers of the remaining constraints are assigned under assumption that
+the original order of constraints is not changed. Let, for example,
+there be four constraints $a$, $b$, $c$ and $d$ in the cut pool, which
+have ordinal numbers 1, 2, 3 and 4, respectively, and let constraint
+$b$ have been deleted. Then after deletion the remaining constraint $a$,
+$c$ and $d$ are assigned new ordinal numbers 1, 2 and 3, respectively.
+
+To find the constraint to be deleted the routine \verb|glp_ios_del_row|
+uses ``smart'' linear search, so it is recommended to remove
+constraints in a natural or reverse order and avoid removing them in
+a random order.
+
+\para{Example}
+
+\begin{verbatim}
+/* keep first 10 constraints in the cut pool and remove other
+ constraints */
+while (glp_ios_pool_size(tree) > 10)
+ glp_ios_del_row(tree, glp_ios_pool_size(tree));
+\end{verbatim}
+
+\subsection{glp\_ios\_clear\_pool --- remove all constraints from the
+cut pool}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_ios_clear_pool(glp_tree *T);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_ios_clear_pool| makes the cut pool empty deleting
+all existing rows (cutting plane constraints) from it.
+
+%* eof *%
diff --git a/glpk-5.0/doc/glpk06.tex b/glpk-5.0/doc/glpk06.tex
new file mode 100644
index 0000000..51bec18
--- /dev/null
+++ b/glpk-5.0/doc/glpk06.tex
@@ -0,0 +1,464 @@
+%* glpk06.tex *%
+
+\chapter{Miscellaneous API Routines}
+
+\section{GLPK environment routines}
+
+\subsection{glp\_init\_env --- initialize GLPK environment}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_init_env(void);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_init_env| initializes the GLPK environment.
+Normally the application program does not need to call this routine,
+because it is called automatically on the first call to any API
+routine.
+
+\returns
+
+\begin{retlist}
+0 & initialization successful;\\
+1 & environment is already initialized;\\
+2 & initialization failed (insufficient memory);\\
+3 & initialization failed (unsupported programming model).\\
+\end{retlist}
+
+\subsection{glp\_version --- determine library version}
+
+\synopsis
+
+\begin{verbatim}
+ const char *glp_version(void);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_version| returns a pointer to a null-terminated
+character string, which specifies the version of the GLPK library in
+the form \verb|"X.Y"|, where `\verb|X|' is the major version number,
+and `\verb|Y|' is the minor version number, for example, \verb|"4.16"|.
+
+\newpage
+
+\subsection{glp\_free\_env --- free GLPK environment}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_free_env(void);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_free_env| frees all resources used by GLPK
+routines (memory blocks, etc.) which are currently still in use.
+
+Normally the application program does not need to call this routine,
+because GLPK routines always free all unused resources. However, if
+the application program even has deleted all problem objects, there
+will be several memory blocks still allocated for the internal library
+needs. For some reasons the application program may want GLPK to free
+this memory, in which case it should call \verb|glp_free_env|.
+
+Note that a call to \verb|glp_free_env| invalidates all problem objects
+which still exist.
+
+\returns
+
+\begin{retlist}
+0 & termination successful;\\
+1 & environment is inactive (was not initialized).\\
+\end{retlist}
+
+\subsection{glp\_printf --- write formatted output to terminal}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_printf(const char *fmt, ...);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_printf| uses the format control string
+\verb|fmt| to format its parameters and writes the formatted output to
+the terminal.
+
+This routine is a replacement of the standard C function
+\verb|printf| and used by all GLPK routines to perform terminal
+output. The application program may use \verb|glp_printf| for the same
+purpose that allows controlling its terminal output with the routines
+\verb|glp_term_out| and \verb|glp_term_hook|.
+
+\subsection{glp\_vprintf --- write formatted output to terminal}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_vprintf(const char *fmt, va_list arg);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_vprintf| uses the format control string
+\verb|fmt| to format its parameters specified by the list \verb|arg|
+and writes the formatted output to the terminal.
+
+This routine is a replacement of the standard C function
+\verb|vprintf| and used by all GLPK routines to perform terminal
+output. The application program may use \verb|glp_vprintf| for the same
+purpose that allows controlling its terminal output with the routines
+\verb|glp_term_out| and \verb|glp_term_hook|.
+
+\newpage
+
+\subsection{glp\_term\_out --- enable/disable terminal output}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_term_out(int flag);
+\end{verbatim}
+
+\description
+
+Depending on the parameter flag the routine \verb|glp_term_out| enables
+or disables terminal output performed by glpk routines:
+
+\verb|GLP_ON | --- enable terminal output;
+
+\verb|GLP_OFF| --- disable terminal output.
+
+\returns
+
+The routine \verb|glp_term_out| returns the previous value of the
+terminal output flag.
+
+\subsection{glp\_term\_hook --- intercept terminal output}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_term_hook(int (*func)(void *info, const char *s), void *info);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_term_hook| installs the user-defined hook routine
+to intercept all terminal output performed by GLPK routines.
+
+%This feature can be used to redirect the terminal output to other
+%destination, for example, to a file or a text window.
+
+The parameter {\it func} specifies the user-defined hook routine. It is
+called from an internal printing routine, which passes to it two
+parameters: {\it info} and {\it s}. The parameter {\it info} is a
+transit pointer specified in corresponding call to the routine
+\verb|glp_term_hook|; it may be used to pass some additional information
+to the hook routine. The parameter {\it s} is a pointer to the null
+terminated character string, which is intended to be written to the
+terminal. If the hook routine returns zero, the printing routine writes
+the string {\it s} to the terminal in a usual way; otherwise, if the
+hook routine returns non-zero, no terminal output is performed.
+
+To uninstall the hook routine both parameters {\it func} and {\it info}
+should be specified as \verb|NULL|.
+
+\para{Example}
+
+\begin{footnotesize}
+\begin{verbatim}
+static int hook(void *info, const char *s)
+{ FILE *foo = info;
+ fputs(s, foo);
+ return 1;
+}
+
+int main(void)
+{ FILE *foo;
+ . . .
+ glp_term_hook(hook, foo); /* redirect terminal output */
+ . . .
+ glp_term_hook(NULL, NULL); /* resume terminal output */
+ . . .
+}
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+\subsection{glp\_open\_tee --- start copying terminal output}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_open_tee(const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_open_tee| starts copying all the terminal output
+to an output text file, whose name is specified by the character string
+\verb|fname|.
+
+\returns
+
+\begin{retlist}
+0 & operation successful;\\
+1 & copying terminal output is already active;\\
+2 & unable to create output file.\\
+\end{retlist}
+
+\subsection{glp\_close\_tee --- stop copying terminal output}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_close_tee(void);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_close_tee| stops copying the terminal output to
+the output text file previously open by the routine \verb|glp_open_tee|
+closing that file.
+
+\returns
+
+\begin{retlist}
+0 & operation successful;\\
+1 & copying terminal output was not started.\\
+\end{retlist}
+
+\subsection{glp\_error --- display error message and terminate
+execution}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_error(const char *fmt, ...);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_error| (implemented as a macro) formats its
+parameters using the format control string \verb|fmt|, writes the
+formatted message to the terminal, and then abnormally terminates the
+program.
+
+\newpage
+
+\subsection{glp\_at\_error --- check for error state}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_at_error(void);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_at_error| checks if the GLPK environment is at
+error state, i.~e.~if the call to the routine is (indirectly) made from
+the \verb|glp_error| routine via an user-defined hook routine.
+
+This routine can be used, for example, by a custom output handler
+(installed with the routine \verb|glp_term_hook|) to determine whether
+or not the message to be displayed is an error message.
+
+\returns
+
+If the GLPK environment is at error state, the routine returns
+non-zero, otherwise zero.
+
+\subsection{glp\_assert --- check logical condition}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_assert(int expr);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_assert| (implemented as a macro) checks
+a logical condition specified by the expression \verb|expr|. If the
+condition is true (non-zero), the routine does nothing; otherwise, if
+the condition is false (zero), the routine prints an error message and
+abnormally terminates the program.
+
+This routine is a replacement of the standard C function \verb|assert|
+and used by all GLPK routines to check program logic. The application
+program may use \verb|glp_assert| for the same purpose.
+
+\subsection{glp\_error\_hook --- install hook to intercept abnormal
+termination}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_error_hook(void (*func)(void *info), void *info);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_error_hook| installs a user-defined hook routine
+to intercept abnormal termination.
+
+The parameter \verb|func| specifies the user-defined hook routine. It
+is called from the routine \verb|glp_error| before the latter calls the
+abort function to abnormally terminate the application program because
+of fatal error. The parameter \verb|info| is a transit pointer,
+specified in the corresponding call to the routine
+\verb|glp_error_hook|; it may be used to pass some information to the
+hook routine.
+
+To uninstall the hook routine the parameters \verb|func| and \verb|info|
+should be specified as \verb|NULL|.
+
+If the hook routine returns, the application program is abnormally
+terminated. To prevent abnormal termnation the hook routine may perform
+a global jump using the standard function \verb|longjmp|, in which case
+the application program {\it must} call the routine \verb|glp_free_env|.
+
+\subsection{glp\_alloc --- allocate memory block}
+
+\synopsis
+
+\begin{verbatim}
+ void *glp_alloc(int n, int size);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_alloc| dynamically allocates a memory block of
+\verb|n|$\times$\verb|size| bytes long. Note that:
+
+1) the parameters \verb|n| and \verb|size| must be positive;
+
+2) having been allocated the memory block contains arbitrary data, that
+is, it is {\it not} initialized by binary zeros;
+
+3) if the block cannot be allocated due to insufficient memory, the
+routine prints an error message and abnormally terminates the program.
+
+This routine is a replacement of the standard C function \verb|malloc|
+and used by GLPK routines for dynamic memory allocation. The
+application program may use \verb|glp_alloc| for the same purpose.
+
+\returns
+
+The routine \verb|glp_alloc| returns a pointer to the memory block
+allocated. To free this block the routine \verb|glp_free| (not the
+standard C function \verb|free|!) should be used.
+
+\subsection{glp\_realloc --- reallocate memory block}
+
+\synopsis
+
+\begin{verbatim}
+ void *glp_realloc(void *ptr, int n, int size);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_realloc| dynamically reallocates a memory block
+pointed to by \verb|ptr|, which was previously allocated by the routine
+\verb|glp_alloc| or reallocated by this routine. Note that the pointer
+\verb|ptr| must be valid and must not be \verb|NULL|. The new size of
+the memory block is \verb|n|$\times$\verb|size| bytes long. Note that:
+
+1) both parameters \verb|n| and \verb|size| must be positive;
+
+2) if the block cannot be reallocated due to insufficient memory, the
+routine prints an error message and abnormally terminates the program.
+
+This routine is a replacement of the standard C function \verb|realloc|
+and used by GLPK routines for dynamic memory allocation. The
+application program may use \verb|glp_realloc| for the same purpose.
+
+\returns
+
+The routine \verb|glp_realloc| returns a pointer to the memory block
+reallocated. To free this block the routine \verb|glp_free| (not the
+standard C function \verb|free|!) should be used.
+
+\newpage
+
+\subsection{glp\_free --- free memory block}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_free(void *ptr);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_free| deallocates a memory block pointed to by
+\verb|ptr|, which was previously allocated by the routine
+\verb|glp_malloc| or reallocated by the routine \verb|glp_realloc|.
+Note that the pointer \verb|ptr| must be valid and must not be
+\verb|NULL|.
+
+This routine is a replacement of the standard C function \verb|free|
+and used by GLPK routines for dynamic memory allocation. The
+application program may use \verb|glp_free| for the same purpose.
+
+\subsection{glp\_mem\_usage --- get memory usage information}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_mem_usage(int *count, int *cpeak, size_t *total, size_t *tpeak);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mem_usage| reports some information about
+utilization of the memory by the routines \verb|glp_malloc|,
+\verb|glp_calloc|, and \verb|glp_free|. Information is stored to
+locations specified by corresponding parameters (see below). Any
+parameter can be specified as \verb|NULL|, in which case corresponding
+information is not stored.
+
+\verb|*count| is the number of currently allocated memory blocks.
+
+\verb|*cpeak| is the peak value of \verb|*count| reached since the
+initialization of the GLPK library environment.
+
+\verb|*total| is the total amount, in bytes, of currently allocated
+memory blocks.
+
+\verb|*tpeak| is the peak value of \verb|*total| reached since the
+initialization of the GLPK library envirionment.
+
+\para{Example}
+
+\begin{footnotesize}
+\begin{verbatim}
+glp_mem_usage(&count, NULL, NULL, NULL);
+printf("%d memory block(s) are still allocated\n", count);
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_mem\_limit --- set memory usage limit}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_mem_limit(int limit);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mem_limit| limits the amount of memory available
+for dynamic allocation (with the routines \verb|glp_malloc| and
+\verb|glp_calloc|) to \verb|limit| megabytes.
+
+%* eof *%
diff --git a/glpk-5.0/doc/glpk07.tex b/glpk-5.0/doc/glpk07.tex
new file mode 100644
index 0000000..004fe2e
--- /dev/null
+++ b/glpk-5.0/doc/glpk07.tex
@@ -0,0 +1,258 @@
+%* glpk07.tex *%
+
+\chapter{Installing GLPK on Your Computer}
+\label{install}
+
+\section{Downloading the distribution tarball}
+
+The distribution tarball of the most recent version of the GLPK
+package can be found on \url{http://ftp.gnu.org/gnu/glpk/} [via http]
+and \url{ftp://ftp.gnu.org/gnu/glpk/} [via FTP]. It can also be found
+on one of the FTP mirrors; see \url{http://www.gnu.org/prep/ftp.html}.
+Please use a mirror if possible.
+
+To make sure that the GLPK distribution tarball you have downloaded is
+intact you need to download the corresponding `\verb|.sig|' file and
+run a command like this:
+
+\begin{verbatim}
+ gpg --verify glpk-4.38.tar.gz.sig
+\end{verbatim}
+
+\noindent
+If that command fails because you do not have the required public key,
+run the following command to import it:
+
+\begin{verbatim}
+ gpg --keyserver keys.gnupg.net --recv-keys 5981E818
+\end{verbatim}
+
+\noindent
+and then re-run the previous command.
+
+\section{Unpacking the distribution tarball}
+
+The GLPK package (like all other GNU software) is distributed in the
+form of packed archive. This is one file named \verb|glpk-X.Y.tar.gz|,
+where {\it X} is the major version number and {\it Y} is the minor
+version number.
+
+In order to prepare the distribution for installation you need to copy
+the GLPK distribution file to a working subdirectory and then unpack
+and unarchive the distribution file with the following command:
+
+\begin{verbatim}
+ tar zx < glpk-X.Y.tar
+\end{verbatim}
+
+\newpage
+
+\section{Configuring the package}
+
+After unpacking and unarchiving the GLPK distribution you should
+configure the package,\linebreak i.e. automatically tune it for your
+platform.
+
+Normally, you should just \verb|cd| to the subdirectory \verb|glpk-X.Y|
+and run the configure script, e.g.
+
+\begin{verbatim}
+ ./configure
+\end{verbatim}
+
+The `\verb|configure|' shell script attempts to guess correct values
+for various system-dependent variables used during compilation. It uses
+those values to create a `\verb|Makefile|' in each directory of the
+package. It also creates file `\verb|config.h|' containing
+platform-dependent definitions. Finally, it creates a shell script
+`\verb|config.status|' that you can run in the future to recreate the
+current configuration, a file `\verb|config.cache|' that saves the
+results of its tests to speed up reconfiguring, and a file
+`\verb|config.log|' containing compiler output (useful mainly for
+debugging `\verb|configure|').
+
+Running `\verb|configure|' takes about a minute. While it is running,
+it displays some informational messages that tell you what it
+is doing. If you don't want to see these messages, run
+`\verb|configure|' with its standard output redirected to
+`\verb|dev/null|'; for example, `\verb|./configure > /dev/null|'.
+
+By default both static and shared versions of the GLPK library will be
+compiled. Compilation of the shared librariy can be turned off by
+specifying the `\verb|--disable-shared|' option to `\verb|configure|':
+
+\begin{verbatim}
+ ./configure --disable-shared
+\end{verbatim}
+
+\noindent
+If you encounter problems building the library try using the above
+option, because some platforms do not support shared libraries.
+
+The GLPK package has some optional features listed below. By default
+all these features are disabled. To enable a feature the corresponding
+option should be passed to the configure script.
+
+\verb|--with-gmp | Enable using the GNU MP bignum library
+
+This feature allows the exact simplex solver to use the GNU MP bignum
+library. If it is disabled, the exact simplex solver uses the GLPK
+bignum module, which provides the same functionality as GNU MP, however,
+it is much less efficient.
+
+For details about the GNU MP bignum library see its web page at
+\url{http://gmplib.org/}.
+
+\verb|--enable-dl | The same as `\verb|--enable-dl=ltdl|'
+
+\verb|--enable-dl=ltdl | Enable shared library support (GNU)
+
+\verb|--enable-dl=dlfcn | Enable shared library support (POSIX)
+
+Currently this feature is only needed to provide dynamic linking to
+ODBC and MySQL shared libraries (see below).
+
+For details about the GNU shared library support see the manual at
+\url{http://www.gnu.org/software/libtool/manual/}.
+
+\verb|--enable-odbc |
+Enable using ODBC table driver (\verb|libiodbc|)
+
+\verb|--enable-odbc=unix |
+Enable using ODBC table driver (\verb|libodbc|)
+
+This feature allows transmitting data between MathProg model objects
+and relational databases accessed through ODBC.
+
+For more details about this feature see the supplement ``Using Data
+Tables in the GNU MathProg Modeling Language'' (\verb|doc/tables.pdf|).
+
+\verb|--enable-mysql |
+Enable using MySQL table driver (\verb|libmysql|)
+
+This feature allows transmitting data between MathProg model objects
+and MySQL relational databases.
+
+For more details about this feature see the supplement ``Using Data
+Tables in the GNU MathProg Modeling Language'' (\verb|doc/tables.pdf|).
+
+\section{Compiling the package}
+
+Normally, you can compile (build) the package by typing the command:
+
+\begin{verbatim}
+ make
+\end{verbatim}
+
+\noindent
+It reads `\verb|Makefile|' generated by `\verb|configure|' and performs
+all necessary jobs.
+
+If you want, you can override the `\verb|make|' variables \verb|CFLAGS|
+and \verb|LDFLAGS| like this:
+
+\begin{verbatim}
+ make CFLAGS=-O2 LDFLAGS=-s
+\end{verbatim}
+
+To compile the package in a different directory from the one containing
+the source code, you must use a version of `\verb|make|' that supports
+`\verb|VPATH|' variable, such as GNU `\verb|make|'. `\verb|cd|' to the
+directory where you want the object files and executables to go and run
+the `\verb|configure|' script. `\verb|configure|' automatically checks
+for the source code in the directory that `\verb|configure|' is in and
+in `\verb|..|'. If for some reason `\verb|configure|' is not in the
+source code directory that you are configuring, then it will report
+that it can't find the source code. In that case, run `\verb|configure|'
+with the option `\verb|--srcdir=DIR|', where \verb|DIR| is the
+directory that contains the source code.
+
+Some systems require unusual options for compilation or linking that
+the `\verb|configure|' script does not know about. You can give
+`\verb|configure|' initial values for variables by setting them in the
+environment. Using a Bourne-compatible shell, you can do that on the
+command line like this:
+
+\begin{verbatim}
+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+\end{verbatim}
+
+\noindent
+Or on systems that have the `\verb|env|' program, you can do it like
+this:
+
+\begin{verbatim}
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+\end{verbatim}
+
+Here are the `\verb|make|' variables that you might want to override
+with environment variables when running `\verb|configure|'.
+
+For these variables, any value given in the environment overrides the
+value that `\verb|configure|' would choose:
+
+\verb|CC | C compiler program. The default is `\verb|cc|'.
+
+\verb|INSTALL | Program used to install files. The default value is
+`\verb|install|' if you have it,\\
+\verb| | otherwise `\verb|cp|'.
+
+For these variables, any value given in the environment is added to the
+value that `\verb|configure|' chooses:
+
+\verb|DEFS | Configuration options, in the form
+`\verb|-Dfoo -Dbar| \dots'.
+
+\verb|LIBS | Libraries to link with, in the form
+`\verb|-lfoo -lbar| \dots'.
+
+\section{Checking the package}
+
+To check the package, i.e. to run some tests included in the package,
+you can use the following command:
+
+\begin{verbatim}
+ make check
+\end{verbatim}
+
+\section{Installing the package}
+
+Normally, to install the GLPK package you should type the following
+command:
+
+\begin{verbatim}
+ make install
+\end{verbatim}
+
+\noindent
+By default, `\verb|make install|' will install the package's files in
+`\verb|usr/local/bin|', `\verb|usr/local/lib|', etc. You can specify an
+installation prefix other than `\verb|/usr/local|' by giving
+`\verb|configure|' the option `\verb|--prefix=PATH|'. Alternately, you
+can do so by consistently giving a value for the `\verb|prefix|'
+variable when you run `\verb|make|', e.g.
+
+\begin{verbatim}
+ make prefix=/usr/gnu
+ make prefix=/usr/gnu install
+\end{verbatim}
+
+After installing you can remove the program binaries and object files
+from the source directory by typing `\verb|make clean|'. To remove all
+files that `\verb|configure|' created (`\verb|Makefile|',
+`\verb|config.status|', etc.), just type `\verb|make distclean|'.
+
+The file `\verb|configure.ac|' is used to create `\verb|configure|' by
+a program called `\verb|autoconf|'. You only need it if you want to
+remake `\verb|configure|' using a newer version of `\verb|autoconf|'.
+
+\section{Uninstalling the package}
+
+To uninstall the GLPK package, i.e. to remove all the package's files
+from the system places, you can use the following command:
+
+\begin{verbatim}
+ make uninstall
+\end{verbatim}
+
+%* eof *%
diff --git a/glpk-5.0/doc/glpk08.tex b/glpk-5.0/doc/glpk08.tex
new file mode 100644
index 0000000..2636cb3
--- /dev/null
+++ b/glpk-5.0/doc/glpk08.tex
@@ -0,0 +1,740 @@
+%* glpk08.tex *%
+
+\chapter{MPS Format}
+\label{champs}
+
+\section{Fixed MPS Format}
+\label{secmps}
+
+The MPS format\footnote{The MPS format was developed in 1960's by IBM
+as input format for their mathematical programming system MPS/360.
+Today the MPS format is a most widely used format understood by most
+mathematical programming packages. This appendix describes only the
+features of the MPS format, which are implemented in the GLPK package.}
+is intended for coding LP/MIP problem data. This format assumes the
+formulation of LP/MIP problem (1.1)---(1.3) (see Section \ref{seclp},
+page \pageref{seclp}).
+
+{\it MPS file} is a text file, which contains two types of
+cards\footnote{In 1960's MPS file was a deck of 80-column punched
+cards, so the author decided to keep the word ``card'', which may be
+understood as ``line of text file''.}: indicator cards and data cards.
+
+Indicator cards determine a kind of succeeding data. Each indicator
+card has one word in uppercase letters beginning in column 1.
+
+Data cards contain problem data. Each data card is divided into six
+fixed fields:
+
+\begin{center}
+\begin{tabular}{lcccccc}
+& Field 1 & Field 2 & Field 3 & Field 4 & Field 5 & Field 6 \\
+\hline
+Columns & 2---3 & 5---12 & 15---22 & 25---36 & 40---47 & 50---61 \\
+Contents & Code & Name & Name & Number & Name & Number \\
+\end{tabular}
+\end{center}
+
+On a particular data card some fields may be optional.
+
+Names are used to identify rows, columns, and some vectors (see below).
+
+Aligning the indicator code in the field 1 to the left margin is
+optional.
+
+All names specified in the fields 2, 3, and 5 should contain from 1 up
+to 8 arbitrary characters (except control characters). If a name is
+placed in the field 3 or 5, its first character should not be the dollar
+sign `\verb|$|'. If a name contains spaces, the spaces are ignored.
+
+All numerical values in the fields 4 and 6 should be coded in the form
+$sxx$\verb|E|$syy$, where $s$ is the plus `\verb|+|' or the minus
+`\verb|-|' sign, $xx$ is a real number with optional decimal point,
+$yy$ is an integer decimal exponent. Any number should contain up to 12
+characters. If the sign $s$ is omitted, the plus sign is assumed. The
+exponent part is optional. If a number contains spaces, the spaces are
+ignored.
+
+%\newpage
+
+If a card has the asterisk `\verb|*|' in the column 1, this card is
+considered as a comment and ignored. Besides, if the first character in
+the field 3 or 5 is the dollar sign `\verb|$|', all characters from the
+dollar sign to the end of card are considered as a comment and ignored.
+
+MPS file should contain cards in the following order:
+
+%\vspace*{-8pt}
+
+%\begin{itemize}
+\Item{---}NAME indicator card;
+
+\Item{---}ROWS indicator card;
+
+\Item{---}data cards specifying rows (constraints);
+
+\Item{---}COLUMNS indicator card;
+
+\Item{---}data cards specifying columns (structural variables) and
+constraint coefficients;
+
+\Item{---}RHS indicator card;
+
+\Item{---}data cards specifying right-hand sides of constraints;
+
+\Item{---}RANGES indicator card;
+
+\Item{---}data cards specifying ranges for double-bounded constraints;
+
+\Item{---}BOUNDS indicator card;
+
+\Item{---}data cards specifying types and bounds of structural
+variables;
+
+\Item{---}ENDATA indicator card.
+%\end{itemize}
+
+%\vspace*{-8pt}
+
+{\it Section} is a group of cards consisting of an indicator card and
+data cards succeeding this indicator card. For example, the ROWS section
+consists of the ROWS indicator card and data cards specifying rows.
+
+The sections RHS, RANGES, and BOUNDS are optional and may be omitted.
+
+\section{Free MPS Format}
+
+{\it Free MPS format} is an improved version of the standard (fixed)
+MPS format described above.\footnote{This format was developed in the
+beginning of 1990's by IBM as an alternative to the standard fixed MPS
+format for Optimization Subroutine Library (OSL).} Note that all
+changes in free MPS format concern only the coding of data while the
+structure of data is the same for both fixed and free versions of the
+MPS format.
+
+In free MPS format indicator and data records\footnote{{\it Record} in
+free MPS format has the same meaning as {\it card} in fixed MPS format.}
+may have arbitrary length not limited to 80 characters. Fields of data
+records have no predefined positions, i.e. the fields may begin in any
+position, except position 1, which must be blank, and must be separated
+from each other by one or more blanks. However, the fields must appear
+in the same order as in fixed MPS format.
+
+%\newpage
+
+Symbolic names in fields 2, 3, and 5 may be longer than 8
+characters\footnote{GLPK allows symbolic names having up to 255
+characters.} and must not contain embedded blanks.
+
+Numeric values in fields 4 and 6 are limited to 12 characters and must
+not contain embedded blanks.
+
+Only six fields on each data record are used. Any other fields are
+ignored.
+
+If the first character of any field (not necessarily fields 3 and 5)
+is the dollar sign (\$), all characters from the dollar sign to the end
+of record are considered as a comment and ignored.
+
+\newpage
+
+\section{NAME indicator card}
+
+The NAME indicator card should be the first card in the MPS file
+(except optional comment cards, which may precede the NAME card). This
+card should contain the word \verb|NAME| in the columns 1---4 and the
+problem name in the field 3. The problem name is optional and may be
+omitted.
+
+\section{ROWS section}
+\label{secrows}
+
+The ROWS section should start with the indicator card, which contains
+the word \verb|ROWS| in the columns 1---4.
+
+Each data card in the ROWS section specifies one row (constraint) of
+the problem. All these data cards have the following format.
+
+`\verb|N|' in the field 1 means that the row is free (unbounded):
+$$-\infty < x_i = a_{i1}x_{m+1} + a_{i2}x_{m+2} + \dots + a_{in}x_{m+n}
+< +\infty;$$
+
+`\verb|L|' in the field 1 means that the row is of ``less than or equal
+to'' type:
+$$-\infty < x_i = a_{i1}x_{m+1} + a_{i2}x_{m+2} + \dots + a_{in}x_{m+n}
+\leq b_i;$$
+
+`\verb|G|' in the field 1 means that the row is of ``greater than or
+equal to'' type:
+$$b_i \leq x_i = a_{i1}x_{m+1} + a_{i2}x_{m+2} + \dots + a_{in}x_{m+n}
+< +\infty;$$
+
+`\verb|E|' in the field 1 means that the row is of ``equal to'' type:
+$$x_i = a_{i1}x_{m+1} + a_{i2}x_{m+2} + \dots + a_{in}x_{m+n} \leq
+b_i,$$
+where $b_i$ is a right-hand side. Note that each constraint has a
+corresponding implictly defined auxiliary variable ($x_i$ above), whose
+value is a value of the corresponding linear form, therefore row bounds
+can be considered as bounds of such auxiliary variable.
+
+The filed 2 specifies a row name (which is considered as the name of
+the corresponding auxiliary variable).
+
+%\newpage
+
+The fields 3, 4, 5, and 6 are not used and should be empty.
+
+Numerical values of all non-zero right-hand sides $b_i$ should be
+specified in the RHS section (see below). All double-bounded (ranged)
+constraints should be specified in the RANGES section (see below).
+
+\section{COLUMNS section}
+
+The COLUMNS section should start with the indicator card, which
+contains the word \verb|COLUMNS| in the columns 1---7.
+
+Each data card in the COLUMNS section specifies one or two constraint
+coefficients $a_{ij}$ and also introduces names of columns, i.e. names
+of structural variables. All these data cards have the following
+format.
+
+The field 1 is not used and should be empty.
+
+The field 2 specifies a column name. If this field is empty, the column
+name from the immediately preceeding data card is assumed.
+
+The field 3 specifies a row name defined in the ROWS section.
+
+The field 4 specifies a numerical value of the constraint coefficient
+$a_{ij}$, which is placed in the corresponding row and column.
+
+The fields 5 and 6 are optional. If they are used, they should contain
+a second pair ``row name---constraint coefficient'' for the same column.
+
+Elements of the constraint matrix (i.e. constraint coefficients) should
+be enumerated in the column wise manner: all elements for the current
+column should be specified before elements for the next column. However,
+the order of rows in the COLUMNS section may differ from the order of
+rows in the ROWS section.
+
+Constraint coefficients not specified in the COLUMNS section are
+considered as zeros. Therefore zero coefficients may be omitted,
+although it is allowed to explicitly specify them.
+
+\section{RHS section}
+
+The RHS section should start with the indicator card, which contains the
+word \verb|RHS| in the columns 1---3.
+
+Each data card in the RHS section specifies one or two right-hand sides
+$b_i$ (see Section \ref{secrows}, page \pageref{secrows}). All these
+data cards have the following format.
+
+The field 1 is not used and should be empty.
+
+The field 2 specifies a name of the right-hand side (RHS)
+vector\footnote{This feature allows the user to specify several RHS
+vectors in the same MPS file. However, before solving the problem a
+particular RHS vector should be chosen.}. If this field is empty, the
+RHS vector name from the immediately preceeding data card is assumed.
+
+%\newpage
+
+The field 3 specifies a row name defined in the ROWS section.
+
+The field 4 specifies a right-hand side $b_i$ for the row, whose name is
+specified in the field 3. Depending on the row type $b_i$ is a lower
+bound (for the row of \verb|G| type), an upper bound (for the row of
+\verb|L| type), or a fixed value (for the row of \verb|E|
+type).\footnote{If the row is of {\tt N} type, $b_i$ is considered as
+a constant term of the corresponding linear form. Should note, however,
+this convention is non-standard.}
+
+The fields 5 and 6 are optional. If they are used, they should contain
+a second pair ``row name---right-hand side'' for the same RHS vector.
+
+All right-hand sides for the current RHS vector should be specified
+before right-hand sides for the next RHS vector. However, the order of
+rows in the RHS section may differ from the order of rows in the ROWS
+section.
+
+Right-hand sides not specified in the RHS section are considered as
+zeros. Therefore zero right-hand sides may be omitted, although it is
+allowed to explicitly specify them.
+
+\newpage
+
+\section{RANGES section}
+
+The RANGES section should start with the indicator card, which contains
+the word \verb|RANGES| in the columns 1---6.
+
+Each data card in the RANGES section specifies one or two ranges for
+double-side constraints, i.e. for constraints that are of the types
+\verb|L| and \verb|G| at the same time:
+$$l_i \leq x_i = a_{i1}x_{m+1} + a_{i2}x_{m+2} + \dots + a_{in}x_{m+n}
+\leq u_i,$$
+where $l_i$ is a lower bound, $u_i$ is an upper bound. All these data
+cards have the following format.
+
+The field 1 is not used and should be empty.
+
+The field 2 specifies a name of the range vector\footnote{This feature
+allows the user to specify several range vectors in the same MPS file.
+However, before solving the problem a particular range vector should be
+chosen.}. If this field is empty, the range vector name from the
+immediately preceeding data card is assumed.
+
+The field 3 specifies a row name defined in the ROWS section.
+
+The field 4 specifies a range value $r_i$ (see the table below) for the
+row, whose name is specified in the field 3.
+
+The fields 5 and 6 are optional. If they are used, they should contain
+a second pair ``row name---range value'' for the same range vector.
+
+All range values for the current range vector should be specified before
+range values for the next range vector. However, the order of rows in
+the RANGES section may differ from the order of rows in the ROWS
+section.
+
+For each double-side constraint specified in the RANGES section its
+lower and upper bounds are determined as follows:
+
+%\newpage
+
+\begin{center}
+\begin{tabular}{cccc}
+Row type & Sign of $r_i$ & Lower bound & Upper bound \\
+\hline
+{\tt G} & $+$ or $-$ & $b_i$ & $b_i + |r_i|$ \\
+{\tt L} & $+$ or $-$ & $b_i - |r_i|$ & $b_i$ \\
+{\tt E} & $+$ & $b_i$ & $b_i + |r_i|$ \\
+{\tt E} & $-$ & $b_i - |r_i|$ & $b_i$ \\
+\end{tabular}
+\end{center}
+
+\noindent
+where $b_i$ is a right-hand side specified in the RHS section (if $b_i$
+is not specified, it is considered as zero), $r_i$ is a range value
+specified in the RANGES section.
+
+\section{BOUNDS section}
+\label{secbounds}
+
+The BOUNDS section should start with the indicator card, which contains
+the word \verb|BOUNDS| in the columns 1---6.
+
+Each data card in the BOUNDS section specifies one (lower or upper)
+bound for one structural variable (column). All these data cards have
+the following format.
+
+The indicator in the field 1 specifies the bound type:
+
+\verb|LO| --- lower bound;
+
+\verb|UP| --- upper bound;
+
+\verb|FX| --- fixed variable (lower and upper bounds are equal);
+
+\verb|FR| --- free variable (no bounds);
+
+\verb|MI| --- no lower bound (lower bound is ``minus infinity'');
+
+\verb|PL| --- no upper bound (upper bound is ``plus infinity'').
+
+The field 2 specifies a name of the bound vector\footnote{This feature
+allows the user to specify several bound vectors in the same MPS file.
+However, before solving the problem a particular bound vector should be
+chosen.}. If this field is empty, the bound vector name from the
+immediately preceeding data card is assumed.
+
+The field 3 specifies a column name defined in the COLUMNS section.
+
+The field 4 specifies a bound value. If the bound type in the field 1
+differs from \verb|LO|, \verb|UP|, and \verb|FX|, the value in the field
+4 is ignored and may be omitted.
+
+The fields 5 and 6 are not used and should be empty.
+
+All bound values for the current bound vector should be specified before
+bound values for the next bound vector. However, the order of columns in
+the BOUNDS section may differ from the order of columns in the COLUMNS
+section. Specification of a lower bound should precede specification of
+an upper bound for the same column (if both the lower and upper bounds
+are explicitly specified).
+
+By default, all columns (structural variables) are non-negative, i.e.
+have zero lower bound and no upper bound. Lower ($l_j$) and upper
+($u_j$) bounds of some column (structural variable $x_j$) are set in the
+following way, where $s_j$ is a corresponding bound value explicitly
+specified in the BOUNDS section:
+
+%\newpage
+
+\verb|LO| sets $l_j$ to $s_j$;
+
+\verb|UP| sets $u_j$ to $s_j$;
+
+\verb|FX| sets both $l_j$ and $u_j$ to $s_j$;
+
+\verb|FR| sets $l_j$ to $-\infty$ and $u_j$ to $+\infty$;
+
+\verb|MI| sets $l_j$ to $-\infty$;
+
+\verb|PL| sets $u_j$ to $+\infty$.
+
+\section{ENDATA indicator card}
+
+The ENDATA indicator card should be the last card of MPS file (except
+optional comment cards, which may follow the ENDATA card). This card
+should contain the word \verb|ENDATA| in the columns 1---6.
+
+\section{Specifying objective function}
+
+It is impossible to explicitly specify the objective function and
+optimization direction in the MPS file. However, the following implicit
+rule is used by default: the first row of \verb|N| type is considered
+as a row of the objective function (i.e. the objective function is the
+corresponding auxiliary variable), which should be {\it minimized}.
+
+GLPK also allows specifying a constant term of the objective function
+as a right-hand side of the corresponding row in the RHS section.
+
+\section{Example of MPS file}
+\label{secmpsex}
+
+To illustrate what the MPS format is, consider the following example of
+LP problem:
+
+\def\arraystretch{1.2}
+
+\noindent\hspace{.5in}minimize
+$$
+value = .03\ bin_1 + .08\ bin_2 + .17\ bin_3 + .12\ bin_4 + .15\ bin_5
++ .21\ al + .38\ si
+$$
+\noindent\hspace{.5in}subject to linear constraints
+$$
+\begin{array}{@{}l@{\:}l@{}}
+yield &= \ \ \ \ \;bin_1 + \ \ \ \ \;bin_2 + \ \ \ \ \;bin_3 +
+ \ \ \ \ \;bin_4 + \ \ \ \ \;bin_5 + \ \ \ \ \;al +
+ \ \ \ \ \;si \\
+FE &= .15\ bin_1 + .04\ bin_2 + .02\ bin_3 + .04\ bin_4 + .02\ bin_5
+ + .01\ al + .03\ si \\
+CU &= .03\ bin_1 + .05\ bin_2 + .08\ bin_3 + .02\ bin_4 + .06\ bin_5
+ + .01\ al \\
+MN &= .02\ bin_1 + .04\ bin_2 + .01\ bin_3 + .02\ bin_4 + .02\ bin_5
+ \\
+MG &= .02\ bin_1 + .03\ bin_2
+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ + .01\ bin_5 \\
+AL &= .70\ bin_1 + .75\ bin_2 + .80\ bin_3 + .75\ bin_4 + .80\ bin_5
+ + .97\ al \\
+SI &= .02\ bin_1 + .06\ bin_2 + .08\ bin_3 + .12\ bin_4 + .02\ bin_5
+ + .01\ al + .97\ si \\
+\end{array}
+$$
+\noindent\hspace{.5in}and bounds of (auxiliary and structural)
+variables
+$$
+\begin{array}{r@{\ }l@{\ }l@{\ }l@{\ }rcr@{\ }l@{\ }l@{\ }l@{\ }r}
+&&yield&=&2000&&0&\leq&bin_1&\leq&200\\
+-\infty&<&FE&\leq&60&&0&\leq&bin_2&\leq&2500\\
+-\infty&<&CU&\leq&100&&400&\leq&bin_3&\leq&800\\
+-\infty&<&MN&\leq&40&&100&\leq&bin_4&\leq&700\\
+-\infty&<&MG&\leq&30&&0&\leq&bin_5&\leq&1500\\
+1500&\leq&AL&<&+\infty&&0&\leq&al&<&+\infty\\
+250&\leq&SI&\leq&300&&0&\leq&si&<&+\infty\\
+\end{array}
+$$
+
+\def\arraystretch{1}
+
+A complete MPS file which specifies data for this example is shown
+below (the first two comment lines show card positions).
+
+\newpage
+
+\begin{footnotesize}
+\begin{verbatim}
+*000000001111111111222222222233333333334444444444555555555566
+*234567890123456789012345678901234567890123456789012345678901
+NAME PLAN
+ROWS
+ N VALUE
+ E YIELD
+ L FE
+ L CU
+ L MN
+ L MG
+ G AL
+ L SI
+COLUMNS
+ BIN1 VALUE .03000 YIELD 1.00000
+ FE .15000 CU .03000
+ MN .02000 MG .02000
+ AL .70000 SI .02000
+ BIN2 VALUE .08000 YIELD 1.00000
+ FE .04000 CU .05000
+ MN .04000 MG .03000
+ AL .75000 SI .06000
+ BIN3 VALUE .17000 YIELD 1.00000
+ FE .02000 CU .08000
+ MN .01000 AL .80000
+ SI .08000
+ BIN4 VALUE .12000 YIELD 1.00000
+ FE .04000 CU .02000
+ MN .02000 AL .75000
+ SI .12000
+ BIN5 VALUE .15000 YIELD 1.00000
+ FE .02000 CU .06000
+ MN .02000 MG .01000
+ AL .80000 SI .02000
+ ALUM VALUE .21000 YIELD 1.00000
+ FE .01000 CU .01000
+ AL .97000 SI .01000
+ SILICON VALUE .38000 YIELD 1.00000
+ FE .03000 SI .97000
+RHS
+ RHS1 YIELD 2000.00000 FE 60.00000
+ CU 100.00000 MN 40.00000
+ SI 300.00000
+ MG 30.00000 AL 1500.00000
+RANGES
+ RNG1 SI 50.00000
+BOUNDS
+ UP BND1 BIN1 200.00000
+ UP BIN2 2500.00000
+ LO BIN3 400.00000
+ UP BIN3 800.00000
+ LO BIN4 100.00000
+ UP BIN4 700.00000
+ UP BIN5 1500.00000
+ENDATA
+\end{verbatim}
+\end{footnotesize}
+
+%\vspace*{-6pt}
+
+\section{MIP features}
+
+%\vspace*{-4pt}
+
+The MPS format provides two ways for introducing integer variables into
+the problem.
+
+The first way is most general and based on using special marker cards
+INTORG and INTEND. These marker cards are placed in the COLUMNS section.
+The INTORG card indicates the start of a group of integer variables
+(columns), and the card INTEND indicates the end of the group. The MPS
+file may contain arbitrary number of the marker cards.
+
+The marker cards have the same format as the data cards (see Section
+\ref{secmps}, page \pageref{secmps}).
+
+The fields 1, 2, and 6 are not used and should be empty.
+
+The field 2 should contain a marker name. This name may be arbitrary.
+
+The field 3 should contain the word \verb|'MARKER'| (including
+apostrophes).
+
+The field 5 should contain either the word \verb|'INTORG'| (including
+apostrophes) for the marker card, which begins a group of integer
+columns, or the word \verb|'INTEND'| (including apostrophes) for the
+marker card, which ends the group.
+
+The second way is less general but more convenient in some cases. It
+allows the user declaring integer columns using three additional types
+of bounds, which are specified in the field 1 of data cards in the
+BOUNDS section (see Section \ref{secbounds}, page \pageref{secbounds}):
+
+\verb|LI| --- lower integer. This bound type specifies that the
+corresponding column (structural variable), whose name is specified in
+field 3, is of integer kind. In this case an lower bound of the
+column should be specified in field 4 (like in the case of \verb|LO|
+bound type).
+
+\verb|UI| --- upper integer. This bound type specifies that the
+corresponding column (structural variable), whose name is specified in
+field 3, is of integer kind. In this case an upper bound of the
+column should be specified in field 4 (like in the case of \verb|UP|
+bound type).
+
+\verb|BV| --- binary variable. This bound type specifies that the
+corresponding column (structural variable), whose name is specified in
+the field 3, is of integer kind, its lower bound is zero, and its upper
+bound is one (thus, such variable being of integer kind can have only
+two values zero and one). In this case a numeric value specified in the
+field 4 is ignored and may be omitted.
+
+Consider the following example of MIP problem:
+
+\noindent
+\hspace{1in} minimize
+$$Z = 3 x_1 + 7 x_2 - x_3 + x4$$
+\hspace{1in} subject to linear constraints
+$$
+\begin{array}{c}
+\nonumber r_1 = 2 x_1 - \ \ x_2 + \ \ x_3 - \ \;x_4 \\
+\nonumber r_2 = \ \;x_1 - \ \;x_2 - 6 x_3 + 4 x_4 \\
+\nonumber r_3 = 5 x_1 + 3 x_2 \ \ \ \ \ \ \ \ \ + \ \ x_4 \\
+\end{array}
+$$
+\hspace{1in} and bound of variables
+$$
+\begin{array}{cccl}
+\nonumber 1 \leq r_1 < +\infty && 0 \leq x_1 \leq 4 &{\rm(continuous)}\\
+\nonumber 8 \leq r_2 < +\infty && 2 \leq x_2 \leq 5 &{\rm(integer)} \\
+\nonumber 5 \leq r_3 < +\infty && 0 \leq x_3 \leq 1 &{\rm(integer)} \\
+\nonumber && 3 \leq x_4 \leq 8 &{\rm(continuous)}\\
+\end{array}
+$$
+
+The corresponding MPS file may look like follows:
+
+\newpage
+
+\begin{footnotesize}
+\begin{verbatim}
+NAME SAMP1
+ROWS
+ N Z
+ G R1
+ G R2
+ G R3
+COLUMNS
+ X1 R1 2.0 R2 1.0
+ X1 R3 5.0 Z 3.0
+ MARK0001 'MARKER' 'INTORG'
+ X2 R1 -1.0 R2 -1.0
+ X2 R3 3.0 Z 7.0
+ X3 R1 1.0 R2 -6.0
+ X3 Z -1.0
+ MARK0002 'MARKER' 'INTEND'
+ X4 R1 -1.0 R2 4.0
+ X4 R3 1.0 Z 1.0
+RHS
+ RHS1 R1 1.0
+ RHS1 R2 8.0
+ RHS1 R3 5.0
+BOUNDS
+ UP BND1 X1 4.0
+ LO BND1 X2 2.0
+ UP BND1 X2 5.0
+ UP BND1 X3 1.0
+ LO BND1 X4 3.0
+ UP BND1 X4 8.0
+ENDATA
+\end{verbatim}
+\end{footnotesize}
+
+%\newpage
+\vspace{-3pt}
+
+The same example may be coded without INTORG/INTEND markers using the
+bound type UI for the variable $x_2$ and the bound type BV for the
+variable $x_3$:
+
+%\medskip
+
+\begin{footnotesize}
+\begin{verbatim}
+NAME SAMP2
+ROWS
+ N Z
+ G R1
+ G R2
+ G R3
+COLUMNS
+ X1 R1 2.0 R2 1.0
+ X1 R3 5.0 Z 3.0
+ X2 R1 -1.0 R2 -1.0
+ X2 R3 3.0 Z 7.0
+ X3 R1 1.0 R2 -6.0
+ X3 Z -1.0
+ X4 R1 -1.0 R2 4.0
+ X4 R3 1.0 Z 1.0
+RHS
+ RHS1 R1 1.0
+ RHS1 R2 8.0
+ RHS1 R3 5.0
+BOUNDS
+ UP BND1 X1 4.0
+ LO BND1 X2 2.0
+ UI BND1 X2 5.0
+ BV BND1 X3
+ LO BND1 X4 3.0
+ UP BND1 X4 8.0
+ENDATA
+\end{verbatim}
+\end{footnotesize}
+
+%\section{Specifying predefined basis}
+%\label{secbas}
+%
+%The MPS format can also be used to specify some predefined basis for an
+%LP problem, i.e. to specify which rows and columns are basic and which
+%are non-basic.
+%
+%The order of a basis file in the MPS format is:
+%
+%$\bullet$ NAME indicator card;
+%
+%$\bullet$ data cards (can appear in arbitrary order);
+%
+%$\bullet$ ENDATA indicator card.
+%
+%Each data card specifies either a pair "basic column---non-basic row"
+%or a non-basic column. All the data cards have the following format.
+%
+%`\verb|XL|' in the field 1 means that a column, whose name is given in
+%the field 2, is basic, and a row, whose name is given in the field 3,
+%is non-basic and placed on its lower bound.
+%
+%`\verb|XU|' in the field 1 means that a column, whose name is given in
+%the field 2, is basic, and a row, whose name is given in the field 3,
+%is non-basic and placed on its upper bound.
+%
+%`\verb|LL|' in the field 1 means that a column, whose name is given in
+%the field 3, is non-basic and placed on its lower bound.
+%
+%`\verb|UL|' in the field 1 means that a column, whose name is given in
+%the field 3, is non-basic and placed on its upper bound.
+%
+%The field 2 contains a column name.
+%
+%If the indicator given in the field 1 is `\verb|XL|' or `\verb|XU|',
+%the field 3 contains a row name. Otherwise, if the indicator is
+%`\verb|LL|' or `\verb|UL|', the field 3 is not used and should be
+%empty.
+%
+%The field 4, 5, and 6 are not used and should be empty.
+%
+%A basis file in the MPS format acts like a patch: it doesn't specify
+%a basis completely, instead that it is just shows in what a given basis
+%differs from the "standard" basis, where all rows (auxiliary variables)
+%are assumed to be basic and all columns (structural variables) are
+%assumed to be non-basic.
+%
+%As an example here is a basis file that specifies an optimal basis
+%for the example LP problem given in Section \ref{secmpsex},
+%Page \pageref{secmpsex}:
+%
+%\pagebreak
+%
+%\begin{verbatim}
+%*000000001111111111222222222233333333334444444444555555555566
+%*234567890123456789012345678901234567890123456789012345678901
+%NAME PLAN
+% XL BIN2 YIELD
+% XL BIN3 FE
+% XL BIN4 MN
+% XL ALUM AL
+% XL SILICON SI
+% LL BIN1
+% LL BIN5
+%ENDATA
+%\end{verbatim}
+
+%* eof *%
diff --git a/glpk-5.0/doc/glpk09.tex b/glpk-5.0/doc/glpk09.tex
new file mode 100644
index 0000000..a78e987
--- /dev/null
+++ b/glpk-5.0/doc/glpk09.tex
@@ -0,0 +1,423 @@
+%* glpk09.tex *%
+
+\chapter{CPLEX LP Format}
+\label{chacplex}
+
+\section{Prelude}
+
+The CPLEX LP format\footnote{The CPLEX LP format was developed in
+the end of 1980's by CPLEX Optimization, Inc. as an input format for
+the CPLEX linear programming system. Although the CPLEX LP format is
+not as widely used as the MPS format, being row-oriented it is more
+convenient for coding mathematical programming models by human. This
+appendix describes only the features of the CPLEX LP format which are
+implemented in the GLPK package.} is intended for coding LP/MIP problem
+data. It is a row-oriented format that assumes the formulation of
+LP/MIP problem (1.1)---(1.3) (see Section \ref{seclp}, page
+\pageref{seclp}).
+
+CPLEX LP file is a plain text file written in CPLEX LP format. Each
+text line of this file may contain up to 255 characters\footnote{GLPK
+allows text lines of arbitrary length.}. Blank lines are ignored.
+If a line contains the backslash character ($\backslash$), this
+character and everything that follows it until the end of line are
+considered as a comment and also ignored.
+
+An LP file is coded by the user using the following elements: keywords,
+symbolic names, numeric constants, delimiters, and blanks.
+
+{\it Keywords} which may be used in the LP file are the following:
+
+\begin{verbatim}
+ minimize minimum min
+ maximize maximum max
+ subject to such that s.t. st. st
+ bounds bound
+ general generals gen
+ integer integers int
+ binary binaries bin
+ infinity inf
+ free
+ end
+\end{verbatim}
+
+\noindent
+All the keywords are case insensitive. Keywords given above on the same
+line are equivalent. Any keyword (except \verb|infinity|, \verb|inf|,
+and \verb|free|) being used in the LP file must start at the beginning
+of a text line.
+
+\newpage
+
+{\it Symbolic names} are used to identify the objective function,
+constraints (rows), and variables (columns). All symbolic names are case
+sensitive and may contain up to 16 alphanumeric characters\footnote{GLPK
+allows symbolic names having up to 255 characters.} (\verb|a|, \dots,
+\verb|z|, \verb|A|, \dots, \verb|Z|, \verb|0|, \dots, \verb|9|) as well
+as the following characters:
+
+\begin{verbatim}
+ ! " # $ % & ( ) / , . ; ? @ _ ` ' { } | ~
+\end{verbatim}
+
+\noindent
+with exception that no symbolic name can begin with a digit or
+a period.
+
+{\it Numeric constants} are used to denote constraint and objective
+coefficients, right-hand sides of constraints, and bounds of variables.
+They are coded in the standard form $xx$\verb|E|$syy$, where $xx$ is
+a real number with optional decimal point, $s$ is a sign (\verb|+| or
+\verb|-|), $yy$ is an integer decimal exponent. Numeric constants may
+contain arbitrary number of characters. The exponent part is optional.
+The letter `\verb|E|' can be coded as `\verb|e|'. If the sign $s$ is
+omitted, plus is assumed.
+
+{\it Delimiters} that may be used in the LP file are the following:
+
+\begin{verbatim}
+ :
+ +
+ -
+ < <= =<
+ > >= =>
+ =
+\end{verbatim}
+
+\noindent
+Delimiters given above on the same line are equivalent. The meaning of
+the delimiters will be explained below.
+
+{\it Blanks} are non-significant characters. They may be used freely to
+improve readability of the LP file. Besides, blanks should be used to
+separate elements from each other if there is no other way to do that
+(for example, to separate a keyword from a following symbolic name).
+
+The order of an LP file is the following:
+
+%\vspace*{-8pt}
+
+%\begin{itemize}
+\Item{---}objective function definition;
+
+\Item{---}constraints section;
+
+\Item{---}bounds section;
+
+\Item{---}general, integer, and binary sections (can appear in
+arbitrary order);
+
+\Item{---}end keyword.
+%\end{itemize}
+
+%\vspace*{-8pt}
+
+These components are discussed in following sections.
+
+\section{Objective function definition}
+
+The objective function definition must appear first in the LP file.
+It defines the objective function and specifies the optimization
+direction.
+
+The objective function definition has the following form:
+$$
+\left\{
+\begin{array}{@{}c@{}}
+{\tt minimize} \\ {\tt maximize}
+\end{array}
+\right\}\ f\ {\tt :}\ s\ c\ x\ \dots\ s\ c\ x
+$$
+where $f$ is a symbolic name of the objective function, $s$ is a sign
+\verb|+| or \verb|-|, $c$ is a numeric constant that denotes an
+objective coefficient, $x$ is a symbolic name of a variable.
+
+If necessary, the objective function definition can be continued on as
+many text lines as desired.
+
+The name of the objective function is optional and may be omitted
+(together with the semicolon that follows it). In this case the default
+name `\verb|obj|' is assigned to the objective function.
+
+If the very first sign $s$ is omitted, the sign plus is assumed. Other
+signs cannot be omitted.
+
+If some objective coefficient $c$ is omitted, 1 is assumed.
+
+Symbolic names $x$ used to denote variables are recognized by context
+and therefore needn't to be declared somewhere else.
+
+Here is an example of the objective function definition:
+
+\begin{verbatim}
+ Minimize Z : - x1 + 2 x2 - 3.5 x3 + 4.997e3x(4) + x5 + x6 +
+ x7 - .01x8
+\end{verbatim}
+
+\section{Constraints section}
+
+The constraints section must follow the objective function definition.
+It defines a system of equality and/or inequality constraints.
+
+The constraint section has the following form:
+
+\begin{center}
+\begin{tabular}{l}
+\verb|subject to| \\
+{\it constraint}$_1$ \\
+\hspace{20pt}\dots \\
+{\it constraint}$_m$ \\
+\end{tabular}
+\end{center}
+
+\noindent where {\it constraint}$_i, i=1,\dots,m,$ is a particular
+constraint definition.
+
+Each constraint definition can be continued on as many text lines as
+desired. However, each constraint definition must begin on a new line
+except the very first constraint definition which can begin on the same
+line as the keyword `\verb|subject to|'.
+
+Constraint definitions have the following form:
+$$
+r\ {\tt:}\ s\ c\ x\ \dots\ s\ c\ x
+\ \left\{
+\begin{array}{@{}c@{}}
+\mbox{\tt<=} \\ \mbox{\tt>=} \\ \mbox{\tt=}
+\end{array}
+\right\}\ b
+$$
+where $r$ is a symbolic name of a constraint, $s$ is a sign \verb|+| or
+\verb|-|, $c$ is a numeric constant that denotes a constraint
+coefficient, $x$ is a symbolic name of a variable, $b$ is a right-hand
+side.
+
+The name $r$ of a constraint (which is the name of the corresponding
+auxiliary variable) is optional and may be omitted together with the
+semicolon that follows it. In the latter case the default names like
+`\verb|r.nnn|' are assigned to unnamed constraints.
+
+The linear form $s\ c\ x\ \dots\ s\ c\ x$ in the left-hand side of
+a constraint definition has exactly the same meaning as in the case of
+the objective function definition (see above).
+
+After the linear form one of the following delimiters that indicates
+the constraint sense must be specified:
+
+\verb|<=| \ means `less than or equal to'
+
+\verb|>=| \ means `greater than or equal to'
+
+\verb|= | \ means `equal to'
+
+The right hand side $b$ is a numeric constant with an optional sign.
+
+Here is an example of the constraints section:
+
+\begin{verbatim}
+ Subject To
+ one: y1 + 3 a1 - a2 - b >= 1.5
+ y2 + 2 a3 + 2
+ a4 - b >= -1.5
+ two : y4 + 3 a1 + 4 a5 - b <= +1
+ .20y5 + 5 a2 - b = 0
+ 1.7 y6 - a6 + 5 a777 - b >= 1
+\end{verbatim}
+
+Should note that it is impossible to express ranged constraints in the
+CPLEX LP format. Each a ranged constraint can be coded as two
+constraints with identical linear forms in the left-hand side, one of
+which specifies a lower bound and other does an upper one of the
+original ranged constraint. Another way is to introduce a slack
+double-bounded variable; for example, the
+constraint
+$$10\leq x+2y+3z\leq 50$$
+can be written as follows:
+$$x+2y+3z+t=50,$$
+where $0\leq t\leq 40$ is a slack variable.
+
+\section{Bounds section}
+
+The bounds section is intended to define bounds of variables. This
+section is optional; if it is specified, it must follow the constraints
+section. If the bound section is omitted, all variables are assumed to
+be non-negative (i.e. that they have zero lower bound and no upper
+bound).
+
+The bounds section has the following form:
+
+\begin{center}
+\begin{tabular}{l}
+\verb|bounds| \\
+{\it definition}$_1$ \\
+\hspace{20pt}\dots \\
+{\it definition}$_p$ \\
+\end{tabular}
+\end{center}
+
+\noindent
+where {\it definition}$_k, k=1,\dots,p,$ is a particular bound
+definition.
+
+Each bound definition must begin on a new line\footnote{The GLPK
+implementation allows several bound definitions to be placed on the
+same line.} except the very first bound definition which can begin on
+the same line as the keyword `\verb|bounds|'.
+
+%\newpage
+
+Syntactically constraint definitions can have one of the following six
+forms:
+
+\begin{center}
+\begin{tabular}{ll}
+$x$ \verb|>=| $l$ & specifies a lower bound \\
+$l$ \verb|<=| $x$ & specifies a lower bound \\
+$x$ \verb|<=| $u$ & specifies an upper bound \\
+$l$ \verb|<=| $x$ \verb|<=| $u$ &specifies both lower and upper bounds\\
+$x$ \verb|=| $t$ &specifies a fixed value \\
+$x$ \verb|free| &specifies free variable
+\end{tabular}
+\end{center}
+
+\noindent
+where $x$ is a symbolic name of a variable, $l$ is a numeric constant
+with an optional sign that defines a lower bound of the variable or
+\verb|-inf| that means that the variable has no lower bound, $u$ is
+a~numeric constant with an optional sign that defines an upper bound of
+the variable or \verb|+inf| that means that the variable has no upper
+bound, $t$ is a numeric constant with an optional sign that defines a
+fixed value of the variable.
+
+By default all variables are non-negative, i.e. have zero lower bound
+and no upper bound. Therefore definitions of these default bounds can
+be omitted in the bounds section.
+
+Here is an example of the bounds section:
+
+\begin{verbatim}
+ Bounds
+ -inf <= a1 <= 100
+ -100 <= a2
+ b <= 100
+ x2 = +123.456
+ x3 free
+\end{verbatim}
+
+\section{General, integer, and binary sections}
+
+The general, integer, and binary sections are intended to define
+some variables as integer or binary. All these sections are optional
+and needed only in case of MIP problems. If they are specified, they
+must follow the bounds section or, if the latter is omitted, the
+constraints section.
+
+All the general, integer, and binary sections have the same form as
+follows:
+
+\begin{center}
+\begin{tabular}{l}
+$
+\left\{
+\begin{array}{@{}l@{}}
+\verb|general| \\
+\verb|integer| \\
+\verb|binary | \\
+\end{array}
+\right\}
+$ \\
+\hspace{10pt}$x_1$ \\
+\hspace{10pt}\dots \\
+\hspace{10pt}$x_q$ \\
+\end{tabular}
+\end{center}
+
+\noindent
+where $x_k$ is a symbolic name of variable, $k=1,\dots,q$.
+
+Each symbolic name must begin on a new line\footnote{The GLPK
+implementation allows several symbolic names to be placed on the same
+line.} except the very first symbolic name which can begin on the same
+line as the keyword `\verb|general|', `\verb|integer|', or
+`\verb|binary|'.
+
+%\newpage
+
+If a variable appears in the general or the integer section, it is
+assumed to be general integer variable. If a variable appears in the
+binary section, it is assumed to be binary variable, i.e. an integer
+variable whose lower bound is zero and upper bound is one. (Note that
+if bounds of a variable are specified in the bounds section and then
+the variable appears in the binary section, its previously specified
+bounds are ignored.)
+
+Here is an example of the integer section:
+
+\begin{verbatim}
+ Integer
+ z12
+ z22
+ z35
+\end{verbatim}
+
+\newpage
+
+\section{End keyword}
+
+The keyword `\verb|end|' is intended to end the LP file. It must begin
+on a separate line and no other elements (except comments and blank
+lines) must follow it. Although this keyword is optional, it is strongly
+recommended to include it in the LP file.
+
+\section{Example of CPLEX LP file}
+
+Here is a complete example of CPLEX LP file that corresponds to the
+example given in Section \ref{secmpsex}, page \pageref{secmpsex}.
+
+\medskip
+
+\begin{footnotesize}
+\begin{verbatim}
+\* plan.lp *\
+
+Minimize
+ value: .03 bin1 + .08 bin2 + .17 bin3 + .12 bin4 + .15 bin5 +
+ .21 alum + .38 silicon
+
+Subject To
+ yield: bin1 + bin2 + bin3 + bin4 + bin5 +
+ alum + silicon = 2000
+
+ fe: .15 bin1 + .04 bin2 + .02 bin3 + .04 bin4 + .02 bin5 +
+ .01 alum + .03 silicon <= 60
+
+ cu: .03 bin1 + .05 bin2 + .08 bin3 + .02 bin4 + .06 bin5 +
+ .01 alum <= 100
+
+ mn: .02 bin1 + .04 bin2 + .01 bin3 + .02 bin4 + .02 bin5 <= 40
+
+ mg: .02 bin1 + .03 bin2 + .01 bin5 <= 30
+
+ al: .70 bin1 + .75 bin2 + .80 bin3 + .75 bin4 + .80 bin5 +
+ .97 alum >= 1500
+
+ si1: .02 bin1 + .06 bin2 + .08 bin3 + .12 bin4 + .02 bin5 +
+ .01 alum + .97 silicon >= 250
+
+ si2: .02 bin1 + .06 bin2 + .08 bin3 + .12 bin4 + .02 bin5 +
+ .01 alum + .97 silicon <= 300
+
+Bounds
+ bin1 <= 200
+ bin2 <= 2500
+ 400 <= bin3 <= 800
+ 100 <= bin4 <= 700
+ bin5 <= 1500
+
+End
+
+\* eof *\
+\end{verbatim}
+\end{footnotesize}
+
+%* eof *%
diff --git a/glpk-5.0/doc/glpk10.tex b/glpk-5.0/doc/glpk10.tex
new file mode 100644
index 0000000..1943ef0
--- /dev/null
+++ b/glpk-5.0/doc/glpk10.tex
@@ -0,0 +1,160 @@
+%* glpk10.tex *%
+
+\chapter{Stand-alone LP/MIP Solver}
+\label{chaglpsol}
+
+The GLPK package includes the program \verb|glpsol|, which is a
+stand-alone LP/MIP solver. This program can be invoked from the command
+line to read LP/MIP problem data in any format supported by GLPK, solve
+the problem, and write its solution to an output text file.
+
+\para{Usage}
+
+\verb|glpsol| [{\it options\dots}] [{\it filename}]
+
+\para{General options}
+
+\begin{verbatim}
+ --mps read LP/MIP problem in fixed MPS format
+ --freemps read LP/MIP problem in free MPS format (default)
+ --lp read LP/MIP problem in CPLEX LP format
+ --glp read LP/MIP problem in GLPK format
+ --math read LP/MIP model written in GNU MathProg modeling
+ language
+ -m filename, --model filename
+ read model section and optional data section from
+ filename (same as --math)
+ -d filename, --data filename
+ read data section from filename (for --math only);
+ if model file also has data section, it is ignored
+ -y filename, --display filename
+ send display output to filename (for --math only);
+ by default the output is sent to terminal
+ --seed value initialize pseudo-random number generator used in
+ MathProg model with specified seed (any integer);
+ if seed value is ?, some random seed will be used
+ --mincost read min-cost flow problem in DIMACS format
+ --maxflow read maximum flow problem in DIMACS format
+ --cnf read CNF-SAT problem in DIMACS format
+ --simplex use simplex method (default)
+ --interior use interior point method (LP only)
+ -r filename, --read filename
+ read solution from filename rather to find it with
+ the solver
+ --min minimization
+ --max maximization
+ --scale scale problem (default)
+ --noscale do not scale problem
+ -o filename, --output filename
+ write solution to filename in printable format
+ -w filename, --write filename
+ write solution to filename in plain text format
+ --ranges filename
+ write sensitivity analysis report to filename in
+ printable format (simplex only)
+ --tmlim nnn limit solution time to nnn seconds
+ --memlim nnn limit available memory to nnn megabytes
+ --check do not solve problem, check input data only
+ --name probname change problem name to probname
+ --wmps filename write problem to filename in fixed MPS format
+ --wfreemps filename
+ write problem to filename in free MPS format
+ --wlp filename write problem to filename in CPLEX LP format
+ --wglp filename write problem to filename in GLPK format
+ --wcnf filename write problem to filename in DIMACS CNF-SAT format
+ --log filename write copy of terminal output to filename
+ -h, --help display this help information and exit
+ -v, --version display program version and exit
+\end{verbatim}
+
+\para{LP basis factorization options}
+
+\begin{verbatim}
+ --luf plain LU factorization (default)
+ --btf block triangular LU factorization
+ --ft Forrest-Tomlin update (requires --luf; default)
+ --cbg Schur complement + Bartels-Golub update
+ --cgr Schur complement + Givens rotation update
+\end{verbatim}
+
+\para{Options specific to the simplex solver}
+
+\begin{verbatim}
+ --primal use primal simplex (default)
+ --dual use dual simplex
+ --std use standard initial basis of all slacks
+ --adv use advanced initial basis (default)
+ --bib use Bixby's initial basis
+ --ini filename use as initial basis previously saved with -w
+ (disables LP presolver)
+ --steep use steepest edge technique (default)
+ --nosteep use standard "textbook" pricing
+ --relax use Harris' two-pass ratio test (default)
+ --norelax use standard "textbook" ratio test
+ --presol use presolver (default; assumes --scale and --adv)
+ --nopresol do not use presolver
+ --exact use simplex method based on exact arithmetic
+ --xcheck check final basis using exact arithmetic
+\end{verbatim}
+
+\para{Options specific to the interior-point solver}
+
+\begin{verbatim}
+ --nord use natural (original) ordering
+ --qmd use quotient minimum degree ordering
+ --amd use approximate minimum degree ordering (default)
+ --symamd use approximate minimum degree ordering
+\end{verbatim}
+
+\para{Options specific to the MIP solver}
+
+\begin{verbatim}
+ --nomip consider all integer variables as continuous
+ (allows solving MIP as pure LP)
+ --first branch on first integer variable
+ --last branch on last integer variable
+ --mostf branch on most fractional variable
+ --drtom branch using heuristic by Driebeck and Tomlin
+ (default)
+ --pcost branch using hybrid pseudocost heuristic (may be
+ useful for hard instances)
+ --dfs backtrack using depth first search
+ --bfs backtrack using breadth first search
+ --bestp backtrack using the best projection heuristic
+ --bestb backtrack using node with best local bound
+ (default)
+ --intopt use MIP presolver (default)
+ --nointopt do not use MIP presolver
+ --binarize replace general integer variables by binary ones
+ (assumes --intopt)
+ --fpump apply feasibility pump heuristic
+ --proxy [nnn] apply proximity search heuristic (nnn is time limit
+ in seconds; default is 60)
+ --gomory generate Gomory's mixed integer cuts
+ --mir generate MIR (mixed integer rounding) cuts
+ --cover generate mixed cover cuts
+ --clique generate clique cuts
+ --cuts generate all cuts above
+ --mipgap tol set relative mip gap tolerance to tol
+ --minisat translate integer feasibility problem to CNF-SAT
+ and solve it with MiniSat solver
+ --objbnd bound add inequality obj <= bound (minimization) or
+ obj >= bound (maximization) to integer feasibility
+ problem (assumes --minisat)
+\end{verbatim}
+
+For description of the MPS format see Appendix \ref{champs}, page
+\pageref{champs}.
+
+For description of the CPLEX LP format see Appendix \ref{chacplex},
+page \pageref{chacplex}.
+
+For description of the modeling language see the document ``Modeling
+Language GNU MathProg: Language Reference'' included in the GLPK
+distribution.
+
+For description of the DIMACS min-cost flow problem format and DIMACS
+maximum flow problem format see the document ``GLPK: Graph and Network
+Routines'' included in the GLPK distribution.
+
+%* eof *%
diff --git a/glpk-5.0/doc/glpk11.tex b/glpk-5.0/doc/glpk11.tex
new file mode 100644
index 0000000..ff731fb
--- /dev/null
+++ b/glpk-5.0/doc/glpk11.tex
@@ -0,0 +1,207 @@
+%* glpk11.tex *%
+
+\chapter{External Software Used In GLPK}
+
+In the GLPK package there are used some external software listed in
+this Appendix. Note that these software are {\it not} part of GLPK, but
+are used with GLPK and included in the distribution.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{AMD}
+
+\noindent
+AMD Version 2.2, Copyright {\copyright} 2007 by Timothy A. Davis,
+Patrick R. Amestoy, and Iain S. Duff. All Rights Reserved.
+
+\para{Description}
+
+AMD is a set of routines for pre-ordering sparse matrices prior to
+Cholesky or LU factorization, using the approximate minimum degree
+ordering algorithm.
+
+\para{License}
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public License
+as published by the Free Software Foundation; either version 2.1 of
+the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA.
+
+Permission is hereby granted to use or copy this program under the
+terms of the GNU LGPL, provided that the Copyright, this License,
+and the Availability of the original version is retained on all
+copies. User documentation of any code that uses this code or any
+modified version of this code must cite the Copyright, this License,
+the Availability note, and ``Used by permission.'' Permission to
+modify the code and to distribute modified code is granted, provided
+the Copyright, this License, and the Availability note are retained,
+and a notice that the code was modified is included.
+
+AMD is available under alternate licences; contact T. Davis for
+details.
+
+\para{Availability}
+
+\noindent
+\url{http://www.cise.ufl.edu/research/sparse/amd}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{COLAMD/SYMAMD}
+
+\noindent
+COLAMD/SYMAMD Version 2.7, Copyright {\copyright} 1998-2007, Timothy A.
+Davis, All Rights Reserved.
+
+\para{Description}
+
+colamd: an approximate minimum degree column ordering algorithm, for
+LU factorization of symmetric or unsymmetric matrices, QR factorization,
+least squares, interior point methods for linear programming problems,
+and other related problems.
+
+symamd: an approximate minimum degree ordering algorithm for Cholesky
+factorization of symmetric matrices.
+
+\para{Authors}
+
+The authors of the code itself are Stefan I. Larimore and Timothy A.
+Davis (davis at cise.ufl.edu), University of Florida. The algorithm
+was developed in collaboration with John Gilbert, Xerox PARC, and
+Esmond Ng, Oak Ridge National Laboratory.
+
+\para{License}
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public License
+as published by the Free Software Foundation; either version 2.1 of
+the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA.
+
+Permission is hereby granted to use or copy this program under the
+terms of the GNU LGPL, provided that the Copyright, this License,
+and the Availability of the original version is retained on all
+copies. User documentation of any code that uses this code or any
+modified version of this code must cite the Copyright, this License,
+the Availability note, and ``Used by permission.'' Permission to
+modify the code and to distribute modified code is granted, provided
+the Copyright, this License, and the Availability note are retained,
+and a notice that the code was modified is included.
+
+COLAMD is also available under alternate licenses, contact T. Davis for
+details.
+
+\para{Availability}
+
+\noindent
+\url{http://www.cise.ufl.edu/research/sparse/colamd}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%\newpage
+
+\section{MiniSat}
+
+\noindent
+MiniSat-C v1.14.1, Copyright {\copyright} 2005, Niklas Sorensson.
+
+\para{Description}
+
+MiniSat is a minimalistic implementation of a Chaff-like SAT solver
+based on the two-literal watch scheme for fast BCP and clause learning
+by conflict analysis.
+
+\newpage
+
+\para{License}
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+\para{Availability}
+
+\noindent
+\url{http://www.cs.chalmers.se/Cs/Research/FormalMethods/MiniSat}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{zlib}
+
+\noindent
+zlib version 1.2.5, Copyright {\copyright} 1995--2010 Jean-loup Gailly
+and Mark Adler.
+
+\para{Description}
+
+zlib is a general purpose data compression library. All the code is
+thread safe. The data format used by the zlib library is described by
+RFCs (Request for Comments) 1950 to 1952 in the files
+\verb|rfc1950.txt| (zlib format), \verb|rfc1951.txt| (deflate format)
+and \verb|rfc1952.txt| (gzip format).
+
+\para{License}
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would
+ be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and must not
+ be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+ distribution.
+
+\hfill Jean-loup Gailly
+
+\hfill Mark Adler
+
+\para{Availability}
+
+\noindent
+\url{http://www.zlib.net/}
+
+%* eof *%
diff --git a/glpk-5.0/doc/glpk12.tex b/glpk-5.0/doc/glpk12.tex
new file mode 100644
index 0000000..ea69587
--- /dev/null
+++ b/glpk-5.0/doc/glpk12.tex
@@ -0,0 +1,710 @@
+%* glpk12.tex *%
+
+\begin{footnotesize}
+
+\chapter*{\sf\bfseries GNU General Public License}
+\addcontentsline{toc}{chapter}{GNU General Public License}
+
+\begin{center}
+{\bf Version 3, 29 June 2007}
+\end{center}
+
+\begin{quotation}
+\noindent
+Copyright {\copyright} 2007 Free Software Foundation, Inc.
+\verb|<http://fsf.org/>|
+\end{quotation}
+
+\begin{quotation}
+\noindent
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+\end{quotation}
+
+\medskip\para{\normalsize Preamble}
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+\newpage
+
+\medskip\para{\normalsize TERMS AND CONDITIONS}
+
+\medskip\para{\normalsize 0. Definitions.}
+
+ ``This License'' refers to version 3 of the GNU General Public
+License.
+
+ ``Copyright'' also means copyright-like laws that apply to other kinds
+of works, such as semiconductor masks.
+
+ ``The Program'' refers to any copyrightable work licensed under this
+License. Each licensee is addressed as ``you''. ``Licensees'' and
+``recipients'' may be individuals or organizations.
+
+ To ``modify'' a work means to copy from or adapt all or part of the
+work in a fashion requiring copyright permission, other than the making
+of an exact copy. The resulting work is called a ``modified version''
+of the earlier work or a work ``based on'' the earlier work.
+
+ A ``covered work'' means either the unmodified Program or a work based
+on the Program.
+
+ To ``propagate'' a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To ``convey'' a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays ``Appropriate Legal Notices''
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+\medskip\para{\normalsize 1. Source Code.}
+
+ The ``source code'' for a work means the preferred form of the work
+for making modifications to it. ``Object code'' means any non-source
+form of a work.
+
+ A ``Standard Interface'' means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The ``System Libraries'' of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+``Major Component'', in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The ``Corresponding Source'' for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+\medskip\para{\normalsize 2. Basic Permissions.}
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+\medskip\para{\normalsize 3. Protecting Users' Legal Rights From
+Anti-Circumvention Law.}
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+\medskip\para{\normalsize 4. Conveying Verbatim Copies.}
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+\medskip\para{\normalsize 5. Conveying Modified Source Versions.}
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ ``keep intact all notices''.
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+``aggregate'' if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+\medskip\para{\normalsize 6. Conveying Non-Source Forms.}
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A ``User Product'' is either (1) a ``consumer product'', which means
+any tangible personal property which is normally used for personal,
+family, or household purposes, or (2) anything designed or sold for
+incorporation into a dwelling. In determining whether a product is a
+consumer product, doubtful cases shall be resolved in favor of coverage.
+For a particular product received by a particular user, ``normally
+used'' refers to a typical or common use of that class of product,
+regardless of the status of the particular user or of the way in which
+the particular user actually uses, or expects or is expected to use, the
+product. A product is a consumer product regardless of whether the
+product has substantial commercial, industrial or non-consumer uses,
+unless such uses represent the only significant mode of use of the
+product.
+
+ ``Installation Information'' for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product
+from a modified version of its Corresponding Source. The information
+must suffice to ensure that the continued functioning of the modified
+object code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to
+a network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+\medskip\para{\normalsize 7. Additional Terms.}
+
+ ``Additional permissions'' are terms that supplement the terms of
+this License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders
+of that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered ``further
+restrictions'' within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+\medskip\para{\normalsize 8. Termination.}
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+\medskip\para{\normalsize 9. Acceptance Not Required for Having Copies.}
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+\medskip\para{\normalsize 10. Automatic Licensing of Downstream Recipients.}
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An ``entity transaction'' is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+\medskip\para{\normalsize 11. Patents.}
+
+ A ``contributor'' is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's ``contributor version''.
+
+ A contributor's ``essential patent claims'' are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, ``control'' includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a ``patent license'' is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To ``grant'' such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. ``Knowingly relying'' means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is ``discriminatory'' if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+\medskip\para{\normalsize 12. No Surrender of Others' Freedom.}
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not convey it at all. For example, if you agree to terms that
+obligate you to collect a royalty for further conveying from those to
+whom you convey the Program, the only way you could satisfy both those
+terms and this License would be to refrain entirely from conveying the
+Program.
+
+\medskip\para{\normalsize 13. Use with the GNU Affero General Public
+License.}
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+\medskip\para{\normalsize 14. Revised Versions of this License.}
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU General Public License from time to time. Such new versions
+will be similar in spirit to the present version, but may differ in
+detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License ``or any later version'' applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+\medskip\para{\normalsize 15. Disclaimer of Warranty.}
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM ``AS IS'' WITHOUT
+WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
+OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU
+ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+\medskip\para{\normalsize 16. Limitation of Liability.}
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
+CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
+NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES
+SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE
+WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+\medskip\para{\normalsize 17. Interpretation of Sections 15 and 16.}
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+\medskip\para{\normalsize END OF TERMS AND CONDITIONS}
+
+\newpage
+
+\medskip\para{\normalsize How to Apply These Terms to Your New Programs}
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the ``copyright'' line and a pointer to where the full notice is found.
+
+\begin{verbatim}
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+\end{verbatim}
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+\begin{verbatim}
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+\end{verbatim}
+
+\noindent
+The hypothetical commands `show w' and `show c' should show the
+appropriate parts of the General Public License. Of course, your
+program's commands might be different; for a GUI interface, you would
+use an ``about box''.
+
+ You should also get your employer (if you work as a programmer) or
+school, if any, to sign a ``copyright disclaimer'' for the program, if
+necessary. For more information on this, and how to apply and follow the
+GNU GPL, see \verb|<http://www.gnu.org/licenses/>|.
+
+ The GNU General Public License does not permit incorporating your
+program into proprietary programs. If your program is a subroutine
+library, you may consider it more useful to permit linking proprietary
+applications with the library. If this is what you want to do, use the
+GNU Lesser General Public License instead of this License. But first,
+please read \verb|<http://www.gnu.org/philosophy/why-not-lgpl.html>|.
+
+\end{footnotesize}
+
+%* eof *%
diff --git a/glpk-5.0/doc/gmpl.pdf b/glpk-5.0/doc/gmpl.pdf
new file mode 100644
index 0000000..eb69d17
--- /dev/null
+++ b/glpk-5.0/doc/gmpl.pdf
Binary files differ
diff --git a/glpk-5.0/doc/gmpl.tex b/glpk-5.0/doc/gmpl.tex
new file mode 100644
index 0000000..8fd8d03
--- /dev/null
+++ b/glpk-5.0/doc/gmpl.tex
@@ -0,0 +1,4285 @@
+%* gmpl.tex *%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% The GLPK package is part of the GNU Project released under the aegis
+% of GNU.
+%
+% Copyright (c) 2003-2020 Free Software Foundation, Inc.
+%
+% Author: Andrew Makhorin <mao@gnu.org>.
+%
+% Permission is granted to copy, distribute and/or modify this
+% document under the terms of the GNU Free Documentation License,
+% Version 1.3 or any later version published by the Free Software
+% Foundation.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% To produce gmpl.pdf from gmpl.tex run the following two commands:
+% latex gmpl.tex
+% dvipdfm -p letter gmpl.dvi
+% Note: You need TeX Live 2010 or later version.
+
+\documentclass[11pt]{report}
+\usepackage{amssymb}
+\usepackage[dvipdfm,linktocpage,colorlinks,linkcolor=blue,
+urlcolor=blue]{hyperref}
+\usepackage{indentfirst}
+\usepackage{niceframe}
+
+\setlength{\textwidth}{6.5in}
+\setlength{\textheight}{8.5in}
+\setlength{\oddsidemargin}{0in}
+\setlength{\topmargin}{0in}
+\setlength{\headheight}{0in}
+\setlength{\headsep}{0in}
+\setlength{\footskip}{0.5in}
+\setlength{\parindent}{16pt}
+\setlength{\parskip}{5pt}
+\setlength{\topsep}{0pt}
+\setlength{\partopsep}{0pt}
+\setlength{\itemsep}{\parskip}
+\setlength{\parsep}{0pt}
+\setlength{\leftmargini}{\parindent}
+\renewcommand{\labelitemi}{---}
+
+\def\para#1{\noindent{\bf#1}}
+
+\renewcommand\contentsname{\sf\bfseries Contents}
+\renewcommand\chaptername{\sf\bfseries Chapter}
+\renewcommand\appendixname{\sf\bfseries Appendix}
+
+\begin{document}
+
+\thispagestyle{empty}
+
+\artdecoframe{
+
+\begin{center}
+
+\vspace*{1.5in}
+
+\begin{huge}
+\sf\bfseries Modeling Language GNU MathProg
+\end{huge}
+
+\vspace{0.5in}
+
+\begin{LARGE}
+\sf Language Reference
+\end{LARGE}
+
+\vspace{0.5in}
+
+\begin{LARGE}
+\sf for GLPK Version 5.0
+\end{LARGE}
+
+\vspace{0.5in}
+\begin{Large}
+\sf (December 2020)
+\end{Large}
+
+\end{center}
+
+\vspace*{3.2in}
+}
+
+\newpage
+
+\vspace*{1in}
+
+\vfill
+
+\noindent
+The GLPK package is part of the GNU Project released under the aegis of
+GNU.
+
+\noindent
+Copyright \copyright{} 2003-2020 Free Software Foundation, Inc.
+
+\noindent
+Authors: Andrew Makhorin $\langle$mao@gnu.org$\rangle$,
+Heinrich Schuchardt $\langle$heinrich.schuchardt@gmx.de$\rangle$.
+
+\noindent
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+{\setlength{\parskip}{0pt}
+\tableofcontents
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Introduction}
+
+{\it 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: {\it Robert Fourer}, {\it David M. Gay}, and
+{\it Brian W. Kernighan}, ``A Modeling Language for Mathematical
+Programming.'' {\it Management Science} 36 (1990), pp.~519-54.}
+
+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 {\it translation}, a program called the {\it 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 {\it solver} to obtain numeric solution of the problem.
+
+\section{Linear programming problem}
+\label{problem}
+
+In MathProg the linear programming (LP) problem is stated as follows:
+
+\medskip
+
+\noindent\hspace{1in}minimize (or maximize)
+$$z=c_1x_1+c_2x_2+\dots+c_nx_n+c_0\eqno(1.1)$$
+\noindent\hspace{1in}subject to linear constraints
+$$
+\begin{array}{l@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }l}
+L_1&\leq&a_{11}x_1&+&a_{12}x_2&+\dots+&a_{1n}x_n&\leq&U_1\\
+L_2&\leq&a_{21}x_1&+&a_{22}x_2&+\dots+&a_{2n}x_n&\leq&U_2\\
+\multicolumn{9}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\
+L_m&\leq&a_{m1}x_1&+&a_{m2}x_2&+\dots+&a_{mn}x_n&\leq&U_m\\
+\end{array}\eqno(1.2)
+$$
+\noindent\hspace{1in}and bounds of variables
+$$
+\begin{array}{l@{\ }c@{\ }c@{\ }c@{\ }l}
+l_1&\leq&x_1&\leq&u_1\\
+l_2&\leq&x_2&\leq&u_2\\
+\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .}\\
+l_n&\leq&x_n&\leq&u_n\\
+\end{array}\eqno(1.3)
+$$
+
+\newpage
+
+\noindent
+where $x_1$, $x_2$, \dots, $x_n$ are variables; $z$ is the objective
+function; $c_1$, $c_2$, \dots, $c_n$ are objective coefficients; $c_0$
+is the constant term (``shift'') of the objective function; $a_{11}$,
+$a_{12}$, \dots, $a_{mn}$ are constraint coefficients; $L_1$, $L_2$,
+\dots, $L_m$ are lower constraint bounds; $U_1$, $U_2$, \dots, $U_m$
+are upper constraint bounds; $l_1$, $l_2$, \dots, $l_n$ are lower
+bounds of variables; $u_1$, $u_2$, \dots, $u_n$ are upper bounds of
+variables.
+
+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:
+
+\medskip
+
+{\def\arraystretch{1.4}
+\noindent\hspace{54pt}
+\begin{tabular}{@{}r@{\ }c@{\ }c@{\ }c@{\ }l@{\hspace*{39.5pt}}l}
+$-\infty$&$<$&$x$&$<$&$+\infty$&Free (unbounded) variable\\
+$l$&$\leq$&$x$&$<$&$+\infty$&Variable with lower bound\\
+$-\infty$&$<$&$x$&$\leq$&$u$&Variable with upper bound\\
+$l$&$\leq$&$x$&$\leq$&$u$&Double-bounded variable\\
+$l$&$=$&$x$&=&$u$&Fixed variable\\
+\end{tabular}
+
+\noindent\hfil
+\begin{tabular}{@{}r@{\ }c@{\ }c@{\ }c@{\ }ll}
+$-\infty$&$<$&$\sum a_jx_j$&$<$&$+\infty$&Free (unbounded) linear
+form\\
+$L$&$\leq$&$\sum a_jx_j$&$<$&$+\infty$&Inequality constraint ``greater
+than or equal to''\\
+$-\infty$&$<$&$\sum a_jx_j$&$\leq$&$U$&Inequality constraint ``less
+than or equal to''\\
+$L$&$\leq$&$\sum a_jx_j$&$\leq$&$U$&Double-bounded inequality
+constraint\\
+$L$&$=$&$\sum a_jx_j$&=&$U$&Equality constraint\\
+\end{tabular}
+}
+
+\medskip
+
+In addition to pure LP problems MathProg also allows mixed integer
+linear programming (MIP) problems, where some or all variables are
+restricted to be integer or binary.
+
+\section{Model objects}
+
+In MathProg the model is described in terms of sets, parameters,
+variables, constraints, and objectives, which are called {\it model
+objects}.
+
+The user introduces particular model objects using the language
+statements. Each model object is provided with a symbolic name which
+uniquely identifies the object and is intended for referencing
+purposes.
+
+Model objects, including sets, can be multidimensional arrays built
+over indexing sets. Formally, $n$-dimensional array $A$ is the mapping:
+$$A:\Delta\rightarrow\Xi,\eqno(1.4)$$
+where $\Delta\subseteq S_1\times\dots\times S_n$ is a subset of the
+Cartesian product of indexing sets, $\Xi$ is a set of array members.
+In MathProg the set $\Delta$ is called the {\it subscript domain}. Its
+members are $n$-tuples $(i_1,\dots,i_n)$, where $i_1\in S_1$, \dots,
+$i_n\in S_n$.
+
+If $n=0$, the Cartesian product above has exactly one member (namely,
+0-tuple), so it is convenient to think scalar objects as 0-dimensional
+arrays having one member.
+
+\newpage
+
+The type of array members is determined by the type of corresponding
+model object as follows:
+
+\medskip
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Model object&Array member\\
+\hline
+Set&Elemental plain set\\
+Parameter&Number or symbol\\
+Variable&Elemental variable\\
+Constraint&Elemental constraint\\
+Objective&Elemental objective\\
+\end{tabular}
+
+\medskip
+
+In order to refer to a particular object member the object should be
+provided with {\it subscripts}. For example, if $a$ is a 2-dimensional
+parameter defined over $I\times J$, a reference to its particular
+member can be written as $a[i,j]$, where $i\in I$ and $j\in J$. It is
+understood that scalar objects being 0-dimensional need no subscripts.
+
+\section{Structure of model description}
+
+It is sometimes desirable to write a model which, at various points,
+may require different data for each problem instance to be solved using
+that model. For this reason in MathProg the model description consists
+of two parts: the {\it model section} and the {\it data section}.
+
+The 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.
+
+The data section is an optional part of the model description that
+contains data specific for a particular problem instance.
+
+Depending on what is more convenient the model and data sections can be
+placed either in one file or in two separate files. The latter feature
+allows having arbitrary number of different data sections to be used
+with the same model section.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Coding model description}
+\label{coding}
+
+The model description is coded in a plain text format using ASCII
+character set. Characters valid in the model description are the
+following:
+
+\begin{itemize}
+\item alphabetic characters:\\
+\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 _|
+\item numeric characters:\\
+\verb|0 1 2 3 4 5 6 7 8 9|
+\item special characters:\\
+\verb?! " # & ' ( ) * + , - . / : ; < = > [ ] ^ { | } ~?
+\item white-space characters:\\
+\verb|SP HT CR NL VT FF|
+\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:
+
+\begin{itemize}
+\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.
+
+\newpage
+
+\section{Symbolic names}
+
+A {\it symbolic name} consists of alphabetic and numeric characters,
+the first of which should be alphabetic. All symbolic names are
+distinct (case sensitive).
+
+\para{Examples}
+
+\begin{verbatim}
+alpha123
+This_is_a_name
+_P123_abc_321
+\end{verbatim}
+
+Symbolic names are used to identify model objects (sets, parameters,
+variables, constraints, objectives) and dummy indices.
+
+All symbolic names (except names of dummy indices) should be unique,
+i.e. the model description should have no objects with identical names.
+Symbolic names of dummy indices should be unique within the scope,
+where they are valid.
+
+\section{Numeric literals}
+
+A {\it numeric literal} has the form {\it xx}{\tt E}{\it syy}, where
+{\it xx} is a number with optional decimal point, {\it s} is the sign
+{\tt+} or {\tt-}, {\it yy} is a decimal exponent. The letter {\tt E} is
+case insensitive and can be coded as {\tt e}.
+
+\para{Examples}
+
+\begin{verbatim}
+123
+3.14159
+56.E+5
+.78
+123.456e-7
+\end{verbatim}
+
+Numeric literals are used to represent numeric quantities. They have
+obvious fixed meaning.
+
+\section{String literals}
+
+A {\it string literal} is a sequence of arbitrary characters enclosed
+either in single quotes or in double quotes. Both these forms are
+equivalent.
+
+If a single quote is part of a string literal enclosed in single
+quotes, it should be coded twice. Analogously, if a double quote is
+part of a string literal enclosed in double quotes, it should be coded
+twice.
+
+\para{Examples}
+
+\begin{verbatim}
+'This is a string'
+"This is another string"
+'That''s all'
+"""Hello there,"" said the captain."
+\end{verbatim}
+
+String literals are used to represent symbolic quantities.
+
+\section{Keywords}
+
+A {\it keyword} is a sequence of alphabetic characters and possibly
+some special characters.
+
+All keywords fall into two categories: {\it reserved keywords}, which
+cannot be used as symbolic names, and {\it non-reserved keywords},
+which are recognized by context and therefore can be used as symbolic
+names.
+
+The reserved keywords are the following:
+
+\noindent\hfil
+\begin{tabular}{@{}p{.7in}p{.7in}p{.7in}p{.7in}@{}}
+{\tt and}&{\tt else}&{\tt mod}&{\tt union}\\
+{\tt by}&{\tt if}&{\tt not}&{\tt within}\\
+{\tt cross}&{\tt in}&{\tt or}\\
+{\tt diff}&{\tt inter}&{\tt symdiff}\\
+{\tt div}&{\tt less}&{\tt then}\\
+\end{tabular}
+
+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.
+
+\section{Delimiters}
+
+A {\it delimiter} is either a single special character or a sequence of
+two special characters as follows:
+
+\noindent\hfil
+\begin{tabular}{@{}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}
+p{.3in}p{.3in}@{}}
+{\tt+}&{\tt**}&{\tt<=}&{\tt>}&{\tt\&\&}&{\tt:}&{\tt|}&{\tt[}&
+{\tt>>}\\
+{\tt-}&{\tt\textasciicircum}&{\tt=}&{\tt<>}&{\tt||}&{\tt;}&
+{\tt\char126}&{\tt]}&{\tt<-}\\
+{\tt*}&{\tt\&}&{\tt==}&{\tt!=}&{\tt.}&{\tt:=}&{\tt(}&{\tt\{}\\
+{\tt/}&{\tt<}&{\tt>=}&{\tt!}&{\tt,}&{\tt..}&{\tt)}&{\tt\}}\\
+\end{tabular}
+
+If the delimiter consists of two characters, there should 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.
+
+\section{Comments}
+
+For documenting purposes the model description can be provided with
+{\it comments}, which may have two different forms. The first form is
+a {\it single-line comment}, which begins with the character {\tt\#}
+and extends until end of line. The second form is a {\it comment
+sequence}, which is a sequence of any characters enclosed within
+{\tt/*} and {\tt*/}.
+
+\para{Examples}
+
+\begin{verbatim}
+param n := 10; # This is a comment
+/* This is another comment */
+\end{verbatim}
+
+Comments are ignored by the model translator and can appear anywhere in
+the model description, where white-space characters are allowed.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\chapter{Expressions}
+
+An {\it 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:
+
+\vspace*{-8pt}
+
+\begin{itemize}
+\item numeric expressions;
+\item symbolic expressions;
+\item indexing expressions;
+\item set expressions;
+\item logical expressions;
+\item linear expressions.
+\end{itemize}
+
+\vspace*{-8pt}
+
+\section{Numeric expressions}
+
+A {\it numeric expression} is a rule for computing a single numeric
+value represented as a 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.
+
+\para{Examples}
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|1.23 |&(numeric literal)\\
+\verb|j|&(dummy index)\\
+\verb|time|&(unsubscripted parameter)\\
+\verb|a['May 2003',j+1]|&(subscripted parameter)\\
+\verb|abs(b[i,j])|&(function reference)\\
+\end{tabular}
+
+\newpage
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|sum{i in S diff T} alpha[i] * b[i,j]|&(iterated expression)\\
+\verb|if i in I then 2 * p else q[i+1]|&(conditional expression)\\
+\verb|(b[i,j] + .5 * c)|&(parenthesized expression)\\
+\end{tabular}
+
+More general numeric expressions containing two or more primary numeric
+expressions may be constructed by using certain arithmetic operators.
+
+\para{Examples}
+
+\begin{verbatim}
+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 and p >= 1 then 2 * p else q[i+1]) / (a[i,j] + 1.5)
+\end{verbatim}
+
+\subsection{Numeric literals}
+
+If the primary numeric expression is a numeric literal, the resultant
+value is obvious.
+
+\subsection{Dummy indices}
+
+If the primary numeric expression is a dummy index, the resultant value
+is current value assigned to that dummy index.
+
+\subsection{Unsubscripted parameters}
+
+If the primary numeric expression is an unsubscripted parameter (which
+should be 0-dimen\-sional), the resultant value is the value of that
+parameter.
+
+\subsection{Subscripted parameters}
+
+The primary numeric expression, which refers to a subscripted
+parameter, has the following syntactic form:
+$$
+\mbox{{\it name}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,} $i_n${\tt]}}
+$$
+where {\it name} is the symbolic name of the parameter, $i_1$, $i_2$,
+\dots, $i_n$ are subscripts.
+
+Each subscript should be a numeric or symbolic expression. The number
+of subscripts in the subscript list should 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.
+
+\newpage
+
+\subsection{Function references}
+
+In MathProg there exist the following built-in functions which may be
+used in numeric expressions:
+
+\begin{tabular}{@{}p{112pt}p{328pt}@{}}
+{\tt abs(}$x${\tt)}&$|x|$, absolute value of $x$\\
+{\tt atan(}$x${\tt)}&$\arctan x$, principal value of the arc tangent of
+$x$ (in radians)\\
+{\tt atan(}$y${\tt,} $x${\tt)}&$\arctan y/x$, principal value of the
+arc tangent of $y/x$ (in radians). In this case the signs of both
+arguments $y$ and $x$ are used to determine the quadrant of the
+resultant value\\
+{\tt card(}$X${\tt)}&$|X|$, cardinality (the number of elements) of
+set $X$\\
+{\tt ceil(}$x${\tt)}&$\lceil x\rceil$, smallest integer not less than
+$x$ (``ceiling of $x$'')\\
+{\tt cos(}$x${\tt)}&$\cos x$, cosine of $x$ (in radians)\\
+{\tt exp(}$x${\tt)}&$e^x$, base-$e$ exponential of $x$\\
+{\tt floor(}$x${\tt)}&$\lfloor x\rfloor$, largest integer not greater
+than $x$ (``floor of $x$'')\\
+{\tt gmtime()}&the number of seconds elapsed since 00:00:00~Jan~1, 1970,
+Coordinated Universal Time (for details see Section \ref{gmtime},
+page \pageref{gmtime})\\
+{\tt length(}$s${\tt)}&$|s|$, length of character string $s$\\
+{\tt log(}$x${\tt)}&$\log x$, natural logarithm of $x$\\
+{\tt log10(}$x${\tt)}&$\log_{10}x$, common (decimal) logarithm of $x$\\
+{\tt max(}$x_1${\tt,} $x_2${\tt,} \dots{\tt,} $x_n${\tt)}&the largest
+of values $x_1$, $x_2$, \dots, $x_n$\\
+{\tt min(}$x_1${\tt,} $x_2${\tt,} \dots{\tt,} $x_n${\tt)}&the smallest
+of values $x_1$, $x_2$, \dots, $x_n$\\
+{\tt round(}$x${\tt)}&rounding $x$ to nearest integer\\
+{\tt round(}$x${\tt,} $n${\tt)}&rounding $x$ to $n$ fractional decimal
+digits\\
+{\tt sin(}$x${\tt)}&$\sin x$, sine of $x$ (in radians)\\
+{\tt sqrt(}$x${\tt)}&$\sqrt{x}$, non-negative square root of $x$\\
+{\tt str2time(}$s${\tt,} $f${\tt)}&converting character string $s$ to
+calendar time (for details see Section \ref{str2time}, page
+\pageref{str2time})\\
+{\tt tan(}$x${\tt)}&$\tan x$, tangent of $x$ (in radians)\\
+{\tt trunc(}$x${\tt)}&truncating $x$ to nearest integer\\
+{\tt trunc(}$x${\tt,} $n${\tt)}&truncating $x$ to $n$ fractional
+decimal digits\\
+{\tt Irand224()}&generating pseudo-random integer uniformly distributed
+in $[0,2^{24})$\\
+{\tt Uniform01()}&generating pseudo-random number uniformly distributed
+in $[0,1)$\\
+{\tt Uniform(}$a${\tt,} $b${\tt)}&generating pseudo-random number
+uniformly distributed in $[a,b)$\\
+{\tt Normal01()}&generating Gaussian pseudo-random variate with
+$\mu=0$ and $\sigma=1$\\
+{\tt Normal(}$\mu${\tt,} $\sigma${\tt)}&generating Gaussian
+pseudo-random variate with given $\mu$ and $\sigma$\\
+\end{tabular}
+
+Arguments of all built-in functions, except {\tt card}, {\tt length},
+and {\tt str2time}, should be numeric expressions. The argument of
+{\tt card} should be a set expression. The argument of {\tt length} and
+both arguments of {\tt str2time} should 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 has 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.
+
+\newpage
+
+\subsection{Iterated expressions}
+\label{itexpr}
+
+An {\it iterated numeric expression} is a primary numeric expression,
+which has the following syntactic form:
+$$\mbox{\it iterated-operator indexing-expression integrand}$$
+where {\it iterated-operator} is the symbolic name of the iterated
+operator to be performed (see below), {\it indexing-expression} is an
+indexing expression which introduces dummy indices and controls
+iterating, {\it integrand} is a numeric expression that participates in
+the operation.
+
+In MathProg there exist four iterated operators, which may be used in
+numeric expressions:
+
+{\def\arraystretch{2}
+\noindent\hfil
+\begin{tabular}{@{}lll@{}}
+{\tt sum}&summation&$\displaystyle\sum_{(i_1,\dots,i_n)\in\Delta}
+f(i_1,\dots,i_n)$\\
+{\tt prod}&production&$\displaystyle\prod_{(i_1,\dots,i_n)\in\Delta}
+f(i_1,\dots,i_n)$\\
+{\tt min}&minimum&$\displaystyle\min_{(i_1,\dots,i_n)\in\Delta}
+f(i_1,\dots,i_n)$\\
+{\tt max}&maximum&$\displaystyle\max_{(i_1,\dots,i_n)\in\Delta}
+f(i_1,\dots,i_n)$\\
+\end{tabular}
+}
+
+\noindent where $i_1$, \dots, $i_n$ are dummy indices introduced in
+the indexing expression, $\Delta$ is the domain, a set of $n$-tuples
+specified by the indexing expression which defines particular values
+assigned to the dummy indices on performing the iterated operation,
+$f(i_1,\dots,i_n)$ is the integrand, a numeric expression whose
+resultant value depends on the dummy indices.
+
+The resultant value of an iterated numeric expression is the result of
+applying of the iterated operator to its integrand over all $n$-tuples
+contained in the domain.
+
+\subsection{Conditional expressions}
+\label{ifthen}
+
+A {\it conditional numeric expression} is a primary numeric expression,
+which has one of the following two syntactic forms:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{{\tt if} $b$ {\tt then} $x$ {\tt else} $y$}\\
+\mbox{{\tt if} $b$ {\tt then} $x$}\\
+\end{array}
+}
+$$
+where $b$ is an logical expression, $x$ and $y$ are numeric
+expressions.
+
+The resultant value of the conditional expression depends on the value
+of the logical expression that follows the keyword {\tt if}. If it
+takes on the value {\it true}, the value of the conditional expression
+is the value of the expression that follows the keyword {\tt then}.
+Otherwise, if the logical expression takes on the value {\it false},
+the value of the conditional expression is the value of the expression
+that follows the keyword {\it else}. If the second, reduced form of the
+conditional expression is used and the logical expression takes on the
+value {\it false}, the resultant value of the conditional expression is
+zero.
+
+\newpage
+
+\subsection{Parenthesized expressions}
+
+Any numeric expression may be enclosed in parentheses that
+syntactically makes it a 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.
+
+\subsection{Arithmetic operators}
+
+In MathProg there exist the following arithmetic operators, which may
+be used in numeric expressions:
+
+\begin{tabular}{@{}ll@{}}
+{\tt +} $x$&unary plus\\
+{\tt -} $x$&unary minus\\
+$x$ {\tt +} $y$&addition\\
+$x$ {\tt -} $y$&subtraction\\
+$x$ {\tt less} $y$&positive difference (if $x<y$ then 0 else $x-y$)\\
+$x$ {\tt *} $y$&multiplication\\
+$x$ {\tt /} $y$&division\\
+$x$ {\tt div} $y$&quotient of exact division\\
+$x$ {\tt mod} $y$&remainder of exact division\\
+$x$ {\tt **} $y$, $x$ {\tt\textasciicircum} $y$&exponentiation (raising
+to power)\\
+\end{tabular}
+
+\noindent where $x$ and $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.
+
+\subsection{Hierarchy of operations}
+\label{hierarchy}
+
+The following list shows the hierarchy of operations in numeric
+expressions:
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Operation&Hierarchy\\
+\hline
+Evaluation of functions ({\tt abs}, {\tt ceil}, etc.)&1st\\
+Exponentiation ({\tt**}, {\tt\textasciicircum})&2nd\\
+Unary plus and minus ({\tt+}, {\tt-})&3rd\\
+Multiplication and division ({\tt*}, {\tt/}, {\tt div}, {\tt mod})&4th\\
+Iterated operations ({\tt sum}, {\tt prod}, {\tt min}, {\tt max})&5th\\
+Addition and subtraction ({\tt+}, {\tt-}, {\tt less})&6th\\
+Conditional evaluation ({\tt if} \dots {\tt then} \dots {\tt else})&
+7th\\
+\end{tabular}
+
+\newpage
+
+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.
+
+\section{Symbolic expressions}
+
+A {\it symbolic expression} is a rule for computing a single symbolic
+value represented as a 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.
+
+\para{Examples}
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|'May 2003'|&(string literal)\\
+\verb|j|&(dummy index)\\
+\verb|p|&(unsubscripted parameter)\\
+\verb|s['abc',j+1]|&(subscripted parameter)\\
+\verb|substr(name[i],k+1,3)|&(function reference)\\
+\verb|if i in I then s[i,j] & "..." else t[i+1]|
+& (conditional expression) \\
+\verb|((10 * b[i,j]) & '.bis')|&(parenthesized expression)\\
+\end{tabular}
+
+More general symbolic expressions containing two or more primary
+symbolic expressions may be constructed by using the concatenation
+operator.
+
+\para{Examples}
+
+\begin{verbatim}
+'abc[' & i & ',' & j & ']'
+"from " & city[i] " to " & city[j]
+\end{verbatim}
+
+The principles of evaluation of symbolic expressions are completely
+analogous to the ones given for numeric expressions (see above).
+
+\subsection{Function references}
+
+In MathProg there exist the following built-in functions which may be
+used in symbolic expressions:
+
+\begin{tabular}{@{}p{112pt}p{328pt}@{}}
+{\tt substr(}$s${\tt,} $x${\tt)}&substring of $s$ starting from
+position $x$\\
+{\tt substr(}$s${\tt,} $x${\tt,} $y${\tt)}&substring of $s$ starting
+from position $x$ and having length $y$\\
+{\tt time2str(}$t${\tt,} $f${\tt)}&converting calendar time to
+character string (for details see Section \ref{time2str}, page
+\pageref{time2str})\\
+\end{tabular}
+
+The first argument of {\tt substr} should be a symbolic expression
+while its second and optional third arguments should be numeric
+expressions.
+
+The first argument of {\tt time2str} should be a numeric expression,
+and its second argument should 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.
+
+\subsection{Symbolic operators}
+
+Currently in MathProg there exists the only symbolic operator:
+$$\mbox{\tt s \& t}$$
+where $s$ and $t$ are symbolic expressions. This operator means
+concatenation of its two symbolic operands, which are character
+strings.
+
+\subsection{Hierarchy of operations}
+
+The following list shows the hierarchy of operations in symbolic
+expressions:
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Operation&Hierarchy\\
+\hline
+Evaluation of numeric operations&1st-7th\\
+Concatenation ({\tt\&})&8th\\
+Conditional evaluation ({\tt if} \dots {\tt then} \dots {\tt else})&
+9th\\
+\end{tabular}
+
+This hierarchy has the same meaning as was explained above for numeric
+expressions (see Subsection \ref{hierarchy}, page \pageref{hierarchy}).
+
+\section{Indexing expressions and dummy indices}
+\label{indexing}
+
+An {\it indexing expression} is an auxiliary construction, which
+specifies a plain set of $n$-tuples and introduces dummy indices. It
+has two syntactic forms:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{{\tt\{} {\it entry}$_1${\tt,} {\it entry}$_2${\tt,} \dots{\tt,}
+{\it entry}$_m$ {\tt\}}}\\
+\mbox{{\tt\{} {\it entry}$_1${\tt,} {\it entry}$_2${\tt,} \dots{\tt,}
+{\it entry}$_m$ {\tt:} {\it predicate} {\tt\}}}\\
+\end{array}
+}
+$$
+where {\it entry}{$_1$}, {\it entry}{$_2$}, \dots, {\it entry}{$_m$}
+are indexing entries, {\it predicate} is a logical expression that
+specifies an optional predicate (logical condition).
+
+Each {\it indexing entry} in the indexing expression has one of the
+following three forms:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{$i$ {\tt in} $S$}\\
+\mbox{{\tt(}$i_1${\tt,} $i_2${\tt,} \dots{\tt,}$i_n${\tt)} {\tt in}
+$S$}\\
+\mbox{$S$}\\
+\end{array}
+}
+$$
+where $i_1$, $i_2$, \dots, $i_n$ are indices, $S$ is a set expression
+(discussed in the next section) that specifies the basic set.
+
+\newpage
+
+The number of indices in the indexing entry should be the same as the
+dimension of the basic set $S$, i.e. if $S$ consists of 1-tuples, the
+first form should be used, and if $S$ consists of $n$-tuples, where
+$n>1$, the second form should be used.
+
+If the first form of the indexing entry is used, the index $i$ can be
+a dummy index only (see below). If the second form is used, the indices
+$i_1$, $i_2$, \dots, $i_n$ can be either dummy indices or some numeric
+or symbolic expressions, where at least one index should be a dummy
+index. The third, reduced form of the indexing entry has the same
+effect as if there were $i$ (if $S$ is 1-dimensional) or
+$i_1$, $i_2$, \dots, $i_n$ (if $S$ is $n$-dimensional) all specified as
+dummy indices.
+
+A {\it dummy index} is an auxiliary model object, which acts like an
+individual variable. Values assigned to dummy indices are components of
+$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 need not be explicitly declared. Each {\it 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:
+
+\vspace*{-8pt}
+
+\begin{itemize}
+\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 that 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{itemize}
+
+\vspace*{-8pt}
+
+The indexing mechanism implemented by means of indexing expressions is
+best explained by some examples discussed below.
+
+Let there be given three sets:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+A=\{4,7,9\},\\
+B=\{(1,Jan),(1,Feb),(2,Mar),(2,Apr),(3,May),(3,Jun)\},\\
+C=\{a,b,c\},\\
+\end{array}
+}
+$$
+where $A$ and $C$ consist of 1-tuples (singlets), $B$ consists of
+2-tuples (doublets). Consider the following indexing expression:
+$$\mbox{{\tt\{i in A, (j,k) in B, l in C\}}}$$
+where {\tt i}, {\tt j}, {\tt k}, and {\tt l} are dummy indices.
+
+\newpage
+
+Although MathProg is not a procedural language, for any indexing
+expression an equivalent algorithmic description can be given. In
+particular, the algorithmic description of the indexing expression
+above could look like follows:
+
+\noindent\hfil
+\begin{tabular}{@{}l@{}}
+{\bf for all} $i\in A$ {\bf do}\\
+\hspace{16pt}{\bf for all} $(j,k)\in B$ {\bf do}\\
+\hspace{32pt}{\bf for all} $l\in C$ {\bf do}\\
+\hspace{48pt}{\it action};\\
+\end{tabular}
+
+\noindent where the dummy indices $i$, $j$, $k$, $l$ are consecutively
+assigned corresponding components of $n$-tuples from the basic sets $A$,
+$B$, $C$, and {\it action} is some action that depends on the context,
+where the indexing expression is used. For example, if the action were
+printing current values of dummy indices, the printout would look like
+follows:
+
+\noindent\hfil
+\begin{tabular}{@{}llll@{}}
+$i=4$&$j=1$&$k=Jan$&$l=a$\\
+$i=4$&$j=1$&$k=Jan$&$l=b$\\
+$i=4$&$j=1$&$k=Jan$&$l=c$\\
+$i=4$&$j=1$&$k=Feb$&$l=a$\\
+$i=4$&$j=1$&$k=Feb$&$l=b$\\
+\multicolumn{4}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\
+$i=9$&$j=3$&$k=Jun$&$l=b$\\
+$i=9$&$j=3$&$k=Jun$&$l=c$\\
+\end{tabular}
+
+Let the example indexing expression be used in the following iterated
+operation:
+$$\mbox{{\tt sum\{i in A, (j,k) in B, l in C\} p[i,j,k,l]}}$$
+where {\tt p} is a 4-dimensional numeric parameter or some numeric
+expression whose resultant value depends on {\tt i}, {\tt j}, {\tt k},
+and {\tt l}. In this case the action is summation, so the resultant
+value of the primary numeric expression is:
+$$\sum_{i\in A,(j,k)\in B,l\in C}(p_{ijkl}).$$
+
+Now let the example indexing expression be used as a primary set
+expression. In this case the action is gathering all 4-tuples
+(quadruplets) of the form $(i,j,k,l)$ in one set, so the resultant
+value of such operation is simply the Cartesian product of the basic
+sets:
+$$A\times B\times C=\{(i,j,k,l):i\in A,(j,k)\in B,l\in C\}.$$
+Note that in this case the same indexing expression might be written in
+the reduced form:
+$$\mbox{{\tt\{A, B, C\}}}$$
+because the dummy indices $i$, $j$, $k$, and $l$ are not referenced and
+therefore their symbolic names need not be specified.
+
+\newpage
+
+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:
+$$\mbox{{\tt param p\{i in A, (j,k) in B, l in C\}} \dots {\tt;}}$$
+
+\noindent In this case the action is generating the parameter members,
+where each member has the form $p[i,j,k,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 $n$-tuples from the Cartesian product of
+basic sets that satisfy these conditions.
+
+Consider, for example, the following indexing expression:
+$$\mbox{{\tt\{i in A, (i-1,k) in B, l in C\}}}$$
+where {\tt i}, {\tt k}, {\tt l} are dummy indices, and {\tt i-1} is
+a numeric expression. The algorithmic decsription of this indexing
+expression is the following:
+
+\noindent\hfil
+\begin{tabular}{@{}l@{}}
+{\bf for all} $i\in A$ {\bf do}\\
+\hspace{16pt}{\bf for all} $(j,k)\in B$ {\bf and} $j=i-1$ {\bf do}\\
+\hspace{32pt}{\bf for all} $l\in C$ {\bf do}\\
+\hspace{48pt}{\it action};\\
+\end{tabular}
+
+\noindent Thus, if this indexing expression were used as a primary set
+expression, the resultant set would be the following:
+$$\{(4,May,a),(4,May,b),(4,May,c),(4,Jun,a),(4,Jun,b),(4,Jun,c)\}.$$
+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
+$B$.
+
+The general rule is: the number of components of $n$-tuples defined by
+an indexing expression is the same as the number of dummy indices in
+that expression, where the correspondence between dummy indices and
+components on $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 some 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 the indexing expression.
+
+Consider, for example, the following indexing expression:
+$$\mbox{{\tt\{i in A, (j,k) in B, l in C: i <= 5 and k <> 'Mar'\}}}$$
+where the logical expression following the colon is a predicate. The
+algorithmic description of this indexing expression is the following:
+
+\noindent\hfil
+\begin{tabular}{@{}l@{}}
+{\bf for all} $i\in A$ {\bf do}\\
+\hspace{16pt}{\bf for all} $(j,k)\in B$ {\bf do}\\
+\hspace{32pt}{\bf for all} $l\in C$ {\bf do}\\
+\hspace{48pt}{\bf if} $i\leq 5$ {\bf and} $k\neq`Mar'$ {\bf then}\\
+\hspace{64pt}{\it action};\\
+\end{tabular}
+
+\noindent Thus, if this indexing expression were used as a primary set
+expression, the resultant set would be the following:
+$$\{(4,1,Jan,a),(4,1,Feb,a),(4,2,Apr,a),\dots,(4,3,Jun,c)\}.$$
+
+If no predicate is specified in the indexing expression, one, which
+takes on the value {\it true}, is assumed.
+
+\section{Set expressions}
+
+A {\it set expression} is a rule for computing an elemental set, i.e.
+a collection of $n$-tuples, where components of $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.
+
+\para{Examples}
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|{(123,'aaa'), (i+1,'bbb'), (j-1,'ccc')}| &(literal set)\\
+\verb|I| &(unsubscripted set)\\
+\verb|S[i-1,j+1]| &(subscripted set)\\
+\verb|1..t-1 by 2| &(``arithmetic'' set)\\
+\verb|{t in 1..T, (t+1,j) in S: (t,j) in F}| &(indexing expression)\\
+\verb|setof{i in I, j in J}(i+1,j-1)| &(iterated set expression)\\
+\verb|if i < j then S[i,j] else F diff S[i,j]| &(conditional set
+expression)\\
+\verb|(1..10 union 21..30)| &(parenthesized set expression)\\
+\end{tabular}
+
+More general set expressions containing two or more primary set
+expressions may be constructed by using certain set operators.
+
+\para{Examples}
+
+\begin{verbatim}
+(A union B) inter (I cross J)
+1..10 cross (if i < j then {'a', 'b', 'c'} else {'d', 'e', 'f'})
+\end{verbatim}
+
+\subsection{Literal sets}
+
+A {\it literal set} is a primary set expression, which has the
+following two syntactic forms:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{{\tt\{}$e_1${\tt,} $e_2${\tt,} \dots{\tt,} $e_m${\tt\}}}\\
+\mbox{{\tt\{(}$e_{11}${\tt,} \dots{\tt,} $e_{1n}${\tt),}
+{\tt(}$e_{21}${\tt,} \dots{\tt,} $e_{2n}${\tt),} \dots{\tt,}
+{\tt(}$e_{m1}${\tt,} \dots{\tt,} $e_{mn}${\tt)\}}}\\
+\end{array}
+}
+$$
+where $e_1$, \dots, $e_m$, $e_{11}$, \dots, $e_{mn}$ are numeric or
+symbolic expressions.
+
+If the first form is used, the resultant set consists of 1-tuples
+(singlets) enumerated within the curly braces. It is allowed to specify
+an empty set as {\tt\{\ \}}, which has no 1-tuples. If the second form
+is used, the resultant set consists of $n$-tuples enumerated within the
+curly braces, where a particular $n$-tuple consists of corresponding
+components enumerated within the parentheses. All $n$-tuples should
+have the same number of components.
+
+\subsection{Unsubscripted sets}
+
+If the primary set expression is an unsubscripted set (which should be
+0-dimen\-sional), the resultant set is an elemental set associated with
+the corresponding set object.
+
+\subsection{Subscripted sets}
+
+The primary set expression, which refers to a subscripted set, has the
+following syntactic form:
+$$\mbox{{\it name}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,}
+$i_n${\tt]}}$$
+where {\it name} is the symbolic name of the set object, $i_1$, $i_2$,
+\dots, $i_n$ are subscripts.
+
+Each subscript should be a numeric or symbolic expression. The number
+of subscripts in the subscript list should 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.
+
+\subsection{``Arithmetic'' sets}
+
+The primary set expression, which is an ``arithmetic'' set, has the
+following two syntactic forms:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{$t_0$ {\tt..} $t_1$ {\tt by} $\delta t$}\\
+\mbox{$t_0$ {\tt..} $t_1$}\\
+\end{array}
+}
+$$
+where $t_0$, $t_1$, and $\delta t$ are numeric expressions (the value
+of $\delta t$ should not be zero). The second form is equivalent to the
+first form, where $\delta t=1$.
+
+If $\delta t>0$, the resultant set is determined as follows:
+$$\{t:\exists k\in{\cal Z}(t=t_0+k\delta t,\ t_0\leq t\leq t_1)\}.$$
+Otherwise, if $\delta t<0$, the resultant set is determined as follows:
+$$\{t:\exists k\in{\cal Z}(t=t_0+k\delta t,\ t_1\leq t\leq t_0)\}.$$
+
+\subsection{Indexing expressions}
+
+If the primary set expression is an indexing expression, the resultant
+set is determined as described above in Section \ref{indexing}, page
+\pageref{indexing}.
+
+\newpage
+
+\subsection{Iterated expressions}
+
+An {\it iterated set expression} is a primary set expression, which has
+the following syntactic form:
+$$\mbox{{\tt setof} {\it indexing-expression} {\it integrand}}$$
+where {\it indexing-expression} is an indexing expression, which
+introduces dummy indices and controls iterating, {\it 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:
+$$\{x:(i_1,\dots,i_n)\in\Delta\},$$
+\noindent where $x$ is a value of the integrand, $i_1$, \dots, $i_n$
+are dummy indices introduced in the indexing expression, $\Delta$ is
+the domain, a set of $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 $m$ numeric and symbolic
+expressions, the resultant set consists of $m$-tuples and is determined
+as follows:
+$$\{(x_1,\dots,x_m):(i_1,\dots,i_n)\in\Delta\},$$
+where $x_1$, \dots, $x_m$ are values of the expressions in the
+integrand list, $i_1$, \dots, $i_n$ and $\Delta$ have the same meaning
+as above.
+
+\subsection{Conditional expressions}
+
+A {\it conditional set expression} is a primary set expression that has
+the following syntactic form:
+$$\mbox{{\tt if} $b$ {\tt then} $X$ {\tt else} $Y$}$$
+where $b$ is an logical expression, $X$ and $Y$ are set expressions,
+which should 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 {\tt if}. If it
+takes on the value {\it true}, the resultant set is the value of the
+expression that follows the keyword {\tt then}. Otherwise, if the
+logical expression takes on the value {\it false}, the resultant set is
+the value of the expression that follows the keyword {\tt else}.
+
+\subsection{Parenthesized expressions}
+
+Any set expression may be enclosed in parentheses that syntactically
+makes it a 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.
+
+\newpage
+
+\subsection{Set operators}
+
+In MathProg there exist the following set operators, which may be used
+in set expressions:
+
+\begin{tabular}{@{}ll@{}}
+$X$ {\tt union} $Y$&union $X\cup Y$\\
+$X$ {\tt diff} $Y$&difference $X\backslash Y$\\
+$X$ {\tt symdiff} $Y$&symmetric difference
+$X\oplus Y=(X\backslash Y)\cup(Y\backslash X)$\\
+$X$ {\tt inter} $Y$&intersection $X\cap Y$\\
+$X$ {\tt cross} $Y$&cross (Cartesian) product $X\times Y$\\
+\end{tabular}
+
+\noindent where $X$ and Y are set expressions, which should define sets
+of identical dimension (except 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 $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 the dimensions of its operands.
+
+\subsection{Hierarchy of operations}
+
+The following list shows the hierarchy of operations in set
+expressions:
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Operation&Hierarchy\\
+\hline
+Evaluation of numeric operations&1st-7th\\
+Evaluation of symbolic operations&8th-9th\\
+Evaluation of iterated or ``arithmetic'' set ({\tt setof}, {\tt..})&
+10th\\
+Cartesian product ({\tt cross})&11th\\
+Intersection ({\tt inter})&12th\\
+Union and difference ({\tt union}, {\tt diff}, {\tt symdiff})&13th\\
+Conditional evaluation ({\tt if} \dots {\tt then} \dots {\tt else})&
+14th\\
+\end{tabular}
+
+This hierarchy has the same meaning as was explained above for numeric
+expressions (see Subsection \ref{hierarchy}, page \pageref{hierarchy}).
+
+\newpage
+
+\section{Logical expressions}
+
+A {\it logical expression} is a rule for computing a single logical
+value, which can be either {\it true} or {\it false}.
+
+The primary logical expression may be a numeric expression, relational
+expression, iterated logical expression, or another logical expression
+enclosed in parentheses.
+
+\para{Examples}
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|i+1| &(numeric expression)\\
+\verb|a[i,j] < 1.5| &(relational expression)\\
+\verb|s[i+1,j-1] <> 'Mar' & year | &(relational expression)\\
+\verb|(i+1,'Jan') not in I cross J| &(relational expression)\\
+\verb|S union T within A[i] inter B[j]| &(relational expression)\\
+\verb|forall{i in I, j in J} a[i,j] < .5 * b[i]| &(iterated logical
+expression)\\
+\verb|(a[i,j] < 1.5 or b[i] >= a[i,j])| &(parenthesized logical
+expression)\\
+\end{tabular}
+
+More general logical expressions containing two or more primary logical
+expressions may be constructed by using certain logical operators.
+
+\para{Examples}
+
+\begin{verbatim}
+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{verbatim}
+
+\vspace*{-8pt}
+
+\subsection{Numeric expressions}
+
+The resultant value of the primary logical expression, which is a
+numeric expression, is {\it true}, if the resultant value of the
+numeric expression is non-zero. Otherwise the resultant value of the
+logical expression is {\it false}.
+
+\vspace*{-8pt}
+
+\subsection{Relational operators}
+
+In MathProg there exist the following relational operators, which may
+be used in logical expressions:
+
+\begin{tabular}{@{}ll@{}}
+$x$ {\tt<} $y$&test on $x<y$\\
+$x$ {\tt<=} $y$&test on $x\leq y$\\
+$x$ {\tt=} $y$, $x$ {\tt==} $y$&test on $x=y$\\
+$x$ {\tt>=} $y$&test on $x\geq y$\\
+$x$ {\tt>} $y$&test on $x>y$\\
+$x$ {\tt<>} $y$, $x$ {\tt!=} $y$&test on $x\neq y$\\
+$x$ {\tt in} $Y$&test on $x\in Y$\\
+{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt in} $Y$&test on
+$(x_1,\dots,x_n)\in Y$\\
+$x$ {\tt not} {\tt in} $Y$, $x$ {\tt!in} $Y$&test on $x\not\in Y$\\
+{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt not} {\tt in} $Y$,
+{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt !in} $Y$&test on
+$(x_1,\dots,x_n)\not\in Y$\\
+$X$ {\tt within} $Y$&test on $X\subseteq Y$\\
+$X$ {\tt not} {\tt within} $Y$, $X$ {\tt !within} $Y$&test on
+$X\not\subseteq Y$\\
+\end{tabular}
+
+\noindent where $x$, $x_1$, \dots, $x_n$, $y$ are numeric or symbolic
+expressions, $X$ and $Y$ are set expression.
+
+\newpage
+
+1. In the operations {\tt in}, {\tt not in}, and {\tt !in} the
+number of components in the first operands should be the same as the
+dimension of the second operand.
+
+2. In the operations {\tt within}, {\tt not within}, and {\tt !within}
+both operands should have identical dimension.
+
+All the relational operators listed above have their conventional
+mathematical meaning. The resultant value is {\it true}, if
+corresponding relation is satisfied for its operands, otherwise
+{\it false}. (Note that symbolic values are ordered lexicographically,
+and any numeric value precedes any symbolic value.)
+
+\subsection{Iterated expressions}
+
+An {\it iterated logical expression} is a primary logical expression,
+which has the following syntactic form:
+$$\mbox{{\it iterated-operator} {\it indexing-expression}
+{\it integrand}}$$
+where {\it iterated-operator} is the symbolic name of the iterated
+operator to be performed (see below), {\it indexing-expression} is an
+indexing expression which introduces dummy indices and controls
+iterating, {\it integrand} is a numeric expression that participates in
+the operation.
+
+In MathProg there exist two iterated operators, which may be used in
+logical expressions:
+
+{\def\arraystretch{1.4}
+\noindent\hfil
+\begin{tabular}{@{}lll@{}}
+{\tt forall}&$\forall$-quantification&$\displaystyle
+\forall(i_1,\dots,i_n)\in\Delta[f(i_1,\dots,i_n)],$\\
+{\tt exists}&$\exists$-quantification&$\displaystyle
+\exists(i_1,\dots,i_n)\in\Delta[f(i_1,\dots,i_n)],$\\
+\end{tabular}
+}
+
+\noindent where $i_1$, \dots, $i_n$ are dummy indices introduced in
+the indexing expression, $\Delta$ is the domain, a set of $n$-tuples
+specified by the indexing expression which defines particular values
+assigned to the dummy indices on performing the iterated operation,
+$f(i_1,\dots,i_n)$ is the integrand, a logical expression whose
+resultant value depends on the dummy indices.
+
+For $\forall$-quantification the resultant value of the iterated
+logical expression is {\it true}, if the value of the integrand is
+{\it true} for all $n$-tuples contained in the domain, otherwise
+{\it false}.
+
+For $\exists$-quantification the resultant value of the iterated
+logical expression is {\it false}, if the value of the integrand is
+{\it false} for all $n$-tuples contained in the domain, otherwise
+{\it true}.
+
+\subsection{Parenthesized expressions}
+
+Any logical expression may be enclosed in parentheses that
+syntactically makes it a 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.
+
+\newpage
+
+\subsection{Logical operators}
+
+In MathProg there exist the following logical operators, which may be
+used in logical expressions:
+
+\begin{tabular}{@{}ll@{}}
+{\tt not} $x$, {\tt!}$x$&negation $\neg\ x$\\
+$x$ {\tt and} $y$, $x$ {\tt\&\&} $y$&conjunction (logical ``and'')
+$x\;\&\;y$\\
+$x$ {\tt or} $y$, $x$ {\tt||} $y$&disjunction (logical ``or'')
+$x\vee y$\\
+\end{tabular}
+
+\noindent where $x$ and $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 the operations (see below). The resultant value of the expression,
+which contains logical operators, is the result of applying the
+operators to their operands.
+
+\subsection{Hierarchy of operations}
+
+The following list shows the hierarchy of operations in logical
+expressions:
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Operation&Hierarchy\\
+\hline
+Evaluation of numeric operations&1st-7th\\
+Evaluation of symbolic operations&8th-9th\\
+Evaluation of set operations&10th-14th\\
+Relational operations ({\tt<}, {\tt<=}, etc.)&15th\\
+Negation ({\tt not}, {\tt!})&16th\\
+Conjunction ({\tt and}, {\tt\&\&})&17th\\
+$\forall$- and $\exists$-quantification ({\tt forall}, {\tt exists})&
+18th\\
+Disjunction ({\tt or}, {\tt||})&19th\\
+\end{tabular}
+
+This hierarchy has the same meaning as was explained above for numeric
+expressions (see Subsection \ref{hierarchy}, page \pageref{hierarchy}).
+
+\section{Linear expressions}
+
+A {\it linear expression} is a rule for computing so called
+a {\it linear form} or simply a {\it 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 a formula that includes the constant term
+only.
+
+\para{Examples}
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|z| &(unsubscripted variable)\\
+\verb|x[i,j]| &(subscripted variable)\\
+\verb|sum{j in J} (a[i,j] * x[i,j] + 3 * y[i-1])| &
+(iterated linear expression)\\
+\verb|if i in I then x[i,j] else 1.5 * z + 3.25| &
+(conditional linear expression)\\
+\verb|(a[i,j] * x[i,j] + y[i-1] + .1)| &
+(parenthesized linear expression)\\
+\end{tabular}
+
+More general linear expressions containing two or more primary linear
+expressions may be constructed by using certain arithmetic operators.
+
+\para{Examples}
+
+\begin{verbatim}
+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{verbatim}
+
+\vspace*{-5pt}
+
+\subsection{Unsubscripted variables}
+
+If the primary linear expression is an unsubscripted variable (which
+should be 0-dimensional), the resultant formula is that unsubscripted
+variable.
+
+\vspace*{-5pt}
+
+\subsection{Subscripted variables}
+
+The primary linear expression, which refers to a subscripted variable,
+has the following syntactic form:
+$$\mbox{{\it name}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,}
+$i_n${\tt]}}$$
+where {\it name} is the symbolic name of the model variable, $i_1$,
+$i_2$, \dots, $i_n$ are subscripts.
+
+Each subscript should be a numeric or symbolic expression. The number
+of subscripts in the subscript list should be the same as the dimension
+of the model variable with which the subscript list is associated.
+
+Actual values of the 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 corresponding
+member.
+
+\vspace*{-5pt}
+
+\subsection{Iterated expressions}
+
+An {\it iterated linear expression} is a primary linear expression,
+which has the following syntactic form:
+$$\mbox{{\tt sum} {\it indexing-expression} {\it integrand}}$$
+where {\it indexing-expression} is an indexing expression, which
+introduces dummy indices and controls iterating, {\it 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 Subection \ref{itexpr}, page
+\pageref{itexpr}) with exception that the integrand participated in the
+summation is a formula, not a numeric value.
+
+\vspace*{-5pt}
+
+\subsection{Conditional expressions}
+
+A {\it conditional linear expression} is a primary linear expression,
+which has one of the following two syntactic forms:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{{\tt if} $b$ {\tt then} $f$ {\tt else} $g$}\\
+\mbox{{\tt if} $b$ {\tt then} $f$}\\
+\end{array}
+}
+$$
+where $b$ is an logical expression, $f$ and $g$ are linear expressions.
+
+\newpage
+
+The conditional linear expression is evaluated exactly in the same way
+as the conditional numeric expression (see Subsection \ref{ifthen},
+page \pageref{ifthen}) with exception that operands participated in the
+operation are formulae, not numeric values.
+
+\subsection{Parenthesized expressions}
+
+Any linear expression may be enclosed in parentheses that syntactically
+makes it a 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.
+
+\subsection{Arithmetic operators}
+
+In MathProg there exists the following arithmetic operators, which may
+be used in linear expressions:
+
+\begin{tabular}{@{}ll@{}}
+{\tt+} $f$&unary plus\\
+{\tt-} $f$&unary minus\\
+$f$ {\tt+} $g$&addition\\
+$f$ {\tt-} $g$&subtraction\\
+$x$ {\tt*} $f$, $f$ {\tt*} $x$&multiplication\\
+$f$ {\tt/} $x$&division
+\end{tabular}
+
+\noindent where $f$ and $g$ are linear expressions, $x$ is a numeric
+expression (more precisely, a linear expression containing only the
+constant term).
+
+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.
+
+\subsection{Hierarchy of operations}
+
+The hierarchy of arithmetic operations used in linear expressions is
+the same as for numeric expressions (see Subsection \ref{hierarchy},
+page \pageref{hierarchy}).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Statements}
+
+{\it Statements} are basic units of the model description. In MathProg
+all statements are divided into two categories: declaration statements
+and functional statements.
+
+{\it Declaration statements} (set statement, parameter statement,
+variable statement, constraint statement, objective statement) are used
+to declare model objects of certain kinds and define certain properties
+of such objects.
+
+{\it Functional statements} (solve statement, check statement, display
+statement, printf statement, loop statement, table 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
+should be declared before it is referenced in other statements.
+
+\section{Set statement}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt set} {\it name} {\it alias} {\it domain} {\tt,}
+{\it attrib} {\tt,} \dots {\tt,} {\it attrib} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it name} is a symbolic name of the set;
+
+\noindent
+{\it alias} is an optional string literal, which specifies an alias of
+the set;
+
+\noindent
+{\it domain} is an optional indexing expression, which specifies
+a subscript domain of the set;
+
+\noindent
+{\it attrib}, \dots, {\it attrib} are optional attributes of the set.
+(Commae preceding attributes may be omitted.)
+
+\para{Optional attributes}
+
+\vspace*{-8pt}
+
+\begin{description}
+\item[{\tt dimen} $n$]\hspace*{0pt}\\
+specifies the dimension of $n$-tuples which the set consists of;
+\item[{\tt within} {\it expression}]\hspace*{0pt}\\
+specifies a superset which restricts the set or all its members
+(elemental sets) to be within that superset;
+\item[{\tt:=} {\it expression}]\hspace*{0pt}\\
+specifies an elemental set assigned to the set or its members;
+\item[{\tt default} {\it expression}]\hspace*{0pt}\\
+specifies an elemental set assigned to the set or its members whenever
+no appropriate data are available in the data section.
+\end{description}
+
+\vspace*{-8pt}
+
+\para{Examples}
+
+\begin{verbatim}
+set nodes;
+set arcs within nodes cross nodes;
+set step{s in 1..maxiter} dimen 2 := if s = 1 then arcs else step[s-1]
+ union setof{k in nodes, (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{verbatim}
+
+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 {\tt dimen} attribute specifies the dimension of $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 $n$ should be an unsigned integer
+from 1 to 20. At most one {\tt dimen} attribute can be specified. If
+the {\tt dimen} attribute is not specified, the dimension of $n$-tuples
+is implicitly determined by other attributes (for example, if there is
+a set expression that follows {\tt:=} or the keyword {\tt default}, the
+dimension of $n$-tuples of corresponding elemental set is used).
+If no dimension information is available, {\tt dimen 1} is assumed.
+
+The {\tt 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
+that superset. Arbitrary number of {\tt within} attributes may be
+specified in the same set statement.
+
+The assign ({\tt:=}) 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 {\it computable} and
+therefore needs no data to be provided in the data section. If the
+assign attribute is not specified, the set should be provided with data
+in the data section. At most one assign or default attribute can be
+specified for the same set.
+
+The {\tt 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 default attribute is specified, missing data will cause an
+error.
+
+\newpage
+
+\section{Parameter statement}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt param} {\it name} {\it alias} {\it domain} {\tt,}
+{\it attrib} {\tt,} \dots {\tt,} {\it attrib} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it name} is a symbolic name of the parameter;
+
+\noindent
+{\it alias} is an optional string literal, which specifies an alias of
+the parameter;
+
+\noindent
+{\it domain} is an optional indexing expression, which specifies
+a subscript domain of the parameter;
+
+\noindent
+{\it attrib}, \dots, {\it attrib} are optional attributes of the
+parameter. (Commae preceding attributes may be omitted.)
+
+\para{Optional attributes}
+
+\vspace*{-8pt}
+
+\begin{description}
+\item[{\tt integer}]\hspace*{0pt}\\
+specifies that the parameter is integer;
+\item[{\tt binary}]\hspace*{0pt}\\
+specifies that the parameter is binary;
+\item[{\tt symbolic}]\hspace*{0pt}\\
+specifies that the parameter is symbolic;
+\item[{\it relation expression}]\hspace*{0pt}\\
+(where {\it relation} is one of: {\tt<}, {\tt<=}, {\tt=}, {\tt==},
+{\tt>=}, {\tt>}, {\tt<>}, {\tt!=})\\
+specifies a condition that restricts the parameter or its members to
+satisfy that condition;
+\item[{\tt in} {\it expression}]\hspace*{0pt}\\
+specifies a superset that restricts the parameter or its members to be
+in that superset;
+\item[{\tt:=} {\it expression}]\hspace*{0pt}\\
+specifies a value assigned to the parameter or its members;
+\item[{\tt default} {\it expression}]\hspace*{0pt}\\
+specifies a value assigned to the parameter or its members whenever
+no appropriate data are available in the data section.
+\end{description}
+
+\vspace*{-8pt}
+
+\para{Examples}
+
+\begin{verbatim}
+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{verbatim}
+
+The parameter statement declares a parameter. If a subscript domain is
+not specified, the parameter is a simple (scalar) parameter, otherwise
+it is a $n$-dimensional array.
+
+The type attributes {\tt integer}, {\tt binary}, and {\tt symbolic}
+qualify the type of values that can be assigned to the parameter as
+shown below:
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Type attribute&Assigned values\\
+\hline
+(not specified)&Any numeric values\\
+{\tt integer}&Only integer numeric values\\
+{\tt binary}&Either 0 or 1\\
+{\tt symbolic}&Any numeric and symbolic values\\
+\end{tabular}
+
+The {\tt symbolic} attribute cannot be specified along with other type
+attributes. Being specified it should precede all other attributes.
+
+The condition attribute specifies an optional condition that restricts
+values assigned to the parameter to satisfy that condition. This
+attribute has the following syntactic forms:
+
+\begin{tabular}{@{}ll@{}}
+{\tt<} $v$&check for $x<v$\\
+{\tt<=} $v$&check for $x\leq v$\\
+{\tt=} $v$, {\tt==} $v$&check for $x=v$\\
+{\tt>=} $v$&check for $x\geq v$\\
+{\tt>} $v$&check for $x\geq v$\\
+{\tt<>} $v$, {\tt!=} $v$&check for $x\neq v$\\
+\end{tabular}
+
+\noindent where $x$ is a value assigned to the parameter, $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 of specified
+conditions, an error is raised. (Note that symbolic values are ordered
+lexicographically, and any numeric value precedes any symbolic value.)
+
+The {\tt 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
+that superset. Arbitrary number of the {\tt 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 of specified
+supersets, an error is raised.
+
+The assign ({\tt:=}) 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 {\it computable}
+and therefore needs no data to be provided in the data section. If the
+assign attribute is not specified, the parameter should be provided
+with data in the data section. At most one assign or {\tt default}
+attribute can be specified for the same parameter.
+
+The {\tt 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 {\tt default} attribute is specified, missing data
+will cause an error.
+
+\newpage
+
+\section{Variable statement}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt var} {\it name} {\it alias} {\it domain} {\tt,}
+{\it attrib} {\tt,} \dots {\tt,} {\it attrib} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it name} is a symbolic name of the variable;
+
+\noindent
+{\it alias} is an optional string literal, which specifies an alias of
+the variable;
+
+\noindent
+{\it domain} is an optional indexing expression, which specifies
+a subscript domain of the variable;
+
+\noindent
+{\it attrib}, \dots, {\it attrib} are optional attributes of the
+variable. (Commae preceding attributes may be omitted.)
+
+\para{Optional attributes}
+
+\vspace*{-8pt}
+
+\begin{description}
+\item[{\tt integer}]\hspace*{0pt}\\
+restricts the variable to be integer;
+\item[{\tt binary}]\hspace*{0pt}\\
+restricts the variable to be binary;
+\item[{\tt>=} {\it expression}]\hspace*{0pt}\\
+specifies an lower bound of the variable;
+\item[{\tt<=} {\it expression}]\hspace*{0pt}\\
+specifies an upper bound of the variable;
+\item[{\tt=} {\it expression}]\hspace*{0pt}\\
+specifies a fixed value of the variable;
+\end{description}
+
+\vspace*{-8pt}
+
+\para{Examples}
+
+\begin{verbatim}
+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{verbatim}
+
+The variable statement declares a variable. If a subscript domain is
+not specified, the variable is a simple (scalar) variable, otherwise it
+is a $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 \ref{problem},
+page \pageref{problem}). Note that only elemental variables actually
+referenced in some constraints and/or objectives are included in the
+LP/MIP problem instance to be generated.
+
+The type attributes {\tt integer} and {\tt 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 ({\tt>=}) attribute specifies a numeric expression for
+computing an lower bound of the variable. At most one lower bound can
+be specified. By default all variables (except binary ones) have no
+lower bound, so if a variable is required to be non-negative, its zero
+lower bound should be explicitly specified.
+
+The upper bound ({\tt<=}) attribute specifies a numeric expression for
+computing an upper bound of the variable. At most one upper bound
+attribute can be specified.
+
+The fixed value ({\tt=}) attribute specifies a numeric expression for
+computing a value, at which the variable is fixed. This attribute
+cannot be specified along with the bound attributes.
+
+\section{Constraint statement}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][106pt]{468pt}{
+\hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:}
+{\it expression} {\tt,} {\tt=} {\it expression} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:}
+{\it expression} {\tt,} {\tt<=} {\it expression} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:}
+{\it expression} {\tt,} {\tt>=} {\it expression} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:}
+{\it expression} {\tt,} {\tt<=} {\it expression} {\tt,} {\tt<=}
+{\it expression} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:}
+{\it expression} {\tt,} {\tt>=} {\it expression} {\tt,} {\tt>=}
+{\it expression} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it name} is a symbolic name of the constraint;
+
+\noindent
+{\it alias} is an optional string literal, which specifies an alias of
+the constraint;
+
+\noindent
+{\it domain} is an optional indexing expression, which specifies
+a subscript domain of the constraint;
+
+\noindent
+{\it expression} is a linear expression used to compute a component of
+the constraint. (Commae following expressions may be omitted.)
+
+\noindent
+(The keyword {\tt s.t.} may be written as {\tt subject to} or as
+{\tt subj to}, or may be omitted at all.)
+
+\para{Examples}
+
+\begin{verbatim}
+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{verbatim}
+
+The constraint statement declares a constraint. If a subscript domain
+is not specified, the\linebreak constraint is a simple (scalar)
+constraint, otherwise it is a $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 \ref{problem}, page \pageref{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 {\tt=}, {\tt<=}, or {\tt>=}, both expressions
+in the statement can be linear expressions. If the constraint has the
+form of double inequality,\linebreak 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, roughly speaking, generating its constraints,
+which are always evaluated for the entire subscript domain. Evaluation
+of the constraints leads, in turn, to evaluation of other model objects
+such as sets, parameters, and variables.
+
+Constructing an actual linear constraint included in the problem
+instance, 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:
+$$\begin{array}{r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r}
+f&=&a_1x_1&+&a_2x_2&+\dots+&a_nx_n&+&a_0,\\
+g&=&b_1x_1&+&a_2x_2&+\dots+&a_nx_n&+&b_0,\\
+\end{array}$$
+where $x_1$, $x_2$, \dots, $x_n$ are elemental variables; $a_1$, $a_2$,
+\dots, $a_n$, $b_1$, $b_2$, \dots, $b_n$ are numeric coefficients;
+$a_0$ and $b_0$ are constant terms. Then all linear terms of $f$ and
+$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:
+$$(a_1-b_1)x_1+(a_2-b_2)x_2+\dots+(a_n-b_n)x_n\left\{
+\begin{array}{@{}c@{}}=\\\leq\\\geq\\\end{array}\right\}b_0-a_0.$$
+
+If the constraint has the form of double inequality, evaluation of the
+middle linear expression gives the resultant linear form:
+$$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$
+and evaluation of the leftmost and rightmost numeric expressions gives
+two numeric values $l$ and $u$, respectively. Then the constant term of
+the linear form is carried to both left-hand and right-handsides that
+gives the final elemental constraint in the standard form:
+$$l-a_0\leq a_1x_1+a_2x_2+\dots+a_nx_n\leq u-a_0.$$
+
+\section{Objective statement}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][44pt]{468pt}{
+\hspace{6pt} {\tt minimize} {\it name} {\it alias} {\it domain} {\tt:}
+{\it expression} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt maximize} {\it name} {\it alias} {\it domain} {\tt:}
+{\it expression} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it name} is a symbolic name of the objective;
+
+\noindent
+{\it alias} is an optional string literal, which specifies an alias of
+the objective;
+
+\noindent
+{\it domain} is an optional indexing expression, which specifies
+a subscript domain of the objective;
+
+\noindent
+{\it expression} is a linear expression used to compute the linear form
+of the objective.
+
+\newpage
+
+\para{Examples}
+
+\begin{verbatim}
+minimize obj: x + 1.5 * (y + z);
+maximize total_profit: sum{p in prd} profit[p] * make[p];
+\end{verbatim}
+
+The objective statement declares an objective. If a subscript domain is
+not specified, the objective is a simple (scalar) objective. Otherwise
+it is a $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 \ref{problem}, page \pageref{problem}). However, unlike
+constraints the corresponding linear forms are free (unbounded).
+
+Constructing an actual linear constraint included in the problem
+instance, which (constraint) corresponds to a particular elemental
+constraint, is performed as follows. The linear expression specified in
+the objective statement is evaluated that, gives the resultant linear
+form:
+$$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$
+where $x_1$, $x_2$, \dots, $x_n$ are elemental variables; $a_1$, $a_2$,
+\dots, $a_n$ are numeric coefficients; $a_0$ is the constant term. Then
+the linear form is used to construct the final elemental constraint in
+the standard form:
+$$-\infty<a_1x_1+a_2x_2+\dots+a_nx_n+a_0<+\infty.$$
+
+As a rule the model description contains only one objective statement
+that defines the objective function used in the problem instance.
+However, it is allowed to declare arbitrary number of objectives, in
+which case the actual objective function is the first objective
+encountered in the model description. Other objectives are also
+included in the problem instance, but they do not affect the objective
+function.
+
+\section{Solve statement}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt solve} {\tt;}
+}}
+
+\medskip
+
+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.
+
+The solve statement causes the model to be solved, that means 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 the variable, constraint, and objective statements cannot be
+used below the solve statement, i.e. all principal components of the
+model should be declared above the solve statement.
+
+\newpage
+
+\section{Check statement}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt check} {\it domain} {\tt:} {\it expression} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it domain} is an optional indexing expression, which specifies
+a subscript domain of the check statement;
+
+\noindent
+{\it expression} is an logical expression which specifies the logical
+condition to be checked. (The colon preceding {\it expression} may be
+omitted.)
+
+\para{Examples}
+
+\begin{verbatim}
+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{verbatim}
+
+The check statement allows checking the resultant value of an logical
+expression specified in the statement. If the value is {\it false}, an
+error is reported.
+
+If the subscript domain is not specified, the check is performed only
+once. Specifying the subscript domain allows performing multiple check
+for every $n$-tuple in the domain set. In the latter case the logical
+expression may include dummy indices introduced in corresponding
+indexing expression.
+
+\section{Display statement}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt display} {\it domain} {\tt:} {\it item} {\tt,}
+\dots {\tt,} {\it item} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it domain} is an optional indexing expression, which specifies
+a subscript domain of the display statement;
+
+\noindent
+{\it item}, \dots, {\it item} are items to be displayed. (The colon
+preceding the first item may be omitted.)
+
+\para{Examples}
+
+\begin{verbatim}
+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{verbatim}
+
+The display statement evaluates all items specified in the statement
+and writes their values on the standard output (terminal) in plain text
+format.
+
+If a subscript domain is not specified, items are evaluated and then
+displayed only once. Specifying the subscript domain causes items to be
+evaluated and displayed for every $n$-tuple in the domain set. In the
+latter case items may include dummy indices introduced in corresponding
+indexing expression.
+
+An 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. members actually generated during the model
+evaluation) is displayed.
+
+If the item is an expression, the expression is evaluated and its
+resultant value is displayed.
+
+\section{Printf statement}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][64pt]{468pt}{
+\hspace{6pt} {\tt printf} {\it domain} {\tt:} {\it format} {\tt,}
+{\it expression} {\tt,} \dots {\tt,} {\it expression} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt printf} {\it domain} {\tt:} {\it format} {\tt,}
+{\it expression} {\tt,} \dots {\tt,} {\it expression} {\tt>}
+{\it filename} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt printf} {\it domain} {\tt:} {\it format} {\tt,}
+{\it expression} {\tt,} \dots {\tt,} {\it expression} {\tt>>}
+{\it filename} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it domain} is an optional indexing expression, which specifies
+a subscript domain of the printf statement;
+
+\noindent
+{\it format} is a symbolic expression whose value specifies a format
+control string. (The colon preceding the format expression may be
+omitted.)
+
+\noindent
+{\it expression}, \dots, {\it expression} are zero or more expressions
+whose values have to be formatted and printed. Each expression should
+be of numeric, symbolic, or logical type.
+
+\noindent
+{\it filename} is a symbolic expression whose value specifies a name
+of a text file, to which the output is redirected. The flag {\tt>}
+means creating a new empty file while the flag {\tt>>} means appending
+the output to an existing file. If no file name is specified, the
+output is written on the standard output (terminal).
+
+\para{Examples}
+
+\begin{verbatim}
+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]
+ >> result_file & ".txt";
+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{verbatim}
+
+The printf statement is similar to the display statement, however, it
+allows formatting data to be written.
+
+If a subscript domain is not specified, the printf statement is
+executed only once. Specifying a subscript domain causes executing the
+printf statement for every $n$-tuple in the domain set. In the latter
+case the format and expression may include dummy indices introduced in
+corresponding indexing expression.
+
+The format control string is a value of the symbolic expression
+{\it format} specified in the printf statement. It is composed of zero
+or more directives as follows: ordinary characters (not {\tt\%}), which
+are copied unchanged to the output stream, and conversion
+specifications, each of which causes evaluating corresponding
+expression specified in the printf statement, formatting it, and
+writing its resultant value to the output stream.
+
+Conversion specifications that may be used in the format control string
+are the following:\linebreak {\tt d}, {\tt i}, {\tt f}, {\tt F},
+{\tt e}, {\tt E}, {\tt g}, {\tt G}, and {\tt s}. These specifications
+have the same syntax and semantics as in the C programming language.
+
+\section{For statement}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][44pt]{468pt}{
+\hspace{6pt} {\tt for} {\it domain} {\tt:} {\it statement} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt for} {\it domain} {\tt:} {\tt\{} {\it statement}
+\dots {\it statement} {\tt\}} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it domain} is an indexing expression which specifies a subscript
+domain of the for statement. (The colon following the indexing
+expression may be omitted.)
+
+\noindent
+{\it statement} is a statement, which should be executed under control
+of the for statement;
+
+\noindent
+{\it statement}, \dots, {\it statement} is a sequence of statements
+(enclosed in curly braces), which should be executed under control of
+the for statement.
+
+Only the following statements can be used within the for statement:
+check, display, printf, and another for.
+
+\para{Examples}
+
+\begin{verbatim}
+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{verbatim}
+
+The for statement causes a statement or a sequence of statements
+specified as part of the for statement to be executed for every
+$n$-tuple in the domain set. Thus, statements within the for statement
+may include dummy indices introduced in corresponding indexing
+expression.
+
+\newpage
+
+\section{Table statement}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][80pt]{468pt}{
+\hspace{6pt} {\tt table} {\it name} {\it alias} {\tt IN} {\it driver}
+{\it arg} \dots {\it arg} {\tt:}
+
+\hspace{6pt} {\tt\ \ \ \ \ } {\it set} {\tt<-} {\tt[} {\it fld} {\tt,}
+\dots {\tt,} {\it fld} {\tt]} {\tt,} {\it par} {\tt\textasciitilde}
+{\it fld} {\tt,} \dots {\tt,} {\it par} {\tt\textasciitilde} {\it fld}
+{\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt table} {\it name} {\it alias} {\it domain} {\tt OUT}
+{\it driver} {\it arg} \dots {\it arg} {\tt:}
+
+\hspace{6pt} {\tt\ \ \ \ \ } {\it expr} {\tt\textasciitilde} {\it fld}
+{\tt,} \dots {\tt,} {\it expr} {\tt\textasciitilde} {\it fld} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it name} is a symbolic name of the table;
+
+\noindent
+{\it alias} is an optional string literal, which specifies an alias of
+the table;
+
+\noindent
+{\it domain} is an indexing expression, which specifies a subscript
+domain of the (output) table;
+
+\noindent
+{\tt IN} means reading data from the input table;
+
+\noindent
+{\tt OUT} means writing data to the output table;
+
+\noindent
+{\it driver} is a symbolic expression, which specifies the driver used
+to access the table (for details see Appendix \ref{drivers}, page
+\pageref{drivers});
+
+\noindent
+{\it arg} is an optional symbolic expression, which is an argument
+pass\-ed to the table driver. This symbolic expression should not
+include dummy indices specified in the domain;
+
+\noindent
+{\it set} is the name of an optional simple set called {\it control
+set}. It can be omitted along with the delimiter {\tt<-};
+
+\noindent
+{\it fld} is a field name. Within square brackets at least one field
+should be specified. The field name following a parameter name or
+expression is optional and can be omitted along with the
+delimiter~{\tt\textasciitilde}, in which case the name of corresponding
+model object is used as the field name;
+
+\noindent
+{\it par} is a symbolic name of a model parameter;
+
+\noindent
+{\it expr} is a numeric or symbolic expression.
+
+\para{Examples}
+
+\begin{verbatim}
+table data IN "CSV" "data.csv": S <- [FROM,TO], d~DISTANCE,
+ c~COST;
+table result{(f,t) in S} OUT "CSV" "result.csv": f~FROM, t~TO,
+ x[f,t]~FLOW;
+\end{verbatim}
+
+The table statement allows reading data from a table into model
+objects such as sets and (non-scalar) parameters as well as writing
+data from the model to a table.
+
+\newpage
+
+\subsection{Table structure}
+
+A {\it data table} is an (unordered) set of {\it records}, where each
+record consists of the same number of {\it fields}, and each field is
+provided with a unique symbolic name called the {\it field name}. For
+example:
+
+\bigskip
+
+\begin{tabular}{@{\hspace*{42mm}}c@{\hspace*{11mm}}c@{\hspace*{10mm}}c
+@{\hspace*{9mm}}c}
+First&Second&&Last\\
+field&field&.\ \ .\ \ .&field\\
+$\downarrow$&$\downarrow$&&$\downarrow$\\
+\end{tabular}
+
+\begin{tabular}{ll@{}}
+Table header&$\rightarrow$\\
+First record&$\rightarrow$\\
+Second record&$\rightarrow$\\
+\\
+\hfil .\ \ .\ \ .\\
+\\
+Last record&$\rightarrow$\\
+\end{tabular}
+\begin{tabular}{|l|l|c|c|}
+\hline
+{\tt FROM}&{\tt TO}&{\tt DISTANCE}&{\tt COST}\\
+\hline
+{\tt Seattle} &{\tt New-York}&{\tt 2.5}&{\tt 0.12}\\
+{\tt Seattle} &{\tt Chicago} &{\tt 1.7}&{\tt 0.08}\\
+{\tt Seattle} &{\tt Topeka} &{\tt 1.8}&{\tt 0.09}\\
+{\tt San-Diego}&{\tt New-York}&{\tt 2.5}&{\tt 0.15}\\
+{\tt San-Diego}&{\tt Chicago} &{\tt 1.8}&{\tt 0.10}\\
+{\tt San-Diego}&{\tt Topeka} &{\tt 1.4}&{\tt 0.07}\\
+\hline
+\end{tabular}
+
+\subsection{Reading data from input table}
+
+The input table statement causes reading data from the specified table
+record by record.
+
+Once a next record has been read, numeric or symbolic values of fields,
+whose names are enclosed in square brackets in the table statement, are
+gathered into $n$-tuple, and if the control set is specified in the
+table statement, this $n$-tuple is added to it. Besides, a numeric or
+symbolic value of each field associated with a model parameter is
+assigned to the parameter member identified by subscripts, which are
+components of the $n$-tuple just read.
+
+For example, the following input table statement:
+
+\noindent\hfil
+\verb|table data IN "...": S <- [FROM,TO], d~DISTANCE, c~COST;|
+
+\noindent
+causes reading values of four fields named {\tt FROM}, {\tt TO},
+{\tt DISTANCE}, and {\tt COST} from each record of the specified table.
+Values of fields {\tt FROM} and {\tt TO} give a pair $(f,t)$, which is
+added to the control set {\tt S}. The value of field {\tt DISTANCE} is
+assigned to parameter member ${\tt d}[f,t]$, and the value of field
+{\tt COST} is assigned to parameter member ${\tt c}[f,t]$.
+
+Note that the input table may contain extra fields whose names are not
+specified in the table statement, in which case values of these fields
+on reading the table are ignored.
+
+\subsection{Writing data to output table}
+
+The output table statement causes writing data to the specified table.
+Note that some drivers (namely, CSV and xBASE) destroy the output table
+before writing data, i.e. delete all its existing records.
+
+Each $n$-tuple in the specified domain set generates one record written
+to the output table. Values of fields are numeric or symbolic values of
+corresponding expressions specified in the table statement. These
+expressions are evaluated for each $n$-tuple in the domain set and,
+thus, may include dummy indices introduced in the corresponding indexing
+expression.
+
+For example, the following output table statement:
+
+\noindent\hfil
+\verb|table result{(f,t) in S} OUT "...": f~FROM, t~TO, x[f,t]~FLOW;|
+
+\noindent
+causes writing records, by one record for each pair $(f,t)$ in set
+{\tt S}, to the output table, where each record consists of three
+fields named {\tt FROM}, {\tt TO}, and {\tt FLOW}. The values written
+to fields {\tt FROM} and {\tt TO} are current values of dummy indices
+{\tt f} and {\tt t}, and the value written to field {\tt FLOW} is
+a value of member ${\tt x}[f,t]$ of corresponding subscripted parameter
+or variable.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Model data}
+
+{\it 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 another way, when the model
+description is divided into two parts: model section and data section.
+
+A {\it 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.
+
+A {\it 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.
+
+1. If both model and data sections are placed in one file, the file is
+composed as follows:
+
+\bigskip
+
+\noindent\hfil
+\framebox{\begin{tabular}{l}
+{\it statement}{\tt;}\\
+{\it statement}{\tt;}\\
+\hfil.\ \ .\ \ .\\
+{\it statement}{\tt;}\\
+{\tt data;}\\
+{\it data block}{\tt;}\\
+{\it data block}{\tt;}\\
+\hfil.\ \ .\ \ .\\
+{\it data block}{\tt;}\\
+{\tt end;}
+\end{tabular}}
+
+\newpage
+
+2. If the model and data sections are placed in two separate files, the
+files are composed as follows:
+
+\bigskip
+
+\noindent\hfil
+\begin{tabular}{@{}c@{}}
+\framebox{\begin{tabular}{l}
+{\it statement}{\tt;}\\
+{\it statement}{\tt;}\\
+\hfil.\ \ .\ \ .\\
+{\it statement}{\tt;}\\
+{\tt end;}\\
+\end{tabular}}\\
+\\\\Model file\\
+\end{tabular}
+\hspace{32pt}
+\begin{tabular}{@{}c@{}}
+\framebox{\begin{tabular}{l}
+{\tt data;}\\
+{\it data block}{\tt;}\\
+{\it data block}{\tt;}\\
+\hfil.\ \ .\ \ .\\
+{\it data block}{\tt;}\\
+{\tt end;}\\
+\end{tabular}}\\
+\\Data file\\
+\end{tabular}
+
+\bigskip
+
+Note: If the data section is placed in a separate file, the keyword
+{\tt data} is optional and may be omitted along with the semicolon that
+follows it.
+
+\section{Coding data section}
+
+The {\it data section} is a sequence of data blocks in various formats,
+which are discussed in following sections. The order, in which data
+blocks follow in the data section, may be arbitrary, not necessarily
+the same, in which 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 (see Section \ref{coding}, page
+\pageref{coding}), 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 for
+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 {\tt+} and {\tt-}, and/or the
+decimal point, it may be coded without bordering by (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
+{\tt+} and {\tt-} can precede numeric literals to allow coding signed
+numeric quantities, in which case there should 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 two different lexical units).
+
+\newpage
+
+\section{Set data block}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][44pt]{468pt}{
+\hspace{6pt} {\tt set} {\it name} {\tt,} {\it record} {\tt,} \dots
+{\tt,} {\it record} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt set} {\it name} {\tt[} {\it symbol} {\tt,} \dots
+{\tt,} {\it symbol} {\tt]} {\tt,} {\it record} {\tt,} \dots {\tt,}
+{\it record} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it name} is a symbolic name of the set;
+
+\noindent
+{\it symbol}, \dots, {\it symbol} are subscripts, which specify
+a particular member of the set (if the set is an array, i.e. a set of
+sets);
+
+\noindent
+{\it record}, \dots, {\it record} are data records.
+
+\noindent
+Commae preceding data records may be omitted.
+
+\para{Data records}
+
+\vspace*{-8pt}
+
+\begin{description}
+\item[{\tt :=}]\hspace*{0pt}\\
+is a non-significant data record, which may be used freely to improve
+readability;
+\item[{\tt(} {\it slice} {\tt)}]\hspace*{0pt}\\
+specifies a slice;
+\item[{\it simple-data}]\hspace*{0pt}\\
+specifies set data in the simple format;
+\item[{\tt:} {\it matrix-data}]\hspace*{0pt}\\
+specifies set data in the matrix format;
+\item[{\tt(tr)} {\tt:} {\it matrix-data}]\hspace*{0pt}\\
+specifies set data in the transposed matrix format. (In this case the
+colon following the keyword {\tt(tr)} may be omitted.)
+\end{description}
+
+\vspace*{-8pt}
+
+\para{Examples}
+
+\begin{verbatim}
+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 3 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{verbatim}
+
+\noindent(In these examples {\tt month} is a simple set of singlets,
+{\tt A} is a 2-dimensional array of doublets, and {\tt B} is a simple
+set of triplets. Data blocks for the same set are equivalent in the
+sense that they specify the same data in different formats.)
+
+The {\it 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. for
+sets, which have no assign attribute ({\tt:=}) in the corresponding set
+statements.
+
+If the set is a simple set, only its symbolic name should be specified
+in the header of the data block. Otherwise, if the set is a
+$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 should be the same as the dimension of the set array, where
+each subscript should be a number or symbol.
+
+An elemental set defined in the set data block is coded as a sequence
+of data records described below.\footnote{{\it Data record} is simply a
+technical term. It does not mean that data records have any special
+formatting.}
+
+\subsection{Assign data record}
+
+The {\it assign data record} ({\tt:=}) is a non-signficant element.
+It may be used for improving readability of data blocks.
+
+\subsection{Slice data record}
+
+The {\it slice data record} is a control record, which specifies a
+{\it slice} of the elemental set defined in the data block. It has the
+following syntactic form:
+$$\mbox{{\tt(} $s_1$ {\tt,} $s_2$ {\tt,} \dots {\tt,} $s_n$ {\tt)}}$$
+where $s_1$, $s_2$, \dots, $s_n$ are components of the slice.
+
+Each component of the slice can be a number or symbol or the asterisk
+({\tt*}). The number of components in the slice should be the same as
+the dimension of $n$-tuples in the elemental set to be defined. For
+instance, if the elemental set contains 4-tuples (quadruplets), the
+slice should have four components. The number of asterisks in the slice
+is called the {\it slice dimension}.
+
+The effect of using slices is the following. If a $m$-dimensional slice
+(i.e. a slice having $m$ asterisks) is specified in the data block, all
+subsequent data records should specify tuples of the dimension~$m$.
+Whenever a $m$-tuple is encountered, each asterisk in the slice is
+replaced by corresponding components of the $m$-tuple that gives the
+resultant $n$-tuple, which is included in the elemental set to be
+defined. For example, if the slice $(a,*,1,2,*)$ is in effect, and
+2-tuple $(3,b)$ is encountered in a subsequent data record, the
+resultant 5-tuple included in the elemental set is $(a,3,1,2,b)$.
+
+The slice having no asterisks itself defines a complete $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 is encountered. Note that if no slice is specified in
+the data block, one, components of which are all asterisks, is assumed.
+
+\subsection{Simple data record}
+
+The {\it simple data record} defines one $n$-tuple in a simple format
+and has the following syntactic form:
+$$\mbox{$t_1$ {\tt,} $t_2$ {\tt,} \dots {\tt,} $t_n$}$$
+where $t_1$, $t_2$, \dots, $t_n$ are components of the $n$-tuple. Each
+component can be a number or symbol. Commae between components are
+optional and may be omitted.
+
+\subsection{Matrix data record}
+
+The {\it matrix data record} defines several 2-tuples (doublets) in
+a matrix format and has the following syntactic form:
+$$\begin{array}{cccccc}
+\mbox{{\tt:}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
+r_1&a_{11}&a_{12}&\dots&a_{1n}&\\
+r_2&a_{21}&a_{22}&\dots&a_{2n}&\\
+\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
+r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
+\end{array}$$
+where $r_1$, $r_2$, \dots, $r_m$ are numbers and/or symbols
+corresponding to rows of the matrix; $c_1$, $c_2$, \dots, $c_n$ are
+numbers and/or symbols corresponding to columns of the matrix, $a_{11}$,
+$a_{12}$, \dots, $a_{mn}$ are matrix elements, which can be either
+{\tt+} or {\tt-}. (In this data record the delimiter {\tt:} preceding
+the column list and the delimiter {\tt:=} following the column list
+cannot be omitted.)
+
+Each element $a_{ij}$ of the matrix data block (where $1\leq i\leq m$,
+$1\leq j\leq n$) corresponds to 2-tuple $(r_i,c_j)$. If $a_{ij}$ is the
+plus sign ({\tt+}), that 2-tuple (or a longer $n$-tuple, if a slice is
+used) is included in the elemental set. Otherwise, if $a_{ij}$ is the
+minus sign ({\tt-}), that 2-tuple is not included in the elemental set.
+
+Since the matrix data record defines 2-tuples, either the elemental set
+should consist of 2-tuples or the slice currently used should be
+2-dimensional.
+
+\newpage
+
+\subsection{Transposed matrix data record}
+
+The {\it transposed matrix data record} has the following syntactic
+form:
+$$\begin{array}{cccccc}
+\mbox{{\tt(tr) :}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
+r_1&a_{11}&a_{12}&\dots&a_{1n}&\\
+r_2&a_{21}&a_{22}&\dots&a_{2n}&\\
+\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
+r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
+\end{array}$$
+(In this case the delimiter {\tt:} following the keyword {\tt(tr)} is
+optional and may be omitted.)
+
+This data record is completely analogous to the matrix data record (see
+above) with only exception that in this case each element $a_{ij}$ of
+the matrix corresponds to 2-tuple $(c_j,r_i)$ rather than $(r_i,c_j)$.
+
+Being once specified the {\tt(tr)} indicator affects all subsequent
+data records until either a slice or the end of data block is
+encountered.
+
+\section{Parameter data block}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][88pt]{468pt}{
+\hspace{6pt} {\tt param} {\it name} {\tt,} {\it record} {\tt,} \dots
+{\tt,} {\it record} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt param} {\it name} {\tt default} {\it value} {\tt,}
+{\it record} {\tt,} \dots {\tt,} {\it record} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt param} {\tt:} {\it tabbing-data} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt param} {\tt default} {\it value} {\tt:}
+{\it tabbing-data} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it name} is a symbolic name of the parameter;
+
+\noindent
+{\it value} is an optional default value of the parameter;
+
+\noindent
+{\it record}, \dots, {\it record} are data records;
+
+\noindent
+{\it tabbing-data} specifies parameter data in the tabbing format.
+
+\noindent
+Commae preceding data records may be omitted.
+
+\para{Data records}
+
+\vspace*{-8pt}
+
+\begin{description}
+\item[{\tt :=}]\hspace*{0pt}\\
+is a non-significant data record, which may be used freely to improve
+readability;
+\item[{\tt[} {\it slice} {\tt]}]\hspace*{0pt}\\
+specifies a slice;
+\item[{\it plain-data}]\hspace*{0pt}\\
+specifies parameter data in the plain format;
+\item[{\tt:} {\it tabular-data}]\hspace*{0pt}\\
+specifies parameter data in the tabular format;
+\item[{\tt(tr)} {\tt:} {\it tabular-data}]\hspace*{0pt}\\
+specifies set data in the transposed tabular format. (In this case the
+colon following the keyword {\tt(tr)} may be omitted.)
+\end{description}
+
+\vspace*{-8pt}
+
+\para{Examples}
+
+\begin{verbatim}
+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{verbatim}
+
+The {\it parameter data block} is used to specify complete data for a
+parameter (or parameters, if data are specified in the tabbing format).
+
+Data blocks can be specified only for non-computable parameters, i.e.
+for parameters, which have no assign attribute ({\tt:=}) 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 {\tt 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 when
+no appropriate value is defined in the parameter data block. The
+{\tt default} attribute cannot be used, if it is already specified in
+the corresponding parameter statement.
+
+\subsection{Assign data record}
+
+The {\it assign data record} ({\tt:=}) is a non-signficant element.
+It may be used for improving readability of data blocks.
+
+\subsection{Slice data record}
+
+The {\it slice data record} is a control record, which specifies a
+{\it slice} of the parameter array. It has the following syntactic
+form:
+$$\mbox{{\tt[} $s_1$ {\tt,} $s_2$ {\tt,} \dots {\tt,} $s_n$ {\tt]}}$$
+where $s_1$, $s_2$, \dots, $s_n$ are components of the slice.
+
+Each component of the slice can be a number or symbol or the asterisk
+({\tt*}). The number of components in the slice should be the same as
+the dimension of the parameter. For instance, if the parameter is a
+4-dimensional array, the slice should have four components. The number
+of asterisks in the slice is called the {\it slice dimension}.
+
+The effect of using slices is the following. If a $m$-dimensional slice
+(i.e. a slice having $m$ asterisks) is specified in the data block, all
+subsequent data records should specify subscripts of the parameter
+members as if the parameter were $m$-dimensional, not $n$-dimensional.
+
+Whenever $m$ subscripts are encountered, each asterisk in the slice is
+replaced by corresponding subscript that gives $n$ subscripts, which
+define the actual parameter member. For example, if the slice
+$[a,*,1,2,*]$ is in effect, and subscripts 3 and $b$ are encountered in
+a subsequent data record, the complete subscript list used to choose a
+parameter member is $[a,3,1,2,b]$.
+
+It is allowed to specify a slice having no asterisks. Such slice itself
+defines a complete subscript list, in which case the next data record
+should define only a single value of corresponding parameter member.
+
+Being once specified the slice effects until either a new slice or the
+end of data block is encountered. Note that if no slice is specified in
+the data block, one, components of which are all asterisks, is assumed.
+
+\subsection{Plain data record}
+
+The {\it plain data record} defines a subscript list and a single value
+in the plain format. This record has the following syntactic form:
+$$\mbox{$t_1$ {\tt,} $t_2$ {\tt,} \dots {\tt,} $t_n$ {\tt,} $v$}$$
+where $t_1$, $t_2$, \dots, $t_n$ are subscripts, and $v$ 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 has
+no subscripts and consists of a single value only.
+
+\subsection{Tabular data record}
+
+The {\it tabular data record} defines several values, where each value
+is provided with two subscripts. This record has the following
+syntactic form:
+$$\begin{array}{cccccc}
+\mbox{{\tt:}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
+r_1&a_{11}&a_{12}&\dots&a_{1n}&\\
+r_2&a_{21}&a_{22}&\dots&a_{2n}&\\
+\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
+r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
+\end{array}$$
+where $r_1$, $r_2$, \dots, $r_m$ are numbers and/or symbols
+corresponding to rows of the table; $c_1$, $c_2$, \dots, $c_n$ are
+numbers and/or symbols corresponding to columns of the table, $a_{11}$,
+$a_{12}$, \dots, $a_{mn}$ are table elements. Each element can be a
+number or symbol or the single decimal point ({\tt.}). (In this data
+record the delimiter {\tt:} preceding the column list and the delimiter
+{\tt:=} following the column list cannot be omitted.)
+
+Each element $a_{ij}$ of the tabular data block ($1\leq i\leq m$,
+$1\leq j\leq n$) defines two subscripts, where the first subscript is
+$r_i$, and the second one is $c_j$. These subscripts are used in
+conjunction with the current slice to form the complete subscript list
+that identifies a particular member of the parameter array. If $a_{ij}$
+is a number or symbol, this value is assigned to the parameter member.
+However, if $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.
+
+Since the tabular data record provides two subscripts for each value,
+either the parameter or the slice currently used should be
+2-dimensional.
+
+\subsection{Transposed tabular data record}
+
+The {\it transposed tabular data record} has the following syntactic
+form:
+$$\begin{array}{cccccc}
+\mbox{{\tt(tr) :}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
+r_1&a_{11}&a_{12}&\dots&a_{1n}&\\
+r_2&a_{21}&a_{22}&\dots&a_{2n}&\\
+\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
+r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
+\end{array}$$
+(In this case the delimiter {\tt:} following the keyword {\tt(tr)} is
+optional and may be omitted.)
+
+This data record is completely analogous to the tabular data record
+(see above) with only exception that the first subscript defined by
+element $a_{ij}$ is $c_j$ while the second one is $r_i$.
+
+Being once specified the {\tt(tr)} indicator affects all subsequent
+data records until either a slice or the end of data block is
+encountered.
+
+\newpage
+
+\subsection{Tabbing data format}
+
+The parameter data block in the {\it tabbing format} has the following
+syntactic form:
+$$
+\begin{array}{*{8}{l}}
+\multicolumn{4}{l}
+{{\tt param}\ {\tt default}\ value\ {\tt :}\ s\ {\tt :}}&
+p_1\ \ \verb|,|&p_2\ \ \verb|,|&\dots\ \verb|,|&p_r\ \ \verb|:=|\\
+r_{11}\ \verb|,|& r_{12}\ \verb|,|& \dots\ \verb|,|& r_{1n}\ \verb|,|&
+a_{11}\ \verb|,|& a_{12}\ \verb|,|& \dots\ \verb|,|& a_{1r}\ \verb|,|\\
+r_{21}\ \verb|,|& r_{22}\ \verb|,|& \dots\ \verb|,|& r_{2n}\ \verb|,|&
+a_{21}\ \verb|,|& a_{22}\ \verb|,|& \dots\ \verb|,|& a_{2r}\ \verb|,|\\
+\dots & \dots & \dots & \dots & \dots & \dots & \dots & \dots \\
+r_{m1}\ \verb|,|& r_{m2}\ \verb|,|& \dots\ \verb|,|& r_{mn}\ \verb|,|&
+a_{m1}\ \verb|,|& a_{m2}\ \verb|,|& \dots\ \verb|,|& a_{mr}\ \verb|;|\\
+\end{array}
+$$
+
+1. The keyword {\tt default} may be omitted along with a value
+following it.
+
+2. Symbolic name $s$ may be omitted along with the colon following it.
+
+3. All commae are optional and may be omitted.
+
+The data block in the tabbing format shown above is exactly equivalent
+to the following data blocks:
+
+\verb|set| $s$\ \verb|:=|\ $
+\verb|(|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|) |
+\verb|(|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|) |
+\dots
+\verb| (|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|);|$
+
+\verb|param| $p_1$\ \verb|default|\ $value$\ \verb|:=|
+
+$\verb| |
+\verb|[|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|] |a_{11}
+\verb| [|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|] |a_{21}
+\verb| |\dots
+\verb| [|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|] |a_{m1}
+\verb|;|
+$
+
+\verb|param| $p_2$\ \verb|default|\ $value$\ \verb|:=|
+
+$\verb| |
+\verb|[|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|] |a_{12}
+\verb| [|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|] |a_{22}
+\verb| |\dots
+\verb| [|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|] |a_{m2}
+\verb|;|
+$
+
+\verb| |.\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .
+
+\verb|param| $p_r$\ \verb|default|\ $value$\ \verb|:=|
+
+$\verb| |
+\verb|[|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|] |a_{1r}
+\verb| [|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|] |a_{2r}
+\verb| |\dots
+\verb| [|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|] |a_{mr}
+\verb|;|
+$
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\appendix
+
+\chapter{Using suffixes}
+
+\vspace*{-12pt}
+
+Suffixes can be used to retrieve additional values associated with
+model variables, constraints, and objectives.
+
+A {\it suffix} consists of a period ({\tt.}) followed by a non-reserved
+keyword. For example, if {\tt x} is a two-dimensional variable,
+{\tt x[i,j].lb} is a numeric value equal to the lower bound of
+elemental variable {\tt x[i,j]}, which (value) can be used everywhere
+in expressions like a numeric parameter.
+
+For model variables suffixes have the following meaning:
+
+\begin{tabular}{@{}ll@{}}
+{\tt.lb}&lower bound\\
+{\tt.ub}&upper bound\\
+{\tt.status}&status in the solution:\\
+&0 --- undefined\\
+&1 --- basic\\
+&2 --- non-basic on lower bound\\
+&3 --- non-basic on upper bound\\
+&4 --- non-basic free (unbounded) variable\\
+&5 --- non-basic fixed variable\\
+{\tt.val}&primal value in the solution\\
+{\tt.dual}&dual value (reduced cost) in the solution\\
+\end{tabular}
+
+For model constraints and objectives suffixes have the following
+meaning:
+
+\begin{tabular}{@{}ll@{}}
+{\tt.lb}&lower bound of the linear form\\
+{\tt.ub}&upper bound of the linear form\\
+{\tt.status}&status in the solution:\\
+&0 --- undefined\\
+&1 --- non-active\\
+&2 --- active on lower bound\\
+&3 --- active on upper bound\\
+&4 --- active free (unbounded) row\\
+&5 --- active equality constraint\\
+{\tt.val}&primal value of the linear form in the solution\\
+{\tt.dual}&dual value (reduced cost) of the linear form in the
+solution\\
+\end{tabular}
+
+Note that suffixes {\tt.status}, {\tt.val}, and {\tt.dual} can be used
+only below the solve statement.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Date and time functions}
+
+\noindent\hfil
+\begin{tabular}{c}
+by Andrew Makhorin \verb|<mao@gnu.org>|\\
+and Heinrich Schuchardt \verb|<heinrich.schuchardt@gmx.de>|\\
+\end{tabular}
+
+\section{Obtaining current calendar time}
+\label{gmtime}
+
+To obtain the current calendar time in MathProg there exists the
+function {\tt 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:
+
+\begin{verbatim}
+ param utc := gmtime();
+\end{verbatim}
+
+MathProg has no function to convert UTC time returned by the function
+{\tt gmtime} to {\it 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:
+
+\begin{verbatim}
+ param now := gmtime() + 3600;
+\end{verbatim}
+
+\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:
+
+\begin{verbatim}
+ param now := gmtime() - 5 * 3600;
+\end{verbatim}
+
+Note that the value returned by {\tt gmtime} is volatile, i.e. being
+called several times this function may return different values.
+
+\section{Converting character string to calendar time}
+\label{str2time}
+
+The function {\tt str2time(}{\it s}{\tt,} {\it f}{\tt)} converts a
+character string (timestamp) specified by its first argument {\it s},
+which should be a symbolic expression, to the calendar time suitable
+for arithmetic calculations. The conversion is controlled by the
+specified format string {\it f} (the second argument), which also
+should be a symbolic expression.
+
+\newpage
+
+The result of conversion returned by {\tt str2time} has the same
+meaning as values returned by the function {\tt gmtime} (see Subsection
+\ref{gmtime}, page \pageref{gmtime}). Note that {\tt str2time} does
+{\tt 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:
+
+\begin{verbatim}
+ param s, symbolic, := "07/14/98 13:47";
+ param t := str2time(s, "%m/%d/%y %H:%M");
+ display t;
+\end{verbatim}
+
+\noindent produce the following printout:
+
+\begin{verbatim}
+ t = 900424020
+\end{verbatim}
+
+\noindent where the calendar time printed corresponds to 13:47:00 on
+July 14, 1998.
+
+The format string passed to the function {\tt str2time} consists of
+conversion specifiers and ordinary characters. Each conversion
+specifier begins with a percent ({\tt\%}) character followed by a
+letter.
+
+The following conversion specifiers may be used in the format string:
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%b}&The abbreviated month name (case insensitive). At least three
+first letters of the month name should appear in the input string.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%d}&The day of the month as a decimal number (range 1 to 31).
+Leading zero is permitted, but not required.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%h}&The same as {\tt\%b}.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%H}&The hour as a decimal number, using a 24-hour clock (range 0
+to 23). Leading zero is permitted, but not required.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%m}&The month as a decimal number (range 1 to 12). Leading zero is
+permitted, but not required.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%M}&The minute as a decimal number (range 0 to 59). Leading zero
+is permitted, but not required.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%S}&The second as a decimal number (range 0 to 60). Leading zero
+is permitted, but not required.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%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.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%z}&The offset from GMT in ISO 8601 format.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%\%}&A literal {\tt\%} character.\\
+\end{tabular}
+
+All other (ordinary) characters in the format string should 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.
+
+\newpage
+
+If some date and/or time component(s) are missing in the format and,
+therefore, in the input string, the function {\tt 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 {\tt 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.
+
+\section{Converting calendar time to character string}
+\label{time2str}
+
+The function {\tt time2str(}{\it t}{\tt,} {\it f}{\tt)} converts the
+calendar time specified by its first argument {\it t}, which should be
+a numeric expression, to a character string (symbolic value). The
+conversion is controlled by the specified format string {\it f} (the
+second argument), which should be a symbolic expression.
+
+The calendar time passed to {\tt time2str} has the same meaning as
+values returned by the function {\tt gmtime} (see Subsection
+\ref{gmtime}, page \pageref{gmtime}). Note that {\tt time2str} does
+{\it 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.
+
+For example, the model statements:
+
+\begin{verbatim}
+ param s, symbolic, := time2str(gmtime(), "%FT%TZ");
+ display s;
+\end{verbatim}
+
+\noindent may produce the following printout:
+
+\begin{verbatim}
+ s = '2008-12-04T00:23:45Z'
+\end{verbatim}
+
+\noindent which is a timestamp in the ISO format.
+
+The format string passed to the function {\tt time2str} consists of
+conversion specifiers and ordinary characters. Each conversion
+specifier begins with a percent ({\tt\%}) character followed by a
+letter.
+
+The following conversion specifiers may be used in the format string:
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%a}&The abbreviated (2-character) weekday name.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%A}&The full weekday name.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%b}&The abbreviated (3-character) month name.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%B}&The full month name.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%C}&The century of the year, that is the greatest integer not
+greater than the year divided by~100.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%d}&The day of the month as a decimal number (range 01 to 31).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%D}&The date using the format \verb|%m/%d/%y|.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%e}&The day of the month like with \verb|%d|, but padded with
+blank rather than zero.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%F}&The date using the format \verb|%Y-%m-%d|.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%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
+\verb|%y|, except that if the ISO week number (see \verb|%V|) belongs
+to the previous or next year, that year is used instead.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%G}&The year corresponding to the ISO week number. This has the
+same format and value as \verb|%Y|, except that if the ISO week number
+(see \verb|%V|) belongs to the previous or next year, that year is used
+instead.
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%h}&The same as \verb|%b|.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%H}&The hour as a decimal number, using a 24-hour clock (range 00
+to 23).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%I}&The hour as a decimal number, using a 12-hour clock (range 01
+to 12).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%j}&The day of the year as a decimal number (range 001 to 366).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%k}&The hour as a decimal number, using a 24-hour clock like
+\verb|%H|, but padded with blank rather than zero.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%l}&The hour as a decimal number, using a 12-hour clock like
+\verb|%I|, but padded with blank rather than zero.
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%m}&The month as a decimal number (range 01 to 12).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%M}&The minute as a decimal number (range 00 to 59).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%p}&Either {\tt AM} or {\tt PM}, according to the given time value.
+Midnight is treated as {\tt AM} and noon as {\tt PM}.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%P}&Either {\tt am} or {\tt pm}, according to the given time value.
+Midnight is treated as {\tt am} and noon as {\tt pm}.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%R}&The hour and minute in decimal numbers using the format
+\verb|%H:%M|.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%S}&The second as a decimal number (range 00 to 59).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%T}&The time of day in decimal numbers using the format
+\verb|%H:%M:%S|.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%u}&The day of the week as a decimal number (range 1 to 7), Monday
+being 1.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%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.
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%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.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%w}&The day of the week as a decimal number (range 0 to 6), Sunday
+being 0.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%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.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%y}&The year without a century as a decimal number (range 00 to
+99), that is the year modulo~100.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%Y}&The year as a decimal number, using the Gregorian calendar.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%\%}&A literal \verb|%| character.\\
+\end{tabular}
+
+All other (ordinary) characters in the format string are simply copied
+to the resultant string.
+
+The first argument (calendar time) passed to the function {\tt time2str}
+should 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.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Table drivers}
+\label{drivers}
+
+\noindent\hfil
+\begin{tabular}{c}
+by Andrew Makhorin \verb|<mao@gnu.org>|\\
+and Heinrich Schuchardt \verb|<heinrich.schuchardt@gmx.de>|\\
+\end{tabular}
+
+\bigskip\bigskip
+
+The {\it table driver} is a program module which provides transmitting
+data between MathProg model objects and data tables.
+
+Currently the GLPK package has four table drivers:
+
+\vspace*{-8pt}
+
+\begin{itemize}
+\item built-in CSV table driver;
+\item built-in xBASE table driver;
+\item ODBC table driver;
+\item MySQL table driver.
+\end{itemize}
+
+\vspace*{-8pt}
+
+\section{CSV table driver}
+
+The CSV table driver assumes that the data table is represented in the
+form of a plain text file in the CSV (comma-separated values) file
+format as described below.
+
+To choose the CSV table driver its name in the table statement should
+be specified as \verb|"CSV"|, and the only argument should specify the
+name of a plain text file containing the table. For example:
+
+\begin{verbatim}
+ table data IN "CSV" "data.csv": ... ;
+\end{verbatim}
+
+The filename suffix may be arbitrary, however, it is recommended to use
+the suffix `\verb|.csv|'.
+
+On reading input tables the CSV table driver provides an implicit field
+named \verb|RECNO|, which contains the current record number. This
+field can be specified in the input table statement as if there were
+the actual field named \verb|RECNO| in the CSV file. For example:
+
+\begin{verbatim}
+ table list IN "CSV" "list.csv": num <- [RECNO], ... ;
+\end{verbatim}
+
+\newpage
+
+\subsection*{CSV format\footnote{This material is based on the RFC
+document 4180.}}
+
+The CSV (comma-separated values) format is a plain text file format
+defined as follows.
+
+1. Each record is located on a separate line, delimited by a line
+break. For example:
+
+\begin{verbatim}
+ aaa,bbb,ccc\n
+ xxx,yyy,zzz\n
+\end{verbatim}
+
+\noindent
+where \verb|\n| means the control character \verb|LF| ({\tt 0x0A}).
+
+2. The last record in the file may or may not have an ending line
+break. For example:
+
+\begin{verbatim}
+ aaa,bbb,ccc\n
+ xxx,yyy,zzz
+\end{verbatim}
+
+3. There should be a header line appearing as the first line of the
+file in the same format as normal record lines. This header should
+contain names corresponding to the fields in the file. The number of
+field names in the header line should be the same as the number of
+fields in the records of the file. For example:
+
+\begin{verbatim}
+ name1,name2,name3\n
+ aaa,bbb,ccc\n
+ xxx,yyy,zzz\n
+\end{verbatim}
+
+4. Within the header and each record there may be one or more fields
+separated by commas. Each line should contain the same number of fields
+throughout the file. Spaces are considered as part of a field and
+therefore not ignored. The last field in the record should not be
+followed by a comma. For example:
+
+\begin{verbatim}
+ aaa,bbb,ccc\n
+\end{verbatim}
+
+5. Fields may or may not be enclosed in double quotes. For example:
+
+\begin{verbatim}
+ "aaa","bbb","ccc"\n
+ zzz,yyy,xxx\n
+\end{verbatim}
+
+6. If a field is enclosed in double quotes, each double quote which is
+part of the field should be coded twice. For example:
+
+\begin{verbatim}
+ "aaa","b""bb","ccc"\n
+\end{verbatim}
+
+\para{Example}
+
+\begin{verbatim}
+FROM,TO,DISTANCE,COST
+Seattle,New-York,2.5,0.12
+Seattle,Chicago,1.7,0.08
+Seattle,Topeka,1.8,0.09
+San-Diego,New-York,2.5,0.15
+San-Diego,Chicago,1.8,0.10
+San-Diego,Topeka,1.4,0.07
+\end{verbatim}
+
+\newpage
+
+\section{xBASE table driver}
+
+The xBASE table driver assumes that the data table is stored in the
+.dbf file format.
+
+To choose the xBASE table driver its name in the table statement should
+be specified as \verb|"xBASE"|, and the first argument should specify
+the name of a .dbf file containing the table. For the output table there
+should be the second argument defining the table format in the form
+\verb|"FF...F"|, where \verb|F| is either {\tt C({\it n})},
+which specifies a character field of length $n$, or
+{\tt N({\it n}{\rm [},{\it p}{\rm ]})}, which specifies a numeric field
+of length $n$ and precision $p$ (by default $p$ is 0).
+
+The following is a simple example which illustrates creating and
+reading a .dbf file:
+
+\begin{verbatim}
+table tab1{i in 1..10} OUT "xBASE" "foo.dbf"
+ "N(5)N(10,4)C(1)C(10)": 2*i+1 ~ B, Uniform(-20,+20) ~ A,
+ "?" ~ FOO, "[" & i & "]" ~ C;
+set S, dimen 4;
+table tab2 IN "xBASE" "foo.dbf": S <- [B, C, RECNO, A];
+display S;
+end;
+\end{verbatim}
+
+\section{ODBC table driver}
+
+The ODBC table driver allows connecting to SQL databases using an
+implementation of the ODBC interface based on the Call Level Interface
+(CLI).\footnote{The corresponding software standard is defined in
+ISO/IEC 9075-3:2003.}
+
+\para{Debian GNU/Linux.}
+Under Debian GNU/Linux the ODBC table driver uses the iODBC
+package,\footnote{See {\tt<http://www.iodbc.org/>}.} which should be
+installed before building the GLPK package. The installation can be
+effected with the following command:
+
+\begin{verbatim}
+ sudo apt-get install libiodbc2-dev
+\end{verbatim}
+
+Note that on configuring the GLPK package to enable using the iODBC
+library the option `\verb|--enable-odbc|' should be passed to the
+configure script.
+
+The individual databases should be entered for systemwide usage in
+\verb|/etc/odbc.ini| and\linebreak \verb|/etc/odbcinst.ini|. Database
+connections to be used by a single user are specified by files in the
+home directory (\verb|.odbc.ini| and \verb|.odbcinst.ini|).
+
+\para{Microsoft Windows.}
+Under Microsoft Windows the ODBC table driver uses the Microsoft ODBC
+library. To enable this feature the symbol:
+
+\begin{verbatim}
+ #define ODBC_DLNAME "odbc32.dll"
+\end{verbatim}
+
+\noindent
+should be defined in the GLPK configuration file `\verb|config.h|'.
+
+Data sources can be created via the Administrative Tools from the
+Control Panel.
+
+To choose the ODBC table driver its name in the table statement should
+be specified as \verb|'ODBC'| or \verb|'iODBC'|.
+
+\newpage
+
+The argument list is specified as follows.
+
+The first argument is the connection string passed to the ODBC library,
+for example:
+
+\verb|'DSN=glpk;UID=user;PWD=password'|, or
+
+\verb|'DRIVER=MySQL;DATABASE=glpkdb;UID=user;PWD=password'|.
+
+Different parts of the string are separated by semicolons. Each part
+consists of a pair {\it fieldname} and {\it value} separated by the
+equal sign. Allowable fieldnames depend on the ODBC library. Typically
+the following fieldnames are allowed:
+
+\verb|DATABASE | database;
+
+\verb|DRIVER | ODBC driver;
+
+\verb|DSN | name of a data source;
+
+\verb|FILEDSN | name of a file data source;
+
+\verb|PWD | user password;
+
+\verb|SERVER | database;
+
+\verb|UID | user name.
+
+The second argument and all following are considered to be SQL
+statements
+
+SQL statements may be spread over multiple arguments. If the last
+character of an argument is a semicolon this indicates the end of
+a SQL statement.
+
+The arguments of a SQL statement are concatenated separated by space.
+The eventual trailing semicolon will be removed.
+
+All but the last SQL statement will be executed directly.
+
+For IN-table the last SQL statement can be a SELECT command starting
+with the capitalized letters \verb|'SELECT '|. If the string does not
+start with \verb|'SELECT '| it is considered to be a table name and a
+SELECT statement is automatically generated.
+
+For OUT-table the last SQL statement can contain one or multiple
+question marks. If it contains a question mark it is considered a
+template for the write routine. Otherwise the string is considered a
+table name and an INSERT template is automatically generated.
+
+The writing routine uses the template with the question marks and
+replaces the first question mark by the first output parameter, the
+second question mark by the second output parameter and so forth. Then
+the SQL command is issued.
+
+The following is an example of the output table statement:
+
+\begin{verbatim}
+table ta { l in LOCATIONS } OUT
+ 'ODBC'
+ 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'DROP TABLE IF EXISTS result;'
+ 'CREATE TABLE result ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );'
+ 'INSERT INTO result 'VALUES ( 4, ?, ? )' :
+ l ~ LOC, quantity[l] ~ QUAN;
+\end{verbatim}
+
+\newpage
+
+\noindent
+Alternatively it could be written as follows:
+
+\begin{verbatim}
+table ta { l in LOCATIONS } OUT
+ 'ODBC'
+ 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'DROP TABLE IF EXISTS result;'
+ 'CREATE TABLE result ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );'
+ 'result' :
+ l ~ LOC, quantity[l] ~ QUAN, 4 ~ ID;
+\end{verbatim}
+
+Using templates with `\verb|?|' supports not only INSERT, but also
+UPDATE, DELETE, etc. For example:
+
+\begin{verbatim}
+table ta { l in LOCATIONS } OUT
+ 'ODBC'
+ 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'UPDATE result SET DATE = ' & date & ' WHERE ID = 4;'
+ 'UPDATE result SET QUAN = ? WHERE LOC = ? AND ID = 4' :
+ quantity[l], l;
+\end{verbatim}
+
+\section{MySQL table driver}
+
+The MySQL table driver allows connecting to MySQL databases.
+
+\para{Debian GNU/Linux.}
+Under Debian GNU/Linux the MySQL table driver uses the MySQL
+package,\footnote{For download development files see
+{\tt<http://dev.mysql.com/downloads/mysql/>}.} which should be
+installed before building the GLPK package. The installation can be
+effected with the following command:
+
+\begin{verbatim}
+ sudo apt-get install libmysqlclient15-dev
+\end{verbatim}
+
+Note that on configuring the GLPK package to enable using the MySQL
+library the option `\verb|--enable-mysql|' should be passed to the
+configure script.
+
+\para{Microsoft Windows.}
+Under Microsoft Windows the MySQL table driver also uses the MySQL
+library. To enable this feature the symbol:
+
+\begin{verbatim}
+ #define MYSQL_DLNAME "libmysql.dll"
+\end{verbatim}
+
+\noindent
+should be defined in the GLPK configuration file `\verb|config.h|'.
+
+To choose the MySQL table driver its name in the table statement should
+be specified as \verb|'MySQL'|.
+
+The argument list is specified as follows.
+
+The first argument specifies how to connect the data base in the DSN
+style, for example:
+
+\verb|'Database=glpk;UID=glpk;PWD=gnu'|.
+
+Different parts of the string are separated by semicolons. Each part
+consists of a pair {\it fieldname} and {\it value} separated by the
+equal sign. The following fieldnames are allowed:
+
+\newpage
+
+\verb|Server | server running the database (defaulting to localhost);
+
+\verb|Database | name of the database;
+
+\verb|UID | user name;
+
+\verb|PWD | user password;
+
+\verb|Port | port used by the server (defaulting to 3306).
+
+The second argument and all following are considered to be SQL
+statements.
+
+SQL statements may be spread over multiple arguments. If the last
+character of an argument is a semicolon this indicates the end of
+a SQL statement.
+
+The arguments of a SQL statement are concatenated separated by space.
+The eventual trailing semicolon will be removed.
+
+All but the last SQL statement will be executed directly.
+
+For IN-table the last SQL statement can be a SELECT command starting
+with the capitalized letters \verb|'SELECT '|. If the string does not
+start with \verb|'SELECT '| it is considered to be a table name and a
+SELECT statement is automatically generated.
+
+For OUT-table the last SQL statement can contain one or multiple
+question marks. If it contains a question mark it is considered a
+template for the write routine. Otherwise the string is considered a
+table name and an INSERT template is automatically generated.
+
+The writing routine uses the template with the question marks and
+replaces the first question mark by the first output parameter, the
+second question mark by the second output parameter and so forth. Then
+the SQL command is issued.
+
+The following is an example of the output table statement:
+
+\begin{verbatim}
+table ta { l in LOCATIONS } OUT
+ 'MySQL'
+ 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'DROP TABLE IF EXISTS result;'
+ 'CREATE TABLE result ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );'
+ 'INSERT INTO result VALUES ( 4, ?, ? )' :
+ l ~ LOC, quantity[l] ~ QUAN;
+\end{verbatim}
+
+\noindent
+Alternatively it could be written as follows:
+
+\begin{verbatim}
+table ta { l in LOCATIONS } OUT
+ 'MySQL'
+ 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'DROP TABLE IF EXISTS result;'
+ 'CREATE TABLE result ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );'
+ 'result' :
+ l ~ LOC, quantity[l] ~ QUAN, 4 ~ ID;
+\end{verbatim}
+
+\newpage
+
+Using templates with `\verb|?|' supports not only INSERT, but also
+UPDATE, DELETE, etc. For example:
+
+\begin{verbatim}
+table ta { l in LOCATIONS } OUT
+ 'MySQL'
+ 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'UPDATE result SET DATE = ' & date & ' WHERE ID = 4;'
+ 'UPDATE result SET QUAN = ? WHERE LOC = ? AND ID = 4' :
+ quantity[l], l;
+\end{verbatim}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Solving models with glpsol}
+
+The GLPK package\footnote{{\tt http://www.gnu.org/software/glpk/}}
+includes the program {\tt glpsol}, 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.
+
+To tell the solver that the input file contains a model description you
+need to specify the option \verb|--model| in the command line.
+For example:
+
+\begin{verbatim}
+ glpsol --model foo.mod
+\end{verbatim}
+
+Sometimes it is necessary to use the data section placed in a separate
+file, in which case you may use the following command:
+
+\begin{verbatim}
+ glpsol --model foo.mod --data foo.dat
+\end{verbatim}
+
+\noindent Note that if the model file also contains the data section,
+that section is ignored.
+
+It is also allowed to specify more than one file containing the data
+section, for example:
+
+\begin{verbatim}
+ glpsol --model foo.mod --data foo1.dat --data foo2.dat
+\end{verbatim}
+
+If the model description contains some display and/or printf
+statements, by default the output is sent to the terminal. If you need
+to redirect the output to a file, you may use the following command:
+
+\begin{verbatim}
+ glpsol --model foo.mod --display foo.out
+\end{verbatim}
+
+If you need to look at the problem, which has been generated by the
+model translator, you may use the option \verb|--wlp| as follows:
+
+\begin{verbatim}
+ glpsol --model foo.mod --wlp foo.lp
+\end{verbatim}
+
+\noindent In this 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 instance. In this case you may specify
+the option \verb|--check|, for example:
+
+\begin{verbatim}
+ glpsol --check --model foo.mod --wlp foo.lp
+\end{verbatim}
+
+\newpage
+
+If you need to write a numeric solution obtained by the solver to
+a file, you may use the following command:
+
+\begin{verbatim}
+ glpsol --model foo.mod --output foo.sol
+\end{verbatim}
+
+\noindent in which case the solution is written to file \verb|foo.sol|
+in a plain text format suitable for visual analysis.
+
+The complete list of the \verb|glpsol| options can be found in the
+GLPK reference manual included in the GLPK distribution.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Example model description}
+
+\section{Model description written in MathProg}
+
+Below here is a complete example of the model description written in
+the GNU MathProg modeling language.
+
+\bigskip
+
+\begin{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}
+
+\newpage
+
+\section{Generated LP problem instance}
+
+Below here is the result of the translation of the example model
+produced by the solver \verb|glpsol| and written in CPLEX LP format
+with the option \verb|--wlp|.
+
+\medskip
+
+\begin{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}
+
+\section{Optimal LP solution}
+
+Below here is the optimal solution of the generated LP problem instance
+found by the solver \verb|glpsol| and written in plain text format
+with the option \verb|--output|.
+
+\medskip
+
+\begin{footnotesize}
+\begin{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]
+ NU 350 350 < eps
+ 3 supply[San-Diego]
+ B 550 600
+ 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 50 0
+ 2 x[Seattle,Chicago]
+ B 300 0
+ 3 x[Seattle,Topeka]
+ NL 0 0 0.036
+ 4 x[San-Diego,New-York]
+ B 275 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{footnotesize}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section*{Acknowledgements}
+\addcontentsline{toc}{chapter}{Acknowledgements}
+
+The authors would like to thank the following people, who kindly read,
+commented, and corrected the draft of this document:
+
+\noindent Juan Carlos Borras \verb|<borras@cs.helsinki.fi>|
+
+\noindent Harley Mackenzie \verb|<hjm@bigpond.com>|
+
+\noindent Robbie Morrison \verb|<robbie@actrix.co.nz>|
+
+\end{document}
diff --git a/glpk-5.0/doc/gmpl_es.pdf b/glpk-5.0/doc/gmpl_es.pdf
new file mode 100644
index 0000000..126f9e8
--- /dev/null
+++ b/glpk-5.0/doc/gmpl_es.pdf
Binary files differ
diff --git a/glpk-5.0/doc/gmpl_es.tex b/glpk-5.0/doc/gmpl_es.tex
new file mode 100644
index 0000000..7a61125
--- /dev/null
+++ b/glpk-5.0/doc/gmpl_es.tex
@@ -0,0 +1,3231 @@
+%* gmpl_es.tex *%
+
+%***********************************************************************
+% This code is part of GLPK (GNU Linear Programming Kit).
+%
+% Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+% 2009, 2010, 2011, 2013, 2014, 2015 Andrew Makhorin, Department for
+% Applied Informatics, Moscow Aviation Institute, Moscow, Russia. All
+% rights reserved. E-mail: <mao@gnu.org>.
+%
+% GLPK is free software: you can redistribute it and/or modify it
+% under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% GLPK is distributed in the hope that it will be useful, but WITHOUT
+% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+% License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with GLPK. If not, see <http://www.gnu.org/licenses/>.
+%***********************************************************************
+
+\documentclass[11pt,spanish]{report}
+\usepackage[utf8]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage{lmodern}
+\usepackage{amssymb}
+\usepackage[dvipdfm,linktocpage,colorlinks,linkcolor=blue,
+urlcolor=blue]{hyperref}
+\usepackage{indentfirst}
+
+\setlength{\textwidth}{6.5in}
+\setlength{\textheight}{8.5in}
+\setlength{\oddsidemargin}{0in}
+\setlength{\topmargin}{0in}
+\setlength{\headheight}{0in}
+\setlength{\headsep}{0in}
+\setlength{\footskip}{0.5in}
+\setlength{\parindent}{16pt}
+\setlength{\parskip}{5pt}
+\setlength{\topsep}{0pt}
+\setlength{\partopsep}{0pt}
+\setlength{\itemsep}{\parskip}
+\setlength{\parsep}{0pt}
+\setlength{\leftmargini}{\parindent}
+\renewcommand{\labelitemi}{---}
+
+\def\para#1{\noindent{\bf#1}}
+
+\renewcommand\contentsname{\sf\bfseries Contenidos}
+\renewcommand\chaptername{\sf\bfseries Capítulo}
+\renewcommand\appendixname{\sf\bfseries Apéndice}
+
+\begin{document}
+
+\thispagestyle{empty}
+
+\begin{center}
+
+\vspace*{1.5in}
+
+\begin{huge}
+\sf\bfseries Lenguaje de Modelado GNU MathProg
+\end{huge}
+
+\vspace{0.5in}
+
+\begin{LARGE}
+\sf Referencia del Lenguaje
+\end{LARGE}
+
+\vspace{0.5in}
+
+\begin{LARGE}
+\sf para GLPK Versión 4.57
+\end{LARGE}
+
+\vspace{0.5in}
+\begin{Large}
+\sf (BORRADOR, octubre del 2015)
+\end{Large}
+
+\end{center}
+
+\newpage
+
+\vspace*{1in}
+
+\vfill
+
+\noindent
+El paquete GLPK es parte del Proyecto GNU distribuido bajo la égida de GNU
+
+\noindent
+Copyright \copyright{} 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2015 Andrew Makhorin, Department for Applied Informatics, Moscow Aviation Institute, Moscow, Russia. Todos los derechos reservados.
+
+\noindent
+Título original en inglés: Modeling Language GNU MathProg - Language Reference for GLPK Version 4.50
+
+\noindent
+Traducción: Pablo Yapura, Facultad de Ciencias Agrarias y Forestales, Universidad Nacional de La Plata, La Plata, Argentina.
+
+\noindent
+Copyright \copyright{} 2013, 2014, 2015 Pablo Yapura, para esta traducción. Todos los derechos reservados.
+
+\noindent
+Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+MA 02110-1301, USA.
+
+\noindent
+Se permite realizar y distribuir copias textuales de este manual siempre que se preserve este aviso de permiso y el aviso del copyright en todas las copias.
+
+\noindent
+Se permite copiar y distribuir versiones modificadas de este manual bajo las condiciones de copias textuales, siempre que también se distribuya íntegro el trabajo derivado resultante bajo los términos de un aviso de permiso idéntico al presente.
+
+\noindent
+Se permite copiar y distribuir traducciones de este manual en otro idioma bajo las condiciones establecidas arriba para versiones modificadas.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+{\setlength{\parskip}{0pt}
+\tableofcontents
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Introducción}
+
+{\it GNU MathProg} es un lenguaje de modelado diseñado para describir modelos lineales de programación matemática.\footnote{El lenguaje GNU MathProg es un subconjunto del lenguaje AMPL. Su implementación en GLPK está basada principalmente en el paper: {\it Robert Fourer}, {\it David M. Gay} \& {\it Brian W. Kernighan}, ``A Modeling Language for Mathematical Programming.'' {\it Management Science} 36 (1990), pp.~519-554.}
+
+La descripción del modelo escrita en el lenguaje GNU MathProg consiste en un conjunto de sentencias y bloques de datos construidos por el usuario a partir de los elementos del lenguaje que se describen en este documento.
+
+En un proceso que se denomina {\it traducción}, un programa denominado {\it traductor del modelo} analiza la descripción del modelo y la traduce en una estructura interna de datos, la que puede ser usada tanto para generar una instancia de un problema de programación matemática, como para obtener directamente una solución numérica del problema mediante un programa denominado {\it solver}.
+
+\section{El problema de la programación lineal}
+\label{problem}
+
+En MathProg el problema de la programación lineal (PL) se expresa como sigue:
+
+\medskip
+
+\noindent\hspace{1in}minimizar (o maximizar)
+$$z=c_1x_1+c_2x_2+\dots+c_nx_n+c_0\eqno(1.1)$$
+\noindent\hspace{1in}sujeto a las restricciones lineales
+$$
+\begin{array}{l@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }l}
+L_1&\leq&a_{11}x_1&+&a_{12}x_2&+\dots+&a_{1n}x_n&\leq&U_1\\
+L_2&\leq&a_{21}x_1&+&a_{22}x_2&+\dots+&a_{2n}x_n&\leq&U_2\\
+\multicolumn{9}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\
+L_m&\leq&a_{m1}x_1&+&a_{m2}x_2&+\dots+&a_{mn}x_n&\leq&U_m\\
+\end{array}\eqno(1.2)
+$$
+\noindent\hspace{1in}y a las cotas de las variables
+$$
+\begin{array}{l@{\ }c@{\ }c@{\ }c@{\ }l}
+l_1&\leq&x_1&\leq&u_1\\
+l_2&\leq&x_2&\leq&u_2\\
+\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .}\\
+l_n&\leq&x_n&\leq&u_n\\
+\end{array}\eqno(1.3)
+$$
+
+\noindent
+donde $x_1$, $x_2$, \dots, $x_n$ son variables; $z$ es la función objetivo; $c_1$, $c_2$, \dots, $c_n$ son coeficientes de la función objetivo; $c_0$ es el término constante (``de traslación'') de la función objetivo; $a_{11}$,
+$a_{12}$, \dots, $a_{mn}$ son coeficientes de las restricciones; $L_1$, $L_2$,
+\dots, $L_m$ son cotas inferiores de las restricciones; $U_1$, $U_2$, \dots, $U_m$ son cotas superiores de las restricciones; $l_1$, $l_2$, \dots, $l_n$ son cotas inferiores de las variables y $u_1$, $u_2$, \dots, $u_n$ son cotas superiores de las variables.
+
+Las cotas de las variables y las cotas de las restricciones pueden ser tanto finitas como infinitas. Además, las cotas inferiores pueden ser iguales a las correspondientes cotas superiores. Entonces, están permitidos los siguientes tipos de variables y restricciones:
+
+\medskip
+
+{\def\arraystretch{1.4}
+\noindent\hspace{54pt}
+\begin{tabular}{@{}r@{\ }c@{\ }c@{\ }c@{\ }l@{\hspace*{39.5pt}}l}
+$-\infty$&$<$&$x$&$<$&$+\infty$&Variable libre (no acotada)\\
+$l$&$\leq$&$x$&$<$&$+\infty$&Variable con cota inferior\\
+$-\infty$&$<$&$x$&$\leq$&$u$&Variable con cota superior\\
+$l$&$\leq$&$x$&$\leq$&$u$&Variable doblemente acotada\\
+$l$&$=$&$x$&=&$u$&Variable fija\\
+\end{tabular}
+
+\noindent\hspace{54pt}
+\begin{tabular}{@{}r@{\ }c@{\ }c@{\ }c@{\ }ll}
+$-\infty$&$<$&$\sum a_jx_j$&$<$&$+\infty$&Forma lineal libre (no acotada)\\
+$L$&$\leq$&$\sum a_jx_j$&$<$&$+\infty$&Restricción de inecuación ``mayor o igual que''\\
+$-\infty$&$<$&$\sum a_jx_j$&$\leq$&$U$&Restricción de inecuación ``menor o igual que''\\
+$L$&$\leq$&$\sum a_jx_j$&$\leq$&$U$&Restricción de inecuación doblemente acotada\\
+$L$&$=$&$\sum a_jx_j$&=&$U$&Restricción de igualdad\\
+\end{tabular}
+}
+
+\medskip
+
+Además de problemas puros de PL, MathProg también permite problemas de programación entera lineal mixta (PEM), en los que algunas o todas las variables se han restringido a ser enteras o binarias.
+
+\section{Objetos del modelo}
+
+En MathProg el modelo se describe mediante conjuntos, parámetros, variables, restricciones y objetivos, los que se denominan {\it objetos del modelo}.
+
+El usuario introduce objetos particulares del modelo usando las sentencias del lenguaje. Cada objeto del modelo está provisto de un nombre simbólico que lo identifica de manera única y está pensado con propósitos de referencia.
+
+\newpage
+
+Los objetos del modelo, incluyendo los conjuntos, pueden ser arreglos multidimensionales construidos sobre conjuntos indizantes. Formalmente, el arreglo $n$-dimensional $A$ es el mapeo $$A:\Delta\rightarrow\Xi,\eqno(1.4)$$ donde $\Delta\subseteq C_1\times\dots\times C_n$ es el subconjunto del producto cartesiano de los conjuntos indizantes, $\Xi$ es el conjunto de los miembros del arreglo. En MathProg, el conjunto $\Delta$ se denomina {\it dominio del subíndice}. Sus miembros son los $n$-tuplos $(i_1,\dots,i_n)$, donde
+$i_1\in C_1$, \dots, $i_n\in C_n$.
+
+Si $n=0$, el producto cartesiano tiene exactamente un miembro (específicamente, un 0-tuplo), de forma tal que es conveniente pensar en los objetos escalares como arreglos 0-dimensionales que tienen un solo miembro.
+
+El tipo de los miembros del arreglo se determina por el tipo del objeto del modelo correspondiente como sigue:
+
+\medskip
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Objeto del modelo&Miembro del arreglo\\
+\hline
+Conjunto&Conjunto plano elemental\\
+Parámetro&Número o símbolo\\
+Variable&Variable elemental\\
+Restricción&Restricción elemental\\
+Objetivo&Objetivo elemental\\
+\end{tabular}
+
+\medskip
+
+Para referir al miembro particular de un objeto, el mismo debe estar provisto de {\it subíndices}. Por ejemplo, si $a$ es un parámetro 2-dimensional definido sobre $I\times J$, una referencia a sus miembros particulares se puede escribir como $a[i,j]$, donde $i\in I$ y $j\in J$. Se sobreentiende que los objetos escalares no necesitan subíndices por ser 0-dimensionales.
+
+\section{Estructura de la descripción del modelo}
+
+A veces es deseable escribir un modelo que, en distintos momentos, puede requerir diferentes datos para solucionar cada instancia del problema usando el modelo. Por esta razón, en MathProg la descripción del modelo consta de dos partes: la {\it sección del modelo} y la {\it sección de los datos}.
+
+La sección del modelo es la parte principal de la descripción del modelo que contiene las declaraciones de los objetos del modelo; es común a todos los problemas basados en el modelo correspondiente.
+
+La sección de los datos es una parte opcional de la descripción del modelo que contiene los datos específicos para una instancia particular del problema.
+
+Dependiendo de lo que sea más conveniente, las secciones del modelo y de los datos pueden disponerse en el mismo archivo o en dos archivos separados. Esta última característica permite tener un número arbitrario de secciones con datos diferentes para ser usadas con la misma sección del modelo.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\chapter{Codificación de la descripción del modelo}
+\label{coding}
+
+La descripción del modelo se codifica en formato de texto plano usando el juego de caracteres ASCII. Los caracteres válidos en la descripción del modelo son los siguientes:
+
+\begin{itemize}
+\item caracteres alfabéticos:\\
+\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 _|
+\item caracteres numéricos:\\
+\verb|0 1 2 3 4 5 6 7 8 9|
+\item caracteres especiales:\\
+\verb?! " # & ' ( ) * + , - . / : ; < = > [ ] ^ { | } ~?
+\item caracteres no imprimibles:\\
+\verb|SP HT CR NL VT FF|
+\end{itemize}
+
+Dentro de los literales de cadena y de los comentarios, cualquier carácter ASCII (excepto los caracteres de control) son válidos.
+
+Los caracteres no imprimibles no son significativos. Se pueden usar libremente entre las unidades léxicas para mejorar la legibilidad de la descripción del modelo. También se usan para separar unidades léxicas entre sí, en caso de no existir otra forma de hacerlo.
+
+Sintácticamente, la descripción del modelo es una secuencia de unidades léxicas de las siguientes categorías:
+
+\begin{itemize}
+\item nombres simbólicos;
+\item literales numéricos;
+\item literales de cadena;
+\item palabras clave;
+\item delimitadores;
+\item comentarios.
+\end{itemize}
+
+Las unidades léxicas del lenguaje se discuten a continuación.
+
+\section{Nombres simbólicos}
+
+Un {\it nombre simbólico} consiste de caracteres alfabéticos y numéricos, el primero de los cuales debe ser alfabético. Todos los nombres simbólicos deben ser distintos (sensibilidad a las mayúsculas).
+
+\para{Ejemplos}
+
+\begin{verbatim}
+alfa123
+Esto_es_un_nombre
+_P123_abc_321
+\end{verbatim}
+
+Los nombres simbólicos se usan para identificar los objetos del modelo (conjuntos, parámetros, variables, restricciones y objetivos) y los índices.
+
+Todos los nombres simbólicos (exceptuando los nombres de los índices) deben ser únicos, {\it i.e.} la descripción del modelo no debe tener objetos distintos con el mismo nombre. Los nombres simbólicos de los índices deben ser únicos dentro del alcance en el que son válidos.
+
+\section{Literales numéricos}
+
+Un {\it literal numérico} sigue la forma {\it xx}{\tt E}{\it syy}, donde {\it xx} es un número con punto decimal optativo, {\it s} es el signo {\tt+} o {\tt-} e {\it yy} es un exponente decimal. La letra {\tt E} es insensible a las mayúsculas y se puede codificar como {\tt e}.
+
+\para{Ejemplos}
+
+\begin{verbatim}
+123
+3.14159
+56.E+5
+.78
+123.456e-7
+\end{verbatim}
+
+Los literales numéricos se usan para representar cantidades numéricas y tienen significado fijo obvio.
+
+\section{Literales de cadena}
+
+Un {\it literal de cadena} es una secuencia arbitraria de caracteres encerrados entre comillas, tanto simples como dobles. Ambas formas son equivalentes.
+
+Si una comilla simple es parte de un literal de cadena encerrado entre comillas simples, se debe codificar dos veces. Análogamente, si una comilla doble es parte de un literal de cadena encerrado entre comillas dobles, se debe codificar dos veces.
+
+\para{Ejemplos}
+
+\begin{verbatim}
+'Esta es una cadena'
+"Esta es otra cadena"
+'No debe usarse los 20''s'
+"""Hola, che"" cantaba Favio."
+\end{verbatim}
+
+Los literales de cadena se usan para representar cantidades simbólicas.
+
+\section{Palabras clave}
+
+Una {\it palabra clave} es una secuencia de caracteres alfabéticos y posiblemente algunos caracteres especiales.
+
+Todas la palabras clave caen en alguna de dos categorías: las {\it palabras clave reservadas}, que no pueden usarse como nombres simbólicos, y las {\it palabras clave no reservadas}, que son reconocidas por el contexto y entonces pueden usarse como nombres simbólicos.
+
+Las palabras clave reservadas son las siguientes:
+
+\noindent\hfil
+\begin{tabular}{@{}p{.7in}p{.7in}p{.7in}p{.7in}@{}}
+{\tt and}&{\tt else}&{\tt mod}&{\tt union}\\
+{\tt by}&{\tt if}&{\tt not}&{\tt within}\\
+{\tt cross}&{\tt in}&{\tt or}\\
+{\tt diff}&{\tt inter}&{\tt symdiff}\\
+{\tt div}&{\tt less}&{\tt then}\\
+\end{tabular}
+
+Las palabras clave no reservadas se describen en secciones posteriores.
+
+Todas las palabras clave tienen un significado fijo, el que se explicará en las discusiones de las correspondientes construcciones sintácticas donde las palabras claves sean usadas.
+
+\section{Delimitadores}
+
+Un {\it delimitador} es tanto un carácter especial individual como una secuencia de dos caracteres especiales, como sigue:
+
+\noindent\hfil
+\begin{tabular}{@{}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}
+p{.3in}p{.3in}@{}}
+{\tt+}&{\tt**}&{\tt<=}&{\tt>}&{\tt\&\&}&{\tt:}&{\tt|}&{\tt[}&{\tt>}{\tt>}\\
+{\tt-}&{\tt\textasciicircum}&{\tt=}&{\tt<>}&{\tt||}&{\tt;}&{\tt\char126}
+&{\tt]}&{\tt<-}\\
+{\tt*}&{\tt\&}&{\tt==}&{\tt!=}&{\tt.}&{\tt:=}&{\tt(}&{\tt\{}\\
+{\tt/}&{\tt<}&{\tt>=}&{\tt!}&{\tt,}&{\tt..}&{\tt)}&{\tt\}}\\
+\end{tabular}
+
+Si el delimitador está compuesto por dos caracteres, no debe haber espacios entre ellos.
+
+Todos los delimitadores tienen un significado fijo, el que se explicará en las discusiones de las correspondientes construcciones sintácticas donde los delimitadores sean usados.
+
+\section{Comentarios}
+
+Con propósitos de documentación, la descripción del modelo puede ser provista de {\it comentarios}, los que pueden ser de dos formas diferentes. La primera es un {\it comentario de una línea individual}, el que debe comenzar con el carácter {\tt\#} y se extiende hasta el final de la línea. La segunda forma es un {\it comentario en secuencia}, el que consiste en una secuencia de caracteres cualesquiera encerrados entre {\tt/*} y {\tt*/}.
+
+\para{Ejemplos}
+
+\begin{verbatim}
+param n := 10; # Esto es un comentario
+/* Esto es otro comentario */
+\end{verbatim}
+
+Los comentarios son ignorados por el traductor del modelo y pueden aparecer en cualquier sitio de la descripción del modelo en la que que se permitan caracteres no imprimibles.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\chapter{Expresiones}
+
+Una {\it expresión} es una regla para calcular un valor. En la descripción de un modelo, las expresiones se usan como constituyentes de ciertas sentencias.
+
+En general, las expresiones están compuestas por operandos y operadores.
+
+Dependiendo del tipo del valor resultante, todas las expresiones pertenecen a alguna de las siguientes categorías:
+
+\vspace*{-8pt}
+
+\begin{itemize}
+\item expresiones numéricas;
+\item expresiones simbólicas;
+\item expresiones indizantes;
+\item expresiones de conjuntos;
+\item expresiones lógicas;
+\item expresiones lineales.
+\end{itemize}
+
+\vspace*{-8pt}
+
+\section{Expresiones numéricas}
+
+Una {\it expresión numérica} es una regla para calcular un valor numérico individual representado como un número de punto flotante.
+
+La expresión numérica primaria puede ser un literal numérico, un índice, un parámetro no-indizado, un parámetro indizado, una función interna de referencia, una expresión numérica iterada, una expresión numérica condicional u otra expresión numérica encerrada entre paréntesis.
+
+\newpage
+
+\para{Ejemplos}
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|1.23|&(literal numérico)\\
+\verb|j|&(índice)\\
+\verb|tiempo|&(parámetro no-indizado)\\
+\verb|a['Mayo de 2003',j+1]|&(parámetro indizado)\\
+\verb|abs(b[i,j])|&(función de referencia)\\
+\verb|sum{i in S diff T} alfa[i] * b[i,j]|&(expresión iterada)\\
+\verb|if i in I then 2 * p else q[i+1]|&(expresión condicional)\\
+\verb|(b[i,j] + .5 * c)|&(expresión parentética)\\
+\end{tabular}
+
+Empleando ciertos operadores aritméticos se pueden construir expresiones numéricas más generales conteniendo dos o más expresiones numéricas primarias.
+
+\para{Ejemplos}
+
+\begin{verbatim}
+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 and p >= 1 then 2 * p else q[i+1]) / (a[i,j] + 1.5)
+\end{verbatim}
+
+\subsection{Literales numéricos}
+
+Si la expresión numérica primaria es un literal numérico, el valor resultante es obvio.
+
+\subsection{Índices}
+
+Si la expresión numérica primaria es un índice, el valor resultante es el valor corriente asignado al índice.
+
+\subsection{Parámetros no-indizados}
+
+Si la expresión numérica primaria es un parámetro no-indizado (el que debe ser 0-dimensional), el valor resultante es el valor del parámetro.
+
+\subsection{Parámetros indizados}
+
+La expresión numérica primaria que se refiere a parámetros indizados tiene la siguiente forma sintáctica:
+$$
+\mbox{{\it nombre}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,} $i_n${\tt]}}
+$$
+donde {\it nombre} es el nombre simbólico del parámetro e $i_1$, $i_2$,
+\dots, $i_n$ son subíndices.
+
+Cada subíndice debe ser una expresión numérica o simbólica. El número de subíndices en la lista de subíndices debe ser igual a la dimensión del parámetro con el cual está asociada la lista de subíndices.
+
+Los valores reales de las expresiones de subíndices se usan para identificar al miembro particular del parámetro que determina el valor resultante de la expresión primaria.
+
+\subsection{Funciones de referencia}
+
+En MathProg existen las siguientes funciones internas, las que se pueden usar en expresiones numéricas:
+
+\begin{tabular}{@{}p{112pt}p{328pt}@{}}
+{\tt abs(}$x${\tt)}&$|x|$, valor absoluto de $x$\\
+{\tt atan(}$x${\tt)}&$\arctan x$, valor principal del arcotangente de
+$x$ (en radianes)\\
+{\tt atan(}$y${\tt,} $x${\tt)}&$\arctan y/x$, valor principal del arcotangente de $y/x$ (en radianes). En este caso, los signos de ambos argumentos, $y$ y $x$, se usan para determinar el cuadrante del valor resultante\\
+{\tt card(}$X${\tt)}&$|X|$, el cardinal (número de elementos) del conjunto $X$\\
+{\tt ceil(}$x${\tt)}&$\lceil x\rceil$, el menor entero no menor que $x$ (``techo de $x$'')\\
+{\tt cos(}$x${\tt)}&$\cos x$, coseno de $x$ (en radianes)\\
+{\tt exp(}$x${\tt)}&$e^x$, exponencial en base $e$ de $x$\\
+{\tt floor(}$x${\tt)}&$\lfloor x\rfloor$, el mayor entero no mayor que $x$ (``piso de $x$'')\\
+{\tt gmtime()}&el número de segundos transcurridos desde las 00:00:00 del 1 de enero de 1970, Tiempo Universal Coordinado (para los detalles ver la Sección \ref{gmtime}, página \pageref{gmtime})\\
+{\tt length(}$c${\tt)}&$|c|$, longitud de la cadena de caracteres $c$\\
+{\tt log(}$x${\tt)}&$\log x$, logaritmo natural de $x$\\
+{\tt log10(}$x${\tt)}&$\log_{10}x$, logaritmo común (decimal) de $x$\\
+{\tt max(}$x_1${\tt,} $x_2${\tt,} \dots{\tt,} $x_n${\tt)}&el mayor de los valores $x_1$, $x_2$, \dots, $x_n$\\
+{\tt min(}$x_1${\tt,} $x_2${\tt,} \dots{\tt,} $x_n${\tt)}&el menor de los valores $x_1$, $x_2$, \dots, $x_n$\\
+{\tt round(}$x${\tt)}&redondeo de $x$ al entero más próximo\\
+{\tt round(}$x${\tt,} $n${\tt)}&redondeo de $x$ a $n$ dígitos decimales\\
+{\tt sin(}$x${\tt)}&$\sin x$, seno de $x$ (en radianes)\\
+{\tt sqrt(}$x${\tt)}&$\sqrt{x}$, raíz cuadrada no-negativa de $x$\\
+{\tt str2time(}$c${\tt,} $f${\tt)}&conversión de la cadena de caracteres $c$ a tiempo calendario (para los detalles ver la Sección \ref{str2time}, página \pageref{str2time})\\
+{\tt trunc(}$x${\tt)}&truncado de $x$ al entero más próximo\\
+{\tt trunc(}$x${\tt,} $n${\tt)}&truncado de $x$ a $n$ dígitos decimales\\
+{\tt Irand224()}&generación de un entero pseudo-aleatorio uniformemente distribuido en $[0,2^{24})$\\
+{\tt Uniform01()}&generación de un número pseudo-aleatorio uniformemente distribuido en $[0,1)$\\
+{\tt Uniform(}$a${\tt,} $b${\tt)}&generación de un número pseudo-aleatorio uniformemente distribuido en $[a,b)$\\
+{\tt Normal01()}&generación de una variable gaussiana pseudo-aleatoria con $\mu=0$ y $\sigma=1$\\
+{\tt Normal(}$\mu${\tt,} $\sigma${\tt)}&generación de una variable gaussiana pseudo-aleatoria con $\mu$ y $\sigma$ dadas\\
+\end{tabular}
+
+Los argumentos de todas la funciones internas, excepto {\tt card}, {\tt length} y {\tt str2time}, deben ser expresiones numéricas. El argumento de {\tt card} debe ser una expresión de conjunto. El argumento de {\tt length} y ambos argumentos de {\tt str2time} deben ser expresiones simbólicas.
+
+El valor resultante de una expresión numérica que es una función de referencia es el resultado de aplicar la función a sus argumentos.
+
+Se debe notar que cada función generadora pseudo-aleatoria tiene un argumento latente ({\it i.e.} algún estado interno) que cambia cada vez que se aplica la función. Así, si la función se aplica repetidamente, aún con argumentos idénticos, debido al efecto colateral siempre se producirán valores resultantes diferentes.
+
+\subsection{Expresiones iteradas}
+\label{itexpr}
+
+Una {\it expresión numérica iterada} es una expresión numérica primaria que tiene la siguiente forma sintáctica:
+$$\mbox{\it operador-iterado expresión-indizante integrando}$$
+donde {\it operador-iterado} es el nombre simbólico del operador iterado que se ejecutará (ver más adelante), {\it expresión-indizante} es una expresión indizante que introduce índices y controla la iteración e {\it integrando} es una expresión numérica que participa en la operación.
+
+En MathProg existen cuatro operadores iterados que se pueden usar en expresiones numéricas:
+
+{\def\arraystretch{2}
+\noindent\hfil
+\begin{tabular}{@{}lll@{}}
+{\tt sum}&sumatoria&$\displaystyle\sum_{(i_1,\dots,i_n)\in\Delta}
+f(i_1,\dots,i_n)$\\
+{\tt prod}&multiplicatoria&$\displaystyle\prod_{(i_1,\dots,i_n)\in\Delta}
+f(i_1,\dots,i_n)$\\
+{\tt min}&mínimo&$\displaystyle\min_{(i_1,\dots,i_n)\in\Delta}
+f(i_1,\dots,i_n)$\\
+{\tt max}&máximo&$\displaystyle\max_{(i_1,\dots,i_n)\in\Delta}
+f(i_1,\dots,i_n)$\\
+\end{tabular}
+}
+
+\noindent donde $i_1$, \dots, $i_n$ son índices introducidos en la expresión indizante, $\Delta$ es el dominio, el conjunto de los $n$-tuplos especificados en la expresión indizante que define valores particulares asignados a los índices para ejecutar la operación iterada y $f(i_1,\dots,i_n)$ es el integrando, una expresión numérica cuyo valor resultante depende de los índices.
+
+El valor resultante de una expresión numérica iterada es el resultado de aplicar el operador iterado a sus integrandos a través de todos los $n$-tuplos contenidos en el dominio.
+
+\subsection{Expresiones condicionales}
+\label{ifthen}
+
+Una {\it expresión numérica condicional} es una expresión numérica primaria que tiene una de las dos formas sintácticas siguientes:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{{\tt if} $b$ {\tt then} $x$ {\tt else} $y$}\\
+\mbox{{\tt if} $b$ {\tt then} $x$}\\
+\end{array}
+}
+$$
+donde $b$ es una expresión lógica, mientras que $x$ e $y$ son expresiones numéricas.
+
+El valor resultante de un expresión condicional depende del valor de la expresión lógica que sigue a la palabra clave {\tt if}. Si toma el valor {\it verdadero}, el valor de la expresión condicional es el valor de la expresión que sigue a la palabra clave {\tt then}. De otro modo, si la expresión lógica toma el valor {\it falso}, el valor de la expresión condicional es el valor de la expresión que sigue a la palabra clave {\tt else}. Si se usa la segunda forma sintáctica, la reducida, y la expresión lógica toma el valor {\it falso}, el valor resultante de la expresión condicional será cero.
+
+\subsection{Expresiones parentéticas}
+
+Cualquier expresión numérica puede ser encerrada entre paréntesis, lo que las torna sintácticamente en una expresión numérica primaria.
+
+Los paréntesis pueden usarse en expresiones numéricas, como en el álgebra, para especificar el orden deseado en el cual se ejecutarán las operaciones. Cuando se usan paréntesis, la expresión entre paréntesis se evalúa antes que el valor resultante sea usado.
+
+El valor resultante de la expresión parentética es idéntico al valor de la expresión encerrada entre paréntesis.
+
+\subsection{Operadores aritméticos}
+
+En MathProg existen los siguientes operadores aritméticos, los que se pueden usar en expresiones numéricas:
+
+\begin{tabular}{@{}ll@{}}
+{\tt +} $x$&más unario\\
+{\tt -} $x$&menos unario\\
+$x$ {\tt +} $y$&adición\\
+$x$ {\tt -} $y$&sustracción\\
+$x$ {\tt less} $y$&diferencia positiva (si $x<y$ entonces 0, de otro modo $x-y$)\\
+$x$ {\tt *} $y$&multiplicación\\
+$x$ {\tt /} $y$&división\\
+$x$ {\tt div} $y$&cociente de la división exacta\\
+$x$ {\tt mod} $y$&resto de la división exacta\\
+$x$ {\tt **} $y$, $x$ {\tt\textasciicircum} $y$&exponenciación (elevación a una potencia)\\
+\end{tabular}
+
+\noindent donde $x$ e $y$ son expresiones numéricas.
+
+Si la expresión incluye más de un operador aritmético, todos los operadores se ejecutan de izquierda a derecha, de acuerdo con la jerarquía de las operaciones (ver más adelante), con la única excepción del operador de exponenciación que se ejecuta de derecha a izquierda.
+
+El valor resultante de la expresión que contiene operadores aritméticos es el resultado de aplicar los operadores a sus operandos.
+
+\subsection{Jerarquía de las operaciones}
+\label{hierarchy}
+
+La siguiente lista muestra la jerarquía de las operaciones en expresiones numéricas:
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Operación&Jerarquía\\
+\hline
+Evaluación de funciones ({\tt abs}, {\tt ceil}, etc.)&
+1.{\textsuperscript{\b{a}}}\\
+Exponenciación ({\tt**}, {\tt\textasciicircum})&
+2.{\textsuperscript{\b{a}}}\\
+Más y menos unario ({\tt+}, {\tt-})&
+3.{\textsuperscript{\b{a}}}\\
+Multiplicación y división ({\tt*}, {\tt/}, {\tt div}, {\tt mod})&
+4.{\textsuperscript{\b{a}}}\\
+Operaciones iteradas ({\tt sum}, {\tt prod}, {\tt min}, {\tt max})&
+5.{\textsuperscript{\b{a}}}\\
+Adición y sustracción ({\tt+}, {\tt-}, {\tt less})&
+6.{\textsuperscript{\b{a}}}\\
+Evaluación condicional ({\tt if} \dots {\tt then} \dots {\tt else})&
+7.{\textsuperscript{\b{a}}}\\
+\end{tabular}
+
+Esta jerarquía se usa para determinar cual de dos operaciones consecutivas se realizará primero. Si el primer operador tiene jerarquía mayor o igual que el segundo, la primera operación se realiza. En caso contrario, el segundo operador es comparado con el tercero y así sucesivamente. Cuando se alcanza el final de la expresión, todas las operaciones restantes se realizan en el orden inverso.
+
+\section{Expresiones simbólicas}
+
+Una {\it expresión simbólica} es una regla para calcular un valor simbólico individual representado como una cadena de caracteres.
+
+La expresión simbólica primaria puede ser un literal de cadena, un índice, un parámetro no-indizado, un parámetro indizado, una función interna de referencia, una expresión simbólica condicional u otra expresión simbólica encerrada entre paréntesis.
+
+También está permitido usar una expresión numérica como la expresión simbólica primaria, en cuyo caso el valor resultante de la expresión numérica se convierte automáticamente al tipo simbólico.
+
+\para{Ejemplos}
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|'Mayo de 2003'|&(literal de cadena)\\
+\verb|j|&(índice)\\
+\verb|p|&(parámetro no-indizado)\\
+\verb|s['abc',j+1]|&(parámetro indizado)\\
+\verb|substr(nombre[i],k+1,3)|&(función de referencia)\\
+\verb|if i in I then s[i,j] & "..." else t[i+1]|& (expresión condicional) \\
+\verb|((10 * b[i,j]) & '.bis')|&(expresión parentética)\\
+\end{tabular}
+
+Empleando el operador de concatenación se pueden construir expresiones simbólicas más generales conteniendo dos o más expresiones simbólicas primarias.
+
+\para{Ejemplos}
+
+\begin{verbatim}
+'abc[' & i & ',' & j & ']'
+"desde " & ciudad[i] " hasta " & ciudad[j]
+\end{verbatim}
+
+Los principios de evaluación de las expresiones simbólicas son enteramente análogos a los dados para las expresiones numéricas (ver más atrás).
+
+\subsection{Funciones de referencia}
+
+En MathProg existen las siguientes funciones internas que pueden ser usadas en expresiones simbólicas:
+
+\begin{tabular}{@{}p{112pt}p{328pt}@{}}
+{\tt substr(}$c${\tt,} $x${\tt)}&subcadena de $c$ empezando en la posición $x$\\
+{\tt substr(}$c${\tt,} $x${\tt,} $y${\tt)}&subcadena de $c$ empezando en la posición $x$ con longitud $y$\\
+{\tt time2str(}$t${\tt,} $f${\tt)}&conversión de tiempo calendario a una cadena de caracteres (para los detalles, ver Sección \ref{time2str}, página
+\pageref{time2str})\\
+\end{tabular}
+
+El primer argumento de {\tt substr} debe ser una expresión simbólica, mientras que el segundo y el tercero (opcional) deben ser expresiones numéricas.
+
+El primer argumento de {\tt time2str} debe ser una expresión numérica y su segundo argumento debe ser una expresión simbólica.
+
+El valor resultante de una expresión simbólica que es una función de referencia es el resultado de aplicar la función a sus argumentos.
+
+\subsection{Operadores simbólicos}
+
+Actualmente, en MathProg existe un único operador simbólico:
+$$\mbox{\tt c \& t}$$
+donde $c$ y $t$ son expresiones simbólicas. Este operador implica la concatenación de sus dos operandos simbólicos, los que son cadenas de caracteres.
+
+\subsection{Jerarquía de las operaciones}
+
+La siguiente lista muestra la jerarquía de las operaciones en expresiones simbólicas:
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Operación&Jerarquía\\
+\hline
+Evaluación de operaciones numéricas&
+1.{\textsuperscript{\b{a}}}-7.{\textsuperscript{\b{a}}}\\
+Concatenación ({\tt\&})&
+8.{\textsuperscript{\b{a}}}\\
+Evaluación condicional ({\tt if} \dots {\tt then} \dots {\tt else})&
+9.{\textsuperscript{\b{a}}}\\
+\end{tabular}
+
+Esta jerarquía tiene el mismo significado que se explicó anteriormente para expresiones numéricas (ver Subsección \ref{hierarchy}, página \pageref{hierarchy}).
+
+\section{Expresiones de indización e índices}
+\label{indexing}
+
+Una {\it expresión indizante} es una construcción auxiliar que especifica un conjunto plano de $n$-tuplos e introduce índices. Tiene dos formas sintácticas:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{{\tt\{} {\it entrada}$_1${\tt,} {\it entrada}$_2${\tt,} \dots{\tt,}
+{\it entrada}$_m$ {\tt\}}}\\
+\mbox{{\tt\{} {\it entrada}$_1${\tt,} {\it entrada}$_2${\tt,} \dots{\tt,}
+{\it entrada}$_m$ {\tt:} {\it predicado} {\tt\}}}\\
+\end{array}
+}
+$$
+donde {\it entrada}{$_1$}, {\it entrada}{$_2$}, \dots, {\it entrada}{$_m$}
+son entradas indizantes y {\it predicado} es una expresión lógica que especifica un predicado opcional (condición lógica).
+
+Cada {\it entrada indizante} en la expresión indizante puede tomar una de las tres formas siguientes:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{$i$ {\tt in} $C$}\\
+\mbox{{\tt(}$i_1${\tt,} $i_2${\tt,} \dots{\tt,}$i_n${\tt)} {\tt in}
+$C$}\\
+\mbox{$C$}\\
+\end{array}
+}
+$$
+donde $i_1$, $i_2$, \dots, $i_n$ son índices y $C$ es una expresión de conjunto (discutida en la próxima sección) que especifica el conjunto básico.
+
+El número de índices de la entrada indizante debe coincidir con la dimensión del conjunto básico $C$, {\it i.e.} si $C$ consiste de 1-tuplos, se debe usar la primera forma y, si $C$ consiste de $n$-tuplos, siendo $n>1$, la segunda forma es la que debe usarse.
+
+Si se usa la primera forma de la entrada indizante, el índice $i$ sólo puede ser un índice (ver más adelante). Si se usa la segunda forma, los índices $i_1$, $i_2$, \dots, $i_n$ pueden ser indistintamente índices o alguna expresión numérica o simbólica, siempre que al menos uno de los índices sea un índice. La tercera forma, reducida, de la entrada indizante tiene el mismo efecto que si
+$i$ (si $C$ es 1-dimensional) o $i_1$, $i_2$, \dots, $i_n$ (si $C$ es $n$-dimensional) se hubieran especificado todos como índices.
+
+Un {\it índice} es un objeto auxiliar del modelo que actúa como una variable individual. Los valores asignados a los índices son componentes de los $n$-tuplos de conjuntos básicos, {\it i.e.} algunas cantidades numéricas y simbólicas.
+
+Para referenciarlos, los índices pueden ser provistos con nombres simbólicos. Sin embargo, a diferencia de otros objetos del modelo (conjuntos, parámetros, etc.), los índices no necesitan ser declarados explícitamente. Cada nombre simbólico {\it no-declarado} que se usa en una posición indizante de alguna entrada indizante es reconocido como el nombre simbólico correspondiente al índice.
+
+Los nombre simbólicos de los índices son válidos solamente dentro del alcance de la expresión indizante en la que se introdujo el índice. Más allá del alcance, estos índices son completamente inaccesibles, de modo que los mismos nombres simbólicos se pueden usar para diferentes propósitos, en particular para representar índices en otras expresiones indizantes.
+
+El alcance de la expresión indizante, en el que las declaraciones implícitas de los índices son válidas, depende del contexto en que se usa la expresión indizante:
+
+\vspace*{-8pt}
+
+\begin{itemize}
+\item Si la expresión indizante se usa en un operador-iterado, su alcance se extiende hasta el final del integrando;
+\item Si la expresión indizante se usa como una expresión de conjunto primaria, su alcance se extiende hasta el final de esta expresión indizante;
+\item Si la expresión indizante se usa para definir el dominio del subíndice en la declaración de algún objeto del modelo, su alcance se extiende hasta el final de la correspondiente sentencia.
+\end{itemize}
+
+\vspace*{-8pt}
+
+El mecanismo de indización implementado mediante las expresiones indizantes se explica mejor con algunos ejemplos que se discuten a continuación.
+
+Sean tres conjuntos:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+A=\{4,7,9\},\\
+B=\{(1,Ene),(1,Feb),(2,Mar),(2,Abr),(3,May),(3,Jun)\},\\
+C=\{a,b,c\},\\
+\end{array}
+}
+$$
+donde $A$ y $C$ consisten de 1-tuplos (singletones) y $B$ consiste de
+2-tuplos (duplos). Considérese la siguiente expresión indizante:
+$$\mbox{{\tt\{i in A, (j,k) in B, l in C\}}}$$
+donde {\tt i}, {\tt j}, {\tt k} y {\tt l} son índices.
+
+Aunque MathProg no es un lenguaje de programación por procedimientos, para cualquier expresión indizante se puede dar una descripción algorítmica equivalente. En particular, la descripción algorítmica de la expresión indizante anterior se vería como sigue:
+
+\noindent\hfil
+\begin{tabular}{@{}l@{}}
+{\bf para todo} $i\in A$ {\bf ejecutar}\\
+\hspace{16pt}{\bf para todo} $(j,k)\in B$ {\bf ejecutar}\\
+\hspace{32pt}{\bf para todo} $l\in C$ {\bf ejecutar}\\
+\hspace{48pt}{\it acción};\\
+\end{tabular}
+
+\noindent donde los índices $i$, $j$, $k$ y $l$ son asignados consecutivamente a los correspondientes componentes de los $n$-tuplos a partir de los conjuntos básicos $A$, $B$ y $C$ y {\it acción} es alguna acción que depende del contexto en el que se esté usando la expresión indizante. Por ejemplo, si la acción fuese imprimir los valores corrientes de los índices, la impresión se vería como sigue:
+
+\noindent\hfil
+\begin{tabular}{@{}llll@{}}
+$i=4$&$j=1$&$k=Ene$&$l=a$\\
+$i=4$&$j=1$&$k=Ene$&$l=b$\\
+$i=4$&$j=1$&$k=Ene$&$l=c$\\
+$i=4$&$j=1$&$k=Feb$&$l=a$\\
+$i=4$&$j=1$&$k=Feb$&$l=b$\\
+\multicolumn{4}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\
+$i=9$&$j=3$&$k=Jun$&$l=b$\\
+$i=9$&$j=3$&$k=Jun$&$l=c$\\
+\end{tabular}
+
+Sea la expresión indizante del ejemplo usada en la siguiente operación iterada:
+$$\mbox{{\tt sum\{i in A, (j,k) in B, l in C\} p[i,j,k,l]}}$$
+donde {\tt p} es un parámetro numérico 4-dimensional o alguna expresión numérica cuyos valores resultantes dependan de {\tt i}, {\tt j}, {\tt k} y {\tt l}. En este caso la acción es la sumatoria, de modo que el valor resultante de la expresión numérica primaria es:
+$$\sum_{i\in A,(j,k)\in B,l\in C}(p_{ijkl}).$$
+
+Ahora, sea la expresión indizante del ejemplo usada como una expresión de conjunto primaria. En este caso, la acción es reunir a todos los 4-tuplos (cuádruplos) de la forma $(i,j,k,l)$ en un conjunto, de modo que el valor resultante de tal operación es simplemente el producto cartesiano de los conjuntos básicos:
+$$A\times B\times C=\{(i,j,k,l):i\in A,(j,k)\in B,l\in C\}.$$
+Se debe notar que, en este caso, la misma expresión indizante podría escribirse en la forma reducida:
+$$\mbox{{\tt\{A, B, C\}}}$$
+ya que los índices $i$, $j$, $k$ y $l$ no son referenciados y, consecuentemente, sus nombres simbólicos no necesitan ser especificados.
+
+Finalmente, sea la expresión indizante del ejemplo usada como el dominio del subíndice en la declaración de algún objeto 4-dimensional del modelo, por ejemplo un parámetro numérico:
+$$\mbox{{\tt param p\{i in A, (j,k) in B, l in C\}} \dots {\tt;}}$$
+
+\noindent En este caso la acción es generar los miembros del parámetro, donde cada uno de los cuales tiene la forma $p[i,j,k,l]$.
+
+Como se dijo anteriormente, algunos índices en la segunda forma de las entradas indizantes pueden ser expresiones numéricas o simbólicas, no solamente índices. En este caso, los valores resultantes de tales expresiones desempeñan el papel de algunas condiciones lógicas para seleccionar, solamente, aquellos $n$-tuplos del producto cartesiano de los conjuntos básicos que satisfacen estas condiciones.
+
+Considérese, por ejemplo, la siguiente expresión indizante:
+$$\mbox{{\tt\{i in A, (i-1,k) in B, l in C\}}}$$
+donde {\tt i}, {\tt k} y {\tt l} son índices e {\tt i-1} es una expresión numérica. La descripción algorítmica de esta expresión indizante sería la siguiente:
+
+\noindent\hfil
+\begin{tabular}{@{}l@{}}
+{\bf para todo} $i\in A$ {\bf ejecutar}\\
+\hspace{16pt}{\bf para todo} $(j,k)\in B$ {\bf y} $j=i-1$ {\bf ejecutar}\\
+\hspace{32pt}{\bf para todo} $l\in C$ {\bf ejecutar}\\
+\hspace{48pt}{\it acción};\\
+\end{tabular}
+
+\noindent Así, si la expresión indizante se usara como una expresión de conjunto primaria, el conjunto resultante sería el siguiente:
+$$\{(4,May,a),(4,May,b),(4,May,c),(4,Jun,a),(4,Jun,b),(4,Jun,c)\}.$$
+Debe notarse que, en este caso, el conjunto resultante consistirá de 3-tuplos y no de 4-tuplos, puesto que en la expresión indizante no hay un índice que corresponda al primer componente de los 2-tuplos del conjunto $B$.
+
+La regla general es: el número de componentes de los $n$-tuplos definido por una expresión indizante es igual al número de índices de tal expresión, en la que la correspondencia entre los índices y los componentes de los $n$-tuplos en el conjunto resultante es posicional, {\it i.e.} el primer índice se corresponde con el primer componente, el segundo índice se corresponde con el segundo componente, etc.
+
+En algunos casos es necesario seleccionar un subconjunto del producto cartesiano de algunos conjuntos. Esto se puede lograr mediante el empleo de un predicado lógico opcional, el que se especifica en la expresión indizante.
+
+Considérese, por ejemplo, la siguiente expresión indizante:
+$$\mbox{{\tt\{i in A, (j,k) in B, l in C: i <= 5 and k <> 'Mar'\}}}$$
+donde la expresión lógica que sigue a los dos puntos es un predicado. La descripción algorítmica de tal expresión indizante sería la siguiente:
+
+\noindent\hfil
+\begin{tabular}{@{}l@{}}
+{\bf para todo} $i\in A$ {\bf ejecutar}\\
+\hspace{16pt}{\bf para todo} $(j,k)\in B$ {\bf ejecutar}\\
+\hspace{32pt}{\bf para todo} $l\in C$ {\bf ejecutar}\\
+\hspace{48pt}{\bf si} $i\leq 5$ {\bf y} $k\neq`Mar'$ {\bf entonces}\\
+\hspace{64pt}{\it acción};\\
+\end{tabular}
+
+\noindent Así, si esta expresión indizante se usara como una expresión de conjunto primaria, el conjunto resultante sería el siguiente:
+$$\{(4,1,Ene,a),(4,1,Feb,a),(4,2,Abr,a),\dots,(4,3,Jun,c)\}.$$
+
+Si no se especifica un predicado en la expresión indizante, se asume uno que toma el valor {\it verdadero}.
+
+\section{Expresiones de conjunto}
+
+Una {\it expresión de conjunto} es una regla para calcular un conjunto elemental, {\it i.e.} una colección de $n$-tuplos cuyos componentes son cantidades numéricas y simbólicas.
+
+La expresión de conjunto primaria puede ser un conjunto de literales, un conjunto no-indizado, un conjunto indizado, un conjunto ``aritmético'', una expresión indizante, una expresión de conjunto iterada, una expresión de conjunto condicional u otra expresión de conjunto encerrada entre paréntesis.
+
+\para{Ejemplos}
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|{(123,'aaa'), (i+1,'bbb'), (j-1,'ccc')}| &(conjunto de literales)\\
+\verb|I| &(conjunto no-indizado)\\
+\verb|S[i-1,j+1]| &(conjunto indizado)\\
+\verb|1..t-1 by 2| &(conjunto ``aritmético'')\\
+\verb|{t in 1..T, (t+1,j) in S: (t,j) in F}| &(expresión indizante)\\
+\verb|setof{i in I, j in J}(i+1,j-1)| &(expresión de conjunto iterada)\\
+\verb|if i < j then S[i,j] else F diff S[i,j]| &(expresión de conjunto condicional)\\
+\verb|(1..10 union 21..30)| &(expresión de conjunto parentética)\\
+\end{tabular}
+
+Empleando ciertos operadores de conjunto se pueden construir expresiones de conjunto más generales conteniendo dos o más expresiones de conjunto primarias.
+
+\newpage
+
+\para{Ejemplos}
+
+\begin{verbatim}
+(A union B) inter (I cross J)
+1..10 cross (if i < j then {'a', 'b', 'c'} else {'d', 'e', 'f'})
+\end{verbatim}
+
+\subsection{Conjuntos de literales}
+
+Un {\it conjunto de literales} es una expresión de conjunto primaria que tiene las dos formas sintácticas siguientes:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{{\tt\{}$e_1${\tt,} $e_2${\tt,} \dots{\tt,} $e_m${\tt\}}}\\
+\mbox{{\tt\{(}$e_{11}${\tt,} \dots{\tt,} $e_{1n}${\tt),}
+{\tt(}$e_{21}${\tt,} \dots{\tt,} $e_{2n}${\tt),} \dots{\tt,}
+{\tt(}$e_{m1}${\tt,} \dots{\tt,} $e_{mn}${\tt)\}}}\\
+\end{array}
+}
+$$
+donde $e_1$, \dots, $e_m$, $e_{11}$, \dots, $e_{mn}$ son expresiones numéricas o simbólicas.
+
+Si se usa la primera forma, el conjunto resultante consiste de 1-tuplos (singletones), enumerados entre las llaves. Se permite especificar un conjunto vacío como {\tt\{\ \}}, el que no tiene 1-tuplos. Si se usa la segunda forma, el conjunto resultante consiste de $n$-tuplos enumerados entre las llaves, donde cada $n$-tuplo particular está compuesto por los correspondientes componentes enumerados entre los paréntesis. Todos los $n$-tuplos deben tener el mismo número de componentes.
+
+\subsection{Conjuntos no-indizados}
+
+Si la expresión de conjunto primaria es un conjunto no-indizado (el que debe ser 0-dimensional), el conjunto resultante es un conjunto elemental asociado con el objeto conjunto correspondiente.
+
+\subsection{Conjuntos indizados}
+
+La expresión de conjunto primaria que se refiere a un conjunto indizado tiene la siguiente forma sintáctica:
+$$\mbox{{\it nombre}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,}
+$i_n${\tt]}}$$
+donde {\it nombre} es el nombre simbólico del objeto conjunto e $i_1$, $i_2$,
+\dots, $i_n$ son subíndices.
+
+Cada subíndice debe ser una expresión numérica o simbólica. El número de subíndices en la lista de subíndices debe coincidir con la dimensión del objeto conjunto al cual está asociada la lista de subíndices.
+
+Los valores corrientes de las expresiones de los subíndices se usan para identificar un miembro particular del objeto conjunto que determina el conjunto resultante.
+
+\subsection{Conjuntos ``aritméticos''}
+
+La expresión de conjunto primaria que constituye un conjunto ``aritmético'' tiene las dos formas sintácticas siguientes:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{$t_0$ {\tt..} $t_1$ {\tt by} $\delta t$}\\
+\mbox{$t_0$ {\tt..} $t_1$}\\
+\end{array}
+}
+$$
+donde $t_0$, $t_1$ y $\delta t$ son expresiones numéricas (el valor de
+$\delta t$ no debe ser cero). La segunda forma es equivalente a la primera con $\delta t=1$.
+
+Si $\delta t>0$, el conjunto resultante se determina como sigue:
+$$\{t:\exists k\in{\cal Z}(t=t_0+k\delta t,\ t_0\leq t\leq t_1)\}.$$
+De otro modo, si $\delta t<0$, el conjunto resultante se determina como sigue:
+$$\{t:\exists k\in{\cal Z}(t=t_0+k\delta t,\ t_1\leq t\leq t_0)\}.$$
+
+\subsection{Expresiones de indización}
+
+Si la expresión de conjunto primaria es una expresión indizante, el conjunto resultante se determina como se ha descripto anteriormente en la Sección \ref{indexing}, página \pageref{indexing}.
+
+\subsection{Expresiones iteradas}
+
+Una {\it expresión de conjunto iterada} es una expresión de conjunto primaria que tiene la siguiente forma sintáctica:
+$$\mbox{{\tt setof} {\it expresión-indizante} {\it integrando}}$$
+donde {\it expresión-indizante} es una expresión indizante que introduce índices y controla la iteración e {\it integrando} es tanto una expresión numérica o simbólica individual como una lista de expresiones numéricas o simbólicas separadas por coma y encerradas entre paréntesis.
+
+Si el integrando es una expresión numérica o simbólica individual, el conjunto resultante está compuesto por 1-tuplos y se determina como sigue:
+$$\{x:(i_1,\dots,i_n)\in\Delta\},$$
+\noindent donde $x$ es un valor del integrando, $i_1$, \dots, $i_n$ son índices introducidos en la expresión indizante y $\Delta$ es el dominio, un conjunto de $n$-tuplos especificados por la expresión indizante que define los valores particulares asignados a los índices para realizar la operación iterada.
+
+Si el integrando es una lista conteniendo $m$ expresiones numéricas y simbólicas, el conjunto resultante está compuesto por $m$-tuplos y se determina como sigue:
+$$\{(x_1,\dots,x_m):(i_1,\dots,i_n)\in\Delta\},$$
+donde $x_1$, \dots, $x_m$ son valores de las expresiones en la lista de integrandos e $i_1$, \dots, $i_n$ y $\Delta$ tienen el mismo significado anterior.
+
+\subsection{Expresiones condicionales}
+
+Una {\it expresión de conjunto condicional} es una expresión de conjunto primaria que tiene la siguiente forma sintáctica:
+$$\mbox{{\tt if} $b$ {\tt then} $X$ {\tt else} $Y$}$$
+donde $b$ es una expresión lógica y $X$ e $Y$ son expresiones de conjunto que deben definir conjuntos de igual dimensión.
+
+El valor resultante de la expresión condicional depende del valor de la expresión lógica que sigue a la palabra clave {\tt if}. Si toma el valor {\it verdadero}, el conjunto resultante es el valor de la expresión que sigue a la palabra clave {\tt then}. De otro modo, si la expresión lógica toma el valor {\it falso}, el conjunto resultante es el valor de la expresión que sigue a la palabra clave {\tt else}.
+
+\subsection{Expresiones parentéticas}
+
+Cualquier expresión de conjunto puede encerrarse entre paréntesis, lo que la convierte sintácticamente en una expresión de conjunto primaria.
+
+Los paréntesis pueden usarse en expresiones de conjunto, como en el álgebra, para especificar el orden deseado en el cual se ejecutarán las operaciones. Cuando se usan paréntesis, la expresión entre paréntesis se evalúa antes que el valor resultante sea usado.
+
+El valor resultante de la expresión parentética es idéntico al valor de la expresión encerrada entre paréntesis.
+
+\subsection{Operadores de conjunto}
+
+En MathProg existen los siguientes operadores de conjunto, los que se pueden usar en expresiones de conjunto:
+
+\begin{tabular}{@{}ll@{}}
+$X$ {\tt union} $Y$&union $X\cup Y$\\
+$X$ {\tt diff} $Y$&diferencia $X\backslash Y$\\
+$X$ {\tt symdiff} $Y$&diferencia simétrica $X\oplus Y=(X\backslash Y)\cup(Y\backslash X)$\\
+$X$ {\tt inter} $Y$&intersección $X\cap Y$\\
+$X$ {\tt cross} $Y$&producto cartesiano (``cruzado'') $X\times Y$\\
+\end{tabular}
+
+\noindent donde $X$ e $Y$ son expresiones de conjunto que deben definir conjuntos de la misma dimensión (excepto para el producto cartesiano).
+
+Si la expresión incluye más de un operador de conjunto, todos los operadores se ejecutan de izquierda a derecha, de acuerdo con la jerarquía de las operaciones (ver más adelante).
+
+El valor resultante de la expresión que contiene operadores de conjunto es el resultado de aplicar los operadores a sus operandos.
+
+La dimensión del conjunto resultante, {\it i.e.} la dimensión de los $n$-tuplos de los que consiste el conjunto resultante, es la dimensión de los operandos, excepto en el producto cartesiano, en la que la dimensión del conjunto resultante es la suma de las dimensiones de sus operandos.
+
+\subsection{Jerarquía de las operaciones}
+
+La siguiente lista muestra la jerarquía de las operaciones en expresiones de conjunto:
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Operación&Jerarquía\\
+\hline
+Evaluación de operaciones numéricas&
+1.{\textsuperscript{\b{a}}}-7.{\textsuperscript{\b{a}}}\\
+Evaluación de operaciones simbólicas&
+8.{\textsuperscript{\b{a}}}-9.{\textsuperscript{\b{a}}}\\
+Evaluación de conjuntos iterados o ``aritméticos'' ({\tt setof}, {\tt..})&
+10.{\textsuperscript{\b{a}}}\\
+Producto cartesiano ({\tt cross})&
+11.{\textsuperscript{\b{a}}}\\
+Intersección ({\tt inter})&
+12.{\textsuperscript{\b{a}}}\\
+Unión y diferencia ({\tt union}, {\tt diff}, {\tt symdiff})&
+13.{\textsuperscript{\b{a}}}\\
+Evaluación condicional ({\tt if} \dots {\tt then} \dots {\tt else})&
+14.{\textsuperscript{\b{a}}}\\
+\end{tabular}
+
+Esta jerarquía tiene el mismo significado que se explicó anteriormente para expresiones numéricas (ver Subsección \ref{hierarchy}, página \pageref{hierarchy}).
+
+\section{Expresiones lógicas}
+
+Una {\it expresión lógica} es una regla para calcular un valor lógico individual, el que puede ser tanto {\it verdadero} como {\it falso}.
+
+La expresión lógica primaria puede ser una expresión numérica, una expresión relacional, una expresión lógica iterada u otra expresión lógica encerrada entre paréntesis.
+
+\para{Ejemplos}
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|i+1| &(expresión numérica)\\
+\verb|a[i,j] < 1.5| &(expresión relacional)\\
+\verb|s[i+1,j-1] <> 'Mar' & anho | &(expresión relacional)\\
+\verb|(i+1,'Ene') not in I cross J| &(expresión relacional)\\
+\verb|S union T within A[i] inter B[j]| &(expresión relacional)\\
+\verb|forall{i in I, j in J} a[i,j] < .5 * b[i]| &(expresión lógica iterada)\\
+\verb|(a[i,j] < 1.5 or b[i] >= a[i,j])| &(expresión lógica parentética)\\
+\end{tabular}
+
+Empleando ciertos operadores lógicos se pueden construir expresiones lógicas más generales conteniendo dos o más expresiones lógicas primarias.
+
+\para{Ejemplos}
+
+\begin{verbatim}
+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{verbatim}
+
+\vspace*{-8pt}
+
+\subsection{Expresiones numéricas}
+
+El valor resultante de una expresión lógica primaria, cuando es una expresión numérica, es {\it verdadero} si el valor resultante de la expresión numérica es distinto de cero. De otro modo, el valor resultante de la expresión lógica es {\it falso}.
+
+\vspace*{-8pt}
+
+\subsection{Operadores relacionales}
+
+En MathProg existen los siguientes operadores relacionales, los que se pueden usar en expresiones lógicas:
+
+\begin{tabular}{@{}ll@{}}
+$x$ {\tt<} $y$&comprueba si $x<y$\\
+$x$ {\tt<=} $y$&comprueba si $x\leq y$\\
+$x$ {\tt=} $y$, $x$ {\tt==} $y$&comprueba si $x=y$\\
+$x$ {\tt>=} $y$&comprueba si $x\geq y$\\
+$x$ {\tt>} $y$&comprueba si $x>y$\\
+$x$ {\tt<>} $y$, $x$ {\tt!=} $y$&comprueba si $x\neq y$\\
+$x$ {\tt in} $Y$&comprueba si $x\in Y$\\
+{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt in} $Y$&comprueba si
+$(x_1,\dots,x_n)\in Y$\\
+$x$ {\tt not} {\tt in} $Y$, $x$ {\tt!in} $Y$&comprueba si $x\not\in Y$\\
+{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt not} {\tt in} $Y$,
+{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt !in} $Y$&comprueba si
+$(x_1,\dots,x_n)\not\in Y$\\
+$X$ {\tt within} $Y$&comprueba si $X\subseteq Y$\\
+$X$ {\tt not} {\tt within} $Y$, $X$ {\tt !within} $Y$&comprueba si
+$X\not\subseteq Y$\\
+\end{tabular}
+
+\noindent donde $x$, $x_1$, \dots, $x_n$ e $y$ son expresiones numéricas o simbólicas, mientras que $X$ e $Y$ son expresiones de conjunto.
+
+Notas:
+
+1. En las operaciones {\tt in}, {\tt not in} y {\tt !in} el número de componentes del primer operando debe ser igual a la dimensión del segundo operando.
+
+2. En las operaciones {\tt within}, {\tt not within} y {\tt !within} ambos operandos deben tener la misma dimensión.
+
+Todos los operadores relacionales listados anteriormente tienen su significado matemático convencional. El valor resultante es {\it verdadero} si los operandos satisfacen la correspondiente relación, o es {\it falso} en caso contrario. (Debe notarse que los valores simbólicos se ordenan lexicográficamente y que cualquier valor numérico precede a cualquier valor simbólico.)
+
+\subsection{Expresiones iteradas}
+
+Una {\it expresión lógica iterada} es una expresión lógica primaria que tiene la siguiente forma sintáctica:
+$$\mbox{{\it operador-iterado} {\it expresión-indizante}
+{\it integrando}}$$
+donde {\it operador-iterado} es el nombre simbólico del operador iterado que se ejecutará (ver más adelante), {\it expresión-indizante} es una expresión indizante que introduce índices y controla la iteración e {\it integrando} es una expresión lógica que participa en la operación.
+
+En MathProg existen dos operadores iterados que se pueden usar en expresiones lógicas:
+
+{\def\arraystretch{1.4}
+\noindent\hfil
+\begin{tabular}{@{}lll@{}}
+{\tt forall}&cuantificador-$\forall$&$\displaystyle
+\forall(i_1,\dots,i_n)\in\Delta[f(i_1,\dots,i_n)],$\\
+{\tt exists}&cuantificador-$\exists$&$\displaystyle
+\exists(i_1,\dots,i_n)\in\Delta[f(i_1,\dots,i_n)],$\\
+\end{tabular}
+}
+
+\noindent donde $i_1$, \dots, $i_n$ son índices introducidos en la expresión indizante, $\Delta$ es el dominio, un conjunto de $n$-tuplos especificados por la expresión indizante que define los valores particulares asignados a los índices para ejecutar la operación iterada y $f(i_1,\dots,i_n)$ es el integrando, una expresión lógica cuyo valor resultante depende de los índices.
+
+Para el cuantificador-$\forall$, el valor resultante de la expresión lógica iterada es {\it verdadero} si el valor del integrando es {\it verdadero} para todos los $n$-tuplos contenidos en el dominio, de otro modo es {\it falso}.
+
+Para el cuantificador-$\exists$, el valor resultante de la expresión lógica iterada es {\it falso} si el valor del integrando es {\it falso} para todos los $n$-tuplos contenidos en el dominio, de otro modo es {\it verdadero}.
+
+\subsection{Expresiones parentéticas}
+
+Cualquier expresión lógica puede encerrarse entre paréntesis, lo que la convierte sintácticamente en una expresión lógica primaria.
+
+Los paréntesis pueden usarse en expresiones lógicas, como en el álgebra, para especificar el orden deseado en el cual se ejecutarán las operaciones. Cuando se usan paréntesis, la expresión entre paréntesis se evalúa antes que el valor resultante sea usado.
+
+El valor resultante de la expresión parentética es idéntico al valor de la expresión encerrada entre paréntesis.
+
+\subsection{Operadores lógicos}
+
+En MathProg existen los siguientes operadores lógicos, los que se pueden usar en expresiones lógicas:
+
+\begin{tabular}{@{}ll@{}}
+{\tt not} $x$, {\tt!}$x$&negación $\neg\ x$\\
+$x$ {\tt and} $y$, $x$ {\tt\&\&} $y$&conjunción (``y'' lógico)
+$x\;\&\;y$\\
+$x$ {\tt or} $y$, $x$ {\tt||} $y$&disyunción (``o'' lógico)
+$x\vee y$\\
+\end{tabular}
+
+\noindent donde $x$ e $y$ son expresiones lógicas.
+
+Si la expresión incluye más de un operador lógico, todos los operadores se ejecutan de izquierda a derecha, de acuerdo con la jerarquía de las operaciones (ver más adelante). El valor resultante de la expresión que contiene operadores lógicos es el resultado de aplicar los operadores a sus operandos.
+
+\subsection{Jerarquía de las operaciones}
+
+La siguiente lista muestra la jerarquía de las operaciones en expresiones lógicas:
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Operación&Jerarquía\\
+\hline
+Evaluación de operaciones numéricas&
+1.{\textsuperscript{\b{a}}}-7.{\textsuperscript{\b{a}}}\\
+Evaluación de operaciones simbólicas&
+8.{\textsuperscript{\b{a}}}-9.{\textsuperscript{\b{a}}}\\
+Evaluación de operaciones de conjuntos&
+10.{\textsuperscript{\b{a}}}-14.{\textsuperscript{\b{a}}}\\
+Operaciones relacionales ({\tt<}, {\tt<=}, etc.)&
+15.{\textsuperscript{\b{a}}}\\
+Negación ({\tt not}, {\tt!})&
+16.{\textsuperscript{\b{a}}}\\
+Conjunción ({\tt and}, {\tt\&\&})&
+17.{\textsuperscript{\b{a}}}\\
+Cuantificación-$\forall$ y -$\exists$ ({\tt forall}, {\tt exists})&
+18.{\textsuperscript{\b{a}}}\\
+Disyunción ({\tt or}, {\tt||})&
+19.{\textsuperscript{\b{a}}}\\
+\end{tabular}
+
+Esta jerarquía tiene el mismo significado que se explicó anteriormente para expresiones numéricas (ver Subsección \ref{hierarchy}, página \pageref{hierarchy}).
+
+\section{Expresiones lineales}
+
+Una {\it expresión lineal} es una regla para calcular la denominada {\it forma lineal}, que es una función lineal (o afín) de variables elementales.
+
+La expresión lineal primaria puede ser una variable no-indizada, una variable indizada, una expresión lineal iterada, una expresión lineal condicional u otra expresión lineal encerrada entre paréntesis.
+
+También está permitido usar una expresión numérica como una expresión lineal primaria, en cuyo caso el valor resultante de la expresión numérica se convierte automáticamente a una forma lineal que incluye el término constante solamente.
+
+\para{Ejemplos}
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|z| &(variable no-indizada)\\
+\verb|x[i,j]| &(variable indizada)\\
+\verb|sum{j in J} (a[i,j] * x[i,j] + 3 * y[i-1])| &
+(expresión lineal iterada)\\
+\verb|if i in I then x[i,j] else 1.5 * z + 3.25| &
+(expresión lineal condicional)\\
+\verb|(a[i,j] * x[i,j] + y[i-1] + .1)| &
+(expresión lineal parentética)\\
+\end{tabular}
+
+Empleando ciertos operadores aritméticos se pueden construir expresiones lineales más generales conteniendo dos o más expresiones lineales primarias.
+
+\para{Ejemplos}
+
+\begin{verbatim}
+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{verbatim}
+
+\vspace*{-5pt}
+
+\subsection{Variables no-indizadas}
+
+Si la expresión lineal primaria es una variable no-indizada (que debe ser 0-dimensional), la forma lineal resultante es aquella variable no-indizada.
+
+\vspace*{-5pt}
+
+\subsection{Variables indizadas}
+
+La expresión lineal primaria que se refiere a una variable indizada tiene la siguiente forma sintáctica:
+$$\mbox{{\it nombre}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,}
+$i_n${\tt]}}$$
+donde {\it nombre} es el nombre simbólico de la variable del modelo e $i_1$,
+$i_2$, \dots, $i_n$ son subíndices.
+
+Cada subíndice debe ser una expresión numérica o simbólica. El número de subíndices en la lista de subíndices debe ser igual a la dimensión de la variable del modelo con la cual está asociada la lista de subíndices.
+
+Los valores corrientes de las expresiones de los subíndices se usan para identificar un miembro particular de la variable del modelo que determina la forma lineal resultante, la cual es una variable elemental asociada con el miembro correspondiente.
+
+\vspace*{-5pt}
+
+\subsection{Expresiones iteradas}
+
+Una {\it expresión lineal iterada} es una expresión lineal primaria que tiene la siguiente forma sintáctica:
+$$\mbox{{\tt sum} {\it expresión-indizante} {\it integrando}}$$
+donde {\it expresión-indizante} es una expresión indizante que introduce índices y controla la iteración e {\it integrando} es una expresión lineal que participa en la operación.
+
+La expresión lineal iterada se evalúa exactamente de la misma manera que la expresión numérica iterada (ver Subsección \ref{itexpr}, página
+\pageref{itexpr}), excepto que el integrando participante en la sumatoria es una forma lineal y no un valor numérico.
+
+\vspace*{-5pt}
+
+\subsection{Expresiones condicionales}
+
+Una {\it expresión lineal condicional} es una expresión lineal primaria que tiene alguna de las dos formas sintácticas siguientes:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{{\tt if} $b$ {\tt then} $f$ {\tt else} $g$}\\
+\mbox{{\tt if} $b$ {\tt then} $f$}\\
+\end{array}
+}
+$$
+donde $b$ es una expresión lógica, mientras que $f$ y $g$ son expresiones lineales.
+
+La expresión lineal condicional se evalúa exactamente de la misma manera que la expresión numérica condicional (ver Subsección \ref{ifthen}, página \pageref{ifthen}), excepto que los operandos participantes en la operación son formas lineales y no valores numéricos.
+
+\subsection{Expresiones parentéticas}
+
+Cualquier expresión lineal puede encerrarse entre paréntesis, lo que la convierte sintácticamente en una expresión lineal primaria.
+
+Los paréntesis pueden usarse en expresiones lineales, como en el álgebra, para especificar el orden deseado en el cual se ejecutarán las operaciones. Cuando se usan paréntesis, la expresión entre paréntesis se evalúa antes que el valor resultante sea usado.
+
+El valor resultante de la expresión parentética es idéntico al valor de la expresión encerrada entre paréntesis.
+
+\subsection{Operadores aritméticos}
+
+En MathProg existen los siguientes operadores aritméticos, los que se pueden usar en expresiones lineales:
+
+\begin{tabular}{@{}ll@{}}
+{\tt+} $f$&más unario\\
+{\tt-} $f$&menos unario\\
+$f$ {\tt+} $g$&adición\\
+$f$ {\tt-} $g$&sustracción\\
+$x$ {\tt*} $f$, $f$ {\tt*} $x$&multiplicación\\
+$f$ {\tt/} $x$&división
+\end{tabular}
+
+\noindent donde $f$ y $g$ son expresiones lineales, mientras que $x$ es una expresión numérica (más precisamente, una expresión lineal conteniendo únicamente el término constante).
+
+Si la expresión incluye más de un operador aritmético, todos los operadores se ejecutan de izquierda a derecha, de acuerdo con la jerarquía de las operaciones (ver más adelante). El valor resultante de la expresión que contiene operadores aritméticos es el resultado de aplicar los operadores a sus operandos.
+
+\subsection{Jerarquía de las operaciones}
+
+La jerarquía de las operaciones aritméticas usadas en las expresiones lineales es la misma que en las expresiones numéricas (ver Subsección \ref{hierarchy},
+página \pageref{hierarchy}).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Sentencias}
+
+Las {\it sentencias} son unidades básicas de la descripción del modelo. En MathProg todas las sentencias se clasifican en dos categorías: sentencias declarativas y sentencias funcionales.
+
+Las {\it sentencias declarativas} (sentencia {\it set}, sentencia {\it parameter}, sentencia {\it variable}, sentencia {\it constraint} y sentencia {\it objective}) se usan para declarar objetos de cierto tipo del modelo y definir ciertas propiedades de tales objetos.
+
+Las {\it sentencias funcionales} (sentencia {\it solve}, sentencia {\it check}, sentencia {\it display}, sentencia {\it printf}, sentencia {\it loop} y sentencia {\it table}) están ideadas para ejecutar ciertas acciones específicas.
+
+Debe notarse que las sentencias declarativas pueden seguir cualquier orden arbitrario, lo cual no afecta el resultado de la traducción. Sin embargo, todos los objetos del modelo deben ser declarados antes de ser referenciados en otras sentencias.
+
+\section{Sentencia set}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt set} {\it nombre} {\it alias} {\it dominio} {\tt,}
+{\it atributo} {\tt,} \dots {\tt,} {\it atributo} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it nombre} es el nombre simbólico del conjunto;
+
+\noindent
+{\it alias} es un literal de cadena opcional que especifica un alias para el conjunto;
+
+\noindent
+{\it dominio} es una expresión-indizante opcional que especifica el dominio del subíndice del conjunto;
+
+\noindent
+{\it atributo}, \dots, {\it atributo} son atributos opcionales del conjunto (las comas que preceden a los atributos se pueden omitir).
+
+\para{Atributos opcionales}
+
+\vspace*{-8pt}
+
+\begin{description}
+\item[{\tt dimen} $n$]\hspace*{0pt}\\
+especifica la dimensión de los $n$-tuplos de los que consiste el conjunto;
+\item[{\tt within} {\it expresión}]\hspace*{0pt}\\
+especifica un superconjunto que restringe al conjunto o a todos sus miembros (conjuntos elementales) a estar incluido en aquel superconjunto;
+\item[{\tt:=} {\it expresión}]\hspace*{0pt}\\
+especifica un conjunto elemental asignado al conjunto o sus miembros;
+\item[{\tt default} {\it expresión}]\hspace*{0pt}\\
+especifica un conjunto elemental asignado al conjunto o sus miembros cuando no haya datos apropiados disponibles en la sección de datos.
+\end{description}
+
+\vspace*{-8pt}
+
+\para{Ejemplos}
+
+\begin{verbatim}
+set nodos;
+set arcos within nodos cross nodos;
+set paso{p in 1..maxiter} dimen 2 := if p = 1 then arcos else paso[p-1]
+ union setof{k in nodos, (i,k) in paso[p-1], (k,j) in paso[p-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{verbatim}
+
+La sentencia set declara un conjunto. Si no se especifica el dominio del subíndice, el conjunto será simple, de otro modo será un arreglo de conjuntos elementales.
+
+El atributo {\tt dimen} especifica la dimensión de los $n$-tuplos de los que consiste el conjunto (si es un conjunto simple) o sus miembros (si el conjunto es un arreglo de conjuntos elementales), en la que $n$ debe ser un entero sin signo desde 1 hasta 20. Como mucho se puede especificar un atributo {\tt dimen}. Si no se especifica el atributo {\tt dimen}, la dimensión de los $n$-tuplos se determina implícitamente por otros atributos (por ejemplo, si hay una expresión de conjunto que sigue a {\tt :=} o a la palabra clave {\tt default}, se usará la dimensión de los $n$-tuplos del correspondiente conjunto elemental). Si no hay información disponible sobre la dimensión, se asume {\tt dimen 1}.
+
+El atributo {\tt within} especifica una expresión de conjunto cuyo valor resultante es un superconjunto usado para restringir al conjunto (si es un conjunto simple) o a sus miembros (si el conjunto es un arreglo de conjuntos elementales) a estar incluido en aquel superconjunto. Se puede especificar un número arbitrario de atributos {\tt within} en la misma sentencia set.
+
+El atributo de asignación ({\tt :=}) especifica una expresión de conjunto usada para evaluar conjuntos elementales asignados al conjunto (si es un conjunto simple) o sus miembros (si el conjunto es un arreglo de conjuntos elementales). Si se especifica el atributo de asignación, el conjunto es {\it calculable} y consecuentemente no es necesario proveerle datos en la sección de datos. Si no se especifica el atributo de asignación, entonces se deben proveer datos para el conjunto en la sección de datos. Como mucho, se puede especificar una asignación o un atributo {\tt default} para el mismo conjunto.
+
+El atributo {\tt default} especifica una expresión de conjunto usada para evaluar conjuntos elementales asignados al conjunto (si es un conjunto simple) o sus miembros (si el conjunto es un arreglo de conjuntos elementales) toda vez que no haya datos apropiados disponibles en la sección de datos. Si no se especifica una asignación o un atributo {\tt default}, la carencia de datos causará un error.
+
+\newpage
+
+\section{Sentencia parameter}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt param} {\it nombre} {\it alias} {\it dominio} {\tt,}
+{\it atributo} {\tt,} \dots {\tt,} {\it atributo} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it nombre} es el nombre simbólico del parámetro;
+
+\noindent
+{\it alias} es un literal de cadena opcional que especifica un alias para el parámetro;
+
+\noindent
+{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice del parámetro;
+
+\noindent
+{\it atributo}, \dots, {\it atributo} son atributos opcionales del parámetro (las comas que preceden a los atributos se pueden omitir).
+
+\para{Atributos opcionales}
+
+\vspace*{-8pt}
+
+\begin{description}
+\item[{\tt integer}]\hspace*{0pt}\\
+especifica que el parámetro es entero;
+\item[{\tt binary}]\hspace*{0pt}\\
+especifica que el parámetro es binario;
+\item[{\tt symbolic}]\hspace*{0pt}\\
+especifica que el parámetro es simbólico;
+\item[{\it relación expresión}]\hspace*{0pt}\\
+(donde {\it relación} es alguno de: {\tt<}, {\tt<=}, {\tt=}, {\tt==},
+{\tt>=}, {\tt>}, {\tt<>}, {\tt!=})\\
+especifica una condición que restringe al parámetro o a sus miembros a satisfacer aquella condición;
+\item[{\tt in} {\it expresión}]\hspace*{0pt}\\
+especifica un superconjunto que restringe al parámetro o a sus miembros a estar incluidos en aquel superconjunto;
+\item[{\tt:=} {\it expresión}]\hspace*{0pt}\\
+especifica un valor asignado al parámetro o a sus miembros;
+\item[{\tt default} {\it expresión}]\hspace*{0pt}\\
+especifica un valor asignado al parámetro o a sus miembros cuando no haya datos apropiados disponibles en la sección de datos.
+\end{description}
+
+\vspace*{-8pt}
+
+\para{Ejemplos}
+
+\begin{verbatim}
+param unidades{insumo,producto} >= 0;
+param ganancia{producto, 1..T+1};
+param N := 20 integer >= 0 <= 100;
+param combinacion 'n elige k' {n in 0..N, k in 0..n} :=
+ if k = 0 or k = n then 1 else combinacion[n-1,k-1] + combinacion[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 mes symbolic default 'May' in {'Mar', 'Abr', 'May'};
+\end{verbatim}
+
+La sentencia parameter declara un parámetro. Si el dominio del subíndice no se especifica, el parámetro es un parámetro simple (escalar); de otro modo es un arreglo $n$-dimensional.
+
+Los atributos de tipo {\tt integer}, {\tt binary} y {\tt symbolic} califican el tipo de valores que se le puede asignar al parámetro como se muestra a continuación:
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Atributo de tipo&Valores asignado\\
+\hline
+(no especificado)&Cualquier valor numérico\\
+{\tt integer}&Solamente valores numéricos enteros\\
+{\tt binary}&Tanto 0 como 1\\
+{\tt symbolic}&Cualquier valor numérico y simbólico\\
+\end{tabular}
+
+El atributo {\tt symbolic} no se puede especificar junto con otros atributos de tipo. Cuando se especifica debe preceder a todos los demás atributos.
+
+El atributo de condición especifica una condición opcional que restringe los valores asignados al parámetro a satisfacer esta condición. Este atributo tiene las siguientes formas sintácticas:
+
+\begin{tabular}{@{}ll@{}}
+{\tt<} $v$&comprueba si $x<v$\\
+{\tt<=} $v$&comprueba si $x\leq v$\\
+{\tt=} $v$, {\tt==} $v$&comprueba si $x=v$\\
+{\tt>=} $v$&comprueba si $x\geq v$\\
+{\tt>} $v$&comprueba si $x\geq v$\\
+{\tt<>} $v$, {\tt!=} $v$&comprueba si $x\neq v$\\
+\end{tabular}
+
+\noindent donde $x$ es un valor asignado al parámetro y $v$ es el valor resultante de una expresión numérica o simbólica especificada en el atributo de condición. Se puede especificar un número arbitrario de atributos de condición para el mismo parámetro. Si el valor que se está asignando al parámetro durante la evaluación del modelo viola al menos una de las condiciones especificadas, se producirá un error. (Debe notarse que los valores simbólicos se ordenan lexicográficamente y que cualquier valor numérico precede a cualquier valor simbólico.)
+
+El atributo {\tt in} es semejante al atributo de condición y especifica una expresión de conjunto cuyo valor resultante es un superconjunto usado para restringir los valores numéricos o simbólicos asignados al parámetro a estar incluidos en aquel superconjunto. Se puede especificar un número arbitrario de atributos {\tt in} para el mismo parámetro. Si el valor que se está asignando al parámetro durante la evaluación del modelo no pertenece al menos a uno de los superconjuntos especificados, se producirá un error.
+
+El atributo de asignación ({\tt:=}) especifica una expresión numérica o simbólica usada para calcular un valor asignado al parámetro (si es un parámetro simple) o a sus miembros (si el parámetro es un arreglo). Si se especifica el atributo de asignación, el parámetro es {\it calculable} y consecuentemente no es necesario proveer datos en la sección de datos. Si no se especifica el atributo de asignación, entonces se deben proveer datos para el parámetro en la sección de datos. Como mucho, se puede especificar una asignación o un atributo {\tt default} para el mismo conjunto.
+
+El atributo {\tt default} especifica una expresión numérica o simbólica que se usa para calcular un valor asignado al parámetro o a sus miembros, toda vez que no haya datos apropiados disponibles en la sección de datos. Si no se especifica una asignación ni un atributo {\tt default}, la carencia de datos causará un error.
+
+\section{Sentencia variable}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt var} {\it nombre} {\it alias} {\it dominio} {\tt,}
+{\it atributo} {\tt,} \dots {\tt,} {\it atributo} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it nombre} es el nombre simbólico de la variable;
+
+\noindent
+{\it alias} es un literal de cadena opcional que especifica un alias para la variable;
+
+\noindent
+{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la variable;
+
+\noindent
+{\it atributo}, \dots, {\it atributo} son atributos opcionales de la variable (las comas que preceden a los atributos se pueden omitir).
+
+\para{Atributos opcionales}
+
+\vspace*{-8pt}
+
+\begin{description}
+\item[{\tt integer}]\hspace*{0pt}\\
+restringe la variable a ser entera;
+\item[{\tt binary}]\hspace*{0pt}\\
+restringe la variable a ser binaria;
+\item[{\tt>=} {\it expresión}]\hspace*{0pt}\\
+especifica una cota inferior para la variable;
+\item[{\tt<=} {\it expresión}]\hspace*{0pt}\\
+especifica una cota superior para la variable;
+\item[{\tt=} {\it expresión}]\hspace*{0pt}\\
+especifica un valor fijo para la variable.
+\end{description}
+
+\vspace*{-8pt}
+
+\para{Ejemplos}
+
+\begin{verbatim}
+var x >= 0;
+var y{I,J};
+var elaborar{p in producto}, integer, >= compromiso[p], <= mercado[p];
+var almacenar{insumo, 1..T+1} >= 0;
+var z{i in I, j in J} >= i+j;
+\end{verbatim}
+
+La sentencia variable declara una variable. Si no se especifica el dominio del subíndice, la variable es una variable simple (escalar); de otro modo es un arreglo $n$-dimensional de variables elementales.
+
+Las variables elementales asociadas con una variable del modelo (si es una variable simple) o sus miembros (si es un arreglo) corresponde a las variables en la formulación del problema de PL/PEM (ver Sección \ref{problem}, página \pageref{problem}). Debe notarse que sólo variables elementales realmente referenciadas en algunas restricciones y/u objetivos se incluirán en la instancia del problema de PL/PEM que se generará.
+
+Los atributos de tipo {\tt integer} y {\tt binary} restringen la variable a ser entera o binaria, respectivamente. Si no se especifica un atributo de tipo, la variable será continua. Si todas las variables en el modelo son continuas, el problema correspondiente será de la clase PL. Si hay al menos una variable entera o binaria, el problema será de la clase PEM.
+
+El atributo de cota inferior ({\tt>=}) especifica una expresión numérica para calcular la cota inferior de la variable. Se puede especificar una cota inferior como máximo. Por defecto, todas las variables no tienen cota inferior (excepto las binarias), de modo que si se requiere que sea no-negativa, su cota inferior cero debe especificarse explícitamente.
+
+El atributo de cota superior ({\tt<=}) especifica una expresión numérica para calcular la cota superior de la variable. Se puede especificar una cota superior como máximo.
+
+El atributo de valor fijo ({\tt=}) especifica una expresión numérica para calcular el valor en el cual se fijará la variable. Este atributo no puede especificarse junto con los atributos de cota.
+
+\section{Sentencia constraint}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][106pt]{468pt}{
+\hspace{6pt} {\tt s.t.} {\it nombre} {\it alias} {\it dominio} {\tt:}
+{\it expresión} {\tt,} {\tt=} {\it expresión} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt s.t.} {\it nombre} {\it alias} {\it dominio} {\tt:}
+{\it expresión} {\tt,} {\tt<=} {\it expresión} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt s.t.} {\it nombre} {\it alias} {\it dominio} {\tt:}
+{\it expresión} {\tt,} {\tt>=} {\it expresión} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt s.t.} {\it nombre} {\it alias} {\it dominio} {\tt:}
+{\it expresión} {\tt,} {\tt<=} {\it expresión} {\tt,} {\tt<=}
+{\it expresión} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt s.t.} {\it nombre} {\it alias} {\it dominio} {\tt:}
+{\it expresión} {\tt,} {\tt>=} {\it expresión} {\tt,} {\tt>=}
+{\it expresión} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it nombre} es el nombre simbólico de la restricción;
+
+\noindent
+{\it alias} es un literal de cadena opcional que especifica un alias para la restricción;
+
+\noindent
+{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la restricción;
+
+\noindent
+{\it expresión} es una expresión lineal usada para calcular un componente de la restricción (las comas que siguen a las expresiones pueden omitirse).
+
+\noindent
+(La palabra clave {\tt s.t.} se puede escribir como {\tt subject to}, o como {\tt subj to} o ser completamente omitida.)
+
+\para{Ejemplos}
+
+\begin{verbatim}
+s.t. r: x + y + z, >= 0, <= 1;
+limite{t in 1..T}: sum{j in producto} elaborar[j,t] <= max_producto;
+subject to balance{i in insumo, t in 1..T}:
+ almacenar[i,t+1] = almacenar[i,t] -
+ sum{j in producto} unidades[i,j] * elaborar[j,t];
+subject to ltn 'limite tiempo normal' {t in tiempo}:
+ sum{p in producto} pt[p] * rprd[p,t] <= 1.3 * dpp[t] * brigadas[t];
+\end{verbatim}
+
+La sentencia constraint declara una restricción. Si no se especifica el dominio del subíndice, la restricción es una restricción simple (escalar); de otro modo, es un arreglo $n$-dimensional de restricciones elementales.
+
+Las restricciones elementales asociadas con la restricción del modelo (si es una restricción simple) o sus miembros (si es un arreglo) corresponde a las restricciones lineales en la formulación del problema de PL/PEM (ver Sección \ref{problem}, página \pageref{problem}).
+
+Si la restricción tiene la forma de una igualdad o desigualdad simple, {\it i.e.} incluye dos expresiones, una de las cuales está a continuación de los dos puntos y la otra está a continuación del signo relacional {\tt=}, {\tt<=} o {\tt>=}, ambas expresiones de la sentencia pueden ser expresiones lineales. Si la restricción tiene la forma de una doble desigualdad, {\it i.e.} incluye tres expresiones, la expresión del medio puede ser una expresión lineal mientras que la de la izquierda y la de la derecha sólo pueden ser expresiones numéricas.
+
+Generar el modelo es, groseramente hablando, generar sus restricciones, las que son siempre evaluadas para todo el dominio del subíndice. A su vez, la evaluación de las restricciones lleva a la evaluación de otros objetos del modelo tales como los conjuntos, los parámetros y las variables.
+
+La construcción de una restricción lineal real incluida en la instancia del problema, la cual corresponde a una restricción elemental particular, se realiza como sigue.
+
+Si la restricción tiene la forma de una igualdad o desigualdad simple, la evaluación de ambas expresiones lineales resulta en dos formas lineales:
+$$\begin{array}{r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r}
+f&=&a_1x_1&+&a_2x_2&+\dots+&a_nx_n&+&a_0,\\
+g&=&b_1x_1&+&b_2x_2&+\dots+&b_nx_n&+&b_0,\\
+\end{array}$$
+donde $x_1$, $x_2$, \dots, $x_n$ son variables elementales; $a_1$, $a_2$,
+\dots, $a_n$, $b_1$, $b_2$, \dots, $b_n$ son coeficientes numéricos y
+$a_0$ y $b_0$ son términos constantes. Luego, todos los términos lineales de $f$ y $g$ se llevan al lado izquierdo y los términos constantes se llevan al lado derecho, para dar la restricción elemental final en forma estándar:
+$$(a_1-b_1)x_1+(a_2-b_2)x_2+\dots+(a_n-b_n)x_n\left\{
+\begin{array}{@{}c@{}}=\\\leq\\\geq\\\end{array}\right\}b_0-a_0.$$
+
+Si la restricción tiene la forma de una doble desigualdad, la evaluación de la expresión lineal del medio resulta en una forma lineal:
+$$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$
+y la evaluación de las expresiones numéricas de la izquierda y de la derecha dará dos valores numéricos $l$ y $u$, respectivamente. Luego, el término constante de la forma lineal se lleva tanto a la izquierda como a la derecha para dar la restricción elemental final en forma estándar:
+$$l-a_0\leq a_1x_1+a_2x_2+\dots+a_nx_n\leq u-a_0.$$
+
+\section{Sentencia objective}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][44pt]{468pt}{
+\hspace{6pt} {\tt minimize} {\it nombre} {\it alias} {\it dominio} {\tt:}
+{\it expresión} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt maximize} {\it nombre} {\it alias} {\it dominio} {\tt:}
+{\it expresión} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it nombre} es el nombre simbólico del objetivo;
+
+\noindent
+{\it alias} es un literal de cadena opcional que especifica un alias para el objetivo;
+
+\noindent
+{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice del objetivo;
+
+\noindent
+{\it expresión} es una expresión lineal usada para calcular la forma lineal del objetivo.
+
+\para{Ejemplos}
+
+\begin{verbatim}
+minimize objetivo: x + 1.5 * (y + z);
+maximize ganancia_total: sum{p in producto} ganancia[p] * elaborar[p];
+\end{verbatim}
+
+La sentencia objective declara un objetivo. Si no se especifica el dominio del subíndice, el objetivo es un objetivo simple (escalar); de otro modo, es un arreglo $n$-dimensional de objetivos elementales.
+
+Los objetivos elementales asociados con el objetivo del modelo (si es un objetivo simple) o sus miembros (si es un arreglo) corresponden a restricciones lineales generales en la formulación del problema de PL/PEM (ver Sección \ref{problem}, página \pageref{problem}). Sin embargo, a diferencia de las restricciones, las correspondientes formas lineales son libres (no tienen cota).
+
+La construcción de una restricción lineal real incluida en la instancia del problema, la cual corresponde a una restricción elemental particular, se realiza como sigue. La expresión lineal especificada en la sentencia objective se evalúa para resultar en una forma lineal:
+$$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$
+donde $x_1$, $x_2$, \dots, $x_n$ son variables elementales; $a_1$, $a_2$,
+\dots, $a_n$ son coeficientes numéricos y $a_0$ es el término constante. Luego se usa la forma lineal para construir la restricción elemental final en forma estándar:
+$$-\infty<a_1x_1+a_2x_2+\dots+a_nx_n+a_0<+\infty.$$
+
+Como norma, la descripción del modelo contiene solamente una sentencia objective para definir la función objetivo usada en la instancia del problema. Sin embargo, se permite declarar un número arbitrario de objetivos, en cuyo caso la función objetivo real es el primer objetivo que se encuentra en la descripción del modelo. Otros objetivos también se incluyen en la instancia del problema pero ellos no afectan la función objetivo.
+
+\section{Sentencia solve}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt solve} {\tt;}
+}}
+
+\medskip
+
+La sentencia solve es opcional y puede usarse solamente una vez. Si no se usa la sentencia solve, se asume una al final de la sección del modelo.
+
+La sentencia solve provoca que el modelo sea resuelto, lo que significa calcular los valores numéricos de todas las variables del modelo. Esto permite usar variables en sentencias luego de la sentencia solve, de la misma forma que si fuesen parámetros numéricos.
+
+Debe notarse que las sentencias variable, constraint y objective no pueden usarse luego de la sentencia solve, {\it i.e.} todos los componentes principales del modelo deben ser declarados antes de la sentencia solve.
+
+\section{Sentencia check}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt check} {\it dominio} {\tt:} {\it expresión} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la sentencia check;
+
+\noindent
+{\it expresión} es una expresión lógica que especifica una condición lógica para ser comprobada (los dos puntos que preceden a {\it expresión} pueden omitirse).
+
+\para{Ejemplos}
+
+\begin{verbatim}
+check: x + y <= 1 and x >= 0 and y >= 0;
+check sum{i in ORIGEN} oferta[i] = sum{j in DESTINO} demanda[j];
+check{i in I, j in 1..10}: S[i,j] in U[i] union V[j];
+\end{verbatim}
+
+El sentencia check permite comprobar el valor resultante de una expresión lógica especificada en la sentencia. Si el valor es {\it falso} se reporta un error.
+
+Si el dominio del subíndice no se especifica, la comprobación se ejecuta solamente una vez. Especificar el dominio del subíndice permite ejecutar múltiples comprobaciones para cada $n$-tuplo en el conjunto dominio. En este último caso, la expresión lógica puede incluir índices introducidos en la correspondiente expresión indizante.
+
+\section{Sentencia display}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt display} {\it dominio} {\tt:} {\it ítem} {\tt,}
+\dots {\tt,} {\it ítem} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la sentencia display;
+
+\noindent
+{\it ítem}, \dots, {\it ítem} son ítems que se mostrarán (los dos puntos que preceden al primer ítem pueden omitirse).
+
+\para{Ejemplos}
+
+\begin{verbatim}
+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{verbatim}
+
+La sentencia display evalúa todos los ítems especificados en la sentencia y escribe sus valores en la salida estándar (terminal) en formato de texto plano.
+
+Si el dominio del subíndice no se especifica, los ítems son evaluados y mostrados solamente una vez. Especificar el dominio del subíndice produce que los ítems sean evaluados y mostrados para cada $n$-tuplo en el conjunto dominio. En este último caso, los ítems pueden incluir índices introducidos en la correspondiente expresión indizante.
+
+Un ítem a ser mostrado puede ser un objeto del modelo (conjunto, parámetro, variable, restricción u objetivo) o una expresión.
+
+Si el ítem es un objeto calculable ({\it i.e.} un conjunto o parámetro provisto con el atributo de asignación), el mismo es evaluado a través de todo su dominio y luego se muestra su contenido ({\it i.e.} el contenido del arreglo de objetos). De otro modo, si el ítem no es un objeto calculable, solamente se muestra su contenido corriente ({\it i.e.} los miembros realmente generados durante la evaluación del modelo).
+
+Si el ítem es una expresión, la misma se evalúa y se muestra su valor resultante.
+
+\section{Sentencia printf}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][64pt]{468pt}{
+\hspace{6pt} {\tt printf} {\it dominio} {\tt:} {\it formato} {\tt,}
+{\it expresión} {\tt,} \dots {\tt,} {\it expresión} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt printf} {\it dominio} {\tt:} {\it formato} {\tt,}
+{\it expresión} {\tt,} \dots {\tt,} {\it expresión} {\tt>}
+{\it archivo} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt printf} {\it dominio} {\tt:} {\it formato} {\tt,}
+{\it expresión} {\tt,} \dots {\tt,} {\it expresión} {\tt>}{\tt>}
+{\it archivo} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la sentencia printf;
+
+\noindent
+{\it formato} es una expresión simbólica cuyo valor especifica una cadena de control de formato (los dos puntos que preceden a la expresión de formato pueden omitirse).
+
+\noindent
+{\it expresión}, \dots, {\it expresión} son cero o más expresiones cuyos valores deben ser formateados e impresos. Cada expresión debe ser de tipo numérico, simbólico o lógico.
+
+\noindent
+{\it archivo} es una expresión simbólica cuyo valor especifica el nombre de un archivo de texto al cual se redirigirá la salida. La señal {\tt>} significa la creación de un archivo nuevo y vacío, mientras que la señal {\tt>}{\tt>} significa anexar la salida a un archivo existente. Si no se especifica un nombre de archivo, la salida se escribe en la salida estándar (terminal).
+
+\para{Ejemplos}
+
+\begin{verbatim}
+printf 'Hola, mundo!\n';
+printf: "x = %.3f; y = %.3f; z = %.3f\n", x, y, z > "resultado.txt";
+printf{i in I, j in J}: "el flujo desde %s hacia %s es %d\n", i, j, x[i,j]
+ >> archivo_resultados & ".txt";
+printf{i in I} 'el flujo total de %s es %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{verbatim}
+
+La sentencia printf es semejante a la sentencia display; sin embargo, la misma permite formatear los datos que se escribirán.
+
+Si el dominio del subíndice no se especifica, la sentencia printf es ejecutada solamente una vez. Especificar el dominio del subíndice produce que la sentencia printf sea ejecutada para cada $n$-tuplo en el conjunto dominio. En este último caso, el formato y la expresión pueden incluir índices introducidos en la correspondiente expresión indizante.
+
+La cadena de control de formato es el valor de la expresión simbólica {\it formato} especificado en la sentencia printf. Se compone con cero o más directivas como sigue: caracteres ordinarios (no {\tt\%}), que son copiados sin modificación al flujo de salida, y especificaciones de conversión, cada una de las cuales provoca la evaluación de la expresión correspondiente especificada en la sentencia printf, su formateo y la escritura del valor resultante en el flujo de salida.
+
+Las especificaciones de conversión que se pueden usar en la cadena de control de formato son las siguientes: {\tt d}, {\tt i}, {\tt f}, {\tt F}, {\tt e}, {\tt E}, {\tt g}, {\tt G} y {\tt s}. Estas especificaciones tienen la misma semántica y sintaxis que en el lenguaje de programación C.
+
+\section{Sentencia for}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][44pt]{468pt}{
+\hspace{6pt} {\tt for} {\it dominio} {\tt:} {\it sentencia} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt for} {\it dominio} {\tt:} {\tt\{} {\it sentencia}
+\dots {\it sentencia} {\tt\}} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la sentencia for (los dos puntos a continuación de la expresión indizante pueden omitirse);
+
+\noindent
+{\it sentencia} es una sentencia que será ejecutada bajo el control de la sentencia for;
+
+\noindent
+{\it sentencia}, \dots, {\it sentencia} es una secuencia de sentencias (encerrada entre llaves) que serán ejecutadas bajo el control de la sentencia for.
+
+Solamente se pueden usar las siguientes sentencias dentro de la sentencia for: check, display, printf y otra sentencia for.
+
+\para{Ejemplos}
+
+\begin{verbatim}
+for {(i,j) in E: i != j}
+{ printf "el flujo desde %s hacia %s es %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{verbatim}
+
+La sentencia for provoca que la sentencia o secuencia de sentencias especificadas como parte de la sentencia for sea ejecutada para cada $n$-tuplo en el conjunto dominio. De modo que las sentencias dentro de la sentencia for pueden incluir índices introducidos en la correspondiente expresión indizante.
+
+\section{Sentencia table}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][80pt]{468pt}{
+\hspace{6pt} {\tt table} {\it nombre} {\it alias} {\tt IN} {\it controlador}
+{\it arg} \dots {\it arg} {\tt:}
+
+\hspace{6pt} {\tt\ \ \ \ \ } {\it conjunto} {\tt<-} {\tt[} {\it cmp} {\tt,}
+\dots {\tt,} {\it cmp} {\tt]} {\tt,} {\it par} {\tt\textasciitilde}
+{\it cmp} {\tt,} \dots {\tt,} {\it par} {\tt\textasciitilde} {\it cmp}
+{\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt table} {\it nombre} {\it alias} {\it dominio} {\tt OUT}
+{\it controlador} {\it arg} \dots {\it arg} {\tt:}
+
+\hspace{6pt} {\tt\ \ \ \ \ } {\it expr} {\tt\textasciitilde} {\it cmp}
+{\tt,} \dots {\tt,} {\it expr} {\tt\textasciitilde} {\it cmp} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it nombre} es el nombre simbólico de la tabla;
+
+\noindent
+{\it alias} es un literal de cadena opcional que especifica un alias para la tabla;
+
+\noindent
+{\it dominio} es una expresión indizante que especifica el dominio del subíndice de la tabla (de salida);
+
+\noindent
+{\tt IN} significa leer datos desde la tabla de entrada;
+
+\noindent
+{\tt OUT} significa escribir datos en la tabla de salida;
+
+\noindent
+{\it controlador} es una expresión simbólica que especifica el controlador usado para acceder a la tabla (para más detalles, ver Apéndice \ref{drivers}, página \pageref{drivers});
+
+\noindent
+{\it arg} es una expresión simbólica opcional que es un argumento pasado al controlador de la tabla. Esta expresión simbólica no debe incluir índices especificados en el dominio;
+
+\noindent
+{\it conjunto} es el nombre de un conjunto simple opcional llamado {\it conjunto de control}. Puede ser omitido junto con el delimitador {\tt<-};
+
+\noindent
+{\it cmp} es un nombre de campo. Entre corchetes se debe especificar al menos un campo. El nombre de campo a continuación de un nombre de parámetro o de una expresión es opcional y puede ser omitido junto con el delimitador~{\tt\textasciitilde}, en cuyo caso el nombre del objeto del modelo que corresponda se usará como el nombre de campo;
+
+\noindent
+{\it par} es el nombre simbólico de un parámetro del modelo;
+
+\noindent
+{\it expr} es una expresión numérica o simbólica.
+
+\para{Ejemplos}
+
+\begin{verbatim}
+table datos IN "CSV" "datos.csv": M <- [DESDE,HACIA], d~DISTANCIA,
+ c~COSTO;
+table resultado{(s,h) in M} OUT "CSV" "resultado.csv": s~DESDE, h~HACIA,
+ x[s,h]~FLUJO;
+\end{verbatim}
+
+La sentencia table permite leer datos desde una tabla y asignarlos a objetos del modelo tales como conjuntos y parámetros (no escalares), al igual que escribir datos del modelo en una tabla.
+
+\subsection{Estructura de tablas}
+
+Una {\it tabla de datos} es un conjunto (desordenado) de {\it registros}, en el que cada registro consiste del mismo número de {\it campos}, y cada campo está provisto de un nombre simbólico único denominado {\it nombre de campo}. Por ejemplo:
+
+\bigskip
+
+\begin{tabular}{@{\hspace*{51mm}}c@{\hspace*{9mm}}c@{\hspace*{10mm}}c
+@{\hspace*{7mm}}c}
+Primer&Segundo&&Último\\
+campo&campo&.\ \ .\ \ .&campo\\
+$\downarrow$&$\downarrow$&&$\downarrow$\\
+\end{tabular}
+
+\begin{tabular}{ll@{}}
+Encabezado de tabla&$\rightarrow$\\
+Primer registro&$\rightarrow$\\
+Segundo registro&$\rightarrow$\\
+\\
+\hfil .\ \ .\ \ .\\
+\\
+Último registro&$\rightarrow$\\
+\end{tabular}
+\begin{tabular}{|l|l|c|c|}
+\hline
+{\tt DESDE}&{\tt HACIA}&{\tt DISTANCIA}&{\tt COSTO}\\
+\hline
+{\tt Seattle} &{\tt New-York}&{\tt 2.5}&{\tt 0.12}\\
+{\tt Seattle} &{\tt Chicago} &{\tt 1.7}&{\tt 0.08}\\
+{\tt Seattle} &{\tt Topeka} &{\tt 1.8}&{\tt 0.09}\\
+{\tt San-Diego}&{\tt New-York}&{\tt 2.5}&{\tt 0.15}\\
+{\tt San-Diego}&{\tt Chicago} &{\tt 1.8}&{\tt 0.10}\\
+{\tt San-Diego}&{\tt Topeka} &{\tt 1.4}&{\tt 0.07}\\
+\hline
+\end{tabular}
+
+\subsection{Lectura de datos desde una tabla de entrada}
+
+La sentencia table de entrada produce la lectura de los datos desde la tabla especificada, registro por registro.
+
+Una vez que se ha leído el próximo registro, los valores numéricos o simbólicos de los campos cuyos nombres se han encerrado entre corchetes en la sentencia table se reúnen en un $n$-tuplo y, si se ha especificado el conjunto de control en la sentencia table, este $n$-tuplo es agregado al mismo. Además, un valor numérico o simbólico de cada campo asociado con un parámetro del modelo se asigna al miembro del parámetro identificado por subíndices, los cuales son componentes del $n$-tuplo que se acaba de leer.
+
+Por ejemplo, la siguiente sentencia table de entrada:
+
+\noindent\hfil
+\verb|table datos IN "...": M <- [DESDE,HACIA], d~DISTANCIA, c~COSTO;|
+
+\noindent
+produce la lectura de valores de cuatro campos llamados {\tt DESDE}, {\tt HACIA}, {\tt DISTANCIA} y {\tt COSTO} de cada registro de la tabla especificada. Los valores de los campos {\tt DESDE} y {\tt HACIA} proveen un par $(s,h)$ que se agrega al conjunto de control {\tt M}. El valor del campo {\tt DISTANCIA} se asigna al miembro del parámetro ${\tt d}[s,h]$ y el valor del campo {\tt COSTO} se asigna al miembro del parámetro ${\tt c}[s,h]$.
+
+Debe notarse que la tabla de entrada puede contener campos adicionales cuyos nombres no sean especificados en la sentencia table, en cuyo caso los valores de estos campos serán ignorados al leer la tabla.
+
+\subsection{Escritura de datos en una tabla de salida}
+
+La sentencia table de salida produce la escritura de datos en la tabla especificada. Debe notarse que algunos controladores (concretamente CSV y xBASE) destruyen la tabla de salida antes de escribir los datos, {\it i.e.} borran todos sus registros existentes.
+
+Cada $n$-tuplo en el conjunto dominio especificado genera un registro escrito en la tabla de salida. Los valores de los campos son valores numéricos o simbólicos de las correspondientes expresiones especificadas en la sentencia table. Estas expresiones se evalúan para cada $n$-tuplo en el conjunto dominio y, de este modo, puede incluir índices que se introdujeron en la correspondiente expresión indizante.
+
+Por ejemplo, la siguiente sentencia table de salida:
+
+\noindent\hfil
+\verb|table resultado{(s,h) in M} OUT "...": s~DESDE, h~HACIA, x[s,h]~FLUJO;|
+
+\noindent
+produce la escritura de registros en la tabla de salida, a razón de un registro por cada par $(s,h)$ en el conjunto {\tt M}, en el que cada registro consiste de tres campos llamados {\tt DESDE}, {\tt HACIA} y {\tt FLUJO}. Los valores escritos en los campos {\tt DESDE} y {\tt HACIA} son los valores corrientes de los índices {\tt s} y {\tt h}, y el valor escrito en el campo {\tt FLUJO} es un valor del miembro ${\tt x}[s,h]$ del correspondiente parámetro o variable indexada.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Datos del modelo}
+
+Los {\it datos del modelo} incluyen conjuntos elementales, los cuales son ``valores'' de los conjuntos del modelo, y valores simbólicos y numéricos de los parámetros del modelo.
+
+En MathProg hay dos maneras diferentes de proveer valores para los conjuntos y parámetros del modelo. Una manera es simplemente proveyendo los datos necesarios mediante el atributo de asignación. Sin embargo, en muchos casos es más práctico separar el modelo en sí mismo de los datos particulares necesarios para el modelo. Por esta última razón, en MathProg hay otra manera que consiste en separar la descripción del modelo en dos partes: la sección del modelo y la sección de los datos.
+
+La {\it sección del modelo} es la parte principal de la descripción del modelo que contiene las declaraciones de todos los objetos del modelo y es común a todos los problemas basados en tal modelo.
+
+La {\it sección de los datos} es una parte opcional de la descripción del modelo que contiene datos específicos para un problema particular.
+
+En MathProg las secciones del modelo y de los datos se pueden ubicar tanto en un único archivo de texto, como en dos archivos de texto separados.
+
+1. Si ambas secciones se ubican en un archivo, este debe componerse como sigue:
+
+\bigskip
+
+\noindent\hfil
+\framebox{\begin{tabular}{l}
+{\it sentencia}{\tt;}\\
+{\it sentencia}{\tt;}\\
+\hfil.\ \ .\ \ .\\
+{\it sentencia}{\tt;}\\
+{\tt data;}\\
+{\it bloque de datos}{\tt;}\\
+{\it bloque de datos}{\tt;}\\
+\hfil.\ \ .\ \ .\\
+{\it bloque de datos}{\tt;}\\
+{\tt end;}
+\end{tabular}}
+
+\newpage
+
+2. Si ambas secciones se ubican en dos archivos separados, los archivos se componen como sigue:
+
+\bigskip
+
+\noindent\hfil
+\begin{tabular}{@{}c@{}}
+\framebox{\begin{tabular}{l}
+{\it sentencia}{\tt;}\\
+{\it sentencia}{\tt;}\\
+\hfil.\ \ .\ \ .\\
+{\it sentencia}{\tt;}\\
+{\tt end;}\\
+\end{tabular}}\\
+\\\\Archivo del modelo\\
+\end{tabular}
+\hspace{32pt}
+\begin{tabular}{@{}c@{}}
+\framebox{\begin{tabular}{l}
+{\tt data;}\\
+{\it bloque de datos}{\tt;}\\
+{\it bloque de datos}{\tt;}\\
+\hfil.\ \ .\ \ .\\
+{\it bloque de datos}{\tt;}\\
+{\tt end;}\\
+\end{tabular}}\\
+\\Archivo de datos\\
+\end{tabular}
+
+\bigskip
+
+Nota: si la sección de datos se ubica en un archivo separado, la palabra clave {\tt data} es opcional y puede omitirse, al igual que el punto y coma que le sigue.
+
+\section{Codificación de la sección de los datos}
+
+La {\it sección de los datos} es una secuencia de bloques de datos en varios formatos que se discuten en las siguientes secciones. El orden que siguen los bloques de datos en la sección de los datos puede ser arbitrario, no necesariamente el mismo que se siguió en la sección del modelo para sus correspondientes objetos.
+
+Las reglas para codificar la sección de los datos comúnmente son las mismas reglas que para codificar la descripción del modelo (ver Sección \ref{coding}, página \pageref{coding}), {\it i.e.} los bloques de datos se componen con unidades léxicas básicas como nombres simbólicos, literales numéricos y de cadena, palabras clave, delimitadores y comentarios. Sin embargo, por conveniencia y para mejorar la legibilidad hay una desviación de la regla común: si un literal de cadena consiste únicamente de caracteres alfanuméricos (incluyendo el carácter de subrayado), los signos {\tt+} y {\tt-} y/o el punto decimal, el mismo puede codificarse sin comillas delimitadoras (simples o dobles).
+
+Todo el material numérico y simbólico provisto en la sección de los datos se codifica en la forma de números y símbolos, {\it i.e.} a diferencia de la sección del modelo, en la sección de los datos no se permiten expresiones. Sin embargo, los signos {\tt+} y {\tt-} pueden preceder a literales numéricos para permitir la codificación de cantidades numéricas con signo, en cuyo caso no debe haber caracteres de espacio en blanco entre el signo y el literal numérico que le sigue (si hay al menos un espacio en blanco, el signo y el literal numérico que le sigue serán reconocidos como dos unidades léxicas diferentes).
+
+\newpage
+
+\section{Bloque de datos de conjunto}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][44pt]{468pt}{
+\hspace{6pt} {\tt set} {\it nombre} {\tt,} {\it registro} {\tt,} \dots
+{\tt,} {\it registro} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt set} {\it nombre} {\tt[} {\it símbolo} {\tt,} \dots
+{\tt,} {\it símbolo} {\tt]} {\tt,} {\it registro} {\tt,} \dots {\tt,}
+{\it registro} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it nombre} es el nombre simbólico del conjunto;
+
+\noindent
+{\it símbolo}, \dots, {\it símbolo} son subíndices que especifican un miembro particular del conjunto (si el conjunto es un arreglo, {\it i.e.} un conjunto de conjuntos);
+
+\noindent
+{\it registro}, \dots, {\it registro} son registros.
+
+\noindent
+Las comas que preceden a los registros pueden omitirse.
+
+\para{Registros}
+
+\vspace*{-8pt}
+
+\begin{description}
+\item[{\tt :=}]\hspace*{0pt}\\
+es un elemento de asignación de registro no-significativo que puede ser usado libremente para mejorar la legibilidad;
+\item[{\tt(} {\it porción} {\tt)}]\hspace*{0pt}\\
+especifica una porción;
+\item[{\it datos-simples}]\hspace*{0pt}\\
+especifica los datos del conjunto en formato simple;
+\item[{\tt:} {\it datos-matriciales}]\hspace*{0pt}\\
+especifica los datos del conjunto en formato matricial;
+\item[{\tt(tr)} {\tt:} {\it datos-matriciales}]\hspace*{0pt}\\
+especifica los datos del conjunto en formato matricial traspuesto (en este caso, los dos puntos que siguen a la palabra clave {\tt(tr)} pueden omitirse).
+\end{description}
+
+\vspace*{-8pt}
+
+\para{Ejemplos}
+
+\begin{verbatim}
+set mes := Ene Feb Mar Abr May Jun;
+set mes "Ene", "Feb", "Mar", "Abr", "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 3 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{verbatim}
+
+\noindent(En estos ejemplos, {\tt mes} es un conjunto simple de singletones, {\tt A} es un arreglo 2-dimensional de duplos y {\tt B} es un conjunto simple de triplos. Los bloques de datos para el mismo conjunto son equivalentes en el sentido de que especifican los mismos datos en formatos distintos.
+
+El {\it bloque de datos del conjunto} se usa para especificar un conjunto elemental completo, el que se asigna a un conjunto (si es un conjunto simple) o a uno de sus miembros (si el conjunto es un arreglo de conjuntos).\footnote{Hay otra forma de especificar datos para un conjunto simple junto con los datos para los parámetros. Esta característica se discute en la próxima sección.}
+
+Los bloques de datos sólo pueden ser especificados para conjuntos no-calculables, {\it i.e.} para conjuntos que no tienen el atributo de asignación ({\tt:=}) en la correspondiente sentencia set.
+
+Si el conjunto es un conjunto simple, sólo se debe especificar su nombre simbólico en el encabezado del bloque de datos. De otro modo, si el conjunto es un arreglo $n$-dimensional, su nombre simbólico debe proveerse con una lista completa de subíndices separados por coma y encerrados entre corchetes para especificar un miembro particular del arreglo de conjuntos. El número de subíndices debe ser igual a la dimensión del arreglo de conjuntos, en el que cada subíndice deben ser un número o símbolo.
+
+Un conjunto elemental definido en el bloque de datos del conjunto se codifica como una secuencia de registros según se describe luego.\footnote{{Registro} es simplemente un término técnico. No significa que los mismos presenten algún formateo especial.}
+
+\subsection{Asignación de registro}
+
+La {\it asignación de registro} ({\tt:=}) es un elemento no-significativo. Se puede usar para mejorar la legibilidad de los bloques de datos.
+
+\subsection{Registro en porción}
+
+El {\it registro en porción} es un registro de control que especifica una {\it porción} del conjunto elemental definido en el bloque de datos. Tiene la siguiente forma sintáctica:
+$$\mbox{{\tt(} $p_1$ {\tt,} $p_2$ {\tt,} \dots {\tt,} $p_n$ {\tt)}}$$
+donde $p_1$, $p_2$, \dots, $p_n$ son componentes de la porción.
+
+Cada componente de la porción puede ser un número o un símbolo o el asterisco ({\tt*}). El número de componentes de la porción debe coincidir con la dimensión de los $n$-tuplos del conjunto elemental que se define. Por ejemplo, si el conjunto elemental contiene 4-tuplos (cuádruplos), la porción debe tener cuatro componentes. El número de asteriscos en la porción se denomina la {\it dimensión de la porción}.
+
+El efecto de usar las porciones es como sigue: si se especifica una porción $m$-dimensional ({\it i.e.} una porción que tiene $m$ asteriscos) en el bloque de datos, todos los registros subsecuentes deben especificar tuplos de dimensión $m$. Cuando se encuentra un $m$-tuplo, cada asterisco en la porción se reemplaza por los correspondientes componentes del $m$-tuplo para dar el $n$-tuplo resultante, el que es incluido en el conjunto elemental que se define. Por ejemplo, si está vigente la porción $(a,*,1,2,*)$ y se encuentra el duplo $(3,b)$ en el registro subsecuente, el 5-tuplo resultante que se incluye en el conjunto elemental es $(a,3,1,2,b)$.
+
+Las porciones que no tienen asteriscos en si mismas, definen un $n$-tuplo completo que se incluye en el conjunto elemental.
+
+Una vez especificada una porción, la misma está vigente hasta que aparezca una nueva porción o bien hasta que se encuentra el final del bloque de datos. Debe notarse que si no se especifica una porción en el bloque de datos, se asume una cuyos componentes son asteriscos en todas las posiciones.
+
+\subsection{Registro simple}
+
+El {\it registro simple} define un $n$-tuplo en formato simple y tiene la siguiente forma sintáctica:
+$$\mbox{$t_1$ {\tt,} $t_2$ {\tt,} \dots {\tt,} $t_n$}$$
+donde $t_1$, $t_2$, \dots, $t_n$ son componentes del $n$-tuplo. Cada componente puede ser un número o símbolo. Las comas entre componentes son opcionales y pueden omitirse.
+
+\subsection{Registro matricial}
+
+El {\it registro matricial} define varios 2-tuplos (duplos) en formato matricial y tiene la siguiente forma sintáctica:
+$$\begin{array}{cccccc}
+\mbox{{\tt:}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
+f_1&a_{11}&a_{12}&\dots&a_{1n}&\\
+f_2&a_{21}&a_{22}&\dots&a_{2n}&\\
+\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
+f_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
+\end{array}$$
+donde $f_1$, $f_2$, \dots, $f_m$ son números y/o símbolos que corresponden a filas de la matriz; $c_1$, $c_2$, \dots, $c_n$ son números y/o símbolos que corresponden a columnas de la matriz, mientras que $a_{11}$, $a_{12}$, \dots, $a_{mn}$ son los elementos de la matriz, los cuales pueden ser tanto {\tt+} como {\tt-}. (En este registro, el delimitador {\tt:} que precede a la lista de columnas y el delimitador {\tt:=} a continuación de la lista de columnas, no pueden ser omitidos.)
+
+Cada elemento $a_{ij}$ del bloque de datos matricial (donde $1\leq i\leq m$,
+$1\leq j\leq n$) corresponde a 2-tuplos $(f_i,c_j)$. Si en $a_{ij}$ se indica el signo más ({\tt+}), el correspondiente 2-tuplo (o un $n$-tuplo más largo si se usa una porción) se incluye en el conjunto elemental. De otro modo, si en $a_{ij}$ se indica el signo menos ({\tt-}) el 2-tuplo no se incluye en el conjunto elemental.
+
+Puesto que el registro matricial define 2-tuplos, ya sea el conjunto elemental o bien la porción vigente en uso deben ser 2-dimensionales.
+
+\subsection{Registro matricial traspuesto}
+
+El {\it registro matricial traspuesto} tiene la siguiente forma sintáctica:
+$$\begin{array}{cccccc}
+\mbox{{\tt(tr) :}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
+f_1&a_{11}&a_{12}&\dots&a_{1n}&\\
+f_2&a_{21}&a_{22}&\dots&a_{2n}&\\
+\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
+f_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
+\end{array}$$
+(En este caso el delimitador {\tt:} a continuación de la palabra clave {\tt (tr)} es opcional y puede omitirse.)
+
+Este registro es completamente análogo al registro matricial (ver anteriormente) con la única excepción, en este caso, de que cada elemento $a_{ij}$ de la matriz corresponde al 2-tuplo $(c_j,f_i)$ en vez de a $(f_i,c_j)$.
+
+Una vez especificado, el indicador {\tt(tr)} tiene alcance en todos los registros subsecuentes hasta que se encuentra otra porción o bien el fin del bloque de datos.
+
+\section{Bloque de datos de parámetro}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][88pt]{468pt}{
+\hspace{6pt} {\tt param} {\it nombre} {\tt,} {\it registro} {\tt,} \dots
+{\tt,} {\it registro} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt param} {\it nombre} {\tt default} {\it valor} {\tt,}
+{\it registro} {\tt,} \dots {\tt,} {\it registro} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt param} {\tt:} {\it datos-tabulación} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt param} {\tt default} {\it valor} {\tt:}
+{\it datos-tabulación} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it nombre} es el nombre simbólico del parámetro;
+
+\noindent
+{\it valor} es un valor por defecto opcional del parámetro;
+
+\noindent
+{\it registro}, \dots, {\it registro} son registros.
+
+\noindent
+{\it datos-tabulación} especifica los datos del parámetro en el formato tabulación.
+
+\noindent
+Las comas que preceden a los registros pueden omitirse.
+
+\para{Registros}
+
+\vspace*{-8pt}
+
+\begin{description}
+\item[{\tt :=}]\hspace*{0pt}\\
+es un elemento de asignación de registro no-significativo que puede ser usado libremente para mejorar la legibilidad;
+\item[{\tt[} {\it porción} {\tt]}]\hspace*{0pt}\\
+especifica una porción;
+\item[{\it datos-planos}]\hspace*{0pt}\\
+especifica los datos del parámetro en formato plano;
+\item[{\tt:} {\it datos-tabulares}]\hspace*{0pt}\\
+especifica los datos del parámetro en formato tabular;
+\item[{\tt(tr)} {\tt:} {\it datos-tabulares}]\hspace*{0pt}\\
+especifica los datos del parámetro en formato matricial traspuesto (en este caso, los dos puntos que siguen a la palabra clave {\tt(tr)} pueden omitirse).
+\end{description}
+
+\vspace*{-8pt}
+
+\para{Ejemplos}
+
+\begin{verbatim}
+param T := 4;
+param mes := 1 Ene 2 Feb 3 Mar 4 Abr 5 May;
+param mes := [1] 'Ene', [2] 'Feb', [3] 'Mar', [4] 'Abr', [5] 'May';
+param stock_inicial := hierro 7.32 niquel 35.8;
+param stock_inicial [*] hierro 7.32, niquel 35.8;
+param costo [hierro] .025 [niquel] .03;
+param valor := hierro -.1, niquel .02;
+param : stock_inicial costo valor :=
+ hierro 7.32 .025 -.1
+ niquel 35.8 .03 .02 ;
+param : insumo : stock_inicial costo valor :=
+ hierro 7.32 .025 -.1
+ niquel 35.8 .03 .02 ;
+param demanda default 0 (tr)
+ : FRA DET LAN WIN STL FRE LAF :=
+ laminas 300 . 100 75 . 225 250
+ rollos 500 750 400 250 . 850 500
+ cintas 100 . . 50 200 . 250 ;
+param costo_transporte :=
+ [*,*,laminas]: 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
+ [*,*,rollos]: 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
+ [*,*,cintas]: 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{verbatim}
+
+El {\it bloque de datos del parámetro} se usa para especificar datos completos a un parámetro (o a varios parámetros si los datos se especifican en el formato tabulaciones)
+
+Los bloques de datos sólo pueden ser especificados para parámetros no-calculables, {\it i.e.} para parámetros que no tienen el atributo de asignación({\tt:=}) en la correspondiente sentencia parameter.
+
+Los datos definidos en el bloque de datos del parámetro se codifican como una secuencia de registros descriptos luego. Adicionalmente, el bloque de datos puede ser provisto con el atributo opcional {\tt default}, el cual especifica un valor numérico o simbólico por defecto para el parámetro (parámetros). Este valor por defecto se asigna al parámetro, o a sus miembros, cuando no se definen valores apropiados en el bloque de datos del parámetro. El atributo {\tt default} no se puede usar si ya se ha especificado en la correspondiente sentencia parameter.
+
+\subsection{Asignación de registro}
+
+La {\it asignación de registro} ({\tt:=}) es un elemento no-significativo. Se puede usar para mejorar la legibilidad de los bloques de datos.
+
+\subsection{Registro en porción}
+
+El {\it registro en porción} es un registro de control que especifica una {\it porción} del arreglo de parámetros. Tiene la siguiente forma sintáctica:
+$$\mbox{{\tt[} $p_1$ {\tt,} $p_2$ {\tt,} \dots {\tt,} $p_n$ {\tt]}}$$
+donde $p_1$, $p_2$, \dots, $p_n$ son componentes de la porción.
+
+Cada componente de la porción puede ser un número o un símbolo o el asterisco ({\tt*}). El número de componentes de la porción debe coincidir con la dimensión del parámetro. Por ejemplo, si el parámetro es un arreglo 4-dimensional, la porción debe tener cuatro componentes. El número de asteriscos en la porción se denomina la {\it dimensión de la porción}.
+
+El efecto de usar las porciones es como sigue: si se especifica una porción $m$-dimensional ({\it i.e.} una porción que tiene $m$ asteriscos) en el bloque de datos, todos los registros subsecuentes deben especificar los subíndices de los miembros del parámetro como si el parámetro fuese $m$-dimensional y no $n$-dimensional.
+
+Cuando se encuentran los $m$ subíndices, cada asterisco en la porción se reemplaza por el correspondiente subíndice para dar los $n$ subíndices, los cuales definen al miembro corriente del parámetro. Por ejemplo, si está vigente la porción $(a,*,1,2,*)$ y se encuentran los subíndices 3 y $b$ en el registro subsecuente, la lista completa de subíndices que se usa para elegir un miembro del parámetro es $(a,3,1,2,b)$.
+
+Se permite especificar una porción que no tenga asteriscos. Tal porción, en sí misma define una lista completa de subíndices, en cuyo caso el próximo registro debe definir solamente un valor individual del correspondiente miembro del parámetro.
+
+Una vez especificada una porción, la misma está vigente hasta que aparezca una nueva porción o bien hasta que se encuentra el final del bloque de datos. Debe notarse que si no se especifica una porción en el bloque de datos, se asume una cuyos componentes son todos asteriscos.
+
+\subsection{Registro plano}
+
+El {\it registro plano} define la lista de subíndices y un valor individual en el formato plano. Este registro tiene la siguiente forma sintáctica:
+$$\mbox{$t_1$ {\tt,} $t_2$ {\tt,} \dots {\tt,} $t_n$ {\tt,} $v$}$$
+donde $t_1$, $t_2$, \dots, $t_n$ son subíndices y $v$ es un valor. Cada subíndice, al igual que el valor, puede ser un número o un símbolo. Las comas que siguen a los subíndices son opcionales y pueden omitirse.
+
+En el caso de parámetros o porciones 0-dimensionales, el registro plano no tiene subíndice y consiste solamente de un valor individual.
+
+\subsection{Registro tabular}
+
+El {\it registro tabular} define varios valores, cada uno de los cuales viene provisto con dos subíndices. Este registro tiene la siguiente forma sintáctica:
+$$\begin{array}{cccccc}
+\mbox{{\tt:}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
+f_1&a_{11}&a_{12}&\dots&a_{1n}&\\
+f_2&a_{21}&a_{22}&\dots&a_{2n}&\\
+\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
+f_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
+\end{array}$$
+donde los $f_1$, $f_2$, \dots, $f_m$ son números y/o símbolos que corresponden a filas de la tabla; $c_1$, $c_2$, \dots, $c_n$ son números y/o símbolos que corresponden a columnas de la tabla; mientras que $a_{11}$, $a_{12}$, \dots, $a_{mn}$ son elementos de la tabla. Cada elemento puede ser un número o símbolo o el punto decimal ({\tt.}) solo (en este registro, el delimitador {\tt:} que precede a la lista de columnas y el delimitador {\tt:=} a continuación de la lista de columnas, no pueden ser omitidos.).
+
+Cada elemento $a_{ij}$ del bloque de datos tabulares ($1\leq i\leq m$,
+$1\leq j\leq n$) define dos subíndices, siendo el primero $f_i$ y el segundo $c_j$. Estos subíndices se usan junto con la porción vigente para formar la lista completa de subíndices que identifica a un miembro particular del arreglo de parámetros. Si $a_{ij}$ es un número o símbolo, tal valor se asigna al miembro del parámetro. Sin embargo, si $a_{ij}$ es un punto decimal solo, el miembro recibe el valor por defecto especificado ya sea en el bloque de datos del parámetro o en la sentencia parameter, o si no hay un valor por defecto especificado, el miembro permanece indefinido.
+
+Puesto que el registro tabular provee dos subíndices para cada valor, ya sea el parámetro o bien la porción vigente en uso deben ser 2-dimensionales.
+
+\subsection{Registro tabular traspuesto}
+
+El {\it registro tabular traspuesto} tiene la siguiente forma sintáctica:
+$$\begin{array}{cccccc}
+\mbox{{\tt(tr) :}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
+f_1&a_{11}&a_{12}&\dots&a_{1n}&\\
+f_2&a_{21}&a_{22}&\dots&a_{2n}&\\
+\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
+f_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
+\end{array}$$
+(En este caso el delimitador {\tt:} a continuación de la palabra clave {\tt (tr)} es opcional y puede omitirse.)
+
+Este registro es completamente análogo al registro tabular (ver anteriormente), con la única excepción de que el primer subíndice definido por el elemento $a_{ij}$ es $c_j$ mientras que el segundo es $f_i$.
+
+Una vez especificado, el indicador {\tt(tr)} tiene alcance en todos los registros subsecuentes hasta que se encuentre otra porción o bien el fin del bloque de datos.
+
+\subsection{Formato de datos tabulación}
+
+El bloque de datos del parámetro en el {\it formato tabulación} tiene la siguiente forma sintáctica:
+$$
+\begin{array}{*{8}{l}}
+\multicolumn{4}{l}
+{{\tt param}\ {\tt default}\ valor\ {\tt :}\ c\ {\tt :}}&
+p_1\ \ \verb|,|&p_2\ \ \verb|,|&\dots\ \verb|,|&p_f\ \ \verb|:=|\\
+f_{11}\ \verb|,|& f_{12}\ \verb|,|& \dots\ \verb|,|& f_{1n}\ \verb|,|&
+a_{11}\ \verb|,|& a_{12}\ \verb|,|& \dots\ \verb|,|& a_{1f}\ \verb|,|\\
+f_{21}\ \verb|,|& f_{22}\ \verb|,|& \dots\ \verb|,|& f_{2n}\ \verb|,|&
+a_{21}\ \verb|,|& a_{22}\ \verb|,|& \dots\ \verb|,|& a_{2f}\ \verb|,|\\
+\dots & \dots & \dots & \dots & \dots & \dots & \dots & \dots \\
+f_{m1}\ \verb|,|& f_{m2}\ \verb|,|& \dots\ \verb|,|& f_{mn}\ \verb|,|&
+a_{m1}\ \verb|,|& a_{m2}\ \verb|,|& \dots\ \verb|,|& a_{mf}\ \verb|;|\\
+\end{array}
+$$
+
+1. La palabra clave {\tt default} puede omitirse junto con el valor que le sigue.
+
+2. El nombre simbólico $c$ puede omitirse junto con los dos puntos que le siguen.
+
+3. Todas las comas son opcionales y pueden omitirse.
+
+El bloque de datos en el formato tabulación mostrado arriba es exactamente equivalente a los siguientes bloques de datos:
+
+\verb|set| $c$\ \verb|:=|\ $
+\verb|(|f_{11}\verb|,|f_{12}\verb|,|\dots\verb|,|f_{1n}\verb|) |
+\verb|(|f_{21}\verb|,|f_{22}\verb|,|\dots\verb|,|f_{2n}\verb|) |
+\dots
+\verb| (|f_{m1}\verb|,|f_{m2}\verb|,|\dots\verb|,|f_{mn}\verb|);|$
+
+\verb|param| $p_1$\ \verb|default|\ $valor$\ \verb|:=|
+
+$\verb| |
+\verb|[|f_{11}\verb|,|f_{12}\verb|,|\dots\verb|,|f_{1n}\verb|] |a_{11}
+\verb| [|f_{21}\verb|,|f_{22}\verb|,|\dots\verb|,|f_{2n}\verb|] |a_{21}
+\verb| |\dots
+\verb| [|f_{m1}\verb|,|f_{m2}\verb|,|\dots\verb|,|f_{mn}\verb|] |a_{m1}
+\verb|;|
+$
+
+\verb|param| $p_2$\ \verb|default|\ $valor$\ \verb|:=|
+
+$\verb| |
+\verb|[|f_{11}\verb|,|f_{12}\verb|,|\dots\verb|,|f_{1n}\verb|] |a_{12}
+\verb| [|f_{21}\verb|,|f_{22}\verb|,|\dots\verb|,|f_{2n}\verb|] |a_{22}
+\verb| |\dots
+\verb| [|f_{m1}\verb|,|f_{m2}\verb|,|\dots\verb|,|f_{mn}\verb|] |a_{m2}
+\verb|;|
+$
+
+\verb| |.\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .
+
+\verb|param| $p_f$\ \verb|default|\ $valor$\ \verb|:=|
+
+$\verb| |
+\verb|[|f_{11}\verb|,|f_{12}\verb|,|\dots\verb|,|f_{1n}\verb|] |a_{1f}
+\verb| [|f_{21}\verb|,|f_{22}\verb|,|\dots\verb|,|f_{2n}\verb|] |a_{2f}
+\verb| |\dots
+\verb| [|f_{m1}\verb|,|f_{m2}\verb|,|\dots\verb|,|f_{mn}\verb|] |a_{mf}
+\verb|;|
+$
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\appendix
+
+\chapter{Uso de sufijos}
+
+\vspace*{-12pt}
+
+Se pueden usar sufijos para recuperar valores adicionales relacionados con las variables, restricciones y objetivos del modelo.
+
+Un {\it sufijo} consiste de un punto ({\tt.}) seguido de una palabra clave no-reservada. Por ejemplo, si {\tt x} es una variable bidimensional, {\tt x[i,j].lb} es un valor numérico igual a la cota inferior de la variable elemental {\tt x[i,j]} que se puede usar como un parámetro numérico dondequiera que sea en expresiones.
+
+Para las variables del modelo, los sufijos tienen los siguientes significados:
+
+\begin{tabular}{@{}ll@{}}
+{\tt.lb}&cota inferior\\
+{\tt.ub}&cota superior\\
+{\tt.status}&estatus en la solución:\\
+&0 --- indefinida\\
+&1 --- básica\\
+&2 --- no-básica en la cota inferior\\
+&3 --- no-básica en la cota superior\\
+&4 --- variable no-básica libre (no acotada)\\
+&5 --- variable no-básica fija\\
+{\tt.val}&valor primal en la solución\\
+{\tt.dual}&valor dual (costo reducido) en la solución\\
+\end{tabular}
+
+Para las restricciones y objetivos del modelo, los sufijos tienen los siguientes significados:
+
+\begin{tabular}{@{}ll@{}}
+{\tt.lb}&cota inferior de la forma lineal\\
+{\tt.ub}&cota superior de la forma lineal\\
+{\tt.status}&estatus en la solución:\\
+&0 --- indefinida\\
+&1 --- no-limitante\\
+&2 --- limitante en la cota inferior\\
+&3 --- limitante en la cota superior\\
+&4 --- fila limitante libre (no-acotada)\\
+&5 --- restricción de igualdad limitante\\
+{\tt.val}&valor primal de la forma lineal en la solución\\
+{\tt.dual}&valor dual (costo reducido) de la forma lineal en la solución\\
+\end{tabular}
+
+Debe notarse que los sufijos {\tt.status}, {\tt.val} y {\tt.dual} solamente pueden usarse luego de la sentencia solve.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Funciones de fecha y hora}
+
+\noindent\hfil
+\begin{tabular}{c}
+por Andrew Makhorin \verb|<mao@gnu.org>|\\
+y Heinrich Schuchardt \verb|<heinrich.schuchardt@gmx.de>|\\
+\end{tabular}
+
+\section{Obtención del tiempo calendario corriente}
+\label{gmtime}
+
+Para obtener el tiempo calendario\footnote{N. del T.: el tiempo calendario es un punto en el {\it continuum} del tiempo, por ejemplo 4 de noviembre de 1990 a las 18:02.5 UTC. A veces se lo llama ``tiempo absoluto''. La definición está tomada de {\it Sandra Loosemore}, {\it Richard M. Stallman}, {\it Roland McGrath}, {\it Andrew Oram} \& {\it Ulrich Drepper}, ``The GNU C Library Reference Manual - for version 2.17'', Free Software Foundation, Inc, 2012.} corriente en MathProg existe la función {\tt gmtime}. No tiene argumentos y devuelve el número de segundos transcurridos desde las 00:00:00 del 1 de enero de 1970, Tiempo Universal Coordinado (UTC). Por ejemplo:
+
+\begin{verbatim}
+ param utc := gmtime();
+\end{verbatim}
+
+MathPro no tiene una función para convertir el tiempo UTC devuelto por la función {\tt gmtime} a tiempo calendario {\it local}. Entonces, si se necesita determinar el tiempo calendario local corriente, se debe agregar al tiempo UTC devuelto la diferencia horaria con respecto al UTC expresada en segundos. Por ejemplo, la hora en Berlín durante el invierno está una hora adelante del UTC, lo que corresponde una diferencia horaria de +1~hora~= +3600~segundos, de modo que el tiempo calendario corriente del invierno en Berlín se puede determinar como sigue:
+
+\begin{verbatim}
+ param ahora := gmtime() + 3600;
+\end{verbatim}
+
+\noindent Análogamente, el horario de verano en Chicago (Zona Horaria Central) está cinco horas por detrás del UTC, de modo que el correspondiente tiempo calendario local corriente se puede determinar como sigue:
+
+\begin{verbatim}
+ param ahora := gmtime() - 5 * 3600;
+\end{verbatim}
+
+Debe notarse que el valor devuelto por {\tt gmtime} es volátil, {\it i.e.} si se la invoca varias veces, esta función devolverá valores diferentes.
+
+\section{Conversión de una cadena de caracteres a un tiempo calendario}
+\label{str2time}
+
+La función {\tt str2time(}{\it c}{\tt,} {\it f}{\tt)} convierte una cadena de caracteres (una {\it estampa de la fecha y hora}) especificada por su primer argumento {\it c}, la que debe ser una expresión simbólica, a un tiempo calendario apropiado para cálculos aritméticos. La conversión se controla mediante la especificación de una cadena de formato {\it f} (el segundo argumento), la que también debe ser una expresión simbólica.
+
+El resultado de la conversión devuelto por {\tt str2time} tiene el mismo significado que los valores devueltos por la función {\tt gmtime} (ver Subsección \ref{gmtime}, página \pageref{gmtime}). Debe notarse que {\tt str2time} {\it no corrige} el tiempo calendario devuelto para considerar la zona horaria local, {\it i.e.} si se aplica a las 00:00:00 del 1 de enero de 1970, siempre devolverá 0.
+
+Por ejemplo, las sentencias del modelo
+
+\begin{verbatim}
+ param c, symbolic, := "07/14/98 13:47";
+ param t := str2time(c, "%m/%d/%y %H:%M");
+ display t;
+\end{verbatim}
+
+\noindent imprime lo siguiente en la salida estándar:
+
+\begin{verbatim}
+ t = 900424020
+\end{verbatim}
+
+\noindent donde el tiempo calendario mostrado corresponde a las 13:47:00 del 14 de julio de 1998.
+
+La cadena de formato que se pasa a la función {\tt str2time} consiste de especificadores de conversión y caracteres ordinarios. Cada especificador de conversión empieza con un carácter de porcentaje ({\tt\%}) seguido por una letra.
+
+Los siguientes especificadores de conversión se pueden usar en la cadena de formato\footnote{N. del T.: en todas las funciones de fecha y hora, nombre del mes y del día de la semana refiere a su denominación en inglés, {\it e.g.}: {\tt August}, {\tt Aug}, {\tt Wednesday}, {\tt We}.}:
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%b}&El nombre del mes abreviado (insensible a mayúsculas). Al menos las tres primeras letras del nombre del mes deben aparecer en la cadena de entrada.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%d}&El día del mes como un número decimal (rango de 1 a 31). Se permite el cero como primer dígito, aunque no es requerido.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%h}&Lo mismo que {\tt\%b}.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%H}&La hora como un número decimal, empleando un reloj de 24 horas (rango de 0 a 23). Se permite el cero como primer dígito, aunque no es requerido.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%m}&El mes como un número decimal (rango de 1 a 12). Se permite el cero como primer dígito, aunque no es requerido.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%M}&El minuto como número decimal (rango de 0 a 59). Se permite el cero como primer dígito, aunque no es requerido.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%S}&El segundo como un número decimal (rango de 0 a 59). Se permite el cero como primer dígito, aunque no es requerido.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%y}&El año sin un siglo como un número decimal (rango de 0 a 99). Se permite el cero como primer dígito, aunque no es requerido. Los valores de entrada en el rango de 0 a 68 se consideran como los años 2000 al 2068, mientras que los valores del 69 al 99 como los años 1969 a 1999.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%z}&La diferencia horaria con respecto a GMT en formato ISO 8601.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%\%}&Un carácter {\tt\%} literal.\\
+\end{tabular}
+
+Todos los demás caracteres (ordinarios) en la cadena de formato deben tener un carácter de coincidencia con la cadena de entrada a ser convertida. Las excepciones son los espacios en la cadena de entrada, la cual puede coincidir con cero o más caracteres de espacio en la cadena de formato.
+
+Si algún componente de la fecha y/u hora están ausentes en el formato y, consecuentemente, en la cadena de entrada, la función {\tt str2time} usa sus valores por defecto de las 00:00:00 del 1 de enero de 1970, es decir que el valor por defecto para el año es 1970, el valor por defecto para el mes es enero, etc.
+
+La función {} es aplicable a todos los tiempos calendarios en el rango desde las 00:00:00 del 1 de enero del 0001 hasta las 23:59:59 del 31 de diciembre del 4000 del calendario gregoriano.
+
+\section{Conversión de un tiempo calendario a una cadena de caracteres}
+\label{time2str}
+
+La función {\tt time2str(}{\it t}{\tt,} {\it f}{\tt)} convierte el tiempo calendario especificado por su primer argumento {\it t}, el que debe ser una expresión numérica, a una cadena de caracteres (valor simbólico). La conversión se controla con la cadena de formato {\it f} especificada (el segundo argumento), la que debe ser una expresión simbólica.
+
+El tiempo calendario que se le pasa a {\tt time2str} tiene el mismo significado que el valor devuelto por la función {\tt gmtime} (ver Subsección \ref{gmtime}, página \pageref{gmtime}). Debe notarse que {\tt time2str} {\it no corrige} el tiempo calendario especificado para considerar la zona horaria local, {\it i.e.} el tiempo calendario 0 siempre corresponde a las 00:00:00 del 1 de enero de 1970.
+
+Por ejemplo, las sentencias del modelo
+
+\begin{verbatim}
+ param c, symbolic, := time2str(gmtime(), "%FT%TZ");
+ display c;
+\end{verbatim}
+
+\noindent puede producir la siguiente impresión:
+
+\begin{verbatim}
+ c = '2008-12-04T00:23:45Z'
+\end{verbatim}
+
+\noindent que es una estampa de una fecha y hora en el formato ISO.
+
+La cadena de formato que se pasa a la función {\tt time2str} consiste de especificadores de conversión y caracteres ordinarios. Cada especificador de conversión empieza con un carácter de porcentaje ({\tt\%}) seguido por una letra.
+
+Los siguientes especificadores de conversión se pueden usar en la cadena de formato:
+
+\newpage
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%a}&El nombre del día de la semana abreviado (2 caracteres).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%A}&El nombre del día de la semana completo.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%b}&El nombre del mes abreviado (3 caracteres).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%B}&El nombre del mes completo.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%C}&El siglo del año, es decir el mayor entero no mayor que el año dividido por~100.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%d}&El día del mes como un número decimal (rango de 01 a 31).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%D}&La fecha, usando el formato \verb|%m/%d/%y|.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%e}&El día del mes, como con \verb|%d|, pero rellenado con un espacio en blanco en vez de cero.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%F}&La fecha, usando el formato \verb|%Y-%m-%d|.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%g}&El año correspondiente al número de semana ISO, pero sin el siglo (rango de 00 a 99). Tiene el mismo formato y valor que \verb|%y|, excepto que si el número de semana ISO (ver \verb|%V|) pertenece al año previo o siguiente, se usa aquel año en su lugar.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%G}&El año correspondiente al número de semana ISO. Tiene el mismo formato y valor que \verb|%Y|, excepto que si el número de semana ISO (ver \verb|%V|) pertenece al año previo o siguiente, se usa aquel año en su lugar.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%h}&Lo mismo que \verb|%b|.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%H}&La hora como un número decimal, empleando un reloj de 24 horas (rango de 00 a 23).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%I}&La hora como un número decimal, empleando un reloj de 12 horas (rango de 01 a 12).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%j}&El día del año como un número decimal (rango de 001 a 366).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%k}&La hora como un número decimal, empleando un reloj de 24 horas como con \verb|%H|, pero rellenado con un espacio en blanco en vez de cero.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%l}&La hora como un número decimal, empleando un reloj de 12 horas como con \verb|%I|, pero rellenado con un espacio en blanco en vez de cero.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%m}&El mes como un número decimal (rango de 01 a 12).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%M}&El minuto como un número decimal (rango de 00 a 59).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%p}&Tanto {\tt AM} como {\tt PM}, de acuerdo con el valor horario dado. La medianoche es tratada como {\tt AM} y el mediodía como {\tt PM}.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%P}&Tanto {\tt am} como {\tt pm}, de acuerdo con el valor horario dado. La medianoche es tratada como {\tt am} y el mediodía como {\tt pm}.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%R}&La hora y los minutos en números decimales, usando el formato \verb|%H:%M|.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%S}&Los segundos como un número decimal (rango de 00 a 59).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%T}&La hora del día en números decimales, usando el formato \verb|%H:%M:%S|.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%u}&El día de la semana como un número decimal (rango de 1 a 7), siendo 1 el lunes.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%U}&El número de semana del año corriente como un número decimal (rango de 00 a 53), empezando con el primer domingo como el primer día de la primer semana. Se considera que los días del año anteriores al primer domingo son parte de la semana 00.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%V}&El número de semana ISO como un número decimal (rango 01 a 53). Las semanas de ISO empiezan los lunes y terminan los domingos. La semana 01 de un año es la primer semana que tiene la mayoría de sus días en ese año, lo cual es equivalente a la semana que contiene al 4 de enero. La semana 01 de un año puede contener días del año previo. La semana anterior a la semana 01 de un año es la última semana (52 o 53) del año previo, aún si esta contiene días del nuevo año. En otras palabras, si el 1 de enero cae en lunes, martes, miércoles o jueves, está en la semana 01; si el 1 de enero cae en viernes, sábado o domingo, está en la semana 52 o 53 del año previo.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%w}&El día de la semana como un número decimal (rango de 0 a 6), siendo 0 el domingo.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%W}&El número de semana del año corriente como un número decimal (rango de 00 a 53), empezando con el primer lunes como el primer día de la primer semana. Se considera que los días del año anteriores al primer lunes son parte de la semana 00.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%y}&El año sin el siglo como un número decimal (rango de 00 a 99), es decir año {\tt mod} 100.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%Y}&El año como un número decimal, usando el calendario gregoriano.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%\%}& Un carácter \verb|%| literal.\\
+\end{tabular}
+
+Todos los demás caracteres (ordinarios) en la cadena de formato simplemente se copian a la cadena resultante.
+
+El primer argumento (tiempo calendario) que se le pasa a la función {\tt time2str} debe están en el rango entre $-62135596800$ y $+64092211199$, lo que corresponde al período desde las 00:00:00 del 1 de enero del 0001 hasta las 23:59:59 del 31 de diciembre del 4000 del calendario gregoriano.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Controladores de tablas}
+\label{drivers}
+
+\noindent\hfil
+\begin{tabular}{c}
+por Andrew Makhorin \verb|<mao@gnu.org>|\\
+y Heinrich Schuchardt \verb|<heinrich.schuchardt@gmx.de>|\\
+\end{tabular}
+
+\bigskip\bigskip
+
+El {\it controlador de tablas} es un módulo del programa que permite la trasmisión de datos entre objetos de un modelo MathProg y tablas de datos.
+
+Actualmente, el paquete GLPK tiene cuatro controladores de tablas:
+
+\vspace*{-8pt}
+
+\begin{itemize}
+\item controlador interno de tablas CSV;
+\item controlador interno de tablas xBASE;
+\item controlador de tablas ODBC;
+\item controlador de tablas MySQL.
+\end{itemize}
+
+\vspace*{-8pt}
+
+\section{Controlador de tablas CSV}
+
+El controlador de tablas CSV asume que la tabla de datos está representada en la forma de un archivo de texto plano, en el formato de archivo CSV (valores separados por coma) como se describe más adelante.
+
+Para elegir el controlador de tablas CSV, su nombre en la sentencia table debe especificarse como \verb|"CSV"| y el único argumento debe especificar el nombre de un archivo de texto plano conteniendo la tabla. Por ejemplo:
+
+\begin{verbatim}
+ table datos IN "CSV" "datos.csv": ... ;
+\end{verbatim}
+
+El sufijo del nombre de archivo puede ser arbitrario; sin embargo, se recomienda usar el sufijo `\verb|.csv|'.
+
+\newpage
+
+Al leer tablas de entrada, el controlador de tablas CSV provee un campo implícito llamado \verb|RECNO|, el cual contiene el número del registro corriente. Este campo puede especificarse en la sentencia table de entrada, como si existiera un verdadero campo llamado \verb|RECNO| en el archivo CSV. Por ejemplo:
+
+\begin{verbatim}
+ table lista IN "CSV" "lista.csv": num <- [RECNO], ... ;
+\end{verbatim}
+
+\subsection*{Formato CSV\footnote{Este material está basado en el documento RFC 4180.}}
+
+El formato CSV (valores separados por coma) es un formato de archivo de texto plano definido como sigue:
+
+1. Cada registro se ubica en una línea separada, delimitada por un salto de línea. Por ejemplo:
+
+\begin{verbatim}
+ aaa,bbb,ccc\n
+ xxx,yyy,zzz\n
+\end{verbatim}
+
+\noindent
+donde \verb|\n| significa el carácter de control \verb|LF| ({\tt 0x0A}).
+
+2. El último registro en el archivo puede tener un salto de línea final o no. Por ejemplo:
+
+\begin{verbatim}
+ aaa,bbb,ccc\n
+ xxx,yyy,zzz
+\end{verbatim}
+
+3. Debería haber una línea de encabezado que aparezca en la primera línea del archivo, en el mismo formato que las líneas de registro normales. Este encabezado debería contener nombres que correspondan a los campos en el archivo. El número de nombres de campo en la línea de encabezado debe ser igual al número de campos de los registros en el archivo. Por ejemplo:
+
+\begin{verbatim}
+ nombre1,nombre2,nombre3\n
+ aaa,bbb,ccc\n
+ xxx,yyy,zzz\n
+\end{verbatim}
+
+4. Dentro del encabezado y de cada registro puede haber uno o más campos separados por comas. Cada línea debe contener el mismo número de campos a través de todo el archivo. Los espacios se consideran parte del campo y, consecuentemente, no son ignorados. El último campo en el registro no debe estar seguido de una coma. Por ejemplo:
+
+\begin{verbatim}
+ aaa,bbb,ccc\n
+\end{verbatim}
+
+5. Los campos pueden estar encerrados entre comillas dobles o no. Por ejemplo:
+
+\begin{verbatim}
+ "aaa","bbb","ccc"\n
+ zzz,yyy,xxx\n
+\end{verbatim}
+
+6. Si el campo se encierra entre comillas dobles, cada comilla doble que sea parte del campo debe codificarse dos veces. Por ejemplo:
+
+\begin{verbatim}
+ "aaa","b""bb","ccc"\n
+\end{verbatim}
+
+\newpage
+
+\para{Ejemplo}
+
+\begin{verbatim}
+DESDE,HACIA,DISTANCIA,COSTO
+Seattle,New-York,2.5,0.12
+Seattle,Chicago,1.7,0.08
+Seattle,Topeka,1.8,0.09
+San-Diego,New-York,2.5,0.15
+San-Diego,Chicago,1.8,0.10
+San-Diego,Topeka,1.4,0.07
+\end{verbatim}
+
+\section{Controlador de tablas xBASE}
+
+El controlador de tablas xBASE asume que la tabla de datos se almacenó en formato de archivo .dbf.
+
+Para elegir el controlador de tablas xBASE, su nombre en la sentencia table debe especificarse como \verb|"xBASE"| y el primer argumento debe especificar el nombre de un archivo .dbf que contenga la tabla. Para la tabla de salida, debe haber un segundo argumento definiendo el formato de la tabla en la forma \verb|"FF...F"|, donde \verb|F| es tanto {\tt C({\it n})}, el cual especifica un campo de caracteres de longitud $n$, como
+ {\tt N({\it n}{\rm [},{\it p}{\rm ]})}, el cual especifica un campo numérico de longitud $n$ y precisión $p$ (por defecto, $p$ es 0).
+
+El siguiente es un ejemplo simple que ilustra la creación y lectura de un archivo .dbf:
+
+\begin{verbatim}
+table tab1{i in 1..10} OUT "xBASE" "foo.dbf"
+ "N(5)N(10,4)C(1)C(10)": 2*i+1 ~ B, Uniform(-20,+20) ~ A,
+ "?" ~ FOO, "[" & i & "]" ~ C;
+set M, dimen 4;
+table tab2 IN "xBASE" "foo.dbf": M <- [B, C, RECNO, A];
+display M;
+end;
+\end{verbatim}
+
+\section{Controlador de tablas ODBC}
+
+El controlador de tablas ODBC permite conexiones con bases de datos SQL usando una implementación de la interfaz ODBC basada en la Call Level Interface (CLI).\footnote{La norma de software correspondiente se define en ISO/IEC 9075-3:2003.}
+
+\para{Debian GNU/Linux.}
+Bajo Debian GNU/Linux, el controlador de tablas ODBC usa el paquete iODBC,\footnote{Ver {\tt<http://www.iodbc.org/>}.} el cual debe estar instalado antes de compilar el paquete GLPK. La instalación se puede efectuar con el siguiente comando:
+
+\begin{verbatim}
+ sudo apt-get install libiodbc2-dev
+\end{verbatim}
+
+Debe notarse que para la configuración del paquete GLPK para activar el uso de la librería iODBC, se debe pasar la opción `\verb|--enable-odbc|' al script de configuración.
+
+Para su uso en todo el sistema, las bases de datos individuales deben ingresarse en \verb|/etc/odbc.ini| y \verb|/etc/odbcinst.ini|. Las conexiones de las bases de datos usadas por un usuario individual se especifican mediante archivos en el directorio home (\verb|.odbc.ini| y \verb|.odbcinst.ini|).
+
+\para{Microsoft Windows.}
+Bajo Microsoft Windows, el controlador de tablas ODBC usa la librería ODBC de Microsoft. Para activar esta característica, el símbolo:
+
+\begin{verbatim}
+ #define ODBC_DLNAME "odbc32.dll"
+\end{verbatim}
+
+\noindent
+debe definirse en el archivo de configuración de GLPK `\verb|config.h|'.
+
+Las fuentes de datos pueden crearse por intermedio de las Herramientas Administrativas del Panel de Control.
+
+Para elegir el controlador de tablas ODBC, su nombre en la sentencia table debe especificarse como \verb|'ODBC'| o \verb|'iODBC'|.
+
+La lista de argumentos se especifica como sigue.
+
+El primer argumento es la cadena de conexión que se pasa a la librería ODBC, por ejemplo:
+
+\verb|'DSN=glpk;UID=user;PWD=password'|, o
+
+\verb|'DRIVER=MySQL;DATABASE=glpkdb;UID=user;PWD=password'|.
+
+Las diferentes partes de la cadena se separan con punto y coma. Cada parte consiste de un par {\it nombre de campo} y {\it valor} separados por el signo igual. Los nombres de campo permitidos dependen de la librería ODBC. Típicamente, se permiten los siguientes nombres de campo:
+
+\verb|DATABASE | base de datos;
+
+\verb|DRIVER | controlador ODBC;
+
+\verb|DSN | nombre de una fuente de datos;
+
+\verb|FILEDSN | nombre de un archivo de fuente de datos;
+
+\verb|PWD | clave de usuario;
+
+\verb|SERVER | base de datos;
+
+\verb|UID | nombre de usuario.
+
+El segundo argumento, y todos los siguientes, son considerados como sentencias SQL.
+
+Las sentencias SQL se pueden extender sobre múltiples argumentos. Si el último carácter de un argumento es un punto y coma, este indica el final de una sentencia SQL.
+
+Los argumentos de una sentencia SQL se concatenan separados por espacios. El eventual punto y coma final será removido.
+
+Todas las sentencias SQL, excepto la última, se ejecutarán directamente.
+
+Para table-IN, la última sentencia SQL puede ser un comando SELECT que empieza con \verb|'SELECT '| en letras mayúsculas. Si la cadena no se inicia con \verb|'SELECT '|, se considera que es un nombre de tabla y automáticamente se genera una sentencia SELECT.
+
+Para table-OUT, la última sentencia SQL puede contener uno o múltiples signos de interrogación. Si contiene un signo de interrogación, se considera como una plantilla para la rutina de escritura. De otro modo, la cadena es considerada un nombre de tabla y se genera automáticamente una plantilla INSERT.
+
+La rutina de escritura usa la plantilla con el signo de interrogación y reemplaza al primer signo de interrogación con el primer parámetro de salida, el segundo signo de interrogación con el segundo parámetro de salida, y así sucesivamente. Luego se emite el comando SQL.
+
+El siguiente es un ejemplo de la sentencia table de salida:
+
+\begin{verbatim}
+table ta { l in LOCALIDADES } OUT
+ 'ODBC'
+ 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'DROP TABLE IF EXISTS resultados;'
+ 'CREATE TABLE resultados ( ID INT, LOC VARCHAR(255), CANT DOUBLE );'
+ 'INSERT INTO resultados 'VALUES ( 4, ?, ? )' :
+ l ~ LOC, cantidad[l] ~ CANT;
+\end{verbatim}
+
+\noindent
+Alternativamente, se puede escribir como sigue:
+
+\begin{verbatim}
+table ta { l in LOCALIDADES } OUT
+ 'ODBC'
+ 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'DROP TABLE IF EXISTS resultados;'
+ 'CREATE TABLE resultados ( ID INT, LOC VARCHAR(255), CANT DOUBLE );'
+ 'resultados' :
+ l ~ LOC, cantidad[l] ~ CANT, 4 ~ ID;
+\end{verbatim}
+
+El uso de plantillas con `\verb|?|' no sólo permite INSERT, sino también UPDATE, DELETE, etc. Por ejemplo:
+
+\begin{verbatim}
+table ta { l in LOCALIDADES } OUT
+ 'ODBC'
+ 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'UPDATE resultados SET FECHA = ' & fecha & ' WHERE ID = 4;'
+ 'UPDATE resultados SET CANT = ? WHERE LOC = ? AND ID = 4' :
+ cantidad[l], l;
+\end{verbatim}
+
+\section{Controlador de tablas MySQL}
+
+El controlador de tablas permite conexiones con bases de datos MySQL.
+
+\para{Debian GNU/Linux.}
+Bajo Debian GNU/Linux, el controlador de tablas MySQL usa el paquete MySQL,\footnote{Para descargar los archivos de desarrollo, ver
+{\tt<http://dev.mysql.com/downloads/mysql/>}.} el cual debe estar instalado antes de compilar el paquete GLPK. La instalación se puede efectuar con el siguiente comando:
+
+\begin{verbatim}
+ sudo apt-get install libmysqlclient15-dev
+\end{verbatim}
+
+Debe notarse que para la configuración del paquete GLPK para activar el uso de la librería MySQL, se debe pasar la opción `\verb|--enable-mysql|' al script de configuración.
+
+\para{Microsoft Windows.}
+Bajo Microsoft Windows, el controlador de tablas MySQL también usa la librería MySQL. Para activar esta característica, el símbolo:
+
+\begin{verbatim}
+ #define MYSQL_DLNAME "libmysql.dll"
+\end{verbatim}
+
+\noindent
+debe definirse en el archivo de configuración de GLPK `\verb|config.h|'.
+
+Para elegir el controlador de tablas MySQL, su nombre en la sentencia table debe especificarse como \verb|'MySQL'|.
+
+La lista de argumentos se especifica como sigue.
+
+El primer argumento especifica como conectar la base de datos en el estilo DSN, por ejemplo:
+
+\verb|'Database=glpk;UID=glpk;PWD=gnu'|.
+
+Las diferentes partes de la cadena se separan con punto y coma. Cada parte consiste de un par {\it nombre de campo} y {\it valor} separados por el signo igual. Se permiten los siguientes nombres de campo:
+
+\verb|Server | servidor corriendo la base de datos (localhost por defecto);
+
+\verb|Database | nombre de la base de datos;
+
+\verb|UID | nombre de usuario;
+
+\verb|PWD | clave de usuario;
+
+\verb|Port | puerto usado por el servidor (3306 por defecto).
+
+El segundo argumento, y todos los siguientes, son considerados como sentencias SQL.
+
+Las sentencias SQL se pueden extender sobre múltiples argumentos. Si el último carácter de un argumento es un punto y coma, este indica el final de una sentencia SQL.
+
+Los argumentos de una sentencia SQL se concatenan separados por espacios. El eventual punto y coma final será removido.
+
+Todas las sentencias SQL, excepto la última, se ejecutarán directamente.
+
+Para table-IN, la última sentencia SQL puede ser un comando SELECT que empieza con \verb|'SELECT '| en letras mayúsculas. Si la cadena no se inicia con \verb|'SELECT '|, se considera que es un nombre de tabla y automáticamente se genera una sentencia SELECT.
+
+Para table-OUT, la última sentencia SQL puede contener uno o múltiples signos de interrogación. Si contiene un signo de interrogación, se considera como una plantilla para la rutina de escritura. De otro modo, la cadena es considerada un nombre de tabla y se genera automáticamente una plantilla INSERT.
+
+La rutina de escritura usa la plantilla con el signo de interrogación y reemplaza al primer signo de interrogación con el primer parámetro de salida, el segundo signo de interrogación con el segundo parámetro de salida y así sucesivamente. Luego se emite el comando SQL.
+
+El siguiente es un ejemplo de la sentencia table de salida:
+
+\newpage
+
+\begin{verbatim}
+table ta { l in LOCALIDADES } OUT
+ 'MySQL'
+ 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'DROP TABLE IF EXISTS resultados;'
+ 'CREATE TABLE resultados ( ID INT, LOC VARCHAR(255), CANT DOUBLE );'
+ 'INSERT INTO resultados VALUES ( 4, ?, ? )' :
+ l ~ LOC, cantidad[l] ~ CANT;
+\end{verbatim}
+
+\noindent
+Alternativamente, se puede escribir como sigue:
+
+\begin{verbatim}
+table ta { l in LOCALIDADES } OUT
+ 'MySQL'
+ 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'DROP TABLE IF EXISTS resultados;'
+ 'CREATE TABLE resultados ( ID INT, LOC VARCHAR(255), CANT DOUBLE );'
+ 'resultados' :
+ l ~ LOC, cantidad[l] ~ CANT, 4 ~ ID;
+\end{verbatim}
+
+El uso de plantillas con `\verb|?|' no sólo permite INSERT, sino también UPDATE, DELETE, etc. Por ejemplo:
+
+\begin{verbatim}
+table ta { l in LOCALIDADES } OUT
+ 'MySQL'
+ 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'UPDATE resultados SET FECHA = ' & fecha & ' WHERE ID = 4;'
+ 'UPDATE resultados SET CANT = ? WHERE LOC = ? AND ID = 4' :
+ cantidad[l], l;
+\end{verbatim}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Solución de modelos con glpsol}
+
+El paquete GLPK\footnote{{\tt http://www.gnu.org/software/glpk/}} incluye el programa {\tt glpsol}, un {\it solver} autónomo de PL/PEM. Este programa puede ser invocado desde la línea de comando o desde el {\it shell} para resolver modelos escritos en el lenguaje de modelado GNU MathProg.
+
+Para comunicarle al solver que el archivo de entrada contiene una descripción del modelo, es necesario especificar la opción \verb|--model| en la línea de comando. Por ejemplo:
+
+\begin{verbatim}
+ glpsol --model foo.mod
+\end{verbatim}
+
+A veces es necesario usar la sección de datos colocada en un archivo separado, en cuyo caso se debe usar el siguiente comando:
+
+\begin{verbatim}
+ glpsol --model foo.mod --data foo.dat
+\end{verbatim}
+
+\noindent Debe notarse que, si el archivo del modelo también contiene una sección de datos, esta sección será ignorada.
+
+También se permite especificar más de un archivo conteniendo la sección de datos, por ejemplo:
+
+\begin{verbatim}
+ glpsol --model foo.mod --data foo1.dat --data foo2.dat
+\end{verbatim}
+
+Si la descripción del modelo contiene algunas sentencias display y/o printf, por defecto la salida es enviada a la terminal. Si se necesita redirigir la salida a un archivo, se puede usar el siguiente comando:
+
+\begin{verbatim}
+ glpsol --model foo.mod --display foo.out
+\end{verbatim}
+
+Si se necesita inspeccionar el problema, el cual ha sido generado por el traductor del modelo, se puede usar la opción \verb|--wlp| como sigue:
+
+\begin{verbatim}
+ glpsol --model foo.mod --wlp foo.lp
+\end{verbatim}
+
+\noindent En este caso el problema se escribe en el archivo \verb|foo.lp|, en formato CPLEX LP apropiado para el análisis visual.
+
+\newpage
+
+A veces sólo se necesita chequear la descripción del modelo, sin resolver la instancia generada del problema. En este caso, se debe especificar la opción \verb|--check|, por ejemplo:
+
+\begin{verbatim}
+ glpsol --check --model foo.mod --wlp foo.lp
+\end{verbatim}
+
+Si se necesita escribir una solución numérica obtenida por el solver en un archivo, se puede usar el siguiente comando:
+
+\begin{verbatim}
+ glpsol --model foo.mod --output foo.sol
+\end{verbatim}
+
+\noindent en cuyo caso la solución se escribe en el archivo \verb|foo.sol| en formato de texto plano apropiado para el análisis visual.
+
+La lista completa de opciones de \verb|glpsol| se puede encontrar en el manual de referencia de GLPK incluido en la distribución de GLPK.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Ejemplo de descripción del modelo}
+
+\section{Descripción del modelo escrita en MathProg}
+
+Abajo hay un ejemplo completo de la descripción de un modelo escrito en el lenguaje de modelado GNU MathProg.
+
+\bigskip
+
+\begin{verbatim}
+# UN PROBLEMA DE TRANSPORTE
+#
+# Este problema determina la logística de costo mínimo de flete
+# que cumple los requerimientos en los mercados y en las fábricas
+# de suministro.
+#
+# Referencia:
+# Dantzig G B. 1963. Linear Programming and Extensions.
+# Princeton University Press, Princeton, New Jersey.
+# Sección 3-3.
+
+set I;
+/* plantas de enlatado */
+
+set J;
+/* mercados */
+
+param a{i in I};
+/* producción de la planta i, en cajas */
+
+param b{j in J};
+/* demanda en el mercado j, en cajas */
+
+param d{i in I, j in J};
+/* distancia, en miles de millas */
+
+param f;
+/* flete, en dólares por caja cada mil millas */
+
+param c{i in I, j in J} := f * d[i,j] / 1000;
+/* costo de transporte, en miles de dólares por caja */
+
+var x{i in I, j in J} >= 0;
+/* cantidades despachadas, en cajas */
+
+minimize costo: sum{i in I, j in J} c[i,j] * x[i,j];
+/* costo total de transporte, en miles de dólares */
+
+s.t. suministro{i in I}: sum{j in J} x[i,j] <= a[i];
+/* observar el límite de suministro de la planta i */
+
+s.t. demanda{j in J}: sum{i in I} x[i,j] >= b[j];
+/* satisfacer la demanda del mercado 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}
+
+%\newpage
+
+\section{Instancia generada del problema de PL}
+
+Abajo está el resultado de la traducción del modelo de ejemplo producido por el solver \verb|glpsol|, con la opción \verb|--wlp| y escrita en el formato CPLEX LP.
+
+\medskip
+
+\begin{verbatim}
+\* Problem: transporte *\
+
+Minimize
+ costo: + 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
+ suministro(Seattle): + x(Seattle,New~York) + x(Seattle,Chicago)
+ + x(Seattle,Topeka) <= 350
+ suministro(San~Diego): + x(San~Diego,New~York) + x(San~Diego,Chicago)
+ + x(San~Diego,Topeka) <= 600
+ demanda(New~York): + x(Seattle,New~York) + x(San~Diego,New~York) >= 325
+ demanda(Chicago): + x(Seattle,Chicago) + x(San~Diego,Chicago) >= 300
+ demanda(Topeka): + x(Seattle,Topeka) + x(San~Diego,Topeka) >= 275
+
+End
+\end{verbatim}
+
+\section{Solución óptima del problema de PL}
+
+Abajo está la solución óptima de la instancia generada del problema de PL encontrada por el solver \verb|glpsol|, con la opción \verb|--output| y escrita en formato de texto plano.
+
+\medskip
+
+%\begin{footnotesize}
+\begin{verbatim}
+Problem: transporte
+Rows: 6
+Columns: 6
+Non-zeros: 18
+Status: OPTIMAL
+Objective: costo = 153.675 (MINimum)
+
+ No. Row name St Activity Lower bound Upper bound Marginal
+------ ------------ -- ------------- ------------- ------------- -------------
+ 1 costo B 153.675
+ 2 suministro[Seattle]
+ NU 350 350 < eps
+ 3 suministro[San-Diego]
+ B 550 600
+ 4 demanda[New-York]
+ NL 325 325 0.225
+ 5 demanda[Chicago]
+ NL 300 300 0.153
+ 6 demanda[Topeka]
+ NL 275 275 0.126
+
+ No. Column name St Activity Lower bound Upper bound Marginal
+------ ------------ -- ------------- ------------- ------------- -------------
+ 1 x[Seattle,New-York]
+ B 50 0
+ 2 x[Seattle,Chicago]
+ B 300 0
+ 3 x[Seattle,Topeka]
+ NL 0 0 0.036
+ 4 x[San-Diego,New-York]
+ B 275 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{footnotesize}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section*{Reconocimientos}
+\addcontentsline{toc}{chapter}{Reconocimientos}
+
+Los autores desean agradecer a las siguientes personas, quienes amablemente leyeron, comentaron y corrigieron el borrador de este documento:
+
+\noindent Juan Carlos Borrás \verb|<borras@cs.helsinki.fi>|
+
+\noindent Harley Mackenzie \verb|<hjm@bigpond.com>|
+
+\noindent Robbie Morrison \verb|<robbie@actrix.co.nz>|
+
+\end{document}
diff --git a/glpk-5.0/doc/gmpl_pt-BR.pdf b/glpk-5.0/doc/gmpl_pt-BR.pdf
new file mode 100644
index 0000000..a2f25cb
--- /dev/null
+++ b/glpk-5.0/doc/gmpl_pt-BR.pdf
Binary files differ
diff --git a/glpk-5.0/doc/gmpl_pt-BR.tex b/glpk-5.0/doc/gmpl_pt-BR.tex
new file mode 100644
index 0000000..ee5723b
--- /dev/null
+++ b/glpk-5.0/doc/gmpl_pt-BR.tex
@@ -0,0 +1,7893 @@
+%* gmpl.tex *%
+
+%***********************************************************************
+% This code is part of GLPK (GNU Linear Programming Kit).
+%
+% Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+% 2009, 2010, 2011, 2013, 2014, 2015 Andrew Makhorin, Department for
+% Applied Informatics, Moscow Aviation Institute, Moscow, Russia. All
+% rights reserved. E-mail: <mao@gnu.org>.
+%
+% GLPK is free software: you can redistribute it and/or modify it
+% under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% GLPK is distributed in the hope that it will be useful, but WITHOUT
+% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+% License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with GLPK. If not, see <http://www.gnu.org/licenses/>.
+%***********************************************************************
+
+\documentclass[11pt, brazil]{report}
+\usepackage[utf8]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage{amssymb}
+\usepackage[dvipdfm,linktocpage,colorlinks,linkcolor=blue,
+urlcolor=blue]{hyperref}
+\usepackage{indentfirst}
+
+\setlength{\textwidth}{6.5in}
+\setlength{\textheight}{8.5in}
+\setlength{\oddsidemargin}{0in}
+\setlength{\topmargin}{0in}
+\setlength{\headheight}{0in}
+\setlength{\headsep}{0in}
+\setlength{\footskip}{0.5in}
+\setlength{\parindent}{16pt}
+\setlength{\parskip}{5pt}
+\setlength{\topsep}{0pt}
+\setlength{\partopsep}{0pt}
+\setlength{\itemsep}{\parskip}
+\setlength{\parsep}{0pt}
+\setlength{\leftmargini}{\parindent}
+\renewcommand{\labelitemi}{---}
+
+\def\para#1{\noindent{\bf#1}}
+
+\renewcommand\contentsname{\sf\bfseries Conteúdo}
+\renewcommand\chaptername{\sf\bfseries Capítulo}
+\renewcommand\appendixname{\sf\bfseries Apêndice}
+
+% \renewcommand\contentsname{\sf\bfseries Contents}
+% \renewcommand\chaptername{\sf\bfseries Chapter}
+% \renewcommand\appendixname{\sf\bfseries Appendix}
+
+\begin{document}
+
+\thispagestyle{empty}
+
+\begin{center}
+
+\vspace*{1.5in}
+
+\begin{huge}
+\sf\bfseries Linguagem de Modelagem GNU MathProg
+\end{huge}
+
+\vspace{0.5in}
+
+\begin{LARGE}
+\sf Linguagem de Referência % Language Reference
+\end{LARGE}
+
+\vspace{0.5in}
+
+\begin{LARGE}
+\sf para o GLPK Versão 4.57
+\end{LARGE}
+
+\vspace{0.5in}
+\begin{Large}
+\sf (RASCUNHO, Fevereiro 2016)
+\end{Large}
+
+\end{center}
+
+\newpage
+
+\vspace*{1in}
+
+\vfill
+
+\noindent
+% The GLPK package is part of the GNU Project released under the aegis of GNU.
+O pacote GLPK é parte do Projeto GNU distribuído sob a égide do GNU.
+
+\noindent
+Copyright \copyright{} 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016 Andrew Makhorin, Department
+for Applied Informatics, Moscow Aviation Institute, Moscow, Russia.
+% All rights reserved.
+Todos os direitos reservados.
+
+\noindent
+Título original: Modeling Language GNU MathProg - Language Reference for GLPK Version 4.57
+
+\noindent
+Tradução: João Flávio de Freitas Almeida, Departamento de Engenharia de Produção, Universidade Federal de Minas Gerais,
+Minas Gerais, Brasil.
+
+\noindent
+Copyright \copyright{} 2015 João Flávio de Freitas Almeida, para esta tradução. Todos os direitos reservados.
+
+\noindent
+Free Software Foundation, Inc., Rua Franklin, 51, 5$^{o}$ andar, Boston,
+MA 02110-1301, USA.
+
+\noindent
+É permitido realizar e distribuir cópias textuais deste manual
+mantendo o aviso de copyright e preservando este aviso de permissão
+em todas as cópias.
+% 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.
+
+\noindent
+É concedida a permissão para copiar e distribuir versões modificadas deste manual sob
+as condições de cópias textuais, desde que o resultado completo derivado
+do trabalho resultante seja distribuído sob os termos de uma notificação
+de permissão idêntica a esta.
+
+% 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.
+
+\noindent
+É concedida a permissão para copiar e distribuir traduções deste manual
+em outra linguagem, sob as condições acima para as versões modificadas.
+
+% Permission is granted to copy and distribute translations of this
+% manual into another language, under the above conditions for modified
+% versions.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+{\setlength{\parskip}{0pt}
+\tableofcontents
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Introdução}
+
+{\it GNU MathProg} é uma linguagem de modelagem projetada para descrever
+modelos lineares de programação matemática.
+\footnote{A linguagem GNU MathProg é um subconjunto da linguagem AMPL.
+A implementação do GLPK é \linebreak principalmente baseada no artigo:
+{\it Robert Fourer}, {\it David M. Gay}, and
+{\it Brian W. Kernighan}, ``A Modeling Language for Mathematical
+Programming.'' {\it Management Science} 36 (1990), pp.~519-54.}
+
+% {\it 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: {\it Robert Fourer}, {\it David M. Gay}, and
+% {\it Brian W. Kernighan}, ``A Modeling Language for Mathematical
+% Programming.'' {\it Management Science} 36 (1990), pp.~519-54.}
+
+A descrição de um modelo escrito na linguagem GNU MathProg consiste
+em um conjunto de sentenças e blocos de dados construído pelo
+usuário a partir dos elementos de linguagem descritos neste documento.
+
+
+% 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.
+
+Em um processo denominado {\it tradução}, um programa denominado
+{\it tradutor do modelo} analisa a descrição do modelo e o traduz
+para uma estrutura de dados interna, que pode ser usado tanto para gerar
+instância de um problema de programação matemática ou obter diretamente
+a solução numérica do problema por meio de um programa chamado {\it solver}.
+
+% In a process called {\it translation}, a program called the {\it 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 {\it solver} to obtain numeric solution of the problem.
+
+\section{Problema de programação linear}
+\label{problem}
+
+Em MathProg o problema de programação linear (PL) é expresso da seguinte forma:
+
+% In MathProg the linear programming (LP) problem is stated as follows:
+
+\medskip
+
+\noindent\hspace{1in}minimizar (ou maximizar)
+$$z=c_1x_1+c_2x_2+\dots+c_nx_n+c_0\eqno(1.1)$$
+\noindent\hspace{1in}subjeito às restrições lineares
+$$
+\begin{array}{l@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }l}
+L_1&\leq&a_{11}x_1&+&a_{12}x_2&+\dots+&a_{1n}x_n&\leq&U_1\\
+L_2&\leq&a_{21}x_1&+&a_{22}x_2&+\dots+&a_{2n}x_n&\leq&U_2\\
+\multicolumn{9}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\
+L_m&\leq&a_{m1}x_1&+&a_{m2}x_2&+\dots+&a_{mn}x_n&\leq&U_m\\
+\end{array}\eqno(1.2)
+$$
+\noindent\hspace{1in}e os limites das variáveis
+$$
+\begin{array}{l@{\ }c@{\ }c@{\ }c@{\ }l}
+l_1&\leq&x_1&\leq&u_1\\
+l_2&\leq&x_2&\leq&u_2\\
+\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .}\\
+l_n&\leq&x_n&\leq&u_n\\
+\end{array}\eqno(1.3)
+$$
+
+% \newpage
+
+\noindent
+onde $x_1$, $x_2$, \dots, $x_n$ são variáveis; $z$ é a função objetivo
+; $c_1$, $c_2$, \dots, $c_n$ são coeficientes da função objetivo; $c_0$
+é o termo constante da função objetivo; $a_{11}$,
+$a_{12}$, \dots, $a_{mn}$ são coeficientes das restrições; $L_1$, $L_2$,
+\dots, $L_m$ são limites inferiores das restrições; $U_1$, $U_2$, \dots, $U_m$
+são limites superiores das restrições; $l_1$, $l_2$, \dots, $l_n$ são limites
+inferiores das variáveis; $u_1$, $u_2$, \dots, $u_n$ são limites superiores das
+variáveis.
+
+Os limites das variáveis e das restrições podem ser tanto finitos quanto
+infinitos. Além disso, os limites inferiores podem ser igual aos limites
+superiores correspondentes. Logo, os seguintes tipos de variáveis e
+restrições são permitidos:
+
+
+% where $x_1$, $x_2$, \dots, $x_n$ are variables; $z$ is the objective
+% function; $c_1$, $c_2$, \dots, $c_n$ are objective coefficients; $c_0$
+% is the constant term (``shift'') of the objective function; $a_{11}$,
+% $a_{12}$, \dots, $a_{mn}$ are constraint coefficients; $L_1$, $L_2$,
+% \dots, $L_m$ are lower constraint bounds; $U_1$, $U_2$, \dots, $U_m$
+% are upper constraint bounds; $l_1$, $l_2$, \dots, $l_n$ are lower
+% bounds of variables; $u_1$, $u_2$, \dots, $u_n$ are upper bounds of
+% variables.
+%
+% 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:
+
+\medskip
+
+{\def\arraystretch{1.4}
+\noindent\hspace{54pt}
+\begin{tabular}{@{}r@{\ }c@{\ }c@{\ }c@{\ }l@{\hspace*{39.5pt}}l}
+$-\infty$&$<$&$x$&$<$&$+\infty$&Variável livre (ilimitada)\\
+$l$&$\leq$&$x$&$<$&$+\infty$&Variável com limite inferior\\
+$-\infty$&$<$&$x$&$\leq$&$u$&Variável com limite superior\\
+$l$&$\leq$&$x$&$\leq$&$u$&Variável duplamente limitada\\
+$l$&$=$&$x$&=&$u$&Variável fixa\\
+\end{tabular}
+% \begin{tabular}{@{}r@{\ }c@{\ }c@{\ }c@{\ }l@{\hspace*{39.5pt}}l}
+% $-\infty$&$<$&$x$&$<$&$+\infty$&Free (unbounded) variable\\
+% $l$&$\leq$&$x$&$<$&$+\infty$&Variable with lower bound\\
+% $-\infty$&$<$&$x$&$\leq$&$u$&Variable with upper bound\\
+% $l$&$\leq$&$x$&$\leq$&$u$&Double-bounded variable\\
+% $l$&$=$&$x$&=&$u$&Fixed variable\\
+% \end{tabular}
+
+\noindent\hfil
+\begin{tabular}{@{}r@{\ }c@{\ }c@{\ }c@{\ }ll}
+$-\infty$&$<$&$\sum a_jx_j$&$<$&$+\infty$&Forma linear livre (ilimitada)\\
+$L$&$\leq$&$\sum a_jx_j$&$<$&$+\infty$&Restrição de desigualdade ``maior ou igual a''\\
+$-\infty$&$<$&$\sum a_jx_j$&$\leq$&$U$&Restrição de desigualdade ``menor ou igual a''\\
+$L$&$\leq$&$\sum a_jx_j$&$\leq$&$U$&Restrição de desigualdade duplamente limitada\\
+$L$&$=$&$\sum a_jx_j$&=&$U$&Restrição de igualdade\\
+\end{tabular}
+% \begin{tabular}{@{}r@{\ }c@{\ }c@{\ }c@{\ }ll}
+% $-\infty$&$<$&$\sum a_jx_j$&$<$&$+\infty$&Free (unbounded) linear
+% form\\
+% $L$&$\leq$&$\sum a_jx_j$&$<$&$+\infty$&Inequality constraint ``greater
+% than or equal to''\\
+% $-\infty$&$<$&$\sum a_jx_j$&$\leq$&$U$&Inequality constraint ``less
+% than or equal to''\\
+% $L$&$\leq$&$\sum a_jx_j$&$\leq$&$U$&Double-bounded inequality
+% constraint\\
+% $L$&$=$&$\sum a_jx_j$&=&$U$&Equality constraint\\
+% \end{tabular}
+}
+
+\medskip
+
+Além de problemas puramente PL, MathProg também permite
+problemas de programação inteira mista (PIM), onde algumas ou
+todas as variáveis são restritas a serem inteiras ou binárias.
+
+% In addition to pure LP problems MathProg also allows mixed integer
+% linear programming (MIP) problems, where some or all variables are
+% restricted to be integer or binary.
+
+\section{Objetos do modelo}
+
+Em MathProg o modelo é descrito em termos de conjuntos, parâmetros,
+variáveis, restrições e objetivos, que se denominam {\it objetos
+do modelo}.
+
+O usuário introduz objetos particulares do modelo usando as sentenças
+da linguagem. Cada objeto do modelo possui um nome simbólico que o identifica
+de maneira única sendo projetado para propósitos de referenciação.
+
+% In MathProg the model is described in terms of sets, parameters,
+% variables, constraints, and objectives, which are called {\it model
+% objects}.
+%
+% The user introduces particular model objects using the language
+% statements. Each model object is provided with a symbolic name which
+% uniquely identifies the object and is intended for referencing
+% purposes.
+
+Objetos do modelo, incluindo conjuntos, podem ser matrizes multidimensionais
+construídos sobre conjuntos indexantes. Formalmente, uma matriz $n$-dimensional $A$
+é o mapeamento:
+% Model objects, including sets, can be multidimensional arrays built
+% over indexing sets. Formally, $n$-dimensional array $A$ is the mapping:
+$$A:\Delta\rightarrow\Xi,\eqno(1.4)$$
+onde $\Delta\subseteq S_1\times\dots\times S_n$ é um subconjunto do
+produto Cartesiano de conjuntos indexantes, $\Xi$ é um conjunto dos
+membros da matriz. Em MathProg o conjunto $\Delta$ é chamado o {\it domínio do subíndice}. % REVISAR
+Seus membros são $n$-tuplas $(i_1,\dots,i_n)$, onde $i_1\in S_1$, \dots,
+$i_n\in S_n$.
+% where $\Delta\subseteq S_1\times\dots\times S_n$ is a subset of the
+% Cartesian product of indexing sets, $\Xi$ is a set of array members.
+% In MathProg the set $\Delta$ is called the {\it subscript domain}. Its
+% members are $n$-tuples $(i_1,\dots,i_n)$, where $i_1\in S_1$, \dots,
+% $i_n\in S_n$.
+
+Se $n=0$, o produto Cartesiano acima possui exatamente um membro (denominado
+0-tupla), portanto, é conveniente pensar nos objetos escalares como sendo
+matrizes 0-dimensionais que \linebreak possuem apenas um membro.
+% If $n=0$, the Cartesian product above has exactly one member (namely,
+% 0-tuple), so it is convenient to think scalar objects as 0-dimensional
+% arrays having one member.
+
+% \newpage
+
+O tipo dos membros da matriz é determinado pelo tipo de objeto do modelo
+correspondente, como segue:
+% The type of array members is determined by the type of corresponding
+% model object as follows:
+
+\medskip
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Objeto do modelo&Membro da matriz\\
+\hline
+Conjunto&Conjunto plano elementar\\
+Parâmetro&Número ou símbolo\\
+Variável&Variável elementar\\
+Restrição&Restrição elementar\\
+Objetivo&Objetivo elementar\\
+\end{tabular}
+% \begin{tabular}{@{}ll@{}}
+% Model object&Array member\\
+% \hline
+% Set&Elemental plain set\\
+% Parameter&Number or symbol\\
+% Variable&Elemental variable\\
+% Constraint&Elemental constraint\\
+% Objective&Elemental objective\\
+% \end{tabular}
+
+\medskip
+
+Para referir a um membro particular de um objeto, este deve possuir
+{\it subíndices}. Por exemplo, se $a$ é um parâmetro 2-dimensional
+definido sobre $I\times J$, uma referência a seus membros particulares
+pode ser escrito como $a[i,j]$, onde $i\in I$ e $j\in J$. Entende-se
+que objetos escalares não necessitam de subíndices por serem 0-dimensionais.
+
+% In order to refer to a particular object member the object should be
+% provided with {\it subscripts}. For example, if $a$ is a 2-dimensional
+% parameter defined over $I\times J$, a reference to its particular
+% member can be written as $a[i,j]$, where $i\in I$ and $j\in J$. It is
+% understood that scalar objects being 0-dimensional need no subscripts.
+
+\section{Estrutura da descrição do modelo}
+
+Às vezes é desejável escrever um modelo que, por diferentes motivos,
+tenha que requerer diferentes dados para resolver cada instância do problema
+usando o mesmo modelo.
+Por esta razão, em MathProg a descrição do modelo consiste em duas partes:
+a {\it seção de modelo} e a {\it seção de dados}.
+
+% It is sometimes desirable to write a model which, at various points,
+% may require different data for each problem instance to be solved using
+% that model. For this reason in MathProg the model description consists
+% of two parts: the {\it model section} and the {\it data section}.
+
+A seção de modelo é a principal parte da descrição do modelo, pois ela contém
+as declarações dos objetos do modelo. Ela também é comum a todos os problemas
+baseados no modelo correspondente.
+
+% The 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.
+
+A seção de dados é uma parte opcional da descrição do modelo que
+contém dados específicos para uma instância particular do problema.
+
+% The data section is an optional part of the model description that
+% contains data specific for a particular problem instance.
+
+Dependendo do que seja mais conveniente, as seções de modelo e de dados
+podem ser dispostas em um arquivo único ou em dois arquivos separados.
+Esta última funcionalidade permite que se tenha um quantidade arbitrária
+de seções de dados diferentes a serem usadas com a mesma seção de modelo.
+
+% Depending on what is more convenient the model and data sections can be
+% placed either in one file or in two separate files. The latter feature
+% allows having arbitrary number of different data sections to be used
+% with the same model section.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Codificação da descrição do modelo}
+\label{coding}
+
+A descrição do modelo é codificada em um formato de arquivo plano de
+texto usando o conjunto de caracteres ASCII.
+Os caracteres válidos na descrição do modelo são os seguintes:
+
+% The model description is coded in a plain text format using ASCII
+% character set. Characters valid in the model description are the
+% following:
+
+\begin{itemize}
+\item Caracteres alfabéticos:\\
+\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 _|
+\item caracteres numéricos:\\
+\verb|0 1 2 3 4 5 6 7 8 9|
+\item caracteres especiais:\\
+\verb?! " # & ' ( ) * + , - . / : ; < = > [ ] ^ { | } ~?
+\item caracteres de espaço em branco:\\
+\verb|SP HT CR NL VT FF|
+\end{itemize}
+
+Dentro de literais de cadeia e comentários quaisquer
+caracteres ASCII (exceto caracteres de controle) são válidos.
+
+% Within string literals and comments any ASCII characters (except
+% control characters) are valid.
+
+
+Caracteres de espaço-em-branco não são significativos. Eles podem ser
+usados livremente entre unidades léxicas para melhorar a legibilidade da
+descrição do modelo. Eles também são usados para separar unidades léxicas
+entre si, no caso de não existir outra forma de fazê-lo.
+
+% 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.
+
+Sintaticamente a descrição do modelo é uma sequência de unidades léxicas
+nas seguintes \linebreak categorias:
+
+% Syntactically model description is a sequence of lexical units in the
+% following categories:
+
+\begin{itemize}
+\item nomes simbólicos;
+\item literais numéricos;
+\item literais de cadeia;
+\item palavras-chave;
+\item delimitadores;
+\item comentários.
+\end{itemize}
+
+% \begin{itemize}
+% \item symbolic names;
+% \item numeric literals;
+% \item string literals;
+% \item keywords;
+% \item delimiters;
+% \item comments.
+% \end{itemize}
+
+As unidades léxicas da linguagem são discutidas abaixo.
+
+% \newpage
+
+\section{Nomes simbólicos}
+
+Um {\it nome simbólico} consiste de caracteres alfabéticos e numéricos,
+em que o primeiro deste deve ser alfabético. Todos os nomes simbólicos
+devem ser distintos (sensibilidade às maiúsculas: case-sensitive).
+
+% A {\it symbolic name} consists of alphabetic and numeric characters,
+% the first of which should be alphabetic. All symbolic names are
+% distinct (case sensitive).
+
+\para{Exemplos}
+
+\begin{verbatim}
+alfa123
+Este_eh_um_nome
+_P123_abc_321
+\end{verbatim}
+
+Nomes simbólicos são usados para identificar objetos do modelo
+(conjuntos, parâmetros, \linebreak variáveis, restrições, objetivos)
+e os índices.
+
+% Symbolic names are used to identify model objects (sets, parameters,
+% variables, constraints, objectives) and dummy indices.
+
+Todos os nomes simbólicos (exceto os nomes dos índices) devem ser únicos,
+i.e., a descrição do modelo não pode ter objetos com nomes idênticos.
+Nomes simbólicos de índices devem ser únicos dentro do escopo em que são válidos.
+
+% All symbolic names (except names of dummy indices) should be unique,
+% i.e. the model description should have no objects with identical names.
+% Symbolic names of dummy indices should be unique within the scope,
+% where they are valid.
+
+\section{Literais numéricos}
+
+Um {\it literal numérico} possui a forma {\it xx}{\tt E}{\it syy}, onde
+{\it xx} é um número com ponto decimal opcional, {\it s} é o sinal
+{\tt+} ou {\tt-}, {\it yy} é um expoente decimal. A letra {\tt E} é
+insensível à maiúsculas (case-insensitive) e pode ser codificada como {\tt e}.
+
+% A {\it numeric literal} has the form {\it xx}{\tt E}{\it syy}, where
+% {\it xx} is a number with optional decimal point, {\it s} is the sign
+% {\tt+} or {\tt-}, {\it yy} is a decimal exponent. The letter {\tt E} is
+% case insensitive and can be coded as {\tt e}.
+
+\para{Exemplos}
+
+\begin{verbatim}
+123
+3.14159
+56.E+5
+.78
+123.456e-7
+\end{verbatim}
+
+Literais numéricos são usados para representar quantidades numéricas. Eles
+possuem significado fixo óbvio.
+
+% Numeric literals are used to represent numeric quantities. They have
+% obvious fixed meaning.
+
+\section{Literais de cadeia}
+
+Uma {\it literal de cadeia} é uma sequência arbitrária de caracteres cercada
+por aspas tanto simples como duplas. Ambas formas são equivalentes.
+
+% A {\it string literal} is a sequence of arbitrary characters enclosed
+% either in single quotes or in double quotes. Both these forms are
+% equivalent.
+
+Se uma aspa simples é parte de uma literal de cadeia cercada por
+aspas simples, ela deve ser codificada duas vezes. De forma análoga,
+se uma aspa dupla é parte de um literal de cadeia cercada por aspas duplas,
+ela deve ser codificada duas vezes.
+
+% If a single quote is part of a string literal enclosed in single
+% quotes, it should be coded twice. Analogously, if a double quote is
+% part of a string literal enclosed in double quotes, it should be coded
+% twice.
+
+\para{Exemplos}
+
+\begin{verbatim}
+'Esta eh uma string'
+"Esta eh outra string"
+'Copo d''agua'
+"""Beleza"" disse o capitao."
+\end{verbatim}
+
+Literais de cadeia são usadas para representar quantidades simbólicas.
+% String literals are used to represent symbolic quantities.
+
+\section{Palavras-chave}
+
+Uma {\it palavra-chave} é uma sequência de caracteres alfabéticos e
+possivelmente alguns caracteres especiais.
+
+% A {\it keyword} is a sequence of alphabetic characters and possibly
+% some special characters.
+
+Todas as palavras-chave caem em algumas das duas categorias:
+{\it palavras-chave reservadas}, que não podem ser usadas como nomes simbólicos,
+e {\it palavras-chave não-reservadas}, que são reconhecidas pelo contexto,
+portanto, podem ser usadas como nomes simbólicos.
+
+
+As palavras-chave reservadas são as seguintes:
+
+% All keywords fall into two categories: {\it reserved keywords}, which
+% cannot be used as symbolic names, and {\it non-reserved keywords},
+% which are recognized by context and therefore can be used as symbolic
+% names.
+%
+% The reserved keywords are the following:
+
+\noindent\hfil
+\begin{tabular}{@{}p{.7in}p{.7in}p{.7in}p{.7in}@{}}
+{\tt and}&{\tt else}&{\tt mod}&{\tt union}\\
+{\tt by}&{\tt if}&{\tt not}&{\tt within}\\
+{\tt cross}&{\tt in}&{\tt or}\\
+{\tt diff}&{\tt inter}&{\tt symdiff}\\
+{\tt div}&{\tt less}&{\tt then}\\
+\end{tabular}
+
+Palavras-chave não-reservadas são descritas nas seções posteriores.
+
+Todas as palavras-chave possuem um significado fixo, a ser
+explicado nas discussões das \linebreak construções sintáticas correspondentes,
+onde as palavras-chave são usadas.
+
+% 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.
+
+\section{Delimitadores}
+
+Um {\it delimitador} é tanto um caractere especial único quanto uma sequência
+de dois caracteres especiais, como segue:
+
+% A {\it delimiter} is either a single special character or a sequence of
+% two special characters as follows:
+
+\noindent\hfil
+\begin{tabular}{@{}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}
+p{.3in}p{.3in}@{}}
+{\tt+}&{\tt**}&{\tt<=}&{\tt>}&{\tt\&\&}&{\tt:}&{\tt|}&{\tt[}&
+{\tt>>}\\
+{\tt-}&{\tt\textasciicircum}&{\tt=}&{\tt<>}&{\tt||}&{\tt;}&
+{\tt\char126}&{\tt]}&{\tt<-}\\
+{\tt*}&{\tt\&}&{\tt==}&{\tt!=}&{\tt.}&{\tt:=}&{\tt(}&{\tt\{}\\
+{\tt/}&{\tt<}&{\tt>=}&{\tt!}&{\tt,}&{\tt..}&{\tt)}&{\tt\}}\\
+\end{tabular}
+
+Se um delimitador consiste de dois caracteres, não deve haver espaços
+entre os eles.
+
+Todos os delimitadores possuem um significado fixo, a ser
+explicado nas discussões das \linebreak construções sintáticas correspondentes,
+onde os delimitadores são usados.
+
+% If the delimiter consists of two characters, there should 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.
+
+\section{Comentários}
+
+Com propósitos de documentação, a descrição do modelo pode conter
+{\it comentários}, que podem ter duas formas diferentes. A primeira forma é
+um {\it comentário de linha-única}, que começa com o caractere {\tt\#}
+e se estende até o final da linha. A segunda forma é uma {\it sequência de
+comentários}, que é uma sequência de quaisquer caracteres cercados por
+{\tt/*} e {\tt*/}.
+
+% For documenting purposes the model description can be provided with
+% {\it comments}, which may have two different forms. The first form is
+% a {\it single-line comment}, which begins with the character {\tt\#}
+% and extends until end of line. The second form is a {\it comment
+% sequence}, which is a sequence of any characters enclosed within
+% {\tt/*} and {\tt*/}.
+
+\para{Exemplos}
+
+\begin{verbatim}
+param n := 10; # Este é um comentario
+/* Este é outro comentário */
+\end{verbatim}
+
+Comentários e caracteres de espaço-em-branco são ignorados pelo tradutor
+do modelo e podem aparecer em qualquer local da descrição do modelo.
+
+% Comments are ignored by the model translator and can appear anywhere in
+% the model description, where white-space characters are allowed.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\chapter{Expressões}
+
+Uma {\it expressão} é uma regra para calcular um valor. Na descrição
+de um modelo, expressões são usadas como constituintes de certas sentenças.
+
+No geral, expressões são constituídas de operandos e operadores.
+
+Dependendo do tipo de valor resultante, todas expressões se enquadram nas
+seguintes categorias:
+
+% An {\it 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:
+
+\vspace*{-8pt}
+
+\begin{itemize}
+\item expressões numéricas;
+\item expressões simbólicas;
+\item expressões indexantes;
+\item expressões de conjuntos;
+\item expressões lógicas;
+\item expressões lineares.
+\end{itemize}
+
+% \begin{itemize}
+% \item numeric expressions;
+% \item symbolic expressions;
+% \item indexing expressions;
+% \item set expressions;
+% \item logical expressions;
+% \item linear expressions.
+% \end{itemize}
+
+\vspace*{-8pt}
+
+\section{Expressões numéricas}
+
+Uma {\it expressão numérica} é uma regra para calcular um valor numérico individual
+representado como um número de ponto-flutuante.
+
+A expressão numérica primária pode ser um literal numérico, um índice,
+um parâmetro não-indexado, um parâmetro indexado, uma função interna de
+referência, uma expressão numérica iterada, uma expressão numérica condicional
+ou outra expressão cercada por parênteses.
+
+% A {\it numeric expression} is a rule for computing a single numeric
+% value represented as a 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.
+
+\para{Exemplos}
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|1.23 |&(literal numérico)\\
+\verb|j|&(índice)\\
+\verb|time|&(parâmetro não-indexado)\\
+\verb|a['May 2003',j+1]|&(parâmetro indexado)\\
+\verb|abs(b[i,j])|&(função de referência)\\
+\end{tabular}
+
+% \begin{tabular}{@{}ll@{}}
+% \verb|1.23 |&(numeric literal)\\
+% \verb|j|&(dummy index)\\
+% \verb|time|&(unsubscripted parameter)\\
+% \verb|a['May 2003',j+1]|&(subscripted parameter)\\
+% \verb|abs(b[i,j])|&(function reference)\\
+% \end{tabular}
+
+\newpage
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|sum{i in S diff T} alpha[i] * b[i,j]|&(expressão iterada)\\
+\verb|if i in I then 2 * p else q[i+1]|&(expressão condicional)\\
+\verb|(b[i,j] + .5 * c)|&(expressão entre parênteses)\\
+\end{tabular}
+
+% \begin{tabular}{@{}ll@{}}
+% \verb|sum{i in S diff T} alpha[i] * b[i,j]|&(iterated expression)\\
+% \verb|if i in I then 2 * p else q[i+1]|&(conditional expression)\\
+% \verb|(b[i,j] + .5 * c)|&(parenthesized expression)\\
+% \end{tabular}
+
+Expressões numéricas mais genéricas, contendo duas ou mais
+expressões numéricas primárias, podem ser construídas usando
+determinados operadores aritméticos.
+
+% More general numeric expressions containing two or more primary numeric
+% expressions may be constructed by using certain arithmetic operators.
+
+\para{Exemplos}
+
+\begin{verbatim}
+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 and p >= 1 then 2 * p else q[i+1]) / (a[i,j] + 1.5)
+\end{verbatim}
+
+\subsection{Literais numéricos}
+
+Se a expressão numérica primária é um literal numérico,
+o valor resultante é óbvio.
+
+% If the primary numeric expression is a numeric literal, the resultant
+% value is obvious.
+
+\subsection{Índices}
+
+Se a expressão numérica primária é um índice,
+o valor resultante é o valor corrente atribuído àquele índice.
+
+% If the primary numeric expression is a dummy index, the resultant value
+% is current value assigned to that dummy index.
+
+\subsection{Parâmetros não-indexados}
+
+Se a expressão numérica primária é um parâmetro não-indexado
+(que deve ser 0-dimensional), o valor resultante é o valor
+do parâmetro.
+
+% If the primary numeric expression is an unsubscripted parameter (which
+% should be 0-dimen\-sional), the resultant value is the value of that
+% parameter.
+
+\subsection{Parâmetros indexados}
+
+A expressão numérica primária, que se refere ao parâmetro indexado,
+possui a seguinte forma sintática:
+% The primary numeric expression, which refers to a subscripted
+% parameter, has the following syntactic form:
+$$
+\mbox{{\it nome}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,} $i_n${\tt]}}
+$$
+onde {\it nome} é o nome simbólico do parâmetro e $i_1$, $i_2$,
+\dots, $i_n$ são subíndices.
+
+Cada subíndice deve ser uma expressão numérica ou simbólica. O número
+de subíndices na lista de subíndices deve ser o mesmo da dimensão
+do parâmetro com o qual a lista de subíndices está associada.
+
+Os valores reais das expressões de subíndice são usadas para identificar
+um membro particular do parâmetro que determina o valor resultante
+da expressão primária.
+
+% where {\it name} is the symbolic name of the parameter, $i_1$, $i_2$,
+% \dots, $i_n$ are subscripts.
+%
+% Each subscript should be a numeric or symbolic expression. The number
+% of subscripts in the subscript list should 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.
+
+\newpage
+
+\subsection{Funções de referência}
+
+Em MathProg existem as seguintes funções internas, que podem ser
+usadas como expressões numéricas:
+
+% In MathProg there exist the following built-in functions which may be
+% used in numeric expressions:
+
+\begin{tabular}{@{}p{112pt}p{328pt}@{}}
+{\tt abs(}$x${\tt)}&$|x|$, valor absoluto de $x$\\
+{\tt atan(}$x${\tt)}&$\arctan x$, valor principal do arco tangente de
+$x$ (em radianos)\\
+{\tt atan(}$y${\tt,} $x${\tt)}&$\arctan y/x$, valor principal do
+arco tangente de $y/x$ (em radianos). Neste caso, os sinais de ambos
+argumentos $y$ e $x$ são usados para determinar o quadrante do valor
+resultante\\
+{\tt card(}$X${\tt)}&$|X|$, cardinalidade (o número de elementos) do
+conjunto $X$\\
+{\tt ceil(}$x${\tt)}&$\lceil x\rceil$, menor inteiro não menor que
+$x$ (``teto de $x$'')\\
+{\tt cos(}$x${\tt)}&$\cos x$, cosseno de $x$ (em radianos)\\
+{\tt exp(}$x${\tt)}&$e^x$, exponencial de $x$ na base-$e$\\
+{\tt floor(}$x${\tt)}&$\lfloor x\rfloor$, maior inteiro não maior
+que $x$ (``piso de $x$'')\\
+{\tt gmtime()}&o número de segundos decorridos deste 00:00:00 de~01~de~Jan de 1970,
+Tempo Universal Coordenado (detalhes na Seção \ref{gmtime},
+página \pageref{gmtime})\\
+{\tt length(}$s${\tt)}&$|s|$, comprimento da cadeia de caracteres $s$\\
+{\tt log(}$x${\tt)}&$\log x$, logaritmo natural de $x$\\
+{\tt log10(}$x${\tt)}&$\log_{10}x$, logaritmo comum (decimal) de $x$\\
+{\tt max(}$x_1${\tt,} $x_2${\tt,} \dots{\tt,} $x_n${\tt)}&o maior
+dos valores $x_1$, $x_2$, \dots, $x_n$\\
+{\tt min(}$x_1${\tt,} $x_2${\tt,} \dots{\tt,} $x_n${\tt)}&o menor
+dos valores $x_1$, $x_2$, \dots, $x_n$\\
+{\tt round(}$x${\tt)}&arrendondamento de $x$ ao inteiro mais próximo\\
+{\tt round(}$x${\tt,} $n${\tt)}&arrendondamento de $x$ a $n$ dígitos decimais\\
+{\tt sin(}$x${\tt)}&$\sin x$, seno de $x$ (em radianos)\\
+{\tt sqrt(}$x${\tt)}&$\sqrt{x}$, raiz quadrada não-negativa de $x$\\
+{\tt str2time(}$s${\tt,} $f${\tt)}&conversão de uma cadeia de caracteres $s$ ao
+tempo calendário (detalhes na Seção \ref{str2time}, página
+\pageref{str2time})\\
+{\tt trunc(}$x${\tt)}&truncado de $x$ ao inteiro mais próximo\\
+{\tt trunc(}$x${\tt,} $n${\tt)}&truncado de $x$ a $n$ dígitos decimais\\
+{\tt Irand224()}&gera inteiro pseudo-aleatório uniformemente distribuído
+em $[0,2^{24})$\\
+{\tt Uniform01()}&gera número pseudo-aleatório uniformemente distribuído
+em $[0,1)$\\
+{\tt Uniform(}$a${\tt,} $b${\tt)}&gera número pseudo-aleatório uniformemente
+distribuído em $[a,b)$\\
+{\tt Normal01()}&gera variável Gaussiana pseudo-aleatória com
+$\mu=0$ e $\sigma=1$\\
+{\tt Normal(}$\mu${\tt,} $\sigma${\tt)}&gera variável Gaussiana pseudo-aleatória
+com $\mu$ e $\sigma$ dados\\
+\end{tabular}
+
+% \begin{tabular}{@{}p{112pt}p{328pt}@{}}
+% {\tt abs(}$x${\tt)}&$|x|$, absolute value of $x$\\
+% {\tt atan(}$x${\tt)}&$\arctan x$, principal value of the arc tangent of
+% $x$ (in radians)\\
+% {\tt atan(}$y${\tt,} $x${\tt)}&$\arctan y/x$, principal value of the
+% arc tangent of $y/x$ (in radians). In this case the signs of both
+% arguments $y$ and $x$ are used to determine the quadrant of the
+% resultant value\\
+% {\tt card(}$X${\tt)}&$|X|$, cardinality (the number of elements) of
+% set $X$\\
+% {\tt ceil(}$x${\tt)}&$\lceil x\rceil$, smallest integer not less than
+% $x$ (``ceiling of $x$'')\\
+% {\tt cos(}$x${\tt)}&$\cos x$, cosine of $x$ (in radians)\\
+% {\tt exp(}$x${\tt)}&$e^x$, base-$e$ exponential of $x$\\
+% {\tt floor(}$x${\tt)}&$\lfloor x\rfloor$, largest integer not greater
+% than $x$ (``floor of $x$'')\\
+% {\tt gmtime()}&the number of seconds elapsed since 00:00:00~Jan~1, 1970,
+% Coordinated Universal Time (for details see Section \ref{gmtime},
+% page \pageref{gmtime})\\
+% {\tt length(}$s${\tt)}&$|s|$, length of character string $s$\\
+% {\tt log(}$x${\tt)}&$\log x$, natural logarithm of $x$\\
+% {\tt log10(}$x${\tt)}&$\log_{10}x$, common (decimal) logarithm of $x$\\
+% {\tt max(}$x_1${\tt,} $x_2${\tt,} \dots{\tt,} $x_n${\tt)}&the largest
+% of values $x_1$, $x_2$, \dots, $x_n$\\
+% {\tt min(}$x_1${\tt,} $x_2${\tt,} \dots{\tt,} $x_n${\tt)}&the smallest
+% of values $x_1$, $x_2$, \dots, $x_n$\\
+% {\tt round(}$x${\tt)}&rounding $x$ to nearest integer\\
+% {\tt round(}$x${\tt,} $n${\tt)}&rounding $x$ to $n$ fractional decimal
+% digits\\
+% {\tt sin(}$x${\tt)}&$\sin x$, sine of $x$ (in radians)\\
+% {\tt sqrt(}$x${\tt)}&$\sqrt{x}$, non-negative square root of $x$\\
+% {\tt str2time(}$s${\tt,} $f${\tt)}&converting character string $s$ to
+% calendar time (for details see Section \ref{str2time}, page
+% \pageref{str2time})\\
+% {\tt trunc(}$x${\tt)}&truncating $x$ to nearest integer\\
+% {\tt trunc(}$x${\tt,} $n${\tt)}&truncating $x$ to $n$ fractional
+% decimal digits\\
+% {\tt Irand224()}&generating pseudo-random integer uniformly distributed
+% in $[0,2^{24})$\\
+% {\tt Uniform01()}&generating pseudo-random number uniformly distributed
+% in $[0,1)$\\
+% {\tt Uniform(}$a${\tt,} $b${\tt)}&generating pseudo-random number
+% uniformly distributed in $[a,b)$\\
+% {\tt Normal01()}&generating Gaussian pseudo-random variate with
+% $\mu=0$ and $\sigma=1$\\
+% {\tt Normal(}$\mu${\tt,} $\sigma${\tt)}&generating Gaussian
+% pseudo-random variate with given $\mu$ and $\sigma$\\
+% \end{tabular}
+
+Os argumentos de todas as funções internas, exceto {\tt card}, {\tt length},
+e {\tt str2time}, devem ser \linebreak expressões numéricas. O argumento de
+{\tt card} deve ser uma expressão de conjunto. O argumento de {\tt length} e
+ambos argumentos de {\tt str2time} devem ser expressões simbólicas.
+
+O valor resultante da expressão numérica, que é uma função de referência,
+é o resultado da aplicação da função ao(s) seu(s) argumento(s).
+
+Note que cada função geradora de números pseudo-aleatórios possui um argumento
+latente (i.e., algum estado interno), que é alterado sempre que função é aplicada.
+Assim, se a função é aplicada repetidamente mesmos aos argumentos idênticos,
+devido ao efeito secundário, sempre se produzirão valores resultantes diferentes.
+
+% Arguments of all built-in functions, except {\tt card}, {\tt length},
+% and {\tt str2time}, should be numeric expressions. The argument of
+% {\tt card} should be a set expression. The argument of {\tt length} and
+% both arguments of {\tt str2time} should 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 has 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.
+\newpage
+
+\subsection{Expressões iteradas}
+\label{itexpr}
+
+Uma {\it expressão numérica iterada} é uma expressão numérica primária,
+que possui a seguinte forma sintática:
+$$\mbox{\it operador-iterado expressão-indexada integrando}$$
+onde o {\it operador-iterado} é o nome simbólico do operador de iteração
+a ser executado (veja abaixo), {\it expressão-indexada} é uma
+expressão indexada que introduz índices e controla a iteração e
+{\it integrando} é uma expressão numérica que participa da operação.
+
+\noindent
+Em MathProg existem quatro operadores iterados, que podem ser usados
+em expressões numéricas:
+
+% An {\it iterated numeric expression} is a primary numeric expression,
+% which has the following syntactic form:
+% $$\mbox{\it iterated-operator indexing-expression integrand}$$
+% where {\it iterated-operator} is the symbolic name of the iterated
+% operator to be performed (see below), {\it indexing-expression} is an
+% indexing expression which introduces dummy indices and controls
+% iterating, {\it integrand} is a numeric expression that participates in
+% the operation.
+%
+% In MathProg there exist four iterated operators, which may be used in
+% numeric expressions:
+
+{\def\arraystretch{2}
+\noindent\hfil
+\begin{tabular}{@{}lll@{}}
+{\tt sum}&somatório&$\displaystyle\sum_{(i_1,\dots,i_n)\in\Delta}
+f(i_1,\dots,i_n)$\\
+{\tt prod}&produtório&$\displaystyle\prod_{(i_1,\dots,i_n)\in\Delta}
+f(i_1,\dots,i_n)$\\
+{\tt min}&mínimo&$\displaystyle\min_{(i_1,\dots,i_n)\in\Delta}
+f(i_1,\dots,i_n)$\\
+{\tt max}&máximo&$\displaystyle\max_{(i_1,\dots,i_n)\in\Delta}
+f(i_1,\dots,i_n)$\\
+\end{tabular}
+}
+
+% {\def\arraystretch{2}
+% \noindent\hfil
+% \begin{tabular}{@{}lll@{}}
+% {\tt sum}&summation&$\displaystyle\sum_{(i_1,\dots,i_n)\in\Delta}
+% f(i_1,\dots,i_n)$\\
+% {\tt prod}&production&$\displaystyle\prod_{(i_1,\dots,i_n)\in\Delta}
+% f(i_1,\dots,i_n)$\\
+% {\tt min}&minimum&$\displaystyle\min_{(i_1,\dots,i_n)\in\Delta}
+% f(i_1,\dots,i_n)$\\
+% {\tt max}&maximum&$\displaystyle\max_{(i_1,\dots,i_n)\in\Delta}
+% f(i_1,\dots,i_n)$\\
+% \end{tabular}
+% }
+
+\noindent onde $i_1$, \dots, $i_n$ são índices introduzidos nas
+expressões indexadas, $\Delta$ é o domínio, um conjunto de $n$-tuplas
+especificado pela expressão indexada que define valores particulares
+atribuído aos índices ao executar a operação iterada e
+$f(i_1,\dots,i_n)$ é o integrando, uma expressão numérica cujo valor
+resultante depende dos índices.
+
+O valor resultante de uma expressão numérica iterada é o resultado da aplicação
+do operador iterado ao seu integrando por todas as $n$-tuplas
+contidas no domínio.
+
+% \noindent where $i_1$, \dots, $i_n$ are dummy indices introduced in
+% the indexing expression, $\Delta$ is the domain, a set of $n$-tuples
+% specified by the indexing expression which defines particular values
+% assigned to the dummy indices on performing the iterated operation,
+% $f(i_1,\dots,i_n)$ is the integrand, a numeric expression whose
+% resultant value depends on the dummy indices.
+%
+% The resultant value of an iterated numeric expression is the result of
+% applying of the iterated operator to its integrand over all $n$-tuples
+% contained in the domain.
+
+\subsection{Expressões condicionais}
+\label{ifthen}
+
+Uma {\it expressão numérica condicional} é uma expressão numérica primária
+que possui uma das seguintes formas sintáticas:
+% A {\it conditional numeric expression} is a primary numeric expression,
+% which has one of the following two syntactic forms:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{{\tt if} $b$ {\tt then} $x$ {\tt else} $y$}\\
+\mbox{{\tt if} $b$ {\tt then} $x$}\\
+\end{array}
+}
+$$
+onde $b$ é uma expressão lógica, enquanto que $x$ e $y$ são expressões numéricas.
+
+% where $b$ is an logical expression, $x$ and $y$ are numeric
+% expressions.
+
+
+O valor resultante da expressão condicional depende do valor da
+expressão lógica que segue a palavra-chave {\tt if}. Se ela recebe
+o valor {\it verdadeiro}, o valor da expressão condicional é o valor
+da expressão que segue a palavra-chave {\tt then}.
+Caso contrário, se a expressão lógica recebe o valor {\it falso},
+o valor da expressão condicional é o valor da expressão que segue
+a palavra-chave {\it else}. Se ocorre a segunda forma sintática
+da expressão condicional, a reduzida, e a expressão lógica recebe o valor
+{\it falso}, então o valor resultante da expressão condicional é zero.
+
+% The resultant value of the conditional expression depends on the value
+% of the logical expression that follows the keyword {\tt if}. If it
+% takes on the value {\it true}, the value of the conditional expression
+% is the value of the expression that follows the keyword {\tt then}.
+% Otherwise, if the logical expression takes on the value {\it false},
+% the value of the conditional expression is the value of the expression
+% that follows the keyword {\it else}. If the second, reduced form of the
+% conditional expression is used and the logical expression takes on the
+% value {\it false}, the resultant value of the conditional expression is
+% zero.
+
+\newpage
+
+\subsection{Expressões parentizadas}
+
+Qualquer expressão numérica pode ser cercada por parênteses, o que as
+torna sintaticamente uma expressão numérica primária.
+
+Parênteses podem ser usados em expressões numéricas, como em álgebra, para
+especificar a ordem desejada na qual as operações devem ser realizadas.
+Quando se usam parênteses, a expressão entre parênteses é avaliada
+antes e seu o valor resultante é usado.
+
+O valor resultante de uma expressão parentizada é o mesmo
+valor de uma expressão cercada entre parênteses.
+
+% Any numeric expression may be enclosed in parentheses that
+% syntactically makes it a 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.
+
+\subsection{Operadores aritméticos}
+
+Em MathProg exitem os seguintes operadores aritméticos, que podem ser
+usados em expressões numéricas:
+
+% In MathProg there exist the following arithmetic operators, which may
+% be used in numeric expressions:
+
+\begin{tabular}{@{}ll@{}}
+{\tt +} $x$&mais unário\\
+{\tt -} $x$&menos unário\\
+$x$ {\tt +} $y$&adição\\
+$x$ {\tt -} $y$&subtração\\
+$x$ {\tt less} $y$&diferença positiva (se $x<y$ então 0 senão $x-y$)\\
+$x$ {\tt *} $y$&multiplicação\\
+$x$ {\tt /} $y$&divisão\\
+$x$ {\tt div} $y$&quociente da divisão exata\\
+$x$ {\tt mod} $y$&resto da divisão exata\\
+$x$ {\tt **} $y$, $x$ {\tt\textasciicircum} $y$&exponenciação (elevação a uma potência)\\
+\end{tabular}
+
+% \begin{tabular}{@{}ll@{}}
+% {\tt +} $x$&unary plus\\
+% {\tt -} $x$&unary minus\\
+% $x$ {\tt +} $y$&addition\\
+% $x$ {\tt -} $y$&subtraction\\
+% $x$ {\tt less} $y$&positive difference (if $x<y$ then 0 else $x-y$)\\
+% $x$ {\tt *} $y$&multiplication\\
+% $x$ {\tt /} $y$&division\\
+% $x$ {\tt div} $y$&quotient of exact division\\
+% $x$ {\tt mod} $y$&remainder of exact division\\
+% $x$ {\tt **} $y$, $x$ {\tt\textasciicircum} $y$&exponentiation (raising
+% to power)\\
+% \end{tabular}
+
+\noindent onde $x$ e $y$ são expressões numéricas.
+
+Se a expressão inclui mais de um operador aritmético, todos
+operadores são executados da esquerda para a direita de acordo
+com a hierarquia das operações (veja abaixo) com a única exceção de
+que os operadores de exponenciação são executados da direita para a esquerda.
+
+O valor resultante da expressão, que contém operadores aritméticos,
+é o resultado da aplicação dos operadores aos seus operandos.
+
+% \noindent where $x$ and $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.
+
+\subsection{Hierarquia das operações}
+\label{hierarchy}
+
+A lista seguinte apresenta a hierarquia das operações
+em expressões numéricas:
+
+% The following list shows the hierarchy of operations in numeric
+% expressions:
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Operação&Hierarquia\\
+\hline
+Avaliação das funções ({\tt abs}, {\tt ceil}, etc.)&
+1{\textsuperscript{\b{a}}}\\
+Exponenciação ({\tt**}, {\tt\textasciicircum})&
+2{\textsuperscript{\b{a}}}\\
+Mais e menos unário ({\tt+}, {\tt-})&
+3{\textsuperscript{\b{a}}}\\
+Multiplicação e divisão ({\tt*}, {\tt/}, {\tt div}, {\tt mod})&
+4{\textsuperscript{\b{a}}}\\
+Operações iteradas ({\tt sum}, {\tt prod}, {\tt min}, {\tt max})&
+5{\textsuperscript{\b{a}}}\\
+Adição e subtração ({\tt+}, {\tt-}, {\tt less})&
+6{\textsuperscript{\b{a}}}\\
+Avaliação condicional ({\tt if} \dots {\tt then} \dots {\tt else})&
+7{\textsuperscript{\b{a}}}\\
+\end{tabular}
+
+% \noindent\hfil
+% \begin{tabular}{@{}ll@{}}
+% Operation&Hierarchy\\
+% \hline
+% Evaluation of functions ({\tt abs}, {\tt ceil}, etc.)&1st\\
+% Exponentiation ({\tt**}, {\tt\textasciicircum})&2nd\\
+% Unary plus and minus ({\tt+}, {\tt-})&3rd\\
+% Multiplication and division ({\tt*}, {\tt/}, {\tt div}, {\tt mod})&4th\\
+% Iterated operations ({\tt sum}, {\tt prod}, {\tt min}, {\tt max})&5th\\
+% Addition and subtraction ({\tt+}, {\tt-}, {\tt less})&6th\\
+% Conditional evaluation ({\tt if} \dots {\tt then} \dots {\tt else})&
+% 7th\\
+% \end{tabular}
+
+\newpage
+
+Esta hierarquia é usada para determinar qual de duas operações consecutivas
+deve ser executada primeiro. Se o primeiro operador possui hierarquia
+maior ou igual ao segundo, a primeira operação é executada. Caso contrário,
+a segunda operação é comparada à terceira e assim sucessivamente.
+Quando se alcança o fim da expressão, todas as operações remanescentes
+são executadas na ordem inversa.
+
+% 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.
+
+\section{Expressões simbólicas}
+
+Uma {\it expressão simbólica} é uma regra para calcular um valor simbólico individual
+representado como uma cadeia de caracteres.
+
+A expressão simbólica primária pode ser uma cadeia literal, um índice,
+um parâmetro não-indexado, um parâmetro indexado, uma função interna de referência,
+uma expressão simbólica condicional ou outra expressão simbólica cercada
+entre parênteses.
+
+Também é permitido usar uma expressão numérica como a expressão simbólica primária,
+neste caso o valor resultante da expressão numérica é automaticamente convertido
+em um tipo simbólico.
+
+% A {\it symbolic expression} is a rule for computing a single symbolic
+% value represented as a 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.
+
+\para{Exemplos}
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|'Maio de 2003'|&(literal de cadeia)\\
+\verb|j|&(índice)\\
+\verb|p|&(parâmetro não-indexado)\\
+\verb|s['abc',j+1]|&(parâmetro indexado)\\
+\verb|substr(name[i],k+1,3)|&(função de referência)\\
+\verb|if i in I then s[i,j] & "..." else t[i+1]|& (expressão condicional) \\
+\verb|((10 * b[i,j]) & '.bis')|&(expressão parentizada)\\
+\end{tabular}
+
+% \noindent
+% \begin{tabular}{@{}ll@{}}
+% \verb|'May 2003'|&(string literal)\\
+% \verb|j|&(dummy index)\\
+% \verb|p|&(unsubscripted parameter)\\
+% \verb|s['abc',j+1]|&(subscripted parameter)\\
+% \verb|substr(name[i],k+1,3)|&(function reference)\\
+% \verb|if i in I then s[i,j] & "..." else t[i+1]|
+% & (conditional expression) \\
+% \verb|((10 * b[i,j]) & '.bis')|&(parenthesized expression)\\
+% \end{tabular}
+
+Expressões simbólicas mais genéricas contendo duas ou mais expressões
+simbólicas primárias podem ser construídas usando o operador de
+concatenação.
+
+% More general symbolic expressions containing two or more primary
+% symbolic expressions may be constructed by using the concatenation
+% operator.
+
+\para{Exemplos}
+
+\begin{verbatim}
+'abc[' & i & ',' & j & ']'
+"de " & cidade[i] " para " & cidade[j]
+\end{verbatim}
+
+% \begin{verbatim}
+% 'abc[' & i & ',' & j & ']'
+% "from " & city[i] " to " & city[j]
+% \end{verbatim}
+
+Os princípios da avaliação de expressões simbólicas são completamente
+análogos àqueles dados para expressões numéricas (veja acima).
+
+% The principles of evaluation of symbolic expressions are completely
+% analogous to the ones given for numeric expressions (see above).
+
+\subsection{Funções de referência}
+
+Em MathProg existem as seguintes funções internas que podem ser usadas em
+expressões \linebreak simbólicas:
+
+% In MathProg there exist the following built-in functions which may be
+% used in symbolic expressions:
+
+\begin{tabular}{@{}p{112pt}p{328pt}@{}}
+{\tt substr(}$s${\tt,} $x${\tt)}&substring de $s$ iniciado na
+posição $x$\\
+{\tt substr(}$s${\tt,} $x${\tt,} $y${\tt)}&substring de $s$ iniciado
+na posição $x$ com tamanho $y$\\
+{\tt time2str(}$t${\tt,} $f${\tt)}&converte o tempo de calendário para
+uma cadeia de caracteres \linebreak (detalhes na Seção \ref{time2str}, página
+\pageref{time2str})\\
+\end{tabular}
+
+% \begin{tabular}{@{}p{112pt}p{328pt}@{}}
+% {\tt substr(}$s${\tt,} $x${\tt)}&substring of $s$ starting from
+% position $x$\\
+% {\tt substr(}$s${\tt,} $x${\tt,} $y${\tt)}&substring of $s$ starting
+% from position $x$ and having length $y$\\
+% {\tt time2str(}$t${\tt,} $f${\tt)}&converting calendar time to
+% character string (for details see Section \ref{time2str}, page
+% \pageref{time2str})\\
+% \end{tabular}
+
+O primeiro argumento de {\tt substr} deve ser uma expressão simbólica
+enquanto que o segundo e o terceiro (opcional) argumentos devem ser
+expressões numéricas.
+
+O primeiro argumento de {\tt time2str} deve ser uma expressão numérica,
+e seu segundo argumento deve ser uma expressão simbólica.
+
+O valor resultante da expressão simbólica, que é uma função de referência,
+é o resultado de aplicar a função aos seus argumentos.
+
+% The first argument of {\tt substr} should be a symbolic expression
+% while its second and optional third arguments should be numeric
+% expressions.
+%
+% The first argument of {\tt time2str} should be a numeric expression,
+% and its second argument should 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.
+
+\subsection{Operadores simbólicos}
+
+Atualmente, em MathProg exite um único operador simbólico:
+$$\mbox{\tt s \& t}$$
+onde $s$ e $t$ são expressões simbólicas. Este operador implica na
+concatenação dos seus dois operandos simbólicos, que são cadeias
+de caracteres.
+
+% Currently in MathProg there exists the only symbolic operator:
+% $$\mbox{\tt s \& t}$$
+% where $s$ and $t$ are symbolic expressions. This operator means
+% concatenation of its two symbolic operands, which are character
+% strings.
+
+\subsection{Hierarquia de operações}
+
+A lista seguinte mostra a hierarquia das operações em expressões
+simbólicas:
+
+% The following list shows the hierarchy of operations in symbolic
+% expressions:
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Operação&Hierarquia\\
+\hline
+Avaliação de operações numéricas&
+1{\textsuperscript{\b{a}}}-7{\textsuperscript{\b{a}}}\\
+Concatenação ({\tt\&})&8{\textsuperscript{\b{a}}}\\
+Avaliação condicional ({\tt if} \dots {\tt then} \dots {\tt else})&
+9{\textsuperscript{\b{a}}}\\
+\end{tabular}
+
+% \noindent\hfil
+% \begin{tabular}{@{}ll@{}}
+% Operation&Hierarchy\\
+% \hline
+% Evaluation of numeric operations&1st-7th\\
+% Concatenation ({\tt\&})&8th\\
+% Conditional evaluation ({\tt if} \dots {\tt then} \dots {\tt else})&
+% 9th\\
+% \end{tabular}
+
+Esta hierarquia possui o mesmo significado como explicado acima para
+expressões numéricas (ver Subseção \ref{hierarchy}, página \pageref{hierarchy}).
+
+% This hierarchy has the same meaning as was explained above for numeric
+% expressions (see Subsection \ref{hierarchy}, page \pageref{hierarchy}).
+
+
+\section{Expressões de indexação e índices}
+\label{indexing}
+
+Uma {\it expressão indexante} é uma construção auxiliar que especifica um
+conjunto plano de $n$-tuplas e introduz índices. Possui duas formas
+sintáticas:
+% An {\it indexing expression} is an auxiliary construction, which
+% specifies a plain set of $n$-tuples and introduces dummy indices. It
+% has two syntactic forms:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{{\tt\{} {\it entrada}$_1${\tt,} {\it entrada}$_2${\tt,} \dots{\tt,}
+{\it entrada}$_m$ {\tt\}}}\\
+\mbox{{\tt\{} {\it entrada}$_1${\tt,} {\it entrada}$_2${\tt,} \dots{\tt,}
+{\it entrada}$_m$ {\tt:} {\it predicado} {\tt\}}}\\
+\end{array}
+}
+$$
+% $$
+% {\def\arraystretch{1.4}
+% \begin{array}{l}
+% \mbox{{\tt\{} {\it entry}$_1${\tt,} {\it entry}$_2${\tt,} \dots{\tt,}
+% {\it entry}$_m$ {\tt\}}}\\
+% \mbox{{\tt\{} {\it entry}$_1${\tt,} {\it entry}$_2${\tt,} \dots{\tt,}
+% {\it entry}$_m$ {\tt:} {\it predicate} {\tt\}}}\\
+% \end{array}
+% }
+% $$
+onde {\it entrada}{$_1$}, {\it entrada}{$_2$}, \dots, {\it entrada}{$_m$}
+são entradas indexantes, {\it predicado} é uma expressão lógica que especifica
+um predicado opcional (condição lógica).
+
+% where {\it entry}{$_1$}, {\it entry}{$_2$}, \dots, {\it entry}{$_m$}
+% are indexing entries, {\it predicate} is a logical expression that
+% specifies an optional predicate (logical condition).
+
+Cada {\it entrada indexante} na expressão indexante possui uma das três
+formas seguintes:
+% Each {\it indexing entry} in the indexing expression has one of the
+% following three forms:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{$i$ {\tt in} $S$}\\
+\mbox{{\tt(}$i_1${\tt,} $i_2${\tt,} \dots{\tt,}$i_n${\tt)} {\tt in}
+$S$}\\
+\mbox{$S$}\\
+\end{array}
+}
+$$
+onde $i_1$, $i_2$, \dots, $i_n$ são índices e $S$ é uma expressão de conjunto
+(discutido na próxima seção) que especifica o conjunto básico.
+
+% where $i_1$, $i_2$, \dots, $i_n$ are indices, $S$ is a set expression
+% (discussed in the next section) that specifies the basic set.
+
+\newpage
+
+O número de índices na entrada indexante deve coincidir com a
+dimensão do conjunto básico $S$, i.e., se $S$ consiste de 1-tuplas,
+deve-se usar a primeira forma. Se $S$ consiste de $n$-tuplas, onde
+$n>1$, a segunda forma deve ser usada.
+
+% The number of indices in the indexing entry should be the same as the
+% dimension of the basic set $S$, i.e. if $S$ consists of 1-tuples, the
+% first form should be used, and if $S$ consists of $n$-tuples, where
+% $n>1$, the second form should be used.
+
+Se a primeira forma da entrada indexante é usada, o índice $i$ pode ser
+apenas um índice (veja mais adiante). Se a segunda forma é utilizada, os índices
+$i_1$, $i_2$, \dots, $i_n$ podem ser tanto índices como alguma expressão numérica
+ou simbólica, em que pelo menos um dos índices deve ser um índice.
+Na terceira, a forma reduzida da entrada indexante possui o mesmo efeito
+se houver $i$ (se $S$ é 1-dimensional) ou
+$i_1$, $i_2$, \dots, $i_n$ (se $S$ é $n$-dimensional) onde todos são especificados
+como índices.
+
+% If the first form of the indexing entry is used, the index $i$ can be
+% a dummy index only (see below). If the second form is used, the indices
+% $i_1$, $i_2$, \dots, $i_n$ can be either dummy indices or some numeric
+% or symbolic expressions, where at least one index should be a dummy
+% index. The third, reduced form of the indexing entry has the same
+% effect as if there were $i$ (if $S$ is 1-dimensional) or
+% $i_1$, $i_2$, \dots, $i_n$ (if $S$ is $n$-dimensional) all specified as
+% dummy indices.
+
+Um {\it índice} é um objeto auxiliar do modelo, que atua como uma
+variável individual. Os valores atribuídos aos índices são componentes
+das $n$-tuplas dos conjuntos básicos, i.e., algumas quantidades
+numéricas e simbólicas.
+
+% A {\it dummy index} is an auxiliary model object, which acts like an
+% individual variable. Values assigned to dummy indices are components of
+% $n$-tuples from basic sets, i.e. some numeric and symbolic quantities.
+
+Com propósitos de referência, índices podem ter nomes simbólicos.
+No entanto, diferentemente de outros objetos de modelo (conjuntos,
+parâmetros, etc.) índices não precisam ser \linebreak explicitamente declarados.
+Cada nome simbólico {\it não-declarado} usado na posição indexante de
+uma entrada indexante é reconhecida como o nome simbólico do índice
+correspondente.
+
+% For referencing purposes dummy indices can be provided with symbolic
+% names. However, unlike other model objects (sets, parameters, etc.)
+% dummy indices need not be explicitly declared. Each {\it undeclared}
+% symbolic name being used in the indexing position of an indexing entry
+% is recognized as the symbolic name of corresponding dummy index.
+
+Os nomes simbólicos dos índices são válidos somente dentro do escopo
+da expressão indexante, onde o índice foi inserido. Além do escopo,
+os índices são completamente inacessíveis, de modo que os mesmos
+nomes simbólicos podem ser usados para outros propósitos, em particular,
+para representar índices em outras expressões indexantes.
+
+% 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.
+
+O escopo da expressão indexante, em que declarações implícitas de índices
+são válidas, depende do contexto em que a expressão indexante é usada:
+
+% The scope of indexing expression, where implicit declarations of dummy
+% indices are valid, depends on the context, in which the indexing
+% expression is used:
+
+\vspace*{-8pt}
+
+\begin{itemize}
+\item Se a expressão indexante é usada em um operador-iterado, seu
+escopo se estende até o final do integrando.
+\item Se a expressão indexante é usada como uma expressão de conjunto
+primária, seu escopo de estende até o final desta expressão indexante.
+\item Se a expressão indexante é usada para definir o domínio do subíndice
+na declaração de alguns objetos de modelo, seu escopo se estende até o
+final da declaração correspondente.
+\end{itemize}
+
+% \begin{itemize}
+% \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 that 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{itemize}
+
+\vspace*{-8pt}
+
+O mecanismo de indexação implementado para indexar expressões é melhor
+explicado por alguns exemplos discutidos abaixo.
+
+Sejam três conjuntos:
+% The indexing mechanism implemented by means of indexing expressions is
+% best explained by some examples discussed below.
+%
+% Let there be given three sets:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+A=\{4,7,9\},\\
+B=\{(1,Jan),(1,Fev),(2,Mar),(2,Abr),(3,Mai),(3,Jun)\},\\
+C=\{a,b,c\},\\
+\end{array}
+}
+$$
+% $$
+% {\def\arraystretch{1.4}
+% \begin{array}{l}
+% A=\{4,7,9\},\\
+% B=\{(1,Jan),(1,Feb),(2,Mar),(2,Apr),(3,May),(3,Jun)\},\\
+% C=\{a,b,c\},\\
+% \end{array}
+% }
+% $$
+onde $A$ e $C$ consistem de 1-tuplas (singletos), $B$ consiste de
+2-tuplas (dobletes). Considere a seguinte expressão indexante:
+$$\mbox{{\tt\{i in A, (j,k) in B, l in C\}}}$$
+onde {\tt i}, {\tt j}, {\tt k}, e {\tt l} são índices.
+
+% where $A$ and $C$ consist of 1-tuples (singlets), $B$ consists of
+% 2-tuples (doublets). Consider the following indexing expression:
+% $$\mbox{{\tt\{i in A, (j,k) in B, l in C\}}}$$
+% where {\tt i}, {\tt j}, {\tt k}, and {\tt l} are dummy indices.
+
+\newpage
+
+Embora MathProg não seja uma linguagem procedural, para qualquer
+expressão indexante uma descrição algorítmica equivalente pode ser dada.
+Em particular, a descrição algorítmica da expressão indexante acima
+poderia ser vista como segue:
+
+% Although MathProg is not a procedural language, for any indexing
+% expression an equivalent algorithmic description can be given. In
+% particular, the algorithmic description of the indexing expression
+% above could look like follows:
+
+\noindent\hfil
+\begin{tabular}{@{}l@{}}
+{\bf para todo} $i\in A$ {\bf faça}\\
+\hspace{16pt}{\bf para todo} $(j,k)\in B$ {\bf faça}\\
+\hspace{32pt}{\bf para todo} $l\in C$ {\bf faça}\\
+\hspace{48pt}{\it ação};\\
+\end{tabular}
+
+% \noindent\hfil
+% \begin{tabular}{@{}l@{}}
+% {\bf for all} $i\in A$ {\bf do}\\
+% \hspace{16pt}{\bf for all} $(j,k)\in B$ {\bf do}\\
+% \hspace{32pt}{\bf for all} $l\in C$ {\bf do}\\
+% \hspace{48pt}{\it action};\\
+% \end{tabular}
+
+\noindent onde os índices $i$, $j$, $k$, $l$ são consecutivamente
+atribuídos aos componentes correspondentes das $n$-tuplas dos conjuntos
+básicos $A$, $B$, $C$, e {\it ação} é alguma ação que dependa do contexto
+no qual a expressão indexante é usada. Por exemplo, se a ação fosse
+imprimir os valores atuais dos índices, a impressão seria vista como segue:
+
+% \noindent where the dummy indices $i$, $j$, $k$, $l$ are consecutively
+% assigned corresponding components of $n$-tuples from the basic sets $A$,
+% $B$, $C$, and {\it action} is some action that depends on the context,
+% where the indexing expression is used. For example, if the action were
+% printing current values of dummy indices, the printout would look like
+% follows:
+
+\noindent\hfil
+\begin{tabular}{@{}llll@{}}
+$i=4$&$j=1$&$k=Jan$&$l=a$\\
+$i=4$&$j=1$&$k=Jan$&$l=b$\\
+$i=4$&$j=1$&$k=Jan$&$l=c$\\
+$i=4$&$j=1$&$k=Fev$&$l=a$\\
+$i=4$&$j=1$&$k=Fev$&$l=b$\\
+\multicolumn{4}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\
+$i=9$&$j=3$&$k=Jun$&$l=b$\\
+$i=9$&$j=3$&$k=Jun$&$l=c$\\
+\end{tabular}
+
+% \noindent\hfil
+% \begin{tabular}{@{}llll@{}}
+% $i=4$&$j=1$&$k=Jan$&$l=a$\\
+% $i=4$&$j=1$&$k=Jan$&$l=b$\\
+% $i=4$&$j=1$&$k=Jan$&$l=c$\\
+% $i=4$&$j=1$&$k=Feb$&$l=a$\\
+% $i=4$&$j=1$&$k=Feb$&$l=b$\\
+% \multicolumn{4}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\
+% $i=9$&$j=3$&$k=Jun$&$l=b$\\
+% $i=9$&$j=3$&$k=Jun$&$l=c$\\
+% \end{tabular}
+
+Seja o exemplo da expressão indexante usado na seguinte
+operação iterada:
+$$\mbox{{\tt sum\{i in A, (j,k) in B, l in C\} p[i,j,k,l]}}$$
+onde {\tt p} é uma parâmetro numérico 4-dimensional ou alguma
+expressão numérica cujo valor resultante dependa de
+{\tt i}, {\tt j}, {\tt k} e {\tt l}. Neste caso, a ação é o somatório,
+de forma que o valor resultante da expressão numérica primária é:
+$$\sum_{i\in A,(j,k)\in B,l\in C}(p_{ijkl}).$$
+
+% Let the example indexing expression be used in the following iterated
+% operation:
+% $$\mbox{{\tt sum\{i in A, (j,k) in B, l in C\} p[i,j,k,l]}}$$
+% where {\tt p} is a 4-dimensional numeric parameter or some numeric
+% expression whose resultant value depends on {\tt i}, {\tt j}, {\tt k},
+% and {\tt l}. In this case the action is summation, so the resultant
+% value of the primary numeric expression is:
+% $$\sum_{i\in A,(j,k)\in B,l\in C}(p_{ijkl}).$$
+
+Agora seja a expressão indexante do exemplo usada como uma expressão
+de conjunto primária. Neste caso, a ação é reunir todas as 4-tuplas
+(quádruplas) da forma $(i,j,k,l)$ em um conjunto, de forma que o
+valor resultante de tal operação é simplesmente o produto
+Cartesiano dos conjuntos básicos:
+$$A\times B\times C=\{(i,j,k,l):i\in A,(j,k)\in B,l\in C\}.$$
+Note que neste caso, a mesma expressão indexante pode ser escrita
+na forma reduzida:
+$$\mbox{{\tt\{A, B, C\}}}$$
+pois os índices $i$, $j$, $k$ e $l$ não são referenciados, portanto,
+seus nomes simbólicos não precisam ser especificados.
+
+% Now let the example indexing expression be used as a primary set
+% expression. In this case the action is gathering all 4-tuples
+% (quadruplets) of the form $(i,j,k,l)$ in one set, so the resultant
+% value of such operation is simply the Cartesian product of the basic
+% sets:
+% $$A\times B\times C=\{(i,j,k,l):i\in A,(j,k)\in B,l\in C\}.$$
+% Note that in this case the same indexing expression might be written in
+% the reduced form:
+% $$\mbox{{\tt\{A, B, C\}}}$$
+% because the dummy indices $i$, $j$, $k$, and $l$ are not referenced and
+% therefore their symbolic names need not be specified.
+
+\newpage
+
+Finalmente, seja a expressão indexante do exemplo usada como o domínio do
+subíndice na declaração de um objeto de modelo 4-dimensional, por exemplo,
+um parâmetro numérico:
+% 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:
+$$\mbox{{\tt param p\{i in A, (j,k) in B, l in C\}} \dots {\tt;}}$$
+
+\noindent Neste caso, a ação é gerar os membros do parâmetro,
+onde cada membro possui a forma $p[i,j,k,l]$.
+
+% \noindent In this case the action is generating the parameter members,
+% where each member has the form $p[i,j,k,l]$.
+
+Como mencionado anteriormente, alguns índices da segunda forma das entradas
+indexantes podem ser expressões numéricas ou simbólicas, não apenas índices.
+Neste caso, os valores resultantes destas expressões desempenham o papel
+de algumas condições lógicas para selecionar apenas aquelas $n$-tuplas
+do produto Cartesiano dos conjuntos básicos que satisfaçam estas
+condições.
+
+% 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 $n$-tuples from the Cartesian product of
+% basic sets that satisfy these conditions.
+
+Considere, por exemplo, a seguinte expressão indexante:
+$$\mbox{{\tt\{i in A, (i-1,k) in B, l in C\}}}$$
+onde {\tt i}, {\tt k} e {\tt l} são índices, e {\tt i-1} é uma
+expressão numérica. A descrição algorítmica desta expressão
+indexante é a seguinte:
+
+% Consider, for example, the following indexing expression:
+% $$\mbox{{\tt\{i in A, (i-1,k) in B, l in C\}}}$$
+% where {\tt i}, {\tt k}, {\tt l} are dummy indices, and {\tt i-1} is
+% a numeric expression. The algorithmic decsription of this indexing
+% expression is the following:
+
+\noindent\hfil
+\begin{tabular}{@{}l@{}}
+{\bf para todo} $i\in A$ {\bf faça}\\
+\hspace{16pt}{\bf para todo} $(j,k)\in B$ {\bf e} $j=i-1$ {\bf faça}\\
+\hspace{32pt}{\bf para todo} $l\in C$ {\bf faça}\\
+\hspace{48pt}{\it ação};\\
+\end{tabular}
+
+% \noindent\hfil
+% \begin{tabular}{@{}l@{}}
+% {\bf for all} $i\in A$ {\bf do}\\
+% \hspace{16pt}{\bf for all} $(j,k)\in B$ {\bf and} $j=i-1$ {\bf do}\\
+% \hspace{32pt}{\bf for all} $l\in C$ {\bf do}\\
+% \hspace{48pt}{\it action};\\
+% \end{tabular}
+
+\noindent Assim, se esta expressão indexante fosse usada como uma expressão de conjunto
+primária, o conjunto resultante seira o seguinte:
+$$\{(4,Mai,a),(4,Mai,b),(4,Mai,c),(4,Jun,a),(4,Jun,b),(4,Jun,c)\}.$$
+Deve-se notar que neste caso o conjunto resultante consiste em 3-tuplas,
+e não de 4-tuplas, porque na expressão indexante não há índice que
+corresponda ao primeiro componente das 2-tuplas do conjunto $B$.
+
+% \noindent Thus, if this indexing expression were used as a primary set
+% expression, the resultant set would be the following:
+% $$\{(4,May,a),(4,May,b),(4,May,c),(4,Jun,a),(4,Jun,b),(4,Jun,c)\}.$$
+% 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
+% $B$.
+
+A regra geral é: o número de componentes de $n$-tuplas definido por
+uma expressão indexante é o mesmo do número de índices naquela expressão,
+onde a correspondência entre índices e componentes nas $n$-tuplas no
+conjunto resultante é posicional, i.e., o primeiro índice corresponde
+ao primeiro componente, o segundo índice corresponde ao segundo
+componente, etc.
+
+% The general rule is: the number of components of $n$-tuples defined by
+% an indexing expression is the same as the number of dummy indices in
+% that expression, where the correspondence between dummy indices and
+% components on $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.
+
+Em alguns casos é necessário selecionar um subconjunto do produto
+Cartesiano de alguns \linebreak conjuntos. Isto pode ser alcançado mediante o
+emprego de um predicado lógico opcional, que é especificado na
+expressão indexante.
+
+% In some 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 the indexing expression.
+
+Considere, por exemplo, a seguinte expressão indexante:
+$$\mbox{{\tt\{i in A, (j,k) in B, l in C: i <= 5 and k <> 'Mar'\}}}$$
+onde a expressão lógica após os dois pontos é um predicado. A
+descrição algorítmica desta expressão indexante é a seguinte:
+
+% Consider, for example, the following indexing expression:
+% $$\mbox{{\tt\{i in A, (j,k) in B, l in C: i <= 5 and k <> 'Mar'\}}}$$
+% where the logical expression following the colon is a predicate. The
+% algorithmic description of this indexing expression is the following:
+
+\noindent\hfil
+\begin{tabular}{@{}l@{}}
+{\bf para todo} $i\in A$ {\bf faça}\\
+\hspace{16pt}{\bf para todo} $(j,k)\in B$ {\bf faça}\\
+\hspace{32pt}{\bf para todo} $l\in C$ {\bf faça}\\
+\hspace{48pt}{\bf se} $i\leq 5$ {\bf e} $k\neq`Mar'$ {\bf então}\\
+\hspace{64pt}{\it ação};\\
+\end{tabular}
+
+% \noindent\hfil
+% \begin{tabular}{@{}l@{}}
+% {\bf for all} $i\in A$ {\bf do}\\
+% \hspace{16pt}{\bf for all} $(j,k)\in B$ {\bf do}\\
+% \hspace{32pt}{\bf for all} $l\in C$ {\bf do}\\
+% \hspace{48pt}{\bf if} $i\leq 5$ {\bf and} $k\neq`Mar'$ {\bf then}\\
+% \hspace{64pt}{\it action};\\
+% \end{tabular}
+
+\noindent Assim, se a expressão indexante fosse usada como uma
+expressão de conjunto primária, o conjunto resultante seria o seguinte:
+$$\{(4,1,Jan,a),(4,1,Fev,a),(4,2,Abr,a),\dots,(4,3,Jun,c)\}.$$
+
+Se o predicado não é especificado na expressão indexante assume-se um,
+que recebe o valor {\it verdadeiro}.
+
+% \noindent Thus, if this indexing expression were used as a primary set
+% expression, the resultant set would be the following:
+% $$\{(4,1,Jan,a),(4,1,Feb,a),(4,2,Apr,a),\dots,(4,3,Jun,c)\}.$$
+%
+% If no predicate is specified in the indexing expression, one, which
+% takes on the value {\it true}, is assumed.
+
+\section{Expressões de conjunto}
+
+Uma {\it expressão de conjunto} é uma regra para calcular um conjunto
+elementar, i.e., uma coleção de $n$-tuplas, onde os componentes das
+$n$-tuplas são quantidades numéricas e simbólicas.
+
+% A {\it set expression} is a rule for computing an elemental set, i.e.
+% a collection of $n$-tuples, where components of $n$-tuples are numeric
+% and symbolic quantities.
+
+A expressão de conjunto primária pode ser um conjunto de literais, um conjunto
+não-indexado, um conjunto indexado, um conjunto ``aritmético'', uma expressão
+indexante, uma expressão de \linebreak conjunto iterada, uma expressão de conjunto
+condicional ou outra expressão cercada por \linebreak parênteses.
+
+\para{Exemplos}
+
+% 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.
+%
+% \para{Examples}
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|{(123,'aaa'), (i+1,'bbb'), (j-1,'ccc')}| &(conjunto de literais)\\
+\verb|I| &(conjunto não-indexado)\\
+\verb|S[i-1,j+1]| &(conjunto indexado)\\
+\verb|1..t-1 by 2| &(conjunto ``aritmético'')\\
+\verb|{t in 1..T, (t+1,j) in S: (t,j) in F}| &(expressão indexante)\\
+\verb|setof{i in I, j in J}(i+1,j-1)| &(expressão de conjunto iterado)\\
+\verb|if i < j then S[i,j] else F diff S[i,j]| &(expressão de conjunto
+condicional)\\
+\verb|(1..10 union 21..30)| &(expressão de conjunto parentizado)\\
+\end{tabular}
+
+% \noindent
+% \begin{tabular}{@{}ll@{}}
+% \verb|{(123,'aaa'), (i+1,'bbb'), (j-1,'ccc')}| &(literal set)\\
+% \verb|I| &(unsubscripted set)\\
+% \verb|S[i-1,j+1]| &(subscripted set)\\
+% \verb|1..t-1 by 2| &(``arithmetic'' set)\\
+% \verb|{t in 1..T, (t+1,j) in S: (t,j) in F}| &(indexing expression)\\
+% \verb|setof{i in I, j in J}(i+1,j-1)| &(iterated set expression)\\
+% \verb|if i < j then S[i,j] else F diff S[i,j]| &(conditional set
+% expression)\\
+% \verb|(1..10 union 21..30)| &(parenthesized set expression)\\
+% \end{tabular}
+
+Expressões de conjuntos mais genéricas contendo duas ou mais expressões
+de conjunto primárias podem ser construídas usando operadores
+específicos de conjunto .
+
+\para{Exemplos}
+
+% More general set expressions containing two or more primary set
+% expressions may be constructed by using certain set operators.
+%
+% \para{Examples}
+
+\begin{verbatim}
+(A union B) inter (I cross J)
+1..10 cross (if i < j then {'a', 'b', 'c'} else {'d', 'e', 'f'})
+\end{verbatim}
+
+\subsection{Conjuntos de literais}
+
+Um {\it conjunto de literais} é uma expressão de conjunto primária
+que possui as duas formas \linebreak sintáticas seguintes:
+% A {\it literal set} is a primary set expression, which has the
+% following two syntactic forms:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{{\tt\{}$e_1${\tt,} $e_2${\tt,} \dots{\tt,} $e_m${\tt\}}}\\
+\mbox{{\tt\{(}$e_{11}${\tt,} \dots{\tt,} $e_{1n}${\tt),}
+{\tt(}$e_{21}${\tt,} \dots{\tt,} $e_{2n}${\tt),} \dots{\tt,}
+{\tt(}$e_{m1}${\tt,} \dots{\tt,} $e_{mn}${\tt)\}}}\\
+\end{array}
+}
+$$
+% $$
+% {\def\arraystretch{1.4}
+% \begin{array}{l}
+% \mbox{{\tt\{}$e_1${\tt,} $e_2${\tt,} \dots{\tt,} $e_m${\tt\}}}\\
+% \mbox{{\tt\{(}$e_{11}${\tt,} \dots{\tt,} $e_{1n}${\tt),}
+% {\tt(}$e_{21}${\tt,} \dots{\tt,} $e_{2n}${\tt),} \dots{\tt,}
+% {\tt(}$e_{m1}${\tt,} \dots{\tt,} $e_{mn}${\tt)\}}}\\
+% \end{array}
+% }
+% $$
+onde $e_1$, \dots, $e_m$, $e_{11}$, \dots, $e_{mn}$ são expressões
+numéricas ou simbólicas.
+
+Se a primeira forma é adotada, o conjunto resultante consiste
+de 1-tuplas (singletos) enumerados entre as chaves.
+É permitido especificar um conjunto vazio como {\tt\{\ \}},
+que não possui 1-tuplas. Se a segunda forma é adotada,
+o conjunto resultante consiste de $n$-tuplas enumeradas entre as chaves,
+onde uma $n$-tupla particular consiste nos componentes correspondentes
+enumerados entre parênteses. Todas as $n$-tuplas devem ter o mesmo
+número de componentes.
+
+% where $e_1$, \dots, $e_m$, $e_{11}$, \dots, $e_{mn}$ are numeric or
+% symbolic expressions.
+%
+% If the first form is used, the resultant set consists of 1-tuples
+% (singlets) enumerated within the curly braces. It is allowed to specify
+% an empty set as {\tt\{\ \}}, which has no 1-tuples. If the second form
+% is used, the resultant set consists of $n$-tuples enumerated within the
+% curly braces, where a particular $n$-tuple consists of corresponding
+% components enumerated within the parentheses. All $n$-tuples should
+% have the same number of components.
+
+\subsection{Conjuntos não-indexados}
+
+Se a expressão de conjunto primária é um conjunto não-indexado
+(que deve ser 0-dimensional), o conjunto resultante é um conjunto
+elementar associado com o objeto conjunto correspondente.
+
+% If the primary set expression is an unsubscripted set (which should be
+% 0-dimen\-sional), the resultant set is an elemental set associated with
+% the corresponding set object.
+
+\subsection{Conjuntos indexados}
+
+A expressão de conjunto primária, que se refere a um conjunto indexado,
+tem a seguinte forma sintática:
+$$\mbox{{\it nome}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,}
+$i_n${\tt]}}$$
+onde {\it nome} é o nome simbólico do objeto conjunto e $i_1$, $i_2$,
+\dots, $i_n$ são subíndices.
+
+% The primary set expression, which refers to a subscripted set, has the
+% following syntactic form:
+% $$\mbox{{\it name}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,}
+% $i_n${\tt]}}$$
+% where {\it name} is the symbolic name of the set object, $i_1$, $i_2$,
+% \dots, $i_n$ are subscripts.
+
+Cada subíndice deve ser uma expressão numérica ou simbólica. O número de
+subíndices nas lista de subíndices deve ser o mesmo da dimensão do objeto
+conjunto com o qual as lista de subíndice está associada.
+
+Os valores correntes das expressões de subíndices são usados para identificar
+um membro \linebreak particular do objeto conjunto que determina o conjunto resultante.
+
+% Each subscript should be a numeric or symbolic expression. The number
+% of subscripts in the subscript list should 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.
+
+\subsection{Conjuntos ``aritméticos''}
+
+A expressão de conjunto primária que constitui um conjunto ``aritmético'',
+possui as duas formas sintáticas seguintes:
+% The primary set expression, which is an ``arithmetic'' set, has the
+% following two syntactic forms:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{$t_0$ {\tt..} $t_1$ {\tt by} $\delta t$}\\
+\mbox{$t_0$ {\tt..} $t_1$}\\
+\end{array}
+}
+$$
+onde $t_0$, $t_1$, e $\delta t$ são expressões numéricas (o valor de
+$\delta t$ não deve ser zero). A segunda forma é equivalente a primeira
+forma, onde $\delta t=1$.
+
+Se $\delta t>0$, o conjunto resultante é determinado como segue:
+$$\{t:\exists k\in{\cal Z}(t=t_0+k\delta t,\ t_0\leq t\leq t_1)\}.$$
+Caso contrário, se $\delta t<0$, o conjunto resultante é determinado como segue:
+$$\{t:\exists k\in{\cal Z}(t=t_0+k\delta t,\ t_1\leq t\leq t_0)\}.$$
+% $$
+% {\def\arraystretch{1.4}
+% \begin{array}{l}
+% \mbox{$t_0$ {\tt..} $t_1$ {\tt by} $\delta t$}\\
+% \mbox{$t_0$ {\tt..} $t_1$}\\
+% \end{array}
+% }
+% $$
+% where $t_0$, $t_1$, and $\delta t$ are numeric expressions (the value
+% of $\delta t$ should not be zero). The second form is equivalent to the
+% first form, where $\delta t=1$.
+%
+% If $\delta t>0$, the resultant set is determined as follows:
+% $$\{t:\exists k\in{\cal Z}(t=t_0+k\delta t,\ t_0\leq t\leq t_1)\}.$$
+% Otherwise, if $\delta t<0$, the resultant set is determined as follows:
+% $$\{t:\exists k\in{\cal Z}(t=t_0+k\delta t,\ t_1\leq t\leq t_0)\}.$$
+
+\subsection{Expressões indexantes}
+
+Se a expressão primária é uma expressão indexante, o conjunto resultante
+é determinado como descrito anteriormente, na Seção \ref{indexing}, página
+\pageref{indexing}.
+
+% If the primary set expression is an indexing expression, the resultant
+% set is determined as described above in Section \ref{indexing}, page
+% \pageref{indexing}.
+
+\newpage
+
+\subsection{Expressões iteradas}
+
+Uma {\it expressão de conjunto iterada} é uma expressão de conjunto
+primária, que possui a seguinte forma sintática:
+$$\mbox{{\tt setof} {\it expressão-indexante} {\it integrando}}$$
+onde {\it expressão-indexante} é uma expressão indexante, que
+introduz índices e controla a iteração, {\it integrando} é
+tanto uma expressão numérica ou simbólica individual, como uma
+lista de expressões numéricas ou simbólicas separadas por vírgula
+e cercadas entre parênteses.
+
+% An {\it iterated set expression} is a primary set expression, which has
+% the following syntactic form:
+% $$\mbox{{\tt setof} {\it indexing-expression} {\it integrand}}$$
+% where {\it indexing-expression} is an indexing expression, which
+% introduces dummy indices and controls iterating, {\it integrand} is
+% either a single numeric or symbolic expression or a list of numeric and
+% symbolic expressions separated by commae and enclosed in parentheses.
+
+Se o integrando é uma expressão numérica ou simbólica individual, o
+conjunto resultante consiste de 1-tuplas, sendo determinado como segue:
+$$\{x:(i_1,\dots,i_n)\in\Delta\},$$
+\noindent onde $x$ é um valor do integrando, $i_1$, \dots, $i_n$
+são índices introduzidos na expressão indexante, $\Delta$ é
+o domínio, um conjunto de $n$-tuplas especificado pela expressão
+indexante que define valores particulares atribuídos aos índices ao
+realizar a operação de iteração.
+
+% If the integrand is a single numeric or symbolic expression, the
+% resultant set consists of 1-tuples and is determined as follows:
+% $$\{x:(i_1,\dots,i_n)\in\Delta\},$$
+% \noindent where $x$ is a value of the integrand, $i_1$, \dots, $i_n$
+% are dummy indices introduced in the indexing expression, $\Delta$ is
+% the domain, a set of $n$-tuples specified by the indexing expression,
+% which defines particular values assigned to the dummy indices on
+% performing the iterated operation.
+
+Se o integrando é uma lista contendo $m$ expressões numéricas e simbólicas,
+o conjunto resultante consiste de $m$-tuplas, sendo determinado
+como segue:
+$$\{(x_1,\dots,x_m):(i_1,\dots,i_n)\in\Delta\},$$
+onde $x_1$, \dots, $x_m$ são valores das expressões na lista
+de integrandos, $i_1$, \dots, $i_n$ e $\Delta$ possuem o mesmo significado
+anterior.
+
+% If the integrand is a list containing $m$ numeric and symbolic
+% expressions, the resultant set consists of $m$-tuples and is determined
+% as follows:
+% $$\{(x_1,\dots,x_m):(i_1,\dots,i_n)\in\Delta\},$$
+% where $x_1$, \dots, $x_m$ are values of the expressions in the
+% integrand list, $i_1$, \dots, $i_n$ and $\Delta$ have the same meaning
+% as above.
+
+\subsection{Expressões condicionais}
+
+Uma {\it expressão de conjunto condicional} é uma expressão de conjunto
+primária que possui a seguinte forma sintática:
+$$\mbox{{\tt if} $b$ {\tt then} $X$ {\tt else} $Y$}$$
+onde $b$ é uma expressão lógica, $X$ e $Y$ são expressões de conjunto,
+que devem definir conjuntos da mesma dimensão.
+
+% A {\it conditional set expression} is a primary set expression that has
+% the following syntactic form:
+% $$\mbox{{\tt if} $b$ {\tt then} $X$ {\tt else} $Y$}$$
+% where $b$ is an logical expression, $X$ and $Y$ are set expressions,
+% which should define sets of the same dimension.
+
+O valor resultante da expressão condicional depende do valor da
+expressão lógica que segue a palavra-chave {\tt if}. Se ela recebe
+o valor {\it verdadeiro}, o conjunto resultante é o valor da expressão
+que segue a palavra-chave {\tt then}. Caso contrário, se a
+expressão lógica recebe o valor {\it falso}, o conjunto resultante é
+o valor da expressão que segue a palavra-chave {\tt else}.
+
+% The resultant value of the conditional expression depends on the value
+% of the logical expression that follows the keyword {\tt if}. If it
+% takes on the value {\it true}, the resultant set is the value of the
+% expression that follows the keyword {\tt then}. Otherwise, if the
+% logical expression takes on the value {\it false}, the resultant set is
+% the value of the expression that follows the keyword {\tt else}.
+
+\subsection{Expressões parentizadas}
+
+Qualquer expressão de conjunto pode ser cercada entre parênteses, o que as tornam
+\linebreak sintaticamente uma expressão de conjunto primária.
+Parênteses podem ser usados em expressões de conjunto, como em álgebra, para
+especificar a ordem desejada nas quais as operações devem ser executadas.
+Quando se usam parênteses, a expressão entre parênteses é avaliada
+antes que o valor resultante seja usado.
+O valor resultante de uma expressão parentizada é idêntico ao valor da expressão
+cercada entre parênteses.
+
+% Any set expression may be enclosed in parentheses that syntactically
+% makes it a 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.
+
+\newpage
+
+\subsection{Operadores de conjunto}
+
+Em MathProg existem os seguintes operadores de conjunto, que podem ser
+usados em expressões de conjunto:
+
+% In MathProg there exist the following set operators, which may be used
+% in set expressions:
+
+\begin{tabular}{@{}ll@{}}
+$X$ {\tt union} $Y$&união $X\cup Y$\\
+$X$ {\tt diff} $Y$&diferença $X\backslash Y$\\
+$X$ {\tt symdiff} $Y$&diferença simétrica
+$X\oplus Y=(X\backslash Y)\cup(Y\backslash X)$\\
+$X$ {\tt inter} $Y$&interseção $X\cap Y$\\
+$X$ {\tt cross} $Y$&produto Cartesiano (cruzado) $X\times Y$\\
+\end{tabular}
+
+% \begin{tabular}{@{}ll@{}}
+% $X$ {\tt union} $Y$&union $X\cup Y$\\
+% $X$ {\tt diff} $Y$&difference $X\backslash Y$\\
+% $X$ {\tt symdiff} $Y$&symmetric difference
+% $X\oplus Y=(X\backslash Y)\cup(Y\backslash X)$\\
+% $X$ {\tt inter} $Y$&intersection $X\cap Y$\\
+% $X$ {\tt cross} $Y$&cross (Cartesian) product $X\times Y$\\
+% \end{tabular}
+
+\noindent onde $X$ e Y são expressões de conjunto, que devem definir conjuntos
+de dimensões idênticas (exceto o produto Cartesiano).
+
+Se a expressão inclui mais de um operador de conjunto, todos operadores
+são executados da esquerda para a direita de acordo com a hierarquia das
+operações (veja adiante).
+
+O valor resultante da expressão, que contém operadores de conjunto, é
+o resultado da aplicação dos operadores aos seus operandos.
+
+A dimensão do conjunto resultante, i.e., a dimensão das $n$-tuplas,
+dos quais consistem o conjunto resultante, é a mesma da dimensão dos
+operandos, exceto o produto Cartesiano, onde a dimensão do conjunto
+resultante é a soma das dimensões dos seus operandos.
+
+% \noindent where $X$ and Y are set expressions, which should define sets
+% of identical dimension (except 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 $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 the dimensions of its operands.
+
+\subsection{Hierarquia das operações}
+
+A lista seguinte mostra a hierarquia das operações em expressões de conjunto:
+
+% The following list shows the hierarchy of operations in set
+% expressions:
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Operação&Hierarquia\\
+\hline
+Avaliação de operações numéricas&
+1{\textsuperscript{\b{a}}}-7{\textsuperscript{\b{a}}}\\
+Avaliação de operações simbólicas&
+8{\textsuperscript{\b{a}}}-9{\textsuperscript{\b{a}}}\\
+Avaliação de conjuntos iterados ou ``aritméticos'' ({\tt setof}, {\tt..})&
+10{\textsuperscript{\b{a}}}\\
+Produto Cartesiano ({\tt cross})&
+11{\textsuperscript{\b{a}}}\\
+Interseção ({\tt inter})&
+12{\textsuperscript{\b{a}}}\\
+União e diferença ({\tt union}, {\tt diff}, {\tt symdiff})&
+13{\textsuperscript{\b{a}}}\\
+Avaliação condicional ({\tt if} \dots {\tt then} \dots {\tt else})&
+14{\textsuperscript{\b{a}}}\\
+\end{tabular}
+
+% \noindent\hfil
+% \begin{tabular}{@{}ll@{}}
+% Operation&Hierarchy\\
+% \hline
+% Evaluation of numeric operations&1st-7th\\
+% Evaluation of symbolic operations&8th-9th\\
+% Evaluation of iterated or ``arithmetic'' set ({\tt setof}, {\tt..})&
+% 10th\\
+% Cartesian product ({\tt cross})&11th\\
+% Intersection ({\tt inter})&12th\\
+% Union and difference ({\tt union}, {\tt diff}, {\tt symdiff})&13th\\
+% Conditional evaluation ({\tt if} \dots {\tt then} \dots {\tt else})&
+% 14th\\
+% \end{tabular}
+
+Esta hierarquia possui o mesmo significado como explicado anteriormente
+para expressões \linebreak numéricas (ver Subseção \ref{hierarchy}, página \pageref{hierarchy}).
+
+% This hierarchy has the same meaning as was explained above for numeric
+% expressions (see Subsection \ref{hierarchy}, page \pageref{hierarchy}).
+
+\newpage
+
+\section{Expressões lógicas}
+
+Uma {\it expressão lógica} é uma regra para calcular um valor lógico
+individual, que pode ser {\it verdadeiro} ou {\it falso}.
+
+A expressão lógica primária pode ser uma expressão numérica,
+uma expressão relacional, uma expressão lógica iterada ou
+outra expressão lógica cercada entre parênteses.
+
+\para{Exemplos}
+
+% A {\it logical expression} is a rule for computing a single logical
+% value, which can be either {\it true} or {\it false}.
+%
+% The primary logical expression may be a numeric expression, relational
+% expression, iterated logical expression, or another logical expression
+% enclosed in parentheses.
+%
+% \para{Examples}
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|i+1| &(expressão numérica)\\
+\verb|a[i,j] < 1.5| &(expressão relacional)\\
+\verb|s[i+1,j-1] <> 'Mar' & year | &(expressão relacional)\\
+\verb|(i+1,'Jan') not in I cross J| &(expressão relacional)\\
+\verb|S union T within A[i] inter B[j]| &(expressão relacional)\\
+\verb|forall{i in I, j in J} a[i,j] < .5 * b[i]| &(expressão lógica iterada)\\
+\verb|(a[i,j] < 1.5 or b[i] >= a[i,j])| &(expressão lógica parentizada)\\
+\end{tabular}
+
+% \noindent
+% \begin{tabular}{@{}ll@{}}
+% \verb|i+1| &(numeric expression)\\
+% \verb|a[i,j] < 1.5| &(relational expression)\\
+% \verb|s[i+1,j-1] <> 'Mar' & year | &(relational expression)\\
+% \verb|(i+1,'Jan') not in I cross J| &(relational expression)\\
+% \verb|S union T within A[i] inter B[j]| &(relational expression)\\
+% \verb|forall{i in I, j in J} a[i,j] < .5 * b[i]| &(iterated logical
+% expression)\\
+% \verb|(a[i,j] < 1.5 or b[i] >= a[i,j])| &(parenthesized logical
+% expression)\\
+% \end{tabular}
+
+Expressões lógicas mais genéricas, contendo duas ou mais
+expressões lógicas primárias, podem ser construídas usando
+determinados operadores lógicos.
+
+\para{Exemplos}
+
+\begin{verbatim}
+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{verbatim}
+
+% More general logical expressions containing two or more primary logical
+% expressions may be constructed by using certain logical operators.
+%
+% \para{Examples}
+%
+% \begin{verbatim}
+% 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{verbatim}
+\vspace*{-8pt}
+
+\subsection{Expressões numéricas}
+
+O valor resultante da expressão lógica primária, que é uma
+expressão numérica, é {\it verdadeiro}, se o valor resultante da
+expressão numérica é diferente de zero. Caso contrário o valor resultante
+da expressão lógica é {\it falso}.
+
+% The resultant value of the primary logical expression, which is a
+% numeric expression, is {\it true}, if the resultant value of the
+% numeric expression is non-zero. Otherwise the resultant value of the
+% logical expression is {\it false}.
+
+\vspace*{-8pt}
+
+\subsection{Operadores relacionais}
+
+Em MathProg existem os seguintes operadores relacionais, que podem
+ser usados em expressões lógicas:
+
+% In MathProg there exist the following relational operators, which may
+% be used in logical expressions:
+
+\begin{tabular}{@{}ll@{}}
+$x$ {\tt<} $y$&verifica se $x<y$\\
+$x$ {\tt<=} $y$&verifica se $x\leq y$\\
+$x$ {\tt=} $y$, $x$ {\tt==} $y$&verifica se $x=y$\\
+$x$ {\tt>=} $y$&verifica se $x\geq y$\\
+$x$ {\tt>} $y$&verifica se $x>y$\\
+$x$ {\tt<>} $y$, $x$ {\tt!=} $y$&verifica se $x\neq y$\\
+$x$ {\tt in} $Y$&verifica se $x\in Y$\\
+{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt in} $Y$&verifica se
+$(x_1,\dots,x_n)\in Y$\\
+$x$ {\tt not} {\tt in} $Y$, $x$ {\tt!in} $Y$&verifica se $x\not\in Y$\\
+{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt not} {\tt in} $Y$,
+{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt !in} $Y$&verifica se
+$(x_1,\dots,x_n)\not\in Y$\\
+$X$ {\tt within} $Y$&verifica se $X\subseteq Y$\\
+$X$ {\tt not} {\tt within} $Y$, $X$ {\tt !within} $Y$&verifica se
+$X\not\subseteq Y$\\
+\end{tabular}
+
+% \begin{tabular}{@{}ll@{}}
+% $x$ {\tt<} $y$&test on $x<y$\\
+% $x$ {\tt<=} $y$&test on $x\leq y$\\
+% $x$ {\tt=} $y$, $x$ {\tt==} $y$&test on $x=y$\\
+% $x$ {\tt>=} $y$&test on $x\geq y$\\
+% $x$ {\tt>} $y$&test on $x>y$\\
+% $x$ {\tt<>} $y$, $x$ {\tt!=} $y$&test on $x\neq y$\\
+% $x$ {\tt in} $Y$&test on $x\in Y$\\
+% {\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt in} $Y$&test on
+% $(x_1,\dots,x_n)\in Y$\\
+% $x$ {\tt not} {\tt in} $Y$, $x$ {\tt!in} $Y$&test on $x\not\in Y$\\
+% {\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt not} {\tt in} $Y$,
+% {\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt !in} $Y$&test on
+% $(x_1,\dots,x_n)\not\in Y$\\
+% $X$ {\tt within} $Y$&test on $X\subseteq Y$\\
+% $X$ {\tt not} {\tt within} $Y$, $X$ {\tt !within} $Y$&test on
+% $X\not\subseteq Y$\\
+% \end{tabular}
+
+\noindent onde $x$, $x_1$, \dots, $x_n$, $y$ são expressões numéricas ou
+simbólicas, $X$ e $Y$ são expressões de conjunto.
+
+% \noindent where $x$, $x_1$, \dots, $x_n$, $y$ are numeric or symbolic
+% expressions, $X$ and $Y$ are set expression.
+
+\newpage
+
+1. Nas operações {\tt in}, {\tt not in} e {\tt !in} o número
+de componentes nos primeiros operandos deve ser igual a
+dimensão do segundo operando.
+
+2. Nas operações {\tt within}, {\tt not within} e {\tt !within}
+ambos operandos devem ter a mesma dimensão.
+
+Todos operadores relacionais listados acima têm seus significados
+matemáticos convencionais. O valor resultante é {\it verdadeiro}, se
+a relação correspondente é satisfeita para seus operandos, caso contrário
+é {\it falso}. (Note que valores simbólicos são ordenados de forma
+lexicográfica e qualquer valor numérico precede qualquer valor simbólico.)
+
+% 1. In the operations {\tt in}, {\tt not in}, and {\tt !in} the
+% number of components in the first operands should be the same as the
+% dimension of the second operand.
+%
+% 2. In the operations {\tt within}, {\tt not within}, and {\tt !within}
+% both operands should have identical dimension.
+%
+% All the relational operators listed above have their conventional
+% mathematical meaning. The resultant value is {\it true}, if
+% corresponding relation is satisfied for its operands, otherwise
+% {\it false}. (Note that symbolic values are ordered lexicographically,
+% and any numeric value precedes any symbolic value.)
+
+\subsection{Expressões iteradas}
+
+Uma {\it expressão lógica iterada} é uma expressão lógica primária
+com a seguinte forma sintática:
+$$\mbox{{\it operador-iterado} {\it expressão-indexante}
+{\it integrando}}$$
+onde {\it operador-iterado} é o nome simbólico do operador iterado
+a ser executado (veja adiante), {\it expressão-indexante} é uma
+expressão indexante que introduz índices e controla a iteração, \linebreak
+{\it integrando} é uma expressão numérica que participa da operação.
+
+Em MathProg existem dois operadores iterados que podem ser usados
+em expressões lógicas:
+
+% An {\it iterated logical expression} is a primary logical expression,
+% which has the following syntactic form:
+% $$\mbox{{\it iterated-operator} {\it indexing-expression}
+% {\it integrand}}$$
+% where {\it iterated-operator} is the symbolic name of the iterated
+% operator to be performed (see below), {\it indexing-expression} is an
+% indexing expression which introduces dummy indices and controls
+% iterating, {\it integrand} is a numeric expression that participates in
+% the operation.
+%
+% In MathProg there exist two iterated operators, which may be used in
+% logical expressions:
+
+{\def\arraystretch{1.4}
+\noindent\hfil
+\begin{tabular}{@{}lll@{}}
+{\tt forall}&quantificador-$\forall$&$\displaystyle
+\forall(i_1,\dots,i_n)\in\Delta[f(i_1,\dots,i_n)],$\\
+{\tt exists}&quantificador-$\exists$&$\displaystyle
+\exists(i_1,\dots,i_n)\in\Delta[f(i_1,\dots,i_n)],$\\
+\end{tabular}
+}
+
+% {\def\arraystretch{1.4}
+% \noindent\hfil
+% \begin{tabular}{@{}lll@{}}
+% {\tt forall}&$\forall$-quantification&$\displaystyle
+% \forall(i_1,\dots,i_n)\in\Delta[f(i_1,\dots,i_n)],$\\
+% {\tt exists}&$\exists$-quantification&$\displaystyle
+% \exists(i_1,\dots,i_n)\in\Delta[f(i_1,\dots,i_n)],$\\
+% \end{tabular}
+% }
+
+\noindent onde $i_1$, \dots, $i_n$ são índices introduzidos na
+expressão indexante, $\Delta$ é o domínio, um conjunto de $n$-tuplas
+especificado pela expressão indexante que define valores específicos
+atribuídos aos índices ao executar a operação iterada, e
+$f(i_1,\dots,i_n)$ é o integrando, uma expressão lógica cujo
+valor resultante depende dos índices.
+
+Para o quantificador $\forall$, o valor resultante da expressão
+lógica iterada é {\it verdadeiro}, se o valor do integrando é
+{\it verdadeiro} para todas as $n$-tuplas contidas no domínio,
+caso contrário, é {\it falso}.
+
+Para o quantificador $\exists$ o valor resultante da expressão
+lógica iterada é {\it falso}, se o valor do integrando é
+{\it falso} para todas as $n$-tuplas contidas no domínio,
+caso contrário, é {\it verdadeiro}.
+
+% \noindent where $i_1$, \dots, $i_n$ are dummy indices introduced in
+% the indexing expression, $\Delta$ is the domain, a set of $n$-tuples
+% specified by the indexing expression which defines particular values
+% assigned to the dummy indices on performing the iterated operation,
+% $f(i_1,\dots,i_n)$ is the integrand, a logical expression whose
+% resultant value depends on the dummy indices.
+%
+% For $\forall$-quantification the resultant value of the iterated
+% logical expression is {\it true}, if the value of the integrand is
+% {\it true} for all $n$-tuples contained in the domain, otherwise
+% {\it false}.
+%
+% For $\exists$-quantification the resultant value of the iterated
+% logical expression is {\it false}, if the value of the integrand is
+% {\it false} for all $n$-tuples contained in the domain, otherwise
+% {\it true}.
+
+\subsection{Expressões parentizadas}
+
+Qualquer expressão lógica pode ser cercada entre parênteses, o que a
+converte sintaticamente em uma expressão lógica primária.
+
+Parênteses podem ser usados em expressões lógicas, como em álgebra, para
+especificar a ordem desejada na qual as operações devem ser executadas.
+Quando se usam parênteses, a expressão entre parênteses é avaliada antes
+que o valor resultante seja usado.
+
+O valor resultante da expressão parentizada é idêntico ao valor da expressão
+cercada entre parênteses.
+
+% Any logical expression may be enclosed in parentheses that
+% syntactically makes it a 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.
+
+\newpage
+
+\subsection{Operadores lógicos}
+
+Em MathProg existem os seguintes operadores lógicos, que podem ser usados em
+expressões lógicas:
+
+% In MathProg there exist the following logical operators, which may be
+% used in logical expressions:
+
+\begin{tabular}{@{}ll@{}}
+{\tt not} $x$, {\tt!}$x$&negação $\neg\ x$\\
+$x$ {\tt and} $y$, $x$ {\tt\&\&} $y$&conjunção (``e'' lógico)
+$x\;\&\;y$\\
+$x$ {\tt or} $y$, $x$ {\tt||} $y$&disjunção (``ou'' lógico)
+$x\vee y$\\
+\end{tabular}
+
+% \begin{tabular}{@{}ll@{}}
+% {\tt not} $x$, {\tt!}$x$&negation $\neg\ x$\\
+% $x$ {\tt and} $y$, $x$ {\tt\&\&} $y$&conjunction (logical ``and'')
+% $x\;\&\;y$\\
+% $x$ {\tt or} $y$, $x$ {\tt||} $y$&disjunction (logical ``or'')
+% $x\vee y$\\
+% \end{tabular}
+
+\noindent onde $x$ e $y$ são expressões lógicas.
+
+Se a expressão inclui mais de um operador lógico, todos operadores
+são executados da esquerda para a direita de acordo com a hierarquia
+das operações (veja adiante). O valor resultante da \linebreak expressão
+que contém operadores lógicos é o resultado da aplicação dos
+operadores aos seus \linebreak operandos.
+
+% \noindent where $x$ and $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 the operations (see below). The resultant value of the expression,
+% which contains logical operators, is the result of applying the
+% operators to their operands.
+
+\subsection{Hierarquia das operações}
+
+A lista seguinte mostra a hierarquia das operações em expressões
+lógicas:
+
+% The following list shows the hierarchy of operations in logical
+% expressions:
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Operation&Hierarchy\\
+\hline
+Avaliação de operações numéricas&
+1{\textsuperscript{\b{a}}}-7{\textsuperscript{\b{a}}}\\
+Avaliação de operações simbólicas&
+8{\textsuperscript{\b{a}}}-9{\textsuperscript{\b{a}}}\\
+Avaliação de operações de conjunto&
+10{\textsuperscript{\b{a}}}-14{\textsuperscript{\b{a}}}\\
+Operações relacionais ({\tt<}, {\tt<=}, etc.)&
+15{\textsuperscript{\b{a}}}\\
+negação ({\tt not}, {\tt!})&
+16{\textsuperscript{\b{a}}}\\
+Conjunção({\tt and}, {\tt\&\&})&
+17{\textsuperscript{\b{a}}}\\
+Quantificação-$\forall$ e -$\exists$ ({\tt forall}, {\tt exists})&
+18{\textsuperscript{\b{a}}}\\
+Disjunção ({\tt or}, {\tt||})&
+19{\textsuperscript{\b{a}}}\\
+\end{tabular}
+
+% \noindent\hfil
+% \begin{tabular}{@{}ll@{}}
+% Operation&Hierarchy\\
+% \hline
+% Evaluation of numeric operations&1st-7th\\
+% Evaluation of symbolic operations&8th-9th\\
+% Evaluation of set operations&10th-14th\\
+% Relational operations ({\tt<}, {\tt<=}, etc.)&15th\\
+% Negation ({\tt not}, {\tt!})&16th\\
+% Conjunction ({\tt and}, {\tt\&\&})&17th\\
+% $\forall$- and $\exists$-quantification ({\tt forall}, {\tt exists})&
+% 18th\\
+% Disjunction ({\tt or}, {\tt||})&19th\\
+% \end{tabular}
+
+Esta hierarquia possui o mesmo significado como explicado anteriormente
+para expressões \linebreak numéricas (ver Subseção \ref{hierarchy}, página \pageref{hierarchy}).
+
+% This hierarchy has the same meaning as was explained above for numeric
+% expressions (see Subsection \ref{hierarchy}, page \pageref{hierarchy}).
+
+\newpage
+
+\section{Expressões lineares}
+
+Uma {\it expressão linear} é uma regra para calcular a chamada
+{\it forma linear} ou simplesmente {\it fórmula}, que é uma função linear (ou
+afim) de variáveis elementares.
+
+A expressão linear primária pode ser uma variável não-indexada, uma
+variável indexada, uma expressão linear iterada, uma expressão linear condicional
+ou outra expressão linear cercada entre parênteses.
+
+Também e permitido usar uma expressão numérica como a expressão linear
+primária, neste caso, o valor resultante da expressão numérica
+é automaticamente convertido para uma fórmula que inclui o
+termo constante apenas.
+
+\para{Exemplos}
+
+% A {\it linear expression} is a rule for computing so called
+% a {\it linear form} or simply a {\it 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 a formula that includes the constant term
+% only.
+%
+% \para{Examples}
+
+\noindent
+\begin{tabular}{@{}ll@{}}
+\verb|z| &(variável não-indexada)\\
+\verb|x[i,j]| &(variável indexada)\\
+\verb|sum{j in J} (a[i,j] * x[i,j] + 3 * y[i-1])| &
+(expressão linear iterada)\\
+\verb|if i in I then x[i,j] else 1.5 * z + 3.25| &
+(expressão linear condicional)\\
+\verb|(a[i,j] * x[i,j] + y[i-1] + .1)| &
+(expressão linear parentizada)\\
+\end{tabular}
+
+% \noindent
+% \begin{tabular}{@{}ll@{}}
+% \verb|z| &(unsubscripted variable)\\
+% \verb|x[i,j]| &(subscripted variable)\\
+% \verb|sum{j in J} (a[i,j] * x[i,j] + 3 * y[i-1])| &
+% (iterated linear expression)\\
+% \verb|if i in I then x[i,j] else 1.5 * z + 3.25| &
+% (conditional linear expression)\\
+% \verb|(a[i,j] * x[i,j] + y[i-1] + .1)| &
+% (parenthesized linear expression)\\
+% \end{tabular}
+
+Expressões lineares mais genéricas, contendo duas ou mais
+expressões lineares primárias, podem ser construídas usando
+determinados operadores aritméticos.
+
+\para{Exemplos}
+
+% More general linear expressions containing two or more primary linear
+% expressions may be constructed by using certain arithmetic operators.
+%
+% \para{Examples}
+
+\begin{verbatim}
+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{verbatim}
+
+\vspace*{-5pt}
+
+\subsection{Variáveis não-indexadas}
+
+Se a expressão linear primária é uma variável não-indexada (que deve
+se 0-dimensional), a fórmula resultante formula é aquela variável
+não-indexada.
+
+% If the primary linear expression is an unsubscripted variable (which
+% should be 0-dimensional), the resultant formula is that unsubscripted
+% variable.
+
+\vspace*{-5pt}
+
+\subsection{Variáveis indexadas}
+
+A expressão linear primária que se refere a uma variável indexada possui
+a seguinte forma sintática:
+$$\mbox{{\it nome}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,}
+$i_n${\tt]}}$$
+onde {\it nome} é o nome simbólico da variável do modelo, $i_1$,
+$i_2$, \dots, $i_n$ são subíndices.
+
+Cada subíndice deve ser uma expressão numérica ou simbólica. O número
+de subíndices na lista de subíndices deve ser igual ao da dimensão da
+variável do modelo com a qual está associada a lista de subíndices.
+
+Os valores correntes das expressões dos subíndices são usados para identificar
+um membro \linebreak particular da variável do modelo que determina a fórmula resultante,
+que é uma variável elementar associada com o membro correspondente.
+
+% The primary linear expression, which refers to a subscripted variable,
+% has the following syntactic form:
+% $$\mbox{{\it name}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,}
+% $i_n${\tt]}}$$
+% where {\it name} is the symbolic name of the model variable, $i_1$,
+% $i_2$, \dots, $i_n$ are subscripts.
+%
+% Each subscript should be a numeric or symbolic expression. The number
+% of subscripts in the subscript list should be the same as the dimension
+% of the model variable with which the subscript list is associated.
+%
+% Actual values of the 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 corresponding
+% member.
+
+\vspace*{-5pt}
+
+\subsection{Expressões iteradas}
+
+Uma {\it expressão linear iterada} é uma expressão linear primária,
+que tem a seguinte forma sintática:
+$$\mbox{{\tt sum} {\it expressão-indexante} {\it integrando}}$$
+onde {\it expressão-indexante} é uma expressão indexante, que
+introduz índices e controla iterações, {\it integrando} é
+uma expressão linear que participa da operação.
+
+A expressão linear iterada é avaliada exatamente da mesma forma que a
+expressão numérica iterada (ver Subseção \ref{itexpr}, página
+\pageref{itexpr}), exceto que o integrando participante do
+somatório é uma fórmula e não um valor numérico.
+
+% An {\it iterated linear expression} is a primary linear expression,
+% which has the following syntactic form:
+% $$\mbox{{\tt sum} {\it indexing-expression} {\it integrand}}$$
+% where {\it indexing-expression} is an indexing expression, which
+% introduces dummy indices and controls iterating, {\it 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 Subection \ref{itexpr}, page
+% \pageref{itexpr}) with exception that the integrand participated in the
+% summation is a formula, not a numeric value.
+
+\vspace*{-5pt}
+
+\subsection{Expressões condicionais}
+
+Uma {\it expressão linear condicional} é uma expressão linear primária,
+que possui uma das duas formas sintáticas seguintes:
+$$
+{\def\arraystretch{1.4}
+\begin{array}{l}
+\mbox{{\tt if} $b$ {\tt then} $f$ {\tt else} $g$}\\
+\mbox{{\tt if} $b$ {\tt then} $f$}\\
+\end{array}
+}
+$$
+onde $b$ é uma expressão lógica, $f$ e $g$ são expressões lineares.
+
+
+% A {\it conditional linear expression} is a primary linear expression,
+% which has one of the following two syntactic forms:
+% $$
+% {\def\arraystretch{1.4}
+% \begin{array}{l}
+% \mbox{{\tt if} $b$ {\tt then} $f$ {\tt else} $g$}\\
+% \mbox{{\tt if} $b$ {\tt then} $f$}\\
+% \end{array}
+% }
+% $$
+% where $b$ is an logical expression, $f$ and $g$ are linear expressions.
+
+% \newpage
+
+A expressão linear condicional é avaliada exatamente da mesma forma
+que a expressão \linebreak condicional numérica (ver Subseção \ref{ifthen},
+página \pageref{ifthen}), exceto que os operandos que participam da operação
+são fórmulas e não valores numéricos.
+
+% The conditional linear expression is evaluated exactly in the same way
+% as the conditional numeric expression (see Subsection \ref{ifthen},
+% page \pageref{ifthen}) with exception that operands participated in the
+% operation are formulae, not numeric values.
+
+\subsection{Expressões parentizadas}
+
+Qualquer expressão linear pode ser cercada entre parênteses, o que a
+converte sintaticamente em uma expressão linear primária.
+
+Parênteses podem ser usados em expressões lineares, como em álgebra, para
+especificar a ordem desejada na qual as operações devem ser executadas.
+Quando se usam parênteses, a expressão entre parênteses é avaliada antes
+que a fórmula resultante seja usada.
+
+O valor resultante da expressão parentizada é idêntico ao valor da
+expressão cercada entre parênteses.
+
+% Any linear expression may be enclosed in parentheses that syntactically
+% makes it a 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.
+
+\subsection{Operadores aritméticos}
+
+Em MathProg existem os seguintes operadores aritméticos, que podem ser
+usados em expressões lineares:
+
+% In MathProg there exists the following arithmetic operators, which may
+% be used in linear expressions:
+
+\begin{tabular}{@{}ll@{}}
+{\tt+} $f$&mais unário\\
+{\tt-} $f$&menos unário\\
+$f$ {\tt+} $g$&adição\\
+$f$ {\tt-} $g$&subtração\\
+$x$ {\tt*} $f$, $f$ {\tt*} $x$&multiplicação\\
+$f$ {\tt/} $x$&divisão
+\end{tabular}
+
+% \begin{tabular}{@{}ll@{}}
+% {\tt+} $f$&unary plus\\
+% {\tt-} $f$&unary minus\\
+% $f$ {\tt+} $g$&addition\\
+% $f$ {\tt-} $g$&subtraction\\
+% $x$ {\tt*} $f$, $f$ {\tt*} $x$&multiplication\\
+% $f$ {\tt/} $x$&division
+% \end{tabular}
+
+\noindent onde $f$ e $g$ são expressões lineares, $x$ é uma expressão
+numérica (mais precisamente, uma expressão linear contendo apenas o termo
+constante).
+
+Se a expressão inclui mais de um operador aritmético, todos
+operadores são executados da esquerda para a direita de acordo com a hierarquia
+das operações (veja adiante). O valor resultante da expressão, que
+contém operadores aritméticos, é o resultado de aplicar os operadores aos
+seus operandos.
+
+% \noindent where $f$ and $g$ are linear expressions, $x$ is a numeric
+% expression (more precisely, a linear expression containing only the
+% constant term).
+%
+% 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.
+
+\subsection{Hierarquia das operações}
+
+A hierarquia de operações aritméticas usada em expressões lineares é a mesma
+para expressões numéricas (ver Subseção \ref{hierarchy}, página \pageref{hierarchy}).
+
+% The hierarchy of arithmetic operations used in linear expressions is
+% the same as for numeric expressions (see Subsection \ref{hierarchy},
+% page \pageref{hierarchy}).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Sentenças}
+
+{\it Sentenças} são unidades básicas da descrição do modelo. Em MathProg
+todas as sentenças são divididas em duas categorias: sentenças de declaração
+e sentenças funcionais.
+
+{\it Sentenças de declaração} (sentença {\it set}, sentença {\it parameter},
+sentença {\it variable}, sentença \linebreak {\it constraint}, sentença {\it objective}) são
+usados para declarar objetos de certo tipo do modelo e definir certas propriedades
+de tais objetos.
+
+{\it Sentenças funcionais} (sentença {\it solve}, sentença {\it check},
+sentença {\it display}, sentença {\it printf}, sentença {\it loop}, sentença
+{\it table}) são projetadas para executar ações específicas.
+
+Note que sentenças de declaração podem seguir em qualquer ordem arbitrária,
+o que não afeta o resultado da tradução. Entretanto, qualquer objeto de modelo
+deve ser declarado antes de ser referenciado por outras sentenças.
+
+% {\it Statements} are basic units of the model description. In MathProg
+% all statements are divided into two categories: declaration statements
+% and functional statements.
+%
+% {\it Declaration statements} (set statement, parameter statement,
+% variable statement, constraint statement, objective statement) are used
+% to declare model objects of certain kinds and define certain properties
+% of such objects.
+%
+% {\it Functional statements} (solve statement, check statement, display
+% statement, printf statement, loop statement, table 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
+% should be declared before it is referenced in other statements.
+
+\section{Sentença set}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt set} {\it nome} {\it alias} {\it domínio} {\tt,}
+{\it atributo} {\tt,} \dots {\tt,} {\it atributo} {\tt;}
+}}
+
+% \noindent
+% \framebox[468pt][l]{
+% \parbox[c][24pt]{468pt}{
+% \hspace{6pt} {\tt set} {\it name} {\it alias} {\it domain} {\tt,}
+% {\it attrib} {\tt,} \dots {\tt,} {\it attrib} {\tt;}
+% }}
+
+\medskip
+
+\noindent
+{\it nome} é um nome simbólico do conjunto;
+
+\noindent
+{\it alias} é um literal de cadeia opcional que especifica um pseudônimo
+para o conjunto;
+
+\noindent
+{\it domínio} é uma expressão indexante opcional que especifica o domínio
+do subíndice do conjunto;
+
+\noindent
+{\it atributo}, \dots, {\it atributo} são atributos opcionais do conjunto
+(as vírgulas que precedem os atributos podem ser omitidas.)
+
+\para{Atributos opcionais}
+
+% \noindent
+% {\it name} is a symbolic name of the set;
+%
+% \noindent
+% {\it alias} is an optional string literal, which specifies an alias of
+% the set;
+%
+% \noindent
+% {\it domain} is an optional indexing expression, which specifies
+% a subscript domain of the set;
+%
+% \noindent
+% {\it attrib}, \dots, {\it attrib} are optional attributes of the set.
+% (Commae preceding attributes may be omitted.)
+%
+% \para{Optional attributes}
+
+\vspace*{-8pt}
+
+\begin{description}
+\item[{\tt dimen} $n$]\hspace*{0pt}\\
+especifica a dimensão de $n$-tuplas das quais o conjunto é consistido;
+\item[{\tt within} {\it expressão}]\hspace*{0pt}\\
+especifica um superconjunto que restringe ao conjunto ou a todos seus
+membros (conjuntos elementares) a estarem incluídos naquele superconjunto;
+\item[{\tt:=} {\it expressão}]\hspace*{0pt}\\
+especifica um conjunto elementar atribuído ao conjunto ou aos seus membros;
+\item[{\tt default} {\it expressão}]\hspace*{0pt}\\
+especifica um conjunto elementar atribuído ao conjunto ou aos seus membros
+sempre que não há dados apropriados disponíveis na seção de dados.
+\end{description}
+
+% \begin{description}
+% \item[{\tt dimen} $n$]\hspace*{0pt}\\
+% specifies the dimension of $n$-tuples which the set consists of;
+% \item[{\tt within} {\it expression}]\hspace*{0pt}\\
+% specifies a superset which restricts the set or all its members
+% (elemental sets) to be within that superset;
+% \item[{\tt:=} {\it expression}]\hspace*{0pt}\\
+% specifies an elemental set assigned to the set or its members;
+% \item[{\tt default} {\it expression}]\hspace*{0pt}\\
+% specifies an elemental set assigned to the set or its members whenever
+% no appropriate data are available in the data section.
+% \end{description}
+
+\vspace*{-8pt}
+
+\para{Exemplos}
+
+% \para{Examples}
+
+\begin{verbatim}
+set nos;
+set arcos within nos cross nos;
+set passo{s in 1..maxiter} dimen 2 := if s = 1 then arcos else passo[s-1]
+ union setof{k in nos, (i,k) in passo[s-1], (k,j) in passo[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{verbatim}
+
+% \begin{verbatim}
+% set nodes;
+% set arcs within nodes cross nodes;
+% set step{s in 1..maxiter} dimen 2 := if s = 1 then arcs else step[s-1]
+% union setof{k in nodes, (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{verbatim}
+
+A sentença set declara um conjunto. Se o domínio do subíndice não é
+especificado, o conjunto é um conjunto simples, caso contrário será
+uma matriz de conjuntos elementares.
+
+O atributo {\tt dimen} especifica a dimensão de $n$-tuplas da qual é
+consistida o conjunto (se o conjunto é simples) ou seus membros
+(se o conjunto é uma matriz de conjuntos elementares),
+em que $n$ deve ser um inteiro de 1 a 20. Pode-se especificar
+no máximo um atributo {\tt dimen}. Se o atributo {\tt dimen} não é
+especificado, a dimensão das $n$-tuplas é implicitamente determinada
+por outros atributos (por exemplo, se há uma expressão que segue
+{\tt:=} ou a palavra-chave {\tt default}, usa-se a dimensão das $n$-tuplas
+do conjunto elementar correspondente).
+Se nenhuma informação de dimensão é fornecida, assume-se
+{\tt dimen 1}.
+
+O atributo {\tt within} especifica uma expressão de conjunto cujo
+valor resultante é um superconjunto usado para restringir o conjunto
+(se o conjunto é simples) ou seus membros (se o conjunto é uma matriz
+de conjuntos elementares) a estar incluído naquele superconjunto.
+Um número arbitrário de atributos {\tt within} podem ser especificados
+na mesma sentença set.
+
+O atributo de atribuição ({\tt:=}) especifica uma expressão de conjunto
+usada para avaliar conjunto(s) \linebreak elementar(es) atribuído(s) ao conjunto
+(se o conjunto é simples) ou seus membros (se o conjunto é uma matriz
+de conjuntos elementares). Se o atributo de atribuição é especificado,
+o conjunto é {\it calculável}, portanto, não há a necessidade de fornecer
+dados na seção de dados. Se o atributo de atribuição não é especificado,
+deve-se fornecer os dados na seção de dados. Pode-se especificar no
+máximo um atributo de atribuição ou {\tt default} para o mesmo conjunto.
+
+O atributo {\tt default} especifica uma expressão de conjunto usado para
+avaliar conjunto(s) \linebreak elementar(es) atribuído(s) ao conjunto
+(se o conjunto é simples) ou seus membros (se o conjunto é uma matriz
+de conjuntos elementares) sempre que não houver dados apropriados
+disponíveis na seção de dados. Se não se especifica nem o atributo de
+atribuição nem o atributo {\tt default}, a falta de dados causará um erro.
+
+% 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 {\tt dimen} attribute specifies the dimension of $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 $n$ should be an unsigned integer
+% from 1 to 20. At most one {\tt dimen} attribute can be specified. If
+% the {\tt dimen} attribute is not specified, the dimension of $n$-tuples
+% is implicitly determined by other attributes (for example, if there is
+% a set expression that follows {\tt:=} or the keyword {\tt default}, the
+% dimension of $n$-tuples of corresponding elemental set is used).
+% If no dimension information is available, {\tt dimen 1} is assumed.
+%
+% The {\tt 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
+% that superset. Arbitrary number of {\tt within} attributes may be
+% specified in the same set statement.
+%
+% The assign ({\tt:=}) 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 {\it computable} and
+% therefore needs no data to be provided in the data section. If the
+% assign attribute is not specified, the set should be provided with data
+% in the data section. At most one assign or default attribute can be
+% specified for the same set.
+%
+% The {\tt 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 default attribute is specified, missing data will cause an
+% error.
+
+\newpage
+
+\section{Sentença parameter}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt param} {\it nome} {\it alias} {\it domínio} {\tt,}
+{\it attrib} {\tt,} \dots {\tt,} {\it attrib} {\tt;}
+}}
+
+% \noindent
+% \framebox[468pt][l]{
+% \parbox[c][24pt]{468pt}{
+% \hspace{6pt} {\tt param} {\it name} {\it alias} {\it domain} {\tt,}
+% {\it attrib} {\tt,} \dots {\tt,} {\it attrib} {\tt;}
+% }}
+
+\medskip
+
+\noindent
+{\it nome} é um nome simbólico do parâmetro;
+
+\noindent
+{\it alias} é um literal de cadeia opcional que especifica um pseudônimo
+para o parâmetro;
+
+\noindent
+{\it domínio} é uma expressão indexante opcional que especifica o domínio
+do subíndice do parâmetro;
+
+\noindent
+{\it atributo}, \dots, {\it atributo} são atributos opcionais do parâmetro
+(as vírgulas que precedem os atributos podem ser omitidas.)
+
+\para{Atributos opcionais}
+
+% \noindent
+% {\it name} is a symbolic name of the parameter;
+%
+% \noindent
+% {\it alias} is an optional string literal, which specifies an alias of
+% the parameter;
+%
+% \noindent
+% {\it domain} is an optional indexing expression, which specifies
+% a subscript domain of the parameter;
+%
+% \noindent
+% {\it attrib}, \dots, {\it attrib} are optional attributes of the
+% parameter. (Commae preceding attributes may be omitted.)
+%
+% \para{Optional attributes}
+
+\vspace*{-8pt}
+
+\begin{description}
+\item[{\tt integer}]\hspace*{0pt}\\
+especifica que o parâmetro é inteiro;
+\item[{\tt binary}]\hspace*{0pt}\\
+especifica que o parâmetro é binário;
+\item[{\tt symbolic}]\hspace*{0pt}\\
+especifica que o parâmetro é simbólico;
+\item[{\it expressão de relação}]\hspace*{0pt}\\
+(onde {\it relação} é algum de: {\tt<}, {\tt<=}, {\tt=}, {\tt==},
+{\tt>=}, {\tt>}, {\tt<>}, {\tt!=})\\
+especifica uma condição que restringe o parâmetro ou seus membros a
+satisfazer aquela condição;
+\item[{\tt in} {\it expressão}]\hspace*{0pt}\\
+especifica um superconjunto que restringe o parâmetro ou seus membros
+a estarem inseridos naquele superconjunto;
+\item[{\tt:=} {\it expressão}]\hspace*{0pt}\\
+especifica um valor atribuído ao parâmetro ou a seus membros;
+\item[{\tt default} {\it expressão}]\hspace*{0pt}\\
+especifica um valor atribuído ao parâmetro ou aos seus membros sempre
+que não houverem dados disponíveis na seção de dados.
+\end{description}
+
+% \begin{description}
+% \item[{\tt integer}]\hspace*{0pt}\\
+% specifies that the parameter is integer;
+% \item[{\tt binary}]\hspace*{0pt}\\
+% specifies that the parameter is binary;
+% \item[{\tt symbolic}]\hspace*{0pt}\\
+% specifies that the parameter is symbolic;
+% \item[{\it relation expression}]\hspace*{0pt}\\
+% (where {\it relation} is one of: {\tt<}, {\tt<=}, {\tt=}, {\tt==},
+% {\tt>=}, {\tt>}, {\tt<>}, {\tt!=})\\
+% specifies a condition that restricts the parameter or its members to
+% satisfy that condition;
+% \item[{\tt in} {\it expression}]\hspace*{0pt}\\
+% specifies a superset that restricts the parameter or its members to be
+% in that superset;
+% \item[{\tt:=} {\it expression}]\hspace*{0pt}\\
+% specifies a value assigned to the parameter or its members;
+% \item[{\tt default} {\it expression}]\hspace*{0pt}\\
+% specifies a value assigned to the parameter or its members whenever
+% no appropriate data are available in the data section.
+% \end{description}
+
+\vspace*{-8pt}
+
+\para{Exemplos}
+
+% \para{Examples}
+
+\begin{verbatim}
+param unidades{insumo, produto} >= 0;
+param lucro{produto, 1..T+1};
+param N := 20 integer >= 0 <= 100;
+param combinacao 'n escolhe k' {n in 0..N, k in 0..n} :=
+ if k = 0 or k = n then 1 else combinacao[n-1,k-1] + combinacao[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 mes symbolic default 'Mai' in {'Mar', 'Abr', 'Mai'};
+\end{verbatim}
+
+% \begin{verbatim}
+% 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{verbatim}
+
+A sentença parameter declara um parâmetro. Se o domínio de subíndice não
+é especificado, o parâmetro é simples (escalar), caso contrário,
+é uma matriz $n$-dimensional.
+
+Os atributos de tipo {\tt integer}, {\tt binary} e {\tt symbolic}
+qualificam os tipos de valores que podem ser atribuídos ao parâmetro, conforme
+demonstrado:
+
+% The parameter statement declares a parameter. If a subscript domain is
+% not specified, the parameter is a simple (scalar) parameter, otherwise
+% it is a $n$-dimensional array.
+%
+% The type attributes {\tt integer}, {\tt binary}, and {\tt symbolic}
+% qualify the type of values that can be assigned to the parameter as
+% shown below:
+
+\noindent\hfil
+\begin{tabular}{@{}ll@{}}
+Tipo de atributo&Valores atribuídos\\
+\hline
+(não especificado)&Qualquer valor numérico\\
+{\tt integer}&Apenas valores numéricos inteiros\\
+{\tt binary}&Tanto 0 quanto 1\\
+{\tt symbolic}&Qualquer valor numérico e simbólico\\
+\end{tabular}
+
+% \noindent\hfil
+% \begin{tabular}{@{}ll@{}}
+% Type attribute&Assigned values\\
+% \hline
+% (not specified)&Any numeric values\\
+% {\tt integer}&Only integer numeric values\\
+% {\tt binary}&Either 0 or 1\\
+% {\tt symbolic}&Any numeric and symbolic values\\
+% \end{tabular}
+
+O atributo {\tt symbolic} não pode ser especificado juntamente com outros tipos
+de atributos. Uma vez especificado, ele deve preceder todos os outros atributos.
+
+O atributo de condição especifica uma condição opcional que restringe
+os valores atribuídos ao parâmetro para satisfazer aquela condição.
+Este atributo tem as seguintes formas sintáticas:
+
+% The {\tt symbolic} attribute cannot be specified along with other type
+% attributes. Being specified it should precede all other attributes.
+%
+% The condition attribute specifies an optional condition that restricts
+% values assigned to the parameter to satisfy that condition. This
+% attribute has the following syntactic forms:
+
+\begin{tabular}{@{}ll@{}}
+{\tt<} $v$&verifica se $x<v$\\
+{\tt<=} $v$&verifica se $x\leq v$\\
+{\tt=} $v$, {\tt==} $v$&verifica se $x=v$\\
+{\tt>=} $v$&verifica se $x\geq v$\\
+{\tt>} $v$&verifica se $x\geq v$\\
+{\tt<>} $v$, {\tt!=} $v$&verifica se $x\neq v$\\
+\end{tabular}
+
+% \begin{tabular}{@{}ll@{}}
+% {\tt<} $v$&check for $x<v$\\
+% {\tt<=} $v$&check for $x\leq v$\\
+% {\tt=} $v$, {\tt==} $v$&check for $x=v$\\
+% {\tt>=} $v$&check for $x\geq v$\\
+% {\tt>} $v$&check for $x\geq v$\\
+% {\tt<>} $v$, {\tt!=} $v$&check for $x\neq v$\\
+% \end{tabular}
+
+\noindent onde $x$ é um valor atribuído ao parâmetro, $v$ é o
+valor resultante de uma expressão numérica ou simbólica especificado
+no atributo de condição. Um número arbitrário de atributos de condição
+pode ser especificado para o mesmo parâmetro. Se, durante a avaliação do
+modelo, um valor atribuído ao parâmetro viola pelo menos uma das
+condições especificadas, ocorrerá um erro. (Note que valores simbólicos
+são ordenados de forma lexicográfica e qualquer valor numérico precede
+qualquer valor simbólico.)
+
+O atributo {\tt in} é similar ao atributo de condição e especifica
+uma expressão de conjunto cujo valor resultante é um superconjunto usado
+para restringir valores numéricos ou simbólicos atribuídos ao parâmetro
+a estarem incluídos naquele superconjunto. Pode-se especificar um número
+arbitrário de atributos {\tt in} para o mesmo parâmetro. Se, durante a avaliação do
+modelo, o valor atribuído ao parâmetro não pertence a pelo menos um dos
+superconjuntos especificados, ocorrerá um erro.
+
+O atributo de atribuição ({\tt:=}) especifica uma expressão numérica
+ou simbólica usada para \linebreak computar um valor atribuído ao parâmetro
+(se é um parâmetro simples) ou seus membros (se o parâmetro é uma matriz).
+Se o atributo de atribuição é especificado,
+o parâmetro é {\it calculável}, \linebreak portanto, não há a necessidade de fornecer
+dados na seção de dados. Se o atributo de atribuição não é especificado,
+deve-se fornecer os dados para o parâmetro na seção de dados. Pode-se especificar no
+máximo um atributo de atribuição ou {\tt default} para o mesmo parâmetro.
+
+O atributo {\tt default} especifica uma expressão numérica ou simbólica
+usada para computar um valor atribuído ao parâmetro ou seus membros
+sempre que não houver dados apropriados disponíveis na seção de dados.
+Se não se especifica nem o atributo de atribuição nem o atributo
+{\tt default}, a falta de dados causará um erro.
+
+% \noindent where $x$ is a value assigned to the parameter, $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 of specified
+% conditions, an error is raised. (Note that symbolic values are ordered
+% lexicographically, and any numeric value precedes any symbolic value.)
+%
+% The {\tt 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
+% that superset. Arbitrary number of the {\tt 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 of specified
+% supersets, an error is raised.
+%
+% The assign ({\tt:=}) 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 {\it computable}
+% and therefore needs no data to be provided in the data section. If the
+% assign attribute is not specified, the parameter should be provided
+% with data in the data section. At most one assign or {\tt default}
+% attribute can be specified for the same parameter.
+%
+% The {\tt 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 {\tt default} attribute is specified, missing data
+% will cause an error.
+
+\newpage
+
+\section{Sentença variable}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt var} {\it nome} {\it alias} {\it domínio} {\tt,}
+{\it atrib} {\tt,} \dots {\tt,} {\it atrib} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it nome} é um nome simbólico da variável;
+
+\noindent
+{\it alias} é um literal de cadeia opcional que especifica um pseudônimo
+para a variável;
+
+\noindent
+{\it domínio} é uma expressão indexante opcional que especifica o domínio
+do subíndice da variável;
+
+\noindent
+{\it atrib}, \dots, {\it atrib} são atributos opcionais da variável
+(as vírgulas que precedem os atributos podem ser omitidas.)
+
+\para{Atributos opcionais}
+
+\vspace*{-8pt}
+
+\begin{description}
+\item[{\tt integer}]\hspace*{0pt}\\
+restringe a variável a ser inteira;
+\item[{\tt binary}]\hspace*{0pt}\\
+restringe a variável a ser binária;
+\item[{\tt>=} {\it expressão}]\hspace*{0pt}\\
+especifica um limite inferior para a variável;
+\item[{\tt<=} {\it expressão}]\hspace*{0pt}\\
+especifica um limite superior para a variável;
+\item[{\tt=} {\it expressão}]\hspace*{0pt}\\
+especifica um valor fixo para a variável;
+\end{description}
+
+
+% \noindent
+% \framebox[468pt][l]{
+% \parbox[c][24pt]{468pt}{
+% \hspace{6pt} {\tt var} {\it name} {\it alias} {\it domain} {\tt,}
+% {\it attrib} {\tt,} \dots {\tt,} {\it attrib} {\tt;}
+% }}
+%
+% \medskip
+%
+% \noindent
+% {\it name} is a symbolic name of the variable;
+%
+% \noindent
+% {\it alias} is an optional string literal, which specifies an alias of
+% the variable;
+%
+% \noindent
+% {\it domain} is an optional indexing expression, which specifies
+% a subscript domain of the variable;
+%
+% \noindent
+% {\it attrib}, \dots, {\it attrib} are optional attributes of the
+% variable. (Commae preceding attributes may be omitted.)
+%
+% \para{Optional attributes}
+%
+% \vspace*{-8pt}
+%
+% \begin{description}
+% \item[{\tt integer}]\hspace*{0pt}\\
+% restricts the variable to be integer;
+% \item[{\tt binary}]\hspace*{0pt}\\
+% restricts the variable to be binary;
+% \item[{\tt>=} {\it expression}]\hspace*{0pt}\\
+% specifies an lower bound of the variable;
+% \item[{\tt<=} {\it expression}]\hspace*{0pt}\\
+% specifies an upper bound of the variable;
+% \item[{\tt=} {\it expression}]\hspace*{0pt}\\
+% specifies a fixed value of the variable;
+% \end{description}
+
+\vspace*{-8pt}
+
+\para{Exemplos}
+
+% \para{Examples}
+
+\begin{verbatim}
+var x >= 0;
+var y{I,J};
+var produzir{p in prod}, integer, >= comprometido[p], <= mercado[p];
+var armazenar{insumo, 1..T+1} >= 0;
+var z{i in I, j in J} >= i+j;
+\end{verbatim}
+
+% \begin{verbatim}
+% 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{verbatim}
+
+A sentença variable declara uma variável. Se não se especifica o
+domínio do subíndice, a variável e uma variável simples (escalar),
+caso contrário é uma matriz $n$-dimensional de variáveis elementares.
+
+As variáveis elementares associadas com a variável do modelo
+(se é uma variável simples) ou seus membros (se é uma matriz) corresponde
+às variáveis na formulação do problema PL/PIM (ver Seção \ref{problem},
+página \pageref{problem}). Note que somente variáveis elementares
+realmente referenciadas em algumas restrições e/ou objetivos serão
+incluídas na instância do problema PL/PIM a ser gerado.
+
+Os atributos de tipo {\tt integer} e {\tt binary} restringem a variável
+a ser inteira ou binária, \linebreak respectivamente. Se nenhum atributo de tipo
+é especificado, a variável é contínua. Se todas as variáveis no modelo
+são contínuas, o problema correspondente é da classe PL. Se há pelo
+menos uma variável inteira ou binária, o problema é da classe PIM.
+
+\newpage
+
+O atributo de limite inferior ({\tt>=}) especifica uma expressão numérica
+para calcular um limite inferior da variável. No máximo um limite inferior
+pode ser especificado. Por padrão, todas as variáveis (exceto as binárias)
+não tem limite inferior, assim, se há a necessidade de uma variável ser
+não-negativa, seu limite inferior zero deve ser explicitamente especificado.
+
+O atributo de limite superior ({\tt<=}) especifica uma expressão numérica
+para calcular um limite superior da variável. No máximo um limite superior
+pode ser especificado.
+
+O atributo de valor fixo ({\tt=}) especifica uma expressão numérica para
+calcular um valor no qual a variável é fixada. Este atributo não pode
+ser especificado junto com os atributos de limite.
+
+
+% The variable statement declares a variable. If a subscript domain is
+% not specified, the variable is a simple (scalar) variable, otherwise it
+% is a $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 \ref{problem},
+% page \pageref{problem}). Note that only elemental variables actually
+% referenced in some constraints and/or objectives are included in the
+% LP/MIP problem instance to be generated.
+%
+% The type attributes {\tt integer} and {\tt 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 ({\tt>=}) attribute specifies a numeric expression for
+% computing an lower bound of the variable. At most one lower bound can
+% be specified. By default all variables (except binary ones) have no
+% lower bound, so if a variable is required to be non-negative, its zero
+% lower bound should be explicitly specified.
+%
+% The upper bound ({\tt<=}) attribute specifies a numeric expression for
+% computing an upper bound of the variable. At most one upper bound
+% attribute can be specified.
+%
+% The fixed value ({\tt=}) attribute specifies a numeric expression for
+% computing a value, at which the variable is fixed. This attribute
+% cannot be specified along with the bound attributes.
+
+
+\section{Sentença constraint}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][106pt]{468pt}{
+\hspace{6pt} {\tt s.t.} {\it nome} {\it alias} {\it domínio} {\tt:}
+{\it expressão} {\tt,} {\tt=} {\it expressão} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt s.t.} {\it nome} {\it alias} {\it domínio} {\tt:}
+{\it expressão} {\tt,} {\tt<=} {\it expressão} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt s.t.} {\it nome} {\it alias} {\it domínio} {\tt:}
+{\it expressão} {\tt,} {\tt>=} {\it expressão} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt s.t.} {\it nome} {\it alias} {\it domínio} {\tt:}
+{\it expressão} {\tt,} {\tt<=} {\it expressão} {\tt,} {\tt<=}
+{\it expressão} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt s.t.} {\it nome} {\it alias} {\it domínio} {\tt:}
+{\it expressão} {\tt,} {\tt>=} {\it expressão} {\tt,} {\tt>=}
+{\it expressão} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it nome} é um nome simbólico da restrição;
+
+\noindent
+{\it alias} é um literal de cadeia opcional que especifica um pseudônimo
+da restrição;
+
+\noindent
+{\it domínio} é uma expressão indexante opcional, que especifica
+o domínio do subíndice da restrição;
+
+\noindent
+{\it expressão} é uma expressão linear usada para calcular um componente
+da restrição (as vírgulas que precedem os atributos podem ser omitidas).
+
+\noindent
+(A palavra-chave {\tt s.t.} pode ser escrita como {\tt subject to}, como
+{\tt subj to} ou pode ser omitido por completo).
+
+
+% \noindent
+% \framebox[468pt][l]{
+% \parbox[c][106pt]{468pt}{
+% \hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:}
+% {\it expression} {\tt,} {\tt=} {\it expression} {\tt;}
+%
+% \medskip
+%
+% \hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:}
+% {\it expression} {\tt,} {\tt<=} {\it expression} {\tt;}
+%
+% \medskip
+%
+% \hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:}
+% {\it expression} {\tt,} {\tt>=} {\it expression} {\tt;}
+%
+% \medskip
+%
+% \hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:}
+% {\it expression} {\tt,} {\tt<=} {\it expression} {\tt,} {\tt<=}
+% {\it expression} {\tt;}
+%
+% \medskip
+%
+% \hspace{6pt} {\tt s.t.} {\it name} {\it alias} {\it domain} {\tt:}
+% {\it expression} {\tt,} {\tt>=} {\it expression} {\tt,} {\tt>=}
+% {\it expression} {\tt;}
+% }}
+%
+% \medskip
+%
+% \noindent
+% {\it name} is a symbolic name of the constraint;
+%
+% \noindent
+% {\it alias} is an optional string literal, which specifies an alias of
+% the constraint;
+%
+% \noindent
+% {\it domain} is an optional indexing expression, which specifies
+% a subscript domain of the constraint;
+%
+% \noindent
+% {\it expression} is a linear expression used to compute a component of
+% the constraint. (Commae following expressions may be omitted.)
+%
+% \noindent
+% (The keyword {\tt s.t.} may be written as {\tt subject to} or as
+% {\tt subj to}, or may be omitted at all.)
+
+
+\para{Exemplos}
+
+% \para{Examples}
+
+\begin{verbatim}
+s.t. r: x + y + z, >= 0, <= 1;
+limite{t in 1..T}: sum{j in produto} produzir[j,t] <= max_prod;
+subject to balanco{i in insumo, t in 1..T}:
+ estoque[i,t+1] = estoque[i,t] - sum{j in produto} unidades[i,j] * produzir[j,t];
+subject to rlim 'limite tempo-regular' {t in tempo}:
+ sum{p in produto} pt[p] * rprod[p,t] <= 1.3 * dpp[t] * equipes[t];
+\end{verbatim}
+
+% \begin{verbatim}
+% 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{verbatim}
+
+A sentença de restrição declara uma restrição. Se o domínio do subíndice
+não é especificado, a restrição é uma restrição simples (escalar),
+caso contrário, é uma matriz $n$-dimensional de restrições elementares.
+
+Restrições elementares associadas com a restrição do modelo (se é
+uma restrição simples) ou seus membros (se é uma matriz) correspondem
+a restrições lineares na formulação do problema de PL/PIM (ver
+Seção \ref{problem}, página \pageref{problem}).
+
+Se a restrição possui a forma de igualdade ou desigualdade simples, i.e.,
+inclui duas expressões, uma segue depois dos dois pontos e a outra
+segue depois do sinal de relação {\tt=}, {\tt<=} ou {\tt>=}, \linebreak ambas
+expressões na sentença podem ser expressões lineares. Se a restrição
+possui a forma de uma \linebreak desigualdade dupla, i.e., inclui três expressões,
+a expressão do meio pode ser uma expressão linear, enquanto a da
+esquerda e a da direita podem ser apenas expressões numéricas.
+
+Gerar o modelo é, a grosso modo, gerar suas restrições, que são sempre
+avaliadas para todo domínio do subíndice. Avaliar as restrições,
+por sua vez, leva a avaliação de outros objetos de modelo tais como
+conjuntos, parâmetros e variáveis.
+
+A construção de uma restrição linear incluída na instância do problema,
+que corresponde a uma restrição elementar particular, é realizada
+como segue.
+
+
+% The constraint statement declares a constraint. If a subscript domain
+% is not specified, the\linebreak constraint is a simple (scalar)
+% constraint, otherwise it is a $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 \ref{problem}, page \pageref{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 {\tt=}, {\tt<=}, or {\tt>=}, both expressions
+% in the statement can be linear expressions. If the constraint has the
+% form of double inequality,\linebreak 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, roughly speaking, generating its constraints,
+% which are always evaluated for the entire subscript domain. Evaluation
+% of the constraints leads, in turn, to evaluation of other model objects
+% such as sets, parameters, and variables.
+%
+% Constructing an actual linear constraint included in the problem
+% instance, which (constraint) corresponds to a particular elemental
+% constraint, is performed as follows.
+
+
+Se a restrição possui a forma de igualdade ou desigualdade simples,
+a avaliação de ambas \linebreak expressões lineares resultam em duas formas lineares:
+$$\begin{array}{r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r}
+f&=&a_1x_1&+&a_2x_2&+\dots+&a_nx_n&+&a_0,\\
+g&=&b_1x_1&+&b_2x_2&+\dots+&b_nx_n&+&b_0,\\
+\end{array}$$
+onde $x_1$, $x_2$, \dots, $x_n$ são variáveis elementares; $a_1$, $a_2$,
+\dots, $a_n$, $b_1$, $b_2$, \dots, $b_n$ são coeficientes numéricos;
+$a_0$ e $b_0$ são termos constantes. Em seguida, todos os termos lineares
+de $f$ e $g$ são levados ao lado esquerdo, enquanto que os termos constantes
+são levados ao lado direito, resultando na restrição elementar
+final na forma padrão:
+$$(a_1-b_1)x_1+(a_2-b_2)x_2+\dots+(a_n-b_n)x_n\left\{
+\begin{array}{@{}c@{}}=\\\leq\\\geq\\\end{array}\right\}b_0-a_0.$$
+
+Se a restrição possui a forma de desigualdade dupla, a avaliação da
+expressão linear do meio resulta na seguinte forma linear:
+$$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$
+e a avaliação das expressões numéricas da esquerda e da direita dão
+dois valores numéricos $l$ e $u$, respectivamente. Logo,
+o termo constante da forma linear é levado tanto à esquerda como
+à direita para gerar a restrição elementar final na forma padrão:
+$$l-a_0\leq a_1x_1+a_2x_2+\dots+a_nx_n\leq u-a_0.$$
+
+
+% If the constraint has the form of equality or single inequality,
+% evaluation of both linear expressions gives two resultant linear forms:
+% $$\begin{array}{r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r}
+% f&=&a_1x_1&+&a_2x_2&+\dots+&a_nx_n&+&a_0,\\
+% g&=&b_1x_1&+&a_2x_2&+\dots+&a_nx_n&+&b_0,\\
+% \end{array}$$
+% where $x_1$, $x_2$, \dots, $x_n$ are elemental variables; $a_1$, $a_2$,
+% \dots, $a_n$, $b_1$, $b_2$, \dots, $b_n$ are numeric coefficients;
+% $a_0$ and $b_0$ are constant terms. Then all linear terms of $f$ and
+% $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:
+% $$(a_1-b_1)x_1+(a_2-b_2)x_2+\dots+(a_n-b_n)x_n\left\{
+% \begin{array}{@{}c@{}}=\\\leq\\\geq\\\end{array}\right\}b_0-a_0.$$
+%
+% If the constraint has the form of double inequality, evaluation of the
+% middle linear expression gives the resultant linear form:
+% $$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$
+% and evaluation of the leftmost and rightmost numeric expressions gives
+% two numeric values $l$ and $u$, respectively. Then the constant term of
+% the linear form is carried to both left-hand and right-handsides that
+% gives the final elemental constraint in the standard form:
+% $$l-a_0\leq a_1x_1+a_2x_2+\dots+a_nx_n\leq u-a_0.$$
+
+
+\section{Sentença objective}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][44pt]{468pt}{
+\hspace{6pt} {\tt minimize} {\it nome} {\it alias} {\it domínio} {\tt:}
+{\it expressão} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt maximize} {\it nome} {\it alias} {\it domínio} {\tt:}
+{\it expressão} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it nome} é um nome simbólico do objetivo;
+
+\noindent
+{\it alias} é uma literal de cadeia opcional que especifica um
+pseudônimo do objetivo;
+
+\noindent
+{\it domínio} é uma expressão indexante opcional que especifica
+um domínio do subíndice do objetivo;
+
+\noindent
+{\it expressão} é uma expressão linear usada pra calcular a forma
+linear do objetivo.
+
+
+% \noindent
+% \framebox[468pt][l]{
+% \parbox[c][44pt]{468pt}{
+% \hspace{6pt} {\tt minimize} {\it name} {\it alias} {\it domain} {\tt:}
+% {\it expression} {\tt;}
+%
+% \medskip
+%
+% \hspace{6pt} {\tt maximize} {\it name} {\it alias} {\it domain} {\tt:}
+% {\it expression} {\tt;}
+% }}
+%
+% \medskip
+%
+% \noindent
+% {\it name} is a symbolic name of the objective;
+%
+% \noindent
+% {\it alias} is an optional string literal, which specifies an alias of
+% the objective;
+%
+% \noindent
+% {\it domain} is an optional indexing expression, which specifies
+% a subscript domain of the objective;
+%
+% \noindent
+% {\it expression} is a linear expression used to compute the linear form
+% of the objective.
+
+\newpage
+
+\para{Exemplos}
+
+% \para{Examples}
+
+\begin{verbatim}
+minimize obj: x + 1.5 * (y + z);
+maximize lucro_total: sum{p in produto} lucro[p] * produzir[p];
+\end{verbatim}
+
+% \begin{verbatim}
+% minimize obj: x + 1.5 * (y + z);
+% maximize total_profit: sum{p in prd} profit[p] * make[p];
+% \end{verbatim}
+
+A sentença objective declara um objetivo. Se o domínio do subíndice
+não é especificado, o objetivo é um objetivo simples (escalar). Caso contrário,
+é uma matriz $n$-dimensional de objetivos elementares.
+
+Objetivos elementares associados com o objetivo do modelo (se é um
+objetivo simples) ou seus membros (se é uma matriz) correspondem
+a restrições lineares genéricas na formulação do problema PL/PIM
+(ver Seção \ref{problem}, página \pageref{problem}). No entanto,
+diferentemente das restrições, estas formas lineares são livres
+(ilimitadas).
+
+A construção de uma forma linear incluída na instância do problema,
+a qual corresponde a uma restrição elementar particular,
+é realizada como segue. A expressão linear especificada da na
+sentença objective é avaliada para resultar na seguinte forma linear:
+$$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$
+onde $x_1$, $x_2$, \dots, $x_n$ são variáveis elementares; $a_1$, $a_2$,
+\dots, $a_n$ são coeficientes numéricos; $a_0$ é o termo constante. Logo,
+a forma linear é usada para construir a restrição final elementar na
+forma padrão:
+$$-\infty<a_1x_1+a_2x_2+\dots+a_nx_n+a_0<+\infty.$$
+
+Como via de regra, a descrição do modelo contém apenas uma sentença objective
+que define a função objetivo usada na instância do problema.
+No entanto, é permitido declarar uma quantidade arbitrária de objetivos.
+Neste caso, a função objetivo real será o primeiro objetivo
+encontrado na descrição do modelo. Outros objetivos também estão
+incluídos na instância do problema, mas eles não afetam a função
+objetivo.
+
+
+
+% The objective statement declares an objective. If a subscript domain is
+% not specified, the objective is a simple (scalar) objective. Otherwise
+% it is a $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 \ref{problem}, page \pageref{problem}). However, unlike
+% constraints the corresponding linear forms are free (unbounded).
+%
+% Constructing an actual linear constraint included in the problem
+% instance, which (constraint) corresponds to a particular elemental
+% constraint, is performed as follows. The linear expression specified in
+% the objective statement is evaluated that, gives the resultant linear
+% form:
+% $$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$
+% where $x_1$, $x_2$, \dots, $x_n$ are elemental variables; $a_1$, $a_2$,
+% \dots, $a_n$ are numeric coefficients; $a_0$ is the constant term. Then
+% the linear form is used to construct the final elemental constraint in
+% the standard form:
+% $$-\infty<a_1x_1+a_2x_2+\dots+a_nx_n+a_0<+\infty.$$
+%
+% As a rule the model description contains only one objective statement
+% that defines the objective function used in the problem instance.
+% However, it is allowed to declare arbitrary number of objectives, in
+% which case the actual objective function is the first objective
+% encountered in the model description. Other objectives are also
+% included in the problem instance, but they do not affect the objective
+% function.
+
+\section{Sentença solve}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt solve} {\tt;}
+}}
+
+\medskip
+
+A sentença solve é opcional e pode ser usada apenas uma vez.
+Se a sentença solve não é usada, ela é assumida ao final da seção de modelo.
+
+A sentença solve provoca que o modelo seja resolvido, o que significa calcular
+os valores numéricos de todas as variáveis do modelo. Isto permite usar
+variáveis em sentenças abaixo da sentença solve como se fossem parâmetros
+numéricos.
+
+Note que a sentença variable, constraint e objective não podem ser usadas
+abaixo da sentença solve, i.e., todos os principais componentes do modelo
+devem ser declarados acima da sentença solve.
+
+
+% 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.
+%
+% The solve statement causes the model to be solved, that means 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 the variable, constraint, and objective statements cannot be
+% used below the solve statement, i.e. all principal components of the
+% model should be declared above the solve statement.
+
+\newpage
+
+\section{Sentença check}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt check} {\it domínio} {\tt:} {\it expressão} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it domínio} é uma expressão indexante opcional que especifica o
+domínio do subíndice da sentença check;
+
+\noindent
+{\it expressão} é uma expressão lógica que especifica a condição
+lógica a ser verificada (os dois pontos que precedem a {\it expressão}
+podem ser omitidos).
+
+\para{Exemplos}
+
+\begin{verbatim}
+check: x + y <= 1 and x >= 0 and y >= 0;
+check sum{i in ORIG} suprimento[i] = sum{j in DEST} demanda[j];
+check{i in I, j in 1..10}: S[i,j] in U[i] union V[j];
+\end{verbatim}
+
+A sentença check permite a verificação do valor resultante
+de uma expressão lógica especificada na sentença. Se o valor
+é {\it falso}, um erro é reportado.
+
+Se o domínio do subíndice não é especificado, a verificação é realizada
+apenas uma vez. \linebreak Especificar o domínio do subíndice
+permite a execução de verificações múltiplas para cada $n$-tupla
+no conjunto domínio. Neste último caso, a expressão lógica pode
+incluir índices introduzidos na expressão indexante correspondente.
+
+
+% \noindent
+% \framebox[468pt][l]{
+% \parbox[c][24pt]{468pt}{
+% \hspace{6pt} {\tt check} {\it domain} {\tt:} {\it expression} {\tt;}
+% }}
+%
+% \medskip
+%
+% \noindent
+% {\it domain} is an optional indexing expression, which specifies
+% a subscript domain of the check statement;
+%
+% \noindent
+% {\it expression} is an logical expression which specifies the logical
+% condition to be checked. (The colon preceding {\it expression} may be
+% omitted.)
+%
+% \para{Examples}
+%
+% \begin{verbatim}
+% 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{verbatim}
+%
+% The check statement allows checking the resultant value of an logical
+% expression specified in the statement. If the value is {\it false}, an
+% error is reported.
+%
+% If the subscript domain is not specified, the check is performed only
+% once. Specifying the subscript domain allows performing multiple check
+% for every $n$-tuple in the domain set. In the latter case the logical
+% expression may include dummy indices introduced in corresponding
+% indexing expression.
+
+\section{Sentença display}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][24pt]{468pt}{
+\hspace{6pt} {\tt display} {\it domínio} {\tt:} {\it item} {\tt,}
+\dots {\tt,} {\it item} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it domínio} é uma expressão indexante opcional que especifica
+um domínio do subíndice da sentença display;
+
+\noindent
+{\it item}, \dots, {\it item} são itens a serem mostrados (os dois pontos
+que precedem o primeiro item podem ser omitidos).
+
+\para{Exemplos}
+
+\begin{verbatim}
+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{verbatim}
+
+A sentença display avalia todos itens especificados na sentença
+e escreve seus valores em saída padrão (terminal) em formato de
+texto plano.
+
+Se um domínio de subíndice não é especificado, os itens são avaliados e
+mostrados apenas uma vez. Ao especificar o domínio do subíndice, itens
+são avaliados e mostrados para cada $n$-tupla no conjunto do domínio. No
+último caso, os itens podem incluir índices introduzidos na expressão
+indexante correspondente.
+
+Um item a ser mostrado pode ser um objeto de modelo (conjunto, parâmetro,
+variável, restrição, objetivo) ou uma expressão.
+
+Se um item é um objeto calculável (i.e., um conjunto ou parâmetro com
+o atributo de atribuição), o objeto é avaliado por todo domínio
+e em seguida, seu conteúdo (i.e., o conteúdo da matriz de objetos) é
+mostrado. Caso contrário, se o item não é um objeto calculável, somente seu
+seu conteúdo corrente (i.e., os membros realmente gerados durante a
+avaliação do modelo) é mostrado.
+
+Se o item é uma expressão, a expressão é avaliada e seu valor
+resultante é mostrado.
+
+
+% \noindent
+% \framebox[468pt][l]{
+% \parbox[c][24pt]{468pt}{
+% \hspace{6pt} {\tt display} {\it domain} {\tt:} {\it item} {\tt,}
+% \dots {\tt,} {\it item} {\tt;}
+% }}
+%
+% \medskip
+%
+% \noindent
+% {\it domain} is an optional indexing expression, which specifies
+% a subscript domain of the display statement;
+%
+% \noindent
+% {\it item}, \dots, {\it item} are items to be displayed. (The colon
+% preceding the first item may be omitted.)
+%
+% \para{Examples}
+%
+% \begin{verbatim}
+% 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{verbatim}
+%
+% The display statement evaluates all items specified in the statement
+% and writes their values on the standard output (terminal) in plain text
+% format.
+%
+% If a subscript domain is not specified, items are evaluated and then
+% displayed only once. Specifying the subscript domain causes items to be
+% evaluated and displayed for every $n$-tuple in the domain set. In the
+% latter case items may include dummy indices introduced in corresponding
+% indexing expression.
+%
+% An 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. members actually generated during the model
+% evaluation) is displayed.
+%
+% If the item is an expression, the expression is evaluated and its
+% resultant value is displayed.
+
+\section{Sentença printf}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][64pt]{468pt}{
+\hspace{6pt} {\tt printf} {\it domínio} {\tt:} {\it formato} {\tt,}
+{\it expressão} {\tt,} \dots {\tt,} {\it expressão} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt printf} {\it domínio} {\tt:} {\it formato} {\tt,}
+{\it expressão} {\tt,} \dots {\tt,} {\it expressão} {\tt>}
+{\it nome-do-arquivo} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt printf} {\it domínio} {\tt:} {\it formato} {\tt,}
+{\it expressão} {\tt,} \dots {\tt,} {\it expressão} {\tt>>}
+{\it nome-do-arquivo} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it domínio} é uma expressão indexante opcional que especifica o domínio
+do subíndice da sentença printf;
+
+\noindent
+{\it formato} é uma expressão simbólica cujo valor especifica uma cadeia de
+controle de formato (os dois pontos que precedem a expressão de formato
+podem ser omitidos).
+
+\noindent
+{\it expressão}, \dots, {\it expressão} são zero ou mais expressões
+cujos valores devem ser formatados e impressos. Cada expressão deve
+ser de tipo numérico, simbólico ou lógico.
+
+\noindent
+{\it nome-do-arquivo} é uma expressão simbólica cujo valor especifica um nome
+de um arquivo de texto para onde a saída é redirecionada. O sinal {\tt>}
+significa criar um novo aquivo vazio, enquanto o sinal {\tt>>} significa
+acrescentar a saída a um arquivo existente. Se o nome do arquivo não é especificado,
+a saída é escrita na saída padrão (terminal).
+
+\para{Exemplos}
+
+\begin{verbatim}
+printf 'Ola, mundo!\n';
+printf: "x = %.3f; y = %.3f; z = %.3f\n", x, y, z > "resultado.txt";
+printf{i in I, j in J}: "fluxo de %s para %s eh %d\n", i, j, x[i,j]
+ >> arquivo_resultado & ".txt";
+printf{i in I} 'fluxo total de %s eh %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{verbatim}
+
+A sentença printf é similar a sentença display, no entanto, ela
+permite formatar os dados a serem escritos.
+
+Se um domínio do subíndice não é especificado, a sentença printf
+é executada apenas uma vez. Especificar um domínio do subíndice gera
+a execução da sentença printf para cada $n$-tupla no conjunto do domínio.
+No último caso, o formato e a expressão podem incluir índices introduzidos
+nas expressões indexantes correspondentes.
+
+A cadeia de controle de formato é valor da expressão simbólica
+{\it formato} especificada na sentença printf. Ela é composta de zero
+ou mais diretivas, como segue: tanto caracteres ordinários (exceto {\tt\%}), que
+são copiados sem modificação ao fluxo de saída, quanto especificações de conversão,
+provocam a avaliação da expressão correspondente especificada na sentença
+printf, do seu formato e da escrita do valor resultante no fluxo de saída.
+
+As especificações de conversão que podem ser usadas na cadeia de controle
+de formato são as seguintes: {\tt d}, {\tt i}, {\tt f}, {\tt F},
+{\tt e}, {\tt E}, {\tt g}, {\tt G} e {\tt s}. Estas especificações
+possuem a mesma sintaxe e semântica que na linguagem de programação C.
+
+
+% \noindent
+% \framebox[468pt][l]{
+% \parbox[c][64pt]{468pt}{
+% \hspace{6pt} {\tt printf} {\it domain} {\tt:} {\it format} {\tt,}
+% {\it expression} {\tt,} \dots {\tt,} {\it expression} {\tt;}
+%
+% \medskip
+%
+% \hspace{6pt} {\tt printf} {\it domain} {\tt:} {\it format} {\tt,}
+% {\it expression} {\tt,} \dots {\tt,} {\it expression} {\tt>}
+% {\it filename} {\tt;}
+%
+% \medskip
+%
+% \hspace{6pt} {\tt printf} {\it domain} {\tt:} {\it format} {\tt,}
+% {\it expression} {\tt,} \dots {\tt,} {\it expression} {\tt>>}
+% {\it filename} {\tt;}
+% }}
+%
+% \medskip
+%
+% \noindent
+% {\it domain} is an optional indexing expression, which specifies
+% a subscript domain of the printf statement;
+%
+% \noindent
+% {\it format} is a symbolic expression whose value specifies a format
+% control string. (The colon preceding the format expression may be
+% omitted.)
+%
+% \noindent
+% {\it expression}, \dots, {\it expression} are zero or more expressions
+% whose values have to be formatted and printed. Each expression should
+% be of numeric, symbolic, or logical type.
+%
+% \noindent
+% {\it filename} is a symbolic expression whose value specifies a name
+% of a text file, to which the output is redirected. The flag {\tt>}
+% means creating a new empty file while the flag {\tt>>} means appending
+% the output to an existing file. If no file name is specified, the
+% output is written on the standard output (terminal).
+%
+% \para{Examples}
+%
+% \begin{verbatim}
+% 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]
+% >> result_file & ".txt";
+% 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{verbatim}
+%
+% The printf statement is similar to the display statement, however, it
+% allows formatting data to be written.
+%
+% If a subscript domain is not specified, the printf statement is
+% executed only once. Specifying a subscript domain causes executing the
+% printf statement for every $n$-tuple in the domain set. In the latter
+% case the format and expression may include dummy indices introduced in
+% corresponding indexing expression.
+%
+% The format control string is a value of the symbolic expression
+% {\it format} specified in the printf statement. It is composed of zero
+% or more directives as follows: ordinary characters (not {\tt\%}), which
+% are copied unchanged to the output stream, and conversion
+% specifications, each of which causes evaluating corresponding
+% expression specified in the printf statement, formatting it, and
+% writing its resultant value to the output stream.
+%
+% Conversion specifications that may be used in the format control string
+% are the following:\linebreak {\tt d}, {\tt i}, {\tt f}, {\tt F},
+% {\tt e}, {\tt E}, {\tt g}, {\tt G}, and {\tt s}. These specifications
+% have the same syntax and semantics as in the C programming language.
+
+\section{Sentença for}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][44pt]{468pt}{
+\hspace{6pt} {\tt for} {\it domínio} {\tt:} {\it sentença} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt for} {\it domínio} {\tt:} {\tt\{} {\it sentença}
+\dots {\it sentença} {\tt\}} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it domínio} é uma expressão indexante que especifica um
+domínio do subíndice da sentença for. (Os dois pontos que seguem a
+expressão indexante podem ser omitidos).
+
+\noindent
+{\it sentença} é uma sentença que deve ser executada sob o controle
+da sentença for;
+
+\noindent
+{\it sentença}, \dots, {\it sentença} é uma sequência de sentenças
+(cercada entre chaves) que deve ser executada sob o controle da
+sentença for.
+
+Apenas as sentenças seguintes podem ser usadas dentro da
+sentença for: check, display, printf e outro for.
+
+\para{Exemplos}
+
+\begin{verbatim}
+for {(i,j) in E: i != j}
+{ printf "fluxo de %s para %s eh %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{verbatim}
+
+A sentença for faz com que a sentença, ou uma sequência de sentenças
+especificadas como parte da sentença for, seja executada para cada
+$n$-tupla no conjunto do domínio. Assim, sentenças dentro da sentença for
+podem incluir índices introduzidos na expressão indexante correspondente.
+
+% \noindent
+% \framebox[468pt][l]{
+% \parbox[c][44pt]{468pt}{
+% \hspace{6pt} {\tt for} {\it domain} {\tt:} {\it statement} {\tt;}
+%
+% \medskip
+%
+% \hspace{6pt} {\tt for} {\it domain} {\tt:} {\tt\{} {\it statement}
+% \dots {\it statement} {\tt\}} {\tt;}
+% }}
+%
+% \medskip
+%
+% \noindent
+% {\it domain} is an indexing expression which specifies a subscript
+% domain of the for statement. (The colon following the indexing
+% expression may be omitted.)
+%
+% \noindent
+% {\it statement} is a statement, which should be executed under control
+% of the for statement;
+%
+% \noindent
+% {\it statement}, \dots, {\it statement} is a sequence of statements
+% (enclosed in curly braces), which should be executed under control of
+% the for statement.
+%
+% Only the following statements can be used within the for statement:
+% check, display, printf, and another for.
+%
+% \para{Examples}
+%
+% \begin{verbatim}
+% 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{verbatim}
+%
+% The for statement causes a statement or a sequence of statements
+% specified as part of the for statement to be executed for every
+% $n$-tuple in the domain set. Thus, statements within the for statement
+% may include dummy indices introduced in corresponding indexing
+% expression.
+
+\newpage
+
+\section{Sentença table}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][80pt]{468pt}{
+\hspace{6pt} {\tt table} {\it nome} {\it alias} {\tt IN} {\it controlador}
+{\it arg} \dots {\it arg} {\tt:}
+
+\hspace{6pt} {\tt\ \ \ \ \ } {\it conjunto} {\tt<-} {\tt[} {\it cmp} {\tt,}
+\dots {\tt,} {\it cmp} {\tt]} {\tt,} {\it par} {\tt\textasciitilde}
+{\it cmp} {\tt,} \dots {\tt,} {\it par} {\tt\textasciitilde} {\it cmp}
+{\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt table} {\it nome} {\it alias} {\it domínio} {\tt OUT}
+{\it controlador} {\it arg} \dots {\it arg} {\tt:}
+
+\hspace{6pt} {\tt\ \ \ \ \ } {\it expr} {\tt\textasciitilde} {\it cmp}
+{\tt,} \dots {\tt,} {\it expr} {\tt\textasciitilde} {\it cmp} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it nome} é um nome simbólico da tabela;
+
+\noindent
+{\it alias} é um literal de cadeia opcional que especifica um pseudônimo
+da tabela;
+
+\noindent
+{\it domínio} é uma expressão indexante que especifica o domínio do
+subíndice da tabela (de saída);
+
+\noindent
+{\tt IN} significa ler dados de uma tabela de entrada;
+
+\noindent
+{\tt OUT} significa escrever dados em uma tabela de saída;
+
+\noindent
+{\it controlador} é uma expressão simbólica que especifica o controlador
+usado para acessar a tabela (para mais detalhes, ver Apêndice \ref{drivers},
+página \pageref{drivers});
+
+\noindent
+{\it arg} é uma expressão simbólica opcional, que é um argumento
+passado ao controlador da tabela. Esta expressão simbólica não deveria
+incluir índices especificados no domínio;
+
+\noindent
+{\it conjunto} é o nome de um conjunto simples opcional chamado
+{\it conjunto de controle}. Pode ser omitido junto com o delimitador {\tt<-};
+
+\noindent
+{\it cmp} é um nome de campo. Entre colchetes, pelo menos um campo deve ser
+especificado. O nome do campo, que segue o nome do parâmetro ou de uma
+expressão, é opcional e pode ser omitido juntamente com o
+delimitador~{\tt\textasciitilde}. Neste caso o nome do objeto de modelo
+correspondente é usado como nome de campo;
+
+\noindent
+{\it par} é um nome simbólico de um parâmetro do modelo;
+
+\noindent
+{\it expr} é uma expressão numérica ou simbólica.
+
+\para{Exemplos}
+
+\begin{verbatim}
+table dados IN "CSV" "dados.csv": S <- [DE,PARA], d~DISTANCIA,
+ c~CUSTO;
+table resultado{(d,p) in S} OUT "CSV" "resultado.csv": d~DE, p~PARA,
+ x[d,p]~FLUXO;
+\end{verbatim}
+
+A sentença table permite a leitura de dados de uma tabela para objetos
+de modelo como conjuntos e parâmetros (não-escalares) assim como escrever
+dados do modelo para uma tabela.
+
+
+% \noindent
+% \framebox[468pt][l]{
+% \parbox[c][80pt]{468pt}{
+% \hspace{6pt} {\tt table} {\it name} {\it alias} {\tt IN} {\it driver}
+% {\it arg} \dots {\it arg} {\tt:}
+%
+% \hspace{6pt} {\tt\ \ \ \ \ } {\it set} {\tt<-} {\tt[} {\it fld} {\tt,}
+% \dots {\tt,} {\it fld} {\tt]} {\tt,} {\it par} {\tt\textasciitilde}
+% {\it fld} {\tt,} \dots {\tt,} {\it par} {\tt\textasciitilde} {\it fld}
+% {\tt;}
+%
+% \medskip
+%
+% \hspace{6pt} {\tt table} {\it name} {\it alias} {\it domain} {\tt OUT}
+% {\it driver} {\it arg} \dots {\it arg} {\tt:}
+%
+% \hspace{6pt} {\tt\ \ \ \ \ } {\it expr} {\tt\textasciitilde} {\it fld}
+% {\tt,} \dots {\tt,} {\it expr} {\tt\textasciitilde} {\it fld} {\tt;}
+% }}
+%
+% \medskip
+%
+% \noindent
+% {\it name} is a symbolic name of the table;
+%
+% \noindent
+% {\it alias} is an optional string literal, which specifies an alias of
+% the table;
+%
+% \noindent
+% {\it domain} is an indexing expression, which specifies a subscript
+% domain of the (output) table;
+%
+% \noindent
+% {\tt IN} means reading data from the input table;
+%
+% \noindent
+% {\tt OUT} means writing data to the output table;
+%
+% \noindent
+% {\it driver} is a symbolic expression, which specifies the driver used
+% to access the table (for details see Appendix \ref{drivers}, page
+% \pageref{drivers});
+%
+% \noindent
+% {\it arg} is an optional symbolic expression, which is an argument
+% pass\-ed to the table driver. This symbolic expression should not
+% include dummy indices specified in the domain;
+%
+% \noindent
+% {\it set} is the name of an optional simple set called {\it control
+% set}. It can be omitted along with the delimiter {\tt<-};
+%
+% \noindent
+% {\it fld} is a field name. Within square brackets at least one field
+% should be specified. The field name following a parameter name or
+% expression is optional and can be omitted along with the
+% delimiter~{\tt\textasciitilde}, in which case the name of corresponding
+% model object is used as the field name;
+%
+% \noindent
+% {\it par} is a symbolic name of a model parameter;
+%
+% \noindent
+% {\it expr} is a numeric or symbolic expression.
+%
+% \para{Examples}
+%
+% \begin{verbatim}
+% table data IN "CSV" "data.csv": S <- [FROM,TO], d~DISTANCE,
+% c~COST;
+% table result{(f,t) in S} OUT "CSV" "result.csv": f~FROM, t~TO,
+% x[f,t]~FLOW;
+% \end{verbatim}
+%
+% The table statement allows reading data from a table into model
+% objects such as sets and (non-scalar) parameters as well as writing
+% data from the model to a table.
+
+\newpage
+
+\subsection{Estrutura de tabelas}
+
+Uma {\it tabela de dados} é um conjunto (desordenado) de {\it registros}, onde cada
+registro consiste do mesmo número de {\it campos} e cada campo possui um único
+nome simbólico denominado o {\it nome do campo}. Por exemplo:
+
+\bigskip
+
+\begin{tabular}{@{\hspace*{42mm}}c@{\hspace*{11mm}}c@{\hspace*{10mm}}c
+@{\hspace*{9mm}}c}
+Primeiro&Segundo&&Último\\
+campo&campo&.\ \ .\ \ .&campo\\
+$\downarrow$&$\downarrow$&&$\downarrow$\\
+\end{tabular}
+
+\begin{tabular}{ll@{}}
+Cabeçalho da tabela&$\rightarrow$\\
+Primeiro registro&$\rightarrow$\\
+Segundo registro&$\rightarrow$\\
+\\
+\hfil .\ \ .\ \ .\\
+\\
+Último registro&$\rightarrow$\\
+\end{tabular}
+\begin{tabular}{|l|l|c|c|}
+\hline
+{\tt DE}&{\tt PARA}&{\tt DISTANCIA}&{\tt CUSTO}\\
+\hline
+{\tt Seattle} &{\tt New-York}&{\tt 2.5}&{\tt 0.12}\\
+{\tt Seattle} &{\tt Chicago} &{\tt 1.7}&{\tt 0.08}\\
+{\tt Seattle} &{\tt Topeka} &{\tt 1.8}&{\tt 0.09}\\
+{\tt San-Diego}&{\tt New-York}&{\tt 2.5}&{\tt 0.15}\\
+{\tt San-Diego}&{\tt Chicago} &{\tt 1.8}&{\tt 0.10}\\
+{\tt San-Diego}&{\tt Topeka} &{\tt 1.4}&{\tt 0.07}\\
+\hline
+\end{tabular}
+
+
+% A {\it data table} is an (unordered) set of {\it records}, where each
+% record consists of the same number of {\it fields}, and each field is
+% provided with a unique symbolic name called the {\it field name}. For
+% example:
+%
+% \bigskip
+%
+% \begin{tabular}{@{\hspace*{42mm}}c@{\hspace*{11mm}}c@{\hspace*{10mm}}c
+% @{\hspace*{9mm}}c}
+% First&Second&&Last\\
+% field&field&.\ \ .\ \ .&field\\
+% $\downarrow$&$\downarrow$&&$\downarrow$\\
+% \end{tabular}
+%
+% \begin{tabular}{ll@{}}
+% Table header&$\rightarrow$\\
+% First record&$\rightarrow$\\
+% Second record&$\rightarrow$\\
+% \\
+% \hfil .\ \ .\ \ .\\
+% \\
+% Last record&$\rightarrow$\\
+% \end{tabular}
+% \begin{tabular}{|l|l|c|c|}
+% \hline
+% {\tt FROM}&{\tt TO}&{\tt DISTANCE}&{\tt COST}\\
+% \hline
+% {\tt Seattle} &{\tt New-York}&{\tt 2.5}&{\tt 0.12}\\
+% {\tt Seattle} &{\tt Chicago} &{\tt 1.7}&{\tt 0.08}\\
+% {\tt Seattle} &{\tt Topeka} &{\tt 1.8}&{\tt 0.09}\\
+% {\tt San-Diego}&{\tt New-York}&{\tt 2.5}&{\tt 0.15}\\
+% {\tt San-Diego}&{\tt Chicago} &{\tt 1.8}&{\tt 0.10}\\
+% {\tt San-Diego}&{\tt Topeka} &{\tt 1.4}&{\tt 0.07}\\
+% \hline
+% \end{tabular}
+
+\subsection{Lendo dados de uma tabela de entrada}
+
+A sentença tabela de entrada faz a leitura de dados
+da tabela especificada, registro por registro.
+
+Uma vez que o registro subsequente foi lido, valores numéricos ou simbólicos
+dos campos, cujos nomes são cercados entre colchetes na sentença table,
+são reunidos em um $n$-tuplo. Se o conjunto de controle é especificado
+na sentença table, este $n$-tuplo é adicionado a ele. Além disso, um valor
+numérico ou simbólico de cada campo associado com um parâmetro do modelo
+é atribuído ao membro do parâmetro identificado por subíndices, que são
+componentes da $n$-tupla que acabou de ser lida.
+
+Por exemplo, a seguinte sentença de tabela de entrada:
+
+\noindent\hfil
+\verb|table dados IN "...": S <- [DE,PARA], d~DISTANCIA, c~CUSTO;|
+
+\noindent
+faz a leitura de valores de quatro campos chamados {\tt DE}, {\tt PARA},
+{\tt DISTANCIA} e {\tt CUSTO} de cada registro da tabela especificada.
+Os valores dos campos {\tt DE} e {\tt PARA} dão um par $(f,t)$, que é
+adicionado ao conjunto de controle {\tt S}. O valor do campo {\tt DISTANCIA} é
+atribuído ao membro do parâmetro ${\tt d}[f,t]$ enquanto que o valor do campo
+{\tt CUSTO} é atribuído ao membro do parâmetro ${\tt c}[f,t]$.
+
+Note que a tabela de entrada pode conter campos adicionais cujos nomes
+não sejam especificados na sentença tabela, neste caso, os valores destes
+campos serão ignorados na leitura da tabela.
+
+% The input table statement causes reading data from the specified table
+% record by record.
+%
+% Once a next record has been read, numeric or symbolic values of fields,
+% whose names are enclosed in square brackets in the table statement, are
+% gathered into $n$-tuple, and if the control set is specified in the
+% table statement, this $n$-tuple is added to it. Besides, a numeric or
+% symbolic value of each field associated with a model parameter is
+% assigned to the parameter member identified by subscripts, which are
+% components of the $n$-tuple just read.
+%
+% For example, the following input table statement:
+%
+% \noindent\hfil
+% \verb|table data IN "...": S <- [FROM,TO], d~DISTANCE, c~COST;|
+%
+% \noindent
+% causes reading values of four fields named {\tt FROM}, {\tt TO},
+% {\tt DISTANCE}, and {\tt COST} from each record of the specified table.
+% Values of fields {\tt FROM} and {\tt TO} give a pair $(f,t)$, which is
+% added to the control set {\tt S}. The value of field {\tt DISTANCE} is
+% assigned to parameter member ${\tt d}[f,t]$, and the value of field
+% {\tt COST} is assigned to parameter member ${\tt c}[f,t]$.
+%
+% Note that the input table may contain extra fields whose names are not
+% specified in the table statement, in which case values of these fields
+% on reading the table are ignored.
+
+\subsection{Escrevendo dados em uma tabela de saída}
+
+A sentença tabela de saída gera a escrita de dados na tabela especificada.
+Note que alguns controladores (chamados CSV e xBASE) destroem a tabela de saída
+antes de escrever os dados, i.e., deletam todos os registros existentes.
+
+Cada $n$-tupla no domínio do conjunto especificado gera um registro escrito na
+tabela de saída. Os valores dos campos são valores numéricos ou simbólicos
+das expressões correspondentes especificadas na sentença table. Estas
+expressões são avaliadas para cada $n$-tupla no conjunto do domínio,
+portanto, podem incluir índices introduzidos na expressão indexante correspondente.
+
+Por exemplo, a seguinte sentença da tabela de saída:
+
+\noindent\hfil
+\verb|table resultado{(f,t) in S} OUT "...": f~DE, t~PARA, x[f,t]~FLUXO;|
+
+\noindent
+gera a escrita de registros; um registro para cada par $(f,t)$ no conjunto
+{\tt S} para a tabela de saída, onde cada registro consiste de três campos
+chamados {\tt DE}, {\tt PARA} e {\tt FLUXO}. Os valores escritos nos campos
+{\tt DE} e {\tt PARA} são os valores correntes dos índices {\tt f} e {\tt t}.
+O valor escrito no campo {\tt FLUXO} é um valor do membro ${\tt x}[f,t]$
+do correspondente parâmetro ou variável indexada.
+
+
+% The output table statement causes writing data to the specified table.
+% Note that some drivers (namely, CSV and xBASE) destroy the output table
+% before writing data, i.e. delete all its existing records.
+%
+% Each $n$-tuple in the specified domain set generates one record written
+% to the output table. Values of fields are numeric or symbolic values of
+% corresponding expressions specified in the table statement. These
+% expressions are evaluated for each $n$-tuple in the domain set and,
+% thus, may include dummy indices introduced in the corresponding indexing
+% expression.
+%
+% For example, the following output table statement:
+%
+% \noindent\hfil
+% \verb|table result{(f,t) in S} OUT "...": f~FROM, t~TO, x[f,t]~FLOW;|
+%
+% \noindent
+% causes writing records, by one record for each pair $(f,t)$ in set
+% {\tt S}, to the output table, where each record consists of three
+% fields named {\tt FROM}, {\tt TO}, and {\tt FLOW}. The values written
+% to fields {\tt FROM} and {\tt TO} are current values of dummy indices
+% {\tt f} and {\tt t}, and the value written to field {\tt FLOW} is
+% a value of member ${\tt x}[f,t]$ of corresponding subscripted parameter
+% or variable.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Dados do modelo}
+
+Os {\it dados do modelo} includem conjuntos elementares, que são ``valores'' dos
+conjuntos do modelo, e valores numéricos e simbólicos dos parâmetros do modelo.
+
+Em MathProg existem duas formas diferentes de fornecer valores aos conjuntos
+e parâmetros do modelo. Uma forma é simplesmente prover os dados necessários
+usando o atributo de atribuição. No entanto, em muitos casos é mais prático separar
+o modelo próprio dos dados particulares necessários para o modelo. Para o último
+caso, em MathProg há uma outra forma, em que a descrição do modelo é dividida
+em duas partes: a seção de modelo e a seção de dados.
+
+A {\it seção de modelo} é a principal parte da descrição do modelo. Ela contém
+todas as declarações de todos objetos do modelo, sendo comum a todos problemas
+baseados naquele modelo.
+
+A {\it seção de dados} é uma parte opcional da descrição do modelo que contém
+dados específicos para um problema particular.
+
+Em MathProg seções de modelo e de dados podem ser localizadas tanto em um arquivo
+de texto ou em dois arquivos de texto separados.
+
+1. Se ambas seções de modelo e de dados estão localizados em um arquivo,
+o arquivo é composto como segue:
+
+
+
+\bigskip
+
+\noindent\hfil
+\framebox{\begin{tabular}{l}
+{\it sentença}{\tt;}\\
+{\it sentença}{\tt;}\\
+\hfil.\ \ .\ \ .\\
+{\it sentença}{\tt;}\\
+{\tt data;}\\
+{\it bloco de dados}{\tt;}\\
+{\it bloco de dados}{\tt;}\\
+\hfil.\ \ .\ \ .\\
+{\it bloco de dados}{\tt;}\\
+{\tt end;}
+\end{tabular}}
+
+
+
+% {\it 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 another way, when the model
+% description is divided into two parts: model section and data section.
+%
+% A {\it 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.
+%
+% A {\it 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.
+%
+% 1. If both model and data sections are placed in one file, the file is
+% composed as follows:
+%
+% \bigskip
+%
+% \noindent\hfil
+% \framebox{\begin{tabular}{l}
+% {\it statement}{\tt;}\\
+% {\it statement}{\tt;}\\
+% \hfil.\ \ .\ \ .\\
+% {\it statement}{\tt;}\\
+% {\tt data;}\\
+% {\it data block}{\tt;}\\
+% {\it data block}{\tt;}\\
+% \hfil.\ \ .\ \ .\\
+% {\it data block}{\tt;}\\
+% {\tt end;}
+% \end{tabular}}
+
+% 2. Se a seção de modelo e dados são posicionados em dois arquivos separados, os
+% arquivos são compostos como segue:
+
+\newpage
+
+2. Se a seção de modelo e dados são posicionados em dois arquivos separados, os
+arquivos são compostos como segue:
+
+\bigskip
+
+\noindent\hfil
+\begin{tabular}{@{}c@{}}
+\framebox{\begin{tabular}{l}
+{\it sentença}{\tt;}\\
+{\it sentença}{\tt;}\\
+\hfil.\ \ .\ \ .\\
+{\it sentença}{\tt;}\\
+{\tt end;}\\
+\end{tabular}}\\
+\\\\Arquivo de modelo\\
+\end{tabular}
+\hspace{32pt}
+\begin{tabular}{@{}c@{}}
+\framebox{\begin{tabular}{l}
+{\tt data;}\\
+{\it bloco de dados}{\tt;}\\
+{\it bloco de dados}{\tt;}\\
+\hfil.\ \ .\ \ .\\
+{\it bloco de dados}{\tt;}\\
+{\tt end;}\\
+\end{tabular}}\\
+\\Arquivo de dados\\
+\end{tabular}
+
+\bigskip
+
+Nota: Se a seção de dados é posicionada em um arquivo separado, a palavra-chave
+{\tt data} é opcional e pode ser omitida juntamente como o ponto e vírgula que a segue.
+
+
+% \bigskip
+%
+% \noindent\hfil
+% \begin{tabular}{@{}c@{}}
+% \framebox{\begin{tabular}{l}
+% {\it statement}{\tt;}\\
+% {\it statement}{\tt;}\\
+% \hfil.\ \ .\ \ .\\
+% {\it statement}{\tt;}\\
+% {\tt end;}\\
+% \end{tabular}}\\
+% \\\\Model file\\
+% \end{tabular}
+% \hspace{32pt}
+% \begin{tabular}{@{}c@{}}
+% \framebox{\begin{tabular}{l}
+% {\tt data;}\\
+% {\it data block}{\tt;}\\
+% {\it data block}{\tt;}\\
+% \hfil.\ \ .\ \ .\\
+% {\it data block}{\tt;}\\
+% {\tt end;}\\
+% \end{tabular}}\\
+% \\Data file\\
+% \end{tabular}
+%
+% \bigskip
+%
+% Note: If the data section is placed in a separate file, the keyword
+% {\tt data} is optional and may be omitted along with the semicolon that
+% follows it.
+
+
+\section{Programando a seção de dados}
+
+A {\it seção de dados} é uma sequência de blocos de dados em vários formatos
+e são discutidos nas seções seguintes. A ordem na qual os blocos de dados
+seguem na seção de dados pode ser arbitrária, portanto, não precisa ser
+necessariamente a mesma ordem que seguem os elementos correspondentes
+da seção de modelo.
+
+As regras para programar a seção de dados são comumente as mesmas que as regras
+de \linebreak programar a descrição do modelo (ver Seção \ref{coding}, página
+\pageref{coding}), i.e., blocos de dados são compostos com unidades léxicas
+básicas, como nomes simbólicos, literais numéricos e de cadeia,
+palavras-chave, \linebreak delimitadores e comentários. No entanto, por conveniência
+e para melhorar legibilidade, há um desvio da regra comum: se um literal
+de cadeia consiste unicamente de caracteres alfanuméricos (incluindo
+o caractere sublinhado), os sinais {\tt+} e {\tt-} e/ou o ponto decimal,
+ele pode ser programado sem aspas limitadoras (simples ou duplas).
+
+Todo material numérico e simbólico provido na seção de dados é programado
+na forma de números e símbolos, i.e., diferentemente da seção de modelo,
+não são permitidas expressões na seção de dados. Apesar disso, os sinais
+{\tt+} e {\tt-} podem preceder literais numéricos para permitir a programação
+de quantidades numéricas com sinais. Neste caso não deve haver caractere de
+espaço em branco entre o sinal e o literal numérico seguinte (se houver
+pelo menos uma espaço em branco, o sinal e o literal numérico seguinte são
+reconhecidos como duas unidades léxicas diferentes).
+
+
+
+% The {\it data section} is a sequence of data blocks in various formats,
+% which are discussed in following sections. The order, in which data
+% blocks follow in the data section, may be arbitrary, not necessarily
+% the same, in which 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 (see Section \ref{coding}, page
+% \pageref{coding}), 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 for
+% 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 {\tt+} and {\tt-}, and/or the
+% decimal point, it may be coded without bordering by (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
+% {\tt+} and {\tt-} can precede numeric literals to allow coding signed
+% numeric quantities, in which case there should 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 two different lexical units).
+
+\newpage
+
+\section{Bloco de dados set}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][44pt]{468pt}{
+\hspace{6pt} {\tt set} {\it nome} {\tt,} {\it registro} {\tt,} \dots
+{\tt,} {\it registro} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt set} {\it nome} {\tt[} {\it símbolo} {\tt,} \dots
+{\tt,} {\it símbolo} {\tt]} {\tt,} {\it registro} {\tt,} \dots {\tt,}
+{\it registro} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it nome} é um nome simbólico do conjunto;
+
+\noindent
+{\it símbolo}, \dots, {\it símbolo} são subíndices que especificam
+um membro particular do conjunto \linebreak(se o conjunto é uma matriz, i.e.,
+um conjunto de conjuntos);
+
+\noindent
+{\it registro}, \dots, {\it registro} são registros.
+
+\noindent
+As vírgulas que precedem os registros podem ser omitidas.
+
+\para{Registros}
+
+\vspace*{-8pt}
+
+\begin{description}
+\item[{\tt :=}]\hspace*{0pt}\\
+é um elemento de atribuição de registro não-significativo que pode ser usado
+livremente para melhorar a legibilidade;
+\item[{\tt(} {\it fatia} {\tt)}]\hspace*{0pt}\\
+especifica uma fatia;
+\item[{\it dados-simples}]\hspace*{0pt}\\
+especifica os dados do conjunto em formato simples;
+\item[{\tt:} {\it dados matriciais}]\hspace*{0pt}\\
+especifica os dados do conjunto em formato de matriz;
+\item[{\tt(tr)} {\tt:} {\it dados matriciais}]\hspace*{0pt}\\
+especifica os dados do conjunto em formato de matriz transposta.
+(Neste caso, os dois pontos que seguem a palavra-chave {\tt(tr)} podem ser omitidos).
+\end{description}
+
+\vspace*{-8pt}
+
+\para{Exemplos}
+
+\begin{verbatim}
+set mes := Jan Fev Mar Abr Mai Jun;
+set mes "Jan", "Fev", "Mar", "Abr", "Mai", "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 3 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{verbatim}
+
+\noindent(Nestes exemplos {\tt mes} é um conjunto simples de singletos,
+{\tt A} é uma matriz 2-dimensional de duplas e {\tt B} é um conjunto
+simples de triplas. Os blocos de dados para o mesmo conjunto são equivalentes
+no sentido que especificam os mesmos dados em formatos distintos.)
+
+O {\it bloco de dados do conjunto} é usado para especificar um conjunto elementar
+completo que é atribuído a um conjunto (se é um conjunto simples) ou a um de
+seus membros (se o conjunto é uma matriz de conjuntos).\footnote{Há uma outra forma
+de especificar dados para um conjunto simples com dados para os parâmetros.
+Esta questão é discutida na próxima seção.}
+
+Blocos de dados podem ser especificados somente para conjuntos não-calculáveis,
+i.e., para \linebreak conjuntos que possuem o atributo de atribuição ({\tt:=})
+na sentença set correspondente.
+
+Se o conjunto é um conjunto simples, somente seus nomes simbólicos devem ser
+especificados no cabeçalho do bloco de dados. Caso contrário, se o conjunto
+é uma matriz $n$-dimensional, seus nomes simbólicos devem ser fornecidos com
+uma lista completa de subíndices separados por vírgulas e cercados em colchetes
+para especificar um membro particular da matriz de conjuntos. O número de
+subíndices deve ser igual ao da dimensão da matriz de conjuntos, onde
+cada subíndice deve ser um número ou um símbolo.
+
+Um conjunto elementar definido no bloco de dados é programado como uma sequência
+de \linebreak registros descritos abaixo.\footnote{{\it Registro} é simplesmente
+um termo técnico. Não significa que os mesmos possuem qualquer formato
+especial.}
+
+
+% \noindent
+% \framebox[468pt][l]{
+% \parbox[c][44pt]{468pt}{
+% \hspace{6pt} {\tt set} {\it name} {\tt,} {\it record} {\tt,} \dots
+% {\tt,} {\it record} {\tt;}
+%
+% \medskip
+%
+% \hspace{6pt} {\tt set} {\it name} {\tt[} {\it symbol} {\tt,} \dots
+% {\tt,} {\it symbol} {\tt]} {\tt,} {\it record} {\tt,} \dots {\tt,}
+% {\it record} {\tt;}
+% }}
+%
+% \medskip
+%
+% \noindent
+% {\it name} is a symbolic name of the set;
+%
+% \noindent
+% {\it symbol}, \dots, {\it symbol} are subscripts, which specify
+% a particular member of the set (if the set is an array, i.e. a set of
+% sets);
+%
+% \noindent
+% {\it record}, \dots, {\it record} are data records.
+%
+% \noindent
+% Commae preceding data records may be omitted.
+%
+% \para{Data records}
+%
+% \vspace*{-8pt}
+%
+% \begin{description}
+% \item[{\tt :=}]\hspace*{0pt}\\
+% is a non-significant data record, which may be used freely to improve
+% readability;
+% \item[{\tt(} {\it slice} {\tt)}]\hspace*{0pt}\\
+% specifies a slice;
+% \item[{\it simple-data}]\hspace*{0pt}\\
+% specifies set data in the simple format;
+% \item[{\tt:} {\it matrix-data}]\hspace*{0pt}\\
+% specifies set data in the matrix format;
+% \item[{\tt(tr)} {\tt:} {\it matrix-data}]\hspace*{0pt}\\
+% specifies set data in the transposed matrix format. (In this case the
+% colon following the keyword {\tt(tr)} may be omitted.)
+% \end{description}
+%
+% \vspace*{-8pt}
+%
+% \para{Examples}
+%
+% \begin{verbatim}
+% 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 3 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{verbatim}
+%
+% \noindent(In these examples {\tt month} is a simple set of singlets,
+% {\tt A} is a 2-dimensional array of doublets, and {\tt B} is a simple
+% set of triplets. Data blocks for the same set are equivalent in the
+% sense that they specify the same data in different formats.)
+%
+% The {\it 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. for
+% sets, which have no assign attribute ({\tt:=}) in the corresponding set
+% statements.
+%
+% If the set is a simple set, only its symbolic name should be specified
+% in the header of the data block. Otherwise, if the set is a
+% $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 should be the same as the dimension of the set array, where
+% each subscript should be a number or symbol.
+%
+% An elemental set defined in the set data block is coded as a sequence
+% of data records described below.\footnote{{\it Data record} is simply a
+% technical term. It does not mean that data records have any special
+% formatting.}
+
+
+\subsection{Registro de atribuição de dados}
+
+O {\it registro de atribuição de dados} ({\tt:=}) é um elemento não-significante.
+Ele pode ser usado para melhorar a legibilidade de blocos de dados.
+
+% The {\it assign data record} ({\tt:=}) is a non-signficant element.
+% It may be used for improving readability of data blocks.
+
+\subsection{Registro em fatia de dados}
+
+O {\it registro em fatia de dados} é um registro de controle que especifica
+uma {\it fatia} do conjunto elementar definido no bloco de dados. Ele possui
+a seguinte forma sintática:
+$$\mbox{{\tt(} $s_1$ {\tt,} $s_2$ {\tt,} \dots {\tt,} $s_n$ {\tt)}}$$
+onde $s_1$, $s_2$, \dots, $s_n$ são componentes da fatia.
+
+Cada componente da fatia pode ser um número, símbolo ou asterisco
+({\tt*}). O número de \linebreak componentes na fatia deve ser o mesmo da
+dimensão $n$-tuplas do conjunto elementar a ser definido. Por exemplo,
+se o conjunto elementar contém 4-tuplas (quádruplas), a fatia deve ter
+quatro \linebreak componentes. O número de asteriscos na fatia denomina a
+{\it dimensão da fatia}.
+
+O efeito de usar fatias é o seguinte: se uma fatia $m$-dimensional
+(i.e., uma fatia contendo $m$ asteriscos) é especificada no bloco de dados,
+todos registros subsequentes devem especificar tuplas de dimensão~$m$.
+Sempre que uma $m$-tupla é encontrada, cada asterisco da fatia é substituído
+pelos componentes correspondentes da $m$-tupla, o que resulta na
+$n$-tupla, que é incluída no conjunto \linebreak elementar a ser definido.
+Por exemplo, se a fatia $(a,*,1,2,*)$ está vigente e a dupla
+$(3,b)$ é encontrada no registro subsequente, a 5-tupla resultante a ser incluída
+no conjunto elementar é $(a,3,1,2,b)$.
+
+Se a fatia não possui asteriscos, ela própria define uma $n$-tupla completa
+que é incluída no conjunto elementar.
+
+Uma vez especificada uma fatia, a mesma está vigente até que apareça uma nova
+fatia ou até que se encontre o fim do bloco de dados. Note que se uma fatia
+não é especificada no bloco de dados, assume-se uma cujos componentes são
+asteriscos em todas as posições.
+
+
+% The {\it slice data record} is a control record, which specifies a
+% {\it slice} of the elemental set defined in the data block. It has the
+% following syntactic form:
+% $$\mbox{{\tt(} $s_1$ {\tt,} $s_2$ {\tt,} \dots {\tt,} $s_n$ {\tt)}}$$
+% where $s_1$, $s_2$, \dots, $s_n$ are components of the slice.
+%
+% Each component of the slice can be a number or symbol or the asterisk
+% ({\tt*}). The number of components in the slice should be the same as
+% the dimension of $n$-tuples in the elemental set to be defined. For
+% instance, if the elemental set contains 4-tuples (quadruplets), the
+% slice should have four components. The number of asterisks in the slice
+% is called the {\it slice dimension}.
+%
+% The effect of using slices is the following. If a $m$-dimensional slice
+% (i.e. a slice having $m$ asterisks) is specified in the data block, all
+% subsequent data records should specify tuples of the dimension~$m$.
+% Whenever a $m$-tuple is encountered, each asterisk in the slice is
+% replaced by corresponding components of the $m$-tuple that gives the
+% resultant $n$-tuple, which is included in the elemental set to be
+% defined. For example, if the slice $(a,*,1,2,*)$ is in effect, and
+% 2-tuple $(3,b)$ is encountered in a subsequent data record, the
+% resultant 5-tuple included in the elemental set is $(a,3,1,2,b)$.
+%
+% The slice having no asterisks itself defines a complete $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 is encountered. Note that if no slice is specified in
+% the data block, one, components of which are all asterisks, is assumed.
+
+\subsection{Registro simples}
+
+O {\it registro simples} define uma $n$-tupla em um formato simples
+e possui a seguinte forma sintática:
+$$\mbox{$t_1$ {\tt,} $t_2$ {\tt,} \dots {\tt,} $t_n$}$$
+onde $t_1$, $t_2$, \dots, $t_n$ são componentes da $n$-tupla. Cada
+componente pode ser um número ou um símbolo. As vírgulas entre os componentes
+são opcionais e podem ser omitidas.
+
+% The {\it simple data record} defines one $n$-tuple in a simple format
+% and has the following syntactic form:
+% $$\mbox{$t_1$ {\tt,} $t_2$ {\tt,} \dots {\tt,} $t_n$}$$
+% where $t_1$, $t_2$, \dots, $t_n$ are components of the $n$-tuple. Each
+% component can be a number or symbol. Commae between components are
+% optional and may be omitted.
+
+\subsection{Registro de matriz}
+
+O {\it registro de matriz} define diversas 2-tuplas (duplas) em
+um formato matricial e possui a seguinte forma sintática:
+$$\begin{array}{cccccc}
+\mbox{{\tt:}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
+r_1&a_{11}&a_{12}&\dots&a_{1n}&\\
+r_2&a_{21}&a_{22}&\dots&a_{2n}&\\
+\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
+r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
+\end{array}$$
+onde $r_1$, $r_2$, \dots, $r_m$ são números e/ou símbolos
+que correspondem a linhas da matriz; $c_1$, $c_2$, \dots, $c_n$ são
+números e/ou símbolos que correspondem a colunas da matriz, $a_{11}$,
+$a_{12}$, \dots, $a_{mn}$ são elementos da matriz, que podem ser tanto
+{\tt+} como {\tt-}. (Neste registro, o delimitador {\tt:} que precede a
+lista de colunas e o delimitador {\tt:=} que segue após a lista de colunas,
+não podem ser omitidos.)
+
+Cada elemento $a_{ij}$ do bloco de dados matricial (onde $1\leq i\leq m$,
+$1\leq j\leq n$) correspondem a 2-tuplas $(r_i,c_j)$. Se $a_{ij}$ é o
+sinal mais ({\tt+}), a 2-tupla correspondente (ou uma $n$-tupla maior, se uma
+fatia é usada) é incluída no conjunto elementar. Caso contrário, se $a_{ij}$ é o
+sinal menos ({\tt-}), aquela 2-tupla não é incluída no conjunto elementar.
+
+Uma vez que o registro de matriz define 2-tuplas, tanto o conjunto elementar
+quanto a fatia vigente devem ser 2-dimensional.
+
+\newpage
+
+\subsection{Registro de matriz transposta}
+
+O {\it registro de matriz transposta} possui a seguinte forma sintática:
+$$\begin{array}{cccccc}
+\mbox{{\tt(tr) :}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
+r_1&a_{11}&a_{12}&\dots&a_{1n}&\\
+r_2&a_{21}&a_{22}&\dots&a_{2n}&\\
+\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
+r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
+\end{array}$$
+(Neste caso, o delimitador {\tt:} que segue a palavra-chave {\tt(tr)} é
+opcional e pode ser omitido.)
+
+Este registro é completamente análogo ao registro de matriz (ver
+anteriormente) com a única exceção de que neste caso, cada elemento $a_{ij}$ da
+matriz passa a corresponder a 2-tupla $(c_j,r_i)$ ao invés de $(r_i,c_j)$.
+
+Uma vez especificado, o indicador {\tt(tr)} tem alcance em todos registros
+subsequentes até que se encontre outra fatia ou o fim do bloco de dados.
+
+
+% The {\it transposed matrix data record} has the following syntactic
+% form:
+% $$\begin{array}{cccccc}
+% \mbox{{\tt(tr) :}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
+% r_1&a_{11}&a_{12}&\dots&a_{1n}&\\
+% r_2&a_{21}&a_{22}&\dots&a_{2n}&\\
+% \multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
+% r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
+% \end{array}$$
+% (In this case the delimiter {\tt:} following the keyword {\tt(tr)} is
+% optional and may be omitted.)
+%
+% This data record is completely analogous to the matrix data record (see
+% above) with only exception that in this case each element $a_{ij}$ of
+% the matrix corresponds to 2-tuple $(c_j,r_i)$ rather than $(r_i,c_j)$.
+%
+% Being once specified the {\tt(tr)} indicator affects all subsequent
+% data records until either a slice or the end of data block is
+% encountered.
+
+\section{Bloco de dados de parâmetro}
+
+\noindent
+\framebox[468pt][l]{
+\parbox[c][88pt]{468pt}{
+\hspace{6pt} {\tt param} {\it nome} {\tt,} {\it registro} {\tt,} \dots
+{\tt,} {\it registro} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt param} {\it nome} {\tt default} {\it valor} {\tt,}
+{\it registro} {\tt,} \dots {\tt,} {\it registro} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt param} {\tt:} {\it dados-tabulação} {\tt;}
+
+\medskip
+
+\hspace{6pt} {\tt param} {\tt default} {\it valor} {\tt:}
+{\it dados-tabulação} {\tt;}
+}}
+
+\medskip
+
+\noindent
+{\it nome} é um nome simbólico do parâmetro;
+
+\noindent
+{\it valor} é um valor opcional padrão do parâmetro;
+
+\noindent
+{\it registro}, \dots, {\it registro} são registros;
+
+\noindent
+{\it dados-tabulação} especifica os dados do parâmetro em formato tabulação.
+
+\noindent
+As vírgulas que precedem os registros podem ser omitidas.
+
+\para{Registros}
+
+\vspace*{-8pt}
+
+\begin{description}
+\item[{\tt :=}]\hspace*{0pt}\\
+é um elemento de atribuição de registro não-significativo que pode ser usado
+livremente para melhorar a legibilidade;
+\item[{\tt[} {\it fatia} {\tt]}]\hspace*{0pt}\\
+especifica uma fatia;
+\item[{\it dados-planos}]\hspace*{0pt}\\
+especifica os dados do parâmetro em formato simples;
+\item[{\tt:} {\it dados-tabulares}]\hspace*{0pt}\\
+especifica dados do parâmetro em formato tabular;
+\item[{\tt(tr)} {\tt:} {\it dados-tabulares}]\hspace*{0pt}\\
+especifica dados do parâmetro no formato tabular transposto.
+(Neste caso, os dois pontos que seguem a palavra-chave {\tt(tr)} podem ser omitidos).
+\end{description}
+
+\vspace*{-8pt}
+
+\para{Exemplos}
+
+\begin{verbatim}
+param T := 4;
+param mes := 1 Jan 2 Fev 3 Mar 4 Abr 5 Mai;
+param mes := [1] 'Jan', [2] 'Fev', [3] 'Mar', [4] 'Abr', [5] 'Mai';
+param estoque_inicial := ferro 7.32 niquel 35.8;
+param estoque_inicial [*] ferro 7.32, niquel 35.8;
+param custo [ferro] .025 [niquel] .03;
+param valor := ferro -.1, niquel .02;
+param : estoque_inicial custo valor :=
+ ferro 7.32 .025 -.1
+ niquel 35.8 .03 .02 ;
+param : insumo : estoque_inicial custo valor :=
+ ferro 7.32 .025 -.1
+ niquel 35.8 .03 .02 ;
+param demanda default 0 (tr)
+ : FRA DET LAN WIN STL FRE LAF :=
+ chapa 300 . 100 75 . 225 250
+ bobina 500 750 400 250 . 850 500
+ placa 100 . . 50 200 . 250 ;
+param custo_transporte :=
+ [*,*,chapa]: 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
+ [*,*,bobina]: 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
+ [*,*,placa]: 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{verbatim}
+
+O {\it bloco de dados do parâmetro} é usado para especificar dados
+completos para um parâmetro (ou parâmetros, se os dados são especificados
+no formato tabulação).
+
+Os blocos de dados podem ser especificados apenas para parâmetros não-calculáveis, i.e.,
+para parâmetros que não possuem o atributo de atribuição ({\tt:=}) nas
+sentenças parameter correspondentes.
+
+Os dados definidos no bloco de dados do parâmetro são programados como uma sequência
+de registros descritos em seguida. Adicionalmente, o bloco de dados pode vir com
+o atributo opcional {\tt default}, que especifica um valor numérico ou simbólico
+padrão do parâmetro (ou parâmetros). Este valor padrão é atribuído ao parâmetro ou
+a seus membros quando não se definem valores apropriados no bloco de dados do
+parâmetro. O atributo {\tt default} não pode ser usado se ele já tiver sido
+especificado na sentença parameter correspondente.
+
+
+% \noindent
+% \framebox[468pt][l]{
+% \parbox[c][88pt]{468pt}{
+% \hspace{6pt} {\tt param} {\it name} {\tt,} {\it record} {\tt,} \dots
+% {\tt,} {\it record} {\tt;}
+%
+% \medskip
+%
+% \hspace{6pt} {\tt param} {\it name} {\tt default} {\it value} {\tt,}
+% {\it record} {\tt,} \dots {\tt,} {\it record} {\tt;}
+%
+% \medskip
+%
+% \hspace{6pt} {\tt param} {\tt:} {\it tabbing-data} {\tt;}
+%
+% \medskip
+%
+% \hspace{6pt} {\tt param} {\tt default} {\it value} {\tt:}
+% {\it tabbing-data} {\tt;}
+% }}
+%
+% \medskip
+%
+% \noindent
+% {\it name} is a symbolic name of the parameter;
+%
+% \noindent
+% {\it value} is an optional default value of the parameter;
+%
+% \noindent
+% {\it record}, \dots, {\it record} are data records;
+%
+% \noindent
+% {\it tabbing-data} specifies parameter data in the tabbing format.
+%
+% \noindent
+% Commae preceding data records may be omitted.
+%
+% \para{Data records}
+%
+% \vspace*{-8pt}
+%
+% \begin{description}
+% \item[{\tt :=}]\hspace*{0pt}\\
+% is a non-significant data record, which may be used freely to improve
+% readability;
+% \item[{\tt[} {\it slice} {\tt]}]\hspace*{0pt}\\
+% specifies a slice;
+% \item[{\it plain-data}]\hspace*{0pt}\\
+% specifies parameter data in the plain format;
+% \item[{\tt:} {\it tabular-data}]\hspace*{0pt}\\
+% specifies parameter data in the tabular format;
+% \item[{\tt(tr)} {\tt:} {\it tabular-data}]\hspace*{0pt}\\
+% specifies set data in the transposed tabular format. (In this case the
+% colon following the keyword {\tt(tr)} may be omitted.)
+% \end{description}
+%
+% \vspace*{-8pt}
+%
+% \para{Examples}
+%
+% \begin{verbatim}
+% 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{verbatim}
+%
+% The {\it parameter data block} is used to specify complete data for a
+% parameter (or parameters, if data are specified in the tabbing format).
+%
+% Data blocks can be specified only for non-computable parameters, i.e.
+% for parameters, which have no assign attribute ({\tt:=}) 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 {\tt 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 when
+% no appropriate value is defined in the parameter data block. The
+% {\tt default} attribute cannot be used, if it is already specified in
+% the corresponding parameter statement.
+
+\subsection{Registro de atribuição}
+
+O {\it registro de atribuição} ({\tt:=}) é um elemento não-significativo.
+Ele pode ser usado para melhorar a legibilidade dos blocos de dados;
+
+% The {\it assign data record} ({\tt:=}) is a non-signficant element.
+% It may be used for improving readability of data blocks.
+
+\subsection{Registro em fatia}
+
+O {\it registro em fatia} é um registro de controle que especifica uma
+{\it fatia} da matriz do parâmetro. Ele tem a seguinte forma sintática:
+$$\mbox{{\tt[} $s_1$ {\tt,} $s_2$ {\tt,} \dots {\tt,} $s_n$ {\tt]}}$$
+onde $s_1$, $s_2$, \dots, $s_n$ são componentes da fatia.
+
+Cada componente da fatia pode ser um número, símbolo ou asterisco
+({\tt*}). O número de componentes na fatia deve ser o mesmo da
+dimensão $n$-tuplas do parâmetro. Por exemplo,
+se o parâmetro é uma matriz 4-dimensional, a fatia deve ter
+quatro componentes. O número de \linebreak asteriscos na fatia denomina a
+{\it dimensão da fatia}.
+
+O efeito de usar fatias é o seguinte: se uma fatia $m$-dimensional
+(i.e., uma fatia contendo $m$ asteriscos) é especificada no bloco de dados,
+todos registros subsequentes devem especificar os subíndices do membros do
+parâmetro, como se o parâmetro fosse $m$-dimensional, não $n$-dimensional.
+
+Sempre que $m$ subíndices são encontrados, cada asterisco da fatia é substituído
+pelos \linebreak componentes correspondentes que dão $n$ subíndices, que definem o
+membro corrente do parâmetro.
+Por exemplo, se a fatia $(a,*,1,2,*)$ está vigente e os subíndices 3 e
+$b$ são encontradas no \linebreak registro subsequente, a lista completa de subíndices
+usada para escolher o membro do parâmetro é $(a,3,1,2,b)$.
+
+
+É permitido especificar uma fatia que não tenha asteriscos. Tal fatia, em si
+própria, define uma lista completa de subíndice, em cujo caso o próximo
+registro deve definir apenas um único valor do membro correspondentes do parâmetro.
+
+Uma vez especificada uma fatia, a mesma está vigente até que apareça uma nova
+fatia ou até que se encontre o fim do bloco de dados. Note que se uma fatia
+não é especificada no bloco de dados, assume-se uma cujos componentes são
+asteriscos em todas as posições.
+
+
+\subsection{Registro plano}
+
+O {\it registro plano} define uma lista de subíndice e um valor individual
+no formato plano. Este registro possui a seguinte forma sintática:
+$$\mbox{$t_1$ {\tt,} $t_2$ {\tt,} \dots {\tt,} $t_n$ {\tt,} $v$}$$
+onde $t_1$, $t_2$, \dots, $t_n$ são subíndices e $v$ é um valor.
+Cada subíndice, assim como o valor, pode ser um número ou um símbolo. As
+vírgulas que seguem os subíndices são opcionais e podem ser omitidas.
+
+No caso de um parâmetro ou fatia 0-dimensional, o registro plano não possui
+subíndice e consiste de um valor individual apenas.
+
+
+% The {\it plain data record} defines a subscript list and a single value
+% in the plain format. This record has the following syntactic form:
+% $$\mbox{$t_1$ {\tt,} $t_2$ {\tt,} \dots {\tt,} $t_n$ {\tt,} $v$}$$
+% where $t_1$, $t_2$, \dots, $t_n$ are subscripts, and $v$ 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 has
+% no subscripts and consists of a single value only.
+
+\subsection{Registro tabular}
+
+O {\it registro tabular} define diversos valores onde cada valor é provido
+de dois subíndices. Este registro possui a seguinte forma sintática:
+$$\begin{array}{cccccc}
+\mbox{{\tt:}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
+r_1&a_{11}&a_{12}&\dots&a_{1n}&\\
+r_2&a_{21}&a_{22}&\dots&a_{2n}&\\
+\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
+r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
+\end{array}$$
+onde $r_1$, $r_2$, \dots, $r_m$ são números e/ou símbolos
+que correspondem a linhas da tabela; enquanto que $c_1$, $c_2$, \dots, $c_n$ são
+são números e/ou símbolos que correspondem a colunas da tabela, $a_{11}$,
+$a_{12}$, \dots, $a_{mn}$ são elementos da tabela. Cada elemento pode ser
+um número, símbolo ou o ponto decimal ({\tt.}) individual. (neste registro,
+o delimitador {\tt:} que precede a lista de colunas e o delimitador
+{\tt:=} que segue após a lista de colunas, não podem ser omitidos).
+
+Cada elemento $a_{ij}$ do bloco de dados tabulares ($1\leq i\leq m$,
+$1\leq j\leq n$) define dois subíndices, onde o primeiro subíndice é
+$r_i$ e o segundo é $c_j$. Estes subíndices são usados juntamente com
+a fatia vigente para formar a lista completa de subíndices que identifica
+um membro particular da matriz de parâmetros. Se $a_{ij}$
+é um número ou um símbolo, este valor é atribuído ao membro do parâmetro.
+No entanto, se $a_{ij}$ é um ponto decimal individual, o membro é atribuído
+ao valor padrão especificado ou no bloco de dados do parâmetro
+ou na sentença parameter, ou ainda, se nenhum valor padrão é especificado,
+o membro permanece indefinido.
+
+Uma vez que o registro tabular fornece dois subíndices para cada valor,
+tanto o parâmetro quanto a fatia vigente em uso devem ser 2-dimensional.
+
+
+% The {\it tabular data record} defines several values, where each value
+% is provided with two subscripts. This record has the following
+% syntactic form:
+% $$\begin{array}{cccccc}
+% \mbox{{\tt:}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
+% r_1&a_{11}&a_{12}&\dots&a_{1n}&\\
+% r_2&a_{21}&a_{22}&\dots&a_{2n}&\\
+% \multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
+% r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
+% \end{array}$$
+% where $r_1$, $r_2$, \dots, $r_m$ are numbers and/or symbols
+% corresponding to rows of the table; $c_1$, $c_2$, \dots, $c_n$ are
+% numbers and/or symbols corresponding to columns of the table, $a_{11}$,
+% $a_{12}$, \dots, $a_{mn}$ are table elements. Each element can be a
+% number or symbol or the single decimal point ({\tt.}). (In this data
+% record the delimiter {\tt:} preceding the column list and the delimiter
+% {\tt:=} following the column list cannot be omitted.)
+%
+% Each element $a_{ij}$ of the tabular data block ($1\leq i\leq m$,
+% $1\leq j\leq n$) defines two subscripts, where the first subscript is
+% $r_i$, and the second one is $c_j$. These subscripts are used in
+% conjunction with the current slice to form the complete subscript list
+% that identifies a particular member of the parameter array. If $a_{ij}$
+% is a number or symbol, this value is assigned to the parameter member.
+% However, if $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.
+%
+% Since the tabular data record provides two subscripts for each value,
+% either the parameter or the slice currently used should be
+% 2-dimensional.
+
+\subsection{Registro tabular transposto}
+
+O {\it registro tabular transposto} possui a seguinte forma sintática:
+$$\begin{array}{cccccc}
+\mbox{{\tt(tr) :}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
+r_1&a_{11}&a_{12}&\dots&a_{1n}&\\
+r_2&a_{21}&a_{22}&\dots&a_{2n}&\\
+\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
+r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
+\end{array}$$
+(Neste caso, o delimitador {\tt:} que segue a palavra-chave {\tt(tr)} é
+opcional e pode ser omitida.)
+
+Este registro é completamente análogo ao registro tabular
+(ver anteriormente) com a única exceção que o primeiro subíndice definido
+pelo elemento $a_{ij}$ é $c_j$ enquanto que o segundo é $r_i$.
+
+Uma vez especificado, o indicador {\tt(tr)} afeta todos registros subsequentes
+até que se encontre outra fatia ou o fim do bloco de dados.
+
+
+% The {\it transposed tabular data record} has the following syntactic
+% form:
+% $$\begin{array}{cccccc}
+% \mbox{{\tt(tr) :}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
+% r_1&a_{11}&a_{12}&\dots&a_{1n}&\\
+% r_2&a_{21}&a_{22}&\dots&a_{2n}&\\
+% \multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
+% r_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
+% \end{array}$$
+% (In this case the delimiter {\tt:} following the keyword {\tt(tr)} is
+% optional and may be omitted.)
+%
+% This data record is completely analogous to the tabular data record
+% (see above) with only exception that the first subscript defined by
+% element $a_{ij}$ is $c_j$ while the second one is $r_i$.
+%
+% Being once specified the {\tt(tr)} indicator affects all subsequent
+% data records until either a slice or the end of data block is
+% encountered.
+
+% \newpage
+
+\subsection{Formato de dados em tabulação}
+
+O bloco de dados do parâmetro no {\it formato tabulação} possui a seguinte
+forma sintática:
+$$
+\begin{array}{*{8}{l}}
+\multicolumn{4}{l}
+{{\tt param}\ {\tt default}\ valor\ {\tt :}\ s\ {\tt :}}&
+p_1\ \ \verb|,|&p_2\ \ \verb|,|&\dots\ \verb|,|&p_r\ \ \verb|:=|\\
+r_{11}\ \verb|,|& r_{12}\ \verb|,|& \dots\ \verb|,|& r_{1n}\ \verb|,|&
+a_{11}\ \verb|,|& a_{12}\ \verb|,|& \dots\ \verb|,|& a_{1r}\ \verb|,|\\
+r_{21}\ \verb|,|& r_{22}\ \verb|,|& \dots\ \verb|,|& r_{2n}\ \verb|,|&
+a_{21}\ \verb|,|& a_{22}\ \verb|,|& \dots\ \verb|,|& a_{2r}\ \verb|,|\\
+\dots & \dots & \dots & \dots & \dots & \dots & \dots & \dots \\
+r_{m1}\ \verb|,|& r_{m2}\ \verb|,|& \dots\ \verb|,|& r_{mn}\ \verb|,|&
+a_{m1}\ \verb|,|& a_{m2}\ \verb|,|& \dots\ \verb|,|& a_{mr}\ \verb|;|\\
+\end{array}
+$$
+
+1. A palavra-chave {\tt default} pode ser omitida juntamente
+com o valor que a segue.
+
+2. O nome simbólico $s$ pode ser omitido juntamente com
+os dois pontos que o segue.
+
+3. Todas as vírgulas são opcionais e podem ser omitidas.
+
+O bloco de dados no formato tabulação mostrado acima é exatamente
+equivalente aos seguintes blocos de dados:
+
+\verb|set| $s$\ \verb|:=|\ $
+\verb|(|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|) |
+\verb|(|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|) |
+\dots
+\verb| (|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|);|$
+
+\verb|param| $p_1$\ \verb|default|\ $valor$\ \verb|:=|
+
+$\verb| |
+\verb|[|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|] |a_{11}
+\verb| [|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|] |a_{21}
+\verb| |\dots
+\verb| [|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|] |a_{m1}
+\verb|;|
+$
+
+\verb|param| $p_2$\ \verb|default|\ $valor$\ \verb|:=|
+
+$\verb| |
+\verb|[|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|] |a_{12}
+\verb| [|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|] |a_{22}
+\verb| |\dots
+\verb| [|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|] |a_{m2}
+\verb|;|
+$
+
+\verb| |.\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .
+
+\verb|param| $p_r$\ \verb|default|\ $valor$\ \verb|:=|
+
+$\verb| |
+\verb|[|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|] |a_{1r}
+\verb| [|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|] |a_{2r}
+\verb| |\dots
+\verb| [|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|] |a_{mr}
+\verb|;|
+$
+
+
+% The parameter data block in the {\it tabbing format} has the following
+% syntactic form:
+% $$
+% \begin{array}{*{8}{l}}
+% \multicolumn{4}{l}
+% {{\tt param}\ {\tt default}\ value\ {\tt :}\ s\ {\tt :}}&
+% p_1\ \ \verb|,|&p_2\ \ \verb|,|&\dots\ \verb|,|&p_r\ \ \verb|:=|\\
+% r_{11}\ \verb|,|& r_{12}\ \verb|,|& \dots\ \verb|,|& r_{1n}\ \verb|,|&
+% a_{11}\ \verb|,|& a_{12}\ \verb|,|& \dots\ \verb|,|& a_{1r}\ \verb|,|\\
+% r_{21}\ \verb|,|& r_{22}\ \verb|,|& \dots\ \verb|,|& r_{2n}\ \verb|,|&
+% a_{21}\ \verb|,|& a_{22}\ \verb|,|& \dots\ \verb|,|& a_{2r}\ \verb|,|\\
+% \dots & \dots & \dots & \dots & \dots & \dots & \dots & \dots \\
+% r_{m1}\ \verb|,|& r_{m2}\ \verb|,|& \dots\ \verb|,|& r_{mn}\ \verb|,|&
+% a_{m1}\ \verb|,|& a_{m2}\ \verb|,|& \dots\ \verb|,|& a_{mr}\ \verb|;|\\
+% \end{array}
+% $$
+%
+% 1. The keyword {\tt default} may be omitted along with a value
+% following it.
+%
+% 2. Symbolic name $s$ may be omitted along with the colon following it.
+%
+% 3. All commae are optional and may be omitted.
+%
+% The data block in the tabbing format shown above is exactly equivalent
+% to the following data blocks:
+%
+% \verb|set| $s$\ \verb|:=|\ $
+% \verb|(|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|) |
+% \verb|(|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|) |
+% \dots
+% \verb| (|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|);|$
+%
+% \verb|param| $p_1$\ \verb|default|\ $value$\ \verb|:=|
+%
+% $\verb| |
+% \verb|[|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|] |a_{11}
+% \verb| [|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|] |a_{21}
+% \verb| |\dots
+% \verb| [|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|] |a_{m1}
+% \verb|;|
+% $
+%
+% \verb|param| $p_2$\ \verb|default|\ $value$\ \verb|:=|
+%
+% $\verb| |
+% \verb|[|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|] |a_{12}
+% \verb| [|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|] |a_{22}
+% \verb| |\dots
+% \verb| [|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|] |a_{m2}
+% \verb|;|
+% $
+%
+% \verb| |.\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .
+%
+% \verb|param| $p_r$\ \verb|default|\ $value$\ \verb|:=|
+%
+% $\verb| |
+% \verb|[|r_{11}\verb|,|r_{12}\verb|,|\dots\verb|,|r_{1n}\verb|] |a_{1r}
+% \verb| [|r_{21}\verb|,|r_{22}\verb|,|\dots\verb|,|r_{2n}\verb|] |a_{2r}
+% \verb| |\dots
+% \verb| [|r_{m1}\verb|,|r_{m2}\verb|,|\dots\verb|,|r_{mn}\verb|] |a_{mr}
+% \verb|;|
+% $
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\appendix
+
+\chapter{Usando sufixos}
+
+\vspace*{-12pt}
+
+Sufixos podem ser usados para recuperar valores adicionais
+associados com as variáveis, restrições e objetivos do modelo.
+
+Um {\it sufixo} consiste de um ponto ({\tt.}) seguido por uma palavra-chave
+não-reservada. Por exemplo, se {\tt x} é uma variável bi-dimensional,
+{\tt x[i,j].lb} é um valor numérico igual ao limite inferior da variável
+elementar {\tt x[i,j]}, que (cujo valor) pode ser usado em expressões
+como um parâmetro numérico.
+
+Para as variáveis do modelo, os sufixos possuem o seguinte significado:
+
+\begin{tabular}{@{}ll@{}}
+{\tt.lb}&limite inferior (lower bound)\\
+{\tt.ub}&limite superior (upper bound)\\
+{\tt.status}&status na solução:\\
+&0 --- indefinida\\
+&1 --- básica\\
+&2 --- não-básica no limite inferior\\
+&3 --- não-básica no limite superior\\
+&4 --- variável não-básica livre (ilimitada)\\
+&5 --- variável não-básica fixa\\
+{\tt.val}&valor primal na solução\\
+{\tt.dual}&valor dual (custo reduzido) na solução\\
+\end{tabular}
+
+Para as restrições e objetivos do modelo, os sufixos têm os seguintes significados:
+
+\begin{tabular}{@{}ll@{}}
+{\tt.lb}&limite inferior (lower bound) da forma linear\\
+{\tt.ub}&limite superior (upper bound) da forma linear\\
+{\tt.status}&status na solução:\\
+&0 --- indefinida\\
+&1 --- não-limitante\\
+&2 --- limitante no limite inferior\\
+&3 --- limitante no limite superior\\
+&4 --- linha limitante livre (ilimitada)\\
+&5 --- restrição de igualdade limitante\\
+{\tt.val}&valor primal da forma linear na solução\\
+{\tt.dual}&valor dual (custo reduzido) da forma linear na solução\\
+\end{tabular}
+
+Note que os sufixos {\tt.status}, {\tt.val} e {\tt.dual} podem ser usados
+apenas abaixo da sentença solve.
+
+
+% Suffixes can be used to retrieve additional values associated with
+% model variables, constraints, and objectives.
+%
+% A {\it suffix} consists of a period ({\tt.}) followed by a non-reserved
+% keyword. For example, if {\tt x} is a two-dimensional variable,
+% {\tt x[i,j].lb} is a numeric value equal to the lower bound of
+% elemental variable {\tt x[i,j]}, which (value) can be used everywhere
+% in expressions like a numeric parameter.
+%
+% For model variables suffixes have the following meaning:
+%
+% \begin{tabular}{@{}ll@{}}
+% {\tt.lb}&lower bound\\
+% {\tt.ub}&upper bound\\
+% {\tt.status}&status in the solution:\\
+% &0 --- undefined\\
+% &1 --- basic\\
+% &2 --- non-basic on lower bound\\
+% &3 --- non-basic on upper bound\\
+% &4 --- non-basic free (unbounded) variable\\
+% &5 --- non-basic fixed variable\\
+% {\tt.val}&primal value in the solution\\
+% {\tt.dual}&dual value (reduced cost) in the solution\\
+% \end{tabular}
+%
+% For model constraints and objectives suffixes have the following
+% meaning:
+%
+% \begin{tabular}{@{}ll@{}}
+% {\tt.lb}&lower bound of the linear form\\
+% {\tt.ub}&upper bound of the linear form\\
+% {\tt.status}&status in the solution:\\
+% &0 --- undefined\\
+% &1 --- non-active\\
+% &2 --- active on lower bound\\
+% &3 --- active on upper bound\\
+% &4 --- active free (unbounded) row\\
+% &5 --- active equality constraint\\
+% {\tt.val}&primal value of the linear form in the solution\\
+% {\tt.dual}&dual value (reduced cost) of the linear form in the
+% solution\\
+% \end{tabular}
+%
+% Note that suffixes {\tt.status}, {\tt.val}, and {\tt.dual} can be used
+% only below the solve statement.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Funções de data e hora}
+
+\noindent\hfil
+\begin{tabular}{c}
+por Andrew Makhorin \verb|<mao@gnu.org>|\\
+e Heinrich Schuchardt \verb|<heinrich.schuchardt@gmx.de>|\\
+\end{tabular}
+
+\section{Obtendo o tempo de calendário corrente}
+\label{gmtime}
+
+Para obter o tempo de calendário corrente em MathProg existe a função
+{\tt gmtime}. Ela não possui argumentos e retorna o número de segundos
+transcorridos desde 00:00:00 de 1{\textsuperscript{\b{o}}}
+de Janeiro de 1970, pelo
+Tempo Universal Coordenado (UTC). Por exemplo:
+
+\begin{verbatim}
+ param utc := gmtime();
+\end{verbatim}
+
+MathProg não possui uma função para converter o tempo UTC retornado pela função
+{\tt gmtime} para os tempos de calendário {\it local}. Assim, para
+determinar o tempo de calendário local corrente, é preciso que adicione ao
+tempo UTC retornado a diferença de horas, com respeito a UTC, expressa em
+segundos. Por exemplo, a hora em Berlim durante o inverno é uma hora à frente
+do UTC, que corresponde a uma diferença horária de +1~hora~= +3600~segundos,
+assim, o tempo de calendário corrente no inverno em Berlim pode ser determinado
+como segue:
+
+\begin{verbatim}
+ param now := gmtime() + 3600;
+\end{verbatim}
+
+\noindent De forma análoga, o horário de verão em Chicago (Zona Horária Central-CDT)
+é cinco horas atrás da UTC, de modo que o horário corrente do calendário local
+pode ser determinado como segue:
+
+\begin{verbatim}
+ param now := gmtime() - 5 * 3600;
+\end{verbatim}
+
+Note que o valor retornado por {\tt gmtime} é volátil, i.e., ao ser
+chamada diversas vezes, esta função pode retornar diferentes valores.
+
+% \noindent\hfil
+% \begin{tabular}{c}
+% by Andrew Makhorin \verb|<mao@gnu.org>|\\
+% and Heinrich Schuchardt \verb|<heinrich.schuchardt@gmx.de>|\\
+% \end{tabular}
+%
+% \section{Obtaining current calendar time}
+% \label{gmtime}
+%
+% To obtain the current calendar time in MathProg there exists the
+% function {\tt 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:
+%
+% \begin{verbatim}
+% param utc := gmtime();
+% \end{verbatim}
+%
+% MathProg has no function to convert UTC time returned by the function
+% {\tt gmtime} to {\it 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:
+%
+% \begin{verbatim}
+% param now := gmtime() + 3600;
+% \end{verbatim}
+%
+% \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:
+%
+% \begin{verbatim}
+% param now := gmtime() - 5 * 3600;
+% \end{verbatim}
+%
+% Note that the value returned by {\tt gmtime} is volatile, i.e. being
+% called several times this function may return different values.
+
+\section{Convertendo cadeia de caracteres ao tempo de calendário}
+\label{str2time}
+
+A função {\tt str2time(}{\it s}{\tt,} {\it f}{\tt)} converte uma
+cadeia de caractere (impressão da data e hora) \linebreak especificada pelo seu
+primeiro argumento {\it s}, que deve ser uma expressão simbólica,
+para o tempo de calendário apropriado para cálculos aritméticos.
+A conversão é controlada pela cadeia de formato especificado {\it f}
+(o segundo argumento), que também deve ser uma expressão simbólica.
+
+
+% The function {\tt str2time(}{\it s}{\tt,} {\it f}{\tt)} converts a
+% character string (timestamp) specified by its first argument {\it s},
+% which should be a symbolic expression, to the calendar time suitable
+% for arithmetic calculations. The conversion is controlled by the
+% specified format string {\it f} (the second argument), which also
+% should be a symbolic expression.
+
+% \newpage
+
+
+A conversão resultante retornada por {\tt str2time} possui o mesmo significado
+dos valores retornados pela função {\tt gmtime} (ver Subseção
+\ref{gmtime}, página \pageref{gmtime}). Note que {\tt str2time}
+{\tt não corrige} o tempo de calendário retornado para zona horária local,
+i.e., ao se aplicar a 00:00:00 de 1{\textsuperscript{\b{o}}}
+de Janeiro de 1970, ela sempre retorna 0.
+
+% The result of conversion returned by {\tt str2time} has the same
+% meaning as values returned by the function {\tt gmtime} (see Subsection
+% \ref{gmtime}, page \pageref{gmtime}). Note that {\tt str2time} does
+% {\tt 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.
+
+Por exemplo, as sentenças de modelo:
+
+\begin{verbatim}
+ param s, symbolic, := "07/14/98 13:47";
+ param t := str2time(s, "%m/%d/%y %H:%M");
+ display t;
+\end{verbatim}
+
+\noindent produz a seguinte saída:
+
+\begin{verbatim}
+ t = 900424020
+\end{verbatim}
+
+\noindent onde o tempo de calendário impresso corresponde a 13:47:00 em
+14 de Julho de 1998.
+
+A cadeia de formato passada à função {\tt str2time} consiste de
+especificadores de conversão e caracteres ordinários. Cada especificador de
+conversão inicia com um caractere de porcentagem ({\tt\%}) seguido de
+uma letra.
+
+Os seguintes especificadores de conversão podem ser usados na cadeia de formato:
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%b}&O nome do mês abreviado (insensível a maiúsculas). Pelo menos as três
+primeiras letras do mês devem aparecer na cadeia de entrada.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%d}&O dia do mês como número decimal (de 1 até 31).
+Se permite o zero como primeiro dígito, embora não seja necessário.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%h}&O mesmo que {\tt\%b}.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%H}&A hora como um número decimal, usando um relógio de 24-horas (de 0
+a 23). Se permite o zero como primeiro dígito, embora não seja necessário.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%m}&O mês como um número decimal (de 1 a 12).
+Se permite o zero como primeiro dígito, embora não seja necessário.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%M}&O minuto como um número decimal (de 0 a 59).
+Se permite o zero como primeiro dígito, embora não seja necessário.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%S}&O segundo como um número decimal (de 0 to 60).
+Se permite o zero como primeiro dígito, embora não seja necessário.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%y}&O ano sem o século, como um número decimal (de 0 to 99).
+Se permite o zero como primeiro dígito, embora não seja necessário.
+Valores de entrada de 0 a 68 são considerados dos anos 2000 a 2068
+enquanto que os valores 69 até 99 como dos anos 1969 to 1999.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%z}&A diferença horária do GMT no formato ISO 8601.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%\%}&Um caractere {\tt\%} literal.\\
+\end{tabular}
+
+Todos os outros caracteres (ordinários) na cadeia de formato devem ter um
+caractere \linebreak correspondente com a cadeia de entrada a ser convertida. Exceções
+são espaços na cadeia de entrada, a qual pode coincidir com zero ou mais
+caracteres de espaço na cadeia de formato.
+
+% For example, the model statements:
+%
+% \begin{verbatim}
+% param s, symbolic, := "07/14/98 13:47";
+% param t := str2time(s, "%m/%d/%y %H:%M");
+% display t;
+% \end{verbatim}
+%
+% \noindent produce the following printout:
+%
+% \begin{verbatim}
+% t = 900424020
+% \end{verbatim}
+%
+% \noindent where the calendar time printed corresponds to 13:47:00 on
+% July 14, 1998.
+%
+% The format string passed to the function {\tt str2time} consists of
+% conversion specifiers and ordinary characters. Each conversion
+% specifier begins with a percent ({\tt\%}) character followed by a
+% letter.
+%
+% The following conversion specifiers may be used in the format string:
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%b}&The abbreviated month name (case insensitive). At least three
+% first letters of the month name should appear in the input string.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%d}&The day of the month as a decimal number (range 1 to 31).
+% Leading zero is permitted, but not required.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%h}&The same as {\tt\%b}.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%H}&The hour as a decimal number, using a 24-hour clock (range 0
+% to 23). Leading zero is permitted, but not required.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%m}&The month as a decimal number (range 1 to 12). Leading zero is
+% permitted, but not required.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%M}&The minute as a decimal number (range 0 to 59). Leading zero
+% is permitted, but not required.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%S}&The second as a decimal number (range 0 to 60). Leading zero
+% is permitted, but not required.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%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.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%z}&The offset from GMT in ISO 8601 format.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%\%}&A literal {\tt\%} character.\\
+% \end{tabular}
+%
+% All other (ordinary) characters in the format string should 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.
+
+% \newpage
+
+Se algum componente de data e/ou hora estão ausentes no formato e,
+portanto, na cadeia de entrada, a função {\tt str2time} usa seus valores
+padrão correspondendo a 00:00:00 de 1{\textsuperscript{\b{o}}}
+de Janeiro de 1970, ou seja, o valor padrão para o ano é 1970, o valor
+padrão para o mês é Janeiro, etc.
+
+A função {\tt str2time} é aplicável a todos horários calendário desde
+00:00:00 de 1{\textsuperscript{\b{o}}} de Janeiro de 0001 até 23:59:59
+de 31 de Dezembro de 4000 do calendário Gregoriano.
+
+% If some date and/or time component(s) are missing in the format and,
+% therefore, in the input string, the function {\tt 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 {\tt 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.
+
+
+
+\section{Convertendo tempo de calendário a uma cadeia de caracteres}
+\label{time2str}
+
+A função {\tt time2str(}{\it t}{\tt,} {\it f}{\tt)} converte o tempo
+de calendário especificado pelo seu primeiro \linebreak argumento {\it t}, que
+deve ser uma expressão numérica, para uma cadeia de caracteres
+(valor \linebreak simbólico). A conversão é controlada pela cadeia de formato
+{\it f} (o segundo argumento), que deve ser uma expressão numérica.
+
+O tempo de calendário passado para {\tt time2str} possui o mesmo
+significado dos valores retornados pela função {\tt gmtime} (ver Subseção
+\ref{gmtime}, página \pageref{gmtime}). Note que {\tt time2str}
+{\it não corrige} o tempo de calendário especificado para zona horária local,
+i.e., o tempo de calendário 0 sempre corresponde a 00:00:00 de
+1{\textsuperscript{\b{o}}} de Janeiro de 1970.
+
+Por exemplo, as sentenças de modelo:
+
+\begin{verbatim}
+ param s, symbolic, := time2str(gmtime(), "%FT%TZ");
+ display s;
+\end{verbatim}
+
+\noindent pode produzir a seguinte impressão:
+
+\begin{verbatim}
+ s = '2008-12-04T00:23:45Z'
+\end{verbatim}
+
+\noindent que é a impressão da data e hora no formato ISO.
+
+A cadeia de formato passada para a função {\tt time2str} consiste de
+especificadores de conversão e caracteres ordinários. Cada especificador
+de conversão começa com um caractere de porcentagem ({\tt\%}) seguido
+de uma letra.
+
+Os seguintes especificadores de conversão podem ser usados na cadeia de formato:
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%a}&O nome do dia da semana abreviado(2 caracteres).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%A}&O nome do dia da semana completo.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%b}&O nome do dia do mês abreviado (3 caracteres).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%B}&O nome do mês completo.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%C}&O século do ano, ou seja, o maior inteiro não maior que o
+ano dividido por~100.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%d}&O dia do mês como um número decimal (de 01 até 31).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%D}&A data usando o formato \verb|%m/%d/%y|.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%e}&O dia do mês, como em \verb|%d|, mas preenchido com espaço
+em branco ao invés de zero.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%F}&A data usando o formato \verb|%Y-%m-%d|.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%g}&O ano correspondente ao número de semana ISO, mas sem o século
+(de 00 até~99). Este possui o mesmo formato e valor que \verb|%y|,
+exceto que se o número de semana ISO (ver \verb|%V|) pertence
+ao ano anterior ou seguinte, se usa aquele ano em seu lugar.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%G}&O ano correspondente ao número de semana ISO.
+Este possui o mesmo formato e valor que \verb|%Y|,
+exceto que se o número de semana ISO (ver \verb|%V|) pertence
+ao ano anterior ou seguinte, se usa aquele ano em seu lugar.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%h}&O mesmo que \verb|%b|.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%H}&A hora como um número decimal usando um relógio 24 horas (de 00 até 23).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%I}&A hora como um número decimal usando um relógio 12 horas (de 01 até 12).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%j}&O dia do ano como um número decimal (de 001 até 366).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%k}&A hora como um número decimal usando um relógio 24 horas, como
+\verb|%H|, mas preenchido com espaço em branco ao invés de zero.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%l}&A hora como um número decimal usando um relógio 12 horas, como
+\verb|%I|, mas preenchido com espaço em branco ao invés de zero.
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%m}&O mês como um número decimal (de 01 até 12).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%M}&O minuto como um número decimal (de 00 até 59).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%p}&Tanto {\tt AM} como {\tt PM}, de acordo com o valor da hora fornecido.
+Meia-noite é tratada como {\tt AM} e meio-dia, como {\tt PM}.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%P}&Tanto {\tt am} como {\tt pm}, de acordo com o valor da hora fornecido.
+Meia-noite é tratada como {\tt am} e meio-dia, como {\tt pm}.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%R}&A hora e minuto em números decimais usando o formato
+\verb|%H:%M|.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%S}&O segundo como um número decimal (de 00 até 59).\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%T}&A hora do dia em números decimais usando o formato
+\verb|%H:%M:%S|.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%u}&O dia da semana como número decimal (de 1 até 7) em que Segunda
+é 1.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%U}&O número da semana do ano corrente como um número decimal (de
+00 até 53) iniciando com o primeiro Domingo como o primeiro dia da
+primeira semana. Os dias que precedem o primeiro Domingo do ano são
+considerados parte da semana 00.
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%V}&O número da semana ISO como um número decimal (de 01 até 53).
+Semanas ISO iniciam com Segunda e finalizam com Domingo.
+A semana 01 de um ano é a primeira semana que possui a maioria de
+seus dias naquele ano. Isto é equivalente à semana contendo 4 de
+Janeiro. A semana 01 de um ano pode conter dias do ano anterior.
+A semana anterior à semana 01 de um ano é a última semana
+(52 ou 53) do ano anterior, mesmo se ela contém dias do novo ano.
+Em outras palavras, se 1{\textsuperscript{\b{o}}} de Janeiro
+é Segunda, Terça, Quarta ou Quinta, ele está na semana 01;
+Se 1{\textsuperscript{\b{o}}} de Janeiro é Sexta,
+Sábado ou Domingo, ele está na semana 52 ou 53 do ano anterior.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%w}&O dia da semana como um número decimal (de 0 até 6) em que Domingo
+é 0.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%W}&O número da semana do ano corrente como um número decimal (de
+00 até 53), iniciando com a primeira Segunda como o primeiro dia da primeira
+semana. Dias que precedem a primeira Segunda do ano são considerados parte
+da semana 00.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%y}&O ano sem o século como um número decimal (de 00 até
+99), ou seja, o ano \verb|mod|~100.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%Y}&O ano como um número decimal, usando o calendário Gregoriano.\\
+\end{tabular}
+
+\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+{\tt\%\%}&Um caractere \verb|%| literal.\\
+\end{tabular}
+
+Todos os outros caracteres (ordinários) na cadeia de formato são simplesmente copiados
+à cadeia resultante.
+
+O primeiro argumento (tempo do calendário) passado para a função {\tt time2str}
+deve estar entre $-62135596800$ até $+64092211199$, o que corresponde ao período
+de 00:00:00 de 1{\textsuperscript{\b{o}}} de Janeiro de 0001 até 23:59:59
+de 31 de Dezembro de 4000 do calendário Gregoriano.
+
+
+% The function {\tt time2str(}{\it t}{\tt,} {\it f}{\tt)} converts the
+% calendar time specified by its first argument {\it t}, which should be
+% a numeric expression, to a character string (symbolic value). The
+% conversion is controlled by the specified format string {\it f} (the
+% second argument), which should be a symbolic expression.
+%
+% The calendar time passed to {\tt time2str} has the same meaning as
+% values returned by the function {\tt gmtime} (see Subsection
+% \ref{gmtime}, page \pageref{gmtime}). Note that {\tt time2str} does
+% {\it 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.
+%
+% For example, the model statements:
+%
+% \begin{verbatim}
+% param s, symbolic, := time2str(gmtime(), "%FT%TZ");
+% display s;
+% \end{verbatim}
+%
+% \noindent may produce the following printout:
+%
+% \begin{verbatim}
+% s = '2008-12-04T00:23:45Z'
+% \end{verbatim}
+%
+% \noindent which is a timestamp in the ISO format.
+%
+% The format string passed to the function {\tt time2str} consists of
+% conversion specifiers and ordinary characters. Each conversion
+% specifier begins with a percent ({\tt\%}) character followed by a
+% letter.
+%
+% The following conversion specifiers may be used in the format string:
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%a}&The abbreviated (2-character) weekday name.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%A}&The full weekday name.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%b}&The abbreviated (3-character) month name.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%B}&The full month name.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%C}&The century of the year, that is the greatest integer not
+% greater than the year divided by~100.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%d}&The day of the month as a decimal number (range 01 to 31).\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%D}&The date using the format \verb|%m/%d/%y|.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%e}&The day of the month like with \verb|%d|, but padded with
+% blank rather than zero.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%F}&The date using the format \verb|%Y-%m-%d|.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%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
+% \verb|%y|, except that if the ISO week number (see \verb|%V|) belongs
+% to the previous or next year, that year is used instead.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%G}&The year corresponding to the ISO week number. This has the
+% same format and value as \verb|%Y|, except that if the ISO week number
+% (see \verb|%V|) belongs to the previous or next year, that year is used
+% instead.
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%h}&The same as \verb|%b|.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%H}&The hour as a decimal number, using a 24-hour clock (range 00
+% to 23).\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%I}&The hour as a decimal number, using a 12-hour clock (range 01
+% to 12).\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%j}&The day of the year as a decimal number (range 001 to 366).\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%k}&The hour as a decimal number, using a 24-hour clock like
+% \verb|%H|, but padded with blank rather than zero.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%l}&The hour as a decimal number, using a 12-hour clock like
+% \verb|%I|, but padded with blank rather than zero.
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%m}&The month as a decimal number (range 01 to 12).\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%M}&The minute as a decimal number (range 00 to 59).\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%p}&Either {\tt AM} or {\tt PM}, according to the given time value.
+% Midnight is treated as {\tt AM} and noon as {\tt PM}.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%P}&Either {\tt am} or {\tt pm}, according to the given time value.
+% Midnight is treated as {\tt am} and noon as {\tt pm}.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%R}&The hour and minute in decimal numbers using the format
+% \verb|%H:%M|.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%S}&The second as a decimal number (range 00 to 59).\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%T}&The time of day in decimal numbers using the format
+% \verb|%H:%M:%S|.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%u}&The day of the week as a decimal number (range 1 to 7), Monday
+% being 1.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%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.
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%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.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%w}&The day of the week as a decimal number (range 0 to 6), Sunday
+% being 0.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%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.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%y}&The year without a century as a decimal number (range 00 to
+% 99), that is the year modulo~100.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%Y}&The year as a decimal number, using the Gregorian calendar.\\
+% \end{tabular}
+%
+% \begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
+% {\tt\%\%}&A literal \verb|%| character.\\
+% \end{tabular}
+%
+% All other (ordinary) characters in the format string are simply copied
+% to the resultant string.
+%
+% The first argument (calendar time) passed to the function {\tt time2str}
+% should 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.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\chapter{Controladores de tabelas}
+\label{drivers}
+
+\noindent\hfil
+\begin{tabular}{c}
+por Andrew Makhorin \verb|<mao@gnu.org>|\\
+e Heinrich Schuchardt \verb|<heinrich.schuchardt@gmx.de>|\\
+\end{tabular}
+
+\bigskip\bigskip
+
+O {\it controlador de tabelas} é um módulo do programa que permite transmitir
+dados entre objetos de um modelo MathProg e tabela de dados.
+
+Atualmente, o pacote GLPK possui quatro controladores de tabelas:
+
+\vspace*{-8pt}
+
+\begin{itemize}
+\item controlador interno de tabelas CSV;
+\item controlador interno de tabelas xBASE;
+\item controlador de tabelas ODBC;
+\item controlador de tabelas MySQL.
+\end{itemize}
+
+
+% The {\it table driver} is a program module which provides transmitting
+% data between MathProg model objects and data tables.
+%
+% Currently the GLPK package has four table drivers:
+%
+% \vspace*{-8pt}
+%
+% \begin{itemize}
+% \item built-in CSV table driver;
+% \item built-in xBASE table driver;
+% \item ODBC table driver;
+% \item MySQL table driver.
+% \end{itemize}
+
+\vspace*{-8pt}
+
+\section{Controlador de tabelas CSV}
+
+O controlador de tabelas CSV assume que a tabela de dados está representada
+na forma de \linebreak arquivo de texto plano, em formato de arquivo CSV
+(valores serparados por vígula: \linebreak comma-separated values) como descrito
+abaixo.
+
+Para escolher o controlador de tabelas CSV, seu nome na sentença table deve ser
+especificado como \verb|"CSV"| e o único argumento deve especificar o nome do
+arquivo de texto plano contendo a tabela. Por exemplo:
+
+\begin{verbatim}
+ table dados IN "CSV" "dados.csv": ... ;
+\end{verbatim}
+
+O sufixo do nome do arquivo pode ser arbitrário, no entanto,
+é recomendado usar o sufixo `\verb|.csv|'.
+
+Ao ler tabelas de entrada o controlador de tabelas CSV fornece um campo
+implícito chamado \verb|RECNO|, que contém o número do registro corrente.
+Este campo pode ser especificado na sentença de entrada table, como
+se realmente houvesse um campo chamado \verb|RECNO| no arquivo CSV. Por exemplo:
+
+\begin{verbatim}
+ table lista IN "CSV" "lista.csv": num <- [RECNO], ... ;
+\end{verbatim}
+
+
+% The CSV table driver assumes that the data table is represented in the
+% form of a plain text file in the CSV (comma-separated values) file
+% format as described below.
+%
+% To choose the CSV table driver its name in the table statement should
+% be specified as \verb|"CSV"|, and the only argument should specify the
+% name of a plain text file containing the table. For example:
+%
+% \begin{verbatim}
+% table data IN "CSV" "data.csv": ... ;
+% \end{verbatim}
+%
+% The filename suffix may be arbitrary, however, it is recommended to use
+% the suffix `\verb|.csv|'.
+%
+% On reading input tables the CSV table driver provides an implicit field
+% named \verb|RECNO|, which contains the current record number. This
+% field can be specified in the input table statement as if there were
+% the actual field named \verb|RECNO| in the CSV file. For example:
+%
+% \begin{verbatim}
+% table list IN "CSV" "list.csv": num <- [RECNO], ... ;
+% \end{verbatim}
+
+\newpage
+
+\subsection*{Formato CSV\footnote{Este material é baseado no documento RFC
+4180.}}
+
+O formato CSV (\textit{comma-separated values}) é um formato de arquivo de texto plano
+definido como segue.
+
+1. Cada registro é localizado em uma linha separada, delimitada por uma quebra de linha. Por exemplo:
+
+\begin{verbatim}
+ aaa,bbb,ccc\n
+ xxx,yyy,zzz\n
+\end{verbatim}
+
+\noindent
+onde \verb|\n| significa o caractere de controle \verb|LF| ({\tt 0x0A}).
+
+2. O último registro no arquivo pode ou não ter a quebra de linha. Por exemplo:
+
+\begin{verbatim}
+ aaa,bbb,ccc\n
+ xxx,yyy,zzz
+\end{verbatim}
+
+3. Deve haver uma linha de cabeçalho na primeira linha do arquivo no
+mesmo formato das linhas de registros normais. Este cabeçalho deve
+conter nomes correspondendo aos campos no arquivo. O número de nomes
+de campos na linha de cabeçalho deve ser o mesmo do número de campos
+dos registros do arquivo. Por exemplo:
+
+\begin{verbatim}
+ nome1,nome2,nome3\n
+ aaa,bbb,ccc\n
+ xxx,yyy,zzz\n
+\end{verbatim}
+
+4. Dentro do cabeçalho e de cada registro, podem haver um ou mais campos
+separados por vírgulas. Cada linha deve conter o mesmo número de campos
+por todos arquivo. Espaços são considerados parte de um campo, portanto,
+não são ignorados. O último campo do registro não deve ser seguido de
+vírgula. Por exemplo:
+
+\begin{verbatim}
+ aaa,bbb,ccc\n
+\end{verbatim}
+
+5. Campos podem ou não estar cercados em aspas duplas. Por exemplo:
+
+\begin{verbatim}
+ "aaa","bbb","ccc"\n
+ zzz,yyy,xxx\n
+\end{verbatim}
+
+6. Se um campo é cercado de aspas duplas, cada aspa dupla que faça
+parte do campo deve ser codificado duas vezes. Por exemplo:
+
+\begin{verbatim}
+ "aaa","b""bb","ccc"\n
+\end{verbatim}
+
+\para{Exemplo}
+
+\begin{verbatim}
+DE,PARA,DISTANCIA,CUSTO
+Seattle,New-York,2.5,0.12
+Seattle,Chicago,1.7,0.08
+Seattle,Topeka,1.8,0.09
+San-Diego,New-York,2.5,0.15
+San-Diego,Chicago,1.8,0.10
+San-Diego,Topeka,1.4,0.07
+\end{verbatim}
+
+
+
+% The CSV (comma-separated values) format is a plain text file format
+% defined as follows.
+%
+% 1. Each record is located on a separate line, delimited by a line
+% break. For example:
+%
+% \begin{verbatim}
+% aaa,bbb,ccc\n
+% xxx,yyy,zzz\n
+% \end{verbatim}
+%
+% \noindent
+% where \verb|\n| means the control character \verb|LF| ({\tt 0x0A}).
+%
+% 2. The last record in the file may or may not have an ending line
+% break. For example:
+%
+% \begin{verbatim}
+% aaa,bbb,ccc\n
+% xxx,yyy,zzz
+% \end{verbatim}
+%
+% 3. There should be a header line appearing as the first line of the
+% file in the same format as normal record lines. This header should
+% contain names corresponding to the fields in the file. The number of
+% field names in the header line should be the same as the number of
+% fields in the records of the file. For example:
+%
+% \begin{verbatim}
+% name1,name2,name3\n
+% aaa,bbb,ccc\n
+% xxx,yyy,zzz\n
+% \end{verbatim}
+%
+% 4. Within the header and each record there may be one or more fields
+% separated by commas. Each line should contain the same number of fields
+% throughout the file. Spaces are considered as part of a field and
+% therefore not ignored. The last field in the record should not be
+% followed by a comma. For example:
+%
+% \begin{verbatim}
+% aaa,bbb,ccc\n
+% \end{verbatim}
+%
+% 5. Fields may or may not be enclosed in double quotes. For example:
+%
+% \begin{verbatim}
+% "aaa","bbb","ccc"\n
+% zzz,yyy,xxx\n
+% \end{verbatim}
+%
+% 6. If a field is enclosed in double quotes, each double quote which is
+% part of the field should be coded twice. For example:
+%
+% \begin{verbatim}
+% "aaa","b""bb","ccc"\n
+% \end{verbatim}
+%
+% \para{Example}
+%
+% \begin{verbatim}
+% FROM,TO,DISTANCE,COST
+% Seattle,New-York,2.5,0.12
+% Seattle,Chicago,1.7,0.08
+% Seattle,Topeka,1.8,0.09
+% San-Diego,New-York,2.5,0.15
+% San-Diego,Chicago,1.8,0.10
+% San-Diego,Topeka,1.4,0.07
+% \end{verbatim}
+
+\newpage
+
+\section{Controlador de tabelas xBASE}
+
+O controlador de tabelas xBASE assume que a tabela de dados é armazenada no
+formato de arquivo .dbf.
+
+Para escolher o controlador de tabela xBASE, seu nome na sentença table deve ser
+especificado como \verb|"xBASE"| e o primeiro argumento deve especificar o nome
+de um arquivo .dbf contendo a tabela. Para a tabela de saída deve haver um
+segundo argumento definindo o formato da tabela na forma
+\verb|"FF...F"|, onde \verb|F| é tanto {\tt C({\it n})},
+que especifica um campo de caractere de tamanho $n$, ou
+{\tt N({\it n}{\rm [},{\it p}{\rm ]})}, que especifica um campo numérico
+de tamanho $n$ e precisão $p$ (por padrão $p$ é 0).
+
+Adiante está um simples exemplo que ilustra a criação e leitura de um arquivo .dbf:
+
+\begin{verbatim}
+table tab1{i in 1..10} OUT "xBASE" "foo.dbf"
+ "N(5)N(10,4)C(1)C(10)": 2*i+1 ~ B, Uniform(-20,+20) ~ A,
+ "?" ~ FOO, "[" & i & "]" ~ C;
+set S, dimen 4;
+table tab2 IN "xBASE" "foo.dbf": S <- [B, C, RECNO, A];
+display S;
+end;
+\end{verbatim}
+
+
+% The xBASE table driver assumes that the data table is stored in the
+% .dbf file format.
+%
+% To choose the xBASE table driver its name in the table statement should
+% be specified as \verb|"xBASE"|, and the first argument should specify
+% the name of a .dbf file containing the table. For the output table there
+% should be the second argument defining the table format in the form
+% \verb|"FF...F"|, where \verb|F| is either {\tt C({\it n})},
+% which specifies a character field of length $n$, or
+% {\tt N({\it n}{\rm [},{\it p}{\rm ]})}, which specifies a numeric field
+% of length $n$ and precision $p$ (by default $p$ is 0).
+%
+% The following is a simple example which illustrates creating and
+% reading a .dbf file:
+%
+% \begin{verbatim}
+% table tab1{i in 1..10} OUT "xBASE" "foo.dbf"
+% "N(5)N(10,4)C(1)C(10)": 2*i+1 ~ B, Uniform(-20,+20) ~ A,
+% "?" ~ FOO, "[" & i & "]" ~ C;
+% set S, dimen 4;
+% table tab2 IN "xBASE" "foo.dbf": S <- [B, C, RECNO, A];
+% display S;
+% end;
+% \end{verbatim}
+
+\section{Controlador de tabelas ODBC}
+
+O controlador de tabelas ODBC permite conexões com bancos de dados SQL usando
+uma \linebreak implementação da interface ODBC baseada na Call Level Interface
+(CLI).\footnote{A norma software correspondente é definida na
+ISO/IEC 9075-3:2003.}
+
+\para{Debian GNU/Linux.}
+No Debian GNU/Linux o controlador de tabelas ODBC usa o pacote iODBC,
+\footnote{Ver {\tt<http://www.iodbc.org/>}.} que deve ser instalado antes
+de montar o pacote GLPK. A instalação pode ser efetuada com o seguinte
+comando:
+
+\begin{verbatim}
+ sudo apt-get install libiodbc2-dev
+\end{verbatim}
+
+Note que, ao configurar o pacote GLPK, para habilitar o uso da biblioteca do iODBC
+a opção `\verb|--enable-odbc|' deve ser passada para o script de configuração.
+
+Para seu uso em todo sistema, as bases de dados individuais devem ser inseridas em
+\verb|/etc/odbc.ini| e \verb|/etc/odbcinst.ini|. As conexões das bases de dados
+a serem usadas por um único usuário são especificadas por arquivos do diretório
+home (\verb|.odbc.ini| e \verb|.odbcinst.ini|).
+
+\para{Microsoft Windows.}
+No Microsoft Windows o controlador de tabelas ODBC usa a biblioteca Microsoft ODBC.
+Para habilitar esta funcionalidade, o símbolo:
+
+\begin{verbatim}
+ #define ODBC_DLNAME "odbc32.dll"
+\end{verbatim}
+
+\noindent
+deve ser definido no arquivo de configuração do GLPK `\verb|config.h|'.
+
+Fontes de dados podem ser criados via Ferramentas Administrativas do
+Painel de Controle.
+
+Para escolher do controlador de tabelas ODBC, seu nome na sentença table deve
+ser especificado como \verb|'ODBC'| ou \verb|'iODBC'|.
+
+% \newpage
+
+A lista de argumentos é especificada como segue.
+
+O primeiro argumento é a cadeia de conexão passada para a biblioteca ODBC,
+por exemplo:
+
+\verb|'DSN=glpk;UID=user;PWD=password'|, ou
+
+\verb|'DRIVER=MySQL;DATABASE=glpkdb;UID=user;PWD=password'|.
+
+Diferentes partes da cadeia são separadas por ponto e vírgula. Cada parte
+consiste de um par {\it nome-do-campo} e {\it valor} separados pelo sinar
+de igualdade. Os nomes de campo permitidos dependem da biblioteca ODBC.
+Tipicamente os seguintes nomes-de-campo são permitidos:
+
+\verb|DATABASE | base de dados;
+
+\verb|DRIVER | controlador ODBC;
+
+\verb|DSN | nome de uma fonte de dados;
+
+\verb|FILEDSN | nome de um arquivo de fonte de dados;
+
+\verb|PWD | senha de usuário;
+
+\verb|SERVER | base de dados;
+
+\verb|UID | nome de usuário.
+
+O segundo argumento e todos os seguintes são considerados como
+sentenças SQL.
+
+As sentenças SQL podem ser estendidas sobre múltiplos argumentos. Se o
+último caractere de um argumento é um ponto e vírgula, este indica
+o fim de uma sentença SQL.
+
+Os argumentos de uma sentença SQL são concatenados separados por espaço.
+O eventual ponto e vírgula final será removido.
+
+Todas as sentenças SQL, exceto a última, serão executadas diretamente.
+
+Para tabela-IN, a última sentença SQL pode ser um comando SELECT que se inicia
+com \verb|'SELECT '| em letras maiúsculas. Se a cadeia não se inicia com
+\verb|'SELECT '|, se considera que é um nome de uma tabela e uma sentença
+SELECT é automaticamente gerada.
+
+
+Para tabela-OUT, a última sentença SQL pode conter um ou múltiplos pontos de
+interrogação. Se contém um ponto de interrogação, é considerado um gabarito
+para a rotina de escrita. Caso contrário, a cadeia é considerada um
+nome de tabela e um gabarito INSERT é automaticamente gerado.
+
+A rotina de escrita usa um gabarito com o pontos de interrogação e
+o substitui o primeiro ponto de interrogação pelo primeiro parâmetro
+de saída, o segundo ponto de interrogação, pelo segundo parâmetro e
+assim por diante. Em seguida, o comando SQL é emitido.
+
+O que segue é um exemplo da sentença table de saída:
+
+\begin{verbatim}
+table ta { l in LOCAIS } OUT
+ 'ODBC'
+ 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'DROP TABLE IF EXISTS resultado;'
+ 'CREATE TABLE resultado ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );'
+ 'INSERT INTO resultado 'VALUES ( 4, ?, ? )' :
+ l ~ LOC, quantidade[l] ~ QUAN;
+\end{verbatim}
+
+% \newpage
+
+\noindent
+Alternativamente pode se escrever como segue:
+
+\begin{verbatim}
+table ta { l in LOCAIS } OUT
+ 'ODBC'
+ 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'DROP TABLE IF EXISTS resultado;'
+ 'CREATE TABLE resultado ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );'
+ 'resultado' :
+ l ~ LOC, quantidade[l] ~ QUAN, 4 ~ ID;
+\end{verbatim}
+
+O uso de gabaritos com `\verb|?|' não só permite INSERT, como também o
+UPDATE, DELETE, etc. Por exemplo:
+
+\begin{verbatim}
+table ta { l in LOCAIS } OUT
+ 'ODBC'
+ 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'UPDATE resultado SET DATA = ' & data & ' WHERE ID = 4;'
+ 'UPDATE resultado SET QUAN = ? WHERE LOC = ? AND ID = 4' :
+ quantidade[l], l;
+\end{verbatim}
+
+
+
+% The ODBC table driver allows connecting to SQL databases using an
+% implementation of the ODBC interface based on the Call Level Interface
+% (CLI).\footnote{The corresponding software standard is defined in
+% ISO/IEC 9075-3:2003.}
+%
+% \para{Debian GNU/Linux.}
+% Under Debian GNU/Linux the ODBC table driver uses the iODBC
+% package,\footnote{See {\tt<http://www.iodbc.org/>}.} which should be
+% installed before building the GLPK package. The installation can be
+% effected with the following command:
+%
+% \begin{verbatim}
+% sudo apt-get install libiodbc2-dev
+% \end{verbatim}
+%
+% Note that on configuring the GLPK package to enable using the iODBC
+% library the option `\verb|--enable-odbc|' should be passed to the
+% configure script.
+%
+% The individual databases should be entered for systemwide usage in
+% \verb|/etc/odbc.ini| and\linebreak \verb|/etc/odbcinst.ini|. Database
+% connections to be used by a single user are specified by files in the
+% home directory (\verb|.odbc.ini| and \verb|.odbcinst.ini|).
+%
+% \para{Microsoft Windows.}
+% Under Microsoft Windows the ODBC table driver uses the Microsoft ODBC
+% library. To enable this feature the symbol:
+%
+% \begin{verbatim}
+% #define ODBC_DLNAME "odbc32.dll"
+% \end{verbatim}
+%
+% \noindent
+% should be defined in the GLPK configuration file `\verb|config.h|'.
+%
+% Data sources can be created via the Administrative Tools from the
+% Control Panel.
+%
+% To choose the ODBC table driver its name in the table statement should
+% be specified as \verb|'ODBC'| or \verb|'iODBC'|.
+%
+% \newpage
+%
+% The argument list is specified as follows.
+%
+% The first argument is the connection string passed to the ODBC library,
+% for example:
+%
+% \verb|'DSN=glpk;UID=user;PWD=password'|, or
+%
+% \verb|'DRIVER=MySQL;DATABASE=glpkdb;UID=user;PWD=password'|.
+%
+% Different parts of the string are separated by semicolons. Each part
+% consists of a pair {\it fieldname} and {\it value} separated by the
+% equal sign. Allowable fieldnames depend on the ODBC library. Typically
+% the following fieldnames are allowed:
+%
+% \verb|DATABASE | database;
+%
+% \verb|DRIVER | ODBC driver;
+%
+% \verb|DSN | name of a data source;
+%
+% \verb|FILEDSN | name of a file data source;
+%
+% \verb|PWD | user password;
+%
+% \verb|SERVER | database;
+%
+% \verb|UID | user name.
+%
+% The second argument and all following are considered to be SQL
+% statements
+%
+% SQL statements may be spread over multiple arguments. If the last
+% character of an argument is a semicolon this indicates the end of
+% a SQL statement.
+%
+% The arguments of a SQL statement are concatenated separated by space.
+% The eventual trailing semicolon will be removed.
+%
+% All but the last SQL statement will be executed directly.
+%
+% For IN-table the last SQL statement can be a SELECT command starting
+% with the capitalized letters \verb|'SELECT '|. If the string does not
+% start with \verb|'SELECT '| it is considered to be a table name and a
+% SELECT statement is automatically generated.
+%
+% For OUT-table the last SQL statement can contain one or multiple
+% question marks. If it contains a question mark it is considered a
+% template for the write routine. Otherwise the string is considered a
+% table name and an INSERT template is automatically generated.
+%
+% The writing routine uses the template with the question marks and
+% replaces the first question mark by the first output parameter, the
+% second question mark by the second output parameter and so forth. Then
+% the SQL command is issued.
+%
+% The following is an example of the output table statement:
+%
+% \begin{verbatim}
+% table ta { l in LOCATIONS } OUT
+% 'ODBC'
+% 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword'
+% 'DROP TABLE IF EXISTS result;'
+% 'CREATE TABLE result ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );'
+% 'INSERT INTO result 'VALUES ( 4, ?, ? )' :
+% l ~ LOC, quantity[l] ~ QUAN;
+% \end{verbatim}
+%
+% \newpage
+%
+% \noindent
+% Alternatively it could be written as follows:
+%
+% \begin{verbatim}
+% table ta { l in LOCATIONS } OUT
+% 'ODBC'
+% 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword'
+% 'DROP TABLE IF EXISTS result;'
+% 'CREATE TABLE result ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );'
+% 'result' :
+% l ~ LOC, quantity[l] ~ QUAN, 4 ~ ID;
+% \end{verbatim}
+%
+% Using templates with `\verb|?|' supports not only INSERT, but also
+% UPDATE, DELETE, etc. For example:
+%
+% \begin{verbatim}
+% table ta { l in LOCATIONS } OUT
+% 'ODBC'
+% 'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword'
+% 'UPDATE result SET DATE = ' & date & ' WHERE ID = 4;'
+% 'UPDATE result SET QUAN = ? WHERE LOC = ? AND ID = 4' :
+% quantity[l], l;
+% \end{verbatim}
+
+
+\section{Controlador de tabelas MySQL}
+
+O controlador de tabelas MySQL permite a conexão a base de dados MySQL.
+
+\para{Debian GNU/Linux.}
+No Debian GNU/Linux o controlador de tabelas MySQL usa o pacote MySQL,
+\footnote{Para fazer o download de arquivos de desenvolvimento, ver
+{\tt<http://dev.mysql.com/downloads/mysql/>}.} que deve ser instalado
+antes da criação do pacote GLPK. A instalação pode ser efetuada com
+o seguinte comando:
+
+\begin{verbatim}
+ sudo apt-get install libmysqlclient15-dev
+\end{verbatim}
+
+Note que ao configurar o pacote GLPK para habilitar o uso da biblioteca MySQL
+a opção `\verb|--enable-mysql|' deve ser passada ao script de
+configuração.
+
+\para{Microsoft Windows.}
+No Microsoft Windows o controlador de tabelas MySQL também usa
+a biblioteca MySQL. Para habilitar esta funcionalidade o símbolo:
+
+\begin{verbatim}
+ #define MYSQL_DLNAME "libmysql.dll"
+\end{verbatim}
+
+\noindent
+deve ser definido no arquivo de configuração do GLPK `\verb|config.h|'.
+
+Para escolher o controlador de tabelas MySQL, seu nome na sentença table deve
+ser especificada como \verb|'MySQL'|.
+
+A lista de argumentos é especificada como segue.
+
+O primeiro argumento especifica como conectar a base de dados no estilo DSN,
+por exemplo:
+
+\verb|'Database=glpk;UID=glpk;PWD=gnu'|.
+
+Diferentes partes da cadeia são separadas por ponto e vírgula. Cada parte
+consiste de um par {\it nome-do-campo} e {\it valor} separado pelo sinal
+de igualdade. Os seguintes nomes de campo são permitidos:
+
+% \newpage
+
+\verb|Server | servidor rodando a base de dados (localhost por padrão);
+
+\verb|Database | nome da base de dados;
+
+\verb|UID | nome de usuário;
+
+\verb|PWD | senha de usuário;
+
+\verb|Port | porta usada pelo servidor (3306 por padrão).
+
+O segundo argumento e todos os seguintes são considerados sentenças SQL.
+
+Sentenças SQL podem se estender sobre múltiplos argumentos. Se o último
+caractere de um argumento é um ponto e vírgula, isto indica o fim de uma
+sentença SQL.
+
+Os argumentos de uma sentença SQL são concatenados e separados por espaço.
+O eventual ponto e vírgula final será removido.
+
+Todas sentenças SQL, menos a última, serão executadas diretamente.
+
+Para tabela-IN, a última sentença SQL pode ser um comando SELECT iniciado
+com letras maiúsculas \verb|'SELECT '|. Se a cadeia não inicia com
+\verb|'SELECT '| é considerado um nome de tabela e a sentença
+SELECT é automaticamente gerada.
+
+Para tabela-OUT, a última sentença SQL pode conter um ou múltiplos pontos de
+interrogação. Se contém um ponto de interrogação, é considerado um gabarito
+para a rotina de escrita. Caso contrário, a cadeia é considerada um
+nome de tabela e um gabarito INSERT é automaticamente gerado.
+
+A rotina de escrita usa um gabarito com o pontos de interrogação e
+o substitui o primeiro ponto de interrogação pelo primeiro parâmetro
+de saída, o segundo ponto de interrogação, pelo segundo parâmetro e
+assim por diante. Em seguida, o comando SQL é emitido.
+
+O que segue é um exemplo da sentença table de saída:
+
+\begin{verbatim}
+table ta { l in LOCAIS } OUT
+ 'MySQL'
+ 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'DROP TABLE IF EXISTS resultado;'
+ 'CREATE TABLE resultado ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );'
+ 'INSERT INTO resultado VALUES ( 4, ?, ? )' :
+ l ~ LOC, quantidade[l] ~ QUAN;
+\end{verbatim}
+
+\noindent
+Alternativamente poderia ser escrito como segue:
+
+\begin{verbatim}
+table ta { l in LOCAIS } OUT
+ 'MySQL'
+ 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'DROP TABLE IF EXISTS resultado;'
+ 'CREATE TABLE resultado ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );'
+ 'resultado' :
+ l ~ LOC, quantidade[l] ~ QUAN, 4 ~ ID;
+\end{verbatim}
+
+% \newpage
+
+O uso de gabaritos com `\verb|?|' não só permite INSERT, como também o
+UPDATE, DELETE, etc. Por exemplo:
+
+\begin{verbatim}
+table ta { l in LOCAIS } OUT
+ 'MySQL'
+ 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword'
+ 'UPDATE resultado SET DATE = ' & date & ' WHERE ID = 4;'
+ 'UPDATE resultado SET QUAN = ? WHERE LOC = ? AND ID = 4' :
+ quantidade[l], l;
+\end{verbatim}
+
+
+% The MySQL table driver allows connecting to MySQL databases.
+%
+% \para{Debian GNU/Linux.}
+% Under Debian GNU/Linux the MySQL table driver uses the MySQL
+% package,\footnote{For download development files see
+% {\tt<http://dev.mysql.com/downloads/mysql/>}.} which should be
+% installed before building the GLPK package. The installation can be
+% effected with the following command:
+%
+% \begin{verbatim}
+% sudo apt-get install libmysqlclient15-dev
+% \end{verbatim}
+%
+% Note that on configuring the GLPK package to enable using the MySQL
+% library the option `\verb|--enable-mysql|' should be passed to the
+% configure script.
+%
+% \para{Microsoft Windows.}
+% Under Microsoft Windows the MySQL table driver also uses the MySQL
+% library. To enable this feature the symbol:
+%
+% \begin{verbatim}
+% #define MYSQL_DLNAME "libmysql.dll"
+% \end{verbatim}
+%
+% \noindent
+% should be defined in the GLPK configuration file `\verb|config.h|'.
+%
+% To choose the MySQL table driver its name in the table statement should
+% be specified as \verb|'MySQL'|.
+%
+% The argument list is specified as follows.
+%
+% The first argument specifies how to connect the data base in the DSN
+% style, for example:
+%
+% \verb|'Database=glpk;UID=glpk;PWD=gnu'|.
+%
+% Different parts of the string are separated by semicolons. Each part
+% consists of a pair {\it fieldname} and {\it value} separated by the
+% equal sign. The following fieldnames are allowed:
+%
+% \newpage
+%
+% \verb|Server | server running the database (defaulting to localhost);
+%
+% \verb|Database | name of the database;
+%
+% \verb|UID | user name;
+%
+% \verb|PWD | user password;
+%
+% \verb|Port | port used by the server (defaulting to 3306).
+%
+% The second argument and all following are considered to be SQL
+% statements.
+%
+% SQL statements may be spread over multiple arguments. If the last
+% character of an argument is a semicolon this indicates the end of
+% a SQL statement.
+%
+% The arguments of a SQL statement are concatenated separated by space.
+% The eventual trailing semicolon will be removed.
+%
+% All but the last SQL statement will be executed directly.
+%
+% For IN-table the last SQL statement can be a SELECT command starting
+% with the capitalized letters \verb|'SELECT '|. If the string does not
+% start with \verb|'SELECT '| it is considered to be a table name and a
+% SELECT statement is automatically generated.
+%
+% For OUT-table the last SQL statement can contain one or multiple
+% question marks. If it contains a question mark it is considered a
+% template for the write routine. Otherwise the string is considered a
+% table name and an INSERT template is automatically generated.
+%
+% The writing routine uses the template with the question marks and
+% replaces the first question mark by the first output parameter, the
+% second question mark by the second output parameter and so forth. Then
+% the SQL command is issued.
+%
+% The following is an example of the output table statement:
+%
+% \begin{verbatim}
+% table ta { l in LOCATIONS } OUT
+% 'MySQL'
+% 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword'
+% 'DROP TABLE IF EXISTS result;'
+% 'CREATE TABLE result ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );'
+% 'INSERT INTO result VALUES ( 4, ?, ? )' :
+% l ~ LOC, quantity[l] ~ QUAN;
+% \end{verbatim}
+%
+% \noindent
+% Alternatively it could be written as follows:
+%
+% \begin{verbatim}
+% table ta { l in LOCATIONS } OUT
+% 'MySQL'
+% 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword'
+% 'DROP TABLE IF EXISTS result;'
+% 'CREATE TABLE result ( ID INT, LOC VARCHAR(255), QUAN DOUBLE );'
+% 'result' :
+% l ~ LOC, quantity[l] ~ QUAN, 4 ~ ID;
+% \end{verbatim}
+%
+% \newpage
+%
+% Using templates with `\verb|?|' supports not only INSERT, but also
+% UPDATE, DELETE, etc. For example:
+%
+% \begin{verbatim}
+% table ta { l in LOCATIONS } OUT
+% 'MySQL'
+% 'Database=glpkdb;UID=glpkuser;PWD=glpkpassword'
+% 'UPDATE result SET DATE = ' & date & ' WHERE ID = 4;'
+% 'UPDATE result SET QUAN = ? WHERE LOC = ? AND ID = 4' :
+% quantity[l], l;
+% \end{verbatim}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% ##################### PAREI AQUI % #####################
+
+\chapter{Resolvendo modelos com glpsol}
+
+O pacote GLPK \footnote{{\tt http://www.gnu.org/software/glpk/}}
+inclui o programa {\tt glpsol}, um solver de PL/PIM autônomo. Este
+programa pode ser chamado por uma linha de comando ou pelo shell para
+resolver modelos escritos na \linebreak linguagem de modelagem GNU MathProg.
+
+Para comunicar ao solver que o arquivo de entrada contém uma descrição
+do modelo, é necessário especificar a opção \verb|--model| na linha de
+comando. Por exemplo:
+
+\begin{verbatim}
+ glpsol --model foo.mod
+\end{verbatim}
+
+Às vezes é necessário usar a seção de dados posicionado em um arquivo
+separado. Neste caso, deve-se usar o seguinte comando:
+
+\begin{verbatim}
+ glpsol --model foo.mod --data foo.dat
+\end{verbatim}
+
+\noindent Note que ser o arquivo de modelo também contém a seção de dados,
+aquela seção é ignorada.
+
+Também é permitido especificar mais de um arquivo contendo a seção de dados,
+por exemplo:
+
+\begin{verbatim}
+ glpsol --model foo.mod --data foo1.dat --data foo2.dat
+\end{verbatim}
+
+Se a descrição do modelo contém alguma sentença display e/ou printf,
+o resultado é enviado para o terminal por padrão. Se há a necessidade
+de redirecionar a saída para um arquivo, deve-se usar o seguinte comando:
+
+\begin{verbatim}
+ glpsol --model foo.mod --display foo.out
+\end{verbatim}
+
+Se há a necessidade de ver o problema que está sendo gerado pelo tradutor
+de modelo, deve-ser usar a opção \verb|--wlp| como segue:
+
+\begin{verbatim}
+ glpsol --model foo.mod --wlp foo.lp
+\end{verbatim}
+
+\noindent Neste caso, os dados do problema são escritos no arquivo
+\verb|foo.lp| no formato CPLEX LP viável para análise visual.
+
+Ás vezes, é necessário checar a descrição do modelo sem ter que resolver
+a instância do problema gerado. Neste caso, deve-se especificar a opção
+\verb|--check|, por exemplo:
+
+\begin{verbatim}
+ glpsol --check --model foo.mod --wlp foo.lp
+\end{verbatim}
+
+\newpage
+
+Se há a necessidade de escrever uma solução numérica obtida pelo solver
+para um arquivo, deve-se usar o seguinte comando:
+
+\begin{verbatim}
+ glpsol --model foo.mod --output foo.sol
+\end{verbatim}
+
+\noindent neste caso, a solução é escrita no arquivo \verb|foo.sol|
+em formato de texto plano, viável para análise visual.
+
+A lista completa de opções do \verb|glpsol| pode ser encontrada no manual
+de referência do GLPK incluída na distribuição do GLPK.
+
+
+
+% The GLPK package\footnote{{\tt http://www.gnu.org/software/glpk/}}
+% includes the program {\tt glpsol}, 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.
+%
+% To tell the solver that the input file contains a model description you
+% need to specify the option \verb|--model| in the command line.
+% For example:
+%
+% \begin{verbatim}
+% glpsol --model foo.mod
+% \end{verbatim}
+%
+% Sometimes it is necessary to use the data section placed in a separate
+% file, in which case you may use the following command:
+%
+% \begin{verbatim}
+% glpsol --model foo.mod --data foo.dat
+% \end{verbatim}
+%
+% \noindent Note that if the model file also contains the data section,
+% that section is ignored.
+%
+% It is also allowed to specify more than one file containing the data
+% section, for example:
+%
+% \begin{verbatim}
+% glpsol --model foo.mod --data foo1.dat --data foo2.dat
+% \end{verbatim}
+%
+% If the model description contains some display and/or printf
+% statements, by default the output is sent to the terminal. If you need
+% to redirect the output to a file, you may use the following command:
+%
+% \begin{verbatim}
+% glpsol --model foo.mod --display foo.out
+% \end{verbatim}
+%
+% If you need to look at the problem, which has been generated by the
+% model translator, you may use the option \verb|--wlp| as follows:
+%
+% \begin{verbatim}
+% glpsol --model foo.mod --wlp foo.lp
+% \end{verbatim}
+%
+% \noindent In this 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 instance. In this case you may specify
+% the option \verb|--check|, for example:
+%
+% \begin{verbatim}
+% glpsol --check --model foo.mod --wlp foo.lp
+% \end{verbatim}
+%
+% \newpage
+%
+% If you need to write a numeric solution obtained by the solver to
+% a file, you may use the following command:
+%
+% \begin{verbatim}
+% glpsol --model foo.mod --output foo.sol
+% \end{verbatim}
+%
+% \noindent in which case the solution is written to file \verb|foo.sol|
+% in a plain text format suitable for visual analysis.
+%
+% The complete list of the \verb|glpsol| options can be found in the
+% GLPK reference manual included in the GLPK distribution.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Exemplo de descrição de modelo}
+
+\section{Descrição de modelo escrito em MathProg}
+
+Este é um exemplo completo de descrição de modelo escrito na linguagem
+de modelagem GNU MathProg.
+
+\bigskip
+
+\begin{verbatim}
+# UM PROBLEMA DE TRANSPORTE
+#
+# Este problema encontra a logística de custo mínimo que atende das demandas
+# de mercado e as ofertas das fábricas.
+#
+# Referência:
+# Dantzig G B, "Linear Programming and Extensions."
+# Princeton University Press, Princeton, New Jersey, 1963,
+# Chapter 3-3.
+
+set I;
+/* fábricas de enlatados*/
+
+set J;
+/* mercados */
+
+param a{i in I};
+/* capacidade da fábrica i, em caixas */
+
+param b{j in J};
+/* demanda no mercado j, em caixas */
+
+param d{i in I, j in J};
+/* distância, em milhares de milhas */
+
+param f;
+/* frete, em dólares por caixa a cada mil milhas */
+
+param c{i in I, j in J} := f * d[i,j] / 1000;
+/* custo de transporte, em milhares de dólares por caixa */
+
+var x{i in I, j in J} >= 0;
+/* quantidade enviada, em caixas */
+
+minimize custo: sum{i in I, j in J} c[i,j] * x[i,j];
+/* custo total de transporte, em milhares de dólares */
+
+s.t. suprimento{i in I}: sum{j in J} x[i,j] <= a[i];
+/* observa o limite de suprimento na fábrica i */
+
+s.t. demanda{j in J}: sum{i in I} x[i,j] >= b[j];
+/* satisfaz a demanda do mercado 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}
+
+
+% Below here is a complete example of the model description written in
+% the GNU MathProg modeling language.
+%
+% \bigskip
+%
+% \begin{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}
+
+\newpage
+
+\section{Instância gerada do problema de PL}
+
+Este é o resultado da tradução do modelo de exemplo produzido
+pelo solver \verb|glpsol| e escrito no formato CPLEX LP
+com a opção \verb|--wlp|.
+
+\medskip
+
+\begin{verbatim}
+\* Problem: transporte *\
+
+Minimize
+ custo: + 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
+ suprimento(Seattle): + x(Seattle,New~York) + x(Seattle,Chicago)
+ + x(Seattle,Topeka) <= 350
+ suprimento(San~Diego): + x(San~Diego,New~York) + x(San~Diego,Chicago)
+ + x(San~Diego,Topeka) <= 600
+ demanda(New~York): + x(Seattle,New~York) + x(San~Diego,New~York) >= 325
+ demanda(Chicago): + x(Seattle,Chicago) + x(San~Diego,Chicago) >= 300
+ demanda(Topeka): + x(Seattle,Topeka) + x(San~Diego,Topeka) >= 275
+
+End
+\end{verbatim}
+
+\section{solução ótima do problema de PL}
+
+Esta é a solução ótima da instância gerada do problema de PL
+encontrada pelo solver \verb|glpsol| e escrita em formato de texto plano
+com a opção\verb|--output|.
+
+\medskip
+
+\begin{footnotesize}
+\begin{verbatim}
+Problem: transporte
+Rows: 6
+Columns: 6
+Non-zeros: 18
+Status: OPTIMAL
+Objective: custo = 153.675 (MINimum)
+
+ No. Row name St Activity Lower bound Upper bound Marginal
+------ ------------ -- ------------- ------------- ------------- -------------
+ 1 cust B 153.675
+ 2 suprimento[Seattle]
+ NU 350 350 < eps
+ 3 suprimento[San-Diego]
+ B 550 600
+ 4 demanda[New-York]
+ NL 325 325 0.225
+ 5 demanda[Chicago]
+ NL 300 300 0.153
+ 6 demanda[Topeka]
+ NL 275 275 0.126
+
+ No. Column name St Activity Lower bound Upper bound Marginal
+------ ------------ -- ------------- ------------- ------------- -------------
+ 1 x[Seattle,New-York]
+ B 50 0
+ 2 x[Seattle,Chicago]
+ B 300 0
+ 3 x[Seattle,Topeka]
+ NL 0 0 0.036
+ 4 x[San-Diego,New-York]
+ B 275 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{footnotesize}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section*{Agradecimentos}
+\addcontentsline{toc}{chapter}{Agradecimentos}
+
+Os autores gostariam de agradecer as seguintes pessoas que gentilmente leram,
+comentaram e corrigiram o rascunho deste documento:
+
+\noindent Juan Carlos Borras \verb|<borras@cs.helsinki.fi>|
+
+\noindent Harley Mackenzie \verb|<hjm@bigpond.com>|
+
+\noindent Robbie Morrison \verb|<robbie@actrix.co.nz>|
+
+\end{document}
diff --git a/glpk-5.0/doc/graphs.pdf b/glpk-5.0/doc/graphs.pdf
new file mode 100644
index 0000000..47163f2
--- /dev/null
+++ b/glpk-5.0/doc/graphs.pdf
Binary files differ
diff --git a/glpk-5.0/doc/graphs.tex b/glpk-5.0/doc/graphs.tex
new file mode 100644
index 0000000..9f953bd
--- /dev/null
+++ b/glpk-5.0/doc/graphs.tex
@@ -0,0 +1,4180 @@
+%* graphs.tex *%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% The GLPK package is part of the GNU Project released under the aegis
+% of GNU.
+%
+% Copyright (c) 2007-2020 Free Software Foundation, Inc.
+%
+% Author: Andrew Makhorin <mao@gnu.org>.
+%
+% Permission is granted to copy, distribute and/or modify this
+% document under the terms of the GNU Free Documentation License,
+% Version 1.3 or any later version published by the Free Software
+% Foundation.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% To make graphs.pdf from graphs.tex run the following two commands:
+% latex graphs.tex
+% dvipdfm -p letter graphs.dvi
+% Note: You need TeX Live 2010 or later version.
+
+\documentclass[11pt]{report}
+\usepackage{amssymb}
+\usepackage[dvipdfm,linktocpage,colorlinks,linkcolor=blue,
+urlcolor=blue]{hyperref}
+\usepackage{indentfirst}
+\usepackage{niceframe}
+\usepackage[all]{xy}
+
+% US Letter = 8.5 x 11 in
+\setlength{\textwidth}{6.5in}
+\setlength{\textheight}{9in}
+\setlength{\oddsidemargin}{0in}
+\setlength{\topmargin}{0in}
+\setlength{\headheight}{0in}
+\setlength{\headsep}{0in}
+%\setlength{\footskip}{0.5in}
+\setlength{\parindent}{16pt}
+\setlength{\parskip}{5pt}
+\setlength{\topsep}{0pt}
+\setlength{\partopsep}{0pt}
+%\setlength{\itemsep}{\parskip}
+%\setlength{\parsep}{0pt}
+%\setlength{\leftmargini}{\parindent}
+%\renewcommand{\labelitemi}{---}
+
+\newcommand{\Item}[1]{\parbox[t]{\parindent}{#1}}
+\def\para#1{\noindent{\bf#1}}
+\def\synopsis{\para{Synopsis}}
+\def\description{\para{Description}}
+\def\note{\para{Note}}
+\def\returns{\para{Returns}}
+
+\renewcommand\contentsname{\sf\bfseries Contents}
+\renewcommand\chaptername{\sf\bfseries Chapter}
+\renewcommand\appendixname{\sf\bfseries Appendix}
+
+\newenvironment{retlist}
+{ \def\arraystretch{1.5}
+ \noindent
+ \begin{tabular}{@{}p{1in}@{}p{5.5in}@{}}
+}
+{\end{tabular}}
+
+\begin{document}
+
+\thispagestyle{empty}
+
+\artdecoframe{
+
+\begin{center}
+
+\vspace*{1.5in}
+
+\begin{huge}
+\sf\bfseries GNU Linear Programming Kit
+\end{huge}
+
+\vspace{0.5in}
+
+\begin{LARGE}
+\sf Graph and Network Routines
+\end{LARGE}
+
+\vspace{0.5in}
+
+\begin{LARGE}
+\sf for GLPK Version 5.0
+\end{LARGE}
+
+\vspace{0.5in}
+\begin{Large}
+\sf (December 2020)
+\end{Large}
+\end{center}
+
+\vspace*{3.2in}
+}
+
+\newpage
+
+\vspace*{1in}
+
+\vfill
+
+\noindent
+The GLPK package is part of the GNU Project released under the aegis of
+GNU.
+
+\noindent
+Copyright \copyright{} 2007-2020 Free Software Foundation, Inc.
+
+\noindent
+Author: Andrew Makhorin $\langle$mao@gnu.org$\rangle$.
+
+\noindent
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+{\setlength{\parskip}{0pt}\tableofcontents}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Basic Graph API Routines}
+
+\section{Graph program object}
+
+In GLPK the base program object used to represent graphs and networks
+is a directed graph (digraph).
+
+Formally, {\it digraph} (or simply, {\it graph}) is a pair $G=(V,A)$,
+where $V$ is a set of {\it vertices}, and $A$ is a set
+{\it arcs}.\footnote{$A$ may be a multiset.} Each arc $a\in A$ is an
+ordered pair of vertices $a=(x,y)$, where $x\in V$ is called {\it tail
+vertex} of arc $a$, and $y\in V$ is called its {\it head vertex}.
+
+Representation of a graph in the program includes three structs defined
+by typedef in the header \verb|glpk.h|:
+
+%\vspace*{-8pt}
+
+%\begin{itemize}
+\Item{---}\verb|glp_graph|, which represents the graph in a whole,
+
+\Item{---}\verb|glp_vertex|, which represents a vertex of the graph, and
+
+\Item{---}\verb|glp_arc|, which represents an arc of the graph.
+%\end{itemize}
+
+%\vspace*{-8pt}
+
+All these three structs are ``semi-opaque'', i.e. the application
+program can directly access their fields through pointers, however,
+changing the fields directly is not allowed --- all changes should be
+performed only with appropriate GLPK API routines.
+
+\newenvironment{comment}
+{\addtolength{\leftskip}{16pt}\noindent}
+{\par\addtolength{\leftskip}{-16pt}}
+
+\subsection{Structure glp\_graph}
+
+%\para{\bf glp\_graph.}
+The struct \verb|glp_graph| has the following fields available to the
+application program.
+
+\noindent
+\verb|char *name;|
+
+\begin{comment}Symbolic name assigned to the graph. It is a pointer to
+a null terminated character string of length from 1 to 255 characters.
+If no name is assigned to the graph, this field contains \verb|NULL|.
+\end{comment}
+
+\noindent
+\verb|int nv;|
+
+\begin{comment}The number of vertices in the graph, $nv\geq 0$.
+\end{comment}
+
+\noindent
+\verb|int na;|
+
+\begin{comment}The number of arcs in the graph, $na\geq 0$.
+\end{comment}
+
+\newpage
+
+\noindent
+\verb|glp_vertex **v;|
+
+\begin{comment}Pointer to an array containing the list of vertices.
+Element $v[0]$ is not used. Element $v[i]$, $1\leq i\leq nv$, is a
+pointer to $i$-th vertex of the graph. Note that on adding new vertices
+to the graph the field $v$ may be altered due to reallocation. However,
+pointers $v[i]$ are not changed while corresponding vertices exist in
+the graph.
+\end{comment}
+
+\noindent
+\verb|int v_size;|
+
+\begin{comment}Size of vertex data blocks, in bytes,
+$0\leq v\_size\leq 256$. (See also the field \verb|data| in the struct
+\verb|glp_vertex|.)
+\end{comment}
+
+\noindent
+\verb|int a_size;|
+
+\begin{comment}Size of arc data blocks, in bytes,
+$0\leq v\_size\leq 256$. (See also the field \verb|data| in the struct
+\verb|glp_arc|.)
+\end{comment}
+
+\subsection{Structure glp\_vertex}
+
+%\para{\bf glp\_vertex.}
+The struct \verb|glp_vertex| has the following fields available to the
+application program.
+
+\noindent
+\verb|int i;|
+
+\begin{comment}Ordinal number of the vertex, $1\leq i\leq nv$. Note
+that element $v[i]$ in the struct \verb|glp_graph| points to the vertex,
+whose ordinal number is $i$.
+\end{comment}
+
+\noindent
+\verb|char *name;|
+
+\begin{comment}Symbolic name assigned to the vertex. It is a pointer to
+a null terminated character string of length from 1 to 255 characters.
+If no name is assigned to the vertex, this field contains \verb|NULL|.
+\end{comment}
+
+\noindent
+\verb|void *data;|
+
+\begin{comment}Pointer to a data block associated with the vertex. This
+data block is automatically allocated on creating a new vertex and freed
+on deleting the vertex. If $v\_size=0$, the block is not allocated, and
+this field contains \verb|NULL|.
+\end{comment}
+
+\noindent
+\verb|void *temp;|
+
+\begin{comment}Working pointer, which may be used freely for any
+purposes. The application program can change this field directly.
+\end{comment}
+
+\noindent
+\verb|glp_arc *in;|
+
+\begin{comment}Pointer to the (unordered) list of incoming arcs. If the
+vertex has no incoming arcs, this field contains \verb|NULL|.
+\end{comment}
+
+\noindent
+\verb|glp_arc *out;|
+
+\begin{comment}Pointer to the (unordered) list of outgoing arcs. If the
+vertex has no outgoing arcs, this field contains \verb|NULL|.
+\end{comment}
+
+\subsection{Structure glp\_arc}
+
+%\para{\bf glp\_arc.}
+The struct \verb|glp_arc| has the following fields available to the
+application program.
+
+\noindent
+\verb|glp_vertex *tail;|
+
+\begin{comment}Pointer to a vertex, which is tail endpoint of the arc.
+\end{comment}
+
+\newpage
+
+\noindent
+\verb|glp_vertex *head;|
+
+\begin{comment}Pointer to a vertex, which is head endpoint of the arc.
+\end{comment}
+
+%\newpage
+
+\noindent
+\verb|void *data;|
+
+\begin{comment}Pointer to a data block associated with the arc. This
+data block is automatically allocated on creating a new arc and freed on
+deleting the arc. If $v\_size=0$, the block is not allocated, and this
+field contains \verb|NULL|.
+\end{comment}
+
+\noindent
+\verb|void *temp;|
+
+\begin{comment}Working pointer, which may be used freely for any
+purposes. The application program can change this field directly.
+\end{comment}
+
+\noindent
+\verb|glp_arc *t_next;|
+
+\begin{comment}Pointer to another arc, which has the same tail endpoint
+as this one. \verb|NULL| in this field indicates the end of the list of
+outgoing arcs.
+\end{comment}
+
+\noindent
+\verb|glp_arc *h_next;|
+
+\begin{comment}Pointer to another arc, which has the same head endpoint
+as this one. \verb|NULL| in this field indicates the end of the list of
+incoming arcs.
+\end{comment}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\setlength{\parskip}{4.6pt}
+
+\section{Graph creating and modifying routines}
+
+\subsection{glp\_create\_graph --- create graph}
+
+\synopsis
+
+\begin{verbatim}
+ glp_graph *glp_create_graph(int v_size, int a_size);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_create_graph| creates a new graph, which
+initially is empty, i.e. has no vertices and arcs.
+
+The parameter \verb|v_size| specifies the size of vertex data blocks,
+in bytes, $0\leq v\_size\leq 256$.
+
+The parameter \verb|a_size| specifies the size of arc data blocks, in
+bytes, $0\leq a\_size\leq 256$.
+
+\returns
+
+The routine returns a pointer to the graph object created.
+
+\subsection{glp\_set\_graph\_name --- assign (change) graph name}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_graph_name(glp_graph *G, const char *name);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_graph_name| assigns a symbolic name specified
+by the character string \verb|name| (1 to 255 chars) to the graph.
+
+If the parameter \verb|name| is \verb|NULL| or an empty string, the
+routine erases the existing symbolic name of the graph.
+
+\subsection{glp\_add\_vertices --- add new vertices to graph}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_add_vertices(glp_graph *G, int nadd);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_add_vertices| adds \verb|nadd| vertices to the
+specified graph. New vertices are always added to the end of the vertex
+list, so ordinal numbers of existing vertices remain unchanged. Note
+that this operation may change the field \verb|v| in the struct
+\verb|glp_graph| (pointer to the vertex array) due to reallocation.
+
+Being added each new vertex is isolated, i.e. has no incident arcs.
+
+If the size of vertex data blocks specified on creating the graph is
+non-zero, the routine also allocates a memory block of that size for
+each new vertex added, fills it by binary zeros, and stores a pointer
+to it in the field \verb|data| of the struct \verb|glp_vertex|.
+Otherwise, if the block size is zero, the field \verb|data| is set to
+\verb|NULL|.
+
+\returns
+
+The routine \verb|glp_add_vertices| returns the ordinal number of the
+first new vertex added to the graph.
+
+\setlength{\parskip}{5pt}
+
+\newpage
+
+\subsection{glp\_set\_vertex\_name --- assign (change) vertex name}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_set_vertex_name(glp_graph *G, int i, const char *name);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_set_vertex_name| assigns a given symbolic name
+(1 up to 255 characters) to \verb|i|-th vertex of the specified graph.
+
+If the parameter \verb|name| is \verb|NULL| or empty string, the
+routine erases an existing name of \verb|i|-th vertex.
+
+\subsection{glp\_add\_arc --- add new arc to graph}
+
+\synopsis
+
+\begin{verbatim}
+ glp_arc *glp_add_arc(glp_graph *G, int i, int j);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_add_arc| adds one new arc to the specified graph.
+
+The parameters \verb|i| and \verb|j| specify the ordinal numbers of,
+resp., tail and head endpoints (vertices) of the arc. Note that
+self-loops and multiple arcs are allowed.
+
+If the size of arc data blocks specified on creating the graph is
+non-zero, the routine also allocates a memory block of that size, fills
+it by binary zeros, and stores a pointer to it in the field \verb|data|
+of the struct \verb|glp_arc|. Otherwise, if the block size is zero, the
+field \verb|data| is set to \verb|NULL|.
+
+\subsection{glp\_del\_vertices --- delete vertices from graph}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_del_vertices(glp_graph *G, int ndel, const int num[]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_del_vertices| deletes vertices along with all
+incident arcs from the specified graph. Ordinal numbers of vertices to
+be deleted should be placed in locations \verb|num[1]|, \dots,
+\verb|num[ndel]|, \verb|ndel| $>0$.
+
+Note that deleting vertices involves changing ordinal numbers of other
+vertices remaining in the graph. New ordinal numbers of the remaining
+vertices are assigned under the assumption that the original order of
+vertices is not changed.
+
+%\newpage
+
+\subsection{glp\_del\_arc --- delete arc from graph}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_del_arc(glp_graph *G, glp_arc *a);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_del_arc| deletes an arc from the specified graph.
+The arc to be deleted must exist.
+
+\subsection{glp\_erase\_graph --- erase graph content}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_erase_graph(glp_graph *G, int v_size, int a_size);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_erase_graph| erases the content of the specified
+graph. The effect of this operation is the same as if the graph would
+be deleted with the routine \verb|glp_delete_graph| and then created
+anew with the routine \verb|glp_create_graph|, with exception that the
+pointer to the graph remains valid.
+
+The parameters \verb|v_size| and \verb|a_size| have the same meaning as
+for \verb|glp_create_graph|.
+
+\subsection{glp\_delete\_graph --- delete graph}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_delete_graph(glp_graph *G);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_delete_graph| deletes the specified graph and
+frees all the memory allocated to this program object.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Graph searching routines}
+
+\subsection{glp\_create\_v\_index --- create vertex name index}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_create_v_index(glp_graph *G);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_create_v_index| creates the name index for the
+specified graph. The name index is an auxiliary data structure, which
+is intended to quickly (i.e. for logarithmic time) find vertices by
+their names.
+
+This routine can be called at any time. If the name index already
+exists, the routine does nothing.
+
+\subsection{glp\_find\_vertex --- find vertex by its name}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_find_vertex(glp_graph *G, const char *name);
+\end{verbatim}
+
+\returns
+
+The routine \verb|glp_find_vertex| returns the ordinal number of
+a vertex, which is assigned (by the routine \verb|glp_set_vertex_name|)
+the specified symbolic \verb|name|. If no such vertex exists, the
+routine returns 0.
+
+\subsection{glp\_delete\_v\_index --- delete vertex name index}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_delete_v_index(glp_graph *G);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_delete_v_index| deletes the name index previously
+created by the routine \verb|glp_create_v_index| and frees the memory
+allocated to this auxiliary data structure.
+
+This routine can be called at any time. If the name index does not
+exist, the routine does nothing.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Graph reading/writing routines}
+
+\subsection{glp\_read\_graph --- read graph from text file}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_read_graph(glp_graph *G, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_read_graph| reads a graph from a text file, whose
+name is specified by the parameter \verb|fname|. It is equivalent to
+
+\begin{verbatim}
+ glp_read_ccdata(G, -1, fname);
+\end{verbatim}
+
+Note that before reading data the current content of the graph object
+is completely erased with the routine \verb|glp_erase_graph|.
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise
+it prints an error message and returns non-zero.
+
+\subsection{glp\_write\_graph --- write graph to text file}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_write_graph(glp_graph *G, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_write_graph| writes the graph to a text file,
+whose name is specified by the parameter \verb|fname|.
+It is equivalent to
+
+\begin{verbatim}
+ glp_write_ccdata(G, -1, fname);
+\end{verbatim}
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise
+it prints an error message and returns non-zero.
+
+\subsection{glp\_read\_ccdata --- read graph from text file in DIMACS
+clique/coloring\\format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_read_ccdata(glp_graph *G, int v_wgt, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine {\tt glp\_read\_ccdata} reads a graph from a text file in
+DIMACS clique/coloring format. (Though this format is originally
+designed to represent data for the minimal vertex coloring and maximal
+clique problems, it may be used to represent general undirected and
+directed graphs, because the routine allows reading self-loops and
+multiple edges/arcs keeping the order of vertices specified for each
+edge/arc of the graph.)
+
+\newpage
+
+The parameter {\tt G} specifies the graph object to be read in. Note
+that before reading data the current content of the graph object is
+completely erased with the routine {\tt glp\_erase\_graph}.
+
+The parameter {\tt v\_wgt} specifies an offset of the field of type
+{\tt double} in the vertex data block, to which the routine stores the
+vertex weight. If {\tt v\_wgt} $<0$, the vertex weights are not stored.
+
+The character string {\tt fname} specifies the name of a text file to
+be read in. (If the file name ends with the suffix `\verb|.gz|', the
+file is assumed to be compressed, in which case the routine
+decompresses it ``on the fly''.)
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+\para{DIMACS clique/coloring format\footnote{This material is
+based on the paper ``Clique and Coloring Problems Graph Format'', which
+is publicly available at \url{http://dimacs.rutgers.edu/Challenges}.}}
+
+The DIMACS input file is a plain ASCII text file. It contains
+{\it lines} of several types described below. A line is terminated with
+an end-of-line character. Fields in each line are separated by at least
+one blank space. Each line begins with a one-character designator to
+identify the line type.
+
+Note that DIMACS requires all numerical quantities to be integers in
+the range $[-2^{31},2^{31}-1]$ while GLPK allows the quantities to be
+floating-point numbers.
+
+\para{Comment lines.} Comment lines give human-readable information
+about the file and are ignored by programs. Comment lines can appear
+anywhere in the file. Each comment line begins with a lower-case
+character \verb|c|.
+
+\begin{verbatim}
+ c This is a comment line
+\end{verbatim}
+
+\para{Problem line.} There is one problem line per data file.
+The problem line must appear before any node or edge descriptor lines.
+It has the following format:
+
+\begin{verbatim}
+ p edge NODES EDGES
+\end{verbatim}
+
+\noindent
+The lower-case letter \verb|p| signifies that this is a problem line.
+The four-character problem designator \verb|edge| identifies the file
+as containing data for the minimal vertex coloring or maximal clique
+problem. The \verb|NODES| field contains an integer value specifying
+the number of vertices in the graph. The \verb|EDGES| field contains an
+integer value specifying the number of edges (arcs) in the graph.
+
+\para{Vertex descriptors.} These lines give the weight assigned to
+a vertex of the graph. There is one vertex descriptor line for each
+vertex, with the following format. Vertices without a descriptor take
+on a default value of 1.
+
+\begin{verbatim}
+ n ID VALUE
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|n| signifies that this is a vertex
+descriptor line. The \verb|ID| field gives a vertex identification
+number, an integer between 1 and $n$, where $n$ is the number of
+vertices in the graph. The \verb|VALUE| field gives a vertex weight,
+which can either positive or negative (or zero).
+
+\para{Edge descriptors.} There is one edge descriptor line for each
+edge (arc) of the graph, each with the following format:
+
+\begin{verbatim}
+ e I J
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|e| signifies that this is an edge
+descriptor line. For an edge (arc) $(i,j)$ the fields \verb|I| and
+\verb|J| specify its endpoints.
+
+\newpage
+
+\para{Example.} The following undirected graph
+
+\bigskip
+
+\noindent\hfil
+\xymatrix %@C=32pt
+{&{v_1}\ar@{-}[ldd]\ar@{-}[dd]\ar@{-}[rd]\ar@{-}[rr]&&{v_2}\ar@{-}[ld]
+\ar@{-}[dd]\ar@{-}[rdd]&\\
+&&{v_7}\ar@{-}[ld]\ar@{-}[rd]&&\\
+{v_6}\ar@{-}[r]\ar@{-}[rdd]&{v_{10}}\ar@{-}[rr]\ar@{-}[rd]\ar@{-}[dd]&&
+{v_8}\ar@{-}[ld]\ar@{-}[dd]\ar@{-}[r]&{v_3}\ar@{-}[ldd]\\
+&&{v_9}\ar@{-}[ld]\ar@{-}[rd]&&\\
+&{v_5}\ar@{-}[rr]&&{v_4}&\\
+}
+
+\bigskip
+
+\noindent
+might be coded in DIMACS clique/coloring format as follows.
+
+\begin{footnotesize}
+\begin{verbatim}
+c sample.col
+c
+c This is an example of the vertex coloring problem data
+c in DIMACS format.
+c
+p edge 10 21
+c
+e 1 2
+e 1 6
+e 1 7
+e 1 10
+e 2 3
+e 2 7
+e 2 8
+e 3 4
+e 3 8
+e 4 5
+e 4 8
+e 4 9
+e 5 6
+e 5 9
+e 5 10
+e 6 10
+e 7 8
+e 7 10
+e 8 9
+e 8 10
+e 9 10
+c
+c eof
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+\subsection{glp\_write\_ccdata --- write graph to text file in DIMACS
+clique/coloring\\format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_write_ccdata(glp_graph *G, int v_wgt, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine {\tt glp\_write\_ccdata} writes the graph object specified
+by the parameter {\tt G} to a text file in DIMACS clique/coloring
+format. (Though this format is originally designed to represent data
+for the minimal vertex coloring and maximal clique problems, it may be
+used to represent general undirected and directed graphs, because the
+routine allows writing self-loops and multiple edges/arcs keeping the
+order of vertices specified for each edge/arc of the graph.)
+
+The parameter {\tt v\_wgt} specifies an offset of the field of type
+{\tt double} in the vertex data block, which contains the vertex
+weight. If {\tt v\_wgt} $<0$, it is assumed that the weight of each
+vertex is 1.
+
+The character string {\tt fname} specifies a name of the text file to
+be written out. (If the file name ends with suffix `\verb|.gz|', the
+file is assumed to be compressed, in which case the routine performs
+automatic compression on writing it.)
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Graph analysis routines}
+
+\subsection{glp\_weak\_comp --- find all weakly connected components of
+graph}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_weak_comp(glp_graph *G, int v_num);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_weak_comp| finds all weakly connected components
+of the specified graph.
+
+The parameter \verb|v_num| specifies an offset of the field of type
+\verb|int| in the vertex data block, to which the routine stores the
+number of a weakly connected component containing that vertex. If
+\verb|v_num| $<0$, no component numbers are stored.
+
+The components are numbered in arbitrary order from 1 to \verb|nc|,
+where \verb|nc| is the total number of components found,
+$0\leq$ \verb|nc| $\leq|V|$.
+
+\returns
+
+The routine returns \verb|nc|, the total number of components found.
+
+\subsection{glp\_strong\_comp --- find all strongly connected
+components of graph}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_strong_comp(glp_graph *G, int v_num);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_strong_comp| finds all strongly connected
+components of the specified graph.
+
+The parameter \verb|v_num| specifies an offset of the field of type
+\verb|int| in the vertex data block, to which the routine stores the
+number of a strongly connected component containing that vertex. If
+\verb|v_num| $<0$, no component numbers are stored.
+
+The components are numbered in arbitrary order from 1 to \verb|nc|,
+where \verb|nc| is the total number of components found,
+$0\leq$ \verb|nc| $\leq|V|$. However, the component numbering has the
+property that for every arc $(i\rightarrow j)$ in the graph the
+condition $num(i)\geq num(j)$ holds.
+
+\returns
+
+The routine returns \verb|nc|, the total number of components found.
+
+\para{References}
+
+I.~S.~Duff, J.~K.~Reid, Algorithm 529: Permutations to block triangular
+form, ACM Trans. on Math. Softw. 4 (1978), 189-92.
+
+\newpage
+
+\para{Example}
+
+The following program reads a graph from a plain text file
+`\verb|graph.txt|' and finds all its strongly connected components.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { int num; } v_data;
+
+#define vertex(v) ((v_data *)((v)->data))
+
+int main(void)
+{ glp_graph *G;
+ int i, nc;
+ G = glp_create_graph(sizeof(v_data), 0);
+ glp_read_graph(G, "graph.txt");
+ nc = glp_strong_comp(G, offsetof(v_data, num));
+ printf("nc = %d\n", nc);
+ for (i = 1; i <= G->nv; i++)
+ printf("num[%d] = %d\n", i, vertex(G->v[i])->num);
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+\noindent
+If the file `\verb|graph.txt|' contains the following graph:
+
+\medskip
+
+\noindent\hfil
+\xymatrix
+{1\ar[r]&2\ar[r]&3\ar[r]\ar[dd]&4\ar[dd]\\
+5\ar[u]&6\ar[l]\\
+7\ar[u]&&8\ar[lu]\ar[ll]\ar[r]&9\ar[r]&10\ar[r]\ar[d]&11\ar[d]\\
+12\ar[u]\ar[rru]\ar@/_/[rr]&&13\ar[ll]\ar[u]\ar[rr]&&14\ar[lu]&15\ar[l]
+\\
+}
+
+\medskip\medskip
+
+\noindent
+the program output may look like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading graph from `graph.txt'...
+Graph has 15 vertices and 30 arcs
+31 lines were read
+nc = 4
+num[1] = 3
+num[2] = 3
+num[3] = 3
+num[4] = 2
+num[5] = 3
+num[6] = 3
+num[7] = 3
+num[8] = 3
+num[9] = 1
+num[10] = 1
+num[11] = 1
+num[12] = 4
+num[13] = 4
+num[14] = 1
+num[15] = 1
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_top\_sort --- topological sorting of acyclic digraph}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_top_sort(glp_graph *G, int v_num);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_top_sort| performs topological sorting of
+vertices of the specified acyclic digraph.
+
+The parameter \verb|v_num| specifies an offset of the field of type
+\verb|int| in the vertex data block, to which the routine stores the
+vertex number assigned. If \verb|v_num| $<0$, vertex numbers are not
+stored.
+
+The vertices are numbered from 1 to $n$, where $n$ is the total number
+of vertices in the graph. The vertex numbering has the property that
+for every arc $(i\rightarrow j)$ in the graph the condition
+$num(i)<num(j)$ holds. Special case $num(i)=0$ means that vertex $i$ is
+not assigned a number, because the graph is {\it not} acyclic.
+
+\returns
+
+If the graph is acyclic and therefore all the vertices have been
+assigned numbers, the routine \verb|glp_top_sort| returns zero.
+Otherwise, if the graph is not acyclic, the routine returns the number
+of vertices which have not been numbered, i.e. for which $num(i)=0$.
+
+\para{Example}
+
+The following program reads a digraph from a plain text file
+`\verb|graph.txt|' and performs topological sorting of its vertices.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { int num; } v_data;
+
+#define vertex(v) ((v_data *)((v)->data))
+
+int main(void)
+{ glp_graph *G;
+ int i, cnt;
+ G = glp_create_graph(sizeof(v_data), 0);
+ glp_read_graph(G, "graph.txt");
+ cnt = glp_top_sort(G, offsetof(v_data, num));
+ printf("cnt = %d\n", cnt);
+ for (i = 1; i <= G->nv; i++)
+ printf("num[%d] = %d\n", i, vertex(G->v[i])->num);
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+\noindent
+If the file `\verb|graph.txt|' contains the following graph:
+
+\medskip
+
+\noindent\hfil
+\xymatrix @=20pt
+{
+1\ar[rrr]&&&2\ar[r]\ar[rddd]&3\ar[rd]&&&&\\
+&&&4\ar[ru]&&5\ar[r]&6\ar[rd]\ar[dd]&&\\
+7\ar[r]&8\ar[r]&9\ar[ruu]\ar[ru]\ar[r]\ar[rd]&10\ar[rr]\ar[rru]&&
+11\ar[ru]&&12\ar[r]&13\\
+&&&14\ar[r]&15\ar[rrru]\ar[rr]&&16\ar[rru]\ar[rr]&&17\\
+}
+
+\medskip\medskip
+
+\noindent
+the program output may look like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading graph from `graph.txt'...
+Graph has 17 vertices and 23 arcs
+24 lines were read
+cnt = 0
+num[1] = 8
+num[2] = 9
+num[3] = 10
+num[4] = 4
+num[5] = 11
+num[6] = 12
+num[7] = 1
+num[8] = 2
+num[9] = 3
+num[10] = 5
+num[11] = 6
+num[12] = 14
+num[13] = 16
+num[14] = 7
+num[15] = 13
+num[16] = 15
+num[17] = 17
+\end{verbatim}
+\end{footnotesize}
+
+\noindent
+The output corresponds to the following vertex numbering:
+
+\medskip
+
+\noindent\hfil
+\xymatrix @=20pt
+{
+8\ar[rrr]&&&9\ar[r]\ar[rddd]&10\ar[rd]&&&&\\
+&&&4\ar[ru]&&11\ar[r]&12\ar[rd]\ar[dd]&&\\
+1\ar[r]&2\ar[r]&3\ar[ruu]\ar[ru]\ar[r]\ar[rd]&5\ar[rr]\ar[rru]&&
+6\ar[ru]&&14\ar[r]&16\\
+&&&7\ar[r]&13\ar[rrru]\ar[rr]&&15\ar[rru]\ar[rr]&&17\\
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Network optimization API routines}
+
+\section{Minimum cost flow problem}
+
+\subsection{Background}
+
+The {\it minimum cost flow problem} (MCFP) is stated as follows. Let
+there be given a directed graph (flow network) $G=(V,A)$, where $V$ is
+a set of vertices (nodes), and $A\subseteq V\times V$ is a set of arcs.
+Let for each node $i\in V$ there be given a quantity $b_i$ having the
+following meaning:
+
+if $b_i>0$, then $|b_i|$ is a {\it supply} at node $i$, which shows
+how many flow units are {\it generated} at node $i$ (or, equivalently,
+entering the network through node $i$ from outside);
+
+if $b_i<0$, then $|b_i|$ is a {\it demand} at node $i$, which shows how
+many flow units are {\it lost} at node $i$ (or, equivalently, leaving
+the network through node $i$ to outside);
+
+if $b_i=0$, then $i$ is a {\it transshipment} node, at which the flow
+is conserved, i.e. neither generated nor lost.
+
+Let also for each arc $a=(i,j)\in A$ there be given the following three
+quantities:
+
+$l_{ij}$, a (non-negative) lower bound to the flow through arc $(i,j)$;
+
+$u_{ij}$, an upper bound to the flow through arc $(i,j)$, which is the
+{\it arc capacity};
+
+$c_{ij}$, a per-unit cost of the flow through arc $(i,j)$.
+
+The problem is to find flows $x_{ij}$ through every arc of the network,
+which satisfy the specified bounds and the conservation constraints at
+all nodes, and minimize the total flow cost. Here the conservation
+constraint at a node means that the total flow entering this node
+through its incoming arcs plus the supply at this node must be equal to
+the total flow leaving this node through its outgoing arcs plus the
+demand at this node.
+
+An example of the minimum cost flow problem is shown on Fig.~1.
+
+\newpage
+
+\noindent\hfil
+\xymatrix @C=48pt
+{_{20}\ar@{~>}[d]&
+v_2\ar[r]|{_{0,10,\$2}}\ar[dd]|{_{0,9,\$3}}&
+v_3\ar[dd]|{_{2,12,\$1}}\ar[r]|{_{0,18,\$0}}&
+v_8\ar[rd]|{_{0,20,\$9}}&\\
+v_1\ar[ru]|{_{0,14,\$0}}\ar[rd]|{_{0,23,\$0}}&&&
+v_6\ar[d]|{_{0,7,\$0}}\ar[u]|{_{4,8,\$0}}&
+v_9\ar@{~>}[d]\\
+&v_4\ar[r]|{_{0,26,\$0}}&
+v_5\ar[luu]|{_{0,11,\$1}}\ar[ru]|{_{0,25,\$5}}\ar[r]|{_{0,4,\$7}}&
+v_7\ar[ru]|{_{0,15,\$3}}&_{20}\\
+}
+
+\noindent\hfil
+\begin{tabular}{ccc}
+\xymatrix @C=48pt{v_i\ar[r]|{\ l,u,\$c\ }&v_j\\}&
+\xymatrix{\hbox{\footnotesize supply}\ar@{~>}[r]&v_i\\}&
+\xymatrix{v_i\ar@{~>}[r]&\hbox{\footnotesize demand}\\}\\
+\end{tabular}
+
+\noindent\hfil
+Fig.~1. An example of the minimum cost flow problem.
+
+\medskip
+
+The minimum cost flow problem can be naturally formulated as the
+following LP problem:
+
+\noindent
+\hspace{1in}minimize
+$$z=\sum_{(i,j)\in A}c_{ij}x_{ij}\eqno(1)$$
+\hspace{1in}subject to
+$$\sum_{(i,j)\in A}x_{ij}-\sum_{(j,i)\in A}x_{ji}=b_i\ \ \ \hbox
+{for all}\ i\in V\eqno(2)$$
+$$l_{ij}\leq x_{ij}\leq u_{ij}\ \ \ \hbox{for all}\ (i,j)\in A
+\eqno(3)$$
+
+\subsection{glp\_read\_mincost --- read minimum cost flow problem data
+in DIMACS\\format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_read_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap,
+ int a_cost, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_read_mincost| reads the minimum cost flow problem
+data from a text file in DIMACS format.
+
+The parameter \verb|G| specifies the graph object, to which the problem
+data have to be stored. Note that before reading data the current
+content of the graph object is completely erased with the routine
+\verb|glp_erase_graph|.
+
+The parameter \verb|v_rhs| specifies an offset of the field of type
+\verb|double| in the vertex data block, to which the routine stores
+$b_i$, the supply/demand value. If \verb|v_rhs| $<0$, the value is not
+stored.
+
+The parameter \verb|a_low| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores
+$l_{ij}$, the lower bound to the arc flow. If \verb|a_low| $<0$, the
+lower bound is not stored.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores
+$u_{ij}$, the upper bound to the arc flow (the arc capacity). If
+\verb|a_cap| $<0$, the upper bound is not stored.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores
+$c_{ij}$, the per-unit cost of the arc flow. If \verb|a_cost| $<0$, the
+cost is not stored.
+
+The character string \verb|fname| specifies the name of a text file to
+be read in. (If the file name name ends with the suffix `\verb|.gz|',
+the file is assumed to be compressed, in which case the routine
+decompresses it ``on the fly''.)
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+\para{Example}
+
+\begin{footnotesize}
+\begin{verbatim}
+typedef struct
+{ /* vertex data block */
+ ...
+ double rhs;
+ ...
+} v_data;
+
+typedef struct
+{ /* arc data block */
+ ...
+ double low, cap, cost;
+ ...
+} a_data;
+
+int main(void)
+{ glp_graph *G;
+ int ret;
+ G = glp_create_graph(sizeof(v_data), sizeof(a_data));
+ ret = glp_read_mincost(G, offsetof(v_data, rhs),
+ offsetof(a_data, low), offsetof(a_data, cap),
+ offsetof(a_data, cost), "sample.min");
+ if (ret != 0) goto ...
+ ...
+}
+\end{verbatim}
+\end{footnotesize}
+
+\para{DIMACS minimum cost flow problem format\footnote{This
+material is based on the paper ``The First DIMACS International
+Algorithm Implementation Challenge: Problem Definitions and
+Specifications'', which is publicly available at
+\url{http://dimacs.rutgers.edu/Challenges}.}}
+\label{subsecmincost}
+
+The DIMACS input file is a plain ASCII text file. It contains
+{\it lines} of several types described below. A line is terminated with
+an end-of-line character. Fields in each line are separated by at least
+one blank space. Each line begins with a one-character designator to
+identify the line type.
+
+Note that DIMACS requires all numerical quantities to be integers in
+the range $[-2^{31},\ 2^{31}-1]$ while GLPK allows the quantities to be
+floating-point numbers.
+
+\para{Comment lines.} Comment lines give human-readable information
+about the file and are ignored by programs. Comment lines can appear
+anywhere in the file. Each comment line begins with a lower-case
+character \verb|c|.
+
+\begin{verbatim}
+ c This is a comment line
+\end{verbatim}
+
+%\newpage
+
+\para{Problem line.} There is one problem line per data file. The
+problem line must appear before any node or arc descriptor lines. It
+has the following format:
+
+\begin{verbatim}
+ p min NODES ARCS
+\end{verbatim}
+
+\newpage
+
+\noindent
+The lower-case character \verb|p| signifies that this is a problem line.
+The three-character problem designator \verb|min| identifies the file as
+containing specification information for the minimum cost flow problem.
+The \verb|NODES| field contains an integer value specifying the number
+of nodes in the network. The \verb|ARCS| field contains an integer value
+specifying the number of arcs in the network.
+
+\para{Node descriptors.} All node descriptor lines must appear before
+all arc descriptor lines. The node descriptor lines describe supply and
+demand nodes, but not transshipment nodes. That is, only nodes with
+non-zero node supply/demand values appear. There is one node descriptor
+line for each such node, with the following format:
+
+\begin{verbatim}
+ n ID FLOW
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|n| signifies that this is a node
+descriptor line. The \verb|ID| field gives a node identification
+number, an integer between 1 and \verb|NODES|. The \verb|FLOW| field
+gives the amount of supply (if positive) or demand (if negative) at
+node \verb|ID|.
+
+\para{Arc descriptors.} There is one arc descriptor line for each arc
+in the network. Arc descriptor lines are of the following format:
+
+\begin{verbatim}
+ a SRC DST LOW CAP COST
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|a| signifies that this is an arc
+descriptor line. For a directed arc $(i,j)$ the \verb|SRC| field gives
+the identification number $i$ for the tail endpoint, and the \verb|DST|
+field gives the identification number $j$ for the head endpoint.
+Identification numbers are integers between 1 and \verb|NODES|. The
+\verb|LOW| field specifies the minimum amount of flow that can be sent
+along arc $(i,j)$, and the \verb|CAP| field gives the maximum amount of
+flow that can be sent along arc $(i,j)$ in a feasible flow. The
+\verb|COST| field contains the per-unit cost of flow sent along arc
+$(i,j)$.
+
+\para{Example.} Below here is an example of the data file in DIMACS
+format corresponding to the minimum cost flow problem shown on Fig~1.
+
+\begin{footnotesize}
+\begin{verbatim}
+c sample.min
+c
+c This is an example of the minimum cost flow problem data
+c in DIMACS format.
+c
+p min 9 14
+c
+n 1 20
+n 9 -20
+c
+a 1 2 0 14 0
+a 1 4 0 23 0
+a 2 3 0 10 2
+a 2 4 0 9 3
+a 3 5 2 12 1
+a 3 8 0 18 0
+a 4 5 0 26 0
+a 5 2 0 11 1
+a 5 6 0 25 5
+a 5 7 0 4 7
+a 6 7 0 7 0
+a 6 8 4 8 0
+a 7 9 0 15 3
+a 8 9 0 20 9
+c
+c eof
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+\subsection{glp\_write\_mincost --- write minimum cost flow problem
+data in DIMACS\\format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_write_mincost(glp_graph *G, int v_rhs, int a_low, int a_cap,
+ int a_cost, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_write_mincost| writes the minimum cost flow
+problem data to a text file in DIMACS format.
+
+The parameter \verb|G| is the graph (network) program object, which
+specifies the minimum cost flow problem instance.
+
+The parameter \verb|v_rhs| specifies an offset of the field of type
+\verb|double| in the vertex data block, which contains $b_i$, the
+supply/demand value. If \verb|v_rhs| $<0$, it is assumed that $b_i=0$
+for all nodes.
+
+The parameter \verb|a_low| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $l_{ij}$, the lower
+bound to the arc flow. If \verb|a_low| $<0$, it is assumed that
+$l_{ij}=0$ for all arcs.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $u_{ij}$, the upper
+bound to the arc flow (the arc capacity). If the upper bound is
+specified as \verb|DBL_MAX|, it is assumed that $u_{ij}=\infty$, i.e.
+the arc is uncapacitated. If \verb|a_cap| $<0$, it is assumed that
+$u_{ij}=1$ for all arcs.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $c_{ij}$, the
+per-unit cost of the arc flow. If \verb|a_cost| $<0$, it is assumed
+that $c_{ij}=0$ for all arcs.
+
+The character string \verb|fname| specifies a name of the text file to
+be written out. (If the file name ends with suffix `\verb|.gz|', the
+file is assumed to be compressed, in which case the routine performs
+automatic compression on writing it.)
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+%\newpage
+
+\subsection{glp\_mincost\_lp --- convert minimum cost flow problem
+to LP}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_mincost_lp(glp_prob *P, glp_graph *G, int names, int v_rhs,
+ int a_low, int a_cap, int a_cost);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mincost_lp| builds LP problem (1)---(3), which
+corresponds to the specified minimum cost flow problem.
+
+The parameter \verb|P| is the resultant LP problem object to be built.
+Note that on entry its current content is erased with the routine
+\verb|glp_erase_prob|.
+
+The parameter \verb|G| is the graph (network) program object, which
+specifies the minimum cost flow problem instance.
+
+The parameter \verb|names| is a flag. If it is \verb|GLP_ON|, the
+routine uses symbolic names of the graph object components to assign
+symbolic names to the LP problem object components. If the flag is
+\verb|GLP_OFF|, no symbolic names are assigned.
+
+The parameter \verb|v_rhs| specifies an offset of the field of type
+\verb|double| in the vertex data block, which contains $b_i$, the
+supply/demand value. If \verb|v_rhs| $<0$, it is assumed that $b_i=0$
+for all nodes.
+
+The parameter \verb|a_low| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $l_{ij}$, the lower
+bound to the arc flow. If \verb|a_low| $<0$, it is assumed that
+$l_{ij}=0$ for all arcs.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $u_{ij}$, the upper
+bound to the arc flow (the arc capacity). If the upper bound is
+specified as \verb|DBL_MAX|, it is assumed that $u_{ij}=\infty$, i.e.
+the arc is uncapacitated. If \verb|a_cap| $<0$, it is assumed that
+$u_{ij}=1$ for all arcs.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $c_{ij}$, the
+per-unit cost of the arc flow. If \verb|a_cost| $<0$, it is assumed that
+$c_{ij}=0$ for all arcs.
+
+\para{Example}
+
+The example program below reads the minimum cost problem instance in
+DIMACS format from file `\verb|sample.min|', converts the instance to
+LP, and then writes the resultant LP in CPLEX format to file
+`\verb|mincost.lp|'.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <glpk.h>
+
+typedef struct { double rhs; } v_data;
+typedef struct { double low, cap, cost; } a_data;
+
+int main(void)
+{ glp_graph *G;
+ glp_prob *P;
+ G = glp_create_graph(sizeof(v_data), sizeof(a_data));
+ glp_read_mincost(G, offsetof(v_data, rhs),
+ offsetof(a_data, low), offsetof(a_data, cap),
+ offsetof(a_data, cost), "sample.min");
+ P = glp_create_prob();
+ glp_mincost_lp(P, G, GLP_ON, offsetof(v_data, rhs),
+ offsetof(a_data, low), offsetof(a_data, cap),
+ offsetof(a_data, cost));
+ glp_delete_graph(G);
+ glp_write_lp(P, NULL, "mincost.lp");
+ glp_delete_prob(P);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+If `\verb|sample.min|' is the example data file from the subsection
+describing \verb|glp_read_mincost|, file `\verb|mincost.lp|' may look
+like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+Minimize
+ obj: + 3 x(2,4) + 2 x(2,3) + x(3,5) + 7 x(5,7) + 5 x(5,6)
+ + x(5,2) + 3 x(7,9) + 9 x(8,9)
+
+Subject To
+ r_1: + x(1,2) + x(1,4) = 20
+ r_2: - x(5,2) + x(2,3) + x(2,4) - x(1,2) = 0
+ r_3: + x(3,5) + x(3,8) - x(2,3) = 0
+ r_4: + x(4,5) - x(2,4) - x(1,4) = 0
+ r_5: + x(5,2) + x(5,6) + x(5,7) - x(4,5) - x(3,5) = 0
+ r_6: + x(6,7) + x(6,8) - x(5,6) = 0
+ r_7: + x(7,9) - x(6,7) - x(5,7) = 0
+ r_8: + x(8,9) - x(6,8) - x(3,8) = 0
+ r_9: - x(8,9) - x(7,9) = -20
+
+Bounds
+ 0 <= x(1,4) <= 23
+ 0 <= x(1,2) <= 14
+ 0 <= x(2,4) <= 9
+ 0 <= x(2,3) <= 10
+ 0 <= x(3,8) <= 18
+ 2 <= x(3,5) <= 12
+ 0 <= x(4,5) <= 26
+ 0 <= x(5,7) <= 4
+ 0 <= x(5,6) <= 25
+ 0 <= x(5,2) <= 11
+ 4 <= x(6,8) <= 8
+ 0 <= x(6,7) <= 7
+ 0 <= x(7,9) <= 15
+ 0 <= x(8,9) <= 20
+
+End
+\end{verbatim}
+\end{footnotesize}
+
+%\newpage
+
+\subsection{glp\_mincost\_okalg --- solve minimum cost flow problem
+with out-of-kilter\\algorithm}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_mincost_okalg(glp_graph *G, int v_rhs, int a_low, int a_cap,
+ int a_cost, double *sol, int a_x, int v_pi);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mincost_okalg| finds optimal solution to the
+minimum cost flow problem with the out-of-kilter
+algorithm.\footnote{GLPK implementation of the out-of-kilter algorithm
+is based on the following book: L.~R.~Ford,~Jr., and D.~R.~Fulkerson,
+``Flows in Networks,'' The RAND Corp., Report R-375-PR (August 1962),
+Chap. III ``Minimal Cost Flow Problems,'' pp.~113-26.} Note that this
+routine requires all the problem data to be integer-valued.
+
+The parameter \verb|G| is a graph (network) program object which
+specifies the minimum cost flow problem instance to be solved.
+
+The parameter \verb|v_rhs| specifies an offset of the field of type
+\verb|double| in the vertex data block, which contains $b_i$, the
+supply/demand value. This value must be integer in the range
+[$-$\verb|INT_MAX|, $+$\verb|INT_MAX|]. If \verb|v_rhs| $<0$, it is
+assumed that $b_i=0$ for all nodes.
+
+The parameter \verb|a_low| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $l_{ij}$, the lower
+bound to the arc flow. This bound must be integer in the range
+[$0$, \verb|INT_MAX|]. If \verb|a_low| $<0$, it is assumed that
+$l_{ij}=0$ for all arcs.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $u_{ij}$, the upper
+bound to the arc flow (the arc capacity). This bound must be integer in
+the range [$l_{ij}$, \verb|INT_MAX|]. If \verb|a_cap| $<0$, it is
+assumed that $u_{ij}=1$ for all arcs.
+
+\newpage
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $c_{ij}$, the
+per-unit cost of the arc flow. This value must be integer in the range
+[$-$\verb|INT_MAX|, $+$\verb|INT_MAX|]. If \verb|a_cost| $<0$, it is
+assumed that $c_{ij}=0$ for all arcs.
+
+The parameter \verb|sol| specifies a location, to which the routine
+stores the objective value (that is, the total cost) found. If
+\verb|sol| is NULL, the objective value is not stored.
+
+The parameter \verb|a_x| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores
+$x_{ij}$, the arc flow found. If \verb|a_x| $<0$, the arc flow value is
+not stored.
+
+The parameter \verb|v_pi| specifies an offset of the field of type
+\verb|double| in the vertex data block, to which the routine stores
+$\pi_i$, the node potential, which is the Lagrange multiplier for the
+corresponding flow conservation equality constraint (see (2) in
+Subsection ``Background''). If necessary, the application program may
+use the node potentials to compute $\lambda_{ij}$, reduced costs of the
+arc flows $x_{ij}$, which are the Lagrange multipliers for the arc flow
+bound constraints (see (3) ibid.), using the following formula:
+$$\lambda_{ij}=c_{ij}-(\pi_i-\pi_j),$$
+where $c_{ij}$ is the per-unit cost for arc $(i,j)$.
+
+%\newpage
+
+Note that all solution components (the objective value, arc flows, and
+node potentials) computed by the routine are always integer-valued.
+
+\returns
+
+\begin{retlist}
+0 & Optimal solution found.\\
+
+\verb|GLP_ENOPFS| & No (primal) feasible solution exists.\\
+
+\verb|GLP_EDATA| & Unable to start the search, because some problem
+data are either not integer-valued or out of range. This code is also
+returned if the total supply, which is the sum of $b_i$ over all source
+nodes (nodes with $b_i>0$), exceeds \verb|INT_MAX|.\\
+
+\verb|GLP_ERANGE| & The search was prematurely terminated because of
+integer overflow.\\
+
+\verb|GLP_EFAIL| & An error has been detected in the program logic.
+(If this code is returned for your problem instance, please report to
+\verb|<bug-glpk@gnu.org>|.)\\
+\end{retlist}
+
+\para{Comments}
+
+By design the out-of-kilter algorithm is applicable only to networks,
+where $b_i=0$ for {\it all} nodes, i.e. actually this algorithm finds a
+minimal cost {\it circulation}. Due to this requirement the routine
+\verb|glp_mincost_okalg| converts the original network to a network
+suitable for the out-of-kilter algorithm in the following
+way:\footnote{The conversion is performed internally and does not change
+the original network program object passed to the routine.}
+
+1) it adds two auxiliary nodes $s$ and $t$;
+
+2) for each original node $i$ with $b_i>0$ the routine adds auxiliary
+supply arc $(s\rightarrow i)$, flow $x_{si}$ through which is costless
+($c_{si}=0$) and fixed to $+b_i$ ($l_{si}=u_{si}=+b_i$);
+
+3) for each original node $i$ with $b_i<0$ the routine adds auxiliary
+demand arc $(i\rightarrow t)$, flow $x_{it}$ through which is costless
+($c_{it}=0$) and fixed to $-b_i$ ($l_{it}=u_{it}=-b_i$);
+
+4) finally, the routine adds auxiliary feedback arc $(t\rightarrow s)$,
+flow $x_{ts}$ through which is also costless ($c_{ts}=0$) and fixed to
+$F$ ($l_{ts}=u_{ts}=F$), where $\displaystyle F=\sum_{b_i>0}b_i$ is the
+total supply.
+
+\newpage
+
+\para{Example}
+
+The example program below reads the minimum cost problem instance in
+DIMACS format from file `\verb|sample.min|', solves it by using the
+routine \verb|glp_mincost_okalg|, and writes the solution found on the
+standard output.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { double rhs, pi; } v_data;
+typedef struct { double low, cap, cost, x; } a_data;
+
+#define node(v) ((v_data *)((v)->data))
+#define arc(a) ((a_data *)((a)->data))
+
+int main(void)
+{ glp_graph *G;
+ glp_vertex *v, *w;
+ glp_arc *a;
+ int i, ret;
+ double sol;
+ G = glp_create_graph(sizeof(v_data), sizeof(a_data));
+ glp_read_mincost(G, offsetof(v_data, rhs),
+ offsetof(a_data, low), offsetof(a_data, cap),
+ offsetof(a_data, cost), "sample.min");
+ ret = glp_mincost_okalg(G, offsetof(v_data, rhs),
+ offsetof(a_data, low), offsetof(a_data, cap),
+ offsetof(a_data, cost), &sol, offsetof(a_data, x),
+ offsetof(v_data, pi));
+ printf("ret = %d; sol = %5g\n", ret, sol);
+ for (i = 1; i <= G->nv; i++)
+ { v = G->v[i];
+ printf("node %d: pi = %5g\n", i, node(v)->pi);
+ for (a = v->out; a != NULL; a = a->t_next)
+ { w = a->head;
+ printf("arc %d->%d: x = %5g; lambda = %5g\n",
+ v->i, w->i, arc(a)->x,
+ arc(a)->cost - (node(v)->pi - node(w)->pi));
+ }
+ }
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+If `\verb|sample.min|' is the example data file from the subsection
+describing \verb|glp_read_mincost|, the output may look like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading min-cost flow problem data from `sample.min'...
+Flow network has 9 nodes and 14 arcs
+24 lines were read
+ret = 0; sol = 213
+node 1: pi = -12
+arc 1->4: x = 13; lambda = 0
+arc 1->2: x = 7; lambda = 0
+node 2: pi = -12
+arc 2->4: x = 0; lambda = 3
+arc 2->3: x = 7; lambda = 0
+node 3: pi = -14
+arc 3->8: x = 5; lambda = 0
+arc 3->5: x = 2; lambda = 3
+node 4: pi = -12
+arc 4->5: x = 13; lambda = 0
+node 5: pi = -12
+arc 5->7: x = 4; lambda = -1
+arc 5->6: x = 11; lambda = 0
+arc 5->2: x = 0; lambda = 1
+node 6: pi = -17
+arc 6->8: x = 4; lambda = 3
+arc 6->7: x = 7; lambda = -3
+node 7: pi = -20
+arc 7->9: x = 11; lambda = 0
+node 8: pi = -14
+arc 8->9: x = 9; lambda = 0
+node 9: pi = -23
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_mincost\_relax4 --- solve minimum cost flow problem
+with relaxation\\method of Bertsekas and Tseng (RELAX-IV)}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_mincost_relax4(glp_graph *G, int v_rhs, int a_low, int a_cap,
+ int a_cost, int crash, double *sol, int a_x, int a_rc);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mincost_relax4| finds optimal solution to the
+minimum cost flow problem with the relaxation method RELAX-IV developed
+by Bertsekas and Tseng.\footnote{GLPK implementation of this method is
+based on a C translation of the original Fortran code {\tt RELAX4}
+written by Dimitri P. Bertsekas and Paul Tseng, with a contribution by
+Jonathan Eckstein in the phase II initialization.} This method is one
+of most efficient methods for network optimization.
+
+Note that this routine requires all the problem data to be
+integer-valued.
+
+The parameter \verb|G| is a graph (network) program object which
+specifies the minimum cost flow problem instance to be solved.
+
+The parameter \verb|v_rhs| specifies an offset of the field of type
+\verb|double| in the vertex data block, which contains $b_i$, the
+supply/demand value. This value must be integer in the range
+[$-$\verb|INT_MAX|/4, $+$\verb|INT_MAX|/4]. If \verb|v_rhs| $<0$, it is
+assumed that $b_i=0$ for all nodes.
+
+The parameter \verb|a_low| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $l_{ij}$, the lower
+bound to the arc flow. This bound must be integer in the range
+{\linebreak} [$0$, \verb|INT_MAX|/4]. If \verb|a_low| $<0$, it is
+assumed that $l_{ij}=0$ for all arcs.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $u_{ij}$, the upper
+bound to the arc flow (the arc capacity). This bound must be integer in
+the range [$l_{ij}$, \verb|INT_MAX|/4]. If \verb|a_cap| $<0$, it is
+assumed that $u_{ij}=1$ for all arcs.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $c_{ij}$, the
+per-unit cost of the arc flow. This value must be integer in the range
+[$-$\verb|INT_MAX|/4, $+$\verb|INT_MAX|/4]. If \verb|a_cost| $<0$, it
+is assumed that $c_{ij}=0$ for all arcs.
+
+\newpage
+
+The parameter \verb|crash| is an option that specifies initialization
+method:
+
+0 --- default initialization is used;
+
+1 --- auction initialization is used.
+
+\noindent
+If \verb|crash| = 1, initialization is performed with a special crash
+procedure based on an auction/shorest path method. This option is
+recommended for difficult problems where the default initialization
+results in long running times.
+
+The parameter \verb|sol| specifies a location, to which the routine
+stores the objective value (that is, the total cost) found. If
+\verb|sol| is NULL, the objective value is not stored.
+
+The parameter \verb|a_x| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores
+$x_{ij}$, the arc flow found. If \verb|a_x| $<0$, the arc flow value is
+not stored.
+
+The parameter \verb|a_rc| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores
+the reduced cost for corresponding arc flow (see (3) in Subsection
+``Background''). If \verb|a_rc| $<0$, the reduced cost is not stored.
+
+Note that all solution components (the objective value, arc flows, and
+node potentials) computed by the routine are always integer-valued.
+
+\returns
+
+\begin{retlist}
+0 & Optimal solution found.\\
+
+\verb|GLP_ENOPFS| & No (primal) feasible solution exists.\\
+
+\verb|GLP_EDATA| & Unable to start the search, because some problem
+data are either not integer-valued or out of range.\\
+
+\verb|GLP_ERANGE| & Unable to start the search because of integer
+overflow.\\
+\end{retlist}
+
+\para{Example}
+
+The example program below reads the minimum cost problem instance in
+DIMACS format from file `\verb|sample.min|', solves it by using the
+routine \verb|glp_mincost_relax4|, and writes the solution found on the
+standard output.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { double rhs; } v_data;
+typedef struct { double low, cap, cost, x, rc; } a_data;
+
+#define node(v) ((v_data *)((v)->data))
+#define arc(a) ((a_data *)((a)->data))
+
+int main(void)
+{ glp_graph *G;
+ glp_vertex *v, *w;
+ glp_arc *a;
+ int i, ret;
+ double sol;
+ G = glp_create_graph(sizeof(v_data), sizeof(a_data));
+ glp_read_mincost(G, offsetof(v_data, rhs),
+ offsetof(a_data, low), offsetof(a_data, cap),
+ offsetof(a_data, cost), "sample.min");
+ ret = glp_mincost_relax4(G, offsetof(v_data, rhs),
+ offsetof(a_data, low), offsetof(a_data, cap),
+ offsetof(a_data, cost), 0, &sol, offsetof(a_data, x),
+ offsetof(a_data, rc));
+ printf("ret = %d; sol = %5g\n", ret, sol);
+ for (i = 1; i <= G->nv; i++)
+ { v = G->v[i];
+ for (a = v->out; a != NULL; a = a->t_next)
+ { w = a->head;
+ printf("arc %d->%d: x = %5g; rc = %5g\n",
+ v->i, w->i, arc(a)->x, arc(a)->rc);
+ }
+ }
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+If `\verb|sample.min|' is the example data file from the subsection
+describing \verb|glp_read_mincost|, the output may look like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading min-cost flow problem data from `sample.min'...
+Flow network has 9 nodes and 14 arcs
+24 lines were read
+ret = 0; sol = 213
+arc 1->4: x = 13; rc = 0
+arc 1->2: x = 7; rc = 0
+arc 2->4: x = 0; rc = 3
+arc 2->3: x = 7; rc = 0
+arc 3->8: x = 5; rc = 0
+arc 3->5: x = 2; rc = 3
+arc 4->5: x = 13; rc = 0
+arc 5->7: x = 4; rc = -1
+arc 5->6: x = 11; rc = 0
+arc 5->2: x = 0; rc = 1
+arc 6->8: x = 4; rc = 3
+arc 6->7: x = 7; rc = -3
+arc 7->9: x = 11; rc = 0
+arc 8->9: x = 9; rc = 0
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_netgen --- Klingman's network problem generator}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_netgen(glp_graph *G, int v_rhs, int a_cap, int a_cost,
+ const int parm[1+15]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_netgen| is a GLPK version of the network problem
+generator developed by Dr.~Darwin~Klingman.\footnote{D.~Klingman,
+A.~Napier, and J.~Stutz. NETGEN: A program for generating large scale
+capacitated assignment, transportation, and minimum cost flow networks.
+Management Science 20 (1974), 814-20.} It can create capacitated and
+uncapacitated minimum cost flow (or transshipment), transportation, and
+assignment problems.
+
+The parameter \verb|G| specifies the graph object, to which the
+generated problem data have to be stored. Note that on entry the graph
+object is erased with the routine \verb|glp_erase_graph|.
+
+\newpage
+
+The parameter \verb|v_rhs| specifies an offset of the field of type
+\verb|double| in the vertex data block, to which the routine stores the
+supply or demand value. If \verb|v_rhs| $<0$, the value is not stored.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores the
+arc capacity. If \verb|a_cap| $<0$, the capacity is not stored.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores the
+per-unit cost if the arc flow. If \verb|a_cost| $<0$, the cost is not
+stored.
+
+The array \verb|parm| contains description of the network to be
+generated:
+
+\begin{tabular}{@{}lll@{}}
+\verb|parm[0] |& &not used\\
+\verb|parm[1] |&\verb|iseed |&8-digit positive random number seed\\
+\verb|parm[2] |&\verb|nprob |&8-digit problem id number\\
+\verb|parm[3] |&\verb|nodes |&total number of nodes\\
+\verb|parm[4] |&\verb|nsorc |&total number of source nodes
+(including transshipment nodes)\\
+\verb|parm[5] |&\verb|nsink |&total number of sink nodes
+(including transshipment nodes)\\
+\verb|parm[6] |&\verb|iarcs |&number of arc\\
+\verb|parm[7] |&\verb|mincst|&minimum cost for arcs\\
+\verb|parm[8] |&\verb|maxcst|&maximum cost for arcs\\
+\verb|parm[9] |&\verb|itsup |&total supply\\
+\verb|parm[10]|&\verb|ntsorc|&number of transshipment source nodes\\
+\verb|parm[11]|&\verb|ntsink|&number of transshipment sink nodes\\
+\verb|parm[12]|&\verb|iphic |&percentage of skeleton arcs to be given
+the maximum cost\\
+\verb|parm[13]|&\verb|ipcap |&percentage of arcs to be capacitated\\
+\verb|parm[14]|&\verb|mincap|&minimum upper bound for capacitated arcs\\
+\verb|parm[15]|&\verb|maxcap|&maximum upper bound for capacitated arcs\\
+\end{tabular}
+
+\returns
+
+If the instance was successfully generated, the routine
+\verb|glp_netgen| returns zero; otherwise, if specified parameters are
+inconsistent, the routine returns a non-zero error code.
+
+\para{Notes}
+
+1. The routine generates a transportation problem if:
+$${\tt nsorc}+{\tt nsink}={\tt nodes},
+\ {\tt ntsorc}=0,\ \mbox{and}\ {\tt ntsink}=0.$$
+
+2. The routine generates an assignment problem if the requirements for
+a transportation problem are met and:
+$${\tt nsorc}={\tt nsink}\ \mbox{and}\ {\tt itsup}={\tt nsorc}.$$
+
+3. The routine always generates connected graphs. So, if the number of
+requested arcs has been reached and the generated instance is not fully
+connected, the routine generates a few remaining arcs to ensure
+connectedness. Thus, the actual number of arcs generated by the routine
+may be greater than the requested number of arcs.
+
+\newpage
+
+\subsection{glp\_netgen\_prob --- Klingman's standard network problem
+instance}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_netgen_prob(int nprob, int parm[1+15]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_netgen_prob| provides the set of parameters for
+Klingman's network problem generator (see the routine
+\verb|glp_netgen|), which describe a standard network problem instance.
+
+The parameter \verb|nprob| ($101\leq$ \verb|nprob| $\leq 150$)
+specifies the problem instance number.
+
+The array \verb|parm| contains description of the network, provided by
+the routine. (For detailed description of these parameters see comments
+to the routine \verb|glp_netgen|.)
+
+\para{Problem characteristics}
+
+The table below shows characteristics of Klingman's standard network
+problem instances.
+$$
+\begin{array}{crrr}
+{\rm Problem} & {\rm Nodes} & {\rm Arcs} & {\rm Optimum} \\
+\hline
+101 & 5000 & 25336 & 6191726 \\
+102 & 5000 & 25387 & 72337144 \\
+103 & 5000 & 25355 & 218947553 \\
+104 & 5000 & 25344 & -19100371 \\
+105 & 5000 & 25332 & 31192578 \\
+106 & 5000 & 12870 & 4314276 \\
+107 & 5000 & 37832 & 7393769 \\
+108 & 5000 & 50309 & 8405738 \\
+109 & 5000 & 75299 & 9190300 \\
+110 & 5000 & 12825 & 8975048 \\
+111 & 5000 & 37828 & 4747532 \\
+112 & 5000 & 50325 & 4012671 \\
+113 & 5000 & 75318 & 2979725 \\
+114 & 5000 & 26514 & 5821181 \\
+115 & 5000 & 25962 & 6353310 \\
+116 & 5000 & 25304 & 5915426 \\
+117 & 5000 & 12816 & 4420560 \\
+118 & 5000 & 37797 & 7045842 \\
+119 & 5000 & 50301 & 7724179 \\
+120 & 5000 & 75330 & 8455200 \\
+121 & 5000 & 25000 & 66366360 \\
+122 & 5000 & 25000 & 30997529 \\
+123 & 5000 & 25000 & 23388777 \\
+124 & 5000 & 25000 & 17803443 \\
+125 & 5000 & 25000 & 14119622 \\
+\end{array}
+\hspace{.5in}
+\begin{array}{crrr}
+{\rm Problem} & {\rm Nodes} & {\rm Arcs} & {\rm Optimum} \\
+\hline
+126 & 5000 & 12500 & 18802218 \\
+127 & 5000 & 37500 & 27674647 \\
+128 & 5000 & 50000 & 30906194 \\
+129 & 5000 & 75000 & 40905209 \\
+130 & 5000 & 12500 & 38939608 \\
+131 & 5000 & 37500 & 16752978 \\
+132 & 5000 & 50000 & 13302951 \\
+133 & 5000 & 75000 & 9830268 \\
+134 & 1000 & 25000 & 3804874 \\
+135 & 2500 & 25000 & 11729616 \\
+136 & 7500 & 25000 & 33318101 \\
+137 & 10000 & 25000 & 46426030 \\
+138 & 5000 & 25000 & 60710879 \\
+139 & 5000 & 25000 & 32729682 \\
+140 & 5000 & 25000 & 27183831 \\
+141 & 5000 & 25000 & 19963286 \\
+142 & 5000 & 25000 & 20243457 \\
+143 & 5000 & 25000 & 18586777 \\
+144 & 5000 & 25000 & 2504591 \\
+145 & 5000 & 25000 & 215956138 \\
+146 & 5000 & 25000 & 2253113811 \\
+147 & 5000 & 25000 & -427908373 \\
+148 & 5000 & 25000 & -92965318 \\
+149 & 5000 & 25000 & 86051224 \\
+150 & 5000 & 25000 & 619314919 \\
+\end{array}
+$$
+
+\newpage
+
+\subsection{glp\_gridgen --- grid-like network problem generator}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_gridgen(glp_graph *G, int v_rhs, int a_cap, int a_cost,
+ const int parm[1+14]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_gridgen| is a GLPK version of the grid-like
+network problem generator developed by Yusin Lee and Jim
+Orlin.\footnote{Y.~Lee and J.~Orlin. GRIDGEN generator., 1991. The
+original code is publicly available from
+\url{ftp://dimacs.rutgers.edu/pub/netflow/generators/network/gridgen}.}
+
+The parameter \verb|G| specifies the graph object, to which the
+generated problem data have to be stored. Note that on entry the graph
+object is erased with the routine \verb|glp_erase_graph|.
+
+The parameter \verb|v_rhs| specifies an offset of the field of type
+\verb|double| in the vertex data block, to which the routine stores the
+supply or demand value. If \verb|v_rhs| $<0$, the value is not stored.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores the
+arc capacity. If \verb|a_cap| $<0$, the capacity is not stored.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores the
+per-unit cost if the arc flow. If \verb|a_cost| $<0$, the cost is not
+stored.
+
+The array \verb|parm| contains parameters of the network to be
+generated:
+
+\begin{tabular}{@{}ll@{}}
+\verb|parm[0] |&not used\\
+\verb|parm[1] |&two-ways arcs indicator:\\
+ &1 --- if links in both direction should be generated\\
+ &0 --- otherwise\\
+\verb|parm[2] |&random number seed (a positive integer)\\
+\verb|parm[3] |&number of nodes (the number of nodes generated might
+be slightly different to\\&make the network a grid)\\
+\verb|parm[4] |&grid width\\
+\verb|parm[5] |&number of sources\\
+\verb|parm[6] |&number of sinks\\
+\verb|parm[7] |&average degree\\
+\verb|parm[8] |&total flow\\
+\verb|parm[9] |&distribution of arc costs:
+1 --- uniform, 2 --- exponential\\
+\verb|parm[10]|&lower bound for arc cost (uniform),
+$100\lambda$ (exponential)\\
+\verb|parm[11]|&upper bound for arc cost (uniform),
+not used (exponential)\\
+\verb|parm[12]|&distribution of arc capacities:
+1 --- uniform, 2 --- exponential\\
+\verb|parm[13]|&lower bound for arc capacity (uniform),
+$100\lambda$ (exponential)\\
+\verb|parm[14]|&upper bound for arc capacity (uniform),
+not used (exponential)\\
+\end{tabular}
+
+\returns
+
+If the instance was successfully generated, the routine
+\verb|glp_gridgen| returns zero; otherwise, if specified parameters are
+inconsistent, the routine returns a non-zero error code.
+
+\newpage
+
+\para{Comments\footnote{This material is based on comments
+to the original version of GRIDGEN.}}
+
+This network generator generates a grid-like network plus a super node.
+In additional to the arcs connecting the nodes in the grid, there is an
+arc from each supply node to the super node and from the super node to
+each demand node to guarantee feasiblity. These arcs have very high
+costs and very big capacities.
+
+The idea of this network generator is as follows: First, a grid of
+$n_1\times n_2$ is generated. For example, $5\times 3$. The nodes are
+numbered as 1 to 15, and the supernode is numbered as
+$n_1\times n_2+1$. Then arcs between adjacent nodes are generated.
+For these arcs, the user is allowed to specify either to generate
+two-way arcs or one-way arcs. If two-way arcs are to be generated, two
+arcs, one in each direction, will be generated between each adjacent
+node pairs. Otherwise, only one arc will be generated. If this is the
+case, the arcs will be generated in alterntive directions as shown
+below.
+
+\medskip
+
+\noindent\hfil
+\xymatrix
+{1\ar[r]\ar[d]&2\ar[r]&3\ar[r]\ar[d]&4\ar[r]&5\ar[d]\\
+6\ar[d]&7\ar[l]\ar[u]&8\ar[l]\ar[d]&9\ar[l]\ar[u]&10\ar[l]\ar[d]\\
+11\ar[r]&12\ar[r]\ar[u]&13\ar[r]&14\ar[r]\ar[u]&15\\
+}
+
+\medskip
+
+Then the arcs between the super node and the source/sink nodes are
+added as mentioned before. If the number of arcs still doesn't reach
+the requirement, additional arcs will be added by uniformly picking
+random node pairs. There is no checking to prevent multiple arcs
+between any pair of nodes. However, there will be no self-arcs (arcs
+that poins back to its tail node) in the network.
+
+The source and sink nodes are selected uniformly in the network, and
+the imbalances of each source/sink node are also assigned by uniform
+distribution.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Maximum flow problem}
+
+\subsection{Background}
+
+The {\it maximum flow problem} (MAXFLOW) is stated as follows. Let
+there be given a directed graph (flow network) $G=(V,A)$, where $V$ is
+a set of vertices (nodes), and $A\subseteq V\times V$ is a set of arcs.
+Let also for each arc $a=(i,j)\in A$ there be given its capacity
+$u_{ij}$. The problem is, for given {\it source} node $s\in V$ and
+{\it sink} node $t\in V$, to find flows $x_{ij}$ through every arc of
+the network, which satisfy the specified arc capacities and the
+conservation constraints at all nodes, and maximize the total flow $F$
+through the network from $s$ to $t$. Here the conservation constraint
+at a node means that the total flow entering this node through its
+incoming arcs (plus $F$, if it is the source node) must be equal to the
+total flow leaving this node through its outgoing arcs (plus $F$, if it
+is the sink node). An example of the maximum flow problem,
+where $s=v_1$ and $t=v_9$, is shown on Fig.~2.
+
+\medskip
+
+\noindent\hfil
+\xymatrix @C=48pt
+{_{F}\ar@{~>}[d]&
+v_2\ar[r]|{_{10}}\ar[dd]|{_{9}}&
+v_3\ar[dd]|{_{12}}\ar[r]|{_{18}}&
+v_8\ar[rd]|{_{20}}&\\
+v_1\ar[ru]|{_{14}}\ar[rd]|{_{23}}&&&
+v_6\ar[d]|{_{7}}\ar[u]|{_{8}}&
+v_9\ar@{~>}[d]\\
+&v_4\ar[r]|{_{26}}&
+v_5\ar[luu]|{_{11}}\ar[ru]|{_{25}}\ar[r]|{_{4}}&
+v_7\ar[ru]|{_{15}}&_{F}\\
+}
+
+\medskip
+
+\noindent\hfil
+Fig.~2. An example of the maximum flow problem.
+
+\medskip
+
+The maximum flow problem can be naturally formulated as the following
+LP problem:
+
+\noindent
+\hspace{1in}maximize
+$$F\eqno(4)$$
+\hspace{1in}subject to
+$$\sum_{(i,j)\in A}x_{ij}-\sum_{(j,i)\in A}x_{ji}=\left\{
+\begin{array}{@{\ }rl}
++F,&\hbox{for}\ i=s\\
+ 0,&\hbox{for all}\ i\in V\backslash\{s,t\}\\
+-F,&\hbox{for}\ i=t\\
+\end{array}
+\right.\eqno(5)
+$$
+$$0\leq x_{ij}\leq u_{ij}\ \ \ \hbox{for all}\ (i,j)\in A
+\eqno(6)$$
+
+\noindent
+where $F\geq 0$ is an additional variable playing the role of the
+objective.
+
+Another LP formulation of the maximum flow problem, which does not
+include the variable $F$, is the following:
+
+\noindent
+\hspace{1in}maximize
+$$z=\sum_{(s,j)\in A}x_{sj}-\sum_{(j,s)\in A}x_{js}\ (=F)\eqno(7)$$
+\hspace{1in}subject to
+$$\sum_{(i,j)\in A}x_{ij}-\sum_{(j,i)\in A}x_{ji}\left\{
+\begin{array}{@{\ }rl}
+\geq 0,&\hbox{for}\ i=s\\
+=0,&\hbox{for all}\ i\in V\backslash\{s,t\}\\
+\leq 0,&\hbox{for}\ i=t\\
+\end{array}
+\right.\eqno(8)
+$$
+$$0\leq x_{ij}\leq u_{ij}\ \ \ \hbox{for all}\ (i,j)\in A
+\eqno(9)$$
+
+\newpage
+
+\subsection{glp\_read\_maxflow --- read maximum flow problem data in
+DIMACS\\format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_read_maxflow(glp_graph *G, int *s, int *t, int a_cap,
+ const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_read_maxflow| reads the maximum flow problem
+data from a text file in DIMACS format.
+
+The parameter \verb|G| specifies the graph object, to which the problem
+data have to be stored. Note that before reading data the current
+content of the graph object is completely erased with the routine
+\verb|glp_erase_graph|.
+
+The pointer \verb|s| specifies a location, to which the routine stores
+the ordinal number of the source node. If \verb|s| is \verb|NULL|, the
+source node number is not stored.
+
+The pointer \verb|t| specifies a location, to which the routine stores
+the ordinal number of the sink node. If \verb|t| is \verb|NULL|, the
+sink node number is not stored.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores
+$u_{ij}$, the arc capacity. If \verb|a_cap| $<0$, the arc capacity is
+not stored.
+
+The character string \verb|fname| specifies the name of a text file to
+be read in. (If the file name name ends with the suffix `\verb|.gz|',
+the file is assumed to be compressed, in which case the routine
+decompresses it ``on the fly''.)
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+\para{Example}
+
+\begin{footnotesize}
+\begin{verbatim}
+typedef struct
+{ /* arc data block */
+ ...
+ double cap;
+ ...
+} a_data;
+
+int main(void)
+{ glp_graph *G;
+ int s, t, ret;
+ G = glp_create_graph(..., sizeof(a_data));
+ ret = glp_read_maxflow(G, &s, &t, offsetof(a_data, cap),
+ "sample.max");
+ if (ret != 0) goto ...
+ ...
+}
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+\para{DIMACS maximum flow problem format\footnote{This material is
+based on the paper ``The First DIMACS International Algorithm
+Implementation Challenge: Problem Definitions and Specifications'',
+which is publicly available at
+\url{http://dimacs.rutgers.edu/Challenges/}.}}
+\label{subsecmaxflow}
+
+The DIMACS input file is a plain ASCII text file. It contains
+{\it lines} of several types described below. A line is terminated with
+an end-of-line character. Fields in each line are separated by at least
+one blank space. Each line begins with a one-character designator to
+identify the line type.
+
+Note that DIMACS requires all numerical quantities to be integers in
+the range $[-2^{31},\ 2^{31}-1]$ while GLPK allows the quantities to be
+floating-point numbers.
+
+\para{Comment lines.} Comment lines give human-readable information
+about the file and are ignored by programs. Comment lines can appear
+anywhere in the file. Each comment line begins with a lower-case
+character \verb|c|.
+
+\begin{verbatim}
+ c This is a comment line
+\end{verbatim}
+
+\para{Problem line.} There is one problem line per data file. The
+problem line must appear before any node or arc descriptor lines.
+It has the following format:
+
+\begin{verbatim}
+ p max NODES ARCS
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|p| signifies that this is a problem line.
+The three-character problem designator \verb|max| identifies the file as
+containing specification information for the maximum flow problem. The
+\verb|NODES| field contains an integer value specifying the number of
+nodes in the network. The \verb|ARCS| field contains an integer value
+specifying the number of arcs in the network.
+
+\para{Node descriptors.} Two node descriptor lines for the source and
+sink nodes must appear before all arc descriptor lines. They may appear
+in either order, each with the following format:
+
+\begin{verbatim}
+ n ID WHICH
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|n| signifies that this a node descriptor
+line. The \verb|ID| field gives a node identification number,
+an integer between 1 and \verb|NODES|. The \verb|WHICH| field gives
+either a lower-case \verb|s| or \verb|t|, designating the source and
+sink, respectively.
+
+\para{Arc descriptors.} There is one arc descriptor line for each arc
+in the network. Arc descriptor lines are of the following format:
+
+\begin{verbatim}
+ a SRC DST CAP
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|a| signifies that this is an arc
+descriptor line. For a directed arc $(i,j)$ the \verb|SRC| field gives
+the identification number $i$ for the tail endpoint, and the \verb|DST|
+field gives the identification number $j$ for the head endpoint.
+Identification numbers are integers between 1 and \verb|NODES|. The
+\verb|CAP| field gives the arc capacity, i.e. maximum amount of flow
+that can be sent along arc $(i,j)$ in a feasible flow.
+
+\para{Example.} Below here is an example of the data file in DIMACS
+format corresponding to the maximum flow problem shown on Fig~2.
+
+\begin{footnotesize}
+\begin{verbatim}
+c sample.max
+c
+c This is an example of the maximum flow problem data
+c in DIMACS format.
+c
+p max 9 14
+c
+n 1 s
+n 9 t
+c
+a 1 2 14
+a 1 4 23
+a 2 3 10
+a 2 4 9
+a 3 5 12
+a 3 8 18
+a 4 5 26
+a 5 2 11
+a 5 6 25
+a 5 7 4
+a 6 7 7
+a 6 8 8
+a 7 9 15
+a 8 9 20
+c
+c eof
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_write\_maxflow --- write maximum flow problem data in
+DIMACS\\format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_write_maxflow(glp_graph *G, int s, int t, int a_cap,
+ const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_write_maxflow| writes the maximum flow problem
+data to a text file in DIMACS format.
+
+The parameter \verb|G| is the graph (network) program object, which
+specifies the maximum flow problem instance.
+
+The parameter \verb|s| specifies the ordinal number of the source node.
+
+The parameter \verb|t| specifies the ordinal number of the sink node.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $u_{ij}$, the upper
+bound to the arc flow (the arc capacity). If the upper bound is
+specified as \verb|DBL_MAX|, it is assumed that $u_{ij}=\infty$, i.e.
+the arc is uncapacitated. If \verb|a_cap| $<0$, it is assumed that
+$u_{ij}=1$ for all arcs.
+
+The character string \verb|fname| specifies a name of the text file to
+be written out. (If the file name ends with suffix `\verb|.gz|', the
+file is assumed to be compressed, in which case the routine performs
+automatic compression on writing it.)
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+\newpage
+
+\subsection{glp\_maxflow\_lp --- convert maximum flow problem to LP}
+
+\synopsis
+
+\begin{verbatim}
+ void glp_maxflow_lp(glp_prob *P, glp_graph *G, int names, int s, int t,
+ int a_cap);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_maxflow_lp| builds LP problem (7)---(9), which
+corresponds to the specified maximum flow problem.
+
+The parameter \verb|P| is the resultant LP problem object to be built.
+Note that on entry its current content is erased with the routine
+\verb|glp_erase_prob|.
+
+The parameter \verb|G| is the graph (network) program object, which
+specifies the maximum flow problem instance.
+
+The parameter \verb|names| is a flag. If it is \verb|GLP_ON|, the
+routine uses symbolic names of the graph object components to assign
+symbolic names to the LP problem object components. If the flag is
+\verb|GLP_OFF|, no symbolic names are assigned.
+
+The parameter \verb|s| specifies the ordinal number of the source node.
+
+The parameter \verb|t| specifies the ordinal number of the sink node.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $u_{ij}$, the upper
+bound to the arc flow (the arc capacity). If the upper bound is
+specified as \verb|DBL_MAX|, it is assumed that $u_{ij}=\infty$, i.e.
+the arc is uncapacitated. If \verb|a_cap| $<0$, it is assumed that
+$u_{ij}=1$ for all arcs.
+
+\para{Example}
+
+The example program below reads the maximum flow problem in DIMACS
+format from file `\verb|sample.max|', converts the instance to LP, and
+then writes the resultant LP in CPLEX format to file
+`\verb|maxflow.lp|'.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <glpk.h>
+
+int main(void)
+{ glp_graph *G;
+ glp_prob *P;
+ int s, t;
+ G = glp_create_graph(0, sizeof(double));
+ glp_read_maxflow(G, &s, &t, 0, "sample.max");
+ P = glp_create_prob();
+ glp_maxflow_lp(P, G, GLP_ON, s, t, 0);
+ glp_delete_graph(G);
+ glp_write_lp(P, NULL, "maxflow.lp");
+ glp_delete_prob(P);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+If `\verb|sample.max|' is the example data file from the previous
+subsection, the output `\verb|maxflow.lp|' may look like follows:
+
+\newpage
+
+\begin{footnotesize}
+\begin{verbatim}
+Maximize
+ obj: + x(1,4) + x(1,2)
+
+Subject To
+ r_1: + x(1,2) + x(1,4) >= 0
+ r_2: - x(5,2) + x(2,3) + x(2,4) - x(1,2) = 0
+ r_3: + x(3,5) + x(3,8) - x(2,3) = 0
+ r_4: + x(4,5) - x(2,4) - x(1,4) = 0
+ r_5: + x(5,2) + x(5,6) + x(5,7) - x(4,5) - x(3,5) = 0
+ r_6: + x(6,7) + x(6,8) - x(5,6) = 0
+ r_7: + x(7,9) - x(6,7) - x(5,7) = 0
+ r_8: + x(8,9) - x(6,8) - x(3,8) = 0
+ r_9: - x(8,9) - x(7,9) <= 0
+
+Bounds
+ 0 <= x(1,4) <= 23
+ 0 <= x(1,2) <= 14
+ 0 <= x(2,4) <= 9
+ 0 <= x(2,3) <= 10
+ 0 <= x(3,8) <= 18
+ 0 <= x(3,5) <= 12
+ 0 <= x(4,5) <= 26
+ 0 <= x(5,7) <= 4
+ 0 <= x(5,6) <= 25
+ 0 <= x(5,2) <= 11
+ 0 <= x(6,8) <= 8
+ 0 <= x(6,7) <= 7
+ 0 <= x(7,9) <= 15
+ 0 <= x(8,9) <= 20
+
+End
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_maxflow\_ffalg --- solve maximum flow problem with
+Ford-Fulkerson\\algorithm}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_maxflow_ffalg(glp_graph *G, int s, int t, int a_cap, double *sol,
+ int a_x, int v_cut);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mincost_ffalg| finds optimal solution to the
+maximum flow problem with the Ford-Fulkerson algorithm.\footnote{GLPK
+implementation of the Ford-Fulkerson algorithm is based on the
+following book: L.~R.~Ford,~Jr., and D.~R.~Fulkerson, ``Flows in
+Networks,'' The RAND Corp., Report R-375-PR (August 1962), Chap. I
+``Static Maximal Flow,'' pp.~30-33.} Note that this routine requires
+all the problem data to be integer-valued.
+
+The parameter \verb|G| is a graph (network) program object which
+specifies the maximum flow problem instance to be solved.
+
+The parameter $s$ specifies the ordinal number of the source node.
+
+The parameter $t$ specifies the ordinal number of the sink node.
+
+\newpage
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $u_{ij}$, the upper
+bound to the arc flow (the arc capacity). This bound must be integer in
+the range [0, \verb|INT_MAX|]. If \verb|a_cap| $<0$, it is assumed that
+$u_{ij}=1$ for all arcs.
+
+The parameter \verb|sol| specifies a location, to which the routine
+stores the objective value (that is, the total flow from $s$ to $t$)
+found. If \verb|sol| is NULL, the objective value is not stored.
+
+The parameter \verb|a_x| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores
+$x_{ij}$, the arc flow found. If \verb|a_x| $<0$, the arc flow values
+are not stored.
+
+The parameter \verb|v_cut| specifies an offset of the field of type
+\verb|int| in the vertex data block, to which the routine stores node
+flags corresponding to the optimal solution found: if the node flag is
+1, the node is labelled, and if the node flag is 0, the node is
+unlabelled. The calling program may use these node flags to determine
+the {\it minimal cut}, which is a subset of arcs whose one endpoint is
+labelled and other is not. If \verb|v_cut| $<0$, the node flags are not
+stored.
+
+Note that all solution components (the objective value and arc flows)
+computed by the routine are always integer-valued.
+
+\returns
+
+\begin{retlist}
+0 & Optimal solution found.\\
+
+\verb|GLP_EDATA| & Unable to start the search, because some problem
+data are either not integer-valued or out of range.\\
+\end{retlist}
+
+\para{Example}
+
+The example program shown below reads the maximum flow problem instance
+in DIMACS format from file `\verb|sample.max|', solves it using the
+routine \verb|glp_maxflow_ffalg|, and write the solution found to the
+standard output.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { int cut; } v_data;
+typedef struct { double cap, x; } a_data;
+
+#define node(v) ((v_data *)((v)->data))
+#define arc(a) ((a_data *)((a)->data))
+
+int main(void)
+{ glp_graph *G;
+ glp_vertex *v, *w;
+ glp_arc *a;
+ int i, s, t, ret;
+ double sol;
+ G = glp_create_graph(sizeof(v_data), sizeof(a_data));
+ glp_read_maxflow(G, &s, &t, offsetof(a_data, cap),
+ "sample.max");
+ ret = glp_maxflow_ffalg(G, s, t, offsetof(a_data, cap),
+ &sol, offsetof(a_data, x), offsetof(v_data, cut));
+ printf("ret = %d; sol = %5g\n", ret, sol);
+ for (i = 1; i <= G->nv; i++)
+ { v = G->v[i];
+ for (a = v->out; a != NULL; a = a->t_next)
+ { w = a->head;
+ printf("x[%d->%d] = %5g (%d)\n", v->i, w->i,
+ arc(a)->x, node(v)->cut ^ node(w)->cut);
+ }
+ }
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+If `\verb|sample.max|' is the example data file from the subsection
+describing \verb|glp_read_maxflow|, the output may look like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading maximum flow problem data from `sample.max'...
+Flow network has 9 nodes and 14 arcs
+24 lines were read
+ret = 0; sol = 29
+x[1->4] = 19 (0)
+x[1->2] = 10 (0)
+x[2->4] = 0 (0)
+x[2->3] = 10 (1)
+x[3->8] = 10 (0)
+x[3->5] = 0 (1)
+x[4->5] = 19 (0)
+x[5->7] = 4 (1)
+x[5->6] = 15 (0)
+x[5->2] = 0 (0)
+x[6->8] = 8 (1)
+x[6->7] = 7 (1)
+x[7->9] = 11 (0)
+x[8->9] = 18 (0)
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_rmfgen --- Goldfarb's maximum flow problem generator}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_rmfgen(glp_graph *G, int *s, int *t, int a_cap, const int parm[1+5]);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_rmfgen| is a GLPK version of the maximum flow
+problem generator developed by D.~Goldfarb and
+M.~Grigoriadis.\footnote{D.~Goldfarb and M.~D.~Grigoriadis,
+``A computational comparison of the Dinic and network simplex methods
+for maximum flow.'' Annals of Op. Res. 13 (1988),
+pp.~83-123.}$^{,}$\footnote{U.~Derigs and W.~Meier, ``Implementing
+Goldberg's max-flow algorithm: A computational investigation.''
+Zeitschrift f\"ur Operations Research 33 (1989),
+pp.~383-403.}$^{,}$\footnote{The original code of RMFGEN implemented by
+Tamas Badics is publicly available from
+\url{ftp://dimacs.rutgers.edu/pub/netflow/generators/network/genrmf}.}
+
+The parameter \verb|G| specifies the graph object, to which the
+generated problem data have to be stored. Note that on entry the graph
+object is erased with the routine \verb|glp_erase_graph|.
+
+The pointers \verb|s| and \verb|t| specify locations, to which the
+routine stores the source and sink node numbers, respectively. If
+\verb|s| or \verb|t| is \verb|NULL|, corresponding node number is not
+stored.
+
+The parameter \verb|a_cap| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores the
+arc capacity. If \verb|a_cap| $<0$, the capacity is not stored.
+
+\newpage
+
+The array \verb|parm| contains description of the network to be
+generated:
+
+\begin{tabular}{@{}lll@{}}
+\verb|parm[0]|& &not used\\
+\verb|parm[1]|&\verb|seed|&random number seed (a positive integer)\\
+\verb|parm[2]|&\verb|a |&frame size\\
+\verb|parm[3]|&\verb|b |&depth\\
+\verb|parm[4]|&\verb|c1 |&minimal arc capacity\\
+\verb|parm[5]|&\verb|c2 |&maximal arc capacity\\
+\end{tabular}
+
+\returns
+
+If the instance was successfully generated, the routine
+\verb|glp_netgen| returns zero; otherwise, if specified parameters are
+inconsistent, the routine returns a non-zero error code.
+
+\para{Comments\footnote{This material is based on comments to the
+original version of RMFGEN.}}
+
+The generated network is as follows. It has $b$ pieces of frames of
+size $a\times a$. (So alltogether the number of vertices is
+$a\times a\times b$.)
+
+In each frame all the vertices are connected with their neighbours
+(forth and back). In addition the vertices of a frame are connected
+one to one with the vertices of next frame using a random permutation
+of those vertices.
+
+The source is the lower left vertex of the first frame, the sink is
+the upper right vertex of the $b$-th frame.
+
+\begin{verbatim}
+ t
+ +-------+
+ | .|
+ | . |
+ / | / |
+ +-------+/ -+ b
+ | | |/.
+ a | -v- |/
+ | | |/
+ +-------+ 1
+ s a
+\end{verbatim}
+
+The capacities are randomly chosen integers from the range of
+$[c_1,c_2]$ in the case of interconnecting edges, and $c_2\cdot a^2$
+for the in-frame edges.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Assignment problem}
+
+\subsection{Background}
+
+Let there be given an undirected bipartite graph $G=(R\cup S,E)$, where
+$R$ and $S$ are disjoint sets of vertices (nodes), and
+$E\subseteq R\times S$ is a set of edges. Let also for each edge
+$e=(i,j)\in E$ there be given its cost $c_{ij}$. A {\it matching}
+(which in case of bipartite graph is also called {\it assignment})
+$M\subseteq E$ in $G$ is a set of pairwise non-adjacent edges, that is,
+no two edges in $M$ share a common vertex. A matching, which matches
+all vertices of the graph, is called a {\it perfect matching}.
+Obviously, a perfect matching in bipartite graph $G=(R\cup S,E)$
+defines some bijection $R\leftrightarrow S$.
+
+The {\it assignment problem} has two different variants. In the first
+variant the problem is to find matching (assignment) $M$, which
+maximizes the sum:
+$$\sum_{(i,j)\in M}c_{ij}\eqno(10)$$
+(so this variant is also called the {\it maximum weighted bipartite
+matching problem} or, if all $c_{ij}=1$, the {\it maximum cardinality
+bipartite matching problem}). In the second, classic variant the
+problem is to find {\it perfect} matching (assignment) $M$, which
+minimizes or maximizes the sum (10).
+
+An example of the assignment problem, which is the maximum weighted
+bipartite matching problem, is shown on Fig. 3.
+
+The maximum weighted bipartite matching problem can be naturally
+formulated as the following LP problem:
+
+\noindent
+\hspace{1in}maximize
+$$z=\sum_{(i,j)\in E}c_{ij}x_{ij}\eqno(11)$$
+\hspace{1in}subject to
+$$\sum_{(i,j)\in E}x_{ij}\leq 1\ \ \ \hbox{for all}\ i\in R\eqno(12)$$
+$$\sum_{(i,j)\in E}x_{ij}\leq 1\ \ \ \hbox{for all}\ j\in S\eqno(13)$$
+$$\ \ \ \ \ \ \ \ 0\leq x_{ij}\leq 1\ \ \ \hbox{for all}\ (i,j)\in E
+\eqno(14)$$
+
+\noindent
+where $x_{ij}=1$ means that $(i,j)\in M$, and $x_{ij}=0$ means that
+$(i,j)\notin M$.\footnote{The constraint matrix of LP formulation
+(11)---(14) is totally unimodular, due to which $x_{ij}\in\{0,1\}$ for
+any basic solution.}
+
+\newpage
+
+\noindent\hfil
+\xymatrix @C=48pt
+{v_1\ar@{-}[rr]|{_{13}}\ar@{-}[rrd]|{_{21}}\ar@{-}[rrddd]|(.2){_{20}}&&
+v_9\\
+v_2\ar@{-}[rr]|{_{12}}\ar@{-}[rrdd]|(.3){_{8}}
+\ar@{-}[rrddd]|(.4){_{26}}&&v_{10}\\
+v_3\ar@{-}[rr]|(.2){_{22}}\ar@{-}[rrdd]|(.3){_{11}}&&v_{11}\\
+v_4\ar@{-}[rruuu]|(.6){_{12}}\ar@{-}[rr]|(.2){_{36}}
+\ar@{-}[rrdd]|(.7){_{25}}&&v_{12}\\
+v_5\ar@{-}[rruu]|(.42){_{41}}\ar@{-}[rru]|(.4){_{40}}
+\ar@{-}[rr]|(.75){_{11}}\ar@{-}[rrd]|(.6){_{4}}\ar@{-}[rrdd]|{_{8}}
+\ar@{-}[rrddd]|{_{35}}\ar@{-}[rrdddd]|{_{32}}&&v_{13}\\
+v_6\ar@{-}[rruuuuu]|(.7){_{13}}&&v_{14}\\
+v_7\ar@{-}[rruuuuu]|(.15){_{19}}&&v_{15}\\
+v_8\ar@{-}[rruuuuuu]|(.25){_{39}}\ar@{-}[rruuuuu]|(.65){_{15}}&&
+v_{16}\\
+&&v_{17}\\
+}
+
+\medskip
+
+\noindent\hfil
+Fig.~3. An example of the assignment problem.
+
+\medskip
+
+Similarly, the perfect assignment problem can be naturally formulated
+as the following LP problem:
+
+\noindent
+\hspace{1in}minimize (or maximize)
+$$z=\sum_{(i,j)\in E}c_{ij}x_{ij}\eqno(15)$$
+\hspace{1in}subject to
+$$\sum_{(i,j)\in E}x_{ij}=1\ \ \ \hbox{for all}\ i\in R\eqno(16)$$
+$$\sum_{(i,j)\in E}x_{ij}=1\ \ \ \hbox{for all}\ j\in S\eqno(17)$$
+$$\ \ \ \ \ \ \ \ 0\leq x_{ij}\leq 1\ \ \ \hbox{for all}\ (i,j)\in E
+\eqno(18)$$
+
+\noindent
+where variables $x_{ij}$ have the same meaning as for (11)---(14)
+above.
+
+In GLPK an undirected bipartite graph $G=(R\cup S,E)$ is represented as
+directed graph $\overline{G}=(V,A)$, where $V=R\cup S$ and
+$A=\{(i,j):(i,j)\in E\}$, i.e. every edge $(i,j)\in E$ in $G$
+corresponds to arc $(i\rightarrow j)\in A$ in $\overline{G}$.
+
+\newpage
+
+\setlength{\parskip}{4.4pt}
+
+\subsection{glp\_read\_asnprob --- read assignment problem data in
+DIMACS format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_read_asnprob(glp_graph *G, int v_set, int a_cost, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_read_asnprob| reads the assignment problem data
+from a text file in DIMACS format.
+
+The parameter \verb|G| specifies the graph object, to which the problem
+data have to be stored. Note that before reading data the current
+content of the graph object is completely erased with the routine
+\verb|glp_erase_graph|.
+
+The parameter \verb|v_set| specifies an offset of the field of type
+\verb|int| in the vertex data block, to which the routine stores the
+node set indicator:
+
+0 --- the node is in set $R$;
+
+1 --- the node is in set $S$.
+
+\noindent
+If \verb|v_set| $<0$, the node set indicator is not stored.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, to which the routine stores the
+edge cost $c_{ij}$. If \verb|a_cost| $<0$, the edge cost is not stored.
+
+The character string \verb|fname| specifies the name of a text file to
+be read in. (If the file name name ends with the suffix `\verb|.gz|',
+the file is assumed to be compressed, in which case the routine
+decompresses it ``on the fly''.)
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+\para{Example.} Below here is an example program that read the
+assignment problem data in DIMACS format from a text file
+`\verb|sample.asn|'.
+
+\begin{footnotesize}
+\begin{verbatim}
+typedef struct
+{ /* vertex data block */
+ ...
+ int set;
+ ...
+} v_data;
+
+typedef struct
+{ /* arc data block */
+ ...
+ double cost;
+ ...
+} a_data;
+
+int main(void)
+{ glp_graph *G;
+ int ret;
+ G = glp_create_graph(sizeof(v_data), sizeof(a_data));
+ ret = glp_read_asnprob(G, offsetof(v_data, set),
+ offsetof(a_data, cost), "sample.asn");
+ if (ret != 0) goto ...
+ ...
+}
+\end{verbatim}
+\end{footnotesize}
+
+\setlength{\parskip}{5pt}
+
+\newpage
+
+\para{DIMACS assignment problem format\footnote{This material is based
+on the paper ``The First DIMACS International Algorithm Implementation
+Challenge: Problem Definitions and Specifications'', which is
+publicly available at \url{http://dimacs.rutgers.edu/Challenges/}.}}
+\label{subsecasnprob}
+
+The DIMACS input file is a plain ASCII text file. It contains
+{\it lines} of several types described below. A line is terminated with
+an end-of-line character. Fields in each line are separated by at least
+one blank space. Each line begins with a one-character designator to
+identify the line type.
+
+Note that DIMACS requires all numerical quantities to be integers in
+the range $[-2^{31},\ 2^{31}-1]$ while GLPK allows the quantities to be
+floating-point numbers.
+
+\para{Comment lines.} Comment lines give human-readable information
+about the file and are ignored by programs. Comment lines can appear
+anywhere in the file. Each comment line begins with a lower-case
+character \verb|c|.
+
+\begin{verbatim}
+ c This is a comment line
+\end{verbatim}
+
+\para{Problem line.} There is one problem line per data file. The
+problem line must appear before any node or arc descriptor lines. It
+has the following format:
+
+\begin{verbatim}
+ p asn NODES EDGES
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|p| signifies that this is a problem line.
+The three-character problem designator \verb|asn| identifies the file as
+containing specification information for the assignment problem.
+The \verb|NODES| field contains an integer value specifying the total
+number of nodes in the graph (i.e. in both sets $R$ and $S$). The
+\verb|EDGES| field contains an integer value specifying the number of
+edges in the graph.
+
+\para{Node descriptors.} All node descriptor lines must appear before
+all edge descriptor lines. The node descriptor lines lists the nodes in
+set $R$ only, and all other nodes are assumed to be in set $S$. There
+is one node descriptor line for each such node, with the following
+format:
+
+\begin{verbatim}
+ n ID
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|n| signifies that this is a node
+descriptor line. The \verb|ID| field gives a node identification number,
+an integer between 1 and \verb|NODES|.
+
+\para{Edge descriptors.} There is one edge descriptor line for each
+edge in the graph. Edge descriptor lines are of the following format:
+
+\begin{verbatim}
+ a SRC DST COST
+\end{verbatim}
+
+\noindent
+The lower-case character \verb|a| signifies that this is an edge
+descriptor line. For each edge $(i,j)$, where $i\in R$ and $j\in S$,
+the \verb|SRC| field gives the identification number of vertex $i$, and
+the \verb|DST| field gives the identification number of vertex $j$.
+Identification numbers are integers between 1 and \verb|NODES|. The
+\verb|COST| field contains the cost of edge $(i,j)$.
+
+\para{Example.} Below here is an example of the data file in DIMACS
+format corresponding to the assignment problem shown on Fig~3.
+
+\begin{footnotesize}
+\begin{verbatim}
+c sample.asn
+c
+c This is an example of the assignment problem data
+c in DIMACS format.
+c
+p asn 17 22
+c
+n 1
+n 2
+n 3
+n 4
+n 5
+n 6
+n 7
+n 8
+c
+a 1 9 13
+a 1 10 21
+a 1 12 20
+a 2 10 12
+a 2 12 8
+a 2 13 26
+a 3 11 22
+a 3 13 11
+a 4 9 12
+a 4 12 36
+a 4 14 25
+a 5 11 41
+a 5 12 40
+a 5 13 11
+a 5 14 4
+a 5 15 8
+a 5 16 35
+a 5 17 32
+a 6 9 13
+a 7 10 19
+a 8 10 39
+a 8 11 15
+c
+c eof
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_write\_asnprob --- write assignment problem data in
+DIMACS format}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_write_asnprob(glp_graph *G, int v_set, int a_cost, const char *fname);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_write_asnprob| writes the assignment problem data
+to a text file in DIMACS format.
+
+The parameter \verb|G| is the graph program object, which specifies the
+assignment problem instance.
+
+The parameter \verb|v_set| specifies an offset of the field of type
+\verb|int| in the vertex data block, which contains the node set
+indicator:
+
+0 --- the node is in set $R$;
+
+1 --- the node is in set $S$.
+
+\noindent
+If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs
+is in set $R$, and a node having no outgoing arcs is in set $S$.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $c_{ij}$, the edge
+cost. If \verb|a_cost| $<0$, it is assumed that $c_{ij}=1$ for all
+edges.
+
+\newpage
+
+The character string \verb|fname| specifies a name of the text file to
+be written out. (If the file name ends with suffix `\verb|.gz|', the
+file is assumed to be compressed, in which case the routine performs
+automatic compression on writing it.)
+
+\para{Note}
+
+The routine \verb|glp_write_asnprob| does not check that the specified
+graph object correctly represents a bipartite graph. To make sure that
+the problem data are correct, use the routine \verb|glp_check_asnprob|.
+
+\returns
+
+If the operation was successful, the routine returns zero. Otherwise,
+it prints an error message and returns non-zero.
+
+\vspace*{-4pt}
+
+\subsection{glp\_check\_asnprob --- check correctness of assignment
+problem data}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_check_asnprob(glp_graph *G, int v_set);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_check_asnprob| checks that the specified graph
+object \verb|G| correctly represents a bipartite graph.
+
+The parameter \verb|v_set| specifies an offset of the field of type
+\verb|int| in the vertex data block, which contains the node set
+indicator:
+
+0 --- the node is in set $R$;
+
+1 --- the node is in set $S$.
+
+\noindent
+If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs
+is in set $R$, and a node having no outgoing arcs is in set $S$.
+
+\returns
+
+0 --- the data are correct;
+
+1 --- the set indicator of some node is 0, however, that node has one
+or more incoming arcs;
+
+2 --- the set indicator of some node is 1, however, that node has one
+or more outgoing arcs;
+
+3 --- the set indicator of some node is invalid (neither 0 nor 1);
+
+4 --- some node has both incoming and outgoing arcs.
+
+\subsection{glp\_asnprob\_lp --- convert assignment problem to LP}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_asnprob_lp(glp_prob *P, int form, glp_graph *G, int names, int v_set,
+ int a_cost);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_asnprob_lp| builds LP problem, which corresponds
+to the specified assignment problem.
+
+\newpage
+
+The parameter \verb|P| is the resultant LP problem object to be built.
+Note that on entry its current content is erased with the routine
+\verb|glp_erase_prob|.
+
+The parameter \verb|form| defines which LP formulation should be used:
+
+\verb|GLP_ASN_MIN| --- perfect matching (15)---(18), minimization;
+
+\verb|GLP_ASN_MAX| --- perfect matching (15)---(18), maximization;
+
+\verb|GLP_ASN_MMP| --- maximum weighted matching (11)---(14).
+
+The parameter \verb|G| is the graph program object, which specifies the
+assignment problem instance.
+
+The parameter \verb|names| is a flag. If it is \verb|GLP_ON|, the
+routine uses symbolic names of the graph object components to assign
+symbolic names to the LP problem object components. If the \verb|flag|
+is \verb|GLP_OFF|, no symbolic names are assigned.
+
+The parameter \verb|v_set| specifies an offset of the field of type
+\verb|int| in the vertex data block, which contains the node set
+indicator:
+
+0 --- the node is in set $R$;
+
+1 --- the node is in set $S$.
+
+\noindent
+If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs
+is in set $R$, and a node having no outgoing arcs is in set $S$.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $c_{ij}$, the edge
+cost. If \verb|a_cost| $<0$, it is assumed that $c_{ij}=1$ for all
+edges.
+
+\returns
+
+If the LP problem has been successfully built, the routine
+\verb|glp_asnprob_lp| returns zero, otherwise, non-zero (see the
+routine \verb|glp_check_asnprob|).
+
+\para{Example}
+
+The example program below reads the assignment problem instance in
+DIMACS format from file `\verb|sample.asn|', converts the instance to
+LP (11)---(14), and writes the resultant LP in CPLEX format to file
+`\verb|matching.lp|'.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <glpk.h>
+
+typedef struct { int set; } v_data;
+typedef struct { double cost; } a_data;
+
+int main(void)
+{ glp_graph *G;
+ glp_prob *P;
+ G = glp_create_graph(sizeof(v_data), sizeof(a_data));
+ glp_read_asnprob(G, offsetof(v_data, set),
+ offsetof(a_data, cost), "sample.asn");
+ P = glp_create_prob();
+ glp_asnprob_lp(P, GLP_ASN_MMP, G, GLP_ON,
+ offsetof(v_data, set), offsetof(a_data, cost));
+ glp_delete_graph(G);
+ glp_write_lp(P, NULL, "matching.lp");
+ glp_delete_prob(P);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+If `\verb|sample.asn|' is the example data file from the subsection
+describing \verb|glp_read_asnprob|, file `\verb|matching.lp|' may look
+like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+Maximize
+ obj: + 20 x(1,12) + 21 x(1,10) + 13 x(1,9) + 26 x(2,13) + 8 x(2,12)
+ + 12 x(2,10) + 11 x(3,13) + 22 x(3,11) + 25 x(4,14) + 36 x(4,12)
+ + 12 x(4,9) + 32 x(5,17) + 35 x(5,16) + 8 x(5,15) + 4 x(5,14)
+ + 11 x(5,13) + 40 x(5,12) + 41 x(5,11) + 13 x(6,9) + 19 x(7,10)
+ + 15 x(8,11) + 39 x(8,10)
+
+Subject To
+ r_1: + x(1,9) + x(1,10) + x(1,12) <= 1
+ r_2: + x(2,10) + x(2,12) + x(2,13) <= 1
+ r_3: + x(3,11) + x(3,13) <= 1
+ r_4: + x(4,9) + x(4,12) + x(4,14) <= 1
+ r_5: + x(5,11) + x(5,12) + x(5,13) + x(5,14) + x(5,15) + x(5,16)
+ + x(5,17) <= 1
+ r_6: + x(6,9) <= 1
+ r_7: + x(7,10) <= 1
+ r_8: + x(8,10) + x(8,11) <= 1
+ r_9: + x(6,9) + x(4,9) + x(1,9) <= 1
+ r_10: + x(8,10) + x(7,10) + x(2,10) + x(1,10) <= 1
+ r_11: + x(8,11) + x(5,11) + x(3,11) <= 1
+ r_12: + x(5,12) + x(4,12) + x(2,12) + x(1,12) <= 1
+ r_13: + x(5,13) + x(3,13) + x(2,13) <= 1
+ r_14: + x(5,14) + x(4,14) <= 1
+ r_15: + x(5,15) <= 1
+ r_16: + x(5,16) <= 1
+ r_17: + x(5,17) <= 1
+
+Bounds
+ 0 <= x(1,12) <= 1
+ 0 <= x(1,10) <= 1
+ 0 <= x(1,9) <= 1
+ 0 <= x(2,13) <= 1
+ 0 <= x(2,12) <= 1
+ 0 <= x(2,10) <= 1
+ 0 <= x(3,13) <= 1
+ 0 <= x(3,11) <= 1
+ 0 <= x(4,14) <= 1
+ 0 <= x(4,12) <= 1
+ 0 <= x(4,9) <= 1
+ 0 <= x(5,17) <= 1
+ 0 <= x(5,16) <= 1
+ 0 <= x(5,15) <= 1
+ 0 <= x(5,14) <= 1
+ 0 <= x(5,13) <= 1
+ 0 <= x(5,12) <= 1
+ 0 <= x(5,11) <= 1
+ 0 <= x(6,9) <= 1
+ 0 <= x(7,10) <= 1
+ 0 <= x(8,11) <= 1
+ 0 <= x(8,10) <= 1
+
+End
+\end{verbatim}
+\end{footnotesize}
+
+\newpage
+
+\subsection{glp\_asnprob\_okalg --- solve assignment problem with
+out-of-kilter\\algorithm}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_asnprob_okalg(int form, glp_graph *G, int v_set, int a_cost,
+ double *sol, int a_x);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_mincost_okalg| finds optimal solution to the
+assignment problem with the out-of-kilter
+algorithm.\footnote{GLPK implementation of the out-of-kilter algorithm
+is based on the following book: L.~R.~Ford,~Jr., and D.~R.~Fulkerson,
+``Flows in Networks,'' The RAND Corp., Report R-375-PR (August 1962),
+Chap. III ``Minimal Cost Flow Problems,'' pp.~113-26.} Note that this
+routine requires all the problem data to be integer-valued.
+
+The parameter \verb|form| defines which LP formulation should be used:
+
+\verb|GLP_ASN_MIN| --- perfect matching (15)---(18), minimization;
+
+\verb|GLP_ASN_MAX| --- perfect matching (15)---(18), maximization;
+
+\verb|GLP_ASN_MMP| --- maximum weighted matching (11)---(14).
+
+The parameter \verb|G| is the graph program object, which specifies the
+assignment problem instance.
+
+The parameter \verb|v_set| specifies an offset of the field of type
+\verb|int| in the vertex data block, which contains the node set
+indicator:
+
+0 --- the node is in set $R$;
+
+1 --- the node is in set $S$.
+
+\noindent
+If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs
+is in set $R$, and a node having no outgoing arcs is in set $S$.
+
+The parameter \verb|a_cost| specifies an offset of the field of type
+\verb|double| in the arc data block, which contains $c_{ij}$, the edge
+cost. This value must be integer in the range [\verb|-INT_MAX|,
+\verb|+INT_MAX|]. If \verb|a_cost| $<0$, it is assumed that $c_{ij}=1$
+for all edges.
+
+The parameter \verb|sol| specifies a location, to which the routine
+stores the objective value (that is, the total cost) found.
+If \verb|sol| is \verb|NULL|, the objective value is not stored.
+
+The parameter \verb|a_x| specifies an offset of the field of type
+\verb|int| in the arc data block, to which the routine stores $x_{ij}$.
+If \verb|a_x| $<0$, this value is not stored.
+
+\returns
+
+\begin{retlist}
+0 & Optimal solution found.\\
+
+\verb|GLP_ENOPFS| & No (primal) feasible solution exists.\\
+
+\verb|GLP_EDATA| & Unable to start the search, because the assignment
+problem data are either incorrect (this error is detected by the
+routine \verb|glp_check_asnprob|), not integer-valued or out of range.\\
+
+\verb|GLP_ERANGE| & The search was prematurely terminated because of
+integer overflow.\\
+
+\verb|GLP_EFAIL| & An error has been detected in the program logic.
+(If this code is returned for your problem instance, please report to
+\verb|<bug-glpk@gnu.org>|.)\\
+\end{retlist}
+
+\newpage
+
+\para{Comments}
+
+Since the out-of-kilter algorithm is designed to find a minimal cost
+circulation, the routine \verb|glp_asnprob_okalg| converts the original
+graph to a network suitable for this algorithm in the following
+way:\footnote{The conversion is performed internally and does not
+change the original graph program object passed to the routine.}
+
+1) it replaces each edge $(i,j)$ by arc $(i\rightarrow j)$,
+flow $x_{ij}$ through which has zero lower bound ($l_{ij}=0$), unity
+upper bound ($u_{ij}=1$), and per-unit cost $+c_{ij}$ (in case of
+\verb|GLP_ASN_MIN|), or $-c_{ij}$ (in case of \verb|GLP_ASN_MAX| and
+\verb|GLP_ASN_MMP|);
+
+2) then it adds one auxiliary feedback node $k$;
+
+3) for each original node $i\in R$ the routine adds auxiliary supply
+arc $(k\rightarrow i)$, flow $x_{ki}$ through which is costless
+($c_{ki}=0$) and either fixed at 1 ($l_{ki}=u_{ki}=1$, in case of
+\verb|GLP_ASN_MIN| and \verb|GLP_ASN_MAX|) or has zero lower bound and
+unity upper bound ($l_{ij}=0$, $u_{ij}=1$, in case of
+\verb|GLP_ASN_MMP|);
+
+4) similarly, for each original node $j\in S$ the routine adds
+auxiliary demand arc $(j\rightarrow k)$, flow $x_{jk}$ through which is
+costless ($c_{jk}=0$) and either fixed at 1 ($l_{jk}=u_{jk}=1$, in case
+of \verb|GLP_ASN_MIN| and \verb|GLP_ASN_MAX|) or has zero lower bound
+and unity upper bound ($l_{jk}=0$, $u_{jk}=1$, in case of
+\verb|GLP_ASN_MMP|).
+
+\para{Example}
+
+The example program shown below reads the assignment problem instance
+in DIMACS format from file `\verb|sample.asn|', solves it by using the
+routine \verb|glp_asnprob_okalg|, and writes the solution found to the
+standard output.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { int set; } v_data;
+typedef struct { double cost; int x; } e_data;
+
+#define node(v) ((v_data *)((v)->data))
+#define edge(e) ((e_data *)((e)->data))
+
+int main(void)
+{ glp_graph *G;
+ glp_vertex *v;
+ glp_arc *e;
+ int i, ret;
+ double sol;
+ G = glp_create_graph(sizeof(v_data), sizeof(e_data));
+ glp_read_asnprob(G, offsetof(v_data, set),
+ offsetof(e_data, cost), "sample.asn");
+ ret = glp_asnprob_okalg(GLP_ASN_MMP, G,
+ offsetof(v_data, set), offsetof(e_data, cost), &sol,
+ offsetof(e_data, x));
+ printf("ret = %d; sol = %5g\n", ret, sol);
+ for (i = 1; i <= G->nv; i++)
+ { v = G->v[i];
+ for (e = v->out; e != NULL; e = e->t_next)
+ printf("edge %2d %2d: x = %d; c = %g\n",
+ e->tail->i, e->head->i, edge(e)->x, edge(e)->cost);
+ }
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+If `\verb|sample.asn|' is the example data file from the subsection
+describing \verb|glp_read_asnprob|, the output may look like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading assignment problem data from `sample.asn'...
+Assignment problem has 8 + 9 = 17 nodes and 22 arcs
+38 lines were read
+ret = 0; sol = 180
+edge 1 12: x = 1; c = 20
+edge 1 10: x = 0; c = 21
+edge 1 9: x = 0; c = 13
+edge 2 13: x = 1; c = 26
+edge 2 12: x = 0; c = 8
+edge 2 10: x = 0; c = 12
+edge 3 13: x = 0; c = 11
+edge 3 11: x = 1; c = 22
+edge 4 14: x = 1; c = 25
+edge 4 12: x = 0; c = 36
+edge 4 9: x = 0; c = 12
+edge 5 17: x = 0; c = 32
+edge 5 16: x = 1; c = 35
+edge 5 15: x = 0; c = 8
+edge 5 14: x = 0; c = 4
+edge 5 13: x = 0; c = 11
+edge 5 12: x = 0; c = 40
+edge 5 11: x = 0; c = 41
+edge 6 9: x = 1; c = 13
+edge 7 10: x = 0; c = 19
+edge 8 11: x = 0; c = 15
+edge 8 10: x = 1; c = 39
+\end{verbatim}
+\end{footnotesize}
+
+\subsection{glp\_asnprob\_hall --- find bipartite matching of maximum
+cardinality}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_asnprob_hall(glp_graph *G, int v_set, int a_x);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_asnprob_hall| finds a matching of maximal
+cardinality in the specified bipartite graph. It uses a version of the
+Fortran routine \verb|MC21A| developed by
+I.~S.~Duff\footnote{I.~S.~Duff, Algorithm 575: Permutations for
+zero-free diagonal, ACM Trans. on Math. Softw. 7 (1981),\linebreak
+pp.~387-390.}, which implements Hall's algorithm.\footnote{M.~Hall,
+``An Algorithm for Distinct Representatives,'' Am. Math. Monthly 63
+(1956), pp.~716-717.}
+
+The parameter \verb|G| is a pointer to the graph program object.
+
+The parameter \verb|v_set| specifies an offset of the field of type
+\verb|int| in the vertex data block, which contains the node set
+indicator:
+
+0 --- the node is in set $R$;
+
+1 --- the node is in set $S$.
+
+\newpage
+
+\noindent
+If \verb|v_set| $<0$, it is assumed that a node having no incoming arcs
+is in set $R$, and a node having no outgoing arcs is in set $S$.
+
+The parameter \verb|a_x| specifies an offset of the field of type
+\verb|int| in the arc data block, to which the routine stores $x_{ij}$.
+If \verb|a_x| $<0$, this value is not stored.
+
+\returns
+
+The routine \verb|glp_asnprob_hall| returns the cardinality of the
+matching found. However, if the specified graph is incorrect (as
+detected by the routine \verb|glp_check_asnprob|), this routine returns
+a negative value.
+
+\para{Comments}
+
+The same solution may be obtained with the routine
+\verb|glp_asnprob_okalg| (for LP formulation \verb|GLP_ASN_MMP| and
+all edge costs equal to 1). However, the routine
+\verb|glp_asnprob_hall| is much faster.
+
+\para{Example}
+
+The example program shown below reads the assignment problem instance
+in DIMACS format from file `\verb|sample.asn|', finds a bipartite
+matching of maximal cardinality by using the routine
+\verb|glp_asnprob_hall|, and writes the solution found to the standard
+output.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { int set; } v_data;
+typedef struct { int x; } e_data;
+
+#define node(v) ((v_data *)((v)->data))
+#define edge(e) ((e_data *)((e)->data))
+
+int main(void)
+{ glp_graph *G;
+ glp_vertex *v;
+ glp_arc *e;
+ int i, card;
+ G = glp_create_graph(sizeof(v_data), sizeof(e_data));
+ glp_read_asnprob(G, offsetof(v_data, set), -1,
+ "sample.asn");
+ card = glp_asnprob_hall(G, offsetof(v_data, set),
+ offsetof(e_data, x));
+ printf("card = %d\n", card);
+ for (i = 1; i <= G->nv; i++)
+ { v = G->v[i];
+ for (e = v->out; e != NULL; e = e->t_next)
+ printf("edge %2d %2d: x = %d\n",
+ e->tail->i, e->head->i, edge(e)->x);
+ }
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+If `\verb|sample.asn|' is the example data file from the subsection
+describing \verb|glp_read_asnprob|, the output may look like follows:
+
+\newpage
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading assignment problem data from `sample.asn'...
+Assignment problem has 8 + 9 = 17 nodes and 22 arcs
+38 lines were read
+card = 7
+edge 1 12: x = 1
+edge 1 10: x = 0
+edge 1 9: x = 0
+edge 2 13: x = 1
+edge 2 12: x = 0
+edge 2 10: x = 0
+edge 3 13: x = 0
+edge 3 11: x = 1
+edge 4 14: x = 1
+edge 4 12: x = 0
+edge 4 9: x = 0
+edge 5 17: x = 1
+edge 5 16: x = 0
+edge 5 15: x = 0
+edge 5 14: x = 0
+edge 5 13: x = 0
+edge 5 12: x = 0
+edge 5 11: x = 0
+edge 6 9: x = 1
+edge 7 10: x = 1
+edge 8 11: x = 0
+edge 8 10: x = 0
+\end{verbatim}
+\end{footnotesize}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newpage
+
+\section{Critical path problem}
+
+\subsection{Background}
+
+The {\it critical path problem} (CPP) is stated as follows. Let there
+be given a project $J$, which is a set of jobs (tasks, activities,
+etc.). Performing each job $i\in J$ requires time $t_i\geq 0$. Besides,
+over the set $J$ there is given a precedence relation
+$R\subseteq J\times J$, where $(i,j)\in R$ means that job $i$
+immediately precedes job $j$, i.e. performing job $j$ cannot start
+until job $i$ has been completely performed. The problem is to find
+starting times $x_i$ for each job $i\in J$, which satisfy to the
+precedence relation and minimize the total duration (makespan) of the
+project.
+
+The following is an example of the critical path problem:
+
+\bigskip
+
+\begin{center}
+\begin{tabular}{|c|l|c|c|}
+\hline
+Job&Desription&Time&Predecessors\\
+\hline
+A&Excavate&3&---\\
+B&Lay foundation&4&A\\
+C&Rough plumbing&3&B\\
+D&Frame&10&B\\
+E&Finish exterior&8&D\\
+F&Install HVAC&4&D\\
+G&Rough electric&6&D\\
+H&Sheet rock&8&C, E, F, G\\
+I&Install cabinets&5&H\\
+J&Paint&5&H\\
+K&Final plumbing&4&I\\
+L&Final electric&2&J\\
+M&Install flooring&4&K, L\\
+\hline
+\end{tabular}
+\end{center}
+
+\bigskip
+
+Obviously, the project along with the precedence relation can be
+represented as a directed graph $G=(J,R)$ called {\it project network},
+where each node $i\in J$ corresponds to a job, and arc
+$(i\rightarrow j)\in R$ means that job $i$ immediately precedes job
+$j$.\footnote{There exists another network representation of the
+critical path problem, where jobs correspond to arcs while nodes
+correspond to events introduced to express the precedence relation.
+That representation, however, is much less convenient than the one,
+where jobs are represented as nodes of the network.} The project network
+for the example above is shown on Fig.~4.
+
+\hspace*{.5in}
+\xymatrix
+{&&&C|3\ar[rd]&&I|5\ar[r]&K|4\ar[rd]&\\
+A|3\ar[r]&B|4\ar[rru]\ar[rd]&&E|8\ar[r]&H|8\ar[ru]\ar[rd]&&&M|4\\
+&&D|10\ar[ru]\ar[r]\ar[rd]&F|4\ar[ru]&&J|5\ar[r]&L|2\ar[ru]&\\
+&&&G|6\ar[ruu]&&&&\\
+}
+
+\medskip
+
+\noindent\hfil
+Fig.~4. An example of the project network.
+
+\newpage
+
+May note that the project network must be acyclic; otherwise, it would
+be impossible to satisfy to the precedence relation for any job that
+belongs to a cycle.
+
+The critical path problem can be naturally formulated as the following
+LP problem:
+
+\medskip
+
+\noindent
+\hspace{.5in}minimize
+$$z\eqno(19)$$
+\hspace{.5in}subject to
+$$x_i+t_i\leq z\ \ \ \hbox{for all}\ i\in J\ \ \ \ \eqno(20)$$
+$$x_i+t_i\leq x_j\ \ \ \hbox{for all}\ (i,j)\in R\eqno(21)$$
+$$x_i\geq 0\ \ \ \ \ \ \ \hbox{for all}\ i\in J\ \ \eqno(22)$$
+
+The inequality constraints (21), which are active in the optimal
+solution, define so called {\it critical path} having the following
+property: the minimal project duration $z$ can be decreased only by
+decreasing the times $t_j$ for jobs on the critical path, and delaying
+any critical job delays the entire project.
+
+\subsection{glp\_cpp --- solve critical path problem}
+
+\synopsis
+
+\begin{verbatim}
+ double glp_cpp(glp_graph *G, int v_t, int v_es, int v_ls);
+\end{verbatim}
+
+\description
+
+The routine \verb|glp_cpp| solves the critical path problem represented
+in the form of the project network.
+
+The parameter \verb|G| is a pointer to the graph object, which
+specifies the project network. This graph must be acyclic. Multiple
+arcs are allowed being considered as single arcs.
+
+The parameter \verb|v_t| specifies an offset of the field of type
+\verb|double| in the vertex data block, which contains time $t_i\geq 0$
+needed to perform corresponding job $j\in J$. If \verb|v_t| $<0$, it is
+assumed that $t_i=1$ for all jobs.
+
+The parameter \verb|v_es| specifies an offset of the field of type
+\verb|double| in the vertex data block, to which the routine stores
+the {\it earliest start time} for corresponding job. If \verb|v_es|
+$<0$, this time is not stored.
+
+The parameter \verb|v_ls| specifies an offset of the field of type
+\verb|double| in the vertex data block, to which the routine stores
+the {\it latest start time} for corresponding job. If \verb|v_ls|
+$<0$, this time is not stored.
+
+The difference between the latest and earliest start times of some job
+is called its {\it time reserve}. Delaying a job within its time
+reserve does not affect the project duration, so if the time reserve is
+zero, the corresponding job is critical.
+
+\para{Returns}
+
+The routine \verb|glp_cpp| returns the minimal project duration, i.e.
+minimal time needed to perform all jobs in the project.
+
+\newpage
+
+\para{Example}
+
+The example program below solves the critical path problem shown on
+Fig.~4 by using the routine \verb|glp_cpp| and writes the solution
+found on the standard output.
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { double t, es, ls; } v_data;
+
+#define node(v) ((v_data *)((v)->data))
+
+int main(void)
+{ glp_graph *G;
+ int i;
+ double t, es, ef, ls, lf, total;
+ G = glp_create_graph(sizeof(v_data), 0);
+ glp_add_vertices(G, 13);
+ node(G->v[1])->t = 3; /* A: Excavate */
+ node(G->v[2])->t = 4; /* B: Lay foundation */
+ node(G->v[3])->t = 3; /* C: Rough plumbing */
+ node(G->v[4])->t = 10; /* D: Frame */
+ node(G->v[5])->t = 8; /* E: Finish exterior */
+ node(G->v[6])->t = 4; /* F: Install HVAC */
+ node(G->v[7])->t = 6; /* G: Rough elecrtic */
+ node(G->v[8])->t = 8; /* H: Sheet rock */
+ node(G->v[9])->t = 5; /* I: Install cabinets */
+ node(G->v[10])->t = 5; /* J: Paint */
+ node(G->v[11])->t = 4; /* K: Final plumbing */
+ node(G->v[12])->t = 2; /* L: Final electric */
+ node(G->v[13])->t = 4; /* M: Install flooring */
+ glp_add_arc(G, 1, 2); /* A precedes B */
+ glp_add_arc(G, 2, 3); /* B precedes C */
+ glp_add_arc(G, 2, 4); /* B precedes D */
+ glp_add_arc(G, 4, 5); /* D precedes E */
+ glp_add_arc(G, 4, 6); /* D precedes F */
+ glp_add_arc(G, 4, 7); /* D precedes G */
+ glp_add_arc(G, 3, 8); /* C precedes H */
+ glp_add_arc(G, 5, 8); /* E precedes H */
+ glp_add_arc(G, 6, 8); /* F precedes H */
+ glp_add_arc(G, 7, 8); /* G precedes H */
+ glp_add_arc(G, 8, 9); /* H precedes I */
+ glp_add_arc(G, 8, 10); /* H precedes J */
+ glp_add_arc(G, 9, 11); /* I precedes K */
+ glp_add_arc(G, 10, 12); /* J precedes L */
+ glp_add_arc(G, 11, 13); /* K precedes M */
+ glp_add_arc(G, 12, 13); /* L precedes M */
+ total = glp_cpp(G, offsetof(v_data, t), offsetof(v_data, es),
+ offsetof(v_data, ls));
+ printf("Minimal project duration is %.2f\n\n", total);
+ printf("Job Time ES EF LS LF\n");
+ printf("--- ------ ------ ------ ------ ------\n");
+ for (i = 1; i <= G->nv; i++)
+ { t = node(G->v[i])->t;
+ es = node(G->v[i])->es;
+ ef = es + node(G->v[i])->t;
+ ls = node(G->v[i])->ls;
+ lf = ls + node(G->v[i])->t;
+ printf("%3d %6.2f %s %6.2f %6.2f %6.2f %6.2f\n",
+ i, t, ls - es < 0.001 ? "*" : " ", es, ef, ls, lf);
+ }
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+The output from the example program shown below includes job number,
+the time needed to perform a job, earliest start time (\verb|ES|),
+earliest finish time (\verb|EF|), latest start time (\verb|LS|), and
+latest finish time (\verb|LF|) for each job in the project. Critical
+jobs are marked by asterisks.
+
+\begin{footnotesize}
+\begin{verbatim}
+Minimal project duration is 46.00
+
+Job Time ES EF LS LF
+--- ------ ------ ------ ------ ------
+ 1 3.00 * 0.00 3.00 0.00 3.00
+ 2 4.00 * 3.00 7.00 3.00 7.00
+ 3 3.00 7.00 10.00 22.00 25.00
+ 4 10.00 * 7.00 17.00 7.00 17.00
+ 5 8.00 * 17.00 25.00 17.00 25.00
+ 6 4.00 17.00 21.00 21.00 25.00
+ 7 6.00 17.00 23.00 19.00 25.00
+ 8 8.00 * 25.00 33.00 25.00 33.00
+ 9 5.00 * 33.00 38.00 33.00 38.00
+ 10 5.00 33.00 38.00 35.00 40.00
+ 11 4.00 * 38.00 42.00 38.00 42.00
+ 12 2.00 38.00 40.00 40.00 42.00
+ 13 4.00 * 42.00 46.00 42.00 46.00
+\end{verbatim}
+\end{footnotesize}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\end{document}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Graph Optimization API Routines}
+
+\section{Maximum clique problem}
+
+\subsection{Background}
+
+The {\it maximum clique problem (MCP)} is a classic combinatorial
+optimization problem. Given an undirected graph $G=(V,E)$, where $V$ is
+a set of vertices, and $E$ is a set of edges, this problem is to find
+the largest {\it clique} $C\subseteq G$, i.e. the largest induced
+complete subgraph. A generalization of this problem is the {\it maximum
+weight clique problem (MWCP)}, which is to find a clique $C\subseteq G$
+of the largest weight $\displaystyle\sum_{v\in C}w(v)\rightarrow\max$,
+where $w(v)$ is a weight of vertex $v\in V$.
+
+An example of the maximum weight clique problem is shown on Fig.~5.
+
+\begin{figure}
+\noindent\hfil
+\begin{tabular}{c}
+{\xymatrix %@C=16pt
+{&&&{v_1}\ar@{-}[lllddd]\ar@{-}[llddddd]\ar@{-}[dddddd]
+\ar@{-}[rrrddd]&&&\\
+&{v_2}\ar@{-}[rrrr]\ar@{-}[rrrrdddd]\ar@{-}[rrddddd]\ar@{-}[dddd]&&&&
+{v_3}\ar@{-}[llllldd]\ar@{-}[lllldddd]\ar@{-}[dddd]&\\
+&&&&&&\\
+{v_4}\ar@{-}[rrrrrr]\ar@{-}[rrrddd]&&&&&&{v_5}\ar@{-}[lllddd]
+\ar@{-}[ldd]\\
+&&&&&&\\
+&{v_6}\ar@{-}[rrrr]&&&&{v_7}&\\
+&&&{v_8}&&&\\
+}}
+\end{tabular}
+\begin{tabular}{r@{\ }c@{\ }l}
+$w(v_1)$&=&3\\$w(v_2)$&=&4\\$w(v_3)$&=&8\\$w(v_4)$&=&1\\
+$w(v_5)$&=&5\\$w(v_6)$&=&2\\$w(v_7)$&=&1\\$w(v_8)$&=&3\\
+\end{tabular}
+
+\bigskip
+
+\begin{center}
+Fig.~5. An example of the maximum weight clique problem.
+\end{center}
+\end{figure}
+
+\subsection{glp\_wclique\_exact --- find maximum weight clique with
+exact algorithm}
+
+\synopsis
+
+\begin{verbatim}
+ int glp_wclique_exact(glp_graph *G, int v_wgt, double *sol, int v_set);
+\end{verbatim}
+
+\description
+
+The routine {\tt glp\_wclique\_exact} finds a maximum weight clique in
+the specified undirected graph with the exact algorithm developed by
+Patric \"Osterg{\aa}rd.\footnote{P.~R.~J.~\"Osterg{\aa}rd, A new
+algorithm for the maximum-weight clique problem, Nordic J. of
+Computing, Vol.~8, No.~4, 2001, pp.~424--36.}
+
+The parameter {\tt G} is the program object, which specifies
+an undirected graph. Each arc $(x\rightarrow y)$ in {\tt G} is
+considered as edge $(x,y)$, self-loops are ignored, and multiple edges,
+if present, are replaced (internally) by simple edges.
+
+The parameter {\tt v\_wgt} specifies an offset of the field of type
+{\tt double} in the vertex data block, which contains a weight of
+corresponding vertex. Vertex weights must be integer-valued in the
+range $[0,$ {\tt INT\_MAX}$]$. If {\tt v\_wgt} $<0$, it is assumed that
+all vertices of the graph have the weight 1.
+
+\newpage
+
+The parameter {\tt sol} specifies a location, to which the routine
+stores the weight of the clique found (the clique weight is the sum
+of weights of all vertices included in the clique.) If {\tt sol} is
+{\tt NULL}, the solution is not stored.
+
+The parameter {\tt v\_set} specifies an offset of the field of type
+{\tt int} in the vertex data block, to which the routines stores a
+vertex flag: 1 means that the corresponding vertex is included in the
+clique found, and 0 otherwise. If {\tt v\_set} $<0$, vertex flags are
+not stored.
+
+\returns
+
+\begin{retlist}
+0 & Optimal solution found.\\
+
+\verb|GLP_EDATA| & Unable to start the search, because some vertex
+weights are either not integer-valued or out of range. This code is
+also returned if the sum of weights of all vertices exceeds
+{\tt INT\_MAX}. \\
+\end{retlist}
+
+\para{Notes}
+
+1. The routine {\it glp\_wclique\_exact} finds exact solution. Since
+both MCP and MWCP problems are NP-complete, the algorithm may require
+exponential time in worst cases.
+
+2. Internally the specified graph is converted to an adjacency matrix
+in {\it dense} format. This requires about $|V|^2/16$ bytes of memory,
+where $|V|$ is the number of vertices in the graph.
+
+\para{Example}
+
+The example program shown below reads a MWCP instance in DIMACS
+clique/coloring format from file `\verb|sample.clq|', finds the clique
+of largest weight, and writes the solution found on the standard
+output.
+
+\newpage
+
+\begin{footnotesize}
+\begin{verbatim}
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+typedef struct { double wgt; int set; } v_data;
+
+#define vertex(v) ((v_data *)((v)->data))
+
+int main(void)
+{ glp_graph *G;
+ glp_vertex *v;
+ int i, ret;
+ double sol;
+ G = glp_create_graph(sizeof(v_data), 0);
+ glp_read_ccdata(G, offsetof(v_data, wgt), "sample.clq");
+ ret = glp_wclique_exact(G, offsetof(v_data, wgt), &sol,
+ offsetof(v_data, set));
+ printf("ret = %d; sol = %g\n", ret, sol);
+ for (i = 1; i <= G->nv; i++)
+ { v = G->v[i];
+ printf("vertex %d: weight = %g, flag = %d\n",
+ i, vertex(v)->wgt, vertex(v)->set);
+ }
+ glp_delete_graph(G);
+ return 0;
+}
+\end{verbatim}
+\end{footnotesize}
+
+For the example shown on Fig.~5 the data file may look like follows:
+
+\begin{footnotesize}
+\begin{verbatim}
+c sample.clq
+c
+c This is an example of the maximum weight clique
+c problem in DIMACS clique/coloring format.
+c
+p edge 8 16
+n 1 3
+n 2 4
+n 3 8
+n 5 5
+n 6 2
+n 8 3
+e 1 4
+e 1 5
+e 1 6
+e 1 8
+e 2 3
+e 2 6
+e 2 7
+e 2 8
+e 3 4
+e 3 6
+e 3 7
+e 4 5
+e 4 8
+e 5 7
+e 5 8
+e 6 7
+c
+c eof
+\end{verbatim}
+\end{footnotesize}
+
+The corresponding output from the example program is the following:
+
+\begin{footnotesize}
+\begin{verbatim}
+Reading graph from `sample.clq'...
+Graph has 8 vertices and 16 edges
+28 lines were read
+ret = 0; sol = 15
+vertex 1: weight = 3, flag = 0
+vertex 2: weight = 4, flag = 1
+vertex 3: weight = 8, flag = 1
+vertex 4: weight = 1, flag = 0
+vertex 5: weight = 5, flag = 0
+vertex 6: weight = 2, flag = 1
+vertex 7: weight = 1, flag = 1
+vertex 8: weight = 3, flag = 0
+\end{verbatim}
+\end{footnotesize}
+
+\end{document}
diff --git a/glpk-5.0/doc/miplib2.txt b/glpk-5.0/doc/miplib2.txt
new file mode 100644
index 0000000..762c83f
--- /dev/null
+++ b/glpk-5.0/doc/miplib2.txt
@@ -0,0 +1,135 @@
+Solver: GLPSOL 4.40 (options used: --pcost)
+Computer: Intel Pentium 4, 3.0 GHz
+Platform: Cygwin 1.5.25
+Compiler: GCC 3.4.4 (options used: -O3)
+Test set: MIPLIB 2.0 <http://miplib.zib.de/miplib3/miplib/>
+
+Problem Optimal Solution Cuts Used Nodes Iters Time,s Mem,MB
+-------- ---------------- --------- -------- ------ ------ ------
+air01 +6.796000000e+03 3 41 < 1 1.2
+air02 +7.810000000e+03 43 201 6 13.8
+air03 +3.401600000e+05 33 414 12 21.0
+air04 +5.613700000e+04 1901 109800 396 32.4
+air05 +2.637400000e+04 6445 201649 452 45.0
+air06 +4.964900000e+04 11 6868 31 18.1
+bell3a +8.784303160e+05 --gomory 7965 42363 17 6.1
+bell3b +1.178616062e+07 --gomory 6031 30467 19 3.2
+bell4 +1.854148420e+07 --gomory 7203 25019 16 2.9
+bell5 +8.966406492e+06 --gomory 5605 18555 8 1.5
+bm23 +3.400000000e+01 373 878 < 1 0.2
+cracpb1 +2.219900000e+04 47 5258 2 1.3
+dcmulti +1.881820000e+05 743 3366 2 1.1
+diamond infeasible 3 4 < 1 0.1
+dsbmip -3.051981750e+02 --mir 217 46088 24 4.5
+egout +5.681007000e+02 91 137 < 1 0.3
+enigma +0.000000000e+00 16419 55071 6 3.2
+fixnet3 +5.197300000e+04 81 380 < 1 1.4
+fixnet4 +8.936000000e+03 211 1095 1 1.4
+fixnet6 +3.983000000e+03 1031 3136 2 1.7
+flugpl +1.201500000e+06 397 231 < 1 0.1
+gen +1.123133627e+05 195 3991 1 1.7
+khb05250 +1.069402260e+08 2163 14498 5 2.8
+l152lav +4.722000000e+03 7419 95299 68 12.0
+lp4l +2.967000000e+03 173 1331 2 1.7
+lseu +1.120000000e+03 10821 31954 5 2.5
+misc01 +5.635000000e+02 769 4593 1 0.5
+misc02 +1.690000000e+03 29 282 < 1 0.2
+misc03 +3.360000000e+03 957 6742 2 1.1
+misc04 +2.666699247e+03 17 2052 1 7.0
+misc05 +2.984500000e+03 293 2520 1 1.1
+misc06 +1.285086074e+04 57 941 < 1 2.7
+misc07 +2.810000000e+03 --mir 66075 579129 424 33.4
+mod008 +3.070000000e+02 8185 24245 8 2.3
+mod010 +6.548000000e+03 315 6283 7 5.3
+mod011
+mod013 +2.809500000e+02 545 1155 < 1 0.3
+modglob +2.074050809e+07 --mir 5197 31985 20 2.8
+noswot
+p0033 +3.089000000e+03 305 955 < 1 0.2
+p0040 +6.202700000e+04 17 66 < 1 0.1
+p0201 +7.615000000e+03 521 3660 1 0.9
+p0282 +2.584110000e+05 623 1204 1 0.8
+p0291 +5.223749000e+03 71 154 < 1 0.7
+p0548 +8.691000000e+03 7617 23556 9 2.9
+p2756 +3.124000000e+03 --mir 3911 15157 57 10.9
+p6000 -2.451377000e+06 19209 40906 570 15.8
+pipex +7.882630000e+02 1569 2469 < 1 0.4
+qiu -1.328731369e+02 80473 1918742 1174 69.2
+rentacar +3.035676098e+07 43 1649 3 12.1
+rgn +8.219999924e+01 3325 18700 2 1.2
+sample2 +3.750000000e+02 163 347 < 1 0.2
+sentoy -7.772000000e+03 335 723 < 1 0.4
+set1al +1.586975000e+04 --mir 17 532 < 1 1.5
+set1ch
+set1cl +6.484250000e+03 --mir 1 502 < 1 1.1
+stein15 +9.000000000e+00 87 375 < 1 0.2
+stein27 +1.800000000e+01 3255 15327 2 1.0
+stein45 +3.000000000e+01 52301 389140 139 19.2
+stein9 +5.000000000e+00 17 45 < 1 0.1
+vpm1 +2.000000000e+01 --mir 9 836 < 1 0.9
+
+PROBLEM CHARACTERISTICS
+
+Problem Rows Cols ( Int 0/1) Nonz Best Solution
+-------- ------ ---------------------- ------ --------------------------
+air01 24 771 ( all all) 4986 6796 (opt)
+air02 51 6774 ( all all) 68329 7810 (opt)
+air03 125 10757 ( all all) 101785 340160 (opt)
+air04 824 8904 ( all all) 81869 56138 (opt)
+air05 427 7195 ( all all) 59316 26402 (not opt)
+air06 826 8627 ( all all) 79433 49649 (opt)
+bell3a 124 133 ( 71 39) 441 878430.32 (opt)
+bell3b 124 133 ( 71 39) 441 11786160.62 (opt)
+bell4 106 117 ( 64 34) 385 18541484.20 (opt)
+bell5 92 104 ( 58 30) 340 8966406.49 (opt)
+bm23 21 27 ( all all) 505 34 (opt)
+cracpb1 144 572 ( all all) 4730 22199 (opt)
+dcmulti 291 548 ( 75 all) 1833 188182.0000 (opt)
+diamond 5 2 ( all all) 9 integer infeasible
+dsbmip 1855 1886 ( 192 160) 9768 -305.198 (opt)
+egout 99 141 ( 55 all) 392 568.101 (opt)
+enigma 22 100 ( all all) 298 0.0 (opt)
+fixnet3 479 878 ( 378 all) 2631 51973 (opt)
+fixnet4 479 878 ( 378 all) 2621 8936 (opt)
+fixnet6 479 878 ( 378 all) 2550 3983 (opt)
+flugpl 19 18 ( 11 none) 64 1201500 (opt)
+gen 781 870 ( 150 144) 3174 112313 (opt)
+khb05250 102 1350 ( 24 all) 3973 106940226 (opt)
+l152lav 98 1989 ( all all) 11911 4750 (not opt)
+lp4l 86 1086 ( all all) 5763 2967 (opt)
+lseu 29 89 ( all all) 394 1120 (opt)
+misc01 55 83 ( 82 all) 746 563.5 (opt)
+misc02 40 59 ( 58 all) 414 1690 (opt)
+misc03 97 160 ( 159 all) 2054 3360 (opt)
+misc04 1726 4897 ( 30 all) 17253 2666.699 (opt)
+misc05 301 136 ( 74 all) 2946 2984.5 (opt)
+misc06 821 1808 ( 112 all) 5860 12850.8607 (opt)
+misc07 213 260 ( 259 all) 8620 2810 (not opt)
+mod008 7 319 ( all all) 1562 307 (opt)
+mod010 147 2655 ( all all) 13858 6548 (opt)
+mod011 4482 10958 ( 96 all) 37425 -54558535 (opt)
+mod013 63 96 ( 48 all) 288 280.95 (opt)
+modglob 292 422 ( 98 all) 1390 20740508 (opt)
+noswot 183 128 ( 100 75) 760 -43 (opt)
+p0033 17 33 ( all all) 131 3089 (opt)
+p0040 24 40 ( all all) 150 62027 (opt)
+p0201 134 201 ( all all) 2124 7615 (opt)
+p0282 242 282 ( all all) 2248 258411 (opt)
+p0291 253 291 ( all all) 349 5223.7490 (opt)
+p0548 177 548 ( all all) 2127 8691 (opt)
+p2756 756 2756 ( all all) 11103 3124 (opt)
+p6000 2177 6000 ( all all) 54238 -2451377 (opt)
+pipex 26 48 ( all all) 240 788.263 (opt)
+qiu 1193 840 ( 48 all) 3432 -132.873137 (opt)
+rentacar 6804 9557 ( 55 all) 42019 30356761 (opt)
+rgn 25 180 ( 100 all) 540 82.1999 (opt)
+sample2 46 67 ( 21 all) 179 375 (opt)
+sentoy 31 60 ( all all) 1860 -7772 (opt)
+set1al 493 712 ( 240 all) 1884 15869.7 (opt)
+set1ch 493 712 ( 240 all) 1884 54537.7 (opt)
+set1cl 493 712 ( 240 all) 1884 6484.25 (opt)
+stein15 37 15 ( all all) 135 9 (opt)
+stein27 119 27 ( all all) 405 18 (opt)
+stein45 332 45 ( all all) 1079 30 (opt)
+stein9 14 9 ( all all) 54 5 (opt)
+vpm1 235 378 ( 168 all) 917 20 (opt)
diff --git a/glpk-5.0/doc/miplib3.txt b/glpk-5.0/doc/miplib3.txt
new file mode 100644
index 0000000..ad7884b
--- /dev/null
+++ b/glpk-5.0/doc/miplib3.txt
@@ -0,0 +1,143 @@
+Solver: GLPSOL 4.40
+Computer: Intel Pentium 4, 3.0 GHz
+Platform: Cygwin 1.5.25
+Compiler: GCC 3.4.4 (options used: -O3)
+Test set: MIPLIB 3.0 <http://miplib.zib.de/miplib3/miplib.html>
+
+Problem Optimal Solution Options Used Nodes Iters Time,s Mem,MB
+-------- ---------------- ---------------- -------- ------ ------ ------
+10teams +9.240000000e+02 --pcost --gomory 6013 349276 207 12.7
+air03 +3.401600000e+05 --pcost 33 414 12 21.0
+air04 +5.613700000e+04 --pcost 1901 109800 396 32.4
+air05 +2.637400000e+04 --pcost 6445 201649 452 45.0
+arki001
+bell3a +8.784303160e+05 --pcost --gomory 7965 42363 17 6.1
+bell5 +8.966406492e+06 --pcost --gomory 5605 18555 8 1.5
+blend2 +7.598985000e+00 --pcost 7185 24256 7 2.1
+cap6000 -2.451377000e+06 --pcost 19209 40906 569 15.8
+dano3mip
+danoint
+dcmulti +1.881820000e+05 --pcost 743 3366 2 1.1
+dsbmip -3.051981750e+02 --pcost --mir 217 46088 24 4.5
+egout +5.681007000e+02 --pcost 91 137 < 1 0.3
+enigma +0.000000000e+00 --pcost 16419 55071 6 3.2
+fast0507
+fiber +4.059351800e+05 --pcost --mir 407 3108 4 2.4
+fixnet6 +3.983000000e+03 --pcost 1031 3136 2 1.7
+flugpl +1.201500000e+06 --pcost 397 231 < 1 0.1
+gen +1.123133627e+05 --pcost 195 3991 1 1.7
+gesa2 +2.577985637e+07 --pcost --mir 59 2723 4 4.1
+gesa2_o +2.577985637e+07 --pcost --mir 69 2588 5 3.7
+gesa3 +2.799104265e+07 --pcost --mir 93 2774 5 3.7
+gesa3_o +2.799104265e+07 --pcost --mir 117 3271 6 3.6
+gt2 +2.116600000e+04 --pcost 5613 26115 2 1.2
+harp2
+khb05250 +1.069402260e+08 --pcost 2163 14498 5 2.8
+l152lav +4.722000000e+03 --pcost 7419 95299 68 12.0
+lseu +1.120000000e+03 --pcost 10821 31954 5 2.5
+marksh1
+marksh2
+mas74
+mas76
+misc03 +3.360000000e+03 --pcost 957 6742 2 1.1
+misc06 +1.285086074e+04 --pcost 57 941 < 1 2.7
+misc07 +2.810000000e+03 --pcost --mir 66075 579129 424 33.4
+mitre
+mkc
+mod008 +3.070000000e+02 --pcost 8185 24245 8 2.3
+mod010 +6.548000000e+03 --pcost 315 6283 7 5.3
+mod011
+modglob +2.074050809e+07 --pcost --mir 5197 31985 20 2.8
+noswot
+nw04 +1.686200000e+04 (none) 361 5544 345 138.3
+p0033 +3.089000000e+03 --pcost 305 955 < 1 0.2
+p0201 +7.615000000e+03 --pcost 521 3660 1 0.9
+p0282 +2.584110000e+05 --pcost 623 1204 1 0.8
+p0548 +8.691000000e+03 --pcost 7617 23556 9 2.9
+p2756 +3.124000000e+03 --pcost --mir 3911 15157 57 10.9
+pk1
+pp08a +7.350000000e+03 --pcost --mir 663 9196 4 1.3
+pp08acut +7.350000000e+03 --pcost --mir 17233 260160 154 21.1
+qiu -1.328731369e+02 --pcost 80473 1918742 1174 69.2
+qnet1 +1.602969268e+04 --pcost --mir 183 20352 16 3.6
+qnet1_o +1.602969268e+04 --pcost --mir 75 7645 9 3.3
+rentacar +3.035676098e+07 --pcost 43 1649 3 12.1
+rgn +8.219999924e+01 --pcost 3325 18700 2 1.2
+rout
+set1ch
+seymour
+stein27 +1.800000000e+01 --pcost 3255 15327 2 1.0
+stein45 +3.000000000e+01 --pcost 52301 389140 139 19.2
+swath
+vpm1 +2.000000000e+01 --pcost --mir 9 836 < 1 0.9
+vpm2 +1.375000000e+01 --pcost --mir 11729 164856 91 9.2
+
+PROBLEM CHARACTERISTICS
+
+Problem Rows Cols ( Int 0/1) Nonz Best Solution
+-------- ------ ---------------------- ------ --------------------------
+10teams 230 2025 ( 1800 all) 12150 924 (opt)
+air03 125 10757 ( all all) 101785 340160 (opt)
+air04 824 8904 ( all all) 81869 56138 (opt)
+air05 427 7195 ( all all) 59316 26402 (not opt)
+arki001 1048 1388 ( 538 415) 20439 7580813.0459 (not opt)
+bell3a 124 133 ( 71 39) 441 878430.32 (opt)
+bell5 92 104 ( 58 30) 340 8966406.49 (opt)
+blend2 274 353 ( 264 231) 1409 7.598985 (opt)
+cap6000 2176 6000 ( all all) 48249 -2451377 (opt)
+dano3mip 3202 13873 ( 552 all) 79655 728.1111 (not opt)
+danoint 664 521 ( 56 all) 3232 65.67 (opt)
+dcmulti 291 548 ( 75 all) 1833 188182.0000 (opt)
+dsbmip 1855 1886 ( 192 160) 9768 -305.198 (opt)
+egout 99 141 ( 55 all) 392 568.101 (opt)
+enigma 22 100 ( all all) 298 0.0 (opt)
+fast0507 507 63009 ( all all) 409439 174 (opt)
+fiber 363 1298 ( 1254 all) 2944 405935.18000 (opt)
+fixnet6 479 878 ( 378 all) 2550 3983 (opt)
+flugpl 19 18 ( 11 none) 64 1201500 (opt)
+gen 781 870 ( 150 144) 3174 112313 (opt)
+gesa2 1392 1224 ( 408 240) 5064 25779856.372 (opt)
+gesa2_o 1248 1224 ( 720 384) 3672 25779856.372 (opt)
+gesa3 1368 1152 ( 384 216) 4944 27991042.648 (opt)
+gesa3_o 1224 1152 ( 672 336) 3624 27991042.648 (opt)
+gt2 29 188 ( all 24) 376 21166.000 (opt)
+harp2 112 2993 ( all all) 5840 -73899798.00 (opt)
+khb05250 102 1350 ( 24 all) 3973 106940226 (opt)
+l152lav 98 1989 ( all all) 11911 4750 (not opt)
+lseu 29 89 ( all all) 394 1120 (opt)
+marksh1 7 62 ( 50 all) 324
+marksh2 8 74 ( 60 all) 448
+mas74 13 151 ( 150 all) 1705 11801.1857 (opt)
+mas76 12 151 ( 150 all) 1639 40005.0541 (opt)
+misc03 97 160 ( 159 all) 2054 3360 (opt)
+misc06 821 1808 ( 112 all) 5860 12850.8607 (opt)
+misc07 213 260 ( 259 all) 8620 2810 (not opt)
+mitre 2054 10724 ( all all) 39704 115155 (opt)
+mkc 3412 5325 ( 5323 all) 20621
+mod008 7 319 ( all all) 1562 307 (opt)
+mod010 147 2655 ( all all) 13858 6548 (opt)
+mod011 4482 10958 ( 96 all) 37425 -54558535 (opt)
+modglob 292 422 ( 98 all) 1390 20740508 (opt)
+noswot 183 128 ( 100 75) 760 -43 (opt)
+nw04 36 87482 ( all all) 636666 16862 (opt)
+p0033 17 33 ( all all) 131 3089 (opt)
+p0201 134 201 ( all all) 2124 7615 (opt)
+p0282 242 282 ( all all) 2248 258411 (opt)
+p0548 177 548 ( all all) 2127 8691 (opt)
+p2756 756 2756 ( all all) 11103 3124 (opt)
+pk1 45 86 ( 55 all) 915 11 (opt)
+pp08a 136 240 ( 64 all) 480 7350 (opt)
+pp08acut 246 240 ( 64 all) 839 7350 (opt)
+qiu 1193 840 ( 48 all) 3432 -132.873137 (opt)
+qnet1 503 1541 ( 1417 1288) 4622 16029.692681 (opt)
+qnet1_o 456 1541 ( 1417 1288) 4214 16029.692681 (opt)
+rentacar 6804 9557 ( 55 all) 42019 30356761 (opt)
+rgn 25 180 ( 100 all) 540 82.1999 (opt)
+rout 291 556 ( 315 300) 2431 1077.56 (opt)
+set1ch 493 712 ( 240 all) 1884 54537.7 (opt)
+seymour 4944 1372 ( all all) 33549 423 (not opt)
+stein27 119 27 ( all all) 405 18 (opt)
+stein45 332 45 ( all all) 1079 30 (opt)
+swath 885 6805 ( 6724 all) 34966
+vpm1 235 378 ( 168 all) 917 20 (opt)
+vpm2 234 378 ( 168 all) 917 13.75 (opt)
diff --git a/glpk-5.0/doc/netlib.txt b/glpk-5.0/doc/netlib.txt
new file mode 100644
index 0000000..a5c01ca
--- /dev/null
+++ b/glpk-5.0/doc/netlib.txt
@@ -0,0 +1,103 @@
+Solver: GLPSOL 4.40 (default options used)
+Computer: Intel Pentium 4, 3.0 GHz
+Platform: Cygwin 1.5.25
+Compiler: GCC 3.4.4 (options used: -O3)
+Test set: Netlib LP collection <ftp://ftp.netlib.org/lp/data/>
+
+Problem Rows Cols Nonz Optimum Iters Time,s Mem,MB
+-------- ----- ----- ------ ---------------- ------ ------ ------
+25fv47 822 1571 11127 +5.501845888e+03 1651 < 1 2.1
+80bau3b 2263 9799 29063 +9.872241924e+05 5358 3 6.4
+adlittle 57 97 465 +2.254949632e+05 71 < 1 0.1
+afiro 28 32 88 -4.647531429e+02 10 < 1 0.1
+agg 489 163 2541 -3.599176729e+07 100 < 1 0.5
+agg2 517 302 4515 -2.023925236e+07 178 < 1 0.8
+agg3 517 302 4531 +1.031211594e+07 182 < 1 0.8
+bandm 306 472 2659 -1.586280185e+02 252 < 1 0.6
+beaconfd 174 262 3476 +3.359248581e+04 61 < 1 0.4
+blend 75 83 521 -3.081214985e+01 41 < 1 0.1
+bnl1 644 1175 6129 +1.977629562e+03 581 < 1 1.4
+bnl2 2325 3489 16124 +1.811236540e+03 1730 1 3.7
+boeing1 351 384 3865 -3.352135675e+02 419 < 1 0.7
+boeing2 167 143 1339 -3.150187280e+02 161 < 1 0.3
+bore3d 234 315 1525 +1.373080394e+03 38 < 1 0.3
+brandy 221 249 2150 +1.518509896e+03 191 < 1 0.5
+capri 272 353 1786 +2.690012914e+03 203 < 1 0.4
+cycle 1904 2857 21322 -5.226393025e+00 953 < 1 3.5
+czprob 930 3523 14173 +2.185196699e+06 754 < 1 2.6
+d2q06c 2172 5167 35674 +1.227842108e+05 5368 7 6.2
+d6cube 416 6184 43888 +3.154916667e+02 6596 6 6.0
+degen2 445 534 4449 -1.435178000e+03 506 < 1 1.0
+degen3 1504 1818 26230 -9.872940000e+02 2205 2 4.1
+dfl001 6072 12230 41873 +1.126639605e+07 39863 117 11.0
+e226 224 282 2767 -2.586492907e+01 206 < 1 0.5
+etamacro 401 688 2489 -7.557152333e+02 444 < 1 0.7
+fffff800 525 854 6235 +5.556795648e+05 167 < 1 1.0
+finnis 498 614 2714 +1.727910656e+05 338 < 1 0.6
+fit1d 25 1026 14430 -9.146378092e+03 488 < 1 1.7
+fit1p 628 1677 10894 +9.146378092e+03 1379 < 1 1.9
+fit2d 26 10500 138018 -6.846429329e+04 5751 16 15.8
+fit2p 3001 13525 60784 +6.846429329e+04 11960 17 11.3
+forplan 162 421 4916 -6.642189613e+02 170 < 1 0.7
+ganges 1310 1681 7021 -1.095857361e+05 724 < 1 1.9
+gfrd-pnc 617 1092 3467 +6.902236000e+06 416 < 1 1.0
+greenbea 2393 5405 31499 -7.255524813e+07 3012 3 5.8
+greenbeb 2393 5405 31499 -4.302260261e+06 2153 2 5.8
+grow15 301 645 5665 -1.068709413e+08 358 < 1 1.1
+grow22 441 946 8318 -1.608343365e+08 606 < 1 1.6
+grow7 141 301 2633 -4.778781181e+07 159 < 1 0.5
+israel 175 142 2358 -8.966448219e+05 123 < 1 0.4
+kb2 44 41 291 -1.749900130e+03 38 < 1 0.1
+lotfi 154 308 1086 -2.526470606e+01 104 < 1 0.3
+maros 847 1443 10006 -5.806374370e+04 703 < 1 1.8
+maros-r7 3137 9408 151120 +1.497185166e+06 2340 5 16.7
+modszk1 688 1620 4158 +3.206197291e+02 705 < 1 1.4
+nesm 663 2923 13988 +1.407603649e+07 2240 1 2.4
+perold 626 1376 6026 -9.380755278e+03 1103 < 1 1.5
+pilot 1442 3652 43220 -5.574831533e+02 5726 11 7.8
+pilot-ja 941 1988 14706 -6.113136466e+03 1697 1 2.5
+pilot-we 723 2789 9218 -2.720107533e+06 1382 1 2.3
+pilot4 411 1000 5145 -2.581139259e+03 532 < 1 1.3
+pilot87 2031 4883 73804 +3.017103744e+02 7573 28 12.2
+pilotnov 976 2172 13129 -4.497276188e+03 988 1 2.5
+recipe 92 180 752 -2.666160000e+02 17 < 1 0.2
+sc105 106 103 281 -5.220206121e+01 51 < 1 0.2
+sc205 206 203 552 -5.220206121e+01 124 < 1 0.3
+sc50a 51 48 131 -6.457507706e+01 25 < 1 0.1
+sc50b 51 48 119 -7.000000000e+01 30 < 1 0.1
+scagr25 472 500 2029 -1.475343306e+07 352 < 1 0.7
+scagr7 130 140 553 -2.331389824e+06 94 < 1 0.2
+scfxm1 331 457 2612 +1.841675903e+04 281 < 1 0.6
+scfxm2 661 914 5229 +3.666026156e+04 587 < 1 1.1
+scfxm3 991 1371 7846 +5.490125455e+04 881 < 1 1.7
+scorpion 389 358 1708 +1.878124823e+03 146 < 1 0.4
+scrs8 491 1169 4029 +9.042969538e+02 545 < 1 1.1
+scsd1 78 760 3148 +8.666666674e+00 91 < 1 0.6
+scsd6 148 1350 5666 +5.050000008e+01 182 < 1 1.0
+scsd8 398 2750 11334 +9.049999999e+02 397 < 1 2.1
+sctap1 301 480 2052 +1.412250000e+03 196 < 1 0.5
+sctap2 1091 1880 8124 +1.724807143e+03 425 < 1 1.7
+sctap3 1481 2480 10734 +1.424000000e+03 729 < 1 2.4
+seba 516 1028 4874 +1.571160000e+04 883 < 1 1.0
+share1b 118 225 1182 -7.658931858e+04 167 < 1 0.3
+share2b 97 79 730 -4.157322407e+02 87 < 1 0.2
+shell 537 1775 4900 +1.208825346e+09 467 < 1 1.2
+ship04l 403 2118 8450 +1.793324538e+06 373 < 1 1.5
+ship04s 403 1458 5810 +1.798714700e+06 262 < 1 1.0
+ship08l 779 4283 17085 +1.909055211e+06 516 < 1 2.9
+ship08s 779 2387 9501 +1.920098211e+06 274 < 1 1.7
+ship12l 1152 5427 21597 +1.470187919e+06 686 < 1 3.7
+ship12s 1152 2763 10941 +1.489236134e+06 383 < 1 2.0
+sierra 1228 2036 9252 +1.539436218e+07 857 < 1 2.1
+stair 357 467 3857 -2.512669512e+02 399 < 1 1.0
+standata 360 1075 3038 +1.257699500e+03 140 < 1 0.7
+standgub 362 1184 3147 +1.257699500e+03 140 < 1 0.8
+standmps 468 1075 3686 +1.406017500e+03 299 < 1 0.9
+stocfor1 118 111 474 -4.113197622e+04 24 < 1 0.2
+stocfor2 2158 2031 9492 -3.902440854e+04 499 < 1 2.6
+stocfor3 16676 15695 74004 -3.997678394e+04 4456 11 19.7
+truss 1001 8806 36642 +4.588158472e+05 4744 4 6.5
+tuff 334 587 4523 +2.921477651e-01 61 < 1 0.8
+vtp-base 199 203 914 +1.298314625e+05 69 < 1 0.2
+wood1p 245 2594 70216 +1.442902412e+00 326 < 1 7.1
+woodw 1099 8405 37478 +1.304476333e+00 1093 < 1 6.0
diff --git a/glpk-5.0/doc/notes/gomory.pdf b/glpk-5.0/doc/notes/gomory.pdf
new file mode 100644
index 0000000..b680627
--- /dev/null
+++ b/glpk-5.0/doc/notes/gomory.pdf
Binary files differ
diff --git a/glpk-5.0/doc/notes/keller.pdf b/glpk-5.0/doc/notes/keller.pdf
new file mode 100644
index 0000000..3aa6938
--- /dev/null
+++ b/glpk-5.0/doc/notes/keller.pdf
Binary files differ
diff --git a/glpk-5.0/doc/notes/scf.pdf b/glpk-5.0/doc/notes/scf.pdf
new file mode 100644
index 0000000..da324f2
--- /dev/null
+++ b/glpk-5.0/doc/notes/scf.pdf
Binary files differ
diff --git a/glpk-5.0/doc/notes/simplex1.pdf b/glpk-5.0/doc/notes/simplex1.pdf
new file mode 100644
index 0000000..af8306d
--- /dev/null
+++ b/glpk-5.0/doc/notes/simplex1.pdf
Binary files differ
diff --git a/glpk-5.0/doc/notes/simplex2.pdf b/glpk-5.0/doc/notes/simplex2.pdf
new file mode 100644
index 0000000..313ca69
--- /dev/null
+++ b/glpk-5.0/doc/notes/simplex2.pdf
Binary files differ
diff --git a/glpk-5.0/doc/npp.txt b/glpk-5.0/doc/npp.txt
new file mode 100644
index 0000000..e5dc144
--- /dev/null
+++ b/glpk-5.0/doc/npp.txt
@@ -0,0 +1,283 @@
+@.@ LP/MIP PREPROCESSING ROUTINES
+=================================
+
+@.@.1 Introduction
+
+GLPK has a set of routines that constitute so called the LP/MIP
+preprocessor. Its main purpose is to improve a given formulation of the
+LP or MIP problem instance provided by the user.
+
+As a rule the LP/MIP preprocessor is used internally (if enabled) in
+the LP or MIP solver. However, for various reasons the user may need
+to call the preprocessing routines directly in his/her application
+program, in which case he/she may use API routines described in this
+section.
+
+The preprocessing of an LP/MIP problem instance and recovering its
+solution include several steps, which are performed in the following
+order.
+
+1. Allocating the workspace. The preprocessor allocates the workspace,
+ an internal data structure used on all subsequent steps.
+
+2. Loading the original problem instance. The preprocessor copies all
+ the problem components from the original problem object (glp_prob)
+ specified by the user into the workspace. On this step the user also
+ should specify the solution type: basic solution (assumes the
+ primal or dual simplex solver), interior-point solution (assumes the
+ interior-point solver), or MIP solution (assumes the MIP solver).
+ This is needed, because some preprocessing transformations depend on
+ the solution type.
+
+3. Preprocessing. The user calls preprocessing routines that transform
+ the problem instance residing in the workspace.
+
+4. Building the resultant problem instance. The preprocessor converts
+ the problem instance from an internal workspace representation
+ to the standard problem object (glp_prob) and returns that object to
+ the user.
+
+5. Solving the resultant problem instance. The user calls an
+ appropriate solver routine to obtain a solution to the resultant
+ problem instance.
+
+6. Postprocessing. The user provides the solution to the resultant
+ problem instance found on the previous step, and the preprocessor
+ performs inverse transformations to recover the solution to the
+ original problem instance. Should note that only optimal or integer
+ feasible (for MIP) solutions can be recovered.
+
+7. Obtaining original solution. The preprocessor copies the solution
+ to the original problem instance recovered on the previous step from
+ the workspace to the original problem object (glp_prob). The effect
+ is the same as if the solution were computed by a solver. Note that
+ steps 6 and 7 can be performed multiple times (for example, to
+ recover intermediate integer feasible solutions during the integer
+ optimization).
+
+8. Freeing the workspace. The preprocessor frees all the memory
+ allocated to the workspace.
+
+EXAMPLE
+
+In this example the program reads the LP problem data from input file
+murtagh.mps\footnote{This is an example model included in the GLPK
+distribution.}, performs standard preprocessing, solves the resultant
+LP with the primal simplex method, and then recovers the solution to
+the original LP.
+
+/* nppsamp.c */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glpk.h>
+
+int main(void)
+{ glp_prep *npp;
+ glp_prob *P, *Q;
+ int ret;
+ npp = glp_npp_alloc_wksp();
+ P = glp_create_prob();
+ ret = glp_read_mps(P, GLP_MPS_DECK, NULL, "murtagh.mps");
+ if (ret != 0)
+ { printf("Error on reading problem data\n");
+ goto skip;
+ }
+ glp_set_obj_dir(P, GLP_MAX);
+ glp_npp_load_prob(npp, P, GLP_SOL, GLP_ON);
+ ret = glp_npp_preprocess1(npp, 0);
+ switch (ret)
+ { case 0:
+ break;
+ case GLP_ENOPFS:
+ printf("LP has no primal feasible solution\n");
+ goto skip;
+ case GLP_ENODFS:
+ printf("LP has no dual feasible solution\n");
+ goto skip;
+ default:
+ xassert(ret != ret);
+ }
+ Q = glp_create_prob();
+ glp_npp_build_prob(npp, Q);
+ ret = glp_simplex(Q, NULL);
+ if (ret == 0 && glp_get_status(Q) == GLP_OPT)
+ { glp_npp_postprocess(npp, Q);
+ glp_npp_obtain_sol(npp, P);
+ }
+ else
+ printf("Unable to recover non-optimal solution\n");
+ glp_delete_prob(Q);
+skip: glp_npp_free_wksp(npp);
+ glp_delete_prob(P);
+ return 0;
+}
+
+/* eof */
+------------------------------------------------------------------------
+@.@.2 glp_npp_alloc_wksp - allocate the preprocessor workspace
+
+SYNOPSIS
+
+glp_prep *glp_npp_alloc_wksp(void);
+
+DESCRIPTION
+
+The routine glp_npp_alloc_wksp allocates the preprocessor workspace.
+(Note that multiple instances of the workspace may be allocated, if
+necessary.)
+
+RETURNS
+
+The routine returns a pointer to the workspace, which should be used in
+all subsequent operations.
+------------------------------------------------------------------------
+@.@.3 glp_npp_load_prob - load original problem instance
+
+SYNOPSIS
+
+void glp_npp_load_prob(glp_prep *prep, glp_prob *P, int sol,
+ int names);
+
+DESCRIPTION
+
+The routine glp_npp_load_prob loads the original problem instance from
+the specified problem object P into the preprocessor workspace. (Note
+that this operation can be performed only once.)
+
+The parameter sol specifies which solution is required:
+
+GLP_SOL - basic solution;
+
+GLP_IPT - interior-point solution;
+
+GLP_MIP - mixed integer solution.
+
+The parameter names is a flag. If it is GLP_ON, the symbolic names of
+original rows and columns are also loaded into the workspace. Otherwise,
+if the flag is GLP_OFF, the row and column names are not loaded.
+------------------------------------------------------------------------
+@.@.4 glp_npp_preprocess1 - perform basic LP/MIP preprocessing
+
+SYNOPSIS
+
+int glp_npp_preprocess1(glp_prep *prep, int hard);
+
+DESCRIPTION
+
+The routine glp_npp_preprocess1 performs basic LP/MIP preprocessing
+that currently includes:
+
+-- removing free rows;
+
+-- replacing double-sided constraint rows with almost identical bounds,
+ by equality constraint rows;
+
+-- removing fixed columns;
+
+-- replacing double-bounded columns with almost identical bounds by
+ fixed columns and removing those columns;
+
+-- removing empty rows;
+
+-- removing equality constraint row singletons and corresponding
+ columns;
+
+-- removing inequality constraint row singletons and corresponding
+ columns;
+
+-- performing general row analysis;
+
+-- removing redundant row bounds;
+
+-- removing forcing rows and corresponding columns;
+
+-- removing rows which become free due to redundant bounds;
+
+-- computing implied bounds for all columns and using them to
+ strengthen current column bounds (MIP only, optional, performed if
+ the flag hard is on);
+
+-- fixing and removing empty columns;
+
+-- removing column singletons, which are implied slack variables, and
+ corresponding rows;
+
+-- removing bounds of columns, which are implied free variables, and
+ replacing corresponding rows by equality constraints.
+
+If the flag hard is GLP_ON, the routine attempts to improve current
+column bounds multiple times within the main processing loop, in which
+case this feature may take a time. Otherwise, if the flag hard is
+GLP_OFF, improving column bounds is performed only once at the end of
+the main loop. (Note that this feature is used for MIP only.)
+
+RETURNS
+
+0 - the problem instance has been successfully preprocessed;
+
+GLP_ENOPFS - primal/integer infeasibility has been detected;
+
+GLP_ENODFS - dual infeasibility has been detected.
+------------------------------------------------------------------------
+@.@.5 glp_npp_build_prob - build resultant problem instance
+
+SYNOPSIS
+
+void glp_npp_build_prob(glp_prep *prep, glp_prob *Q);
+
+DESCRIPTION
+
+The routine glp_npp_build_prob obtains all necessary information from
+the preprocessor workspace to build the resultant (preprocessed)
+problem instance, and stores it in the specified problem object Q. Note
+that before building the current content of this problem object is
+erased with the routine glp_erase_prob.
+------------------------------------------------------------------------
+@.@.6 glp_npp_postprocess - postprocess solution to resultant problem
+
+SYNOPSIS
+
+void glp_npp_postprocess(glp_prep *prep, glp_prob *Q);
+
+DESCRIPTION
+
+The routine glp_npp_postprocess performs postprocessing of a solution
+to the resultant (preprocessed) problem instance specified by the
+problem object Q and recovers corrseponding solution to the original
+problem instance. The recovered solution is stored in the preprocessor
+workspace and can be obtained with the routine glp_npp_obtain_sol.
+
+It is assumed that the resultant problem instance Q has been solved
+with an appropriate solver depending on the solution type previously
+passed to the routine glp_npp_load_prob (the parameter sol). Note that
+only optimal or integer feasible (for MIP) solution can be recovered,
+so the calling program should use the routine glp_status to make sure
+that this condition is met.
+------------------------------------------------------------------------
+@.@.7 glp_npp_obtain_sol - obtain solution to original problem
+
+SYNOPSIS
+
+void glp_npp_obtain_sol(glp_prep *prep, glp_prob *P);
+
+DESCRIPTION
+
+The routine glp_npp_obtain_sol copies the solution to the original
+problem instance previously recovered by the routine
+glp_npp_postorocess from the preprocessor workspace to the problem
+object P. The effect is the same as if the solution were computed by an
+appropriate solver.
+------------------------------------------------------------------------
+@.@.8 glp_npp_free_wksp - free the preprocessor workspace
+
+SYNOPSIS
+
+void glp_npp_free_wksp(glp_prep *prep);
+
+DESCRIPTION
+
+The routine glp_npp_free_wksp frees all the memory allocated to the
+preprocessor workspace.
+
+===EOF===