void read_eqie( RAT **ar, int dim, int *equa, int *ineq, int *maxrows, int *line, char *fname, char in_line[], char *scanned_inline ) /*****************************************************************/ /* * Read the INEQUALITY_SECTION into the table "ar". * For each (in)equality, the corresponding line of "ar" contains, in this order: * the "dim" coefficients of the variables x1--xn, * the right-hand side, * 0 if it was an equation, 1 if it was an inequality. * All inequalities are stored as "<=" inequalities. * Lines as * "x1 - 1 <= 3 + x2" * are interpreted as * "x1 -x2 <= 4" */ { char *p,*in; int i,rs=0,index=0,j,sysrow, numberread,nonempty; RAT val; sysrow = dim+2; /* row length of array "ar" */ do { nonempty = get_line(fp,fname,in_line,line); } while (!nonempty); for (i = 0; scan_line(&val,3,dim,*line, fname,in_line,scanned_inline); i++) { /* * scan_line() reads an inequality into string "scanned_inline", * with a little formatting. * "val" is not used. */ p = in = scanned_inline; rs = 0; /* rs records the type of inequality, * rs = 0 means: type not yet known. */ /* scan string "scanned_inline" up to '\0' or '#' */ while (*p != '\0' && *p != '#' ) { val.den.i = 1; val.num = 1; if (*p == '-') val.num = -1; /* * If: {+,-} has been read, * or {<,=,>} followed by {x,0,1,..,9} has been read, * or it is the beginning of the line. then ... */ if ( *p == '-' || *p == '+' || (p == scanned_inline || (p != scanned_inline && (*(p-1)=='<' || *(p-1)=='=' || *(p-1)=='>')) && ((*p < 58 && *p > 47) || *p =='x') ) ) { numberread = 0; if ( *p == '-' || *p == '+') p++; in = p; while (*p > 47 && *p < 58) p++; if (in != p) { /* in points to a number, p to the next non-number */ numberread = 1; val.num *= atoi(in); if (*p == '/') { p++; in = p; while (*p > 47 && *p < 58) p++; if (p == in) msg("%s, line %i : invalid denominator", fname,*line); if ((val.den.i = atoi(in)) <= 0) msg("%s, line %i : invalid denominator", fname,*line); } } /* if (in != p) */ if (*p == 'x') { p++; in = p; while (*p > 47 && *p < 58) p++; if (p == in) msg("%s, line %i : invalid format",fname,*line); index = atoi(in)-1; if (index > dim-1 || index < 0) msg("%s, line %i : only variable names x1,...,xdim allowed", fname,*line); } /* * Change by M.S. 1.6.92: * The following four lines of code are changed. * * In the case (*p in {+,-}), * something like "10 +", but not "x10 +" has been encountered. * In the case (rs==0 && *p in {<,>,>} ), * something like "10 <", but not "x10 <" has been encountered. * In both cases, the number "10" is interpreted as part of * the right-hand side. * But it should be tested, * whether a number has actually been read. * Otherwise * "x1++x2 <= 20\n" is interpreted as * "x1+1+x2 <= 20\n". */ else if (numberread && (*p == '+' || *p == '-' || ((rs == 0) && (*p =='<'||*p == '>'||*p == '=')))) { index = dim; } /* The following four lines mean: * If "<=" or ">=" or "==" has already been read (i.e. rs > 0), * and if p points to the end of the line, * then interpret the number in val as the right hand side. * to be stored in the dim-th position of the current row * of table "ar". */ else if (numberread && rs && (*(p) == '\0' || *(p) == '#')) { index = dim; } else msg("%s, line %i : invalid format",fname,*line); } /* if ......... */ else if ((p != scanned_inline) && (*p == '<' || *p == '>' || *p == '=')) { /* * Record the type of inequality: * rs = 1 if it is an equation ("=" or "==") * rs = 2 if it is a "<=" inequality (may also be written "=<") * rs = 3 if it is a ">=" inequality (may also be written "=>") */ if (++rs > 1) msg("%s, line %i : invalid format",fname,*line); if ((*p == '=') && (*(p+1) == '=')) p++; else if ((*p == '=') && (*(p+1) != '>') && (*(p+1) != '<')); else if ((*p == '=' && *(p+1) == '>') || (*p == '>' && *(p+1) == '=')) { rs++;rs++; p++; } else if ((*p == '=' && *(p+1) == '<') || (*p == '<' && *(p+1) == '=')) { rs++; p++; } else msg("%s, line %i : invalid format",fname,*line); p++; index = -1; } /* else if < = > */ else msg("%s, line %i : invalid format",fname,*line); if (index > -1) { /* not "< > =" */ if (index == dim) val.num *= -1; if (rs ) I_RAT_sub(*(*ar+i*sysrow+index),val,*ar+i*sysrow+index); else I_RAT_add(*(*ar+i*sysrow+index),val,*ar+i*sysrow+index); } } /* while */ /* transform ">=" into "<=" by multiplying the inequality with -1 */ if (rs == 3 ) { /* >= */ for (j = 0; j <= dim; j++) (*ar+i*sysrow+j)->num = -(*ar+i*sysrow+j)->num; rs -= 1; } (*ar+(i+1)*sysrow-1)->num = --rs; /* * Now rs = 0 if the line was an equation, * and rs = 1 if the line was an inequality. * The last line stored rs into the "dim+1"th position of ar[i]. */ (rs == 1) ? (*ineq)++ : (*equa)++; if ((*ineq)+(*equa)+2 > *maxrows) { *ar = (RAT *) RATallo(*ar,(*maxrows)*(dim+2),(*maxrows+INCR_INSYS_ROW)*(dim+2)); *maxrows += INCR_INSYS_ROW; } do { nonempty = get_line(fp,fname,in_line,line); } while (!nonempty); } /* for i */ }
void integ_rekurs( RAT *eqsum, RAT *iesum, int lev ) { val.den.i = 1; if (reknum % 1000 == 0) { fprintf(prt,"."); fflush(prt); /* 17.01.1994: include logging on file porta.log */ porta_log("."); fflush(logfile); } reknum++; if (lev == eqdim) { for (ptr = eqar+eqdim; ptr < ubea; ptr += eqrl, eqsum++) { I_RAT_sub(*eqsum,*ptr,&val); if (val.num != 0) return; } for (ptr = iear+iedim; ptr < ubia; ptr += ierl, iesum++) { I_RAT_sub(*iesum,*ptr,&val); if (val.num > 0) return; } intnum++; fprintf(fp,"(%3d) ",intnum); for (i = 0; i < eqdim; i++) fprintf(fp,"%i ",integ[i]); fprintf(fp,"\n"); } else { val.num = lowbds[lev]; osump = eqsum; nsump = eqsum+neq; for (ptr = eqar+lev; ptr < ubea; ptr += eqrl,osump++,nsump++) { I_RAT_mul(*ptr,val,nsump); I_RAT_add(*osump,*nsump,nsump); } osump = iesum; nsump = iesum+nie; for (ptr = iear+lev; ptr < ubia; ptr += ierl,osump++,nsump++) { I_RAT_mul(*ptr,val,nsump); I_RAT_add(*osump,*nsump,nsump); } for (integ[lev]=lowbds[lev]; integ[lev]<upbds[lev]; integ[lev]+=1) { integ_rekurs(eqsum+neq,iesum+nie,lev+1); osump = eqsum; nsump = eqsum+neq; for (ptr = eqar+lev; ptr < ubea; ptr += eqrl,nsump++) I_RAT_add(*nsump,*ptr,nsump); osump = iesum; nsump = iesum+nie; for (ptr = iear+lev; ptr < ubia; ptr += ierl,nsump++) I_RAT_add(*nsump,*ptr,nsump); } integ_rekurs(eqsum+neq,iesum+nie,lev+1); } }
int scan_line( RAT *rat_in, int type, int d, int line, char fname[], char *in_line, char scanned_inline[] ) /*****************************************************************/ /* * Read the string "in_line" * of "d" integers or fractions into the array rat_in * in case of type = 0 or 1, fractions are accepted: 1/2 400/5 * in case of type = 2, only integers are accepted: 1 2 400 5 * Brackets starting the line are overread. * The statistical part is also overread. * Return with 1. * * If the type = 3 * or in_line is not started by brackets or integers or '+' or '-', * scan_line2() is used to scan the string in_line. * Output is string scanned_inline then. * Return with 0 if in_line begins with a number (not counting blanks), * with 1 otherwise. * * Change by M.S. 1.6.92: * Overread also tabs. */ { char ch, *ptr; int j,*int_in; RAT val; do { ch = *(in_line++); } while (ch == ' ' || ch == '\t'); /* overread brackets () and text inside */ if (ch == '(') { do { ch = *(in_line++); if (ch == '\n') msg("%s, line %i : unexpected end of line", fname,line); } while (ch != ')'); do { ch = *(in_line++); } while (ch == ' ' || ch == '\t'); } in_line--; if ((((ch < '0' || ch > '9') && ch != '+' && ch != '-')) || type == 3 ) { /* NO POINT-LINE */ return(scan_line2(line,fname,in_line,scanned_inline)); } int_in = (int *) rat_in; /* read exactly d fractions or integers */ for (j = 0; j < d; j++,rat_in++) { val.num = (int) strtol(in_line,&ptr,10); if (ptr == in_line) msg("%s, line %i : invalid format of input file ", fname,line); /* position in_line after the number */ in_line = ptr; /* read the denominator, if type < 2 */ if (type < 2) { do { ch = *(in_line++); } while (ch == ' ' || ch == '\t'); if (ch == '/') { val.den.i = (int) strtol(in_line,&ptr,10); if (ptr == in_line || val.den.i <= 0) msg("%s, line %i : invalid denominator", fname,line); in_line = ptr; } else { /* default denominator = 1 */ in_line--; (val.den.i = 1); } } if (type == 0) *rat_in = val; else if (type == 1) I_RAT_add(val,*rat_in,rat_in); else *(int_in+j) = val.num; } /* * change by M.S. 1.7.92: * the following three lines lead to the rejection of * "(..) 1 1 # statistical part\n" * As for inequality-lines, the comment sign # should also be allowed * for point-lines. * * for (ch = getc(fp); ch != '\n' ; ch = getc(fp)) * if (ch != ' ') * msg("%sline : %i invalid format of input file ","",line); */ ch = *(in_line++); while (ch != '\n' && ch != '#') { if (ch >= '0' && ch <= '9') msg("%s, line %i : dimension error",fname,line); /* too many numbers on the line */ else if (ch != ' ' && ch != '\t') msg("%s, line %i : invalid format of input file ", fname,line); ch = *(in_line++); } return(1); }