Scippy

SCIP

Solving Constraint Integer Programs

type_nlhdlr.h
Go to the documentation of this file.
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 scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file type_nlhdlr.h
17  * @ingroup TYPEDEFINITIONS
18  * @brief type definitions related to nonlinear handlers of nonlinear constraints
19  * @author Ksenia Bestuzheva
20  * @author Benjamin Mueller
21  * @author Felipe Serrano
22  * @author Stefan Vigerske
23  *
24  * This file defines the interface for nonlinear handlers.
25  *
26  * - \ref NLHDLRS "List of available nonlinear handlers"
27  */
28 
29 /** @defgroup DEFPLUGINS_NLHDLR Default nonlinear handlers
30  * @ingroup DEFPLUGINS
31  * @brief implementation files (.c files) of the default nonlinear handlers of SCIP
32  */
33 
34 #ifndef SCIP_TYPE_NLHDLR_H_
35 #define SCIP_TYPE_NLHDLR_H_
36 
37 #include "scip/type_expr.h"
38 #include "scip/type_cons.h"
39 #include "scip/type_misc.h"
40 
41 #define SCIP_NLHDLR_METHOD_NONE 0x0u /**< no enforcement */
42 #define SCIP_NLHDLR_METHOD_SEPABELOW 0x1u /**< separation for expr <= auxvar, thus might estimate expr from below */
43 #define SCIP_NLHDLR_METHOD_SEPAABOVE 0x2u /**< separation for expr >= auxvar, thus might estimate expr from above */
44 #define SCIP_NLHDLR_METHOD_SEPABOTH (SCIP_NLHDLR_METHOD_SEPABELOW | SCIP_NLHDLR_METHOD_SEPAABOVE) /**< separation for expr == auxvar */
45 #define SCIP_NLHDLR_METHOD_ACTIVITY 0x4u /**< activity computation (interval evaluation) and propagation (reverse propagation) */
46 #define SCIP_NLHDLR_METHOD_ALL (SCIP_NLHDLR_METHOD_SEPABOTH | SCIP_NLHDLR_METHOD_ACTIVITY) /**< all enforcement methods */
47 
48 typedef unsigned int SCIP_NLHDLR_METHOD; /**< nlhdlr methods bitflags */
49 
50 /** nonlinear handler copy callback
51  *
52  * The method includes the nonlinear handler into a nonlinear constraint handler.
53  *
54  * This method is usually called when doing a copy of a nonlinear constraint handler.
55  *
56  * \param[in] targetscip target SCIP main data structure
57  * \param[in] targetconshdlr target nonlinear constraint handler
58  * \param[out] sourceconshdlr nonlinear constraint handler in source SCIP
59  * \param[out] sourcenlhdlr nonlinear handler in source SCIP
60  */
61 #define SCIP_DECL_NLHDLRCOPYHDLR(x) SCIP_RETCODE x (\
62  SCIP* targetscip, \
63  SCIP_CONSHDLR* targetconshdlr, \
64  SCIP_CONSHDLR* sourceconshdlr, \
65  SCIP_NLHDLR* sourcenlhdlr)
66 
67 /** callback to free data of handler
68  *
69  * \param[in] scip SCIP data structure
70  * \param[in] nlhdlr nonlinear handler
71  * \param[in] nlhdlrdata nonlinear handler data to be freed
72  */
73 #define SCIP_DECL_NLHDLRFREEHDLRDATA(x) SCIP_RETCODE x (\
74  SCIP* scip, \
75  SCIP_NLHDLR* nlhdlr, \
76  SCIP_NLHDLRDATA** nlhdlrdata)
77 
78 /** callback to free expression specific data
79  *
80  * \param[in] scip SCIP data structure
81  * \param[in] nlhdlr nonlinear handler
82  * \param[in] expr expression
83  * \param[in] nlhdlrexprdata nonlinear handler expression data to be freed
84  */
85 #define SCIP_DECL_NLHDLRFREEEXPRDATA(x) SCIP_RETCODE x (\
86  SCIP* scip, \
87  SCIP_NLHDLR* nlhdlr, \
88  SCIP_EXPR* expr, \
89  SCIP_NLHDLREXPRDATA** nlhdlrexprdata)
90 
91 /** callback to be called in initialization (called after problem was transformed)
92  *
93  * \param[in] scip SCIP data structure
94  * \param[in] nlhdlr nonlinear handler
95  */
96 #define SCIP_DECL_NLHDLRINIT(x) SCIP_RETCODE x (\
97  SCIP* scip, \
98  SCIP_NLHDLR* nlhdlr)
99 
100 /** callback to be called in deinitialization (called before transformed problem is freed)
101  *
102  * \param[in] scip SCIP data structure
103  * \param[in] nlhdlr nonlinear handler
104  */
105 #define SCIP_DECL_NLHDLREXIT(x) SCIP_RETCODE x (\
106  SCIP* scip, \
107  SCIP_NLHDLR* nlhdlr)
108 
109 /** callback to detect structure in expression
110  *
111  * The nonlinear handler shall analyze the current expression and decide whether it wants to contribute
112  * in enforcing the relation between this expression (`expr`) and its descendants (e.g., children) via
113  * linear under- or overestimation, cut generation, and/or activity computation and propagation.
114  * For linear under- or overestimation and cut generation, an auxiliary variable (`auxvar`) can be assumed to
115  * be associated with `expr` and auxiliary variables may be requested in descendant expressions.
116  *
117  * We distinguish the following enforcement methods:
118  * - \ref SCIP_NLHDLR_METHOD_SEPABELOW : linear underestimation of `expr` or cut generation for the relation `expr` &le; `auxvar` (denoted as "below")
119  * - \ref SCIP_NLHDLR_METHOD_SEPAABOVE : linear overestimation of `expr` or cut generation for the relation `expr` &ge; `auxvar` (denoted as "above")
120  * - \ref SCIP_NLHDLR_METHOD_ACTIVITY : domain propagation (i.e., constant under/overestimation) for the relation `expr` = `auxvar`.
121  *
122  * On input, parameter `enforcing` indicates for any of these methods, whether
123  * - it is not necessary to have such a method, e.g., because no `auxvar` will exist for `expr`, or no one uses or sets activities of this expression,
124  * or because analysis of the expression has shown that a relation like `expr` &ge; `auxvar` is not necessary to be satisfied,
125  * - or there already exists a nonlinear handler that will provide this method in an "enforcement" sense, that is,
126  * it believes that no one else could provide this method in a stronger sense. (This is mainly used by nlhdlr_default to check whether
127  * it should still reach out to the exprhdlr or whether it would be dominated by some nonlinear handler.)
128  *
129  * The DETECT callback shall augment the `enforcing` bitmask by setting the enforcement methods it wants to provide in an "enforcement" sense.
130  *
131  * Additionally, the `participating` bitmask shall be set if the nonlinear handler wants to be called on this expression at all.
132  * Here, it shall set all methods that it wants to provide, which are those set in `enforcing`, but additionally those where it wants
133  * to participate but leave enforcement to another nonlinear handler.
134  * This can be useful for nonlinear handlers that do not implement a complete enforcement, e.g., a handler that only contributes
135  * cutting planes in some situations only.
136  *
137  * A nonlinear handler will be called only for those callbacks that it mentioned in `participating`, which is
138  * - \ref SCIP_DECL_NLHDLRENFO "ENFO" and/or \ref SCIP_DECL_NLHDLRESTIMATE "ESTIMATE" will be called with `overestimate==FALSE` if \ref SCIP_NLHDLR_METHOD_SEPABELOW has been set
139  * - \ref SCIP_DECL_NLHDLRENFO "ENFO" and/or \ref SCIP_DECL_NLHDLRESTIMATE "ESTIMATE" will be called with `overestimate==TRUE` if \ref SCIP_NLHDLR_METHOD_SEPAABOVE has been set
140  * - \ref SCIP_DECL_NLHDLRINTEVAL "INTEVAL" and/or \ref SCIP_DECL_NLHDLRREVERSEPROP "REVERSEPROP" will be called if \ref SCIP_NLHDLR_METHOD_ACTIVITY has been set
141  *
142  * If \ref SCIP_NLHDLR_METHOD_SEPABELOW or \ref SCIP_NLHDLR_METHOD_SEPAABOVE has been set, then at least one of the
143  * callbacks \ref SCIP_DECL_NLHDLRENFO "ENFO" and \ref SCIP_DECL_NLHDLRESTIMATE "ESTIMATE" needs to be implemented.
144  * Also \ref SCIP_DECL_NLHDLREVALAUX "EVALAUX" will be called in this case.
145  * If \ref SCIP_NLHDLR_METHOD_ACTIVITY has been set, then at least one of \ref SCIP_DECL_NLHDLRINTEVAL "INTEVAL" and
146  * \ref SCIP_DECL_NLHDLRREVERSEPROP "REVERSEPROP" needs to be implemented.
147  * If the nonlinear handler chooses not to participate, then it must not set `nlhdlrexprdata` and can leave `participating` at its
148  * initial value (\ref SCIP_NLHDLR_METHOD_NONE).
149  *
150  * Additionally, a nonlinear handler that decides to participate in any of the enforcement methods must call
151  * @ref SCIPregisterExprUsageNonlinear() for every subexpression that it will use and indicate whether
152  * - it will use an auxiliary variable in \ref SCIP_DECL_NLHDLRENFO "ENFO" or \ref SCIP_DECL_NLHDLRESTIMATE "ESTIMATE",
153  * - it will use activity for some subexpressions when computing estimators or cuts, and
154  * - it will use activity for some subexpressions when in \ref SCIP_DECL_NLHDLRINTEVAL "INTEVAL" or \ref SCIP_DECL_NLHDLRREVERSEPROP "REVERSEPROP".
155  *
156  * @note Auxiliary variables do not exist in subexpressions during DETECT and are not created by a call to @ref SCIPregisterExprUsageNonlinear().
157  * They will be available when the \ref SCIP_DECL_NLHDLRINITSEPA "INITSEPA" callback is called.
158  *
159  * \param[in] scip SCIP data structure
160  * \param[in] conshdlr nonlinear constraint handler
161  * \param[in] nlhdlr nonlinear handler
162  * \param[in] expr expression to analyze
163  * \param[in] cons the constraint that expression defines, or NULL when the expr does not define any constraint, that is, when it is not the root of an expression of a constraint
164  * \param[in,out] enforcing enforcement methods that are provided by some nonlinear handler (to be updated by detect callback)
165  * \param[out] participating enforcement methods that this nonlinear handler should be called for (to be set by detect callback), initialized to SCIP_NLHDLR_METHOD_NONE
166  * \param[out] nlhdlrexprdata nlhdlr's expr data to be stored in expr, can only be set to non-NULL if success is set to TRUE
167  */
168 #define SCIP_DECL_NLHDLRDETECT(x) SCIP_RETCODE x (\
169  SCIP* scip, \
170  SCIP_CONSHDLR* conshdlr, \
171  SCIP_NLHDLR* nlhdlr, \
172  SCIP_EXPR* expr, \
173  SCIP_CONS* cons, \
174  SCIP_NLHDLR_METHOD* enforcing, \
175  SCIP_NLHDLR_METHOD* participating, \
176  SCIP_NLHDLREXPRDATA** nlhdlrexprdata)
177 
178 /** auxiliary evaluation callback of nonlinear handler
179  *
180  * Evaluates the expression w.r.t. the auxiliary variables that were introduced by the nonlinear handler (if any).
181  * The method is used to determine the violation of the relation that the nonlinear handler attempts to enforce.
182  * During enforcement, this violation value is used to decide whether estimation/separation callbacks should be called.
183  *
184  * It can be assumed that the expression itself has been evaluated in the given sol.
185  *
186  * \param[in] scip SCIP data structure
187  * \param[in] nlhdlr nonlinear handler
188  * \param[in] expr expression to evaluate
189  * \param[in] nlhdlrexprdata expression specific data of the nonlinear handler
190  * \param[out] auxvalue buffer to store value of expression w.r.t. auxiliary variables
191  * \param[in] sol point to evaluate
192  */
193 #define SCIP_DECL_NLHDLREVALAUX(x) SCIP_RETCODE x (\
194  SCIP* scip, \
195  SCIP_NLHDLR* nlhdlr, \
196  SCIP_EXPR* expr, \
197  SCIP_NLHDLREXPRDATA* nlhdlrexprdata, \
198  SCIP_Real* auxvalue, \
199  SCIP_SOL* sol)
200 
201 /** nonlinear handler interval evaluation (activity computation) callback
202  *
203  * The method computes an interval that contains the image (range) of the expression.
204  *
205  * \param[in] scip SCIP main data structure
206  * \param[in] nlhdlr nonlinear handler
207  * \param[in] expr expression
208  * \param[in] nlhdlrexprdata expression specific data of the nonlinear handler
209  * \param[in,out] interval buffer where to store interval (on input: current interval for expr, on output: computed interval for expr)
210  * \param[in] intevalvar callback to be called when interval evaluating a variable
211  * \param[in] intevalvardata data to be passed to intevalvar callback
212  */
213 #define SCIP_DECL_NLHDLRINTEVAL(x) SCIP_RETCODE x (\
214  SCIP* scip, \
215  SCIP_NLHDLR* nlhdlr, \
216  SCIP_EXPR* expr, \
217  SCIP_NLHDLREXPRDATA* nlhdlrexprdata, \
218  SCIP_INTERVAL* interval, \
219  SCIP_DECL_EXPR_INTEVALVAR((*intevalvar)), \
220  void* intevalvardata)
221 
222 /** nonlinear handler callback for reverse propagation
223  *
224  * The method propagates the given bounds over the arguments of an expression.
225  * The arguments of an expression are other expressions and the tighter intervals should be passed
226  * to the corresponding argument (expression) via SCIPtightenExprIntervalNonlinear().
227  *
228  * \param[in] scip SCIP main data structure
229  * \param[in] conshdlr nonlinear constraint handler
230  * \param[in] nlhdlr nonlinear handler
231  * \param[in] expr expression
232  * \param[in] nlhdlrexprdata expression specific data of the nonlinear handler
233  * \param[in] bounds the bounds on the expression that should be propagated
234  * \param[out] infeasible buffer to store whether an expression's bounds were propagated to an empty interval
235  * \param[out] nreductions buffer to store the number of interval reductions of all children
236  */
237 #define SCIP_DECL_NLHDLRREVERSEPROP(x) SCIP_RETCODE x (\
238  SCIP* scip, \
239  SCIP_CONSHDLR* conshdlr, \
240  SCIP_NLHDLR* nlhdlr, \
241  SCIP_EXPR* expr, \
242  SCIP_NLHDLREXPRDATA* nlhdlrexprdata, \
243  SCIP_INTERVAL bounds, \
244  SCIP_Bool* infeasible, \
245  int* nreductions)
246 
247 /** separation initialization method of a nonlinear handler (called during CONSINITLP)
248  *
249  * The method shall initialize the separation data of the nonlinear handler, if any, and add initial cuts to the LP relaxation.
250  *
251  * \param[in] scip SCIP main data structure
252  * \param[in] conshdlr nonlinear constraint handler
253  * \param[in] cons nonlinear constraint
254  * \param[in] nlhdlr nonlinear handler
255  * \param[in] nlhdlrexprdata exprdata of nonlinear handler
256  * \param[in] expr expression
257  * \param[in] overestimate whether the expression needs to be overestimated
258  * \param[in] underestimate whether the expression needs to be underestimated
259  * \param[out] infeasible buffer to store whether infeasibility was detected while building the LP
260  */
261 #define SCIP_DECL_NLHDLRINITSEPA(x) SCIP_RETCODE x (\
262  SCIP* scip, \
263  SCIP_CONSHDLR* conshdlr, \
264  SCIP_CONS* cons, \
265  SCIP_NLHDLR* nlhdlr, \
266  SCIP_EXPR* expr, \
267  SCIP_NLHDLREXPRDATA* nlhdlrexprdata, \
268  SCIP_Bool overestimate, \
269  SCIP_Bool underestimate, \
270  SCIP_Bool* infeasible)
271 
272 /** separation deinitialization method of a nonlinear handler (called during CONSEXITSOL)
273  *
274  * The method shall deinitialize the separation data of the nonlinear handler, if any.
275  *
276  * \param[in] scip SCIP main data structure
277  * \param[in] nlhdlr nonlinear handler
278  * \param[in] nlhdlrexprdata exprdata of nonlinear handler
279  * \param[in] expr expression
280  */
281 #define SCIP_DECL_NLHDLREXITSEPA(x) SCIP_RETCODE x (\
282  SCIP* scip, \
283  SCIP_NLHDLR* nlhdlr, \
284  SCIP_EXPR* expr, \
285  SCIP_NLHDLREXPRDATA* nlhdlrexprdata)
286 
287 /** nonlinear handler separation and enforcement callback
288  *
289  * The method tries to separate the given solution from the set defined by either
290  * <pre>
291  * expr - auxvar <= 0 (if !overestimate)
292  * </pre>
293  * or
294  * <pre>
295  * expr - auxvar >= 0 (if overestimate),
296  * </pre>
297  * where `auxvar = SCIPgetExprAuxVarNonlinear(expr)`.
298  *
299  * It can do so by
300  * - separation, i.e., finding an affine hyperplane (a cut) that separates the given point,
301  * - bound tightening, i.e., changing bounds on a variable so that the given point is outside the updated domain,
302  * - adding branching scores to potentially split the current problem into 2 subproblems
303  *
304  * If parameter `inenforcement` is FALSE, then only the first option (separation) is allowed.
305  *
306  * If the nonlinear handler always separates by computing a linear under- or overestimator of expr,
307  * then it could be advantageous to implement the \ref SCIP_DECL_NLHDLRESTIMATE "ESTIMATE" callback instead.
308  *
309  * Note, that the nonlinear handler may also choose to separate for a relaxation of the mentioned sets,
310  * e.g., `expr` &le; upperbound(`auxvar`) or `expr` &ge; lowerbound(`auxvar`).
311  * This is especially useful in situations where `expr` is the root expression of a constraint
312  * and it is sufficient to satisfy `lhs` &le; `expr` &le; `rhs`.
313  * cons_nonlinear ensures that `lhs` &le; lowerbound(`auxvar`) and upperbound(`auxvar`) &le; `rhs`.
314  *
315  * cons_nonlinear may call this callback first with `allowweakcuts` = FALSE and repeat later with
316  * `allowweakcuts` = TRUE, if it didn't succeed to enforce a solution without using weak cuts.
317  * If in enforcement and the nonlinear handler cannot enforce by separation or bound tightening, it should register
318  * branching scores for those expressions where branching may help to compute tighter cuts in children.
319  *
320  * The nonlinear handler must set `result` to \ref SCIP_SEPARATED if it added a cut,
321  * to \ref SCIP_REDUCEDDOM if it added a bound change, and
322  * to \ref SCIP_BRANCHED if it added branching scores.
323  * Otherwise, it may set result to \ref SCIP_DIDNOTRUN or \ref SCIP_DIDNOTFIND.
324  *
325  * Parameter `cons` gives the constraint that is currently enforced.
326  * Note that `expr` does not need to be the root of this constraint, i.e., `SCIPgetExprNonlinear(cons)==expr` may not hold.
327  * If an expression appears in several constraints, it is not well defined which constraint is given in `cons`.
328  * The main purpose of `cons` is to provide a constraint source for LP rows that are added in this callback.
329  *
330  * \param[in] scip SCIP main data structure
331  * \param[in] conshdlr nonlinear constraint handler
332  * \param[in] cons nonlinear constraint that is currently enforced
333  * \param[in] nlhdlr nonlinear handler
334  * \param[in] expr expression
335  * \param[in] nlhdlrexprdata expression specific data of the nonlinear handler
336  * \param[in] sol solution to be separated (NULL for the LP solution)
337  * \param[in] auxvalue current value of expression w.r.t. auxiliary variables as obtained from \ref SCIP_DECL_NLHDLREVALAUX "EVALAUX"
338  * \param[in] overestimate whether the expression needs to be over- or underestimated
339  * \param[in] allowweakcuts whether we should only look for "strong" cuts, or anything that separates is fine
340  * \param[in] separated whether another nonlinear handler already added a cut for this expression
341  * \param[in] inenforcement whether we are in enforcement, or only in separation
342  * \param[out] result pointer to store the result
343  */
344 #define SCIP_DECL_NLHDLRENFO(x) SCIP_RETCODE x (\
345  SCIP* scip, \
346  SCIP_CONSHDLR* conshdlr, \
347  SCIP_CONS* cons, \
348  SCIP_NLHDLR* nlhdlr, \
349  SCIP_EXPR* expr, \
350  SCIP_NLHDLREXPRDATA* nlhdlrexprdata, \
351  SCIP_SOL* sol, \
352  SCIP_Real auxvalue, \
353  SCIP_Bool overestimate, \
354  SCIP_Bool allowweakcuts, \
355  SCIP_Bool separated, \
356  SCIP_Bool addbranchscores, \
357  SCIP_RESULT* result)
358 
359 /** nonlinear handler under/overestimation callback
360  *
361  * The method tries to compute linear under- or overestimators of `expr` that are as tight as possible at a given point.
362  * If the value of the estimator in the solution is smaller (larger) than `targetvalue`
363  * when underestimating (overestimating), then no estimator needs to be computed.
364  * Note, that `targetvalue` can be infinite if any estimator will be accepted.
365  * If successful, it shall store the estimators in the given `rowpreps` data structure and set the
366  * `rowprep->local` flag accordingly (SCIProwprepSetLocal()).
367  * The sidetype of a rowprep must be set to \ref SCIP_SIDETYPE_LEFT if overestimating and
368  * \ref SCIP_SIDETYPE_RIGHT if underestimating.
369  *
370  * If the callback is required to indicate for which expression a reduction in the local bounds (usually by branching)
371  * would improve the estimator, it shall do so via calls to SCIPaddExprsViolScoreNonlinear().
372  *
373  * \param[in] scip SCIP main data structure
374  * \param[in] conshdlr constraint handler
375  * \param[in] nlhdlr nonlinear handler
376  * \param[in] expr expression
377  * \param[in] nlhdlrexprdata expression data of nonlinear handler
378  * \param[in] sol solution at which to estimate (NULL for the LP solution)
379  * \param[in] auxvalue current value of expression w.r.t. auxiliary variables as obtained from \ref SCIP_DECL_NLHDLREVALAUX "EVALAUX"
380  * \param[in] overestimate whether the expression needs to be over- or underestimated
381  * \param[in] targetvalue a value the estimator shall exceed, can be +/-infinity
382  * \param[in] addbranchscores indicates whether to register branching scores
383  * \param[out] rowpreps an array where to store the estimators
384  * \param[out] success buffer to indicate whether an estimator could be computed
385  * \param[out] addedbranchscores buffer to store whether the branching score callback was successful
386  */
387 #define SCIP_DECL_NLHDLRESTIMATE(x) SCIP_RETCODE x (\
388  SCIP* scip, \
389  SCIP_CONSHDLR* conshdlr, \
390  SCIP_NLHDLR* nlhdlr, \
391  SCIP_EXPR* expr, \
392  SCIP_NLHDLREXPRDATA* nlhdlrexprdata, \
393  SCIP_SOL* sol, \
394  SCIP_Real auxvalue, \
395  SCIP_Bool overestimate, \
396  SCIP_Real targetvalue, \
397  SCIP_Bool addbranchscores, \
398  SCIP_PTRARRAY* rowpreps, \
399  SCIP_Bool* success, \
400  SCIP_Bool* addedbranchscores)
401 
402 typedef struct SCIP_Nlhdlr SCIP_NLHDLR; /**< nonlinear handler */
403 typedef struct SCIP_NlhdlrData SCIP_NLHDLRDATA; /**< nonlinear handler data */
404 typedef struct SCIP_NlhdlrExprData SCIP_NLHDLREXPRDATA; /**< nonlinear handler data for a specific expression */
405 
406 #endif /* SCIP_TYPE_NLHDLR_H_ */
type definitions for miscellaneous datastructures
unsigned int SCIP_NLHDLR_METHOD
Definition: type_nlhdlr.h:48
type and macro definitions related to algebraic expressions
struct SCIP_NlhdlrExprData SCIP_NLHDLREXPRDATA
Definition: type_nlhdlr.h:404
struct SCIP_NlhdlrData SCIP_NLHDLRDATA
Definition: type_nlhdlr.h:403
type definitions for constraints and constraint handlers