1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the program and library             */
4    	/*         SCIP --- Solving Constraint Integer Programs                      */
5    	/*                                                                           */
6    	/*  Copyright (c) 2002-2023 Zuse Institute Berlin (ZIB)                      */
7    	/*                                                                           */
8    	/*  Licensed under the Apache License, Version 2.0 (the "License");          */
9    	/*  you may not use this file except in compliance with the License.         */
10   	/*  You may obtain a copy of the License at                                  */
11   	/*                                                                           */
12   	/*      http://www.apache.org/licenses/LICENSE-2.0                           */
13   	/*                                                                           */
14   	/*  Unless required by applicable law or agreed to in writing, software      */
15   	/*  distributed under the License is distributed on an "AS IS" BASIS,        */
16   	/*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17   	/*  See the License for the specific language governing permissions and      */
18   	/*  limitations under the License.                                           */
19   	/*                                                                           */
20   	/*  You should have received a copy of the Apache-2.0 license                */
21   	/*  along with SCIP; see the file LICENSE. If not visit scipopt.org.         */
22   	/*                                                                           */
23   	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24   	
25   	/**@file   cons_nonlinear.h
26   	 * @ingroup CONSHDLRS
27   	 * @brief  constraint handler for nonlinear constraints specified by algebraic expressions
28   	 * @author Ksenia Bestuzheva
29   	 * @author Benjamin Mueller
30   	 * @author Felipe Serrano
31   	 * @author Stefan Vigerske
32   	 *
33   	 * For additional documentation on this constraint handler, see also the SCIP 8 release report.
34   	 */
35   	
36   	/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
37   	
38   	#ifndef __SCIP_CONS_NONLINEAR_H__
39   	#define __SCIP_CONS_NONLINEAR_H__
40   	
41   	
42   	#include "scip/scip.h"
43   	#include "scip/type_nlhdlr.h"
44   	
45   	#ifdef __cplusplus
46   	extern "C" {
47   	#endif
48   	
49   	/**@addtogroup CONSHDLRS
50   	 * @{
51   	 *
52   	 * @name Nonlinear Constraints
53   	 * @{
54   	 */
55   	
56   	/** linear auxiliary expression of the form xy {≤,≥,=} coefs[0]w + coefs[1]x + coefs[2]y + cst */
57   	struct SCIP_ConsNonlinear_Auxexpr
58   	{
59   	   SCIP_Real             coefs[3];           /**< coefficients in the auxiliary expression */
60   	   SCIP_Real             cst;                /**< constant */
61   	   SCIP_VAR*             auxvar;             /**< auxiliary variable w in xy {&le;,&ge;,=} auxexpr(w, x, y) */
62   	   SCIP_Bool             underestimate;      /**< whether the auxexpr underestimates the product */
63   	   SCIP_Bool             overestimate;       /**< whether the auxexpr overestimates the product */
64   	};
65   	typedef struct SCIP_ConsNonlinear_Auxexpr SCIP_CONSNONLINEAR_AUXEXPR;
66   	
67   	/** bilinear term structure
68   	 *
69   	 * This can represent a product which
70   	 * - explicitly exists in the problem and is under- and/or overestimated by a single auxiliary variable
71   	 *   stored as `var` in the union `aux` (case `nauxexprs` = 0) or
72   	 * - is involved in bilinear relations implicitly given by linear constraints with binary variables, and
73   	 *   is under- and/or overestimated by linear expression(s) stored as `exprs` in the union `aux` (case `nauxexprs` > 0).
74   	 *
75   	 * An explicitly existing product can also be involved in implicit relations, then it will be stored as in
76   	 * the second case.
77   	 */
78   	struct SCIP_ConsNonlinear_BilinTerm
79   	{
80   	   SCIP_VAR*             x;                  /**< first variable */
81   	   SCIP_VAR*             y;                  /**< second variable */
82   	   union
83   	   {
84   	      SCIP_CONSNONLINEAR_AUXEXPR** exprs;    /**< auxiliary expressions for the implicit product of x and y */
85   	      SCIP_VAR*          var;                /**< auxiliary variable for the explicit product of x and y */
86   	   }                     aux;
87   	   int                   nauxexprs;          /**< number of aux.exprs (0 for products without implicit relations) */
88   	   int                   auxexprssize;       /**< size of the aux.exprs array */
89   	   int                   nlockspos;          /**< number of positive expression locks */
90   	   int                   nlocksneg;          /**< number of negative expression locks */
91   	   SCIP_Bool             existing;           /**< does the product exist explicitly in the problem? */
92   	};
93   	typedef struct SCIP_ConsNonlinear_BilinTerm SCIP_CONSNONLINEAR_BILINTERM; /**< bilinear term structure */
94   	
95   	/** evaluation callback for (vertex-polyhedral) functions used as input for facet computation of its envelopes
96   	 *
97   	 * \param[in] args     the point to be evaluated
98   	 * \param[in] nargs    the number of arguments of the function (length of array `args`)
99   	 * \param[in] funcdata user-data of function evaluation callback
100  	 * \return value of function in point given by `args` or SCIP_INVALID if could not be evaluated
101  	 */
102  	#define SCIP_DECL_VERTEXPOLYFUN(f) SCIP_Real f (SCIP_Real* args, int nargs, void* funcdata)
103  	
104  	/** maximum dimension of vertex-polyhedral function for which we can try to compute a facet of its convex or concave envelope */
105  	#define SCIP_MAXVERTEXPOLYDIM 14
106  	
107  	/** upgrading method for nonlinear constraints into more specific constraints
108  	 *
109  	 * The method might upgrade a nonlinear constraint into a set of upgrade constraints.
110  	 * The caller provided an array `upgdconss` of size `upgdconsssize` to store upgrade constraints.
111  	 * If an upgrade is not possible, set `*nupgdconss` to zero.
112  	 * If more than `upgdconsssize` many constraints shall replace `cons`, the function
113  	 * should return the required number as negated value in `*nupgdconss`,
114  	 * e.g., if `cons` should be replaced by 3 constraints, the function should set
115  	 * `*nupgdconss` to -3 and return with SCIP_OKAY.
116  	 *
117  	 * \param[in] scip           SCIP main data structure
118  	 * \param[in] cons           the nonlinear constraint to upgrade
119  	 * \param[in] nvarexprs      total number of variable expressions in the nonlinear constraint
120  	 * \param[out] nupgdconss    pointer to store number of constraints that replace this constraint
121  	 * \param[out] upgdconss     array to store constraints that replace this constraint
122  	 * \param[in] upgdconsssize  length of the provided `upgdconss` array
123  	 */
124  	#define SCIP_DECL_NONLINCONSUPGD(x) SCIP_RETCODE x (SCIP* scip, SCIP_CONS* cons, int nvarexprs, \
125  	      int* nupgdconss, SCIP_CONS** upgdconss, int upgdconsssize)
126  	
127  	/** @} */
128  	/** @} */
129  	
130  	/** creates the handler for nonlinear constraints and includes it in SCIP
131  	 *
132  	 * @ingroup ConshdlrIncludes
133  	 */
134  	SCIP_EXPORT
135  	SCIP_RETCODE SCIPincludeConshdlrNonlinear(
136  	   SCIP*                 scip                /**< SCIP data structure */
137  	   );
138  	
139  	/**@addtogroup CONSHDLRS
140  	 *
141  	 * @{
142  	 *
143  	 * @name Nonlinear Constraints
144  	 *
145  	 * @{
146  	 */
147  	
148  	/* Nonlinear Constraint Handler Methods */
149  	
150  	/** includes a nonlinear constraint upgrade method into the nonlinear constraint handler */
151  	SCIP_EXPORT
152  	SCIP_RETCODE SCIPincludeConsUpgradeNonlinear(
153  	   SCIP*                 scip,               /**< SCIP data structure */
154  	   SCIP_DECL_NONLINCONSUPGD((*nlconsupgd)),  /**< method to call for upgrading nonlinear constraint */
155  	   int                   priority,           /**< priority of upgrading method */
156  	   SCIP_Bool             active,             /**< should the upgrading method by active by default? */
157  	   const char*           conshdlrname        /**< name of the constraint handler */
158  	   );
159  	
160  	/** creates and captures a nonlinear constraint
161  	 *
162  	 *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
163  	 */
164  	SCIP_EXPORT
165  	SCIP_RETCODE SCIPcreateConsNonlinear(
166  	   SCIP*                 scip,               /**< SCIP data structure */
167  	   SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
168  	   const char*           name,               /**< name of constraint */
169  	   SCIP_EXPR*            expr,               /**< expression of constraint (must not be NULL) */
170  	   SCIP_Real             lhs,                /**< left hand side of constraint */
171  	   SCIP_Real             rhs,                /**< right hand side of constraint */
172  	   SCIP_Bool             initial,            /**< should the LP relaxation of constraint be in the initial LP?
173  	                                              *   Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
174  	   SCIP_Bool             separate,           /**< should the constraint be separated during LP processing?
175  	                                              *   Usually set to TRUE. */
176  	   SCIP_Bool             enforce,            /**< should the constraint be enforced during node processing?
177  	                                              *   TRUE for model constraints, FALSE for additional, redundant constraints. */
178  	   SCIP_Bool             check,              /**< should the constraint be checked for feasibility?
179  	                                              *   TRUE for model constraints, FALSE for additional, redundant constraints. */
180  	   SCIP_Bool             propagate,          /**< should the constraint be propagated during node processing?
181  	                                              *   Usually set to TRUE. */
182  	   SCIP_Bool             local,              /**< is constraint only valid locally?
183  	                                              *   Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
184  	   SCIP_Bool             modifiable,         /**< is constraint modifiable (subject to column generation)?
185  	                                              *   Usually set to FALSE. In column generation applications, set to TRUE if pricing
186  	                                              *   adds coefficients to this constraint. */
187  	   SCIP_Bool             dynamic,            /**< is constraint subject to aging?
188  	                                              *   Usually set to FALSE. Set to TRUE for own cuts which
189  	                                              *   are separated as constraints. */
190  	   SCIP_Bool             removable           /**< should the relaxation be removed from the LP due to aging or cleanup?
191  	                                              *   Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
192  	   );
193  	
194  	/** creates and captures a nonlinear constraint with all its constraint flags set to their default values
195  	 *
196  	 *  All flags can be set via SCIPconsSetFLAGNAME-methods.
197  	 *
198  	 *  @see SCIPcreateConsNonlinear() for information about the basic constraint flag configuration.
199  	 *
200  	 *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
201  	 */
202  	SCIP_EXPORT
203  	SCIP_RETCODE SCIPcreateConsBasicNonlinear(
204  	   SCIP*                 scip,               /**< SCIP data structure */
205  	   SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
206  	   const char*           name,               /**< name of constraint */
207  	   SCIP_EXPR*            expr,               /**< expression of constraint (must not be NULL) */
208  	   SCIP_Real             lhs,                /**< left hand side of constraint */
209  	   SCIP_Real             rhs                 /**< right hand side of constraint */
210  	   );
211  	
212  	/** creates and captures a quadratic nonlinear constraint
213  	 *
214  	 *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
215  	 */
216  	SCIP_EXPORT
217  	SCIP_RETCODE SCIPcreateConsQuadraticNonlinear(
218  	   SCIP*                 scip,               /**< SCIP data structure */
219  	   SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
220  	   const char*           name,               /**< name of constraint */
221  	   int                   nlinvars,           /**< number of linear terms */
222  	   SCIP_VAR**            linvars,            /**< array with variables in linear part */
223  	   SCIP_Real*            lincoefs,           /**< array with coefficients of variables in linear part */
224  	   int                   nquadterms,         /**< number of quadratic terms */
225  	   SCIP_VAR**            quadvars1,          /**< array with first variables in quadratic terms */
226  	   SCIP_VAR**            quadvars2,          /**< array with second variables in quadratic terms */
227  	   SCIP_Real*            quadcoefs,          /**< array with coefficients of quadratic terms */
228  	   SCIP_Real             lhs,                /**< left hand side of quadratic equation */
229  	   SCIP_Real             rhs,                /**< right hand side of quadratic equation */
230  	   SCIP_Bool             initial,            /**< should the LP relaxation of constraint be in the initial LP?
231  	                                              *   Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
232  	   SCIP_Bool             separate,           /**< should the constraint be separated during LP processing?
233  	                                              *   Usually set to TRUE. */
234  	   SCIP_Bool             enforce,            /**< should the constraint be enforced during node processing?
235  	                                              *   TRUE for model constraints, FALSE for additional, redundant constraints. */
236  	   SCIP_Bool             check,              /**< should the constraint be checked for feasibility?
237  	                                              *   TRUE for model constraints, FALSE for additional, redundant constraints. */
238  	   SCIP_Bool             propagate,          /**< should the constraint be propagated during node processing?
239  	                                              *   Usually set to TRUE. */
240  	   SCIP_Bool             local,              /**< is constraint only valid locally?
241  	                                              *   Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
242  	   SCIP_Bool             modifiable,         /**< is constraint modifiable (subject to column generation)?
243  	                                              *   Usually set to FALSE. In column generation applications, set to TRUE if pricing
244  	                                              *   adds coefficients to this constraint. */
245  	   SCIP_Bool             dynamic,            /**< is constraint subject to aging?
246  	                                              *   Usually set to FALSE. Set to TRUE for own cuts which
247  	                                              *   are separated as constraints. */
248  	   SCIP_Bool             removable           /**< should the relaxation be removed from the LP due to aging or cleanup?
249  	                                              *   Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
250  	   );
251  	
252  	/** creates and captures a quadratic nonlinear constraint with all its constraint flags set to their default values
253  	 *
254  	 *  All flags can be set via SCIPconsSetFLAGNAME-methods.
255  	 *
256  	 *  @see SCIPcreateConsQuadraticNonlinear() for information about the basic constraint flag configuration.
257  	 *
258  	 *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
259  	 */
260  	SCIP_EXPORT
261  	SCIP_RETCODE SCIPcreateConsBasicQuadraticNonlinear(
262  	   SCIP*                 scip,               /**< SCIP data structure */
263  	   SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
264  	   const char*           name,               /**< name of constraint */
265  	   int                   nlinvars,           /**< number of linear terms */
266  	   SCIP_VAR**            linvars,            /**< array with variables in linear part */
267  	   SCIP_Real*            lincoefs,           /**< array with coefficients of variables in linear part */
268  	   int                   nquadterms,         /**< number of quadratic terms */
269  	   SCIP_VAR**            quadvars1,          /**< array with first variables in quadratic terms */
270  	   SCIP_VAR**            quadvars2,          /**< array with second variables in quadratic terms */
271  	   SCIP_Real*            quadcoefs,          /**< array with coefficients of quadratic terms */
272  	   SCIP_Real             lhs,                /**< left hand side of quadratic equation */
273  	   SCIP_Real             rhs                 /**< right hand side of quadratic equation */
274  	   );
275  	
276  	/** creates and captures a nonlinear constraint that is a second-order cone constraint with all its constraint flags set to their default values
277  	 *
278  	 * \f$\sqrt{\gamma + \sum_{i=1}^{n} (\alpha_i\, (x_i + \beta_i))^2} \leq \alpha_{n+1}\, (x_{n+1}+\beta_{n+1})\f$
279  	 *
280  	 *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
281  	 */
282  	SCIP_EXPORT
283  	SCIP_RETCODE SCIPcreateConsBasicSOCNonlinear(
284  	   SCIP*                 scip,               /**< SCIP data structure */
285  	   SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
286  	   const char*           name,               /**< name of constraint */
287  	   int                   nvars,              /**< number of variables on left hand side of constraint (n) */
288  	   SCIP_VAR**            vars,               /**< array with variables on left hand side (x_i) */
289  	   SCIP_Real*            coefs,              /**< array with coefficients of left hand side variables (alpha_i), or NULL if all 1.0 */
290  	   SCIP_Real*            offsets,            /**< array with offsets of variables (beta_i), or NULL if all 0.0 */
291  	   SCIP_Real             constant,           /**< constant on left hand side (gamma) */
292  	   SCIP_VAR*             rhsvar,             /**< variable on right hand side of constraint (x_{n+1}) */
293  	   SCIP_Real             rhscoeff,           /**< coefficient of variable on right hand side (alpha_{n+1}) */
294  	   SCIP_Real             rhsoffset           /**< offset of variable on right hand side (beta_{n+1}) */
295  	   );
296  	
297  	/** creates and captures a signpower nonlinear constraint with all its constraint flags set to their default values
298  	 *
299  	 * \f$\textrm{lhs} \leq \textrm{sign}(x+a) |x+a|^n + c z \leq \textrm{rhs}\f$
300  	 *
301  	 *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
302  	 */
303  	SCIP_EXPORT
304  	SCIP_RETCODE SCIPcreateConsBasicSignpowerNonlinear(
305  	   SCIP*                 scip,               /**< SCIP data structure */
306  	   SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
307  	   const char*           name,               /**< name of constraint */
308  	   SCIP_VAR*             x,                  /**< nonlinear variable x in constraint */
309  	   SCIP_VAR*             z,                  /**< linear variable z in constraint */
310  	   SCIP_Real             exponent,           /**< exponent n of |x+offset|^n term in constraint */
311  	   SCIP_Real             xoffset,            /**< offset in |x+offset|^n term in constraint */
312  	   SCIP_Real             zcoef,              /**< coefficient of z in constraint */
313  	   SCIP_Real             lhs,                /**< left hand side of constraint */
314  	   SCIP_Real             rhs                 /**< right hand side of constraint */
315  	   );
316  	
317  	/** gets tag indicating current local variable bounds */
318  	SCIP_EXPORT
319  	SCIP_Longint SCIPgetCurBoundsTagNonlinear(
320  	   SCIP_CONSHDLR*        conshdlr            /**< nonlinear constraint handler */
321  	   );
322  	
323  	/** gets the `curboundstag` from the last time where variable bounds were relaxed */
324  	SCIP_EXPORT
325  	SCIP_Longint SCIPgetLastBoundRelaxTagNonlinear(
326  	   SCIP_CONSHDLR*        conshdlr            /**< nonlinear constraint handler */
327  	   );
328  	
329  	/** increments `curboundstag` and resets `lastboundrelax` in constraint handler data
330  	 *
331  	 * @attention This method is not intended for normal use.
332  	 *   These tags are maintained by the event handler for variable bound change events.
333  	 *   This method is used by some unittests.
334  	 */
335  	SCIP_EXPORT
336  	void SCIPincrementCurBoundsTagNonlinear(
337  	   SCIP_CONSHDLR*          conshdlr,         /**< nonlinear constraint handler */
338  	   SCIP_Bool               boundrelax        /**< indicates whether a bound was relaxed, i.e., lastboundrelax should be set too */
339  	   );
340  	
341  	/** returns the hashmap that is internally used to map variables to their corresponding variable expressions */
342  	SCIP_EXPORT
343  	SCIP_HASHMAP* SCIPgetVarExprHashmapNonlinear(
344  	   SCIP_CONSHDLR*        conshdlr            /**< nonlinear constraint handler */
345  	   );
346  	
347  	/** processes a rowprep for cut addition and maybe report branchscores */
348  	SCIP_EXPORT
349  	SCIP_RETCODE SCIPprocessRowprepNonlinear(
350  	   SCIP*                 scip,               /**< SCIP data structure */
351  	   SCIP_NLHDLR*          nlhdlr,             /**< nonlinear handler which provided the estimator */
352  	   SCIP_CONS*            cons,               /**< nonlinear constraint */
353  	   SCIP_EXPR*            expr,               /**< expression */
354  	   SCIP_ROWPREP*         rowprep,            /**< cut to be added */
355  	   SCIP_Bool             overestimate,       /**< whether the expression needs to be over- or underestimated */
356  	   SCIP_VAR*             auxvar,             /**< auxiliary variable */
357  	   SCIP_Real             auxvalue,           /**< current value of expression w.r.t. auxiliary variables as obtained from EVALAUX */
358  	   SCIP_Bool             allowweakcuts,      /**< whether we should only look for "strong" cuts, or anything that separates is fine */
359  	   SCIP_Bool             branchscoresuccess, /**< whether the estimator generation generated branching scores */
360  	   SCIP_Bool             inenforcement,      /**< whether we are in enforcement, or only in separation */
361  	   SCIP_SOL*             sol,                /**< solution to be separated (NULL for the LP solution) */
362  	   SCIP_RESULT*          result              /**< pointer to store the result */
363  	   );
364  	
365  	/** returns whether all nonlinear constraints are assumed to be convex */
366  	SCIP_EXPORT
367  	SCIP_Bool SCIPassumeConvexNonlinear(
368  	   SCIP_CONSHDLR*        conshdlr
369  	   );
370  	
371  	/** collects all bilinear terms for a given set of constraints
372  	 *
373  	 * @attention This method should only be used for unit tests that depend on SCIPgetBilinTermsNonlinear(),
374  	 *       SCIPgetBilinTermNonlinear() or SCIPgetBilinTermIdxNonlinear().
375  	 */
376  	SCIP_EXPORT
377  	SCIP_RETCODE SCIPcollectBilinTermsNonlinear(
378  	   SCIP*                 scip,               /**< SCIP data structure */
379  	   SCIP_CONSHDLR*        conshdlr,           /**< nonlinear constraint handler */
380  	   SCIP_CONS**           conss,              /**< nonlinear constraints */
381  	   int                   nconss              /**< total number of nonlinear constraints */
382  	   );
383  	
384  	/** returns the total number of bilinear terms that are contained in all nonlinear constraints
385  	 *
386  	 *  @note This method should only be used after auxiliary variables have been created, i.e., after CONSINITLP.
387  	 */
388  	SCIP_EXPORT
389  	int SCIPgetNBilinTermsNonlinear(
390  	   SCIP_CONSHDLR*        conshdlr            /**< nonlinear constraint handler */
391  	   );
392  	
393  	/** returns all bilinear terms that are contained in all nonlinear constraints
394  	 *
395  	 * @note This method should only be used after auxiliary variables have been created, i.e., after CONSINITLP.
396  	 * @note The value of the auxiliary variable of a bilinear term might be NULL, which indicates that the term does not have an auxiliary variable.
397  	 */
398  	SCIP_EXPORT
399  	SCIP_CONSNONLINEAR_BILINTERM* SCIPgetBilinTermsNonlinear(
400  	   SCIP_CONSHDLR*        conshdlr            /**< nonlinear constraint handler */
401  	   );
402  	
403  	/** returns the index of the bilinear term representing the product of the two given variables
404  	 *
405  	 * @note The method should only be used after auxiliary variables have been created, i.e., after CONSINITLP.
406  	 * @return The method returns -1 if the variables do not appear bilinearly.
407  	 */
408  	SCIP_EXPORT
409  	int SCIPgetBilinTermIdxNonlinear(
410  	   SCIP_CONSHDLR*        conshdlr,           /**< nonlinear constraint handler */
411  	   SCIP_VAR*             x,                  /**< first variable */
412  	   SCIP_VAR*             y                   /**< second variable */
413  	   );
414  	
415  	/** returns the bilinear term that represents the product of two given variables
416  	 *
417  	 * @note The method should only be used after auxiliary variables have been created, i.e., after CONSINITLP.
418  	 * @return The method returns NULL if the variables do not appear bilinearly.
419  	 */
420  	SCIP_EXPORT
421  	SCIP_CONSNONLINEAR_BILINTERM* SCIPgetBilinTermNonlinear(
422  	   SCIP_CONSHDLR*        conshdlr,           /**< nonlinear constraint handler */
423  	   SCIP_VAR*             x,                  /**< first variable */
424  	   SCIP_VAR*             y                   /**< second variable */
425  	   );
426  	
427  	/** evaluates an auxiliary expression for a bilinear term */
428  	SCIP_EXPORT
429  	SCIP_Real SCIPevalBilinAuxExprNonlinear(
430  	   SCIP*                 scip,               /**< SCIP data structure */
431  	   SCIP_VAR*             x,                  /**< first variable of the bilinear term */
432  	   SCIP_VAR*             y,                  /**< second variable of the bilinear term */
433  	   SCIP_CONSNONLINEAR_AUXEXPR* auxexpr,      /**< auxiliary expression */
434  	   SCIP_SOL*             sol                 /**< solution at which to evaluate (can be NULL) */
435  	   );
436  	
437  	/** stores the variables of a bilinear term in the data of the constraint handler */
438  	SCIP_EXPORT
439  	SCIP_RETCODE SCIPinsertBilinearTermExistingNonlinear(
440  	   SCIP*                 scip,               /**< SCIP data structure */
441  	   SCIP_CONSHDLR*        conshdlr,           /**< constraint handler */
442  	   SCIP_VAR*             x,                  /**< first variable */
443  	   SCIP_VAR*             y,                  /**< second variable */
444  	   SCIP_VAR*             auxvar,             /**< auxiliary variable (might be NULL) */
445  	   int                   nlockspos,          /**< number of positive expression locks */
446  	   int                   nlocksneg           /**< number of negative expression locks */
447  	   );
448  	
449  	/** stores the variables of a bilinear term in the data of the constraint handler */
450  	SCIP_EXPORT
451  	SCIP_RETCODE SCIPinsertBilinearTermImplicitNonlinear(
452  	   SCIP*                 scip,               /**< SCIP data structure */
453  	   SCIP_CONSHDLR*        conshdlr,           /**< constraint handler */
454  	   SCIP_VAR*             x,                  /**< first variable */
455  	   SCIP_VAR*             y,                  /**< second variable */
456  	   SCIP_VAR*             auxvar,             /**< auxiliary variable (might be NULL) */
457  	   SCIP_Real             coefx,              /**< coefficient of x in the auxiliary expression */
458  	   SCIP_Real             coefy,              /**< coefficient of y in the auxiliary expression */
459  	   SCIP_Real             coefaux,            /**< coefficient of auxvar in the auxiliary expression */
460  	   SCIP_Real             cst,                /**< constant of the auxiliary expression */
461  	   SCIP_Bool             overestimate        /**< whether the auxiliary expression overestimates the bilinear product */
462  	   );
463  	
464  	/** computes a facet of the convex or concave envelope of a vertex polyhedral function
465  	 *
466  	 * If \f$ f(x) \f$ is vertex-polyhedral, then \f$ g \f$ is a convex underestimator if and only if
467  	 * \f$ g(v^i) \leq f(v^i), \forall i \f$, where \f$ \{ v^i \}_{i = 1}^{2^n} \subseteq \mathbb R^n \f$ are the vertices
468  	 * of the domain of \f$ x \f$, \f$ [\ell,u] \f$. Hence, we can compute a linear underestimator by solving the following
469  	 * LP (we don't necessarily get a facet of the convex envelope, see below):
470  	 *
471  	 * \f{align*}{
472  	 *              \max \, & \alpha^T x^* + \beta \\
473  	 *     s.t. \; & \alpha^T v^i + \beta \le f(v^i), \, \forall i = 1, \ldots, 2^n
474  	 * \f}
475  	 *
476  	 * In principle, one would need to update the LP whenever the domain changes. However, \f$ [\ell,u] = T([0, 1]^n) \f$,
477  	 * where \f$ T \f$ is an affine linear invertible transformation given by \f$ T(y)_i = (u_i - \ell_i) y_i + \ell_i \f$.
478  	 * Working with the change of variables \f$ x = T(y) \f$ allows us to keep the constraints of the LP, even if the domain
479  	 * changes. Indeed, after the change of variables, the problem is: find an affine underestimator \f$ g \f$ such that \f$
480  	 * g(T(y)) \le f(T(y)) \f$, for all \f$ y \in [0, 1]^n \f$. Now \f$ f(T(y)) \f$ is componentwise affine, but still
481  	 * satisfies that \f$ g \f$ is a valid underestimator if and only if \f$ g(T(u)) \leq f(T(u)), \forall u \in \{0, 1\}^n
482  	 * \f$. So we now look for \f$ \bar g(y) := g(T(y)) = g(((u_i - \ell_i) y_i + \ell_i)_i) = \bar \alpha^T y + \bar \beta
483  	 * \f$, where \f$ \bar \alpha_i = (u_i - \ell_i) \alpha_i \f$ and \f$ \bar \beta = \sum_i \alpha_i \ell_i + \beta \f$. So
484  	 * we find \f$ \bar g \f$ by solving the LP:
485  	 *
486  	 * \f{align*}{
487  	 *              \max \, & \bar \alpha^T T^{-1}(x^*) + \bar \beta \\
488  	 *     s.t. \; & \bar \alpha^T u + \bar \beta \le f(T(u)), \, \forall u \in \{0, 1\}^n
489  	 * \f}
490  	 *
491  	 * and recover \f$ g \f$ by calculating \f$ \bar \alpha_i = (u_i - \ell_i) \alpha_i, \bar \beta = \sum_i \alpha_i \ell_i +
492  	 * \beta \f$. Notice that \f$ f(T(u^i)) = f(v^i) \f$ so the right hand side doesn't change after the change of variables.
493  	 *
494  	 * Furthermore, the LP has more constraints than variables, so we solve its dual:
495  	 * \f{align*}{
496  	 *              \min \, & \sum_i \lambda_i f(v^i) \\
497  	 *     s.t. \; & \sum_i \lambda_i u^i = T^{-1}(x^*) \\
498  	 *             & \sum_i \lambda_i = 1 \\
499  	 *             & \forall i, \, \lambda_i \geq 0
500  	 * \f}
501  	 *
502  	 * In case we look for an overestimate, we do exactly the same, but have to maximize in the dual LP instead
503  	 * of minimize.
504  	 *
505  	 * #### Technical and implementation details
506  	 * -# \f$ U \f$ has exponentially many variables, so we only apply this separator for \f$n\f$ &le; \ref SCIP_MAXVERTEXPOLYDIM.
507  	 * -# If the bounds are not finite, there is no underestimator. Also, \f$ T^{-1}(x^*) \f$ must be in the domain,
508  	 * otherwise the dual is infeasible.
509  	 * -# After a facet is computed, we check whether it is a valid facet (i.e. we check \f$ \alpha^T v + \beta \le f(v) \f$
510  	 *  for every vertex \f$ v \f$). If we find a violation of at most ADJUSTFACETFACTOR * SCIPlpfeastol(), then we weaken \f$
511  	 *  \beta \f$ by this amount, otherwise, we discard the cut.
512  	 * -# If a variable is fixed within tolerances, we replace it with its value and compute the facet of the remaining
513  	 * expression. Note that since we are checking the cut for validity, this will never produce wrong result.
514  	 * -# If \f$ x^* \f$ is in the boundary of the domain, then the LP has infinitely many solutions, some of which might
515  	 * have very bad numerical properties. For this reason, we perturb \f$ x^* \f$ to be in the interior of the region.
516  	 * Furthermore, for some interior points, there might also be infinitely many solutions (e.g. for \f$ x y \f$ in \f$
517  	 * [0,1]^2 \f$ any point \f$ (x^*, y^*) \f$ such that \f$ y^* = 1 - x^* \f$ has infinitely many solutions). For this
518  	 * reason, we perturb any given \f$ x^* \f$. The idea is to try to get a facet of the convex/concave envelope. This only
519  	 * happens when the solution has \f$ n + 1 \f$ non zero \f$ \lambda \f$'s (i.e. the primal has a unique solution).
520  	 * -# We need to compute \f$ f(v^i) \f$ for every vertex of \f$ [\ell,u] \f$. A vertex is encoded by a number between 0
521  	 * and \f$ 2^n - 1 \f$, via its binary representation (0 bit is lower bound, 1 bit is upper bound), so we can compute
522  	 * all these values by iterating between 0 and \f$ 2^n - 1 \f$.
523  	 * -# To check that the computed cut is valid we do the following: we use a gray code to loop over the vertices
524  	 * of the box domain w.r.t. unfixed variables in order to evaluate the underestimator. To ensure the validity of the
525  	 * underestimator, we check whether \f$ \alpha v^i + \beta \le f(v^i) \f$ for every vertex \f$ v^i \f$ and adjust
526  	 * \f$ \beta \f$ if the maximal violation is small.
527  	 *
528  	 * @todo the solution is a facet if all variables of the primal have positive reduced costs (i.e. the solution is
529  	 * unique). In the dual, this means that there are \f$ n + 1 \f$ variables with positive value. Can we use this or some
530  	 * other information to handle any of both cases (point in the boundary or point in the intersection of polytopes
531  	 * defining different pieces of the convex envelope)? In the case where the point is in the boundary, can we use that
532  	 * information to maybe solve another to find a facet? How do the polytopes defining the pieces where the convex
533  	 * envelope is linear looks like, i.e, given a point in the interior of a facet of the domain, does the midpoint of the
534  	 * segment joining \f$ x^* \f$ with the center of the domain, always belongs to the interior of one of those polytopes?
535  	 */
536  	SCIP_EXPORT
537  	SCIP_RETCODE SCIPcomputeFacetVertexPolyhedralNonlinear(
538  	   SCIP*                 scip,               /**< SCIP data structure */
539  	   SCIP_CONSHDLR*        conshdlr,           /**< nonlinear constraint handler */
540  	   SCIP_Bool             overestimate,       /**< whether to compute facet of concave (TRUE) or convex (FALSE) envelope */
541  	   SCIP_DECL_VERTEXPOLYFUN((*function)),     /**< pointer to vertex polyhedral function */
542  	   void*                 fundata,            /**< data for function evaluation (can be NULL) */
543  	   SCIP_Real*            xstar,              /**< point to be separated */
544  	   SCIP_Real*            box,                /**< box where to compute facet: should be lb_1, ub_1, lb_2, ub_2... */
545  	   int                   nallvars,           /**< half of the length of box */
546  	   SCIP_Real             targetvalue,        /**< target value: no need to compute facet if value in xstar would be worse than this value */
547  	   SCIP_Bool*            success,            /**< buffer to store whether a facet could be computed successfully */
548  	   SCIP_Real*            facetcoefs,         /**< buffer to store coefficients of facet defining inequality; must be an array of length at least nallvars */
549  	   SCIP_Real*            facetconstant       /**< buffer to store constant part of facet defining inequality */
550  	   );
551  	
552  	
553  	/* Nonlinear Constraint Methods */
554  	
555  	/** returns the expression of the given nonlinear constraint */
556  	SCIP_EXPORT
557  	SCIP_EXPR* SCIPgetExprNonlinear(
558  	   SCIP_CONS*            cons                /**< constraint data */
559  	   );
560  	
561  	/** gets the left hand side of a nonlinear constraint */
562  	SCIP_EXPORT
563  	SCIP_Real SCIPgetLhsNonlinear(
564  	   SCIP_CONS*            cons                /**< constraint data */
565  	   );
566  	
567  	/** gets the right hand side of a nonlinear constraint */
568  	SCIP_EXPORT
569  	SCIP_Real SCIPgetRhsNonlinear(
570  	   SCIP_CONS*            cons                /**< constraint data */
571  	   );
572  	
573  	/** gets the nonlinear constraint as a nonlinear row representation. */
574  	SCIP_EXPORT
575  	SCIP_RETCODE SCIPgetNlRowNonlinear(
576  	   SCIP*                 scip,               /**< SCIP data structure */
577  	   SCIP_CONS*            cons,               /**< constraint */
578  	   SCIP_NLROW**          nlrow               /**< pointer to store nonlinear row */
579  	   );
580  	
581  	/** returns the curvature of the expression of a given nonlinear constraint
582  	 *
583  	 * @note The curvature information is computed during CONSINITSOL.
584  	 */
585  	SCIP_EXPORT
586  	SCIP_EXPRCURV SCIPgetCurvatureNonlinear(
587  	   SCIP_CONS*            cons                /**< constraint data */
588  	   );
589  	
590  	/** checks whether expression of constraint can be represented as quadratic form
591  	 *
592  	 * Only sets `*isquadratic` to TRUE if the whole expression is quadratic (in the non-extended formulation) and non-linear.
593  	 * That is, the expression in each \ref SCIP_QUADEXPR_QUADTERM will be a variable expressions and
594  	 * \ref SCIPgetVarExprVar() can be used to retrieve the variable.
595  	 */
596  	SCIP_EXPORT
597  	SCIP_RETCODE SCIPcheckQuadraticNonlinear(
598  	   SCIP*                    scip,               /**< SCIP data structure */
599  	   SCIP_CONS*               cons,               /**< constraint data */
600  	   SCIP_Bool*               isquadratic         /**< buffer to store whether constraint is quadratic */
601  	   );
602  	
603  	/** changes left-hand-side of a nonlinear constraint
604  	 *
605  	 * @attention This method can only be called in the problem stage.
606  	 */
607  	SCIP_EXPORT
608  	SCIP_RETCODE SCIPchgLhsNonlinear(
609  	   SCIP*                 scip,               /**< SCIP data structure */
610  	   SCIP_CONS*            cons,               /**< constraint data */
611  	   SCIP_Real             lhs                 /**< new left-hand-side */
612  	   );
613  	
614  	/** changes right-hand-side of a nonlinear constraint
615  	 *
616  	 * @attention This method can only be called in the problem stage.
617  	 */
618  	SCIP_EXPORT
619  	SCIP_RETCODE SCIPchgRhsNonlinear(
620  	   SCIP*                 scip,               /**< SCIP data structure */
621  	   SCIP_CONS*            cons,               /**< constraint data */
622  	   SCIP_Real             rhs                 /**< new right-hand-side */
623  	   );
624  	
625  	/** changes expression of a nonlinear constraint
626  	 *
627  	 * @attention This method can only be called in the problem stage.
628  	 */
629  	SCIP_EXPORT
630  	SCIP_RETCODE SCIPchgExprNonlinear(
631  	   SCIP*                 scip,               /**< SCIP data structure */
632  	   SCIP_CONS*            cons,               /**< constraint data */
633  	   SCIP_EXPR*            expr                /**< new expression */
634  	   );
635  	
636  	/** adds coef * var to nonlinear constraint
637  	 *
638  	 * @attention This method can only be called in the problem stage.
639  	 */
640  	SCIP_EXPORT
641  	SCIP_RETCODE SCIPaddLinearVarNonlinear(
642  	   SCIP*                 scip,               /**< SCIP data structure */
643  	   SCIP_CONS*            cons,               /**< constraint data */
644  	   SCIP_VAR*             var,                /**< variable */
645  	   SCIP_Real             coef                /**< coefficient */
646  	   );
647  	
648  	/** adds coef * expr to nonlinear constraint
649  	 *
650  	 * @attention This method can only be called in the problem stage.
651  	 */
652  	SCIP_EXPORT
653  	SCIP_RETCODE SCIPaddExprNonlinear(
654  	   SCIP*                 scip,               /**< SCIP data structure */
655  	   SCIP_CONS*            cons,               /**< nonlinear constraint */
656  	   SCIP_EXPR*            expr,               /**< expression */
657  	   SCIP_Real             coef                /**< coefficient */
658  	   );
659  	
660  	/** gets absolute violation of nonlinear constraint
661  	 *
662  	 * This function evaluates the constraints in the given solution.
663  	 *
664  	 * If this value is at most SCIPfeastol(), the constraint would be considered feasible.
665  	 */
666  	SCIP_EXPORT
667  	SCIP_RETCODE SCIPgetAbsViolationNonlinear(
668  	   SCIP*                 scip,               /**< SCIP data structure */
669  	   SCIP_CONS*            cons,               /**< constraint */
670  	   SCIP_SOL*             sol,                /**< solution to check */
671  	   SCIP_Real*            viol                /**< buffer to store computed violation */
672  	   );
673  	
674  	/** gets scaled violation of nonlinear constraint
675  	 *
676  	 * This function evaluates the constraints in the given solution.
677  	 *
678  	 * The scaling that is applied to the absolute violation of the constraint
679  	 * depends on the setting of parameter constraints/nonlinear/violscale.
680  	 */
681  	SCIP_EXPORT
682  	SCIP_RETCODE SCIPgetRelViolationNonlinear(
683  	   SCIP*                 scip,               /**< SCIP data structure */
684  	   SCIP_CONS*            cons,               /**< constraint */
685  	   SCIP_SOL*             sol,                /**< solution to check */
686  	   SCIP_Real*            viol                /**< buffer to store computed violation */
687  	   );
688  	
689  	/** returns a variable that appears linearly that may be decreased without making any other constraint infeasible */
690  	SCIP_EXPORT
691  	void SCIPgetLinvarMayDecreaseNonlinear(
692  	   SCIP*                 scip,               /**< SCIP data structure */
693  	   SCIP_CONS*            cons,               /**< nonlinear constraint */
694  	   SCIP_VAR**            var,                /**< pointer to store the variable */
695  	   SCIP_Real*            coef                /**< pointer to store the coefficient */
696  	   );
697  	
698  	/** returns a variable that appears linearly that may be increased without making any other constraint infeasible */
699  	SCIP_EXPORT
700  	void SCIPgetLinvarMayIncreaseNonlinear(
701  	   SCIP*                 scip,               /**< SCIP data structure */
702  	   SCIP_CONS*            cons,               /**< nonlinear constraint */
703  	   SCIP_VAR**            var,                /**< pointer to store the variable */
704  	   SCIP_Real*            coef                /**< pointer to store the coefficient */
705  	   );
706  	
707  	
708  	/* Methods for Expressions in Nonlinear Constraints
709  	 * All functions in this group assume that the expression is owned by a the nonlinear constraint handler.
710  	 */
711  	
712  	/** returns the number of positive rounding locks of an expression */
713  	SCIP_EXPORT
714  	int SCIPgetExprNLocksPosNonlinear(
715  	   SCIP_EXPR*            expr                /**< expression */
716  	   );
717  	
718  	/** returns the number of negative rounding locks of an expression */
719  	SCIP_EXPORT
720  	int SCIPgetExprNLocksNegNonlinear(
721  	   SCIP_EXPR*            expr                /**< expression */
722  	   );
723  	
724  	/** returns the variable used for linearizing a given expression (return value might be NULL)
725  	 *
726  	 * @note for variable expression it returns the corresponding variable
727  	 */
728  	SCIP_EXPORT
729  	SCIP_VAR* SCIPgetExprAuxVarNonlinear(
730  	   SCIP_EXPR*            expr                /**< expression */
731  	   );
732  	
733  	/** returns the number of enforcements for an expression */
734  	SCIP_EXPORT
735  	int SCIPgetExprNEnfosNonlinear(
736  	   SCIP_EXPR*            expr                /**< expression */
737  	   );
738  	
739  	/** returns the data for one of the enforcements of an expression */
740  	SCIP_EXPORT
741  	void SCIPgetExprEnfoDataNonlinear(
742  	   SCIP_EXPR*            expr,               /**< expression */
743  	   int                   idx,                /**< position of enforcement in enfos array */
744  	   SCIP_NLHDLR**         nlhdlr,             /**< buffer to store nlhldr */
745  	   SCIP_NLHDLREXPRDATA** nlhdlrexprdata,     /**< buffer to store nlhdlr data for expression, or NULL */
746  	   SCIP_NLHDLR_METHOD* nlhdlrparticipation, /**< buffer to store methods where nonlinear handler participates, or NULL */
747  	   SCIP_Bool*            sepabelowusesactivity, /**< buffer to store whether sepabelow uses activity of some expression, or NULL */
748  	   SCIP_Bool*            sepaaboveusesactivity, /**< buffer to store whether sepaabove uses activity of some expression, or NULL */
749  	   SCIP_Real*            auxvalue            /**< buffer to store current auxvalue, or NULL */
750  	   );
751  	
752  	/** sets the auxiliary value of expression for one of the enforcements of an expression */
753  	SCIP_EXPORT
754  	void SCIPsetExprEnfoAuxValueNonlinear(
755  	   SCIP_EXPR*            expr,               /**< expression */
756  	   int                   idx,                /**< position of enforcement in enfos array */
757  	   SCIP_Real             auxvalue            /**< the new value of auxval */
758  	   );
759  	
760  	/** number of nonlinear handlers whose activity computation and propagation methods depend on the activity of the expression
761  	 *
762  	 * @note This method can only be used after the detection methods of the nonlinear handlers have been called.
763  	 */
764  	SCIP_EXPORT
765  	unsigned int SCIPgetExprNPropUsesActivityNonlinear(
766  	   SCIP_EXPR*            expr                /**< expression */
767  	   );
768  	
769  	/** number of nonlinear handlers whose separation methods (estimate or enforcement) depend on the activity of the expression
770  	 *
771  	 * @note This method can only be used after the detection methods of the nonlinear handlers have been called.
772  	 */
773  	SCIP_EXPORT
774  	unsigned int SCIPgetExprNSepaUsesActivityNonlinear(
775  	   SCIP_EXPR*            expr                /**< expression */
776  	   );
777  	
778  	/** number of nonlinear handlers whose separation methods (estimate or enforcement) use auxiliary variable of the expression
779  	 *
780  	 * @note This method can only be used after the detection methods of the nonlinear handlers have been called.
781  	 */
782  	SCIP_EXPORT
783  	unsigned int SCIPgetExprNAuxvarUsesNonlinear(
784  	   SCIP_EXPR*            expr                /**< expression */
785  	   );
786  	
787  	/** method to be called by a nlhdlr during NLHDLRDETECT to notify an expression that it will be used
788  	 *
789  	 * - if `useauxvar` is enabled, then ensures that an auxiliary variable will be created in INITLP
790  	 * - if `useactivityforprop` or `useactivityforsepa{below,above}` is enabled, then ensured that activity will be updated for `expr`
791  	 * - if `useactivityforprop` is enabled, then increments the count returned by SCIPgetExprNPropUsesActivityNonlinear()
792  	 * - if `useactivityforsepa{below,above}` is enabled, then increments the count returned by SCIPgetExprNSepaUsesActivityNonlinear()
793  	 *   and also increments this count for all variables in the expression.
794  	 *
795  	 * The distinction into `useactivityforprop` and `useactivityforsepa{below,above}` is to recognize variables which domain influences
796  	 * under/overestimators. Domain propagation routines (like OBBT) may invest more work for these variables.
797  	 * The distinction into `useactivityforsepabelow` and `useactivityforsepaabove` is to recognize whether a nlhdlr that called this method
798  	 * will use activity of `expr` in enfomethod \ref SCIP_NLHDLR_METHOD_SEPABELOW or \ref SCIP_NLHDLR_METHOD_SEPAABOVE.
799  	 */
800  	SCIP_EXPORT
801  	SCIP_RETCODE SCIPregisterExprUsageNonlinear(
802  	   SCIP*                 scip,               /**< SCIP data structure */
803  	   SCIP_EXPR*            expr,               /**< expression */
804  	   SCIP_Bool             useauxvar,          /**< whether an auxiliary variable will be used for estimate or cut generation */
805  	   SCIP_Bool             useactivityforprop, /**< whether activity of expr will be used by domain propagation or activity calculation (inteval) */
806  	   SCIP_Bool             useactivityforsepabelow, /**< whether activity of expr will be used by underestimation */
807  	   SCIP_Bool             useactivityforsepaabove  /**< whether activity of expr will be used by overestimation */
808  	   );
809  	
810  	/** computes absolute violation for auxvar relation in an expression w.r.t. original variables
811  	 *
812  	 * Assume the expression is f(x), where x are original (i.e., not auxiliary) variables.
813  	 * Assume that f(x) is associated with auxiliary variable z.
814  	 *
815  	 * If there are negative locks, then returns the violation of z &le; f(x) and sets `violover` to TRUE.
816  	 * If there are positive locks, then returns the violation of z &ge; f(x) and sets `violunder` to TRUE.
817  	 * Of course, if there both negative and positive locks, then return the violation of z = f(x).
818  	 *
819  	 * If necessary, f is evaluated in the given solution. If that fails (domain error),
820  	 * then `viol` is set to SCIPinfinity() and both `violover` and `violunder` are set to TRUE.
821  	 */
822  	SCIP_EXPORT
823  	SCIP_RETCODE SCIPgetExprAbsOrigViolationNonlinear(
824  	   SCIP*                 scip,               /**< SCIP data structure */
825  	   SCIP_EXPR*            expr,               /**< expression */
826  	   SCIP_SOL*             sol,                /**< solution */
827  	   SCIP_Longint          soltag,             /**< tag of solution */
828  	   SCIP_Real*            viol,               /**< buffer to store computed violation */
829  	   SCIP_Bool*            violunder,          /**< buffer to store whether z >= f(x) is violated, or NULL */
830  	   SCIP_Bool*            violover            /**< buffer to store whether z <= f(x) is violated, or NULL */
831  	   );
832  	
833  	/** computes absolute violation for auxvar relation in an expression w.r.t. auxiliary variables
834  	 *
835  	 * Assume the expression is f(w), where w are auxiliary variables that were introduced by some nlhdlr.
836  	 * Assume that f(w) is associated with auxiliary variable z.
837  	 *
838  	 * If there are negative locks, then returns the violation of z &le; f(w) and sets `violover` to TRUE.
839  	 * If there are positive locks, then returns the violation of z &ge; f(w) and sets `violunder` to TRUE.
840  	 * Of course, if there both negative and positive locks, then return the violation of z = f(w).
841  	 *
842  	 * If the given value of f(w) is SCIP_INVALID, then `viol` is set to SCIPinfinity() and
843  	 * both `violover` and `violunder` are set to TRUE.
844  	 */
845  	SCIP_EXPORT
846  	SCIP_RETCODE SCIPgetExprAbsAuxViolationNonlinear(
847  	   SCIP*                 scip,               /**< SCIP data structure */
848  	   SCIP_EXPR*            expr,               /**< expression */
849  	   SCIP_Real             auxvalue,           /**< the value of f(w) */
850  	   SCIP_SOL*             sol,                /**< solution that has been evaluated */
851  	   SCIP_Real*            viol,               /**< buffer to store computed violation */
852  	   SCIP_Bool*            violunder,          /**< buffer to store whether z >= f(w) is violated, or NULL */
853  	   SCIP_Bool*            violover            /**< buffer to store whether z <= f(w) is violated, or NULL */
854  	   );
855  	
856  	/** computes relative violation for auxvar relation in an expression w.r.t. auxiliary variables
857  	 *
858  	 * Assume the expression is f(w), where w are auxiliary variables that were introduced by some nlhdlr.
859  	 * Assume that f(w) is associated with auxiliary variable z.
860  	 *
861  	 * Taking the absolute violation from SCIPgetExprAbsAuxViolationNonlinear(), this function returns
862  	 * the absolute violation divided by max(1,|f(w)|).
863  	 *
864  	 * If the given value of f(w) is SCIP_INVALID, then `viol` is set to SCIPinfinity() and
865  	 * both `violover` and `violunder` are set to TRUE.
866  	 */
867  	SCIP_EXPORT
868  	SCIP_RETCODE SCIPgetExprRelAuxViolationNonlinear(
869  	   SCIP*                 scip,               /**< SCIP data structure */
870  	   SCIP_EXPR*            expr,               /**< expression */
871  	   SCIP_Real             auxvalue,           /**< the value of f(w) */
872  	   SCIP_SOL*             sol,                /**< solution that has been evaluated */
873  	   SCIP_Real*            viol,               /**< buffer to store computed violation */
874  	   SCIP_Bool*            violunder,          /**< buffer to store whether z >= f(w) is violated, or NULL */
875  	   SCIP_Bool*            violover            /**< buffer to store whether z <= f(w) is violated, or NULL */
876  	   );
877  	
878  	/** returns bounds on the expression
879  	 *
880  	 * This gives an intersection of bounds from
881  	 * - activity calculation (SCIPexprGetActivity()), if valid,
882  	 * - auxiliary variable, if present,
883  	 * - stored by SCIPtightenExprIntervalNonlinear() during domain propagation
884  	 *
885  	 * @note The returned interval can be empty!
886  	 */
887  	SCIP_EXPORT
888  	SCIP_INTERVAL SCIPgetExprBoundsNonlinear(
889  	   SCIP*                 scip,               /**< SCIP data structure */
890  	   SCIP_EXPR*            expr                /**< expression */
891  	   );
892  	
893  	/** informs the expression about new bounds that can be used for reverse-propagation and to tighten bounds of
894  	 * corresponding (auxiliary) variable (if any)
895  	 *
896  	 * @attention this function should only be called during domain propagation in cons_nonlinear
897  	 */
898  	SCIP_EXPORT
899  	SCIP_RETCODE SCIPtightenExprIntervalNonlinear(
900  	   SCIP*                 scip,               /**< SCIP data structure */
901  	   SCIP_EXPR*            expr,               /**< expression to be tightened */
902  	   SCIP_INTERVAL         newbounds,          /**< new bounds for the expression */
903  	   SCIP_Bool*            cutoff,             /**< buffer to store whether a cutoff was detected */
904  	   int*                  ntightenings        /**< buffer to add the total number of tightenings, or NULL */
905  	   );
906  	
907  	/** mark constraints that include this expression to be propagated again
908  	 *
909  	 * This can be used by, e.g., nlhdlrs, to trigger a new propagation of constraints without
910  	 * a change of variable bounds, e.g., because new information on the expression is available
911  	 * that could potentially lead to tighter expression activity values.
912  	 *
913  	 * Note, that this call marks also constraints for propagation which only share some variable
914  	 * with this expression.
915  	 */
916  	SCIP_EXPORT
917  	SCIP_RETCODE SCIPmarkExprPropagateNonlinear(
918  	   SCIP*                 scip,               /**< SCIP data structure */
919  	   SCIP_EXPR*            expr                /**< expression to propagate again */
920  	   );
921  	
922  	/** adds violation-branching score to an expression
923  	 *
924  	 * Adds a score to the expression-specific violation-branching score, thereby marking it as branching candidate.
925  	 * The expression must either be a variable expression or have an aux-variable.
926  	 * In the latter case, branching on auxiliary variables must have been enabled.
927  	 * In case of doubt, use SCIPaddExprsViolScoreNonlinear(). Roughly, the difference between these functions is that the current
928  	 * function adds `violscore` to the expression directly, while SCIPaddExprsViolScoreNonlinear() will split the
929  	 * violation score among all the given expressions according to parameter constraints/nonlinear/branching/violsplit.
930  	 *
931  	 * @see SCIPaddExprsViolScoreNonlinear()
932  	 */
933  	SCIP_EXPORT
934  	void SCIPaddExprViolScoreNonlinear(
935  	   SCIP*                 scip,               /**< SCIP data structure */
936  	   SCIP_EXPR*            expr,               /**< expression where to add branching score */
937  	   SCIP_Real             violscore           /**< violation score to add to expression */
938  	   );
939  	
940  	/** adds violation-branching score to a set of expressions, distributing the score among all the expressions
941  	 *
942  	 * Each expression must either be a variable expression or have an aux-variable.
943  	 * If branching on aux-variables is disabled, then the violation branching score will be distributed among all
944  	 * variables present in `exprs`.
945  	 */
946  	SCIP_EXPORT
947  	SCIP_RETCODE SCIPaddExprsViolScoreNonlinear(
948  	   SCIP*                 scip,               /**< SCIP data structure */
949  	   SCIP_EXPR**           exprs,              /**< expressions where to add branching score */
950  	   int                   nexprs,             /**< number of expressions */
951  	   SCIP_Real             violscore,          /**< violation score to add to expression */
952  	   SCIP_SOL*             sol,                /**< current solution */
953  	   SCIP_Bool*            success             /**< buffer to store whether at least one violscore was added */
954  	   );
955  	
956  	/** gives violation-branching score stored in expression, or 0.0 if no valid score has been stored */
957  	SCIP_EXPORT
958  	SCIP_Real SCIPgetExprViolScoreNonlinear(
959  	   SCIP_EXPR*            expr                /**< expression */
960  	   );
961  	
962  	/** returns the partial derivative of an expression w.r.t. a variable (or SCIP_INVALID if there was an evaluation error)
963  	 *
964  	 * @see SCIPexprGetDerivative()
965  	 */
966  	SCIP_EXPORT
967  	SCIP_Real SCIPgetExprPartialDiffNonlinear(
968  	   SCIP*                 scip,               /**< SCIP data structure */
969  	   SCIP_EXPR*            expr,               /**< root expression of constraint used in the last SCIPevalExprGradient() call */
970  	   SCIP_VAR*             var                 /**< variable (needs to be in the expression) */
971  	   );
972  	
973  	/** returns the var's coordinate of Hu partial derivative of an expression w.r.t. a variable (or SCIP_INVALID if there was an evaluation error)
974  	 *
975  	 * @see SCIPexprGetBardot()
976  	 */
977  	SCIP_EXPORT
978  	SCIP_Real SCIPgetExprPartialDiffGradientDirNonlinear(
979  	   SCIP*                 scip,               /**< SCIP data structure */
980  	   SCIP_EXPR*            expr,               /**< root expression of constraint used in the last SCIPevalExprHessianDir() call */
981  	   SCIP_VAR*             var                 /**< variable (needs to be in the expression) */
982  	   );
983  	
984  	/** evaluates quadratic term in a solution w.r.t. auxiliary variables
985  	 *
986  	 * \note This requires that for every expr used in the quadratic data, a variable or auxiliary variable is available.
987  	 */
988  	SCIP_EXPORT
989  	SCIP_Real SCIPevalExprQuadraticAuxNonlinear(
990  	   SCIP*                 scip,               /**< SCIP data structure */
991  	   SCIP_EXPR*            expr,               /**< quadratic expression */
992  	   SCIP_SOL*             sol                 /**< solution to evaluate, or NULL for LP solution */
993  	   );
994  	
995  	/** @} */
996  	/** @} */
997  	
998  	/**@addtogroup PublicNlhdlrInterfaceMethods
999  	 * @{
1000 	 */
1001 	
1002 	/** creates a nonlinear handler and includes it into the nonlinear constraint handler */
1003 	SCIP_EXPORT
1004 	SCIP_RETCODE SCIPincludeNlhdlrNonlinear(
1005 	   SCIP*                 scip,               /**< SCIP data structure */
1006 	   SCIP_NLHDLR**         nlhdlr,             /**< buffer where to store nonlinear handler */
1007 	   const char*           name,               /**< name of nonlinear handler (must not be NULL) */
1008 	   const char*           desc,               /**< description of nonlinear handler (can be NULL) */
1009 	   int                   detectpriority,     /**< detection priority of nonlinear handler */
1010 	   int                   enfopriority,       /**< enforcement priority of nonlinear handler */
1011 	   SCIP_DECL_NLHDLRDETECT((*detect)),        /**< structure detection callback of nonlinear handler */
1012 	   SCIP_DECL_NLHDLREVALAUX((*evalaux)),      /**< auxiliary evaluation callback of nonlinear handler */
1013 	   SCIP_NLHDLRDATA*      nlhdlrdata          /**< data of nonlinear handler (can be NULL) */
1014 	   );
1015 	
1016 	/** get number of nonlinear handler */
1017 	SCIP_EXPORT
1018 	int SCIPgetNNlhdlrsNonlinear(
1019 	   SCIP_CONSHDLR*        conshdlr            /**< nonlinear constraint handler */
1020 	   );
1021 	
1022 	/** get nonlinear handlers */
1023 	SCIP_EXPORT
1024 	SCIP_NLHDLR** SCIPgetNlhdlrsNonlinear(
1025 	   SCIP_CONSHDLR*        conshdlr            /**< nonlinear constraint handler */
1026 	   );
1027 	/** returns a nonlinear handler of a given name (or NULL if not found) */
1028 	SCIP_EXPORT
1029 	SCIP_NLHDLR* SCIPfindNlhdlrNonlinear(
1030 	   SCIP_CONSHDLR*        conshdlr,           /**< nonlinear constraint handler */
1031 	   const char*           name                /**< name of nonlinear handler */
1032 	   );
1033 	
1034 	/** gives expression data that a given nonlinear handler stored in an expression
1035 	 *
1036 	 * Returns NULL if expr has not been detected by nlhdlr or nlhdlr did not store data.
1037 	 */
1038 	SCIP_EXPORT
1039 	SCIP_NLHDLREXPRDATA* SCIPgetNlhdlrExprDataNonlinear(
1040 	   SCIP_NLHDLR*          nlhdlr,             /**< nonlinear handler */
1041 	   SCIP_EXPR*            expr                /**< expression */
1042 	   );
1043 	
1044 	/** @} */
1045 	
1046 	#ifdef __cplusplus
1047 	}
1048 	#endif
1049 	
1050 	#endif
1051