1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the program and library             */
4    	/*         SCIP --- Solving Constraint Integer Programs                      */
5    	/*                                                                           */
6    	/*    Copyright (C) 2002-2022 Konrad-Zuse-Zentrum                            */
7    	/*                            fuer Informationstechnik Berlin                */
8    	/*                                                                           */
9    	/*  SCIP is distributed under the terms of the ZIB Academic License.         */
10   	/*                                                                           */
11   	/*  You should have received a copy of the ZIB Academic License              */
12   	/*  along with SCIP; see the file COPYING. If not visit scip.zib.de.         */
13   	/*                                                                           */
14   	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15   	
16   	/**@file   scip_expr.c
17   	 * @ingroup OTHER_CFILES
18   	 * @brief  public functions to work with algebraic expressions
19   	 * @author Ksenia Bestuzheva
20   	 * @author Benjamin Mueller
21   	 * @author Felipe Serrano
22   	 * @author Stefan Vigerske
23   	 */
24   	
25   	#include <string.h>
26   	#include <ctype.h>
27   	
28   	#include "scip/scip_expr.h"
29   	#include "scip/expr.h"
30   	#include "scip/set.h"
31   	#include "scip/misc.h"
32   	#include "scip/scip_copy.h"
33   	#include "scip/scip_mem.h"
34   	#include "scip/scip_message.h"
35   	#include "scip/scip_prob.h"
36   	#include "scip/scip_var.h"
37   	#include "scip/scip_sol.h"
38   	#include "scip/pub_var.h"
39   	#include "scip/struct_scip.h"
40   	#include "scip/struct_mem.h"
41   	#include "scip/struct_stat.h"
42   	
43   	/* core expression handler plugins */
44   	#include "scip/expr_value.h"
45   	#include "scip/expr_var.h"
46   	#include "scip/expr_sum.h"
47   	#include "scip/expr_product.h"
48   	#include "scip/expr_pow.h"
49   	
50   	/* #define PARSE_DEBUG */
51   	
52   	/*lint -e440*/
53   	/*lint -e441*/
54   	
55   	/*
56   	 * local functions
57   	 */
58   	
59   	/** variable mapping data passed on during copying expressions when copying SCIP instances */
60   	typedef struct
61   	{
62   	   SCIP_HASHMAP*         varmap;             /**< SCIP_HASHMAP mapping variables of the source SCIP to corresponding
63   	                                                  variables of the target SCIP */
64   	   SCIP_HASHMAP*         consmap;            /**< SCIP_HASHMAP mapping constraints of the source SCIP to corresponding
65   	                                                  constraints of the target SCIP */
66   	   SCIP_Bool             global;             /**< should a global or a local copy be created */
67   	   SCIP_Bool             valid;              /**< indicates whether every variable copy was valid */
68   	} COPY_MAPEXPR_DATA;
69   	
70   	/** variable expression mapping callback to call when copying expressions (within same or different SCIPs) */
71   	static
72   	SCIP_DECL_EXPR_MAPEXPR(copyVarExpr)
73   	{
74   	   COPY_MAPEXPR_DATA* data;
75   	   SCIP_Bool valid;
76   	   SCIP_VAR* targetvar;
77   	
78   	   assert(sourcescip != NULL);
79   	   assert(sourceexpr != NULL);
80   	   assert(targetscip != NULL);
81   	   assert(targetexpr != NULL);
82   	   assert(mapexprdata != NULL);
83   	
84   	   *targetexpr = NULL;
85   	
86   	   if( !SCIPisExprVar(sourcescip, sourceexpr) )
87   	      return SCIP_OKAY;
88   	
89   	   data = (COPY_MAPEXPR_DATA*)mapexprdata;
90   	
91   	   SCIP_CALL( SCIPgetVarCopy(sourcescip, targetscip, SCIPgetVarExprVar(sourceexpr), &targetvar, data->varmap,
92   	         data->consmap, data->global, &valid) );
93   	   assert(targetvar != NULL);
94   	
95   	   /* if copy was not valid, store so in mapvar data */
96   	   if( !valid )
97   	      data->valid = FALSE;
98   	
99   	   SCIP_CALL( SCIPcreateExprVar(targetscip, targetexpr, targetvar, ownercreate, ownercreatedata) );
100  	
101  	   return SCIP_OKAY;
102  	}
103  	
104  	
105  	/** @name Parsing methods (internal)
106  	 * @{
107  	 * Here is an attempt at defining the grammar of an expression.
108  	 * We use upper case names for variables (in the grammar sense) and terminals are between "".
109  	 * Loosely speaking, a Base will be any "block", a Factor is a Base to a power, a Term is a product of Factors
110  	 * and an Expression is a sum of terms.
111  	 * The actual definition:
112  	 * <pre>
113  	 * Expression -> ["+" | "-"] Term { ("+" | "-" | "number *") ] Term }
114  	 * Term       -> Factor { ("*" | "/" ) Factor }
115  	 * Factor     -> Base [ "^" "number" | "^(" "number" ")" ]
116  	 * Base       -> "number" | "<varname>" | "(" Expression ")" | Op "(" OpExpression ")
117  	 * </pre>
118  	 * where [a|b] means a or b or none, (a|b) means a or b, {a} means 0 or more a.
119  	 *
120  	 * Note that Op and OpExpression are undefined. Op corresponds to the name of an expression handler and
121  	 * OpExpression to whatever string the expression handler accepts (through its parse method).
122  	 *
123  	 * parse(Expr|Term|Base) returns an SCIP_EXPR
124  	 *
125  	 * @todo We can change the grammar so that Factor becomes base and we allow a Term to be
126  	 *       <pre> Term       -> Factor { ("*" | "/" | "^") Factor } </pre>
127  	 */
128  	
129  	/*lint -emacro(681,debugParse) */
130  	/*lint -emacro(506,debugParse) */
131  	/*lint -emacro(774,debugParse) */
132  	#ifdef PARSE_DEBUG
133  	#define debugParse                      printf
134  	#else
135  	#define debugParse                      while( FALSE ) printf
136  	#endif
137  	
138  	/* forward declaration */
139  	static
140  	SCIP_RETCODE parseExpr(
141  	   SCIP*                 scip,               /**< SCIP data structure */
142  	   SCIP_HASHMAP*         vartoexprvarmap,    /**< hashmap to map between scip vars and var expressions */
143  	   const char*           expr,               /**< expr that we are parsing */
144  	   const char**          newpos,             /**< buffer to store the position of expr where we finished reading */
145  	   SCIP_EXPR**           exprtree,           /**< buffer to store the expr parsed by Expr */
146  	   SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
147  	   void*                 ownercreatedata     /**< data to pass to ownercreate */
148  	   );
149  	
150  	/** Parses base to build a value, variable, sum, or function-like ("func(...)") expression.
151  	 * <pre>
152  	 * Base       -> "number" | "<varname>" | "(" Expression ")" | Op "(" OpExpression ")
153  	 * </pre>
154  	 */
155  	static
156  	SCIP_RETCODE parseBase(
157  	   SCIP*                 scip,               /**< SCIP data structure */
158  	   SCIP_HASHMAP*         vartoexprvarmap,    /**< hashmap to map between SCIP vars and var expressions */
159  	   const char*           expr,               /**< expr that we are parsing */
160  	   const char**          newpos,             /**< buffer to store the position of expr where we finished reading */
161  	   SCIP_EXPR**           basetree,           /**< buffer to store the expr parsed by Base */
162  	   SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
163  	   void*                 ownercreatedata     /**< data to pass to ownercreate */
164  	   )
165  	{
166  	   debugParse("parsing base from %s\n", expr);
167  	
168  	   /* ignore whitespace */
169  	   while( isspace((unsigned char)*expr) )
170  	      ++expr;
171  	
172  	   if( *expr == '\0' )
173  	   {
174  	      SCIPerrorMessage("Unexpected end of expression string\n");
175  	      return SCIP_READERROR;
176  	   }
177  	
178  	   if( *expr == '<' )
179  	   {
180  	      /* parse a variable */
181  	      SCIP_VAR* var;
182  	
183  	      SCIP_CALL( SCIPparseVarName(scip, expr, &var, (char**)newpos) );
184  	      if( var == NULL )
185  	      {
186  	         SCIPerrorMessage("Could not find variable with name '%s'\n", expr);
187  	         return SCIP_READERROR;
188  	      }
189  	      expr = *newpos;
190  	
191  	      /* check if we have already created an expression out of this var */
192  	      if( SCIPhashmapExists(vartoexprvarmap, (void*)var) )
193  	      {
194  	         debugParse("Variable <%s> has already been parsed, capturing its expression\n", SCIPvarGetName(var));
195  	         *basetree = (SCIP_EXPR*)SCIPhashmapGetImage(vartoexprvarmap, (void*)var);
196  	         SCIPexprCapture(*basetree);
197  	      }
198  	      else
199  	      {
200  	         debugParse("First time parsing variable <%s>, creating varexpr and adding it to hashmap\n", SCIPvarGetName(var));
201  	         /* intentionally not using createExprVar here, since parsed expressions are not part of a constraint
202  	          * (they will be copied when a constraint is created)
203  	          */
204  	         SCIP_CALL( SCIPcreateExprVar(scip, basetree, var, ownercreate, ownercreatedata) );
205  	         SCIP_CALL( SCIPhashmapInsert(vartoexprvarmap, (void*)var, (void*)(*basetree)) );
206  	      }
207  	   }
208  	   else if( *expr == '(' )
209  	   {
210  	      /* parse expression */
211  	      SCIP_CALL( parseExpr(scip, vartoexprvarmap, ++expr, newpos, basetree, ownercreate, ownercreatedata) );
212  	      expr = *newpos;
213  	
214  	      /* expect ')' */
215  	      if( *expr != ')' )
216  	      {
217  	         SCIPerrorMessage("Read a '(', parsed expression inside --> expecting closing ')'. Got <%c>: rest of string <%s>\n", *expr, expr);
218  	         SCIP_CALL( SCIPreleaseExpr(scip, basetree) );
219  	         return SCIP_READERROR;
220  	      }
221  	      ++expr;
222  	      debugParse("Done parsing expression, continue with <%s>\n", expr);
223  	   }
224  	   else if( isdigit(*expr) )
225  	   {
226  	      /* parse number */
227  	      SCIP_Real value;
228  	      if( !SCIPstrToRealValue(expr, &value, (char**)&expr) )
229  	      {
230  	         SCIPerrorMessage("error parsing number from <%s>\n", expr);
231  	         return SCIP_READERROR;
232  	      }
233  	      debugParse("Parsed value %g, creating a value-expression.\n", value);
234  	      SCIP_CALL( SCIPcreateExprValue(scip, basetree, value, ownercreate, ownercreatedata) );
235  	   }
236  	   else if( isalpha(*expr) )
237  	   {
238  	      /* a (function) name is coming, should find exprhandler with such name */
239  	      int i;
240  	      char operatorname[SCIP_MAXSTRLEN];
241  	      SCIP_EXPRHDLR* exprhdlr;
242  	      SCIP_Bool success;
243  	
244  	      /* get name */
245  	      i = 0;
246  	      while( *expr != '(' && !isspace((unsigned char)*expr) && *expr != '\0' )
247  	      {
248  	         operatorname[i] = *expr;
249  	         ++expr;
250  	         ++i;
251  	      }
252  	      operatorname[i] = '\0';
253  	
254  	      /* after name we must see a '(' */
255  	      if( *expr != '(' )
256  	      {
257  	         SCIPerrorMessage("Expected '(' after operator name <%s>, but got %s.\n", operatorname, expr);
258  	         return SCIP_READERROR;
259  	      }
260  	
261  	      /* search for expression handler */
262  	      exprhdlr = SCIPfindExprhdlr(scip, operatorname);
263  	
264  	      /* check expression handler exists and has a parsing method */
265  	      if( exprhdlr == NULL )
266  	      {
267  	         SCIPerrorMessage("No expression handler with name <%s> found.\n", operatorname);
268  	         return SCIP_READERROR;
269  	      }
270  	
271  	      ++expr;
272  	      SCIP_CALL( SCIPexprhdlrParseExpr(exprhdlr, scip->set, expr, newpos, basetree, &success, ownercreate, ownercreatedata) );
273  	
274  	      if( !success )
275  	      {
276  	         SCIPerrorMessage("Error while expression handler <%s> was parsing %s\n", operatorname, expr);
277  	         assert(*basetree == NULL);
278  	         return SCIP_READERROR;
279  	      }
280  	      expr = *newpos;
281  	
282  	      /* we should see the ')' of Op "(" OpExpression ") */
283  	      assert(*expr == ')');
284  	
285  	      /* move one character forward */
286  	      ++expr;
287  	   }
288  	   else
289  	   {
290  	      /* Base -> "number" | "<varname>" | "(" Expression ")" | Op "(" OpExpression ") */
291  	      SCIPerrorMessage("Expected a number, (expression), <varname>, Opname(Opexpr), instead got <%c> from %s\n", *expr, expr);
292  	      return SCIP_READERROR;
293  	   }
294  	
295  	   *newpos = expr;
296  	
297  	   return SCIP_OKAY;
298  	}
299  	
300  	/** Parses a factor and builds a product-expression if there is an exponent, otherwise returns the base expression.
301  	 * <pre>
302  	 * Factor -> Base [ "^" "number" | "^(" "number" ")" ]
303  	 * </pre>
304  	 */
305  	static
306  	SCIP_RETCODE parseFactor(
307  	   SCIP*                 scip,               /**< SCIP data structure */
308  	   SCIP_Bool             isdenominator,      /**< whether factor is in the denominator */
309  	   SCIP_HASHMAP*         vartoexprvarmap,    /**< hashmap to map between scip vars and var expressions */
310  	   const char*           expr,               /**< expr that we are parsing */
311  	   const char**          newpos,             /**< buffer to store the position of expr where we finished reading */
312  	   SCIP_EXPR**           factortree,         /**< buffer to store the expr parsed by Factor */
313  	   SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
314  	   void*                 ownercreatedata     /**< data to pass to ownercreate */
315  	   )
316  	{
317  	   SCIP_EXPR*  basetree;
318  	   SCIP_Real exponent;
319  	
320  	   debugParse("parsing factor from %s\n", expr);
321  	
322  	   if( *expr == '\0' )
323  	   {
324  	      SCIPerrorMessage("Unexpected end of expression string.\n");
325  	      return SCIP_READERROR;
326  	   }
327  	
328  	   /* parse Base */
329  	   /* ignore whitespace */
330  	   while( isspace((unsigned char)*expr) )
331  	      ++expr;
332  	
333  	   SCIP_CALL( parseBase(scip, vartoexprvarmap, expr, newpos, &basetree, ownercreate, ownercreatedata) );
334  	   expr = *newpos;
335  	
336  	   /* check if there is an exponent */
337  	   /* ignore whitespace */
338  	   while( isspace((unsigned char)*expr) )
339  	      ++expr;
340  	   if( *expr == '^' )
341  	   {
342  	      ++expr;
343  	      while( isspace((unsigned char)*expr) )
344  	         ++expr;
345  	
346  	      if( *expr == '\0' )
347  	      {
348  	         SCIPerrorMessage("Unexpected end of expression string after '^'.\n");
349  	         SCIP_CALL( SCIPreleaseExpr(scip, &basetree) );
350  	         return SCIP_READERROR;
351  	      }
352  	
353  	      if( *expr == '(' )
354  	      {
355  	         ++expr;
356  	
357  	         /* it is exponent with parenthesis; expect number possibly starting with + or - */
358  	         if( !SCIPstrToRealValue(expr, &exponent, (char**)&expr) )
359  	         {
360  	            SCIPerrorMessage("error parsing number from <%s>\n", expr);
361  	            SCIP_CALL( SCIPreleaseExpr(scip, &basetree) );
362  	            return SCIP_READERROR;
363  	         }
364  	
365  	         /* expect the ')' */
366  	         while( isspace((unsigned char)*expr) )
367  	            ++expr;
368  	         if( *expr != ')' )
369  	         {
370  	            SCIPerrorMessage("error in parsing exponent: expected ')', received <%c> from <%s>\n", *expr,  expr);
371  	            SCIP_CALL( SCIPreleaseExpr(scip, &basetree) );
372  	            return SCIP_READERROR;
373  	         }
374  	         ++expr;
375  	      }
376  	      else
377  	      {
378  	         /* no parenthesis, we should see just a positive number */
379  	
380  	         /* expect a digit */
381  	         if( isdigit(*expr) )
382  	         {
383  	            if( !SCIPstrToRealValue(expr, &exponent, (char**)&expr) )
384  	            {
385  	               SCIPerrorMessage("error parsing number from <%s>\n", expr);
386  	               SCIP_CALL( SCIPreleaseExpr(scip, &basetree) );
387  	               return SCIP_READERROR;
388  	            }
389  	         }
390  	         else
391  	         {
392  	            SCIPerrorMessage("error in parsing exponent, expected a digit, received <%c> from <%s>\n", *expr,  expr);
393  	            SCIP_CALL( SCIPreleaseExpr(scip, &basetree) );
394  	            return SCIP_READERROR;
395  	         }
396  	      }
397  	
398  	      debugParse("parsed the exponent %g\n", exponent); /*lint !e506 !e681*/
399  	   }
400  	   else
401  	   {
402  	      /* there is no explicit exponent */
403  	      exponent = 1.0;
404  	   }
405  	   *newpos = expr;
406  	
407  	   /* multiply with -1 when we are in the denominator */
408  	   if( isdenominator )
409  	      exponent *= -1.0;
410  	
411  	   /* create power */
412  	   if( exponent != 1.0 )
413  	   {
414  	      SCIP_CALL( SCIPcreateExprPow(scip, factortree, basetree, exponent, ownercreate, ownercreatedata) );
415  	      SCIP_CALL( SCIPreleaseExpr(scip, &basetree) );
416  	   }
417  	   else
418  	      /* Factor consists of this unique Base */
419  	      *factortree = basetree;
420  	
421  	   return SCIP_OKAY;
422  	}
423  	
424  	/** Parses a term and builds a product-expression, where each factor is a child.
425  	 * <pre>
426  	 * Term -> Factor { ("*" | "/" ) Factor }
427  	 * </pre>
428  	 */
429  	static
430  	SCIP_RETCODE parseTerm(
431  	   SCIP*                 scip,               /**< SCIP data structure */
432  	   SCIP_HASHMAP*         vartoexprvarmap,    /**< hashmap to map between scip vars and var expressions */
433  	   const char*           expr,               /**< expr that we are parsing */
434  	   const char**          newpos,             /**< buffer to store the position of expr where we finished reading */
435  	   SCIP_EXPR**           termtree,           /**< buffer to store the expr parsed by Term */
436  	   SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
437  	   void*                 ownercreatedata     /**< data to pass to ownercreate */
438  	   )
439  	{
440  	   SCIP_EXPR* factortree;
441  	
442  	   debugParse("parsing term from %s\n", expr);
443  	
444  	   /* parse Factor */
445  	   /* ignore whitespace */
446  	   while( isspace((unsigned char)*expr) )
447  	      ++expr;
448  	
449  	   SCIP_CALL( parseFactor(scip, FALSE, vartoexprvarmap, expr, newpos, &factortree, ownercreate, ownercreatedata) );
450  	   expr = *newpos;
451  	
452  	   debugParse("back to parsing Term, continue parsing from %s\n", expr);
453  	
454  	   /* check if Terms has another Factor incoming */
455  	   while( isspace((unsigned char)*expr) )
456  	      ++expr;
457  	   if( *expr == '*' || *expr == '/' )
458  	   {
459  	      /* initialize termtree as a product expression with a single term, so we can append the extra Factors */
460  	      SCIP_CALL( SCIPcreateExprProduct(scip, termtree, 1, &factortree, 1.0, ownercreate, ownercreatedata) );
461  	      SCIP_CALL( SCIPreleaseExpr(scip, &factortree) );
462  	
463  	      /* loop: parse Factor, find next symbol */
464  	      do
465  	      {
466  	         SCIP_RETCODE retcode;
467  	         SCIP_Bool isdivision;
468  	
469  	         isdivision = (*expr == '/') ? TRUE : FALSE;
470  	
471  	         debugParse("while parsing term, read char %c\n", *expr); /*lint !e506 !e681*/
472  	
473  	         ++expr;
474  	         retcode = parseFactor(scip, isdivision, vartoexprvarmap, expr, newpos, &factortree, ownercreate, ownercreatedata);
475  	
476  	         /* release termtree, if parseFactor fails with a read-error */
477  	         if( retcode == SCIP_READERROR )
478  	         {
479  	            SCIP_CALL( SCIPreleaseExpr(scip, termtree) );
480  	         }
481  	         SCIP_CALL( retcode );
482  	
483  	         /* append newly created factor */
484  	         SCIP_CALL( SCIPappendExprChild(scip, *termtree, factortree) );
485  	         SCIP_CALL( SCIPreleaseExpr(scip, &factortree) );
486  	
487  	         /* find next symbol */
488  	         expr = *newpos;
489  	         while( isspace((unsigned char)*expr) )
490  	            ++expr;
491  	      }
492  	      while( *expr == '*' || *expr == '/' );
493  	   }
494  	   else
495  	   {
496  	      /* Term consists of this unique factor */
497  	      *termtree = factortree;
498  	   }
499  	
500  	   *newpos = expr;
501  	
502  	   return SCIP_OKAY;
503  	}
504  	
505  	/** parses an expression and builds a sum-expression with children
506  	 *
507  	 * <pre>
508  	 * Expression -> ["+" | "-"] Term { ("+" | "-" | "number *") ] Term }
509  	 * </pre>
510  	 */
511  	static
512  	SCIP_RETCODE parseExpr(
513  	   SCIP*                 scip,               /**< SCIP data structure */
514  	   SCIP_HASHMAP*         vartoexprvarmap,    /**< hashmap to map between scip vars and var expressions */
515  	   const char*           expr,               /**< expr that we are parsing */
516  	   const char**          newpos,             /**< buffer to store the position of expr where we finished reading */
517  	   SCIP_EXPR**           exprtree,           /**< buffer to store the expr parsed by Expr */
518  	   SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
519  	   void*                 ownercreatedata     /**< data to pass to ownercreate */
520  	   )
521  	{
522  	   SCIP_Real sign;
523  	   SCIP_EXPR* termtree;
524  	
525  	   debugParse("parsing expression %s\n", expr); /*lint !e506 !e681*/
526  	
527  	   /* ignore whitespace */
528  	   while( isspace((unsigned char)*expr) )
529  	      ++expr;
530  	
531  	   /* if '+' or '-', store it */
532  	   sign = 1.0;
533  	   if( *expr == '+' || *expr == '-' )
534  	   {
535  	      debugParse("while parsing expression, read char %c\n", *expr); /*lint !e506 !e681*/
536  	      sign = *expr == '+' ? 1.0 : -1.0;
537  	      ++expr;
538  	   }
539  	
540  	   SCIP_CALL( parseTerm(scip, vartoexprvarmap, expr, newpos, &termtree, ownercreate, ownercreatedata) );
541  	   expr = *newpos;
542  	
543  	   debugParse("back to parsing expression (we have the following term), continue parsing from %s\n", expr); /*lint !e506 !e681*/
544  	
545  	   /* check if Expr has another Term incoming */
546  	   while( isspace((unsigned char)*expr) )
547  	      ++expr;
548  	   if( *expr == '+' || *expr == '-' )
549  	   {
550  	      if( SCIPexprIsValue(scip->set, termtree) )
551  	      {
552  	         /* initialize exprtree as a sum expression with a constant only, so we can append the following terms */
553  	         SCIP_CALL( SCIPcreateExprSum(scip, exprtree, 0, NULL, NULL, sign * SCIPgetValueExprValue(termtree), ownercreate, ownercreatedata) );
554  	         SCIP_CALL( SCIPreleaseExpr(scip, &termtree) );
555  	      }
556  	      else
557  	      {
558  	         /* initialize exprtree as a sum expression with a single term, so we can append the following terms */
559  	         SCIP_CALL( SCIPcreateExprSum(scip, exprtree, 1, &termtree, &sign, 0.0, ownercreate, ownercreatedata) );
560  	         SCIP_CALL( SCIPreleaseExpr(scip, &termtree) );
561  	      }
562  	
563  	      /* loop: parse Term, find next symbol */
564  	      do
565  	      {
566  	         SCIP_RETCODE retcode;
567  	         SCIP_Real coef;
568  	
569  	         /* check if we have a "coef * <term>" */
570  	         if( SCIPstrToRealValue(expr, &coef, (char**)newpos) )
571  	         {
572  	            while( isspace((unsigned char)**newpos) )
573  	               ++(*newpos);
574  	
575  	            if( **newpos != '*' )
576  	            {
577  	               /* no '*', so fall back to parsing term after sign */
578  	               coef = (*expr == '+') ? 1.0 : -1.0;
579  	               ++expr;
580  	            }
581  	            else
582  	            {
583  	               /* keep coefficient in coef and continue parsing term after coefficient */
584  	               expr = (*newpos)+1;
585  	
586  	               while( isspace((unsigned char)*expr) )
587  	                  ++expr;
588  	            }
589  	         }
590  	         else
591  	         {
592  	            coef = (*expr == '+') ? 1.0 : -1.0;
593  	            ++expr;
594  	         }
595  	
596  	         debugParse("while parsing expression, read coefficient %g\n", coef); /*lint !e506 !e681*/
597  	
598  	         retcode = parseTerm(scip, vartoexprvarmap, expr, newpos, &termtree, ownercreate, ownercreatedata);
599  	
600  	         /* release exprtree if parseTerm fails with an read-error */
601  	         if( retcode == SCIP_READERROR )
602  	         {
603  	            SCIP_CALL( SCIPreleaseExpr(scip, exprtree) );
604  	         }
605  	         SCIP_CALL( retcode );
606  	
607  	         /* append newly created term */
608  	         SCIP_CALL( SCIPappendExprSumExpr(scip, *exprtree, termtree, coef) );
609  	         SCIP_CALL( SCIPreleaseExpr(scip, &termtree) );
610  	
611  	         /* find next symbol */
612  	         expr = *newpos;
613  	         while( isspace((unsigned char)*expr) )
614  	            ++expr;
615  	      } while( *expr == '+' || *expr == '-' );
616  	   }
617  	   else
618  	   {
619  	      /* Expr consists of this unique ['+' | '-'] Term */
620  	      if( sign  < 0.0 )
621  	      {
622  	         assert(sign == -1.0);
623  	         SCIP_CALL( SCIPcreateExprSum(scip, exprtree, 1, &termtree, &sign, 0.0, ownercreate, ownercreatedata) );
624  	         SCIP_CALL( SCIPreleaseExpr(scip, &termtree) );
625  	      }
626  	      else
627  	         *exprtree = termtree;
628  	   }
629  	
630  	   *newpos = expr;
631  	
632  	   return SCIP_OKAY;
633  	}
634  	
635  	/** @} */  /* end of parsing methods */
636  	
637  	/** @name Simplify methods (internal)
638  	 * @{
639  	 */
640  	
641  	/** returns an equivalent expression for a given expression if possible
642  	 *
643  	 * it adds the expression to key2expr if the map does not contain the key
644  	 */
645  	static
646  	SCIP_RETCODE findEqualExpr(
647  	   SCIP_SET*             set,                /**< global SCIP settings */
648  	   SCIP_EXPR*            expr,               /**< expression to replace */
649  	   SCIP_MULTIHASH*       key2expr,           /**< mapping of hashes to expressions */
650  	   SCIP_EXPR**           newexpr             /**< pointer to store an equivalent expression (NULL if there is none) */
651  	   )
652  	{  /*lint --e{438}*/
653  	   SCIP_MULTIHASHLIST* multihashlist;
654  	
655  	   assert(set != NULL);
656  	   assert(expr != NULL);
657  	   assert(key2expr != NULL);
658  	   assert(newexpr != NULL);
659  	
660  	   *newexpr = NULL;
661  	   multihashlist = NULL;
662  	   do
663  	   {
664  	      /* search for an equivalent expression */
665  	      *newexpr = (SCIP_EXPR*)(SCIPmultihashRetrieveNext(key2expr, &multihashlist, (void*)expr));
666  	
667  	      if( *newexpr == NULL )
668  	      {
669  	         /* processed all expressions like expr from hash table, so insert expr */
670  	         SCIP_CALL( SCIPmultihashInsert(key2expr, (void*) expr) );
671  	         break;
672  	      }
673  	      else if( expr != *newexpr )
674  	      {
675  	         assert(SCIPexprCompare(set, expr, *newexpr) == 0);
676  	         break;
677  	      }
678  	      else
679  	      {
680  	         /* can not replace expr since it is already contained in the hashtablelist */
681  	         assert(expr == *newexpr);
682  	         *newexpr = NULL;
683  	         break;
684  	      }
685  	   }
686  	   while( TRUE ); /*lint !e506*/
687  	
688  	   return SCIP_OKAY;
689  	}
690  	
691  	/** userdata for multihash for common subexpression */
692  	typedef struct
693  	{
694  	   SCIP_SET*      set;
695  	   SCIP_EXPRITER* hashiterator;
696  	} COMMONSUBEXPR_HASH_DATA;
697  	
698  	/** get key of hash element */
699  	static
700  	SCIP_DECL_HASHGETKEY(hashCommonSubexprGetKey)
701  	{
702  	   return elem;
703  	}  /*lint !e715*/
704  	
705  	/** checks if two expressions are structurally the same */
706  	static
707  	SCIP_DECL_HASHKEYEQ(hashCommonSubexprEq)
708  	{
709  	   COMMONSUBEXPR_HASH_DATA* data;
710  	   SCIP_EXPR* expr1;
711  	   SCIP_EXPR* expr2;
712  	
713  	   data = (COMMONSUBEXPR_HASH_DATA*)userptr;
714  	   assert(data != NULL);
715  	
716  	   expr1 = (SCIP_EXPR*)key1;
717  	   expr2 = (SCIP_EXPR*)key2;
718  	   assert(expr1 != NULL);
719  	   assert(expr2 != NULL);
720  	
721  	   return expr1 == expr2 || SCIPexprCompare(data->set, expr1, expr2) == 0;
722  	}  /*lint !e715*/
723  	
724  	/** get value of hash element when comparing with another expression */
725  	static
726  	SCIP_DECL_HASHKEYVAL(hashCommonSubexprKeyval)
727  	{
728  	   COMMONSUBEXPR_HASH_DATA* data;
729  	   SCIP_EXPR* expr;
730  	
731  	   expr = (SCIP_EXPR*) key;
732  	   assert(expr != NULL);
733  	
734  	   data = (COMMONSUBEXPR_HASH_DATA*) userptr;
735  	   assert(data != NULL);
736  	
737  	   return SCIPexpriterGetExprUserData(data->hashiterator, expr).uintval;
738  	}  /*lint !e715*/
739  	
740  	/** hashes an expression using an already existing iterator
741  	 *
742  	 * The iterator must by of type DFS with allowrevisit=FALSE and only the leaveexpr stage enabled.
743  	 * The hashes of all visited expressions will be stored in the iterators expression data.
744  	 */
745  	static
746  	SCIP_RETCODE hashExpr(
747  	   SCIP_SET*             set,                /**< global SCIP settings */
748  	   BMS_BUFMEM*           bufmem,             /**< buffer memory */
749  	   SCIP_EXPR*            expr,               /**< expression to hash */
750  	   SCIP_EXPRITER*        hashiterator,       /**< iterator to use for hashing */
751  	   int*                  nvisitedexprs       /**< counter to increment by the number of expressions visited, or NULL */
752  	   )
753  	{
754  	   SCIP_EXPRITER_USERDATA iterdata;
755  	   unsigned int* childrenhashes;
756  	   int childrenhashessize;
757  	   int i;
758  	
759  	   assert(set != NULL);
760  	   assert(expr != NULL);
761  	   assert(hashiterator != NULL);
762  	
763  	   childrenhashessize = 5;
764  	   SCIP_ALLOC( BMSallocBufferMemoryArray(bufmem, &childrenhashes, childrenhashessize) );
765  	
766  	   for( expr = SCIPexpriterRestartDFS(hashiterator, expr); !SCIPexpriterIsEnd(hashiterator); expr = SCIPexpriterGetNext(hashiterator) ) /*lint !e441*/
767  	   {
768  	      assert(SCIPexpriterGetStageDFS(hashiterator) == SCIP_EXPRITER_LEAVEEXPR);
769  	
770  	      if( nvisitedexprs != NULL )
771  	         ++*nvisitedexprs;
772  	
773  	      /* collect hashes of children */
774  	      if( childrenhashessize < SCIPexprGetNChildren(expr) )
775  	      {
776  	         childrenhashessize = SCIPsetCalcMemGrowSize(set, SCIPexprGetNChildren(expr));
777  	         SCIP_ALLOC( BMSreallocBufferMemoryArray(bufmem, &childrenhashes, childrenhashessize) );
778  	      }
779  	      for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
780  	         childrenhashes[i] = SCIPexpriterGetExprUserData(hashiterator, SCIPexprGetChildren(expr)[i]).uintval;
781  	
782  	      SCIP_CALL( SCIPexprhdlrHashExpr(SCIPexprGetHdlr(expr), set, expr, &iterdata.uintval, childrenhashes) );
783  	
784  	      SCIPexpriterSetCurrentUserData(hashiterator, iterdata);
785  	   }
786  	
787  	   BMSfreeBufferMemoryArray(bufmem, &childrenhashes);
788  	
789  	   return SCIP_OKAY;
790  	}
791  	
792  	/** @} */  /* end of simplify methods */
793  	
794  	/*
795  	 * public functions
796  	 */
797  	
798  	/**@addtogroup PublicExprHandlerMethods
799  	 * @{
800  	 */
801  	
802  	#ifdef NDEBUG
803  	#undef SCIPgetExprhdlrs
804  	#undef SCIPgetNExprhdlrs
805  	#undef SCIPfindExprhdlr
806  	#undef SCIPgetExprhdlrVar
807  	#undef SCIPgetExprhdlrValue
808  	#undef SCIPgetExprhdlrSum
809  	#undef SCIPgetExprhdlrProduct
810  	#undef SCIPgetExprhdlrPower
811  	#endif
812  	
813  	/** creates the handler for an expression handler and includes it into SCIP */
814  	SCIP_RETCODE SCIPincludeExprhdlr(
815  	   SCIP*                 scip,               /**< SCIP data structure */
816  	   SCIP_EXPRHDLR**       exprhdlr,           /**< buffer where to store created expression handler */
817  	   const char*           name,               /**< name of expression handler (must not be NULL) */
818  	   const char*           desc,               /**< description of expression handler (can be NULL) */
819  	   unsigned int          precedence,         /**< precedence of expression operation (used for printing) */
820  	   SCIP_DECL_EXPREVAL((*eval)),              /**< point evaluation callback (must not be NULL) */
821  	   SCIP_EXPRHDLRDATA*    data                /**< data of expression handler (can be NULL) */
822  	   )
823  	{
824  	   assert(scip != NULL);
825  	   assert(scip->mem != NULL);
826  	   assert(exprhdlr != NULL);
827  	
828  	   SCIP_CALL( SCIPexprhdlrCreate(scip->mem->setmem, exprhdlr, name, desc, precedence, eval, data) );
829  	   assert(*exprhdlr != NULL);
830  	
831  	   SCIP_CALL( SCIPsetIncludeExprhdlr(scip->set, *exprhdlr) );
832  	
833  	   return SCIP_OKAY;
834  	}
835  	
836  	/** gives expression handlers */
837  	SCIP_EXPRHDLR** SCIPgetExprhdlrs(
838  	   SCIP*                 scip                /**< SCIP data structure */
839  	   )
840  	{
841  	   assert(scip != NULL);
842  	   assert(scip->set != NULL);
843  	
844  	   return scip->set->exprhdlrs;
845  	}
846  	
847  	/** gives number of expression handlers */
848  	int SCIPgetNExprhdlrs(
849  	   SCIP*                 scip                /**< SCIP data structure */
850  	   )
851  	{
852  	   assert(scip != NULL);
853  	   assert(scip->set != NULL);
854  	
855  	   return scip->set->nexprhdlrs;
856  	}
857  	
858  	/** returns an expression handler of a given name (or NULL if not found) */
859  	SCIP_EXPRHDLR* SCIPfindExprhdlr(
860  	   SCIP*                 scip,               /**< SCIP data structure */
861  	   const char*           name                /**< name of expression handler */
862  	   )
863  	{
864  	   assert(scip != NULL);
865  	   assert(scip->set != NULL);
866  	
867  	   return SCIPsetFindExprhdlr(scip->set, name);
868  	}
869  	
870  	/** returns expression handler for variable expressions (or NULL if not included) */
871  	SCIP_EXPRHDLR* SCIPgetExprhdlrVar(
872  	   SCIP*                 scip                /**< SCIP data structure */
873  	   )
874  	{
875  	   assert(scip != NULL);
876  	   assert(scip->set != NULL);
877  	
878  	   return scip->set->exprhdlrvar;
879  	}
880  	
881  	/** returns expression handler for constant value expressions (or NULL if not included) */
882  	SCIP_EXPRHDLR* SCIPgetExprhdlrValue(
883  	   SCIP*                 scip                /**< SCIP data structure */
884  	   )
885  	{
886  	   assert(scip != NULL);
887  	   assert(scip->set != NULL);
888  	
889  	   return scip->set->exprhdlrval;
890  	}
891  	
892  	/** returns expression handler for sum expressions (or NULL if not included) */
893  	SCIP_EXPRHDLR* SCIPgetExprhdlrSum(
894  	   SCIP*                 scip                /**< SCIP data structure */
895  	   )
896  	{
897  	   assert(scip != NULL);
898  	   assert(scip->set != NULL);
899  	
900  	   return scip->set->exprhdlrsum;
901  	}
902  	
903  	/** returns expression handler for product expressions (or NULL if not included) */
904  	SCIP_EXPRHDLR* SCIPgetExprhdlrProduct(
905  	   SCIP*                 scip                /**< SCIP data structure */
906  	   )
907  	{
908  	   assert(scip != NULL);
909  	   assert(scip->set != NULL);
910  	
911  	   return scip->set->exprhdlrproduct;
912  	}
913  	
914  	/** returns expression handler for power expressions (or NULL if not included) */
915  	SCIP_EXPRHDLR* SCIPgetExprhdlrPower(
916  	   SCIP*                 scip                /**< SCIP data structure */
917  	   )
918  	{
919  	   assert(scip != NULL);
920  	   assert(scip->set != NULL);
921  	
922  	   return scip->set->exprhdlrpow;
923  	}
924  	
925  	/**@} */
926  	
927  	
928  	/**@name Expression Methods */
929  	/**@{ */
930  	
931  	#ifdef NDEBUG
932  	#undef SCIPappendExprChild
933  	#undef SCIPreplaceExprChild
934  	#undef SCIPremoveExprChildren
935  	#undef SCIPduplicateExpr
936  	#undef SCIPduplicateExprShallow
937  	#undef SCIPcaptureExpr
938  	#undef SCIPreleaseExpr
939  	#undef SCIPisExprVar
940  	#undef SCIPisExprValue
941  	#undef SCIPisExprSum
942  	#undef SCIPisExprProduct
943  	#undef SCIPisExprPower
944  	#undef SCIPprintExpr
945  	#undef SCIPevalExpr
946  	#undef SCIPgetExprNewSoltag
947  	#undef SCIPevalExprGradient
948  	#undef SCIPevalExprHessianDir
949  	#undef SCIPevalExprActivity
950  	#undef SCIPcompareExpr
951  	#undef SCIPsimplifyExpr
952  	#undef SCIPcallExprCurvature
953  	#undef SCIPcallExprMonotonicity
954  	#undef SCIPcallExprEval
955  	#undef SCIPcallExprEvalFwdiff
956  	#undef SCIPcallExprInteval
957  	#undef SCIPcallExprEstimate
958  	#undef SCIPcallExprInitestimates
959  	#undef SCIPcallExprSimplify
960  	#undef SCIPcallExprReverseprop
961  	#endif
962  	
963  	/** creates and captures an expression with given expression data and children */
964  	SCIP_RETCODE SCIPcreateExpr(
965  	   SCIP*                 scip,               /**< SCIP data structure */
966  	   SCIP_EXPR**           expr,               /**< pointer where to store expression */
967  	   SCIP_EXPRHDLR*        exprhdlr,           /**< expression handler */
968  	   SCIP_EXPRDATA*        exprdata,           /**< expression data (expression assumes ownership) */
969  	   int                   nchildren,          /**< number of children */
970  	   SCIP_EXPR**           children,           /**< children (can be NULL if nchildren is 0) */
971  	   SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
972  	   void*                 ownercreatedata     /**< data to pass to ownercreate */
973  	   )
974  	{
975  	   assert(scip != NULL);
976  	   assert(scip->set != NULL);
977  	
978  	   SCIP_CALL( SCIPexprCreate(scip->set, scip->mem->probmem, expr, exprhdlr, exprdata, nchildren, children, ownercreate,
979  	         ownercreatedata) );
980  	
981  	   return SCIP_OKAY;
982  	}
983  	
984  	/** creates and captures an expression with given expression data and up to two children */
985  	SCIP_RETCODE SCIPcreateExpr2(
986  	   SCIP*                 scip,               /**< SCIP data structure */
987  	   SCIP_EXPR**           expr,               /**< pointer where to store expression */
988  	   SCIP_EXPRHDLR*        exprhdlr,           /**< expression handler */
989  	   SCIP_EXPRDATA*        exprdata,           /**< expression data */
990  	   SCIP_EXPR*            child1,             /**< first child (can be NULL) */
991  	   SCIP_EXPR*            child2,             /**< second child (can be NULL) */
992  	   SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
993  	   void*                 ownercreatedata     /**< data to pass to ownercreate */
994  	   )
995  	{
996  	   assert(scip != NULL);
997  	   assert(expr != NULL);
998  	   assert(exprhdlr != NULL);
999  	
1000 	   if( child1 != NULL && child2 != NULL )
1001 	   {
1002 	      SCIP_EXPR* pair[2];
1003 	      pair[0] = child1;
1004 	      pair[1] = child2;
1005 	
1006 	      SCIP_CALL( SCIPcreateExpr(scip, expr, exprhdlr, exprdata, 2, pair, ownercreate, ownercreatedata) );
1007 	   }
1008 	   else if( child2 == NULL )
1009 	   {
1010 	      SCIP_CALL( SCIPcreateExpr(scip, expr, exprhdlr, exprdata, child1 == NULL ? 0 : 1, &child1, ownercreate,
1011 	            ownercreatedata) );
1012 	   }
1013 	   else
1014 	   {
1015 	      /* child2 != NULL, child1 == NULL */
1016 	      SCIP_CALL( SCIPcreateExpr(scip, expr, exprhdlr, exprdata, 1, &child2, ownercreate, ownercreatedata) );
1017 	   }
1018 	
1019 	   return SCIP_OKAY;
1020 	}
1021 	
1022 	/** creates and captures an expression representing a quadratic function */
1023 	SCIP_RETCODE SCIPcreateExprQuadratic(
1024 	   SCIP*                 scip,               /**< SCIP data structure */
1025 	   SCIP_EXPR**           expr,               /**< pointer where to store expression */
1026 	   int                   nlinvars,           /**< number of linear terms */
1027 	   SCIP_VAR**            linvars,            /**< array with variables in linear part */
1028 	   SCIP_Real*            lincoefs,           /**< array with coefficients of variables in linear part */
1029 	   int                   nquadterms,         /**< number of quadratic terms */
1030 	   SCIP_VAR**            quadvars1,          /**< array with first variables in quadratic terms */
1031 	   SCIP_VAR**            quadvars2,          /**< array with second variables in quadratic terms */
1032 	   SCIP_Real*            quadcoefs,          /**< array with coefficients of quadratic terms */
1033 	   SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
1034 	   void*                 ownercreatedata     /**< data to pass to ownercreate */
1035 	   )
1036 	{
1037 	   SCIP_EXPR** children;
1038 	   SCIP_Real* coefs;
1039 	   int i;
1040 	
1041 	   assert(scip != NULL);
1042 	   assert(expr != NULL);
1043 	   assert(nlinvars == 0 || (linvars != NULL && lincoefs != NULL));
1044 	   assert(nquadterms == 0 || (quadvars1 != NULL && quadvars2 != NULL && quadcoefs != NULL));
1045 	
1046 	   /* allocate memory */
1047 	   SCIP_CALL( SCIPallocBufferArray(scip, &children, nquadterms + nlinvars) );
1048 	   SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nquadterms + nlinvars) );
1049 	
1050 	   /* create children for quadratic terms */
1051 	   for( i = 0; i < nquadterms; ++i )
1052 	   {
1053 	      assert(quadvars1 != NULL && quadvars1[i] != NULL);
1054 	      assert(quadvars2 != NULL && quadvars2[i] != NULL);
1055 	
1056 	      /* quadratic term */
1057 	      if( quadvars1[i] == quadvars2[i] )
1058 	      {
1059 	         SCIP_EXPR* xexpr;
1060 	
1061 	         /* create variable expression; intentionally not using createExprVar here,
1062 	          * since expression created here is not part of a constraint (they will be copied when a constraint is created)
1063 	          */
1064 	         SCIP_CALL( SCIPcreateExprVar(scip, &xexpr, quadvars1[i], ownercreate, ownercreatedata) );
1065 	
1066 	         /* create pow expression */
1067 	         SCIP_CALL( SCIPcreateExprPow(scip, &children[i], xexpr, 2.0, ownercreate, ownercreatedata) );
1068 	
1069 	         /* release variable expression; note that the variable expression is still captured by children[i] */
1070 	         SCIP_CALL( SCIPreleaseExpr(scip, &xexpr) );
1071 	      }
1072 	      else /* bilinear term */
1073 	      {
1074 	         SCIP_EXPR* exprs[2];
1075 	
1076 	         /* create variable expressions; intentionally not using createExprVar here,
1077 	          * since expression created here is not part of a constraint (they will be copied when a constraint is created)
1078 	          */
1079 	         SCIP_CALL( SCIPcreateExprVar(scip, &exprs[0], quadvars1[i], ownercreate, ownercreatedata) );
1080 	         SCIP_CALL( SCIPcreateExprVar(scip, &exprs[1], quadvars2[i], ownercreate, ownercreatedata) );
1081 	
1082 	         /* create product expression */
1083 	         SCIP_CALL( SCIPcreateExprProduct(scip, &children[i], 2, exprs, 1.0, ownercreate, ownercreatedata) );
1084 	
1085 	         /* release variable expressions; note that the variable expressions are still captured by children[i] */
1086 	         SCIP_CALL( SCIPreleaseExpr(scip, &exprs[1]) );
1087 	         SCIP_CALL( SCIPreleaseExpr(scip, &exprs[0]) );
1088 	      }
1089 	
1090 	      /* store coefficient */
1091 	      coefs[i] = quadcoefs[i];
1092 	   }
1093 	
1094 	   /* create children for linear terms */
1095 	   for( i = 0; i < nlinvars; ++i )
1096 	   {
1097 	      assert(linvars != NULL && linvars[i] != NULL);
1098 	
1099 	      /* create variable expression; intentionally not using createExprVar here,
1100 	       * since expression created here is not part of a constraint (they will be copied when a constraint is created);
1101 	       * release variable expression after the sum expression has been created
1102 	       */
1103 	      SCIP_CALL( SCIPcreateExprVar(scip, &children[nquadterms + i], linvars[i], ownercreate, ownercreatedata) );
1104 	
1105 	      /* store coefficient */
1106 	      coefs[nquadterms + i] = lincoefs[i];
1107 	   }
1108 	
1109 	   /* create sum expression */
1110 	   SCIP_CALL( SCIPcreateExprSum(scip, expr, nquadterms + nlinvars, children, coefs, 0.0, ownercreate, ownercreatedata) );
1111 	
1112 	   /* release children */
1113 	   for( i = 0; i < nquadterms + nlinvars; ++i )
1114 	   {
1115 	      assert(children[i] != NULL);
1116 	      SCIP_CALL( SCIPreleaseExpr(scip, &children[i]) );
1117 	   }
1118 	
1119 	   /* free memory */
1120 	   SCIPfreeBufferArray(scip, &coefs);
1121 	   SCIPfreeBufferArray(scip, &children);
1122 	
1123 	   return SCIP_OKAY;
1124 	}
1125 	
1126 	/** creates and captures an expression representing a monomial
1127 	 *
1128 	 * @note In deviation from the actual definition of monomials, we also allow for negative and rational exponents.
1129 	 * So this function actually creates an expression for a signomial that has exactly one term.
1130 	 */
1131 	SCIP_RETCODE SCIPcreateExprMonomial(
1132 	   SCIP*                 scip,               /**< SCIP data structure */
1133 	   SCIP_EXPR**           expr,               /**< pointer where to store expression */
1134 	   int                   nfactors,           /**< number of factors in monomial */
1135 	   SCIP_VAR**            vars,               /**< variables in the monomial */
1136 	   SCIP_Real*            exponents,          /**< exponent in each factor, or NULL if all 1.0 */
1137 	   SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
1138 	   void*                 ownercreatedata     /**< data to pass to ownercreate */
1139 	   )
1140 	{
1141 	   assert(scip != NULL);
1142 	   assert(expr != NULL);
1143 	   assert(nfactors >= 0);
1144 	
1145 	   /* return 1 as constant expression if there are no factors */
1146 	   if( nfactors == 0 )
1147 	   {
1148 	      SCIP_CALL( SCIPcreateExprValue(scip, expr, 1.0, ownercreate, ownercreatedata) );
1149 	   }
1150 	   else if( nfactors == 1 )
1151 	   {
1152 	      /* only one factor and exponent is 1 => return factors[0] */
1153 	      if( exponents == NULL || exponents[0] == 1.0 )
1154 	      {
1155 	         /* intentionally not using createExprVar here, since expression created here is not part of
1156 	          * a constraint (they will be copied when a constraint is created)
1157 	          */
1158 	         SCIP_CALL( SCIPcreateExprVar(scip, expr, vars[0], ownercreate, ownercreatedata) );
1159 	      }
1160 	      else
1161 	      {
1162 	         SCIP_EXPR* varexpr;
1163 	
1164 	         /* create variable and power expression; intentionally not using createExprVar here,
1165 	          * since expression created here is not part of a constraint (they will be copied when a constraint is created)
1166 	          */
1167 	         SCIP_CALL( SCIPcreateExprVar(scip, &varexpr, vars[0], ownercreate, ownercreatedata) );
1168 	         SCIP_CALL( SCIPcreateExprPow(scip, expr, varexpr, exponents[0], ownercreate, ownercreatedata) );
1169 	         SCIP_CALL( SCIPreleaseExpr(scip, &varexpr) );
1170 	      }
1171 	   }
1172 	   else
1173 	   {
1174 	      SCIP_EXPR** children;
1175 	      int i;
1176 	
1177 	      /* allocate memory to store the children */
1178 	      SCIP_CALL( SCIPallocBufferArray(scip, &children, nfactors) );
1179 	
1180 	      /* create children */
1181 	      for( i = 0; i < nfactors; ++i )
1182 	      {
1183 	         /* check whether to create a power expression or not, i.e., exponent == 1 */
1184 	         if( exponents == NULL || exponents[i] == 1.0 )
1185 	         {
1186 	            SCIP_CALL( SCIPcreateExprVar(scip, &children[i], vars[i], ownercreate, ownercreatedata) );
1187 	         }
1188 	         else
1189 	         {
1190 	            SCIP_EXPR* varexpr;
1191 	
1192 	            /* create variable and pow expression */
1193 	            SCIP_CALL( SCIPcreateExprVar(scip, &varexpr, vars[i], ownercreate, ownercreatedata) );
1194 	            SCIP_CALL( SCIPcreateExprPow(scip, &children[i], varexpr, exponents[i], ownercreate, ownercreatedata) );
1195 	            SCIP_CALL( SCIPreleaseExpr(scip, &varexpr) );
1196 	         }
1197 	      }
1198 	
1199 	      /* create product expression */
1200 	      SCIP_CALL( SCIPcreateExprProduct(scip, expr, nfactors, children, 1.0, ownercreate, ownercreatedata) );
1201 	
1202 	      /* release children */
1203 	      for( i = 0; i < nfactors; ++i )
1204 	      {
1205 	         assert(children[i] != NULL);
1206 	         SCIP_CALL( SCIPreleaseExpr(scip, &children[i]) );
1207 	      }
1208 	
1209 	      /* free memory */
1210 	      SCIPfreeBufferArray(scip, &children);
1211 	   }
1212 	
1213 	   return SCIP_OKAY;
1214 	}
1215 	
1216 	/** appends child to the children list of expr
1217 	 *
1218 	 * @attention Only use if you really know what you are doing. The expression handler of the expression needs to be able to handle an increase in the number of children.
1219 	 */
1220 	SCIP_RETCODE SCIPappendExprChild(
1221 	   SCIP*                 scip,               /**< SCIP data structure */
1222 	   SCIP_EXPR*            expr,               /**< expression */
1223 	   SCIP_EXPR*            child               /**< expression to be appended */
1224 	   )
1225 	{
1226 	   assert(scip != NULL);
1227 	   assert(scip->mem != NULL);
1228 	
1229 	   SCIP_CALL( SCIPexprAppendChild(scip->set, scip->mem->probmem, expr, child) );
1230 	
1231 	   return SCIP_OKAY;
1232 	}
1233 	
1234 	/** overwrites/replaces a child of an expressions
1235 	 *
1236 	 * The old child is released and the newchild is captured, unless they are the same (=same pointer).
1237 	 */
1238 	SCIP_RETCODE SCIPreplaceExprChild(
1239 	   SCIP*                 scip,               /**< SCIP data structure */
1240 	   SCIP_EXPR*            expr,               /**< expression which is going to replace a child */
1241 	   int                   childidx,           /**< index of child being replaced */
1242 	   SCIP_EXPR*            newchild            /**< the new child */
1243 	   )
1244 	{
1245 	   assert(scip != NULL);
1246 	   assert(scip->mem != NULL);
1247 	
1248 	   SCIP_CALL( SCIPexprReplaceChild(scip->set, scip->stat, scip->mem->probmem, expr, childidx, newchild) );
1249 	
1250 	   return SCIP_OKAY;
1251 	}
1252 	
1253 	/** remove all children of expr
1254 	 *
1255 	 * @attention Only use if you really know what you are doing. The expression handler of the expression needs to be able to handle the removal of all children.
1256 	 */
1257 	SCIP_RETCODE SCIPremoveExprChildren(
1258 	   SCIP*                 scip,               /**< SCIP data structure */
1259 	   SCIP_EXPR*            expr                /**< expression */
1260 	   )
1261 	{
1262 	   assert(scip != NULL);
1263 	   assert(scip->mem != NULL);
1264 	
1265 	   SCIP_CALL( SCIPexprRemoveChildren(scip->set, scip->stat, scip->mem->probmem, expr) );
1266 	
1267 	   return SCIP_OKAY;
1268 	}
1269 	
1270 	/** duplicates the given expression and its children */
1271 	SCIP_RETCODE SCIPduplicateExpr(
1272 	   SCIP*                 scip,               /**< SCIP data structure */
1273 	   SCIP_EXPR*            expr,               /**< original expression */
1274 	   SCIP_EXPR**           copyexpr,           /**< buffer to store duplicate of expr */
1275 	   SCIP_DECL_EXPR_MAPEXPR((*mapexpr)),       /**< expression mapping function, or NULL for creating new expressions */
1276 	   void*                 mapexprdata,        /**< data of expression mapping function */
1277 	   SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call on expression copy to create ownerdata */
1278 	   void*                 ownercreatedata     /**< data to pass to ownercreate */
1279 	   )
1280 	{
1281 	   assert(scip != NULL);
1282 	   assert(scip->mem != NULL);
1283 	
1284 	   SCIP_CALL( SCIPexprCopy(scip->set, scip->stat, scip->mem->probmem, scip->set, scip->stat, scip->mem->probmem,
1285 	         expr, copyexpr, mapexpr, mapexprdata, ownercreate, ownercreatedata) );
1286 	
1287 	   return SCIP_OKAY;
1288 	}
1289 	
1290 	/** duplicates the given expression, but reuses its children */
1291 	SCIP_RETCODE SCIPduplicateExprShallow(
1292 	   SCIP*                 scip,               /**< SCIP data structure */
1293 	   SCIP_EXPR*            expr,               /**< original expression */
1294 	   SCIP_EXPR**           copyexpr,           /**< buffer to store (shallow) duplicate of expr */
1295 	   SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
1296 	   void*                 ownercreatedata     /**< data to pass to ownercreate */
1297 	   )
1298 	{
1299 	   assert(scip != NULL);
1300 	   assert(scip->mem != NULL);
1301 	
1302 	   SCIP_CALL( SCIPexprDuplicateShallow(scip->set, scip->mem->probmem, expr, copyexpr, ownercreate, ownercreatedata) );
1303 	
1304 	   return SCIP_OKAY;
1305 	}
1306 	
1307 	/** copies an expression including children to use in a (possibly different) SCIP instance */
1308 	SCIP_RETCODE SCIPcopyExpr(
1309 	   SCIP*                 sourcescip,         /**< source SCIP data structure */
1310 	   SCIP*                 targetscip,         /**< target SCIP data structure */
1311 	   SCIP_EXPR*            expr,               /**< original expression */
1312 	   SCIP_EXPR**           copyexpr,           /**< buffer to store duplicate of expr */
1313 	   SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call on expression copy to create ownerdata */
1314 	   void*                 ownercreatedata,    /**< data to pass to ownercreate */
1315 	   SCIP_HASHMAP*         varmap,             /**< a SCIP_HASHMAP mapping variables of the source SCIP to the corresponding
1316 	                                              *   variables of the target SCIP, or NULL */
1317 	   SCIP_HASHMAP*         consmap,            /**< a hashmap to store the mapping of source constraints to the corresponding
1318 	                                              *   target constraints, or NULL */
1319 	   SCIP_Bool             global,             /**< create a global or a local copy? */
1320 	   SCIP_Bool*            valid               /**< pointer to store whether all checked or enforced constraints were validly copied */
1321 	   )
1322 	{
1323 	#ifndef _MSC_VER
1324 	   COPY_MAPEXPR_DATA copydata = {
1325 	      .varmap = varmap,
1326 	      .consmap = consmap,
1327 	      .global = global,
1328 	      .valid = TRUE
1329 	   };
1330 	#else  /* MS compiler doesn't have proper C99 support... */
1331 	   COPY_MAPEXPR_DATA copydata;
1332 	   copydata.varmap = varmap;
1333 	   copydata.consmap = consmap;
1334 	   copydata.global = global;
1335 	   copydata.valid = TRUE;
1336 	#endif
1337 	
1338 	   assert(sourcescip != NULL);
1339 	   assert(sourcescip->mem != NULL);
1340 	   assert(targetscip != NULL);
1341 	   assert(targetscip->mem != NULL);
1342 	
1343 	   SCIP_CALL( SCIPexprCopy(sourcescip->set, sourcescip->stat, sourcescip->mem->probmem,
1344 	      targetscip->set, targetscip->stat, targetscip->mem->probmem,
1345 	      expr, copyexpr, copyVarExpr, &copydata, ownercreate, ownercreatedata) );
1346 	
1347 	   *valid = copydata.valid;
1348 	
1349 	   return SCIP_OKAY;
1350 	}
1351 	
1352 	/** creates an expression from a string
1353 	 *
1354 	 * We specify the grammar that defines the syntax of an expression.
1355 	 * Loosely speaking, a `Base` will be any "block", a `Factor` is a `Base` to a power,
1356 	 * a `Term` is a product of `Factors` and an `Expression` is a sum of `Terms`.
1357 	 *
1358 	 * The actual definition:
1359 	 * <pre>
1360 	 * Expression -> ["+" | "-"] Term { ("+" | "-" | "number *") ] Term }
1361 	 * Term       -> Factor { ("*" | "/" ) Factor }
1362 	 * Factor     -> Base [ "^" "number" | "^(" "number" ")" ]
1363 	 * Base       -> "number" | "<varname>" | "(" Expression ")" | Op "(" OpExpression ")
1364 	 * </pre>
1365 	 * where `[a|b]` means `a` or `b` or none, `(a|b)` means `a` or `b`, `{a}` means 0 or more `a`.
1366 	 *
1367 	 * Note that `Op` and `OpExpression` are undefined.
1368 	 * `Op` corresponds to the name of an expression handler and `OpExpression` to whatever string the expression handler accepts (through its parse method).
1369 	 */
1370 	SCIP_RETCODE SCIPparseExpr(
1371 	   SCIP*                 scip,               /**< SCIP data structure */
1372 	   SCIP_EXPR**           expr,               /**< pointer to store the expr parsed */
1373 	   const char*           exprstr,            /**< string with the expr to parse */
1374 	   const char**          finalpos,           /**< buffer to store the position of exprstr where we finished reading, or NULL if not of interest */
1375 	   SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
1376 	   void*                 ownercreatedata     /**< data to pass to ownercreate */
1377 	   )
1378 	{
1379 	   const char* finalpos_;
1380 	   SCIP_RETCODE retcode;
1381 	   SCIP_HASHMAP* vartoexprvarmap;
1382 	
1383 	   assert(scip != NULL);
1384 	
1385 	   SCIP_CALL( SCIPhashmapCreate(&vartoexprvarmap, SCIPblkmem(scip), 5 * SCIPgetNVars(scip)) );
1386 	
1387 	   /* if parseExpr fails, we still want to free hashmap */
1388 	   retcode = parseExpr(scip, vartoexprvarmap, exprstr, &finalpos_, expr, ownercreate, ownercreatedata);
1389 	
1390 	   SCIPhashmapFree(&vartoexprvarmap);
1391 	
1392 	   if( finalpos != NULL )
1393 	      *finalpos = finalpos_;
1394 	
1395 	   return retcode;
1396 	}
1397 	
1398 	/** captures an expression (increments usage count) */
1399 	void SCIPcaptureExpr(
1400 	   SCIP_EXPR*            expr                /**< expression to be captured */
1401 	   )
1402 	{
1403 	   SCIPexprCapture(expr);
1404 	}
1405 	
1406 	/** releases an expression (decrements usage count and possibly frees expression) */
1407 	SCIP_RETCODE SCIPreleaseExpr(
1408 	   SCIP*                 scip,               /**< SCIP data structure */
1409 	   SCIP_EXPR**           expr                /**< pointer to expression to be released */
1410 	   )
1411 	{
1412 	   assert(scip != NULL);
1413 	   assert(scip->mem != NULL);
1414 	
1415 	   SCIP_CALL( SCIPexprRelease(scip->set, scip->stat, scip->mem->probmem, expr) );
1416 	
1417 	   return SCIP_OKAY;
1418 	}
1419 	
1420 	/** returns whether an expression is a variable expression */
1421 	SCIP_Bool SCIPisExprVar(
1422 	   SCIP*                 scip,               /**< SCIP data structure */
1423 	   SCIP_EXPR*            expr                /**< expression */
1424 	   )
1425 	{
1426 	   assert(scip != NULL);
1427 	
1428 	   return SCIPexprIsVar(scip->set, expr);
1429 	}
1430 	
1431 	/** returns whether an expression is a value expression */
1432 	SCIP_Bool SCIPisExprValue(
1433 	   SCIP*                 scip,               /**< SCIP data structure */
1434 	   SCIP_EXPR*            expr                /**< expression */
1435 	   )
1436 	{
1437 	   assert(scip != NULL);
1438 	
1439 	   return SCIPexprIsValue(scip->set, expr);
1440 	}
1441 	
1442 	/** returns whether an expression is a sum expression */
1443 	SCIP_Bool SCIPisExprSum(
1444 	   SCIP*                 scip,               /**< SCIP data structure */
1445 	   SCIP_EXPR*            expr                /**< expression */
1446 	   )
1447 	{
1448 	   assert(scip != NULL);
1449 	
1450 	   return SCIPexprIsSum(scip->set, expr);
1451 	}
1452 	
1453 	/** returns whether an expression is a product expression */
1454 	SCIP_Bool SCIPisExprProduct(
1455 	   SCIP*                 scip,               /**< SCIP data structure */
1456 	   SCIP_EXPR*            expr                /**< expression */
1457 	   )
1458 	{
1459 	   assert(scip != NULL);
1460 	
1461 	   return SCIPexprIsProduct(scip->set, expr);
1462 	}
1463 	
1464 	/** returns whether an expression is a power expression */
1465 	SCIP_Bool SCIPisExprPower(
1466 	   SCIP*                 scip,               /**< SCIP data structure */
1467 	   SCIP_EXPR*            expr                /**< expression */
1468 	   )
1469 	{
1470 	   assert(scip != NULL);
1471 	
1472 	   return SCIPexprIsPower(scip->set, expr);
1473 	}
1474 	
1475 	/** print an expression as info-message */
1476 	SCIP_RETCODE SCIPprintExpr(
1477 	   SCIP*                 scip,               /**< SCIP data structure */
1478 	   SCIP_EXPR*            expr,               /**< expression to be printed */
1479 	   FILE*                 file                /**< file to print to, or NULL for stdout */
1480 	   )
1481 	{
1482 	   assert(scip != NULL);
1483 	   assert(scip->mem != NULL);
1484 	
1485 	   SCIP_CALL( SCIPexprPrint(scip->set, scip->stat, scip->mem->probmem, scip->messagehdlr, file, expr) );
1486 	
1487 	   return SCIP_OKAY;
1488 	}
1489 	
1490 	/** initializes printing of expressions in dot format to a give FILE* pointer */
1491 	SCIP_RETCODE SCIPprintExprDotInit(
1492 	   SCIP*                 scip,               /**< SCIP data structure */
1493 	   SCIP_EXPRPRINTDATA**  printdata,          /**< buffer to store dot printing data */
(1) Event noescape: "SCIPprintExprDotInit(SCIP *, SCIP_EXPRPRINTDATA **, FILE *, SCIP_EXPRPRINT_WHAT)" does not free or save its parameter "file".
1494 	   FILE*                 file,               /**< file to print to, or NULL for stdout */
1495 	   SCIP_EXPRPRINT_WHAT   whattoprint         /**< info on what to print for each expression */
1496 	   )
1497 	{
1498 	   assert(scip != NULL);
1499 	   assert(scip->mem != NULL);
1500 	
1501 	   SCIP_CALL( SCIPexprPrintDotInit(scip->set, scip->stat, scip->mem->probmem, printdata, file, whattoprint) );
1502 	
1503 	   return SCIP_OKAY;
1504 	}
1505 	
1506 	/** initializes printing of expressions in dot format to a file with given filename */
1507 	SCIP_RETCODE SCIPprintExprDotInit2(
1508 	   SCIP*                 scip,               /**< SCIP data structure */
1509 	   SCIP_EXPRPRINTDATA**  printdata,          /**< buffer to store dot printing data */
1510 	   const char*           filename,           /**< name of file to print to */
1511 	   SCIP_EXPRPRINT_WHAT   whattoprint         /**< info on what to print for each expression */
1512 	   )
1513 	{
1514 	   assert(scip != NULL);
1515 	   assert(scip->mem != NULL);
1516 	
1517 	   SCIP_CALL( SCIPexprPrintDotInit2(scip->set, scip->stat, scip->mem->probmem, printdata, filename, whattoprint) );
1518 	
1519 	   return SCIP_OKAY;
1520 	}
1521 	
1522 	/** main part of printing an expression in dot format */
1523 	SCIP_RETCODE SCIPprintExprDot(
1524 	   SCIP*                 scip,               /**< SCIP data structure */
1525 	   SCIP_EXPRPRINTDATA*   printdata,          /**< data as initialized by \ref SCIPprintExprDotInit() */
1526 	   SCIP_EXPR*            expr                /**< expression to be printed */
1527 	   )
1528 	{
1529 	   assert(scip != NULL);
1530 	
1531 	   SCIP_CALL( SCIPexprPrintDot(scip->set, scip->messagehdlr, printdata, expr) );
1532 	
1533 	   return SCIP_OKAY;
1534 	}
1535 	
1536 	/** finishes printing of expressions in dot format */
1537 	SCIP_RETCODE SCIPprintExprDotFinal(
1538 	   SCIP*                 scip,               /**< SCIP data structure */
1539 	   SCIP_EXPRPRINTDATA**  printdata           /**< buffer where dot printing data has been stored */
1540 	   )
1541 	{
1542 	   assert(scip != NULL);
1543 	   assert(scip->mem != NULL);
1544 	
1545 	   SCIP_CALL( SCIPexprPrintDotFinal(scip->set, scip->stat, scip->mem->probmem, printdata) );
1546 	
1547 	   return SCIP_OKAY;
1548 	}
1549 	
1550 	/** shows a single expression by use of dot and gv
1551 	 *
1552 	 * This function is meant for debugging purposes.
1553 	 * It's signature is kept as simple as possible to make it
1554 	 * easily callable from gdb, for example.
1555 	 *
1556 	 * It prints the expression into a temporary file in dot format, then calls dot to create a postscript file,
1557 	 * then calls ghostview (gv) to show the file. SCIP will hold until ghostscript is closed.
1558 	 */
1559 	SCIP_RETCODE SCIPshowExpr(
1560 	   SCIP*                 scip,               /**< SCIP data structure */
1561 	   SCIP_EXPR*            expr                /**< expression to be printed */
1562 	   )
1563 	{
1564 	   /* this function is for developers, so don't bother with C variants that don't have popen() */
1565 	#if _POSIX_C_SOURCE < 2
1566 	   SCIPerrorMessage("No POSIX version 2. Try http://distrowatch.com/.");
1567 	   return SCIP_ERROR;
1568 	#else
1569 	   SCIP_EXPRPRINTDATA* dotdata;
1570 	   FILE* f;
1571 	
1572 	   assert(scip != NULL);
1573 	   assert(expr != NULL);
1574 	
1575 	   /* call dot to generate postscript output and show it via ghostview */
(1) Event alloc_fn: Storage is returned from allocation function "popen".
(2) Event var_assign: Assigning: "f" = storage returned from "popen("dot -Tps | gv --media=a3 -", "w")".
Also see events: [noescape][leaked_storage]
1576 	   f = popen("dot -Tps | gv --media=a3 -", "w");
(3) Event cond_false: Condition "f == NULL", taking false branch.
1577 	   if( f == NULL )
1578 	   {
1579 	      SCIPerrorMessage("Calling popen() failed");
1580 	      return SCIP_FILECREATEERROR;
(4) Event if_end: End of if statement.
1581 	   }
1582 	
1583 	   /* print all of the expression into the pipe */
(5) Event noescape: Resource "f" is not freed or pointed-to in "SCIPprintExprDotInit". [details]
(6) Event cond_true: Condition "(_restat_ = SCIPprintExprDotInit(scip, &dotdata, f, 255U /* ((((1U | 2U) | 4U) | 0x18U) | 0x60U) | 0x80U */)) != SCIP_OKAY", taking true branch.
(7) Event leaked_storage: Variable "f" going out of scope leaks the storage it points to.
Also see events: [alloc_fn][var_assign]
1584 	   SCIP_CALL( SCIPprintExprDotInit(scip, &dotdata, f, SCIP_EXPRPRINT_ALL) );
1585 	   SCIP_CALL( SCIPprintExprDot(scip, dotdata, expr) );
1586 	   SCIP_CALL( SCIPprintExprDotFinal(scip, &dotdata) );
1587 	
1588 	   /* close the pipe */
1589 	   (void) pclose(f);
1590 	
1591 	   return SCIP_OKAY;
1592 	#endif
1593 	}
1594 	
1595 	/** prints structure of an expression a la Maple's dismantle */
1596 	SCIP_RETCODE SCIPdismantleExpr(
1597 	   SCIP*                 scip,               /**< SCIP data structure */
1598 	   FILE*                 file,               /**< file to print to, or NULL for stdout */
1599 	   SCIP_EXPR*            expr                /**< expression to dismantle */
1600 	   )
1601 	{
1602 	   assert(scip != NULL);
1603 	   assert(scip->mem != NULL);
1604 	
1605 	   SCIP_CALL( SCIPexprDismantle(scip->set, scip->stat, scip->mem->probmem, scip->messagehdlr, file, expr) );
1606 	
1607 	   return SCIP_OKAY;
1608 	}
1609 	
1610 	/** evaluate an expression in a point
1611 	 *
1612 	 * Iterates over expressions to also evaluate children, if necessary.
1613 	 * Value can be received via SCIPexprGetEvalValue().
1614 	 * If an evaluation error (division by zero, ...) occurs, this value will
1615 	 * be set to SCIP_INVALID.
1616 	 *
1617 	 * If a nonzero \p soltag is passed, then only (sub)expressions are
1618 	 * reevaluated that have a different solution tag. If a soltag of 0
1619 	 * is passed, then subexpressions are always reevaluated.
1620 	 * The tag is stored together with the value and can be received via
1621 	 * SCIPexprGetEvalTag().
1622 	 */
1623 	SCIP_RETCODE SCIPevalExpr(
1624 	   SCIP*                 scip,               /**< SCIP data structure */
1625 	   SCIP_EXPR*            expr,               /**< expression to be evaluated */
1626 	   SCIP_SOL*             sol,                /**< solution to be evaluated */
1627 	   SCIP_Longint          soltag              /**< tag that uniquely identifies the solution (with its values), or 0. */
1628 	   )
1629 	{
1630 	   assert(scip != NULL);
1631 	   assert(scip->mem != NULL);
1632 	
1633 	   SCIP_CALL( SCIPexprEval(scip->set, scip->stat, scip->mem->probmem, expr, sol, soltag) );
1634 	
1635 	   return SCIP_OKAY;
1636 	}
1637 	
1638 	/** returns a previously unused solution tag for expression evaluation */
1639 	SCIP_EXPORT
1640 	SCIP_Longint SCIPgetExprNewSoltag(
1641 	   SCIP*                 scip                /**< SCIP data structure */
1642 	   )
1643 	{
1644 	   assert(scip != NULL);
1645 	
1646 	   return ++(scip->stat->exprlastsoltag);
1647 	}
1648 	
1649 	/** evaluates gradient of an expression for a given point
1650 	 *
1651 	 * Initiates an expression walk to also evaluate children, if necessary.
1652 	 * Value can be received via SCIPgetExprPartialDiffNonlinear().
1653 	 * If an error (division by zero, ...) occurs, this value will
1654 	 * be set to SCIP_INVALID.
1655 	 */
1656 	SCIP_RETCODE SCIPevalExprGradient(
1657 	   SCIP*                 scip,               /**< SCIP data structure */
1658 	   SCIP_EXPR*            expr,               /**< expression to be differentiated */
1659 	   SCIP_SOL*             sol,                /**< solution to be evaluated (NULL for the current LP solution) */
1660 	   SCIP_Longint          soltag              /**< tag that uniquely identifies the solution (with its values), or 0. */
1661 	   )
1662 	{
1663 	   assert(scip != NULL);
1664 	   assert(scip->mem != NULL);
1665 	
1666 	   SCIP_CALL( SCIPexprEvalGradient(scip->set, scip->stat, scip->mem->probmem, expr, sol, soltag) );
1667 	
1668 	   return SCIP_OKAY;
1669 	}
1670 	
1671 	/** evaluates Hessian-vector product of an expression for a given point and direction
1672 	 *
1673 	 * Evaluates children, if necessary.
1674 	 * Value can be received via SCIPgetExprPartialDiffGradientDirNonlinear().
1675 	 * If an error (division by zero, ...) occurs, this value will
1676 	 * be set to SCIP_INVALID.
1677 	 */
1678 	SCIP_RETCODE SCIPevalExprHessianDir(
1679 	   SCIP*                 scip,               /**< SCIP data structure */
1680 	   SCIP_EXPR*            expr,               /**< expression to be differentiated */
1681 	   SCIP_SOL*             sol,                /**< solution to be evaluated (NULL for the current LP solution) */
1682 	   SCIP_Longint          soltag,             /**< tag that uniquely identifies the solution (with its values), or 0. */
1683 	   SCIP_SOL*             direction           /**< direction */
1684 	   )
1685 	{
1686 	   assert(scip != NULL);
1687 	   assert(scip->mem != NULL);
1688 	
1689 	   SCIP_CALL( SCIPexprEvalHessianDir(scip->set, scip->stat, scip->mem->probmem, expr, sol, soltag, direction) );
1690 	
1691 	   return SCIP_OKAY;
1692 	}
1693 	
1694 	/** possibly reevaluates and then returns the activity of the expression
1695 	 *
1696 	 * Reevaluate activity if currently stored is no longer uptodate (some bound was changed since last evaluation).
1697 	 *
1698 	 * The owner of the expression may overwrite the methods used to evaluate the activity,
1699 	 * including whether the local or global domain of variables is used.
1700 	 * By default (no owner, or owner doesn't overwrite activity evaluation),
1701 	 * the local domain of variables is used.
1702 	 *
1703 	 * @note If expression is set to be integral, then activities are tightened to integral values.
1704 	 *   Thus, ensure that the integrality information is valid (if set to TRUE; the default (FALSE) is always ok).
1705 	 */
1706 	SCIP_RETCODE SCIPevalExprActivity(
1707 	   SCIP*                 scip,               /**< SCIP data structure */
1708 	   SCIP_EXPR*            expr                /**< expression */
1709 	   )
1710 	{
1711 	   assert(scip != NULL);
1712 	   assert(scip->mem != NULL);
1713 	
1714 	   SCIP_CALL( SCIPexprEvalActivity(scip->set, scip->stat, scip->mem->probmem, expr) );
1715 	
1716 	   return SCIP_OKAY;
1717 	}
1718 	
1719 	/** compare expressions
1720 	 * @return -1, 0 or 1 if expr1 <, =, > expr2, respectively
1721 	 * @note The given expressions are assumed to be simplified.
1722 	 */
1723 	int SCIPcompareExpr(
1724 	   SCIP*                 scip,               /**< SCIP data structure */
1725 	   SCIP_EXPR*            expr1,              /**< first expression */
1726 	   SCIP_EXPR*            expr2               /**< second expression */
1727 	   )
1728 	{
1729 	   assert(scip != NULL);
1730 	
1731 	   return SCIPexprCompare(scip->set, expr1, expr2);
1732 	}
1733 	
1734 	/** compute the hash value of an expression */
1735 	SCIP_RETCODE SCIPhashExpr(
1736 	   SCIP*                 scip,               /**< SCIP data structure */
1737 	   SCIP_EXPR*            expr,               /**< expression */
1738 	   unsigned int*         hashval             /**< pointer to store the hash value */
1739 	   )
1740 	{
1741 	   SCIP_EXPRITER* it;
1742 	
1743 	   assert(scip != NULL);
1744 	   assert(scip->mem != NULL);
1745 	   assert(expr != NULL);
1746 	   assert(hashval != NULL);
1747 	
1748 	   SCIP_CALL( SCIPexpriterCreate(scip->stat, scip->mem->probmem, &it) );
1749 	   SCIP_CALL( SCIPexpriterInit(it, expr, SCIP_EXPRITER_DFS, FALSE) );
1750 	   SCIPexpriterSetStagesDFS(it, SCIP_EXPRITER_LEAVEEXPR);
1751 	
1752 	   SCIP_CALL( hashExpr(scip->set, scip->mem->buffer, expr, it, NULL) );
1753 	
1754 	   *hashval = SCIPexpriterGetExprUserData(it, expr).uintval;
1755 	
1756 	   SCIPexpriterFree(&it);
1757 	
1758 	   return SCIP_OKAY;
1759 	}
1760 	
1761 	/* simplifies an expression (duplication of long doxygen comment omitted here) */
1762 	SCIP_RETCODE SCIPsimplifyExpr(
1763 	   SCIP*                 scip,               /**< SCIP data structure */
1764 	   SCIP_EXPR*            rootexpr,           /**< expression to be simplified */
1765 	   SCIP_EXPR**           simplified,         /**< buffer to store simplified expression */
1766 	   SCIP_Bool*            changed,            /**< buffer to store if rootexpr actually changed */
1767 	   SCIP_Bool*            infeasible,         /**< buffer to store whether infeasibility has been detected */
1768 	   SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
1769 	   void*                 ownercreatedata     /**< data to pass to ownercreate */
1770 	   )
1771 	{
1772 	   assert(scip != NULL);
1773 	   assert(scip->mem != NULL);
1774 	
1775 	   SCIP_CALL( SCIPexprSimplify(scip->set, scip->stat, scip->mem->probmem, rootexpr, simplified, changed, infeasible, ownercreate, ownercreatedata) );
1776 	
1777 	   return SCIP_OKAY;
1778 	}
1779 	
1780 	/** replaces common sub-expressions in a given expression graph by using a hash key for each expression
1781 	 *
1782 	 *  The algorithm consists of two steps:
1783 	 *
1784 	 *  1. traverse through all given expressions and compute for each of them a (not necessarily unique) hash
1785 	 *
1786 	 *  2. initialize an empty hash table and traverse through all expression; check for each of them if we can find a
1787 	 *     structural equivalent expression in the hash table; if yes we replace the expression by the expression inside the
1788 	 *     hash table, otherwise we add it to the hash table
1789 	 *
1790 	 *  @note the hash keys of the expressions are used for the hashing inside the hash table; to compute if two expressions
1791 	 *  (with the same hash) are structurally the same we use the function SCIPexprCompare().
1792 	 */
1793 	SCIP_RETCODE SCIPreplaceCommonSubexpressions(
1794 	   SCIP*                 scip,               /**< SCIP data structure */
1795 	   SCIP_EXPR**           exprs,              /**< expressions (possibly replaced by equivalent on output) */
1796 	   int                   nexprs,             /**< total number of expressions */
1797 	   SCIP_Bool*            replacedroot        /**< buffer to store whether any root expression (expression in exprs) was replaced */
1798 	   )
1799 	{
1800 	   COMMONSUBEXPR_HASH_DATA hashdata;
1801 	   SCIP_EXPRITER* hashiterator;
1802 	   SCIP_EXPRITER* repliterator;
1803 	   SCIP_MULTIHASH* key2expr;
1804 	   int i;
1805 	   int nvisitedexprs = 0;
1806 	
1807 	   assert(scip != NULL);
1808 	   assert(scip->mem != NULL);
1809 	   assert(exprs != NULL);
1810 	   assert(nexprs >= 0);
1811 	   assert(replacedroot != NULL);
1812 	
1813 	   *replacedroot = FALSE;
1814 	
1815 	   if( nexprs == 0 )
1816 	      return SCIP_OKAY;
1817 	
1818 	   SCIP_CALL( SCIPcreateExpriter(scip, &hashiterator) );
1819 	   SCIP_CALL( SCIPexpriterInit(hashiterator, NULL, SCIP_EXPRITER_DFS, FALSE) );
1820 	   SCIPexpriterSetStagesDFS(hashiterator, SCIP_EXPRITER_LEAVEEXPR);
1821 	
1822 	   /* compute all hashes for each sub-expression */
1823 	   for( i = 0; i < nexprs; ++i )
1824 	   {
1825 	      assert(exprs[i] != NULL);
1826 	      SCIP_CALL( hashExpr(scip->set, scip->mem->buffer, exprs[i], hashiterator, &nvisitedexprs) );
1827 	   }
1828 	
1829 	   /* replace equivalent sub-expressions */
1830 	   hashdata.hashiterator = hashiterator;
1831 	   hashdata.set = scip->set;
1832 	   SCIP_CALL( SCIPmultihashCreate(&key2expr, scip->mem->probmem, nvisitedexprs,
1833 	         hashCommonSubexprGetKey, hashCommonSubexprEq, hashCommonSubexprKeyval, (void*)&hashdata) );
1834 	
1835 	   SCIP_CALL( SCIPcreateExpriter(scip, &repliterator) );
1836 	
1837 	   for( i = 0; i < nexprs; ++i )
1838 	   {
1839 	      SCIP_EXPR* newroot;
1840 	      SCIP_EXPR* newchild;
1841 	      SCIP_EXPR* child;
1842 	
1843 	      /* check the root for equivalence separately first */
1844 	      SCIP_CALL( findEqualExpr(scip->set, exprs[i], key2expr, &newroot) );
1845 	
1846 	      if( newroot != NULL )
1847 	      {
1848 	         assert(newroot != exprs[i]);
1849 	         assert(SCIPexprCompare(scip->set, exprs[i], newroot) == 0);
1850 	
1851 	         SCIPdebugMsg(scip, "replacing common root expression of %dth expr: %p -> %p\n", i, (void*)exprs[i], (void*)newroot);
1852 	
1853 	         SCIP_CALL( SCIPreleaseExpr(scip, &exprs[i]) );
1854 	
1855 	         exprs[i] = newroot;
1856 	         SCIPexprCapture(newroot);
1857 	
1858 	         *replacedroot = TRUE;
1859 	
1860 	         continue;
1861 	      }
1862 	
1863 	      /* replace equivalent sub-expressions in the tree */
1864 	      SCIP_CALL( SCIPexpriterInit(repliterator, exprs[i], SCIP_EXPRITER_DFS, FALSE) );
1865 	      SCIPexpriterSetStagesDFS(repliterator, SCIP_EXPRITER_VISITINGCHILD);
1866 	
1867 	      while( !SCIPexpriterIsEnd(repliterator) )
1868 	      {
1869 	         child = SCIPexpriterGetChildExprDFS(repliterator);
1870 	         assert(child != NULL);
1871 	
1872 	         /* try to find an equivalent expression */
1873 	         SCIP_CALL( findEqualExpr(scip->set, child, key2expr, &newchild) );
1874 	
1875 	         /* replace child with newchild */
1876 	         if( newchild != NULL )
1877 	         {
1878 	            assert(child != newchild);
1879 	            assert(SCIPexprCompare(scip->set, child, newchild) == 0);
1880 	
1881 	            SCIPdebugMsg(scip, "replacing common child expression %p -> %p\n", (void*)child, (void*)newchild);
1882 	
1883 	            SCIP_CALL( SCIPreplaceExprChild(scip, SCIPexpriterGetCurrent(repliterator), SCIPexpriterGetChildIdxDFS(repliterator), newchild) );
1884 	
1885 	            (void) SCIPexpriterSkipDFS(repliterator);
1886 	         }
1887 	         else
1888 	         {
1889 	            (void) SCIPexpriterGetNext(repliterator);
1890 	         }
1891 	      }
1892 	   }
1893 	
1894 	   /* free memory */
1895 	   SCIPexpriterFree(&repliterator);
1896 	   SCIPmultihashFree(&key2expr);
1897 	   SCIPexpriterFree(&hashiterator);
1898 	
1899 	   return SCIP_OKAY;
1900 	}
1901 	
1902 	/** computes the curvature of a given expression and all its subexpressions
1903 	 *
1904 	 *  @note this function also evaluates all subexpressions w.r.t. current variable bounds
1905 	 *  @note this function relies on information from the curvature callback of expression handlers only,
1906 	 *    consider using function @ref SCIPhasExprCurvature() of the convex-nlhdlr instead, as that uses more information to deduce convexity
1907 	 */
1908 	SCIP_RETCODE SCIPcomputeExprCurvature(
1909 	   SCIP*                 scip,               /**< SCIP data structure */
1910 	   SCIP_EXPR*            expr                /**< expression */
1911 	   )
1912 	{
1913 	   SCIP_EXPRITER* it;
1914 	   SCIP_EXPRCURV curv;
1915 	   SCIP_EXPRCURV* childcurv;
1916 	   int childcurvsize;
1917 	   SCIP_Bool success;
1918 	   SCIP_EXPRCURV trialcurv[3] = { SCIP_EXPRCURV_LINEAR, SCIP_EXPRCURV_CONVEX, SCIP_EXPRCURV_CONCAVE };
1919 	   int i, c;
1920 	
1921 	   assert(scip != NULL);
1922 	   assert(scip->mem != NULL);
1923 	   assert(expr != NULL);
1924 	
1925 	   childcurvsize = 5;
1926 	   SCIP_CALL( SCIPallocBufferArray(scip, &childcurv, childcurvsize) );
1927 	
1928 	   SCIP_CALL( SCIPexpriterCreate(scip->stat, scip->mem->probmem, &it) );
1929 	   SCIP_CALL( SCIPexpriterInit(it, expr, SCIP_EXPRITER_DFS, FALSE) );
1930 	   SCIPexpriterSetStagesDFS(it, SCIP_EXPRITER_LEAVEEXPR);
1931 	
1932 	   for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
1933 	   {
1934 	      curv = SCIP_EXPRCURV_UNKNOWN;
1935 	
1936 	      if( !SCIPexprhdlrHasCurvature(SCIPexprGetHdlr(expr)) )
1937 	      {
1938 	         /* set curvature in expression */
1939 	         SCIPexprSetCurvature(expr, curv);
1940 	         continue;
1941 	      }
1942 	
1943 	      if( SCIPexprGetNChildren(expr) > childcurvsize )
1944 	      {
1945 	         childcurvsize = SCIPcalcMemGrowSize(scip, SCIPexprGetNChildren(expr));
1946 	         SCIP_CALL( SCIPreallocBufferArray(scip, &childcurv, childcurvsize) );
1947 	      }
1948 	
1949 	      for( i = 0; i < 3; ++i )
1950 	      {
1951 	         /* check if expression can have a curvature trialcurv[i] */
1952 	         SCIP_CALL( SCIPexprhdlrCurvatureExpr(SCIPexprGetHdlr(expr), scip->set, expr, trialcurv[i], &success, childcurv) );
1953 	         if( !success )
1954 	            continue;
1955 	
1956 	         /* check if conditions on children are satisfied */
1957 	         for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
1958 	         {
1959 	            if( (childcurv[c] & SCIPexprGetCurvature(SCIPexprGetChildren(expr)[c])) != childcurv[c] )
1960 	            {
1961 	               success = FALSE;
1962 	               break;
1963 	            }
1964 	         }
1965 	
1966 	         if( success )
1967 	         {
1968 	            curv = trialcurv[i];
1969 	            break;
1970 	         }
1971 	      }
1972 	
1973 	      /* set curvature in expression */
1974 	      SCIPexprSetCurvature(expr, curv);
1975 	   }
1976 	
1977 	   SCIPexpriterFree(&it);
1978 	
1979 	   SCIPfreeBufferArray(scip, &childcurv);
1980 	
1981 	   return SCIP_OKAY;
1982 	}
1983 	
1984 	/** computes integrality information of a given expression and all its subexpressions
1985 	 *
1986 	 * The integrality information can be accessed via SCIPexprIsIntegral().
1987 	 */
1988 	SCIP_RETCODE SCIPcomputeExprIntegrality(
1989 	   SCIP*                 scip,               /**< SCIP data structure */
1990 	   SCIP_EXPR*            expr                /**< expression */
1991 	   )
1992 	{
1993 	   SCIP_EXPRITER* it;
1994 	   SCIP_Bool isintegral;
1995 	
1996 	   assert(scip != NULL);
1997 	   assert(scip->mem != NULL);
1998 	   assert(expr != NULL);
1999 	
2000 	   /* shortcut for expr without children */
2001 	   if( SCIPexprGetNChildren(expr) == 0 )
2002 	   {
2003 	      /* compute integrality information */
2004 	      SCIP_CALL( SCIPexprhdlrIntegralityExpr(SCIPexprGetHdlr(expr), scip->set, expr, &isintegral) );
2005 	      SCIPexprSetIntegrality(expr, isintegral);
2006 	
2007 	      return SCIP_OKAY;
2008 	   }
2009 	
2010 	   SCIP_CALL( SCIPexpriterCreate(scip->stat, scip->mem->probmem, &it) );
2011 	   SCIP_CALL( SCIPexpriterInit(it, expr, SCIP_EXPRITER_DFS, FALSE) );
2012 	   SCIPexpriterSetStagesDFS(it, SCIP_EXPRITER_LEAVEEXPR);
2013 	
2014 	   for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
2015 	   {
2016 	      /* compute integrality information */
2017 	      SCIP_CALL( SCIPexprhdlrIntegralityExpr(SCIPexprGetHdlr(expr), scip->set, expr, &isintegral) );
2018 	      SCIPexprSetIntegrality(expr, isintegral);
2019 	   }
2020 	
2021 	   SCIPexpriterFree(&it);
2022 	
2023 	   return SCIP_OKAY;
2024 	}
2025 	
2026 	/** returns the total number of variable expressions in an expression
2027 	 *
2028 	 * The function counts variable expressions in common sub-expressions only once, but
2029 	 * counts variables appearing in several variable expressions multiple times.
2030 	 */
2031 	SCIP_RETCODE SCIPgetExprNVars(
2032 	   SCIP*                 scip,               /**< SCIP data structure */
2033 	   SCIP_EXPR*            expr,               /**< expression */
2034 	   int*                  nvars               /**< buffer to store the total number of variables */
2035 	   )
2036 	{
2037 	   SCIP_EXPRITER* it;
2038 	
2039 	   assert(scip != NULL);
2040 	   assert(scip->mem != NULL);
2041 	   assert(expr != NULL);
2042 	   assert(nvars != NULL);
2043 	
2044 	   SCIP_CALL( SCIPexpriterCreate(scip->stat, scip->mem->probmem, &it) );
2045 	   SCIP_CALL( SCIPexpriterInit(it, expr, SCIP_EXPRITER_DFS, FALSE) );
2046 	
2047 	   *nvars = 0;
2048 	   for( ; !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
2049 	      if( SCIPexprIsVar(scip->set, expr) )
2050 	         ++(*nvars);
2051 	
2052 	   SCIPexpriterFree(&it);
2053 	
2054 	   return SCIP_OKAY;
2055 	}
2056 	
2057 	/** returns all variable expressions contained in a given expression
2058 	 *
2059 	 * The array to store all variable expressions needs to be at least of size
2060 	 * the number of unique variable expressions in the expression which is given by SCIPgetExprNVars().
2061 	 *
2062 	 * If every variable is represented by only one variable expression (common subexpression have been removed)
2063 	 * then SCIPgetExprNVars() can be bounded by SCIPgetNTotalVars().
2064 	 * If, in addition, non-active variables have been removed from the expression, e.g., by simplifying,
2065 	 * then SCIPgetExprNVars() can be bounded by SCIPgetNVars().
2066 	 *
2067 	 * @note function captures variable expressions
2068 	 */
2069 	SCIP_RETCODE SCIPgetExprVarExprs(
2070 	   SCIP*                 scip,               /**< SCIP data structure */
2071 	   SCIP_EXPR*            expr,               /**< expression */
2072 	   SCIP_EXPR**           varexprs,           /**< array to store all variable expressions */
2073 	   int*                  nvarexprs           /**< buffer to store the total number of variable expressions */
2074 	   )
2075 	{
2076 	   SCIP_EXPRITER* it;
2077 	
2078 	   assert(scip != NULL);
2079 	   assert(scip->mem != NULL);
2080 	   assert(expr != NULL);
2081 	   assert(varexprs != NULL);
2082 	   assert(nvarexprs != NULL);
2083 	
2084 	   SCIP_CALL( SCIPexpriterCreate(scip->stat, scip->mem->probmem, &it) );
2085 	   SCIP_CALL( SCIPexpriterInit(it, expr, SCIP_EXPRITER_DFS, FALSE) );
2086 	
2087 	   *nvarexprs = 0;
2088 	   for( ; !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
2089 	   {
2090 	      assert(expr != NULL);
2091 	
2092 	      if( SCIPexprIsVar(scip->set, expr) )
2093 	      {
2094 	         varexprs[(*nvarexprs)++] = expr;
2095 	
2096 	         /* capture expression */
2097 	         SCIPcaptureExpr(expr);
2098 	      }
2099 	   }
2100 	
2101 	   /* @todo sort variable expressions here? */
2102 	
2103 	   SCIPexpriterFree(&it);
2104 	
2105 	   return SCIP_OKAY;
2106 	}
2107 	
2108 	/** calls the print callback for an expression
2109 	 *
2110 	 * @see SCIP_DECL_EXPRPRINT
2111 	 */
2112 	SCIP_EXPORT
2113 	SCIP_DECL_EXPRPRINT(SCIPcallExprPrint)
2114 	{
2115 	   assert(scip != NULL);
2116 	
2117 	   SCIP_CALL( SCIPexprhdlrPrintExpr(SCIPexprGetHdlr(expr), scip->set, scip->messagehdlr, expr, stage, currentchild, parentprecedence, file) );
2118 	
2119 	   return SCIP_OKAY;
2120 	}
2121 	
2122 	/** calls the curvature callback for an expression
2123 	 *
2124 	 * @see SCIP_DECL_EXPRCURVATURE
2125 	 *
2126 	 * Returns unknown curvature if callback not implemented.
2127 	 */
2128 	SCIP_EXPORT
2129 	SCIP_DECL_EXPRCURVATURE(SCIPcallExprCurvature)
2130 	{
2131 	   assert(scip != NULL);
2132 	
2133 	   SCIP_CALL( SCIPexprhdlrCurvatureExpr(SCIPexprGetHdlr(expr), scip->set, expr, exprcurvature, success, childcurv) );
2134 	
2135 	   return SCIP_OKAY;
2136 	}
2137 	
2138 	/** calls the monotonicity callback for an expression
2139 	 *
2140 	 * @see SCIP_DECL_EXPRMONOTONICITY
2141 	 *
2142 	 * Returns unknown monotonicity if callback not implemented.
2143 	 */
2144 	SCIP_DECL_EXPRMONOTONICITY(SCIPcallExprMonotonicity)
2145 	{
2146 	   assert(scip != NULL);
2147 	
2148 	   SCIP_CALL( SCIPexprhdlrMonotonicityExpr(SCIPexprGetHdlr(expr), scip->set, expr, childidx, result) );
2149 	
2150 	   return SCIP_OKAY;
2151 	}
2152 	
2153 	/** calls the eval callback for an expression with given values for children
2154 	 *
2155 	 * Does not iterates over expressions, but requires values for children to be given.
2156 	 * Value is not stored in expression, but returned in `val`.
2157 	 * If an evaluation error (division by zero, ...) occurs, this value will
2158 	 * be set to `SCIP_INVALID`.
2159 	 */
2160 	SCIP_RETCODE SCIPcallExprEval(
2161 	   SCIP*                 scip,               /**< SCIP data structure */
2162 	   SCIP_EXPR*            expr,               /**< expression to be evaluated */
2163 	   SCIP_Real*            childrenvalues,     /**< values for children */
2164 	   SCIP_Real*            val                 /**< buffer to store evaluated value */
2165 	   )
2166 	{
2167 	   assert(scip != NULL);
2168 	   assert(scip->mem != NULL);
2169 	   assert(childrenvalues != NULL);
2170 	   assert(val != NULL);
2171 	
2172 	   SCIP_CALL( SCIPexprhdlrEvalExpr(SCIPexprGetHdlr(expr), scip->set, scip->mem->buffer, expr, val, childrenvalues, NULL) );
2173 	
2174 	   return SCIP_OKAY;
2175 	}
2176 	
2177 	/** calls the eval and fwdiff callback of an expression with given values for children
2178 	 *
2179 	 * Does not iterates over expressions, but requires values for children and direction to be given.
2180 	 *
2181 	 * Value is not stored in expression, but returned in `val`.
2182 	 * If an evaluation error (division by zero, ...) occurs, this value will be set to `SCIP_INVALID`.
2183 	 *
2184 	 * Direction is not stored in expression, but returned in `dot`.
2185 	 * If an differentiation error (division by zero, ...) occurs, this value will be set to `SCIP_INVALID`.
2186 	 */
2187 	SCIP_RETCODE SCIPcallExprEvalFwdiff(
2188 	   SCIP*                 scip,               /**< SCIP data structure */
2189 	   SCIP_EXPR*            expr,               /**< expression to be evaluated */
2190 	   SCIP_Real*            childrenvalues,     /**< values for children */
2191 	   SCIP_Real*            direction,          /**< direction in which to differentiate */
2192 	   SCIP_Real*            val,                /**< buffer to store evaluated value */
2193 	   SCIP_Real*            dot                 /**< buffer to store derivative value */
2194 	   )
2195 	{
2196 	   assert(scip != NULL);
2197 	   assert(scip->mem != NULL);
2198 	
2199 	   SCIP_CALL( SCIPexprhdlrEvalFwDiffExpr(SCIPexprGetHdlr(expr), scip->set, scip->mem->buffer, expr, val, dot,
2200 	         childrenvalues, NULL, direction, NULL) );
2201 	
2202 	   return SCIP_OKAY;
2203 	}
2204 	
2205 	/** calls the interval evaluation callback for an expression
2206 	 *
2207 	 * @see SCIP_DECL_EXPRINTEVAL
2208 	 *
2209 	 * Returns entire interval if callback not implemented.
2210 	 */
2211 	SCIP_DECL_EXPRINTEVAL(SCIPcallExprInteval)
2212 	{
2213 	   assert(scip != NULL);
2214 	
2215 	   SCIP_CALL( SCIPexprhdlrIntEvalExpr(SCIPexprGetHdlr(expr), scip->set, expr, interval, intevalvar, intevalvardata) );
2216 	
2217 	   return SCIP_OKAY;
2218 	}
2219 	
2220 	/** calls the estimate callback for an expression
2221 	 *
2222 	 * @see SCIP_DECL_EXPRESTIMATE
2223 	 *
2224 	 * Returns without success if callback not implemented.
2225 	 */
2226 	SCIP_EXPORT
2227 	SCIP_DECL_EXPRESTIMATE(SCIPcallExprEstimate)
2228 	{
2229 	   assert(scip != NULL);
2230 	
2231 	   SCIP_CALL( SCIPexprhdlrEstimateExpr(SCIPexprGetHdlr(expr), scip->set, expr, localbounds, globalbounds, refpoint,
2232 	         overestimate, targetvalue, coefs, constant, islocal, success, branchcand) );
2233 	
2234 	   return SCIP_OKAY;
2235 	}
2236 	
2237 	/** calls the initial estimators callback for an expression
2238 	 *
2239 	 * @see SCIP_DECL_EXPRINITESTIMATES
2240 	 *
2241 	 * Returns no estimators if callback not implemented.
2242 	 */
2243 	SCIP_EXPORT
2244 	SCIP_DECL_EXPRINITESTIMATES(SCIPcallExprInitestimates)
2245 	{
2246 	   assert(scip != NULL);
2247 	
2248 	   SCIP_CALL( SCIPexprhdlrInitEstimatesExpr(SCIPexprGetHdlr(expr), scip->set, expr, bounds, overestimate, coefs,
2249 	         constant, nreturned) );
2250 	
2251 	   return SCIP_OKAY;
2252 	}
2253 	
2254 	/** calls the simplify callback for an expression
2255 	 *
2256 	 * @see SCIP_DECL_EXPRSIMPLIFY
2257 	 *
2258 	 * Returns unmodified expression if simplify callback not implemented.
2259 	 *
2260 	 * Does not simplify descendants (children, etc). Use SCIPsimplifyExpr() for that.
2261 	 */
2262 	SCIP_DECL_EXPRSIMPLIFY(SCIPcallExprSimplify)
2263 	{
2264 	   assert(scip != NULL);
2265 	
2266 	   /* use simplification of expression handlers */
2267 	   SCIP_CALL( SCIPexprhdlrSimplifyExpr(SCIPexprGetHdlr(expr), scip->set, expr, simplifiedexpr, ownercreate,
2268 	         ownercreatedata) );
2269 	
2270 	   return SCIP_OKAY;
2271 	}
2272 	
2273 	/** calls the reverse propagation callback for an expression
2274 	 *
2275 	 * @see SCIP_DECL_EXPRREVERSEPROP
2276 	 *
2277 	 * Returns unmodified childrenbounds if reverseprop callback not implemented.
2278 	 */
2279 	SCIP_EXPORT
2280 	SCIP_DECL_EXPRREVERSEPROP(SCIPcallExprReverseprop)
2281 	{
2282 	   assert(scip != NULL);
2283 	
2284 	   SCIP_CALL( SCIPexprhdlrReversePropExpr(SCIPexprGetHdlr(expr), scip->set, expr, bounds, childrenbounds, infeasible) );
2285 	
2286 	   return SCIP_OKAY;
2287 	}
2288 	
2289 	/**@} */
2290 	
2291 	/**@name Expression Iterator Methods */
2292 	/**@{ */
2293 	
2294 	#ifdef NDEBUG
2295 	#undef SCIPcreateExpriter
2296 	#undef SCIPfreeExpriter
2297 	#endif
2298 	
2299 	/** creates an expression iterator */
2300 	SCIP_RETCODE SCIPcreateExpriter(
2301 	   SCIP*                 scip,               /**< SCIP data structure */
2302 	   SCIP_EXPRITER**       iterator            /**< buffer to store expression iterator */
2303 	   )
2304 	{
2305 	   assert(scip != NULL);
2306 	   assert(scip->mem != NULL);
2307 	
2308 	   SCIP_CALL( SCIPexpriterCreate(scip->stat, scip->mem->probmem, iterator) );
2309 	
2310 	   return SCIP_OKAY;
2311 	}
2312 	
2313 	/** frees an expression iterator */
2314 	void SCIPfreeExpriter(
2315 	   SCIP_EXPRITER**       iterator            /**< pointer to the expression iterator */
2316 	   )
2317 	{
2318 	   SCIPexpriterFree(iterator);
2319 	}
2320 	
2321 	/**@} */
2322 	
2323 	
2324 	/**@name Quadratic expression functions */
2325 	/**@{ */
2326 	
2327 	#ifdef NDEBUG
2328 	#undef SCIPcheckExprQuadratic
2329 	#undef SCIPfreeExprQuadratic
2330 	#undef SCIPcomputeExprQuadraticCurvature
2331 	#endif
2332 	
2333 	/** checks whether an expression is quadratic
2334 	 *
2335 	 * An expression is quadratic if it is either a square (of some expression), a product (of two expressions),
2336 	 * or a sum of terms where at least one is a square or a product.
2337 	 *
2338 	 * Use SCIPexprGetQuadraticData() to get data about the representation as quadratic.
2339 	 */
2340 	SCIP_RETCODE SCIPcheckExprQuadratic(
2341 	   SCIP*                 scip,               /**< SCIP data structure */
2342 	   SCIP_EXPR*            expr,               /**< expression */
2343 	   SCIP_Bool*            isquadratic         /**< buffer to store result */
2344 	   )
2345 	{
2346 	   assert(scip != NULL);
2347 	   assert(scip->mem != NULL);
2348 	
2349 	   SCIP_CALL( SCIPexprCheckQuadratic(scip->set, scip->mem->probmem, expr, isquadratic) );
2350 	
2351 	   return SCIP_OKAY;
2352 	}
2353 	
2354 	/** frees information on quadratic representation of an expression
2355 	 *
2356 	 * Before doing changes to an expression, it can be useful to call this function.
2357 	 */
2358 	void SCIPfreeExprQuadratic(
2359 	   SCIP*                 scip,               /**< SCIP data structure */
2360 	   SCIP_EXPR*            expr                /**< expression */
2361 	   )
2362 	{
2363 	   assert(scip != NULL);
2364 	   assert(scip->mem != NULL);
2365 	
2366 	   SCIPexprFreeQuadratic(scip->mem->probmem, expr);
2367 	}
2368 	
2369 	/** evaluates quadratic term in a solution
2370 	 *
2371 	 * \note This requires that every expression used in the quadratic data is a variable expression.
2372 	 */
2373 	SCIP_Real SCIPevalExprQuadratic(
2374 	   SCIP*                 scip,               /**< SCIP data structure */
2375 	   SCIP_EXPR*            expr,               /**< quadratic expression */
2376 	   SCIP_SOL*             sol                 /**< solution to evaluate, or NULL for LP solution */
2377 	   )
2378 	{
2379 	   SCIP_Real auxvalue;
2380 	   int nlinexprs;
2381 	   SCIP_Real* lincoefs;
2382 	   SCIP_EXPR** linexprs;
2383 	   int nquadexprs;
2384 	   int nbilinexprs;
2385 	   int i;
2386 	
2387 	   assert(scip != NULL);
2388 	   assert(expr != NULL);
2389 	
2390 	   SCIPexprGetQuadraticData(expr, &auxvalue, &nlinexprs, &linexprs, &lincoefs, &nquadexprs, &nbilinexprs, NULL, NULL);
2391 	
2392 	   /* linear terms */
2393 	   for( i = 0; i < nlinexprs; ++i )
2394 	   {
2395 	      assert(SCIPexprIsVar(scip->set, linexprs[i]));
2396 	      auxvalue += lincoefs[i] * SCIPgetSolVal(scip, sol, SCIPgetVarExprVar(linexprs[i]));
2397 	   }
2398 	
2399 	   /* quadratic terms */
2400 	   for( i = 0; i < nquadexprs; ++i )
2401 	   {
2402 	      SCIP_EXPR* quadexprterm;
2403 	      SCIP_Real lincoef;
2404 	      SCIP_Real sqrcoef;
2405 	      SCIP_Real solval;
2406 	
2407 	      SCIPexprGetQuadraticQuadTerm(expr, i, &quadexprterm, &lincoef, &sqrcoef, NULL, NULL, NULL);
2408 	
2409 	      assert(SCIPexprIsVar(scip->set, quadexprterm));
2410 	
2411 	      solval = SCIPgetSolVal(scip, sol, SCIPgetVarExprVar(quadexprterm));
2412 	      auxvalue += (lincoef + sqrcoef * solval) * solval;
2413 	   }
2414 	
2415 	   /* bilinear terms */
2416 	   for( i = 0; i < nbilinexprs; ++i )
2417 	   {
2418 	      SCIP_EXPR* expr1;
2419 	      SCIP_EXPR* expr2;
2420 	      SCIP_Real coef;
2421 	
2422 	      SCIPexprGetQuadraticBilinTerm(expr, i, &expr1, &expr2, &coef, NULL, NULL);
2423 	
2424 	      assert(SCIPexprIsVar(scip->set, expr1));
2425 	      assert(SCIPexprIsVar(scip->set, expr2));
2426 	      auxvalue += coef * SCIPgetSolVal(scip, sol, SCIPgetVarExprVar(expr1)) * SCIPgetSolVal(scip, sol, SCIPgetVarExprVar(expr2));
2427 	   }
2428 	
2429 	   return auxvalue;
2430 	}
2431 	
2432 	/** prints quadratic expression */
2433 	SCIP_RETCODE SCIPprintExprQuadratic(
2434 	   SCIP*                 scip,               /**< SCIP data structure */
2435 	   SCIP_EXPR*            expr                /**< quadratic expression */
2436 	   )
2437 	{
2438 	   SCIP_Real constant;
2439 	   int nlinexprs;
2440 	   SCIP_Real* lincoefs;
2441 	   SCIP_EXPR** linexprs;
2442 	   int nquadexprs;
2443 	   int nbilinexprs;
2444 	   int c;
2445 	
2446 	   assert(scip != NULL);
2447 	   assert(expr != NULL);
2448 	
2449 	   SCIPexprGetQuadraticData(expr, &constant, &nlinexprs, &linexprs, &lincoefs, &nquadexprs, &nbilinexprs, NULL, NULL);
2450 	
2451 	   SCIPinfoMessage(scip, NULL, "Constant: %g\n", constant);
2452 	
2453 	   SCIPinfoMessage(scip, NULL, "Linear: ");
2454 	   for( c = 0; c < nlinexprs; ++c )
2455 	   {
2456 	      SCIPinfoMessage(scip, NULL, "%g * ", lincoefs[c]);
2457 	      SCIP_CALL( SCIPprintExpr(scip, linexprs[c], NULL) );
2458 	      if( c < nlinexprs - 1 )
2459 	         SCIPinfoMessage(scip, NULL, " + ");
2460 	   }
2461 	   SCIPinfoMessage(scip, NULL, "\n");
2462 	
2463 	   SCIPinfoMessage(scip, NULL, "Quadratic: ");
2464 	   for( c = 0; c < nquadexprs; ++c )
2465 	   {
2466 	      SCIP_EXPR* quadexprterm;
2467 	      SCIP_Real lincoef;
2468 	      SCIP_Real sqrcoef;
2469 	
2470 	      SCIPexprGetQuadraticQuadTerm(expr, c, &quadexprterm, &lincoef, &sqrcoef, NULL, NULL, NULL);
2471 	      SCIPinfoMessage(scip, NULL, "(%g * sqr(", sqrcoef);
2472 	      SCIP_CALL( SCIPprintExpr(scip, quadexprterm, NULL) );
2473 	      SCIPinfoMessage(scip, NULL, ") + %g) * ", lincoef);
2474 	      SCIP_CALL( SCIPprintExpr(scip, quadexprterm, NULL) );
2475 	      if( c < nquadexprs - 1 )
2476 	         SCIPinfoMessage(scip, NULL, " + ");
2477 	   }
2478 	   SCIPinfoMessage(scip, NULL, "\n");
2479 	
2480 	   if( nbilinexprs == 0 )
2481 	   {
2482 	      SCIPinfoMessage(scip, NULL, "Bilinear: none\n");
2483 	      return SCIP_OKAY;
2484 	   }
2485 	
2486 	   SCIPinfoMessage(scip, NULL, "Bilinear: ");
2487 	   for( c = 0; c < nbilinexprs; ++c )
2488 	   {
2489 	      SCIP_EXPR* expr1;
2490 	      SCIP_EXPR* expr2;
2491 	      SCIP_Real coef;
2492 	
2493 	      SCIPexprGetQuadraticBilinTerm(expr, c, &expr1, &expr2, &coef, NULL, NULL);
2494 	
2495 	      SCIPinfoMessage(scip, NULL, "%g * ", coef);
2496 	      SCIP_CALL( SCIPprintExpr(scip, expr1, NULL) );
2497 	      SCIPinfoMessage(scip, NULL, " * ");
2498 	      SCIP_CALL( SCIPprintExpr(scip, expr2, NULL) );
2499 	      if( c < nbilinexprs - 1 )
2500 	         SCIPinfoMessage(scip, NULL, " + ");
2501 	   }
2502 	   SCIPinfoMessage(scip, NULL, "\n");
2503 	
2504 	   SCIPinfoMessage(scip, NULL, "Bilinear of quadratics: \n");
2505 	   for( c = 0; c < nquadexprs; ++c )
2506 	   {
2507 	      SCIP_EXPR* quadexprterm;
2508 	      int nadjbilin;
2509 	      int* adjbilin;
2510 	      int i;
2511 	
2512 	      SCIPexprGetQuadraticQuadTerm(expr, c, &quadexprterm, NULL, NULL, &nadjbilin, &adjbilin, NULL);
2513 	
2514 	      SCIPinfoMessage(scip, NULL, "  For ");
2515 	      SCIP_CALL( SCIPprintExpr(scip, quadexprterm, NULL) );
2516 	      SCIPinfoMessage(scip, NULL, " we see: ");
2517 	      for( i = 0; i < nadjbilin; ++i )
2518 	      {
2519 	         SCIP_EXPR* expr1;
2520 	         SCIP_EXPR* expr2;
2521 	         SCIP_Real coef;
2522 	
2523 	         SCIPexprGetQuadraticBilinTerm(expr, adjbilin[i], &expr1, &expr2, &coef, NULL, NULL);
2524 	
2525 	         SCIPinfoMessage(scip, NULL, "%g * ", coef);
2526 	         SCIP_CALL( SCIPprintExpr(scip, expr1, NULL) );
2527 	         SCIPinfoMessage(scip, NULL, " * ");
2528 	         SCIP_CALL( SCIPprintExpr(scip, expr2, NULL) );
2529 	         if( i < nadjbilin - 1 )
2530 	            SCIPinfoMessage(scip, NULL, " + ");
2531 	      }
2532 	      SCIPinfoMessage(scip, NULL, "\n");
2533 	   }
2534 	
2535 	   return SCIP_OKAY;
2536 	}
2537 	
2538 	/** checks the curvature of the quadratic expression
2539 	 *
2540 	 * For this, it builds the matrix Q of quadratic coefficients and computes its eigenvalues using LAPACK.
2541 	 * If Q is
2542 	 * - semidefinite positive -> curv is set to convex,
2543 	 * - semidefinite negative -> curv is set to concave,
2544 	 * - otherwise -> curv is set to unknown.
2545 	 *
2546 	 * If `assumevarfixed` is given and some expressions in quadratic terms correspond to variables present in
2547 	 * this hashmap, then the corresponding rows and columns are ignored in the matrix Q.
2548 	 */
2549 	SCIP_RETCODE SCIPcomputeExprQuadraticCurvature(
2550 	   SCIP*                 scip,               /**< SCIP data structure */
2551 	   SCIP_EXPR*            expr,               /**< quadratic expression */
2552 	   SCIP_EXPRCURV*        curv,               /**< pointer to store the curvature of quadratics */
2553 	   SCIP_HASHMAP*         assumevarfixed,     /**< hashmap containing variables that should be assumed to be fixed, or NULL */
2554 	   SCIP_Bool             storeeigeninfo      /**< whether the eigenvalues and eigenvectors should be stored */
2555 	   )
2556 	{
2557 	   assert(scip != NULL);
2558 	   assert(scip->mem != NULL);
2559 	
2560 	   SCIP_CALL( SCIPexprComputeQuadraticCurvature(scip->set, scip->mem->probmem, scip->mem->buffer, scip->messagehdlr,
2561 	         expr, curv, assumevarfixed, storeeigeninfo) );
2562 	
2563 	   return SCIP_OKAY;
2564 	}
2565 	
2566 	/**@} */
2567