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 debug.h 26 * @ingroup INTERNALAPI 27 * @brief methods for debugging 28 * @author Tobias Achterberg 29 */ 30 31 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/ 32 33 #ifndef __SCIP_DEBUG_H__ 34 #define __SCIP_DEBUG_H__ 35 36 /** uncomment this define to activate debugging the LP interface */ 37 /* #define SCIP_DEBUG_LP_INTERFACE */ 38 39 #include "scip/def.h" 40 #include "scip/type_retcode.h" 41 #include "scip/type_scip.h" 42 43 #ifdef WITH_DEBUG_SOLUTION 44 #include "blockmemshell/memory.h" 45 #include "scip/type_cons.h" 46 #include "scip/type_lp.h" 47 #include "scip/type_misc.h" 48 #include "scip/type_set.h" 49 #include "scip/type_sol.h" 50 #include "scip/type_tree.h" 51 #include "scip/type_var.h" 52 #endif 53 54 #ifdef __cplusplus 55 extern "C" { 56 #endif 57 58 /** solution data for debugging purposes */ 59 typedef struct SCIP_DebugSolData SCIP_DEBUGSOLDATA; 60 61 #ifdef WITH_DEBUG_SOLUTION 62 63 /** creates debug solution data */ 64 SCIP_RETCODE SCIPdebugSolDataCreate( 65 SCIP_DEBUGSOLDATA** debugsoldata /**< pointer to debug solution data */ 66 ); 67 68 /** frees the debug solution */ 69 SCIP_RETCODE SCIPdebugFreeSol( 70 SCIP_SET* set 71 ); 72 73 /** resets the data structure after restart */ 74 SCIP_RETCODE SCIPdebugReset( 75 SCIP_SET* set 76 ); 77 78 /** frees debugging data for the particular instance */ 79 SCIP_RETCODE SCIPdebugFreeDebugData( 80 SCIP_SET* set /**< global SCIP settings */ 81 ); 82 83 /** frees all debugging data */ 84 SCIP_RETCODE SCIPdebugFree( 85 SCIP_SET* set /**< global SCIP settings */ 86 ); 87 88 /** checks for validity of the debugging solution in given constraints */ 89 SCIP_RETCODE SCIPdebugCheckConss( 90 SCIP* scip, /**< SCIP data structure */ 91 SCIP_CONS** conss, /**< constraints to check for validity */ 92 int nconss /**< number of given constraints */ 93 ); 94 95 /** checks whether given row is valid for the debugging solution */ 96 SCIP_RETCODE SCIPdebugCheckRow( 97 SCIP_SET* set, /**< global SCIP settings */ 98 SCIP_ROW* row /**< row to check for validity */ 99 ); 100 101 /** checks whether given global lower bound is valid for the debugging solution */ 102 SCIP_RETCODE SCIPdebugCheckLbGlobal( 103 SCIP* scip, /**< SCIP data structure */ 104 SCIP_VAR* var, /**< problem variable */ 105 SCIP_Real lb /**< lower bound */ 106 ); 107 108 /** checks whether given global upper bound is valid for the debugging solution */ 109 SCIP_RETCODE SCIPdebugCheckUbGlobal( 110 SCIP* scip, /**< SCIP data structure */ 111 SCIP_VAR* var, /**< problem variable */ 112 SCIP_Real ub /**< upper bound */ 113 ); 114 115 /** checks whether given local bound implication is valid for the debugging solution */ 116 SCIP_RETCODE SCIPdebugCheckInference( 117 BMS_BLKMEM* blkmem, /**< block memory */ 118 SCIP_SET* set, /**< global SCIP settings */ 119 SCIP_NODE* node, /**< local node where this bound change was applied */ 120 SCIP_VAR* var, /**< problem variable */ 121 SCIP_Real newbound, /**< new value for bound */ 122 SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */ 123 ); 124 125 /** informs solution debugger, that the given node will be freed */ 126 SCIP_RETCODE SCIPdebugRemoveNode( 127 BMS_BLKMEM* blkmem, /**< block memory */ 128 SCIP_SET* set, /**< global SCIP settings */ 129 SCIP_NODE* node /**< node that will be freed */ 130 ); 131 132 /** checks whether global lower bound does not exceed debuging solution value */ 133 SCIP_RETCODE SCIPdebugCheckGlobalLowerbound( 134 BMS_BLKMEM* blkmem, /**< block memory */ 135 SCIP_SET* set /**< global SCIP settings */ 136 ); 137 138 /** checks whether local lower bound does not exceed debuging solution value */ 139 SCIP_RETCODE SCIPdebugCheckLocalLowerbound( 140 BMS_BLKMEM* blkmem, /**< block memory */ 141 SCIP_SET* set, /**< global SCIP settings */ 142 SCIP_NODE* node /**< node that will be freed */ 143 ); 144 145 /** checks whether given variable bound is valid for the debugging solution */ 146 SCIP_RETCODE SCIPdebugCheckVbound( 147 SCIP_SET* set, /**< global SCIP settings */ 148 SCIP_VAR* var, /**< problem variable x in x <= b*z + d or x >= b*z + d */ 149 SCIP_BOUNDTYPE vbtype, /**< type of variable bound (LOWER or UPPER) */ 150 SCIP_VAR* vbvar, /**< variable z in x <= b*z + d or x >= b*z + d */ 151 SCIP_Real vbcoef, /**< coefficient b in x <= b*z + d or x >= b*z + d */ 152 SCIP_Real vbconstant /**< constant d in x <= b*z + d or x >= b*z + d */ 153 ); 154 155 /** checks whether given implication is valid for the debugging solution */ 156 SCIP_RETCODE SCIPdebugCheckImplic( 157 SCIP_SET* set, /**< global SCIP settings */ 158 SCIP_VAR* var, /**< problem variable */ 159 SCIP_Bool varfixing, /**< FALSE if y should be added in implications for x == 0, TRUE for x == 1 */ 160 SCIP_VAR* implvar, /**< variable y in implication y <= b or y >= b */ 161 SCIP_BOUNDTYPE impltype, /**< type of implication y <= b (SCIP_BOUNDTYPE_UPPER) or y >= b (SCIP_BOUNDTYPE_LOWER) */ 162 SCIP_Real implbound /**< bound b in implication y <= b or y >= b */ 163 ); 164 165 /** checks whether given (multi)-aggregation is valid for the debugging solution */ 166 SCIP_RETCODE SCIPdebugCheckAggregation( 167 SCIP_SET* set, /**< global SCIP settings */ 168 SCIP_VAR* var, /**< problem variable */ 169 SCIP_VAR** aggrvars, /**< variables y_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */ 170 SCIP_Real* scalars, /**< multipliers a_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */ 171 SCIP_Real constant, /**< constant shift c in aggregation x = a_1*y_1 + ... + a_n*y_n + c */ 172 int naggrvars /**< number n of variables in aggregation x = a_1*y_1 + ... + a_n*y_n + c */ 173 ); 174 175 /** check whether given clique is valid for the debugging solution */ 176 SCIP_RETCODE SCIPdebugCheckClique( 177 SCIP_SET* set, /**< global SCIP settings */ 178 SCIP_VAR** vars, /**< binary variables in the clique: at most one can be set to the given value */ 179 SCIP_Bool* values, /**< values of the variables in the clique; NULL to use TRUE for all vars */ 180 int nvars /**< number of variables in the clique */ 181 ); 182 183 /** checks whether given conflict is valid for the debugging solution */ 184 SCIP_RETCODE SCIPdebugCheckConflict( 185 BMS_BLKMEM* blkmem, /**< block memory */ 186 SCIP_SET* set, /**< global SCIP settings */ 187 SCIP_NODE* node, /**< node where the conflict clause is added */ 188 SCIP_BDCHGINFO** bdchginfos, /**< bound change informations of the conflict set */ 189 SCIP_Real* relaxedbds, /**< array with relaxed bounds which are efficient to create a valid conflict */ 190 int nbdchginfos /**< number of bound changes in the conflict set */ 191 ); 192 193 /** checks whether given conflict graph frontier is valid for the debugging solution */ 194 SCIP_RETCODE SCIPdebugCheckConflictFrontier( 195 BMS_BLKMEM* blkmem, /**< block memory */ 196 SCIP_SET* set, /**< global SCIP settings */ 197 SCIP_NODE* node, /**< node where the conflict clause is added */ 198 SCIP_BDCHGINFO* bdchginfo, /**< bound change info which got resolved, or NULL */ 199 SCIP_BDCHGINFO** bdchginfos, /**< bound change informations of the conflict set */ 200 SCIP_Real* relaxedbds, /**< array with relaxed bounds which are efficient to create a valid conflict */ 201 int nbdchginfos, /**< number of bound changes in the conflict set */ 202 SCIP_PQUEUE* bdchgqueue, /**< unprocessed conflict bound changes */ 203 SCIP_PQUEUE* forcedbdchgqueue /**< unprocessed conflict bound changes that must be resolved */ 204 ); 205 206 /** creates the debugging propagator and includes it in SCIP */ 207 SCIP_RETCODE SCIPdebugIncludeProp( 208 SCIP* scip /**< SCIP data structure */ 209 ); 210 211 /** adds a solution value for a new variable in the transformed problem that has no original counterpart 212 * a value can only be set if no value has been set for this variable before 213 */ 214 SCIP_EXPORT 215 SCIP_RETCODE SCIPdebugAddSolVal( 216 SCIP* scip, /**< SCIP data structure */ 217 SCIP_VAR* var, /**< variable for which to add a value */ 218 SCIP_Real val /**< solution value for variable */ 219 ); 220 221 /** gets pointer to the debug solution */ 222 SCIP_EXPORT 223 SCIP_RETCODE SCIPdebugGetSol( 224 SCIP* scip, /**< SCIP data structure */ 225 SCIP_SOL** sol /**< buffer to store pointer to the debug solution */ 226 ); 227 228 /** gets value for a variable in the debug solution 229 * 230 * if no value is stored for the variable, gives 0.0 231 */ 232 SCIP_EXPORT 233 SCIP_RETCODE SCIPdebugGetSolVal( 234 SCIP* scip, /**< SCIP data structure */ 235 SCIP_VAR* var, /**< variable for which to get the value */ 236 SCIP_Real* val /**< buffer to store solution value */ 237 ); 238 239 /** check whether the debugging solution is valid in the current node */ 240 SCIP_EXPORT 241 SCIP_RETCODE SCIPdebugSolIsValidInSubtree( 242 SCIP* scip, /**< SCIP data structure */ 243 SCIP_Bool* isvalidinsubtree /**< pointer to store whether the solution is valid in the current 244 * subtree 245 */ 246 ); 247 248 /** checks whether SCIP data structure is the main SCIP (the one for which debugging is enabled) */ 249 SCIP_EXPORT 250 SCIP_Bool SCIPdebugIsMainscip( 251 SCIP* scip /**< SCIP data structure */ 252 ); 253 254 /** enabling solution debugging mechanism */ 255 SCIP_EXPORT 256 void SCIPdebugSolEnable( 257 SCIP* scip /**< SCIP data structure */ 258 ); 259 260 /** disabling solution debugging mechanism */ 261 SCIP_EXPORT 262 void SCIPdebugSolDisable( 263 SCIP* scip /**< SCIP data structure */ 264 ); 265 266 /** check if solution debugging mechanism is enabled */ 267 SCIP_EXPORT 268 SCIP_Bool SCIPdebugSolIsEnabled( 269 SCIP* scip /**< SCIP data structure */ 270 ); 271 272 /** check if SCIP is compiled with WITH_DEBUG_SOLUTION */ 273 SCIP_EXPORT 274 SCIP_Bool SCIPwithDebugSol(void); 275 276 #else 277 278 #define SCIPdebugSolDataCreate(debugsoldata) SCIP_OKAY 279 #define SCIPdebugFreeSol(set) SCIP_OKAY 280 #define SCIPdebugReset(set) SCIP_OKAY 281 #define SCIPdebugFreeDebugData(set) SCIP_OKAY 282 #define SCIPdebugFree(set) SCIP_OKAY 283 #define SCIPdebugCheckConss(scip,conss,nconss) SCIP_OKAY 284 #define SCIPdebugCheckRow(set,row) SCIP_OKAY 285 #define SCIPdebugCheckLbGlobal(scip,var,lb) SCIP_OKAY 286 #define SCIPdebugCheckUbGlobal(scip,var,ub) SCIP_OKAY 287 #define SCIPdebugCheckInference(blkmem,set,node,var,newbound,boundtype) SCIP_OKAY 288 #define SCIPdebugRemoveNode(blkmem,set,node) SCIP_OKAY 289 #define SCIPdebugCheckGlobalLowerbound(blkmem,set) SCIP_OKAY 290 #define SCIPdebugCheckLocalLowerbound(blkmem,set,node) SCIP_OKAY 291 #define SCIPdebugCheckVbound(set,var,vbtype,vbvar,vbcoef,vbconstant) SCIP_OKAY 292 #define SCIPdebugCheckImplic(set,var,varfixing,implvar,impltype,implbound) SCIP_OKAY 293 #define SCIPdebugCheckAggregation(set,var,aggrvars,scalars,constant,naggrvars) SCIP_OKAY 294 #define SCIPdebugCheckClique(set,vars,values,nvars) SCIP_OKAY 295 #define SCIPdebugCheckConflict(blkmem,set,node,bdchginfos,relaxedbds,nliterals) SCIP_OKAY 296 #define SCIPdebugCheckConflictFrontier(blkmem,set,node,bdchginfo,bdchginfos,relaxedbds,nliterals,bdchgqueue,forcedbdchgqueue) SCIP_OKAY 297 #define SCIPdebugIncludeProp(scip) SCIP_OKAY 298 #define SCIPdebugAddSolVal(scip,var,val) SCIP_OKAY 299 #define SCIPdebugGetSolVal(scip,var,val) SCIP_OKAY 300 #define SCIPdebugSolIsValidInSubtree(scip,isvalidinsubtree) SCIP_OKAY 301 #define SCIPdebugSolEnable(scip) /**/ 302 #define SCIPdebugSolDisable(scip) /**/ 303 #define SCIPdebugSolIsEnabled(scip) FALSE 304 #define SCIPwithDebugSol(void) FALSE 305 306 #endif 307 308 309 /* 310 * debug method for LP interface, to check if the LP interface works correct 311 */ 312 #ifdef SCIP_DEBUG_LP_INTERFACE 313 314 /* check if the coef is the r-th line of the inverse matrix B^-1; this is 315 * the case if (coef * B) is the r-th unit vector */ 316 SCIP_RETCODE SCIPdebugCheckBInvRow( 317 SCIP* scip, /**< SCIP data structure */ 318 int r, /**< row number */ 319 SCIP_Real* coef /**< pointer to store the coefficients of the row */ 320 ); 321 322 #else 323 324 #define SCIPdebugCheckBInvRow(scip,r,coef) SCIP_OKAY 325 326 #endif 327 328 /** checks, if SCIP is in one of the feasible stages */ 329 #ifndef NDEBUG 330 331 SCIP_RETCODE SCIPcheckStage( 332 SCIP* scip, /**< SCIP data structure */ 333 const char* method, /**< method that was called */ 334 SCIP_Bool init, /**< may method be called in the INIT stage? */ 335 SCIP_Bool problem, /**< may method be called in the PROBLEM stage? */ 336 SCIP_Bool transforming, /**< may method be called in the TRANSFORMING stage? */ 337 SCIP_Bool transformed, /**< may method be called in the TRANSFORMED stage? */ 338 SCIP_Bool initpresolve, /**< may method be called in the INITPRESOLVE stage? */ 339 SCIP_Bool presolving, /**< may method be called in the PRESOLVING stage? */ 340 SCIP_Bool exitpresolve, /**< may method be called in the EXITPRESOLE stage? */ 341 SCIP_Bool presolved, /**< may method be called in the PRESOLVED stage? */ 342 SCIP_Bool initsolve, /**< may method be called in the INITSOLVE stage? */ 343 SCIP_Bool solving, /**< may method be called in the SOLVING stage? */ 344 SCIP_Bool solved, /**< may method be called in the SOLVED stage? */ 345 SCIP_Bool exitsolve, /**< may method be called in the EXITSOLVE stage? */ 346 SCIP_Bool freetrans, /**< may method be called in the FREETRANS stage? */ 347 SCIP_Bool freescip /**< may method be called in the FREE stage? */ 348 ); 349 #else 350 351 #define SCIPcheckStage(scip,method,init,problem,transforming,transformed,initpresolve,presolving,exitpresolve,presolved, \ 352 initsolve,solving,solved,exitsolve,freetrans,freescip) SCIP_OKAY 353 354 #endif 355 356 #ifdef __cplusplus 357 } 358 #endif 359 360 #endif 361