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