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   scip_cut.c
26   	 * @ingroup OTHER_CFILES
27   	 * @brief  public methods for cuts and aggregation rows
28   	 * @author Tobias Achterberg
29   	 * @author Timo Berthold
30   	 * @author Gerald Gamrath
31   	 * @author Leona Gottwald
32   	 * @author Stefan Heinz
33   	 * @author Gregor Hendel
34   	 * @author Thorsten Koch
35   	 * @author Alexander Martin
36   	 * @author Marc Pfetsch
37   	 * @author Michael Winkler
38   	 * @author Kati Wolter
39   	 *
40   	 * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
41   	 */
42   	
43   	/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
44   	
45   	#include "scip/cutpool.h"
46   	#include "scip/debug.h"
47   	#include "scip/lp.h"
48   	#include "scip/prob.h"
49   	#include "scip/pub_cutpool.h"
50   	#include "scip/pub_lp.h"
51   	#include "scip/pub_message.h"
52   	#include "scip/scip_conflict.h"
53   	#include "scip/scip_cut.h"
54   	#include "scip/scip_numerics.h"
55   	#include "scip/scip_tree.h"
56   	#include "scip/sepastore.h"
57   	#include "scip/set.h"
58   	#include "scip/solve.h"
59   	#include "scip/struct_lp.h"
60   	#include "scip/struct_mem.h"
61   	#include "scip/struct_scip.h"
62   	#include "scip/struct_set.h"
63   	#include "scip/tree.h"
64   	
65   	/** returns row's cutoff distance in the direction of the given primal solution
66   	 *
67   	 *  @return the cutoff distance of the cut with respect to the LP solution in the direction of the given primal solution
68   	 *
69   	 *  @pre This method can be called if @p scip is in one of the following stages:
70   	 *       - \ref SCIP_STAGE_SOLVING
71   	 */
72   	SCIP_Real SCIPgetCutLPSolCutoffDistance(
73   	   SCIP*                 scip,               /**< SCIP data structure */
74   	   SCIP_SOL*             sol,                /**< solution to compute direction for cutoff distance; must not be NULL */
75   	   SCIP_ROW*             cut                 /**< separated cut */
76   	   )
77   	{
78   	   SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetCutLPSolCutoffDistance", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
79   	
80   	   assert(sol != NULL);
81   	
82   	   return SCIProwGetLPSolCutoffDistance(cut, scip->set, scip->stat, sol, scip->lp);
83   	}
84   	
85   	/** returns efficacy of the cut with respect to the given primal solution or the current LP solution:
86   	 *  e = -feasibility/norm
87   	 *
88   	 *  @return the efficacy of the cut with respect to the given primal solution or the current LP solution:
89   	 *          e = -feasibility/norm
90   	 *
91   	 *  @pre This method can be called if @p scip is in one of the following stages:
92   	 *       - \ref SCIP_STAGE_SOLVING
93   	 */
94   	SCIP_Real SCIPgetCutEfficacy(
95   	   SCIP*                 scip,               /**< SCIP data structure */
96   	   SCIP_SOL*             sol,                /**< primal CIP solution, or NULL for current LP solution */
97   	   SCIP_ROW*             cut                 /**< separated cut */
98   	   )
99   	{
100  	   SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetCutEfficacy", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
101  	
102  	   if( sol == NULL )
103  	      return SCIProwGetLPEfficacy(cut, scip->set, scip->stat, scip->lp);
104  	   else
105  	      return SCIProwGetSolEfficacy(cut, scip->set, scip->stat, sol);
106  	}
107  	
108  	/** returns whether the cut's efficacy with respect to the given primal solution or the current LP solution is greater
109  	 *  than the minimal cut efficacy
110  	 *
111  	 *  @return TRUE if the cut's efficacy with respect to the given primal solution or the current LP solution is greater
112  	 *          than the minimal cut efficacy, otherwise FALSE
113  	 *
114  	 *  @pre This method can be called if @p scip is in one of the following stages:
115  	 *       - \ref SCIP_STAGE_SOLVING
116  	 */
117  	SCIP_Bool SCIPisCutEfficacious(
118  	   SCIP*                 scip,               /**< SCIP data structure */
119  	   SCIP_SOL*             sol,                /**< primal CIP solution, or NULL for current LP solution */
120  	   SCIP_ROW*             cut                 /**< separated cut */
121  	   )
122  	{
123  	   SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisCutEfficacious", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
124  	
125  	   if( sol == NULL )
126  	      return SCIProwIsLPEfficacious(cut, scip->set, scip->stat, scip->lp, (SCIPtreeGetCurrentDepth(scip->tree) == 0));
127  	   else
128  	      return SCIProwIsSolEfficacious(cut, scip->set, scip->stat, sol, (SCIPtreeGetCurrentDepth(scip->tree) == 0));
129  	}
130  	
131  	/** checks, if the given cut's efficacy is larger than the minimal cut efficacy
132  	 *
133  	 *  @return TRUE if the given cut's efficacy is larger than the minimal cut efficacy, otherwise FALSE
134  	 */
135  	SCIP_Bool SCIPisEfficacious(
136  	   SCIP*                 scip,               /**< SCIP data structure */
137  	   SCIP_Real             efficacy            /**< efficacy of the cut */
138  	   )
139  	{
140  	   assert(scip != NULL);
141  	
142  	   return SCIPsetIsEfficacious(scip->set, (SCIPtreeGetCurrentDepth(scip->tree) == 0), efficacy);
143  	}
144  	
145  	/** calculates the efficacy norm of the given vector, which depends on the "separating/efficacynorm" parameter
146  	 *
147  	 *  @return the efficacy norm of the given vector, which depends on the "separating/efficacynorm" parameter
148  	 */
149  	SCIP_Real SCIPgetVectorEfficacyNorm(
150  	   SCIP*                 scip,               /**< SCIP data structure */
151  	   SCIP_Real*            vals,               /**< array of values */
152  	   int                   nvals               /**< number of values */
153  	   )
154  	{
155  	   SCIP_Real norm;
156  	   int i;
157  	
158  	   assert(scip != NULL);
159  	   assert(scip->set != NULL);
160  	
161  	   norm = 0.0;
162  	   switch( scip->set->sepa_efficacynorm )
163  	   {
164  	   case 'e':
165  	      for( i = 0; i < nvals; ++i )
166  	         norm += SQR(vals[i]);
167  	      norm = SQRT(norm);
168  	      break;
169  	   case 'm':
170  	      for( i = 0; i < nvals; ++i )
171  	      {
172  	         SCIP_Real absval;
173  	
174  	         absval = REALABS(vals[i]);
175  	         norm = MAX(norm, absval);
176  	      }
177  	      break;
178  	   case 's':
179  	      for( i = 0; i < nvals; ++i )
180  	         norm += REALABS(vals[i]);
181  	      break;
182  	   case 'd':
183  	      for( i = 0; i < nvals; ++i )
184  	      {
185  	         if( !SCIPisZero(scip, vals[i]) )
186  	         {
187  	            norm = 1.0;
188  	            break;
189  	         }
190  	      }
191  	      break;
192  	   default:
193  	      SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", scip->set->sepa_efficacynorm);
194  	      assert(FALSE); /*lint !e506*/
195  	   }
196  	
197  	   return norm;
198  	}
199  	
200  	/** indicates whether a cut is applicable, i.e., will modify the LP when applied
201  	 *
202  	 *  @pre This method can be called if @p scip is in one of the following stages:
203  	 *       - \ref SCIP_STAGE_SOLVING
204  	 *
205  	 *  @return whether the cut is modifiable, not a bound change, or a bound change that changes bounds by at least epsilon
206  	 */
207  	SCIP_Bool SCIPisCutApplicable(
208  	   SCIP*                 scip,               /**< SCIP data structure */
209  	   SCIP_ROW*             cut                 /**< separated cut */
210  	   )
211  	{
212  	   SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisCutApplicable", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
213  	
214  	   return SCIPsepastoreIsCutApplicable(scip->set, cut);
215  	}
216  	
217  	/** adds cut to separation storage
218  	 *
219  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
220  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
221  	 *
222  	 *  @pre This method can be called if @p scip is in one of the following stages:
223  	 *       - \ref SCIP_STAGE_SOLVING
224  	 *
225  	 *  @deprecated Please use SCIPaddRow() instead, or, if the row is a global cut, add it only to the global cutpool.
226  	 */
227  	SCIP_DEPRECATED
228  	SCIP_RETCODE SCIPaddCut(
229  	   SCIP*                 scip,               /**< SCIP data structure */
230  	   SCIP_SOL*             sol,                /**< primal solution that was separated, or NULL for LP solution */
231  	   SCIP_ROW*             cut,                /**< separated cut */
232  	   SCIP_Bool             forcecut,           /**< should the cut be forced to enter the LP? */
233  	   SCIP_Bool*            infeasible          /**< pointer to store whether cut has been detected to be infeasible for local bounds */
234  	   )
235  	{
236  	   SCIP_CALL( SCIPcheckStage(scip, "SCIPaddCut", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
237  	
238  	   SCIP_UNUSED(sol);
239  	
240  	   return SCIPaddRow(scip, cut, forcecut, infeasible);
241  	}
242  	
243  	/** adds row to separation storage
244  	 *
245  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
246  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
247  	 *
248  	 *  @pre This method can be called if @p scip is in one of the following stages:
249  	 *       - \ref SCIP_STAGE_SOLVING
250  	 */
251  	SCIP_RETCODE SCIPaddRow(
252  	   SCIP*                 scip,               /**< SCIP data structure */
253  	   SCIP_ROW*             row,                /**< row */
254  	   SCIP_Bool             forcecut,           /**< should the row be forced to enter the LP? */
255  	   SCIP_Bool*            infeasible          /**< pointer to store whether row has been detected to be infeasible for local bounds */
256  	   )
257  	{
258  	   SCIP_CALL( SCIPcheckStage(scip, "SCIPaddRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
259  	
260  	   assert(SCIPtreeGetCurrentNode(scip->tree) != NULL);
261  	
262  	   SCIP_CALL( SCIPsepastoreAddCut(scip->sepastore, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue,
263  	         scip->eventfilter, scip->lp, row, forcecut, (SCIPtreeGetCurrentDepth(scip->tree) == 0), infeasible) );
264  	
265  	   /* possibly run conflict analysis */
266  	   if ( *infeasible && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && SCIPisConflictAnalysisApplicable(scip) )
267  	   {
268  	      SCIP_Real act;
269  	      SCIP_VAR* var;
270  	      SCIP_Real val;
271  	      int ncols;
272  	      int j;
273  	
274  	      /* initialize conflict analysis */
275  	      SCIP_CALL( SCIPinitConflictAnalysis(scip, SCIP_CONFTYPE_PROPAGATION, FALSE) );
276  	
277  	      if ( ! SCIPisInfinity(scip, -row->lhs) )
278  	      {
279  	         act = SCIProwGetMaxActivity(row, scip->set, scip->stat);
280  	         if ( SCIPisLT(scip, act, row->lhs) )
281  	         {
282  	            ncols = SCIProwGetNNonz(row);
283  	            for (j = 0; j < ncols; ++j)
284  	            {
285  	               val = row->vals[j];
286  	               if ( ! SCIPisZero(scip, val) )
287  	               {
288  	                  var = SCIPcolGetVar(row->cols[j]);
289  	                  assert( var != NULL );
290  	
291  	                  if ( val > 0.0 )
292  	                  {
293  	                     SCIP_CALL( SCIPaddConflictUb(scip, var, NULL) );
294  	                  }
295  	                  else
296  	                  {
297  	                     SCIP_CALL( SCIPaddConflictLb(scip, var, NULL) );
298  	                  }
299  	               }
300  	            }
301  	         }
302  	      }
303  	      else if ( ! SCIPisInfinity(scip, row->rhs) )
304  	      {
305  	         act = SCIProwGetMinActivity(row, scip->set, scip->stat);
306  	         if ( SCIPisGT(scip, act, row->rhs) )
307  	         {
308  	            ncols = SCIProwGetNNonz(row);
309  	            for (j = 0; j < ncols; ++j)
310  	            {
311  	               val = row->vals[j];
312  	               if ( ! SCIPisZero(scip, val) )
313  	               {
314  	                  var = SCIPcolGetVar(row->cols[j]);
315  	                  assert( var != NULL );
316  	
317  	                  if ( val > 0.0 )
318  	                  {
319  	                     SCIP_CALL( SCIPaddConflictLb(scip, var, NULL) );
320  	                  }
321  	                  else
322  	                  {
323  	                     SCIP_CALL( SCIPaddConflictUb(scip, var, NULL) );
324  	                  }
325  	               }
326  	            }
327  	         }
328  	      }
329  	
330  	      /* analyze the conflict */
331  	      SCIP_CALL( SCIPanalyzeConflict(scip, SCIPgetDepth(scip), NULL) );
332  	   }
333  	
334  	   return SCIP_OKAY;
335  	}
336  	
337  	/** checks if cut is already existing in global cutpool
338  	 *
339  	 *  @return TRUE is returned if the cut is not already existing in the global cutpool, FALSE otherwise
340  	 *
341  	 *  @pre This method can be called if @p scip is in one of the following stages:
342  	 *       - \ref SCIP_STAGE_SOLVING
343  	 */
344  	SCIP_Bool SCIPisCutNew(
345  	   SCIP*                 scip,               /**< SCIP data structure */
346  	   SCIP_ROW*             row                 /**< cutting plane to add */
347  	   )
348  	{
349  	   SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisCutNew", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
350  	
351  	   return SCIPcutpoolIsCutNew(scip->cutpool, scip->set, row);
352  	}
353  	
354  	/** if not already existing, adds row to global cut pool
355  	 *
356  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
357  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
358  	 *
359  	 *  @pre This method can be called if @p scip is in one of the following stages:
360  	 *       - \ref SCIP_STAGE_SOLVING
361  	 */
362  	SCIP_RETCODE SCIPaddPoolCut(
363  	   SCIP*                 scip,               /**< SCIP data structure */
364  	   SCIP_ROW*             row                 /**< row to remove */
365  	   )
366  	{
367  	   SCIP_CALL( SCIPcheckStage(scip, "SCIPaddPoolCut", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
368  	
369  	   SCIP_CALL( SCIPcutpoolAddRow(scip->cutpool, scip->mem->probmem, scip->set, scip->stat, scip->lp, row) );
370  	
371  	   return SCIP_OKAY;
372  	}
373  	
374  	/** removes the row from the global cut pool
375  	 *
376  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
377  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
378  	 *
379  	 *  @pre This method can be called if @p scip is in one of the following stages:
380  	 *       - \ref SCIP_STAGE_SOLVING
381  	 */
382  	SCIP_RETCODE SCIPdelPoolCut(
383  	   SCIP*                 scip,               /**< SCIP data structure */
384  	   SCIP_ROW*             row                 /**< cutting plane to add */
385  	   )
386  	{
387  	   SCIP_CALL( SCIPcheckStage(scip, "SCIPdelPoolCut", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
388  	
389  	   SCIP_CALL( SCIPcutpoolDelRow(scip->cutpool, scip->mem->probmem, scip->set, scip->stat, scip->lp, row) );
390  	
391  	   return SCIP_OKAY;
392  	}
393  	
394  	/** gets current cuts in the global cut pool
395  	 *
396  	 *  @return the current cuts in the global cut pool
397  	 *
398  	 *  @pre This method can be called if @p scip is in one of the following stages:
399  	 *       - \ref SCIP_STAGE_SOLVING
400  	 *       - \ref SCIP_STAGE_SOLVED
401  	 *       - \ref SCIP_STAGE_EXITSOLVE
402  	 */
403  	SCIP_CUT** SCIPgetPoolCuts(
404  	   SCIP*                 scip                /**< SCIP data structure */
405  	   )
406  	{
407  	   SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetPoolCuts", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE) );
408  	
409  	   return SCIPcutpoolGetCuts(scip->cutpool);
410  	}
411  	
412  	/** gets current number of rows in the global cut pool
413  	 *
414  	 *  @return the current number of rows in the global cut pool
415  	 *
416  	 *  @pre This method can be called if @p scip is in one of the following stages:
417  	 *       - \ref SCIP_STAGE_SOLVING
418  	 *       - \ref SCIP_STAGE_SOLVED
419  	 *       - \ref SCIP_STAGE_EXITSOLVE
420  	 */
421  	int SCIPgetNPoolCuts(
422  	   SCIP*                 scip                /**< SCIP data structure */
423  	   )
424  	{
425  	   SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNPoolCuts", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE) );
426  	
427  	   return SCIPcutpoolGetNCuts(scip->cutpool);
428  	}
429  	
430  	/** gets the global cut pool used by SCIP
431  	 *
432  	 *  @return the global cut pool used by SCIP
433  	 *
434  	 *  @pre This method can be called if @p scip is in one of the following stages:
435  	 *       - \ref SCIP_STAGE_SOLVING
436  	 *       - \ref SCIP_STAGE_SOLVED
437  	 *       - \ref SCIP_STAGE_EXITSOLVE
438  	 */
439  	SCIP_CUTPOOL* SCIPgetGlobalCutpool(
440  	   SCIP*                 scip                /**< SCIP data structure */
441  	   )
442  	{
443  	   SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetGlobalCutpool", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE) );
444  	
445  	   return scip->cutpool;
446  	}
447  	
448  	/** creates a cut pool
449  	 *
450  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
451  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
452  	 *
453  	 *  @pre This method can be called if @p scip is in one of the following stages:
454  	 *       - \ref SCIP_STAGE_TRANSFORMING
455  	 *       - \ref SCIP_STAGE_TRANSFORMED
456  	 *       - \ref SCIP_STAGE_INITPRESOLVE
457  	 *       - \ref SCIP_STAGE_PRESOLVING
458  	 *       - \ref SCIP_STAGE_EXITPRESOLVE
459  	 *       - \ref SCIP_STAGE_PRESOLVED
460  	 *       - \ref SCIP_STAGE_INITSOLVE
461  	 *       - \ref SCIP_STAGE_SOLVING
462  	 */
463  	SCIP_RETCODE SCIPcreateCutpool(
464  	   SCIP*                 scip,               /**< SCIP data structure */
465  	   SCIP_CUTPOOL**        cutpool,            /**< pointer to store cut pool */
466  	   int                   agelimit            /**< maximum age a cut can reach before it is deleted from the pool */
467  	   )
468  	{
469  	   SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateCutpool", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
470  	
471  	   SCIP_CALL( SCIPcutpoolCreate(cutpool, scip->mem->probmem, scip->set, agelimit, FALSE) );
472  	
473  	   return SCIP_OKAY;
474  	}
475  	
476  	/** frees a cut pool
477  	 *
478  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
479  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
480  	 *
481  	 *  @pre This method can be called if @p scip is in one of the following stages:
482  	 *       - \ref SCIP_STAGE_TRANSFORMING
483  	 *       - \ref SCIP_STAGE_TRANSFORMED
484  	 *       - \ref SCIP_STAGE_INITPRESOLVE
485  	 *       - \ref SCIP_STAGE_PRESOLVING
486  	 *       - \ref SCIP_STAGE_EXITPRESOLVE
487  	 *       - \ref SCIP_STAGE_PRESOLVED
488  	 *       - \ref SCIP_STAGE_INITSOLVE
489  	 *       - \ref SCIP_STAGE_SOLVING
490  	 *       - \ref SCIP_STAGE_SOLVED
491  	 *       - \ref SCIP_STAGE_EXITSOLVE
492  	 *       - \ref SCIP_STAGE_FREETRANS
493  	 */
494  	SCIP_RETCODE SCIPfreeCutpool(
495  	   SCIP*                 scip,               /**< SCIP data structure */
496  	   SCIP_CUTPOOL**        cutpool             /**< pointer to store cut pool */
497  	   )
498  	{
499  	   SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeCutpool", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
500  	
501  	   SCIP_CALL( SCIPcutpoolFree(cutpool, scip->mem->probmem, scip->set, scip->lp) );
502  	
503  	   return SCIP_OKAY;
504  	}
505  	
506  	/** if not already existing, adds row to a cut pool and captures it
507  	 *
508  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
509  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
510  	 *
511  	 *  @pre This method can be called if @p scip is in one of the following stages:
512  	 *       - \ref SCIP_STAGE_INITSOLVE
513  	 *       - \ref SCIP_STAGE_SOLVING
514  	 */
515  	SCIP_RETCODE SCIPaddRowCutpool(
516  	   SCIP*                 scip,               /**< SCIP data structure */
517  	   SCIP_CUTPOOL*         cutpool,            /**< cut pool */
518  	   SCIP_ROW*             row                 /**< cutting plane to add */
519  	   )
520  	{
521  	   SCIP_CALL( SCIPcheckStage(scip, "SCIPaddRowCutpool", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
522  	
523  	   SCIP_CALL( SCIPcutpoolAddRow(cutpool, scip->mem->probmem, scip->set, scip->stat, scip->lp, row) );
524  	
525  	   return SCIP_OKAY;
526  	}
527  	
528  	/** adds row to a cut pool and captures it; doesn't check for multiple cuts
529  	 *
530  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
531  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
532  	 *
533  	 *  @pre This method can be called if @p scip is in one of the following stages:
534  	 *       - \ref SCIP_STAGE_INITSOLVE
535  	 *       - \ref SCIP_STAGE_SOLVING
536  	 */
537  	SCIP_RETCODE SCIPaddNewRowCutpool(
538  	   SCIP*                 scip,               /**< SCIP data structure */
539  	   SCIP_CUTPOOL*         cutpool,            /**< cut pool */
540  	   SCIP_ROW*             row                 /**< cutting plane to add */
541  	   )
542  	{
543  	   SCIP_CALL( SCIPcheckStage(scip, "SCIPaddNewRowCutpool", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
544  	
545  	   SCIP_CALL( SCIPcutpoolAddNewRow(cutpool, scip->mem->probmem, scip->set, scip->stat, scip->lp, row) );
546  	
547  	   return SCIP_OKAY;
548  	}
549  	
550  	/** removes the LP row from a cut pool
551  	 *
552  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
553  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
554  	 *
555  	 *  @pre This method can be called if @p scip is in one of the following stages:
556  	 *       - \ref SCIP_STAGE_INITSOLVE
557  	 *       - \ref SCIP_STAGE_SOLVING
558  	 *       - \ref SCIP_STAGE_SOLVED
559  	 */
560  	SCIP_RETCODE SCIPdelRowCutpool(
561  	   SCIP*                 scip,               /**< SCIP data structure */
562  	   SCIP_CUTPOOL*         cutpool,            /**< cut pool */
563  	   SCIP_ROW*             row                 /**< row to remove */
564  	   )
565  	{
566  	   SCIP_CALL( SCIPcheckStage(scip, "SCIPdelRowCutpool", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
567  	
568  	   SCIP_CALL( SCIPcutpoolDelRow(cutpool, scip->mem->probmem, scip->set, scip->stat, scip->lp, row) );
569  	
570  	   return SCIP_OKAY;
571  	}
572  	
573  	/** separates cuts from a cut pool
574  	 *
575  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
576  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
577  	 *
578  	 *  @pre This method can be called if @p scip is in one of the following stages:
579  	 *       - \ref SCIP_STAGE_SOLVING
580  	 */
581  	SCIP_RETCODE SCIPseparateCutpool(
582  	   SCIP*                 scip,               /**< SCIP data structure */
583  	   SCIP_CUTPOOL*         cutpool,            /**< cut pool */
584  	   SCIP_RESULT*          result              /**< pointer to store the result of the separation call */
585  	   )
586  	{
587  	   SCIP_CALL( SCIPcheckStage(scip, "SCIPseparateCutpool", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
588  	
589  	   assert(SCIPtreeGetCurrentNode(scip->tree) != NULL);
590  	
591  	   if( !SCIPtreeHasCurrentNodeLP(scip->tree) )
592  	   {
593  	      SCIPerrorMessage("cannot add cuts, because node LP is not processed\n");
594  	      return SCIP_INVALIDCALL;
595  	   }
596  	
597  	   SCIP_CALL( SCIPcutpoolSeparate(cutpool, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->eventfilter,
598  	         scip->lp, scip->sepastore, NULL, FALSE, (SCIPtreeGetCurrentDepth(scip->tree) == 0), result) );
599  	
600  	   return SCIP_OKAY;
601  	}
602  	
603  	/** separates cuts w.r.t. given solution from a cut pool
604  	 *
605  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
606  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
607  	 *
608  	 *  @pre This method can be called if @p scip is in one of the following stages:
609  	 *       - \ref SCIP_STAGE_SOLVING
610  	 */
611  	SCIP_RETCODE SCIPseparateSolCutpool(
612  	   SCIP*                 scip,               /**< SCIP data structure */
613  	   SCIP_CUTPOOL*         cutpool,            /**< cut pool */
614  	   SCIP_SOL*             sol,                /**< solution to be separated */
615  	   SCIP_Bool             pretendroot,        /**< should the cut separators be called as if we are at the root node? */
616  	   SCIP_RESULT*          result              /**< pointer to store the result of the separation call */
617  	   )
618  	{
619  	   SCIP_CALL( SCIPcheckStage(scip, "SCIPseparateSolCutpool", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
620  	
621  	   assert(SCIPtreeGetCurrentNode(scip->tree) != NULL);
622  	
623  	   if( !SCIPtreeHasCurrentNodeLP(scip->tree) )
624  	   {
625  	      SCIPerrorMessage("cannot add cuts, because node LP is not processed\n");
626  	      return SCIP_INVALIDCALL;
627  	   }
628  	
629  	   SCIP_CALL( SCIPcutpoolSeparate(cutpool, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->eventfilter,
630  	         scip->lp, scip->sepastore, sol, FALSE, pretendroot, result) );
631  	
632  	   return SCIP_OKAY;
633  	}
634  	
635  	/** if not already existing, adds row to delayed global cut pool
636  	 *
637  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
638  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
639  	 *
640  	 *  @pre This method can be called if @p scip is the stages \ref SCIP_STAGE_SOLVING
641  	 */
642  	SCIP_RETCODE SCIPaddDelayedPoolCut(
643  	   SCIP*                 scip,               /**< SCIP data structure */
644  	   SCIP_ROW*             row                 /**< cutting plane to add */
645  	   )
646  	{
647  	   SCIP_CALL( SCIPcheckStage(scip, "SCIPaddDelayedPoolCut", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
648  	
649  	   SCIP_CALL( SCIPcutpoolAddRow(scip->delayedcutpool, scip->mem->probmem, scip->set, scip->stat, scip->lp, row) );
650  	
651  	   return SCIP_OKAY;
652  	}
653  	
654  	/** removes the row from the delayed global cut pool
655  	 *
656  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
657  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
658  	 *
659  	 *  @pre This method can be called if @p scip is the stages \ref SCIP_STAGE_SOLVING
660  	 */
661  	SCIP_RETCODE SCIPdelDelayedPoolCut(
662  	   SCIP*                 scip,               /**< SCIP data structure */
663  	   SCIP_ROW*             row                 /**< cutting plane to add */
664  	   )
665  	{
666  	   SCIP_CALL( SCIPcheckStage(scip, "SCIPdelDelayedPoolCut", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
667  	
668  	   SCIP_CALL( SCIPcutpoolDelRow(scip->delayedcutpool, scip->mem->probmem, scip->set, scip->stat, scip->lp, row) );
669  	
670  	   return SCIP_OKAY;
671  	}
672  	
673  	/** gets current cuts in the delayed global cut pool
674  	 *
675  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
676  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
677  	 *
678  	 *  @pre This method can be called if @p scip is the stages \ref SCIP_STAGE_SOLVING
679  	 */
680  	SCIP_CUT** SCIPgetDelayedPoolCuts(
681  	   SCIP*                 scip                /**< SCIP data structure */
682  	   )
683  	{
684  	   SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetDelayedPoolCuts", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE) );
685  	
686  	   return SCIPcutpoolGetCuts(scip->delayedcutpool);
687  	}
688  	
689  	/** gets current number of rows in the delayed global cut pool
690  	 *
691  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
692  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
693  	 *
694  	 *  @pre This method can be called if @p scip is the stages \ref SCIP_STAGE_SOLVING
695  	 */
696  	int SCIPgetNDelayedPoolCuts(
697  	   SCIP*                 scip                /**< SCIP data structure */
698  	   )
699  	{
700  	   SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNDelayedPoolCuts", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE) );
701  	
702  	   return SCIPcutpoolGetNCuts(scip->delayedcutpool);
703  	}
704  	
705  	/** gets the delayed global cut pool used by SCIP
706  	 *
707  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
708  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
709  	 *
710  	 *  @pre This method can be called if @p scip is the stages \ref SCIP_STAGE_SOLVING
711  	 */
712  	SCIP_CUTPOOL* SCIPgetDelayedGlobalCutpool(
713  	   SCIP*                 scip                /**< SCIP data structure */
714  	   )
715  	{
716  	   SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetDelayedGlobalCutpool", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE) );
717  	
718  	   return scip->delayedcutpool;
719  	}
720  	
721  	/** separates the given primal solution or the current LP solution by calling the separators and constraint handlers'
722  	 *  separation methods;
723  	 *  the generated cuts are stored in the separation storage and can be accessed with the methods SCIPgetCuts() and
724  	 *  SCIPgetNCuts();
725  	 *  after evaluating the cuts, you have to call SCIPclearCuts() in order to remove the cuts from the
726  	 *  separation storage;
727  	 *  it is possible to call SCIPseparateSol() multiple times with different solutions and evaluate the found cuts
728  	 *  afterwards
729  	 *
730  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
731  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
732  	 *
733  	 *  @pre This method can be called if @p scip is in one of the following stages:
734  	 *       - \ref SCIP_STAGE_SOLVING
735  	 */
736  	SCIP_RETCODE SCIPseparateSol(
737  	   SCIP*                 scip,               /**< SCIP data structure */
738  	   SCIP_SOL*             sol,                /**< primal solution that should be separated, or NULL for LP solution */
739  	   SCIP_Bool             pretendroot,        /**< should the cut separators be called as if we are at the root node? */
740  	   SCIP_Bool             allowlocal,         /**< should the separator be asked to separate local cuts */
741  	   SCIP_Bool             onlydelayed,        /**< should only separators be called that were delayed in the previous round? */
742  	   SCIP_Bool*            delayed,            /**< pointer to store whether a separator was delayed */
743  	   SCIP_Bool*            cutoff              /**< pointer to store whether the node can be cut off */
744  	   )
745  	{
746  	   int actdepth;
747  	
748  	   SCIP_CALL( SCIPcheckStage(scip, "SCIPseparateSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
749  	
750  	   /* get current depth */
751  	   actdepth = (pretendroot ? 0 : SCIPtreeGetCurrentDepth(scip->tree));
752  	
753  	   /* apply separation round */
754  	   SCIP_CALL( SCIPseparationRound(scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, scip->eventqueue,
755  	         scip->eventfilter, scip->transprob, scip->primal, scip->tree, scip->lp, scip->sepastore,
756  	         sol, actdepth, allowlocal, onlydelayed, delayed, cutoff) );
757  	
758  	   return SCIP_OKAY;
759  	}
760  	
761  	/** gets the array of cuts currently stored in the separation storage
762  	 *
763  	 *  @return the array of cuts currently stored in the separation storage
764  	 *
765  	 *  @pre This method can be called if @p scip is in one of the following stages:
766  	 *       - \ref SCIP_STAGE_PRESOLVED
767  	 *       - \ref SCIP_STAGE_SOLVING
768  	 *       - \ref SCIP_STAGE_SOLVED
769  	 */
770  	SCIP_ROW** SCIPgetCuts(
771  	   SCIP*                 scip                /**< SCIP data structure */
772  	   )
773  	{
774  	   SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetCuts", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
775  	
776  	   return SCIPsepastoreGetCuts(scip->sepastore);
777  	}
778  	
779  	/** get current number of cuts in the separation storage
780  	 *
781  	 *  @return the current number of cuts in the separation storage
782  	 *
783  	 *  @pre This method can be called if @p scip is in one of the following stages:
784  	 *       - \ref SCIP_STAGE_PRESOLVED
785  	 *       - \ref SCIP_STAGE_SOLVING
786  	 *       - \ref SCIP_STAGE_SOLVED
787  	 */
788  	int SCIPgetNCuts(
789  	   SCIP*                 scip                /**< SCIP data structure */
790  	   )
791  	{
792  	   SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCuts", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
793  	
794  	   return SCIPsepastoreGetNCuts(scip->sepastore);
795  	}
796  	
797  	/** clears the separation storage
798  	 *
799  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
800  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
801  	 *
802  	 *  @pre This method can be called if @p scip is in one of the following stages:
803  	 *       - \ref SCIP_STAGE_SOLVING
804  	 */
805  	SCIP_RETCODE SCIPclearCuts(
806  	   SCIP*                 scip                /**< SCIP data structure */
807  	   )
808  	{
809  	   SCIP_CALL( SCIPcheckStage(scip, "SCIPclearCuts", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
810  	
811  	   SCIP_CALL( SCIPsepastoreClearCuts(scip->sepastore, scip->mem->probmem, scip->set, scip->eventqueue, scip->eventfilter, scip->lp) );
812  	
813  	   return SCIP_OKAY;
814  	}
815  	
816  	/** removes cuts that are inefficacious w.r.t. the current LP solution from separation storage without adding the cuts to the LP
817  	 *
818  	 *  @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
819  	 *          SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
820  	 *
821  	 *  @pre This method can be called if @p scip is in one of the following stages:
822  	 *       - \ref SCIP_STAGE_SOLVING
823  	 */
824  	SCIP_RETCODE SCIPremoveInefficaciousCuts(
825  	   SCIP*                 scip                /**< SCIP data structure */
826  	   )
827  	{
828  	   SCIP_Bool isroot = FALSE;
829  	
830  	   SCIP_CALL( SCIPcheckStage(scip, "SCIPremoveInefficaciousCuts", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
831  	
832  	   if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
833  	      isroot = TRUE;
834  	
835  	   SCIP_CALL( SCIPsepastoreRemoveInefficaciousCuts(scip->sepastore, scip->mem->probmem, scip->set, scip->stat,
836  	         scip->eventqueue, scip->eventfilter, scip->lp, isroot, SCIP_EFFICIACYCHOICE_LP) );
837  	
838  	   return SCIP_OKAY;
839  	}
840