alpar@1: /* glpmpl.h (GNU MathProg translator) */ alpar@1: alpar@1: /*********************************************************************** alpar@1: * This code is part of GLPK (GNU Linear Programming Kit). alpar@1: * alpar@1: * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, alpar@1: * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, alpar@1: * Moscow Aviation Institute, Moscow, Russia. All rights reserved. alpar@1: * E-mail: . alpar@1: * alpar@1: * GLPK is free software: you can redistribute it and/or modify it alpar@1: * under the terms of the GNU General Public License as published by alpar@1: * the Free Software Foundation, either version 3 of the License, or alpar@1: * (at your option) any later version. alpar@1: * alpar@1: * GLPK is distributed in the hope that it will be useful, but WITHOUT alpar@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY alpar@1: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public alpar@1: * License for more details. alpar@1: * alpar@1: * You should have received a copy of the GNU General Public License alpar@1: * along with GLPK. If not, see . alpar@1: ***********************************************************************/ alpar@1: alpar@1: #ifndef GLPMPL_H alpar@1: #define GLPMPL_H alpar@1: alpar@1: #include "glpavl.h" alpar@1: #include "glprng.h" alpar@1: alpar@1: typedef struct MPL MPL; alpar@1: typedef char STRING; alpar@1: typedef struct SYMBOL SYMBOL; alpar@1: typedef struct TUPLE TUPLE; alpar@1: typedef struct ARRAY ELEMSET; alpar@1: typedef struct ELEMVAR ELEMVAR; alpar@1: typedef struct FORMULA FORMULA; alpar@1: typedef struct ELEMCON ELEMCON; alpar@1: typedef union VALUE VALUE; alpar@1: typedef struct ARRAY ARRAY; alpar@1: typedef struct MEMBER MEMBER; alpar@1: #if 1 alpar@1: /* many C compilers have DOMAIN declared in :( */ alpar@1: #undef DOMAIN alpar@1: #define DOMAIN DOMAIN1 alpar@1: #endif alpar@1: typedef struct DOMAIN DOMAIN; alpar@1: typedef struct DOMAIN_BLOCK DOMAIN_BLOCK; alpar@1: typedef struct DOMAIN_SLOT DOMAIN_SLOT; alpar@1: typedef struct SET SET; alpar@1: typedef struct WITHIN WITHIN; alpar@1: typedef struct GADGET GADGET; alpar@1: typedef struct PARAMETER PARAMETER; alpar@1: typedef struct CONDITION CONDITION; alpar@1: typedef struct VARIABLE VARIABLE; alpar@1: typedef struct CONSTRAINT CONSTRAINT; alpar@1: typedef struct TABLE TABLE; alpar@1: typedef struct TABARG TABARG; alpar@1: typedef struct TABFLD TABFLD; alpar@1: typedef struct TABIN TABIN; alpar@1: typedef struct TABOUT TABOUT; alpar@1: typedef struct TABDCA TABDCA; alpar@1: typedef union OPERANDS OPERANDS; alpar@1: typedef struct ARG_LIST ARG_LIST; alpar@1: typedef struct CODE CODE; alpar@1: typedef struct CHECK CHECK; alpar@1: typedef struct DISPLAY DISPLAY; alpar@1: typedef struct DISPLAY1 DISPLAY1; alpar@1: typedef struct PRINTF PRINTF; alpar@1: typedef struct PRINTF1 PRINTF1; alpar@1: typedef struct FOR FOR; alpar@1: typedef struct STATEMENT STATEMENT; alpar@1: typedef struct TUPLE SLICE; alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * TRANSLATOR DATABASE * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: #define A_BINARY 101 /* something binary */ alpar@1: #define A_CHECK 102 /* check statement */ alpar@1: #define A_CONSTRAINT 103 /* model constraint */ alpar@1: #define A_DISPLAY 104 /* display statement */ alpar@1: #define A_ELEMCON 105 /* elemental constraint/objective */ alpar@1: #define A_ELEMSET 106 /* elemental set */ alpar@1: #define A_ELEMVAR 107 /* elemental variable */ alpar@1: #define A_EXPRESSION 108 /* expression */ alpar@1: #define A_FOR 109 /* for statement */ alpar@1: #define A_FORMULA 110 /* formula */ alpar@1: #define A_INDEX 111 /* dummy index */ alpar@1: #define A_INPUT 112 /* input table */ alpar@1: #define A_INTEGER 113 /* something integer */ alpar@1: #define A_LOGICAL 114 /* something logical */ alpar@1: #define A_MAXIMIZE 115 /* objective has to be maximized */ alpar@1: #define A_MINIMIZE 116 /* objective has to be minimized */ alpar@1: #define A_NONE 117 /* nothing */ alpar@1: #define A_NUMERIC 118 /* something numeric */ alpar@1: #define A_OUTPUT 119 /* output table */ alpar@1: #define A_PARAMETER 120 /* model parameter */ alpar@1: #define A_PRINTF 121 /* printf statement */ alpar@1: #define A_SET 122 /* model set */ alpar@1: #define A_SOLVE 123 /* solve statement */ alpar@1: #define A_SYMBOLIC 124 /* something symbolic */ alpar@1: #define A_TABLE 125 /* data table */ alpar@1: #define A_TUPLE 126 /* n-tuple */ alpar@1: #define A_VARIABLE 127 /* model variable */ alpar@1: alpar@1: #define MAX_LENGTH 100 alpar@1: /* maximal length of any symbolic value (this includes symbolic names, alpar@1: numeric and string literals, and all symbolic values that may appear alpar@1: during the evaluation phase) */ alpar@1: alpar@1: #define CONTEXT_SIZE 60 alpar@1: /* size of the context queue, in characters */ alpar@1: alpar@1: #define OUTBUF_SIZE 1024 alpar@1: /* size of the output buffer, in characters */ alpar@1: alpar@1: struct MPL alpar@1: { /* translator database */ alpar@1: /*--------------------------------------------------------------*/ alpar@1: /* scanning segment */ alpar@1: int line; alpar@1: /* number of the current text line */ alpar@1: int c; alpar@1: /* the current character or EOF */ alpar@1: int token; alpar@1: /* the current token: */ alpar@1: #define T_EOF 201 /* end of file */ alpar@1: #define T_NAME 202 /* symbolic name (model section only) */ alpar@1: #define T_SYMBOL 203 /* symbol (data section only) */ alpar@1: #define T_NUMBER 204 /* numeric literal */ alpar@1: #define T_STRING 205 /* string literal */ alpar@1: #define T_AND 206 /* and && */ alpar@1: #define T_BY 207 /* by */ alpar@1: #define T_CROSS 208 /* cross */ alpar@1: #define T_DIFF 209 /* diff */ alpar@1: #define T_DIV 210 /* div */ alpar@1: #define T_ELSE 211 /* else */ alpar@1: #define T_IF 212 /* if */ alpar@1: #define T_IN 213 /* in */ alpar@1: #define T_INFINITY 214 /* Infinity */ alpar@1: #define T_INTER 215 /* inter */ alpar@1: #define T_LESS 216 /* less */ alpar@1: #define T_MOD 217 /* mod */ alpar@1: #define T_NOT 218 /* not ! */ alpar@1: #define T_OR 219 /* or || */ alpar@1: #define T_SPTP 220 /* s.t. */ alpar@1: #define T_SYMDIFF 221 /* symdiff */ alpar@1: #define T_THEN 222 /* then */ alpar@1: #define T_UNION 223 /* union */ alpar@1: #define T_WITHIN 224 /* within */ alpar@1: #define T_PLUS 225 /* + */ alpar@1: #define T_MINUS 226 /* - */ alpar@1: #define T_ASTERISK 227 /* * */ alpar@1: #define T_SLASH 228 /* / */ alpar@1: #define T_POWER 229 /* ^ ** */ alpar@1: #define T_LT 230 /* < */ alpar@1: #define T_LE 231 /* <= */ alpar@1: #define T_EQ 232 /* = == */ alpar@1: #define T_GE 233 /* >= */ alpar@1: #define T_GT 234 /* > */ alpar@1: #define T_NE 235 /* <> != */ alpar@1: #define T_CONCAT 236 /* & */ alpar@1: #define T_BAR 237 /* | */ alpar@1: #define T_POINT 238 /* . */ alpar@1: #define T_COMMA 239 /* , */ alpar@1: #define T_COLON 240 /* : */ alpar@1: #define T_SEMICOLON 241 /* ; */ alpar@1: #define T_ASSIGN 242 /* := */ alpar@1: #define T_DOTS 243 /* .. */ alpar@1: #define T_LEFT 244 /* ( */ alpar@1: #define T_RIGHT 245 /* ) */ alpar@1: #define T_LBRACKET 246 /* [ */ alpar@1: #define T_RBRACKET 247 /* ] */ alpar@1: #define T_LBRACE 248 /* { */ alpar@1: #define T_RBRACE 249 /* } */ alpar@1: #define T_APPEND 250 /* >> */ alpar@1: #define T_TILDE 251 /* ~ */ alpar@1: #define T_INPUT 252 /* <- */ alpar@1: int imlen; alpar@1: /* length of the current token */ alpar@1: char *image; /* char image[MAX_LENGTH+1]; */ alpar@1: /* image of the current token */ alpar@1: double value; alpar@1: /* value of the current token (for T_NUMBER only) */ alpar@1: int b_token; alpar@1: /* the previous token */ alpar@1: int b_imlen; alpar@1: /* length of the previous token */ alpar@1: char *b_image; /* char b_image[MAX_LENGTH+1]; */ alpar@1: /* image of the previous token */ alpar@1: double b_value; alpar@1: /* value of the previous token (if token is T_NUMBER) */ alpar@1: int f_dots; alpar@1: /* if this flag is set, the next token should be recognized as alpar@1: T_DOTS, not as T_POINT */ alpar@1: int f_scan; alpar@1: /* if this flag is set, the next token is already scanned */ alpar@1: int f_token; alpar@1: /* the next token */ alpar@1: int f_imlen; alpar@1: /* length of the next token */ alpar@1: char *f_image; /* char f_image[MAX_LENGTH+1]; */ alpar@1: /* image of the next token */ alpar@1: double f_value; alpar@1: /* value of the next token (if token is T_NUMBER) */ alpar@1: char *context; /* char context[CONTEXT_SIZE]; */ alpar@1: /* context circular queue (not null-terminated!) */ alpar@1: int c_ptr; alpar@1: /* pointer to the current position in the context queue */ alpar@1: int flag_d; alpar@1: /* if this flag is set, the data section is being processed */ alpar@1: /*--------------------------------------------------------------*/ alpar@1: /* translating segment */ alpar@1: DMP *pool; alpar@1: /* memory pool used to allocate all data instances created during alpar@1: the translation phase */ alpar@1: AVL *tree; alpar@1: /* symbolic name table: alpar@1: node.type = A_INDEX => node.link -> DOMAIN_SLOT alpar@1: node.type = A_SET => node.link -> SET alpar@1: node.type = A_PARAMETER => node.link -> PARAMETER alpar@1: node.type = A_VARIABLE => node.link -> VARIABLE alpar@1: node.type = A_CONSTRANT => node.link -> CONSTRAINT */ alpar@1: STATEMENT *model; alpar@1: /* linked list of model statements in the original order */ alpar@1: int flag_x; alpar@1: /* if this flag is set, the current token being left parenthesis alpar@1: begins a slice that allows recognizing any undeclared symbolic alpar@1: names as dummy indices; this flag is automatically reset once alpar@1: the next token has been scanned */ alpar@1: int as_within; alpar@1: /* the warning "in understood as within" has been issued */ alpar@1: int as_in; alpar@1: /* the warning "within understood as in" has been issued */ alpar@1: int as_binary; alpar@1: /* the warning "logical understood as binary" has been issued */ alpar@1: int flag_s; alpar@1: /* if this flag is set, the solve statement has been parsed */ alpar@1: /*--------------------------------------------------------------*/ alpar@1: /* common segment */ alpar@1: DMP *strings; alpar@1: /* memory pool to allocate STRING data structures */ alpar@1: DMP *symbols; alpar@1: /* memory pool to allocate SYMBOL data structures */ alpar@1: DMP *tuples; alpar@1: /* memory pool to allocate TUPLE data structures */ alpar@1: DMP *arrays; alpar@1: /* memory pool to allocate ARRAY data structures */ alpar@1: DMP *members; alpar@1: /* memory pool to allocate MEMBER data structures */ alpar@1: DMP *elemvars; alpar@1: /* memory pool to allocate ELEMVAR data structures */ alpar@1: DMP *formulae; alpar@1: /* memory pool to allocate FORMULA data structures */ alpar@1: DMP *elemcons; alpar@1: /* memory pool to allocate ELEMCON data structures */ alpar@1: ARRAY *a_list; alpar@1: /* linked list of all arrays in the database */ alpar@1: char *sym_buf; /* char sym_buf[255+1]; */ alpar@1: /* working buffer used by the routine format_symbol */ alpar@1: char *tup_buf; /* char tup_buf[255+1]; */ alpar@1: /* working buffer used by the routine format_tuple */ alpar@1: /*--------------------------------------------------------------*/ alpar@1: /* generating/postsolving segment */ alpar@1: RNG *rand; alpar@1: /* pseudo-random number generator */ alpar@1: int flag_p; alpar@1: /* if this flag is set, the postsolving phase is in effect */ alpar@1: STATEMENT *stmt; alpar@1: /* model statement being currently executed */ alpar@1: TABDCA *dca; alpar@1: /* pointer to table driver communication area for table statement alpar@1: currently executed */ alpar@1: int m; alpar@1: /* number of rows in the problem, m >= 0 */ alpar@1: int n; alpar@1: /* number of columns in the problem, n >= 0 */ alpar@1: ELEMCON **row; /* ELEMCON *row[1+m]; */ alpar@1: /* row[0] is not used; alpar@1: row[i] is elemental constraint or objective, which corresponds alpar@1: to i-th row of the problem, 1 <= i <= m */ alpar@1: ELEMVAR **col; /* ELEMVAR *col[1+n]; */ alpar@1: /* col[0] is not used; alpar@1: col[j] is elemental variable, which corresponds to j-th column alpar@1: of the problem, 1 <= j <= n */ alpar@1: /*--------------------------------------------------------------*/ alpar@1: /* input/output segment */ alpar@1: XFILE *in_fp; alpar@1: /* stream assigned to the input text file */ alpar@1: char *in_file; alpar@1: /* name of the input text file */ alpar@1: XFILE *out_fp; alpar@1: /* stream assigned to the output text file used to write all data alpar@1: produced by display and printf statements; NULL means the data alpar@1: should be sent to stdout via the routine xprintf */ alpar@1: char *out_file; alpar@1: /* name of the output text file */ alpar@1: #if 0 /* 08/XI-2009 */ alpar@1: char *out_buf; /* char out_buf[OUTBUF_SIZE] */ alpar@1: /* buffer to accumulate output data */ alpar@1: int out_cnt; alpar@1: /* count of data bytes stored in the output buffer */ alpar@1: #endif alpar@1: XFILE *prt_fp; alpar@1: /* stream assigned to the print text file; may be NULL */ alpar@1: char *prt_file; alpar@1: /* name of the output print file */ alpar@1: /*--------------------------------------------------------------*/ alpar@1: /* solver interface segment */ alpar@1: jmp_buf jump; alpar@1: /* jump address for non-local go to in case of error */ alpar@1: int phase; alpar@1: /* phase of processing: alpar@1: 0 - database is being or has been initialized alpar@1: 1 - model section is being or has been read alpar@1: 2 - data section is being or has been read alpar@1: 3 - model is being or has been generated/postsolved alpar@1: 4 - model processing error has occurred */ alpar@1: char *mod_file; alpar@1: /* name of the input text file, which contains model section */ alpar@1: char *mpl_buf; /* char mpl_buf[255+1]; */ alpar@1: /* working buffer used by some interface routines */ alpar@1: }; alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * PROCESSING MODEL SECTION * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: #define alloc(type) ((type *)dmp_get_atomv(mpl->pool, sizeof(type))) alpar@1: /* allocate atom of given type */ alpar@1: alpar@1: #define enter_context _glp_mpl_enter_context alpar@1: void enter_context(MPL *mpl); alpar@1: /* enter current token into context queue */ alpar@1: alpar@1: #define print_context _glp_mpl_print_context alpar@1: void print_context(MPL *mpl); alpar@1: /* print current content of context queue */ alpar@1: alpar@1: #define get_char _glp_mpl_get_char alpar@1: void get_char(MPL *mpl); alpar@1: /* scan next character from input text file */ alpar@1: alpar@1: #define append_char _glp_mpl_append_char alpar@1: void append_char(MPL *mpl); alpar@1: /* append character to current token */ alpar@1: alpar@1: #define get_token _glp_mpl_get_token alpar@1: void get_token(MPL *mpl); alpar@1: /* scan next token from input text file */ alpar@1: alpar@1: #define unget_token _glp_mpl_unget_token alpar@1: void unget_token(MPL *mpl); alpar@1: /* return current token back to input stream */ alpar@1: alpar@1: #define is_keyword _glp_mpl_is_keyword alpar@1: int is_keyword(MPL *mpl, char *keyword); alpar@1: /* check if current token is given non-reserved keyword */ alpar@1: alpar@1: #define is_reserved _glp_mpl_is_reserved alpar@1: int is_reserved(MPL *mpl); alpar@1: /* check if current token is reserved keyword */ alpar@1: alpar@1: #define make_code _glp_mpl_make_code alpar@1: CODE *make_code(MPL *mpl, int op, OPERANDS *arg, int type, int dim); alpar@1: /* generate pseudo-code (basic routine) */ alpar@1: alpar@1: #define make_unary _glp_mpl_make_unary alpar@1: CODE *make_unary(MPL *mpl, int op, CODE *x, int type, int dim); alpar@1: /* generate pseudo-code for unary operation */ alpar@1: alpar@1: #define make_binary _glp_mpl_make_binary alpar@1: CODE *make_binary(MPL *mpl, int op, CODE *x, CODE *y, int type, alpar@1: int dim); alpar@1: /* generate pseudo-code for binary operation */ alpar@1: alpar@1: #define make_ternary _glp_mpl_make_ternary alpar@1: CODE *make_ternary(MPL *mpl, int op, CODE *x, CODE *y, CODE *z, alpar@1: int type, int dim); alpar@1: /* generate pseudo-code for ternary operation */ alpar@1: alpar@1: #define numeric_literal _glp_mpl_numeric_literal alpar@1: CODE *numeric_literal(MPL *mpl); alpar@1: /* parse reference to numeric literal */ alpar@1: alpar@1: #define string_literal _glp_mpl_string_literal alpar@1: CODE *string_literal(MPL *mpl); alpar@1: /* parse reference to string literal */ alpar@1: alpar@1: #define create_arg_list _glp_mpl_create_arg_list alpar@1: ARG_LIST *create_arg_list(MPL *mpl); alpar@1: /* create empty operands list */ alpar@1: alpar@1: #define expand_arg_list _glp_mpl_expand_arg_list alpar@1: ARG_LIST *expand_arg_list(MPL *mpl, ARG_LIST *list, CODE *x); alpar@1: /* append operand to operands list */ alpar@1: alpar@1: #define arg_list_len _glp_mpl_arg_list_len alpar@1: int arg_list_len(MPL *mpl, ARG_LIST *list); alpar@1: /* determine length of operands list */ alpar@1: alpar@1: #define subscript_list _glp_mpl_subscript_list alpar@1: ARG_LIST *subscript_list(MPL *mpl); alpar@1: /* parse subscript list */ alpar@1: alpar@1: #define object_reference _glp_mpl_object_reference alpar@1: CODE *object_reference(MPL *mpl); alpar@1: /* parse reference to named object */ alpar@1: alpar@1: #define numeric_argument _glp_mpl_numeric_argument alpar@1: CODE *numeric_argument(MPL *mpl, char *func); alpar@1: /* parse argument passed to built-in function */ alpar@1: alpar@1: #define symbolic_argument _glp_mpl_symbolic_argument alpar@1: CODE *symbolic_argument(MPL *mpl, char *func); alpar@1: alpar@1: #define elemset_argument _glp_mpl_elemset_argument alpar@1: CODE *elemset_argument(MPL *mpl, char *func); alpar@1: alpar@1: #define function_reference _glp_mpl_function_reference alpar@1: CODE *function_reference(MPL *mpl); alpar@1: /* parse reference to built-in function */ alpar@1: alpar@1: #define create_domain _glp_mpl_create_domain alpar@1: DOMAIN *create_domain(MPL *mpl); alpar@1: /* create empty domain */ alpar@1: alpar@1: #define create_block _glp_mpl_create_block alpar@1: DOMAIN_BLOCK *create_block(MPL *mpl); alpar@1: /* create empty domain block */ alpar@1: alpar@1: #define append_block _glp_mpl_append_block alpar@1: void append_block(MPL *mpl, DOMAIN *domain, DOMAIN_BLOCK *block); alpar@1: /* append domain block to specified domain */ alpar@1: alpar@1: #define append_slot _glp_mpl_append_slot alpar@1: DOMAIN_SLOT *append_slot(MPL *mpl, DOMAIN_BLOCK *block, char *name, alpar@1: CODE *code); alpar@1: /* create and append new slot to domain block */ alpar@1: alpar@1: #define expression_list _glp_mpl_expression_list alpar@1: CODE *expression_list(MPL *mpl); alpar@1: /* parse expression list */ alpar@1: alpar@1: #define literal_set _glp_mpl_literal_set alpar@1: CODE *literal_set(MPL *mpl, CODE *code); alpar@1: /* parse literal set */ alpar@1: alpar@1: #define indexing_expression _glp_mpl_indexing_expression alpar@1: DOMAIN *indexing_expression(MPL *mpl); alpar@1: /* parse indexing expression */ alpar@1: alpar@1: #define close_scope _glp_mpl_close_scope alpar@1: void close_scope(MPL *mpl, DOMAIN *domain); alpar@1: /* close scope of indexing expression */ alpar@1: alpar@1: #define iterated_expression _glp_mpl_iterated_expression alpar@1: CODE *iterated_expression(MPL *mpl); alpar@1: /* parse iterated expression */ alpar@1: alpar@1: #define domain_arity _glp_mpl_domain_arity alpar@1: int domain_arity(MPL *mpl, DOMAIN *domain); alpar@1: /* determine arity of domain */ alpar@1: alpar@1: #define set_expression _glp_mpl_set_expression alpar@1: CODE *set_expression(MPL *mpl); alpar@1: /* parse set expression */ alpar@1: alpar@1: #define branched_expression _glp_mpl_branched_expression alpar@1: CODE *branched_expression(MPL *mpl); alpar@1: /* parse conditional expression */ alpar@1: alpar@1: #define primary_expression _glp_mpl_primary_expression alpar@1: CODE *primary_expression(MPL *mpl); alpar@1: /* parse primary expression */ alpar@1: alpar@1: #define error_preceding _glp_mpl_error_preceding alpar@1: void error_preceding(MPL *mpl, char *opstr); alpar@1: /* raise error if preceding operand has wrong type */ alpar@1: alpar@1: #define error_following _glp_mpl_error_following alpar@1: void error_following(MPL *mpl, char *opstr); alpar@1: /* raise error if following operand has wrong type */ alpar@1: alpar@1: #define error_dimension _glp_mpl_error_dimension alpar@1: void error_dimension(MPL *mpl, char *opstr, int dim1, int dim2); alpar@1: /* raise error if operands have different dimension */ alpar@1: alpar@1: #define expression_0 _glp_mpl_expression_0 alpar@1: CODE *expression_0(MPL *mpl); alpar@1: /* parse expression of level 0 */ alpar@1: alpar@1: #define expression_1 _glp_mpl_expression_1 alpar@1: CODE *expression_1(MPL *mpl); alpar@1: /* parse expression of level 1 */ alpar@1: alpar@1: #define expression_2 _glp_mpl_expression_2 alpar@1: CODE *expression_2(MPL *mpl); alpar@1: /* parse expression of level 2 */ alpar@1: alpar@1: #define expression_3 _glp_mpl_expression_3 alpar@1: CODE *expression_3(MPL *mpl); alpar@1: /* parse expression of level 3 */ alpar@1: alpar@1: #define expression_4 _glp_mpl_expression_4 alpar@1: CODE *expression_4(MPL *mpl); alpar@1: /* parse expression of level 4 */ alpar@1: alpar@1: #define expression_5 _glp_mpl_expression_5 alpar@1: CODE *expression_5(MPL *mpl); alpar@1: /* parse expression of level 5 */ alpar@1: alpar@1: #define expression_6 _glp_mpl_expression_6 alpar@1: CODE *expression_6(MPL *mpl); alpar@1: /* parse expression of level 6 */ alpar@1: alpar@1: #define expression_7 _glp_mpl_expression_7 alpar@1: CODE *expression_7(MPL *mpl); alpar@1: /* parse expression of level 7 */ alpar@1: alpar@1: #define expression_8 _glp_mpl_expression_8 alpar@1: CODE *expression_8(MPL *mpl); alpar@1: /* parse expression of level 8 */ alpar@1: alpar@1: #define expression_9 _glp_mpl_expression_9 alpar@1: CODE *expression_9(MPL *mpl); alpar@1: /* parse expression of level 9 */ alpar@1: alpar@1: #define expression_10 _glp_mpl_expression_10 alpar@1: CODE *expression_10(MPL *mpl); alpar@1: /* parse expression of level 10 */ alpar@1: alpar@1: #define expression_11 _glp_mpl_expression_11 alpar@1: CODE *expression_11(MPL *mpl); alpar@1: /* parse expression of level 11 */ alpar@1: alpar@1: #define expression_12 _glp_mpl_expression_12 alpar@1: CODE *expression_12(MPL *mpl); alpar@1: /* parse expression of level 12 */ alpar@1: alpar@1: #define expression_13 _glp_mpl_expression_13 alpar@1: CODE *expression_13(MPL *mpl); alpar@1: /* parse expression of level 13 */ alpar@1: alpar@1: #define set_statement _glp_mpl_set_statement alpar@1: SET *set_statement(MPL *mpl); alpar@1: /* parse set statement */ alpar@1: alpar@1: #define parameter_statement _glp_mpl_parameter_statement alpar@1: PARAMETER *parameter_statement(MPL *mpl); alpar@1: /* parse parameter statement */ alpar@1: alpar@1: #define variable_statement _glp_mpl_variable_statement alpar@1: VARIABLE *variable_statement(MPL *mpl); alpar@1: /* parse variable statement */ alpar@1: alpar@1: #define constraint_statement _glp_mpl_constraint_statement alpar@1: CONSTRAINT *constraint_statement(MPL *mpl); alpar@1: /* parse constraint statement */ alpar@1: alpar@1: #define objective_statement _glp_mpl_objective_statement alpar@1: CONSTRAINT *objective_statement(MPL *mpl); alpar@1: /* parse objective statement */ alpar@1: alpar@1: #define table_statement _glp_mpl_table_statement alpar@1: TABLE *table_statement(MPL *mpl); alpar@1: /* parse table statement */ alpar@1: alpar@1: #define solve_statement _glp_mpl_solve_statement alpar@1: void *solve_statement(MPL *mpl); alpar@1: /* parse solve statement */ alpar@1: alpar@1: #define check_statement _glp_mpl_check_statement alpar@1: CHECK *check_statement(MPL *mpl); alpar@1: /* parse check statement */ alpar@1: alpar@1: #define display_statement _glp_mpl_display_statement alpar@1: DISPLAY *display_statement(MPL *mpl); alpar@1: /* parse display statement */ alpar@1: alpar@1: #define printf_statement _glp_mpl_printf_statement alpar@1: PRINTF *printf_statement(MPL *mpl); alpar@1: /* parse printf statement */ alpar@1: alpar@1: #define for_statement _glp_mpl_for_statement alpar@1: FOR *for_statement(MPL *mpl); alpar@1: /* parse for statement */ alpar@1: alpar@1: #define end_statement _glp_mpl_end_statement alpar@1: void end_statement(MPL *mpl); alpar@1: /* parse end statement */ alpar@1: alpar@1: #define simple_statement _glp_mpl_simple_statement alpar@1: STATEMENT *simple_statement(MPL *mpl, int spec); alpar@1: /* parse simple statement */ alpar@1: alpar@1: #define model_section _glp_mpl_model_section alpar@1: void model_section(MPL *mpl); alpar@1: /* parse model section */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * PROCESSING DATA SECTION * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: #if 2 + 2 == 5 alpar@1: struct SLICE /* see TUPLE */ alpar@1: { /* component of slice; the slice itself is associated with its alpar@1: first component; slices are similar to n-tuples with exception alpar@1: that some slice components (which are indicated by asterisks) alpar@1: don't refer to any symbols */ alpar@1: SYMBOL *sym; alpar@1: /* symbol, which this component refers to; can be NULL */ alpar@1: SLICE *next; alpar@1: /* the next component of slice */ alpar@1: }; alpar@1: #endif alpar@1: alpar@1: #define create_slice _glp_mpl_create_slice alpar@1: SLICE *create_slice(MPL *mpl); alpar@1: /* create slice */ alpar@1: alpar@1: #define expand_slice _glp_mpl_expand_slice alpar@1: SLICE *expand_slice alpar@1: ( MPL *mpl, alpar@1: SLICE *slice, /* destroyed */ alpar@1: SYMBOL *sym /* destroyed */ alpar@1: ); alpar@1: /* append new component to slice */ alpar@1: alpar@1: #define slice_dimen _glp_mpl_slice_dimen alpar@1: int slice_dimen alpar@1: ( MPL *mpl, alpar@1: SLICE *slice /* not changed */ alpar@1: ); alpar@1: /* determine dimension of slice */ alpar@1: alpar@1: #define slice_arity _glp_mpl_slice_arity alpar@1: int slice_arity alpar@1: ( MPL *mpl, alpar@1: SLICE *slice /* not changed */ alpar@1: ); alpar@1: /* determine arity of slice */ alpar@1: alpar@1: #define fake_slice _glp_mpl_fake_slice alpar@1: SLICE *fake_slice(MPL *mpl, int dim); alpar@1: /* create fake slice of all asterisks */ alpar@1: alpar@1: #define delete_slice _glp_mpl_delete_slice alpar@1: void delete_slice alpar@1: ( MPL *mpl, alpar@1: SLICE *slice /* destroyed */ alpar@1: ); alpar@1: /* delete slice */ alpar@1: alpar@1: #define is_number _glp_mpl_is_number alpar@1: int is_number(MPL *mpl); alpar@1: /* check if current token is number */ alpar@1: alpar@1: #define is_symbol _glp_mpl_is_symbol alpar@1: int is_symbol(MPL *mpl); alpar@1: /* check if current token is symbol */ alpar@1: alpar@1: #define is_literal _glp_mpl_is_literal alpar@1: int is_literal(MPL *mpl, char *literal); alpar@1: /* check if current token is given symbolic literal */ alpar@1: alpar@1: #define read_number _glp_mpl_read_number alpar@1: double read_number(MPL *mpl); alpar@1: /* read number */ alpar@1: alpar@1: #define read_symbol _glp_mpl_read_symbol alpar@1: SYMBOL *read_symbol(MPL *mpl); alpar@1: /* read symbol */ alpar@1: alpar@1: #define read_slice _glp_mpl_read_slice alpar@1: SLICE *read_slice alpar@1: ( MPL *mpl, alpar@1: char *name, /* not changed */ alpar@1: int dim alpar@1: ); alpar@1: /* read slice */ alpar@1: alpar@1: #define select_set _glp_mpl_select_set alpar@1: SET *select_set alpar@1: ( MPL *mpl, alpar@1: char *name /* not changed */ alpar@1: ); alpar@1: /* select set to saturate it with elemental sets */ alpar@1: alpar@1: #define simple_format _glp_mpl_simple_format alpar@1: void simple_format alpar@1: ( MPL *mpl, alpar@1: SET *set, /* not changed */ alpar@1: MEMBER *memb, /* modified */ alpar@1: SLICE *slice /* not changed */ alpar@1: ); alpar@1: /* read set data block in simple format */ alpar@1: alpar@1: #define matrix_format _glp_mpl_matrix_format alpar@1: void matrix_format alpar@1: ( MPL *mpl, alpar@1: SET *set, /* not changed */ alpar@1: MEMBER *memb, /* modified */ alpar@1: SLICE *slice, /* not changed */ alpar@1: int tr alpar@1: ); alpar@1: /* read set data block in matrix format */ alpar@1: alpar@1: #define set_data _glp_mpl_set_data alpar@1: void set_data(MPL *mpl); alpar@1: /* read set data */ alpar@1: alpar@1: #define select_parameter _glp_mpl_select_parameter alpar@1: PARAMETER *select_parameter alpar@1: ( MPL *mpl, alpar@1: char *name /* not changed */ alpar@1: ); alpar@1: /* select parameter to saturate it with data */ alpar@1: alpar@1: #define set_default _glp_mpl_set_default alpar@1: void set_default alpar@1: ( MPL *mpl, alpar@1: PARAMETER *par, /* not changed */ alpar@1: SYMBOL *altval /* destroyed */ alpar@1: ); alpar@1: /* set default parameter value */ alpar@1: alpar@1: #define read_value _glp_mpl_read_value alpar@1: MEMBER *read_value alpar@1: ( MPL *mpl, alpar@1: PARAMETER *par, /* not changed */ alpar@1: TUPLE *tuple /* destroyed */ alpar@1: ); alpar@1: /* read value and assign it to parameter member */ alpar@1: alpar@1: #define plain_format _glp_mpl_plain_format alpar@1: void plain_format alpar@1: ( MPL *mpl, alpar@1: PARAMETER *par, /* not changed */ alpar@1: SLICE *slice /* not changed */ alpar@1: ); alpar@1: /* read parameter data block in plain format */ alpar@1: alpar@1: #define tabular_format _glp_mpl_tabular_format alpar@1: void tabular_format alpar@1: ( MPL *mpl, alpar@1: PARAMETER *par, /* not changed */ alpar@1: SLICE *slice, /* not changed */ alpar@1: int tr alpar@1: ); alpar@1: /* read parameter data block in tabular format */ alpar@1: alpar@1: #define tabbing_format _glp_mpl_tabbing_format alpar@1: void tabbing_format alpar@1: ( MPL *mpl, alpar@1: SYMBOL *altval /* not changed */ alpar@1: ); alpar@1: /* read parameter data block in tabbing format */ alpar@1: alpar@1: #define parameter_data _glp_mpl_parameter_data alpar@1: void parameter_data(MPL *mpl); alpar@1: /* read parameter data */ alpar@1: alpar@1: #define data_section _glp_mpl_data_section alpar@1: void data_section(MPL *mpl); alpar@1: /* read data section */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * FLOATING-POINT NUMBERS * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: #define fp_add _glp_mpl_fp_add alpar@1: double fp_add(MPL *mpl, double x, double y); alpar@1: /* floating-point addition */ alpar@1: alpar@1: #define fp_sub _glp_mpl_fp_sub alpar@1: double fp_sub(MPL *mpl, double x, double y); alpar@1: /* floating-point subtraction */ alpar@1: alpar@1: #define fp_less _glp_mpl_fp_less alpar@1: double fp_less(MPL *mpl, double x, double y); alpar@1: /* floating-point non-negative subtraction */ alpar@1: alpar@1: #define fp_mul _glp_mpl_fp_mul alpar@1: double fp_mul(MPL *mpl, double x, double y); alpar@1: /* floating-point multiplication */ alpar@1: alpar@1: #define fp_div _glp_mpl_fp_div alpar@1: double fp_div(MPL *mpl, double x, double y); alpar@1: /* floating-point division */ alpar@1: alpar@1: #define fp_idiv _glp_mpl_fp_idiv alpar@1: double fp_idiv(MPL *mpl, double x, double y); alpar@1: /* floating-point quotient of exact division */ alpar@1: alpar@1: #define fp_mod _glp_mpl_fp_mod alpar@1: double fp_mod(MPL *mpl, double x, double y); alpar@1: /* floating-point remainder of exact division */ alpar@1: alpar@1: #define fp_power _glp_mpl_fp_power alpar@1: double fp_power(MPL *mpl, double x, double y); alpar@1: /* floating-point exponentiation (raise to power) */ alpar@1: alpar@1: #define fp_exp _glp_mpl_fp_exp alpar@1: double fp_exp(MPL *mpl, double x); alpar@1: /* floating-point base-e exponential */ alpar@1: alpar@1: #define fp_log _glp_mpl_fp_log alpar@1: double fp_log(MPL *mpl, double x); alpar@1: /* floating-point natural logarithm */ alpar@1: alpar@1: #define fp_log10 _glp_mpl_fp_log10 alpar@1: double fp_log10(MPL *mpl, double x); alpar@1: /* floating-point common (decimal) logarithm */ alpar@1: alpar@1: #define fp_sqrt _glp_mpl_fp_sqrt alpar@1: double fp_sqrt(MPL *mpl, double x); alpar@1: /* floating-point square root */ alpar@1: alpar@1: #define fp_sin _glp_mpl_fp_sin alpar@1: double fp_sin(MPL *mpl, double x); alpar@1: /* floating-point trigonometric sine */ alpar@1: alpar@1: #define fp_cos _glp_mpl_fp_cos alpar@1: double fp_cos(MPL *mpl, double x); alpar@1: /* floating-point trigonometric cosine */ alpar@1: alpar@1: #define fp_atan _glp_mpl_fp_atan alpar@1: double fp_atan(MPL *mpl, double x); alpar@1: /* floating-point trigonometric arctangent */ alpar@1: alpar@1: #define fp_atan2 _glp_mpl_fp_atan2 alpar@1: double fp_atan2(MPL *mpl, double y, double x); alpar@1: /* floating-point trigonometric arctangent */ alpar@1: alpar@1: #define fp_round _glp_mpl_fp_round alpar@1: double fp_round(MPL *mpl, double x, double n); alpar@1: /* round floating-point value to n fractional digits */ alpar@1: alpar@1: #define fp_trunc _glp_mpl_fp_trunc alpar@1: double fp_trunc(MPL *mpl, double x, double n); alpar@1: /* truncate floating-point value to n fractional digits */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * PSEUDO-RANDOM NUMBER GENERATORS * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: #define fp_irand224 _glp_mpl_fp_irand224 alpar@1: double fp_irand224(MPL *mpl); alpar@1: /* pseudo-random integer in the range [0, 2^24) */ alpar@1: alpar@1: #define fp_uniform01 _glp_mpl_fp_uniform01 alpar@1: double fp_uniform01(MPL *mpl); alpar@1: /* pseudo-random number in the range [0, 1) */ alpar@1: alpar@1: #define fp_uniform _glp_mpl_uniform alpar@1: double fp_uniform(MPL *mpl, double a, double b); alpar@1: /* pseudo-random number in the range [a, b) */ alpar@1: alpar@1: #define fp_normal01 _glp_mpl_fp_normal01 alpar@1: double fp_normal01(MPL *mpl); alpar@1: /* Gaussian random variate with mu = 0 and sigma = 1 */ alpar@1: alpar@1: #define fp_normal _glp_mpl_fp_normal alpar@1: double fp_normal(MPL *mpl, double mu, double sigma); alpar@1: /* Gaussian random variate with specified mu and sigma */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * DATE/TIME * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: #define fn_gmtime _glp_mpl_fn_gmtime alpar@1: double fn_gmtime(MPL *mpl); alpar@1: /* obtain the current calendar time (UTC) */ alpar@1: alpar@1: #define fn_str2time _glp_mpl_fn_str2time alpar@1: double fn_str2time(MPL *mpl, const char *str, const char *fmt); alpar@1: /* convert character string to the calendar time */ alpar@1: alpar@1: #define fn_time2str _glp_mpl_fn_time2str alpar@1: void fn_time2str(MPL *mpl, char *str, double t, const char *fmt); alpar@1: /* convert the calendar time to character string */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * CHARACTER STRINGS * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: #define create_string _glp_mpl_create_string alpar@1: STRING *create_string alpar@1: ( MPL *mpl, alpar@1: char buf[MAX_LENGTH+1] /* not changed */ alpar@1: ); alpar@1: /* create character string */ alpar@1: alpar@1: #define copy_string _glp_mpl_copy_string alpar@1: STRING *copy_string alpar@1: ( MPL *mpl, alpar@1: STRING *str /* not changed */ alpar@1: ); alpar@1: /* make copy of character string */ alpar@1: alpar@1: #define compare_strings _glp_mpl_compare_strings alpar@1: int compare_strings alpar@1: ( MPL *mpl, alpar@1: STRING *str1, /* not changed */ alpar@1: STRING *str2 /* not changed */ alpar@1: ); alpar@1: /* compare one character string with another */ alpar@1: alpar@1: #define fetch_string _glp_mpl_fetch_string alpar@1: char *fetch_string alpar@1: ( MPL *mpl, alpar@1: STRING *str, /* not changed */ alpar@1: char buf[MAX_LENGTH+1] /* modified */ alpar@1: ); alpar@1: /* extract content of character string */ alpar@1: alpar@1: #define delete_string _glp_mpl_delete_string alpar@1: void delete_string alpar@1: ( MPL *mpl, alpar@1: STRING *str /* destroyed */ alpar@1: ); alpar@1: /* delete character string */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * SYMBOLS * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: struct SYMBOL alpar@1: { /* symbol (numeric or abstract quantity) */ alpar@1: double num; alpar@1: /* numeric value of symbol (used only if str == NULL) */ alpar@1: STRING *str; alpar@1: /* abstract value of symbol (used only if str != NULL) */ alpar@1: }; alpar@1: alpar@1: #define create_symbol_num _glp_mpl_create_symbol_num alpar@1: SYMBOL *create_symbol_num(MPL *mpl, double num); alpar@1: /* create symbol of numeric type */ alpar@1: alpar@1: #define create_symbol_str _glp_mpl_create_symbol_str alpar@1: SYMBOL *create_symbol_str alpar@1: ( MPL *mpl, alpar@1: STRING *str /* destroyed */ alpar@1: ); alpar@1: /* create symbol of abstract type */ alpar@1: alpar@1: #define copy_symbol _glp_mpl_copy_symbol alpar@1: SYMBOL *copy_symbol alpar@1: ( MPL *mpl, alpar@1: SYMBOL *sym /* not changed */ alpar@1: ); alpar@1: /* make copy of symbol */ alpar@1: alpar@1: #define compare_symbols _glp_mpl_compare_symbols alpar@1: int compare_symbols alpar@1: ( MPL *mpl, alpar@1: SYMBOL *sym1, /* not changed */ alpar@1: SYMBOL *sym2 /* not changed */ alpar@1: ); alpar@1: /* compare one symbol with another */ alpar@1: alpar@1: #define delete_symbol _glp_mpl_delete_symbol alpar@1: void delete_symbol alpar@1: ( MPL *mpl, alpar@1: SYMBOL *sym /* destroyed */ alpar@1: ); alpar@1: /* delete symbol */ alpar@1: alpar@1: #define format_symbol _glp_mpl_format_symbol alpar@1: char *format_symbol alpar@1: ( MPL *mpl, alpar@1: SYMBOL *sym /* not changed */ alpar@1: ); alpar@1: /* format symbol for displaying or printing */ alpar@1: alpar@1: #define concat_symbols _glp_mpl_concat_symbols alpar@1: SYMBOL *concat_symbols alpar@1: ( MPL *mpl, alpar@1: SYMBOL *sym1, /* destroyed */ alpar@1: SYMBOL *sym2 /* destroyed */ alpar@1: ); alpar@1: /* concatenate one symbol with another */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * N-TUPLES * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: struct TUPLE alpar@1: { /* component of n-tuple; the n-tuple itself is associated with alpar@1: its first component; (note that 0-tuple has no components) */ alpar@1: SYMBOL *sym; alpar@1: /* symbol, which the component refers to; cannot be NULL */ alpar@1: TUPLE *next; alpar@1: /* the next component of n-tuple */ alpar@1: }; alpar@1: alpar@1: #define create_tuple _glp_mpl_create_tuple alpar@1: TUPLE *create_tuple(MPL *mpl); alpar@1: /* create n-tuple */ alpar@1: alpar@1: #define expand_tuple _glp_mpl_expand_tuple alpar@1: TUPLE *expand_tuple alpar@1: ( MPL *mpl, alpar@1: TUPLE *tuple, /* destroyed */ alpar@1: SYMBOL *sym /* destroyed */ alpar@1: ); alpar@1: /* append symbol to n-tuple */ alpar@1: alpar@1: #define tuple_dimen _glp_mpl_tuple_dimen alpar@1: int tuple_dimen alpar@1: ( MPL *mpl, alpar@1: TUPLE *tuple /* not changed */ alpar@1: ); alpar@1: /* determine dimension of n-tuple */ alpar@1: alpar@1: #define copy_tuple _glp_mpl_copy_tuple alpar@1: TUPLE *copy_tuple alpar@1: ( MPL *mpl, alpar@1: TUPLE *tuple /* not changed */ alpar@1: ); alpar@1: /* make copy of n-tuple */ alpar@1: alpar@1: #define compare_tuples _glp_mpl_compare_tuples alpar@1: int compare_tuples alpar@1: ( MPL *mpl, alpar@1: TUPLE *tuple1, /* not changed */ alpar@1: TUPLE *tuple2 /* not changed */ alpar@1: ); alpar@1: /* compare one n-tuple with another */ alpar@1: alpar@1: #define build_subtuple _glp_mpl_build_subtuple alpar@1: TUPLE *build_subtuple alpar@1: ( MPL *mpl, alpar@1: TUPLE *tuple, /* not changed */ alpar@1: int dim alpar@1: ); alpar@1: /* build subtuple of given n-tuple */ alpar@1: alpar@1: #define delete_tuple _glp_mpl_delete_tuple alpar@1: void delete_tuple alpar@1: ( MPL *mpl, alpar@1: TUPLE *tuple /* destroyed */ alpar@1: ); alpar@1: /* delete n-tuple */ alpar@1: alpar@1: #define format_tuple _glp_mpl_format_tuple alpar@1: char *format_tuple alpar@1: ( MPL *mpl, alpar@1: int c, alpar@1: TUPLE *tuple /* not changed */ alpar@1: ); alpar@1: /* format n-tuple for displaying or printing */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * ELEMENTAL SETS * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: #if 2 + 2 == 5 alpar@1: struct ELEMSET /* see ARRAY */ alpar@1: { /* elemental set of n-tuples; formally it is a "value" assigned alpar@1: to members of model sets (like numbers and symbols, which are alpar@1: values assigned to members of model parameters); note that a alpar@1: simple model set is not an elemental set, it is 0-dimensional alpar@1: array, the only member of which (if it exists) is assigned an alpar@1: elemental set */ alpar@1: #endif alpar@1: alpar@1: #define create_elemset _glp_mpl_create_elemset alpar@1: ELEMSET *create_elemset(MPL *mpl, int dim); alpar@1: /* create elemental set */ alpar@1: alpar@1: #define find_tuple _glp_mpl_find_tuple alpar@1: MEMBER *find_tuple alpar@1: ( MPL *mpl, alpar@1: ELEMSET *set, /* not changed */ alpar@1: TUPLE *tuple /* not changed */ alpar@1: ); alpar@1: /* check if elemental set contains given n-tuple */ alpar@1: alpar@1: #define add_tuple _glp_mpl_add_tuple alpar@1: MEMBER *add_tuple alpar@1: ( MPL *mpl, alpar@1: ELEMSET *set, /* modified */ alpar@1: TUPLE *tuple /* destroyed */ alpar@1: ); alpar@1: /* add new n-tuple to elemental set */ alpar@1: alpar@1: #define check_then_add _glp_mpl_check_then_add alpar@1: MEMBER *check_then_add alpar@1: ( MPL *mpl, alpar@1: ELEMSET *set, /* modified */ alpar@1: TUPLE *tuple /* destroyed */ alpar@1: ); alpar@1: /* check and add new n-tuple to elemental set */ alpar@1: alpar@1: #define copy_elemset _glp_mpl_copy_elemset alpar@1: ELEMSET *copy_elemset alpar@1: ( MPL *mpl, alpar@1: ELEMSET *set /* not changed */ alpar@1: ); alpar@1: /* make copy of elemental set */ alpar@1: alpar@1: #define delete_elemset _glp_mpl_delete_elemset alpar@1: void delete_elemset alpar@1: ( MPL *mpl, alpar@1: ELEMSET *set /* destroyed */ alpar@1: ); alpar@1: /* delete elemental set */ alpar@1: alpar@1: #define arelset_size _glp_mpl_arelset_size alpar@1: int arelset_size(MPL *mpl, double t0, double tf, double dt); alpar@1: /* compute size of "arithmetic" elemental set */ alpar@1: alpar@1: #define arelset_member _glp_mpl_arelset_member alpar@1: double arelset_member(MPL *mpl, double t0, double tf, double dt, int j); alpar@1: /* compute member of "arithmetic" elemental set */ alpar@1: alpar@1: #define create_arelset _glp_mpl_create_arelset alpar@1: ELEMSET *create_arelset(MPL *mpl, double t0, double tf, double dt); alpar@1: /* create "arithmetic" elemental set */ alpar@1: alpar@1: #define set_union _glp_mpl_set_union alpar@1: ELEMSET *set_union alpar@1: ( MPL *mpl, alpar@1: ELEMSET *X, /* destroyed */ alpar@1: ELEMSET *Y /* destroyed */ alpar@1: ); alpar@1: /* union of two elemental sets */ alpar@1: alpar@1: #define set_diff _glp_mpl_set_diff alpar@1: ELEMSET *set_diff alpar@1: ( MPL *mpl, alpar@1: ELEMSET *X, /* destroyed */ alpar@1: ELEMSET *Y /* destroyed */ alpar@1: ); alpar@1: /* difference between two elemental sets */ alpar@1: alpar@1: #define set_symdiff _glp_mpl_set_symdiff alpar@1: ELEMSET *set_symdiff alpar@1: ( MPL *mpl, alpar@1: ELEMSET *X, /* destroyed */ alpar@1: ELEMSET *Y /* destroyed */ alpar@1: ); alpar@1: /* symmetric difference between two elemental sets */ alpar@1: alpar@1: #define set_inter _glp_mpl_set_inter alpar@1: ELEMSET *set_inter alpar@1: ( MPL *mpl, alpar@1: ELEMSET *X, /* destroyed */ alpar@1: ELEMSET *Y /* destroyed */ alpar@1: ); alpar@1: /* intersection of two elemental sets */ alpar@1: alpar@1: #define set_cross _glp_mpl_set_cross alpar@1: ELEMSET *set_cross alpar@1: ( MPL *mpl, alpar@1: ELEMSET *X, /* destroyed */ alpar@1: ELEMSET *Y /* destroyed */ alpar@1: ); alpar@1: /* cross (Cartesian) product of two elemental sets */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * ELEMENTAL VARIABLES * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: struct ELEMVAR alpar@1: { /* elemental variable; formally it is a "value" assigned to alpar@1: members of model variables (like numbers and symbols, which alpar@1: are values assigned to members of model parameters) */ alpar@1: int j; alpar@1: /* LP column number assigned to this elemental variable */ alpar@1: VARIABLE *var; alpar@1: /* model variable, which contains this elemental variable */ alpar@1: MEMBER *memb; alpar@1: /* array member, which is assigned this elemental variable */ alpar@1: double lbnd; alpar@1: /* lower bound */ alpar@1: double ubnd; alpar@1: /* upper bound */ alpar@1: double temp; alpar@1: /* working quantity used in operations on linear forms; normally alpar@1: it contains floating-point zero */ alpar@1: #if 1 /* 15/V-2010 */ alpar@1: int stat; alpar@1: double prim, dual; alpar@1: /* solution components provided by the solver */ alpar@1: #endif alpar@1: }; alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * LINEAR FORMS * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: struct FORMULA alpar@1: { /* term of linear form c * x, where c is a coefficient, x is an alpar@1: elemental variable; the linear form itself is the sum of terms alpar@1: and is associated with its first term; (note that the linear alpar@1: form may be empty that means the sum is equal to zero) */ alpar@1: double coef; alpar@1: /* coefficient at elemental variable or constant term */ alpar@1: ELEMVAR *var; alpar@1: /* reference to elemental variable; NULL means constant term */ alpar@1: FORMULA *next; alpar@1: /* the next term of linear form */ alpar@1: }; alpar@1: alpar@1: #define constant_term _glp_mpl_constant_term alpar@1: FORMULA *constant_term(MPL *mpl, double coef); alpar@1: /* create constant term */ alpar@1: alpar@1: #define single_variable _glp_mpl_single_variable alpar@1: FORMULA *single_variable alpar@1: ( MPL *mpl, alpar@1: ELEMVAR *var /* referenced */ alpar@1: ); alpar@1: /* create single variable */ alpar@1: alpar@1: #define copy_formula _glp_mpl_copy_formula alpar@1: FORMULA *copy_formula alpar@1: ( MPL *mpl, alpar@1: FORMULA *form /* not changed */ alpar@1: ); alpar@1: /* make copy of linear form */ alpar@1: alpar@1: #define delete_formula _glp_mpl_delete_formula alpar@1: void delete_formula alpar@1: ( MPL *mpl, alpar@1: FORMULA *form /* destroyed */ alpar@1: ); alpar@1: /* delete linear form */ alpar@1: alpar@1: #define linear_comb _glp_mpl_linear_comb alpar@1: FORMULA *linear_comb alpar@1: ( MPL *mpl, alpar@1: double a, FORMULA *fx, /* destroyed */ alpar@1: double b, FORMULA *fy /* destroyed */ alpar@1: ); alpar@1: /* linear combination of two linear forms */ alpar@1: alpar@1: #define remove_constant _glp_mpl_remove_constant alpar@1: FORMULA *remove_constant alpar@1: ( MPL *mpl, alpar@1: FORMULA *form, /* destroyed */ alpar@1: double *coef /* modified */ alpar@1: ); alpar@1: /* remove constant term from linear form */ alpar@1: alpar@1: #define reduce_terms _glp_mpl_reduce_terms alpar@1: FORMULA *reduce_terms alpar@1: ( MPL *mpl, alpar@1: FORMULA *form /* destroyed */ alpar@1: ); alpar@1: /* reduce identical terms in linear form */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * ELEMENTAL CONSTRAINTS * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: struct ELEMCON alpar@1: { /* elemental constraint; formally it is a "value" assigned to alpar@1: members of model constraints (like numbers or symbols, which alpar@1: are values assigned to members of model parameters) */ alpar@1: int i; alpar@1: /* LP row number assigned to this elemental constraint */ alpar@1: CONSTRAINT *con; alpar@1: /* model constraint, which contains this elemental constraint */ alpar@1: MEMBER *memb; alpar@1: /* array member, which is assigned this elemental constraint */ alpar@1: FORMULA *form; alpar@1: /* linear form */ alpar@1: double lbnd; alpar@1: /* lower bound */ alpar@1: double ubnd; alpar@1: /* upper bound */ alpar@1: #if 1 /* 15/V-2010 */ alpar@1: int stat; alpar@1: double prim, dual; alpar@1: /* solution components provided by the solver */ alpar@1: #endif alpar@1: }; alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * GENERIC VALUES * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: union VALUE alpar@1: { /* generic value, which can be assigned to object member or be a alpar@1: result of evaluation of expression */ alpar@1: /* indicator that specifies the particular type of generic value alpar@1: is stored in the corresponding array or pseudo-code descriptor alpar@1: and can be one of the following: alpar@1: A_NONE - no value alpar@1: A_NUMERIC - floating-point number alpar@1: A_SYMBOLIC - symbol alpar@1: A_LOGICAL - logical value alpar@1: A_TUPLE - n-tuple alpar@1: A_ELEMSET - elemental set alpar@1: A_ELEMVAR - elemental variable alpar@1: A_FORMULA - linear form alpar@1: A_ELEMCON - elemental constraint */ alpar@1: void *none; /* null */ alpar@1: double num; /* value */ alpar@1: SYMBOL *sym; /* value */ alpar@1: int bit; /* value */ alpar@1: TUPLE *tuple; /* value */ alpar@1: ELEMSET *set; /* value */ alpar@1: ELEMVAR *var; /* reference */ alpar@1: FORMULA *form; /* value */ alpar@1: ELEMCON *con; /* reference */ alpar@1: }; alpar@1: alpar@1: #define delete_value _glp_mpl_delete_value alpar@1: void delete_value alpar@1: ( MPL *mpl, alpar@1: int type, alpar@1: VALUE *value /* content destroyed */ alpar@1: ); alpar@1: /* delete generic value */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * SYMBOLICALLY INDEXED ARRAYS * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: struct ARRAY alpar@1: { /* multi-dimensional array, a set of members indexed over simple alpar@1: or compound sets of symbols; arrays are used to represent the alpar@1: contents of model objects (i.e. sets, parameters, variables, alpar@1: constraints, and objectives); arrays also are used as "values" alpar@1: that are assigned to members of set objects, in which case the alpar@1: array itself represents an elemental set */ alpar@1: int type; alpar@1: /* type of generic values assigned to the array members: alpar@1: A_NONE - none (members have no assigned values) alpar@1: A_NUMERIC - floating-point numbers alpar@1: A_SYMBOLIC - symbols alpar@1: A_ELEMSET - elemental sets alpar@1: A_ELEMVAR - elemental variables alpar@1: A_ELEMCON - elemental constraints */ alpar@1: int dim; alpar@1: /* dimension of the array that determines number of components in alpar@1: n-tuples for all members of the array, dim >= 0; dim = 0 means alpar@1: the array is 0-dimensional */ alpar@1: int size; alpar@1: /* size of the array, i.e. number of its members */ alpar@1: MEMBER *head; alpar@1: /* the first array member; NULL means the array is empty */ alpar@1: MEMBER *tail; alpar@1: /* the last array member; NULL means the array is empty */ alpar@1: AVL *tree; alpar@1: /* the search tree intended to find array members for logarithmic alpar@1: time; NULL means the search tree doesn't exist */ alpar@1: ARRAY *prev; alpar@1: /* the previous array in the translator database */ alpar@1: ARRAY *next; alpar@1: /* the next array in the translator database */ alpar@1: }; alpar@1: alpar@1: struct MEMBER alpar@1: { /* array member */ alpar@1: TUPLE *tuple; alpar@1: /* n-tuple, which identifies the member; number of its components alpar@1: is the same for all members within the array and determined by alpar@1: the array dimension; duplicate members are not allowed */ alpar@1: MEMBER *next; alpar@1: /* the next array member */ alpar@1: VALUE value; alpar@1: /* generic value assigned to the member */ alpar@1: }; alpar@1: alpar@1: #define create_array _glp_mpl_create_array alpar@1: ARRAY *create_array(MPL *mpl, int type, int dim); alpar@1: /* create array */ alpar@1: alpar@1: #define find_member _glp_mpl_find_member alpar@1: MEMBER *find_member alpar@1: ( MPL *mpl, alpar@1: ARRAY *array, /* not changed */ alpar@1: TUPLE *tuple /* not changed */ alpar@1: ); alpar@1: /* find array member with given n-tuple */ alpar@1: alpar@1: #define add_member _glp_mpl_add_member alpar@1: MEMBER *add_member alpar@1: ( MPL *mpl, alpar@1: ARRAY *array, /* modified */ alpar@1: TUPLE *tuple /* destroyed */ alpar@1: ); alpar@1: /* add new member to array */ alpar@1: alpar@1: #define delete_array _glp_mpl_delete_array alpar@1: void delete_array alpar@1: ( MPL *mpl, alpar@1: ARRAY *array /* destroyed */ alpar@1: ); alpar@1: /* delete array */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * DOMAINS AND DUMMY INDICES * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: struct DOMAIN alpar@1: { /* domain (a simple or compound set); syntactically domain looks alpar@1: like '{ i in I, (j,k) in S, t in T : }'; domains alpar@1: are used to define sets, over which model objects are indexed, alpar@1: and also as constituents of iterated operators */ alpar@1: DOMAIN_BLOCK *list; alpar@1: /* linked list of domain blocks (in the example above such blocks alpar@1: are 'i in I', '(j,k) in S', and 't in T'); this list cannot be alpar@1: empty */ alpar@1: CODE *code; alpar@1: /* pseudo-code for computing the logical predicate, which follows alpar@1: the colon; NULL means no predicate is specified */ alpar@1: }; alpar@1: alpar@1: struct DOMAIN_BLOCK alpar@1: { /* domain block; syntactically domain blocks look like 'i in I', alpar@1: '(j,k) in S', and 't in T' in the example above (in the sequel alpar@1: sets like I, S, and T are called basic sets) */ alpar@1: DOMAIN_SLOT *list; alpar@1: /* linked list of domain slots (i.e. indexing positions); number alpar@1: of slots in this list is the same as dimension of n-tuples in alpar@1: the basic set; this list cannot be empty */ alpar@1: CODE *code; alpar@1: /* pseudo-code for computing basic set; cannot be NULL */ alpar@1: TUPLE *backup; alpar@1: /* if this n-tuple is not empty, current values of dummy indices alpar@1: in the domain block are the same as components of this n-tuple alpar@1: (note that this n-tuple may have larger dimension than number alpar@1: of dummy indices in this block, in which case extra components alpar@1: are ignored); this n-tuple is used to restore former values of alpar@1: dummy indices, if they were changed due to recursive calls to alpar@1: the domain block */ alpar@1: DOMAIN_BLOCK *next; alpar@1: /* the next block in the same domain */ alpar@1: }; alpar@1: alpar@1: struct DOMAIN_SLOT alpar@1: { /* domain slot; it specifies an individual indexing position and alpar@1: defines the corresponding dummy index */ alpar@1: char *name; alpar@1: /* symbolic name of the dummy index; null pointer means the dummy alpar@1: index is not explicitly specified */ alpar@1: CODE *code; alpar@1: /* pseudo-code for computing symbolic value, at which the dummy alpar@1: index is bound; NULL means the dummy index is free within the alpar@1: domain scope */ alpar@1: SYMBOL *value; alpar@1: /* current value assigned to the dummy index; NULL means no value alpar@1: is assigned at the moment */ alpar@1: CODE *list; alpar@1: /* linked list of pseudo-codes with operation O_INDEX referring alpar@1: to this slot; this linked list is used to invalidate resultant alpar@1: values of the operation, which depend on this dummy index */ alpar@1: DOMAIN_SLOT *next; alpar@1: /* the next slot in the same domain block */ alpar@1: }; alpar@1: alpar@1: #define assign_dummy_index _glp_mpl_assign_dummy_index alpar@1: void assign_dummy_index alpar@1: ( MPL *mpl, alpar@1: DOMAIN_SLOT *slot, /* modified */ alpar@1: SYMBOL *value /* not changed */ alpar@1: ); alpar@1: /* assign new value to dummy index */ alpar@1: alpar@1: #define update_dummy_indices _glp_mpl_update_dummy_indices alpar@1: void update_dummy_indices alpar@1: ( MPL *mpl, alpar@1: DOMAIN_BLOCK *block /* not changed */ alpar@1: ); alpar@1: /* update current values of dummy indices */ alpar@1: alpar@1: #define enter_domain_block _glp_mpl_enter_domain_block alpar@1: int enter_domain_block alpar@1: ( MPL *mpl, alpar@1: DOMAIN_BLOCK *block, /* not changed */ alpar@1: TUPLE *tuple, /* not changed */ alpar@1: void *info, void (*func)(MPL *mpl, void *info) alpar@1: ); alpar@1: /* enter domain block */ alpar@1: alpar@1: #define eval_within_domain _glp_mpl_eval_within_domain alpar@1: int eval_within_domain alpar@1: ( MPL *mpl, alpar@1: DOMAIN *domain, /* not changed */ alpar@1: TUPLE *tuple, /* not changed */ alpar@1: void *info, void (*func)(MPL *mpl, void *info) alpar@1: ); alpar@1: /* perform evaluation within domain scope */ alpar@1: alpar@1: #define loop_within_domain _glp_mpl_loop_within_domain alpar@1: void loop_within_domain alpar@1: ( MPL *mpl, alpar@1: DOMAIN *domain, /* not changed */ alpar@1: void *info, int (*func)(MPL *mpl, void *info) alpar@1: ); alpar@1: /* perform iterations within domain scope */ alpar@1: alpar@1: #define out_of_domain _glp_mpl_out_of_domain alpar@1: void out_of_domain alpar@1: ( MPL *mpl, alpar@1: char *name, /* not changed */ alpar@1: TUPLE *tuple /* not changed */ alpar@1: ); alpar@1: /* raise domain exception */ alpar@1: alpar@1: #define get_domain_tuple _glp_mpl_get_domain_tuple alpar@1: TUPLE *get_domain_tuple alpar@1: ( MPL *mpl, alpar@1: DOMAIN *domain /* not changed */ alpar@1: ); alpar@1: /* obtain current n-tuple from domain */ alpar@1: alpar@1: #define clean_domain _glp_mpl_clean_domain alpar@1: void clean_domain(MPL *mpl, DOMAIN *domain); alpar@1: /* clean domain */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * MODEL SETS * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: struct SET alpar@1: { /* model set */ alpar@1: char *name; alpar@1: /* symbolic name; cannot be NULL */ alpar@1: char *alias; alpar@1: /* alias; NULL means alias is not specified */ alpar@1: int dim; /* aka arity */ alpar@1: /* dimension (number of subscripts); dim = 0 means 0-dimensional alpar@1: (unsubscripted) set, dim > 0 means set of sets */ alpar@1: DOMAIN *domain; alpar@1: /* subscript domain; NULL for 0-dimensional set */ alpar@1: int dimen; alpar@1: /* dimension of n-tuples, which members of this set consist of alpar@1: (note that the model set itself is an array of elemental sets, alpar@1: which are its members; so, don't confuse this dimension with alpar@1: dimension of the model set); always non-zero */ alpar@1: WITHIN *within; alpar@1: /* list of supersets, which restrict each member of the set to be alpar@1: in every superset from this list; this list can be empty */ alpar@1: CODE *assign; alpar@1: /* pseudo-code for computing assigned value; can be NULL */ alpar@1: CODE *option; alpar@1: /* pseudo-code for computing default value; can be NULL */ alpar@1: GADGET *gadget; alpar@1: /* plain set used to initialize the array of sets; can be NULL */ alpar@1: int data; alpar@1: /* data status flag: alpar@1: 0 - no data are provided in the data section alpar@1: 1 - data are provided, but not checked yet alpar@1: 2 - data are provided and have been checked */ alpar@1: ARRAY *array; alpar@1: /* array of members, which are assigned elemental sets */ alpar@1: }; alpar@1: alpar@1: struct WITHIN alpar@1: { /* restricting superset list entry */ alpar@1: CODE *code; alpar@1: /* pseudo-code for computing the superset; cannot be NULL */ alpar@1: WITHIN *next; alpar@1: /* the next entry for the same set or parameter */ alpar@1: }; alpar@1: alpar@1: struct GADGET alpar@1: { /* plain set used to initialize the array of sets with data */ alpar@1: SET *set; alpar@1: /* pointer to plain set; cannot be NULL */ alpar@1: int ind[20]; /* ind[dim+dimen]; */ alpar@1: /* permutation of integers 1, 2, ..., dim+dimen */ alpar@1: }; alpar@1: alpar@1: #define check_elem_set _glp_mpl_check_elem_set alpar@1: void check_elem_set alpar@1: ( MPL *mpl, alpar@1: SET *set, /* not changed */ alpar@1: TUPLE *tuple, /* not changed */ alpar@1: ELEMSET *refer /* not changed */ alpar@1: ); alpar@1: /* check elemental set assigned to set member */ alpar@1: alpar@1: #define take_member_set _glp_mpl_take_member_set alpar@1: ELEMSET *take_member_set /* returns reference, not value */ alpar@1: ( MPL *mpl, alpar@1: SET *set, /* not changed */ alpar@1: TUPLE *tuple /* not changed */ alpar@1: ); alpar@1: /* obtain elemental set assigned to set member */ alpar@1: alpar@1: #define eval_member_set _glp_mpl_eval_member_set alpar@1: ELEMSET *eval_member_set /* returns reference, not value */ alpar@1: ( MPL *mpl, alpar@1: SET *set, /* not changed */ alpar@1: TUPLE *tuple /* not changed */ alpar@1: ); alpar@1: /* evaluate elemental set assigned to set member */ alpar@1: alpar@1: #define eval_whole_set _glp_mpl_eval_whole_set alpar@1: void eval_whole_set(MPL *mpl, SET *set); alpar@1: /* evaluate model set over entire domain */ alpar@1: alpar@1: #define clean_set _glp_mpl_clean_set alpar@1: void clean_set(MPL *mpl, SET *set); alpar@1: /* clean model set */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * MODEL PARAMETERS * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: struct PARAMETER alpar@1: { /* model parameter */ alpar@1: char *name; alpar@1: /* symbolic name; cannot be NULL */ alpar@1: char *alias; alpar@1: /* alias; NULL means alias is not specified */ alpar@1: int dim; /* aka arity */ alpar@1: /* dimension (number of subscripts); dim = 0 means 0-dimensional alpar@1: (unsubscripted) parameter */ alpar@1: DOMAIN *domain; alpar@1: /* subscript domain; NULL for 0-dimensional parameter */ alpar@1: int type; alpar@1: /* parameter type: alpar@1: A_NUMERIC - numeric alpar@1: A_INTEGER - integer alpar@1: A_BINARY - binary alpar@1: A_SYMBOLIC - symbolic */ alpar@1: CONDITION *cond; alpar@1: /* list of conditions, which restrict each parameter member to alpar@1: satisfy to every condition from this list; this list is used alpar@1: only for numeric parameters and can be empty */ alpar@1: WITHIN *in; alpar@1: /* list of supersets, which restrict each parameter member to be alpar@1: in every superset from this list; this list is used only for alpar@1: symbolic parameters and can be empty */ alpar@1: CODE *assign; alpar@1: /* pseudo-code for computing assigned value; can be NULL */ alpar@1: CODE *option; alpar@1: /* pseudo-code for computing default value; can be NULL */ alpar@1: int data; alpar@1: /* data status flag: alpar@1: 0 - no data are provided in the data section alpar@1: 1 - data are provided, but not checked yet alpar@1: 2 - data are provided and have been checked */ alpar@1: SYMBOL *defval; alpar@1: /* default value provided in the data section; can be NULL */ alpar@1: ARRAY *array; alpar@1: /* array of members, which are assigned numbers or symbols */ alpar@1: }; alpar@1: alpar@1: struct CONDITION alpar@1: { /* restricting condition list entry */ alpar@1: int rho; alpar@1: /* flag that specifies the form of the condition: alpar@1: O_LT - less than alpar@1: O_LE - less than or equal to alpar@1: O_EQ - equal to alpar@1: O_GE - greater than or equal to alpar@1: O_GT - greater than alpar@1: O_NE - not equal to */ alpar@1: CODE *code; alpar@1: /* pseudo-code for computing the reference value */ alpar@1: CONDITION *next; alpar@1: /* the next entry for the same parameter */ alpar@1: }; alpar@1: alpar@1: #define check_value_num _glp_mpl_check_value_num alpar@1: void check_value_num alpar@1: ( MPL *mpl, alpar@1: PARAMETER *par, /* not changed */ alpar@1: TUPLE *tuple, /* not changed */ alpar@1: double value alpar@1: ); alpar@1: /* check numeric value assigned to parameter member */ alpar@1: alpar@1: #define take_member_num _glp_mpl_take_member_num alpar@1: double take_member_num alpar@1: ( MPL *mpl, alpar@1: PARAMETER *par, /* not changed */ alpar@1: TUPLE *tuple /* not changed */ alpar@1: ); alpar@1: /* obtain numeric value assigned to parameter member */ alpar@1: alpar@1: #define eval_member_num _glp_mpl_eval_member_num alpar@1: double eval_member_num alpar@1: ( MPL *mpl, alpar@1: PARAMETER *par, /* not changed */ alpar@1: TUPLE *tuple /* not changed */ alpar@1: ); alpar@1: /* evaluate numeric value assigned to parameter member */ alpar@1: alpar@1: #define check_value_sym _glp_mpl_check_value_sym alpar@1: void check_value_sym alpar@1: ( MPL *mpl, alpar@1: PARAMETER *par, /* not changed */ alpar@1: TUPLE *tuple, /* not changed */ alpar@1: SYMBOL *value /* not changed */ alpar@1: ); alpar@1: /* check symbolic value assigned to parameter member */ alpar@1: alpar@1: #define take_member_sym _glp_mpl_take_member_sym alpar@1: SYMBOL *take_member_sym /* returns value, not reference */ alpar@1: ( MPL *mpl, alpar@1: PARAMETER *par, /* not changed */ alpar@1: TUPLE *tuple /* not changed */ alpar@1: ); alpar@1: /* obtain symbolic value assigned to parameter member */ alpar@1: alpar@1: #define eval_member_sym _glp_mpl_eval_member_sym alpar@1: SYMBOL *eval_member_sym /* returns value, not reference */ alpar@1: ( MPL *mpl, alpar@1: PARAMETER *par, /* not changed */ alpar@1: TUPLE *tuple /* not changed */ alpar@1: ); alpar@1: /* evaluate symbolic value assigned to parameter member */ alpar@1: alpar@1: #define eval_whole_par _glp_mpl_eval_whole_par alpar@1: void eval_whole_par(MPL *mpl, PARAMETER *par); alpar@1: /* evaluate model parameter over entire domain */ alpar@1: alpar@1: #define clean_parameter _glp_mpl_clean_parameter alpar@1: void clean_parameter(MPL *mpl, PARAMETER *par); alpar@1: /* clean model parameter */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * MODEL VARIABLES * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: struct VARIABLE alpar@1: { /* model variable */ alpar@1: char *name; alpar@1: /* symbolic name; cannot be NULL */ alpar@1: char *alias; alpar@1: /* alias; NULL means alias is not specified */ alpar@1: int dim; /* aka arity */ alpar@1: /* dimension (number of subscripts); dim = 0 means 0-dimensional alpar@1: (unsubscripted) variable */ alpar@1: DOMAIN *domain; alpar@1: /* subscript domain; NULL for 0-dimensional variable */ alpar@1: int type; alpar@1: /* variable type: alpar@1: A_NUMERIC - continuous alpar@1: A_INTEGER - integer alpar@1: A_BINARY - binary */ alpar@1: CODE *lbnd; alpar@1: /* pseudo-code for computing lower bound; NULL means lower bound alpar@1: is not specified */ alpar@1: CODE *ubnd; alpar@1: /* pseudo-code for computing upper bound; NULL means upper bound alpar@1: is not specified */ alpar@1: /* if both the pointers lbnd and ubnd refer to the same code, the alpar@1: variable is fixed at the corresponding value */ alpar@1: ARRAY *array; alpar@1: /* array of members, which are assigned elemental variables */ alpar@1: }; alpar@1: alpar@1: #define take_member_var _glp_mpl_take_member_var alpar@1: ELEMVAR *take_member_var /* returns reference */ alpar@1: ( MPL *mpl, alpar@1: VARIABLE *var, /* not changed */ alpar@1: TUPLE *tuple /* not changed */ alpar@1: ); alpar@1: /* obtain reference to elemental variable */ alpar@1: alpar@1: #define eval_member_var _glp_mpl_eval_member_var alpar@1: ELEMVAR *eval_member_var /* returns reference */ alpar@1: ( MPL *mpl, alpar@1: VARIABLE *var, /* not changed */ alpar@1: TUPLE *tuple /* not changed */ alpar@1: ); alpar@1: /* evaluate reference to elemental variable */ alpar@1: alpar@1: #define eval_whole_var _glp_mpl_eval_whole_var alpar@1: void eval_whole_var(MPL *mpl, VARIABLE *var); alpar@1: /* evaluate model variable over entire domain */ alpar@1: alpar@1: #define clean_variable _glp_mpl_clean_variable alpar@1: void clean_variable(MPL *mpl, VARIABLE *var); alpar@1: /* clean model variable */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * MODEL CONSTRAINTS AND OBJECTIVES * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: struct CONSTRAINT alpar@1: { /* model constraint or objective */ alpar@1: char *name; alpar@1: /* symbolic name; cannot be NULL */ alpar@1: char *alias; alpar@1: /* alias; NULL means alias is not specified */ alpar@1: int dim; /* aka arity */ alpar@1: /* dimension (number of subscripts); dim = 0 means 0-dimensional alpar@1: (unsubscripted) constraint */ alpar@1: DOMAIN *domain; alpar@1: /* subscript domain; NULL for 0-dimensional constraint */ alpar@1: int type; alpar@1: /* constraint type: alpar@1: A_CONSTRAINT - constraint alpar@1: A_MINIMIZE - objective (minimization) alpar@1: A_MAXIMIZE - objective (maximization) */ alpar@1: CODE *code; alpar@1: /* pseudo-code for computing main linear form; cannot be NULL */ alpar@1: CODE *lbnd; alpar@1: /* pseudo-code for computing lower bound; NULL means lower bound alpar@1: is not specified */ alpar@1: CODE *ubnd; alpar@1: /* pseudo-code for computing upper bound; NULL means upper bound alpar@1: is not specified */ alpar@1: /* if both the pointers lbnd and ubnd refer to the same code, the alpar@1: constraint has the form of equation */ alpar@1: ARRAY *array; alpar@1: /* array of members, which are assigned elemental constraints */ alpar@1: }; alpar@1: alpar@1: #define take_member_con _glp_mpl_take_member_con alpar@1: ELEMCON *take_member_con /* returns reference */ alpar@1: ( MPL *mpl, alpar@1: CONSTRAINT *con, /* not changed */ alpar@1: TUPLE *tuple /* not changed */ alpar@1: ); alpar@1: /* obtain reference to elemental constraint */ alpar@1: alpar@1: #define eval_member_con _glp_mpl_eval_member_con alpar@1: ELEMCON *eval_member_con /* returns reference */ alpar@1: ( MPL *mpl, alpar@1: CONSTRAINT *con, /* not changed */ alpar@1: TUPLE *tuple /* not changed */ alpar@1: ); alpar@1: /* evaluate reference to elemental constraint */ alpar@1: alpar@1: #define eval_whole_con _glp_mpl_eval_whole_con alpar@1: void eval_whole_con(MPL *mpl, CONSTRAINT *con); alpar@1: /* evaluate model constraint over entire domain */ alpar@1: alpar@1: #define clean_constraint _glp_mpl_clean_constraint alpar@1: void clean_constraint(MPL *mpl, CONSTRAINT *con); alpar@1: /* clean model constraint */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * DATA TABLES * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: struct TABLE alpar@1: { /* data table */ alpar@1: char *name; alpar@1: /* symbolic name; cannot be NULL */ alpar@1: char *alias; alpar@1: /* alias; NULL means alias is not specified */ alpar@1: int type; alpar@1: /* table type: alpar@1: A_INPUT - input table alpar@1: A_OUTPUT - output table */ alpar@1: TABARG *arg; alpar@1: /* argument list; cannot be empty */ alpar@1: union alpar@1: { struct alpar@1: { SET *set; alpar@1: /* input set; NULL means the set is not specified */ alpar@1: TABFLD *fld; alpar@1: /* field list; cannot be empty */ alpar@1: TABIN *list; alpar@1: /* input list; can be empty */ alpar@1: } in; alpar@1: struct alpar@1: { DOMAIN *domain; alpar@1: /* subscript domain; cannot be NULL */ alpar@1: TABOUT *list; alpar@1: /* output list; cannot be empty */ alpar@1: } out; alpar@1: } u; alpar@1: }; alpar@1: alpar@1: struct TABARG alpar@1: { /* table argument list entry */ alpar@1: CODE *code; alpar@1: /* pseudo-code for computing the argument */ alpar@1: TABARG *next; alpar@1: /* next entry for the same table */ alpar@1: }; alpar@1: alpar@1: struct TABFLD alpar@1: { /* table field list entry */ alpar@1: char *name; alpar@1: /* field name; cannot be NULL */ alpar@1: TABFLD *next; alpar@1: /* next entry for the same table */ alpar@1: }; alpar@1: alpar@1: struct TABIN alpar@1: { /* table input list entry */ alpar@1: PARAMETER *par; alpar@1: /* parameter to be read; cannot be NULL */ alpar@1: char *name; alpar@1: /* column name; cannot be NULL */ alpar@1: TABIN *next; alpar@1: /* next entry for the same table */ alpar@1: }; alpar@1: alpar@1: struct TABOUT alpar@1: { /* table output list entry */ alpar@1: CODE *code; alpar@1: /* pseudo-code for computing the value to be written */ alpar@1: char *name; alpar@1: /* column name; cannot be NULL */ alpar@1: TABOUT *next; alpar@1: /* next entry for the same table */ alpar@1: }; alpar@1: alpar@1: struct TABDCA alpar@1: { /* table driver communication area */ alpar@1: int id; alpar@1: /* driver identifier (set by mpl_tab_drv_open) */ alpar@1: void *link; alpar@1: /* driver link pointer (set by mpl_tab_drv_open) */ alpar@1: int na; alpar@1: /* number of arguments */ alpar@1: char **arg; /* char *arg[1+ns]; */ alpar@1: /* arg[k], 1 <= k <= ns, is pointer to k-th argument */ alpar@1: int nf; alpar@1: /* number of fields */ alpar@1: char **name; /* char *name[1+nc]; */ alpar@1: /* name[k], 1 <= k <= nc, is name of k-th field */ alpar@1: int *type; /* int type[1+nc]; */ alpar@1: /* type[k], 1 <= k <= nc, is type of k-th field: alpar@1: '?' - value not assigned alpar@1: 'N' - number alpar@1: 'S' - character string */ alpar@1: double *num; /* double num[1+nc]; */ alpar@1: /* num[k], 1 <= k <= nc, is numeric value of k-th field */ alpar@1: char **str; alpar@1: /* str[k], 1 <= k <= nc, is string value of k-th field */ alpar@1: }; alpar@1: alpar@1: #define mpl_tab_num_args _glp_mpl_tab_num_args alpar@1: int mpl_tab_num_args(TABDCA *dca); alpar@1: alpar@1: #define mpl_tab_get_arg _glp_mpl_tab_get_arg alpar@1: const char *mpl_tab_get_arg(TABDCA *dca, int k); alpar@1: alpar@1: #define mpl_tab_num_flds _glp_mpl_tab_num_flds alpar@1: int mpl_tab_num_flds(TABDCA *dca); alpar@1: alpar@1: #define mpl_tab_get_name _glp_mpl_tab_get_name alpar@1: const char *mpl_tab_get_name(TABDCA *dca, int k); alpar@1: alpar@1: #define mpl_tab_get_type _glp_mpl_tab_get_type alpar@1: int mpl_tab_get_type(TABDCA *dca, int k); alpar@1: alpar@1: #define mpl_tab_get_num _glp_mpl_tab_get_num alpar@1: double mpl_tab_get_num(TABDCA *dca, int k); alpar@1: alpar@1: #define mpl_tab_get_str _glp_mpl_tab_get_str alpar@1: const char *mpl_tab_get_str(TABDCA *dca, int k); alpar@1: alpar@1: #define mpl_tab_set_num _glp_mpl_tab_set_num alpar@1: void mpl_tab_set_num(TABDCA *dca, int k, double num); alpar@1: alpar@1: #define mpl_tab_set_str _glp_mpl_tab_set_str alpar@1: void mpl_tab_set_str(TABDCA *dca, int k, const char *str); alpar@1: alpar@1: #define mpl_tab_drv_open _glp_mpl_tab_drv_open alpar@1: void mpl_tab_drv_open(MPL *mpl, int mode); alpar@1: alpar@1: #define mpl_tab_drv_read _glp_mpl_tab_drv_read alpar@1: int mpl_tab_drv_read(MPL *mpl); alpar@1: alpar@1: #define mpl_tab_drv_write _glp_mpl_tab_drv_write alpar@1: void mpl_tab_drv_write(MPL *mpl); alpar@1: alpar@1: #define mpl_tab_drv_close _glp_mpl_tab_drv_close alpar@1: void mpl_tab_drv_close(MPL *mpl); alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * PSEUDO-CODE * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: union OPERANDS alpar@1: { /* operands that participate in pseudo-code operation (choice of alpar@1: particular operands depends on the operation code) */ alpar@1: /*--------------------------------------------------------------*/ alpar@1: double num; /* O_NUMBER */ alpar@1: /* floaing-point number to be taken */ alpar@1: /*--------------------------------------------------------------*/ alpar@1: char *str; /* O_STRING */ alpar@1: /* character string to be taken */ alpar@1: /*--------------------------------------------------------------*/ alpar@1: struct /* O_INDEX */ alpar@1: { DOMAIN_SLOT *slot; alpar@1: /* domain slot, which contains dummy index to be taken */ alpar@1: CODE *next; alpar@1: /* the next pseudo-code with op = O_INDEX, which refers to the alpar@1: same slot as this one; pointer to the beginning of this list alpar@1: is stored in the corresponding domain slot */ alpar@1: } index; alpar@1: /*--------------------------------------------------------------*/ alpar@1: struct /* O_MEMNUM, O_MEMSYM */ alpar@1: { PARAMETER *par; alpar@1: /* model parameter, which contains member to be taken */ alpar@1: ARG_LIST *list; alpar@1: /* list of subscripts; NULL for 0-dimensional parameter */ alpar@1: } par; alpar@1: /*--------------------------------------------------------------*/ alpar@1: struct /* O_MEMSET */ alpar@1: { SET *set; alpar@1: /* model set, which contains member to be taken */ alpar@1: ARG_LIST *list; alpar@1: /* list of subscripts; NULL for 0-dimensional set */ alpar@1: } set; alpar@1: /*--------------------------------------------------------------*/ alpar@1: struct /* O_MEMVAR */ alpar@1: { VARIABLE *var; alpar@1: /* model variable, which contains member to be taken */ alpar@1: ARG_LIST *list; alpar@1: /* list of subscripts; NULL for 0-dimensional variable */ alpar@1: #if 1 /* 15/V-2010 */ alpar@1: int suff; alpar@1: /* suffix specified: */ alpar@1: #define DOT_NONE 0x00 /* none (means variable itself) */ alpar@1: #define DOT_LB 0x01 /* .lb (lower bound) */ alpar@1: #define DOT_UB 0x02 /* .ub (upper bound) */ alpar@1: #define DOT_STATUS 0x03 /* .status (status) */ alpar@1: #define DOT_VAL 0x04 /* .val (primal value) */ alpar@1: #define DOT_DUAL 0x05 /* .dual (dual value) */ alpar@1: #endif alpar@1: } var; alpar@1: #if 1 /* 15/V-2010 */ alpar@1: /*--------------------------------------------------------------*/ alpar@1: struct /* O_MEMCON */ alpar@1: { CONSTRAINT *con; alpar@1: /* model constraint, which contains member to be taken */ alpar@1: ARG_LIST *list; alpar@1: /* list of subscripys; NULL for 0-dimensional constraint */ alpar@1: int suff; alpar@1: /* suffix specified (see O_MEMVAR above) */ alpar@1: } con; alpar@1: #endif alpar@1: /*--------------------------------------------------------------*/ alpar@1: ARG_LIST *list; /* O_TUPLE, O_MAKE, n-ary operations */ alpar@1: /* list of operands */ alpar@1: /*--------------------------------------------------------------*/ alpar@1: DOMAIN_BLOCK *slice; /* O_SLICE */ alpar@1: /* domain block, which specifies slice (i.e. n-tuple that contains alpar@1: free dummy indices); this operation is never evaluated */ alpar@1: /*--------------------------------------------------------------*/ alpar@1: struct /* unary, binary, ternary operations */ alpar@1: { CODE *x; alpar@1: /* pseudo-code for computing first operand */ alpar@1: CODE *y; alpar@1: /* pseudo-code for computing second operand */ alpar@1: CODE *z; alpar@1: /* pseudo-code for computing third operand */ alpar@1: } arg; alpar@1: /*--------------------------------------------------------------*/ alpar@1: struct /* iterated operations */ alpar@1: { DOMAIN *domain; alpar@1: /* domain, over which the operation is performed */ alpar@1: CODE *x; alpar@1: /* pseudo-code for computing "integrand" */ alpar@1: } loop; alpar@1: /*--------------------------------------------------------------*/ alpar@1: }; alpar@1: alpar@1: struct ARG_LIST alpar@1: { /* operands list entry */ alpar@1: CODE *x; alpar@1: /* pseudo-code for computing operand */ alpar@1: ARG_LIST *next; alpar@1: /* the next operand of the same operation */ alpar@1: }; alpar@1: alpar@1: struct CODE alpar@1: { /* pseudo-code (internal form of expressions) */ alpar@1: int op; alpar@1: /* operation code: */ alpar@1: #define O_NUMBER 301 /* take floating-point number */ alpar@1: #define O_STRING 302 /* take character string */ alpar@1: #define O_INDEX 303 /* take dummy index */ alpar@1: #define O_MEMNUM 304 /* take member of numeric parameter */ alpar@1: #define O_MEMSYM 305 /* take member of symbolic parameter */ alpar@1: #define O_MEMSET 306 /* take member of set */ alpar@1: #define O_MEMVAR 307 /* take member of variable */ alpar@1: #define O_MEMCON 308 /* take member of constraint */ alpar@1: #define O_TUPLE 309 /* make n-tuple */ alpar@1: #define O_MAKE 310 /* make elemental set of n-tuples */ alpar@1: #define O_SLICE 311 /* define domain block (dummy op) */ alpar@1: /* 0-ary operations --------------------*/ alpar@1: #define O_IRAND224 312 /* pseudo-random in [0, 2^24-1] */ alpar@1: #define O_UNIFORM01 313 /* pseudo-random in [0, 1) */ alpar@1: #define O_NORMAL01 314 /* gaussian random, mu = 0, sigma = 1 */ alpar@1: #define O_GMTIME 315 /* current calendar time (UTC) */ alpar@1: /* unary operations --------------------*/ alpar@1: #define O_CVTNUM 316 /* conversion to numeric */ alpar@1: #define O_CVTSYM 317 /* conversion to symbolic */ alpar@1: #define O_CVTLOG 318 /* conversion to logical */ alpar@1: #define O_CVTTUP 319 /* conversion to 1-tuple */ alpar@1: #define O_CVTLFM 320 /* conversion to linear form */ alpar@1: #define O_PLUS 321 /* unary plus */ alpar@1: #define O_MINUS 322 /* unary minus */ alpar@1: #define O_NOT 323 /* negation (logical "not") */ alpar@1: #define O_ABS 324 /* absolute value */ alpar@1: #define O_CEIL 325 /* round upward ("ceiling of x") */ alpar@1: #define O_FLOOR 326 /* round downward ("floor of x") */ alpar@1: #define O_EXP 327 /* base-e exponential */ alpar@1: #define O_LOG 328 /* natural logarithm */ alpar@1: #define O_LOG10 329 /* common (decimal) logarithm */ alpar@1: #define O_SQRT 330 /* square root */ alpar@1: #define O_SIN 331 /* trigonometric sine */ alpar@1: #define O_COS 332 /* trigonometric cosine */ alpar@1: #define O_ATAN 333 /* trigonometric arctangent */ alpar@1: #define O_ROUND 334 /* round to nearest integer */ alpar@1: #define O_TRUNC 335 /* truncate to nearest integer */ alpar@1: #define O_CARD 336 /* cardinality of set */ alpar@1: #define O_LENGTH 337 /* length of symbolic value */ alpar@1: /* binary operations -------------------*/ alpar@1: #define O_ADD 338 /* addition */ alpar@1: #define O_SUB 339 /* subtraction */ alpar@1: #define O_LESS 340 /* non-negative subtraction */ alpar@1: #define O_MUL 341 /* multiplication */ alpar@1: #define O_DIV 342 /* division */ alpar@1: #define O_IDIV 343 /* quotient of exact division */ alpar@1: #define O_MOD 344 /* remainder of exact division */ alpar@1: #define O_POWER 345 /* exponentiation (raise to power) */ alpar@1: #define O_ATAN2 346 /* trigonometric arctangent */ alpar@1: #define O_ROUND2 347 /* round to n fractional digits */ alpar@1: #define O_TRUNC2 348 /* truncate to n fractional digits */ alpar@1: #define O_UNIFORM 349 /* pseudo-random in [a, b) */ alpar@1: #define O_NORMAL 350 /* gaussian random, given mu and sigma */ alpar@1: #define O_CONCAT 351 /* concatenation */ alpar@1: #define O_LT 352 /* comparison on 'less than' */ alpar@1: #define O_LE 353 /* comparison on 'not greater than' */ alpar@1: #define O_EQ 354 /* comparison on 'equal to' */ alpar@1: #define O_GE 355 /* comparison on 'not less than' */ alpar@1: #define O_GT 356 /* comparison on 'greater than' */ alpar@1: #define O_NE 357 /* comparison on 'not equal to' */ alpar@1: #define O_AND 358 /* conjunction (logical "and") */ alpar@1: #define O_OR 359 /* disjunction (logical "or") */ alpar@1: #define O_UNION 360 /* union */ alpar@1: #define O_DIFF 361 /* difference */ alpar@1: #define O_SYMDIFF 362 /* symmetric difference */ alpar@1: #define O_INTER 363 /* intersection */ alpar@1: #define O_CROSS 364 /* cross (Cartesian) product */ alpar@1: #define O_IN 365 /* test on 'x in Y' */ alpar@1: #define O_NOTIN 366 /* test on 'x not in Y' */ alpar@1: #define O_WITHIN 367 /* test on 'X within Y' */ alpar@1: #define O_NOTWITHIN 368 /* test on 'X not within Y' */ alpar@1: #define O_SUBSTR 369 /* substring */ alpar@1: #define O_STR2TIME 370 /* convert string to time */ alpar@1: #define O_TIME2STR 371 /* convert time to string */ alpar@1: /* ternary operations ------------------*/ alpar@1: #define O_DOTS 372 /* build "arithmetic" set */ alpar@1: #define O_FORK 373 /* if-then-else */ alpar@1: #define O_SUBSTR3 374 /* substring */ alpar@1: /* n-ary operations --------------------*/ alpar@1: #define O_MIN 375 /* minimal value (n-ary) */ alpar@1: #define O_MAX 376 /* maximal value (n-ary) */ alpar@1: /* iterated operations -----------------*/ alpar@1: #define O_SUM 377 /* summation */ alpar@1: #define O_PROD 378 /* multiplication */ alpar@1: #define O_MINIMUM 379 /* minimum */ alpar@1: #define O_MAXIMUM 380 /* maximum */ alpar@1: #define O_FORALL 381 /* conjunction (A-quantification) */ alpar@1: #define O_EXISTS 382 /* disjunction (E-quantification) */ alpar@1: #define O_SETOF 383 /* compute elemental set */ alpar@1: #define O_BUILD 384 /* build elemental set */ alpar@1: OPERANDS arg; alpar@1: /* operands that participate in the operation */ alpar@1: int type; alpar@1: /* type of the resultant value: alpar@1: A_NUMERIC - numeric alpar@1: A_SYMBOLIC - symbolic alpar@1: A_LOGICAL - logical alpar@1: A_TUPLE - n-tuple alpar@1: A_ELEMSET - elemental set alpar@1: A_FORMULA - linear form */ alpar@1: int dim; alpar@1: /* dimension of the resultant value; for A_TUPLE and A_ELEMSET it alpar@1: is the dimension of the corresponding n-tuple(s) and cannot be alpar@1: zero; for other resultant types it is always zero */ alpar@1: CODE *up; alpar@1: /* parent pseudo-code, which refers to this pseudo-code as to its alpar@1: operand; NULL means this pseudo-code has no parent and defines alpar@1: an expression, which is not contained in another expression */ alpar@1: int vflag; alpar@1: /* volatile flag; being set this flag means that this operation alpar@1: has a side effect; for primary expressions this flag is set alpar@1: directly by corresponding parsing routines (for example, if alpar@1: primary expression is a reference to a function that generates alpar@1: pseudo-random numbers); in other cases this flag is inherited alpar@1: from operands */ alpar@1: int valid; alpar@1: /* if this flag is set, the resultant value, which is a temporary alpar@1: result of evaluating this operation on particular values of alpar@1: operands, is valid; if this flag is clear, the resultant value alpar@1: doesn't exist and therefore not valid; having been evaluated alpar@1: the resultant value is stored here and not destroyed until the alpar@1: dummy indices, which this value depends on, have been changed alpar@1: (and if it doesn't depend on dummy indices at all, it is never alpar@1: destroyed); thus, if the resultant value is valid, evaluating alpar@1: routine can immediately take its copy not computing the result alpar@1: from scratch; this mechanism is similar to moving invariants alpar@1: out of loops and allows improving efficiency at the expense of alpar@1: some extra memory needed to keep temporary results */ alpar@1: /* however, if the volatile flag (see above) is set, even if the alpar@1: resultant value is valid, evaluating routine computes it as if alpar@1: it were not valid, i.e. caching is not used in this case */ alpar@1: VALUE value; alpar@1: /* resultant value in generic format */ alpar@1: }; alpar@1: alpar@1: #define eval_numeric _glp_mpl_eval_numeric alpar@1: double eval_numeric(MPL *mpl, CODE *code); alpar@1: /* evaluate pseudo-code to determine numeric value */ alpar@1: alpar@1: #define eval_symbolic _glp_mpl_eval_symbolic alpar@1: SYMBOL *eval_symbolic(MPL *mpl, CODE *code); alpar@1: /* evaluate pseudo-code to determine symbolic value */ alpar@1: alpar@1: #define eval_logical _glp_mpl_eval_logical alpar@1: int eval_logical(MPL *mpl, CODE *code); alpar@1: /* evaluate pseudo-code to determine logical value */ alpar@1: alpar@1: #define eval_tuple _glp_mpl_eval_tuple alpar@1: TUPLE *eval_tuple(MPL *mpl, CODE *code); alpar@1: /* evaluate pseudo-code to construct n-tuple */ alpar@1: alpar@1: #define eval_elemset _glp_mpl_eval_elemset alpar@1: ELEMSET *eval_elemset(MPL *mpl, CODE *code); alpar@1: /* evaluate pseudo-code to construct elemental set */ alpar@1: alpar@1: #define is_member _glp_mpl_is_member alpar@1: int is_member(MPL *mpl, CODE *code, TUPLE *tuple); alpar@1: /* check if n-tuple is in set specified by pseudo-code */ alpar@1: alpar@1: #define eval_formula _glp_mpl_eval_formula alpar@1: FORMULA *eval_formula(MPL *mpl, CODE *code); alpar@1: /* evaluate pseudo-code to construct linear form */ alpar@1: alpar@1: #define clean_code _glp_mpl_clean_code alpar@1: void clean_code(MPL *mpl, CODE *code); alpar@1: /* clean pseudo-code */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * MODEL STATEMENTS * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: struct CHECK alpar@1: { /* check statement */ alpar@1: DOMAIN *domain; alpar@1: /* subscript domain; NULL means domain is not used */ alpar@1: CODE *code; alpar@1: /* code for computing the predicate to be checked */ alpar@1: }; alpar@1: alpar@1: struct DISPLAY alpar@1: { /* display statement */ alpar@1: DOMAIN *domain; alpar@1: /* subscript domain; NULL means domain is not used */ alpar@1: DISPLAY1 *list; alpar@1: /* display list; cannot be empty */ alpar@1: }; alpar@1: alpar@1: struct DISPLAY1 alpar@1: { /* display list entry */ alpar@1: int type; alpar@1: /* item type: alpar@1: A_INDEX - dummy index alpar@1: A_SET - model set alpar@1: A_PARAMETER - model parameter alpar@1: A_VARIABLE - model variable alpar@1: A_CONSTRAINT - model constraint/objective alpar@1: A_EXPRESSION - expression */ alpar@1: union alpar@1: { DOMAIN_SLOT *slot; alpar@1: SET *set; alpar@1: PARAMETER *par; alpar@1: VARIABLE *var; alpar@1: CONSTRAINT *con; alpar@1: CODE *code; alpar@1: } u; alpar@1: /* item to be displayed */ alpar@1: #if 0 /* 15/V-2010 */ alpar@1: ARG_LIST *list; alpar@1: /* optional subscript list (for constraint/objective only) */ alpar@1: #endif alpar@1: DISPLAY1 *next; alpar@1: /* the next entry for the same statement */ alpar@1: }; alpar@1: alpar@1: struct PRINTF alpar@1: { /* printf statement */ alpar@1: DOMAIN *domain; alpar@1: /* subscript domain; NULL means domain is not used */ alpar@1: CODE *fmt; alpar@1: /* pseudo-code for computing format string */ alpar@1: PRINTF1 *list; alpar@1: /* printf list; can be empty */ alpar@1: CODE *fname; alpar@1: /* pseudo-code for computing filename to redirect the output; alpar@1: NULL means the output goes to stdout */ alpar@1: int app; alpar@1: /* if this flag is set, the output is appended */ alpar@1: }; alpar@1: alpar@1: struct PRINTF1 alpar@1: { /* printf list entry */ alpar@1: CODE *code; alpar@1: /* pseudo-code for computing value to be printed */ alpar@1: PRINTF1 *next; alpar@1: /* the next entry for the same statement */ alpar@1: }; alpar@1: alpar@1: struct FOR alpar@1: { /* for statement */ alpar@1: DOMAIN *domain; alpar@1: /* subscript domain; cannot be NULL */ alpar@1: STATEMENT *list; alpar@1: /* linked list of model statements within this for statement in alpar@1: the original order */ alpar@1: }; alpar@1: alpar@1: struct STATEMENT alpar@1: { /* model statement */ alpar@1: int line; alpar@1: /* number of source text line, where statement begins */ alpar@1: int type; alpar@1: /* statement type: alpar@1: A_SET - set statement alpar@1: A_PARAMETER - parameter statement alpar@1: A_VARIABLE - variable statement alpar@1: A_CONSTRAINT - constraint/objective statement alpar@1: A_TABLE - table statement alpar@1: A_SOLVE - solve statement alpar@1: A_CHECK - check statement alpar@1: A_DISPLAY - display statement alpar@1: A_PRINTF - printf statement alpar@1: A_FOR - for statement */ alpar@1: union alpar@1: { SET *set; alpar@1: PARAMETER *par; alpar@1: VARIABLE *var; alpar@1: CONSTRAINT *con; alpar@1: TABLE *tab; alpar@1: void *slv; /* currently not used (set to NULL) */ alpar@1: CHECK *chk; alpar@1: DISPLAY *dpy; alpar@1: PRINTF *prt; alpar@1: FOR *fur; alpar@1: } u; alpar@1: /* specific part of statement */ alpar@1: STATEMENT *next; alpar@1: /* the next statement; in this list statements follow in the same alpar@1: order as they appear in the model section */ alpar@1: }; alpar@1: alpar@1: #define execute_table _glp_mpl_execute_table alpar@1: void execute_table(MPL *mpl, TABLE *tab); alpar@1: /* execute table statement */ alpar@1: alpar@1: #define free_dca _glp_mpl_free_dca alpar@1: void free_dca(MPL *mpl); alpar@1: /* free table driver communucation area */ alpar@1: alpar@1: #define clean_table _glp_mpl_clean_table alpar@1: void clean_table(MPL *mpl, TABLE *tab); alpar@1: /* clean table statement */ alpar@1: alpar@1: #define execute_check _glp_mpl_execute_check alpar@1: void execute_check(MPL *mpl, CHECK *chk); alpar@1: /* execute check statement */ alpar@1: alpar@1: #define clean_check _glp_mpl_clean_check alpar@1: void clean_check(MPL *mpl, CHECK *chk); alpar@1: /* clean check statement */ alpar@1: alpar@1: #define execute_display _glp_mpl_execute_display alpar@1: void execute_display(MPL *mpl, DISPLAY *dpy); alpar@1: /* execute display statement */ alpar@1: alpar@1: #define clean_display _glp_mpl_clean_display alpar@1: void clean_display(MPL *mpl, DISPLAY *dpy); alpar@1: /* clean display statement */ alpar@1: alpar@1: #define execute_printf _glp_mpl_execute_printf alpar@1: void execute_printf(MPL *mpl, PRINTF *prt); alpar@1: /* execute printf statement */ alpar@1: alpar@1: #define clean_printf _glp_mpl_clean_printf alpar@1: void clean_printf(MPL *mpl, PRINTF *prt); alpar@1: /* clean printf statement */ alpar@1: alpar@1: #define execute_for _glp_mpl_execute_for alpar@1: void execute_for(MPL *mpl, FOR *fur); alpar@1: /* execute for statement */ alpar@1: alpar@1: #define clean_for _glp_mpl_clean_for alpar@1: void clean_for(MPL *mpl, FOR *fur); alpar@1: /* clean for statement */ alpar@1: alpar@1: #define execute_statement _glp_mpl_execute_statement alpar@1: void execute_statement(MPL *mpl, STATEMENT *stmt); alpar@1: /* execute specified model statement */ alpar@1: alpar@1: #define clean_statement _glp_mpl_clean_statement alpar@1: void clean_statement(MPL *mpl, STATEMENT *stmt); alpar@1: /* clean specified model statement */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * GENERATING AND POSTSOLVING MODEL * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: #define alloc_content _glp_mpl_alloc_content alpar@1: void alloc_content(MPL *mpl); alpar@1: /* allocate content arrays for all model objects */ alpar@1: alpar@1: #define generate_model _glp_mpl_generate_model alpar@1: void generate_model(MPL *mpl); alpar@1: /* generate model */ alpar@1: alpar@1: #define build_problem _glp_mpl_build_problem alpar@1: void build_problem(MPL *mpl); alpar@1: /* build problem instance */ alpar@1: alpar@1: #define postsolve_model _glp_mpl_postsolve_model alpar@1: void postsolve_model(MPL *mpl); alpar@1: /* postsolve model */ alpar@1: alpar@1: #define clean_model _glp_mpl_clean_model alpar@1: void clean_model(MPL *mpl); alpar@1: /* clean model content */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * INPUT/OUTPUT * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: #define open_input _glp_mpl_open_input alpar@1: void open_input(MPL *mpl, char *file); alpar@1: /* open input text file */ alpar@1: alpar@1: #define read_char _glp_mpl_read_char alpar@1: int read_char(MPL *mpl); alpar@1: /* read next character from input text file */ alpar@1: alpar@1: #define close_input _glp_mpl_close_input alpar@1: void close_input(MPL *mpl); alpar@1: /* close input text file */ alpar@1: alpar@1: #define open_output _glp_mpl_open_output alpar@1: void open_output(MPL *mpl, char *file); alpar@1: /* open output text file */ alpar@1: alpar@1: #define write_char _glp_mpl_write_char alpar@1: void write_char(MPL *mpl, int c); alpar@1: /* write next character to output text file */ alpar@1: alpar@1: #define write_text _glp_mpl_write_text alpar@1: void write_text(MPL *mpl, char *fmt, ...); alpar@1: /* format and write text to output text file */ alpar@1: alpar@1: #define flush_output _glp_mpl_flush_output alpar@1: void flush_output(MPL *mpl); alpar@1: /* finalize writing data to output text file */ alpar@1: alpar@1: /**********************************************************************/ alpar@1: /* * * SOLVER INTERFACE * * */ alpar@1: /**********************************************************************/ alpar@1: alpar@1: #define MPL_FR 401 /* free (unbounded) */ alpar@1: #define MPL_LO 402 /* lower bound */ alpar@1: #define MPL_UP 403 /* upper bound */ alpar@1: #define MPL_DB 404 /* both lower and upper bounds */ alpar@1: #define MPL_FX 405 /* fixed */ alpar@1: alpar@1: #define MPL_ST 411 /* constraint */ alpar@1: #define MPL_MIN 412 /* objective (minimization) */ alpar@1: #define MPL_MAX 413 /* objective (maximization) */ alpar@1: alpar@1: #define MPL_NUM 421 /* continuous */ alpar@1: #define MPL_INT 422 /* integer */ alpar@1: #define MPL_BIN 423 /* binary */ alpar@1: alpar@1: #define error _glp_mpl_error alpar@1: void error(MPL *mpl, char *fmt, ...); alpar@1: /* print error message and terminate model processing */ alpar@1: alpar@1: #define warning _glp_mpl_warning alpar@1: void warning(MPL *mpl, char *fmt, ...); alpar@1: /* print warning message and continue model processing */ alpar@1: alpar@1: #define mpl_initialize _glp_mpl_initialize alpar@1: MPL *mpl_initialize(void); alpar@1: /* create and initialize translator database */ alpar@1: alpar@1: #define mpl_read_model _glp_mpl_read_model alpar@1: int mpl_read_model(MPL *mpl, char *file, int skip_data); alpar@1: /* read model section and optional data section */ alpar@1: alpar@1: #define mpl_read_data _glp_mpl_read_data alpar@1: int mpl_read_data(MPL *mpl, char *file); alpar@1: /* read data section */ alpar@1: alpar@1: #define mpl_generate _glp_mpl_generate alpar@1: int mpl_generate(MPL *mpl, char *file); alpar@1: /* generate model */ alpar@1: alpar@1: #define mpl_get_prob_name _glp_mpl_get_prob_name alpar@1: char *mpl_get_prob_name(MPL *mpl); alpar@1: /* obtain problem (model) name */ alpar@1: alpar@1: #define mpl_get_num_rows _glp_mpl_get_num_rows alpar@1: int mpl_get_num_rows(MPL *mpl); alpar@1: /* determine number of rows */ alpar@1: alpar@1: #define mpl_get_num_cols _glp_mpl_get_num_cols alpar@1: int mpl_get_num_cols(MPL *mpl); alpar@1: /* determine number of columns */ alpar@1: alpar@1: #define mpl_get_row_name _glp_mpl_get_row_name alpar@1: char *mpl_get_row_name(MPL *mpl, int i); alpar@1: /* obtain row name */ alpar@1: alpar@1: #define mpl_get_row_kind _glp_mpl_get_row_kind alpar@1: int mpl_get_row_kind(MPL *mpl, int i); alpar@1: /* determine row kind */ alpar@1: alpar@1: #define mpl_get_row_bnds _glp_mpl_get_row_bnds alpar@1: int mpl_get_row_bnds(MPL *mpl, int i, double *lb, double *ub); alpar@1: /* obtain row bounds */ alpar@1: alpar@1: #define mpl_get_mat_row _glp_mpl_get_mat_row alpar@1: int mpl_get_mat_row(MPL *mpl, int i, int ndx[], double val[]); alpar@1: /* obtain row of the constraint matrix */ alpar@1: alpar@1: #define mpl_get_row_c0 _glp_mpl_get_row_c0 alpar@1: double mpl_get_row_c0(MPL *mpl, int i); alpar@1: /* obtain constant term of free row */ alpar@1: alpar@1: #define mpl_get_col_name _glp_mpl_get_col_name alpar@1: char *mpl_get_col_name(MPL *mpl, int j); alpar@1: /* obtain column name */ alpar@1: alpar@1: #define mpl_get_col_kind _glp_mpl_get_col_kind alpar@1: int mpl_get_col_kind(MPL *mpl, int j); alpar@1: /* determine column kind */ alpar@1: alpar@1: #define mpl_get_col_bnds _glp_mpl_get_col_bnds alpar@1: int mpl_get_col_bnds(MPL *mpl, int j, double *lb, double *ub); alpar@1: /* obtain column bounds */ alpar@1: alpar@1: #define mpl_has_solve_stmt _glp_mpl_has_solve_stmt alpar@1: int mpl_has_solve_stmt(MPL *mpl); alpar@1: /* check if model has solve statement */ alpar@1: alpar@1: #if 1 /* 15/V-2010 */ alpar@1: #define mpl_put_row_soln _glp_mpl_put_row_soln alpar@1: void mpl_put_row_soln(MPL *mpl, int i, int stat, double prim, alpar@1: double dual); alpar@1: /* store row (constraint/objective) solution components */ alpar@1: #endif alpar@1: alpar@1: #if 1 /* 15/V-2010 */ alpar@1: #define mpl_put_col_soln _glp_mpl_put_col_soln alpar@1: void mpl_put_col_soln(MPL *mpl, int j, int stat, double prim, alpar@1: double dual); alpar@1: /* store column (variable) solution components */ alpar@1: #endif alpar@1: alpar@1: #if 0 /* 15/V-2010 */ alpar@1: #define mpl_put_col_value _glp_mpl_put_col_value alpar@1: void mpl_put_col_value(MPL *mpl, int j, double val); alpar@1: /* store column value */ alpar@1: #endif alpar@1: alpar@1: #define mpl_postsolve _glp_mpl_postsolve alpar@1: int mpl_postsolve(MPL *mpl); alpar@1: /* postsolve model */ alpar@1: alpar@1: #define mpl_terminate _glp_mpl_terminate alpar@1: void mpl_terminate(MPL *mpl); alpar@1: /* free all resources used by translator */ alpar@1: alpar@1: #endif alpar@1: alpar@1: /* eof */