1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the program and library             */
4    	/*         SCIP --- Solving Constraint Integer Programs                      */
5    	/*                                                                           */
6    	/*  Copyright (c) 2002-2023 Zuse Institute Berlin (ZIB)                      */
7    	/*                                                                           */
8    	/*  Licensed under the Apache License, Version 2.0 (the "License");          */
9    	/*  you may not use this file except in compliance with the License.         */
10   	/*  You may obtain a copy of the License at                                  */
11   	/*                                                                           */
12   	/*      http://www.apache.org/licenses/LICENSE-2.0                           */
13   	/*                                                                           */
14   	/*  Unless required by applicable law or agreed to in writing, software      */
15   	/*  distributed under the License is distributed on an "AS IS" BASIS,        */
16   	/*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17   	/*  See the License for the specific language governing permissions and      */
18   	/*  limitations under the License.                                           */
19   	/*                                                                           */
20   	/*  You should have received a copy of the Apache-2.0 license                */
21   	/*  along with SCIP; see the file LICENSE. If not visit scipopt.org.         */
22   	/*                                                                           */
23   	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24   	
25   	/**@file   reader_mps.c
26   	 * @ingroup DEFPLUGINS_READER
27   	 * @brief  (extended) MPS file reader
28   	 * @author Thorsten Koch
29   	 * @author Tobias Achterberg
30   	 * @author Marc Pfetsch
31   	 * @author Stefan Heinz
32   	 * @author Stefan Vigerske
33   	 * @author Michael Winkler
34   	 *
35   	 * This reader/writer handles MPS files in extended MPS format, as it
36   	 * is used by CPLEX. In the extended format the limits on variable
37   	 * name lengths and coefficients are considerably relaxed. The columns
38   	 * in the format are then separated by whitespaces.
39   	 *
40   	 * @todo Check whether constructing the names for aggregated constraint yields name clashes (aggrXXX).
41   	 */
42   	
43   	/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
44   	
45   	#include "blockmemshell/memory.h"
46   	#include <ctype.h>
47   	#include "scip/cons_and.h"
48   	#include "scip/cons_bounddisjunction.h"
49   	#include "scip/cons_nonlinear.h"
50   	#include "scip/cons_indicator.h"
51   	#include "scip/cons_knapsack.h"
52   	#include "scip/cons_linear.h"
53   	#include "scip/cons_logicor.h"
54   	#include "scip/cons_setppc.h"
55   	#include "scip/cons_sos1.h"
56   	#include "scip/cons_sos2.h"
57   	#include "scip/cons_varbound.h"
58   	#include "scip/pub_cons.h"
59   	#include "scip/pub_fileio.h"
60   	#include "scip/pub_message.h"
61   	#include "scip/pub_misc.h"
62   	#include "scip/pub_misc_sort.h"
63   	#include "scip/pub_reader.h"
64   	#include "scip/pub_var.h"
65   	#include "scip/reader_mps.h"
66   	#include "scip/scip_cons.h"
67   	#include "scip/scip_mem.h"
68   	#include "scip/scip_message.h"
69   	#include "scip/scip_numerics.h"
70   	#include "scip/scip_param.h"
71   	#include "scip/scip_prob.h"
72   	#include "scip/scip_reader.h"
73   	#include "scip/scip_solvingstats.h"
74   	#include "scip/scip_var.h"
75   	#include <stdlib.h>
76   	#include <string.h>
77   	
78   	#define READER_NAME             "mpsreader"
79   	#define READER_DESC             "file reader for MIQPs in IBM's Mathematical Programming System format"
80   	#define READER_EXTENSION        "mps"
81   	
82   	#define DEFAULT_LINEARIZE_ANDS         TRUE  /**< should possible \"and\" constraint be linearized when writing the mps file? */
83   	#define DEFAULT_AGGRLINEARIZATION_ANDS TRUE  /**< should an aggregated linearization for and constraints be used? */
84   	
85   	/*
86   	 * mps reader internal methods
87   	 */
88   	
89   	#define MPS_MAX_LINELEN  1024
90   	#define MPS_MAX_NAMELEN   256
91   	#define MPS_MAX_VALUELEN   26
92   	#define MPS_MAX_FIELDLEN   20
93   	
94   	#define PATCH_CHAR    '_'
95   	#define BLANK         ' '
96   	
97   	/** MPS reading data */
98   	struct SCIP_ReaderData
99   	{
100  	   SCIP_Bool             linearizeands;
101  	   SCIP_Bool             aggrlinearizationands;
102  	};
103  	
104  	/** enum containing all mps sections */
105  	enum MpsSection
106  	{
107  	   MPS_NAME,
108  	   MPS_OBJSEN,
109  	   MPS_OBJNAME,
110  	   MPS_ROWS,
111  	   MPS_USERCUTS,
112  	   MPS_LAZYCONS,
113  	   MPS_COLUMNS,
114  	   MPS_RHS,
115  	   MPS_RANGES,
116  	   MPS_BOUNDS,
117  	   MPS_SOS,
118  	   MPS_QUADOBJ,
119  	   MPS_QMATRIX,
120  	   MPS_QCMATRIX,
121  	   MPS_INDICATORS,
122  	   MPS_ENDATA
123  	};
124  	typedef enum MpsSection MPSSECTION;
125  	
126  	/** mps input structure */
127  	struct MpsInput
128  	{
129  	   MPSSECTION            section;
130  	   SCIP_FILE*            fp;
131  	   int                   lineno;
132  	   SCIP_OBJSENSE         objsense;
133  	   SCIP_Bool             haserror;
134  	   char                  buf[MPS_MAX_LINELEN];
135  	   const char*           f0;
136  	   const char*           f1;
137  	   const char*           f2;
138  	   const char*           f3;
139  	   const char*           f4;
140  	   const char*           f5;
141  	   char                  probname[MPS_MAX_NAMELEN];
142  	   char                  objname [MPS_MAX_NAMELEN];
143  	   SCIP_Bool             initialconss;       /**< should model constraints be marked as initial? */
144  	   SCIP_Bool             dynamicconss;       /**< should model constraints be subject to aging? */
145  	   SCIP_Bool             dynamiccols;        /**< should columns be added and removed dynamically to the LP? */
146  	   SCIP_Bool             dynamicrows;        /**< should rows be added and removed dynamically to the LP? */
147  	   SCIP_Bool             isinteger;
148  	   SCIP_Bool             isnewformat;
149  	};
150  	typedef struct MpsInput MPSINPUT;
151  	
152  	/** sparse matrix representation */
153  	struct SparseMatrix
154  	{
155  	   SCIP_Real*            values;             /**< matrix element */
156  	   SCIP_VAR**            columns;            /**< corresponding variables */
157  	   const char**          rows;               /**< corresponding constraint names */ 
158  	   int                   nentries;           /**< number of elements in the arrays */
159  	   int                   sentries;           /**< number of slots in the arrays */
160  	};
161  	typedef struct SparseMatrix SPARSEMATRIX;
162  	
163  	/** struct for mapping cons names to numbers */
164  	struct ConsNameFreq
165  	{
166  	   const char*           consname;           /**< name of the constraint */
167  	   int                   freq;               /**< how often we have seen the name */
168  	};
169  	typedef struct ConsNameFreq CONSNAMEFREQ;
170  	
171  	/** creates the mps input structure */
172  	static
173  	SCIP_RETCODE mpsinputCreate(
174  	   SCIP*                 scip,               /**< SCIP data structure */
175  	   MPSINPUT**            mpsi,               /**< mps input structure */
176  	   SCIP_FILE*            fp                  /**< file object for the input file */
177  	   )
178  	{
179  	   assert(mpsi != NULL);
180  	   assert(fp != NULL);
181  	
182  	   SCIP_CALL( SCIPallocBlockMemory(scip, mpsi) );
183  	
184  	   (*mpsi)->section     = MPS_NAME;
185  	   (*mpsi)->fp          = fp;
186  	   (*mpsi)->lineno      = 0;
187  	   (*mpsi)->objsense    = SCIP_OBJSENSE_MINIMIZE;
188  	   (*mpsi)->haserror    = FALSE;
189  	   (*mpsi)->isinteger   = FALSE;
190  	   (*mpsi)->isnewformat = FALSE;
191  	   (*mpsi)->buf     [0] = '\0';
192  	   (*mpsi)->probname[0] = '\0';
193  	   (*mpsi)->objname [0] = '\0';
194  	   (*mpsi)->f0          = NULL;
195  	   (*mpsi)->f1          = NULL;
196  	   (*mpsi)->f2          = NULL;
197  	   (*mpsi)->f3          = NULL;
198  	   (*mpsi)->f4          = NULL;
199  	   (*mpsi)->f5          = NULL;
200  	
201  	   SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &((*mpsi)->initialconss)) );
202  	   SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &((*mpsi)->dynamicconss)) );
203  	   SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &((*mpsi)->dynamiccols)) );
204  	   SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &((*mpsi)->dynamicrows)) );
205  	
206  	   return SCIP_OKAY;
207  	}
208  	
209  	/** free the mps input structure */
210  	static
211  	void mpsinputFree(
212  	   SCIP*                 scip,               /**< SCIP data structure */
213  	   MPSINPUT**            mpsi                /**< mps input structure */
214  	   )
215  	{
216  	   SCIPfreeBlockMemory(scip, mpsi);
217  	}
218  	
219  	/** returns the current section */
220  	static
221  	MPSSECTION mpsinputSection(
222  	   const MPSINPUT*       mpsi                /**< mps input structure */
223  	   )
224  	{
225  	   assert(mpsi != NULL);
226  	
227  	   return mpsi->section;
228  	}
229  	
230  	/** return the current value of field 0 */
231  	static
232  	const char* mpsinputField0(
233  	   const MPSINPUT*       mpsi                /**< mps input structure */
234  	   )
235  	{
236  	   assert(mpsi != NULL);
237  	
238  	   return mpsi->f0;
239  	}
240  	
241  	/** return the current value of field 1 */
242  	static
243  	const char* mpsinputField1(
244  	   const MPSINPUT*       mpsi                /**< mps input structure */
245  	   )
246  	{
247  	   assert(mpsi != NULL);
248  	
249  	   return mpsi->f1;
250  	}
251  	
252  	/** return the current value of field 2 */
253  	static
254  	const char* mpsinputField2(
255  	   const MPSINPUT*       mpsi                /**< mps input structure */
256  	   )
257  	{
258  	   assert(mpsi != NULL);
259  	
260  	   return mpsi->f2;
261  	}
262  	
263  	/** return the current value of field 3 */
264  	static
265  	const char* mpsinputField3(
266  	   const MPSINPUT*       mpsi                /**< mps input structure */
267  	   )
268  	{
269  	   assert(mpsi != NULL);
270  	
271  	   return mpsi->f3;
272  	}
273  	
274  	/** return the current value of field 4 */
275  	static
276  	const char* mpsinputField4(
277  	   const MPSINPUT*       mpsi                /**< mps input structure */
278  	   )
279  	{
280  	   assert(mpsi != NULL);
281  	
282  	   return mpsi->f4;
283  	}
284  	
285  	/** return the current value of field 5 */
286  	static
287  	const char* mpsinputField5(
288  	   const MPSINPUT*       mpsi                /**< mps input structure */
289  	   )
290  	{
291  	   assert(mpsi != NULL);
292  	
293  	   return mpsi->f5;
294  	}
295  	
296  	/** returns the objective name */
297  	static
298  	const char* mpsinputObjname(
299  	   const MPSINPUT*       mpsi                /**< mps input structure */
300  	   )
301  	{
302  	   assert(mpsi != NULL);
303  	
304  	   return mpsi->objname;
305  	}
306  	
307  	/** returns the objective sense */
308  	static
309  	SCIP_OBJSENSE mpsinputObjsense(
310  	   const MPSINPUT*       mpsi                /**< mps input structure */
311  	   )
312  	{
313  	   assert(mpsi != NULL);
314  	
315  	   return mpsi->objsense;
316  	}
317  	
318  	/** returns if an error was detected */
319  	static
320  	SCIP_Bool mpsinputHasError(
321  	   const MPSINPUT*       mpsi                /**< mps input structure */
322  	   )
323  	{
324  	   assert(mpsi != NULL);
325  	
326  	   return mpsi->haserror;
327  	}
328  	
329  	/** returns the value of the Bool "is integer" in the mps input */
330  	static
331  	SCIP_Bool mpsinputIsInteger(
332  	   const MPSINPUT*       mpsi                /**< mps input structure */
333  	   )
334  	{
335  	   assert(mpsi != NULL);
336  	
337  	   return mpsi->isinteger;
338  	}
339  	
340  	/** set the section in the mps input structure to given section */
341  	static
342  	void mpsinputSetSection(
343  	   MPSINPUT*             mpsi,               /**< mps input structure */
344  	   MPSSECTION            section             /**< section that is set */
345  	   )
346  	{
347  	   assert(mpsi != NULL);
348  	
349  	   mpsi->section = section;
350  	}
351  	
352  	/** set the problem name in the mps input structure to given problem name */
353  	static
354  	void mpsinputSetProbname(
355  	   MPSINPUT*             mpsi,               /**< mps input structure */
356  	   const char*           probname            /**< name of the problem to set */
357  	   )
358  	{
359  	   assert(mpsi     != NULL);
360  	   assert(probname != NULL);
361  	   assert(strlen(probname) < sizeof(mpsi->probname));
362  	
363  	   (void)SCIPmemccpy(mpsi->probname, probname, '\0', MPS_MAX_NAMELEN - 1);
364  	}
365  	
366  	/** set the objective name in the mps input structure to given objective name */
367  	static
368  	void mpsinputSetObjname(
369  	   MPSINPUT*             mpsi,               /**< mps input structure */
370  	   const char*           objname             /**< name of the objective function to set */
371  	   )
372  	{
373  	   assert(mpsi != NULL);
374  	   assert(objname != NULL);
375  	   assert(strlen(objname) < sizeof(mpsi->objname));
376  	
377  	   (void)SCIPmemccpy(mpsi->objname, objname, '\0', MPS_MAX_NAMELEN - 1);
378  	}
379  	
380  	/** set the objective sense in the mps input structure to given objective sense */
381  	static
382  	void mpsinputSetObjsense(
383  	   MPSINPUT*             mpsi,               /**< mps input structure */
384  	   SCIP_OBJSENSE         sense               /**< sense of the objective function */
385  	   )
386  	{
387  	   assert(mpsi != NULL);
388  	
389  	   mpsi->objsense = sense;
390  	}
391  	
392  	static
393  	void mpsinputSyntaxerror(
394  	   MPSINPUT*             mpsi                /**< mps input structure */
395  	   )
396  	{
397  	   assert(mpsi != NULL);
398  	
399  	   SCIPerrorMessage("Syntax error in line %d\n", mpsi->lineno);
400  	   mpsi->section  = MPS_ENDATA;
401  	   mpsi->haserror = TRUE;
402  	}
403  	
404  	/** method post a ignore message  */
405  	static
406  	void mpsinputEntryIgnored(
407  	   SCIP*                 scip,               /**< SCIP data structure */
408  	   MPSINPUT*             mpsi,               /**< mps input structure */
409  	   const char*           what,               /**< what get ignored */
410  	   const char*           what_name,          /**< name of that object */
411  	   const char*           entity,             /**< entity */
412  	   const char*           entity_name,        /**< entity name */
413  	   SCIP_VERBLEVEL        verblevel           /**< SCIP verblevel for this message */
414  	   )
415  	{
416  	   assert(mpsi        != NULL);
417  	   assert(what        != NULL);
418  	   assert(what_name   != NULL);
419  	   assert(entity      != NULL);
420  	   assert(entity_name != NULL);
421  	
422  	   SCIPverbMessage(scip, verblevel, NULL,
423  	      "Warning line %d: %s \"%s\" for %s \"%s\" ignored\n", mpsi->lineno, what, what_name, entity, entity_name);
424  	}
425  	
426  	/** fill the line from \p pos up to column 80 with blanks. */
427  	static
428  	void clearFrom(
429  	   char*                 buf,                /**< buffer to clear */
430  	   unsigned int          pos                 /**< position to start the clearing process */
431  	   )
432  	{
433  	   unsigned int i;
434  	
435  	   for(i = pos; i < 80; i++)
436  	      buf[i] = BLANK;
437  	   buf[80] = '\0';
438  	}
439  	
440  	/** change all blanks inside a field to #PATCH_CHAR. */
441  	static
442  	void patchField(
443  	   char*                 buf,                /**< buffer to patch */
444  	   int                   beg,                /**< position to begin */
445  	   int                   end                 /**< position to end */
446  	   )
447  	{
448  	   int i;
449  	
450  	   while( (beg <= end) && (buf[end] == BLANK) )
451  	      end--;
452  	
453  	   while( (beg <= end) && (buf[beg] == BLANK) )
454  	      beg++;
455  	
456  	   for( i = beg; i <= end; i++ )
457  	      if( buf[i] == BLANK )
458  	         buf[i] = PATCH_CHAR;
459  	}
460  	
461  	/** read a mps format data line and parse the fields. */
462  	static
463  	SCIP_Bool mpsinputReadLine(
464  	   MPSINPUT*             mpsi                /**< mps input structure */
465  	   )
466  	{
467  	   unsigned int len;
468  	   unsigned int i;
469  	   int space;
470  	   char* s;
471  	   SCIP_Bool is_marker;
472  	   SCIP_Bool is_empty;
473  	   char* nexttok;
474  	
475  	   do
476  	   {
477  	      mpsi->f0 = mpsi->f1 = mpsi->f2 = mpsi->f3 = mpsi->f4 = mpsi->f5 = 0;
478  	      is_marker = FALSE;
479  	
480  	      /* Read until we have not a comment line. */
481  	      do
482  	      {
483  	         mpsi->buf[MPS_MAX_LINELEN-1] = '\0';
484  	         if( NULL == SCIPfgets(mpsi->buf, (int) sizeof(mpsi->buf), mpsi->fp) )
485  	            return FALSE;
486  	         mpsi->lineno++;
487  	      }
488  	      while( *mpsi->buf == '*' );   /* coverity[a_loop_bound] */
489  	
490  	      /* Normalize line */
491  	      len = (unsigned int) strlen(mpsi->buf);
492  	
493  	      for( i = 0; i < len; i++ )
494  	         if( (mpsi->buf[i] == '\t') || (mpsi->buf[i] == '\n') || (mpsi->buf[i] == '\r') )
495  	            mpsi->buf[i] = BLANK;
496  	
497  	      if( len < 80 )
498  	         clearFrom(mpsi->buf, len);
499  	
500  	      SCIPdebugMessage("line %d: <%s>\n", mpsi->lineno, mpsi->buf);
501  	
502  	      assert(strlen(mpsi->buf) >= 80);
503  	
504  	      /* Look for new section */
505  	      if( *mpsi->buf != BLANK )
506  	      {
507  	         mpsi->f0 = SCIPstrtok(&mpsi->buf[0], " ", &nexttok);
508  	
509  	         assert(mpsi->f0 != 0);
510  	
511  	         mpsi->f1 = SCIPstrtok(NULL, " ", &nexttok);
512  	
513  	         return TRUE;
514  	      }
515  	
516  	      /* If we decide to use the new format we never revert this decision */
517  	      if( !mpsi->isnewformat )
518  	      {
519  	         /* Test for fixed format comments */
520  	         if( (mpsi->buf[14] == '$') && (mpsi->buf[13] == ' ') )
521  	            clearFrom(mpsi->buf, 14);
522  	         else if( (mpsi->buf[39] == '$') && (mpsi->buf[38] == ' ') )
523  	            clearFrom(mpsi->buf, 39);
524  	
525  	         /* Test for fixed format */
526  	         space = mpsi->buf[12] | mpsi->buf[13]
527  	            | mpsi->buf[22] | mpsi->buf[23]
528  	            | mpsi->buf[36] | mpsi->buf[37] | mpsi->buf[38]
529  	            | mpsi->buf[47] | mpsi->buf[48]
530  	            | mpsi->buf[61] | mpsi->buf[62] | mpsi->buf[63];
531  	
532  	         if( space == BLANK )
533  	         {
534  	            /* Now we have space at the right positions.
535  	             * But are there also the non space where they
536  	             * should be ?
537  	             */
538  	            SCIP_Bool number;
539  	
540  	            number = isdigit((unsigned char)mpsi->buf[24]) || isdigit((unsigned char)mpsi->buf[25])
541  	               || isdigit((unsigned char)mpsi->buf[26]) || isdigit((unsigned char)mpsi->buf[27])
542  	               || isdigit((unsigned char)mpsi->buf[28]) || isdigit((unsigned char)mpsi->buf[29])
543  	               || isdigit((unsigned char)mpsi->buf[30]) || isdigit((unsigned char)mpsi->buf[31])
544  	               || isdigit((unsigned char)mpsi->buf[32]) || isdigit((unsigned char)mpsi->buf[33])
545  	               || isdigit((unsigned char)mpsi->buf[34]) || isdigit((unsigned char)mpsi->buf[35]);
546  	
547  	            /* len < 14 is handle ROW lines with embedded spaces
548  	             * in the names correctly
549  	             */
550  	            if( number || len < 14 )
551  	            {
552  	               /* We assume fixed format, so we patch possible embedded spaces. */
553  	               patchField(mpsi->buf,  4, 12);
554  	               patchField(mpsi->buf, 14, 22);
555  	               patchField(mpsi->buf, 39, 47);
556  	            }
557  	            else
558  	            {
559  	               if( mpsi->section == MPS_COLUMNS || mpsi->section == MPS_RHS
560  	                  || mpsi->section == MPS_RANGES  || mpsi->section == MPS_BOUNDS )
561  	                  mpsi->isnewformat = TRUE;
562  	            }
563  	         }
564  	         else
565  	         {
566  	            mpsi->isnewformat = TRUE;
567  	         }
568  	      }
569  	      s = &mpsi->buf[1];
570  	
571  	      /* At this point it is not clear if we have a indicator field.
572  	       * If there is none (e.g. empty) f1 will be the first name field.
573  	       * If there is one, f2 will be the first name field.
574  	       *
575  	       * Initially comment marks '$' are only allowed in the beginning
576  	       * of the 2nd and 3rd name field. We test all fields but the first.
577  	       * This makes no difference, since if the $ is at the start of a value
578  	       * field, the line will be erroneous anyway.
579  	       */
580  	      do
581  	      {
582  	         if( NULL == (mpsi->f1 = SCIPstrtok(s, " ", &nexttok)) )
583  	            break;
584  	
585  	         if( (NULL == (mpsi->f2 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f2 == '$') )
586  	         {
587  	            mpsi->f2 = 0;
588  	            break;
589  	         }
590  	         if( !strcmp(mpsi->f2, "'MARKER'") )
591  	            is_marker = TRUE;
592  	
593  	         if( (NULL == (mpsi->f3 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f3 == '$') )
594  	         {
595  	            mpsi->f3 = 0;
596  	            break;
597  	         }
598  	         if( is_marker )
599  	         {
600  	            if( !strcmp(mpsi->f3, "'INTORG'") )
601  	               mpsi->isinteger = TRUE;
602  	            else if( !strcmp(mpsi->f3, "'INTEND'") )
603  	               mpsi->isinteger = FALSE;
604  	            else
605  	               break; /* unknown marker */
606  	         }
607  	         if( !strcmp(mpsi->f3, "'MARKER'") )
608  	            is_marker = TRUE;
609  	
610  	         if( (NULL == (mpsi->f4 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f4 == '$') )
611  	         {
612  	            mpsi->f4 = 0;
613  	            break;
614  	         }
615  	         if( is_marker )
616  	         {
617  	            if( !strcmp(mpsi->f4, "'INTORG'") )
618  	               mpsi->isinteger = TRUE;
619  	            else if( !strcmp(mpsi->f4, "'INTEND'") )
620  	               mpsi->isinteger = FALSE;
621  	            else
622  	               break; /* unknown marker */
623  	         }
624  	         if( (NULL == (mpsi->f5 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f5 == '$') )
625  	            mpsi->f5 = 0;
626  	      }
627  	      while( FALSE );
628  	
629  	      /* check for empty lines */
630  	      is_empty = (mpsi->f0 == NULL && mpsi->f1 == NULL);
631  	   }
632  	   while( is_marker || is_empty );
633  	
634  	   return TRUE;
635  	}
636  	
637  	/** Insert \p str as field 4 and shift all other fields up. */
638  	static
639  	void mpsinputInsertField4(
640  	   MPSINPUT*             mpsi,               /**< mps input structure */
641  	   const char*           str                 /**< str to insert */
642  	   )
643  	{
644  	   assert(mpsi != NULL);
645  	   assert(str != NULL);
646  	
647  	   mpsi->f5 = mpsi->f4;
648  	   mpsi->f4 = str;
649  	}
650  	
651  	/** Insert \p name as field 1 or 2 and shift all other fields up. */
652  	static
653  	void mpsinputInsertName(
654  	   MPSINPUT*             mpsi,               /**< mps input structure */
655  	   const char*           name,               /**< name to insert */
656  	   SCIP_Bool             second              /**< insert as second field? */
657  	   )
658  	{
659  	   assert(mpsi != NULL);
660  	   assert(name != NULL);
661  	
662  	   mpsi->f5 = mpsi->f4;
663  	   mpsi->f4 = mpsi->f3;
664  	   mpsi->f3 = mpsi->f2;
665  	
666  	   if( second )
667  	      mpsi->f2 = name;
668  	   else
669  	   {
670  	      mpsi->f2 = mpsi->f1;
671  	      mpsi->f1 = name;
672  	   }
673  	}
674  	
675  	/** Add variable name to storage */
676  	static
677  	SCIP_RETCODE addVarNameToStorage(
678  	   SCIP*                 scip,               /**< SCIP data structure */
679  	   const char***         varnames,           /**< the variable name storage */
680  	   int*                  varnamessize,       /**< the size of the variable names storage */
681  	   int*                  nvars,              /**< the number of variables */
682  	   const char*           colname             /**< the name of the variable */
683  	   )
684  	{
685  	   assert(scip != NULL);
686  	
687  	   if( varnames != NULL )
688  	   {
689  	      SCIP_CALL( SCIPensureBlockMemoryArray(scip, varnames, varnamessize, (*nvars) + 1) );
690  	      SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*varnames)[(*nvars)], colname, strlen(colname) + 1) );     /*lint !e866*/
691  	      (*nvars)++;
692  	   }
693  	
694  	   return SCIP_OKAY;
695  	}
696  	
697  	/** Add constraint name to storage */
698  	static
699  	SCIP_RETCODE addConsNameToStorage(
700  	   SCIP*                 scip,               /**< SCIP data structure */
701  	   const char***         consnames,          /**< the constraint name storage */
702  	   int*                  consnamessize,      /**< the size of the constraint names storage */
703  	   int*                  ncons,              /**< the number of constraint */
704  	   const char*           rowname             /**< the name of the constraint */
705  	   )
706  	{
707  	   assert(scip != NULL);
708  	
709  	   if( consnames != NULL )
710  	   {
711  	      SCIP_CALL( SCIPensureBlockMemoryArray(scip, consnames, consnamessize, (*ncons) + 1) );
712  	      SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consnames)[(*ncons)], rowname, strlen(rowname) + 1) );    /*lint !e866*/
713  	      (*ncons)++;
714  	   }
715  	
716  	   return SCIP_OKAY;
717  	}
718  	
719  	/** Process NAME section. */
720  	static
721  	SCIP_RETCODE readName(
722  	   SCIP*                 scip,               /**< SCIP data structure */
723  	   MPSINPUT*             mpsi                /**< mps input structure */
724  	   )
725  	{
726  	   assert(mpsi != NULL);
727  	
728  	   SCIPdebugMsg(scip, "read problem name\n");
729  	
730  	   /* This has to be the Line with the NAME section. */
731  	   if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL || strcmp(mpsinputField0(mpsi), "NAME") )
732  	   {
733  	      mpsinputSyntaxerror(mpsi);
734  	      return SCIP_OKAY;
735  	   }
736  	
737  	   /* Sometimes the name is omitted. */
738  	   mpsinputSetProbname(mpsi, (mpsinputField1(mpsi) == 0) ? "_MPS_" : mpsinputField1(mpsi));
739  	
740  	   /* This hat to be a new section */
741  	   /* coverity[tainted_data] */
742  	   if( !mpsinputReadLine(mpsi) || (mpsinputField0(mpsi) == NULL) )
743  	   {
744  	      mpsinputSyntaxerror(mpsi);
745  	      return SCIP_OKAY;
746  	   }
747  	
748  	   if( !strncmp(mpsinputField0(mpsi), "ROWS", 4) )
749  	      mpsinputSetSection(mpsi, MPS_ROWS);
750  	   else if( !strncmp(mpsinputField0(mpsi), "USERCUTS", 8) )
751  	      mpsinputSetSection(mpsi, MPS_USERCUTS);
752  	   else if( !strncmp(mpsinputField0(mpsi), "LAZYCONS", 8) )
753  	      mpsinputSetSection(mpsi, MPS_LAZYCONS);
754  	   else if( !strncmp(mpsinputField0(mpsi), "OBJSEN", 6) )
755  	      mpsinputSetSection(mpsi, MPS_OBJSEN);
756  	   else if( !strncmp(mpsinputField0(mpsi), "OBJNAME", 7) )
757  	      mpsinputSetSection(mpsi, MPS_OBJNAME);
758  	   else
759  	   {
760  	      mpsinputSyntaxerror(mpsi);
761  	      return SCIP_OKAY;
762  	   }
763  	
764  	   return SCIP_OKAY;
765  	}
766  	
767  	/** Process OBJSEN section. This Section is a CPLEX extension. */
768  	static
769  	SCIP_RETCODE readObjsen(
770  	   SCIP*                 scip,               /**< SCIP data structure */
771  	   MPSINPUT*             mpsi                /**< mps input structure */
772  	   )
773  	{
774  	   assert(mpsi != NULL);
775  	
776  	   SCIPdebugMsg(scip, "read objective sense\n");
777  	
778  	   /* Although this is not explicitly in the MPS extensions as provided by CPLEX, some other MIP solvers
779  	    * (in particular gurobi), put 'MIN' or 'MAX' as the input field on the same line as the section declaration */
780  	   if( mpsinputField1(mpsi) == NULL){
781  	       /* Normal Cplex extension; info should be on the next line, in field 1 */
782  	       /* This has to be the Line with MIN or MAX. */
783  	       if( !mpsinputReadLine(mpsi) || (mpsinputField1(mpsi) == NULL) )
784  	       {
785  	           mpsinputSyntaxerror(mpsi);
786  	           return SCIP_OKAY;
787  	       }
788  	   }
789  	   /* Otherwise, the input should read e.g. "OBJSENSE MAX" so that MAX is also the first field */
790  	
791  	   if( !strncmp(mpsinputField1(mpsi), "MIN", 3) )
792  	      mpsinputSetObjsense(mpsi, SCIP_OBJSENSE_MINIMIZE);
793  	   else if( !strncmp(mpsinputField1(mpsi), "MAX", 3) )
794  	      mpsinputSetObjsense(mpsi, SCIP_OBJSENSE_MAXIMIZE);
795  	   else
796  	   {
797  	      mpsinputSyntaxerror(mpsi);
798  	      return SCIP_OKAY;
799  	   }
800  	
801  	   /* Look for ROWS, USERCUTS, LAZYCONS, or OBJNAME Section */
802  	   /* coverity[tainted_data] */
803  	   if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL )
804  	   {
805  	      mpsinputSyntaxerror(mpsi);
806  	      return SCIP_OKAY;
807  	   }
808  	
809  	   if( !strcmp(mpsinputField0(mpsi), "ROWS") )
810  	      mpsinputSetSection(mpsi, MPS_ROWS);
811  	   else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
812  	      mpsinputSetSection(mpsi, MPS_USERCUTS);
813  	   else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
814  	      mpsinputSetSection(mpsi, MPS_LAZYCONS);
815  	   else if( !strcmp(mpsinputField0(mpsi), "OBJNAME") )
816  	      mpsinputSetSection(mpsi, MPS_OBJNAME);
817  	   else
818  	   {
819  	      mpsinputSyntaxerror(mpsi);
820  	      return SCIP_OKAY;
821  	   }
822  	
823  	   return SCIP_OKAY;
824  	}
825  	
826  	/** Process OBJNAME section. This Section is a CPLEX extension. */
827  	static
828  	SCIP_RETCODE readObjname(
829  	   SCIP*                 scip,               /**< SCIP data structure */
830  	   MPSINPUT*             mpsi                /**< mps input structure */
831  	   )
832  	{
833  	   assert(mpsi != NULL);
834  	
835  	   SCIPdebugMsg(scip, "read objective name\n");
836  	
837  	   /* This has to be the Line with the name. */
838  	   if( !mpsinputReadLine(mpsi) || mpsinputField1(mpsi) == NULL )
839  	   {
840  	      mpsinputSyntaxerror(mpsi);
841  	      return SCIP_OKAY;
842  	   }
843  	
844  	   mpsinputSetObjname(mpsi, mpsinputField1(mpsi));
845  	
846  	   /* Look for ROWS, USERCUTS, or LAZYCONS Section */
847  	   /* coverity[tainted_data] */
848  	   if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL )
849  	   {
850  	      mpsinputSyntaxerror(mpsi);
851  	      return SCIP_OKAY;
852  	   }
853  	   if( !strcmp(mpsinputField0(mpsi), "ROWS") )
854  	      mpsinputSetSection(mpsi, MPS_ROWS);
855  	   else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
856  	      mpsinputSetSection(mpsi, MPS_USERCUTS);
857  	   else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
858  	      mpsinputSetSection(mpsi, MPS_LAZYCONS);
859  	   else
860  	      mpsinputSyntaxerror(mpsi);
861  	
862  	   return SCIP_OKAY;
863  	}
864  	
865  	/** Process ROWS, USERCUTS, or LAZYCONS section. */
866  	static
867  	SCIP_RETCODE readRows(
868  	   MPSINPUT*             mpsi,               /**< mps input structure */
869  	   SCIP*                 scip,               /**< SCIP data structure */
870  	   const char***         consnames,          /**< storage for the constraint names, or NULL */
871  	   int*                  consnamessize,      /**< the size of the constraint names storage, or NULL */
872  	   int*                  nconsnames          /**< the number of stored constraint names, or NULL */
873  	   )
874  	{
875  	   SCIPdebugMsg(scip, "read rows\n");
876  	
877  	   /* coverity[tainted_data] */
878  	   while( mpsinputReadLine(mpsi) )
879  	   {
880  	      if( mpsinputField0(mpsi) != NULL )
881  	      {
882  	         if( !strcmp(mpsinputField0(mpsi), "ROWS") )
883  	            mpsinputSetSection(mpsi, MPS_ROWS);
884  	         else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
885  	            mpsinputSetSection(mpsi, MPS_USERCUTS);
886  	         else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
887  	            mpsinputSetSection(mpsi, MPS_LAZYCONS);
888  	         else if( !strcmp(mpsinputField0(mpsi), "COLUMNS") )
889  	            mpsinputSetSection(mpsi, MPS_COLUMNS);
890  	         else
891  	            mpsinputSyntaxerror(mpsi);
892  	
893  	         return SCIP_OKAY;
894  	      }
895  	
896  	      if( *mpsinputField1(mpsi) == 'N' )
897  	      {
898  	         if( *mpsinputObjname(mpsi) == '\0' )
899  	            mpsinputSetObjname(mpsi, mpsinputField2(mpsi));
900  	         else
901  	            mpsinputEntryIgnored(scip, mpsi, "row", mpsinputField2(mpsi), "objective function", "N", SCIP_VERBLEVEL_NORMAL);
902  	      }
903  	      else
904  	      {
905  	         SCIP_CONS* cons;
906  	         SCIP_Bool initial;
907  	         SCIP_Bool separate;
908  	         SCIP_Bool enforce;
909  	         SCIP_Bool check;
910  	         SCIP_Bool propagate;
911  	         SCIP_Bool local;
912  	         SCIP_Bool modifiable;
913  	         SCIP_Bool dynamic;
914  	         SCIP_Bool removable;
915  	
916  	         cons = SCIPfindCons(scip, mpsinputField2(mpsi));
917  	         if( cons != NULL )
918  	            break;
919  	
920  	         initial = mpsi->initialconss && (mpsinputSection(mpsi) == MPS_ROWS);
921  	         separate = TRUE;
922  	         enforce = (mpsinputSection(mpsi) != MPS_USERCUTS);
923  	         check = (mpsinputSection(mpsi) != MPS_USERCUTS);
924  	         propagate = TRUE;
925  	         local = FALSE;
926  	         modifiable = FALSE;
927  	         dynamic = mpsi->dynamicconss;
928  	         removable = mpsi->dynamicrows || (mpsinputSection(mpsi) == MPS_USERCUTS);
929  	
930  	         switch(*mpsinputField1(mpsi))
931  	         {
932  	         case 'G' :
933  	            SCIP_CALL( SCIPcreateConsLinear(scip, &cons, mpsinputField2(mpsi), 0, NULL, NULL, 0.0, SCIPinfinity(scip),
934  	                  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
935  	            break;
936  	         case 'E' :
937  	            SCIP_CALL( SCIPcreateConsLinear(scip, &cons, mpsinputField2(mpsi), 0, NULL, NULL, 0.0, 0.0,
938  	                  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
939  	            break;
940  	         case 'L' :
941  	            SCIP_CALL( SCIPcreateConsLinear(scip, &cons, mpsinputField2(mpsi), 0, NULL, NULL, -SCIPinfinity(scip), 0.0,
942  	                  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
943  	            break;
944  	         default :
945  	            mpsinputSyntaxerror(mpsi);
946  	            return SCIP_OKAY;
947  	         }
948  	         SCIP_CALL( SCIPaddCons(scip, cons) );
949  	         SCIP_CALL( SCIPreleaseCons(scip, &cons) );
950  	
951  	         /* if the file is of type cor, then the constraint names must be stored */
952  	         SCIP_CALL( addConsNameToStorage(scip, consnames, consnamessize, nconsnames, mpsinputField2(mpsi)) );
953  	      }
954  	   }
955  	   mpsinputSyntaxerror(mpsi);
956  	
957  	   return SCIP_OKAY;
958  	}
959  	
960  	/** Process COLUMNS section. */
961  	static
962  	SCIP_RETCODE readCols(
963  	   MPSINPUT*             mpsi,               /**< mps input structure */
964  	   SCIP*                 scip,               /**< SCIP data structure */
965  	   const char***         varnames,           /**< storage for the variable names, or NULL */
966  	   int*                  varnamessize,       /**< the size of the variable names storage, or NULL */
967  	   int*                  nvarnames           /**< the number of stored variable names, or NULL */
968  	   )
969  	{
970  	   char          colname[MPS_MAX_NAMELEN] = { '\0' };
971  	   SCIP_CONS*    cons;
972  	   SCIP_VAR*     var;
973  	   SCIP_Real     val;
974  	   SCIP_Bool     usevartable;
975  	
976  	   SCIPdebugMsg(scip, "read columns\n");
977  	
978  	   var = NULL;
979  	   SCIP_CALL( SCIPgetBoolParam(scip, "misc/usevartable", &usevartable) );
980  	
981  	   while( mpsinputReadLine(mpsi) )
982  	   {
983  	      if( mpsinputField0(mpsi) != 0 )
984  	      {
985  	         if( strcmp(mpsinputField0(mpsi), "RHS") )
986  	            break;
987  	
988  	         /* add the last variable to the problem */
989  	         if( var != NULL )
990  	         {
991  	            SCIP_CALL( SCIPaddVar(scip, var) );
992  	            SCIP_CALL( SCIPreleaseVar(scip, &var) );
993  	         }
994  	         assert(var == NULL);
995  	
996  	         mpsinputSetSection(mpsi, MPS_RHS);
997  	         return SCIP_OKAY;
998  	      }
999  	      if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1000 	         break;
1001 	
1002 	      /* new column? */
1003 	      if( strcmp(colname, mpsinputField1(mpsi)) )
1004 	      {
1005 	         /* add the last variable to the problem */
1006 	         if( var != NULL )
1007 	         {
1008 	            SCIP_CALL( SCIPaddVar(scip, var) );
1009 	            SCIP_CALL( SCIPreleaseVar(scip, &var) );
1010 	         }
1011 	         assert(var == NULL);
1012 	
1013 	         (void)SCIPmemccpy(colname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1014 	
1015 	         /* check whether we have seen this variable before, this would not allowed */
1016 	         if( usevartable && SCIPfindVar(scip, colname) != NULL )
1017 	         {
1018 	            SCIPerrorMessage("Coeffients of column <%s> don't appear consecutively (line: %d)\n",
1019 	               colname, mpsi->lineno);
1020 	
1021 	            return SCIP_READERROR;
1022 	         }
1023 	
1024 	         /* if the file type is a cor file, the the variable name must be stored */
1025 	         SCIP_CALL( addVarNameToStorage(scip, varnames, varnamessize, nvarnames, colname) );
1026 	
1027 	         if( mpsinputIsInteger(mpsi) )
1028 	         {
1029 	            /* for integer variables, default bounds are 0 <= x < 1(not +infinity, like it is for continuous variables), and default cost is 0 */
1030 	            SCIP_CALL( SCIPcreateVar(scip, &var, colname, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
1031 	                  !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
1032 	         }
1033 	         else
1034 	         {
1035 	            /* for continuous variables, default bounds are 0 <= x, and default cost is 0 */
1036 	            SCIP_CALL( SCIPcreateVar(scip, &var, colname, 0.0, SCIPinfinity(scip), 0.0, SCIP_VARTYPE_CONTINUOUS,
1037 	                  !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
1038 	         }
1039 	      }
1040 	      assert(var != NULL);
1041 	
1042 	      val = atof(mpsinputField3(mpsi));
1043 	
1044 	      if( !strcmp(mpsinputField2(mpsi), mpsinputObjname(mpsi)) )
1045 	      {
1046 	         SCIP_CALL( SCIPchgVarObj(scip, var, val) );
1047 	      }
1048 	      else
1049 	      {
1050 	         cons = SCIPfindCons(scip, mpsinputField2(mpsi));
1051 	         if( cons == NULL )
1052 	            mpsinputEntryIgnored(scip, mpsi, "Column", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_FULL);
1053 	         else if( !SCIPisZero(scip, val) )
1054 	         {
1055 	            /* warn the user in case the coefficient is infinite */
1056 	            if( SCIPisInfinity(scip, REALABS(val)) )
1057 	            {
1058 	               SCIPwarningMessage(scip, "Coefficient of variable <%s> in constraint <%s> contains infinite value <%e>,"
1059 	                  " consider adjusting SCIP infinity.\n", SCIPvarGetName(var), SCIPconsGetName(cons), val);
1060 	            }
1061 	            SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
1062 	         }
1063 	      }
1064 	      if( mpsinputField5(mpsi) != NULL )
1065 	      {
1066 	         assert(mpsinputField4(mpsi) != NULL);
1067 	
1068 	         val = atof(mpsinputField5(mpsi));
1069 	
1070 	         if( !strcmp(mpsinputField4(mpsi), mpsinputObjname(mpsi)) )
1071 	         {
1072 	            SCIP_CALL( SCIPchgVarObj(scip, var, val) );
1073 	         }
1074 	         else
1075 	         {
1076 	            cons = SCIPfindCons(scip, mpsinputField4(mpsi));
1077 	            if( cons == NULL )
1078 	               mpsinputEntryIgnored(scip, mpsi, "Column", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_FULL);
1079 	            else if( !SCIPisZero(scip, val) )
1080 	            {
1081 	               SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
1082 	            }
1083 	         }
1084 	      }
1085 	   }
1086 	   mpsinputSyntaxerror(mpsi);
1087 	
1088 	   return SCIP_OKAY;
1089 	}
1090 	
1091 	/** Process RHS section. */
1092 	static
1093 	SCIP_RETCODE readRhs(
1094 	   MPSINPUT*             mpsi,               /**< mps input structure */
1095 	   SCIP*                 scip                /**< SCIP data structure */
1096 	   )
1097 	{
1098 	   char        rhsname[MPS_MAX_NAMELEN] = { '\0' };
1099 	   SCIP_CONS*  cons;
1100 	   SCIP_Real   lhs;
1101 	   SCIP_Real   rhs;
1102 	   SCIP_Real   val;
1103 	
1104 	   SCIPdebugMsg(scip, "read right hand sides\n");
1105 	
1106 	   while( mpsinputReadLine(mpsi) )
1107 	   {
1108 	      if( mpsinputField0(mpsi) != NULL )
1109 	      {
1110 	         if( !strcmp(mpsinputField0(mpsi), "RANGES") )
1111 	            mpsinputSetSection(mpsi, MPS_RANGES);
1112 	         else if( !strcmp(mpsinputField0(mpsi), "BOUNDS") )
1113 	            mpsinputSetSection(mpsi, MPS_BOUNDS);
1114 	         else if( !strcmp(mpsinputField0(mpsi), "SOS") )
1115 	            mpsinputSetSection(mpsi, MPS_SOS);
1116 	         else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1117 	            mpsinputSetSection(mpsi, MPS_QMATRIX);
1118 	         else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1119 	            mpsinputSetSection(mpsi, MPS_QUADOBJ);
1120 	         else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1121 	            mpsinputSetSection(mpsi, MPS_QCMATRIX);
1122 	         else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1123 	            mpsinputSetSection(mpsi, MPS_INDICATORS);
1124 	         else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1125 	            mpsinputSetSection(mpsi, MPS_ENDATA);
1126 	         else
1127 	            break;
1128 	         return SCIP_OKAY;
1129 	      }
1130 	      if( (mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL)
1131 	         || (mpsinputField4(mpsi) != NULL && mpsinputField5(mpsi) == NULL) )
1132 	      {
1133 	         SCIPwarningMessage(scip, "reading rhs section, a field is missing, assuming that the vector name is the missing one(, row identfier <%s>)\n", mpsinputField2(mpsi));
1134 	
1135 	         mpsinputInsertName(mpsi, "_RHS_", FALSE);
1136 	      }
1137 	
1138 	      if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1139 	         break;
1140 	
1141 	      if( *rhsname == '\0' )
1142 		 (void)SCIPmemccpy(rhsname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1143 	
1144 	      if( !strcmp(rhsname, mpsinputField1(mpsi)) )
1145 	      {
1146 	         cons = SCIPfindCons(scip, mpsinputField2(mpsi));
1147 	         if( cons == NULL )
1148 	         {
1149 	            /* the rhs of the objective row is treated as objective constant */
1150 	            if( strcmp(mpsinputField2(mpsi), mpsinputObjname(mpsi)) == 0 )
1151 	            {
1152 	               val = atof(mpsinputField3(mpsi));
1153 	               SCIP_CALL( SCIPaddOrigObjoffset(scip, -val) );
1154 	            }
1155 	            else
1156 	               mpsinputEntryIgnored(scip, mpsi, "RHS", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_NORMAL);
1157 	         }
1158 	         else
1159 	         {
1160 	            val = atof(mpsinputField3(mpsi));
1161 	
1162 	            /* find out the row sense */
1163 	            lhs = SCIPgetLhsLinear(scip, cons);
1164 	            rhs = SCIPgetRhsLinear(scip, cons);
1165 	            if( SCIPisInfinity(scip, -lhs) )
1166 	            {
1167 	               /* lhs = -infinity -> lower or equal */
1168 	               assert(SCIPisZero(scip, rhs));
1169 	               SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
1170 	            }
1171 	            else if( SCIPisInfinity(scip, rhs) )
1172 	            {
1173 	               /* rhs = +infinity -> greater or equal */
1174 	               assert(SCIPisZero(scip, lhs));
1175 	               SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
1176 	            }
1177 	            else
1178 	            {
1179 	               /* lhs > -infinity, rhs < infinity -> equality */
1180 	               assert(SCIPisZero(scip, lhs));
1181 	               assert(SCIPisZero(scip, rhs));
1182 	               SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
1183 	               SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
1184 	            }
1185 	            SCIPdebugMsg(scip, "RHS <%s> lhs: %g  rhs: %g  val: <%22.12g>\n", mpsinputField2(mpsi), lhs, rhs, val);
1186 	         }
1187 	         if( mpsinputField5(mpsi) != NULL )
1188 	         {
1189 	            cons = SCIPfindCons(scip, mpsinputField4(mpsi));
1190 	            if( cons == NULL )
1191 	            {
1192 	               /* the rhs of the objective row is treated as objective constant */
1193 	               if( strcmp(mpsinputField4(mpsi), mpsinputObjname(mpsi)) == 0 )
1194 	               {
1195 	                  val = atof(mpsinputField5(mpsi));
1196 	                  SCIP_CALL( SCIPaddOrigObjoffset(scip, -val) );
1197 	               }
1198 	               else
1199 	                  mpsinputEntryIgnored(scip, mpsi, "RHS", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_NORMAL);
1200 	            }
1201 	            else
1202 	            {
1203 	               val = atof(mpsinputField5(mpsi));
1204 	
1205 	               /* find out the row sense */
1206 	               lhs = SCIPgetLhsLinear(scip, cons);
1207 	               rhs = SCIPgetRhsLinear(scip, cons);
1208 	               if( SCIPisInfinity(scip, -lhs) )
1209 	               {
1210 	                  /* lhs = -infinity -> lower or equal */
1211 	                  assert(SCIPisZero(scip, rhs));
1212 	                  SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
1213 	               }
1214 	               else if( SCIPisInfinity(scip, rhs) )
1215 	               {
1216 	                  /* rhs = +infinity -> greater or equal */
1217 	                  assert(SCIPisZero(scip, lhs));
1218 	                  SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
1219 	               }
1220 	               else
1221 	               {
1222 	                  /* lhs > -infinity, rhs < infinity -> equality */
1223 	                  assert(SCIPisZero(scip, lhs));
1224 	                  assert(SCIPisZero(scip, rhs));
1225 	                  SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
1226 	                  SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
1227 	               }
1228 	               SCIPdebugMsg(scip, "RHS <%s> lhs: %g  rhs: %g  val: <%22.12g>\n", mpsinputField4(mpsi), lhs, rhs, val);
1229 	            }
1230 	         }
1231 	      }
1232 	   }
1233 	   mpsinputSyntaxerror(mpsi);
1234 	
1235 	   return SCIP_OKAY;
1236 	}
1237 	
1238 	/** Process RANGES section */
1239 	static
1240 	SCIP_RETCODE readRanges(
1241 	   MPSINPUT*             mpsi,               /**< mps input structure */
1242 	   SCIP*                 scip                /**< SCIP data structure */
1243 	   )
1244 	{
1245 	   char        rngname[MPS_MAX_NAMELEN] = { '\0' };
1246 	   SCIP_CONS*  cons;
1247 	   SCIP_Real   lhs;
1248 	   SCIP_Real   rhs;
1249 	   SCIP_Real   val;
1250 	
1251 	   SCIPdebugMsg(scip, "read ranges\n");
1252 	
1253 	   while( mpsinputReadLine(mpsi) )
1254 	   {
1255 	      if( mpsinputField0(mpsi) != NULL )
1256 	      {
1257 	         if( !strcmp(mpsinputField0(mpsi), "BOUNDS") )
1258 	            mpsinputSetSection(mpsi, MPS_BOUNDS);
1259 	         else if( !strcmp(mpsinputField0(mpsi), "SOS") )
1260 	            mpsinputSetSection(mpsi, MPS_SOS);
1261 	         else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1262 	            mpsinputSetSection(mpsi, MPS_QMATRIX);
1263 	         else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1264 	            mpsinputSetSection(mpsi, MPS_QUADOBJ);
1265 	         else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1266 	            mpsinputSetSection(mpsi, MPS_QCMATRIX);
1267 	         else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1268 	            mpsinputSetSection(mpsi, MPS_INDICATORS);
1269 	         else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1270 	            mpsinputSetSection(mpsi, MPS_ENDATA);
1271 	         else
1272 	            break;
1273 	         return SCIP_OKAY;
1274 	      }
1275 	      if( (mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL)
1276 	         || (mpsinputField4(mpsi) != NULL && mpsinputField5(mpsi) == NULL) )
1277 	      {
1278 	         SCIPwarningMessage(scip, "reading ranged section, a field is missing, assuming that the vector name is the missing one(, row identfier <%s>)\n", mpsinputField2(mpsi));
1279 	
1280 	         mpsinputInsertName(mpsi, "_RNG_", FALSE);
1281 	      }
1282 	
1283 	      if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1284 	         break;
1285 	
1286 	      if( *rngname == '\0' )
1287 		 (void)SCIPmemccpy(rngname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1288 	
1289 	      /* The rules are:
1290 	       * Row Sign   LHS             RHS
1291 	       * ----------------------------------------
1292 	       *  G   +/-   rhs             rhs + |range|
1293 	       *  L   +/-   rhs - |range|   rhs
1294 	       *  E   +     rhs             rhs + range
1295 	       *  E   -     rhs + range     rhs
1296 	       * ----------------------------------------
1297 	       */
1298 	      if( !strcmp(rngname, mpsinputField1(mpsi)) )
1299 	      {
1300 	         cons = SCIPfindCons(scip, mpsinputField2(mpsi));
1301 	         if( cons == NULL )
1302 	            mpsinputEntryIgnored(scip, mpsi, "Range", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_NORMAL);
1303 	         else
1304 	         {
1305 	            val = atof(mpsinputField3(mpsi));
1306 	
1307 	            /* find out the row sense */
1308 	            lhs = SCIPgetLhsLinear(scip, cons);
1309 	            rhs = SCIPgetRhsLinear(scip, cons);
1310 	            if( SCIPisInfinity(scip, -lhs) )
1311 	            {
1312 	               /* lhs = -infinity -> lower or equal */
1313 	               SCIP_CALL( SCIPchgLhsLinear(scip, cons, rhs - REALABS(val)) );
1314 	            }
1315 	            else if( SCIPisInfinity(scip, rhs) )
1316 	            {
1317 	               /* rhs = +infinity -> greater or equal */
1318 	               SCIP_CALL( SCIPchgRhsLinear(scip, cons, lhs + REALABS(val)) );
1319 	            }
1320 	            else
1321 	            {
1322 	               /* lhs > -infinity, rhs < infinity -> equality */
1323 	               assert(SCIPisEQ(scip, lhs, rhs));
1324 	               if( val >= 0.0 )
1325 	               {
1326 	                  SCIP_CALL( SCIPchgRhsLinear(scip, cons, rhs + val) );
1327 	               }
1328 	               else
1329 	               {
1330 	                  SCIP_CALL( SCIPchgLhsLinear(scip, cons, lhs + val) );
1331 	               }
1332 	            }
1333 	         }
1334 	         if( mpsinputField5(mpsi) != NULL )
1335 	         {
1336 	            cons = SCIPfindCons(scip, mpsinputField4(mpsi));
1337 	            if( cons == NULL )
1338 	               mpsinputEntryIgnored(scip, mpsi, "Range", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_NORMAL);
1339 	            else
1340 	            {
1341 	               val = atof(mpsinputField5(mpsi));
1342 	
1343 	               /* find out the row sense */
1344 	               lhs = SCIPgetLhsLinear(scip, cons);
1345 	               rhs = SCIPgetRhsLinear(scip, cons);
1346 	               if( SCIPisInfinity(scip, -lhs) )
1347 	               {
1348 	                  /* lhs = -infinity -> lower or equal */
1349 	                  SCIP_CALL( SCIPchgLhsLinear(scip, cons, rhs - REALABS(val)) );
1350 	               }
1351 	               else if( SCIPisInfinity(scip, rhs) )
1352 	               {
1353 	                  /* rhs = +infinity -> greater or equal */
1354 	                  SCIP_CALL( SCIPchgRhsLinear(scip, cons, lhs + REALABS(val)) );
1355 	               }
1356 	               else
1357 	               {
1358 	                  /* lhs > -infinity, rhs < infinity -> equality */
1359 	                  assert(SCIPisEQ(scip, lhs, rhs));
1360 	                  if( val >= 0.0 )
1361 	                  {
1362 	                     SCIP_CALL( SCIPchgRhsLinear(scip, cons, rhs + val) );
1363 	                  }
1364 	                  else
1365 	                  {
1366 	                     SCIP_CALL( SCIPchgLhsLinear(scip, cons, lhs + val) );
1367 	                  }
1368 	               }
1369 	            }
1370 	         }
1371 	      }
1372 	   }
1373 	   mpsinputSyntaxerror(mpsi);
1374 	
1375 	   return SCIP_OKAY;
1376 	}
1377 	
1378 	/** Process BOUNDS section. */
1379 	static
1380 	SCIP_RETCODE readBounds(
1381 	   MPSINPUT*             mpsi,               /**< mps input structure */
1382 	   SCIP*                 scip                /**< SCIP data structure */
1383 	   )
1384 	{
1385 	   char        bndname[MPS_MAX_NAMELEN] = { '\0' };
1386 	   SCIP_VAR*   var;
1387 	   SCIP_RETCODE retcode;
1388 	   SCIP_Real   val;
1389 	   SCIP_Bool   shifted;
1390 	
1391 	   SCIP_VAR** semicont;
1392 	   int nsemicont;
1393 	   int semicontsize;
1394 	
1395 	   retcode = SCIP_OKAY;
1396 	
1397 	   semicont = NULL;
1398 	   nsemicont = 0;
1399 	   semicontsize = 0;
1400 	
1401 	   SCIPdebugMsg(scip, "read bounds\n");
1402 	
1403 	   while( mpsinputReadLine(mpsi) )
1404 	   {
1405 	      if( mpsinputField0(mpsi) != 0 )
1406 	      {
1407 	         if( !strcmp(mpsinputField0(mpsi), "SOS") )
1408 	            mpsinputSetSection(mpsi, MPS_SOS);
1409 	         else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1410 	            mpsinputSetSection(mpsi, MPS_QMATRIX);
1411 	         else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1412 	            mpsinputSetSection(mpsi, MPS_QUADOBJ);
1413 	         else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1414 	            mpsinputSetSection(mpsi, MPS_QCMATRIX);
1415 	         else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1416 	            mpsinputSetSection(mpsi, MPS_INDICATORS);
1417 	         else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1418 	            mpsinputSetSection(mpsi, MPS_ENDATA);
1419 	         else
1420 	            break;
1421 	         goto READBOUNDS_FINISH;
1422 	      }
1423 	
1424 	      shifted = FALSE;
1425 	
1426 	      /* Is the value field used ? */
1427 	      if( !strcmp(mpsinputField1(mpsi), "LO")  /* lower bound given in field 4 */
1428 	         || !strcmp(mpsinputField1(mpsi), "UP")  /* upper bound given in field 4 */
1429 	         || !strcmp(mpsinputField1(mpsi), "FX")  /* fixed value given in field 4 */
1430 	         || !strcmp(mpsinputField1(mpsi), "LI")  /* CPLEX extension: lower bound of integer variable given in field 4 */
1431 	         || !strcmp(mpsinputField1(mpsi), "UI")  /* CPLEX extension: upper bound of integer variable given in field 4 */
1432 	         || !strcmp(mpsinputField1(mpsi), "SC")  /* CPLEX extension: semi-continuous variable, upper bound given in field 4 */
1433 	         || !strcmp(mpsinputField1(mpsi), "SI") )/* CPLEX extension: semi-integer variable, upper bound given in field 4 */
1434 	      {
1435 	         if( mpsinputField3(mpsi) != NULL && mpsinputField4(mpsi) == NULL )
1436 	         {
1437 	            int l;
1438 	
1439 	            /* check what might be missing, if field 3 is a number the bound name might be missing */
1440 	            for( l = (int) strlen(mpsinputField3(mpsi)) - 1; l >= 0; --l )
1441 	            {
1442 	               if( mpsinputField3(mpsi)[l] != '.' && !isdigit(mpsinputField3(mpsi)[l]) )
1443 	                  break;
1444 	            }
1445 	
1446 	            /* the bound name?! is missing */
1447 	            if( l < 0 )
1448 	            {
1449 	               SCIPwarningMessage(scip, "in bound section a name for value <%s> might be missing\n", mpsinputField3(mpsi));
1450 	
1451 	               mpsinputInsertName(mpsi, "_BND_", TRUE);
1452 	               shifted = TRUE;
1453 	            }
1454 	            /* the bound is be missing */
1455 	            else
1456 	            {
1457 	               SCIPwarningMessage(scip, "in bound section a value for column <%s> is missing, assuming 0.0\n", mpsinputField3(mpsi));
1458 	
1459 	               mpsinputInsertField4(mpsi, "0.0");
1460 	               shifted = TRUE;
1461 	            }
1462 	         }
1463 	      }
1464 	      else if( !strcmp(mpsinputField1(mpsi), "FR") /* free variable */
1465 	         || !strcmp(mpsinputField1(mpsi), "MI")    /* lower bound is minus infinity */
1466 	         || !strcmp(mpsinputField1(mpsi), "PL")    /* upper bound is plus infinity */
1467 	         || !strcmp(mpsinputField1(mpsi), "BV") )  /* CPLEX extension: binary variable */
1468 	      {
1469 	         if( mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL )
1470 	         {
1471 	            SCIPwarningMessage(scip, "in bound section a name for a column is missing\n");
1472 	
1473 	            mpsinputInsertName(mpsi, "_BND_", TRUE);
1474 	            shifted = TRUE;
1475 	         }
1476 	      }
1477 	      else
1478 	      {
1479 	         mpsinputSyntaxerror(mpsi);
1480 	         return SCIP_OKAY;
1481 	      }
1482 	
1483 	      if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1484 	         break;
1485 	
1486 	      if( *bndname == '\0' )
1487 		 (void)SCIPmemccpy(bndname, mpsinputField2(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1488 	
1489 	      /* Only read the first Bound in section */
1490 	      if( !strcmp(bndname, mpsinputField2(mpsi)) )
1491 	      {
1492 	         SCIP_VARTYPE oldvartype;
1493 	         SCIP_Bool infeasible;
1494 	
1495 	         var = SCIPfindVar(scip, mpsinputField3(mpsi));
1496 	         /* if variable did not appear in columns section before, then it may still come in later sections (QCMATRIX, QMATRIX, SOS, ...)
1497 	          * thus add it as continuous variables, which has default bounds 0.0 <= x, and default cost 0.0 */
1498 	         if( var == NULL )
1499 	         {
1500 	            SCIP_VAR* varcpy;
1501 	
1502 	            SCIP_CALL( SCIPcreateVar(scip, &var, mpsinputField3(mpsi), 0.0, SCIPinfinity(scip), 0.0, 
1503 	                  SCIP_VARTYPE_CONTINUOUS, !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
1504 	
1505 	            SCIP_CALL( SCIPaddVar(scip, var) );
1506 	            varcpy = var;
1507 	            SCIP_CALL( SCIPreleaseVar(scip, &varcpy) );
1508 	            /* mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField3(mpsi), "bound", bndname, SCIP_VERBLEVEL_NORMAL); */
1509 	         }
1510 	         assert(var != NULL);
1511 	
1512 	         if( mpsinputField4(mpsi) == NULL )
1513 	            val = 0.0;
1514 	         else
1515 	            val = atof(mpsinputField4(mpsi));
1516 	
1517 	         /* remember variable type */
1518 	         oldvartype = SCIPvarGetType(var);
1519 	
1520 	         /* If a bound of a binary variable is given, the variable is converted into an integer variable
1521 	          * with default bounds 0 <= x <= infinity before applying the bound. Note that integer variables
1522 	          * are by default assumed to be binary, but an explicit lower bound of 0 turns them into integer variables.
1523 	          * Only if the upper bound is explicitly set to 1, we leave the variable as a binary one.
1524 	          */
1525 	         if( oldvartype == SCIP_VARTYPE_BINARY && !((mpsinputField1(mpsi)[0] == 'U' ||
1526 	                  (mpsinputField1(mpsi)[0] == 'F' && mpsinputField1(mpsi)[1] == 'X')) && SCIPisFeasEQ(scip, val, 1.0))
1527 	            && !(mpsinputField1(mpsi)[0] == 'F' && mpsinputField1(mpsi)[1] == 'X'&& SCIPisFeasEQ(scip, val, 0.0)) )
1528 	         {
1529 	            SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1530 	            assert(!infeasible);
1531 	
1532 	            oldvartype =  SCIP_VARTYPE_INTEGER;
1533 	            SCIP_CALL( SCIPchgVarUb(scip, var, SCIPinfinity(scip)) );
1534 	         }
1535 	
1536 	         /* switch variable type to continuous before applying the bound, this is necessary for stupid non-integral
1537 	          * bounds on general variables, which even might lead to infeasibility
1538 	          */
1539 	         if( oldvartype != SCIP_VARTYPE_CONTINUOUS )
1540 	         {
1541 	            assert(SCIP_VARTYPE_CONTINUOUS >= SCIP_VARTYPE_IMPLINT && SCIP_VARTYPE_IMPLINT >= SCIP_VARTYPE_INTEGER && SCIP_VARTYPE_INTEGER >= SCIP_VARTYPE_BINARY); /*lint !e506*//*lint !e1564*/
1542 	            /* relaxing variable type */
1543 	            SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_CONTINUOUS, &infeasible) );
1544 	         }
1545 	         assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
1546 	
1547 	         switch( mpsinputField1(mpsi)[0] )
1548 	         {
1549 	         case 'L':
1550 	            if( !SCIPisZero(scip, SCIPvarGetLbGlobal(var)) && SCIPisLT(scip, val, SCIPvarGetLbGlobal(var)) )
1551 	            {
1552 	               SCIPwarningMessage(scip, "Relaxing already defined lower bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetLbGlobal(var), SCIPvarGetName(var), val);
1553 	            }
1554 	
1555 	            SCIP_CALL( SCIPchgVarLb(scip, var, val) );
1556 	
1557 	            if( mpsinputField1(mpsi)[1] == 'I' ) /* CPLEX extension (Integer Bound) */
1558 	            {
1559 	               if( !SCIPisFeasIntegral(scip, val) )
1560 	               {
1561 	                  SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral lower bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
1562 	               }
1563 	               SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1564 	               /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1565 	            }
1566 	            else if( oldvartype < SCIP_VARTYPE_CONTINUOUS )
1567 	            {
1568 	               if( !SCIPisFeasIntegral(scip, val) )
1569 	               {
1570 	                  SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral lower bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
1571 	               }
1572 	            }
1573 	
1574 	            break;
1575 	         case 'U':
1576 	            if( SCIPisGT(scip, val, SCIPvarGetUbGlobal(var)) )
1577 	            {
1578 	               SCIPwarningMessage(scip, "Relaxing already defined upper bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetUbGlobal(var), SCIPvarGetName(var), val);
1579 	            }
1580 	
1581 	            SCIP_CALL( SCIPchgVarUb(scip, var, val) );
1582 	            if( mpsinputField1(mpsi)[1] == 'I' ) /* CPLEX extension (Integer Bound) */
1583 	            {
1584 	               if( !SCIPisFeasIntegral(scip, val) )
1585 	               {
1586 	                  SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral upper bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
1587 	               }
1588 	
1589 	               SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1590 	               /* don't assert feasibility here because the presolver will and should detect an infeasibility */
1591 	            }
1592 	            else if( oldvartype < SCIP_VARTYPE_CONTINUOUS )
1593 	            {
1594 	               if( !SCIPisFeasIntegral(scip, val) )
1595 	               {
1596 	                  SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral upper bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
1597 	               }
1598 	            }
1599 	            break;
1600 	         case 'S':
1601 	            assert(mpsinputField1(mpsi)[1] == 'C' || mpsinputField1(mpsi)[1] == 'I'); /* semi-continuous or semi-integer (CPLEX extension) */
1602 	            /* remember that variable is semi-continuous/-integer */
1603 	            if( semicontsize <= nsemicont )
1604 	            {
1605 	               semicontsize = SCIPcalcMemGrowSize(scip, nsemicont+1);
1606 	               if( semicont == NULL )
1607 	               {
1608 	                  SCIP_CALL( SCIPallocBufferArray(scip, &semicont, semicontsize) );
1609 	               }
1610 	               else
1611 	               {
1612 	                  SCIP_CALL( SCIPreallocBufferArray(scip, &semicont, semicontsize) );
1613 	               }
1614 	            }
1615 	            assert(semicont != NULL);
1616 	            semicont[nsemicont] = var;
1617 	            ++nsemicont;
1618 	
1619 	            if( mpsinputField1(mpsi)[1] == 'I' ) /* variable is semi-integer, hence change its type to integer (the "semi" part will be handled below) */
1620 	            {
1621 	               SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1622 	               /* don't assert feasibility here because the presolver will and should detect an infeasibility */
1623 	            }
1624 	
1625 	            /* if both bounds are infinite anyway, we do not need to print a warning or change the bound */
1626 	            if( !SCIPisInfinity(scip, val) || !SCIPisInfinity(scip, SCIPvarGetUbGlobal(var)) )
1627 	            {
1628 	               if( SCIPisGT(scip, val, SCIPvarGetUbGlobal(var)) )
1629 	               {
1630 	                  SCIPwarningMessage(scip, "Relaxing already defined upper bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetUbGlobal(var), SCIPvarGetName(var), val);
1631 	               }
1632 	
1633 	               SCIP_CALL( SCIPchgVarUb(scip, var, val) );
1634 	            }
1635 	            break;
1636 	         case 'F':
1637 	            if( mpsinputField1(mpsi)[1] == 'X' )
1638 	            {
1639 	               SCIP_CALL( SCIPchgVarLb(scip, var, val) );
1640 	               SCIP_CALL( SCIPchgVarUb(scip, var, val) );
1641 	            }
1642 	            else
1643 	            {
1644 	               SCIP_CALL( SCIPchgVarLb(scip, var, -SCIPinfinity(scip)) );
1645 	               SCIP_CALL( SCIPchgVarUb(scip, var, +SCIPinfinity(scip)) );
1646 	            }
1647 	            break;
1648 	         case 'M':
1649 	            SCIP_CALL( SCIPchgVarLb(scip, var, -SCIPinfinity(scip)) );
1650 	            break;
1651 	         case 'P':
1652 	            SCIP_CALL( SCIPchgVarUb(scip, var, +SCIPinfinity(scip)) );
1653 	            break;
1654 	         case 'B' : /* CPLEX extension (Binary) */
1655 	            SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
1656 	            SCIP_CALL( SCIPchgVarUb(scip, var, 1.0) );
1657 	            SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
1658 	            /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1659 	            break;
1660 	         default:
1661 	            mpsinputSyntaxerror(mpsi);
1662 	            return SCIP_OKAY;
1663 	         }
1664 	
1665 	         /* switch variable type back to old type if necessary */
1666 	         if( oldvartype < SCIPvarGetType(var) )
1667 	         {
1668 	            SCIP_CALL( SCIPchgVarType(scip, var, oldvartype, &infeasible) );
1669 	         }
1670 	      }
1671 	      else
1672 	      {
1673 	         /* check for syntax error */
1674 	         assert(*bndname != '\0');
1675 	         if( strcmp(bndname, mpsinputField3(mpsi)) == 0 && shifted )
1676 	         {
1677 	            mpsinputSyntaxerror(mpsi);
1678 	            return SCIP_OKAY;
1679 	         }
1680 	
1681 	         mpsinputEntryIgnored(scip, mpsi, "bound", mpsinputField2(mpsi), "variable", mpsinputField3(mpsi), SCIP_VERBLEVEL_NORMAL);
1682 	      }
1683 	   }
1684 	   mpsinputSyntaxerror(mpsi);
1685 	
1686 	 READBOUNDS_FINISH:
1687 	   if( nsemicont > 0 )
1688 	   {
1689 	      SCIP_CONS* cons;
1690 	      SCIP_VAR* vars[2];
1691 	      SCIP_BOUNDTYPE boundtypes[2];
1692 	      SCIP_Real bounds[2];
1693 	      char name[SCIP_MAXSTRLEN];
1694 	      SCIP_Real oldlb;
1695 	      int i;
1696 	
1697 	      assert(semicont != NULL);
1698 	
1699 	      /* add bound disjunction constraints for semi-continuous and semi-integer variables */
1700 	      for( i = 0; i < nsemicont; ++i )
1701 	      {
1702 	         var = semicont[i];
1703 	         assert(SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER || SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
1704 	
1705 	         oldlb = SCIPvarGetLbGlobal(var);
1706 	         assert(oldlb >= 0.0);
1707 	
1708 	         /* if no bound was specified (which we assume if we see lower bound 0.0),
1709 	          * then the default lower bound for a semi-continuous variable is 1.0 */
1710 	         if( oldlb == 0.0 )
1711 	            oldlb = 1.0;
1712 	
1713 	         /* change the lower bound to 0.0 */
1714 	         SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
1715 	
1716 	         /* add a bound disjunction constraint to say var <= 0.0 or var >= oldlb */
1717 	         (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "semicont_%s", SCIPvarGetName(var));
1718 	
1719 	         vars[0] = var;
1720 	         vars[1] = var;
1721 	         boundtypes[0] = SCIP_BOUNDTYPE_UPPER;
1722 	         boundtypes[1] = SCIP_BOUNDTYPE_LOWER;
1723 	         bounds[0] = 0.0;
1724 	         bounds[1] = oldlb;
1725 	
1726 	         retcode = SCIPcreateConsBounddisjunction(scip, &cons, name, 2, vars, boundtypes, bounds,
1727 	            !mpsi->dynamiccols, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, mpsi->dynamicconss, mpsi->dynamiccols, FALSE);
1728 	
1729 	         if( retcode != SCIP_OKAY )
1730 	            break;
1731 	
1732 	         SCIP_CALL( SCIPaddCons(scip, cons) );
1733 	
1734 	         SCIPdebugMsg(scip, "add bound disjunction constraint for semi-continuity/-integrality of <%s>:\n\t", SCIPvarGetName(var));
1735 	         SCIPdebugPrintCons(scip, cons, NULL);
1736 	
1737 	         SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1738 	      }
1739 	   }
1740 	
1741 	   SCIPfreeBufferArrayNull(scip, &semicont);
1742 	
1743 	   SCIP_CALL( retcode );
1744 	
1745 	   return SCIP_OKAY;
1746 	}
1747 	
1748 	
1749 	/** Process SOS section.
1750 	 *
1751 	 *  We read the SOS section, which is a nonstandard section introduced by CPLEX.
1752 	 *
1753 	 *  @note Currently we do not support the standard way of specifying SOS constraints via markers.
1754 	 */
1755 	static
1756 	SCIP_RETCODE readSOS(
1757 	   MPSINPUT*             mpsi,               /**< mps input structure */
1758 	   SCIP*                 scip                /**< SCIP data structure */
1759 	   )
1760 	{
1761 	   SCIP_Bool initial;
1762 	   SCIP_Bool separate;
1763 	   SCIP_Bool enforce;
1764 	   SCIP_Bool check;
1765 	   SCIP_Bool propagate;
1766 	   SCIP_Bool local;
1767 	   SCIP_Bool dynamic;
1768 	   SCIP_Bool removable;
1769 	   char name[MPS_MAX_NAMELEN] = { '\0' };
1770 	   SCIP_CONS* cons = NULL;
1771 	   int consType = -1;
1772 	   int cnt = 0;
1773 	
1774 	   SCIPdebugMsg(scip, "read SOS constraints\n");
1775 	
1776 	   /* standard settings for SOS constraints: */
1777 	   initial = mpsi->initialconss;
1778 	   separate = TRUE;
1779 	   enforce = TRUE;
1780 	   check = TRUE;
1781 	   propagate = TRUE;
1782 	   local = FALSE;
1783 	   dynamic = mpsi->dynamicconss;
1784 	   removable = mpsi->dynamicrows;
1785 	
1786 	   /* loop through section */
1787 	   while( mpsinputReadLine(mpsi) )
1788 	   {
1789 	      int type = -1;
1790 	
1791 	      /* check if next section is found */
1792 	      if( mpsinputField0(mpsi) != NULL )
1793 	      {
1794 	         if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1795 	            mpsinputSetSection(mpsi, MPS_ENDATA);
1796 	         else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1797 	            mpsinputSetSection(mpsi, MPS_QMATRIX);
1798 	         else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1799 	            mpsinputSetSection(mpsi, MPS_QUADOBJ);
1800 	         else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1801 	            mpsinputSetSection(mpsi, MPS_QCMATRIX);
1802 	         else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1803 	            mpsinputSetSection(mpsi, MPS_INDICATORS);
1804 	         break;
1805 	      }
1806 	      if( mpsinputField1(mpsi) == NULL )
1807 	      {
1808 	         SCIPerrorMessage("empty data in a non-comment line.\n");
1809 	         mpsinputSyntaxerror(mpsi);
1810 	         return SCIP_OKAY;
1811 	      }
1812 	
1813 	      /* check for new SOS set */
1814 	      if( strcmp(mpsinputField1(mpsi), "S1") == 0 )
1815 	         type = 1;
1816 	      if( strcmp(mpsinputField1(mpsi), "S2") == 0 )
1817 	         type = 2;
1818 	
1819 	      /* add last constraint and create a new one */
1820 	      if( type > 0 )
1821 	      {
1822 	         assert( type == 1 || type == 2 );
1823 	         if( cons != NULL )
1824 	         {
1825 	            /* add last constraint */
1826 	            SCIP_CALL( SCIPaddCons(scip, cons) );
1827 	            SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
1828 	            SCIPdebugPrintCons(scip, cons, NULL);
1829 	            SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1830 	         }
1831 	
1832 	         /* check name */
1833 	         if( mpsinputField2(mpsi) != NULL )
1834 	            (void)SCIPmemccpy(name, mpsinputField2(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1835 	         else
1836 	         {
1837 	            /* create new name */
1838 	            (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "SOS%d", ++cnt);
1839 	         }
1840 	
1841 	         /* create new SOS constraint */
1842 	         if( type == 1 )
1843 	         {
1844 	            /* we do not know the name of the constraint */
1845 	            SCIP_CALL( SCIPcreateConsSOS1(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
1846 	                  local, dynamic, removable, FALSE) );
1847 	         }
1848 	         else
1849 	         {
1850 	            assert( type == 2 );
1851 	            SCIP_CALL( SCIPcreateConsSOS2(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
1852 	                  local, dynamic, removable, FALSE) );
1853 	         }
1854 	         consType = type;
1855 	         SCIPdebugMsg(scip, "created constraint <%s> of type %d.\n", name, type);
1856 	         /* note: we ignore the priorities! */
1857 	      }
1858 	      else
1859 	      {
1860 	         /* otherwise we are in the section given variables */
1861 	         SCIP_VAR* var;
1862 	         SCIP_Real weight;
1863 	         char* endptr;
1864 	
1865 	         if( consType != 1 && consType != 2 )
1866 	         {
1867 	            SCIPerrorMessage("missing SOS type specification.\n");
1868 	            mpsinputSyntaxerror(mpsi);
1869 	            return SCIP_OKAY;
1870 	         }
1871 	
1872 	         /* get variable */
1873 	         var = SCIPfindVar(scip, mpsinputField1(mpsi));
1874 	         if( var == NULL )
1875 	         {
1876 	            /* ignore unknown variables - we would not know the type anyway */
1877 	            mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "SOS", name, SCIP_VERBLEVEL_NORMAL);
1878 	         }
1879 	         else
1880 	         {
1881 	            /* get weight */
1882 	            if( NULL == mpsinputField2(mpsi)  )
1883 	            {
1884 	               SCIPerrorMessage("weight for variable <%s> not specified.\n", mpsinputField1(mpsi));
1885 	               mpsinputSyntaxerror(mpsi);
1886 	               return SCIP_OKAY;
1887 	            }
1888 	
1889 	            weight = strtod(mpsinputField2(mpsi), &endptr);
1890 	            if( endptr == mpsinputField2(mpsi) || *endptr != '\0' )
1891 	            {
1892 	               SCIPerrorMessage("weight for variable <%s> not specified.\n", mpsinputField1(mpsi));
1893 	               mpsinputSyntaxerror(mpsi);
1894 	               return SCIP_OKAY;
1895 	            }
1896 	
1897 	            /* add variable and weight */
1898 	            assert( consType == 1 || consType == 2 );
1899 	            switch( consType )
1900 	            {
1901 	            case 1: 
1902 	               SCIP_CALL( SCIPaddVarSOS1(scip, cons, var, weight) );
1903 	               break;
1904 	            case 2: 
1905 	               SCIP_CALL( SCIPaddVarSOS2(scip, cons, var, weight) );
1906 	               break;
1907 	            /* coverity[dead_error_begin] */
1908 	            default: 
1909 	               SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
1910 	               SCIPABORT();
1911 	               return SCIP_INVALIDDATA;  /*lint !e527*/
1912 	            }
1913 	            SCIPdebugMsg(scip, "added variable <%s> with weight %g.\n", SCIPvarGetName(var), weight);
1914 	         }
1915 	         /* check other fields */
1916 	         if( (mpsinputField3(mpsi) != NULL && *mpsinputField3(mpsi) != '\0' ) ||
1917 	            (mpsinputField4(mpsi) != NULL && *mpsinputField4(mpsi) != '\0' ) ||
1918 	            (mpsinputField5(mpsi) != NULL && *mpsinputField5(mpsi) != '\0' ) )
1919 	         {
1920 	            SCIPwarningMessage(scip, "ignoring data in fields 3-5 <%s> <%s> <%s>.\n",
1921 	               mpsinputField3(mpsi), mpsinputField4(mpsi), mpsinputField5(mpsi));
1922 	         }
1923 	      }
1924 	   }
1925 	
1926 	   if( cons != NULL )
1927 	   {
1928 	      /* add last constraint */
1929 	      SCIP_CALL( SCIPaddCons(scip, cons) );
1930 	      SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
1931 	      SCIPdebugPrintCons(scip, cons, NULL);
1932 	      SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1933 	   }
1934 	
1935 	   return SCIP_OKAY;
1936 	}
1937 	
1938 	
1939 	/** Process QMATRIX or QUADOBJ section.
1940 	 *
1941 	 *  - We read the QMATRIX or QUADOBJ section, which is a nonstandard section introduced by CPLEX.
1942 	 *  - We create a quadratic constraint for this matrix and add a variable to the objective to
1943 	 *    represent the value of the QMATRIX.
1944 	 *  - For a QMATRIX, we expect that both lower and upper diagonal elements are given and every
1945 	 *    coefficient has to be divided by 2.0.
1946 	 *  - For a QUADOBJ, we expect that only the upper diagonal elements are given and thus only
1947 	 *    coefficients on the diagonal have to be divided by 2.0.
1948 	 */
1949 	static
1950 	SCIP_RETCODE readQMatrix(
1951 	   MPSINPUT*             mpsi,               /**< mps input structure */
1952 	   SCIP_Bool             isQuadObj,          /**< whether we actually read a QUADOBJ section */
1953 	   SCIP*                 scip                /**< SCIP data structure */
1954 	   )
1955 	{
1956 	   SCIP_VAR** quadvars1;
1957 	   SCIP_VAR** quadvars2;
1958 	   SCIP_Real* quadcoefs;
1959 	   SCIP_RETCODE retcode;
1960 	   int cnt  = 0; /* number of qmatrix elements processed so far */
1961 	   int size;     /* size of quad* arrays */
1962 	
1963 	   SCIPdebugMsg(scip, "read %s objective\n", isQuadObj ? "QUADOBJ" : "QMATRIX");
1964 	
1965 	   retcode = SCIP_OKAY;
1966 	
1967 	   size = 1;
1968 	   SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, size) );
1969 	   SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, size) );
1970 	   SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, size) );
1971 	
1972 	   /* loop through section */
1973 	   /* coverity[tainted_data] */
1974 	   while( mpsinputReadLine(mpsi) )
1975 	   {
1976 	      /* otherwise we are in the section given variables */
1977 	      SCIP_VAR* var1;
1978 	      SCIP_VAR* var2;
1979 	      SCIP_Real coef;
1980 	
1981 	      /* check if next section is found */
1982 	      if( mpsinputField0(mpsi) != NULL )
1983 	      {
1984 	         if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1985 	            mpsinputSetSection(mpsi, MPS_QCMATRIX);
1986 	         else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1987 	            mpsinputSetSection(mpsi, MPS_INDICATORS);
1988 	         else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1989 	            mpsinputSetSection(mpsi, MPS_ENDATA);
1990 	         break;
1991 	      }
1992 	      if( mpsinputField1(mpsi) == NULL && mpsinputField2(mpsi) == NULL )
1993 	      {
1994 	         SCIPerrorMessage("empty data in a non-comment line.\n");
1995 	         mpsinputSyntaxerror(mpsi);
1996 	         SCIPfreeBufferArray(scip, &quadvars1);
1997 	         SCIPfreeBufferArray(scip, &quadvars2);
1998 	         SCIPfreeBufferArray(scip, &quadcoefs);
1999 	         return SCIP_OKAY;
2000 	      }
2001 	
2002 	      /* get first variable */
2003 	      var1 = SCIPfindVar(scip, mpsinputField1(mpsi));
2004 	      if( var1 == NULL )
2005 	      {
2006 	         /* ignore unknown variables - we would not know the type anyway */
2007 	         mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
2008 	      }
2009 	      else
2010 	      {
2011 	         int k;
2012 	         for( k = 1; k <= 2; ++k )
2013 	         {
2014 	            /* get second variable */
2015 	            var2 = SCIPfindVar(scip, k == 1 ? mpsinputField2(mpsi) : mpsinputField4(mpsi));
2016 	            if( var2 == NULL )
2017 	            {
2018 	               /* ignore unknown variables - we would not know the type anyway */
2019 	               mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField2(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
2020 	            }
2021 	            else
2022 	            {
2023 	               const char* field;
2024 	               char* endptr;
2025 	
2026 	               /* get coefficient */
2027 	               field = (k == 1 ? mpsinputField3(mpsi) :  mpsinputField5(mpsi));
2028 	               if( NULL == field )
2029 	               {
2030 	                  SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", SCIPvarGetName(var1), SCIPvarGetName(var2));
2031 	                  mpsinputSyntaxerror(mpsi);
2032 	                  SCIPfreeBufferArray(scip, &quadvars1);
2033 	                  SCIPfreeBufferArray(scip, &quadvars2);
2034 	                  SCIPfreeBufferArray(scip, &quadcoefs);
2035 	                  return SCIP_OKAY;
2036 	               }
2037 	
2038 	               coef = strtod(field, &endptr);
2039 	               if( endptr == field || *endptr != '\0' )
2040 	               {
2041 	                  SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", SCIPvarGetName(var1), SCIPvarGetName(var2));
2042 	                  mpsinputSyntaxerror(mpsi);
2043 	                  SCIPfreeBufferArray(scip, &quadvars1);
2044 	                  SCIPfreeBufferArray(scip, &quadvars2);
2045 	                  SCIPfreeBufferArray(scip, &quadcoefs);
2046 	                  return SCIP_OKAY;
2047 	               }
2048 	
2049 	               /* store variables and coefficient */
2050 	               if( cnt >= size )
2051 	               {
2052 	                  int newsize = SCIPcalcMemGrowSize(scip, size+1);
2053 	                  assert(newsize > size);
2054 	                  SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars1, newsize) );
2055 	                  SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars2, newsize) );
2056 	                  SCIP_CALL( SCIPreallocBufferArray(scip, &quadcoefs, newsize) );
2057 	                  size = newsize;
2058 	               }
2059 	               assert(cnt < size);
2060 	               quadvars1[cnt] = var1;
2061 	               quadvars2[cnt] = var2;
2062 	               quadcoefs[cnt] = coef;
2063 	
2064 	               /* diagonal elements have to be divided by 2.0
2065 	                * in a QMATRIX section also off-diagonal have to be divided by 2.0, since both lower and upper diagonal elements are given
2066 	                */
2067 	               if( var1 == var2 || !isQuadObj )
2068 	                  quadcoefs[cnt] /= 2.0;
2069 	               ++cnt;
2070 	
2071 	               SCIPdebugMsg(scip, "stored term %g*<%s>*<%s>.\n", coef, SCIPvarGetName(var1), SCIPvarGetName(var2));
2072 	            }
2073 	
2074 	            if( mpsinputField4(mpsi) == NULL || *mpsinputField4(mpsi) == '\0' )
2075 	               break;
2076 	
2077 	            if( mpsinputField5(mpsi) == NULL || *mpsinputField5(mpsi) == '\0' )
2078 	            {
2079 	               /* ignore unknown variables - we would not know the type anyway */
2080 	               mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField4(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
2081 	               break;
2082 	            }
2083 	         }
2084 	      }
2085 	   }
2086 	
2087 	   /* add constraint */
2088 	   if( cnt )
2089 	   {
2090 	      SCIP_Bool  initial, separate, enforce, check, propagate;
2091 	      SCIP_Bool  local, modifiable, dynamic, removable;
2092 	      SCIP_CONS* cons = NULL;
2093 	      SCIP_VAR*  qmatrixvar = NULL;
2094 	      SCIP_Real  lhs, rhs;
2095 	      SCIP_Real  minusone = -1.0;
2096 	
2097 	      /* determine settings; note that reading/{initialconss,dynamicconss,dynamicrows,dynamiccols} apply only to model
2098 	       * constraints and variables, not to an auxiliary objective constraint (otherwise it can happen that an auxiliary
2099 	       * objective variable is loose with infinite best bound, triggering the problem that an LP that is unbounded
2100 	       * because of loose variables with infinite best bound cannot be solved)
2101 	       */
2102 	      initial    = TRUE;
2103 	      separate   = TRUE;
2104 	      enforce    = TRUE;
2105 	      check      = TRUE;
2106 	      propagate  = TRUE;
2107 	      local      = FALSE;
2108 	      modifiable = FALSE;
2109 	      dynamic    = FALSE;
2110 	      removable  = FALSE;
2111 	
2112 	      SCIP_CALL( SCIPcreateVar(scip, &qmatrixvar, "qmatrixvar", -SCIPinfinity(scip), SCIPinfinity(scip), 1.0,
2113 	            SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
2114 	      SCIP_CALL( SCIPaddVar(scip, qmatrixvar) );
2115 	
2116 	      if( mpsinputObjsense(mpsi) == SCIP_OBJSENSE_MINIMIZE )
2117 	      {
2118 	         lhs = -SCIPinfinity(scip);
2119 	         rhs = 0.0;
2120 	      }
2121 	      else
2122 	      {
2123 	         lhs = 0.0;
2124 	         rhs = SCIPinfinity(scip);
2125 	      }
2126 	
2127 	      retcode = SCIPcreateConsQuadraticNonlinear(scip, &cons, "qmatrix", 1, &qmatrixvar, &minusone, cnt, quadvars1, quadvars2, quadcoefs, lhs, rhs,
2128 	         initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable);
2129 	
2130 	      if( retcode == SCIP_OKAY )
2131 	      {
2132 	         SCIP_CALL( SCIPaddCons(scip, cons) );
2133 	         SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
2134 	         SCIPdebugPrintCons(scip, cons, NULL);
2135 	
2136 	         SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2137 	         SCIP_CALL( SCIPreleaseVar(scip, &qmatrixvar) );
2138 	      }
2139 	   }
2140 	   else
2141 	   {
2142 	      SCIPwarningMessage(scip, "%s section has no entries.\n", isQuadObj ? "QUADOBJ" : "QMATRIX");
2143 	   }
2144 	
2145 	   SCIPfreeBufferArray(scip, &quadvars1);
2146 	   SCIPfreeBufferArray(scip, &quadvars2);
2147 	   SCIPfreeBufferArray(scip, &quadcoefs);
2148 	
2149 	   SCIP_CALL( retcode );
2150 	
2151 	   return SCIP_OKAY;
2152 	}
2153 	
2154 	
2155 	/** Process QCMATRIX section.
2156 	 *
2157 	 *  We read the QCMATRIX section, which is a nonstandard section introduced by CPLEX.
2158 	 *
2159 	 *  We replace the corresponding linear constraint by a quadratic constraint which contains the
2160 	 *  original linear constraint plus the quadratic part specified in the QCMATRIX.
2161 	 */
2162 	static
2163 	SCIP_RETCODE readQCMatrix(
2164 	   MPSINPUT*             mpsi,               /**< mps input structure */
2165 	   SCIP*                 scip                /**< SCIP data structure */
2166 	   )
2167 	{
2168 	   SCIP_CONS* lincons; /* the linear constraint that was added for the corresponding row */
2169 	   SCIP_VAR** quadvars1;
2170 	   SCIP_VAR** quadvars2;
2171 	   SCIP_Real* quadcoefs;
2172 	   SCIP_RETCODE retcode;
2173 	   int cnt  = 0; /* number of qcmatrix elements processed so far */
2174 	   int size;     /* size of quad* arrays */
2175 	
2176 	   if( mpsinputField1(mpsi) == NULL )
2177 	   {
2178 	      SCIPerrorMessage("no row name in QCMATRIX line.\n");
2179 	      mpsinputSyntaxerror(mpsi);
2180 	      return SCIP_OKAY;
2181 	   }
2182 	
2183 	   retcode = SCIP_OKAY;
2184 	
2185 	   SCIPdebugMsg(scip, "read QCMATRIX section for row <%s>\n", mpsinputField1(mpsi));
2186 	
2187 	   lincons = SCIPfindCons(scip, mpsinputField1(mpsi));
2188 	   if( lincons == NULL )
2189 	   {
2190 	      SCIPerrorMessage("no row under name <%s> processed so far.\n", mpsinputField1(mpsi));
2191 	      mpsinputSyntaxerror(mpsi);
2192 	      return SCIP_OKAY;
2193 	   }
2194 	
2195 	   size = 1;
2196 	   SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, size) );
2197 	   SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, size) );
2198 	   SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, size) );
2199 	
2200 	   /* loop through section */
2201 	   /* coverity[tainted_data] */
2202 	   while( mpsinputReadLine(mpsi) )
2203 	   {
2204 	      /* otherwise we are in the section given variables */
2205 	      SCIP_VAR* var1;
2206 	      SCIP_VAR* var2;
2207 	      SCIP_Real coef;
2208 	
2209 	      /* check if next section is found */
2210 	      if( mpsinputField0(mpsi) != NULL )
2211 	      {
2212 	         if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
2213 	            mpsinputSetSection(mpsi, MPS_QMATRIX);
2214 	         else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
2215 	            mpsinputSetSection(mpsi, MPS_QUADOBJ);
2216 	         else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
2217 	            mpsinputSetSection(mpsi, MPS_QCMATRIX);
2218 	         else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
2219 	            mpsinputSetSection(mpsi, MPS_INDICATORS);
2220 	         else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
2221 	            mpsinputSetSection(mpsi, MPS_ENDATA);
2222 	         break;
2223 	      }
2224 	      if( mpsinputField1(mpsi) == NULL && mpsinputField2(mpsi) == NULL )
2225 	      {
2226 	         SCIPerrorMessage("empty data in a non-comment line.\n");
2227 	         mpsinputSyntaxerror(mpsi);
2228 	
2229 	         goto TERMINATE;
2230 	      }
2231 	
2232 	      /* get first variable */
2233 	      var1 = SCIPfindVar(scip, mpsinputField1(mpsi));
2234 	      if( var1 == NULL )
2235 	      {
2236 	         /* ignore unknown variables - we would not know the type anyway */
2237 	         mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "QCMatrix", SCIPconsGetName(lincons), SCIP_VERBLEVEL_NORMAL);
2238 	      }
2239 	      else
2240 	      {
2241 	         /* get second variable */
2242 	         var2 = SCIPfindVar(scip, mpsinputField2(mpsi));
2243 	         if( var2 == NULL )
2244 	         {
2245 	            /* ignore unknown variables - we would not know the type anyway */
2246 	            mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField2(mpsi), "QCMatrix", SCIPconsGetName(lincons), SCIP_VERBLEVEL_NORMAL);
2247 	         }
2248 	         else
2249 	         {
2250 	            char* endptr;
2251 	            if( mpsinputField3(mpsi) ==  NULL )
2252 	            {
2253 	               SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", mpsinputField1(mpsi), mpsinputField2(mpsi));
2254 	               mpsinputSyntaxerror(mpsi);
2255 	
2256 	               goto TERMINATE;
2257 	            }
2258 	
2259 	            /* get coefficient */
2260 	            coef = strtod(mpsinputField3(mpsi), &endptr);
2261 	            if( endptr == mpsinputField3(mpsi) || *endptr != '\0' )
2262 	            {
2263 	               SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", mpsinputField1(mpsi), mpsinputField2(mpsi));
2264 	               mpsinputSyntaxerror(mpsi);
2265 	
2266 	               goto TERMINATE;
2267 	            }
2268 	
2269 	            /* store variables and coefficient */
2270 	            if( cnt >= size )
2271 	            {
2272 	               int newsize = SCIPcalcMemGrowSize(scip, size+1);
2273 	               assert(newsize > size);
2274 	               SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars1, newsize) );
2275 	               SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars2, newsize) );
2276 	               SCIP_CALL( SCIPreallocBufferArray(scip, &quadcoefs, newsize) );
2277 	               size = newsize;
2278 	            }
2279 	            assert(cnt < size);
2280 	            quadvars1[cnt] = var1;
2281 	            quadvars2[cnt] = var2;
2282 	            quadcoefs[cnt] = coef;
2283 	            ++cnt;
2284 	
2285 	            SCIPdebugMsg(scip, "stored term %g*<%s>*<%s>.\n", coef, SCIPvarGetName(var1), SCIPvarGetName(var2));
2286 	
2287 	            /* check other fields */
2288 	            if( (mpsinputField4(mpsi) != NULL && *mpsinputField4(mpsi) != '\0' ) ||
2289 	               (mpsinputField5(mpsi) != NULL && *mpsinputField5(mpsi) != '\0' ) )
2290 	            {
2291 	               SCIPwarningMessage(scip, "ignoring data in fields 4 and 5 <%s> <%s>.\n", mpsinputField4(mpsi), mpsinputField5(mpsi));
2292 	            }
2293 	         }
2294 	      }
2295 	   }
2296 	
2297 	   /* replace linear constraint by quadratic constraint */
2298 	   if( cnt )
2299 	   {
2300 	      SCIP_CONS* cons = NULL;
2301 	
2302 	      retcode = SCIPcreateConsQuadraticNonlinear(scip, &cons, SCIPconsGetName(lincons),
2303 	            SCIPgetNVarsLinear(scip, lincons), SCIPgetVarsLinear(scip, lincons), SCIPgetValsLinear(scip, lincons),
2304 	            cnt, quadvars1, quadvars2, quadcoefs, SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons),
2305 	            SCIPconsIsInitial(lincons), SCIPconsIsSeparated(lincons), SCIPconsIsEnforced(lincons), SCIPconsIsChecked(lincons),
2306 	            SCIPconsIsPropagated(lincons), SCIPconsIsLocal(lincons), SCIPconsIsModifiable(lincons), SCIPconsIsDynamic(lincons),
2307 	            SCIPconsIsRemovable(lincons));
2308 	
2309 	      if( retcode != SCIP_OKAY )
2310 	         goto TERMINATE;
2311 	
2312 	      SCIP_CALL( SCIPaddCons(scip, cons) );
2313 	      SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
2314 	      SCIPdebugPrintCons(scip, cons, NULL);
2315 	
2316 	      SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2317 	
2318 	      SCIP_CALL( SCIPdelCons(scip, lincons) );
2319 	   }
2320 	   else
2321 	   {
2322 	      SCIPwarningMessage(scip, "QCMATRIX section has no entries.\n");
2323 	   }
2324 	
2325 	 TERMINATE:
2326 	   SCIPfreeBufferArray(scip, &quadcoefs);
2327 	   SCIPfreeBufferArray(scip, &quadvars2);
2328 	   SCIPfreeBufferArray(scip, &quadvars1);
2329 	
2330 	   SCIP_CALL( retcode );
2331 	
2332 	   return SCIP_OKAY;
2333 	}
2334 	
2335 	
2336 	/** Process INDICATORS section.
2337 	 *
2338 	 *  We read the INDICATORS section, which is a nonstandard section introduced by CPLEX.
2339 	 *  Note that CPLEX does not allow ranged rows.
2340 	 *
2341 	 *  If the linear constraints are equations or ranged rows, we generate two indicator
2342 	 *  constraints.
2343 	 *
2344 	 *  The section has to come after the QMATRIX* sections.
2345 	 */
2346 	static
2347 	SCIP_RETCODE readIndicators(
2348 	   MPSINPUT*             mpsi,               /**< mps input structure */
2349 	   SCIP*                 scip                /**< SCIP data structure */
2350 	   )
2351 	{
2352 	   SCIP_Bool initial;
2353 	   SCIP_Bool separate;
2354 	   SCIP_Bool enforce;
2355 	   SCIP_Bool check;
2356 	   SCIP_Bool propagate;
2357 	   SCIP_Bool local;
2358 	   SCIP_Bool dynamic;
2359 	   SCIP_Bool removable;
2360 	   SCIP_Bool stickingatnode;
2361 	   char name[MPS_MAX_NAMELEN] = { '\0' };
2362 	
2363 	   SCIPdebugMsg(scip, "read INDICATORS constraints\n");
2364 	
2365 	   /* standard settings for indicator constraints: */
2366 	   initial = mpsi->initialconss;
2367 	   separate = TRUE;
2368 	   enforce = TRUE;
2369 	   check = TRUE;
2370 	   propagate = TRUE;
2371 	   local = FALSE;
2372 	   dynamic = mpsi->dynamicconss;
2373 	   removable = mpsi->dynamicrows;
2374 	   stickingatnode = FALSE;
2375 	
2376 	   /* loop through section */
2377 	   while( mpsinputReadLine(mpsi) )
2378 	   {
2379 	      SCIP_CONSHDLR* conshdlr;
2380 	      SCIP_CONS* cons;
2381 	      SCIP_CONS* lincons;
2382 	      SCIP_VAR* binvar;
2383 	      SCIP_Real lhs;
2384 	      SCIP_Real rhs;
2385 	
2386 	      /* check if next section is found */
2387 	      if( mpsinputField0(mpsi) != NULL )
2388 	      {
2389 	         if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
2390 	            mpsinputSetSection(mpsi, MPS_ENDATA);
2391 	         break;
2392 	      }
2393 	
2394 	      if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL )
2395 	      {
2396 	         SCIPerrorMessage("empty data in a non-comment line.\n");
2397 	         mpsinputSyntaxerror(mpsi);
2398 	         return SCIP_OKAY;
2399 	      }
2400 	
2401 	      /* check for new indicator constraint */
2402 	      if( strcmp(mpsinputField1(mpsi), "IF") != 0 )
2403 	      {
2404 	         SCIPerrorMessage("Indicator constraints need to be introduced by 'IF' in column 1.\n");
2405 	         mpsinputSyntaxerror(mpsi);
2406 	         return SCIP_OKAY;
2407 	      }
2408 	
2409 	      /* get linear constraint (row) */
2410 	      lincons = SCIPfindCons(scip, mpsinputField2(mpsi));
2411 	      if( lincons == NULL )
2412 	      {
2413 	         SCIPerrorMessage("row <%s> does not exist.\n", mpsinputField2(mpsi));
2414 	         mpsinputSyntaxerror(mpsi);
2415 	         return SCIP_OKAY;
2416 	      }
2417 	
2418 	      /* check whether constraint is really linear */
2419 	      conshdlr = SCIPconsGetHdlr(lincons);
2420 	      if( strcmp(SCIPconshdlrGetName(conshdlr), "linear") != 0 )
2421 	      {
2422 	         SCIPerrorMessage("constraint <%s> is not linear.\n", mpsinputField2(mpsi));
2423 	         mpsinputSyntaxerror(mpsi);
2424 	         return SCIP_OKAY;
2425 	      }
2426 	
2427 	      /* get binary variable */
2428 	      binvar = SCIPfindVar(scip, mpsinputField3(mpsi));
2429 	      if( binvar == NULL )
2430 	      {
2431 	         SCIPerrorMessage("binary variable <%s> does not exist.\n", mpsinputField3(mpsi));
2432 	         mpsinputSyntaxerror(mpsi);
2433 	         return SCIP_OKAY;
2434 	      }
2435 	
2436 	      /* check type */
2437 	      if( SCIPvarGetType(binvar) != SCIP_VARTYPE_BINARY )
2438 	      {
2439 	         SCIPerrorMessage("variable <%s> is not binary.\n", mpsinputField3(mpsi));
2440 	         mpsinputSyntaxerror(mpsi);
2441 	         return SCIP_OKAY;
2442 	      }
2443 	
2444 	      /* check whether we need the negated variable */
2445 	      if( mpsinputField4(mpsi) != NULL )
2446 	      {
2447 	         if( *mpsinputField4(mpsi) == '0' )
2448 	         {
2449 	            SCIP_VAR* var;
2450 	            SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &var) );
2451 	            binvar = var;
2452 	            assert( binvar != NULL );
2453 	         }
2454 	         else
2455 	         {
2456 	            if( *mpsinputField4(mpsi) != '1' )
2457 	            {
2458 	               SCIPerrorMessage("binary variable <%s> can only take values 0/1 (%s).\n", mpsinputField3(mpsi), mpsinputField4(mpsi));
2459 	               mpsinputSyntaxerror(mpsi);
2460 	               return SCIP_OKAY;
2461 	            }
2462 	         }
2463 	      }
2464 	
2465 	      /* get lhs/rhs */
2466 	      lhs = SCIPgetLhsLinear(scip, lincons);
2467 	      rhs = SCIPgetRhsLinear(scip, lincons);
2468 	
2469 	      if( !SCIPisInfinity(scip, -lhs) )
2470 	      {
2471 	         if( ! SCIPisInfinity(scip, rhs) )
2472 	         {
2473 	            /* create second indicator constraint */
2474 	            SCIP_VAR** vars;
2475 	            SCIP_Real* vals;
2476 	            SCIP_RETCODE retcode;
2477 	            SCIP_VAR** linvars;
2478 	            SCIP_Real* linvals;
2479 	            int nlinvars;
2480 	            int i;
2481 	
2482 	            nlinvars = SCIPgetNVarsLinear(scip, lincons);
2483 	            linvars = SCIPgetVarsLinear(scip, lincons);
2484 	            linvals = SCIPgetValsLinear(scip, lincons);
2485 	
2486 	            SCIP_CALL( SCIPallocBufferArray(scip, &vars, nlinvars) );
2487 	            SCIP_CALL( SCIPallocBufferArray(scip, &vals, nlinvars) );
2488 	            for( i = 0; i < nlinvars; ++i )
2489 	            {
2490 	               vars[i] = linvars[i];
2491 	               vals[i] = -linvals[i];
2492 	            }
2493 	
2494 	            /* create new name */
2495 	            (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indlhs_%s", SCIPconsGetName(lincons));
2496 	
2497 	            /* create indicator constraint */
2498 	            retcode = SCIPcreateConsIndicator(scip, &cons, name, binvar, nlinvars, vars, vals, -lhs,
2499 	               initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode);
2500 	
2501 	            if( retcode == SCIP_OKAY )
2502 	            {
2503 	               SCIP_CALL( SCIPaddCons(scip, cons) );
2504 	               SCIPdebugMsg(scip, "created indicator constraint <%s>\n", mpsinputField2(mpsi));
2505 	               SCIPdebugPrintCons(scip, cons, NULL);
2506 	               SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2507 	            }
2508 	
2509 	            SCIPfreeBufferArray(scip, &vals);
2510 	            SCIPfreeBufferArray(scip, &vars);
2511 	
2512 	            SCIP_CALL( retcode );
2513 	         }
2514 	      }
2515 	
2516 	      /* correct linear constraint and create new name */
2517 	      if ( ! SCIPisInfinity(scip, -lhs) && ! SCIPisInfinity(scip, rhs) )
2518 	      {
2519 	         /* we have added lhs above and only need the rhs */
2520 	         SCIP_CALL( SCIPchgLhsLinear(scip, lincons, -SCIPinfinity(scip) ) );
2521 	         (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indrhs_%s", SCIPconsGetName(lincons));
2522 	      }
2523 	      else
2524 	         (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "ind_%s", SCIPconsGetName(lincons));
2525 	
2526 	      /* create indicator constraint */
2527 	      SCIP_CALL( SCIPcreateConsIndicatorLinConsPure(scip, &cons, name, binvar, lincons,
2528 	            initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
2529 	
2530 	      SCIP_CALL( SCIPaddCons(scip, cons) );
2531 	      SCIPdebugMsg(scip, "created indicator constraint <%s>", mpsinputField2(mpsi));
2532 	      SCIPdebugPrintCons(scip, cons, NULL);
2533 	      SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2534 	   }
2535 	
2536 	   return SCIP_OKAY;
2537 	}
2538 	
2539 	
2540 	/** Read LP in "MPS File Format".
2541 	 *
2542 	 *  A specification of the MPS format can be found at
2543 	 *
2544 	 *  http://plato.asu.edu/ftp/mps_format.txt,
2545 	 *  ftp://ftp.caam.rice.edu/pub/people/bixby/miplib/mps_format,
2546 	 *
2547 	 *  and in the
2548 	 *
2549 	 *  CPLEX Reference Manual
2550 	 *
2551 	 *  This routine should read all valid MPS format files.
2552 	 *  What it will not do, is to find all cases where a file is ill formed.
2553 	 *  If this happens it may complain and read nothing or read "something".
2554 	 */
2555 	static
2556 	SCIP_RETCODE readMps(
2557 	   SCIP*                 scip,               /**< SCIP data structure */
2558 	   const char*           filename,           /**< name of the input file */
2559 	   const char***         varnames,           /**< storage for the variable names, or NULL */
2560 	   const char***         consnames,          /**< storage for the constraint names, or NULL */
2561 	   int*                  varnamessize,       /**< the size of the variable names storage, or NULL */
2562 	   int*                  consnamessize,      /**< the size of the constraint names storage, or NULL */
2563 	   int*                  nvarnames,          /**< the number of stored variable names, or NULL */
2564 	   int*                  nconsnames          /**< the number of stored constraint names, or NULL */
2565 	   )
2566 	{
2567 	   SCIP_FILE* fp;
2568 	   MPSINPUT* mpsi;
2569 	   SCIP_RETCODE retcode;
2570 	   SCIP_Bool error = TRUE;
2571 	
2572 	   assert(scip != NULL);
2573 	   assert(filename != NULL);
2574 	
2575 	   fp = SCIPfopen(filename, "r");
2576 	   if( fp == NULL )
2577 	   {
2578 	      SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
2579 	      SCIPprintSysError(filename);
2580 	      return SCIP_NOFILE;
2581 	   }
2582 	
2583 	   SCIP_CALL( mpsinputCreate(scip, &mpsi, fp) );
2584 	
2585 	   SCIP_CALL_TERMINATE( retcode, readName(scip, mpsi), TERMINATE );
2586 	
2587 	   SCIP_CALL_TERMINATE( retcode, SCIPcreateProb(scip, mpsi->probname, NULL, NULL, NULL, NULL, NULL, NULL, NULL), TERMINATE );
2588 	
2589 	   if( mpsinputSection(mpsi) == MPS_OBJSEN )
2590 	   {
2591 	      SCIP_CALL_TERMINATE( retcode, readObjsen(scip, mpsi), TERMINATE );
2592 	   }
2593 	   if( mpsinputSection(mpsi) == MPS_OBJNAME )
2594 	   {
2595 	      SCIP_CALL_TERMINATE( retcode, readObjname(scip, mpsi), TERMINATE );
2596 	   }
2597 	   while( mpsinputSection(mpsi) == MPS_ROWS
2598 	      || mpsinputSection(mpsi) == MPS_USERCUTS
2599 	      || mpsinputSection(mpsi) == MPS_LAZYCONS )
2600 	   {
2601 	      SCIP_CALL_TERMINATE( retcode, readRows(mpsi, scip, consnames, consnamessize, nconsnames), TERMINATE );
2602 	   }
2603 	   if( mpsinputSection(mpsi) == MPS_COLUMNS )
2604 	   {
2605 	      SCIP_CALL_TERMINATE( retcode, readCols(mpsi, scip, varnames, varnamessize, nvarnames), TERMINATE );
2606 	   }
2607 	   if( mpsinputSection(mpsi) == MPS_RHS )
2608 	   {
2609 	      SCIP_CALL_TERMINATE( retcode, readRhs(mpsi, scip), TERMINATE );
2610 	   }
2611 	   if( mpsinputSection(mpsi) == MPS_RANGES )
2612 	   {
2613 	      SCIP_CALL_TERMINATE( retcode, readRanges(mpsi, scip), TERMINATE );
2614 	   }
2615 	   if( mpsinputSection(mpsi) == MPS_BOUNDS )
2616 	   {
2617 	      SCIP_CALL_TERMINATE( retcode, readBounds(mpsi, scip), TERMINATE );
2618 	   }
2619 	   if( mpsinputSection(mpsi) == MPS_SOS )
2620 	   {
2621 	      SCIP_CALL_TERMINATE( retcode, readSOS(mpsi, scip), TERMINATE );
2622 	   }
2623 	   while( mpsinputSection(mpsi) == MPS_QCMATRIX )
2624 	   {
2625 	      SCIP_CALL_TERMINATE( retcode, readQCMatrix(mpsi, scip), TERMINATE );
2626 	   }
2627 	   if( mpsinputSection(mpsi) == MPS_QMATRIX )
2628 	   {
2629 	      SCIP_CALL_TERMINATE( retcode, readQMatrix(mpsi, FALSE, scip), TERMINATE );
2630 	   }
2631 	   if( mpsinputSection(mpsi) == MPS_QUADOBJ )
2632 	   {
2633 	      SCIP_CALL_TERMINATE( retcode, readQMatrix(mpsi, TRUE, scip), TERMINATE );
2634 	   }
2635 	   while( mpsinputSection(mpsi) == MPS_QCMATRIX )
2636 	   {
2637 	      SCIP_CALL_TERMINATE( retcode, readQCMatrix(mpsi, scip), TERMINATE );
2638 	   }
2639 	   if( mpsinputSection(mpsi) == MPS_INDICATORS )
2640 	   {
2641 	      SCIP_CALL_TERMINATE( retcode, readIndicators(mpsi, scip), TERMINATE );
2642 	   }
2643 	   if( mpsinputSection(mpsi) != MPS_ENDATA )
2644 	      mpsinputSyntaxerror(mpsi);
2645 	
2646 	   SCIPfclose(fp);
2647 	
2648 	   error = mpsinputHasError(mpsi);
2649 	
2650 	   if( !error )
2651 	   {
2652 	      SCIP_CALL_TERMINATE( retcode, SCIPsetObjsense(scip, mpsinputObjsense(mpsi)), TERMINATE );
2653 	   }
2654 	
2655 	 TERMINATE:
2656 	   mpsinputFree(scip, &mpsi);
2657 	
2658 	   if( error )
2659 	      return SCIP_READERROR;
2660 	   else
2661 	      return SCIP_OKAY;
2662 	}
2663 	
2664 	/*
2665 	 * local methods for writing problem
2666 	 */
2667 	
2668 	/** gets the key (i.e. the name) of the given namefreq */
2669 	static
2670 	SCIP_DECL_HASHGETKEY(hashGetKeyNamefreq)
2671 	{  /*lint --e{715}*/
2672 	   CONSNAMEFREQ* consnamefreq = (CONSNAMEFREQ*)elem;
2673 	
2674 	   assert(consnamefreq != NULL);
2675 	   assert(consnamefreq->consname != NULL);
2676 	
2677 	   return (void*)consnamefreq->consname;
2678 	}
2679 	
2680 	/** returns TRUE iff both keys (i.e. strings) are equal up to max length*/
2681 	static
2682 	SCIP_DECL_HASHKEYEQ(hashKeyEqString)
2683 	{  /*lint --e{715}*/
2684 	   const char* string1 = (const char*)key1;
2685 	   const char* string2 = (const char*)key2;
2686 	
2687 	   return (strncmp(string1, string2, MPS_MAX_NAMELEN - 1) == 0);
2688 	}
2689 	
2690 	/** hash key retrieval function for variables */
2691 	static
2692 	SCIP_DECL_HASHGETKEY(hashGetKeyVar)
2693 	{  /*lint --e{715}*/
2694 	   return elem;
2695 	}
2696 	
2697 	/** returns TRUE iff the indices of both variables are equal */
2698 	static
2699 	SCIP_DECL_HASHKEYEQ(hashKeyEqVar)
2700 	{  /*lint --e{715}*/
2701 	   if( key1 == key2 )
2702 	      return TRUE;
2703 	   return FALSE;
2704 	}
2705 	
2706 	/** returns the hash value of the key */
2707 	static
2708 	SCIP_DECL_HASHKEYVAL(hashKeyValVar)
2709 	{  /*lint --e{715}*/
2710 	   assert( SCIPvarGetIndex((SCIP_VAR*) key) >= 0 );
2711 	   return (unsigned int) SCIPvarGetIndex((SCIP_VAR*) key);
2712 	}
2713 	
2714 	
2715 	/** computes the field width such that the output file is nicely arranged */
2716 	static
2717 	unsigned int computeFieldWidth(
2718 	   unsigned int          width               /**< required width */
2719 	   )
2720 	{
2721 	   width = MAX(8u, width);
2722 	   return MIN(MPS_MAX_FIELDLEN, width);
2723 	}
2724 	
2725 	
2726 	/** output two strings in columns 1 and 2 with computed widths */
2727 	static
2728 	void printRecord(
2729 	   SCIP*                 scip,               /**< SCIP data structure */
2730 	   FILE*                 file,               /**< output file (or NULL for standard output) */
2731 	   const char*           col1,               /**< column 1 */
2732 	   const char*           col2,               /**< column 2 */
2733 	   unsigned int          maxnamelen          /**< maximum name length */
2734 	   )
2735 	{
2736 	   unsigned int fieldwidth;
2737 	   char format[32];
2738 	
2739 	   assert( scip != NULL );
2740 	   assert( col1 != NULL );
2741 	   assert( col2 != NULL );
2742 	   assert( strlen(col1) < MPS_MAX_NAMELEN );
2743 	   assert( strlen(col2) < MPS_MAX_VALUELEN );
2744 	   assert( maxnamelen > 0 );
2745 	
2746 	   fieldwidth = computeFieldWidth(maxnamelen);
2747 	   (void) SCIPsnprintf(format, 32," %%-%ds %%%ds ", fieldwidth, MPS_MAX_VALUELEN - 1);
2748 	
2749 	   SCIPinfoMessage(scip, file, (const char *)format, col1, col2);
2750 	}
2751 	
2752 	/** output two strings in columns 1 (width 2) and 2 (width 8) */
2753 	static
2754 	void printStart(
2755 	   SCIP*                 scip,               /**< SCIP data structure */
2756 	   FILE*                 file,               /**< output file (or NULL for standard output) */
2757 	   const char*           col1,               /**< column 1 */
2758 	   const char*           col2,               /**< column 2 */
2759 	   int                   maxnamelen          /**< maximum name length (-1 if irrelevant) */
2760 	   )
2761 	{
2762 	   unsigned int fieldwidth;
2763 	   char format[32];
2764 	
2765 	   assert( scip != NULL );
2766 	   assert( col1 != NULL );
2767 	   assert( col2 != NULL );
2768 	   assert( strlen(col1) <= 2 );
2769 	   assert( strlen(col2) < MPS_MAX_NAMELEN );
2770 	   assert( maxnamelen == -1 || maxnamelen > 0 );
2771 	
2772 	   if( maxnamelen < 0 )
2773 	   {
2774 	      /* format does not matter */
2775 	      (void) SCIPsnprintf(format, 32, " %%-2.2s %%-s ");
2776 	   }
2777 	   else
2778 	   {
2779 	      fieldwidth = computeFieldWidth((unsigned int) maxnamelen);
2780 	      (void) SCIPsnprintf(format, 32, " %%-2.2s %%-%ds ", fieldwidth);
2781 	   }
2782 	
2783 	   SCIPinfoMessage(scip, file, (const char*)format, col1, col2);
2784 	}
2785 	
2786 	/** prints the given data as column entry */
2787 	static
2788 	void printEntry(
2789 	   SCIP*                 scip,               /**< SCIP data structure */
2790 	   FILE*                 file,               /**< output file (or NULL for standard output) */
2791 	   const char*           varname,            /**< variable name */
2792 	   const char*           consname,           /**< constraint name */
2793 	   SCIP_Real             value,              /**< value to display */
2794 	   int*                  recordcnt,          /**< pointer to store the number of records per line */
2795 	   unsigned int          maxnamelen          /**< maximum name length */
2796 	   )
2797 	{
2798 	   char valuestr[MPS_MAX_VALUELEN] = { '\0' };
2799 	
2800 	   assert( scip != NULL );
2801 	   assert( recordcnt != NULL );
2802 	   assert( *recordcnt >= 0 && *recordcnt < 2 );
2803 	
2804 	   (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", value);
2805 	
2806 	   if( *recordcnt == 0 )
2807 	   {
2808 	      /* start new line with an empty first column and the variable name in the second column */
2809 	      printStart(scip, file, "", varname, (int) maxnamelen);
2810 	      *recordcnt = 0;
2811 	   }
2812 	
2813 	   printRecord(scip, file, consname, valuestr, maxnamelen);
2814 	   (*recordcnt)++;
2815 	
2816 	   if( *recordcnt == 2 )
2817 	   {
2818 	      /* each line can have at most two records */
2819 	      SCIPinfoMessage(scip, file, "\n");
2820 	      *recordcnt = 0;
2821 	   }
2822 	}
2823 	
2824 	/** prints the constraint type to file stream */
2825 	static
2826 	void printRowType(
2827 	   SCIP*                 scip,               /**< SCIP data structure */
2828 	   FILE*                 file,               /**< output file (or NULL for standard output) */
2829 	   SCIP_Real             lhs,                /**< left hand side */
2830 	   SCIP_Real             rhs,                /**< right hand side */
2831 	   const char*           name                /**< constraint name */
2832 	   )
2833 	{
2834 	   char rowtype[2];
2835 	
2836 	   assert( scip != NULL );
2837 	   assert( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) );
2838 	   assert( SCIPisGT(scip, rhs, lhs) || SCIPisEQ(scip, lhs, rhs) );
2839 	   assert( name != NULL );
2840 	
2841 	   if( SCIPisEQ(scip, lhs, rhs) )
2842 	      (void) SCIPsnprintf(rowtype, 2, "%s", "E");
2843 	   else
2844 	   {
2845 	      /* in case the right hand side and the left hand side are not infinity we print a
2846 	       * less or equal constraint and put the right hand side in the RHS section and the
2847 	       * left hand side (hidden) in the RANGE section */
2848 	      if( !SCIPisInfinity(scip, rhs) )
2849 	         (void) SCIPsnprintf(rowtype, 2, "%s", "L");
2850 	      else
2851 	      {
2852 	         assert( !SCIPisInfinity(scip, -lhs) );
2853 	         (void) SCIPsnprintf(rowtype, 2, "%s", "G");
2854 	      }
2855 	   }
2856 	
2857 	   printStart(scip, file, rowtype, name, -1);
2858 	   SCIPinfoMessage(scip, file, "\n");
2859 	}
2860 	
2861 	
2862 	/** initializes the sparse matrix */
2863 	static
2864 	SCIP_RETCODE initializeMatrix(
2865 	   SCIP*                 scip,               /**< SCIP data structure */
2866 	   SPARSEMATRIX**        matrix,             /**< pointer to sparse matrix containing the entries */
2867 	   int                   slots               /**< number of slots */
2868 	   )
2869 	{
2870 	   SCIP_CALL( SCIPallocBuffer(scip, matrix) );
2871 	   (*matrix)->nentries = 0;
2872 	   (*matrix)->sentries = slots;
2873 	   SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->values, (*matrix)->sentries) );
2874 	   SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->columns, (*matrix)->sentries) );
2875 	   SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->rows, (*matrix)->sentries) );
2876 	
2877 	   return SCIP_OKAY;
2878 	}
2879 	
2880 	/** this method takes care that the required capacity is available in the sparse matrix */
2881 	static
2882 	SCIP_RETCODE checkSparseMatrixCapacity(
2883 	   SCIP*                 scip,               /**< SCIP data structure */
2884 	   SPARSEMATRIX*         matrix,             /**< sparse matrix for storing the coefficient */
2885 	   int                   capacity            /**< needed capacity */
2886 	   )
2887 	{
2888 	   if( matrix->nentries + capacity >= matrix->sentries )
2889 	   {
2890 	      matrix->sentries = matrix->sentries * 2 + capacity;
2891 	      SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->values, matrix->sentries) );
2892 	      SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->columns, matrix->sentries) );
2893 	      SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->rows, matrix->sentries) );
2894 	   }
2895 	   return SCIP_OKAY;
2896 	}
2897 	
2898 	/** frees the sparse matrix */
2899 	static
2900 	void freeMatrix(
2901 	   SCIP*                 scip,               /**< SCIP data structure */
2902 	   SPARSEMATRIX*         matrix              /**< sparse matrix to free */
2903 	   )
2904 	{
2905 	   SCIPfreeBufferArray(scip, &matrix->rows);
2906 	   SCIPfreeBufferArray(scip, &matrix->columns);
2907 	   SCIPfreeBufferArray(scip, &matrix->values);
2908 	
2909 	   SCIPfreeBuffer(scip, &matrix);
2910 	}
2911 	
2912 	
2913 	/** computes the coefficient for the given variables and linear constraint information */
2914 	static
2915 	SCIP_RETCODE getLinearCoeffs(
2916 	   SCIP*                 scip,               /**< SCIP data structure */
2917 	   const char*           consname,           /**< name of the constraint */
2918 	   SCIP_VAR**            vars,               /**< array of variables */
2919 	   SCIP_Real*            vals,               /**< array of coefficients values (or NULL if all coefficient values are 1) */
2920 	   int                   nvars,              /**< number of variables */
2921 	   SCIP_Bool             transformed,        /**< transformed constraint? */
2922 	   SPARSEMATRIX*         matrix,             /**< sparse matrix for storing the coefficient */
2923 	   SCIP_Real*            rhs                 /**< pointer to right hand side */
2924 	   )
2925 	{
2926 	   SCIP_VAR** activevars;
2927 	   SCIP_Real* activevals;
2928 	   SCIP_Real activeconstant = 0.0;
2929 	
2930 	   int nactivevars;
2931 	   int requiredsize;
2932 	   int v;
2933 	
2934 	   assert( scip != NULL );
2935 	   assert( nvars == 0 || vars != NULL );
2936 	   assert( !SCIPisInfinity(scip, *rhs) );
2937 	   assert( matrix != NULL );
2938 	
2939 	   /* if the variables array contains no variables, then return without
2940 	    * doing any thing; The MPS format and LP format do not forbid this
2941 	    * situation */
2942 	   if( nvars == 0 ) 
2943 	      return SCIP_OKAY;
2944 	
2945 	   /* duplicate variable and value array */
2946 	   nactivevars = nvars;
2947 	   SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars ) );
2948 	
2949 	   if( vals != NULL )
2950 	   {
2951 	      SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars ) );
2952 	   }
2953 	   else
2954 	   {
2955 	      SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
2956 	
2957 	      for( v = 0; v < nactivevars; ++v )
2958 	         activevals[v] = 1.0;
2959 	   }
2960 	
2961 	   /* retransform given variables to active variables */
2962 	   if( transformed )
2963 	   {
2964 	      SCIP_CALL( SCIPgetProbvarLinearSum(scip, activevars, activevals, &nactivevars, nactivevars, &activeconstant, &requiredsize, TRUE) );
2965 	
2966 	      if( requiredsize > nactivevars )
2967 	      {
2968 	         SCIP_CALL( SCIPreallocBufferArray(scip, &activevars, requiredsize) );
2969 	         SCIP_CALL( SCIPreallocBufferArray(scip, &activevals, requiredsize) );
2970 	
2971 	         SCIP_CALL( SCIPgetProbvarLinearSum(scip, activevars, activevals, &nactivevars, requiredsize, &activeconstant, &requiredsize, TRUE) );
2972 	         assert( requiredsize <= nactivevars );
2973 	      }
2974 	   }
2975 	   else
2976 	   {
2977 	      for( v = 0; v < nactivevars; ++v )
2978 	      {
2979 	         SCIP_CALL( SCIPvarGetOrigvarSum(&activevars[v], &activevals[v], &activeconstant) );
2980 	
2981 	         /* negated variables with an original counterpart may also be returned by SCIPvarGetOrigvarSum();
2982 	          * make sure we get the original variable in that case
2983 	          */
2984 	         if( SCIPvarGetStatus(activevars[v]) == SCIP_VARSTATUS_NEGATED )
2985 	         {
2986 	            activevars[v] = SCIPvarGetNegatedVar(activevars[v]);
2987 	            activeconstant += activevals[v];
2988 	            activevals[v] *= -1.0;
2989 	         }
2990 	      }
2991 	   }
2992 	
2993 	   /* copy the (matrix) row into the sparse matrix */
2994 	   SCIP_CALL( checkSparseMatrixCapacity(scip, matrix, nactivevars) );
2995 	   assert( matrix->nentries + nactivevars < matrix->sentries );
2996 	
2997 	   for( v = 0; v < nactivevars; ++v )
2998 	   {
2999 	      matrix->values[matrix->nentries] = activevals[v];
3000 	      matrix->columns[matrix->nentries] = activevars[v];
3001 	      matrix->rows[matrix->nentries] = consname;
3002 	      matrix->nentries++;
3003 	   }
3004 	
3005 	   /* adjust right hand side */
3006 	   (*rhs) -= activeconstant;
3007 	
3008 	   /* free buffer arrays */
3009 	   SCIPfreeBufferArray(scip, &activevals);
3010 	   SCIPfreeBufferArray(scip, &activevars);
3011 	
3012 	   return SCIP_OKAY;
3013 	}
3014 	
3015 	
3016 	/** check whether given variables are aggregated and put them into an array without duplication */
3017 	static
3018 	SCIP_RETCODE collectAggregatedVars(
3019 	   SCIP*                 scip,               /**< SCIP data structure */
3020 	   SCIP_VAR**            vars,               /**< variable array */
3021 	   int                   nvars,              /**< number of active variables in the problem */
3022 	   SCIP_VAR***           aggvars,            /**< pointer to array storing the aggregated variables on output */
3023 	   int*                  naggvars,           /**< pointer to number of aggregated variables on output */
3024 	   int*                  saggvars,           /**< pointer to number of slots in aggvars array */
3025 	   SCIP_HASHTABLE*       varAggregated       /**< hashtable for checking duplicates */
3026 	   )
3027 	{
3028 	   int v;
3029 	
3030 	   assert( scip != NULL );
3031 	   assert( aggvars != NULL );
3032 	   assert( naggvars != NULL );
3033 	   assert( saggvars != NULL );
3034 	
3035 	   /* check variables */
3036 	   for( v = 0; v < nvars; ++v )
3037 	   {
3038 	      SCIP_VARSTATUS status;
3039 	      SCIP_VAR* var;
3040 	
3041 	      var = vars[v];
3042 	      status = SCIPvarGetStatus(var);
3043 	
3044 	      /* collect aggregated variables in a list */
3045 	      if( status >= SCIP_VARSTATUS_AGGREGATED )
3046 	      {
3047 	         assert( status == SCIP_VARSTATUS_AGGREGATED || status == SCIP_VARSTATUS_MULTAGGR || status == SCIP_VARSTATUS_NEGATED );
3048 	         assert( varAggregated != NULL );
3049 	
3050 	         if( ! SCIPhashtableExists(varAggregated, (void*) var) )
3051 	         {
3052 	            /* possibly enlarge array */
3053 	            if ( *saggvars <= *naggvars )
3054 	            {
3055 	               int newsize;
3056 	               newsize = SCIPcalcMemGrowSize(scip, *naggvars + 1);
3057 	               assert( newsize > *saggvars );
3058 	               SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &aggvars, *saggvars, newsize) );
3059 	               *saggvars = newsize;
3060 	            }
3061 	
3062 	            (*aggvars)[*naggvars] = var;
3063 	            (*naggvars)++;
3064 	            SCIP_CALL( SCIPhashtableInsert(varAggregated, (void*) var) );
3065 	            assert( *naggvars <= *saggvars );
3066 	         }
3067 	      }
3068 	   }
3069 	   return SCIP_OKAY;
3070 	}
3071 	
3072 	
3073 	/** method check if the variable names are not longer than MPS_MAX_NAMELEN - 1*/
3074 	static
3075 	SCIP_RETCODE checkVarnames(
3076 	   SCIP*                 scip,               /**< SCIP data structure */
3077 	   SCIP_VAR**            vars,               /**< array of variables */
3078 	   int                   nvars,              /**< number of variables */
3079 	   unsigned int*         maxnamelen,         /**< pointer to store the maximum name length */
3080 	   const char***         varnames,           /**< pointer to array of variable names */
3081 	   SCIP_HASHMAP**        varnameHashmap      /**< pointer to hash map storing variable, variable name mapping */      
3082 	   )
3083 	{
3084 	   int v;
3085 	   int faulty;
3086 	   char* varname;
3087 	   SCIP_VAR* var;
3088 	
3089 	   assert( scip != NULL );
3090 	   assert( vars != NULL );
3091 	   assert( maxnamelen != NULL );
3092 	
3093 	   faulty = 0;
3094 	
3095 	   /* allocate memory */
3096 	   SCIP_CALL( SCIPhashmapCreate(varnameHashmap, SCIPblkmem(scip), nvars) );
3097 	   SCIP_CALL( SCIPallocBufferArray(scip, varnames, nvars) );
3098 	
3099 	   /* check if the variable names are not to long */
3100 	   for( v = 0; v < nvars; ++v )
3101 	   {
3102 	      size_t l;
3103 	
3104 	      var = vars[v];
3105 	      assert( var != NULL );
3106 	
3107 	      l = strlen(SCIPvarGetName(var));
3108 	
3109 	      if( l >= MPS_MAX_NAMELEN )
3110 	      {
3111 	         faulty++;
3112 	         (*maxnamelen) = MPS_MAX_NAMELEN - 1;
3113 	      }
3114 	      else
3115 	      {
3116 	         (*maxnamelen) = MAX(*maxnamelen, (unsigned int) l);
3117 	      }
3118 	
3119 	      SCIP_CALL( SCIPallocBufferArray(scip, &varname, (int) *maxnamelen + 1) );
3120 	      (void) SCIPsnprintf(varname, (int)(*maxnamelen) + 1, "%s", SCIPvarGetName(var) );
3121 	
3122 	      /* insert variable with variable name into hash map */
3123 	      assert( !SCIPhashmapExists(*varnameHashmap, var) );
3124 	      SCIP_CALL( SCIPhashmapInsert(*varnameHashmap, var, (void*) varname) );
3125 	
3126 	      (*varnames)[v] = varname;
3127 	   }
3128 	
3129 	   if( faulty > 0 )
3130 	   {
3131 	      SCIPwarningMessage(scip, "there are %d variable names which have to be cut down to %d characters; LP might be corrupted\n",
3132 	         faulty, MPS_MAX_NAMELEN - 1);
3133 	   }
3134 	   return SCIP_OKAY;
3135 	}
3136 	
3137 	/** method check if the constraint names are not longer than MPS_MAX_NAMELEN - 1 */
3138 	static
3139 	SCIP_RETCODE checkConsnames(
3140 	   SCIP*                 scip,               /**< SCIP data structure */
3141 	   SCIP_CONS**           conss,              /**< array of all constraints */
3142 	   int                   nconss,             /**< number of all constraints */
3143 	   SCIP_Bool             transformed,        /**< TRUE iff problem is the transformed problem */
3144 	   unsigned int*         maxnamelen,         /**< pointer to store the maximum name length */
3145 	   const char***         consnames,          /**< pointer to array of constraint names */
3146 	   SCIP_Bool*            error               /**< pointer to store whether all constraint names exist */
3147 	   )
3148 	{
3149 	   SCIP_HASHTABLE* consfreq;
3150 	   CONSNAMEFREQ* consnamefreqs;
3151 	   SCIP_CONS* cons;
3152 	   char* consname;
3153 	   int i;
3154 	
3155 	   assert(scip != NULL);
3156 	   assert(maxnamelen != NULL);
3157 	
3158 	   *error = FALSE;
3159 	
3160 	   /* allocate memory */
3161 	   SCIP_CALL( SCIPallocBufferArray(scip, &consnamefreqs, nconss) );
3162 	   SCIP_CALL( SCIPallocBufferArray(scip, consnames, nconss) );
3163 	   SCIP_CALL( SCIPhashtableCreate(&consfreq, SCIPblkmem(scip), SCIP_HASHSIZE_NAMES,
3164 	         hashGetKeyNamefreq, hashKeyEqString, SCIPhashKeyValString, NULL) );
3165 	
3166 	   for( i = 0; i < nconss; ++i )
3167 	   {
3168 	      CONSNAMEFREQ* consnamefreq;
3169 	      size_t l;
3170 	      int freq;
3171 	
3172 	      cons = conss[i];
3173 	      assert( cons != NULL );
3174 	
3175 	      /* in case the transformed problem is written, only constraints are posted which are enabled in the current node */
3176 	      assert(!transformed || SCIPconsIsEnabled(cons));
3177 	
3178 	      l = strlen(SCIPconsGetName(cons));
3179 	
3180 	      if( l == 0 )
3181 	      {
3182 	         SCIPwarningMessage(scip, "At least one name of a constraint is empty, so file will be written with generic names.\n");
3183 	         *error = TRUE;
3184 	
3185 	         goto TERMINATE;
3186 	      }
3187 	
3188 	      consnamefreqs[i].consname = SCIPconsGetName(cons);
3189 	      consnamefreqs[i].freq = 0;
3190 	      freq = 0;
3191 	
3192 	      /* check for duplicate names */
3193 	      if( NULL != (consnamefreq = (CONSNAMEFREQ *)SCIPhashtableRetrieve(consfreq, (void*)SCIPconsGetName(cons))) )
3194 	      {
3195 	         consnamefreq->freq += 1;
3196 	         consnamefreqs[i] = *consnamefreq;
3197 	         freq = consnamefreq->freq;
3198 	      }
3199 	      SCIP_CALL( SCIPhashtableInsert(consfreq, (void*)(&consnamefreqs[i])) );
3200 	
3201 	      /* the new length is the length of the old name + a '_' and the freq number which has floor(log10(freq)) + 1 characters */
3202 	      if( freq > 0 )
3203 	         l = l + 1 + (size_t)log10((SCIP_Real) freq) + 1;
3204 	
3205 	      if( l >= MPS_MAX_NAMELEN )
3206 	      {
3207 	         SCIPwarningMessage(scip, "Constraints have duplicate name and are too long to fix, so file will be written with generic names.\n");
3208 	         *error = TRUE;
3209 	
3210 	         goto TERMINATE;
3211 	      }
3212 	
3213 	      (*maxnamelen) = MAX(*maxnamelen, (unsigned int) l);
3214 	
3215 	      SCIP_CALL( SCIPallocBufferArray(scip, &consname, (int) l + 1) );
3216 	      if( freq > 0 )
3217 	         (void) SCIPsnprintf(consname, (int)l + 1, "%s_%d", SCIPconsGetName(cons), freq);
3218 	      else
3219 	         (void) SCIPsnprintf(consname, (int)l + 1, "%s", SCIPconsGetName(cons));
3220 	
3221 	      (*consnames)[i] = consname;
3222 	   }
3223 	
3224 	TERMINATE:
3225 	   SCIPfreeBufferArray(scip, &consnamefreqs);
3226 	
3227 	   if( *error )
3228 	   {
3229 	      --i;  /*lint !e445*/
3230 	      for( ; i >= 0; --i)  /*lint !e445*/
3231 	      {
3232 	         SCIPfreeBufferArray(scip, &((*consnames)[i]));
3233 	      }
3234 	      SCIPfreeBufferArray(scip, consnames);
3235 	   }
3236 	
3237 	   SCIPhashtableFree(&consfreq);
3238 	
3239 	   return SCIP_OKAY;
3240 	}
3241 	
3242 	
3243 	/** outputs the COLUMNS section of the MPS format */
3244 	static
3245 	void printColumnSection(
3246 	   SCIP*                 scip,               /**< SCIP data structure */
3247 	   FILE*                 file,               /**< output file, or NULL if standard output should be used */
3248 	   SPARSEMATRIX*         matrix,             /**< sparse matrix containing the entries */
3249 	   SCIP_HASHMAP*         varnameHashmap,     /**< map from SCIP_VAR* to variable name */
3250 	   SCIP_HASHTABLE*       indicatorSlackHash, /**< hashtable containing slack variables from indicators (or NULL) */
3251 	   unsigned int          maxnamelen          /**< maximum name length */
3252 	   )
3253 	{
3254 	   SCIP_Bool intSection;
3255 	   SCIP_VAR* var;
3256 	   const char* varname;
3257 	   SCIP_Real value;
3258 	   int v;
3259 	   int recordcnt;
3260 	
3261 	   /* sort sparse matrix w.r.t. the variable indices */
3262 	   SCIPsortPtrPtrReal((void**) matrix->columns, (void**) matrix->rows, matrix->values, SCIPvarComp, matrix->nentries);
3263 	
3264 	   /* print COLUMNS section */
3265 	   SCIPinfoMessage(scip, file, "COLUMNS\n");
3266 	
3267 	   intSection = FALSE;
3268 	
3269 	   for( v = 0; v < matrix->nentries; )
3270 	   {
3271 	      var = matrix->columns[v];
3272 	      assert( var != NULL );
3273 	
3274 	      /* skip slack variables in output */
3275 	      if( indicatorSlackHash != NULL && SCIPhashtableExists(indicatorSlackHash, var) )
3276 	      {
3277 	         ++v;
3278 	         continue;
3279 	      }
3280 	
3281 	      if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS && intSection )
3282 	      {
3283 	         /* end integer section in MPS format */
3284 	         printStart(scip, file, "", "INTEND", (int) maxnamelen);
3285 	         printRecord(scip, file, "'MARKER'", "", maxnamelen);
3286 	         printRecord(scip, file, "'INTEND'", "", maxnamelen);
3287 	         SCIPinfoMessage(scip, file, "\n");
3288 	         intSection = FALSE;
3289 	      }
3290 	      else if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !intSection )
3291 	      {
3292 	         /* start integer section in MPS format */
3293 	         printStart(scip, file, "", "INTSTART", (int) maxnamelen);
3294 	         printRecord(scip, file, "'MARKER'", "", maxnamelen);
3295 	         printRecord(scip, file, "'INTORG'", "", maxnamelen);
3296 	         SCIPinfoMessage(scip, file, "\n");
3297 	         intSection = TRUE;
3298 	      }
3299 	
3300 	      SCIPdebugMsg(scip, "create entries for variable <%s>\n", SCIPvarGetName(var));
3301 	
3302 	      /* record count; there are at most two records per line */
3303 	      recordcnt = 0;
3304 	
3305 	      /* get variable name */
3306 	      assert ( SCIPhashmapExists(varnameHashmap, var) );
3307 	      varname = (const char*) SCIPhashmapGetImage(varnameHashmap, var);
3308 	
3309 	      /* output all entries of the same variable */
3310 	      do
3311 	      {
3312 	         value = matrix->values[v];
3313 	
3314 	         /* print record to file */
3315 	         printEntry(scip, file, varname, matrix->rows[v], value, &recordcnt, maxnamelen);
3316 	         v++;
3317 	      }
3318 	      while( v < matrix->nentries && var == matrix->columns[v] );
3319 	
3320 	      if( recordcnt == 1 )
3321 	         SCIPinfoMessage(scip, file, "\n");
3322 	   }
3323 	   /* end integer section, if the columns sections ends with integer variables */
3324 	   if( intSection )
3325 	   {
3326 	      /* end integer section in MPS format */
3327 	      printStart(scip, file, "", "INTEND", (int) maxnamelen);
3328 	      printRecord(scip, file, "'MARKER'", "", maxnamelen);
3329 	      printRecord(scip, file, "'INTEND'", "", maxnamelen);
3330 	      SCIPinfoMessage(scip, file, "\n");
3331 	   }
3332 	}
3333 	
3334 	
3335 	/** outputs the right hand side section */
3336 	static
3337 	void printRhsSection(
3338 	   SCIP*                 scip,               /**< SCIP data structure */
3339 	   FILE*                 file,               /**< output file, or NULL if standard output should be used */
3340 	   int                   nconss,             /**< number of constraints */
3341 	   const char**          consnames,          /**< constraint names */
3342 	   SCIP_Real*            rhss,               /**< right hand side array */
3343 	   unsigned int          maxnamelen,         /**< maximum name length */
3344 	   SCIP_Real             objoffset           /**< objective offset */
3345 	   )
3346 	{
3347 	   int recordcnt = 0;
3348 	   int c;
3349 	
3350 	   assert( rhss != NULL );
3351 	
3352 	   SCIPinfoMessage(scip, file, "RHS\n");
3353 	   SCIPdebugMsg(scip, "start printing RHS section\n");
3354 	
3355 	   /* take care of the linear constraints */
3356 	   for( c = 0; c < nconss; ++c )
3357 	   {
3358 	      /* skip all constraints which have a right hand side of infinity */
3359 	      if( SCIPisInfinity(scip, rhss[c]) )
3360 	         continue;
3361 	
3362 	      assert(consnames[c] != NULL);
3363 	
3364 	      printEntry(scip, file, "RHS", consnames[c], rhss[c], &recordcnt, maxnamelen);
3365 	   }
3366 	
3367 	   if( ! SCIPisZero(scip, objoffset) )
3368 	   {
3369 	      /* write objective offset (-1 because it is moved to the rhs) */
3370 	      printEntry(scip, file, "RHS", "Obj", -objoffset, &recordcnt, maxnamelen);
3371 	   }
3372 	
3373 	   if( recordcnt == 1 )
3374 	      SCIPinfoMessage(scip, file, "\n");
3375 	}
3376 	
3377 	
3378 	/** outputs the range section */
3379 	static
3380 	void printRangeSection(
3381 	   SCIP*                 scip,               /**< SCIP data structure */
3382 	   FILE*                 file,               /**< output file, or NULL if standard output should be used */
3383 	   SCIP_CONS**           conss,              /**< constraint array */
3384 	   int                   nconss,             /**< number of constraints */
3385 	   const char**          consnames,          /**< constraint names */
3386 	   SCIP_Bool             transformed,        /**< TRUE iff problem is the transformed problem */
3387 	   unsigned int          maxnamelen          /**< maximum name length */
3388 	   )
3389 	{
3390 	   int c;
3391 	   int recordcnt = 0;
3392 	
3393 	   SCIP_CONSHDLR* conshdlr;
3394 	   const char* conshdlrname;
3395 	
3396 	   SCIP_CONS* cons;
3397 	   SCIP_Real lhs;
3398 	   SCIP_Real rhs;
3399 	
3400 	   SCIPinfoMessage(scip, file, "RANGES\n");
3401 	   SCIPdebugMsg(scip, "start printing RANGES section\n");
3402 	
3403 	   for( c = 0; c < nconss; ++c  )
3404 	   {
3405 	      cons = conss[c];
3406 	      assert( cons != NULL);
3407 	
3408 	      /* in case the transformed problems is written only constraint are posted which are enabled in the current node;
3409 	       * the conss array should only contain relevant constraints
3410 	       */
3411 	      assert( !transformed || SCIPconsIsEnabled(cons) );
3412 	
3413 	      assert( consnames[c] != NULL );
3414 	
3415 	      conshdlr = SCIPconsGetHdlr(cons);
3416 	      assert( conshdlr != NULL );
3417 	
3418 	      conshdlrname = SCIPconshdlrGetName(conshdlr);
3419 	
3420 	      if( strcmp(conshdlrname, "linear") == 0 )
3421 	      {
3422 	         lhs = SCIPgetLhsLinear(scip, cons);
3423 	         rhs = SCIPgetRhsLinear(scip, cons);
3424 	      }
3425 	      else if( strcmp(conshdlrname, "varbound") == 0 )
3426 	      {
3427 	         lhs = SCIPgetLhsVarbound(scip, cons);
3428 	         rhs = SCIPgetRhsVarbound(scip, cons);
3429 	      }
3430 	      else
3431 	         continue;
3432 	
3433 	      if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, rhs, lhs) )
3434 	      {
3435 	         assert( SCIPisGT(scip, rhs, lhs) );
3436 	         printEntry(scip, file, "RANGE", consnames[c], rhs - lhs, &recordcnt, maxnamelen);
3437 	      }
3438 	   }
3439 	   if(recordcnt == 1 )
3440 	      SCIPinfoMessage(scip, file, "\n");
3441 	}
3442 	
3443 	/** print bound section name */
3444 	static
3445 	void printBoundSectionName(
3446 	   SCIP*                 scip,               /**< SCIP data structure */
3447 	   FILE*                 file                /**< output file, or NULL if standard output should be used */
3448 	   )
3449 	{
3450 	   SCIPinfoMessage(scip, file, "BOUNDS\n");
3451 	   SCIPdebugMsg(scip, "start printing BOUNDS section\n");
3452 	}
3453 	
3454 	/** output bound section */
3455 	static
3456 	void printBoundSection(
3457 	   SCIP*                 scip,               /**< SCIP data structure */
3458 	   FILE*                 file,               /**< output file, or NULL if standard output should be used */
3459 	   SCIP_VAR**            vars,               /**< active variables */
3460 	   int                   nvars,              /**< number of active variables */
3461 	   SCIP_VAR**            aggvars,            /**< needed aggregated variables */
3462 	   int                   naggvars,           /**< number of aggregated variables */
3463 	   SCIP_VAR**            fixvars,            /**< all fixed variables (or NULL if nfixvars is 0) */
3464 	   int                   nfixvars,           /**< number of fixed variables */
3465 	   SCIP_Bool             transformed,        /**< TRUE iff problem is the transformed problem */
3466 	   const char**          varnames,           /**< array with variable names */
3467 	   SCIP_HASHTABLE*       indicatorSlackHash, /**< hashtable containing slack variables from indicators (or NULL) */
3468 	   unsigned int          maxnamelen          /**< maximum name length */
3469 	   )
3470 	{
3471 	   int v;
3472 	   SCIP_VAR* var;
3473 	   SCIP_Real lb;
3474 	   SCIP_Real ub;
3475 	   SCIP_Bool sectionName;
3476 	   const char* varname;
3477 	   char valuestr[MPS_MAX_VALUELEN] = { '\0' };
3478 	
3479 	   assert(scip != NULL);
3480 	   assert(vars != NULL);
3481 	   assert(nfixvars == 0 || fixvars != NULL);
3482 	
3483 	   sectionName = FALSE;
3484 	
3485 	   /* output the active variables */
3486 	   for( v = 0; v < nvars; ++v )
3487 	   {
3488 	      var = vars[v];
3489 	      assert( var != NULL );
3490 	
3491 	      /* skip slack variables in output */
3492 	      if( indicatorSlackHash != NULL && SCIPhashtableExists(indicatorSlackHash, var) )
3493 	         continue;
3494 	
3495 	      /* get variable name */
3496 	      varname = varnames[v];
3497 	      assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
3498 	
3499 	      if( transformed )
3500 	      {
3501 	         /* in case the transformed is written only local bounds are posted
3502 	          * which are valid in the current node */
3503 	         lb = SCIPvarGetLbLocal(var);
3504 	         ub = SCIPvarGetUbLocal(var);
3505 	      }
3506 	      else
3507 	      {
3508 	         lb = SCIPvarGetLbOriginal(var);
3509 	         ub = SCIPvarGetUbOriginal(var);
3510 	      }
3511 	
3512 	      /* take care of binary variables */
3513 	      if( SCIPvarGetType(var) == SCIP_VARTYPE_BINARY )
3514 	      {
3515 	         if( !sectionName )
3516 	         {
3517 	            printBoundSectionName(scip, file);
3518 	            sectionName = TRUE;
3519 	         }
3520 	
3521 	         if( !SCIPisFeasZero(scip, lb) || !SCIPisFeasEQ(scip, ub, 1.0) )
3522 	         {
3523 	            (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3524 	            printStart(scip, file, "LO", "Bound", (int) maxnamelen);
3525 	            printRecord(scip, file, varname, valuestr, maxnamelen);
3526 	            SCIPinfoMessage(scip, file, "\n");
3527 	
3528 	            (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", ub);
3529 	            printStart(scip, file, "UP", "Bound", (int) maxnamelen);
3530 	            printRecord(scip, file, varname, valuestr, maxnamelen);
3531 	         }
3532 	         else
3533 	         {
3534 	            printStart(scip, file, "BV", "Bound", (int) maxnamelen);
3535 	            printRecord(scip, file, varname, "", maxnamelen);
3536 	         }
3537 	         SCIPinfoMessage(scip, file, "\n");
3538 	
3539 	         continue;
3540 	      }
3541 	
3542 	      /* take care of free variables */
3543 	      if( SCIPisInfinity(scip, -lb) && SCIPisInfinity(scip, ub) )
3544 	      {
3545 	         if( !sectionName )
3546 	         {
3547 	            printBoundSectionName(scip, file);
3548 	            sectionName = TRUE;
3549 	         }
3550 	
3551 	         /* variable is free */
3552 	         printStart(scip, file, "FR", "Bound", (int) maxnamelen);
3553 	         printRecord(scip, file, varname, "", maxnamelen);
3554 	         SCIPinfoMessage(scip, file, "\n");
3555 	         continue;
3556 	      }
3557 	
3558 	      /* take care of fixed variables */
3559 	      if( SCIPisEQ(scip, lb, ub) )
3560 	      {
3561 	         if( !sectionName )
3562 	         {
3563 	            printBoundSectionName(scip, file);
3564 	            sectionName = TRUE;
3565 	         }
3566 	
3567 	         /* variable is fixed */
3568 	         (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3569 	         printStart(scip, file, "FX", "Bound", (int) maxnamelen);
3570 	         printRecord(scip, file, varname, valuestr, maxnamelen);
3571 	         SCIPinfoMessage(scip, file, "\n");
3572 	         continue;
3573 	      }
3574 	
3575 	      /* print lower bound */
3576 	      if( SCIPisInfinity(scip, -lb) )
3577 	      {
3578 	         if( !sectionName )
3579 	         {
3580 	            printBoundSectionName(scip, file);
3581 	            sectionName = TRUE;
3582 	         }
3583 	
3584 	         /* the free variables are processed above */
3585 	         assert( !SCIPisInfinity(scip, ub) );
3586 	         printStart(scip, file, "MI", "Bound", (int) maxnamelen);
3587 	         printRecord(scip, file, varname, "", maxnamelen);
3588 	         SCIPinfoMessage(scip, file, "\n");
3589 	      }
3590 	      else
3591 	      {
3592 	         if( SCIPisZero(scip, lb) )
3593 	         {
3594 	            lb = 0.0;
3595 	         }
3596 	         else
3597 	         {
3598 	            if( !sectionName )
3599 	            {
3600 	               printBoundSectionName(scip, file);
3601 	               sectionName = TRUE;
3602 	            }
3603 	
3604 	            (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3605 	            printStart(scip, file, "LO", "Bound", (int) maxnamelen);
3606 	            printRecord(scip, file, varname, valuestr, maxnamelen);
3607 	            SCIPinfoMessage(scip, file, "\n");
3608 	         }
3609 	      }
3610 	
3611 	      /* print upper bound, infinity has to be printed for integer (!) variables, because during
3612 	       * reading an mps file no upper bound of an integer variable means that the upper bound will
3613 	       * be set to 1 instead of +infinity (like it is for continuous variables) */
3614 	      if( SCIPisInfinity(scip, ub) )
3615 	      {
3616 	         if( !sectionName )
3617 	         {
3618 	            printBoundSectionName(scip, file);
3619 	            sectionName = TRUE;
3620 	         }
3621 	
3622 	         /* the free variables are processed above */
3623 	         assert( !SCIPisInfinity(scip, -lb) );
3624 	         printStart(scip, file, "PL", "Bound", (int) maxnamelen);
3625 	         printRecord(scip, file, varname, "", maxnamelen);
3626 	         SCIPinfoMessage(scip, file, "\n");
3627 	      }
3628 	      else
3629 	      {
3630 	         if( !sectionName )
3631 	         {
3632 	            printBoundSectionName(scip, file);
3633 	            sectionName = TRUE;
3634 	         }
3635 	
3636 	         (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", ub);
3637 	         printStart(scip, file, "UP", "Bound", (int) maxnamelen);
3638 	         printRecord(scip, file, varname, valuestr, maxnamelen);
3639 	         SCIPinfoMessage(scip, file, "\n");
3640 	      }
3641 	   }
3642 	
3643 	   /* output aggregated variables as 'free', except if they are binary */
3644 	   for( v = 0; v < naggvars; ++v )
3645 	   {
3646 	      if( !sectionName )
3647 	      {
3648 	         printBoundSectionName(scip, file);
3649 	         sectionName = TRUE;
3650 	      }
3651 	
3652 	      var = aggvars[v];
3653 	      assert( var != NULL );
3654 	
3655 	      /* get variable name */
3656 	      varname = varnames[nvars + v];
3657 	      assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
3658 	
3659 	      /* take care of binary variables */
3660 	      if( SCIPvarGetType(var) == SCIP_VARTYPE_BINARY )
3661 	      {
3662 	         printStart(scip, file, "BV", "Bound", (int) maxnamelen);
3663 	         printRecord(scip, file, varname, "", maxnamelen);
3664 	         SCIPinfoMessage(scip, file, "\n");
3665 	      }
3666 	      else
3667 	      {
3668 	         /* variable is free */
3669 	         printStart(scip, file, "FR", "Bound", (int) maxnamelen);
3670 	         printRecord(scip, file, varname, "", maxnamelen);
3671 	         SCIPinfoMessage(scip, file, "\n");
3672 	      }
3673 	   }
3674 	
3675 	   /* output all fixed variables */
3676 	   for( v = 0; v < nfixvars; ++v )
3677 	   {
3678 	      /* we should print the transformed problem, otherwise no fixed variable should exists */
3679 	      assert(transformed);
3680 	      assert(fixvars != NULL && fixvars[v] != NULL);
3681 	
3682 	      /* cppcheck-suppress nullPointer */
3683 	      var = fixvars[v];
3684 	
3685 	      assert(var != NULL);
3686 	      assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED);
3687 	
3688 	      /* get variable name */
3689 	      varname = varnames[nvars + naggvars + v];
3690 	      assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
3691 	
3692 	      /* only local bounds are posted which are valid in the current node */
3693 	      lb = SCIPvarGetLbLocal(var);
3694 	      ub = SCIPvarGetUbLocal(var);
3695 	      assert(SCIPisEQ(scip, lb, ub));
3696 	
3697 	      if( !sectionName )
3698 	      {
3699 	         printBoundSectionName(scip, file);
3700 	         sectionName = TRUE;
3701 	      }
3702 	
3703 	      /* print fixed variable */
3704 	      (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3705 	      printStart(scip, file, "FX", "Bound", (int) maxnamelen);
3706 	      printRecord(scip, file, varname, valuestr, maxnamelen);
3707 	      SCIPinfoMessage(scip, file, "\n");
3708 	   }
3709 	}
3710 	
3711 	
3712 	/*
3713 	 * Callback methods of reader
3714 	 */
3715 	
3716 	/** copy method for reader plugins (called when SCIP copies plugins) */
3717 	/**! [SnippetReaderCopyMps] */
3718 	static
3719 	SCIP_DECL_READERCOPY(readerCopyMps)
3720 	{  /*lint --e{715}*/
3721 	   assert(scip != NULL);
3722 	   assert(reader != NULL);
3723 	   assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3724 	
3725 	   /* call inclusion method of reader */
3726 	   SCIP_CALL( SCIPincludeReaderMps(scip) );
3727 	
3728 	   return SCIP_OKAY;
3729 	}
3730 	/**! [SnippetReaderCopyMps] */
3731 	
3732 	/** destructor of reader to free user data (called when SCIP is exiting) */
3733 	/**! [SnippetReaderFreeMps] */
3734 	static
3735 	SCIP_DECL_READERFREE(readerFreeMps)
3736 	{
3737 	   SCIP_READERDATA* readerdata;
3738 	
3739 	   assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3740 	   readerdata = SCIPreaderGetData(reader);
3741 	   assert(readerdata != NULL);
3742 	   SCIPfreeBlockMemory(scip, &readerdata);
3743 	
3744 	   return SCIP_OKAY;
3745 	}
3746 	/**! [SnippetReaderFreeMps] */
3747 	
3748 	/** problem reading method of reader */
3749 	static
3750 	SCIP_DECL_READERREAD(readerReadMps)
3751 	{  /*lint --e{715}*/
3752 	   assert(reader != NULL);
3753 	   assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3754 	
3755 	   SCIP_CALL( SCIPreadMps(scip, reader, filename, result, NULL, NULL, NULL, NULL, NULL, NULL) );
3756 	
3757 	   return SCIP_OKAY;
3758 	}
3759 	
3760 	
3761 	/** problem writing method of reader */
3762 	static
3763 	SCIP_DECL_READERWRITE(readerWriteMps)
3764 	{  /*lint --e{715}*/
3765 	   assert(reader != NULL);
3766 	   assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3767 	
3768 	   SCIP_CALL( SCIPwriteMps(scip, reader, file, name, transformed, objsense, objscale, objoffset, vars,
3769 	         nvars, nbinvars, nintvars, nimplvars, ncontvars, fixedvars, nfixedvars, conss, nconss, result) );
3770 	
3771 	   return SCIP_OKAY;
3772 	}
3773 	
3774 	
3775 	/*
3776 	 * mps file reader specific interface methods
3777 	 */
3778 	
3779 	/** includes the mps file reader in SCIP */
3780 	SCIP_RETCODE SCIPincludeReaderMps(
3781 	   SCIP*                 scip                /**< SCIP data structure */
3782 	   )
3783 	{
3784 	   SCIP_READERDATA* readerdata;
3785 	   SCIP_READER* reader;
3786 	
3787 	   /* create reader data */
3788 	   SCIP_CALL( SCIPallocBlockMemory(scip, &readerdata) );
3789 	
3790 	   /* include reader */
3791 	   SCIP_CALL( SCIPincludeReaderBasic(scip, &reader, READER_NAME, READER_DESC, READER_EXTENSION, readerdata) );
3792 	
3793 	   /* set non fundamental callbacks via setter functions */
3794 	   SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyMps) );
3795 	   SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreeMps) );
3796 	   SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadMps) );
3797 	   SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteMps) );
3798 	
3799 	   /* add lp-reader parameters */
3800 	   SCIP_CALL( SCIPaddBoolParam(scip,
3801 	         "reading/" READER_NAME "/linearize-and-constraints",
3802 	         "should possible \"and\" constraint be linearized when writing the mps file?",
3803 	         &readerdata->linearizeands, TRUE, DEFAULT_LINEARIZE_ANDS, NULL, NULL) );
3804 	   SCIP_CALL( SCIPaddBoolParam(scip,
3805 	         "reading/" READER_NAME "/aggrlinearization-ands",
3806 	         "should an aggregated linearization for and constraints be used?",
3807 	         &readerdata->aggrlinearizationands, TRUE, DEFAULT_AGGRLINEARIZATION_ANDS, NULL, NULL) );
3808 	
3809 	   return SCIP_OKAY;
3810 	}
3811 	
3812 	
3813 	/** reads problem from file */
3814 	SCIP_RETCODE SCIPreadMps(
3815 	   SCIP*                 scip,               /**< SCIP data structure */
3816 	   SCIP_READER*          reader,             /**< the file reader itself */
3817 	   const char*           filename,           /**< full path and name of file to read, or NULL if stdin should be used */
3818 	   SCIP_RESULT*          result,             /**< pointer to store the result of the file reading call */
3819 	   const char***         varnames,           /**< storage for the variable names, or NULL */
3820 	   const char***         consnames,          /**< storage for the constraint names, or NULL */
3821 	   int*                  varnamessize,       /**< the size of the variable names storage, or NULL */
3822 	   int*                  consnamessize,      /**< the size of the constraint names storage, or NULL */
3823 	   int*                  nvarnames,          /**< the number of stored variable names, or NULL */
3824 	   int*                  nconsnames          /**< the number of stored constraint names, or NULL */
3825 	   )
3826 	{
3827 	   SCIP_RETCODE retcode;
3828 	
3829 	   assert(reader != NULL);
3830 	   assert(scip != NULL);
3831 	   assert(result != NULL);
3832 	
3833 	   retcode = readMps(scip, filename, varnames, consnames, varnamessize, consnamessize, nvarnames, nconsnames);
3834 	
3835 	   if( retcode == SCIP_PLUGINNOTFOUND )
3836 	      retcode = SCIP_READERROR;
3837 	
3838 	   if( retcode == SCIP_NOFILE || retcode == SCIP_READERROR )
3839 	      return retcode;
3840 	
3841 	   SCIP_CALL( retcode );
3842 	
3843 	   *result = SCIP_SUCCESS;
3844 	
3845 	   return SCIP_OKAY;
3846 	}
3847 	
3848 	
3849 	/** writes problem to file */
3850 	SCIP_RETCODE SCIPwriteMps(
3851 	   SCIP*                 scip,               /**< SCIP data structure */
3852 	   SCIP_READER*          reader,             /**< the file reader itself */
3853 	   FILE*                 file,               /**< output file, or NULL if standard output should be used */
3854 	   const char*           name,               /**< problem name */
3855 	   SCIP_Bool             transformed,        /**< TRUE iff problem is the transformed problem */
3856 	   SCIP_OBJSENSE         objsense,           /**< objective sense */
3857 	   SCIP_Real             objscale,           /**< scalar applied to objective function; external objective value is
3858 	                                              *   extobj = objsense * objscale * (intobj + objoffset) */
3859 	   SCIP_Real             objoffset,          /**< objective offset from bound shifting and fixing */
3860 	   SCIP_VAR**            vars,               /**< array with active variables ordered binary, integer, implicit, continuous */
3861 	   int                   nvars,              /**< number of active variables in the problem */
3862 	   int                   nbinvars,           /**< number of binary variables */
3863 	   int                   nintvars,           /**< number of general integer variables */
3864 	   int                   nimplvars,          /**< number of implicit integer variables */
3865 	   int                   ncontvars,          /**< number of continuous variables */
3866 	   SCIP_VAR**            fixedvars,          /**< array with fixed and aggregated variables */
3867 	   int                   nfixedvars,         /**< number of fixed and aggregated variables in the problem */
3868 	   SCIP_CONS**           conss,              /**< array with constraints of the problem */
3869 	   int                   nconss,             /**< number of constraints in the problem */
3870 	   SCIP_RESULT*          result              /**< pointer to store the result of the file writing call */
3871 	   )
3872 	{
3873 	   SCIP_READERDATA* readerdata;
3874 	   int naddrows;
3875 	   int faulty = 0;
3876 	   int c;
3877 	   int v;
3878 	   int k;
3879 	   char* namestr;
3880 	
3881 	   SCIP_CONS* cons = NULL;
3882 	   const char* consname;
3883 	   const char** consnames;
3884 	
3885 	   SCIP_CONSHDLR* conshdlr;
3886 	   const char* conshdlrname;
3887 	
3888 	   SCIP_Real lhs;
3889 	   SCIP_Real rhs;
3890 	   SCIP_Real* rhss;
3891 	   SCIP_Real value;
3892 	
3893 	   SCIP_VAR* var = NULL;
3894 	   const char* varname;
3895 	   const char** varnames;
3896 	
3897 	   char valuestr[MPS_MAX_VALUELEN] = { '\0' };
3898 	
3899 	   SCIP_CONS** consIndicator;
3900 	   SCIP_CONS** consSOS1;
3901 	   SCIP_CONS** consSOS2;
3902 	   SCIP_CONS** consQuadratic;
3903 	   int nConsIndicator;
3904 	   int nConsSOS1;
3905 	   int nConsSOS2;
3906 	   int nConsQuadratic;
3907 	
3908 	   SCIP_HASHMAP* varnameHashmap;           /* hash map from SCIP_VAR* to variable name */
3909 	   SPARSEMATRIX* matrix;
3910 	
3911 	   SCIP_VAR** aggvars;
3912 	   int naggvars = 0;
3913 	   int saggvars;
3914 	   SCIP_HASHTABLE* varFixedHash;
3915 	   SCIP_HASHTABLE* indicatorSlackHash;
3916 	
3917 	   SCIP_VAR** fixvars = NULL;
3918 	   int nfixvars = 0;
3919 	
3920 	   SCIP_VAR** consvars;
3921 	   int nconsvars;
3922 	   SCIP_Real* vals;
3923 	   SCIP_Longint* weights;
3924 	
3925 	   SCIP_Bool needRANGES;
3926 	   unsigned int maxnamelen;
3927 	
3928 	   SCIP_Bool error;
3929 	
3930 	   assert(reader != NULL);
3931 	   assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3932 	   assert(scip != NULL);
3933 	   assert(result != NULL);
3934 	
3935 	   needRANGES = FALSE;
3936 	   maxnamelen = 0;
3937 	   nConsSOS1 = 0;
3938 	   nConsSOS2 = 0;
3939 	   nConsQuadratic = 0;
3940 	   nConsIndicator = 0;
3941 	
3942 	   /* check if the constraint names are too long and build the constraint names */
3943 	   SCIP_CALL( checkConsnames(scip, conss, nconss, transformed, &maxnamelen, &consnames, &error) );
3944 	   if( error )
3945 	   {
3946 	      /* call writing with generic names */
3947 	      if( transformed )
3948 	      {
3949 	         SCIPwarningMessage(scip, "write transformed problem with generic variable and constraint names\n");
3950 	         SCIP_CALL( SCIPprintTransProblem(scip, file, "mps", TRUE) );
3951 	      }
3952 	      else
3953 	      {
3954 	         SCIPwarningMessage(scip, "write original problem with generic variable and constraint names\n");
3955 	         SCIP_CALL( SCIPprintOrigProblem(scip, file, "mps", TRUE) );
3956 	      }
3957 	      *result = SCIP_SUCCESS;
3958 	
3959 	      return SCIP_OKAY;
3960 	   }
3961 	
3962 	   /* check if the variable names are not too long and build the "variable" -> "variable name" hash map */
3963 	   SCIP_CALL( checkVarnames(scip, vars, nvars, &maxnamelen, &varnames, &varnameHashmap) );
3964 	
3965 	   /* collect SOS, quadratic, and indicator constraints in array for later output */
3966 	   SCIP_CALL( SCIPallocBufferArray(scip, &consSOS1, nconss) );
3967 	   SCIP_CALL( SCIPallocBufferArray(scip, &consSOS2, nconss) );
3968 	   SCIP_CALL( SCIPallocBufferArray(scip, &consQuadratic, nconss) );
3969 	   SCIP_CALL( SCIPallocBufferArray(scip, &consIndicator, nconss) );
3970 	
3971 	   /* nfixedvars counts all variables with status SCIP_VARSTATUS_FIXED, SCIP_VARSTATUS_AGGREGATED, SCIP_VARSTATUS_MULTAGGR, but not SCIP_VARSTATUS_NEGATED */
3972 	   saggvars = nfixedvars;
3973 	   SCIP_CALL( SCIPallocBlockMemoryArray(scip, &aggvars, saggvars) );
3974 	
3975 	   /* create hashtable for storing aggregated variables */
3976 	   if( nfixedvars > 0 )
3977 	   {
3978 	      SCIP_CALL( SCIPhashtableCreate(&varFixedHash, SCIPblkmem(scip), nfixedvars, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
3979 	   }
3980 	   else
3981 	      varFixedHash = NULL;
3982 	
3983 	   if( nvars > 0 )
3984 	   {
3985 	      SCIP_CALL( SCIPhashtableCreate(&indicatorSlackHash, SCIPblkmem(scip), nvars, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
3986 	   }
3987 	   else
3988 	      indicatorSlackHash = NULL;
3989 	
3990 	   /* initialize sparse matrix */
3991 	   SCIP_CALL( initializeMatrix(scip, &matrix, (nvars * 2 + nfixedvars)) );
3992 	   assert( matrix->sentries >= nvars );
3993 	
3994 	   readerdata = SCIPreaderGetData(reader);
3995 	   assert(readerdata != NULL);
3996 	
3997 	   naddrows = 0;
3998 	
3999 	   /* determine and-constraints and printing format to resize necessary arrays */
4000 	   if( readerdata->linearizeands )
4001 	   {
4002 	      SCIP_CONSHDLR* andconshdlr = SCIPfindConshdlr(scip, "and");
4003 	
4004 	      if( andconshdlr != NULL )
4005 	      {
4006 	         /* need to check for and-constraints, note that in the original problem you cannot get the number of
4007 	          * and-constraints by one call */
4008 	         for( c = nconss - 1; c >= 0; --c )
4009 	         {
4010 	            conshdlr = SCIPconsGetHdlr(conss[c]);
4011 	            assert(conshdlr != NULL);
4012 	
4013 	            conshdlrname = SCIPconshdlrGetName(conshdlr);
4014 	
4015 	            if( strcmp(conshdlrname, "and") == 0 )
4016 	            {
4017 	               if( readerdata->aggrlinearizationands )
4018 	                  ++naddrows;
4019 	               else
4020 	                  naddrows += SCIPgetNVarsAnd(scip, conss[c]);
4021 	            }
4022 	         }
4023 	         assert(naddrows >= 0);
4024 	
4025 	         if( naddrows > 0 )
4026 	         {
4027 	            /* resize consnames vector */
4028 	            SCIP_CALL( SCIPreallocBufferArray(scip, &consnames, nconss + naddrows) );
4029 	         }
4030 	      }
4031 	   }
4032 	
4033 	   /* initialize rhs vector */
4034 	   SCIP_CALL( SCIPallocBufferArray(scip, &rhss, nconss + naddrows) );
4035 	
4036 	   /* print statistics as comment to file stream */
4037 	   SCIPinfoMessage(scip, file, "* SCIP STATISTICS\n");
4038 	   SCIPinfoMessage(scip, file, "*   Problem name     : %s\n", name);
4039 	   SCIPinfoMessage(scip, file, "*   Variables        : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
4040 	      nvars, nbinvars, nintvars, nimplvars, ncontvars);
4041 	   SCIPinfoMessage(scip, file, "*   Constraints      : %d\n", nconss);
4042 	
4043 	   /* print NAME of the problem */
4044 	   SCIPinfoMessage(scip, file, "%-14s%s\n", "NAME", name);
4045 	
4046 	   /* print OBJSENSE of the problem */
4047 	   SCIPinfoMessage(scip, file, "OBJSENSE\n");
4048 	   SCIPinfoMessage(scip, file, "%s\n", objsense == SCIP_OBJSENSE_MAXIMIZE ? "  MAX" : "  MIN");
4049 	
4050 	   /* start ROWS section */
4051 	   SCIPinfoMessage(scip, file, "ROWS\n");
4052 	
4053 	   /* print row type for the objective function */
4054 	   printStart(scip, file, "N", "Obj", -1);
4055 	   SCIPinfoMessage(scip, file, "\n");
4056 	
4057 	   /* first fill the matrix with the objective coefficients */
4058 	   for( v = 0; v < nvars; ++v )
4059 	   {
4060 	      /* take care of the objective entry */
4061 	      var = vars[v];
4062 	      value = SCIPvarGetObj(var);
4063 	
4064 	      /* we also want to add integer variables to the columns section, even if the objective value is 0, because it
4065 	       * might happen that they only exist in non-linear constraints, which leads to no other line in the column section
4066 	       * and therefore do not mark the variable as an integer
4067 	       */
4068 	      if( !SCIPisZero(scip, value) || SCIPvarGetType(var) < SCIP_VARTYPE_IMPLINT
4069 	         || ((SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == 0)
4070 	            && (SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 0)) )
4071 	      {
4072 	         assert( matrix->nentries < matrix->sentries );
4073 	
4074 	         matrix->values[matrix->nentries] = objscale * value;
4075 	         matrix->columns[matrix->nentries] = var;
4076 	         matrix->rows[matrix->nentries] = "Obj";
4077 	         matrix->nentries++;
4078 	      }
4079 	   }
4080 	
4081 	   /* loop over all constraints */
4082 	   k = nconss;
4083 	   for( c = 0; c < nconss; ++c )
4084 	   {
4085 	      cons = conss[c];
4086 	      assert( cons != NULL);
4087 	
4088 	      /* in case the transformed problems is written only constraint are posted which are enabled in the current node;
4089 	       * the conss array should only contain relevant constraints
4090 	       */
4091 	      assert( !transformed || SCIPconsIsEnabled(cons) );
4092 	
4093 	      conshdlr = SCIPconsGetHdlr(cons);
4094 	      assert( conshdlr != NULL );
4095 	
4096 	      conshdlrname = SCIPconshdlrGetName(conshdlr);
4097 	
4098 	      /* construct constraint name */
4099 	      consname = consnames[c];
4100 	
4101 	      /* init rhs value to infinity (would then ignored) */
4102 	      rhss[c] = SCIPinfinity(scip);
4103 	
4104 	      if( strcmp(conshdlrname, "linear") == 0 )
4105 	      {
4106 	         lhs = SCIPgetLhsLinear(scip, cons);
4107 	         rhs = SCIPgetRhsLinear(scip, cons);
4108 	
4109 	         /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
4110 	         if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
4111 	         {
4112 	            if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
4113 	               needRANGES = TRUE;
4114 	
4115 	            /* print row entry */
4116 	            printRowType(scip, file, lhs, rhs, consname);
4117 	
4118 	            if( SCIPisInfinity(scip, rhs) )
4119 	               rhss[c] = lhs;
4120 	            else
4121 	               rhss[c] = rhs;
4122 	
4123 	            assert( !SCIPisInfinity(scip, rhss[c]) );
4124 	
4125 	            /* compute column entries */
4126 	            SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons),
4127 	                  SCIPgetNVarsLinear(scip, cons), transformed, matrix, &rhss[c]) );
4128 	         }
4129 	      }
4130 	      else if( strcmp(conshdlrname, "setppc") == 0 )
4131 	      {
4132 	         /* print row entry */
4133 	         switch( SCIPgetTypeSetppc(scip, cons) )
4134 	         {
4135 	         case SCIP_SETPPCTYPE_PARTITIONING :
4136 	            printRowType(scip, file, 1.0, 1.0, consname);
4137 	            break;
4138 	         case SCIP_SETPPCTYPE_PACKING :
4139 	            printRowType(scip, file, -SCIPinfinity(scip), 1.0, consname);
4140 	            break;
4141 	         case SCIP_SETPPCTYPE_COVERING :
4142 	            printRowType(scip, file, 1.0, SCIPinfinity(scip), consname);
4143 	            break;
4144 	         }
4145 	
4146 	         rhss[c] = 1.0;
4147 	
4148 	         /* compute column entries */
4149 	         SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsSetppc(scip, cons), NULL, SCIPgetNVarsSetppc(scip, cons), transformed, matrix, &rhss[c]) );
4150 	      }
4151 	      else if( strcmp(conshdlrname, "logicor") == 0 )
4152 	      {
4153 	         /* print row entry */
4154 	         printRowType(scip, file, 1.0, SCIPinfinity(scip), consname);
4155 	
4156 	         rhss[c] = 1.0;
4157 	
4158 	         /* compute column entries */
4159 	         SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons), transformed, matrix, &rhss[c]) );
4160 	      }
4161 	      else if( strcmp(conshdlrname, "knapsack") == 0 )
4162 	      {
4163 	         int i;
4164 	
4165 	         /* print row entry */
4166 	         printRowType(scip, file, -SCIPinfinity(scip), (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), consname);
4167 	
4168 	         nconsvars = SCIPgetNVarsKnapsack(scip, cons);
4169 	         weights = SCIPgetWeightsKnapsack(scip, cons);
4170 	
4171 	         /* copy Longint array to SCIP_Real array */
4172 	         SCIP_CALL( SCIPallocBufferArray(scip, &vals, nconsvars ) );
4173 	         for( i = 0; i < nconsvars; ++i )
4174 	            vals[i] = (SCIP_Real)weights[i];
4175 	
4176 	         rhss[c] = (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons);
4177 	
4178 	         /* compute column entries */
4179 	         SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsKnapsack(scip, cons), vals, nconsvars, transformed, matrix, &rhss[c]) );
4180 	
4181 	         SCIPfreeBufferArray(scip, &vals);
4182 	      }
4183 	      else if( strcmp(conshdlrname, "varbound") == 0 )
4184 	      {
4185 	         lhs = SCIPgetLhsVarbound(scip, cons);
4186 	         rhs = SCIPgetRhsVarbound(scip, cons);
4187 	
4188 	         /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
4189 	         if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
4190 	         {
4191 	            if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
4192 	               needRANGES = TRUE;
4193 	
4194 	            /* print row entry */
4195 	            printRowType(scip, file, lhs, rhs, consname);
4196 	
4197 	            /* allocate memory */
4198 	            SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
4199 	            SCIP_CALL( SCIPallocBufferArray(scip, &vals, 2) );
4200 	
4201 	            consvars[0] = SCIPgetVarVarbound(scip, cons);
4202 	            consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
4203 	
4204 	            vals[0] = 1.0;
4205 	            vals[1] = SCIPgetVbdcoefVarbound(scip, cons);
4206 	
4207 	            if( SCIPisInfinity(scip, rhs) )
4208 	               rhss[c] = lhs;
4209 	            else
4210 	               rhss[c] = rhs;
4211 	
4212 	            assert( !SCIPisInfinity(scip, rhss[c]) );
4213 	
4214 	            /* compute column entries */
4215 	            SCIP_CALL( getLinearCoeffs(scip, consname, consvars, vals, 2, transformed, matrix, &rhss[c]) );
4216 	
4217 	            SCIPfreeBufferArray(scip, &vals);
4218 	            SCIPfreeBufferArray(scip, &consvars);
4219 	         }
4220 	      }
4221 	      else if( strcmp(conshdlrname, "indicator") == 0 )
4222 	      {
4223 	         SCIP_VAR* slackvar;
4224 	         SCIP_VAR* binvar;
4225 	
4226 	         /* store slack variable in hash */
4227 	         slackvar = SCIPgetSlackVarIndicator(cons);
4228 	         assert( slackvar != NULL );
4229 	         assert( indicatorSlackHash != NULL );
4230 	         assert( !SCIPhashtableExists(indicatorSlackHash, (void*) slackvar) );
4231 	         SCIP_CALL( SCIPhashtableInsert(indicatorSlackHash, (void*) slackvar) );
4232 	
4233 	         /* if slackvariable is aggregated, we store it in the list of aggregated variables */
4234 	         if ( SCIPvarGetStatus(slackvar) == SCIP_VARSTATUS_AGGREGATED )
4235 	         {
4236 	            SCIP_CALL( collectAggregatedVars(scip, &slackvar, 1, &aggvars, &naggvars, &saggvars, varFixedHash) );
4237 	         }
4238 	
4239 	         /* store aggregated variables */
4240 	         binvar = SCIPgetBinaryVarIndicator(cons);
4241 	         if( SCIPvarIsNegated(binvar) )
4242 	            binvar = SCIPvarGetNegatedVar(binvar);
4243 	         assert( binvar != NULL );
4244 	         SCIP_CALL( collectAggregatedVars(scip, &binvar, 1, &aggvars, &naggvars, &saggvars, varFixedHash) );
4245 	
4246 	         /* indicator constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
4247 	         rhss[c] = SCIPinfinity(scip);
4248 	
4249 	         /* store constraint */
4250 	         consIndicator[nConsIndicator++] = cons;
4251 	         continue;
4252 	      }
4253 	      else if( strcmp(conshdlrname, "SOS1") == 0 )
4254 	      {
4255 	         /* store constraint */
4256 	         consSOS1[nConsSOS1++] = cons;
4257 	
4258 	         /* check for aggregated variables in SOS1 constraints for later output
4259 	          * of aggregations as linear constraints */
4260 	         consvars = SCIPgetVarsSOS1(scip, cons);
4261 	         nconsvars = SCIPgetNVarsSOS1(scip, cons);
4262 	
4263 	         /* SOS constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
4264 	         rhss[c] = SCIPinfinity(scip);
4265 	
4266 	         SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
4267 	      }
4268 	      else if( strcmp(conshdlrname, "SOS2") == 0 )
4269 	      {
4270 	         /* store constraint */
4271 	         consSOS2[nConsSOS2++] = cons;
4272 	
4273 	         /* check for aggregated variables in SOS2 constraints for later output aggregations as linear constraints */
4274 	         consvars = SCIPgetVarsSOS2(scip, cons);
4275 	         nconsvars = SCIPgetNVarsSOS2(scip, cons);
4276 	
4277 	         /* SOS constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
4278 	         rhss[c] = SCIPinfinity(scip);
4279 	
4280 	         SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
4281 	      }
4282 	      else if( strcmp(conshdlrname, "nonlinear") == 0 )
4283 	      {
4284 	         SCIP_EXPR* expr;
4285 	         SCIP_VAR** quadvars;
4286 	         SCIP_Real* quadvarlincoefs;
4287 	         SCIP_Real* lincoefs;
4288 	         SCIP_Real constant;
4289 	         SCIP_EXPR** linexprs;
4290 	         SCIP_Bool isquadratic;
4291 	         int nquadexprs;
4292 	         int nlinexprs;
4293 	         int j;
4294 	
4295 	         /* check if it is a quadratic constraint */
4296 	         SCIP_CALL( SCIPcheckQuadraticNonlinear(scip, cons, &isquadratic) );
4297 	         if( !isquadratic )
4298 	         {
4299 	            /* unknown constraint type; mark this with SCIPinfinity(scip) */
4300 	            rhss[c] = SCIPinfinity(scip);
4301 	
4302 	            SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
4303 	            continue;
4304 	         }
4305 	
4306 	         /* store constraint */
4307 	         consQuadratic[nConsQuadratic++] = cons;
4308 	
4309 	         expr = SCIPgetExprNonlinear(cons);
4310 	
4311 	         /* collect linear coefficients of quadratic part */
4312 	         SCIPexprGetQuadraticData(expr, &constant, &nlinexprs, &linexprs, &lincoefs, &nquadexprs, NULL, NULL,
4313 	               NULL);
4314 	
4315 	         SCIP_CALL( SCIPallocBufferArray(scip, &quadvars, nquadexprs) );
4316 	         SCIP_CALL( SCIPallocBufferArray(scip, &quadvarlincoefs, nquadexprs) );
4317 	         for( j = 0; j < nquadexprs; ++j )
4318 	         {
4319 	            SCIP_EXPR* qexpr;
4320 	
4321 	            SCIPexprGetQuadraticQuadTerm(expr, j, &qexpr, &quadvarlincoefs[j], NULL, NULL, NULL, NULL);
4322 	
4323 	            assert(SCIPisExprVar(scip, qexpr));
4324 	            quadvars[j] = SCIPgetVarExprVar(qexpr);
4325 	         }
4326 	
4327 	         lhs = SCIPgetLhsNonlinear(cons);
4328 	         rhs = SCIPgetRhsNonlinear(cons);
4329 	
4330 	         /* correct side by constant */
4331 	         lhs -= SCIPisInfinity(scip, -lhs) ? 0.0 : constant;
4332 	         rhs -= SCIPisInfinity(scip,  rhs) ? 0.0 : constant;
4333 	
4334 	         /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
4335 	         if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
4336 	         {
4337 	            SCIP_VAR** linvars;
4338 	
4339 	            if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
4340 	               needRANGES = TRUE;
4341 	
4342 	            /* print row entry */
4343 	            printRowType(scip, file, lhs, rhs, consname);
4344 	
4345 	            if( SCIPisInfinity(scip, rhs) )
4346 	               rhss[c] = lhs;
4347 	            else
4348 	               rhss[c] = rhs;
4349 	
4350 	            assert( !SCIPisInfinity(scip, rhss[c]) );
4351 	
4352 	            /* get linear vars */
4353 	            SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nlinexprs) );
4354 	            for( j = 0; j < nlinexprs; ++j )
4355 	               linvars[j] = SCIPgetVarExprVar(linexprs[j]);
4356 	
4357 	            /* compute column entries for linear part */
4358 	            SCIP_CALL( getLinearCoeffs(scip, consname, linvars, lincoefs, nlinexprs, transformed, matrix, &rhss[c]) );
4359 	
4360 	            /* compute column entries for linear part in quadratic part */
4361 	            SCIP_CALL( getLinearCoeffs(scip, consname, quadvars, quadvarlincoefs, nquadexprs, transformed, matrix,
4362 	                     &rhss[c]) );
4363 	
4364 	            SCIPfreeBufferArray(scip, &linvars);
4365 	         }
4366 	
4367 	         /* check for aggregated variables in quadratic part of quadratic constraints for later output of
4368 	          * aggregations as linear constraints */
4369 	         consvars = quadvars;
4370 	         nconsvars = nquadexprs;
4371 	
4372 	         SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
4373 	
4374 	         SCIPfreeBufferArray(scip, &quadvars);
4375 	         SCIPfreeBufferArray(scip, &quadvarlincoefs);
4376 	      }
4377 	      else if( strcmp(conshdlrname, "and") == 0 )
4378 	      {
4379 	         if( readerdata->linearizeands )
4380 	         {
4381 	            SCIP_VAR** rowvars;
4382 	            SCIP_VAR** operands;
4383 	            SCIP_VAR* resultant;
4384 	            SCIP_Real* rowvals;
4385 	            char* rowname;
4386 	            int nrowvars;
4387 	            int l;
4388 	            int n;
4389 	
4390 	            nrowvars = SCIPgetNVarsAnd(scip, cons);
4391 	            operands = SCIPgetVarsAnd(scip, cons);
4392 	            resultant = SCIPgetResultantAnd(scip, cons);
4393 	
4394 	            /* allocate buffer array */
4395 	            SCIP_CALL( SCIPallocBufferArray(scip, &rowvars, nrowvars + 1) );
4396 	            SCIP_CALL( SCIPallocBufferArray(scip, &rowvals, nrowvars + 1) );
4397 	
4398 	            /* get length of constraint name */
4399 	            l = (int) strlen(consname);
4400 	
4401 	            /* the tight relaxtion, number of and-constraint operands rows */
4402 	            if( !readerdata->aggrlinearizationands )
4403 	            {
4404 	               rowvars[0] = resultant;
4405 	               rowvals[0] = 1.0;
4406 	               rowvals[1] = -1.0;
4407 	
4408 	               /* compute maximal length for rowname */
4409 	               /* coverity[negative_returns] */
4410 	               n = (int) log10((double)nrowvars) + 1 + l;
4411 	
4412 	               /* assure maximal allowed value */
4413 	               if( n >= MPS_MAX_NAMELEN )
4414 	                  n = MPS_MAX_NAMELEN - 1;
4415 	
4416 	               /* update maxnamelen */
4417 	               maxnamelen = MAX(maxnamelen, (unsigned int) n);
4418 	
4419 	               /* print operator rows */
4420 	               for( v = 0; v < nrowvars; ++v )
4421 	               {
4422 	                  /* compute maximal length for rowname */
4423 	                  if( v == 0 )
4424 	                     n = 2;
4425 	                  else
4426 	                     n = (int) log10((double)v) + 2;
4427 	                  n += l;
4428 	
4429 	                  /* assure maximal allowed value */
4430 	                  if( n >= MPS_MAX_NAMELEN )
4431 	                  {
4432 	                     n = MPS_MAX_NAMELEN - 1;
4433 	                     ++faulty;
4434 	                  }
4435 	
4436 	                  /* need memory for additional row */
4437 	                  SCIP_CALL( SCIPallocBufferArray(scip, &rowname, n + 1) );
4438 	
4439 	                  assert(k < nconss + naddrows);
4440 	                  consnames[k] = rowname;
4441 	
4442 	                  (void) SCIPsnprintf(rowname, n + 1, "%s_%d", consname, v);
4443 	                  rowvars[1] = operands[v];
4444 	
4445 	                  /* print row entry */
4446 	                  printRowType(scip, file, -SCIPinfinity(scip), 0.0, rowname);
4447 	
4448 	                  rhss[k] = 0.0;
4449 	
4450 	                  /* compute column entries */
4451 	                  SCIP_CALL( getLinearCoeffs(scip, rowname, rowvars, rowvals, 2, transformed, matrix, &rhss[k]) );
4452 	                  ++k;
4453 	               }
4454 	            }
4455 	
4456 	            /* prepare for next row */
4457 	            for( v = nrowvars - 1; v >= 0; --v )
4458 	            {
4459 	               rowvars[v] = operands[v];
4460 	               rowvals[v] = -1.0;
4461 	            }
4462 	
4463 	            rowvars[nrowvars] = resultant;
4464 	
4465 	            /* the weak relaxtion, only one constraint */
4466 	            if( readerdata->aggrlinearizationands )
4467 	            {
4468 	               /* compute maximal length for rowname */
4469 	               n = l + 3;
4470 	
4471 	               /* assure maximal allowed value */
4472 	               if( n >= MPS_MAX_NAMELEN )
4473 	               {
4474 	                  n = MPS_MAX_NAMELEN - 1;
4475 	                  ++faulty;
4476 	               }
4477 	
4478 	               /* update maxnamelen */
4479 	               maxnamelen = MAX(maxnamelen, (unsigned int) n);
4480 	
4481 	               /* need memory for additional row */
4482 	               SCIP_CALL( SCIPallocBufferArray(scip, &rowname, n + 1) );
4483 	
4484 	               assert(k < nconss + naddrows);
4485 	               consnames[k] = rowname;
4486 	
4487 	               /* adjust rowname of constraint */
4488 	               (void) SCIPsnprintf(rowname, n + 1, "%s_op", consname);
4489 	
4490 	               rowvals[nrowvars] = (SCIP_Real) nrowvars;
4491 	
4492 	               /* print row entry */
4493 	               printRowType(scip, file, -SCIPinfinity(scip), 0.0, rowname);
4494 	
4495 	               rhss[k] = 0.0;
4496 	
4497 	               /* compute column entries */
4498 	               SCIP_CALL( getLinearCoeffs(scip, rowname, rowvars, rowvals, nrowvars + 1, transformed, matrix, &rhss[k]) );
4499 	
4500 	               SCIPdebugMsg(scip, "%g, %g\n", rowvals[1], rhss[k]);
4501 	               ++k;
4502 	            }
4503 	
4504 	            rowvals[nrowvars] = 1.0;
4505 	
4506 	            /* print row entry */
4507 	            printRowType(scip, file, -nrowvars + 1.0, SCIPinfinity(scip), consname);
4508 	
4509 	            rhss[c] = -nrowvars + 1.0;
4510 	
4511 	            /* compute column entries */
4512 	            SCIP_CALL( getLinearCoeffs(scip, consname, rowvars, rowvals, nrowvars + 1, transformed, matrix, &rhss[c]) );
4513 	
4514 	            /* free buffer array */
4515 	            SCIPfreeBufferArray(scip, &rowvals);
4516 	            SCIPfreeBufferArray(scip, &rowvars);
4517 	         }
4518 	         else
4519 	         {
4520 	            /* and constraint printing not enabled; mark this with SCIPinfinity(scip) */
4521 	            rhss[c] = SCIPinfinity(scip);
4522 	
4523 	            SCIPwarningMessage(scip, "change parameter \"reading/" READER_NAME "/linearize-and-constraints\" to TRUE to print and-constraints\n");
4524 	         }
4525 	      }
4526 	      else
4527 	      {
4528 	         /* unknown constraint type; mark this with SCIPinfinity(scip) */
4529 	         rhss[c] = SCIPinfinity(scip);
4530 	
4531 	         SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
4532 	      }
4533 	   }
4534 	
4535 	   if( faulty > 0 )
4536 	   {
4537 	      SCIPwarningMessage(scip, "there are %d and-constraint-rownames which have to be cut down to %d characters; MPS file might be corrupted\n",
4538 	         faulty, MPS_MAX_NAMELEN - 1);
4539 	   }
4540 	
4541 	   /* free hash table */
4542 	   if( varFixedHash != NULL )
4543 	      SCIPhashtableFree(&varFixedHash);
4544 	
4545 	   if( indicatorSlackHash != NULL && nConsIndicator == 0 )
4546 	   {
4547 	      SCIPhashtableFree(&indicatorSlackHash);
4548 	      assert( indicatorSlackHash == NULL );
4549 	   }
4550 	
4551 	   if( naggvars > 0 )
4552 	   {
4553 	      /* construct variables name of the needed aggregated variables and the constraint names for the aggregation constraints */
4554 	
4555 	      /* realloc memory */
4556 	      SCIP_CALL( SCIPreallocBufferArray(scip, &consnames, nconss + naddrows + naggvars) );
4557 	      SCIP_CALL( SCIPreallocBufferArray(scip, &rhss, nconss + naddrows + naggvars) );
4558 	      SCIP_CALL( SCIPreallocBufferArray(scip, &varnames, nvars + naggvars) );
4559 	
4560 	      for( c = 0; c < naggvars; ++c )
4561 	      {
4562 	         size_t l;
4563 	
4564 	         /* create variable name */
4565 	         var = aggvars[c];
4566 	
4567 	         l = strlen(SCIPvarGetName(var));
4568 	         if( l >= MPS_MAX_NAMELEN )
4569 	            maxnamelen = MPS_MAX_NAMELEN - 1;
4570 	         else
4571 	            maxnamelen = MAX(maxnamelen, (unsigned int) l);
4572 	
4573 	         SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) );
4574 	         (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
4575 	
4576 	         /* insert variable with variable name into hash map */
4577 	         varnames[nvars + c] = namestr;
4578 	         assert( !SCIPhashmapExists(varnameHashmap, var) );
4579 	         SCIP_CALL( SCIPhashmapInsert(varnameHashmap, var, (void*) namestr) );
4580 	
4581 	         /* output row type (it is an equation) */
4582 	         SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) ); /* note that namestr above is freed via varnames */
4583 	         (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(var));
4584 	         printRowType(scip, file, 1.0, 1.0, namestr);
4585 	
4586 	         l = strlen(namestr);
4587 	         maxnamelen = MAX(maxnamelen, (unsigned int) l);
4588 	         consnames[nconss + naddrows + c] = namestr;
4589 	         rhss[nconss + naddrows + c] = 0.0;
4590 	
4591 	         /* compute column entries */
4592 	         SCIP_CALL( getLinearCoeffs(scip, namestr, &(aggvars[c]), NULL, 1, transformed, matrix, &rhss[nconss + naddrows + c]) );
4593 	
4594 	         /* add the aggregated variables to the sparse matrix */
4595 	         SCIP_CALL( checkSparseMatrixCapacity(scip, matrix, 1) );
4596 	         matrix->values[matrix->nentries] = -1.0;
4597 	         matrix->columns[matrix->nentries] = aggvars[c];
4598 	         matrix->rows[matrix->nentries] = namestr;
4599 	         matrix->nentries++;
4600 	      }
4601 	   }
4602 	
4603 	   /* collect also fixed variables, because they might not be removed from all constraints */
4604 	   /* @todo only collect fixed variables in the non-linear constraint types, where they (could not be)/(were not) removed */
4605 	   if( nfixedvars > 0 )
4606 	   {
4607 	      int startpos = nvars + naggvars;
4608 	      /* construct variables name of fixed variables */
4609 	
4610 	      /* realloc memory */
4611 	      SCIP_CALL( SCIPreallocBufferArray(scip, &varnames, startpos + nfixedvars) );
4612 	
4613 	      /* allocate memory for fixed variables */
4614 	      SCIP_CALL( SCIPallocBufferArray(scip, &fixvars, nfixedvars) );
4615 	
4616 	      for( v = nfixedvars - 1; v >= 0; --v )
4617 	      {
4618 	         /* create variable name */
4619 	         var = fixedvars[v];
4620 	
4621 		 if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED )
4622 		 {
4623 	            size_t l;
4624 		    l = strlen(SCIPvarGetName(var));
4625 		    if( l >= MPS_MAX_NAMELEN )
4626 		       maxnamelen = MPS_MAX_NAMELEN - 1;
4627 		    else
4628 		       maxnamelen = MAX(maxnamelen, (unsigned int) l);
4629 	
4630 		    SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) );
4631 		    (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
4632 	
4633 		    varnames[startpos + nfixvars] = namestr;
4634 		    fixvars[nfixvars] = var;
4635 		    ++nfixvars;
4636 	
4637 		    /* insert variable with variable name into hash map */
4638 		    assert(!SCIPhashmapExists(varnameHashmap, var));
4639 		    SCIP_CALL( SCIPhashmapInsert(varnameHashmap, var, (void*) namestr) );
4640 	
4641 		    /* add the fixed variables to the sparse matrix, needed for columns section */
4642 		    SCIP_CALL( checkSparseMatrixCapacity(scip, matrix, 1) );
4643 		    matrix->values[matrix->nentries] = 0.0;
4644 		    matrix->columns[matrix->nentries] = var;
4645 		    matrix->rows[matrix->nentries] = "Obj";
4646 		    matrix->nentries++;
4647 		 }
4648 	      }
4649 	   }
4650 	
4651 	   /* output COLUMNS section */
4652 	   printColumnSection(scip, file, matrix, varnameHashmap, indicatorSlackHash, maxnamelen);
4653 	
4654 	   /* output RHS section */
4655 	   printRhsSection(scip, file, nconss + naddrows +naggvars, consnames, rhss, maxnamelen, objscale * objoffset);
4656 	
4657 	   /* output RANGES section */
4658 	   if( needRANGES )
4659 	      printRangeSection(scip, file, conss, nconss, consnames, transformed, maxnamelen);
4660 	
4661 	   /* output BOUNDS section */
4662 	   printBoundSection(scip, file, vars, nvars, aggvars, naggvars, fixvars, nfixvars, transformed, varnames, indicatorSlackHash, maxnamelen);
4663 	
4664 	   if( nfixedvars > 0 )
4665 	   {
4666 	      SCIPfreeBufferArray(scip, &fixvars);
4667 	   }
4668 	
4669 	   /* print SOS section */
4670 	   if( nConsSOS1 > 0 || nConsSOS2 > 0 )
4671 	   {
4672 	      SCIP_Real* sosweights;
4673 	
4674 	      SCIPinfoMessage(scip, file, "SOS\n");
4675 	      SCIPdebugMsg(scip, "start printing SOS section\n");
4676 	
4677 	      SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) );
4678 	
4679 	      /* first output SOS1 constraints */
4680 	      for( c = 0; c < nConsSOS1; ++c )
4681 	      {
4682 	         cons = consSOS1[c];
4683 	         consvars = SCIPgetVarsSOS1(scip, cons);
4684 	         nconsvars = SCIPgetNVarsSOS1(scip, cons);
4685 	         sosweights = SCIPgetWeightsSOS1(scip, cons);
4686 	         (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
4687 	
4688 	         printStart(scip, file, "S1", namestr, -1);
4689 	         SCIPinfoMessage(scip, file, "\n");
4690 	
4691 	         for( v = 0; v < nconsvars; ++v )
4692 	         {
4693 	            /* get variable name */
4694 	            assert ( SCIPhashmapExists(varnameHashmap, consvars[v]) );
4695 	            varname = (const char*) SCIPhashmapGetImage(varnameHashmap, consvars[v]);
4696 	
4697 	            printStart(scip, file, "", varname, (int) maxnamelen);
4698 	
4699 	            if( sosweights != NULL )
4700 	               (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sosweights[v]);
4701 	            else
4702 	               (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d ", v);
4703 	
4704 	            SCIPinfoMessage(scip, file, "%25s\n", valuestr);
4705 	         }
4706 	      }
4707 	
4708 	      /* next output SOS2 constraints */
4709 	      for( c = 0; c < nConsSOS2; ++c )
4710 	      {
4711 	         cons = consSOS2[c];
4712 	         consvars = SCIPgetVarsSOS2(scip, cons);
4713 	         nconsvars = SCIPgetNVarsSOS2(scip, cons);
4714 	         sosweights = SCIPgetWeightsSOS2(scip, cons);
4715 	         (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
4716 	
4717 	         printStart(scip, file, "S2", namestr, -1);
4718 	         SCIPinfoMessage(scip, file, "\n");
4719 	
4720 	         for( v = 0; v < nconsvars; ++v )
4721 	         {
4722 	            /* get variable name */
4723 	            assert ( SCIPhashmapExists(varnameHashmap, consvars[v]) );
4724 	            varname = (const char*) SCIPhashmapGetImage(varnameHashmap, consvars[v]);
4725 	
4726 	            printStart(scip, file, "", varname, (int) maxnamelen);
4727 	
4728 	            if( sosweights != NULL )
4729 	               (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sosweights[v]);
4730 	            else
4731 	               (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d ", v);
4732 	
4733 	            SCIPinfoMessage(scip, file, "%25s\n", valuestr);
4734 	         }
4735 	      }
4736 	      SCIPfreeBufferArray(scip, &namestr);
4737 	   }
4738 	
4739 	   /* print QCMATRIX sections for quadratic constraints
4740 	    * in difference to a quadratic term in the objective function, the quadratic part is not divided by 2 here
4741 	    */
4742 	   if( nConsQuadratic > 0 )
4743 	   {
4744 	      const char* varname2;
4745 	      int nbilin;
4746 	
4747 	      SCIPdebugMsg(scip, "start printing QCMATRIX sections for quadratic constraints\n");
4748 	      SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) );
4749 	
4750 	      for( c = 0; c < nConsQuadratic; ++c )
4751 	      {
4752 	         SCIP_EXPR* expr;
4753 	
4754 	         cons = consQuadratic[c];
4755 	         expr = SCIPgetExprNonlinear(cons);
4756 	
4757 	         SCIPexprGetQuadraticData(expr, NULL, NULL, NULL, NULL, &nconsvars, &nbilin, NULL, NULL);
4758 	
4759 	         (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
4760 	
4761 	         SCIPinfoMessage(scip, file, "QCMATRIX %s\n", namestr);
4762 	
4763 	         /* print x^2 terms */
4764 	         for( v = 0; v < nconsvars; ++v )
4765 	         {
4766 	            SCIP_EXPR* qexpr;
4767 	            SCIP_VAR* qvar;
4768 	            SCIP_Real sqrcoef;
4769 	
4770 	            SCIPexprGetQuadraticQuadTerm(expr, v, &qexpr, NULL, &sqrcoef, NULL, NULL, NULL);
4771 	            if( sqrcoef == 0.0 )
4772 	               continue;
4773 	
4774 	            assert(SCIPisExprVar(scip, qexpr));
4775 	            qvar = SCIPgetVarExprVar(qexpr);
4776 	
4777 	            /* get variable name */
4778 	            assert(SCIPhashmapExists(varnameHashmap, qvar));
4779 	            varname = (const char*) SCIPhashmapGetImage(varnameHashmap, qvar);
4780 	
4781 	            /* get coefficient as string */
4782 	            (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sqrcoef);
4783 	
4784 	            /* print "x x coeff" line */
4785 	            printStart(scip, file, "", varname, (int) maxnamelen);
4786 	            printRecord(scip, file, varname, valuestr, maxnamelen);
4787 	            SCIPinfoMessage(scip, file, "\n");
4788 	         }
4789 	
4790 	         /* print bilinear terms; CPLEX format expects a symmetric matrix with all coefficients specified,
4791 	          * i.e., we have to split bilinear coefficients into two off diagonal elements */
4792 	         for( v = 0; v < nbilin; ++v )
4793 	         {
4794 	            SCIP_EXPR* expr1;
4795 	            SCIP_EXPR* expr2;
4796 	            SCIP_VAR* var1;
4797 	            SCIP_VAR* var2;
4798 	            SCIP_Real coef;
4799 	
4800 	            SCIPexprGetQuadraticBilinTerm(expr, v, &expr1, &expr2, &coef, NULL, NULL);
4801 	            assert(SCIPisExprVar(scip, expr1));
4802 	            assert(SCIPisExprVar(scip, expr2));
4803 	
4804 	            if( coef == 0.0 )
4805 	               continue;
4806 	
4807 	            var1 = SCIPgetVarExprVar(expr1);
4808 	            var2 = SCIPgetVarExprVar(expr2);
4809 	
4810 	            /* get name of first variable */
4811 	            assert ( SCIPhashmapExists(varnameHashmap, var1) );
4812 	            varname = (const char*) SCIPhashmapGetImage(varnameHashmap, var1);
4813 	
4814 	            /* get name of second variable */
4815 	            assert ( SCIPhashmapExists(varnameHashmap, var2) );
4816 	            varname2 = (const char*) SCIPhashmapGetImage(varnameHashmap, var2);
4817 	
4818 	            /* get coefficient as string */
4819 	            (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", 0.5*coef);
4820 	
4821 	            /* print "x y coeff/2" line */
4822 	            printStart(scip, file, "", varname, (int) maxnamelen);
4823 	            printRecord(scip, file, varname2, valuestr, maxnamelen);
4824 	            SCIPinfoMessage(scip, file, "\n");
4825 	
4826 	            /* print "y x coeff/2" line */
4827 	            printStart(scip, file, "", varname2, (int) maxnamelen);
4828 	            printRecord(scip, file, varname, valuestr, maxnamelen);
4829 	            SCIPinfoMessage(scip, file, "\n");
4830 	         }
4831 	      }
4832 	
4833 	      SCIPfreeBufferArray(scip, &namestr);
4834 	   }
4835 	
4836 	   /* print indicator section */
4837 	   if( nConsIndicator > 0 )
4838 	   {
4839 	      SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) );
4840 	
4841 	      SCIPinfoMessage(scip, file, "INDICATORS\n");
4842 	      SCIPdebugMsg(scip, "start printing INDICATOR section\n");
4843 	
4844 	      /* output each indicator constraint */
4845 	      for( c = 0; c < nConsIndicator; ++c )
4846 	      {
4847 	         SCIP_CONS* lincons;
4848 	         SCIP_VAR* slackvar;
4849 	         SCIP_VAR* binvar;
4850 	
4851 	         cons = consIndicator[c];
4852 	         binvar = SCIPgetBinaryVarIndicator(cons);
4853 	         lincons = SCIPgetLinearConsIndicator(cons);
4854 	         slackvar = SCIPgetSlackVarIndicator(cons);
4855 	
4856 	         /* linvars always contains slack variable, thus nlinvars >= 1 */
4857 	         if( SCIPgetNVarsLinear(scip, lincons) <= 1 || SCIPconsIsDeleted(lincons) )
4858 	            continue;
4859 	
4860 	         /* create variable and value strings */
4861 	         if( SCIPvarIsNegated(binvar) )
4862 	         {
4863 	            (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d", 0);
4864 	            assert( SCIPvarGetNegatedVar(binvar) != NULL );
4865 	            assert( SCIPhashmapExists(varnameHashmap, SCIPvarGetNegatedVar(binvar)) );
4866 	            varname = (const char*) SCIPhashmapGetImage(varnameHashmap, SCIPvarGetNegatedVar(binvar));
4867 	         }
4868 	         else
4869 	         {
4870 	            (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d", 1);
4871 	            assert ( SCIPhashmapExists(varnameHashmap, binvar) );
4872 	            varname = (const char*) SCIPhashmapGetImage(varnameHashmap, binvar);
4873 	         }
4874 	
4875 	         /* write records */
4876 	         if ( SCIPvarGetStatus(slackvar) == SCIP_VARSTATUS_AGGREGATED )
4877 	         {
4878 	            /* for aggregated variables output name of aggregating constraint */
4879 	            (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(slackvar));
4880 	            printStart(scip, file, "IF", namestr, (int) maxnamelen);
4881 	            printRecord(scip, file, varname, valuestr, maxnamelen);
4882 	            SCIPinfoMessage(scip, file, "\n");
4883 	         }
4884 	         else
4885 	         {
4886 	            printStart(scip, file, "IF", SCIPconsGetName(lincons), (int) maxnamelen);
4887 	            printRecord(scip, file, varname, valuestr, maxnamelen);
4888 	            SCIPinfoMessage(scip, file, "\n");
4889 	         }
4890 	      }
4891 	      SCIPfreeBufferArray(scip, &namestr);
4892 	   }
4893 	
4894 	   /* free matrix data structure */
4895 	   freeMatrix(scip, matrix);
4896 	
4897 	   /* free slackvar hashtable */
4898 	   if( indicatorSlackHash != NULL )
4899 	      SCIPhashtableFree(&indicatorSlackHash);
4900 	
4901 	   /* free variable hashmap */
4902 	   SCIPhashmapFree(&varnameHashmap);
4903 	
4904 	   SCIPfreeBlockMemoryArray(scip, &aggvars, saggvars);
4905 	   SCIPfreeBufferArray(scip, &rhss);
4906 	
4907 	   /* free buffer arrays for SOS1, SOS2, and quadratic */
4908 	   SCIPfreeBufferArray(scip, &consIndicator);
4909 	   SCIPfreeBufferArray(scip, &consQuadratic);
4910 	   SCIPfreeBufferArray(scip, &consSOS2);
4911 	   SCIPfreeBufferArray(scip, &consSOS1);
4912 	
4913 	   /* free variable and constraint name array */
4914 	   for( v = nvars + naggvars + nfixvars - 1; v >= 0; --v )
4915 	      SCIPfreeBufferArray(scip, &varnames[v]);
4916 	   SCIPfreeBufferArray(scip, &varnames);
4917 	
4918 	   for( c = nconss + naddrows + naggvars - 1; c >= 0; --c )
4919 	      SCIPfreeBufferArray(scip, &consnames[c]);
4920 	   SCIPfreeBufferArray(scip, &consnames);
4921 	
4922 	   /* print end of data line */
4923 	   SCIPinfoMessage(scip, file, "ENDATA");
4924 	
4925 	   *result = SCIP_SUCCESS;
4926 	
4927 	   return SCIP_OKAY;
4928 	}
4929