char * problem_string( const Problem *p, int full ) { Pool *pool = p->solver->pool; if (full == 0) { app_debugstart(pool,SAT_DEBUG_RESULT); #if SATSOLVER_VERSION >= 1500 solver_printcompleteprobleminfo(p->solver, p->id); #endif } else if (full > 0) { app_debugstart(pool,SAT_DEBUG_RESULT); #if SATSOLVER_VERSION < 1400 solver_printprobleminfo(p->solver, &(p->request->queue), p->id); #else solver_printprobleminfo(p->solver, p->id); #endif } else { app_debugstart(pool,SAT_DEBUG_SOLUTIONS); solver_printproblem(p->solver, p->id); } return app_debugend(); }
static void refine_suggestion(Solver *solv, Id *problem, Id sug, Queue *refined, int essentialok) { Pool *pool = solv->pool; int i, j; Id v; Queue disabled; int disabledcnt; IF_POOLDEBUG (SOLV_DEBUG_SOLUTIONS) { POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "refine_suggestion start\n"); for (i = 0; problem[i]; i++) { if (problem[i] == sug) POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "=> "); solver_printproblem(solv, problem[i]); } } queue_empty(refined); if (!essentialok && sug < 0 && (solv->job.elements[-sug - 1] & SOLVER_ESSENTIAL) != 0) return; queue_init(&disabled); queue_push(refined, sug); /* re-enable all problem rules with the exception of "sug"(gestion) */ solver_reset(solv); for (i = 0; problem[i]; i++) if (problem[i] != sug) solver_enableproblem(solv, problem[i]); if (sug < 0) solver_reenablepolicyrules(solv, -sug); else if (sug >= solv->updaterules && sug < solv->updaterules_end) { /* enable feature rule */ Rule *r = solv->rules + solv->featurerules + (sug - solv->updaterules); if (r->p) solver_enablerule(solv, r); } enableweakrules(solv); for (;;) { int njob, nfeature, nupdate, pass; queue_empty(&solv->problems); solver_reset(solv); if (!solv->problems.count) solver_run_sat(solv, 0, 0); if (!solv->problems.count) { POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "no more problems!\n"); break; /* great, no more problems */ } disabledcnt = disabled.count; /* start with 1 to skip over proof index */ njob = nfeature = nupdate = 0; for (pass = 0; pass < 2; pass++) { for (i = 1; i < solv->problems.count - 1; i++) { /* ignore solutions in refined */ v = solv->problems.elements[i]; if (v == 0) break; /* end of problem reached */ if (sug != v) { /* check if v is in the given problems list * we allow disabling all problem rules *after* sug in * pass 2, to prevent getting the same solution twice */ for (j = 0; problem[j]; j++) if (problem[j] == v || (pass && problem[j] == sug)) break; if (problem[j] == v) continue; } if (v >= solv->featurerules && v < solv->featurerules_end) nfeature++; else if (v > 0) nupdate++; else { if (!essentialok && (solv->job.elements[-v - 1] & SOLVER_ESSENTIAL) != 0) continue; /* not that one! */ njob++; } queue_push(&disabled, v); } if (disabled.count != disabledcnt) break; } if (disabled.count == disabledcnt) { /* no solution found, this was an invalid suggestion! */ POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "no solution found!\n"); refined->count = 0; break; } if (!njob && nupdate && nfeature) { /* got only update rules, filter out feature rules */ POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "throwing away feature rules\n"); for (i = j = disabledcnt; i < disabled.count; i++) { v = disabled.elements[i]; if (v < solv->featurerules || v >= solv->featurerules_end) disabled.elements[j++] = v; } disabled.count = j; nfeature = 0; } if (disabled.count == disabledcnt + 1) { /* just one suggestion, add it to refined list */ v = disabled.elements[disabledcnt]; if (!nfeature && v != sug) queue_push(refined, v); /* do not record feature rules */ solver_disableproblem(solv, v); if (v >= solv->updaterules && v < solv->updaterules_end) { Rule *r = solv->rules + (v - solv->updaterules + solv->featurerules); if (r->p) solver_enablerule(solv, r); /* enable corresponding feature rule */ } if (v < 0) solver_reenablepolicyrules(solv, -v); } else { /* more than one solution, disable all */ /* do not push anything on refine list, as we do not know which solution to choose */ /* thus, the user will get another problem if he selects this solution, where he * can choose the right one */ IF_POOLDEBUG (SOLV_DEBUG_SOLUTIONS) { POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "more than one solution found:\n"); for (i = disabledcnt; i < disabled.count; i++) solver_printproblem(solv, disabled.elements[i]); } for (i = disabledcnt; i < disabled.count; i++) { v = disabled.elements[i]; solver_disableproblem(solv, v); if (v >= solv->updaterules && v < solv->updaterules_end) { Rule *r = solv->rules + (v - solv->updaterules + solv->featurerules); if (r->p) solver_enablerule(solv, r); } } } } /* all done, get us back into the same state as before */ /* enable refined rules again */ for (i = 0; i < disabled.count; i++) solver_enableproblem(solv, disabled.elements[i]); queue_free(&disabled); /* reset policy rules */ for (i = 0; problem[i]; i++) solver_enableproblem(solv, problem[i]); solver_disablepolicyrules(solv); /* disable problem rules again */ for (i = 0; problem[i]; i++) solver_disableproblem(solv, problem[i]); POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "refine_suggestion end\n"); }