1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /*                                                                           */
3 /*                  This file is part of the program and library             */
4 /*         SCIP --- Solving Constraint Integer Programs                      */
5 /*                                                                           */
6 /*    Copyright (C) 2002-2021 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   prop.c
17  * @ingroup OTHER_CFILES
18  * @brief  methods and datastructures for propagators
19  * @author Tobias Achterberg
20  * @author Timo Berthold
21  */
22 
23 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
24 
25 #include <assert.h>
26 #include <string.h>
27 
28 #include "scip/def.h"
29 #include "scip/set.h"
30 #include "scip/stat.h"
31 #include "scip/clock.h"
32 #include "scip/paramset.h"
33 #include "scip/var.h"
34 #include "scip/scip.h"
35 #include "scip/prop.h"
36 #include "scip/pub_message.h"
37 #include "scip/pub_misc.h"
38 
39 #include "scip/struct_prop.h"
40 
41 
42 /** compares two propagators w. r. to their priority */
SCIP_DECL_SORTPTRCOMP(SCIPpropComp)43 SCIP_DECL_SORTPTRCOMP(SCIPpropComp)
44 {  /*lint --e{715}*/
45    return ((SCIP_PROP*)elem2)->priority - ((SCIP_PROP*)elem1)->priority;
46 }
47 
48 /** compares two propagators w. r. to their priority */
SCIP_DECL_SORTPTRCOMP(SCIPpropCompPresol)49 SCIP_DECL_SORTPTRCOMP(SCIPpropCompPresol)
50 {  /*lint --e{715}*/
51    return ((SCIP_PROP*)elem2)->presolpriority - ((SCIP_PROP*)elem1)->presolpriority;
52 }
53 
54 /** comparison method for sorting propagators w.r.t. to their name */
SCIP_DECL_SORTPTRCOMP(SCIPpropCompName)55 SCIP_DECL_SORTPTRCOMP(SCIPpropCompName)
56 {
57    return strcmp(SCIPpropGetName((SCIP_PROP*)elem1), SCIPpropGetName((SCIP_PROP*)elem2));
58 }
59 
60 /** method to call, when the priority of a propagator was changed */
61 static
SCIP_DECL_PARAMCHGD(paramChgdPropPriority)62 SCIP_DECL_PARAMCHGD(paramChgdPropPriority)
63 {  /*lint --e{715}*/
64    SCIP_PARAMDATA* paramdata;
65 
66    paramdata = SCIPparamGetData(param);
67    assert(paramdata != NULL);
68 
69    /* use SCIPsetPropPriority() to mark the props unsorted */
70    SCIP_CALL( SCIPsetPropPriority(scip, (SCIP_PROP*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
71 
72    return SCIP_OKAY;
73 }
74 
75 /** method to call, when the presolving priority of a propagator was changed */
76 static
SCIP_DECL_PARAMCHGD(paramChgdPropPresolPriority)77 SCIP_DECL_PARAMCHGD(paramChgdPropPresolPriority)
78 {  /*lint --e{715}*/
79    SCIP_PARAMDATA* paramdata;
80 
81    paramdata = SCIPparamGetData(param);
82    assert(paramdata != NULL);
83 
84    /* use SCIPsetPropPriority() to mark the props unsorted */
85    SCIP_CALL( SCIPsetPropPresolPriority(scip, (SCIP_PROP*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
86 
87    return SCIP_OKAY;
88 }
89 
90 /** copies the given propagator to a new scip */
SCIPpropCopyInclude(SCIP_PROP * prop,SCIP_SET * set)91 SCIP_RETCODE SCIPpropCopyInclude(
92    SCIP_PROP*            prop,               /**< propagator */
93    SCIP_SET*             set                 /**< SCIP_SET of SCIP to copy to */
94    )
95 {
96    assert(prop != NULL);
97    assert(set != NULL);
98    assert(set->scip != NULL);
99 
100    if( prop->propcopy != NULL )
101    {
102       SCIPsetDebugMsg(set, "including propagator %s in subscip %p\n", SCIPpropGetName(prop), (void*)set->scip);
103       SCIP_CALL( prop->propcopy(set->scip, prop) );
104    }
105    return SCIP_OKAY;
106 }
107 
108 /** internal method for creating a propagator */
109 static
doPropCreate(SCIP_PROP ** prop,SCIP_SET * set,SCIP_MESSAGEHDLR * messagehdlr,BMS_BLKMEM * blkmem,const char * name,const char * desc,int priority,int freq,SCIP_Bool delay,SCIP_PROPTIMING timingmask,int presolpriority,int presolmaxrounds,SCIP_PRESOLTIMING presoltiming,SCIP_DECL_PROPCOPY ((* propcopy)),SCIP_DECL_PROPFREE ((* propfree)),SCIP_DECL_PROPINIT ((* propinit)),SCIP_DECL_PROPEXIT ((* propexit)),SCIP_DECL_PROPINITPRE ((* propinitpre)),SCIP_DECL_PROPEXITPRE ((* propexitpre)),SCIP_DECL_PROPINITSOL ((* propinitsol)),SCIP_DECL_PROPEXITSOL ((* propexitsol)),SCIP_DECL_PROPPRESOL ((* proppresol)),SCIP_DECL_PROPEXEC ((* propexec)),SCIP_DECL_PROPRESPROP ((* propresprop)),SCIP_PROPDATA * propdata)110 SCIP_RETCODE doPropCreate(
111    SCIP_PROP**           prop,               /**< pointer to propagator data structure */
112    SCIP_SET*             set,                /**< global SCIP settings */
113    SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
114    BMS_BLKMEM*           blkmem,             /**< block memory for parameter settings */
115    const char*           name,               /**< name of propagator */
116    const char*           desc,               /**< description of propagator */
117    int                   priority,           /**< priority of the propagator (>= 0: before, < 0: after constraint handlers) */
118    int                   freq,               /**< frequency for calling propagator */
119    SCIP_Bool             delay,              /**< should propagator be delayed, if other propagators found reductions? */
120    SCIP_PROPTIMING       timingmask,         /**< positions in the node solving loop where propagator should be executed */
121    int                   presolpriority,     /**< priority of the propagator (>= 0: before, < 0: after constraint handlers) */
122    int                   presolmaxrounds,    /**< maximal number of presolving rounds the propagator participates in (-1: no limit) */
123    SCIP_PRESOLTIMING     presoltiming,       /**< timing mask of the propagator's presolving method */
124    SCIP_DECL_PROPCOPY    ((*propcopy)),      /**< copy method of propagator or NULL if you don't want to copy your plugin into sub-SCIPs */
125    SCIP_DECL_PROPFREE    ((*propfree)),      /**< destructor of propagator */
126    SCIP_DECL_PROPINIT    ((*propinit)),      /**< initialize propagator */
127    SCIP_DECL_PROPEXIT    ((*propexit)),      /**< deinitialize propagator */
128    SCIP_DECL_PROPINITPRE ((*propinitpre)),   /**< presolving initialization method of propagator */
129    SCIP_DECL_PROPEXITPRE ((*propexitpre)),   /**< presolving deinitialization method of propagator */
130    SCIP_DECL_PROPINITSOL ((*propinitsol)),   /**< solving process initialization method of propagator */
131    SCIP_DECL_PROPEXITSOL ((*propexitsol)),   /**< solving process deinitialization method of propagator */
132    SCIP_DECL_PROPPRESOL  ((*proppresol)),    /**< presolving method */
133    SCIP_DECL_PROPEXEC    ((*propexec)),      /**< execution method of propagator */
134    SCIP_DECL_PROPRESPROP ((*propresprop)),   /**< propagation conflict resolving method */
135    SCIP_PROPDATA*        propdata            /**< propagator data */
136    )
137 {
138    char paramname[SCIP_MAXSTRLEN];
139    char paramdesc[SCIP_MAXSTRLEN];
140 
141    assert(prop != NULL);
142    assert(name != NULL);
143    assert(desc != NULL);
144    assert(freq >= -1);
145    assert(propexec != NULL);
146 
147    /* the interface change from delay flags to timings cannot be recognized at compile time: Exit with an appropriate
148     * error message
149     */
150    if( presoltiming < SCIP_PRESOLTIMING_NONE || presoltiming > SCIP_PRESOLTIMING_MAX )
151    {
152       SCIPmessagePrintError("ERROR: 'PRESOLDELAY'-flag no longer available since SCIP 3.2, use an appropriate "
153          "'SCIP_PRESOLTIMING' for <%s> propagator instead.\n", name);
154 
155       return SCIP_PARAMETERWRONGVAL;
156    }
157 
158    SCIP_ALLOC( BMSallocMemory(prop) );
159    BMSclearMemory(*prop);
160 
161    SCIP_ALLOC( BMSduplicateMemoryArray(&(*prop)->name, name, strlen(name)+1) );
162    SCIP_ALLOC( BMSduplicateMemoryArray(&(*prop)->desc, desc, strlen(desc)+1) );
163    (*prop)->priority = priority;
164    (*prop)->freq = freq;
165    (*prop)->propcopy = propcopy;
166    (*prop)->propfree = propfree;
167    (*prop)->propinit = propinit;
168    (*prop)->propexit = propexit;
169    (*prop)->propinitpre = propinitpre;
170    (*prop)->propexitpre = propexitpre;
171    (*prop)->propinitsol = propinitsol;
172    (*prop)->propexitsol = propexitsol;
173    (*prop)->proppresol = proppresol;
174    (*prop)->propexec = propexec;
175    (*prop)->propresprop = propresprop;
176    (*prop)->propdata = propdata;
177    SCIP_CALL( SCIPclockCreate(&(*prop)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
178    SCIP_CALL( SCIPclockCreate(&(*prop)->proptime, SCIP_CLOCKTYPE_DEFAULT) );
179    SCIP_CALL( SCIPclockCreate(&(*prop)->sbproptime, SCIP_CLOCKTYPE_DEFAULT) );
180    SCIP_CALL( SCIPclockCreate(&(*prop)->resproptime, SCIP_CLOCKTYPE_DEFAULT) );
181    SCIP_CALL( SCIPclockCreate(&(*prop)->presoltime, SCIP_CLOCKTYPE_DEFAULT) );
182    (*prop)->ncalls = 0;
183    (*prop)->nrespropcalls = 0;
184    (*prop)->ncutoffs = 0;
185    (*prop)->ndomredsfound = 0;
186    (*prop)->wasdelayed = FALSE;
187    (*prop)->initialized = FALSE;
188 
189    /* add parameters */
190    (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/priority", name);
191    (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of propagator <%s>", name);
192    SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
193          &(*prop)->priority, TRUE, priority, INT_MIN/4, INT_MAX/4,
194          paramChgdPropPriority, (SCIP_PARAMDATA*)(*prop)) ); /*lint !e740*/
195 
196    (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/freq", name);
197    (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "frequency for calling propagator <%s> (-1: never, 0: only in root node)", name);
198    SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
199          &(*prop)->freq, FALSE, freq, -1, SCIP_MAXTREEDEPTH, NULL, NULL) );
200 
201    (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/delay", name);
202    SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname,
203          "should propagator be delayed, if other propagators found reductions?",
204          &(*prop)->delay, TRUE, delay, NULL, NULL) ); /*lint !e740*/
205 
206    (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/timingmask", name);
207    (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "timing when propagator should be called (%u:BEFORELP, %u:DURINGLPLOOP, %u:AFTERLPLOOP, %u:ALWAYS))",
208       SCIP_PROPTIMING_BEFORELP, SCIP_PROPTIMING_DURINGLPLOOP, SCIP_PROPTIMING_AFTERLPLOOP, SCIP_PROPTIMING_ALWAYS);
209    SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
210          (int*)(&(*prop)->timingmask), TRUE, (int) timingmask, (int) SCIP_PROPTIMING_BEFORELP, (int) SCIP_PROPTIMING_ALWAYS, NULL, NULL) ); /*lint !e713*/
211 
212    (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/presolpriority", name);
213    (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "presolving priority of propagator <%s>", name);
214    SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
215          &(*prop)->presolpriority, TRUE, presolpriority, INT_MIN/4, INT_MAX/4,
216          paramChgdPropPresolPriority, (SCIP_PARAMDATA*)(*prop)) ); /*lint !e740*/
217 
218    (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/maxprerounds", name);
219    SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname,
220          "maximal number of presolving rounds the propagator participates in (-1: no limit)",
221          &(*prop)->maxprerounds, FALSE, presolmaxrounds, -1, INT_MAX, NULL, NULL) ); /*lint !e740*/
222 
223    (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/presoltiming", name);
224    (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "timing mask of the presolving method of propagator <%s> (%u:FAST, %u:MEDIUM, %u:EXHAUSTIVE, %u:FINAL)",
225       name, SCIP_PRESOLTIMING_FAST, SCIP_PRESOLTIMING_MEDIUM, SCIP_PRESOLTIMING_EXHAUSTIVE, SCIP_PRESOLTIMING_FINAL);
226    SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
227          (int*)&(*prop)->presoltiming, TRUE, (int)presoltiming, (int) SCIP_PRESOLTIMING_NONE, (int) SCIP_PRESOLTIMING_MAX, NULL, NULL) ); /*lint !e740*/
228 
229    return SCIP_OKAY;
230 }
231 
232 /** creates a propagator */
SCIPpropCreate(SCIP_PROP ** prop,SCIP_SET * set,SCIP_MESSAGEHDLR * messagehdlr,BMS_BLKMEM * blkmem,const char * name,const char * desc,int priority,int freq,SCIP_Bool delay,SCIP_PROPTIMING timingmask,int presolpriority,int presolmaxrounds,SCIP_PRESOLTIMING presoltiming,SCIP_DECL_PROPCOPY ((* propcopy)),SCIP_DECL_PROPFREE ((* propfree)),SCIP_DECL_PROPINIT ((* propinit)),SCIP_DECL_PROPEXIT ((* propexit)),SCIP_DECL_PROPINITPRE ((* propinitpre)),SCIP_DECL_PROPEXITPRE ((* propexitpre)),SCIP_DECL_PROPINITSOL ((* propinitsol)),SCIP_DECL_PROPEXITSOL ((* propexitsol)),SCIP_DECL_PROPPRESOL ((* proppresol)),SCIP_DECL_PROPEXEC ((* propexec)),SCIP_DECL_PROPRESPROP ((* propresprop)),SCIP_PROPDATA * propdata)233 SCIP_RETCODE SCIPpropCreate(
234    SCIP_PROP**           prop,               /**< pointer to propagator data structure */
235    SCIP_SET*             set,                /**< global SCIP settings */
236    SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
237    BMS_BLKMEM*           blkmem,             /**< block memory for parameter settings */
238    const char*           name,               /**< name of propagator */
239    const char*           desc,               /**< description of propagator */
240    int                   priority,           /**< priority of the propagator (>= 0: before, < 0: after constraint handlers) */
241    int                   freq,               /**< frequency for calling propagator */
242    SCIP_Bool             delay,              /**< should propagator be delayed, if other propagators found reductions? */
243    SCIP_PROPTIMING       timingmask,         /**< positions in the node solving loop where propagator should be executed */
244    int                   presolpriority,     /**< priority of the propagator (>= 0: before, < 0: after constraint handlers) */
245    int                   presolmaxrounds,    /**< maximal number of presolving rounds the propagator participates in (-1: no limit) */
246    SCIP_PRESOLTIMING     presoltiming,       /**< timing mask of the propagator's presolving method */
247    SCIP_DECL_PROPCOPY    ((*propcopy)),      /**< copy method of propagator or NULL if you don't want to copy your plugin into sub-SCIPs */
248    SCIP_DECL_PROPFREE    ((*propfree)),      /**< destructor of propagator */
249    SCIP_DECL_PROPINIT    ((*propinit)),      /**< initialize propagator */
250    SCIP_DECL_PROPEXIT    ((*propexit)),      /**< deinitialize propagator */
251    SCIP_DECL_PROPINITPRE ((*propinitpre)),   /**< presolving initialization method of propagator */
252    SCIP_DECL_PROPEXITPRE ((*propexitpre)),   /**< presolving deinitialization method of propagator */
253    SCIP_DECL_PROPINITSOL ((*propinitsol)),   /**< solving process initialization method of propagator */
254    SCIP_DECL_PROPEXITSOL ((*propexitsol)),   /**< solving process deinitialization method of propagator */
255    SCIP_DECL_PROPPRESOL  ((*proppresol)),    /**< presolving method */
256    SCIP_DECL_PROPEXEC    ((*propexec)),      /**< execution method of propagator */
257    SCIP_DECL_PROPRESPROP ((*propresprop)),   /**< propagation conflict resolving method */
258    SCIP_PROPDATA*        propdata            /**< propagator data */
259    )
260 {
261    assert(prop != NULL);
262    assert(name != NULL);
263    assert(desc != NULL);
264    assert(freq >= -1);
265    assert(propexec != NULL);
266 
267    SCIP_CALL_FINALLY( doPropCreate(prop, set, messagehdlr, blkmem, name, desc, priority, freq, delay, timingmask,
268       presolpriority, presolmaxrounds, presoltiming, propcopy, propfree, propinit, propexit, propinitpre, propexitpre,
269       propinitsol, propexitsol, proppresol, propexec, propresprop, propdata), (void) SCIPpropFree(prop, set) );
270 
271    return SCIP_OKAY;
272 }
273 
274 /** calls destructor and frees memory of propagator */
SCIPpropFree(SCIP_PROP ** prop,SCIP_SET * set)275 SCIP_RETCODE SCIPpropFree(
276    SCIP_PROP**           prop,               /**< pointer to propagator data structure */
277    SCIP_SET*             set                 /**< global SCIP settings */
278    )
279 {
280    assert(prop != NULL);
281    if( *prop == NULL )
282       return SCIP_OKAY;
283    assert(!(*prop)->initialized);
284    assert(set != NULL);
285 
286    /* call destructor of propagator */
287    if( (*prop)->propfree != NULL )
288    {
289       SCIP_CALL( (*prop)->propfree(set->scip, *prop) );
290    }
291 
292    SCIPclockFree(&(*prop)->presoltime);
293    SCIPclockFree(&(*prop)->resproptime);
294    SCIPclockFree(&(*prop)->sbproptime);
295    SCIPclockFree(&(*prop)->proptime);
296    SCIPclockFree(&(*prop)->setuptime);
297    BMSfreeMemoryArrayNull(&(*prop)->desc);
298    BMSfreeMemoryArrayNull(&(*prop)->name);
299    BMSfreeMemory(prop);
300 
301    return SCIP_OKAY;
302 }
303 
304 /** initializes propagator */
SCIPpropInit(SCIP_PROP * prop,SCIP_SET * set)305 SCIP_RETCODE SCIPpropInit(
306    SCIP_PROP*            prop,               /**< propagator */
307    SCIP_SET*             set                 /**< global SCIP settings */
308    )
309 {
310    assert(prop != NULL);
311    assert(set != NULL);
312 
313    if( prop->initialized )
314    {
315       SCIPerrorMessage("propagator <%s> already initialized\n", prop->name);
316       return SCIP_INVALIDCALL;
317    }
318 
319    if( set->misc_resetstat )
320    {
321       SCIPclockReset(prop->proptime);
322       SCIPclockReset(prop->sbproptime);
323       SCIPclockReset(prop->resproptime);
324       SCIPclockReset(prop->presoltime);
325       SCIPclockReset(prop->setuptime);
326 
327       prop->ncalls = 0;
328       prop->nrespropcalls = 0;
329       prop->ncutoffs = 0;
330       prop->ndomredsfound = 0;
331       prop->lastnfixedvars = 0;
332       prop->lastnaggrvars = 0;
333       prop->lastnchgvartypes = 0;
334       prop->lastnchgbds = 0;
335       prop->lastnaddholes = 0;
336       prop->lastndelconss = 0;
337       prop->lastnaddconss = 0;
338       prop->lastnupgdconss = 0;
339       prop->lastnchgcoefs = 0;
340       prop->lastnchgsides = 0;
341       prop->nfixedvars = 0;
342       prop->naggrvars = 0;
343       prop->nchgvartypes = 0;
344       prop->nchgbds = 0;
345       prop->naddholes = 0;
346       prop->ndelconss = 0;
347       prop->naddconss = 0;
348       prop->nupgdconss = 0;
349       prop->nchgcoefs = 0;
350       prop->nchgsides = 0;
351       prop->npresolcalls = 0;
352       prop->wasdelayed = FALSE;
353    }
354 
355    if( prop->propinit != NULL )
356    {
357       /* start timing */
358       SCIPclockStart(prop->setuptime, set);
359 
360       SCIP_CALL( prop->propinit(set->scip, prop) );
361 
362       /* stop timing */
363       SCIPclockStop(prop->setuptime, set);
364    }
365    prop->initialized = TRUE;
366 
367    return SCIP_OKAY;
368 }
369 
370 /** calls exit method of propagator */
SCIPpropExit(SCIP_PROP * prop,SCIP_SET * set)371 SCIP_RETCODE SCIPpropExit(
372    SCIP_PROP*            prop,               /**< propagator */
373    SCIP_SET*             set                 /**< global SCIP settings */
374    )
375 {
376    assert(prop != NULL);
377    assert(set != NULL);
378 
379    if( !prop->initialized )
380    {
381       SCIPerrorMessage("propagator <%s> not initialized\n", prop->name);
382       return SCIP_INVALIDCALL;
383    }
384 
385    if( prop->propexit != NULL )
386    {
387       /* start timing */
388       SCIPclockStart(prop->setuptime, set);
389 
390       SCIP_CALL( prop->propexit(set->scip, prop) );
391 
392       /* stop timing */
393       SCIPclockStop(prop->setuptime, set);
394    }
395    prop->initialized = FALSE;
396 
397    return SCIP_OKAY;
398 }
399 
400 /** informs propagator that the presolving process is being started */
SCIPpropInitpre(SCIP_PROP * prop,SCIP_SET * set)401 SCIP_RETCODE SCIPpropInitpre(
402    SCIP_PROP*            prop,               /**< propagator */
403    SCIP_SET*             set                 /**< global SCIP settings */
404    )
405 {
406    assert(prop != NULL);
407    assert(set != NULL);
408 
409    prop->lastnfixedvars = 0;
410    prop->lastnaggrvars = 0;
411    prop->lastnchgvartypes = 0;
412    prop->lastnchgbds = 0;
413    prop->lastnaddholes = 0;
414    prop->lastndelconss = 0;
415    prop->lastnaddconss = 0;
416    prop->lastnupgdconss = 0;
417    prop->lastnchgcoefs = 0;
418    prop->lastnchgsides = 0;
419    prop->wasdelayed = FALSE;
420 
421    /* call presolving initialization method of propagator */
422    if( prop->propinitpre != NULL )
423    {
424       /* start timing */
425       SCIPclockStart(prop->setuptime, set);
426 
427       SCIP_CALL( prop->propinitpre(set->scip, prop) );
428 
429       /* stop timing */
430       SCIPclockStop(prop->setuptime, set);
431    }
432 
433    return SCIP_OKAY;
434 }
435 
436 /** informs propagator that the presolving process is finished */
SCIPpropExitpre(SCIP_PROP * prop,SCIP_SET * set)437 SCIP_RETCODE SCIPpropExitpre(
438    SCIP_PROP*            prop,               /**< propagator */
439    SCIP_SET*             set                 /**< global SCIP settings */
440    )
441 {
442    assert(prop != NULL);
443    assert(set != NULL);
444 
445    /* call presolving deinitialization method of propagator */
446    if( prop->propexitpre != NULL )
447    {
448       /* start timing */
449       SCIPclockStart(prop->setuptime, set);
450 
451       SCIP_CALL( prop->propexitpre(set->scip, prop) );
452 
453       /* stop timing */
454       SCIPclockStop(prop->setuptime, set);
455    }
456 
457    return SCIP_OKAY;
458 }
459 
460 /** informs propagator that the prop and bound process is being started */
SCIPpropInitsol(SCIP_PROP * prop,SCIP_SET * set)461 SCIP_RETCODE SCIPpropInitsol(
462    SCIP_PROP*            prop,               /**< propagator */
463    SCIP_SET*             set                 /**< global SCIP settings */
464    )
465 {
466    assert(prop != NULL);
467    assert(set != NULL);
468 
469    /* call solving process initialization method of propagator */
470    if( prop->propinitsol != NULL )
471    {
472       /* start timing */
473       SCIPclockStart(prop->setuptime, set);
474 
475       SCIP_CALL( prop->propinitsol(set->scip, prop) );
476 
477       /* stop timing */
478       SCIPclockStop(prop->setuptime, set);
479    }
480 
481    return SCIP_OKAY;
482 }
483 
484 /** informs propagator that the prop and bound process data is being freed */
SCIPpropExitsol(SCIP_PROP * prop,SCIP_SET * set,SCIP_Bool restart)485 SCIP_RETCODE SCIPpropExitsol(
486    SCIP_PROP*            prop,               /**< propagator */
487    SCIP_SET*             set,                /**< global SCIP settings */
488    SCIP_Bool             restart             /**< was this exit solve call triggered by a restart? */
489    )
490 {
491    assert(prop != NULL);
492    assert(set != NULL);
493 
494    /* call solving process deinitialization method of propagator */
495    if( prop->propexitsol != NULL )
496    {
497       /* start timing */
498       SCIPclockStart(prop->setuptime, set);
499 
500       SCIP_CALL( prop->propexitsol(set->scip, prop, restart) );
501 
502       /* stop timing */
503       SCIPclockStop(prop->setuptime, set);
504    }
505 
506    return SCIP_OKAY;
507 }
508 
509 /** executes presolving method of propagator */
SCIPpropPresol(SCIP_PROP * prop,SCIP_SET * set,SCIP_PRESOLTIMING timing,int nrounds,int * nfixedvars,int * naggrvars,int * nchgvartypes,int * nchgbds,int * naddholes,int * ndelconss,int * naddconss,int * nupgdconss,int * nchgcoefs,int * nchgsides,SCIP_RESULT * result)510 SCIP_RETCODE SCIPpropPresol(
511    SCIP_PROP*            prop,               /**< propagator */
512    SCIP_SET*             set,                /**< global SCIP settings */
513    SCIP_PRESOLTIMING     timing,             /**< current presolving timing */
514    int                   nrounds,            /**< number of presolving rounds already done */
515    int*                  nfixedvars,         /**< pointer to total number of variables fixed of all presolvers */
516    int*                  naggrvars,          /**< pointer to total number of variables aggregated of all presolvers */
517    int*                  nchgvartypes,       /**< pointer to total number of variable type changes of all presolvers */
518    int*                  nchgbds,            /**< pointer to total number of variable bounds tightened of all presolvers */
519    int*                  naddholes,          /**< pointer to total number of domain holes added of all presolvers */
520    int*                  ndelconss,          /**< pointer to total number of deleted constraints of all presolvers */
521    int*                  naddconss,          /**< pointer to total number of added constraints of all presolvers */
522    int*                  nupgdconss,         /**< pointer to total number of upgraded constraints of all presolvers */
523    int*                  nchgcoefs,          /**< pointer to total number of changed coefficients of all presolvers */
524    int*                  nchgsides,          /**< pointer to total number of changed left/right hand sides of all presolvers */
525    SCIP_RESULT*          result              /**< pointer to store the result of the callback method */
526    )
527 {
528    assert(prop != NULL);
529    assert(set != NULL);
530    assert(nfixedvars != NULL);
531    assert(naggrvars != NULL);
532    assert(nchgvartypes != NULL);
533    assert(nchgbds != NULL);
534    assert(naddholes != NULL);
535    assert(ndelconss != NULL);
536    assert(naddconss != NULL);
537    assert(nupgdconss != NULL);
538    assert(nchgcoefs != NULL);
539    assert(nchgsides != NULL);
540    assert(result != NULL);
541 
542    *result = SCIP_DIDNOTRUN;
543 
544    if( prop->proppresol == NULL )
545       return SCIP_OKAY;
546 
547    /* check number of presolving rounds */
548    if( prop->maxprerounds >= 0 && prop->npresolcalls >= prop->maxprerounds )
549       return SCIP_OKAY;
550 
551    /* check, if presolver should be delayed */
552    if( prop->presoltiming & timing )
553    {
554       int nnewfixedvars;
555       int nnewaggrvars;
556       int nnewchgvartypes;
557       int nnewchgbds;
558       int nnewaddholes;
559       int nnewdelconss;
560       int nnewaddconss;
561       int nnewupgdconss;
562       int nnewchgcoefs;
563       int nnewchgsides;
564 
565       SCIPsetDebugMsg(set, "calling presolving method of propagator <%s>\n", prop->name);
566 
567       /* calculate the number of changes since last call */
568       nnewfixedvars = *nfixedvars - prop->lastnfixedvars;
569       nnewaggrvars = *naggrvars - prop->lastnaggrvars;
570       nnewchgvartypes = *nchgvartypes - prop->lastnchgvartypes;
571       nnewchgbds = *nchgbds - prop->lastnchgbds;
572       nnewaddholes = *naddholes - prop->lastnaddholes;
573       nnewdelconss = *ndelconss - prop->lastndelconss;
574       nnewaddconss = *naddconss - prop->lastnaddconss;
575       nnewupgdconss = *nupgdconss - prop->lastnupgdconss;
576       nnewchgcoefs = *nchgcoefs - prop->lastnchgcoefs;
577       nnewchgsides = *nchgsides - prop->lastnchgsides;
578 
579       /* remember the number of changes prior to the call of the presolver method of the propagator */
580       prop->lastnfixedvars = *nfixedvars;
581       prop->lastnaggrvars = *naggrvars;
582       prop->lastnchgvartypes = *nchgvartypes;
583       prop->lastnchgbds = *nchgbds;
584       prop->lastnaddholes = *naddholes;
585       prop->lastndelconss = *ndelconss;
586       prop->lastnaddconss = *naddconss;
587       prop->lastnupgdconss = *nupgdconss;
588       prop->lastnchgcoefs = *nchgcoefs;
589       prop->lastnchgsides = *nchgsides;
590 
591       /* start timing */
592       SCIPclockStart(prop->presoltime, set);
593 
594       /* call external method */
595       SCIP_CALL( prop->proppresol(set->scip, prop, nrounds, timing,
596             nnewfixedvars, nnewaggrvars, nnewchgvartypes, nnewchgbds, nnewaddholes,
597             nnewdelconss, nnewaddconss, nnewupgdconss, nnewchgcoefs, nnewchgsides,
598             nfixedvars, naggrvars, nchgvartypes, nchgbds, naddholes,
599             ndelconss, naddconss, nupgdconss, nchgcoefs, nchgsides, result) );
600 
601       /* stop timing */
602       SCIPclockStop(prop->presoltime, set);
603 
604       /* add/count the new changes */
605       prop->nfixedvars += *nfixedvars - prop->lastnfixedvars;
606       prop->naggrvars += *naggrvars - prop->lastnaggrvars;
607       prop->nchgvartypes += *nchgvartypes - prop->lastnchgvartypes;
608       prop->nchgbds += *nchgbds - prop->lastnchgbds;
609       prop->naddholes += *naddholes - prop->lastnaddholes;
610       prop->ndelconss += *ndelconss - prop->lastndelconss;
611       prop->naddconss += *naddconss - prop->lastnaddconss;
612       prop->nupgdconss += *nupgdconss - prop->lastnupgdconss;
613       prop->nchgcoefs += *nchgcoefs - prop->lastnchgcoefs;
614       prop->nchgsides += *nchgsides - prop->lastnchgsides;
615 
616       /* check result code of callback method */
617       if( *result != SCIP_CUTOFF
618          && *result != SCIP_UNBOUNDED
619          && *result != SCIP_SUCCESS
620          && *result != SCIP_DIDNOTFIND
621          && *result != SCIP_DIDNOTRUN )
622       {
623          SCIPerrorMessage("propagator <%s> returned invalid result <%d>\n", prop->name, *result);
624          return SCIP_INVALIDRESULT;
625       }
626 
627       /* increase the number of presolving calls, if the propagator tried to find reductions */
628       if( *result != SCIP_DIDNOTRUN )
629          ++(prop->npresolcalls);
630    }
631 
632    return SCIP_OKAY;
633 }
634 
635 /** calls execution method of propagator */
SCIPpropExec(SCIP_PROP * prop,SCIP_SET * set,SCIP_STAT * stat,int depth,SCIP_Bool execdelayed,SCIP_Bool instrongbranching,SCIP_PROPTIMING proptiming,SCIP_RESULT * result)636 SCIP_RETCODE SCIPpropExec(
637    SCIP_PROP*            prop,               /**< propagator */
638    SCIP_SET*             set,                /**< global SCIP settings */
639    SCIP_STAT*            stat,               /**< dynamic problem statistics */
640    int                   depth,              /**< depth of current node */
641    SCIP_Bool             execdelayed,        /**< execute propagator even if it is marked to be delayed */
642    SCIP_Bool             instrongbranching,  /**< are we currently doing strong branching? */
643    SCIP_PROPTIMING       proptiming,         /**< current point in the node solving process */
644    SCIP_RESULT*          result              /**< pointer to store the result of the callback method */
645    )
646 {
647    assert(prop != NULL);
648    assert(prop->propexec != NULL);
649    assert(prop->freq >= -1);
650    assert(set != NULL);
651    assert(set->scip != NULL);
652    assert(stat != NULL);
653    assert(depth >= 0);
654    assert(result != NULL);
655 
656    if( (depth == 0 && prop->freq == 0) || (prop->freq > 0 && depth % prop->freq == 0) )
657    {
658       if( !prop->delay || execdelayed )
659       {
660          SCIP_Longint oldndomchgs;
661          SCIP_Longint oldnprobdomchgs;
662 
663          SCIPsetDebugMsg(set, "executing propagator <%s>\n", prop->name);
664 
665          oldndomchgs = stat->nboundchgs + stat->nholechgs;
666          oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs;
667 
668          /* start timing */
669          if( instrongbranching )
670             SCIPclockStart(prop->sbproptime, set);
671          else
672             SCIPclockStart(prop->proptime, set);
673 
674          /* call external propagation method */
675          SCIP_CALL( prop->propexec(set->scip, prop, proptiming, result) );
676 
677          /* stop timing */
678          if( instrongbranching )
679             SCIPclockStop(prop->sbproptime, set);
680          else
681             SCIPclockStop(prop->proptime, set);
682 
683          /* update statistics */
684          if( *result != SCIP_DIDNOTRUN && *result != SCIP_DELAYED )
685             prop->ncalls++;
686          if( *result == SCIP_CUTOFF )
687             prop->ncutoffs++;
688 
689          /* update domain reductions; therefore remove the domain
690           * reduction counts which were generated in probing mode */
691          prop->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs;
692          prop->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs);
693 
694          /* evaluate result */
695          if( *result != SCIP_CUTOFF
696             && *result != SCIP_REDUCEDDOM
697             && *result != SCIP_DIDNOTFIND
698             && *result != SCIP_DIDNOTRUN
699             && *result != SCIP_DELAYED
700             && *result != SCIP_DELAYNODE )
701          {
702             SCIPerrorMessage("execution method of propagator <%s> returned invalid result <%d>\n",
703                prop->name, *result);
704             return SCIP_INVALIDRESULT;
705          }
706       }
707       else
708       {
709          SCIPsetDebugMsg(set, "propagator <%s> was delayed\n", prop->name);
710          *result = SCIP_DELAYED;
711       }
712 
713       /* remember whether propagator was delayed */
714       prop->wasdelayed = (*result == SCIP_DELAYED);
715    }
716    else
717       *result = SCIP_DIDNOTRUN;
718 
719    return SCIP_OKAY;
720 }
721 
722 /** resolves the given conflicting bound, that was deduced by the given propagator, by putting all "reason" bounds
723  *  leading to the deduction into the conflict queue with calls to SCIPaddConflictLb(), SCIPaddConflictUb(), SCIPaddConflictBd(),
724  *  SCIPaddConflictRelaxedLb(), SCIPaddConflictRelaxedUb(), SCIPaddConflictRelaxedBd(), or SCIPaddConflictBinvar();
725  *
726  *  @note it is sufficient to explain the relaxed bound change
727  */
SCIPpropResolvePropagation(SCIP_PROP * prop,SCIP_SET * set,SCIP_VAR * infervar,int inferinfo,SCIP_BOUNDTYPE inferboundtype,SCIP_BDCHGIDX * bdchgidx,SCIP_Real relaxedbd,SCIP_RESULT * result)728 SCIP_RETCODE SCIPpropResolvePropagation(
729    SCIP_PROP*            prop,               /**< propagator */
730    SCIP_SET*             set,                /**< global SCIP settings */
731    SCIP_VAR*             infervar,           /**< variable whose bound was deduced by the constraint */
732    int                   inferinfo,          /**< user inference information attached to the bound change */
733    SCIP_BOUNDTYPE        inferboundtype,     /**< bound that was deduced (lower or upper bound) */
734    SCIP_BDCHGIDX*        bdchgidx,           /**< bound change index, representing the point of time where change took place */
735    SCIP_Real             relaxedbd,          /**< the relaxed bound */
736    SCIP_RESULT*          result              /**< pointer to store the result of the callback method */
737    )
738 {
739    assert(prop != NULL);
740    assert((inferboundtype == SCIP_BOUNDTYPE_LOWER
741          && SCIPgetVarLbAtIndex(set->scip, infervar, bdchgidx, TRUE) > SCIPvarGetLbGlobal(infervar))
742       || (inferboundtype == SCIP_BOUNDTYPE_UPPER
743          && SCIPgetVarUbAtIndex(set->scip, infervar, bdchgidx, TRUE) < SCIPvarGetUbGlobal(infervar)));
744    assert(result != NULL);
745 
746    *result = SCIP_DIDNOTRUN;
747 
748    if( prop->propresprop != NULL )
749    {
750       /* start timing */
751       SCIPclockStart(prop->resproptime, set);
752 
753       SCIP_CALL( prop->propresprop(set->scip, prop, infervar, inferinfo, inferboundtype, bdchgidx,
754             relaxedbd, result) );
755 
756       /* stop timing */
757       SCIPclockStop(prop->resproptime, set);
758 
759       /* update statistic */
760       prop->nrespropcalls++;
761 
762       /* check result code */
763       if( *result != SCIP_SUCCESS && *result != SCIP_DIDNOTFIND )
764       {
765          SCIPerrorMessage("propagation conflict resolving method of propagator <%s> returned invalid result <%d>\n",
766             prop->name, *result);
767          return SCIP_INVALIDRESULT;
768       }
769    }
770    else
771    {
772       SCIPerrorMessage("propagation conflict resolving method of propagator <%s> is not implemented\n", prop->name);
773       return SCIP_PLUGINNOTFOUND;
774    }
775 
776    return SCIP_OKAY;
777 }
778 
779 /** gets user data of propagator */
SCIPpropGetData(SCIP_PROP * prop)780 SCIP_PROPDATA* SCIPpropGetData(
781    SCIP_PROP*            prop                /**< propagator */
782    )
783 {
784    assert(prop != NULL);
785 
786    return prop->propdata;
787 }
788 
789 /** sets user data of propagator; user has to free old data in advance! */
SCIPpropSetData(SCIP_PROP * prop,SCIP_PROPDATA * propdata)790 void SCIPpropSetData(
791    SCIP_PROP*            prop,               /**< propagator */
792    SCIP_PROPDATA*        propdata            /**< new propagator user data */
793    )
794 {
795    assert(prop != NULL);
796 
797    prop->propdata = propdata;
798 }
799 
800 /** sets copy method of propagator */
SCIPpropSetCopy(SCIP_PROP * prop,SCIP_DECL_PROPCOPY ((* propcopy)))801 void SCIPpropSetCopy(
802    SCIP_PROP*            prop,               /**< propagator */
803    SCIP_DECL_PROPCOPY    ((*propcopy))       /**< copy method of propagator or NULL if you don't want to copy your plugin into sub-SCIPs */
804    )
805 {
806    assert(prop != NULL);
807 
808    prop->propcopy = propcopy;
809 }
810 
811 /** sets destructor method of propagator */
SCIPpropSetFree(SCIP_PROP * prop,SCIP_DECL_PROPFREE ((* propfree)))812 void SCIPpropSetFree(
813    SCIP_PROP*            prop,               /**< propagator */
814    SCIP_DECL_PROPFREE    ((*propfree))       /**< destructor of propagator */
815    )
816 {
817    assert(prop != NULL);
818 
819    prop->propfree = propfree;
820 }
821 
822 /** sets initialization method of propagator */
SCIPpropSetInit(SCIP_PROP * prop,SCIP_DECL_PROPINIT ((* propinit)))823 void SCIPpropSetInit(
824    SCIP_PROP*            prop,               /**< propagator */
825    SCIP_DECL_PROPINIT    ((*propinit))       /**< initialize propagator */
826    )
827 {
828    assert(prop != NULL);
829 
830    prop->propinit = propinit;
831 }
832 
833 /** sets deinitialization method of propagator */
SCIPpropSetExit(SCIP_PROP * prop,SCIP_DECL_PROPEXIT ((* propexit)))834 void SCIPpropSetExit(
835    SCIP_PROP*            prop,               /**< propagator */
836    SCIP_DECL_PROPEXIT    ((*propexit))       /**< deinitialize propagator */
837    )
838 {
839    assert(prop != NULL);
840 
841    prop->propexit = propexit;
842 }
843 
844 /** sets solving process initialization method of propagator */
SCIPpropSetInitsol(SCIP_PROP * prop,SCIP_DECL_PROPINITSOL ((* propinitsol)))845 void SCIPpropSetInitsol(
846    SCIP_PROP*            prop,               /**< propagator */
847    SCIP_DECL_PROPINITSOL((*propinitsol))     /**< solving process initialization method of propagator */
848    )
849 {
850    assert(prop != NULL);
851 
852    prop->propinitsol = propinitsol;
853 }
854 
855 /** sets solving process deinitialization method of propagator */
SCIPpropSetExitsol(SCIP_PROP * prop,SCIP_DECL_PROPEXITSOL ((* propexitsol)))856 void SCIPpropSetExitsol(
857    SCIP_PROP*            prop,               /**< propagator */
858    SCIP_DECL_PROPEXITSOL ((*propexitsol))    /**< solving process deinitialization method of propagator */
859    )
860 {
861    assert(prop != NULL);
862 
863    prop->propexitsol = propexitsol;
864 }
865 
866 /** sets preprocessing initialization method of propagator */
SCIPpropSetInitpre(SCIP_PROP * prop,SCIP_DECL_PROPINITPRE ((* propinitpre)))867 void SCIPpropSetInitpre(
868    SCIP_PROP*            prop,               /**< propagator */
869    SCIP_DECL_PROPINITPRE((*propinitpre))     /**< preprocessing initialization method of propagator */
870    )
871 {
872    assert(prop != NULL);
873 
874    prop->propinitpre = propinitpre;
875 }
876 
877 
878 
879 /** sets preprocessing deinitialization method of propagator */
SCIPpropSetExitpre(SCIP_PROP * prop,SCIP_DECL_PROPEXITPRE ((* propexitpre)))880 void SCIPpropSetExitpre(
881    SCIP_PROP*            prop,               /**< propagator */
882    SCIP_DECL_PROPEXITPRE((*propexitpre))     /**< preprocessing deinitialization method of propagator */
883    )
884 {
885    assert(prop != NULL);
886 
887    prop->propexitpre = propexitpre;
888 }
889 
890 /** sets presolving method of propagator */
SCIPpropSetPresol(SCIP_PROP * prop,SCIP_DECL_PROPPRESOL ((* proppresol)),int presolpriority,int presolmaxrounds,SCIP_PRESOLTIMING presoltiming)891 SCIP_RETCODE SCIPpropSetPresol(
892    SCIP_PROP*            prop,               /**< propagator */
893    SCIP_DECL_PROPPRESOL  ((*proppresol)),    /**< presolving method */
894    int                   presolpriority,     /**< presolving priority of the propagator (>= 0: before, < 0: after constraint handlers) */
895    int                   presolmaxrounds,    /**< maximal number of presolving rounds the propagator participates in (-1: no limit) */
896    SCIP_PRESOLTIMING     presoltiming        /**< timing mask of the propagator's presolving method */
897    )
898 {
899    assert(prop != NULL);
900 
901    prop->proppresol = proppresol;
902    prop->presolpriority = presolpriority;
903    /* the interface change from delay flags to timings cannot be recognized at compile time: Exit with an appropriate
904     * error message
905     */
906    if( presoltiming < SCIP_PRESOLTIMING_FAST || presoltiming > SCIP_PRESOLTIMING_MAX )
907    {
908       SCIPmessagePrintError("ERROR: 'PRESOLDELAY'-flag no longer available since SCIP 3.2, use an appropriate "
909          "'SCIP_PRESOLTIMING' for <%s> constraint handler instead.\n", prop->name);
910 
911       return SCIP_PARAMETERWRONGVAL;
912    }
913 
914    prop->presoltiming = presoltiming;
915    prop->maxprerounds = presolmaxrounds;
916 
917    return SCIP_OKAY;
918 }
919 
920 /** sets propagation conflict resolving callback of propagator */
SCIPpropSetResprop(SCIP_PROP * prop,SCIP_DECL_PROPRESPROP ((* propresprop)))921 void SCIPpropSetResprop(
922    SCIP_PROP*            prop,               /**< propagator */
923    SCIP_DECL_PROPRESPROP ((*propresprop))    /**< propagation conflict resolving callback */
924    )
925 {
926    assert(prop != NULL);
927 
928    prop->propresprop = propresprop;
929 }
930 
931 /** gets name of propagator */
SCIPpropGetName(SCIP_PROP * prop)932 const char* SCIPpropGetName(
933    SCIP_PROP*            prop                /**< propagator */
934    )
935 {
936    assert(prop != NULL);
937 
938    return prop->name;
939 }
940 
941 /** gets description of propagator */
SCIPpropGetDesc(SCIP_PROP * prop)942 const char* SCIPpropGetDesc(
943    SCIP_PROP*            prop                /**< propagator */
944    )
945 {
946    assert(prop != NULL);
947 
948    return prop->desc;
949 }
950 
951 /** gets priority of propagator */
SCIPpropGetPriority(SCIP_PROP * prop)952 int SCIPpropGetPriority(
953    SCIP_PROP*            prop                /**< propagator */
954    )
955 {
956    assert(prop != NULL);
957 
958    return prop->priority;
959 }
960 
961 /** gets presolving priority of propagator */
SCIPpropGetPresolPriority(SCIP_PROP * prop)962 int SCIPpropGetPresolPriority(
963    SCIP_PROP*            prop                /**< propagator */
964    )
965 {
966    assert(prop != NULL);
967 
968    return prop->presolpriority;
969 }
970 
971 /** sets priority of propagator */
SCIPpropSetPriority(SCIP_PROP * prop,SCIP_SET * set,int priority)972 void SCIPpropSetPriority(
973    SCIP_PROP*            prop,               /**< propagator */
974    SCIP_SET*             set,                /**< global SCIP settings */
975    int                   priority            /**< new priority of the propagator */
976    )
977 {
978    assert(prop != NULL);
979    assert(set != NULL);
980 
981    prop->priority = priority;
982    set->propssorted = FALSE;
983 }
984 
985 /** sets presolving priority of propagator */
SCIPpropSetPresolPriority(SCIP_PROP * prop,SCIP_SET * set,int presolpriority)986 void SCIPpropSetPresolPriority(
987    SCIP_PROP*            prop,               /**< propagator */
988    SCIP_SET*             set,                /**< global SCIP settings */
989    int                   presolpriority      /**< new priority of the propagator */
990    )
991 {
992    assert(prop != NULL);
993    assert(set != NULL);
994 
995    prop->presolpriority = presolpriority;
996    set->propspresolsorted = FALSE;
997 }
998 
999 /** gets frequency of propagator */
SCIPpropGetFreq(SCIP_PROP * prop)1000 int SCIPpropGetFreq(
1001    SCIP_PROP*            prop                /**< propagator */
1002    )
1003 {
1004    assert(prop != NULL);
1005 
1006    return prop->freq;
1007 }
1008 
1009 /** enables or disables all clocks of \p prop, depending on the value of the flag */
SCIPpropEnableOrDisableClocks(SCIP_PROP * prop,SCIP_Bool enable)1010 void SCIPpropEnableOrDisableClocks(
1011    SCIP_PROP*            prop,               /**< the propagator for which all clocks should be enabled or disabled */
1012    SCIP_Bool             enable              /**< should the clocks of the propagator be enabled? */
1013    )
1014 {
1015    assert(prop != NULL);
1016 
1017    SCIPclockEnableOrDisable(prop->setuptime, enable);
1018    SCIPclockEnableOrDisable(prop->presoltime, enable);
1019    SCIPclockEnableOrDisable(prop->proptime, enable);
1020    SCIPclockEnableOrDisable(prop->resproptime, enable);
1021    SCIPclockEnableOrDisable(prop->sbproptime, enable);
1022 }
1023 
1024 /** gets time in seconds used for setting up this propagator for new stages */
SCIPpropGetSetupTime(SCIP_PROP * prop)1025 SCIP_Real SCIPpropGetSetupTime(
1026    SCIP_PROP*            prop                /**< propagator */
1027    )
1028 {
1029    assert(prop != NULL);
1030 
1031    return SCIPclockGetTime(prop->setuptime);
1032 }
1033 
1034 /** sets frequency of propagator */
SCIPpropSetFreq(SCIP_PROP * prop,int freq)1035 void SCIPpropSetFreq(
1036    SCIP_PROP*            prop,               /**< propagator */
1037    int                   freq                /**< new frequency of propagator */
1038    )
1039 {
1040    assert(prop != NULL);
1041    assert(freq >= -1);
1042 
1043    prop->freq = freq;
1044 }
1045 
1046 /** gets time in seconds used in this propagator for propagation */
SCIPpropGetTime(SCIP_PROP * prop)1047 SCIP_Real SCIPpropGetTime(
1048    SCIP_PROP*            prop                /**< propagator */
1049    )
1050 {
1051    assert(prop != NULL);
1052 
1053    return SCIPclockGetTime(prop->proptime);
1054 }
1055 
1056 /** gets time in seconds used in this propagator for propagation during strong branching */
SCIPpropGetStrongBranchPropTime(SCIP_PROP * prop)1057 SCIP_Real SCIPpropGetStrongBranchPropTime(
1058    SCIP_PROP*            prop                /**< propagator */
1059    )
1060 {
1061    assert(prop != NULL);
1062 
1063    return SCIPclockGetTime(prop->sbproptime);
1064 }
1065 
1066 /** gets time in seconds used in this propagator for resolve propagation */
SCIPpropGetRespropTime(SCIP_PROP * prop)1067 SCIP_Real SCIPpropGetRespropTime(
1068    SCIP_PROP*            prop                /**< propagator */
1069    )
1070 {
1071    assert(prop != NULL);
1072 
1073    return SCIPclockGetTime(prop->resproptime);
1074 }
1075 
1076 /** gets time in seconds used in this propagator for presolving */
SCIPpropGetPresolTime(SCIP_PROP * prop)1077 SCIP_Real SCIPpropGetPresolTime(
1078    SCIP_PROP*            prop                /**< propagator */
1079    )
1080 {
1081    assert(prop != NULL);
1082 
1083    return SCIPclockGetTime(prop->presoltime);
1084 }
1085 
1086 /** gets the total number of times, the propagator was called */
SCIPpropGetNCalls(SCIP_PROP * prop)1087 SCIP_Longint SCIPpropGetNCalls(
1088    SCIP_PROP*            prop                /**< propagator */
1089    )
1090 {
1091    assert(prop != NULL);
1092 
1093    return prop->ncalls;
1094 }
1095 
1096 /** gets the total number of times, the propagator was called for resolving a propagation */
SCIPpropGetNRespropCalls(SCIP_PROP * prop)1097 SCIP_Longint SCIPpropGetNRespropCalls(
1098    SCIP_PROP*            prop                /**< propagator */
1099    )
1100 {
1101    assert(prop != NULL);
1102 
1103    return prop->nrespropcalls;
1104 }
1105 
1106 /** gets total number of times, this propagator detected a cutoff */
SCIPpropGetNCutoffs(SCIP_PROP * prop)1107 SCIP_Longint SCIPpropGetNCutoffs(
1108    SCIP_PROP*            prop                /**< propagator */
1109    )
1110 {
1111    assert(prop != NULL);
1112 
1113    return prop->ncutoffs;
1114 }
1115 
1116 /** gets total number of domain reductions found by this propagator */
SCIPpropGetNDomredsFound(SCIP_PROP * prop)1117 SCIP_Longint SCIPpropGetNDomredsFound(
1118    SCIP_PROP*            prop                /**< propagator */
1119    )
1120 {
1121    assert(prop != NULL);
1122 
1123    return prop->ndomredsfound;
1124 }
1125 
1126 /** should propagator be delayed, if other propagators found reductions? */
SCIPpropIsDelayed(SCIP_PROP * prop)1127 SCIP_Bool SCIPpropIsDelayed(
1128    SCIP_PROP*            prop                /**< propagator */
1129    )
1130 {
1131    assert(prop != NULL);
1132 
1133    return prop->delay;
1134 }
1135 
1136 /** was propagator delayed at the last call? */
SCIPpropWasDelayed(SCIP_PROP * prop)1137 SCIP_Bool SCIPpropWasDelayed(
1138    SCIP_PROP*            prop                /**< propagator */
1139    )
1140 {
1141    assert(prop != NULL);
1142 
1143    return prop->wasdelayed;
1144 }
1145 
1146 /** is propagator initialized? */
SCIPpropIsInitialized(SCIP_PROP * prop)1147 SCIP_Bool SCIPpropIsInitialized(
1148    SCIP_PROP*            prop                /**< propagator */
1149    )
1150 {
1151    assert(prop != NULL);
1152 
1153    return prop->initialized;
1154 }
1155 
1156 /** gets number of variables fixed during presolving of propagator */
SCIPpropGetNFixedVars(SCIP_PROP * prop)1157 int SCIPpropGetNFixedVars(
1158    SCIP_PROP*            prop                /**< propagator */
1159    )
1160 {
1161    assert(prop != NULL);
1162 
1163    return prop->nfixedvars;
1164 }
1165 
1166 /** gets number of variables aggregated during presolving of propagator  */
SCIPpropGetNAggrVars(SCIP_PROP * prop)1167 int SCIPpropGetNAggrVars(
1168    SCIP_PROP*            prop                /**< propagator */
1169    )
1170 {
1171    assert(prop != NULL);
1172 
1173    return prop->naggrvars;
1174 }
1175 
1176 /** gets number of variable types changed during presolving of propagator  */
SCIPpropGetNChgVarTypes(SCIP_PROP * prop)1177 int SCIPpropGetNChgVarTypes(
1178    SCIP_PROP*            prop                /**< propagator */
1179    )
1180 {
1181    assert(prop != NULL);
1182 
1183    return prop->nchgvartypes;
1184 }
1185 
1186 /** gets number of bounds changed during presolving of propagator  */
SCIPpropGetNChgBds(SCIP_PROP * prop)1187 int SCIPpropGetNChgBds(
1188    SCIP_PROP*            prop                /**< propagator */
1189    )
1190 {
1191    assert(prop != NULL);
1192 
1193    return prop->nchgbds;
1194 }
1195 
1196 /** gets number of holes added to domains of variables during presolving of propagator  */
SCIPpropGetNAddHoles(SCIP_PROP * prop)1197 int SCIPpropGetNAddHoles(
1198    SCIP_PROP*            prop                /**< propagator */
1199    )
1200 {
1201    assert(prop != NULL);
1202 
1203    return prop->naddholes;
1204 }
1205 
1206 /** gets number of constraints deleted during presolving of propagator */
SCIPpropGetNDelConss(SCIP_PROP * prop)1207 int SCIPpropGetNDelConss(
1208    SCIP_PROP*            prop                /**< propagator */
1209    )
1210 {
1211    assert(prop != NULL);
1212 
1213    return prop->ndelconss;
1214 }
1215 
1216 /** gets number of constraints added during presolving of propagator */
SCIPpropGetNAddConss(SCIP_PROP * prop)1217 int SCIPpropGetNAddConss(
1218    SCIP_PROP*            prop                /**< propagator */
1219    )
1220 {
1221    assert(prop != NULL);
1222 
1223    return prop->naddconss;
1224 }
1225 
1226 /** gets number of constraints upgraded during presolving of propagator  */
SCIPpropGetNUpgdConss(SCIP_PROP * prop)1227 int SCIPpropGetNUpgdConss(
1228    SCIP_PROP*            prop                /**< propagator */
1229    )
1230 {
1231    assert(prop != NULL);
1232 
1233    return prop->nupgdconss;
1234 }
1235 
1236 /** gets number of coefficients changed during presolving of propagator */
SCIPpropGetNChgCoefs(SCIP_PROP * prop)1237 int SCIPpropGetNChgCoefs(
1238    SCIP_PROP*            prop                /**< propagator */
1239    )
1240 {
1241    assert(prop != NULL);
1242 
1243    return prop->nchgcoefs;
1244 }
1245 
1246 /** gets number of constraint sides changed during presolving of propagator */
SCIPpropGetNChgSides(SCIP_PROP * prop)1247 int SCIPpropGetNChgSides(
1248    SCIP_PROP*            prop                /**< propagator */
1249    )
1250 {
1251    assert(prop != NULL);
1252 
1253    return prop->nchgsides;
1254 }
1255 
1256 /** gets number of times the propagator was called in presolving and tried to find reductions */
SCIPpropGetNPresolCalls(SCIP_PROP * prop)1257 int SCIPpropGetNPresolCalls(
1258    SCIP_PROP*            prop                /**< propagator */
1259    )
1260 {
1261    assert(prop != NULL);
1262 
1263    return prop->npresolcalls;
1264 }
1265 
1266 /** returns the timing mask of the propagator */
SCIPpropGetTimingmask(SCIP_PROP * prop)1267 SCIP_PROPTIMING SCIPpropGetTimingmask(
1268    SCIP_PROP*            prop                /**< propagator */
1269    )
1270 {
1271    assert(prop != NULL);
1272 
1273    return prop->timingmask;
1274 }
1275 
1276 /** does the propagator perform presolving? */
SCIPpropDoesPresolve(SCIP_PROP * prop)1277 SCIP_Bool SCIPpropDoesPresolve(
1278    SCIP_PROP*            prop                /**< propagator */
1279    )
1280 {
1281    assert(prop != NULL);
1282 
1283    return (prop->proppresol != NULL);
1284 }
1285 
1286 /** returns the timing mask of the presolving method of the propagator */
SCIPpropGetPresolTiming(SCIP_PROP * prop)1287 SCIP_PRESOLTIMING SCIPpropGetPresolTiming(
1288    SCIP_PROP*            prop                /**< propagator */
1289    )
1290 {
1291    assert(prop != NULL);
1292 
1293    return prop->presoltiming;
1294 }
1295 
1296 /** sets the timing mask of the presolving method of the propagator */
SCIPpropSetPresolTiming(SCIP_PROP * prop,SCIP_PRESOLTIMING presoltiming)1297 void SCIPpropSetPresolTiming(
1298    SCIP_PROP*            prop,               /**< propagator */
1299    SCIP_PRESOLTIMING     presoltiming        /** timing mask to be set */
1300    )
1301 {
1302    assert(prop != NULL);
1303 
1304    prop->presoltiming = presoltiming;
1305 }
1306