1
// aptitude_resolver.h -*-c++-*-
4
// Copyright (C) 2005, 2008-2010 Daniel Burrows
6
// This program is free software; you can redistribute it and/or
7
// modify it under the terms of the GNU General Public License as
8
// published by the Free Software Foundation; either version 2 of
9
// the License, or (at your option) any later version.
11
// This program is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
// General Public License for more details.
16
// You should have received a copy of the GNU General Public License
17
// along with this program; see the file COPYING. If not, write to
18
// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
// Boston, MA 02111-1307, USA.
25
#ifndef APTITUDE_RESOLVER_H
26
#define APTITUDE_RESOLVER_H
28
#include "aptitude_resolver_cost_settings.h"
29
#include "aptitude_resolver_universe.h"
31
#include <generic/apt/matching/pattern.h>
32
#include <generic/problemresolver/problemresolver.h>
34
#include <generic/util/immset.h>
40
/** \brief Glue code to make the resolver talk to the core aptitude classes.
43
* General comment on how the iterators are handled: basically the
44
* technique is (generally) to have a normalize() routine that
45
* advances the current iterator(s) to the next "interesting"
46
* iterator. For instance, broken_dep_iterator::normalize() moves to
47
* the next broken dependency (sort of). If the current iterator is
48
* already interesting, nothing happens. This is used on
49
* initialization and in operator++ (after advancing the iterator a
50
* single step manually).
52
* \file aptitude_resolver.h
63
class aptitude_resolver:public generic_problem_resolver<aptitude_universe>
65
choice_set keep_all_solution;
68
aptitude_resolver_cost_settings cost_settings;
70
void add_full_replacement_score(const pkgCache::VerIterator &src,
71
const pkgCache::PkgIterator &real_target,
72
const pkgCache::VerIterator &provider,
73
int full_replacement_score,
74
int undo_full_replacement_score);
76
/** \brief Given the first dependency in an OR group, add scores to
77
* bias the resolver in favor of the default candidate that
78
* MarkInstall would pick.
80
void add_default_resolution_score(const pkgCache::DepIterator &dep,
81
int default_resolution_score);
86
/** \brief The type of hint represented by this object. */
89
/** \brief A hint indicating that a named component of the
90
* cost tuple should have a number added to it.
92
add_to_cost_component,
93
/** \brief A hint indicating that the target should be
97
/** \brief A hint indicating that a named component of the
98
* cost tuple should be increased to an upper bound.
100
raise_cost_component,
101
/** \brief A hint that one or more package versions should be
105
/** \brief A hint that one or more package versions should be
109
/** \brief A hint that one or more package versions should
110
* have their scores adjusted by some amount.
115
/** \brief Describes which versions are selected by a hint. */
116
class version_selection
119
/** \brief Describes what sort of version selection is in use. */
120
enum version_selection_type
122
/** \brief All versions.
124
* Matches any version.
128
/** \brief Versions are selected by archive.
130
* Any version contained in an archive that equals the
131
* version selection string will be selected.
135
/** \brief All versions of a package except the
136
* not-installed version will be matched.
138
* This is equivalent to not providing a version string.
142
/** \brief The non-installed version of the package will be
147
/** \brief Versions are selected by version string.
149
* Any version contained in an archive that compares
150
* correctly to the version selection string (according to
151
* the comparison operator) will be selected.
156
/** \brief Lists the comparison operations that are allowed. */
160
less_than_or_equal_to,
164
greater_than_or_equal_to
168
version_selection_type type;
169
compare_op_type compare_op;
170
std::string version_selection_string;
172
version_selection(version_selection_type _type,
173
compare_op_type _compare_op,
174
const std::string &_version_selection_string)
175
: type(_type), compare_op(_compare_op),
176
version_selection_string(_version_selection_string)
182
: type((version_selection_type)-1),
183
compare_op((compare_op_type)-1),
184
version_selection_string()
188
static version_selection make_all()
190
return version_selection(select_all, (compare_op_type)-1, std::string());
193
/** \brief Create a version selection that selects versions by
196
* \param archive The archive to match; only versions that are
197
* contained in this archive will be selected.
199
static version_selection make_archive(const std::string &archive)
201
return version_selection(select_by_archive, (compare_op_type)-1, archive);
204
/** \brief Create a version selection that selects all versions
205
* except the not-installed version.
207
static version_selection make_inst()
209
return version_selection(select_inst, (compare_op_type)-1, std::string());
212
/** \brief Create a version selection that selects not-installed
215
static version_selection make_uninst()
217
return version_selection(select_uninst, (compare_op_type)-1, std::string());
220
/** \brief Create a version selection that selects versions by
223
* \param The version number to compare against.
224
* \param The operation to use in comparison. For instance,
225
* use pkgCache::Dep::Less to select only versions
226
* less than the given version.
228
static version_selection make_version(compare_op_type compare_op,
229
const std::string &version)
231
return version_selection(select_by_version, compare_op, version);
234
/** \brief Test a version against this selector.
236
* \param v The version to test.
238
* \return \b true if v is matched by this selector.
240
bool matches(const aptitude_resolver_version &v) const;
242
/** \brief Compare two version selectors.
244
* \param other The version selector to compare against.
246
* Selectors are arbitrarily arranged in a total ordering.
248
* \return a number less than zero if this selector is less
249
* than the other selector, a number greater than zero if the
250
* other selector is greater than this selector, and zero if
251
* the two selectors are equal.
253
int compare(const version_selection &other) const;
255
bool operator<(const version_selection &other) const { return compare(other) < 0; }
256
bool operator<=(const version_selection &other) const { return compare(other) <= 0; }
257
bool operator==(const version_selection &other) const { return compare(other) == 0; }
258
bool operator!=(const version_selection &other) const { return compare(other) != 0; }
259
bool operator>=(const version_selection &other) const { return compare(other) >= 0; }
260
bool operator>(const version_selection &other) const { return compare(other) > 0; }
262
/** \brief Get the type of this selection. */
263
version_selection_type get_type() const { return type; }
265
/** \brief Get the version selection string of this selection.
267
* Only valid for select_by_archive and select_by_version
270
const std::string &get_version_selection_string() const
272
eassert(type == select_by_archive || type == select_by_version);
274
return version_selection_string;
277
/** \brief Get the comparison operation of this selection.
279
* Only valid for select_by_version selections.
281
compare_op_type get_version_comparison_operator() const
283
eassert(type == select_by_version);
292
cwidget::util::ref_ptr<aptitude::matching::pattern> target;
293
version_selection selection;
294
std::string component_name;
296
hint(hint_type _type, int _amt,
297
const cwidget::util::ref_ptr<aptitude::matching::pattern> &_target,
298
version_selection _selection,
299
const std::string &_component_name)
300
: type(_type), amt(_amt),
301
target(_target), selection(_selection), component_name(_component_name)
307
: type((hint_type)-1), amt(-1), target(NULL), selection(), component_name()
313
/** \brief Create a hint that adds to a single component of the
316
static hint make_add_to_cost_component(const cwidget::util::ref_ptr<aptitude::matching::pattern> &target,
317
const version_selection &selection,
318
const std::string &component_name,
321
return hint(add_to_cost_component, amt,
322
target, selection, component_name);
325
/** \brief Create a hint that discards solutions containing the target. */
326
static hint make_discard(const cwidget::util::ref_ptr<aptitude::matching::pattern> &target,
327
const version_selection &selection)
329
return hint(discard, 0, target, selection, "");
332
/** \brief Create a hint that increases a single component of the
333
* cost level to the given value.
335
static hint make_raise_cost_component(const cwidget::util::ref_ptr<aptitude::matching::pattern> &target,
336
const version_selection &selection,
337
const std::string &component_name,
340
return hint(raise_cost_component, amt,
341
target, selection, component_name);
344
/** \brief Create a hint that rejects a version or versions of a package. */
345
static hint make_reject(const cwidget::util::ref_ptr<aptitude::matching::pattern> &target,
346
const version_selection &selection)
348
return hint(reject, 0, target, selection, "");
351
/** \brief Create a hint that mandates a version or versions of a package. */
352
static hint make_mandate(const cwidget::util::ref_ptr<aptitude::matching::pattern> &target,
353
const version_selection &selection)
355
return hint(mandate, 0, target, selection, "");
358
/** \brief Create a hint that adjusts the score of a package. */
359
static hint make_tweak_score(const cwidget::util::ref_ptr<aptitude::matching::pattern> &target,
360
const version_selection &selection,
363
return hint(tweak_score, score, target, selection, "");
366
/** \brief Parse a resolver hint definition.
368
* Definitions have the form ACTION TARGET [VERSION]. ACTION is
369
* either a number (which will be added to the score of the
370
* selected version), "increase-tier N" where N is a number, or
371
* the special strings "reject" or "approve". If TARGET is a
372
* match pattern (specifically, if the portion of the remaining
373
* string that parses as a match pattern includes a question mark
374
* or tilde), then it will be treated as such; otherwise it is
375
* the name of the package to match. VERSION is the version of
376
* TARGET that is to be tweaked. If VERSION is not present, all
377
* versions of the package (except the removal version) that
378
* match TARGET will be selected. If VERSION has the form
379
* "/<archive>" then the version of the package from that archive
380
* will be selected. If VERSION is ":UNINST" then the
381
* not-installed version of the package will be selected.
382
* Finally, VERSION may be ">VERSION2", "=VERSION2",
383
* ">=VERSION2", "<VERSION2", "<=VERSION2", or "<>VERSION2" to
384
* only apply the hint to versions of the package that compare
385
* accordingly to the version string. (obviously "=VERSION2" is
386
* redundant, but it is included for completeness)
388
* \param definition The text of the hint definition.
389
* \param out A location in which to store the parsed hint.
391
* \return \b true if the hint was parsed successfully, \b false
394
static bool parse(const std::string &definition, hint &out);
396
/** \brief Compare this hint to another hint.
398
* \param other The hint to which this is to be compared.
400
* \return -1 if this is less than other, 0 if the two hints are
401
* equal, and 1 if this is more than other.
403
* Hints exist in an arbitrary total ordering.
405
int compare(const hint &other) const;
407
bool operator<(const hint &other) const { return compare(other) < 0; }
408
bool operator<=(const hint &other) const { return compare(other) <= 0; }
409
bool operator==(const hint &other) const { return compare(other) == 0; }
410
bool operator!=(const hint &other) const { return compare(other) != 0; }
411
bool operator>=(const hint &other) const { return compare(other) >= 0; }
412
bool operator>(const hint &other) const { return compare(other) > 0; }
414
/** \brief Get the type of this hint.
418
hint_type get_type() const { return type; }
420
/** \brief Retrieve the integer associated with this hint.
422
* For score-tweaking hints, this is the number of points to be
423
* added to the version's score. For cost-component-tweaking
424
* hints, this is the amount to increase the cost component by or
425
* the value to increase it to.
427
int get_amt() const { return amt; }
429
/** \brief Retrieve the cost component name associated with this hint. */
430
const std::string &get_component_name() const { return component_name; }
432
/** \brief Return the pattern identifying the package or packages
435
const cwidget::util::ref_ptr<aptitude::matching::pattern> &
436
get_target() const { return target; }
438
/** \brief Return the version selection rule for this hint. */
439
const version_selection &get_version_selection() const { return selection; }
442
aptitude_resolver(int step_score, int broken_score,
443
int unfixed_soft_score,
445
int resolution_score,
446
const cost &unfixed_soft_cost,
448
const aptitude_resolver_cost_settings &_cost_settings,
449
const imm::map<aptitude_resolver_package, aptitude_resolver_version> &initial_installations,
450
aptitudeDepCache *cache,
453
/** \brief Return \b true if the given version will break a hold or
454
* install a forbidden version.
456
bool is_break_hold(const version &v) const;
458
/** Assign scores to all packages and all package versions according
459
* to its arguments. All scores are assigned with add_score, so
460
* this can be easily combined with other policies.
462
* Note: hints are folded into this routine for efficiency
463
* (minimizing the number of passes over the cache. We should
464
* probably fold everything into one enormous monster "set all the
465
* aptitude scores up" routine.
467
* \param preserve_score the score to assign to the version that the
470
* \param auto_score the score to assign to automatically assigned
471
* actions. By making this smaller than preserve_score you can bias
472
* the system towards overriding automatic decisions rather than
475
* \param remove_score the score to assign to removing a package
476
* against the user's wishes.
478
* \param keep_score the score to assign to cancelling actions on a
479
* package against the user's wishes.
481
* \param install_score the score to assign to removing a package
482
* against the user's wishes.
484
* \param upgrade_score the score to assign to upgrading a package
485
* against the user's wishes.
487
* \param non_default_score the score to assign to installing a
488
* non-default version of a package (such as a downgrade or an
489
* experimental version).
491
* \param essential_remove an additional modification applied to the
492
* removal of an essential package (typically used to deep-six such
493
* solutions by, eg, setting it to -100000)
495
* \param full_replacement_score the score for removing a package p
496
* and installing a package that fully replaces p (i.e., conflicts,
497
* provides, and replaces it).
499
* \param undo_full_replacement_score the score for installing a
500
* package p and removing a package that fully replaces p.
502
* \param break_hold_score an additional modification applied to
503
* solutions that break a hold or violate a forbidding.
505
* \param allow_break_holds_and_forbids if false, versions that
506
* would break a package hold or install a forbidden version are
509
* \param default_resolution_score the score for installing a
510
* package and also resolving a dependency in the way that
511
* MarkInstall would, if the dependency isn't current resolved.
512
* (this is arguably not quite right: it ought to be cancelled
513
* whenever the dependency is resolved by a partial solution)
515
* \param initial_state_manual_flags maps packages that have an
516
* overridden initial state to "true" or "false" depending on
517
* whether they should be considered to have a manually chosen
518
* state. The manual states of overridden packages default to
519
* "true" if they do not have a mapping in this collection.
521
void add_action_scores(int preserve_score, int auto_score,
522
int remove_score, int keep_score,
523
int install_score, int upgrade_score,
524
int non_default_score, int essential_remove,
525
int full_replacement_score,
526
int undo_full_replacement_score,
527
int break_hold_score,
528
bool allow_break_holds_and_forbids,
529
int default_resolution_score,
530
const std::map<package, bool> &initial_state_manual_flags,
531
const std::vector<hint> &hints);
533
/** Score packages/versions according to their priorities. Normally
534
* you want important>=required>=standard>=optional>=extra.
536
* \param important score modification for Important versions
537
* \param required score modification for Required versions
538
* \param standard score modification for Standard versions
539
* \param optional score modification for Optional versions
540
* \param extra score modification for Extra versions
542
void add_priority_scores(int important, int required, int standard,
543
int optional, int extra);
545
/** \return the "keep-all" solution, the solution that cancels
546
* all of the user's planned actions.
548
choice_set get_keep_all_solution() const;
551
std::ostream &operator<<(std::ostream &out, const aptitude_resolver::hint &hint);