/* map choice rules back to pkg rules */
if (solver_ruleclass(solv, id) == SOLVER_RULE_CHOICE)
id = solver_rule2pkgrule(solv, id);
+ if (solver_ruleclass(solv, id) == SOLVER_RULE_RECOMMENDS)
+ id = solver_rule2pkgrule(solv, id);
solver_allruleinfos(solv, id, &rq);
for (i = 0; i < rq.count; i += 4)
{
return SOLVER_RULE_YUMOBS;
}
if (rid >= solv->choicerules && rid < solv->choicerules_end)
- {
- return SOLVER_RULE_CHOICE;
- }
+ return SOLVER_RULE_CHOICE;
+ if (rid >= solv->recommendsrules && rid < solv->recommendsrules_end)
+ return SOLVER_RULE_RECOMMENDS;
if (rid >= solv->learntrules)
- {
- return SOLVER_RULE_LEARNT;
- }
+ return SOLVER_RULE_LEARNT;
return SOLVER_RULE_UNKNOWN;
}
return SOLVER_RULE_YUMOBS;
if (rid >= solv->choicerules && rid < solv->choicerules_end)
return SOLVER_RULE_CHOICE;
+ if (rid >= solv->recommendsrules && rid < solv->recommendsrules_end)
+ return SOLVER_RULE_RECOMMENDS;
if (rid >= solv->learntrules && rid < solv->nrules)
return SOLVER_RULE_LEARNT;
return SOLVER_RULE_UNKNOWN;
{
if (rid >= solv->choicerules && rid < solv->choicerules_end)
return solv->choicerules_ref[rid - solv->choicerules];
+ if (rid >= solv->recommendsrules && rid < solv->recommendsrules_end)
+ return solv->recommendsrules_info[rid - solv->recommendsrules];
return 0;
}
POOL_DEBUG(SOLV_DEBUG_STATS, "yumobs rule creation took %d ms\n", solv_timems(now));
}
+/* recommendsrules are a copy of some recommends package rule but
+ * with some disfavored literals removed */
+void
+solver_addrecommendsrules(Solver *solv)
+{
+ Pool *pool = solv->pool;
+ int i, havedis, havepos;
+ Id p, pp;
+ Queue q, infoq;
+
+ solv->recommendsrules = solv->nrules;
+ queue_init(&q);
+ queue_init(&infoq);
+ for (i = 0; i < solv->recommendsruleq->count; i++)
+ {
+ int rid = solv->recommendsruleq->elements[i];
+ Rule *r = solv->rules + rid;
+ queue_empty(&q);
+ havedis = havepos = 0;
+ FOR_RULELITERALS(p, pp, r)
+ {
+ if (p > 0 && solv->favormap[p] < 0)
+ havedis = 1;
+ else
+ {
+ if (p > 0)
+ havepos = 1;
+ queue_push(&q, p);
+ }
+ }
+ if (!havedis)
+ continue;
+ solver_disablerule(solv, r);
+ if (!havepos || q.count < 2)
+ continue;
+ if (q.count == 2)
+ solver_addrule(solv, q.elements[0], q.elements[1], 0);
+ else
+ solver_addrule(solv, q.elements[0], 0, pool_ids2whatprovides(pool, q.elements + 1, q.count - 1));
+ queue_push(&infoq, rid);
+ }
+ if (infoq.count)
+ solv->recommendsrules_info = solv_memdup2(infoq.elements, infoq.count, sizeof(Id));
+ queue_free(&infoq);
+ queue_free(&q);
+ solv->recommendsrules_end = solv->nrules;
+}
+
void
solver_breakorphans(Solver *solv)
{
SOLVER_RULE_CHOICE = 0x700,
SOLVER_RULE_LEARNT = 0x800,
SOLVER_RULE_BEST = 0x900,
- SOLVER_RULE_YUMOBS = 0xa00
+ SOLVER_RULE_YUMOBS = 0xa00,
+ SOLVER_RULE_RECOMMENDS = 0xb00
} SolverRuleinfo;
#define SOLVER_RULE_TYPEMASK 0xff00
/* yumobs rules */
extern void solver_addyumobsrules(struct s_Solver *solv);
+/* recommends rules */
+extern void solver_addrecommendsrules(struct s_Solver *solv);
+
/* policy rule disabling/reenabling */
extern void solver_disablepolicyrules(struct s_Solver *solv);
extern void solver_reenablepolicyrules(struct s_Solver *solv, int jobidx);
disable_recommendsrules(Solver *solv, Queue *weakq)
{
Pool *pool = solv->pool;
- int i;
+ int i, rid;
for (i = 0; i < weakq->count; i++)
{
- Rule *r;
- if (!queue_contains(solv->recommendsruleq, weakq->elements[i]))
- continue;
- r = solv->rules + weakq->elements[i];
- if (r->d >= 0)
+ rid = weakq->elements[i];
+ if ((rid >= solv->recommendsrules && rid < solv->recommendsrules_end) || queue_contains(solv->recommendsruleq, rid))
{
- POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "disabling ");
- solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, r);
- solver_disablerule(solv, r);
+ Rule *r = solv->rules + rid;
+ if (r->d >= 0)
+ {
+ POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "disabling ");
+ solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, r);
+ solver_disablerule(solv, r);
+ }
}
}
}
for (i = 0; i < weakq->count; i++)
if (weakq->elements[i] > lastweak)
lastweak = weakq->elements[i];
+ if (lastweak >= solv->recommendsrules && lastweak < solv->recommendsrules_end)
+ {
+ lastweak = 0;
+ for (i = 0; i < weakq->count; i++)
+ if (weakq->elements[i] < solv->recommendsrules && weakq->elements[i] > lastweak)
+ lastweak = weakq->elements[i];
+ if (lastweak < solv->pkgrules_end)
+ {
+ disable_recommendsrules(solv, weakq);
+ return;
+ }
+ }
if (lastweak < solv->pkgrules_end && solv->strongrecommends && solv->recommendsruleq && queue_contains(solv->recommendsruleq, lastweak))
{
disable_recommendsrules(solv, weakq);
solv_free(solv->choicerules_ref);
solv_free(solv->bestrules_pkg);
solv_free(solv->yumobsrules_info);
+ solv_free(solv->recommendsrules_info);
solv_free(solv->instbuddy);
solv_free(solv);
}
for (; i < pool->nsolvables; i++)
if (MAPTST(addedmap, i))
queue_push(&solv->addedmap_deduceq, i);
- j = 0;
- for (i = 2; i < pool->nsolvables; i++)
- if (MAPTST(addedmap, i))
- j++;
}
static void
queue_empty(&solv->ruleassertions);
solv->bestrules_pkg = solv_free(solv->bestrules_pkg);
solv->yumobsrules_info = solv_free(solv->yumobsrules_info);
+ solv->recommendsrules_info = solv_free(solv->recommendsrules_info);
solv->choicerules_ref = solv_free(solv->choicerules_ref);
if (solv->noupdate.size)
map_empty(&solv->noupdate);
*/
initialnrules = solv->pkgrules_end ? solv->pkgrules_end : 1;
if (initialnrules > 1)
- deduceq2addedmap(solv, &addedmap);
+ deduceq2addedmap(solv, &addedmap); /* also enables all pkg rules */
if (solv->nrules != initialnrules)
- solver_shrinkrules(solv, initialnrules);
+ solver_shrinkrules(solv, initialnrules); /* shrink to just pkg rules */
solv->lastpkgrule = 0;
solv->pkgrules_end = 0;
else
solv->yumobsrules = solv->yumobsrules_end = solv->nrules;
+ if (solv->havedisfavored && solv->strongrecommends)
+ solver_addrecommendsrules(solv);
+ else
+ solv->recommendsrules = solv->recommendsrules_end = solv->nrules;
+
if (1)
solver_addchoicerules(solv);
else
char buf[64];
if (solver_ruleclass(solv, id) == SOLVER_RULE_CHOICE)
id = solver_rule2pkgrule(solv, id);
+ if (solver_ruleclass(solv, id) == SOLVER_RULE_RECOMMENDS)
+ id = solver_rule2pkgrule(solv, id);
rtype = solver_ruleinfo(solv, id, &depfrom, &depto, &dep);
if ((rtype & SOLVER_RULE_TYPEMASK) == SOLVER_RULE_JOB)
{
Id choicerules_end;
Id *choicerules_ref;
+ Id recommendsrules; /* rules from recommends pkg rules with disfavored literals */
+ Id recommendsrules_end;
+ Id *recommendsrules_info; /* the original pkg rule rule */
+
Id learntrules; /* learnt rules, (end == nrules) */
Map noupdate; /* don't try to update these
POOL_DEBUG(type, "FEATURE ");
else if (p >= solv->yumobsrules && p < solv->yumobsrules_end)
POOL_DEBUG(type, "YUMOBS ");
+ else if (p >= solv->recommendsrules && p < solv->recommendsrules_end)
+ POOL_DEBUG(type, "RECOMMENDS ");
solver_printrule(solv, type, r);
}