1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the class library                   */
4    	/*       SoPlex --- the Sequential object-oriented simPlex.                  */
5    	/*                                                                           */
6    	/*    Copyright (C) 1996-2022 Konrad-Zuse-Zentrum                            */
7    	/*                            fuer Informationstechnik Berlin                */
8    	/*                                                                           */
9    	/*  SoPlex is distributed under the terms of the ZIB Academic Licence.       */
10   	/*                                                                           */
11   	/*  You should have received a copy of the ZIB Academic License              */
12   	/*  along with SoPlex; see the file COPYING. If not email to soplex@zib.de.  */
13   	/*                                                                           */
14   	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15   	
16   	/**@file  soplexmain.cpp
17   	 * @brief Command line interface of SoPlex LP solver
18   	 */
19   	
20   	#include <assert.h>
21   	#include <math.h>
22   	#include <string.h>
23   	
24   	#include <iostream>
25   	#include <iomanip>
26   	#include <fstream>
27   	
28   	#include "soplex.h"
29   	#include "soplex/validation.h"
30   	
31   	using namespace soplex;
32   	
33   	// function prototype
34   	int main(int argc, char* argv[]);
35   	
36   	// prints usage and command line options
37   	static
38   	void printUsage(const char* const argv[], int idx)
39   	{
40   	   const char* usage =
41   	      "general options:\n"
42   	      "  --readbas=<basfile>    read starting basis from file\n"
43   	      "  --writebas=<basfile>   write terminal basis to file\n"
44   	      "  --writefile=<lpfile>   write LP to file in LP or MPS format depending on extension\n"
45   	      "  --writedual=<lpfile>   write the dual LP to a file in LP or MPS formal depending on extension\n"
46   	      "  --<type>:<name>=<val>  change parameter value using syntax of settings file entries\n"
47   	      "  --loadset=<setfile>    load parameters from settings file (overruled by command line parameters)\n"
48   	      "  --saveset=<setfile>    save parameters to settings file\n"
49   	      "  --diffset=<setfile>    save modified parameters to settings file\n"
50   	      "  --extsol=<value>       external solution for soplex to use for validation\n"
51   	      "\n"
52   	      "limits and tolerances:\n"
53   	      "  -t<s>                  set time limit to <s> seconds\n"
54   	      "  -i<n>                  set iteration limit to <n>\n"
55   	      "  -f<eps>                set primal feasibility tolerance to <eps>\n"
56   	      "  -o<eps>                set dual feasibility (optimality) tolerance to <eps>\n"
57   	      "  -l<eps>                set validation tolerance to <eps>\n"
58   	      "\n"
59   	      "algorithmic settings (* indicates default):\n"
60   	      "  --readmode=<value>     choose reading mode for <lpfile> (0* - floating-point, 1 - rational)\n"
61   	      "  --solvemode=<value>    choose solving mode (0 - floating-point solve, 1* - auto, 2 - force iterative refinement)\n"
62   	      "  --arithmetic=<value>   choose base arithmetic type (0 - double, 1 - quadprecision, 2 - higher multiprecision)\n"
63   	#ifdef SOPLEX_WITH_MPFR
64   	      "  --precision=<value>    choose precision for multiprecision solve (only active when arithmetic=2 minimal value = 50)\n"
65   	#endif
66   	#ifdef SOPLEX_WITH_CPPMPF
67   	      "  --precision=<value>    choose precision for multiprecision solve (only active when arithmetic=2, possible values 50,100,200, compile with mpfr for arbitrary precision)\n"
68   	#endif
69   	      "  -s<value>              choose simplifier/presolver (0 - off, 1* - internal, 2*- PaPILO)\n"
70   	      "  -g<value>              choose scaling (0 - off, 1 - uni-equilibrium, 2* - bi-equilibrium, 3 - geometric, 4 - iterated geometric, 5 - least squares, 6 - geometric-equilibrium)\n"
71   	      "  -p<value>              choose pricing (0* - auto, 1 - dantzig, 2 - parmult, 3 - devex, 4 - quicksteep, 5 - steep)\n"
72   	      "  -r<value>              choose ratio tester (0 - textbook, 1 - harris, 2 - fast, 3* - boundflipping)\n"
73   	      "\n"
74   	      "display options:\n"
75   	      "  -v<level>              set verbosity to <level> (0 - error, 3 - normal, 5 - high)\n"
76   	      "  -x                     print primal solution\n"
77   	      "  -y                     print dual multipliers\n"
78   	      "  -X                     print primal solution in rational numbers\n"
79   	      "  -Y                     print dual multipliers in rational numbers\n"
80   	      "  -q                     display detailed statistics\n"
81   	      "  -c                     perform final check of optimal solution in original problem\n"
82   	      "\n";
83   	
84   	   if(idx <= 0)
85   	      std::cerr << "missing input file\n\n";
86   	   else
87   	      std::cerr << "invalid option \"" << argv[idx] << "\"\n\n";
88   	
89   	   std::cerr << "usage: " << argv[0] << " " << "[options] <lpfile>\n"
90   	#ifdef SOPLEX_WITH_ZLIB
91   	             << "  <lpfile>               linear program as .mps[.gz] or .lp[.gz] file\n\n"
92   	#else
93   	             << "  <lpfile>               linear program as .mps or .lp file\n\n"
94   	#endif
95   	             << usage;
96   	}
97   	
98   	// cleans up C strings
99   	static
100  	void freeStrings(char*& s1, char*& s2, char*& s3, char*& s4, char*& s5)
101  	{
102  	   if(s1 != 0)
103  	   {
104  	      delete [] s1;
105  	      s1 = 0;
106  	   }
107  	
108  	   if(s2 != 0)
109  	   {
110  	      delete [] s2;
111  	      s2 = 0;
112  	   }
113  	
114  	   if(s3 != 0)
115  	   {
116  	      delete [] s3;
117  	      s3 = 0;
118  	   }
119  	
120  	   if(s4 != 0)
121  	   {
122  	      delete [] s4;
123  	      s4 = 0;
124  	   }
125  	
126  	   if(s5 != 0)
127  	   {
128  	      delete [] s5;
129  	      s5 = 0;
130  	   }
131  	}
132  	
133  	/// performs external feasibility check with real type
134  	///@todo implement external check; currently we use the internal methods for convenience
135  	
136  	template <class R>
137  	static
138  	void checkSolutionReal(SoPlexBase<R>& soplex)
139  	{
140  	   if(soplex.hasPrimal())
141  	   {
142  	      R boundviol;
143  	      R rowviol;
144  	      R sumviol;
145  	
146  	      if(soplex.getBoundViolation(boundviol, sumviol) && soplex.getRowViolation(rowviol, sumviol))
147  	      {
148  	         MSG_INFO1(soplex.spxout,
149  	                   R maxviol = boundviol > rowviol ? boundviol : rowviol;
150  	                   bool feasible = (maxviol <= soplex.realParam(SoPlexBase<R>::FEASTOL));
151  	                   soplex.spxout << "Primal solution " << (feasible ? "feasible" : "infeasible")
152  	                   << " in original problem (max. violation = " << std::scientific << maxviol
153  	                   << std::setprecision(8) << std::fixed << ").\n");
154  	      }
155  	      else
156  	      {
157  	         MSG_INFO1(soplex.spxout, soplex.spxout << "Could not check primal solution.\n");
158  	      }
159  	   }
160  	   else
161  	   {
162  	      MSG_INFO1(soplex.spxout, soplex.spxout << "No primal solution available.\n");
163  	   }
164  	
165  	   if(soplex.hasDual())
166  	   {
167  	      R redcostviol;
168  	      R dualviol;
169  	      R sumviol;
170  	
171  	      if(soplex.getRedCostViolation(redcostviol, sumviol) && soplex.getDualViolation(dualviol, sumviol))
172  	      {
173  	         MSG_INFO1(soplex.spxout,
174  	                   R maxviol = redcostviol > dualviol ? redcostviol : dualviol;
175  	                   bool feasible = (maxviol <= soplex.realParam(SoPlexBase<R>::OPTTOL));
176  	                   soplex.spxout << "Dual solution " << (feasible ? "feasible" : "infeasible")
177  	                   << " in original problem (max. violation = " << std::scientific << maxviol
178  	                   << std::setprecision(8) << std::fixed << ").\n"
179  	                  );
180  	      }
181  	      else
182  	      {
183  	         MSG_INFO1(soplex.spxout, soplex.spxout << "Could not check dual solution.\n");
184  	      }
185  	   }
186  	   else
187  	   {
188  	      MSG_INFO1(soplex.spxout, soplex.spxout << "No dual solution available.\n");
189  	   }
190  	}
191  	
192  	/// performs external feasibility check with rational type
193  	///@todo implement external check; currently we use the internal methods for convenience
194  	template <class R>
195  	static void checkSolutionRational(SoPlexBase<R>& soplex)
196  	{
197  	   if(soplex.hasPrimal())
198  	   {
199  	      Rational boundviol;
200  	      Rational rowviol;
201  	      Rational sumviol;
202  	
203  	      if(soplex.getBoundViolationRational(boundviol, sumviol)
204  	            && soplex.getRowViolationRational(rowviol, sumviol))
205  	      {
206  	         MSG_INFO1(soplex.spxout,
207  	                   Rational maxviol = boundviol > rowviol ? boundviol : rowviol;
208  	                   bool feasible = (maxviol <= soplex.realParam(SoPlexBase<R>::FEASTOL));
209  	                   soplex.spxout << "Primal solution " << (feasible ? "feasible" : "infeasible") <<
210  	                   " in original problem (max. violation = " << maxviol << ").\n"
211  	                  );
212  	      }
213  	      else
214  	      {
215  	         MSG_INFO1(soplex.spxout, soplex.spxout << "Could not check primal solution.\n");
216  	      }
217  	   }
218  	   else
219  	   {
220  	      MSG_INFO1(soplex.spxout, soplex.spxout << "No primal solution available.\n");
221  	   }
222  	
223  	   if(soplex.hasDual())
224  	   {
225  	      Rational redcostviol;
226  	      Rational dualviol;
227  	      Rational sumviol;
228  	
229  	      if(soplex.getRedCostViolationRational(redcostviol, sumviol)
230  	            && soplex.getDualViolationRational(dualviol, sumviol))
231  	      {
232  	         MSG_INFO1(soplex.spxout,
233  	                   Rational maxviol = redcostviol > dualviol ? redcostviol : dualviol;
234  	                   bool feasible = (maxviol <= soplex.realParam(SoPlexBase<R>::OPTTOL));
235  	                   soplex.spxout << "Dual solution " << (feasible ? "feasible" : "infeasible") <<
236  	                   " in original problem (max. violation = " << maxviol << ").\n"
237  	                  );
238  	      }
239  	      else
240  	      {
241  	         MSG_INFO1(soplex.spxout, soplex.spxout << "Could not check dual solution.\n");
242  	      }
243  	   }
244  	   else
245  	   {
246  	      MSG_INFO1(soplex.spxout, soplex.spxout << "No dual solution available.\n");
247  	   }
248  	}
249  	
250  	/// performs external feasibility check according to check mode
251  	template <class R>
252  	void checkSolution(SoPlexBase<R>& soplex)
253  	{
254  	   if(soplex.intParam(SoPlexBase<R>::CHECKMODE) == SoPlexBase<R>::CHECKMODE_RATIONAL
255  	         || (soplex.intParam(SoPlexBase<R>::CHECKMODE) == SoPlexBase<R>::CHECKMODE_AUTO
256  	             && soplex.intParam(SoPlexBase<R>::READMODE) == SoPlexBase<R>::READMODE_RATIONAL))
257  	   {
258  	      checkSolutionRational(soplex);
259  	   }
260  	   else
261  	   {
262  	      checkSolutionReal(soplex);
263  	   }
264  	
265  	   MSG_INFO1(soplex.spxout, soplex.spxout << "\n");
266  	}
267  	
268  	template <class R>
269  	static
270  	void printPrimalSolution(SoPlexBase<R>& soplex, NameSet& colnames, NameSet& rownames,
271  	                         bool real = true, bool rational = false)
272  	{
273  	   int printprec;
274  	   int printwidth;
275  	   printprec = (int) - log10(Real(Param::epsilon()));
276  	   printwidth = printprec + 10;
277  	
278  	   if(real)
279  	   {
280  	      VectorBase<R> primal(soplex.numCols());
281  	
282  	      if(soplex.getPrimalRay(primal))
283  	      {
284  	         MSG_INFO1(soplex.spxout, soplex.spxout << "\nPrimal ray (name, value):\n";)
285  	
286  	         for(int i = 0; i < soplex.numCols(); ++i)
287  	         {
288  	            if(isNotZero(primal[i]))
289  	            {
290  	               MSG_INFO1(soplex.spxout, soplex.spxout << colnames[i] << "\t"
291  	                         << std::setw(printwidth) << std::setprecision(printprec)
292  	                         << primal[i] << std::endl;)
293  	            }
294  	         }
295  	
296  	         MSG_INFO1(soplex.spxout, soplex.spxout << "All other entries are zero (within "
297  	                   << std::setprecision(1) << std::scientific << Param::epsilon()
298  	                   << std::setprecision(8) << std::fixed
299  	                   << ")." << std::endl;)
300  	      }
301  	      else if(soplex.isPrimalFeasible() && soplex.getPrimal(primal))
302  	      {
303  	         int nNonzeros = 0;
304  	         MSG_INFO1(soplex.spxout, soplex.spxout << "\nPrimal solution (name, value):\n";)
305  	
306  	         for(int i = 0; i < soplex.numCols(); ++i)
307  	         {
308  	            if(isNotZero(primal[i]))
309  	            {
310  	               MSG_INFO1(soplex.spxout, soplex.spxout << colnames[i] << "\t"
311  	                         << std::setw(printwidth) << std::setprecision(printprec)
312  	                         << primal[i] << std::endl;)
313  	               ++nNonzeros;
314  	            }
315  	         }
316  	
317  	         MSG_INFO1(soplex.spxout, soplex.spxout << "All other variables are zero (within "
318  	                   << std::setprecision(1) << std::scientific << Param::epsilon()
319  	                   << std::setprecision(8) << std::fixed
320  	                   << "). Solution has " << nNonzeros << " nonzero entries." << std::endl;)
321  	      }
322  	      else
323  	         MSG_INFO1(soplex.spxout, soplex.spxout << "No primal information available.\n")
324  	      }
325  	
326  	   if(rational)
327  	   {
328  	      VectorRational primal(soplex.numCols());
329  	
330  	      if(soplex.getPrimalRayRational(primal))
331  	      {
332  	         MSG_INFO1(soplex.spxout, soplex.spxout << "\nPrimal ray (name, value):\n";)
333  	
334  	         for(int i = 0; i < soplex.numCols(); ++i)
335  	         {
336  	            if(primal[i] != (Rational) 0)
337  	            {
338  	               MSG_INFO1(soplex.spxout, soplex.spxout << colnames[i] << "\t"
339  	                         << std::setw(printwidth) << std::setprecision(printprec)
340  	                         << primal[i] << std::endl;)
341  	            }
342  	         }
343  	
344  	         MSG_INFO1(soplex.spxout, soplex.spxout << "All other entries are zero." << std::endl;)
345  	      }
346  	
347  	      if(soplex.isPrimalFeasible() && soplex.getPrimalRational(primal))
348  	      {
349  	         int nNonzeros = 0;
350  	         MSG_INFO1(soplex.spxout, soplex.spxout << "\nPrimal solution (name, value):\n";)
351  	
352  	         for(int i = 0; i < soplex.numColsRational(); ++i)
353  	         {
354  	            if(primal[i] != (Rational) 0)
355  	            {
356  	               MSG_INFO1(soplex.spxout, soplex.spxout << colnames[i] << "\t" << primal[i] << std::endl;)
357  	               ++nNonzeros;
358  	            }
359  	         }
360  	
361  	         MSG_INFO1(soplex.spxout, soplex.spxout << "All other variables are zero. Solution has "
362  	                   << nNonzeros << " nonzero entries." << std::endl;)
363  	      }
364  	      else
365  	         MSG_INFO1(soplex.spxout, soplex.spxout << "No primal (rational) solution available.\n")
366  	
367  	      }
368  	}
369  	
370  	template <class R>
371  	static
372  	void printDualSolution(SoPlexBase<R>& soplex, NameSet& colnames, NameSet& rownames,
373  	                       bool real = true, bool rational = false)
374  	{
375  	   int printprec;
376  	   int printwidth;
377  	   printprec = (int) - log10(Real(Param::epsilon()));
378  	   printwidth = printprec + 10;
379  	
380  	   if(real)
381  	   {
382  	      VectorBase<R> dual(soplex.numRows());
383  	
384  	      if(soplex.getDualFarkas(dual))
385  	      {
386  	         MSG_INFO1(soplex.spxout, soplex.spxout << "\nDual ray (name, value):\n";)
387  	
388  	         for(int i = 0; i < soplex.numRows(); ++i)
389  	         {
390  	            if(isNotZero(dual[i]))
391  	            {
392  	               MSG_INFO1(soplex.spxout, soplex.spxout << rownames[i] << "\t"
393  	                         << std::setw(printwidth) << std::setprecision(printprec)
394  	                         << dual[i] << std::endl;)
395  	            }
396  	         }
397  	
398  	         MSG_INFO1(soplex.spxout, soplex.spxout << "All other entries are zero (within "
399  	                   << std::setprecision(1) << std::scientific << Param::epsilon()
400  	                   << std::setprecision(8) << std::fixed << ")." << std::endl;)
401  	      }
402  	      else if(soplex.isDualFeasible() && soplex.getDual(dual))
403  	      {
404  	         MSG_INFO1(soplex.spxout, soplex.spxout << "\nDual solution (name, value):\n";)
405  	
406  	         for(int i = 0; i < soplex.numRows(); ++i)
407  	         {
408  	            if(isNotZero(dual[i]))
409  	            {
410  	               MSG_INFO1(soplex.spxout, soplex.spxout << rownames[i] << "\t"
411  	                         << std::setw(printwidth) << std::setprecision(printprec)
412  	                         << dual[i] << std::endl;)
413  	            }
414  	         }
415  	
416  	         MSG_INFO1(soplex.spxout, soplex.spxout << "All other dual values are zero (within "
417  	                   << std::setprecision(1) << std::scientific << Param::epsilon()
418  	                   << std::setprecision(8) << std::fixed << ")." << std::endl;)
419  	
420  	         VectorBase<R> redcost(soplex.numCols());
421  	
422  	         if(soplex.getRedCost(redcost))
423  	         {
424  	            MSG_INFO1(soplex.spxout, soplex.spxout << "\nReduced costs (name, value):\n";)
425  	
426  	            for(int i = 0; i < soplex.numCols(); ++i)
427  	            {
428  	               if(isNotZero(redcost[i]))
429  	               {
430  	                  MSG_INFO1(soplex.spxout, soplex.spxout << colnames[i] << "\t"
431  	                            << std::setw(printwidth) << std::setprecision(printprec)
432  	                            << redcost[i] << std::endl;)
433  	               }
434  	            }
435  	
436  	            MSG_INFO1(soplex.spxout, soplex.spxout << "All other reduced costs are zero (within "
437  	                      << std::setprecision(1) << std::scientific << Param::epsilon()
438  	                      << std::setprecision(8) << std::fixed << ")." << std::endl;)
439  	         }
440  	      }
441  	      else
442  	         MSG_INFO1(soplex.spxout, soplex.spxout << "No dual information available.\n")
443  	      }
444  	
445  	   if(rational)
446  	   {
447  	      VectorRational dual(soplex.numRows());
448  	
449  	      if(soplex.getDualFarkasRational(dual))
450  	      {
451  	         MSG_INFO1(soplex.spxout, soplex.spxout << "\nDual ray (name, value):\n";)
452  	
453  	         for(int i = 0; i < soplex.numRows(); ++i)
454  	         {
455  	            if(dual[i] != (Rational) 0)
456  	            {
457  	               MSG_INFO1(soplex.spxout, soplex.spxout << rownames[i] << "\t"
458  	                         << std::setw(printwidth)
459  	                         << std::setprecision(printprec)
460  	                         << dual[i] << std::endl;)
461  	            }
462  	         }
463  	
464  	         MSG_INFO1(soplex.spxout, soplex.spxout << "All other entries are zero." << std::endl;)
465  	      }
466  	
467  	      if(soplex.isDualFeasible() && soplex.getDualRational(dual))
468  	      {
469  	         MSG_INFO1(soplex.spxout, soplex.spxout << "\nDual solution (name, value):\n";)
470  	
471  	         for(int i = 0; i < soplex.numRowsRational(); ++i)
472  	         {
473  	            if(dual[i] != (Rational) 0)
474  	               MSG_INFO1(soplex.spxout, soplex.spxout << rownames[i] << "\t" << dual[i] << std::endl;)
475  	            }
476  	
477  	         MSG_INFO1(soplex.spxout, soplex.spxout << "All other dual values are zero." << std::endl;)
478  	
479  	         VectorRational redcost(soplex.numCols());
480  	
481  	         if(soplex.getRedCostRational(redcost))
482  	         {
483  	            MSG_INFO1(soplex.spxout, soplex.spxout << "\nReduced costs (name, value):\n";)
484  	
485  	            for(int i = 0; i < soplex.numCols(); ++i)
486  	            {
487  	               if(redcost[i] != (Rational) 0)
488  	                  MSG_INFO1(soplex.spxout, soplex.spxout << colnames[i] << "\t" << redcost[i] << std::endl;)
489  	               }
490  	
491  	            MSG_INFO1(soplex.spxout, soplex.spxout << "All other reduced costs are zero." << std::endl;)
492  	         }
493  	      }
494  	      else
495  	         MSG_INFO1(soplex.spxout, soplex.spxout << "No dual (rational) solution available.\n")
496  	      }
497  	}
498  	
499  	// Runs SoPlex with the parsed boost variables map
500  	template <class R>
501  	int runSoPlex(int argc, char* argv[])
502  	{
503  	   SoPlexBase<R>* soplex = nullptr;
504  	
505  	   Timer* readingTime = nullptr;
506  	   Validation<R>* validation = nullptr;
507  	   int optidx;
508  	
509  	   const char* lpfilename = nullptr;
510  	   char* readbasname = nullptr;
511  	   char* writebasname = nullptr;
512  	   char* writefilename = nullptr;
513  	   char* writedualfilename = nullptr;
514  	   char* loadsetname = nullptr;
515  	   char* savesetname = nullptr;
516  	   char* diffsetname = nullptr;
517  	   bool printPrimal = false;
518  	   bool printPrimalRational = false;
519  	   bool printDual = false;
520  	   bool printDualRational = false;
521  	   bool displayStatistics = false;
522  	   bool checkSol = false;
523  	
524  	   int returnValue = 0;
525  	
526  	   try
527  	   {
528  	      NameSet rownames;
529  	      NameSet colnames;
530  	
531  	      // create default timer (CPU time)
532  	      readingTime = TimerFactory::createTimer(Timer::USER_TIME);
533  	      soplex = nullptr;
534  	      spx_alloc(soplex);
535  	      new(soplex) SoPlexBase<R>();
536  	
537  	      soplex->printVersion();
538  	      MSG_INFO1(soplex->spxout, soplex->spxout << SOPLEX_COPYRIGHT << std::endl << std::endl);
539  	
540  	      validation = nullptr;
541  	      spx_alloc(validation);
542  	      new(validation) Validation<R>();
543  	
544  	      // no options were given
545  	      if(argc <= 1)
546  	      {
547  	         printUsage(argv, 0);
548  	         returnValue = 1;
549  	         goto TERMINATE;
550  	      }
551  	
552  	      // read arguments from command line
553  	      for(optidx = 1; optidx < argc; optidx++)
554  	      {
555  	         char* option = argv[optidx];
556  	
557  	         // we reached <lpfile>
558  	         if(option[0] != '-')
559  	         {
560  	            lpfilename = argv[optidx];
561  	            continue;
562  	         }
563  	
564  	         // option string must start with '-', must contain at least two characters, and exactly two characters if and
565  	         // only if it is -x, -y, -q, or -c
566  	         if(option[0] != '-' || option[1] == '\0'
567  	               || ((option[2] == '\0') != (option[1] == 'x' || option[1] == 'X' || option[1] == 'y'
568  	                                           || option[1] == 'Y' || option[1] == 'q' || option[1] == 'c')))
569  	         {
570  	            printUsage(argv, optidx);
571  	            returnValue = 1;
572  	            goto TERMINATE_FREESTRINGS;
573  	         }
574  	
575  	         switch(option[1])
576  	         {
577  	         case '-' :
578  	         {
579  	            option = &option[2];
580  	
581  	            // --readbas=<basfile> : read starting basis from file
582  	            if(strncmp(option, "readbas=", 8) == 0)
583  	            {
584  	               if(readbasname == nullptr)
585  	               {
586  	                  char* filename = &option[8];
587  	                  readbasname = new char[strlen(filename) + 1];
588  	                  spxSnprintf(readbasname, strlen(filename) + 1, "%s", filename);
589  	               }
590  	            }
591  	            // --writebas=<basfile> : write terminal basis to file
592  	            else if(strncmp(option, "writebas=", 9) == 0)
593  	            {
594  	               if(writebasname == nullptr)
595  	               {
596  	                  char* filename = &option[9];
597  	                  writebasname =  new char[strlen(filename) + 1];
598  	                  spxSnprintf(writebasname, strlen(filename) + 1, "%s", filename);
599  	               }
600  	            }
601  	            // --writefile=<lpfile> : write LP to file
602  	            else if(strncmp(option, "writefile=", 10) == 0)
603  	            {
604  	               if(writefilename == nullptr)
605  	               {
606  	                  char* filename = &option[10];
607  	                  writefilename = new char[strlen(filename) + 1];
608  	                  spxSnprintf(writefilename, strlen(filename) + 1, "%s", filename);
609  	               }
610  	            }
611  	            // --writedual=<lpfile> : write dual LP to a file
612  	            else if(strncmp(option, "writedual=", 10) == 0)
613  	            {
614  	               if(writedualfilename == nullptr)
615  	               {
616  	                  char* dualfilename = &option[10];
617  	                  writedualfilename = new char[strlen(dualfilename) + 1];
618  	                  spxSnprintf(writedualfilename, strlen(dualfilename) + 1, "%s", dualfilename);
619  	               }
620  	            }
621  	            // --loadset=<setfile> : load parameters from settings file
622  	            else if(strncmp(option, "loadset=", 8) == 0)
623  	            {
624  	               if(loadsetname == nullptr)
625  	               {
626  	                  char* filename = &option[8];
627  	                  loadsetname = new char[strlen(filename) + 1];
628  	                  spxSnprintf(loadsetname, strlen(filename) + 1, "%s", filename);
629  	
630  	                  if(!soplex->loadSettingsFile(loadsetname))
631  	                  {
632  	                     printUsage(argv, optidx);
633  	                     returnValue = 1;
634  	                     goto TERMINATE_FREESTRINGS;
635  	                  }
636  	                  else
637  	                  {
638  	                     // we need to start parsing again because some command line parameters might have been overwritten
639  	                     optidx = 0;
640  	                  }
641  	               }
642  	            }
643  	            // --saveset=<setfile> : save parameters to settings file
644  	            else if(strncmp(option, "saveset=", 8) == 0)
645  	            {
646  	               if(savesetname == nullptr)
647  	               {
648  	                  char* filename = &option[8];
649  	                  savesetname = new char[strlen(filename) + 1];
650  	                  spxSnprintf(savesetname, strlen(filename) + 1, "%s", filename);
651  	               }
652  	            }
653  	            // --diffset=<setfile> : save modified parameters to settings file
654  	            else if(strncmp(option, "diffset=", 8) == 0)
655  	            {
656  	               if(diffsetname == nullptr)
657  	               {
658  	                  char* filename = &option[8];
659  	                  diffsetname = new char[strlen(filename) + 1];
660  	                  spxSnprintf(diffsetname, strlen(filename) + 1, "%s", filename);
661  	               }
662  	            }
663  	            // --readmode=<value> : choose reading mode for <lpfile> (0* - floating-point, 1 - rational)
664  	            else if(strncmp(option, "readmode=", 9) == 0)
665  	            {
666  	               if(!soplex->setIntParam(soplex->READMODE, option[9] - '0'))
667  	               {
668  	                  printUsage(argv, optidx);
669  	                  returnValue = 1;
670  	                  goto TERMINATE_FREESTRINGS;
671  	               }
672  	            }
673  	            // --solvemode=<value> : choose solving mode (0* - floating-point solve, 1 - auto, 2 - force iterative refinement)
674  	            else if(strncmp(option, "solvemode=", 10) == 0)
675  	            {
676  	               if(!soplex->setIntParam(soplex->SOLVEMODE, option[10] - '0'))
677  	               {
678  	                  printUsage(argv, optidx);
679  	                  returnValue = 1;
680  	                  goto TERMINATE_FREESTRINGS;
681  	               }
682  	               // if the LP is parsed rationally and might be solved rationally, we choose automatic syncmode such that
683  	               // the rational LP is kept after reading
684  	               else if(soplex->intParam(soplex->READMODE) == soplex->READMODE_RATIONAL
685  	                       && soplex->intParam(soplex->SOLVEMODE) != soplex->SOLVEMODE_REAL)
686  	               {
687  	                  soplex->setIntParam(soplex->SYNCMODE, soplex->SYNCMODE_AUTO);
688  	               }
689  	            }
690  	            // --extsol=<value> : external solution for soplex to use for validation
691  	            else if(strncmp(option, "extsol=", 7) == 0)
692  	            {
693  	               char* input = &option[7];
694  	
695  	               if(!validation->updateExternalSolution(input))
696  	               {
697  	                  printUsage(argv, optidx);
698  	                  returnValue = 1;
699  	                  goto TERMINATE_FREESTRINGS;
700  	               }
701  	            }
702  	            // --arithmetic=<value> : base arithmetic type, directly handled in main()
703  	            else if(strncmp(option, "arithmetic=", 11) == 0)
704  	            {
705  	               continue;
706  	            }
707  	            // --precision=<value> : arithmetic precision, directly handled in main()
708  	            else if(strncmp(option, "precision=", 10) == 0)
709  	            {
710  	               continue;
711  	            }
712  	            // --<type>:<name>=<val> :  change parameter value using syntax of settings file entries
713  	            else if(!soplex->parseSettingsString(option))
714  	            {
715  	               printUsage(argv, optidx);
716  	               returnValue = 1;
717  	               goto TERMINATE_FREESTRINGS;
718  	            }
719  	
720  	            break;
721  	         }
722  	
723  	         case 't' :
724  	
725  	            // -t<s> : set time limit to <s> seconds
726  	            if(!soplex->setRealParam(soplex->TIMELIMIT, atoi(&option[2])))
727  	            {
728  	               printUsage(argv, optidx);
729  	               returnValue = 1;
730  	               goto TERMINATE_FREESTRINGS;
731  	            }
732  	
733  	            break;
734  	
735  	         case 'i' :
736  	
737  	            // -i<n> : set iteration limit to <n>
738  	            if(!soplex->setIntParam(soplex->ITERLIMIT, atoi(&option[2])))
739  	            {
740  	               printUsage(argv, optidx);
741  	               returnValue = 1;
742  	               goto TERMINATE_FREESTRINGS;
743  	            }
744  	
745  	            break;
746  	
747  	         case 'f' :
748  	
749  	            // -f<eps> : set primal feasibility tolerance to <eps>
750  	            if(!soplex->setRealParam(soplex->FEASTOL, atof(&option[2])))
751  	            {
752  	               printUsage(argv, optidx);
753  	               returnValue = 1;
754  	               goto TERMINATE_FREESTRINGS;
755  	            }
756  	
757  	            break;
758  	
759  	         case 'o' :
760  	
761  	            // -o<eps> : set dual feasibility (optimality) tolerance to <eps>
762  	            if(!soplex->setRealParam(soplex->OPTTOL, atof(&option[2])))
763  	            {
764  	               printUsage(argv, optidx);
765  	               returnValue = 1;
766  	               goto TERMINATE_FREESTRINGS;
767  	            }
768  	
769  	            break;
770  	
771  	         case 'l' :
772  	
773  	            // l<eps> : set validation tolerance to <eps>
774  	            if(!validation->updateValidationTolerance(&option[2]))
775  	            {
776  	               printUsage(argv, optidx);
777  	               returnValue = 1;
778  	               goto TERMINATE_FREESTRINGS;
779  	            }
780  	
781  	            break;
782  	
783  	         case 's' :
784  	
785  	            // -s<value> : choose simplifier/presolver (0 - off, 1 - internal, 2* - PaPILO)
786  	            if(!soplex->setIntParam(soplex->SIMPLIFIER, option[2] - '0'))
787  	            {
788  	               printUsage(argv, optidx);
789  	               returnValue = 1;
790  	               goto TERMINATE_FREESTRINGS;
791  	            }
792  	
793  	            break;
794  	
795  	         case 'g' :
796  	
797  	            // -g<value> : choose scaling (0 - off, 1 - uni-equilibrium, 2* - bi-equilibrium, 3 - geometric, 4 - iterated geometric,  5 - least squares, 6 - geometric-equilibrium)
798  	            if(!soplex->setIntParam(soplex->SCALER, option[2] - '0'))
799  	            {
800  	               printUsage(argv, optidx);
801  	               returnValue = 1;
802  	               goto TERMINATE_FREESTRINGS;
803  	            }
804  	
805  	            break;
806  	
807  	         case 'p' :
808  	
809  	            // -p<value> : choose pricing (0* - auto, 1 - dantzig, 2 - parmult, 3 - devex, 4 - quicksteep, 5 - steep)
810  	            if(!soplex->setIntParam(soplex->PRICER, option[2] - '0'))
811  	            {
812  	               printUsage(argv, optidx);
813  	               returnValue = 1;
814  	               goto TERMINATE_FREESTRINGS;
815  	            }
816  	
817  	            break;
818  	
819  	         case 'r' :
820  	
821  	            // -r<value> : choose ratio tester (0 - textbook, 1 - harris, 2* - fast, 3 - boundflipping)
822  	            if(!soplex->setIntParam(soplex->RATIOTESTER, option[2] - '0'))
823  	            {
824  	               printUsage(argv, optidx);
825  	               returnValue = 1;
826  	               goto TERMINATE_FREESTRINGS;
827  	            }
828  	
829  	            break;
830  	
831  	         case 'v' :
832  	
833  	            // -v<level> : set verbosity to <level> (0 - error, 3 - normal, 5 - high)
834  	            if(!soplex->setIntParam(soplex->VERBOSITY, option[2] - '0'))
835  	            {
836  	               printUsage(argv, optidx);
837  	               returnValue = 1;
838  	               goto TERMINATE_FREESTRINGS;
839  	            }
840  	
841  	            break;
842  	
843  	         case 'x' :
844  	            // -x : print primal solution
845  	            printPrimal = true;
846  	            break;
847  	
848  	         case 'X' :
849  	            // -X : print primal solution with rationals
850  	            printPrimalRational = true;
851  	            break;
852  	
853  	         case 'y' :
854  	            // -y : print dual multipliers
855  	            printDual = true;
856  	            break;
857  	
858  	         case 'Y' :
859  	            // -Y : print dual multipliers with rationals
860  	            printDualRational = true;
861  	            break;
862  	
863  	         case 'q' :
864  	            // -q : display detailed statistics
865  	            displayStatistics = true;
866  	            break;
867  	
868  	         case 'c' :
869  	            // -c : perform final check of optimal solution in original problem
870  	            checkSol = true;
871  	            break;
872  	
873  	         case 'h' :
874  	
875  	            // -h : display all parameters
876  	            if(!soplex->saveSettingsFile(0, false))
877  	            {
878  	               MSG_ERROR(std::cerr << "Error printing parameters\n");
879  	            }
880  	
881  	            break;
882  	
883  	         //lint -fallthrough
884  	         default :
885  	         {
886  	            printUsage(argv, optidx);
887  	            returnValue = 1;
888  	            goto TERMINATE_FREESTRINGS;
889  	         }
890  	         }
891  	      }
892  	
893  	      MSG_INFO1(soplex->spxout, soplex->printUserSettings();)
894  	
895  	      // no LP file was given and no settings files are written
896  	      if(lpfilename == nullptr && savesetname == nullptr && diffsetname == nullptr)
897  	      {
898  	         printUsage(argv, 0);
899  	         returnValue = 1;
900  	         goto TERMINATE_FREESTRINGS;
901  	      }
902  	
903  	      // ensure that syncmode is not manual
904  	      if(soplex->intParam(soplex->SYNCMODE) == soplex->SYNCMODE_MANUAL)
905  	      {
906  	         MSG_ERROR(std::cerr <<
907  	                   "Error: manual synchronization is invalid on command line.  Change parameter int:syncmode.\n");
908  	         returnValue = 1;
909  	         goto TERMINATE_FREESTRINGS;
910  	      }
911  	
912  	      // save settings files
913  	      if(savesetname != nullptr)
914  	      {
915  	         MSG_INFO1(soplex->spxout, soplex->spxout << "Saving parameters to settings file <" << savesetname <<
916  	                   "> . . .\n");
917  	
918  	         if(!soplex->saveSettingsFile(savesetname, false))
919  	         {
920  	            MSG_ERROR(std::cerr << "Error writing parameters to file <" << savesetname << ">\n");
921  	         }
922  	      }
923  	
924  	      if(diffsetname != nullptr)
925  	      {
926  	         MSG_INFO1(soplex->spxout, soplex->spxout << "Saving modified parameters to settings file <" <<
927  	                   diffsetname << "> . . .\n");
928  	
929  	         if(!soplex->saveSettingsFile(diffsetname, true))
930  	         {
931  	            MSG_ERROR(std::cerr << "Error writing modified parameters to file <" << diffsetname << ">\n");
932  	         }
933  	      }
934  	
935  	      // no LP file given: exit after saving settings
936  	      if(lpfilename == nullptr)
937  	      {
938  	         if(loadsetname != nullptr || savesetname != nullptr || diffsetname != nullptr)
939  	         {
940  	            MSG_INFO1(soplex->spxout, soplex->spxout << "\n");
941  	         }
942  	
943  	         goto TERMINATE_FREESTRINGS;
944  	      }
945  	
946  	      // measure time for reading LP file and basis file
947  	      readingTime->start();
948  	
949  	      // if the LP is parsed rationally and might be solved rationally, we choose automatic syncmode such that
950  	      // the rational LP is kept after reading
951  	      if(soplex->intParam(soplex->READMODE) == soplex->READMODE_RATIONAL
952  	            && soplex->intParam(soplex->SOLVEMODE) != soplex->SOLVEMODE_REAL)
953  	      {
954  	         soplex->setIntParam(soplex->SYNCMODE, soplex->SYNCMODE_AUTO);
955  	      }
956  	
957  	      // read LP from input file
958  	      MSG_INFO1(soplex->spxout, soplex->spxout << "Reading "
959  	                << (soplex->intParam(soplex->READMODE) == soplex->READMODE_REAL ? "(real)" : "(rational)")
960  	                << " LP file <" << lpfilename << "> . . .\n");
961  	
962  	      if(!soplex->readFile(lpfilename, &rownames, &colnames))
963  	      {
964  	         MSG_ERROR(std::cerr << "Error while reading file <" << lpfilename << ">.\n");
965  	         returnValue = 1;
966  	         goto TERMINATE_FREESTRINGS;
967  	      }
968  	
969  	      // write LP if specified
970  	      if(writefilename != nullptr)
971  	      {
972  	         if(!soplex->writeFile(writefilename, &rownames, &colnames))
973  	         {
974  	            MSG_ERROR(std::cerr << "Error while writing file <" << writefilename << ">.\n\n");
975  	            returnValue = 1;
976  	            goto TERMINATE_FREESTRINGS;
977  	         }
978  	         else
979  	         {
980  	            MSG_INFO1(soplex->spxout, soplex->spxout << "Written LP to file <" << writefilename << ">.\n\n");
981  	         }
982  	      }
983  	
984  	      // write dual LP if specified
985  	      if(writedualfilename != nullptr)
986  	      {
987  	         if(!soplex->writeDualFileReal(writedualfilename, &rownames, &colnames))
988  	         {
989  	            MSG_ERROR(std::cerr << "Error while writing dual file <" << writedualfilename << ">.\n\n");
990  	            returnValue = 1;
991  	            goto TERMINATE_FREESTRINGS;
992  	         }
993  	         else
994  	         {
995  	            MSG_INFO1(soplex->spxout, soplex->spxout << "Written dual LP to file <" << writedualfilename <<
996  	                      ">.\n\n");
997  	         }
998  	      }
999  	
1000 	      // read basis file if specified
1001 	      if(readbasname != nullptr)
1002 	      {
1003 	         MSG_INFO1(soplex->spxout, soplex->spxout << "Reading basis file <" << readbasname << "> . . . ");
1004 	
1005 	         if(!soplex->readBasisFile(readbasname, &rownames, &colnames))
1006 	         {
1007 	            MSG_ERROR(std::cerr << "Error while reading file <" << readbasname << ">.\n");
1008 	            returnValue = 1;
1009 	            goto TERMINATE_FREESTRINGS;
1010 	         }
1011 	      }
1012 	
1013 	      readingTime->stop();
1014 	
1015 	      MSG_INFO1(soplex->spxout,
1016 	                std::streamsize prec = soplex->spxout.precision();
1017 	                soplex->spxout << "Reading took "
1018 	                << std::fixed << std::setprecision(2) << readingTime->time()
1019 	                << std::scientific << std::setprecision(int(prec))
1020 	                << " seconds.\n\n");
1021 	
1022 	      MSG_INFO1(soplex->spxout, soplex->spxout << "LP has " << soplex->numRows() << " rows "
1023 	                << soplex->numCols() << " columns and " << soplex->numNonzeros() << " nonzeros.\n\n");
1024 	
1025 	      // solve the LP
1026 	      soplex->optimize();
1027 	
1028 	      // print solution, check solution, and display statistics
1029 	      printPrimalSolution(*soplex, colnames, rownames, printPrimal, printPrimalRational);
1030 	      printDualSolution(*soplex, colnames, rownames, printDual, printDualRational);
1031 	
1032 	      if(checkSol)
1033 	         checkSolution<R>(*soplex); // The type needs to get fixed here
1034 	
1035 	      if(displayStatistics)
1036 	      {
1037 	         MSG_INFO1(soplex->spxout, soplex->spxout << "Statistics\n==========\n\n");
1038 	         soplex->printStatistics(soplex->spxout.getStream(SPxOut::INFO1));
1039 	      }
1040 	
1041 	      if(validation->validate)
1042 	         validation->validateSolveReal(*soplex);
1043 	
1044 	      // write basis file if specified
1045 	      if(writebasname != nullptr)
1046 	      {
1047 	         if(!soplex->hasBasis())
1048 	         {
1049 	            MSG_WARNING(soplex->spxout, soplex->spxout <<
1050 	                        "No basis information available.  Could not write file <" << writebasname << ">\n\n");
1051 	         }
1052 	         else if(!soplex->writeBasisFile(writebasname, &rownames, &colnames))
1053 	         {
1054 	            MSG_ERROR(std::cerr << "Error while writing file <" << writebasname << ">.\n\n");
1055 	            returnValue = 1;
1056 	            goto TERMINATE_FREESTRINGS;
1057 	         }
1058 	         else
1059 	         {
1060 	            MSG_INFO1(soplex->spxout, soplex->spxout << "Written basis information to file <" << writebasname <<
1061 	                      ">.\n\n");
1062 	         }
1063 	      }
1064 	   }
1065 	   catch(const SPxException& x)
1066 	   {
1067 	      MSG_ERROR(std::cerr << "Exception caught: " << x.what() << "\n");
1068 	      returnValue = 1;
1069 	      goto TERMINATE_FREESTRINGS;
1070 	   }
1071 	
1072 	TERMINATE_FREESTRINGS:
1073 	   freeStrings(readbasname, writebasname, loadsetname, savesetname, diffsetname);
1074 	
1075 	TERMINATE:
1076 	
1077 	   // because EGlpNumClear() calls mpq_clear() for all mpq_t variables, we need to destroy all objects of class Rational
1078 	   // beforehand; hence all Rational objects and all data that uses Rational objects must be allocated dynamically via
1079 	   // spx_alloc() and freed here; disabling the list memory is crucial
1080 	   if(nullptr != soplex)
1081 	   {
1082 	      soplex->~SoPlexBase();
1083 	      spx_free(soplex);
1084 	   }
1085 	
1086 	   if(nullptr != validation)
1087 	   {
1088 	      validation->~Validation();
1089 	      spx_free(validation);
1090 	   }
1091 	
1092 	   if(nullptr != readingTime)
1093 	   {
1094 	      readingTime->~Timer();
1095 	      spx_free(readingTime);
1096 	   }
1097 	
1098 	   return returnValue;
1099 	}
1100 	
1101 	/// runs SoPlexBase command line
1102 	int main(int argc, char* argv[])
1103 	{
(1) Event assignment: Assigning: "arithmetic" = "0".
Also see events: [const][dead_error_condition][dead_error_begin]
1104 	   int arithmetic = 0;
1105 	   int precision = 0;
1106 	   int optidx;
1107 	
1108 	   // find out which precision/solvemode soplex should be run in. the rest happens in runSoPlex
1109 	   // no options were given
1110 	   if(argc <= 1)
1111 	   {
1112 	      printUsage(argv, 0);
1113 	      return 1;
1114 	   }
1115 	
1116 	   // read arguments from command line
1117 	   for(optidx = 1; optidx < argc; optidx++)
1118 	   {
1119 	      char* option = argv[optidx];
1120 	
1121 	      // we reached <lpfile>
1122 	      if(option[0] != '-')
1123 	         continue;
1124 	
1125 	      // option string must start with '-', must contain at least two characters, and exactly two characters if and
1126 	      // only if it is -x, -y, -q, or -c
1127 	      if(option[0] != '-' || option[1] == '\0'
1128 	            || ((option[2] == '\0') != (option[1] == 'x' || option[1] == 'X' || option[1] == 'y'
1129 	                                        || option[1] == 'Y' || option[1] == 'q' || option[1] == 'c')))
1130 	      {
1131 	         printUsage(argv, optidx);
1132 	         return 1;
1133 	      }
1134 	
1135 	      switch(option[1])
1136 	      {
1137 	      case '-' :
1138 	         option = &option[2];
1139 	
1140 	         // --arithmetic=<value> : choose base arithmetic type (0 - double, 1 - quadprecision, 2 - higher multiprecision)
1141 	         // only need to do something here if multi or quad, the rest is handled in runSoPlex
1142 	         if(strncmp(option, "arithmetic=", 11) == 0)
1143 	         {
1144 	            if(option[11] == '1')
1145 	            {
1146 	#ifndef SOPLEX_WITH_FLOAT128
1147 	               MSG_ERROR(std::cerr <<
1148 	                         "Cannot set arithmetic type to quadprecision - Soplex compiled without quadprecision support\n";)
1149 	               printUsage(argv, 0);
1150 	               return 1;
1151 	#else
1152 	               arithmetic = 1;
1153 	#endif
1154 	            }
1155 	            else if(option[11] == '2')
1156 	            {
1157 	#ifndef SOPLEX_WITH_BOOST
1158 	               MSG_ERROR(std::cerr <<
1159 	                         "Cannot set arithmetic type to multiprecision - Soplex compiled without boost\n";)
1160 	               printUsage(argv, 0);
1161 	               return 1;
1162 	#else
1163 	               arithmetic = 2;
1164 	
1165 	               // default precision in multiprecision solve is 50
1166 	               if(precision == 0)
1167 	                  precision = 50;
1168 	
1169 	#endif
1170 	            }
1171 	         }
1172 	         // set precision
1173 	         else if(strncmp(option, "precision=", 10) == 0)
1174 	         {
1175 	            precision = atoi(option + 10);
1176 	#ifndef SOPLEX_WITH_BOOST
1177 	            MSG_ERROR(std::cerr << "Setting precision to non-default value without Boost has no effect\n";)
1178 	#endif
1179 	         }
1180 	
1181 	         break;
1182 	
1183 	      default:
1184 	         break;
1185 	      }
1186 	   }
1187 	
1188 	   if(precision != 0 && arithmetic != 2)
1189 	   {
1190 	      MSG_ERROR(std::cerr <<
1191 	                "Setting precision to non-default value without enabling multiprecision solve has no effect\n";)
1192 	   }
1193 	
(2) Event const: When switching on "arithmetic", the value of "arithmetic" must be equal to 0.
(3) Event dead_error_condition: The "switch" governing value "arithmetic" cannot reach the "default" case.
Also see events: [assignment][dead_error_begin]
1194 	   switch(arithmetic)
1195 	   {
1196 	   case 0:                 // double
1197 	      runSoPlex<Real>(argc, argv);
1198 	      break;
1199 	
1200 	#ifdef SOPLEX_WITH_BOOST
1201 	#ifdef SOPLEX_WITH_FLOAT128
1202 	
1203 	   case 1:                // quadprecision
1204 	#if BOOST_VERSION < 107000
1205 	      std::cerr << "Error: Boost version too old." << std:: endl <<
1206 	                "In order to use the quadprecision feature of SoPlex," <<
1207 	                " Boost Version 1.70.0 or higher is required." << std::endl << \
1208 	                "Included Boost version is " << BOOST_VERSION / 100000 << "."  // maj. version
1209 	                << BOOST_VERSION / 100 % 1000 << "."  // min. version
1210 	                << BOOST_VERSION % 100                // patch version;
1211 	                << std::endl;
1212 	#else
1213 	      using namespace boost::multiprecision;
1214 	      using Quad = boost::multiprecision::float128;
1215 	      runSoPlex<Quad>(argc, argv);
1216 	#endif
1217 	      break;
1218 	#endif
1219 	
1220 	   case 2:                 // soplex mpf
1221 	      using namespace boost::multiprecision;
1222 	
1223 	#if BOOST_VERSION < 107000
1224 	      std::cerr << "Error: Boost version too old." << std:: endl <<
1225 	                "In order to use the multiprecision feature of SoPlex," <<
1226 	                " Boost Version 1.70.0 or higher is required." << std::endl << \
1227 	                "Included Boost version is " << BOOST_VERSION / 100000 << "."  // maj. version
1228 	                << BOOST_VERSION / 100 % 1000 << "."  // min. version
1229 	                << BOOST_VERSION % 100                // patch version;
1230 	                << std::endl;
1231 	#else
1232 	#ifdef SOPLEX_WITH_MPFR
1233 	
1234 	      // et_off means the expression templates options is turned off. TODO:
1235 	      // The documentation also mentions about static vs dynamic memory
1236 	      // allocation for the mpfr types. Is it relevant here? I probably also
1237 	      // need to have the mpfr_float_eto in the global soplex namespace
1238 	      using multiprecision = number<mpfr_float_backend<0>, et_off>;
1239 	      multiprecision::default_precision(precision);
1240 	      runSoPlex<multiprecision>(argc, argv);
1241 	#endif  // SOPLEX_WITH_MPFR
1242 	
1243 	#ifdef SOPLEX_WITH_CPPMPF
1244 	      // It seems that precision cannot be set on run time for cpp_float
1245 	      // backend for boost::number. So a precision of 50 decimal points is
1246 	      // set.
1247 	      using multiprecision1 = number<cpp_dec_float<50>, et_off>;
1248 	      using multiprecision2 = number<cpp_dec_float<100>, et_off>;
1249 	      using multiprecision3 = number<cpp_dec_float<200>, et_off>;
1250 	
1251 	      if(precision <= 50)
1252 	         runSoPlex<multiprecision1>(argc, argv);
1253 	      else if(precision <= 100)
1254 	         runSoPlex<multiprecision2>(argc, argv);
1255 	      else
1256 	         runSoPlex<multiprecision3>(argc, argv);
1257 	
1258 	#endif  // SOPLEX_WITH_CPPMPF
1259 	#endif
1260 	      break;
1261 	#endif
1262 	
(4) Event dead_error_begin: Execution cannot reach this statement: "default:".
Also see events: [assignment][const][dead_error_condition]
1263 	   default:
1264 	      std::cerr << "Wrong value for the arithmetic mode\n";
1265 	      return 0;
1266 	   }
1267 	}
1268