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