d = dp[-1]; /* take single literal */
}
-#if 0
- if (n == 0 && !solv->rpmrules_end)
- {
- /* this is a rpm rule assertion, we do not have to allocate it */
- /* it can be identified by a level of 1 and a zero reason */
- /* we must not drop those rules from the decisionq when rewinding! */
- assert(p < 0);
- assert(solv->decisionmap[-p] == 0 || solv->decisionmap[-p] == -1);
- if (solv->decisionmap[-p])
- return 0; /* already got that one */
- queue_push(&solv->decisionq, p);
- queue_push(&solv->decisionq_why, 0);
- solv->decisionmap[-p] = -1;
- return 0;
- }
-#endif
-
if (n == 1 && p > d && !solv->rpmrules_end)
{
/* smallest literal first so we can find dups */
continue;
}
- assert(solv->decisionq_why.elements[i]);
+ assert(solv->decisionq_why.elements[i] > 0);
/*
* conflict with an rpm rule ?
goto l1retry;
}
why = solv->decisionq_why.elements[idx];
- if (!why) /* just in case, maybe for SYSTEMSOLVABLE */
+ if (why <= 0) /* just in case, maybe for SYSTEMSOLVABLE */
goto l1retry;
c = solv->rules + why;
}
if (!MAPTST(&seen, vv))
continue;
why = solv->decisionq_why.elements[idx];
+ assert(why > 0);
queue_push(&solv->learnt_pool, why);
r = solv->rules + why;
analyze_unsolvable_rule(solv, r, &lastweak);
*/
static int
-setpropagatelearn(Solver *solv, int level, Id decision, int disablerules)
+setpropagatelearn(Solver *solv, int level, Id decision, int disablerules, Id ruleid)
{
Pool *pool = solv->pool;
Rule *r;
Id p = 0, d = 0;
int l, why;
+ assert(ruleid >= 0);
if (decision)
{
level++;
else
solv->decisionmap[-decision] = -level;
queue_push(&solv->decisionq, decision);
- queue_push(&solv->decisionq_why, 0);
+ queue_push(&solv->decisionq_why, -ruleid); /* <= 0 -> free decision */
}
for (;;)
{
*/
static int
-selectandinstall(Solver *solv, int level, Queue *dq, int disablerules)
+selectandinstall(Solver *solv, int level, Queue *dq, int disablerules, Id ruleid)
{
Pool *pool = solv->pool;
Id p;
POOL_DEBUG(SAT_DEBUG_POLICY, "installing %s\n", solvable2str(pool, pool->solvables + p));
- return setpropagatelearn(solv, level, p, disablerules);
+ return setpropagatelearn(solv, level, p, disablerules, ruleid);
}
dq.count = k;
}
olevel = level;
- level = selectandinstall(solv, level, &dq, disablerules);
+ level = selectandinstall(solv, level, &dq, disablerules, i);
if (level == 0)
{
queue_free(&dq);
if (solv->decisionmap[i] != 0)
continue;
+ r = solv->rules + solv->updaterules + (i - solv->installed->start);
+ if (!r->p) /* update rule == feature rule? */
+ r = r - solv->updaterules + solv->featurerules;
+ if (r->p && r->p != i) /* allowed to keep package? */
+ continue;
+
POOL_DEBUG(SAT_DEBUG_PROPAGATE, "keeping %s\n", solvable2str(pool, s));
olevel = level;
- level = setpropagatelearn(solv, level, i, disablerules);
+ level = setpropagatelearn(solv, level, i, disablerules, r->p ? r - solv->rules : 0);
if (level == 0) /* unsolvable */
{
p = dq.elements[0];
if (p != i && solv->decisionmap[p] == 0)
{
+ r = solv->rules + solv->featurerules + (i - solv->installed->start);
+ if (!r->p) /* update rule == feature rule? */
+ r = r - solv->featurerules + solv->updaterules;
olevel = level;
POOL_DEBUG(SAT_DEBUG_POLICY, "installing (multi-version) %s\n", solvable2str(pool, pool->solvables + p));
- level = setpropagatelearn(solv, level, p, disablerules);
+ level = setpropagatelearn(solv, level, p, disablerules, r->p ? r - solv->rules : 0);
if (level == 0)
{
queue_free(&dq);
{
olevel = level;
POOL_DEBUG(SAT_DEBUG_POLICY, "keeping (multi-version) %s\n", solvable2str(pool, pool->solvables + p));
- level = setpropagatelearn(solv, level, p, disablerules);
+ level = setpropagatelearn(solv, level, p, disablerules, r - solv->rules);
if (level == 0)
{
queue_free(&dq);
if (p || !dq.count) /* already fulfilled or empty */
continue;
olevel = level;
- level = selectandinstall(solv, level, &dq, disablerules);
+ level = selectandinstall(solv, level, &dq, disablerules, rr - solv->rules);
if (level == 0)
{
queue_free(&dq);
assert(dq.count > 1);
olevel = level;
- level = selectandinstall(solv, level, &dq, disablerules);
+ level = selectandinstall(solv, level, &dq, disablerules, r - solv->rules);
if (level == 0)
{
queue_free(&dq);
else
POOL_DEBUG(SAT_DEBUG_POLICY, "installing recommended %s\n", solvable2str(pool, pool->solvables + p));
queue_push(&solv->recommendations, p);
- level = setpropagatelearn(solv, level, p, 0);
+ level = setpropagatelearn(solv, level, p, 0, 0);
continue;
}
POOL_DEBUG(SAT_DEBUG_POLICY, "installing supplemented %s\n", solvable2str(pool, pool->solvables + p));
queue_push(&solv->recommendations, p);
olevel = level;
- level = setpropagatelearn(solv, level, p, 0);
+ level = setpropagatelearn(solv, level, p, 0, 0);
if (level <= olevel)
break;
}
POOL_DEBUG(SAT_DEBUG_POLICY, "installing recommended %s\n", solvable2str(pool, pool->solvables + p));
queue_push(&solv->recommendations, p);
olevel = level;
- level = setpropagatelearn(solv, level, p, 0);
+ level = setpropagatelearn(solv, level, p, 0, 0);
if (level <= olevel || solv->decisionq.count < decisioncount)
break;
}
}
POOL_DEBUG(SAT_DEBUG_POLICY, "installing recommended %s\n", solvable2str(pool, pool->solvables + p));
queue_push(&solv->recommendations, p);
- level = setpropagatelearn(solv, level, p, 0);
+ level = setpropagatelearn(solv, level, p, 0, 0);
continue;
}
#endif
if (solv->distupgrade_removeunsupported)
{
POOL_DEBUG(SAT_DEBUG_STATS, "removing unsupported %s\n", solvable2str(pool, pool->solvables + p));
- level = setpropagatelearn(solv, level, -p, 0);
+ level = setpropagatelearn(solv, level, -p, 0, 0);
}
else
{
POOL_DEBUG(SAT_DEBUG_STATS, "keeping unsupported %s\n", solvable2str(pool, pool->solvables + p));
- level = setpropagatelearn(solv, level, p, 0);
+ level = setpropagatelearn(solv, level, p, 0, 0);
}
continue;
}
{
int i = solv->branches.count - 1;
int l = -solv->branches.elements[i];
+ Id why;
+
for (; i > 0; i--)
if (solv->branches.elements[i - 1] < 0)
break;
for (j = 0; j < dq.count; j++)
queue_push(&solv->branches, dq.elements[j]);
olevel = level;
- level = setpropagatelearn(solv, level, p, disablerules);
+ why = -solv->decisionq_why.elements[solv->decisionq_why.count];
+ assert(why >= 0);
+ level = setpropagatelearn(solv, level, p, disablerules, why);
if (level == 0)
{
queue_free(&dq);
if (solv->branches.count)
{
int l = 0, lasti = -1, lastl = -1;
+ Id why;
+
p = 0;
for (i = solv->branches.count - 1; i >= 0; i--)
{
level = lastl;
revert(solv, level);
+ why = -solv->decisionq_why.elements[solv->decisionq_why.count];
+ assert(why >= 0);
olevel = level;
- level = setpropagatelearn(solv, level, p, disablerules);
+ level = setpropagatelearn(solv, level, p, disablerules, why);
if (level == 0)
{
queue_free(&dq);