diff git a/NEWS b/NEWS
index 9eff6971c3f723d89a17e5e6cc101efbadc3bd1f..04efdefdb1308961ce71f9581eabddf5bb52daab 100644
 a/NEWS
+++ b/NEWS
@@ 3,6 +3,14 @@ Gnumeric 1.1.8
Jody:
* Add XL for polygon colours.
+Jukka:
+ * Solver improvements:
+  Imported the GLPK (GNU linear programming kit) version 3.2.
+ It provides a revised simplex algorithm for solving large
+ scale problems, written by Andrew Makhorin. It performs
+ much better than lpsolve if the model is large, see
+ a benchmark in ftp://plato.la.asu.edu/pub/lpsimp.txt.
+
Morten:
* Add poor man's utf8 regexp routines.
diff git a/configure.in b/configure.in
index 3b0e9ef7ce278ca87bd9be125ea24b8b2a40454c..e09b16de0af06e238eed35b2342a64d56bd43b94 100644
 a/configure.in
+++ b/configure.in
@@ 652,6 +652,8 @@ src/pixmaps/Makefile
src/widgets/Makefile
src/tools/Makefile
src/tools/solver/Makefile
+src/tools/solver/glpk/Makefile
+src/tools/solver/glpk/source/Makefile
src/tools/solver/lp_solve/Makefile
doc/Makefile
doc/C/Makefile
diff git a/src/Makefile.am b/src/Makefile.am
index b4d8ea62dcf20296f734d9d060ea70889827193c..b081785b0a80d646f3772b78f69d19c943faa3ba 100644
 a/src/Makefile.am
+++ b/src/Makefile.am
@@ 321,6 +321,7 @@ gnumeric_app_libs = \
widgets/libwidgets.a \
tools/libtools.a \
tools/solver/libsolver.a \
+ tools/solver/glpk/source/libglpk.a \
tools/solver/lp_solve/liblp_solve.a
diff git a/src/tools/solver/ChangeLog b/src/tools/solver/ChangeLog
index 4072e82c0fb598811bd8e83d95da46c2a37337e0..8c2393afce517ec4c5827198be0e045876ff75df 100644
 a/src/tools/solver/ChangeLog
+++ b/src/tools/solver/ChangeLog
@@ 1,3 +1,15 @@
+20020813 Jukka Pekka
+
+ * glpk/*.: Imported GLPK (The GNU linear programming kit) version
+ 3.2.
+
+ * api.c: Lot's of changes for the glpk wrappers since the
+ interface has changed a lot since version 3.0.5.
+
+ * api.h: Added SOLVER_DEBUG constant.
+
+ * solver.c: Moved the model printing into the api.c.
+
20020813 Jukka Pekka
* reports.c (solver_prepare_reports_success): Bug fix: wrong loop
diff git a/src/tools/solver/Makefile.am b/src/tools/solver/Makefile.am
index cbc64abb2f31ea9db1c08a8ae5c0e1fc493b5c37..79753a5c734e6727a2128d24b33fc7aab9bc3644 100644
 a/src/tools/solver/Makefile.am
+++ b/src/tools/solver/Makefile.am
@@ 1,4 +1,4 @@
SUBDIRS = lp_solve
+SUBDIRS = glpk lp_solve
INCLUDES = \
DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
@@ 7,6 +7,7 @@ INCLUDES = \
I$(top_srcdir)/src/dialogs \
I$(top_srcdir)/src/tools \
I$(top_srcdir)/src/tools/solver \
+ I$(top_srcdir)/src/tools/solver/glpk/include \
$(GNUMERIC_CFLAGS)
noinst_LIBRARIES = libsolver.a
diff git a/src/tools/solver/api.c b/src/tools/solver/api.c
index 4e5a095f62a71b01bb287d90bd10111790e5a54d..13c54a12d5f7befe96c124d7418174e69a2c6665 100644
 a/src/tools/solver/api.c
+++ b/src/tools/solver/api.c
@@ 1,3 +1,4 @@
+/* vim: set sw=8: * Mode: C; tabwidth: 8; indenttabsmode: t; cbasicoffset: 8 * */
/*
* api.c: The Solver's API wrappings for various optimization algorithms.
*
@@ 44,6 +45,7 @@
#include "lp_solve/lpkit.h"
#include "api.h"
+#include "glpk.h"
/*  */
@@ 256,11 +258,22 @@ w_lp_solve_set_bool (SolverProgram program, int col)
}
}
+static void
+w_lp_solve_print_lp (SolverProgram program)
+{
+ lp_solve_t *lp = (lp_solve_t *) program;
+
+ lp_solve_print_lp (lp>p);
+}
+
static SolverStatus
w_lp_solve_solve (SolverProgram program)
{
lp_solve_t *lp = (lp_solve_t *) program;
+#if SOLVER_DEBUG
+ w_lp_solve_print_lp (program);
+#endif
return lp_solve_solve (lp>p);
}
@@ 330,76 +343,57 @@ w_lp_solve_set_option (SolverProgram program, SolverOptionType option,
}
}
static void
w_lp_solve_print_lp (SolverProgram program)
{
 lp_solve_t *lp = (lp_solve_t *) program;

 lp_solve_print_lp (lp>p);
}

/*  */
#if __HAVE_GLPK__

