Id b = *(Id *)bp;
r = pool->solvables[a].name - pool->solvables[b].name;
if (r)
- return r;
+ {
+ const char *na, *nb;
+ /* different names. We use real strcmp here so that the result
+ * is not depending on some random solvable order */
+ na = id2str(pool, pool->solvables[a].name);
+ nb = id2str(pool, pool->solvables[b].name);
+ /* bring selections and patterns to the front */
+ if (!strncmp(na, "pattern:", 8))
+ {
+ if (strncmp(nb, "pattern:", 8))
+ return -1;
+ }
+ else if (!strncmp(nb, "pattern:", 8))
+ {
+ if (strncmp(na, "pattern:", 8))
+ return 1;
+ }
+ if (!strncmp(na, "selection:", 10))
+ {
+ if (strncmp(nb, "selection:", 10))
+ return -1;
+ }
+ else if (!strncmp(nb, "selection:", 10))
+ {
+ if (strncmp(na, "selection:", 10))
+ return 1;
+ }
+ return strcmp(na, nb);
+ }
return a - b;
}
/* unit clause found, set other watch to TRUE */
if (DECISIONMAP_TRUE(-ow))
return r; /* eek, a conflict! */
-#if 0
- printf("unit ");
- printrule(solv, r);
-#endif
+ if (pool->verbose > 2)
+ {
+ printf("unit ");
+ printrule(solv, r);
+ }
if (ow > 0)
decisionmap[ow] = level;
else
solv->decisionq_why.count--;
solv->propagate_index = solv->decisionq.count;
}
+ while (solv->minimize.count && solv->minimize.elements[solv->minimize.count - 1] < -level)
+ {
+ solv->minimize.count--;
+ while (solv->minimize.count && solv->minimize.elements[solv->minimize.count - 1] >= 0)
+ solv->minimize.count--;
+ }
solv->recommends_index = -1;
}
queue_init(&solv->suggestions);
queue_init(&solv->learnt_why);
queue_init(&solv->learnt_pool);
+ queue_init(&solv->minimize);
map_init(&solv->recommendsmap, pool->nsolvables);
map_init(&solv->suggestsmap, pool->nsolvables);
memset(solv->rules, 0, sizeof(Rule));
solv->nrules = 1;
- policy_init( pool );
-
return solv;
}
void
solver_free(Solver *solv)
{
- policy_exit();
-
queue_free(&solv->ruletojob);
queue_free(&solv->decisionq);
queue_free(&solv->decisionq_why);
queue_free(&solv->learnt_pool);
queue_free(&solv->problems);
queue_free(&solv->suggestions);
+ queue_free(&solv->minimize);
map_free(&solv->recommendsmap);
map_free(&solv->suggestsmap);
/*
* run_solver
*
- * all rules have been set up, not actually run the solver
+ * all rules have been set up, now actually run the solver
*
*/
Pool *pool = solv->pool;
Id p, *dp;
-if (policy_printrules())
-{
+#if 0
printf("number of rules: %d\n", solv->nrules);
- int i;
for (i = 0; i < solv->nrules; i++)
- {
- printrule(solv, solv->rules + i);
- }
-}
+ printrule(solv, solv->rules + i);
+#endif
/* all new rules are learnt after this point */
solv->learntrules = solv->nrules;
printrule(solv, r);
abort();
}
+ if (pool->verbose > 2)
+ printrule(solv, r);
prune_to_highest_prio(pool, &dq);
if (dq.count > 1)
prune_to_recommended(solv, &dq);
if (dq.count > 1)
prune_best_version_arch(pool, &dq);
- p = dq.elements[dq.count - 1];
+ if (dq.count > 1)
+ {
+ int j;
+ for (j = 1; j < dq.count; j++)
+ queue_push(&solv->minimize, dq.elements[j]);
+ queue_push(&solv->minimize, -level);
+ }
+ p = dq.elements[0];
s = pool->solvables + p;
#if 0
printf("installing %s-%s.%s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
break;
}
else if (solv->decisionmap[p] == 0)
- queue_pushunique(&dq, p);
+ {
+ queue_pushunique(&dq, p);
+ }
}
}
}
prune_to_highest_prio(pool, &dq);
if (dq.count > 1)
prune_best_version_arch(pool, &dq);
- p = dq.elements[dq.count - 1];
+ p = dq.elements[0];
s = pool->solvables + p;
#if 1
printf("installing recommended %s-%s.%s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
continue;
}
}
+ /* minimization step */
+ if (solv->minimize.count)
+ {
+ int l = 0, lasti = -1, lastl = -1;
+ p = 0;
+ for (i = solv->minimize.count - 1; i >= 0; i--)
+ {
+ p = solv->minimize.elements[i];
+ if (p < 0)
+ l = -p;
+ else if (p > 0 && solv->decisionmap[p] > l + 1)
+ {
+ lasti = i;
+ lastl = l;
+ }
+ }
+ if (lasti >= 0)
+ {
+ /* kill old solvable so that we do not loop */
+ p = solv->minimize.elements[lasti];
+ solv->minimize.elements[lasti] = 0;
+ s = pool->solvables + p;
+#if 1
+ printf("minimizing %d -> %d with %s-%s.%s\n", solv->decisionmap[p], l, id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
+#endif
+ level = lastl;
+ revert(solv, level);
+ olevel = level;
+ level = setpropagatelearn(solv, level, p, disablerules);
+ if (level == 0)
+ {
+ printf("UNSOLVABLE\n");
+ queue_free(&dq);
+ return;
+ }
+ continue;
+ }
+ }
break;
}
queue_free(&dq);
{
case SOLVER_INSTALL_SOLVABLE: /* install specific solvable */
s = pool->solvables + what;
- if (solv->rc_output) {
- printf(">!> Installing %s from channel %s\n", id2str(pool, s->name), repo_name(s->repo));
- }
+ if (solv->rc_output)
+ {
+ printf(">!> Installing %s from channel %s\n", id2str(pool, s->name), repo_name(s->repo));
+ }
+ if (pool->verbose)
+ printf("job: install solvable %s-%s.%s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
addrule(solv, what, 0); /* install by Id */
queue_push(&solv->ruletojob, i);
FOR_PROVIDES(p, pp, s->name)
MAPSET(&noupdaterule, p);
break;
case SOLVER_ERASE_SOLVABLE:
+ s = pool->solvables + what;
+ if (pool->verbose)
+ printf("job: erase solvable %s-%s.%s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
addrule(solv, -what, 0); /* remove by Id */
queue_push(&solv->ruletojob, i);
MAPSET(&noupdaterule, what);
break;
case SOLVER_INSTALL_SOLVABLE_NAME: /* install by capability */
case SOLVER_INSTALL_SOLVABLE_PROVIDES:
+ if (pool->verbose && how == SOLVER_INSTALL_SOLVABLE_NAME)
+ printf("job: install name %s\n", id2str(pool, what));
+ if (pool->verbose && how == SOLVER_INSTALL_SOLVABLE_PROVIDES)
+ printf("job: install provides %s\n", dep2str(pool, what));
queue_empty(&q);
FOR_PROVIDES(p, pp, what)
{
break;
case SOLVER_ERASE_SOLVABLE_NAME: /* remove by capability */
case SOLVER_ERASE_SOLVABLE_PROVIDES:
+ if (pool->verbose && how == SOLVER_ERASE_SOLVABLE_NAME)
+ printf("job: erase name %s\n", id2str(pool, what));
+ if (pool->verbose && how == SOLVER_ERASE_SOLVABLE_PROVIDES)
+ printf("job: erase provides %s\n", dep2str(pool, what));
FOR_PROVIDES(p, pp, what)
{
/* if by name, ensure that the name matches */
}
break;
case SOLVER_INSTALL_SOLVABLE_UPDATE: /* find update for solvable */
- addupdaterule(solv, pool->solvables + what, &addedmap, 0, 0, 0, 0);
+ s = pool->solvables + what;
+ MAPSET(&noupdaterule, what);
+ if (pool->verbose)
+ printf("job: update %s-%s.%s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
+ addupdaterule(solv, s, &addedmap, 0, 0, 0, 0);
queue_push(&solv->ruletojob, i);
break;
}
FOR_PROVIDES(p, pp, sug)
MAPSET(&solv->suggestsmap, p);
}
- } }
+ }
+ }
for (i = 1; i < pool->nsolvables; i++)
{
if (solv->decisionmap[i] != 0)