src/glpmpl.h
changeset 1 c445c931472f
equal deleted inserted replaced
-1:000000000000 0:0f7ac9a30f49
       
     1 /* glpmpl.h (GNU MathProg translator) */
       
     2 
       
     3 /***********************************************************************
       
     4 *  This code is part of GLPK (GNU Linear Programming Kit).
       
     5 *
       
     6 *  Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
       
     7 *  2009, 2010 Andrew Makhorin, Department for Applied Informatics,
       
     8 *  Moscow Aviation Institute, Moscow, Russia. All rights reserved.
       
     9 *  E-mail: <mao@gnu.org>.
       
    10 *
       
    11 *  GLPK is free software: you can redistribute it and/or modify it
       
    12 *  under the terms of the GNU General Public License as published by
       
    13 *  the Free Software Foundation, either version 3 of the License, or
       
    14 *  (at your option) any later version.
       
    15 *
       
    16 *  GLPK is distributed in the hope that it will be useful, but WITHOUT
       
    17 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
       
    18 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
       
    19 *  License for more details.
       
    20 *
       
    21 *  You should have received a copy of the GNU General Public License
       
    22 *  along with GLPK. If not, see <http://www.gnu.org/licenses/>.
       
    23 ***********************************************************************/
       
    24 
       
    25 #ifndef GLPMPL_H
       
    26 #define GLPMPL_H
       
    27 
       
    28 #include "glpavl.h"
       
    29 #include "glprng.h"
       
    30 
       
    31 typedef struct MPL MPL;
       
    32 typedef char STRING;
       
    33 typedef struct SYMBOL SYMBOL;
       
    34 typedef struct TUPLE TUPLE;
       
    35 typedef struct ARRAY ELEMSET;
       
    36 typedef struct ELEMVAR ELEMVAR;
       
    37 typedef struct FORMULA FORMULA;
       
    38 typedef struct ELEMCON ELEMCON;
       
    39 typedef union VALUE VALUE;
       
    40 typedef struct ARRAY ARRAY;
       
    41 typedef struct MEMBER MEMBER;
       
    42 #if 1
       
    43 /* many C compilers have DOMAIN declared in <math.h> :( */
       
    44 #undef DOMAIN
       
    45 #define DOMAIN DOMAIN1
       
    46 #endif
       
    47 typedef struct DOMAIN DOMAIN;
       
    48 typedef struct DOMAIN_BLOCK DOMAIN_BLOCK;
       
    49 typedef struct DOMAIN_SLOT DOMAIN_SLOT;
       
    50 typedef struct SET SET;
       
    51 typedef struct WITHIN WITHIN;
       
    52 typedef struct GADGET GADGET;
       
    53 typedef struct PARAMETER PARAMETER;
       
    54 typedef struct CONDITION CONDITION;
       
    55 typedef struct VARIABLE VARIABLE;
       
    56 typedef struct CONSTRAINT CONSTRAINT;
       
    57 typedef struct TABLE TABLE;
       
    58 typedef struct TABARG TABARG;
       
    59 typedef struct TABFLD TABFLD;
       
    60 typedef struct TABIN TABIN;
       
    61 typedef struct TABOUT TABOUT;
       
    62 typedef struct TABDCA TABDCA;
       
    63 typedef union OPERANDS OPERANDS;
       
    64 typedef struct ARG_LIST ARG_LIST;
       
    65 typedef struct CODE CODE;
       
    66 typedef struct CHECK CHECK;
       
    67 typedef struct DISPLAY DISPLAY;
       
    68 typedef struct DISPLAY1 DISPLAY1;
       
    69 typedef struct PRINTF PRINTF;
       
    70 typedef struct PRINTF1 PRINTF1;
       
    71 typedef struct FOR FOR;
       
    72 typedef struct STATEMENT STATEMENT;
       
    73 typedef struct TUPLE SLICE;
       
    74 
       
    75 /**********************************************************************/
       
    76 /* * *                    TRANSLATOR DATABASE                     * * */
       
    77 /**********************************************************************/
       
    78 
       
    79 #define A_BINARY        101   /* something binary */
       
    80 #define A_CHECK         102   /* check statement */
       
    81 #define A_CONSTRAINT    103   /* model constraint */
       
    82 #define A_DISPLAY       104   /* display statement */
       
    83 #define A_ELEMCON       105   /* elemental constraint/objective */
       
    84 #define A_ELEMSET       106   /* elemental set */
       
    85 #define A_ELEMVAR       107   /* elemental variable */
       
    86 #define A_EXPRESSION    108   /* expression */
       
    87 #define A_FOR           109   /* for statement */
       
    88 #define A_FORMULA       110   /* formula */
       
    89 #define A_INDEX         111   /* dummy index */
       
    90 #define A_INPUT         112   /* input table */
       
    91 #define A_INTEGER       113   /* something integer */
       
    92 #define A_LOGICAL       114   /* something logical */
       
    93 #define A_MAXIMIZE      115   /* objective has to be maximized */
       
    94 #define A_MINIMIZE      116   /* objective has to be minimized */
       
    95 #define A_NONE          117   /* nothing */
       
    96 #define A_NUMERIC       118   /* something numeric */
       
    97 #define A_OUTPUT        119   /* output table */
       
    98 #define A_PARAMETER     120   /* model parameter */
       
    99 #define A_PRINTF        121   /* printf statement */
       
   100 #define A_SET           122   /* model set */
       
   101 #define A_SOLVE         123   /* solve statement */
       
   102 #define A_SYMBOLIC      124   /* something symbolic */
       
   103 #define A_TABLE         125   /* data table */
       
   104 #define A_TUPLE         126   /* n-tuple */
       
   105 #define A_VARIABLE      127   /* model variable */
       
   106 
       
   107 #define MAX_LENGTH 100
       
   108 /* maximal length of any symbolic value (this includes symbolic names,
       
   109    numeric and string literals, and all symbolic values that may appear
       
   110    during the evaluation phase) */
       
   111 
       
   112 #define CONTEXT_SIZE 60
       
   113 /* size of the context queue, in characters */
       
   114 
       
   115 #define OUTBUF_SIZE 1024
       
   116 /* size of the output buffer, in characters */
       
   117 
       
   118 struct MPL
       
   119 {     /* translator database */
       
   120       /*--------------------------------------------------------------*/
       
   121       /* scanning segment */
       
   122       int line;
       
   123       /* number of the current text line */
       
   124       int c;
       
   125       /* the current character or EOF */
       
   126       int token;
       
   127       /* the current token: */
       
   128 #define T_EOF           201   /* end of file */
       
   129 #define T_NAME          202   /* symbolic name (model section only) */
       
   130 #define T_SYMBOL        203   /* symbol (data section only) */
       
   131 #define T_NUMBER        204   /* numeric literal */
       
   132 #define T_STRING        205   /* string literal */
       
   133 #define T_AND           206   /* and && */
       
   134 #define T_BY            207   /* by */
       
   135 #define T_CROSS         208   /* cross */
       
   136 #define T_DIFF          209   /* diff */
       
   137 #define T_DIV           210   /* div */
       
   138 #define T_ELSE          211   /* else */
       
   139 #define T_IF            212   /* if */
       
   140 #define T_IN            213   /* in */
       
   141 #define T_INFINITY      214   /* Infinity */
       
   142 #define T_INTER         215   /* inter */
       
   143 #define T_LESS          216   /* less */
       
   144 #define T_MOD           217   /* mod */
       
   145 #define T_NOT           218   /* not ! */
       
   146 #define T_OR            219   /* or || */
       
   147 #define T_SPTP          220   /* s.t. */
       
   148 #define T_SYMDIFF       221   /* symdiff */
       
   149 #define T_THEN          222   /* then */
       
   150 #define T_UNION         223   /* union */
       
   151 #define T_WITHIN        224   /* within */
       
   152 #define T_PLUS          225   /* + */
       
   153 #define T_MINUS         226   /* - */
       
   154 #define T_ASTERISK      227   /* * */
       
   155 #define T_SLASH         228   /* / */
       
   156 #define T_POWER         229   /* ^ ** */
       
   157 #define T_LT            230   /* <  */
       
   158 #define T_LE            231   /* <= */
       
   159 #define T_EQ            232   /* = == */
       
   160 #define T_GE            233   /* >= */
       
   161 #define T_GT            234   /* >  */
       
   162 #define T_NE            235   /* <> != */
       
   163 #define T_CONCAT        236   /* & */
       
   164 #define T_BAR           237   /* | */
       
   165 #define T_POINT         238   /* . */
       
   166 #define T_COMMA         239   /* , */
       
   167 #define T_COLON         240   /* : */
       
   168 #define T_SEMICOLON     241   /* ; */
       
   169 #define T_ASSIGN        242   /* := */
       
   170 #define T_DOTS          243   /* .. */
       
   171 #define T_LEFT          244   /* ( */
       
   172 #define T_RIGHT         245   /* ) */
       
   173 #define T_LBRACKET      246   /* [ */
       
   174 #define T_RBRACKET      247   /* ] */
       
   175 #define T_LBRACE        248   /* { */
       
   176 #define T_RBRACE        249   /* } */
       
   177 #define T_APPEND        250   /* >> */
       
   178 #define T_TILDE         251   /* ~ */
       
   179 #define T_INPUT         252   /* <- */
       
   180       int imlen;
       
   181       /* length of the current token */
       
   182       char *image; /* char image[MAX_LENGTH+1]; */
       
   183       /* image of the current token */
       
   184       double value;
       
   185       /* value of the current token (for T_NUMBER only) */
       
   186       int b_token;
       
   187       /* the previous token */
       
   188       int b_imlen;
       
   189       /* length of the previous token */
       
   190       char *b_image; /* char b_image[MAX_LENGTH+1]; */
       
   191       /* image of the previous token */
       
   192       double b_value;
       
   193       /* value of the previous token (if token is T_NUMBER) */
       
   194       int f_dots;
       
   195       /* if this flag is set, the next token should be recognized as
       
   196          T_DOTS, not as T_POINT */
       
   197       int f_scan;
       
   198       /* if this flag is set, the next token is already scanned */
       
   199       int f_token;
       
   200       /* the next token */
       
   201       int f_imlen;
       
   202       /* length of the next token */
       
   203       char *f_image; /* char f_image[MAX_LENGTH+1]; */
       
   204       /* image of the next token */
       
   205       double f_value;
       
   206       /* value of the next token (if token is T_NUMBER) */
       
   207       char *context; /* char context[CONTEXT_SIZE]; */
       
   208       /* context circular queue (not null-terminated!) */
       
   209       int c_ptr;
       
   210       /* pointer to the current position in the context queue */
       
   211       int flag_d;
       
   212       /* if this flag is set, the data section is being processed */
       
   213       /*--------------------------------------------------------------*/
       
   214       /* translating segment */
       
   215       DMP *pool;
       
   216       /* memory pool used to allocate all data instances created during
       
   217          the translation phase */
       
   218       AVL *tree;
       
   219       /* symbolic name table:
       
   220          node.type = A_INDEX     => node.link -> DOMAIN_SLOT
       
   221          node.type = A_SET       => node.link -> SET
       
   222          node.type = A_PARAMETER => node.link -> PARAMETER
       
   223          node.type = A_VARIABLE  => node.link -> VARIABLE
       
   224          node.type = A_CONSTRANT => node.link -> CONSTRAINT */
       
   225       STATEMENT *model;
       
   226       /* linked list of model statements in the original order */
       
   227       int flag_x;
       
   228       /* if this flag is set, the current token being left parenthesis
       
   229          begins a slice that allows recognizing any undeclared symbolic
       
   230          names as dummy indices; this flag is automatically reset once
       
   231          the next token has been scanned */
       
   232       int as_within;
       
   233       /* the warning "in understood as within" has been issued */
       
   234       int as_in;
       
   235       /* the warning "within understood as in" has been issued */
       
   236       int as_binary;
       
   237       /* the warning "logical understood as binary" has been issued */
       
   238       int flag_s;
       
   239       /* if this flag is set, the solve statement has been parsed */
       
   240       /*--------------------------------------------------------------*/
       
   241       /* common segment */
       
   242       DMP *strings;
       
   243       /* memory pool to allocate STRING data structures */
       
   244       DMP *symbols;
       
   245       /* memory pool to allocate SYMBOL data structures */
       
   246       DMP *tuples;
       
   247       /* memory pool to allocate TUPLE data structures */
       
   248       DMP *arrays;
       
   249       /* memory pool to allocate ARRAY data structures */
       
   250       DMP *members;
       
   251       /* memory pool to allocate MEMBER data structures */
       
   252       DMP *elemvars;
       
   253       /* memory pool to allocate ELEMVAR data structures */
       
   254       DMP *formulae;
       
   255       /* memory pool to allocate FORMULA data structures */
       
   256       DMP *elemcons;
       
   257       /* memory pool to allocate ELEMCON data structures */
       
   258       ARRAY *a_list;
       
   259       /* linked list of all arrays in the database */
       
   260       char *sym_buf; /* char sym_buf[255+1]; */
       
   261       /* working buffer used by the routine format_symbol */
       
   262       char *tup_buf; /* char tup_buf[255+1]; */
       
   263       /* working buffer used by the routine format_tuple */
       
   264       /*--------------------------------------------------------------*/
       
   265       /* generating/postsolving segment */
       
   266       RNG *rand;
       
   267       /* pseudo-random number generator */
       
   268       int flag_p;
       
   269       /* if this flag is set, the postsolving phase is in effect */
       
   270       STATEMENT *stmt;
       
   271       /* model statement being currently executed */
       
   272       TABDCA *dca;
       
   273       /* pointer to table driver communication area for table statement
       
   274          currently executed */
       
   275       int m;
       
   276       /* number of rows in the problem, m >= 0 */
       
   277       int n;
       
   278       /* number of columns in the problem, n >= 0 */
       
   279       ELEMCON **row; /* ELEMCON *row[1+m]; */
       
   280       /* row[0] is not used;
       
   281          row[i] is elemental constraint or objective, which corresponds
       
   282          to i-th row of the problem, 1 <= i <= m */
       
   283       ELEMVAR **col; /* ELEMVAR *col[1+n]; */
       
   284       /* col[0] is not used;
       
   285          col[j] is elemental variable, which corresponds to j-th column
       
   286          of the problem, 1 <= j <= n */
       
   287       /*--------------------------------------------------------------*/
       
   288       /* input/output segment */
       
   289       XFILE *in_fp;
       
   290       /* stream assigned to the input text file */
       
   291       char *in_file;
       
   292       /* name of the input text file */
       
   293       XFILE *out_fp;
       
   294       /* stream assigned to the output text file used to write all data
       
   295          produced by display and printf statements; NULL means the data
       
   296          should be sent to stdout via the routine xprintf */
       
   297       char *out_file;
       
   298       /* name of the output text file */
       
   299 #if 0 /* 08/XI-2009 */
       
   300       char *out_buf; /* char out_buf[OUTBUF_SIZE] */
       
   301       /* buffer to accumulate output data */
       
   302       int out_cnt;
       
   303       /* count of data bytes stored in the output buffer */
       
   304 #endif
       
   305       XFILE *prt_fp;
       
   306       /* stream assigned to the print text file; may be NULL */
       
   307       char *prt_file;
       
   308       /* name of the output print file */
       
   309       /*--------------------------------------------------------------*/
       
   310       /* solver interface segment */
       
   311       jmp_buf jump;
       
   312       /* jump address for non-local go to in case of error */
       
   313       int phase;
       
   314       /* phase of processing:
       
   315          0 - database is being or has been initialized
       
   316          1 - model section is being or has been read
       
   317          2 - data section is being or has been read
       
   318          3 - model is being or has been generated/postsolved
       
   319          4 - model processing error has occurred */
       
   320       char *mod_file;
       
   321       /* name of the input text file, which contains model section */
       
   322       char *mpl_buf; /* char mpl_buf[255+1]; */
       
   323       /* working buffer used by some interface routines */
       
   324 };
       
   325 
       
   326 /**********************************************************************/
       
   327 /* * *                  PROCESSING MODEL SECTION                  * * */
       
   328 /**********************************************************************/
       
   329 
       
   330 #define alloc(type) ((type *)dmp_get_atomv(mpl->pool, sizeof(type)))
       
   331 /* allocate atom of given type */
       
   332 
       
   333 #define enter_context _glp_mpl_enter_context
       
   334 void enter_context(MPL *mpl);
       
   335 /* enter current token into context queue */
       
   336 
       
   337 #define print_context _glp_mpl_print_context
       
   338 void print_context(MPL *mpl);
       
   339 /* print current content of context queue */
       
   340 
       
   341 #define get_char _glp_mpl_get_char
       
   342 void get_char(MPL *mpl);
       
   343 /* scan next character from input text file */
       
   344 
       
   345 #define append_char _glp_mpl_append_char
       
   346 void append_char(MPL *mpl);
       
   347 /* append character to current token */
       
   348 
       
   349 #define get_token _glp_mpl_get_token
       
   350 void get_token(MPL *mpl);
       
   351 /* scan next token from input text file */
       
   352 
       
   353 #define unget_token _glp_mpl_unget_token
       
   354 void unget_token(MPL *mpl);
       
   355 /* return current token back to input stream */
       
   356 
       
   357 #define is_keyword _glp_mpl_is_keyword
       
   358 int is_keyword(MPL *mpl, char *keyword);
       
   359 /* check if current token is given non-reserved keyword */
       
   360 
       
   361 #define is_reserved _glp_mpl_is_reserved
       
   362 int is_reserved(MPL *mpl);
       
   363 /* check if current token is reserved keyword */
       
   364 
       
   365 #define make_code _glp_mpl_make_code
       
   366 CODE *make_code(MPL *mpl, int op, OPERANDS *arg, int type, int dim);
       
   367 /* generate pseudo-code (basic routine) */
       
   368 
       
   369 #define make_unary _glp_mpl_make_unary
       
   370 CODE *make_unary(MPL *mpl, int op, CODE *x, int type, int dim);
       
   371 /* generate pseudo-code for unary operation */
       
   372 
       
   373 #define make_binary _glp_mpl_make_binary
       
   374 CODE *make_binary(MPL *mpl, int op, CODE *x, CODE *y, int type,
       
   375       int dim);
       
   376 /* generate pseudo-code for binary operation */
       
   377 
       
   378 #define make_ternary _glp_mpl_make_ternary
       
   379 CODE *make_ternary(MPL *mpl, int op, CODE *x, CODE *y, CODE *z,
       
   380       int type, int dim);
       
   381 /* generate pseudo-code for ternary operation */
       
   382 
       
   383 #define numeric_literal _glp_mpl_numeric_literal
       
   384 CODE *numeric_literal(MPL *mpl);
       
   385 /* parse reference to numeric literal */
       
   386 
       
   387 #define string_literal _glp_mpl_string_literal
       
   388 CODE *string_literal(MPL *mpl);
       
   389 /* parse reference to string literal */
       
   390 
       
   391 #define create_arg_list _glp_mpl_create_arg_list
       
   392 ARG_LIST *create_arg_list(MPL *mpl);
       
   393 /* create empty operands list */
       
   394 
       
   395 #define expand_arg_list _glp_mpl_expand_arg_list
       
   396 ARG_LIST *expand_arg_list(MPL *mpl, ARG_LIST *list, CODE *x);
       
   397 /* append operand to operands list */
       
   398 
       
   399 #define arg_list_len _glp_mpl_arg_list_len
       
   400 int arg_list_len(MPL *mpl, ARG_LIST *list);
       
   401 /* determine length of operands list */
       
   402 
       
   403 #define subscript_list _glp_mpl_subscript_list
       
   404 ARG_LIST *subscript_list(MPL *mpl);
       
   405 /* parse subscript list */
       
   406 
       
   407 #define object_reference _glp_mpl_object_reference
       
   408 CODE *object_reference(MPL *mpl);
       
   409 /* parse reference to named object */
       
   410 
       
   411 #define numeric_argument _glp_mpl_numeric_argument
       
   412 CODE *numeric_argument(MPL *mpl, char *func);
       
   413 /* parse argument passed to built-in function */
       
   414 
       
   415 #define symbolic_argument _glp_mpl_symbolic_argument
       
   416 CODE *symbolic_argument(MPL *mpl, char *func);
       
   417 
       
   418 #define elemset_argument _glp_mpl_elemset_argument
       
   419 CODE *elemset_argument(MPL *mpl, char *func);
       
   420 
       
   421 #define function_reference _glp_mpl_function_reference
       
   422 CODE *function_reference(MPL *mpl);
       
   423 /* parse reference to built-in function */
       
   424 
       
   425 #define create_domain _glp_mpl_create_domain
       
   426 DOMAIN *create_domain(MPL *mpl);
       
   427 /* create empty domain */
       
   428 
       
   429 #define create_block _glp_mpl_create_block
       
   430 DOMAIN_BLOCK *create_block(MPL *mpl);
       
   431 /* create empty domain block */
       
   432 
       
   433 #define append_block _glp_mpl_append_block
       
   434 void append_block(MPL *mpl, DOMAIN *domain, DOMAIN_BLOCK *block);
       
   435 /* append domain block to specified domain */
       
   436 
       
   437 #define append_slot _glp_mpl_append_slot
       
   438 DOMAIN_SLOT *append_slot(MPL *mpl, DOMAIN_BLOCK *block, char *name,
       
   439       CODE *code);
       
   440 /* create and append new slot to domain block */
       
   441 
       
   442 #define expression_list _glp_mpl_expression_list
       
   443 CODE *expression_list(MPL *mpl);
       
   444 /* parse expression list */
       
   445 
       
   446 #define literal_set _glp_mpl_literal_set
       
   447 CODE *literal_set(MPL *mpl, CODE *code);
       
   448 /* parse literal set */
       
   449 
       
   450 #define indexing_expression _glp_mpl_indexing_expression
       
   451 DOMAIN *indexing_expression(MPL *mpl);
       
   452 /* parse indexing expression */
       
   453 
       
   454 #define close_scope _glp_mpl_close_scope
       
   455 void close_scope(MPL *mpl, DOMAIN *domain);
       
   456 /* close scope of indexing expression */
       
   457 
       
   458 #define iterated_expression _glp_mpl_iterated_expression
       
   459 CODE *iterated_expression(MPL *mpl);
       
   460 /* parse iterated expression */
       
   461 
       
   462 #define domain_arity _glp_mpl_domain_arity
       
   463 int domain_arity(MPL *mpl, DOMAIN *domain);
       
   464 /* determine arity of domain */
       
   465 
       
   466 #define set_expression _glp_mpl_set_expression
       
   467 CODE *set_expression(MPL *mpl);
       
   468 /* parse set expression */
       
   469 
       
   470 #define branched_expression _glp_mpl_branched_expression
       
   471 CODE *branched_expression(MPL *mpl);
       
   472 /* parse conditional expression */
       
   473 
       
   474 #define primary_expression _glp_mpl_primary_expression
       
   475 CODE *primary_expression(MPL *mpl);
       
   476 /* parse primary expression */
       
   477 
       
   478 #define error_preceding _glp_mpl_error_preceding
       
   479 void error_preceding(MPL *mpl, char *opstr);
       
   480 /* raise error if preceding operand has wrong type */
       
   481 
       
   482 #define error_following _glp_mpl_error_following
       
   483 void error_following(MPL *mpl, char *opstr);
       
   484 /* raise error if following operand has wrong type */
       
   485 
       
   486 #define error_dimension _glp_mpl_error_dimension
       
   487 void error_dimension(MPL *mpl, char *opstr, int dim1, int dim2);
       
   488 /* raise error if operands have different dimension */
       
   489 
       
   490 #define expression_0 _glp_mpl_expression_0
       
   491 CODE *expression_0(MPL *mpl);
       
   492 /* parse expression of level 0 */
       
   493 
       
   494 #define expression_1 _glp_mpl_expression_1
       
   495 CODE *expression_1(MPL *mpl);
       
   496 /* parse expression of level 1 */
       
   497 
       
   498 #define expression_2 _glp_mpl_expression_2
       
   499 CODE *expression_2(MPL *mpl);
       
   500 /* parse expression of level 2 */
       
   501 
       
   502 #define expression_3 _glp_mpl_expression_3
       
   503 CODE *expression_3(MPL *mpl);
       
   504 /* parse expression of level 3 */
       
   505 
       
   506 #define expression_4 _glp_mpl_expression_4
       
   507 CODE *expression_4(MPL *mpl);
       
   508 /* parse expression of level 4 */
       
   509 
       
   510 #define expression_5 _glp_mpl_expression_5
       
   511 CODE *expression_5(MPL *mpl);
       
   512 /* parse expression of level 5 */
       
   513 
       
   514 #define expression_6 _glp_mpl_expression_6
       
   515 CODE *expression_6(MPL *mpl);
       
   516 /* parse expression of level 6 */
       
   517 
       
   518 #define expression_7 _glp_mpl_expression_7
       
   519 CODE *expression_7(MPL *mpl);
       
   520 /* parse expression of level 7 */
       
   521 
       
   522 #define expression_8 _glp_mpl_expression_8
       
   523 CODE *expression_8(MPL *mpl);
       
   524 /* parse expression of level 8 */
       
   525 
       
   526 #define expression_9 _glp_mpl_expression_9
       
   527 CODE *expression_9(MPL *mpl);
       
   528 /* parse expression of level 9 */
       
   529 
       
   530 #define expression_10 _glp_mpl_expression_10
       
   531 CODE *expression_10(MPL *mpl);
       
   532 /* parse expression of level 10 */
       
   533 
       
   534 #define expression_11 _glp_mpl_expression_11
       
   535 CODE *expression_11(MPL *mpl);
       
   536 /* parse expression of level 11 */
       
   537 
       
   538 #define expression_12 _glp_mpl_expression_12
       
   539 CODE *expression_12(MPL *mpl);
       
   540 /* parse expression of level 12 */
       
   541 
       
   542 #define expression_13 _glp_mpl_expression_13
       
   543 CODE *expression_13(MPL *mpl);
       
   544 /* parse expression of level 13 */
       
   545 
       
   546 #define set_statement _glp_mpl_set_statement
       
   547 SET *set_statement(MPL *mpl);
       
   548 /* parse set statement */
       
   549 
       
   550 #define parameter_statement _glp_mpl_parameter_statement
       
   551 PARAMETER *parameter_statement(MPL *mpl);
       
   552 /* parse parameter statement */
       
   553 
       
   554 #define variable_statement _glp_mpl_variable_statement
       
   555 VARIABLE *variable_statement(MPL *mpl);
       
   556 /* parse variable statement */
       
   557 
       
   558 #define constraint_statement _glp_mpl_constraint_statement
       
   559 CONSTRAINT *constraint_statement(MPL *mpl);
       
   560 /* parse constraint statement */
       
   561 
       
   562 #define objective_statement _glp_mpl_objective_statement
       
   563 CONSTRAINT *objective_statement(MPL *mpl);
       
   564 /* parse objective statement */
       
   565 
       
   566 #define table_statement _glp_mpl_table_statement
       
   567 TABLE *table_statement(MPL *mpl);
       
   568 /* parse table statement */
       
   569 
       
   570 #define solve_statement _glp_mpl_solve_statement
       
   571 void *solve_statement(MPL *mpl);
       
   572 /* parse solve statement */
       
   573 
       
   574 #define check_statement _glp_mpl_check_statement
       
   575 CHECK *check_statement(MPL *mpl);
       
   576 /* parse check statement */
       
   577 
       
   578 #define display_statement _glp_mpl_display_statement
       
   579 DISPLAY *display_statement(MPL *mpl);
       
   580 /* parse display statement */
       
   581 
       
   582 #define printf_statement _glp_mpl_printf_statement
       
   583 PRINTF *printf_statement(MPL *mpl);
       
   584 /* parse printf statement */
       
   585 
       
   586 #define for_statement _glp_mpl_for_statement
       
   587 FOR *for_statement(MPL *mpl);
       
   588 /* parse for statement */
       
   589 
       
   590 #define end_statement _glp_mpl_end_statement
       
   591 void end_statement(MPL *mpl);
       
   592 /* parse end statement */
       
   593 
       
   594 #define simple_statement _glp_mpl_simple_statement
       
   595 STATEMENT *simple_statement(MPL *mpl, int spec);
       
   596 /* parse simple statement */
       
   597 
       
   598 #define model_section _glp_mpl_model_section
       
   599 void model_section(MPL *mpl);
       
   600 /* parse model section */
       
   601 
       
   602 /**********************************************************************/
       
   603 /* * *                  PROCESSING DATA SECTION                   * * */
       
   604 /**********************************************************************/
       
   605 
       
   606 #if 2 + 2 == 5
       
   607 struct SLICE /* see TUPLE */
       
   608 {     /* component of slice; the slice itself is associated with its
       
   609          first component; slices are similar to n-tuples with exception
       
   610          that some slice components (which are indicated by asterisks)
       
   611          don't refer to any symbols */
       
   612       SYMBOL *sym;
       
   613       /* symbol, which this component refers to; can be NULL */
       
   614       SLICE *next;
       
   615       /* the next component of slice */
       
   616 };
       
   617 #endif
       
   618 
       
   619 #define create_slice _glp_mpl_create_slice
       
   620 SLICE *create_slice(MPL *mpl);
       
   621 /* create slice */
       
   622 
       
   623 #define expand_slice _glp_mpl_expand_slice
       
   624 SLICE *expand_slice
       
   625 (     MPL *mpl,
       
   626       SLICE *slice,           /* destroyed */
       
   627       SYMBOL *sym             /* destroyed */
       
   628 );
       
   629 /* append new component to slice */
       
   630 
       
   631 #define slice_dimen _glp_mpl_slice_dimen
       
   632 int slice_dimen
       
   633 (     MPL *mpl,
       
   634       SLICE *slice            /* not changed */
       
   635 );
       
   636 /* determine dimension of slice */
       
   637 
       
   638 #define slice_arity _glp_mpl_slice_arity
       
   639 int slice_arity
       
   640 (     MPL *mpl,
       
   641       SLICE *slice            /* not changed */
       
   642 );
       
   643 /* determine arity of slice */
       
   644 
       
   645 #define fake_slice _glp_mpl_fake_slice
       
   646 SLICE *fake_slice(MPL *mpl, int dim);
       
   647 /* create fake slice of all asterisks */
       
   648 
       
   649 #define delete_slice _glp_mpl_delete_slice
       
   650 void delete_slice
       
   651 (     MPL *mpl,
       
   652       SLICE *slice            /* destroyed */
       
   653 );
       
   654 /* delete slice */
       
   655 
       
   656 #define is_number _glp_mpl_is_number
       
   657 int is_number(MPL *mpl);
       
   658 /* check if current token is number */
       
   659 
       
   660 #define is_symbol _glp_mpl_is_symbol
       
   661 int is_symbol(MPL *mpl);
       
   662 /* check if current token is symbol */
       
   663 
       
   664 #define is_literal _glp_mpl_is_literal
       
   665 int is_literal(MPL *mpl, char *literal);
       
   666 /* check if current token is given symbolic literal */
       
   667 
       
   668 #define read_number _glp_mpl_read_number
       
   669 double read_number(MPL *mpl);
       
   670 /* read number */
       
   671 
       
   672 #define read_symbol _glp_mpl_read_symbol
       
   673 SYMBOL *read_symbol(MPL *mpl);
       
   674 /* read symbol */
       
   675 
       
   676 #define read_slice _glp_mpl_read_slice
       
   677 SLICE *read_slice
       
   678 (     MPL *mpl,
       
   679       char *name,             /* not changed */
       
   680       int dim
       
   681 );
       
   682 /* read slice */
       
   683 
       
   684 #define select_set _glp_mpl_select_set
       
   685 SET *select_set
       
   686 (     MPL *mpl,
       
   687       char *name              /* not changed */
       
   688 );
       
   689 /* select set to saturate it with elemental sets */
       
   690 
       
   691 #define simple_format _glp_mpl_simple_format
       
   692 void simple_format
       
   693 (     MPL *mpl,
       
   694       SET *set,               /* not changed */
       
   695       MEMBER *memb,           /* modified */
       
   696       SLICE *slice            /* not changed */
       
   697 );
       
   698 /* read set data block in simple format */
       
   699 
       
   700 #define matrix_format _glp_mpl_matrix_format
       
   701 void matrix_format
       
   702 (     MPL *mpl,
       
   703       SET *set,               /* not changed */
       
   704       MEMBER *memb,           /* modified */
       
   705       SLICE *slice,           /* not changed */
       
   706       int tr
       
   707 );
       
   708 /* read set data block in matrix format */
       
   709 
       
   710 #define set_data _glp_mpl_set_data
       
   711 void set_data(MPL *mpl);
       
   712 /* read set data */
       
   713 
       
   714 #define select_parameter _glp_mpl_select_parameter
       
   715 PARAMETER *select_parameter
       
   716 (     MPL *mpl,
       
   717       char *name              /* not changed */
       
   718 );
       
   719 /* select parameter to saturate it with data */
       
   720 
       
   721 #define set_default _glp_mpl_set_default
       
   722 void set_default
       
   723 (     MPL *mpl,
       
   724       PARAMETER *par,         /* not changed */
       
   725       SYMBOL *altval          /* destroyed */
       
   726 );
       
   727 /* set default parameter value */
       
   728 
       
   729 #define read_value _glp_mpl_read_value
       
   730 MEMBER *read_value
       
   731 (     MPL *mpl,
       
   732       PARAMETER *par,         /* not changed */
       
   733       TUPLE *tuple            /* destroyed */
       
   734 );
       
   735 /* read value and assign it to parameter member */
       
   736 
       
   737 #define plain_format _glp_mpl_plain_format
       
   738 void plain_format
       
   739 (     MPL *mpl,
       
   740       PARAMETER *par,         /* not changed */
       
   741       SLICE *slice            /* not changed */
       
   742 );
       
   743 /* read parameter data block in plain format */
       
   744 
       
   745 #define tabular_format _glp_mpl_tabular_format
       
   746 void tabular_format
       
   747 (     MPL *mpl,
       
   748       PARAMETER *par,         /* not changed */
       
   749       SLICE *slice,           /* not changed */
       
   750       int tr
       
   751 );
       
   752 /* read parameter data block in tabular format */
       
   753 
       
   754 #define tabbing_format _glp_mpl_tabbing_format
       
   755 void tabbing_format
       
   756 (     MPL *mpl,
       
   757       SYMBOL *altval          /* not changed */
       
   758 );
       
   759 /* read parameter data block in tabbing format */
       
   760 
       
   761 #define parameter_data _glp_mpl_parameter_data
       
   762 void parameter_data(MPL *mpl);
       
   763 /* read parameter data */
       
   764 
       
   765 #define data_section _glp_mpl_data_section
       
   766 void data_section(MPL *mpl);
       
   767 /* read data section */
       
   768 
       
   769 /**********************************************************************/
       
   770 /* * *                   FLOATING-POINT NUMBERS                   * * */
       
   771 /**********************************************************************/
       
   772 
       
   773 #define fp_add _glp_mpl_fp_add
       
   774 double fp_add(MPL *mpl, double x, double y);
       
   775 /* floating-point addition */
       
   776 
       
   777 #define fp_sub _glp_mpl_fp_sub
       
   778 double fp_sub(MPL *mpl, double x, double y);
       
   779 /* floating-point subtraction */
       
   780 
       
   781 #define fp_less _glp_mpl_fp_less
       
   782 double fp_less(MPL *mpl, double x, double y);
       
   783 /* floating-point non-negative subtraction */
       
   784 
       
   785 #define fp_mul _glp_mpl_fp_mul
       
   786 double fp_mul(MPL *mpl, double x, double y);
       
   787 /* floating-point multiplication */
       
   788 
       
   789 #define fp_div _glp_mpl_fp_div
       
   790 double fp_div(MPL *mpl, double x, double y);
       
   791 /* floating-point division */
       
   792 
       
   793 #define fp_idiv _glp_mpl_fp_idiv
       
   794 double fp_idiv(MPL *mpl, double x, double y);
       
   795 /* floating-point quotient of exact division */
       
   796 
       
   797 #define fp_mod _glp_mpl_fp_mod
       
   798 double fp_mod(MPL *mpl, double x, double y);
       
   799 /* floating-point remainder of exact division */
       
   800 
       
   801 #define fp_power _glp_mpl_fp_power
       
   802 double fp_power(MPL *mpl, double x, double y);
       
   803 /* floating-point exponentiation (raise to power) */
       
   804 
       
   805 #define fp_exp _glp_mpl_fp_exp
       
   806 double fp_exp(MPL *mpl, double x);
       
   807 /* floating-point base-e exponential */
       
   808 
       
   809 #define fp_log _glp_mpl_fp_log
       
   810 double fp_log(MPL *mpl, double x);
       
   811 /* floating-point natural logarithm */
       
   812 
       
   813 #define fp_log10 _glp_mpl_fp_log10
       
   814 double fp_log10(MPL *mpl, double x);
       
   815 /* floating-point common (decimal) logarithm */
       
   816 
       
   817 #define fp_sqrt _glp_mpl_fp_sqrt
       
   818 double fp_sqrt(MPL *mpl, double x);
       
   819 /* floating-point square root */
       
   820 
       
   821 #define fp_sin _glp_mpl_fp_sin
       
   822 double fp_sin(MPL *mpl, double x);
       
   823 /* floating-point trigonometric sine */
       
   824 
       
   825 #define fp_cos _glp_mpl_fp_cos
       
   826 double fp_cos(MPL *mpl, double x);
       
   827 /* floating-point trigonometric cosine */
       
   828 
       
   829 #define fp_atan _glp_mpl_fp_atan
       
   830 double fp_atan(MPL *mpl, double x);
       
   831 /* floating-point trigonometric arctangent */
       
   832 
       
   833 #define fp_atan2 _glp_mpl_fp_atan2
       
   834 double fp_atan2(MPL *mpl, double y, double x);
       
   835 /* floating-point trigonometric arctangent */
       
   836 
       
   837 #define fp_round _glp_mpl_fp_round
       
   838 double fp_round(MPL *mpl, double x, double n);
       
   839 /* round floating-point value to n fractional digits */
       
   840 
       
   841 #define fp_trunc _glp_mpl_fp_trunc
       
   842 double fp_trunc(MPL *mpl, double x, double n);
       
   843 /* truncate floating-point value to n fractional digits */
       
   844 
       
   845 /**********************************************************************/
       
   846 /* * *              PSEUDO-RANDOM NUMBER GENERATORS               * * */
       
   847 /**********************************************************************/
       
   848 
       
   849 #define fp_irand224 _glp_mpl_fp_irand224
       
   850 double fp_irand224(MPL *mpl);
       
   851 /* pseudo-random integer in the range [0, 2^24) */
       
   852 
       
   853 #define fp_uniform01 _glp_mpl_fp_uniform01
       
   854 double fp_uniform01(MPL *mpl);
       
   855 /* pseudo-random number in the range [0, 1) */
       
   856 
       
   857 #define fp_uniform _glp_mpl_uniform
       
   858 double fp_uniform(MPL *mpl, double a, double b);
       
   859 /* pseudo-random number in the range [a, b) */
       
   860 
       
   861 #define fp_normal01 _glp_mpl_fp_normal01
       
   862 double fp_normal01(MPL *mpl);
       
   863 /* Gaussian random variate with mu = 0 and sigma = 1 */
       
   864 
       
   865 #define fp_normal _glp_mpl_fp_normal
       
   866 double fp_normal(MPL *mpl, double mu, double sigma);
       
   867 /* Gaussian random variate with specified mu and sigma */
       
   868 
       
   869 /**********************************************************************/
       
   870 /* * *                         DATE/TIME                          * * */
       
   871 /**********************************************************************/
       
   872 
       
   873 #define fn_gmtime _glp_mpl_fn_gmtime
       
   874 double fn_gmtime(MPL *mpl);
       
   875 /* obtain the current calendar time (UTC) */
       
   876 
       
   877 #define fn_str2time _glp_mpl_fn_str2time
       
   878 double fn_str2time(MPL *mpl, const char *str, const char *fmt);
       
   879 /* convert character string to the calendar time */
       
   880 
       
   881 #define fn_time2str _glp_mpl_fn_time2str
       
   882 void fn_time2str(MPL *mpl, char *str, double t, const char *fmt);
       
   883 /* convert the calendar time to character string */
       
   884 
       
   885 /**********************************************************************/
       
   886 /* * *                     CHARACTER STRINGS                      * * */
       
   887 /**********************************************************************/
       
   888 
       
   889 #define create_string _glp_mpl_create_string
       
   890 STRING *create_string
       
   891 (     MPL *mpl,
       
   892       char buf[MAX_LENGTH+1]  /* not changed */
       
   893 );
       
   894 /* create character string */
       
   895 
       
   896 #define copy_string _glp_mpl_copy_string
       
   897 STRING *copy_string
       
   898 (     MPL *mpl,
       
   899       STRING *str             /* not changed */
       
   900 );
       
   901 /* make copy of character string */
       
   902 
       
   903 #define compare_strings _glp_mpl_compare_strings
       
   904 int compare_strings
       
   905 (     MPL *mpl,
       
   906       STRING *str1,           /* not changed */
       
   907       STRING *str2            /* not changed */
       
   908 );
       
   909 /* compare one character string with another */
       
   910 
       
   911 #define fetch_string _glp_mpl_fetch_string
       
   912 char *fetch_string
       
   913 (     MPL *mpl,
       
   914       STRING *str,            /* not changed */
       
   915       char buf[MAX_LENGTH+1]  /* modified */
       
   916 );
       
   917 /* extract content of character string */
       
   918 
       
   919 #define delete_string _glp_mpl_delete_string
       
   920 void delete_string
       
   921 (     MPL *mpl,
       
   922       STRING *str             /* destroyed */
       
   923 );
       
   924 /* delete character string */
       
   925 
       
   926 /**********************************************************************/
       
   927 /* * *                          SYMBOLS                           * * */
       
   928 /**********************************************************************/
       
   929 
       
   930 struct SYMBOL
       
   931 {     /* symbol (numeric or abstract quantity) */
       
   932       double num;
       
   933       /* numeric value of symbol (used only if str == NULL) */
       
   934       STRING *str;
       
   935       /* abstract value of symbol (used only if str != NULL) */
       
   936 };
       
   937 
       
   938 #define create_symbol_num _glp_mpl_create_symbol_num
       
   939 SYMBOL *create_symbol_num(MPL *mpl, double num);
       
   940 /* create symbol of numeric type */
       
   941 
       
   942 #define create_symbol_str _glp_mpl_create_symbol_str
       
   943 SYMBOL *create_symbol_str
       
   944 (     MPL *mpl,
       
   945       STRING *str             /* destroyed */
       
   946 );
       
   947 /* create symbol of abstract type */
       
   948 
       
   949 #define copy_symbol _glp_mpl_copy_symbol
       
   950 SYMBOL *copy_symbol
       
   951 (     MPL *mpl,
       
   952       SYMBOL *sym             /* not changed */
       
   953 );
       
   954 /* make copy of symbol */
       
   955 
       
   956 #define compare_symbols _glp_mpl_compare_symbols
       
   957 int compare_symbols
       
   958 (     MPL *mpl,
       
   959       SYMBOL *sym1,           /* not changed */
       
   960       SYMBOL *sym2            /* not changed */
       
   961 );
       
   962 /* compare one symbol with another */
       
   963 
       
   964 #define delete_symbol _glp_mpl_delete_symbol
       
   965 void delete_symbol
       
   966 (     MPL *mpl,
       
   967       SYMBOL *sym             /* destroyed */
       
   968 );
       
   969 /* delete symbol */
       
   970 
       
   971 #define format_symbol _glp_mpl_format_symbol
       
   972 char *format_symbol
       
   973 (     MPL *mpl,
       
   974       SYMBOL *sym             /* not changed */
       
   975 );
       
   976 /* format symbol for displaying or printing */
       
   977 
       
   978 #define concat_symbols _glp_mpl_concat_symbols
       
   979 SYMBOL *concat_symbols
       
   980 (     MPL *mpl,
       
   981       SYMBOL *sym1,           /* destroyed */
       
   982       SYMBOL *sym2            /* destroyed */
       
   983 );
       
   984 /* concatenate one symbol with another */
       
   985 
       
   986 /**********************************************************************/
       
   987 /* * *                          N-TUPLES                          * * */
       
   988 /**********************************************************************/
       
   989 
       
   990 struct TUPLE
       
   991 {     /* component of n-tuple; the n-tuple itself is associated with
       
   992          its first component; (note that 0-tuple has no components) */
       
   993       SYMBOL *sym;
       
   994       /* symbol, which the component refers to; cannot be NULL */
       
   995       TUPLE *next;
       
   996       /* the next component of n-tuple */
       
   997 };
       
   998 
       
   999 #define create_tuple _glp_mpl_create_tuple
       
  1000 TUPLE *create_tuple(MPL *mpl);
       
  1001 /* create n-tuple */
       
  1002 
       
  1003 #define expand_tuple _glp_mpl_expand_tuple
       
  1004 TUPLE *expand_tuple
       
  1005 (     MPL *mpl,
       
  1006       TUPLE *tuple,           /* destroyed */
       
  1007       SYMBOL *sym             /* destroyed */
       
  1008 );
       
  1009 /* append symbol to n-tuple */
       
  1010 
       
  1011 #define tuple_dimen _glp_mpl_tuple_dimen
       
  1012 int tuple_dimen
       
  1013 (     MPL *mpl,
       
  1014       TUPLE *tuple            /* not changed */
       
  1015 );
       
  1016 /* determine dimension of n-tuple */
       
  1017 
       
  1018 #define copy_tuple _glp_mpl_copy_tuple
       
  1019 TUPLE *copy_tuple
       
  1020 (     MPL *mpl,
       
  1021       TUPLE *tuple            /* not changed */
       
  1022 );
       
  1023 /* make copy of n-tuple */
       
  1024 
       
  1025 #define compare_tuples _glp_mpl_compare_tuples
       
  1026 int compare_tuples
       
  1027 (     MPL *mpl,
       
  1028       TUPLE *tuple1,          /* not changed */
       
  1029       TUPLE *tuple2           /* not changed */
       
  1030 );
       
  1031 /* compare one n-tuple with another */
       
  1032 
       
  1033 #define build_subtuple _glp_mpl_build_subtuple
       
  1034 TUPLE *build_subtuple
       
  1035 (     MPL *mpl,
       
  1036       TUPLE *tuple,           /* not changed */
       
  1037       int dim
       
  1038 );
       
  1039 /* build subtuple of given n-tuple */
       
  1040 
       
  1041 #define delete_tuple _glp_mpl_delete_tuple
       
  1042 void delete_tuple
       
  1043 (     MPL *mpl,
       
  1044       TUPLE *tuple            /* destroyed */
       
  1045 );
       
  1046 /* delete n-tuple */
       
  1047 
       
  1048 #define format_tuple _glp_mpl_format_tuple
       
  1049 char *format_tuple
       
  1050 (     MPL *mpl,
       
  1051       int c,
       
  1052       TUPLE *tuple            /* not changed */
       
  1053 );
       
  1054 /* format n-tuple for displaying or printing */
       
  1055 
       
  1056 /**********************************************************************/
       
  1057 /* * *                       ELEMENTAL SETS                       * * */
       
  1058 /**********************************************************************/
       
  1059 
       
  1060 #if 2 + 2 == 5
       
  1061 struct ELEMSET /* see ARRAY */
       
  1062 {     /* elemental set of n-tuples; formally it is a "value" assigned
       
  1063          to members of model sets (like numbers and symbols, which are
       
  1064          values assigned to members of model parameters); note that a
       
  1065          simple model set is not an elemental set, it is 0-dimensional
       
  1066          array, the only member of which (if it exists) is assigned an
       
  1067          elemental set */
       
  1068 #endif
       
  1069 
       
  1070 #define create_elemset _glp_mpl_create_elemset
       
  1071 ELEMSET *create_elemset(MPL *mpl, int dim);
       
  1072 /* create elemental set */
       
  1073 
       
  1074 #define find_tuple _glp_mpl_find_tuple
       
  1075 MEMBER *find_tuple
       
  1076 (     MPL *mpl,
       
  1077       ELEMSET *set,           /* not changed */
       
  1078       TUPLE *tuple            /* not changed */
       
  1079 );
       
  1080 /* check if elemental set contains given n-tuple */
       
  1081 
       
  1082 #define add_tuple _glp_mpl_add_tuple
       
  1083 MEMBER *add_tuple
       
  1084 (     MPL *mpl,
       
  1085       ELEMSET *set,           /* modified */
       
  1086       TUPLE *tuple            /* destroyed */
       
  1087 );
       
  1088 /* add new n-tuple to elemental set */
       
  1089 
       
  1090 #define check_then_add _glp_mpl_check_then_add
       
  1091 MEMBER *check_then_add
       
  1092 (     MPL *mpl,
       
  1093       ELEMSET *set,           /* modified */
       
  1094       TUPLE *tuple            /* destroyed */
       
  1095 );
       
  1096 /* check and add new n-tuple to elemental set */
       
  1097 
       
  1098 #define copy_elemset _glp_mpl_copy_elemset
       
  1099 ELEMSET *copy_elemset
       
  1100 (     MPL *mpl,
       
  1101       ELEMSET *set            /* not changed */
       
  1102 );
       
  1103 /* make copy of elemental set */
       
  1104 
       
  1105 #define delete_elemset _glp_mpl_delete_elemset
       
  1106 void delete_elemset
       
  1107 (     MPL *mpl,
       
  1108       ELEMSET *set            /* destroyed */
       
  1109 );
       
  1110 /* delete elemental set */
       
  1111 
       
  1112 #define arelset_size _glp_mpl_arelset_size
       
  1113 int arelset_size(MPL *mpl, double t0, double tf, double dt);
       
  1114 /* compute size of "arithmetic" elemental set */
       
  1115 
       
  1116 #define arelset_member _glp_mpl_arelset_member
       
  1117 double arelset_member(MPL *mpl, double t0, double tf, double dt, int j);
       
  1118 /* compute member of "arithmetic" elemental set */
       
  1119 
       
  1120 #define create_arelset _glp_mpl_create_arelset
       
  1121 ELEMSET *create_arelset(MPL *mpl, double t0, double tf, double dt);
       
  1122 /* create "arithmetic" elemental set */
       
  1123 
       
  1124 #define set_union _glp_mpl_set_union
       
  1125 ELEMSET *set_union
       
  1126 (     MPL *mpl,
       
  1127       ELEMSET *X,             /* destroyed */
       
  1128       ELEMSET *Y              /* destroyed */
       
  1129 );
       
  1130 /* union of two elemental sets */
       
  1131 
       
  1132 #define set_diff _glp_mpl_set_diff
       
  1133 ELEMSET *set_diff
       
  1134 (     MPL *mpl,
       
  1135       ELEMSET *X,             /* destroyed */
       
  1136       ELEMSET *Y              /* destroyed */
       
  1137 );
       
  1138 /* difference between two elemental sets */
       
  1139 
       
  1140 #define set_symdiff _glp_mpl_set_symdiff
       
  1141 ELEMSET *set_symdiff
       
  1142 (     MPL *mpl,
       
  1143       ELEMSET *X,             /* destroyed */
       
  1144       ELEMSET *Y              /* destroyed */
       
  1145 );
       
  1146 /* symmetric difference between two elemental sets */
       
  1147 
       
  1148 #define set_inter _glp_mpl_set_inter
       
  1149 ELEMSET *set_inter
       
  1150 (     MPL *mpl,
       
  1151       ELEMSET *X,             /* destroyed */
       
  1152       ELEMSET *Y              /* destroyed */
       
  1153 );
       
  1154 /* intersection of two elemental sets */
       
  1155 
       
  1156 #define set_cross _glp_mpl_set_cross
       
  1157 ELEMSET *set_cross
       
  1158 (     MPL *mpl,
       
  1159       ELEMSET *X,             /* destroyed */
       
  1160       ELEMSET *Y              /* destroyed */
       
  1161 );
       
  1162 /* cross (Cartesian) product of two elemental sets */
       
  1163 
       
  1164 /**********************************************************************/
       
  1165 /* * *                    ELEMENTAL VARIABLES                     * * */
       
  1166 /**********************************************************************/
       
  1167 
       
  1168 struct ELEMVAR
       
  1169 {     /* elemental variable; formally it is a "value" assigned to
       
  1170          members of model variables (like numbers and symbols, which
       
  1171          are values assigned to members of model parameters) */
       
  1172       int j;
       
  1173       /* LP column number assigned to this elemental variable */
       
  1174       VARIABLE *var;
       
  1175       /* model variable, which contains this elemental variable */
       
  1176       MEMBER *memb;
       
  1177       /* array member, which is assigned this elemental variable */
       
  1178       double lbnd;
       
  1179       /* lower bound */
       
  1180       double ubnd;
       
  1181       /* upper bound */
       
  1182       double temp;
       
  1183       /* working quantity used in operations on linear forms; normally
       
  1184          it contains floating-point zero */
       
  1185 #if 1 /* 15/V-2010 */
       
  1186       int stat;
       
  1187       double prim, dual;
       
  1188       /* solution components provided by the solver */
       
  1189 #endif
       
  1190 };
       
  1191 
       
  1192 /**********************************************************************/
       
  1193 /* * *                        LINEAR FORMS                        * * */
       
  1194 /**********************************************************************/
       
  1195 
       
  1196 struct FORMULA
       
  1197 {     /* term of linear form c * x, where c is a coefficient, x is an
       
  1198          elemental variable; the linear form itself is the sum of terms
       
  1199          and is associated with its first term; (note that the linear
       
  1200          form may be empty that means the sum is equal to zero) */
       
  1201       double coef;
       
  1202       /* coefficient at elemental variable or constant term */
       
  1203       ELEMVAR *var;
       
  1204       /* reference to elemental variable; NULL means constant term */
       
  1205       FORMULA *next;
       
  1206       /* the next term of linear form */
       
  1207 };
       
  1208 
       
  1209 #define constant_term _glp_mpl_constant_term
       
  1210 FORMULA *constant_term(MPL *mpl, double coef);
       
  1211 /* create constant term */
       
  1212 
       
  1213 #define single_variable _glp_mpl_single_variable
       
  1214 FORMULA *single_variable
       
  1215 (     MPL *mpl,
       
  1216       ELEMVAR *var            /* referenced */
       
  1217 );
       
  1218 /* create single variable */
       
  1219 
       
  1220 #define copy_formula _glp_mpl_copy_formula
       
  1221 FORMULA *copy_formula
       
  1222 (     MPL *mpl,
       
  1223       FORMULA *form           /* not changed */
       
  1224 );
       
  1225 /* make copy of linear form */
       
  1226 
       
  1227 #define delete_formula _glp_mpl_delete_formula
       
  1228 void delete_formula
       
  1229 (     MPL *mpl,
       
  1230       FORMULA *form           /* destroyed */
       
  1231 );
       
  1232 /* delete linear form */
       
  1233 
       
  1234 #define linear_comb _glp_mpl_linear_comb
       
  1235 FORMULA *linear_comb
       
  1236 (     MPL *mpl,
       
  1237       double a, FORMULA *fx,  /* destroyed */
       
  1238       double b, FORMULA *fy   /* destroyed */
       
  1239 );
       
  1240 /* linear combination of two linear forms */
       
  1241 
       
  1242 #define remove_constant _glp_mpl_remove_constant
       
  1243 FORMULA *remove_constant
       
  1244 (     MPL *mpl,
       
  1245       FORMULA *form,          /* destroyed */
       
  1246       double *coef            /* modified */
       
  1247 );
       
  1248 /* remove constant term from linear form */
       
  1249 
       
  1250 #define reduce_terms _glp_mpl_reduce_terms
       
  1251 FORMULA *reduce_terms
       
  1252 (     MPL *mpl,
       
  1253       FORMULA *form           /* destroyed */
       
  1254 );
       
  1255 /* reduce identical terms in linear form */
       
  1256 
       
  1257 /**********************************************************************/
       
  1258 /* * *                   ELEMENTAL CONSTRAINTS                    * * */
       
  1259 /**********************************************************************/
       
  1260 
       
  1261 struct ELEMCON
       
  1262 {     /* elemental constraint; formally it is a "value" assigned to
       
  1263          members of model constraints (like numbers or symbols, which
       
  1264          are values assigned to members of model parameters) */
       
  1265       int i;
       
  1266       /* LP row number assigned to this elemental constraint */
       
  1267       CONSTRAINT *con;
       
  1268       /* model constraint, which contains this elemental constraint */
       
  1269       MEMBER *memb;
       
  1270       /* array member, which is assigned this elemental constraint */
       
  1271       FORMULA *form;
       
  1272       /* linear form */
       
  1273       double lbnd;
       
  1274       /* lower bound */
       
  1275       double ubnd;
       
  1276       /* upper bound */
       
  1277 #if 1 /* 15/V-2010 */
       
  1278       int stat;
       
  1279       double prim, dual;
       
  1280       /* solution components provided by the solver */
       
  1281 #endif
       
  1282 };
       
  1283 
       
  1284 /**********************************************************************/
       
  1285 /* * *                       GENERIC VALUES                       * * */
       
  1286 /**********************************************************************/
       
  1287 
       
  1288 union VALUE
       
  1289 {     /* generic value, which can be assigned to object member or be a
       
  1290          result of evaluation of expression */
       
  1291       /* indicator that specifies the particular type of generic value
       
  1292          is stored in the corresponding array or pseudo-code descriptor
       
  1293          and can be one of the following:
       
  1294          A_NONE     - no value
       
  1295          A_NUMERIC  - floating-point number
       
  1296          A_SYMBOLIC - symbol
       
  1297          A_LOGICAL  - logical value
       
  1298          A_TUPLE    - n-tuple
       
  1299          A_ELEMSET  - elemental set
       
  1300          A_ELEMVAR  - elemental variable
       
  1301          A_FORMULA  - linear form
       
  1302          A_ELEMCON  - elemental constraint */
       
  1303       void *none;    /* null */
       
  1304       double num;    /* value */
       
  1305       SYMBOL *sym;   /* value */
       
  1306       int bit;       /* value */
       
  1307       TUPLE *tuple;  /* value */
       
  1308       ELEMSET *set;  /* value */
       
  1309       ELEMVAR *var;  /* reference */
       
  1310       FORMULA *form; /* value */
       
  1311       ELEMCON *con;  /* reference */
       
  1312 };
       
  1313 
       
  1314 #define delete_value _glp_mpl_delete_value
       
  1315 void delete_value
       
  1316 (     MPL *mpl,
       
  1317       int type,
       
  1318       VALUE *value            /* content destroyed */
       
  1319 );
       
  1320 /* delete generic value */
       
  1321 
       
  1322 /**********************************************************************/
       
  1323 /* * *                SYMBOLICALLY INDEXED ARRAYS                 * * */
       
  1324 /**********************************************************************/
       
  1325 
       
  1326 struct ARRAY
       
  1327 {     /* multi-dimensional array, a set of members indexed over simple
       
  1328          or compound sets of symbols; arrays are used to represent the
       
  1329          contents of model objects (i.e. sets, parameters, variables,
       
  1330          constraints, and objectives); arrays also are used as "values"
       
  1331          that are assigned to members of set objects, in which case the
       
  1332          array itself represents an elemental set */
       
  1333       int type;
       
  1334       /* type of generic values assigned to the array members:
       
  1335          A_NONE     - none (members have no assigned values)
       
  1336          A_NUMERIC  - floating-point numbers
       
  1337          A_SYMBOLIC - symbols
       
  1338          A_ELEMSET  - elemental sets
       
  1339          A_ELEMVAR  - elemental variables
       
  1340          A_ELEMCON  - elemental constraints */
       
  1341       int dim;
       
  1342       /* dimension of the array that determines number of components in
       
  1343          n-tuples for all members of the array, dim >= 0; dim = 0 means
       
  1344          the array is 0-dimensional */
       
  1345       int size;
       
  1346       /* size of the array, i.e. number of its members */
       
  1347       MEMBER *head;
       
  1348       /* the first array member; NULL means the array is empty */
       
  1349       MEMBER *tail;
       
  1350       /* the last array member; NULL means the array is empty */
       
  1351       AVL *tree;
       
  1352       /* the search tree intended to find array members for logarithmic
       
  1353          time; NULL means the search tree doesn't exist */
       
  1354       ARRAY *prev;
       
  1355       /* the previous array in the translator database */
       
  1356       ARRAY *next;
       
  1357       /* the next array in the translator database */
       
  1358 };
       
  1359 
       
  1360 struct MEMBER
       
  1361 {     /* array member */
       
  1362       TUPLE *tuple;
       
  1363       /* n-tuple, which identifies the member; number of its components
       
  1364          is the same for all members within the array and determined by
       
  1365          the array dimension; duplicate members are not allowed */
       
  1366       MEMBER *next;
       
  1367       /* the next array member */
       
  1368       VALUE value;
       
  1369       /* generic value assigned to the member */
       
  1370 };
       
  1371 
       
  1372 #define create_array _glp_mpl_create_array
       
  1373 ARRAY *create_array(MPL *mpl, int type, int dim);
       
  1374 /* create array */
       
  1375 
       
  1376 #define find_member _glp_mpl_find_member
       
  1377 MEMBER *find_member
       
  1378 (     MPL *mpl,
       
  1379       ARRAY *array,           /* not changed */
       
  1380       TUPLE *tuple            /* not changed */
       
  1381 );
       
  1382 /* find array member with given n-tuple */
       
  1383 
       
  1384 #define add_member _glp_mpl_add_member
       
  1385 MEMBER *add_member
       
  1386 (     MPL *mpl,
       
  1387       ARRAY *array,           /* modified */
       
  1388       TUPLE *tuple            /* destroyed */
       
  1389 );
       
  1390 /* add new member to array */
       
  1391 
       
  1392 #define delete_array _glp_mpl_delete_array
       
  1393 void delete_array
       
  1394 (     MPL *mpl,
       
  1395       ARRAY *array            /* destroyed */
       
  1396 );
       
  1397 /* delete array */
       
  1398 
       
  1399 /**********************************************************************/
       
  1400 /* * *                 DOMAINS AND DUMMY INDICES                  * * */
       
  1401 /**********************************************************************/
       
  1402 
       
  1403 struct DOMAIN
       
  1404 {     /* domain (a simple or compound set); syntactically domain looks
       
  1405          like '{ i in I, (j,k) in S, t in T : <predicate> }'; domains
       
  1406          are used to define sets, over which model objects are indexed,
       
  1407          and also as constituents of iterated operators */
       
  1408       DOMAIN_BLOCK *list;
       
  1409       /* linked list of domain blocks (in the example above such blocks
       
  1410          are 'i in I', '(j,k) in S', and 't in T'); this list cannot be
       
  1411          empty */
       
  1412       CODE *code;
       
  1413       /* pseudo-code for computing the logical predicate, which follows
       
  1414          the colon; NULL means no predicate is specified */
       
  1415 };
       
  1416 
       
  1417 struct DOMAIN_BLOCK
       
  1418 {     /* domain block; syntactically domain blocks look like 'i in I',
       
  1419          '(j,k) in S', and 't in T' in the example above (in the sequel
       
  1420          sets like I, S, and T are called basic sets) */
       
  1421       DOMAIN_SLOT *list;
       
  1422       /* linked list of domain slots (i.e. indexing positions); number
       
  1423          of slots in this list is the same as dimension of n-tuples in
       
  1424          the basic set; this list cannot be empty */
       
  1425       CODE *code;
       
  1426       /* pseudo-code for computing basic set; cannot be NULL */
       
  1427       TUPLE *backup;
       
  1428       /* if this n-tuple is not empty, current values of dummy indices
       
  1429          in the domain block are the same as components of this n-tuple
       
  1430          (note that this n-tuple may have larger dimension than number
       
  1431          of dummy indices in this block, in which case extra components
       
  1432          are ignored); this n-tuple is used to restore former values of
       
  1433          dummy indices, if they were changed due to recursive calls to
       
  1434          the domain block */
       
  1435       DOMAIN_BLOCK *next;
       
  1436       /* the next block in the same domain */
       
  1437 };
       
  1438 
       
  1439 struct DOMAIN_SLOT
       
  1440 {     /* domain slot; it specifies an individual indexing position and
       
  1441          defines the corresponding dummy index */
       
  1442       char *name;
       
  1443       /* symbolic name of the dummy index; null pointer means the dummy
       
  1444          index is not explicitly specified */
       
  1445       CODE *code;
       
  1446       /* pseudo-code for computing symbolic value, at which the dummy
       
  1447          index is bound; NULL means the dummy index is free within the
       
  1448          domain scope */
       
  1449       SYMBOL *value;
       
  1450       /* current value assigned to the dummy index; NULL means no value
       
  1451          is assigned at the moment */
       
  1452       CODE *list;
       
  1453       /* linked list of pseudo-codes with operation O_INDEX referring
       
  1454          to this slot; this linked list is used to invalidate resultant
       
  1455          values of the operation, which depend on this dummy index */
       
  1456       DOMAIN_SLOT *next;
       
  1457       /* the next slot in the same domain block */
       
  1458 };
       
  1459 
       
  1460 #define assign_dummy_index _glp_mpl_assign_dummy_index
       
  1461 void assign_dummy_index
       
  1462 (     MPL *mpl,
       
  1463       DOMAIN_SLOT *slot,      /* modified */
       
  1464       SYMBOL *value           /* not changed */
       
  1465 );
       
  1466 /* assign new value to dummy index */
       
  1467 
       
  1468 #define update_dummy_indices _glp_mpl_update_dummy_indices
       
  1469 void update_dummy_indices
       
  1470 (     MPL *mpl,
       
  1471       DOMAIN_BLOCK *block     /* not changed */
       
  1472 );
       
  1473 /* update current values of dummy indices */
       
  1474 
       
  1475 #define enter_domain_block _glp_mpl_enter_domain_block
       
  1476 int enter_domain_block
       
  1477 (     MPL *mpl,
       
  1478       DOMAIN_BLOCK *block,    /* not changed */
       
  1479       TUPLE *tuple,           /* not changed */
       
  1480       void *info, void (*func)(MPL *mpl, void *info)
       
  1481 );
       
  1482 /* enter domain block */
       
  1483 
       
  1484 #define eval_within_domain _glp_mpl_eval_within_domain
       
  1485 int eval_within_domain
       
  1486 (     MPL *mpl,
       
  1487       DOMAIN *domain,         /* not changed */
       
  1488       TUPLE *tuple,           /* not changed */
       
  1489       void *info, void (*func)(MPL *mpl, void *info)
       
  1490 );
       
  1491 /* perform evaluation within domain scope */
       
  1492 
       
  1493 #define loop_within_domain _glp_mpl_loop_within_domain
       
  1494 void loop_within_domain
       
  1495 (     MPL *mpl,
       
  1496       DOMAIN *domain,         /* not changed */
       
  1497       void *info, int (*func)(MPL *mpl, void *info)
       
  1498 );
       
  1499 /* perform iterations within domain scope */
       
  1500 
       
  1501 #define out_of_domain _glp_mpl_out_of_domain
       
  1502 void out_of_domain
       
  1503 (     MPL *mpl,
       
  1504       char *name,             /* not changed */
       
  1505       TUPLE *tuple            /* not changed */
       
  1506 );
       
  1507 /* raise domain exception */
       
  1508 
       
  1509 #define get_domain_tuple _glp_mpl_get_domain_tuple
       
  1510 TUPLE *get_domain_tuple
       
  1511 (     MPL *mpl,
       
  1512       DOMAIN *domain          /* not changed */
       
  1513 );
       
  1514 /* obtain current n-tuple from domain */
       
  1515 
       
  1516 #define clean_domain _glp_mpl_clean_domain
       
  1517 void clean_domain(MPL *mpl, DOMAIN *domain);
       
  1518 /* clean domain */
       
  1519 
       
  1520 /**********************************************************************/
       
  1521 /* * *                         MODEL SETS                         * * */
       
  1522 /**********************************************************************/
       
  1523 
       
  1524 struct SET
       
  1525 {     /* model set */
       
  1526       char *name;
       
  1527       /* symbolic name; cannot be NULL */
       
  1528       char *alias;
       
  1529       /* alias; NULL means alias is not specified */
       
  1530       int dim; /* aka arity */
       
  1531       /* dimension (number of subscripts); dim = 0 means 0-dimensional
       
  1532          (unsubscripted) set, dim > 0 means set of sets */
       
  1533       DOMAIN *domain;
       
  1534       /* subscript domain; NULL for 0-dimensional set */
       
  1535       int dimen;
       
  1536       /* dimension of n-tuples, which members of this set consist of
       
  1537          (note that the model set itself is an array of elemental sets,
       
  1538          which are its members; so, don't confuse this dimension with
       
  1539          dimension of the model set); always non-zero */
       
  1540       WITHIN *within;
       
  1541       /* list of supersets, which restrict each member of the set to be
       
  1542          in every superset from this list; this list can be empty */
       
  1543       CODE *assign;
       
  1544       /* pseudo-code for computing assigned value; can be NULL */
       
  1545       CODE *option;
       
  1546       /* pseudo-code for computing default value; can be NULL */
       
  1547       GADGET *gadget;
       
  1548       /* plain set used to initialize the array of sets; can be NULL */
       
  1549       int data;
       
  1550       /* data status flag:
       
  1551          0 - no data are provided in the data section
       
  1552          1 - data are provided, but not checked yet
       
  1553          2 - data are provided and have been checked */
       
  1554       ARRAY *array;
       
  1555       /* array of members, which are assigned elemental sets */
       
  1556 };
       
  1557 
       
  1558 struct WITHIN
       
  1559 {     /* restricting superset list entry */
       
  1560       CODE *code;
       
  1561       /* pseudo-code for computing the superset; cannot be NULL */
       
  1562       WITHIN *next;
       
  1563       /* the next entry for the same set or parameter */
       
  1564 };
       
  1565 
       
  1566 struct GADGET
       
  1567 {     /* plain set used to initialize the array of sets with data */
       
  1568       SET *set;
       
  1569       /* pointer to plain set; cannot be NULL */
       
  1570       int ind[20]; /* ind[dim+dimen]; */
       
  1571       /* permutation of integers 1, 2, ..., dim+dimen */
       
  1572 };
       
  1573 
       
  1574 #define check_elem_set _glp_mpl_check_elem_set
       
  1575 void check_elem_set
       
  1576 (     MPL *mpl,
       
  1577       SET *set,               /* not changed */
       
  1578       TUPLE *tuple,           /* not changed */
       
  1579       ELEMSET *refer          /* not changed */
       
  1580 );
       
  1581 /* check elemental set assigned to set member */
       
  1582 
       
  1583 #define take_member_set _glp_mpl_take_member_set
       
  1584 ELEMSET *take_member_set      /* returns reference, not value */
       
  1585 (     MPL *mpl,
       
  1586       SET *set,               /* not changed */
       
  1587       TUPLE *tuple            /* not changed */
       
  1588 );
       
  1589 /* obtain elemental set assigned to set member */
       
  1590 
       
  1591 #define eval_member_set _glp_mpl_eval_member_set
       
  1592 ELEMSET *eval_member_set      /* returns reference, not value */
       
  1593 (     MPL *mpl,
       
  1594       SET *set,               /* not changed */
       
  1595       TUPLE *tuple            /* not changed */
       
  1596 );
       
  1597 /* evaluate elemental set assigned to set member */
       
  1598 
       
  1599 #define eval_whole_set _glp_mpl_eval_whole_set
       
  1600 void eval_whole_set(MPL *mpl, SET *set);
       
  1601 /* evaluate model set over entire domain */
       
  1602 
       
  1603 #define clean_set _glp_mpl_clean_set
       
  1604 void clean_set(MPL *mpl, SET *set);
       
  1605 /* clean model set */
       
  1606 
       
  1607 /**********************************************************************/
       
  1608 /* * *                      MODEL PARAMETERS                      * * */
       
  1609 /**********************************************************************/
       
  1610 
       
  1611 struct PARAMETER
       
  1612 {     /* model parameter */
       
  1613       char *name;
       
  1614       /* symbolic name; cannot be NULL */
       
  1615       char *alias;
       
  1616       /* alias; NULL means alias is not specified */
       
  1617       int dim; /* aka arity */
       
  1618       /* dimension (number of subscripts); dim = 0 means 0-dimensional
       
  1619          (unsubscripted) parameter */
       
  1620       DOMAIN *domain;
       
  1621       /* subscript domain; NULL for 0-dimensional parameter */
       
  1622       int type;
       
  1623       /* parameter type:
       
  1624          A_NUMERIC  - numeric
       
  1625          A_INTEGER  - integer
       
  1626          A_BINARY   - binary
       
  1627          A_SYMBOLIC - symbolic */
       
  1628       CONDITION *cond;
       
  1629       /* list of conditions, which restrict each parameter member to
       
  1630          satisfy to every condition from this list; this list is used
       
  1631          only for numeric parameters and can be empty */
       
  1632       WITHIN *in;
       
  1633       /* list of supersets, which restrict each parameter member to be
       
  1634          in every superset from this list; this list is used only for
       
  1635          symbolic parameters and can be empty */
       
  1636       CODE *assign;
       
  1637       /* pseudo-code for computing assigned value; can be NULL */
       
  1638       CODE *option;
       
  1639       /* pseudo-code for computing default value; can be NULL */
       
  1640       int data;
       
  1641       /* data status flag:
       
  1642          0 - no data are provided in the data section
       
  1643          1 - data are provided, but not checked yet
       
  1644          2 - data are provided and have been checked */
       
  1645       SYMBOL *defval;
       
  1646       /* default value provided in the data section; can be NULL */
       
  1647       ARRAY *array;
       
  1648       /* array of members, which are assigned numbers or symbols */
       
  1649 };
       
  1650 
       
  1651 struct CONDITION
       
  1652 {     /* restricting condition list entry */
       
  1653       int rho;
       
  1654       /* flag that specifies the form of the condition:
       
  1655          O_LT - less than
       
  1656          O_LE - less than or equal to
       
  1657          O_EQ - equal to
       
  1658          O_GE - greater than or equal to
       
  1659          O_GT - greater than
       
  1660          O_NE - not equal to */
       
  1661       CODE *code;
       
  1662       /* pseudo-code for computing the reference value */
       
  1663       CONDITION *next;
       
  1664       /* the next entry for the same parameter */
       
  1665 };
       
  1666 
       
  1667 #define check_value_num _glp_mpl_check_value_num
       
  1668 void check_value_num
       
  1669 (     MPL *mpl,
       
  1670       PARAMETER *par,         /* not changed */
       
  1671       TUPLE *tuple,           /* not changed */
       
  1672       double value
       
  1673 );
       
  1674 /* check numeric value assigned to parameter member */
       
  1675 
       
  1676 #define take_member_num _glp_mpl_take_member_num
       
  1677 double take_member_num
       
  1678 (     MPL *mpl,
       
  1679       PARAMETER *par,         /* not changed */
       
  1680       TUPLE *tuple            /* not changed */
       
  1681 );
       
  1682 /* obtain numeric value assigned to parameter member */
       
  1683 
       
  1684 #define eval_member_num _glp_mpl_eval_member_num
       
  1685 double eval_member_num
       
  1686 (     MPL *mpl,
       
  1687       PARAMETER *par,         /* not changed */
       
  1688       TUPLE *tuple            /* not changed */
       
  1689 );
       
  1690 /* evaluate numeric value assigned to parameter member */
       
  1691 
       
  1692 #define check_value_sym _glp_mpl_check_value_sym
       
  1693 void check_value_sym
       
  1694 (     MPL *mpl,
       
  1695       PARAMETER *par,         /* not changed */
       
  1696       TUPLE *tuple,           /* not changed */
       
  1697       SYMBOL *value           /* not changed */
       
  1698 );
       
  1699 /* check symbolic value assigned to parameter member */
       
  1700 
       
  1701 #define take_member_sym _glp_mpl_take_member_sym
       
  1702 SYMBOL *take_member_sym       /* returns value, not reference */
       
  1703 (     MPL *mpl,
       
  1704       PARAMETER *par,         /* not changed */
       
  1705       TUPLE *tuple            /* not changed */
       
  1706 );
       
  1707 /* obtain symbolic value assigned to parameter member */
       
  1708 
       
  1709 #define eval_member_sym _glp_mpl_eval_member_sym
       
  1710 SYMBOL *eval_member_sym       /* returns value, not reference */
       
  1711 (     MPL *mpl,
       
  1712       PARAMETER *par,         /* not changed */
       
  1713       TUPLE *tuple            /* not changed */
       
  1714 );
       
  1715 /* evaluate symbolic value assigned to parameter member */
       
  1716 
       
  1717 #define eval_whole_par _glp_mpl_eval_whole_par
       
  1718 void eval_whole_par(MPL *mpl, PARAMETER *par);
       
  1719 /* evaluate model parameter over entire domain */
       
  1720 
       
  1721 #define clean_parameter _glp_mpl_clean_parameter
       
  1722 void clean_parameter(MPL *mpl, PARAMETER *par);
       
  1723 /* clean model parameter */
       
  1724 
       
  1725 /**********************************************************************/
       
  1726 /* * *                      MODEL VARIABLES                       * * */
       
  1727 /**********************************************************************/
       
  1728 
       
  1729 struct VARIABLE
       
  1730 {     /* model variable */
       
  1731       char *name;
       
  1732       /* symbolic name; cannot be NULL */
       
  1733       char *alias;
       
  1734       /* alias; NULL means alias is not specified */
       
  1735       int dim; /* aka arity */
       
  1736       /* dimension (number of subscripts); dim = 0 means 0-dimensional
       
  1737          (unsubscripted) variable */
       
  1738       DOMAIN *domain;
       
  1739       /* subscript domain; NULL for 0-dimensional variable */
       
  1740       int type;
       
  1741       /* variable type:
       
  1742          A_NUMERIC - continuous
       
  1743          A_INTEGER - integer
       
  1744          A_BINARY  - binary */
       
  1745       CODE *lbnd;
       
  1746       /* pseudo-code for computing lower bound; NULL means lower bound
       
  1747          is not specified */
       
  1748       CODE *ubnd;
       
  1749       /* pseudo-code for computing upper bound; NULL means upper bound
       
  1750          is not specified */
       
  1751       /* if both the pointers lbnd and ubnd refer to the same code, the
       
  1752          variable is fixed at the corresponding value */
       
  1753       ARRAY *array;
       
  1754       /* array of members, which are assigned elemental variables */
       
  1755 };
       
  1756 
       
  1757 #define take_member_var _glp_mpl_take_member_var
       
  1758 ELEMVAR *take_member_var      /* returns reference */
       
  1759 (     MPL *mpl,
       
  1760       VARIABLE *var,          /* not changed */
       
  1761       TUPLE *tuple            /* not changed */
       
  1762 );
       
  1763 /* obtain reference to elemental variable */
       
  1764 
       
  1765 #define eval_member_var _glp_mpl_eval_member_var
       
  1766 ELEMVAR *eval_member_var      /* returns reference */
       
  1767 (     MPL *mpl,
       
  1768       VARIABLE *var,          /* not changed */
       
  1769       TUPLE *tuple            /* not changed */
       
  1770 );
       
  1771 /* evaluate reference to elemental variable */
       
  1772 
       
  1773 #define eval_whole_var _glp_mpl_eval_whole_var
       
  1774 void eval_whole_var(MPL *mpl, VARIABLE *var);
       
  1775 /* evaluate model variable over entire domain */
       
  1776 
       
  1777 #define clean_variable _glp_mpl_clean_variable
       
  1778 void clean_variable(MPL *mpl, VARIABLE *var);
       
  1779 /* clean model variable */
       
  1780 
       
  1781 /**********************************************************************/
       
  1782 /* * *              MODEL CONSTRAINTS AND OBJECTIVES              * * */
       
  1783 /**********************************************************************/
       
  1784 
       
  1785 struct CONSTRAINT
       
  1786 {     /* model constraint or objective */
       
  1787       char *name;
       
  1788       /* symbolic name; cannot be NULL */
       
  1789       char *alias;
       
  1790       /* alias; NULL means alias is not specified */
       
  1791       int dim; /* aka arity */
       
  1792       /* dimension (number of subscripts); dim = 0 means 0-dimensional
       
  1793          (unsubscripted) constraint */
       
  1794       DOMAIN *domain;
       
  1795       /* subscript domain; NULL for 0-dimensional constraint */
       
  1796       int type;
       
  1797       /* constraint type:
       
  1798          A_CONSTRAINT - constraint
       
  1799          A_MINIMIZE   - objective (minimization)
       
  1800          A_MAXIMIZE   - objective (maximization) */
       
  1801       CODE *code;
       
  1802       /* pseudo-code for computing main linear form; cannot be NULL */
       
  1803       CODE *lbnd;
       
  1804       /* pseudo-code for computing lower bound; NULL means lower bound
       
  1805          is not specified */
       
  1806       CODE *ubnd;
       
  1807       /* pseudo-code for computing upper bound; NULL means upper bound
       
  1808          is not specified */
       
  1809       /* if both the pointers lbnd and ubnd refer to the same code, the
       
  1810          constraint has the form of equation */
       
  1811       ARRAY *array;
       
  1812       /* array of members, which are assigned elemental constraints */
       
  1813 };
       
  1814 
       
  1815 #define take_member_con _glp_mpl_take_member_con
       
  1816 ELEMCON *take_member_con      /* returns reference */
       
  1817 (     MPL *mpl,
       
  1818       CONSTRAINT *con,        /* not changed */
       
  1819       TUPLE *tuple            /* not changed */
       
  1820 );
       
  1821 /* obtain reference to elemental constraint */
       
  1822 
       
  1823 #define eval_member_con _glp_mpl_eval_member_con
       
  1824 ELEMCON *eval_member_con      /* returns reference */
       
  1825 (     MPL *mpl,
       
  1826       CONSTRAINT *con,        /* not changed */
       
  1827       TUPLE *tuple            /* not changed */
       
  1828 );
       
  1829 /* evaluate reference to elemental constraint */
       
  1830 
       
  1831 #define eval_whole_con _glp_mpl_eval_whole_con
       
  1832 void eval_whole_con(MPL *mpl, CONSTRAINT *con);
       
  1833 /* evaluate model constraint over entire domain */
       
  1834 
       
  1835 #define clean_constraint _glp_mpl_clean_constraint
       
  1836 void clean_constraint(MPL *mpl, CONSTRAINT *con);
       
  1837 /* clean model constraint */
       
  1838 
       
  1839 /**********************************************************************/
       
  1840 /* * *                        DATA TABLES                         * * */
       
  1841 /**********************************************************************/
       
  1842 
       
  1843 struct TABLE
       
  1844 {     /* data table */
       
  1845       char *name;
       
  1846       /* symbolic name; cannot be NULL */
       
  1847       char *alias;
       
  1848       /* alias; NULL means alias is not specified */
       
  1849       int type;
       
  1850       /* table type:
       
  1851          A_INPUT  - input table
       
  1852          A_OUTPUT - output table */
       
  1853       TABARG *arg;
       
  1854       /* argument list; cannot be empty */
       
  1855       union
       
  1856       {  struct
       
  1857          {  SET *set;
       
  1858             /* input set; NULL means the set is not specified */
       
  1859             TABFLD *fld;
       
  1860             /* field list; cannot be empty */
       
  1861             TABIN *list;
       
  1862             /* input list; can be empty */
       
  1863          } in;
       
  1864          struct
       
  1865          {  DOMAIN *domain;
       
  1866             /* subscript domain; cannot be NULL */
       
  1867             TABOUT *list;
       
  1868             /* output list; cannot be empty */
       
  1869          } out;
       
  1870       } u;
       
  1871 };
       
  1872 
       
  1873 struct TABARG
       
  1874 {     /* table argument list entry */
       
  1875       CODE *code;
       
  1876       /* pseudo-code for computing the argument */
       
  1877       TABARG *next;
       
  1878       /* next entry for the same table */
       
  1879 };
       
  1880 
       
  1881 struct TABFLD
       
  1882 {     /* table field list entry */
       
  1883       char *name;
       
  1884       /* field name; cannot be NULL */
       
  1885       TABFLD *next;
       
  1886       /* next entry for the same table */
       
  1887 };
       
  1888 
       
  1889 struct TABIN
       
  1890 {     /* table input list entry */
       
  1891       PARAMETER *par;
       
  1892       /* parameter to be read; cannot be NULL */
       
  1893       char *name;
       
  1894       /* column name; cannot be NULL */
       
  1895       TABIN *next;
       
  1896       /* next entry for the same table */
       
  1897 };
       
  1898 
       
  1899 struct TABOUT
       
  1900 {     /* table output list entry */
       
  1901       CODE *code;
       
  1902       /* pseudo-code for computing the value to be written */
       
  1903       char *name;
       
  1904       /* column name; cannot be NULL */
       
  1905       TABOUT *next;
       
  1906       /* next entry for the same table */
       
  1907 };
       
  1908 
       
  1909 struct TABDCA
       
  1910 {     /* table driver communication area */
       
  1911       int id;
       
  1912       /* driver identifier (set by mpl_tab_drv_open) */
       
  1913       void *link;
       
  1914       /* driver link pointer (set by mpl_tab_drv_open) */
       
  1915       int na;
       
  1916       /* number of arguments */
       
  1917       char **arg; /* char *arg[1+ns]; */
       
  1918       /* arg[k], 1 <= k <= ns, is pointer to k-th argument */
       
  1919       int nf;
       
  1920       /* number of fields */
       
  1921       char **name; /* char *name[1+nc]; */
       
  1922       /* name[k], 1 <= k <= nc, is name of k-th field */
       
  1923       int *type; /* int type[1+nc]; */
       
  1924       /* type[k], 1 <= k <= nc, is type of k-th field:
       
  1925          '?' - value not assigned
       
  1926          'N' - number
       
  1927          'S' - character string */
       
  1928       double *num; /* double num[1+nc]; */
       
  1929       /* num[k], 1 <= k <= nc, is numeric value of k-th field */
       
  1930       char **str;
       
  1931       /* str[k], 1 <= k <= nc, is string value of k-th field */
       
  1932 };
       
  1933 
       
  1934 #define mpl_tab_num_args _glp_mpl_tab_num_args
       
  1935 int mpl_tab_num_args(TABDCA *dca);
       
  1936 
       
  1937 #define mpl_tab_get_arg _glp_mpl_tab_get_arg
       
  1938 const char *mpl_tab_get_arg(TABDCA *dca, int k);
       
  1939 
       
  1940 #define mpl_tab_num_flds _glp_mpl_tab_num_flds
       
  1941 int mpl_tab_num_flds(TABDCA *dca);
       
  1942 
       
  1943 #define mpl_tab_get_name _glp_mpl_tab_get_name
       
  1944 const char *mpl_tab_get_name(TABDCA *dca, int k);
       
  1945 
       
  1946 #define mpl_tab_get_type _glp_mpl_tab_get_type
       
  1947 int mpl_tab_get_type(TABDCA *dca, int k);
       
  1948 
       
  1949 #define mpl_tab_get_num _glp_mpl_tab_get_num
       
  1950 double mpl_tab_get_num(TABDCA *dca, int k);
       
  1951 
       
  1952 #define mpl_tab_get_str _glp_mpl_tab_get_str
       
  1953 const char *mpl_tab_get_str(TABDCA *dca, int k);
       
  1954 
       
  1955 #define mpl_tab_set_num _glp_mpl_tab_set_num
       
  1956 void mpl_tab_set_num(TABDCA *dca, int k, double num);
       
  1957 
       
  1958 #define mpl_tab_set_str _glp_mpl_tab_set_str
       
  1959 void mpl_tab_set_str(TABDCA *dca, int k, const char *str);
       
  1960 
       
  1961 #define mpl_tab_drv_open _glp_mpl_tab_drv_open
       
  1962 void mpl_tab_drv_open(MPL *mpl, int mode);
       
  1963 
       
  1964 #define mpl_tab_drv_read _glp_mpl_tab_drv_read
       
  1965 int mpl_tab_drv_read(MPL *mpl);
       
  1966 
       
  1967 #define mpl_tab_drv_write _glp_mpl_tab_drv_write
       
  1968 void mpl_tab_drv_write(MPL *mpl);
       
  1969 
       
  1970 #define mpl_tab_drv_close _glp_mpl_tab_drv_close
       
  1971 void mpl_tab_drv_close(MPL *mpl);
       
  1972 
       
  1973 /**********************************************************************/
       
  1974 /* * *                        PSEUDO-CODE                         * * */
       
  1975 /**********************************************************************/
       
  1976 
       
  1977 union OPERANDS
       
  1978 {     /* operands that participate in pseudo-code operation (choice of
       
  1979          particular operands depends on the operation code) */
       
  1980       /*--------------------------------------------------------------*/
       
  1981       double num;             /* O_NUMBER */
       
  1982       /* floaing-point number to be taken */
       
  1983       /*--------------------------------------------------------------*/
       
  1984       char *str;              /* O_STRING */
       
  1985       /* character string to be taken */
       
  1986       /*--------------------------------------------------------------*/
       
  1987       struct                  /* O_INDEX */
       
  1988       {  DOMAIN_SLOT *slot;
       
  1989          /* domain slot, which contains dummy index to be taken */
       
  1990          CODE *next;
       
  1991          /* the next pseudo-code with op = O_INDEX, which refers to the
       
  1992             same slot as this one; pointer to the beginning of this list
       
  1993             is stored in the corresponding domain slot */
       
  1994       } index;
       
  1995       /*--------------------------------------------------------------*/
       
  1996       struct                  /* O_MEMNUM, O_MEMSYM */
       
  1997       {  PARAMETER *par;
       
  1998          /* model parameter, which contains member to be taken */
       
  1999          ARG_LIST *list;
       
  2000          /* list of subscripts; NULL for 0-dimensional parameter */
       
  2001       } par;
       
  2002       /*--------------------------------------------------------------*/
       
  2003       struct                  /* O_MEMSET */
       
  2004       {  SET *set;
       
  2005          /* model set, which contains member to be taken */
       
  2006          ARG_LIST *list;
       
  2007          /* list of subscripts; NULL for 0-dimensional set */
       
  2008       } set;
       
  2009       /*--------------------------------------------------------------*/
       
  2010       struct                  /* O_MEMVAR */
       
  2011       {  VARIABLE *var;
       
  2012          /* model variable, which contains member to be taken */
       
  2013          ARG_LIST *list;
       
  2014          /* list of subscripts; NULL for 0-dimensional variable */
       
  2015 #if 1 /* 15/V-2010 */
       
  2016          int suff;
       
  2017          /* suffix specified: */
       
  2018 #define DOT_NONE        0x00  /* none     (means variable itself) */
       
  2019 #define DOT_LB          0x01  /* .lb      (lower bound) */
       
  2020 #define DOT_UB          0x02  /* .ub      (upper bound) */
       
  2021 #define DOT_STATUS      0x03  /* .status  (status) */
       
  2022 #define DOT_VAL         0x04  /* .val     (primal value) */
       
  2023 #define DOT_DUAL        0x05  /* .dual    (dual value) */
       
  2024 #endif
       
  2025       } var;
       
  2026 #if 1 /* 15/V-2010 */
       
  2027       /*--------------------------------------------------------------*/
       
  2028       struct                  /* O_MEMCON */
       
  2029       {  CONSTRAINT *con;
       
  2030          /* model constraint, which contains member to be taken */
       
  2031          ARG_LIST *list;
       
  2032          /* list of subscripys; NULL for 0-dimensional constraint */
       
  2033          int suff;
       
  2034          /* suffix specified (see O_MEMVAR above) */
       
  2035       } con;
       
  2036 #endif
       
  2037       /*--------------------------------------------------------------*/
       
  2038       ARG_LIST *list;         /* O_TUPLE, O_MAKE, n-ary operations */
       
  2039       /* list of operands */
       
  2040       /*--------------------------------------------------------------*/
       
  2041       DOMAIN_BLOCK *slice;    /* O_SLICE */
       
  2042       /* domain block, which specifies slice (i.e. n-tuple that contains
       
  2043          free dummy indices); this operation is never evaluated */
       
  2044       /*--------------------------------------------------------------*/
       
  2045       struct                  /* unary, binary, ternary operations */
       
  2046       {  CODE *x;
       
  2047          /* pseudo-code for computing first operand */
       
  2048          CODE *y;
       
  2049          /* pseudo-code for computing second operand */
       
  2050          CODE *z;
       
  2051          /* pseudo-code for computing third operand */
       
  2052       } arg;
       
  2053       /*--------------------------------------------------------------*/
       
  2054       struct                  /* iterated operations */
       
  2055       {  DOMAIN *domain;
       
  2056          /* domain, over which the operation is performed */
       
  2057          CODE *x;
       
  2058          /* pseudo-code for computing "integrand" */
       
  2059       } loop;
       
  2060       /*--------------------------------------------------------------*/
       
  2061 };
       
  2062 
       
  2063 struct ARG_LIST
       
  2064 {     /* operands list entry */
       
  2065       CODE *x;
       
  2066       /* pseudo-code for computing operand */
       
  2067       ARG_LIST *next;
       
  2068       /* the next operand of the same operation */
       
  2069 };
       
  2070 
       
  2071 struct CODE
       
  2072 {     /* pseudo-code (internal form of expressions) */
       
  2073       int op;
       
  2074       /* operation code: */
       
  2075 #define O_NUMBER        301   /* take floating-point number */
       
  2076 #define O_STRING        302   /* take character string */
       
  2077 #define O_INDEX         303   /* take dummy index */
       
  2078 #define O_MEMNUM        304   /* take member of numeric parameter */
       
  2079 #define O_MEMSYM        305   /* take member of symbolic parameter */
       
  2080 #define O_MEMSET        306   /* take member of set */
       
  2081 #define O_MEMVAR        307   /* take member of variable */
       
  2082 #define O_MEMCON        308   /* take member of constraint */
       
  2083 #define O_TUPLE         309   /* make n-tuple */
       
  2084 #define O_MAKE          310   /* make elemental set of n-tuples */
       
  2085 #define O_SLICE         311   /* define domain block (dummy op) */
       
  2086                               /* 0-ary operations --------------------*/
       
  2087 #define O_IRAND224      312   /* pseudo-random in [0, 2^24-1] */
       
  2088 #define O_UNIFORM01     313   /* pseudo-random in [0, 1) */
       
  2089 #define O_NORMAL01      314   /* gaussian random, mu = 0, sigma = 1 */
       
  2090 #define O_GMTIME        315   /* current calendar time (UTC) */
       
  2091                               /* unary operations --------------------*/
       
  2092 #define O_CVTNUM        316   /* conversion to numeric */
       
  2093 #define O_CVTSYM        317   /* conversion to symbolic */
       
  2094 #define O_CVTLOG        318   /* conversion to logical */
       
  2095 #define O_CVTTUP        319   /* conversion to 1-tuple */
       
  2096 #define O_CVTLFM        320   /* conversion to linear form */
       
  2097 #define O_PLUS          321   /* unary plus */
       
  2098 #define O_MINUS         322   /* unary minus */
       
  2099 #define O_NOT           323   /* negation (logical "not") */
       
  2100 #define O_ABS           324   /* absolute value */
       
  2101 #define O_CEIL          325   /* round upward ("ceiling of x") */
       
  2102 #define O_FLOOR         326   /* round downward ("floor of x") */
       
  2103 #define O_EXP           327   /* base-e exponential */
       
  2104 #define O_LOG           328   /* natural logarithm */
       
  2105 #define O_LOG10         329   /* common (decimal) logarithm */
       
  2106 #define O_SQRT          330   /* square root */
       
  2107 #define O_SIN           331   /* trigonometric sine */
       
  2108 #define O_COS           332   /* trigonometric cosine */
       
  2109 #define O_ATAN          333   /* trigonometric arctangent */
       
  2110 #define O_ROUND         334   /* round to nearest integer */
       
  2111 #define O_TRUNC         335   /* truncate to nearest integer */
       
  2112 #define O_CARD          336   /* cardinality of set */
       
  2113 #define O_LENGTH        337   /* length of symbolic value */
       
  2114                               /* binary operations -------------------*/
       
  2115 #define O_ADD           338   /* addition */
       
  2116 #define O_SUB           339   /* subtraction */
       
  2117 #define O_LESS          340   /* non-negative subtraction */
       
  2118 #define O_MUL           341   /* multiplication */
       
  2119 #define O_DIV           342   /* division */
       
  2120 #define O_IDIV          343   /* quotient of exact division */
       
  2121 #define O_MOD           344   /* remainder of exact division */
       
  2122 #define O_POWER         345   /* exponentiation (raise to power) */
       
  2123 #define O_ATAN2         346   /* trigonometric arctangent */
       
  2124 #define O_ROUND2        347   /* round to n fractional digits */
       
  2125 #define O_TRUNC2        348   /* truncate to n fractional digits */
       
  2126 #define O_UNIFORM       349   /* pseudo-random in [a, b) */
       
  2127 #define O_NORMAL        350   /* gaussian random, given mu and sigma */
       
  2128 #define O_CONCAT        351   /* concatenation */
       
  2129 #define O_LT            352   /* comparison on 'less than' */
       
  2130 #define O_LE            353   /* comparison on 'not greater than' */
       
  2131 #define O_EQ            354   /* comparison on 'equal to' */
       
  2132 #define O_GE            355   /* comparison on 'not less than' */
       
  2133 #define O_GT            356   /* comparison on 'greater than' */
       
  2134 #define O_NE            357   /* comparison on 'not equal to' */
       
  2135 #define O_AND           358   /* conjunction (logical "and") */
       
  2136 #define O_OR            359   /* disjunction (logical "or") */
       
  2137 #define O_UNION         360   /* union */
       
  2138 #define O_DIFF          361   /* difference */
       
  2139 #define O_SYMDIFF       362   /* symmetric difference */
       
  2140 #define O_INTER         363   /* intersection */
       
  2141 #define O_CROSS         364   /* cross (Cartesian) product */
       
  2142 #define O_IN            365   /* test on 'x in Y' */
       
  2143 #define O_NOTIN         366   /* test on 'x not in Y' */
       
  2144 #define O_WITHIN        367   /* test on 'X within Y' */
       
  2145 #define O_NOTWITHIN     368   /* test on 'X not within Y' */
       
  2146 #define O_SUBSTR        369   /* substring */
       
  2147 #define O_STR2TIME      370   /* convert string to time */
       
  2148 #define O_TIME2STR      371   /* convert time to string */
       
  2149                               /* ternary operations ------------------*/
       
  2150 #define O_DOTS          372   /* build "arithmetic" set */
       
  2151 #define O_FORK          373   /* if-then-else */
       
  2152 #define O_SUBSTR3       374   /* substring */
       
  2153                               /* n-ary operations --------------------*/
       
  2154 #define O_MIN           375   /* minimal value (n-ary) */
       
  2155 #define O_MAX           376   /* maximal value (n-ary) */
       
  2156                               /* iterated operations -----------------*/
       
  2157 #define O_SUM           377   /* summation */
       
  2158 #define O_PROD          378   /* multiplication */
       
  2159 #define O_MINIMUM       379   /* minimum */
       
  2160 #define O_MAXIMUM       380   /* maximum */
       
  2161 #define O_FORALL        381   /* conjunction (A-quantification) */
       
  2162 #define O_EXISTS        382   /* disjunction (E-quantification) */
       
  2163 #define O_SETOF         383   /* compute elemental set */
       
  2164 #define O_BUILD         384   /* build elemental set */
       
  2165       OPERANDS arg;
       
  2166       /* operands that participate in the operation */
       
  2167       int type;
       
  2168       /* type of the resultant value:
       
  2169          A_NUMERIC  - numeric
       
  2170          A_SYMBOLIC - symbolic
       
  2171          A_LOGICAL  - logical
       
  2172          A_TUPLE    - n-tuple
       
  2173          A_ELEMSET  - elemental set
       
  2174          A_FORMULA  - linear form */
       
  2175       int dim;
       
  2176       /* dimension of the resultant value; for A_TUPLE and A_ELEMSET it
       
  2177          is the dimension of the corresponding n-tuple(s) and cannot be
       
  2178          zero; for other resultant types it is always zero */
       
  2179       CODE *up;
       
  2180       /* parent pseudo-code, which refers to this pseudo-code as to its
       
  2181          operand; NULL means this pseudo-code has no parent and defines
       
  2182          an expression, which is not contained in another expression */
       
  2183       int vflag;
       
  2184       /* volatile flag; being set this flag means that this operation
       
  2185          has a side effect; for primary expressions this flag is set
       
  2186          directly by corresponding parsing routines (for example, if
       
  2187          primary expression is a reference to a function that generates
       
  2188          pseudo-random numbers); in other cases this flag is inherited
       
  2189          from operands */
       
  2190       int valid;
       
  2191       /* if this flag is set, the resultant value, which is a temporary
       
  2192          result of evaluating this operation on particular values of
       
  2193          operands, is valid; if this flag is clear, the resultant value
       
  2194          doesn't exist and therefore not valid; having been evaluated
       
  2195          the resultant value is stored here and not destroyed until the
       
  2196          dummy indices, which this value depends on, have been changed
       
  2197          (and if it doesn't depend on dummy indices at all, it is never
       
  2198          destroyed); thus, if the resultant value is valid, evaluating
       
  2199          routine can immediately take its copy not computing the result
       
  2200          from scratch; this mechanism is similar to moving invariants
       
  2201          out of loops and allows improving efficiency at the expense of
       
  2202          some extra memory needed to keep temporary results */
       
  2203       /* however, if the volatile flag (see above) is set, even if the
       
  2204          resultant value is valid, evaluating routine computes it as if
       
  2205          it were not valid, i.e. caching is not used in this case */
       
  2206       VALUE value;
       
  2207       /* resultant value in generic format */
       
  2208 };
       
  2209 
       
  2210 #define eval_numeric _glp_mpl_eval_numeric
       
  2211 double eval_numeric(MPL *mpl, CODE *code);
       
  2212 /* evaluate pseudo-code to determine numeric value */
       
  2213 
       
  2214 #define eval_symbolic _glp_mpl_eval_symbolic
       
  2215 SYMBOL *eval_symbolic(MPL *mpl, CODE *code);
       
  2216 /* evaluate pseudo-code to determine symbolic value */
       
  2217 
       
  2218 #define eval_logical _glp_mpl_eval_logical
       
  2219 int eval_logical(MPL *mpl, CODE *code);
       
  2220 /* evaluate pseudo-code to determine logical value */
       
  2221 
       
  2222 #define eval_tuple _glp_mpl_eval_tuple
       
  2223 TUPLE *eval_tuple(MPL *mpl, CODE *code);
       
  2224 /* evaluate pseudo-code to construct n-tuple */
       
  2225 
       
  2226 #define eval_elemset _glp_mpl_eval_elemset
       
  2227 ELEMSET *eval_elemset(MPL *mpl, CODE *code);
       
  2228 /* evaluate pseudo-code to construct elemental set */
       
  2229 
       
  2230 #define is_member _glp_mpl_is_member
       
  2231 int is_member(MPL *mpl, CODE *code, TUPLE *tuple);
       
  2232 /* check if n-tuple is in set specified by pseudo-code */
       
  2233 
       
  2234 #define eval_formula _glp_mpl_eval_formula
       
  2235 FORMULA *eval_formula(MPL *mpl, CODE *code);
       
  2236 /* evaluate pseudo-code to construct linear form */
       
  2237 
       
  2238 #define clean_code _glp_mpl_clean_code
       
  2239 void clean_code(MPL *mpl, CODE *code);
       
  2240 /* clean pseudo-code */
       
  2241 
       
  2242 /**********************************************************************/
       
  2243 /* * *                      MODEL STATEMENTS                      * * */
       
  2244 /**********************************************************************/
       
  2245 
       
  2246 struct CHECK
       
  2247 {     /* check statement */
       
  2248       DOMAIN *domain;
       
  2249       /* subscript domain; NULL means domain is not used */
       
  2250       CODE *code;
       
  2251       /* code for computing the predicate to be checked */
       
  2252 };
       
  2253 
       
  2254 struct DISPLAY
       
  2255 {     /* display statement */
       
  2256       DOMAIN *domain;
       
  2257       /* subscript domain; NULL means domain is not used */
       
  2258       DISPLAY1 *list;
       
  2259       /* display list; cannot be empty */
       
  2260 };
       
  2261 
       
  2262 struct DISPLAY1
       
  2263 {     /* display list entry */
       
  2264       int type;
       
  2265       /* item type:
       
  2266          A_INDEX      - dummy index
       
  2267          A_SET        - model set
       
  2268          A_PARAMETER  - model parameter
       
  2269          A_VARIABLE   - model variable
       
  2270          A_CONSTRAINT - model constraint/objective
       
  2271          A_EXPRESSION - expression */
       
  2272       union
       
  2273       {  DOMAIN_SLOT *slot;
       
  2274          SET *set;
       
  2275          PARAMETER *par;
       
  2276          VARIABLE *var;
       
  2277          CONSTRAINT *con;
       
  2278          CODE *code;
       
  2279       } u;
       
  2280       /* item to be displayed */
       
  2281 #if 0 /* 15/V-2010 */
       
  2282       ARG_LIST *list;
       
  2283       /* optional subscript list (for constraint/objective only) */
       
  2284 #endif
       
  2285       DISPLAY1 *next;
       
  2286       /* the next entry for the same statement */
       
  2287 };
       
  2288 
       
  2289 struct PRINTF
       
  2290 {     /* printf statement */
       
  2291       DOMAIN *domain;
       
  2292       /* subscript domain; NULL means domain is not used */
       
  2293       CODE *fmt;
       
  2294       /* pseudo-code for computing format string */
       
  2295       PRINTF1 *list;
       
  2296       /* printf list; can be empty */
       
  2297       CODE *fname;
       
  2298       /* pseudo-code for computing filename to redirect the output;
       
  2299          NULL means the output goes to stdout */
       
  2300       int app;
       
  2301       /* if this flag is set, the output is appended */
       
  2302 };
       
  2303 
       
  2304 struct PRINTF1
       
  2305 {     /* printf list entry */
       
  2306       CODE *code;
       
  2307       /* pseudo-code for computing value to be printed */
       
  2308       PRINTF1 *next;
       
  2309       /* the next entry for the same statement */
       
  2310 };
       
  2311 
       
  2312 struct FOR
       
  2313 {     /* for statement */
       
  2314       DOMAIN *domain;
       
  2315       /* subscript domain; cannot be NULL */
       
  2316       STATEMENT *list;
       
  2317       /* linked list of model statements within this for statement in
       
  2318          the original order */
       
  2319 };
       
  2320 
       
  2321 struct STATEMENT
       
  2322 {     /* model statement */
       
  2323       int line;
       
  2324       /* number of source text line, where statement begins */
       
  2325       int type;
       
  2326       /* statement type:
       
  2327          A_SET        - set statement
       
  2328          A_PARAMETER  - parameter statement
       
  2329          A_VARIABLE   - variable statement
       
  2330          A_CONSTRAINT - constraint/objective statement
       
  2331          A_TABLE      - table statement
       
  2332          A_SOLVE      - solve statement
       
  2333          A_CHECK      - check statement
       
  2334          A_DISPLAY    - display statement
       
  2335          A_PRINTF     - printf statement
       
  2336          A_FOR        - for statement */
       
  2337       union
       
  2338       {  SET *set;
       
  2339          PARAMETER *par;
       
  2340          VARIABLE *var;
       
  2341          CONSTRAINT *con;
       
  2342          TABLE *tab;
       
  2343          void *slv; /* currently not used (set to NULL) */
       
  2344          CHECK *chk;
       
  2345          DISPLAY *dpy;
       
  2346          PRINTF *prt;
       
  2347          FOR *fur;
       
  2348       } u;
       
  2349       /* specific part of statement */
       
  2350       STATEMENT *next;
       
  2351       /* the next statement; in this list statements follow in the same
       
  2352          order as they appear in the model section */
       
  2353 };
       
  2354 
       
  2355 #define execute_table _glp_mpl_execute_table
       
  2356 void execute_table(MPL *mpl, TABLE *tab);
       
  2357 /* execute table statement */
       
  2358 
       
  2359 #define free_dca _glp_mpl_free_dca
       
  2360 void free_dca(MPL *mpl);
       
  2361 /* free table driver communucation area */
       
  2362 
       
  2363 #define clean_table _glp_mpl_clean_table
       
  2364 void clean_table(MPL *mpl, TABLE *tab);
       
  2365 /* clean table statement */
       
  2366 
       
  2367 #define execute_check _glp_mpl_execute_check
       
  2368 void execute_check(MPL *mpl, CHECK *chk);
       
  2369 /* execute check statement */
       
  2370 
       
  2371 #define clean_check _glp_mpl_clean_check
       
  2372 void clean_check(MPL *mpl, CHECK *chk);
       
  2373 /* clean check statement */
       
  2374 
       
  2375 #define execute_display _glp_mpl_execute_display
       
  2376 void execute_display(MPL *mpl, DISPLAY *dpy);
       
  2377 /* execute display statement */
       
  2378 
       
  2379 #define clean_display _glp_mpl_clean_display
       
  2380 void clean_display(MPL *mpl, DISPLAY *dpy);
       
  2381 /* clean display statement */
       
  2382 
       
  2383 #define execute_printf _glp_mpl_execute_printf
       
  2384 void execute_printf(MPL *mpl, PRINTF *prt);
       
  2385 /* execute printf statement */
       
  2386 
       
  2387 #define clean_printf _glp_mpl_clean_printf
       
  2388 void clean_printf(MPL *mpl, PRINTF *prt);
       
  2389 /* clean printf statement */
       
  2390 
       
  2391 #define execute_for _glp_mpl_execute_for
       
  2392 void execute_for(MPL *mpl, FOR *fur);
       
  2393 /* execute for statement */
       
  2394 
       
  2395 #define clean_for _glp_mpl_clean_for
       
  2396 void clean_for(MPL *mpl, FOR *fur);
       
  2397 /* clean for statement */
       
  2398 
       
  2399 #define execute_statement _glp_mpl_execute_statement
       
  2400 void execute_statement(MPL *mpl, STATEMENT *stmt);
       
  2401 /* execute specified model statement */
       
  2402 
       
  2403 #define clean_statement _glp_mpl_clean_statement
       
  2404 void clean_statement(MPL *mpl, STATEMENT *stmt);
       
  2405 /* clean specified model statement */
       
  2406 
       
  2407 /**********************************************************************/
       
  2408 /* * *              GENERATING AND POSTSOLVING MODEL              * * */
       
  2409 /**********************************************************************/
       
  2410 
       
  2411 #define alloc_content _glp_mpl_alloc_content
       
  2412 void alloc_content(MPL *mpl);
       
  2413 /* allocate content arrays for all model objects */
       
  2414 
       
  2415 #define generate_model _glp_mpl_generate_model
       
  2416 void generate_model(MPL *mpl);
       
  2417 /* generate model */
       
  2418 
       
  2419 #define build_problem _glp_mpl_build_problem
       
  2420 void build_problem(MPL *mpl);
       
  2421 /* build problem instance */
       
  2422 
       
  2423 #define postsolve_model _glp_mpl_postsolve_model
       
  2424 void postsolve_model(MPL *mpl);
       
  2425 /* postsolve model */
       
  2426 
       
  2427 #define clean_model _glp_mpl_clean_model
       
  2428 void clean_model(MPL *mpl);
       
  2429 /* clean model content */
       
  2430 
       
  2431 /**********************************************************************/
       
  2432 /* * *                        INPUT/OUTPUT                        * * */
       
  2433 /**********************************************************************/
       
  2434 
       
  2435 #define open_input _glp_mpl_open_input
       
  2436 void open_input(MPL *mpl, char *file);
       
  2437 /* open input text file */
       
  2438 
       
  2439 #define read_char _glp_mpl_read_char
       
  2440 int read_char(MPL *mpl);
       
  2441 /* read next character from input text file */
       
  2442 
       
  2443 #define close_input _glp_mpl_close_input
       
  2444 void close_input(MPL *mpl);
       
  2445 /* close input text file */
       
  2446 
       
  2447 #define open_output _glp_mpl_open_output
       
  2448 void open_output(MPL *mpl, char *file);
       
  2449 /* open output text file */
       
  2450 
       
  2451 #define write_char _glp_mpl_write_char
       
  2452 void write_char(MPL *mpl, int c);
       
  2453 /* write next character to output text file */
       
  2454 
       
  2455 #define write_text _glp_mpl_write_text
       
  2456 void write_text(MPL *mpl, char *fmt, ...);
       
  2457 /* format and write text to output text file */
       
  2458 
       
  2459 #define flush_output _glp_mpl_flush_output
       
  2460 void flush_output(MPL *mpl);
       
  2461 /* finalize writing data to output text file */
       
  2462 
       
  2463 /**********************************************************************/
       
  2464 /* * *                      SOLVER INTERFACE                      * * */
       
  2465 /**********************************************************************/
       
  2466 
       
  2467 #define MPL_FR          401   /* free (unbounded) */
       
  2468 #define MPL_LO          402   /* lower bound */
       
  2469 #define MPL_UP          403   /* upper bound */
       
  2470 #define MPL_DB          404   /* both lower and upper bounds */
       
  2471 #define MPL_FX          405   /* fixed */
       
  2472 
       
  2473 #define MPL_ST          411   /* constraint */
       
  2474 #define MPL_MIN         412   /* objective (minimization) */
       
  2475 #define MPL_MAX         413   /* objective (maximization) */
       
  2476 
       
  2477 #define MPL_NUM         421   /* continuous */
       
  2478 #define MPL_INT         422   /* integer */
       
  2479 #define MPL_BIN         423   /* binary */
       
  2480 
       
  2481 #define error _glp_mpl_error
       
  2482 void error(MPL *mpl, char *fmt, ...);
       
  2483 /* print error message and terminate model processing */
       
  2484 
       
  2485 #define warning _glp_mpl_warning
       
  2486 void warning(MPL *mpl, char *fmt, ...);
       
  2487 /* print warning message and continue model processing */
       
  2488 
       
  2489 #define mpl_initialize _glp_mpl_initialize
       
  2490 MPL *mpl_initialize(void);
       
  2491 /* create and initialize translator database */
       
  2492 
       
  2493 #define mpl_read_model _glp_mpl_read_model
       
  2494 int mpl_read_model(MPL *mpl, char *file, int skip_data);
       
  2495 /* read model section and optional data section */
       
  2496 
       
  2497 #define mpl_read_data _glp_mpl_read_data
       
  2498 int mpl_read_data(MPL *mpl, char *file);
       
  2499 /* read data section */
       
  2500 
       
  2501 #define mpl_generate _glp_mpl_generate
       
  2502 int mpl_generate(MPL *mpl, char *file);
       
  2503 /* generate model */
       
  2504 
       
  2505 #define mpl_get_prob_name _glp_mpl_get_prob_name
       
  2506 char *mpl_get_prob_name(MPL *mpl);
       
  2507 /* obtain problem (model) name */
       
  2508 
       
  2509 #define mpl_get_num_rows _glp_mpl_get_num_rows
       
  2510 int mpl_get_num_rows(MPL *mpl);
       
  2511 /* determine number of rows */
       
  2512 
       
  2513 #define mpl_get_num_cols _glp_mpl_get_num_cols
       
  2514 int mpl_get_num_cols(MPL *mpl);
       
  2515 /* determine number of columns */
       
  2516 
       
  2517 #define mpl_get_row_name _glp_mpl_get_row_name
       
  2518 char *mpl_get_row_name(MPL *mpl, int i);
       
  2519 /* obtain row name */
       
  2520 
       
  2521 #define mpl_get_row_kind _glp_mpl_get_row_kind
       
  2522 int mpl_get_row_kind(MPL *mpl, int i);
       
  2523 /* determine row kind */
       
  2524 
       
  2525 #define mpl_get_row_bnds _glp_mpl_get_row_bnds
       
  2526 int mpl_get_row_bnds(MPL *mpl, int i, double *lb, double *ub);
       
  2527 /* obtain row bounds */
       
  2528 
       
  2529 #define mpl_get_mat_row _glp_mpl_get_mat_row
       
  2530 int mpl_get_mat_row(MPL *mpl, int i, int ndx[], double val[]);
       
  2531 /* obtain row of the constraint matrix */
       
  2532 
       
  2533 #define mpl_get_row_c0 _glp_mpl_get_row_c0
       
  2534 double mpl_get_row_c0(MPL *mpl, int i);
       
  2535 /* obtain constant term of free row */
       
  2536 
       
  2537 #define mpl_get_col_name _glp_mpl_get_col_name
       
  2538 char *mpl_get_col_name(MPL *mpl, int j);
       
  2539 /* obtain column name */
       
  2540 
       
  2541 #define mpl_get_col_kind _glp_mpl_get_col_kind
       
  2542 int mpl_get_col_kind(MPL *mpl, int j);
       
  2543 /* determine column kind */
       
  2544 
       
  2545 #define mpl_get_col_bnds _glp_mpl_get_col_bnds
       
  2546 int mpl_get_col_bnds(MPL *mpl, int j, double *lb, double *ub);
       
  2547 /* obtain column bounds */
       
  2548 
       
  2549 #define mpl_has_solve_stmt _glp_mpl_has_solve_stmt
       
  2550 int mpl_has_solve_stmt(MPL *mpl);
       
  2551 /* check if model has solve statement */
       
  2552 
       
  2553 #if 1 /* 15/V-2010 */
       
  2554 #define mpl_put_row_soln _glp_mpl_put_row_soln
       
  2555 void mpl_put_row_soln(MPL *mpl, int i, int stat, double prim,
       
  2556       double dual);
       
  2557 /* store row (constraint/objective) solution components */
       
  2558 #endif
       
  2559 
       
  2560 #if 1 /* 15/V-2010 */
       
  2561 #define mpl_put_col_soln _glp_mpl_put_col_soln
       
  2562 void mpl_put_col_soln(MPL *mpl, int j, int stat, double prim,
       
  2563       double dual);
       
  2564 /* store column (variable) solution components */
       
  2565 #endif
       
  2566 
       
  2567 #if 0 /* 15/V-2010 */
       
  2568 #define mpl_put_col_value _glp_mpl_put_col_value
       
  2569 void mpl_put_col_value(MPL *mpl, int j, double val);
       
  2570 /* store column value */
       
  2571 #endif
       
  2572 
       
  2573 #define mpl_postsolve _glp_mpl_postsolve
       
  2574 int mpl_postsolve(MPL *mpl);
       
  2575 /* postsolve model */
       
  2576 
       
  2577 #define mpl_terminate _glp_mpl_terminate
       
  2578 void mpl_terminate(MPL *mpl);
       
  2579 /* free all resources used by translator */
       
  2580 
       
  2581 #endif
       
  2582 
       
  2583 /* eof */