/*
 * Solver's API wrappings for the GLPK 3.0.5.
+ * Solver's API wrappings for the GLPK 3.2.
*
* Package: GLPK
 * Version: 3.0.5 (Jan 29, 2002)
+ * Version: 3.2 (Jul 15, 2002)
* License: GPL
* Homepage: http://www.gnu.org/software/glpk/glpk.html
* Algorithm: revised simplex method
*
*/
#include "glpk.h"
typedef struct {
 LPI *p;
 struct spx2 *param;
+ LPX *p;
+ int *rn;
+ int *cn;
+ gnum_float *a;
+ int n;
gboolean assume_non_negative;
} glpk_simplex2_t;
+ gboolean scaling;
+} glpk_simplex_t;
SolverProgram
w_glpk_init (const SolverParameters *param)
{
 glpk_simplex2_t *lp;
 int i;
 GString *str;
+ glpk_simplex_t *lp;
+ int i, cols;
 lp = g_new (glpk_simplex2_t, 1);
 lp>p = glp_create_prob (NULL);
 lp>param = g_new (struct spx2, 1);
+ lp = g_new (glpk_simplex_t, 1);
+ lp>p = lpx_create_prob ();
lp>assume_non_negative = param>options.assume_non_negative;
+ lp>scaling = param>options.automatic_scaling;
 glp_init_spx2 (lp>param);
+ cols = param>n_variables;
 if (lp>assume_non_negative) {
 for (i = 0; i < param>n_variables; i++) {
 str = g_string_new ("");
 g_string_sprintfa (str, "X%d", i);
 glp_new_col (lp>p, str>str);
 g_string_free (str, FALSE);
 }
 } else {
 for (i = 0; i < param>n_variables; i++) {
 str = g_string_new ("");
 g_string_sprintfa (str, "X%d", i);
 glp_new_col (lp>p, str>str);
 g_string_sprintfa (str, "neg", i);
 glp_new_col (lp>p, str>str);
 g_string_free (str, FALSE);
 }
 }
+ lpx_add_cols (lp>p, cols);
+ lpx_add_rows (lp>p, param>n_constraints);
+ lp>a = g_new (gnum_float, cols * param>n_constraints + 1);
+ lp>cn = g_new (int, cols * param>n_constraints + 1);
+ lp>rn = g_new (int, cols * param>n_constraints + 1);
+ lp>n = 1;
 for (i = 0; i < param>n_constraints; i++) {
 str = g_string_new ("");
 g_string_sprintfa (str, "C%d", i);
 glp_new_row (lp>p, str>str);
 g_string_free (str, FALSE);
 }
+ if (lp>assume_non_negative)
+ for (i = 0; i < cols; i++)
+ lpx_set_col_bnds (lp>p, i + 1, LPX_LO, 0, 0);
+ else
+ for (i = 0; i < cols; i++)
+ lpx_set_col_bnds (lp>p, i + 1, LPX_FR, 0, 0);
return lp;
}
@@ 407,150 +401,251 @@ w_glpk_init (const SolverParameters *param)
void
w_glpk_delete_lp (SolverProgram program)
{
 glpk_simplex2_t *lp = (glpk_simplex2_t *) program;
+ glpk_simplex_t *lp = (glpk_simplex_t *) program;
 glp_delete_prob (lp>p);
 g_free (lp>param);
+ lpx_delete_prob (lp>p);
+ g_free (lp>cn);
+ g_free (lp>rn);
+ g_free (lp>a);
g_free (lp);
}
void
w_glpk_set_maxim (SolverProgram program)
{
 glpk_simplex2_t *lp = (glpk_simplex2_t *) program;
+ glpk_simplex_t *lp = (glpk_simplex_t *) program;
 glp_set_obj_sense(lp>p, '+');
+ lpx_set_obj_dir (lp>p, LPX_MAX);
}
void
w_glpk_set_minim (SolverProgram program)
{
 glpk_simplex2_t *lp = (glpk_simplex2_t *) program;
+ glpk_simplex_t *lp = (glpk_simplex_t *) program;
 glp_set_obj_sense(lp>p, '');
+ lpx_set_obj_dir (lp>p, LPX_MIN);
}
void
w_glpk_set_obj_fn (SolverProgram program, int col, gnum_float value)
{
 glpk_simplex2_t *lp = (glpk_simplex2_t *) program;
+ glpk_simplex_t *lp = (glpk_simplex_t *) program;
 if (lp>assume_non_negative)
 glp_set_obj_coef (lp>p, col + 1, value);
 else {
 glp_set_obj_coef (lp>p, 2 * col + 1, value);
 glp_set_obj_coef (lp>p, 2 * col + 2, value);
 }
+ lpx_set_col_coef (lp>p, col + 1, value);
}
void
w_glpk_set_constr_mat (SolverProgram program, int col, int row, gnum_float value)
+w_glpk_set_constr_mat (SolverProgram program, int col, int row,
+ gnum_float value)
{
 glpk_simplex2_t *lp = (glpk_simplex2_t *) program;
+ glpk_simplex_t *lp = (glpk_simplex_t *) program;
 if (lp>assume_non_negative)
 glp_new_aij (lp>p, row + 1, col + 1, value);
 else {
 glp_new_aij (lp>p, row + 1, 2 * col + 1, value);
 glp_new_aij (lp>p, row + 1, 2 * col + 2, value);
 }
+ lp>cn [lp>n] = col + 1;
+ lp>rn [lp>n] = row + 1;
+ lp>a [lp>n] = value;
+ (lp>n)++;
}
void
w_glpk_set_constr (SolverProgram program, int row, SolverConstraintType type,
gnum_float value)
{
 int typemap [] = { 'U', 'L', 'S', 1, 1, 1 };
 glpk_simplex2_t *lp = (glpk_simplex2_t *) program;
+ int typemap [] = { LPX_UP, LPX_LO, LPX_FX, 1, 1, 1 };
+ glpk_simplex_t *lp = (glpk_simplex_t *) program;
 if (typemap [type] == 1)
 printf ("Error\n");
+ if (typemap [type] != 1)
+ lpx_set_row_bnds (lp>p, row + 1, typemap [type], value,
+ value);
else
 glp_set_row_bnds (lp>p, row + 1, typemap [type], value, value);
+ printf ("Error\n");
}
void
w_glpk_set_int (SolverProgram program, int col)
{
 glpk_simplex2_t *lp = (glpk_simplex2_t *) program;
+ glpk_simplex_t *lp = (glpk_simplex_t *) program;
 if (lp>assume_non_negative)
 glp_set_col_kind (lp>p, col + 1, 'I');
 else {
 glp_set_col_kind (lp>p, 2 * col + 1, 'I');
 glp_set_col_kind (lp>p, 2 * col + 2, 'I');
 }
+ lpx_set_class (lp>p, LPX_MIP);
+ lpx_set_col_kind (lp>p, col + 1, LPX_IV);
}
void
w_glpk_set_bool (SolverProgram program, int col)
{
 glpk_simplex2_t *lp = (glpk_simplex2_t *) program;
+ glpk_simplex_t *lp = (glpk_simplex_t *) program;
 if (lp>assume_non_negative) {
 glp_set_col_kind (lp>p, col + 1, 'I');
 glp_set_col_bnds (lp>p, col + 1, 'D', 0, 1);
 } else {
 glp_set_col_kind (lp>p, 2 * col + 1, 'I');
 glp_set_col_bnds (lp>p, 2 * col + 1, 'D', 0, 1);
 glp_set_col_kind (lp>p, 2 * col + 2, 'I');
 glp_set_col_bnds (lp>p, 2 * col + 2, 'D', 0, 1);
+ lpx_set_class (lp>p, LPX_MIP);
+ lpx_set_col_kind (lp>p, col + 1, LPX_IV);
+ lpx_set_col_bnds (lp>p, col + 1, LPX_DB, 0, 1);
+}
+
+void
+w_glpk_print_lp (SolverProgram program)
+{
+ glpk_simplex_t *lp = (glpk_simplex_t *) program;
+ int i, n, cols, rows;
+ int typex;
+ gnum_float lb, ub;
+
+ cols = lpx_get_num_cols (lp>p);
+ rows = lpx_get_num_rows (lp>p);
+
+ printf ("\t\t");
+ for (i = 0; i < cols; i++)
+ printf ("Var[%3d] ", i + 1);
+ printf ("\n");
+
+ if (lpx_get_obj_dir (lp>p) == LPX_MAX)
+ printf ("Maximize\t");
+ else
+ printf ("Minimize\t");
+ for (i = 0; i < cols; i++)
+ printf ("%8g ", lpx_get_col_coef (lp>p, i + 1));
+ printf ("\n");
+
+ for (i = 0; i < rows; i++) {
+ gnum_float *a;
+ int *ndx, t;
+
+ printf ("Row[%3d]\t", i + 1);
+
+ a = g_new (gnum_float, cols + 1);
+ ndx = g_new (int, cols + 1);
+ lpx_get_mat_row (lp>p, i + 1, ndx, a);
+ for (n = 0, t = 1; n < cols; n++) {
+ if (ndx [t] == n + 1)
+ printf ("%8g ", a[t++]);
+ else
+ printf ("%8g ", 0);
+ }
+ g_free (ndx);
+ g_free (a);
+
+ lpx_get_row_bnds (lp>p, i + 1, &typex, &lb, &ub);
+ if (typex == LPX_LO)
+ printf (">= %8g\n", lb);
+ else if (typex == LPX_UP)
+ printf ("<= %8g\n", ub);
+ else
+ printf ("= %8g\n", lb);
+ }
+
+ printf ("Type\t\t");
+ for (i = 0; i < cols; i++)
+ if (lpx_get_class (lp>p) == LPX_LP
+  lpx_get_col_kind (lp>p, i + 1) == LPX_CV)
+ printf (" Real\t");
+ else
+ printf (" Int\t");
+
+ printf ("\nupbo\t\t");
+ for (i = 0; i < cols; i++) {
+ lpx_get_col_bnds (lp>p, i + 1, &typex, &lb, &ub);
+ if (typex == LPX_LO  typex == LPX_FR)
+ printf ("Infinite ");
+ else
+ printf ("%8g ", ub);
+ }
+
+ printf ("\nlowbo\t\t");
+ for (i = 0; i < cols; i++) {
+ lpx_get_col_bnds (lp>p, i + 1, &typex, &lb, &ub);
+ if (typex == LPX_UP  typex == LPX_FR)
+ printf ("Infinite ");
+ else
+ printf ("%8g ", ub);
}
+ printf ("\n");
}
SolverStatus
w_glpk_simplex2_solve (SolverProgram program)
{
 glpk_simplex2_t *lp = (glpk_simplex2_t *) program;

 glp_simplex2 (lp>p, lp>param);
 switch (glp_get_status (lp>p)) {
 case GLP_OPT:
 return SolverOptimal;
 case GLP_INFEAS:
 return SolverInfeasible;
 case GLP_UNBND:
 return SolverUnbounded;
 default:
 printf ("Error: w_glpk_simplex2_solve\n");
 return SolverInfeasible;
+w_glpk_simplex_solve (SolverProgram program)
+{
+ glpk_simplex_t *lp = (glpk_simplex_t *) program;
+
+ if (lp>scaling)
+ lpx_scale_prob (lp>p);
+
+ lpx_load_mat3 (lp>p, lp>n  1, lp>rn, lp>cn, lp>a);
+
+#if SOLVER_DEBUG
+ w_glpk_print_lp (program);
+#endif
+
+ lpx_simplex (lp>p);
+ if (lpx_get_class (lp>p) == LPX_MIP) {
+ switch (lpx_get_status (lp>p)) {
+ case LPX_OPT:
+ break;
+ case LPX_INFEAS:
+ return SolverInfeasible;
+ case LPX_UNBND:
+ return SolverUnbounded;
+ default:
+ printf ("Error: w_glpk_simplex_solve\n");
+ return SolverInfeasible;
+ }
+
+ lpx_integer (lp>p);
+ switch (lpx_get_mip_stat (lp>p)) {
+ case LPX_I_OPT:
+ return SolverOptimal;
+ case LPX_I_NOFEAS:
+ return SolverInfeasible;
+ default:
+ printf ("Error: w_glpk_simplex_solve\n");
+ return SolverInfeasible;
+ }
+ } else {
+ if (lp>scaling)
+ lpx_unscale_prob (lp>p);
+
+ switch (lpx_get_status (lp>p)) {
+ case LPX_OPT:
+ return SolverOptimal;
+ case LPX_INFEAS:
+ return SolverInfeasible;
+ case LPX_UNBND:
+ return SolverUnbounded;
+ default:
+ printf ("Error: w_glpk_simplex_solve\n");
+ return SolverInfeasible;
+ }
}
}
gnum_float
w_glpk_get_solution (SolverProgram program, int col)
{
 glpk_simplex2_t *lp = (glpk_simplex2_t *) program;
 double x;
+ glpk_simplex_t *lp = (glpk_simplex_t *) program;
+ gnum_float x;
 if (lp>assume_non_negative)
 glp_get_col_soln (lp>p, col + 1, NULL, &x, NULL);
 else {
 double neg_x;
+ if (lpx_get_class (lp>p) == LPX_LP)
+ lpx_get_col_info (lp>p, col + 1, NULL, &x, NULL);
+ else
+ x = lpx_get_mip_col (lp>p, col + 1);
 glp_get_col_soln (lp>p, 2 * col + 1, NULL, &x, NULL);
 glp_get_col_soln (lp>p, 2 * col + 2, NULL, &neg_x, NULL);
 if (x < neg_x)
 return neg_x;
 }
return x;
}
gnum_float
w_glpk_get_value_of_obj_fn (SolverProgram program)
{
 glpk_simplex2_t *lp = (glpk_simplex2_t *) program;
+ glpk_simplex_t *lp = (glpk_simplex_t *) program;
 return glp_get_obj_val (lp>p);
+ if (lpx_get_class (lp>p) == LPX_LP)
+ return lpx_get_obj_val (lp>p);
+ else
+ return lpx_get_mip_obj (lp>p);
}
gnum_float
w_glpk_get_dual (SolverProgram program, int row)
{
 glpk_simplex2_t *lp = (glpk_simplex2_t *) program;
 double x;
+ glpk_simplex_t *lp = (glpk_simplex_t *) program;
+ gnum_float x;
 glp_get_row_soln (lp>p, row + 1, NULL, NULL, &x);
+ lpx_get_row_info (lp>p, row + 1, NULL, NULL, &x);
return x;
}
@@ 565,11 +660,10 @@ w_glpk_set_option (SolverProgram program, SolverOptionType option,
const gboolean *b_value,
const gnum_float *f_value, const int *i_value)
{
 glpk_simplex2_t *lp = (glpk_simplex2_t *) program;
+ glpk_simplex_t *lp = (glpk_simplex_t *) program;
switch (option) {
case SolverOptAutomaticScaling:
 lp>param>scale = *b_value;
return FALSE;
case SolverOptMaxIter:
printf ("FIXME: Max iter=%d\n", *i_value);
@@ 582,13 +676,6 @@ printf ("FIXME: Max time (sec.)=%d\n", *i_value);
}
}
void
w_glpk_print_lp (SolverProgram program)
{
}

#endif

/*  */
@@ 635,16 +722,20 @@ w_qp_dummy_set_obj_fn (SolverProgram program, int col, gnum_float value)
}
static void
w_qp_dummy_set_constr_mat (SolverProgram program, int col, int row, gnum_float value)
+w_qp_dummy_set_constr_mat (SolverProgram program, int col, int row,
+ gnum_float value)
{
 printf ("w_qp_dummy_set_constr_mat %d, %d, %" GNUM_FORMAT_g "\n", col, row, value);
+ printf ("w_qp_dummy_set_constr_mat %d, %d, %" GNUM_FORMAT_g "\n",
+ col, row, value);
}
static void
w_qp_dummy_set_constr (SolverProgram program, int row, SolverConstraintType type,
 gnum_float value)
+w_qp_dummy_set_constr (SolverProgram program, int row,
+ SolverConstraintType type,
+ gnum_float value)
{
 printf ("w_qp_dummy_set_constr %d, %d, %" GNUM_FORMAT_g "\n", row, type, value);
+ printf ("w_qp_dummy_set_constr %d, %d, %" GNUM_FORMAT_g "\n",
+ row, type, value);
}
static void
@@ 749,11 +840,11 @@ const SolverLPAlgorithm lp_algorithm [] = {
(solver_lp_set_minim_fn*) w_glpk_set_minim,
(solver_lp_set_int_fn*) w_glpk_set_int,
(solver_lp_set_bool_fn*) w_glpk_set_bool,
 (solver_lp_solve_fn*) w_glpk_simplex2_solve,
+ (solver_lp_solve_fn*) w_glpk_simplex_solve,
(solver_lp_get_obj_fn_value_fn*) w_glpk_get_value_of_obj_fn,
(solver_lp_get_obj_fn_var_fn*) w_glpk_get_solution,
(solver_lp_get_shadow_prize_fn*) w_glpk_get_dual,
 (solver_lp_get_iterations_fn*) w_glpk_iterations,
+ (solver_lp_get_iterations_fn*) w_glpk_get_iterations,
(solver_lp_set_option_fn*) w_glpk_set_option,
(solver_lp_print_fn*) w_glpk_print_lp
},
diff git a/src/tools/solver/api.h b/src/tools/solver/api.h
index de7e759d0a0ed9780bf62c88b0af4857a9169bf4..0b4fb2d421267709db2032de3e2ef03e30c3b773 100644
 a/src/tools/solver/api.h
+++ b/src/tools/solver/api.h
@@ 31,6 +31,7 @@
extern const SolverLPAlgorithm lp_algorithm [];
extern const SolverLPAlgorithm qp_algorithm [];
#define __HAVE_GLPK__ 0
+#define __HAVE_GLPK__ 1
+#define SOLVER_DEBUG 0
#endif
diff git a/src/tools/solver/glpk/AUTHORS b/src/tools/solver/glpk/AUTHORS
new file mode 100644
index 0000000000000000000000000000000000000000..396c12d67ea87f8ebf0253e4b2720c2eb1fae6d1
 /dev/null
+++ b/src/tools/solver/glpk/AUTHORS
@@ 0,0 +1,8 @@
+The GLPK package was developed and programmed by Andrew Makhorin
+(Department for Applied Informatics, Moscow Aviation Institute, Moscow,
+Russia).
+
+email: ,
+
+paper mail: 125871, Russia, Moscow, Volokolamskoye sh., 4,
+ Moscow Aviation Institute, Andrew O. Makhorin
diff git a/src/tools/solver/glpk/ChangeLog b/src/tools/solver/glpk/ChangeLog
new file mode 100644
index 0000000000000000000000000000000000000000..808350bb4c831e3bbc21d0f4a9efc69bfe46b9ab
 /dev/null
+++ b/src/tools/solver/glpk/ChangeLog
@@ 0,0 +1,484 @@
+Mon Jul 15 12:00:00 2002 Andrew Makhorin
+
+ * GLPK 3.2 has been released.
+
+ * glplpx.h, glplpx1.c, glplpx2.c
+ The identifier 'class' (used as a member name in the structure
+ LPX and as an argument name in the routine lpx_set_class) was
+ changed to 'clss' in order to avoid conflicts with C++ reserved
+ words.
+
+ * glpk.h, glplpx.h, glplpx1.c, glplpx2.c, glplpx6a.c,
+ * glplpx6b.c, glplpx6c.c, glplpx7.c, glplpx8.c
+ The following new api routines were added: lpx_set_obj_name,
+ lpx_get_obj_name, lpx_get_row_mark, lpx_get_col_mark,
+ lpx_transform_row, lpx_transform_col, lpx_prim_ratio_test,
+ lpx_dual_ratio_test, lpx_interior, lpx_get_ips_stat,
+ lpx_get_ips_row, lpx_get_ips_col, lpx_get_ips_obj, lpx_read_lpm,
+ lpx_write_mps, lpx_print_ips.
+
+ * glpsol.c
+ The solver was completely reprogrammed using new api routines.
+
+ * lang.latex, lang.dvi, lang.ps
+ New edition of the document "GLPK: Modeling Language GLPK/L"
+ was included in the distribution.
+
+ * refman.latex, refman.dvi, refman.ps
+ New edition of the document "GLPK: Reference Manual" (which
+ contains descriptions of all new api routines) was included in
+ the distribution.
+
+ * glpapi.h, glpapi1.c, glpapi2.c, glpapi3.c, glpapi4.c
+ These files (which contain old api routines) were removed from
+ the package.
+
+ * glpipm1.c, glpipm2.c
+ The file glpipm1.c was renamed to glpipm.c. The file glpipm2.c
+ was used only by old api routines and therefore was removed from
+ the package.
+
+ * language.texinfo
+ Old version of the document "GLPK: Modeling Language GLPK/L" was
+ removed from the distribution.
+
+Mon May 27 12:00:00 2002 Andrew Makhorin
+
+ * GLPK 3.1 has been released.
+
+ * glplpx.h, glplpx1.c, glplpx2.c, glplpx3.c, glplpx4.c,
+ * glplpx5.c, glplpx6.c, glplpx7.c, glplpx8.c
+ A preliminary implementation of new API routines was completed.
+
+ * refman.latex, refman.dvi, refman.ps
+ A draft edition of the document "GLPK Reference Manual", which
+ describes new API routines, was included.
+
+ * glplib3.c
+ A bug in measuring long time intervals was fixed up.
+
+ * glprsm3.c
+ This module contains some obsolete routines not longer used and
+ therefore it was removed from the package (into the subdirectory
+ 'oldsrc').
+
+ * glprsm.h
+ Some declarations related to the module 'glprsm3.c' (see above)
+ were removed.
+
+ * guide.texinfo
+ The document "GLPK User's Guide" describing old API routines was
+ removed from the package (into the subdirectory 'oldsrc').
+
+ * newapi.txt
+ The document "New GLPK API Routines" was removed at all, because
+ it is superseded by the new reference manual (see above).
+
+Mon May 13 12:00:00 2002 Andrew Makhorin
+
+ * GLPK 3.0.8 has been released.
+
+ * glplpx.h, glplpx1.c, glplpx2.c, glplpx3.c, glplpx4.c,
+ * glplpx5.c, glplpx6.c, glplpx7.c
+ A preliminary (currently incomplete) implementation of new api
+ routines was included.
+
+ * sample/newsamp.c
+ A sample program for the new api routines was included.
+
+ * newapi.txt
+ A draft of the document "New GLPK API Routines" was included.
+
+ * glpapi2.c, glpapi5.c, glpapi6.c
+ These modules (which contain the api routines glp_call_rsm1,
+ glp_simplex1, glp_pivot_in, glp_pivot_out) were removed from the
+ package (to the subdirectory 'oldsrc') since these routines are
+ functionally superseded by the new api routines.
+
+ * glpk.h, glpapi2.c, glpapi3.c, glpapi4.c
+ The api routines glp_simplex2, glp_call_ipm1, glp_call_bbm1 were
+ renamed to glp_simplex, glp_interior, glp_integer, respectively.
+
+ * sample/glpsol.c
+ Some commandline options (which got obsolete due to the recent
+ changes in api) were excluded.
+
+ * doc/guide.texinfo
+ New edition of the document "GLPK User's Guide" was included in
+ the distribution to reflect the changes in some api routines.
+
+ * doc/libref.texinfo
+ This document was removed from the package (to the subdirectory
+ 'oldsrc') since it describes the library routines, most of which
+ got obsolete and no longer used.
+
+ * Makefile.in
+ A minor bug was fixed up due to bug report from Hans Schwengeler
+ .
+
+Mon Apr 22 12:00:00 2002 Andrew Makhorin
+
+ * GLPK 3.0.7 has been released.
+
+ * glpduff.h, glpduff.c, glpspx.h, glpspx1.c, glpspx2.c,
+ * glpapi7.c
+ These modules were replaced by a new implementation of the
+ simplex method and therefore they were removed from the package
+ (however they still can be found in the subdirectory 'oldsrc').
+
+ * glprsm1.c
+ The routine crash_aa was replaced by a new implementation and
+ therefore it was removed from the file 'glprsm1.c'.
+
+ * glplpx.h, glplpx.c, glpspx.h, glpspx1.c, glpspx2.c, glpspx3.c,
+ * glpspx4.c, glpapi7.c
+ New (currently incomplete) implementation of the simplex method
+ components was included in the package.
+
+Thu Mar 28 12:00:00 2002 Andrew Makhorin
+
+ * GLPK 3.0.6 has been released.
+
+ * glpluf.h, glpluf.c, glpinv.h, glpinv.c
+ New version of LUfactorization and basis maintenance routines
+ (based on ForrestTomlin updating technique) was implemented.
+
+ * glpeta.h, glpeta.c, glpfhv.h, glpfhv.c, glpgel.h, glpgel.c,
+ * glppfi.h, glppfi.c, glprfi.h, glprfi.c
+ These routines implement some other forms of the basis matrix.
+ Now they became obsolete being functionally superseded by the
+ new version of basis maintenance routines (see above) and were
+ removed from the package (however they still can be found in the
+ subdirectory 'oldsrc').
+
+ * glpbbm.c, glprsm.h, glprsm1.h, glprsm2.h, glpspx.h, glpspx2.c,
+ * glprsm2.c, glpsol.c
+ Necessary changes were made in order to use the new version of
+ basis maintenance routines.
+
+Tue Jan 29 12:00:00 2002 Andrew Makhorin
+
+ * GLPK 3.0.5 has been released.
+ Structure of the package was reorganized in order to simplify
+ its maintenance.
+
+ * doc/guide.texinfo
+ New edition of the document "GLPK User's Guide" was included in
+ the distribution. Now the document includes descriptions of some
+ additional API routines recently added to the package.
+
+ * doc/newapi.txt
+ The document "Additional GLPK API Routines" was removed from the
+ distribution, because the corresponding material was included in
+ the user's guide (see above).
+
+Mon Dec 10 12:00:00 2001 Andrew Makhorin
+
+ * GLPK 3.0.4 has been released.
+
+ * glpspx.h, glpspx1.c, glpspx2.c, glpapi/glp_simplex2.h
+ A new, more efficient version of the twophase primal simplex
+ method was implemented (advanced initial basis, projected
+ steepest edge, recursive computations of solution components).
+
+ * glpapi/glp_call_bbm1.c
+ Now LP relaxation can be solved either using rsm1_driver(), or
+ using glp_simplex2(). The choice is controlled by the parameter
+ 'meth' (a member of struct bbm1).
+
+ * sample/glpsol.c
+ The new implementation of the simplex method is now used by
+ default. The old version is available via oldsim option.
+
+ * glpmat/gm_scaling.c
+ Now this routine displays only two lines: an initial "quality"
+ and a final "quality".
+
+ * glplp/prepro_lp.c
+ Identifiers 'fmin' and 'fmax' renamed to 'f_min' and 'f_max' in
+ order to avoid conflict with . The bug was fixed due to
+ report provided by Sami Farin .
+
+Wed Oct 03 12:00:00 2001 Andrew Makhorin
+
+ * GLPK 3.0.3 has been released.
+
+ * glprsm/harris_row.c, glprsm/harris_col.c
+ The relative tolerance used on the first pass of the twopass
+ ratio test was replaced by the absolute tolerance.
+
+ * glprsm/rsm_primal.c, glprsm/rsm_feas.c, glprsm/rsm_dual.c
+ The absolute tolerance passed to the twopass ratio test routine
+ was decaresed (for both primal and dual simplex).
+
+ These changes were made in order to improve numerical stability
+ of the simplex method.
+
+ * glprsm/glp_call_rsm1.c, glprsm/glp_call_bbm1.c,
+ * glprsm/glp_simplex1, glprsm/glp_pivoting.c
+ Default form of the inverse was changed from RFI to AFI.
+
+Mon Sep 24 12:00:00 2001 Andrew Makhorin
+
+ * GLPK 3.0.2 has been released.
+
+ * glpfhv.h, glpfhv.c
+ New version of the basis maintaining routines was implemented.
+ These routines, which are based on so called FHVfactorization
+ (a variety of LUfactorization) and Gustavson's data structures,
+ perform the main operations on the basis matrix faster at the
+ expense of some worsening numerical accuracy.
+
+ * glprsm.h, glprsm/afi.c
+ The routines, which implement AFI (Advanced Form of the
+ Inverse) based on FHVfactorization, were added to the package.
+ This new form is available via the parameter form = 3 (on API
+ level) or via the option afi (in GLPSOL solver).
+
+ * EFI was renamed to PFI
+ In order to correct terminology the acronym EFI (Elimination
+ Form of the Inverse) was replaced by PFI (Product Form of the
+ Inverse) everywhere in the source code and the documentation.
+
+ * glpset/umalloc.c, glpset/ucalloc.c
+ * glpset/get_atom.c, glpset/get_atomv.c
+ These memory management routines were changed in order *not* to
+ clear allocated memory blocks by binary zeros.
+
+Wed Aug 01 12:00:00 2001 Andrew Makhorin
+
+ * GLPK 3.0.1 has been released.
+
+ * glpapi/old_api.c, glplp/extract_lp.c, store_lpsol.c
+ Old API routines were deleted from the package.
+
+ * include/glpk.h, include/glpapi.h, include/glplp.h
+ Specifications of old API routines and data structures were
+ removed from the headers.
+
+ * sample/glpsol.c
+ New version of the standalone solver GLPSOL that now uses new
+ API routines was implemented.
+
+ * glpapi/glp_set_row_fctr.c, glpapi/glp_set_col_fctr.c,
+ * glpapi/glp_get_row_fctr.c, glpapi/glp_get_col_fctr.c,
+ * glpapi/glp_scale_prob.c
+ Scaling routines were added.
+
+ * glpapi/glp_write_mps.c
+ The routine for writing problem data in MPS format was added.
+
+ * glpapi/glp_simplex1.c
+ Comprehensive driver to the simplex method was added.
+
+ * glpapi/glp_pivoting.c
+ The routines glp_pivot_in() and glp_pivot_out() intended for
+ basis maintaining were added.
+
+ * glprsm/create_rsm.c, glprsm/delete_rsm.c, glprsm/scale_rsm.c,
+ * glprsm/build_basis.c
+ Additional low level routines related to the simplex method
+ were added.
+
+ * glpk.h, glpapi.h, glprsm.h
+ Additional specifications for new routines and data structures
+ were added.
+
+ * sample/lpglpk30.c
+ A nontrivial example was added. It allows using GLPK as a base
+ LP solver for Concorde, a program for solving Traveling Salesman
+ Problem (TSP). For details see comments in 'lpglpk30.c'.
+
+ * doc/newapi.txt
+ The document "Additional GLPK API Routines" that describes some
+ new API routines was included.
+
+Thu Jul 19 12:00:00 2001 Andrew Makhorin
+
+ * GLPK 3.0 has been released.
+
+ Now GLPK is provided with new API, which is intended for using
+ the package in more complex algorithmic schemes.
+
+ * glpapi/old_api.c
+ All routines related to old API were gathered in one file named
+ 'old_api.c'.
+
+ * glpapi/*.c
+ These routines that implement new API were added to the package.
+
+ * include/glpk.h, include/glpapi.h
+ Specifications of new API routines and data structures were
+ added to these headers. Specifications of old API routines and
+ data structures were locked by #ifdef GLP_OLD_API directive.
+
+ * doc/guide.texinfo
+ New edition of the document "GLPK User's Guide" that correspond
+ to new API was included.
+
+Thu Jun 14 12:00:00 2001 Andrew Makhorin
+
+ * GLPK 2.4.1 has been released.
+
+ * doc/glpk_ml.texinfo
+ The new document "Modeling Language GLPK/L" was included.
+
+ * doc/glpk_ug.texinfo
+ New edition of the document "GLPK User's Guide" was included.
+
+ * doc/language.txt
+ The preliminary document "GLPK/L Modeling Language: A Brief
+ description" was removed from the distribution, because it has
+ been replaced by the new document "Modeling Language GLPK/L".
+
+ * glplang/l_spar.c
+ The routine comparison() was reprogrammed in order to
+ implement the relation operation as specified in the language
+ description.
+
+ * glpmip.h, glpmip/*.c
+ The partition 'glpmip' was renamed to 'glpbbm'.
+
+Thu May 10 12:00:00 2001 Andrew Makhorin
+
+ * GLPK 2.4 has been released.
+
+ Now GLPK includes an implementation of a preliminary version of
+ the GLPK/L modeling language.
+
+ * glplang.h, glplang/*.c
+ The header 'glplang.h' and a set of routines that implements
+ the GLPK/L language processor (the partition 'glplang') were
+ added to the package.
+
+ * doc/language.txt
+ The document "GLPK/L Modeling Language: A Brief Description
+ (Supplement to GLPK User's Guide)" in plain text format was
+ included in the package (see the file 'language.txt' in the
+ subdirectory 'doc' of the distribution).
+
+ * ex/model1.lpm, ex/model2.lpm
+ Two examples of model descriptions written in GLPK/L were added
+ to the package.
+
+ * sample/glpsol.c
+ This program was modified in order: a) to allow processing
+ model description written in GLPK/L; b) to allow solving pure
+ LP problem using the interior point method.
+
+ * sample/glpipm.c
+ This program was removed from the package, because its function
+ was passed to the GLPSOL solver.
+
+ * Makefile.in
+ This file was changed in order to install the GLPSOL solver
+ executable.
+
+Mon Apr 09 12:00:00 2001 Andrew Makhorin
+
+ * GLPK 2.3 has been released.
+
+ * glpmip.h, glpmip/*.c
+ These routines (that implement the branchandbound method) were
+ reprogrammed in order to improve robustness of implementation.
+ In particular, heuristic routines were carried out from the main
+ driver routine.
+
+ Additional GLPK API routines were documented.
+
+ New edition of the document "GLPK User's Guide" was included in
+ the package.
+
+ The preliminary document "Mixed Integer Programming Using GLPK
+ Version 2.2 (Supplement to GLPK User's Guide)" was removed from
+ the package, because this material was included in GLPK User's
+ Guide.
+
+Thu Mar 15 12:00:00 2001 Andrew Makhorin
+
+ * GLPK 2.2 has been released.
+
+ Now GLPK includes a tentative implementation of the
+ branchandbound procedure based on the dual simplex method for
+ mixed integer linear programming (MIP).
+
+ The preliminary document "Mixed Integer Programming Using GLPK
+ Version 2.2 (Supplement to GLPK User's Guide)" was included into
+ the package in plain text format (see the file 'mip.txt' in the
+ subdirectory 'doc' of the distribution).
+
+ * glpmip.h, glpmip/*.c, glpapi/glp_integer.c
+ These routines (that implement the branchandbound method) were
+ added to the package.
+
+ * sample/glpsol.c
+ This program was modified in order to allow solving LP and MIP
+ problems.
+
+ * glprsm/rsm_primal.c, glprsm/rsm_dual.c, glprsm/rsm_feas.c,
+ * glprsm/rsm1_driver.c
+ These routines (which are drivers to basic components of the
+ revised simplex method) were added to the package.
+
+Mon Feb 19 12:00:00 2001 Andrew Makhorin
+
+ * GLPK 2.1 has been released.
+
+ * glprsm.h, glprsm/*.c
+ These routines (that implement components of the revised simplex
+ method) were reprogrammed and documented.
+
+ The document "GLPK Implementation of the Revised Simplex Method"
+ was included into the package.
+
+Thu Jan 25 12:00:00 2001 Andrew Makhorin
+
+ * GLPK 2.0 has been released.
+
+ Now GLPK includes a tentative implementation of the primaldual
+ interior point method for largescale linear programming (for
+ more details see the file `NEWS' in the distribution). A number
+ of routines related to the interior point method were added to
+ the package.
+
+ * insist.c
+ The routine `insist' and the macro of the same name were
+ introduced into the package in order to replace the standard
+ macro `assert'. Some routines require the expression specified
+ in the `assert' macro to be evaluated, but compiling the package
+ with NDEBUG option prevents from that. This bug was fixed due to
+ bug report provided by Peter A. Huegler .
+
+ * Makefile.in
+ Minor bug was fixed due to a patch provided by Alexandre Oliva
+ .
+
+Wed Jan 10 12:00:00 2001 Andrew Makhorin
+
+ * GLPK 1.1.2 has been released.
+
+ * umalloc.c, ufree.c, create_pool.c, get_atom.c, get_atomv.c
+ These routines were changed in order to fix a bug due to
+ report provided by Andrew Hood . Because of
+ this bug data alignment error occured on the Sparc computer.
+
+Tue Dec 14 12:00:00 2000 Andrew Makhorin
+
+ * GLPK 1.1.1 has been released.
+
+ Minor bug was fixed in `Makefile.in'.
+
+ GLPK Library Reference was included.
+
+Mon Nov 27 12:00:00 2000 Andrew Makhorin
+
+ * GLPK 1.1 has been released.
+
+ Minor changes were made in order to coordinate GLPK routines
+ with their descriptions.
+
+ GLPK User's Guide was included.
+
+Fri Oct 20 12:00:00 2000 Andrew Makhorin
+
+ * GLPK 1.0 has been released.
diff git a/src/tools/solver/glpk/Makefile.am b/src/tools/solver/glpk/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..7a4ddc045b62a099259d9f982cb1c2d6608b677d
 /dev/null
+++ b/src/tools/solver/glpk/Makefile.am
@@ 0,0 +1,13 @@
+SUBDIRS = source
+
+INCLUDES = \
+ DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
+ I$(top_srcdir) \
+ I$(top_srcdir)/src \
+ I$(top_srcdir)/src/tools \
+ I$(top_srcdir)/src/tools/solver \
+ I$(top_srcdir)/src/tools/solver/glpk/include \
+ $(GNUMERIC_CFLAGS)
+
+noinst_LIBRARIES =
+
diff git a/src/tools/solver/glpk/NEWS b/src/tools/solver/glpk/NEWS
new file mode 100644
index 0000000000000000000000000000000000000000..4f40415f6e5b209d999b1118b175320c3574b532
 /dev/null
+++ b/src/tools/solver/glpk/NEWS
@@ 0,0 +1,302 @@
+GLPK 3.2 (release date: Jul 15, 2002)
+
+ New edition of the document "GLPK: Reference Manual" was
+ included (see the files 'refman.latex', 'refman.dvi', and
+ 'refman.ps' in the subdirectory 'doc').
+
+ New edition of the document "GLPK: Modeling Language GLPK/L" was
+ included (see the files 'lang.latex', 'lang.dvi', and 'lang.ps'
+ in the subdirectory 'doc').
+
+ The following new API routines were added to the package:
+
+ lpx_transform_row (transform explicitly specified row);
+ lpx_transform_col (transform explicitly specified column);
+ lpx_prim_ratio_test (perform primal ratio test);
+ lpx_dual_ratio_test (perform dual ratio test);
+ lpx_interior (solve LP problem using interior point method);
+ lpx_get_ips_stat (query status of interior point solution);
+ lpx_get_ips_row (obtain row interior point solution);
+ lpx_get_ips_col (obtain column interior point solution);
+ lpx_get_ips_obj (obtain interior point value of obj.func.);
+ lpx_read_lpm (read LP/MIP model written in GLPK/L);
+ lpx_write_mps (write problem data using MPS format);
+ lpx_print_ips (print interior point solution).
+
+ Detailed description of all these new API routines are given in
+ the new edition of the reference manual.
+
+ New version of the standalone solver glpsol (which is based on
+ the new API) was implemented.
+
+ So long as the new API (introduced in glpk 3.0) now provides
+ all the functions, which were provided by the old API, the old
+ API routines were removed from the package at all.
+
+GLPK 3.1 (release date: May 27, 2002)
+
+ A preliminary implementation of new API routines was completed
+ and included in the package.
+
+ These new API routines provide much more flexible interaction
+ between the application program, LP/MIP problem instances, and
+ solver routines. Based on completely changed data structures
+ they are, however, similar to the API routines and provide the
+ same functionality. Please note that three routines, namely,
+ solving LPs using interior point method, reading model written
+ in the GLPK/L modeling language, and writing problem data in
+ the MPS format, are not implemented in the new API, however,
+ these routines are planned to be implemented in the next version
+ of the package.
+
+ A description of the new API routines is given in the document
+ "GLPK Reference Manual", a draft edition of which is included
+ in the package (see the files 'refman.latex', 'refman.dvi', and
+ 'refman.ps' in the subdirectory 'doc').
+
+ Although the old API routines are kept in the package, they are
+ no longer supported and will be removed in the future.
+
+GLPK 3.0.8 (release date: May 13, 2002)
+
+ A preliminary implementation of new API routines was included
+ in the package. These new API routines are intended to provide
+ much more flexible interaction between the application program,
+ LP/MIP problem and solver routines. See the document "New GLPK
+ API Routines" (the file 'newapi.txt' in the subdirectory 'doc')
+ also included in the package.
+
+ The api routines glp_simplex2, glp_call_ipm1, glp_call_bbm1 were
+ renamed, respectively, to glp_simplex, glp_interior, glp_integer
+ in order to reflect changes in implementation. The api routines
+ glp_call_rsm1, glp_simplex1, glp_pivot_in, glp_pivout_out were
+ removed from the package since they are completely supreseded by
+ the new API routines (however, these routines still can be found
+ in the subdirectory 'oldsrc'). Please consult a new edition of
+ the document "GLPK User's Guide" about all these changes in the
+ existing api routines.
+
+ The document "GLPK Library Reference" was removed from the
+ package (into the subdirectory 'oldsrc') since it describes the
+ obsolete library routines, most of which are no longer used.
+
+GLPK 3.0.7 (release date: Apr 22, 2002)
+
+ A new, more efficient implementation of the primal/dual simplex
+ method was included in the package. Due to some improvements the
+ simplexbased solver allows solving many LP problems faster and
+ provides more reliable results. Note that the new implementation
+ is currently incomplete and available only via the api routine
+ glp_simplex2.
+
+ All the changes are transparent on API level.
+
+GLPK 3.0.6 (release date: Mar 28, 2002)
+
+ New version of LUfactorization and basis maintenance routines
+ (based on ForrestTomlin updating technique) was implemented.
+ Since these new routines functionally supersede some routines
+ (which implement other forms of the basis matrix) and make them
+ obsolete, the latter were removed from the package (they still
+ can be found in the subdirectory 'oldsrc').
+
+ All the changes are transparent on API level.
+
+GLPK 3.0.5 (release date: Jan 29, 2002)
+
+ New edition of the document "GLPK User's Guide" was included in
+ the distribution. Now it describes all additional API routines,
+ which were recently added to the package.
+
+ Structure of the package was reorganized in order to make its
+ maintenance easier (all small files in the subdurectory 'source'
+ were merged in bigger units). These changes are transparent for
+ the user.
+
+GLPK 3.0.4 (release date: Dec 10, 2001)
+
+ A new, more efficient implementation of the twophase primal
+ simplex method was included in the package. Due to some new
+ features (an advanced initial basis, projected steepest edge,
+ recursive updating values and reduced costs) the new LP solver
+ is faster and numerically more stable than the old one.
+
+ The new LP solver is available as API routine glp_simplex2 and
+ has the same purpose as API routine glp_call_rsm1. For detailed
+ specification see the file 'newapi.txt' in the directory 'doc'.
+
+ Now the new LP solver is also used by default to solve an
+ initial LP problem in the branchandbound routine glp_call_bbm1
+ instead the routine rsm1_driver. Note that the branchandbound
+ procedure itself is still based on rsm1_driver.
+
+ The new LP solver is also used as default solver in GLPSOL for
+ solving LP and MIP problems. In order to choose the old solver
+ the option 'oldsim' can be specified in the command line.
+
+GLPK 3.0.3 (release date: Oct 03, 2001)
+
+ Some minor changes were made in the simplex method routines in
+ order to improve numerical stability of the method.
+
+GLPK 3.0.2 (release date: Sep 24, 2001)
+
+ A new implementation of the basis maintaining routines was
+ included in the package. These routines, which are based on so
+ called FHVfactorization (a variety of LUfactorization) of the
+ basis matrix and Gustavson's data structures, allows performing
+ the main operations faster at the expense of some worsening
+ numerical accuracy.
+
+ AFI (Advanced Form of the Inverse), which is the form of the
+ basis matrix based on FHVfactorization, is available via the
+ parameter form = 3 (on API level) or via the option afi (in
+ GLPSOL solver).
+
+GLPK 3.0.1 (release date: Aug 01, 2001)
+
+ Old GLPK API routines have been removed from the package.
+
+ New GLPK API routines were added:
+
+  scaling routines;
+
+  a routine for writing problem data in MPS format;
+
+  a comprehensive driver to the simplex method;
+
+  basis maintaining routines.
+
+ A description of the new API routines is given in the document
+ "Additional GLPK API Routines". This document is included into
+ the distribution in plain text format (see the file 'newapi.txt'
+ in the subdirectory 'doc').
+
+ Now the distribution includes a nontrivial example of using
+ GLPK as a base LP solver for Concorde, a well known program that
+ solves Traveling Salesman Problem (TSP). For further details see
+ comments in the file 'sample/lpglpk30.c'.
+
+GLPK 3.0 (release date: Jul 19, 2001)
+
+ Now GLPK is provided with new API, which being more flexible
+ can be used in more complex algorithmic schemes.
+
+ New edition of the document "GLPK User's Guide" is included in
+ the distribution. Now it completely corresponds to the new GLPK
+ API routines.
+
+ Old API routines are not removed yet from the package, however
+ they became obsolete and therefore should not be used. Since now
+ the header glpk.h corresponds to new API, in order to compile
+ existing programs that use old GLPK API routines the statement
+
+ #define GLP_OLD_API
+
+ should be inserted before the statement
+
+ #include "glpk.h"
+
+GLPK 2.4.1 (release date: Jun 14, 2001)
+
+ The document "Modeling language GLPK/L" is included into the
+ distribution in texinfo format.
+
+ New edition of the document "GLPK User's Guide" is included in
+ the distribution. Now it describes all additional API routines
+ which were recently added to the package.
+
+GLPK 2.4 (release date: May 10, 2001)
+
+ Now GLPK includes an implementation of a preliminary version
+ of the GLPK/L modeling language. This language is intended for
+ writing mathematcal programming models. The name GLPK/L is
+ derived from GNU Linear Programming Kit Language.
+
+ A brief description of the GLPK/L language is given in the
+ document "GLPK/L Modeling Language: A Brief Description". This
+ document is included into the distribution in plain text format
+ (see the file 'language.txt' in the subdirectory 'doc').
+
+ The language processor (which is a program that analyzes model
+ description written in GLPK/L and translates it to internal data
+ structures) is available as the GLPK API routine.
+
+ The standalone solver GLPSOL now is able: a) to process model
+ descriptions written in the GLPK/L language; b) to solve pure LP
+ problems using the interior point method (therefore the program
+ GLPIPM was removed from the package).
+
+GLPK 2.3 (release date: Apr 09, 2001)
+
+ New edition of the document "GLPK User's Guide" is included in
+ the distribution. Now it describes all additional API routines
+ which were recently added to the package.
+
+ The MIP solver was fully reprogrammed in order to improve its
+ robustness and performance. In particular, a basis recovering
+ procedure was implemented (this procedure allows switching to
+ the primal simplex method in case when the dual simplex method
+ fails).
+
+GLPK 2.2 (release date: Mar 15, 2001)
+
+ Now GLPK includes a tentative implementation of the
+ branchandbound procedure based on the dual simplex method for
+ mixed integer linear programming (MIP).
+
+ Complete description of this new feature of the package is given
+ in the preliminary document "Mixed Integer Linear Programming
+ Using GLPK Version 2.2 (Supplement to GLPK User's Guide)". This
+ document is included into the distribution in plain text format
+ (see the file 'mip.txt' in the subdirectory 'doc').
+
+ The MIP solver (glp_integer) can be used as GLPK API routine in
+ the same way as the pure LP solver (glp_simplex).
+
+ The standalone program 'glpsol' is now able to solve LP as well
+ as MIP problems.
+
+ Note that the current version of GLPK MIP solver is based on
+ easiest heuristics for branching and backtrackng. Therefore the
+ solver is fit mainly for MIP problems which are not very hard
+ and have few integer variables.
+
+GLPK 2.1 (release date: Feb 19, 2001)
+
+ The document "GLPK Implementation of the Revised Simplex Method"
+ is included into the distribution. This document describes most
+ of routines related to the revised simplex method.
+
+GLPK 2.0 (release date: Jan 25, 2001)
+
+ Now GLPK includes a tentative implementation of the primaldual
+ interior point method for largescale linear programming.
+
+ The interior point solver can be used as GLPK API routine in the
+ same manner as the simplex method solver (glp_simplex):
+
+ ret = glp_interior();
+
+ Note that currently the interior point solver implemented in
+ GLPK doesn't include many important features, in particular:
+
+ * it can't process dense columns; therefore if the problem has
+ dense columns, the solving will be extremely inefficient;
+
+ * it has no special features against numerical unstability;
+ some problems may cause premature termination of the solving
+ when the matrix A*D*A' becomes illconditioned;
+
+ * it computes only values of primal (auxiliary and structural)
+ variables and doesn't compute values of dual variables (i.e.
+ reduced costs) which are just set to zero;
+
+ * it doesn't identify optimal basis corresponding to the found
+ interior point solution; all variables in the found solution
+ are just marked as basic variables.
+
+ GLPK also includes a standalone program 'glpipm' which is a
+ demo based on the interior point method. It may be used in the
+ same way as the program 'glpsol' that is based on the simplex
+ method.
diff git a/src/tools/solver/glpk/README b/src/tools/solver/glpk/README
new file mode 100644
index 0000000000000000000000000000000000000000..f347b62aa70f5c11aff5ef5f3cb2fe7132acb327
 /dev/null
+++ b/src/tools/solver/glpk/README
@@ 0,0 +1,41 @@
+GLPK (GNU Linear Programming Kit) Version 3.2
+
+Copyright (C) 2000, 2001, 2002 Andrew Makhorin ,
+ Department for Applied Informatics, Moscow Aviation
+ Institute, Moscow, Russia. All rights reserved.
+
+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 2, or (at your option) any later
+version.
+
+See the file COPYING for the GNU General Public License.
+
+See the file INSTALL for compilation and installation instructions.
+
+GLPK is a set of routines written in ANSI C and organized in the form
+of a callable library. This package is intended for solving largescale
+linear programming (LP), mixed integer linear programming (MIP), and
+other related problems.
+
+PLEASE NOTE that the current version of GLPK is *tentative*.
+
+GLPK includes the following main components:
+
+* implementation of the simplex method;
+
+* implementation of the primaldual interior point method;
+
+* implementation of the branchandbound procedure;
+
+* application program interface (API);
+
+* GLPK/L, a modeling language intended for writing LP/MIP models;
+
+* GLPSOL, a standalone program intended for solving LP/MIP problems
+ either prepared in the MPS format or written in the GLPK/L modeling
+ language.
+
+See GLPK webpage at .
+
+Report bugs to .
diff git a/src/tools/solver/glpk/doc/bench.txt b/src/tools/solver/glpk/doc/bench.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0a0655d89ca54289aeecc24db1895cda685a8446
 /dev/null
+++ b/src/tools/solver/glpk/doc/bench.txt
@@ 0,0 +1,113 @@
+Solver: GLPSOL 3.0.4 (options used: simplex)
+Computer: Pentium II MMX 266 MHz
+Platform: Debian GNU/Linux 2.2
+Compiler: GCC 2.95.2 (options used: O3)
+Test set: netlib lp collection
+
+Problem Rows Cols Nonzeros Optimum Iters Time,s Mem,MB
+       
+25FV47 822 1571 11127 +5.50185E+03 1317 10.8 1.6
+80BAU3B 2263 9799 29063 +9.87224E+05 6816 196.8 5.7
+ADLITTLE 57 97 465 +2.25495E+05 70 0.0 0.1
+AFIRO 28 32 88 4.64753E+02 15 0.0 0.1
+AGG 489 163 2541 3.59918E+08 96 0.2 0.5
+AGG2 517 302 4515 2.02393E+07 165 0.3 0.7
+AGG3 517 302 4531 1.03121E+07 162 0.3 0.7
+BANDM 306 472 2659 1.58628E+02 231 0.4 0.5
+BEACONFD 174 262 3476 +3.35925E+04 30 0.1 0.4
+BLEND 75 83 521 3.08121E+01 74 0.0 0.1
+BNL1 644 1175 6129 +1.97763E+03 660 3.2 1.1
+BNL2 2325 3489 16124 +1.81124E+03 1328 17.9 3.3
+BOEING1 351 384 3865 3.35214E+02 489 0.9 0.6
+BOEING2 167 143 1339 3.15019E+02 137 0.1 0.3
+BORE3D 234 315 1525 +1.37308E+03 44 0.1 0.3
+BRANDY 221 249 2150 +1.51851E+03 201 0.3 0.4
+CAPRI 272 353 1786 +2.69001E+03 183 0.2 0.4
+CYCLE 1904 2857 21322 5.22639E+00 599 5.8 3.2
+CZPROB 930 3523 14173 +2.18520E+06 995 10.8 2.4
+D2Q06C 2172 5167 35674 +1.22784E+05 6434 180.2 4.8
+D6CUBE 416 6184 43888 +3.15492E+02 5901 188.9 4.6
+DEGEN2 445 534 4449 1.43518E+03 711 1.8 0.7
+DEGEN3 1504 1818 26230 9.87294E+02 2260 27.5 3.4
+DFL001 6072 12230 41873 +1.12664E+07 49946 ~45min 9.4
+E226 224 282 2767 1.16389E+01 265 0.5 0.4 (*)
+ETAMACRO 401 688 2489 7.55715E+02 415 0.9 0.6
+FFFFF800 525 854 6235 +5.55680E+05 167 0.5 1.0
+FINNIS 498 614 2714 +1.72791E+05 362 0.8 0.7
+FIT1D 25 1026 14430 9.14638E+03 491 2.9 1.2
+FIT1P 628 1677 10894 +9.14638E+03 634 3.5 1.7
+FIT2D 26 10500 138018 6.84643E+04 5772 504.4 11.1
+FIT2P 3001 13525 60784 +6.84643E+04 7128 315.4 9.4
+FORPLAN 162 421 4916 6.64219E+02 175 0.4 0.5
+GANGES 1310 1681 7021 1.09586E+05 642 3.4 1.7
+GFRDPNC 617 1092 3467 +6.90224E+06 446 1.0 0.9
+GREENBEA 2393 5405 31499 7.25552E+07 5526 128.2 4.8 (a)
+GREENBEB 2393 5405 31499 4.30226E+06 3587 85.1 4.8
+GROW15 301 645 5665 1.06871E+08 1039 3.4 0.8 (a)
+GROW22 441 946 8318 1.60834E+08 1268 5.9 1.1 (a)
+GROW7 141 301 2633 4.77878E+07 272 0.5 0.4 (a)
+ISRAEL 175 142 2358 8.96645E+05 143 0.2 0.3
+KB2 44 41 291 1.74990E+03 33 0.0 0.1
+LOTFI 154 308 1086 2.52647E+01 104 0.1 0.3
+MAROS 847 1443 10006 5.80637E+04 1258 6.8 1.5
+MAROSR7 3137 9408 151120 +1.49719E+06 3406 216.3 14.9
+MODSZK1 688 1620 4158 +3.20620E+02 646 2.8 1.1
+NESM 663 2923 13988 +1.40760E+07 2453 24.4 2.0
+PEROLD 626 1376 6026 9.38076E+03 1072 6.1 1.1
+PILOT 1442 3652 43220 5.57488E+02 4042 139.3 5.8 (a)
+PILOTJA 941 1988 14706 6.11314E+03 1629 16.3 2.0
+PILOTWE 723 2789 9218 2.72011E+06 1468 13.4 1.8
+PILOT4 411 1000 5145 2.58114E+03 535 2.2 1.0
+PILOT87 2031 4883 73804 +3.01710E+02 5813 339.9 8.5 (a)
+PILOTNOV 976 2172 13129 4.49728E+03 812 7.9 2.0
+QAP12 3193 8856 44244 +5.22894E+02 34453 ~50min 11.0
+QAP15 6331 22275 110700 (b)
+RECIPE 92 180 752 2.66616E+02 17 0.0 0.2
+SC105 106 103 281 5.22021E+01 49 0.0 0.1
+SC205 206 203 552 5.22021E+01 114 0.1 0.2
+SC50A 51 48 131 6.45751E+01 25 0.0 0.1
+SC50B 51 48 119 7.00000E+01 29 0.0 0.1
+SCAGR25 472 500 2029 1.47534E+07 309 0.6 0.6
+SCAGR7 130 140 553 2.33139E+06 97 0.1 0.2
+SCFXM1 331 457 2612 +1.84168E+04 245 0.4 0.5
+SCFXM2 661 914 5229 +3.66603E+04 525 1.8 1.0
+SCFXM3 991 1371 7846 +5.49013E+04 781 3.8 1.5
+SCORPION 389 358 1708 +1.87812E+03 213 0.3 0.5
+SCRS8 491 1169 4029 +9.04297E+02 316 1.0 0.9
+SCSD1 78 760 3148 +8.66667E+00 115 0.3 0.5
+SCSD6 148 1350 5666 +5.05000E+01 251 1.0 0.8
+SCSD8 398 2750 11334 +9.05000E+02 461 3.4 1.7
+SCTAP1 301 480 2052 +1.41225E+03 182 0.3 0.5
+SCTAP2 1091 1880 8124 +1.72481E+03 437 2.5 1.7
+SCTAP3 1481 2480 10734 +1.42400E+03 587 4.7 2.2
+SEBA 516 1028 4874 +1.57116E+04 275 0.5 0.9
+SHARE1B 118 225 1182 7.65893E+04 106 0.1 0.2
+SHARE2B 97 79 730 4.15732E+02 75 0.0 0.2
+SHELL 537 1775 4900 +1.20883E+09 473 2.1 1.1 (a)
+SHIP04L 403 2118 8450 +1.79332E+06 405 1.9 1.3
+SHIP04S 403 1458 5810 +1.79871E+06 295 1.0 1.0
+SHIP08L 779 4283 17085 +1.90906E+06 830 8.9 2.7
+SHIP08S 779 2387 9501 +1.92010E+06 486 2.6 1.7
+SHIP12L 1152 5427 21597 +1.47019E+06 1082 15.7 3.5
+SHIP12S 1152 2763 10941 +1.48924E+06 486 3.3 2.1
+SIERRA 1228 2036 9252 +1.53944E+07 465 2.8 1.9
+STAIR 357 467 3857 2.51267E+02 293 0.8 0.8
+STANDATA 360 1075 3038 +1.25770E+03 130 0.3 0.7
+STANDGUB 362 1184 3147 +1.25770E+03 130 0.4 0.7
+STANDMPS 468 1075 3686 +1.40602E+03 228 0.6 0.8
+STOCFOR1 118 111 474 4.11320E+04 14 0.0 0.1
+STOCFOR2 2158 2031 9492 3.90244E+04 461 4.0 2.4
+STOCFOR3 16676 15695 74004 3.99768E+04 4001 337.2 18.6
+TRUSS 1001 8806 36642 +4.58816E+05 3754 120.0 5.2
+TUFF 334 587 4523 +2.92148E01 106 0.3 0.7
+VTPBASE 199 203 914 +1.29831E+05 138 0.1 0.3
+WOOD1P 245 2594 70216 +1.44290E+00 388 12.4 5.1
+WOODW 1099 8405 37478 +1.30448E+00 1386 37.2 5.2
+
+(*) objective value may differ from values given in other sources due
+ to a constant term of the objective function specified in the mps
+ file; without this term the optimum is 1.87519e+01.
+
+(a) numerical instability
+
+(b) fiasco due to primal degeneracy
diff git a/src/tools/solver/glpk/doc/lang.latex b/src/tools/solver/glpk/doc/lang.latex
new file mode 100644
index 0000000000000000000000000000000000000000..19b06c9694e985692ee298ca81222e46d2af021d
 /dev/null
+++ b/src/tools/solver/glpk/doc/lang.latex
@@ 0,0 +1,2542 @@
+%% lang.latex %%
+
+%% Copyright (C) 2000, 2001, 2002 Andrew Makhorin ,
+%% Department for Applied Informatics, Moscow Aviation
+%% Institute, Moscow, Russia. All rights reserved.
+%%
+%% This file is a part of GLPK (GNU Linear Programming Kit).
+%%
+%% 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 2, 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; see the file COPYING. If not, write to the Free
+%% Software Foundation, Inc., 59 Temple Place  Suite 330, Boston, MA
+%% 021111307, USA.
+
+\documentclass[a4paper,11pt,twoside,draft]{report}
+
+\setlength{\paperwidth}{210mm}
+\setlength{\paperheight}{297mm}
+\setlength{\hoffset}{1in}
+\addtolength{\hoffset}{5mm}
+\setlength{\oddsidemargin}{25mm}
+\setlength{\voffset}{1in}
+\addtolength{\voffset}{20mm}
+\setlength{\topmargin}{0mm}
+\setlength{\headheight}{3mm}
+\setlength{\headsep}{7mm}
+\setlength{\textwidth}{150mm}
+\setlength{\textheight}{230mm}
+\setlength{\parindent}{18pt}
+
+\pagestyle{myheadings}
+\sloppy
+
+\begin{document}
+
+\begin{titlepage}
+\begin{center}
+
+\vspace*{2.5in}
+
+\begin{huge}
+{\bf GNU Linear Programming Kit}
+\end{huge}
+
+\vspace{0.5in}
+
+\begin{LARGE}
+{\bf Modeling Language GLPK/L}
+\end{LARGE}
+
+\vspace{0.5in}
+
+\begin{LARGE}
+{\bf Version 3.2}
+\end{LARGE}
+
+\vspace{0.5in}
+\begin{Large}
+(Draft Edition, June 2002)
+\end{Large}
+\end{center}
+
+\newpage
+\vspace*{1in}
+\vfill
+
+\noindent
+The GLPK package is a part of the GNU project released under the aegis
+of GNU.
+
+\medskip \noindent
+Copyright \copyright{} 2000, 2001, 2002 Andrew Makhorin, Department for
+Applied Informatics, Moscow Aviation Institute, Moscow, Russia. All
+rights reserved.
+
+\medskip \noindent
+Free Software Foundation, Inc., 59 Temple Place  Suite 330, Boston,
+MA 02111, USA.
+
+\medskip \noindent
+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.
+
+\medskip \noindent
+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.
+
+\medskip \noindent
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+\end{titlepage}
+
+\tableofcontents
+
+\chapter{Basic Concepts}
+
+\section{Introduction}
+
+GLPK/L modeling language is intended for writing mathematical
+programming models. Its name is derived from \underline{G}NU
+\underline{L}inear \underline{P}rogramming \underline{K}it
+\underline{L}anguage.
+
+Model description written in GLPK/L language consists of a sequence of
+statements constructed by the user from the language elements described
+in this document.
+
+In a process called translation a program called the language
+processor analyzes the model description statements and translates them
+into internal data structures, which may be then used either for
+generating mathematical programming problem data or directly by
+a program called the solver for obtaining numerical solution of the
+problem.
+
+GLPK/L modeling language is a part of the GLPK package.
+
+\section{Mathematical programming problem}
+
+GLPK/L assumes the following formulation of mathematical nonlinear
+programming (NLP) problem\footnote{Processing model description written
+in GLPK/L language assumes generating data for mathematical programming
+problem. Although the GLPK package is designed for linear problems, the
+GLPK/L language is suitable for expressing linear as well as nonlinear
+problems. That is the reason why the general formulation is given
+here.}:
+
+\medskip
+
+\noindent
+\hspace{1in} minimize (or maximize)
+$$Z = x_{obj} \eqno (1.1)$$
+\hspace{1in} subject to (nonlinear) constraints
+$$
+\begin{array}{c}
+\nonumber x_1 = f_1(x_{m+1}, x_{m+2}, \dots, x_{m+n}) \\
+\nonumber x_2 = f_2(x_{m+1}, x_{m+2}, \dots, x_{m+n}) \\
+\nonumber \dots \dots \dots \dots \dots \dots \\
+\nonumber x_m = f_m(x_{m+1}, x_{m+2}, \dots, x_{m+n}) \\
+\end{array} \eqno (1.2)
+$$
+\hspace{1in} and bounds of variables
+$$
+\begin{array}{c}
+\nonumber l_1 \leq x_1 \leq u_1 \\
+\nonumber l_2 \leq x_2 \leq u_2 \\
+\nonumber \dots \dots \dots \\
+\nonumber l_{m+n} \leq x_{m+n} \leq u_{m+n} \\
+\end{array} \eqno (1.3)
+$$
+where: $x_1, x_2, \dots, x_m$  rows or auxiliary variables;
+$x_{m+1}, x_{m+2}, \dots, x_{m+n}$  columns or structural variables;
+$Z$  objective function;
+$obj$  the number of a row, which defines the objective function;
+$f_1, f_2, \dots, f_m$  (nonlinear) functions, which define the
+equiality constraints;
+$l_1, l_2, \dots, l_{m+n}$  lower bounds of variables;
+$u_1, u_2, \dots, u_{m+n}$  upper bounds of variables.
+
+If all the functions $f_1$, $f_2$, \dots, $f_m$ are linear, the
+problem (1.1)(1.3) turns into linear programming (LP) problem. LP
+differs from NLP only in the system of equality constraints (1.2), which
+in the case of LP is the following:
+$$
+\begin{array}{c}
+\nonumber x_1 = a_{11}x_{m+1} + a_{12}x_{m+2} + \dots + a_{1n}x_{m+n} \\
+\nonumber x_2 = a_{21}x_{m+1} + a_{22}x_{m+2} + \dots + a_{2n}x_{m+n} \\
+\nonumber \dots \dots \dots \dots \dots \dots \\
+\nonumber x_m = a_{m1}x_{m+1} + a_{m2}x_{m+2} + \dots + a_{mn}x_{m+n} \\
+\end{array} \eqno (1.4)
+$$
+where $a_{11}$, $a_{12}$, \dots, $a_{mn}$ are constraint coefficients.
+
+Auxiliary variables are called {\it rows}, because they correspond to
+rows of the constraint matrix (i.e. the matrix built of constraint
+coefficients as in the case of LP). Analogously, structural variables
+are 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$ & Doublebounded 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.
+
+In addition to LP and NLP problems GLPK/L allows mixed integer linear
+or nonlinear (MIP) problems, where some (or all) variables are
+required to be integer. GLPK/L assumes that MIP problem has the same
+formulation as ordinary (pure) LP or NLP problem, i.e. includes
+structural and auxiliary variables, which can have lower and/or upper
+bounds. Note that in GLPK/L only structural variables (columns) are
+allowed to be of integer kind.
+
+\section{Model expressions}
+
+Principal constituents of the system of equality constraints (1.2) are
+functions $f_1$, $f_2$, \dots, $f_m$ of structural variables. In GLPK/L
+it is assumed that these functions can be expressed in the form of so
+called model expressions.
+
+{\it Model expression} is an algebraic formula composed of numeric
+constants, structural variables, and arithmetic operators.
+
+For example, the formula
+$$x+2\cdot(y3\cdot z)+4.5$$
+is a model expression, where $x$, $y$, $z$ are structural variables,
+2, 3, 4.5 are numeric constants, $+$, $$, $\cdot$ are arithmetic
+operators.
+
+In GLPK/L model expressions are used as ``values'', which can be
+assigned to some language objects (like, say, floatingpoint numbers can
+be assigned to variables in programming languages). In this sense the
+language objects are close to objects of computer algebra systems.
+Although model expressions have a special internal representation, the
+user can think them just as character strings that represent the
+corresponding formulae.
+
+Being algebraic objects model expressions allow all operations, which
+are applicable to numbers. Let, for example, $e_1$ and $e_2$ be the
+following model expressions:
+$$
+\begin{array}{r@{}c@{}l}
+e_1 & \ = \ & x + 2\cdot y \\
+e_2 & \ = \ & z + 1 \\
+\end{array}
+$$
+Then it is possible to compute, say, the sum of $e_1$ and $e_2$:
+$$e = e_1+e_2 = x + 2\cdot y + z + 1,$$
+where $e$ is the resultant model expression.
+
+It is understood that ordinary numeric constants can be considered as
+a particular form of model expressions.
+
+Model expression, which contain no structural variables, is called
+{\it constant model expression}. The language processor always reduces
+constant model expressions to the form of numeric constants. On the
+other hand, if at least one model expression participating in an
+operation is not a constant expression, the language processor keeps the
+resultant expression ``as is'', performing no algebraic transformations.
+Let, for example, $e_1=2\cdot x+1$ and $e_2=3\cdot x+2$. Addition of
+$e_1$ and $e_2$ gives the resultant expression
+$e = e_1+e_2 = 2\cdot x + 1 + 3\cdot x + 2$ in spite of that it could be
+reduced to $e=5\cdot x + 3$.
+
+In order to attach a model expression to a particular constraint the
+assigned statement should be used (see Section 5.1).
+
+The GLPK package is not intended to deal with nonlinear problems,
+so all model expressions used to build equiality constraints should be
+linear.
+
+{\it Linear model expression} can be defined recursively as follows:
+
+1. Constant model expression is linear model expression.
+
+2. Structural variable is linear model expression.
+
+3. Let $e_1$ and $e_2$ be linear model expressions, $c$ be constant
+model expression. Then expressions $+e_1$, $e_1$, $e_1+e_2$,
+$e_1e_2$, $c\cdot e_1$, $e_1\cdot c$, and $e_1/c$ are linear model
+expressions.
+
+4. No else is linear model expression.
+
+For example, the expression
+$$x+2\cdot(y3\cdot x)/(10+2.5)4.5$$
+is linear, and the expression
+$$x+2\cdot(y3\cdot x)/(10+2.5\cdot x)4.5$$
+is not.
+
+\section{Model objects}
+
+The GLPK/L modeling language is designed to simplify preparing problem
+data, especially in the case of large scale problems.
+
+So far as components of mathematical programming problems are usually
+correspond to entities of the real world, composing such problems is
+called {\it modeling}, and a description of such problems expressed in
+a formal modeling language is called {\it mathematical model} or simply
+{\it model}.
+
+In GLPK/L model is described in terms of sets, parameters, predicates,
+variables, and constraints, which are called {\it model objects}.
+
+The user introduces particular model objects using declaration
+statements. Each model object is provided with a symbolic name, which
+uniquely identifies the object and is intended for referencing purposes.
+
+\subsection{Sets}
+
+{\it Set} is a collection of elementary abstract objects called
+{\it items}.
+
+Each set and each item have a symbolic name given by the user in the set
+declaration statement.
+
+Set can contain arbitrary number of items. Different sets can't contain
+the same item.
+
+In GLPK/L sets are used only as index sets (domains).
+
+\subsection{Parameters}
+
+{\it Parameter} is a multidimensional array built over sets.
+A particular element of parameter is called {\it parameter member}.
+Within array each parameter member is uniquely identified by its
+subscript list called {\it tuple}, which is an ordered sequence of items
+of the corresponding index sets.
+
+Number of sets, over which a parameter is built (i.e. number of items,
+which identify each parameter member, or, equivalently, number of its
+subscripts), is called {\it dimension}. In the current version of the
+language parameters can be built over up to 6 sets. 0dimensional
+parameter is called {\it scalar parameter}.
+
+Each parameter has a symbolic name given by the user in the parameter
+declaration statement. Parameter members have no individual names.
+
+Parameters have sparse structure. This means that some (or even all)
+parameter members may not exist.
+
+If a parameter member exists, it always has an assigned value. Values
+assigned to parameter members are model expressions (see Section 1.3).
+Since model expressions may have the form of numeric constants,
+parameters are also able to represent ordinary arrays of numeric data.
+
+Formally a parameter $F$ is the mapping
+$$F:S_1\times S_2\times \dots\times S_n \rightarrow \Xi,\eqno(1.5)$$
+where $S_1\times S_2\times \dots\times S_n$ is the Cartesian product of
+index sets, over which the parameter $F$ is built, $\Xi$ is the set of
+all model expressions (expanded with the special value \verbnil, to
+which all missing parameter members are mapped).
+
+The structure of $n$dimensional model parameter is schematically shown
+on Fig. 1.1.
+
+\begin{figure}
+\begin{center}
+\setlength{\unitlength}{0.75mm}
+\begin{picture}(90,70)
+\put(0,0){\makebox(40,10)[b]{Tuple}}
+\put(1,10){$\underbrace{\makebox(38,10){}}$}
+\put(40,0){\makebox(50,10)[b]{Assigned value}}
+\put(41,10){$\underbrace{\makebox(48,10){}}$}
+\put(0,10){\line(1,0){90}}
+\put(0,20){\line(1,0){90}}
+\put(0,10){\line(0,1){10}}
+\put(0,10){\makebox(10,10){$i_1$}}
+\put(10,10){\line(0,1){10}}
+\put(10,10){\makebox(10,10){$i_2$}}
+\put(20,10){\line(0,1){10}}
+\put(20,10){\makebox(10,10){\dots}}
+\put(30,10){\line(0,1){10}}
+\put(30,10){\makebox(10,10){$i_n$}}
+\put(40,10){\line(0,1){10}}
+\put(40,10){\makebox(50,10){Model expression}}
+\put(90,10){\line(0,1){10}}
+\put(30,30){\line(1,0){30}}
+\put(30,40){\line(1,0){30}}
+\put(30,30){\line(0,1){10}}
+\put(60,30){\line(0,1){10}}
+\put(60,35){\line(1,0){5}}
+\put(35,45){\line(1,0){30}}
+\put(35,40){\line(0,1){5}}
+\put(65,35){\line(0,1){10}}
+\put(65,40){\line(1,0){5}}
+\put(40,50){\line(1,0){30}}
+\put(40,45){\line(0,1){5}}
+\put(70,40){\line(0,1){10}}
+\put(30,30){\makebox(30,10){Member}}
+\put(0,20){\line(3,1){30}}
+\put(60,30){\line(3,1){30}}
+\put(30,60){\framebox(40,10){Parameter}}
+\put(50,50){\line(0,1){10}}
+\end{picture}
+
+\bigskip
+
+Fig. 1.1. Structure of $n$dimensional model parameter
+\end{center}
+\end{figure}
+
+Note that from the formal definition (1.5) it follows that:
+
+a) all members of the same parameter should have different tuples, i.e.
+multiplets (members with identical tuples) are not allowed;
+
+b) in the case of 0dimensional (scalar) parameters the Cartesian
+product formally has one element. And since sparse parameters are
+allowed, each scalar parameter can have either one member or no member.
+
+\subsection{Predicates}
+
+Predicates have the same structure as parameters, i.e. {\it predicate}
+is a multidimensional array built over sets. However, unlike parameters
+predicate members have no assigned values.
+
+Formally a predicate $P$ is the mapping
+$$P:S_1\times S_2\times \dots\times S_n \rightarrow
+\{{\tt true}, {\tt false}\}, \eqno(1.6)$$
+where $S_1\times S_2\times \dots\times S_n$ is the Cartesian product of
+index sets, over which the predicate $P$ is built,
+$\{{\tt true}, {\tt false}\}$ is the set of Boolean values. Existing
+predicate members are mapped to {\tt true}, and all other elements of
+the Cartesian product, which are missing in the predicate, are mapped to
+{\tt false} (thus, predicates also have sparse structure).
+
+The structure of $n$dimensional model predicate is schematically shown
+on Fig. 1.2.
+
+\begin{figure}
+\begin{center}
+\setlength{\unitlength}{0.75mm}
+\begin{picture}(90,70)
+\put(0,0){\makebox(40,10)[b]{Tuple}}
+\put(1,10){$\underbrace{\makebox(38,10){}}$}
+\put(0,10){\line(1,0){90}}
+\put(0,20){\line(1,0){90}}
+\put(0,10){\line(0,1){10}}
+\put(0,10){\makebox(10,10){$i_1$}}
+\put(10,10){\line(0,1){10}}
+\put(10,10){\makebox(10,10){$i_2$}}
+\put(20,10){\line(0,1){10}}
+\put(20,10){\makebox(10,10){\dots}}
+\put(30,10){\line(0,1){10}}
+\put(30,10){\makebox(10,10){$i_n$}}
+\put(40,10){\line(0,1){10}}
+\put(40,10){\makebox(50,10){(no assigned value)}}
+\put(90,10){\line(0,1){10}}
+\put(30,30){\line(1,0){30}}
+\put(30,40){\line(1,0){30}}
+\put(30,30){\line(0,1){10}}
+\put(60,30){\line(0,1){10}}
+\put(60,35){\line(1,0){5}}
+\put(35,45){\line(1,0){30}}
+\put(35,40){\line(0,1){5}}
+\put(65,35){\line(0,1){10}}
+\put(65,40){\line(1,0){5}}
+\put(40,50){\line(1,0){30}}
+\put(40,45){\line(0,1){5}}
+\put(70,40){\line(0,1){10}}
+\put(30,30){\makebox(30,10){Member}}
+\put(0,20){\line(3,1){30}}
+\put(60,30){\line(3,1){30}}
+\put(30,60){\framebox(40,10){Predicate}}
+\put(50,50){\line(0,1){10}}
+\end{picture}
+
+\bigskip
+
+Fig. 1.2. Structure of $n$dimensional model predicate
+\end{center}
+\end{figure}
+
+Predicates are mainly intended for expressing relationships between
+items that can be used for constructing various logical conditions.
+
+As a rule predicates appear as intermediate results, but the user can
+explicitly declare a named predicate using the predicate declaration
+statement.
+
+May note that predicates are similar to Boolean arrays in programming
+languages.
+
+\subsection{Variables}
+
+{\it Variable} is a multidimensional array built over sets like
+parameters and predicates.
+
+Members of variables called {\it elemental variables} play double role.
+Firstly, each elemental variable defines the corresponding structural
+variable of the problem. And secondly, each elemental variable being
+a valid model expression can be used in the same sense as model
+expressions assigned to parameter members.
+
+Formally, a variable $V$ is the mapping
+$$V:S_1\times S_2\times \dots\times S_n \rightarrow X, \eqno(1.7)$$
+where $S_1\times S_2\times \dots\times S_n$ is the Cartesian product of
+index sets, over which the variable $V$ is built,
+$X=\{x_{m+1},x_{m+2},\dots,x_{m+n}\}$ is the set of structural
+variables (see Section 1.1).
+
+The structure of $n$dimensional model variable is schematically shown
+on Fig. 1.3.
+
+\begin{figure}
+\begin{center}
+\setlength{\unitlength}{0.75mm}
+\begin{picture}(90,70)
+\put(0,0){\makebox(40,10)[b]{Tuple}}
+\put(1,10){$\underbrace{\makebox(38,10){}}$}
+\put(0,10){\line(1,0){90}}
+\put(0,20){\line(1,0){90}}
+\put(0,10){\line(0,1){10}}
+\put(0,10){\makebox(10,10){$i_1$}}
+\put(10,10){\line(0,1){10}}
+\put(10,10){\makebox(10,10){$i_2$}}
+\put(20,10){\line(0,1){10}}
+\put(20,10){\makebox(10,10){\dots}}
+\put(30,10){\line(0,1){10}}
+\put(30,10){\makebox(10,10){$i_n$}}
+\put(40,10){\line(0,1){10}}
+\put(40,10){\makebox(50,10){Structural variable}}
+\put(90,10){\line(0,1){10}}
+\put(30,30){\line(1,0){30}}
+\put(30,40){\line(1,0){30}}
+\put(30,30){\line(0,1){10}}
+\put(60,30){\line(0,1){10}}
+\put(60,35){\line(1,0){5}}
+\put(35,45){\line(1,0){30}}
+\put(35,40){\line(0,1){5}}
+\put(65,35){\line(0,1){10}}
+\put(65,40){\line(1,0){5}}
+\put(40,50){\line(1,0){30}}
+\put(40,45){\line(0,1){5}}
+\put(70,40){\line(0,1){10}}
+\put(30,30){\makebox(30,10){Member}}
+\put(0,20){\line(3,1){30}}
+\put(60,30){\line(3,1){30}}
+\put(30,60){\framebox(40,10){Variable}}
+\put(50,50){\line(0,1){10}}
+\end{picture}
+
+\bigskip
+
+Fig. 1.3. Structure of $n$dimensional model variable
+\end{center}
+\end{figure}
+
+The user introduces variables into model using the variable declaration
+statements, which also creates all elemental variables. As a rule there
+is no need to have sparse variables, however, the user can declare
+a sparse variable using the predicatecontrolled declaration. Note that
+nothing can be assigned to variables, because variables are unknown
+quantities.
+
+\subsection{Constraints}
+
+{\it Constraint} is a multidimensional array built over sets, i.e. this
+model object has the same structure as parameters, predicates, and
+variables.
+
+Members of constraints called {\it elemental constraints} like members
+of variables play double role. Firstly, each elemental constraint
+defines the corresponding equality constraint of the problem. And
+secondly, since each elemental constraint has an associated model
+expression (which defines a function of structural variables), it can
+be used in the same sense as model expressions assigned to parameter
+members.
+
+Formally a constraint $C$ is the mapping
+$$C:S_1\times S_2\times \dots\times S_n \rightarrow R, \eqno(1.8)$$
+where $S_1\times S_2\times \dots\times S_n$ is the Cartesian product of
+index sets, over which the constraint $C$ is built, $R$ is the set of
+equality constraints (1.2) of the problem (see Section 1.2).
+
+The structure of $n$dimensional model constraint is schematically shown
+on Fig. 1.4.
+
+\begin{figure}
+\begin{center}
+\setlength{\unitlength}{0.75mm}
+\begin{picture}(90,70)
+\put(0,0){\makebox(40,10)[b]{Tuple}}
+\put(1,10){$\underbrace{\makebox(38,10){}}$}
+\put(40,0){\makebox(50,10)[b]{Assigned value}}
+\put(41,10){$\underbrace{\makebox(48,10){}}$}
+\put(0,10){\line(1,0){90}}
+\put(0,20){\line(1,0){90}}
+\put(0,10){\line(0,1){10}}
+\put(0,10){\makebox(10,10){$i_1$}}
+\put(10,10){\line(0,1){10}}
+\put(10,10){\makebox(10,10){$i_2$}}
+\put(20,10){\line(0,1){10}}
+\put(20,10){\makebox(10,10){\dots}}
+\put(30,10){\line(0,1){10}}
+\put(30,10){\makebox(10,10){$i_n$}}
+\put(40,10){\line(0,1){10}}
+\put(40,10){\makebox(50,10){Problem constraint}}
+\put(90,10){\line(0,1){10}}
+\put(30,30){\line(1,0){30}}
+\put(30,40){\line(1,0){30}}
+\put(30,30){\line(0,1){10}}
+\put(60,30){\line(0,1){10}}
+\put(60,35){\line(1,0){5}}
+\put(35,45){\line(1,0){30}}
+\put(35,40){\line(0,1){5}}
+\put(65,35){\line(0,1){10}}
+\put(65,40){\line(1,0){5}}
+\put(40,50){\line(1,0){30}}
+\put(40,45){\line(0,1){5}}
+\put(70,40){\line(0,1){10}}
+\put(30,30){\makebox(30,10){Member}}
+\put(0,20){\line(3,1){30}}
+\put(60,30){\line(3,1){30}}
+\put(30,60){\framebox(40,10){Constraint}}
+\put(50,50){\line(0,1){10}}
+\end{picture}
+
+\bigskip
+
+Fig. 1.4. Structure of $n$dimensional model constraint
+\end{center}
+\end{figure}
+
+The user introduces constraints into model by means of the constraint
+declaration statements. Unlike variables being declared constraints have
+no members. In order to create elemental constraints and assign some
+model expressions to them the assignment statements should be used in
+the same way as for model parameters.
+
+\subsection{Implicit parameters}
+
+Being declared each model variable and each model constraint cause three
+implicit parameters to be automatically introduced into the model, which
+are {\it loparameter}, {\it upparameter}, and {\it fxparameter}.
+These three parameters have the same dimension and are built over the
+same set as the corresponding model object.
+
+Members of implicit parameters define the type and bounds of the
+corresponding elemental structural or auxiliary variable $x_k$ as shown
+below:
+
+\begin{center}
+\begin{tabular}{lccc}
+\hline
+Type of variable & loparameter & upparameter & fxparameter \\
+\hline
+Free (unbounded) variable &  &  &  \\
+Variable with lower bound & $l_k$ &  &  \\
+Variable with upper bound &  & $u_k$ &  \\
+Doublebounded variable & $l_k$ & $u_k$ &  \\
+Fixed variable &  &  & $s_k$ \\
+\hline
+\end{tabular}
+\end{center}
+
+\noindent
+where $l_k$ is lower bound, $u_k$ is upper bound, $s_k$ is fixed value,
+``'' means the corresponding parameter member doesn't exist (see
+also Section 1.2).
+
+Implicit parameters can be used in the same way as explicitly declared
+parameters. However, all model expressions assigned to members of
+implicit parameters should be constant model expressions (see Section
+1.3).
+
+Should note that creating a member of one implicit parameter may
+involve deleting members of other implicit parameters associated with
+the same model object. For example, assigning a constant expression to
+a member of fxparameter causes deleting members with the same tuple
+from lo and upparameter, and vice versa.
+
+Implicit parameters allow the user changing types and bounds of
+elemental variables as well as using the current bounds as numeric data
+for computing other quantities.
+
+\chapter{Elements of the language}
+
+\section{Coding model description}
+
+Model description is coded in the plain text format using the following
+character set:
+
+\begin{verbatim}
+ ::= 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
+ ::= 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
+ ::=  _ 
+ ::= 0  1  2  3  4  5  6  7  8  9
+ ::= !  #  (  )  *  +  ,    .  /  :  ; 
+ <  =  >  [  ]
+ ::= SP  HT  CR  NL  VT  FF
+ ::=   
+
+\end{verbatim}
+
+Only \verb are valid in model description. (However,
+within comment sequences any printable characters are allowed; see
+Section 2.5.)
+
+Whitespace characters are nonsignificant. They can be used freely
+between syntactic units (see below) to improve readability of model
+description. They are also used to separate syntactic units from each
+other if there is no other way to do that.
+
+Syntactically model description is a sequence of the following syntactic
+units composed from letters, digits, and graphic characters:
+
+\begin{verbatim}
+ ::=  
+ 
+\end{verbatim}
+
+Syntactic units are described in the next sections.
+
+\section{Symbolic names}
+
+\paragraph{Syntax}
+
+\begin{verbatim}
+ ::=  
+
+\end{verbatim}
+
+\paragraph{Examples}
+
+\begin{verbatim}
+alpha
+this_is_a_name
+P123_abc321_
+_12345
+\end{verbatim}
+
+\paragraph{Semantics}
+
+Symbolic names are used in model description to identify model objects
+in the following categories: sets, items, parameters, predicates,
+variables, and constraints. Symbolic names should be unique, i.e.
+no objects can have the same symbolic name.
+
+Maximal length of symbolic names is 31 characters. All symbolic names
+are distinct (case sensitive).
+
+Symbolic names are introduced into model description by means of
+declaration statements.
+
+In GLPK/L there are some reserved keywords, which have fixed meaning
+and therefore should not be used as symbolic names. These are:
+
+\begin{verbatim}
+ and binary constraint constraints display
+ end false in integer maximize
+ minimize model nil not or
+ parameter parameters predicate predicates set
+ sets true variable variables where
+\end{verbatim}
+
+\section{Numeric constants}
+
+\paragraph{Syntax}
+
+\begin{verbatim}
+ ::= 
+ ::=  . 
+ .  .
+ ::= e  e + 
+ e 
+ ::= 
+\end{verbatim}
+
+(It is allowed to write the letter \verbE instead the letter
+\verbe.)
+
+\paragraph{Examples}
+
+\begin{verbatim}
+0
+123
+3.14159
+56.
+.78
+123.456e7
+\end{verbatim}
+
+\paragraph{Semantics}
+
+Numeric constants are selfdefined literals, which have obvious fixed
+meaning.
+
+\section{Delimiters}
+
+\paragraph{Syntax}
+
+\begin{verbatim}
+ ::= #  (  )  *  +  ,    .  /  :  ;  <  =  > 
+ [  ]  ++    :=  <=  >=  !=
+\end{verbatim}
+
+(In case of twocharacter delimiter there should be no whitespace
+characters between delimiter characters.)
+
+\paragraph{Semantics}
+
+Delimiters are used for different purposes. Their meaning will be
+explained below.
+
+\section{Comment sequences}
+
+\paragraph{Syntax}
+
+\begin{verbatim}
+ ::= /* */
+\end{verbatim}
+
+\paragraph{Example}
+
+\begin{verbatim}
+/* This is a comment */
+\end{verbatim}
+
+\paragraph{Semantics}
+
+Comment sequences are nonsignificant syntactic units ignored by the
+language processor. They can appear anywhere in model description,
+where whitespace characters are allowed.
+
+The user can provide the model description with comments in order to
+improve its readability and for documenting purposes.
+
+\chapter{Declaration statements}
+
+Declaration statements are intended to explicitly declare certain
+properties of the model objects (which are sets, parameters, predicates,
+variables, and constraints) used in the model description, and to
+associate them with symbolic names.
+
+No symbolic names can be declared more than once.
+
+\section{Set statement}
+
+\paragraph{Syntax}
+
+\begin{verbatim}
+ ::=
+ ::=
+
 ::=
 
 ,

+ ::= = ( )  = (
 )
+ ::=  ,
+ ::= set ;  sets ;
+\end{verbatim}
+
+\paragraph{Examples}
+
+\begin{verbatim}
+set colors = (red, green, blue);
+sets months = (Jan, Feb, Mar, Apr, May, Jun),
+ cities = (Boston, Chicago, Dallas, Memphis, Portland),
+ empty = ();
+\end{verbatim}
+
+\paragraph{Semantics}
+
+The set statement is intended to declare certain symbolic names to
+represent sets and to declare certain symbolic names to represent items
+(see Subsection 1.4.1).
+
+\section{Parameter statement}
+
+\paragraph{Syntax}
+
+\begin{verbatim}
+ ::=
+ ::=
+ ::=  ,
+ ::= 
+ [ ]
+ ::= 
+ ,
+ ::= parameter ; 
+ parameters ;
+\end{verbatim}
+
+\paragraph{Examples}
+
+\begin{verbatim}
+parameter pi;
+parameters dist[cities,cities], st[cities,months,cities];
+\end{verbatim}
+
+\paragraph{Semantics}
+
+The parameter statement is intended to declare certain symbolic names
+to represent model parameters, and to specify sets, over which the
+parameters should be built (see Subsection 1.4.2).
+
+Being declared a parameter initially has no members. In order to create
+some parameter members and to assign some values (i.e. model
+expressions) to them the assignment statement should be used (see
+Section 5.1).
+
+\section{Predicate statement}
+
+\paragraph{Syntax}
+
+\begin{verbatim}
+ ::=
+ ::=
+ ::=  ,
+ ::= 
+ [ ]
+ ::= 
+ ,
+ ::= predicate ; 
+ predicates ;
+\end{verbatim}
+
+\paragraph{Examples}
+
+\begin{verbatim}
+predicate cond[cities,cities];
+predicates winter[months], p123;
+\end{verbatim}
+
+\paragraph{Semantics}
+
+The predicate statement is intended to declare certain symbolic names
+to represent model predicates, and to specify sets, over which the
+predicates should be built (see Subsection 1.4.3).
+
+Being declared a predicate initially has no members (thus, formally,
+such predicate has the Boolean value \verbfalse on all elements of the
+corresponding Cartesian product). In order to create some predicate
+members (i.e. assign the Boolean value \verbtrue to some elements of
+the Cartesian product) the assignment statement should be used (see
+Section 5.1).
+
+\newpage
+
+\section{Variable statement}
+
+\paragraph{Syntax}
+
+\begin{verbatim}
+ ::=
+ ::=
+ ::=  ,
+ ::=
+ ::= in
+ ::= 
+ ,
+ ::= 
+ [ ] 
+ [ ] where
+ ::= 
+ ,
+ ::=  integer  binary
+ ::= variable ; 
+ variables ;
+\end{verbatim}
+
+\paragraph{Examples}
+
+\begin{verbatim}
+variables x[cities,months], z1, z2, z3;
+binary variable t[i in cities, k in cities] where dist[k,i] <= 300;
+\end{verbatim}
+
+\paragraph{Semantics}
+
+The variable statement is intended to declare certain symbolic names to
+represent model variables, and to specify sets, over which the variables
+should be built (see Subsection 1.4.4).
+
+Unlike parameters and predicates, elemental variables (i.e. members)
+associated with a particular model variable are created by the variable
+statement. Note that being initially created and attached to a model
+variable an array of elemental variables can't be changed later by other
+statements.
+
+As it follows from the syntactic definition, the variable declaration
+has two different forms.
+
+The first form called {\it simple declaration} is the following:
+
+\begin{verbatim}
+ [ ]
+\end{verbatim}
+
+If the simple declaration is used, each element of the Cartesian product
+(of sets, over which the variable is built) produces exactly one
+elemental variable.
+
+The second form called {\it predicatecontrolled declaration} is the
+following:
+
+\begin{verbatim}
+ [ ] where
+\end{verbatim}
+
+If the predicate controlled declaration is used, the following actions
+are performed:
+
+1. Qualified list is processed. All mute letters (see Section 4.2) in
+the qualified list should be different.
+
+2. Predicate expression is computed and the resultant predcate is
+determined (see Section 4.6). All mute letters of the resultant
+predicate should be presented in the qualified list.
+
+3. If the qualified list contains mute letter(s), which are missing in
+the resultant predicate, the latter is expanded over set(s) that
+correspond to the missing mute letters.
+
+4. Each member of the resultant predicate (after expansion) produces
+exactly one elemental variable.
+
+Note that simple declaration is equivalent to predicatecontrolled
+declaration, where predicate expression is the constant \verbtrue.
+
+If neither \verbinteger nor \verbbinary keywords appear before the
+keyword \verbvariable, all variables listed in the statement (more
+exactly, all their elemental variables) are considered as
+{\it continuous nonnegative} structural variables. In order to declare
+{\it integer nonnegative} variables the keyword \verbinteger should
+be given before the keyword \verbvariable. Analogously, in order to
+declare {\it binary} variables, i.e. integer variables whose lower bound
+is zero and upper bound is one, the keyword \verbbinary should be
+given before the keyword \verbvariable.
+
+Note that the variable statement doesn't allow to explicitly specify
+lower and/or upper bounds of particular elemental variables. In order to
+do that the assignment statement (see Section 5.1) should be used.
+
+\section{Constraint statement}
+
+\paragraph{Syntax}
+
+\begin{verbatim}
+ ::=
+ ::=
+ ::=  ,
+ ::= 
+ [ ]
+ ::= 
+ ,
+ ::= constraint ; 
+ constraints ;
+\end{verbatim}
+
+\paragraph{Examples}
+
+\begin{verbatim}
+constraints r1, r2, rd[cities];
+constraint rs[months,colors];
+\end{verbatim}
+
+\paragraph{Semantics}
+
+The constraint statement is intended to declare certain symbolic names
+to represent model constraints, and to specify sets, over which the
+constraints should be built (see Subsection 1.4.5).
+
+Being declared a constraint initially has no members (elemental
+constraints). In order to create some elemental constraints and to
+attach some model expressions to them the assignment statement should
+be used (see Section 5.1).
+
+\chapter{Expressions}
+
+\section{Prelude}
+
+\paragraph{Syntax}
+
+\begin{verbatim}
+ ::= 
+\end{verbatim}
+
+\paragraph{Semantics}
+
+Parameter expression is a rule for computing parameter. Analogously,
+predicate expression is a rule for computing predicate. (Should
+especially emphasize that parameter and predicate expressions considered
+in this chapter and model expressions discussed in Section 1.3 are
+absolutely different things. Model expressions are ``values'' that can
+be assigned to parameter or constraint members, and parameter and
+predicate expressions are language constructions used as constituents of
+statements.)
+
+The result of computation of any (intermediate or final) expression is
+always either parameter or predicate. Such temporary objects are
+implicitly introduced into model description by the language processor.
+
+Consider, for example, the following parameter expression:
+
+\begin{verbatim}
+ a + b * c
+\end{verbatim}
+
+\noindent
+This expression is computed by the language processor in the following
+way:
+
+\begin{verbatim}
+ t1 := a;
+ t2 := b;
+ t3 := c;
+ t4 := t2 * t3;
+ t5 := t1 + t4;
+\end{verbatim}
+
+\noindent
+where \verbt1, \dots, \verbt5 are temporary parameters.
+
+\newpage
+
+\section{Mute letters}
+
+\paragraph{Syntax}
+
+\begin{verbatim}
+ ::=
+\end{verbatim}
+
+\paragraph{Semantics}
+
+Being computed each temporary parameter or predicate (see Section 4.1)
+acquires so called mute letters (except scalar parameters and predicates
+which need no mute letters).
+
+{\it Mute letter} is an auxiliary object, which denotes an index set.
+The user can also think mute letters as symbols (or indices), whose
+values are items of the set associated with a mute letter.
+
+In case of designators mute letters are introduced by the user.
+Otherwise, if a parameter or a predicate is the result of an operation,
+it automatically inherits mute letters of operands.
+
+All mute letters associated with index positions of a temporary
+parameter or predicate are always different.
+
+Let, for example, the following declaration be given:
+
+\begin{center}
+\verbparameter dist[cities,cities];
+\end{center}
+
+\noindent
+and consider the expression
+
+\begin{center}
+\verb0.5 * (dist[i,j] + dist[j,i])
+\end{center}
+
+\noindent
+In this expression the letters \verbi and \verbj are mute letters.
+They are used to explain how the language processor should perform
+addition. Thus, in the given case the expression is computed as follows:
+
+\begin{center}
+\begin{tabular}{ll}
+\verbt1[i,j] := dist[i,j] &
+ for all $i \in$ \verbcities, $j \in$ \verbcities \\
+\verbt2[i,j] := dist[j,i] &
+ for all $i \in$ \verbcities, $j \in$ \verbcities \\
+\verbt3[i,j] := t1[i,j] + t2[i,j] &
+ for all $i \in$ \verbcities, $j \in$ \verbcities \\
+\verbt4[i,j] := 0.5 * t3[i,j] &
+ for all $i \in$ \verbcities, $j \in$ \verbcities \\
+\end{tabular}
+\end{center}
+
+\noindent
+where \verbt1, \verbt2, \verbt3 are intermediate temporary
+parameters, and \verbt4 is a final temporary parameter, which defines
+the result of computation.
+
+Now consider another example:
+
+\begin{center}
+\verb0.5 * (dist[i,j] + dist[j,k])
+\end{center}
+
+\noindent
+This expression is computed as follows:
+
+\begin{center}
+\begin{tabular}{ll}
+\verbt1[i,j] := dist[i,j] &
+ for all $i \in$ \verbcities, $j \in$ \verbcities \\
+\verbt2[j,k] := dist[j,k] &
+ for all $j \in$ \verbcities, $k \in$ \verbcities \\
+\verbt3[i,j,k] := t1[i,j] + t2[j,k] &
+ for all $i \in$ \verbcities, $j \in$ \verbcities,
+ $k \in$ \verbcities \\
+\verbt4[i,j,k] := 0.5 * t3[i,j,k] &
+ for all $i \in$ \verbcities, $j \in$ \verbcities,
+ $k \in$ \verbcities \\
+\end{tabular}
+\end{center}
+
+Finally, consider yet another example:
+
+\begin{center}
+\verb0.5 * (dist[i,i] + dist[i,#Boston])
+\end{center}
+
+\noindent
+This expression is computed in the following way:
+
+\begin{center}
+\begin{tabular}{ll}
+\verbt1[i] := dist[i,i] &
+ for all $i \in$ \verbcities \\
+\verbt2[i] := dist[i,j] &
+ for all $i \in$ \verbcities, $j =$ \verbBoston \\
+\verbt3[i] := t1[i] + t2[i] &
+ for all $i \in$ \verbcities \\
+\verbt4[i] := 0.5 * t3[i] &
+ for all $i \in$ \verbcities \\
+\end{tabular}
+\end{center}
+
+Mute letters needn't to be declared. They are recognized by context.
+
+Note that identical mute letters denote the same sets only within a
+statement. If identical mute letters appear in different statements,
+they may denote different sets.
+
+\section{Designators}
+
+\paragraph{Syntax}
+
+\begin{verbatim}
+ ::=
+ ::=
+ ::=
+ ::=
+ ::=
+ ::=  . lo  . up  . fx
+ ::=   
+ 
+ ::=
+
 ::=
+ ::=
+ ::=  #
 
+ +   
+ ++  
+ ::=  ,
+ ::=  [ ]
+\end{verbatim}
+
+\paragraph{Examples}
+
+\begin{verbatim}
+alpha
+x[i,j]
+stat[i++2,j1,#Jan,i]
+r.up[#Feb,#white,k+1]
+\end{verbatim}
+
+\paragraph{Semantics}
+
+Designator is a primary expression, which allows to refer to sets,
+parameters (including implicit parameters), predicates, variables, and
+constraints.
+
+Number of subscripts in the designator should be the same as the
+dimension of the corresponding model object. If the object is
+0dimensional (scalar), subscript list and square brackets \verb[ and
+\verb] should be omitted.
+
+The correspondence between subscripts and sets, over which the object
+is built, is positional, i.e. the first subscript corresponds to the
+first set specified in the object declaration, the second subscript
+corresponds to the second set, and so on.
+
+If all subscripts are different mute letters, the result of computation
+of a designator is determined as follows:
+
+1. If \verb is a set, the result is 1dimensional predicate
+built over this set. Members of the resultant predicate correspond to
+items of this set (i.e. the resultant predicate has the value
+\verbtrue on all items). Being temporary the resultant predicate
+acquires the mute letter specified in the subscript list.
+
+2. If \verb is a parameter, the result is an exact copy of
+this parameter, which acquires the mute letters specified in the
+subscript list.
+
+3. If \verb is a predicate, the result is an exact copy of
+this predicate, which acquires the mute letters specified in the
+subscript list.
+
+4. If \verb is a variable, the result is a parameter, which
+has the same dimension, built over the same sets, and has the same
+members as the specified variable. The model expression assigned to
+a particular member of the resultant parameter is the corresponding
+elemental variable. Being temporary the resultant parameter acquires the
+mute letters specified in the subscript list.
+
+5. If \verb is a constraint, the result is a parameter,
+which has the same dimension, built over the same sets, and has the same
+members as the specified constraint. The model expression assigned to
+a particular member of the resultant parameter is an exact copy of the
+model expression assigned to the corresponding elemental constraint.
+Being temporary the resultant parameter acquires the mute letters
+specified in the subscript list.
+
+6. If \verb has the suffixed form, it refers to an implicit
+parameter associated with the corresponding variable or constraint (see
+Subsection 1.4.6). In this case the result is an exact copy of the
+specified implicit parameter (as if it were an ordinary explicit
+parameter), which acquires the mute letters specified in the subscript
+list.
+
+If some subscripts are identical mute letters, the result of computation
+of the designator is determined in the same way as above, however, the
+resultant object will have only such members, where items that
+correspond to identical mute letters are equal to each other (this
+assumes that identical mute letters should refer to the same set).
+Besides, in the resultant object identical mute letters are replaced by
+one mute letter that involves decreasing the object dimension. For
+example, being computed the designator \verbu[i,j,j,i,j] gives
+a temporary object in the form \verbu'[i,j].
+
+If \verb is a particular item, i.e. has the form
+\verb#
 , the result of computation of the designator is
+determined in the same way as above, however, the resultant object will
+have only such members, where items that correspond to the subscript are
+equal to the specified item (this assumes that the specified item should
+belong to the appropriate set). Using particular items also involves
+decreasing dimension of the resultant object. For example, being
+computed the designator \verbv[i,#aaa,j,#bbb] gives a temporary object
+in the form \verbv'[i,j].
+
+\paragraph{Lag and lead operators}
+
+In GLPK/L there are so called {\it lag} and {\it lead operators}, which
+have the following syntactic forms:
+
+\begin{center}
+\begin{tabular}{ll}
+\verbi + n & linear lag operator \\
+\verbi  n & linear lead operator \\
+\verbi ++ n & circular lag operator \\
+\verbi  n & circular lead operator \\
+\end{tabular}
+\end{center}
+
+\noindent
+where \verbi is a mute letter, \verbn is an offset (unsigned
+integer).
+
+Lag and lead operators assume that items of an index set are renumbered
+by integers 1, 2, \dots, $n$ in the order, in which these items appear
+in the set declaration. Thus, a set $S$ may be written as
+$$S = \{i_1, i_2, \dots, i_n\},$$
+where $i_1$, $i_2$, \dots, $i_n$ are items. In the case of linear
+lag and lead operators items preceding the first item $i_1$ and
+following the last item $i_n$ are undefined. However, in the case of
+circular lag and lead operators it is assumed that the first item
+follows the last item and the last item precedes the first item, thus,
+for example, $i_{n+1}$ is the same as $i_1$ and $i_0$ is the same as
+$i_n$.
+
+The result of computation of a designator, where lag and/or lead
+operators are used, is determined in the following way.
+
+At first, the intermediate object (parameter or predicate) is computed
+in the same way as if there were no lag/lead operators. Then all
+elements of the Cartesian products are looked through. Let
+$t = (i_p, j_q, k_r, \dots)$ be a tuple, i.e. some element of the
+Cartesian product, where $p, q, r, \dots$ are ordinal numbers of items
+in the corresponding sets. If lag or lead operator is applied, say, to
+$i_p$, this means that this item is replaced by $i_{p+\delta}$ (in the
+case of lag operator) or by $i_{p\delta}$ (in the case of lead
+operator). If there are other lag and/or lead operators, they are
+applied in the same way. Such replacement(s) gives a \it shifted \rm
+tuple $t' = (i'_p, j'_q, k'_r, \dots)$. If the shifted tuple $t'$ is
+undefined (that may happen in the case of linear operators as it was
+explained above) or if there is no member with the shifted tuple $t'$
+in the intermediate object, no member is included in the final resultant
+object. Otherwise, the original tuple $t$ (not the shifted tuple $t'$)
+and the value assigned to the member with the shifted tuple $t'$
+(not the original tuple $t$) of the intermediate object give a member,
+which is included in the final resultant object.
+
+Let, for example, the set \verbS be declared as follows:
+
+\begin{center}
+\begin{verbatim}
+ set S = (a, b, c, d, e);
+\end{verbatim}
+\end{center}
+
+\noindent
+and the onedimensional parameter \verbu be built over the set
+\verbS:
+
+\begin{verbatim}
+ parameter u[S];
+ u[i] := data(i in S: a 1, b 2, c 3, d 4, e 5);
+\end{verbatim}
+
+\noindent
+Then some resultant parameters are computed as follows:
+
+\begin{center}
+\begin{tabular}{ccccc}
+\verbu[i]& \verbu[i+2]&\verbu[i2]&\verbu[i++2]&\verbu[i2]\\
+\hline
+\verba 1 &  & \verbc 1 & \verbd 1 & \verbc 1 \\
+\verbb 2 &  & \verbd 2 & \verbe 2 & \verbd 2 \\
+\verbc 3 & \verba 3 & \verbe 3 & \verba 3 & \verbe 3 \\
+\verbd 4 & \verbb 4 &  & \verbb 4 & \verba 4 \\
+\verbe 5 & \verbc 5 &  & \verbc 5 & \verbb 5 \\
+\end{tabular}
+\end{center}
+
+\noindent
+where ``'' means a member, which is not included in the resultant
+object.
+
+\newpage
+
+\section{Parameter expressions}
+
+\paragraph{Syntax}
+
+\begin{verbatim}
+ ::= nil  