From: Michael Schroeder Date: Mon, 3 Jun 2013 18:26:02 +0000 (+0200) Subject: document Solver, Problem, Rule, Ruleinfo, Solution, Solutionelement classes X-Git-Tag: BASE-SuSE-Code-13_1-Branch~119 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c63a0c9ce78bf828e91508981608f7973ac7b1a5;p=thirdparty%2Flibsolv.git document Solver, Problem, Rule, Ruleinfo, Solution, Solutionelement classes --- diff --git a/doc/libsolv-bindings.3 b/doc/libsolv-bindings.3 index 6428c355..e956e161 100644 --- a/doc/libsolv-bindings.3 +++ b/doc/libsolv-bindings.3 @@ -2516,7 +2516,7 @@ Add a raw element to the selection\&. Check the Job class for information about .RS 4 .\} .nf -\fBJob *jobs(int\fR \fIaction\fR\fB)\fR +\fBJob **jobs(int\fR \fIaction\fR\fB)\fR my \fI@jobs\fR \fB=\fR \fI$sel\fR\fB\->jobs(\fR\fI$action\fR\fB)\fR; \fIjobs\fR \fB=\fR \fIsel\fR\fB\&.jobs(\fR\fIaction\fR\fB)\fR \fIjobs\fR \fB=\fR \fIsel\fR\fB\&.jobs(\fR\fIaction\fR\fB)\fR @@ -2531,7 +2531,7 @@ Convert a selection into an array of Job objects\&. The action parameter is or\- .RS 4 .\} .nf -\fBSolvable *solvables()\fR +\fBSolvable **solvables()\fR my \fI@solvables\fR \fB=\fR \fI$sel\fR\fB\->solvables()\fR; \fIsolvables\fR \fB=\fR \fIsel\fR\fB\&.solvables()\fR \fIsolvables\fR \fB=\fR \fIsel\fR\fB\&.solvables()\fR @@ -2782,7 +2782,7 @@ Id describing the set of packages, the meaning depends on the selection part of .RS 4 .\} .nf -\fBSolvable *solvables()\fR +\fBSolvable **solvables()\fR my \fI@solvables\fR \fB=\fR \fI$job\fR\fB\->solvables()\fR; \fIsolvables\fR \fB=\fR \fIjob\fR\fB\&.solvables()\fR \fIsolvables\fR \fB=\fR \fIjob\fR\fB\&.solvables()\fR @@ -2862,8 +2862,886 @@ Set bits specify which parts of the specified packages where specified by the us .sp So if a package "screen\-1\-1" is installed for the x86_64 architecture and version "2\-1" is only available for the i586 architecture, installing package "screen\-2\&.1" will ask the user for confirmation because of the different architecture\&. When using the Selection class to create jobs the set bits are automatically added, e\&.g\&. selecting \(lqscreen\&.i586\(rq will automatically add SOLVER_SETARCH, and thus no problem will be reported\&. .SH "THE SOLVER CLASS" +.SS "CONSTANTS" +.sp +Flags to modify some of the solver\(cqs behaviour: +.PP +\fBSOLVER_FLAG_ALLOW_DOWNGRADE\fR +.RS 4 +Allow the solver to downgrade packages without asking for confirmation (i\&.e\&. reporting a problem)\&. +.RE +.PP +\fBSOLVER_FLAG_ALLOW_ARCHCHANGE\fR +.RS 4 +Allow the solver to change the architecture of an installed package without asking for confirmation\&. Note that changes to/from noarch are always considered to be allowed\&. +.RE +.PP +\fBSOLVER_FLAG_ALLOW_VENDORCHANGE\fR +.RS 4 +Allow the solver to change the vendor of an installed package without asking for confirmation\&. Each vendor is part of one or more vendor equivalence classes, normally installed packages may only change their vendor if the new vendor shares at least one equivalence class\&. +.RE +.PP +\fBSOLVER_FLAG_ALLOW_NAMECHANGE\fR +.RS 4 +Allow the solver to change the name of an installed package, i\&.e\&. install a package with a different name that obsoletes the installed package\&. This option is on by default\&. +.RE +.PP +\fBSOLVER_FLAG_ALLOW_UNINSTALL\fR +.RS 4 +Allow the solver to deinstall installed packages to fulfil the jobs\&. This flag also includes the above flags\&. You may want to set this flag if you only have SOLVER_ERASE jobs, as in that case it\(cqs better for the user to check the transaction overview instead of approving every single package that needs to be deinstalled\&. +.RE +.PP +\fBSOLVER_FLAG_NO_UPDATEPROVIDE\fR +.RS 4 +If multiple packages obsolete an installed package, the solver checks the provides of every such package and ignores all packages that do not provide the installed package name\&. Thus, you can have an official update candidate that provides the old name, and other packages that also obsolete the package but are not considered for updating\&. If you cannot use this feature, you can turn it off by setting this flag\&. +.RE +.PP +\fBSOLVER_FLAG_SPLITPROVIDES\fR +.RS 4 +Make the solver aware of special provides of the form \(lq:\(rq used in SUSE systems to support package splits\&. +.RE +.PP +\fBSOLVER_FLAG_IGNORE_RECOMMENDED\fR +.RS 4 +Do not process optional (aka weak) dependencies\&. +.RE +.PP +\fBSOLVER_FLAG_ADD_ALREADY_RECOMMENDED\fR +.RS 4 +Install recommened or supplemented packages even if they have no connection to the current transaction\&. You can use this feature to implement a simple way for the user to install new recommended packages that were not available in the past\&. +.RE +.PP +\fBSOLVER_FLAG_NO_INFARCHCHECK\fR +.RS 4 +Turn off the inferior architecture checking that is normally done by the solver\&. Normally, the solver allows only the installation of packages from the "best" architecture if a package is available for multiple architectures\&. +.RE +.PP +\fBSOLVER_FLAG_BEST_OBEY_POLICY\fR +.RS 4 +Make the SOLVER_FORCEBEST job option consider only packages that meet the policies for installed packages, i\&.e\&. no downgrades, no architecture change, no vendor change (see the first flags of this section)\&. If the flag is not specified, the solver will enforce the installation of the best package ignoring the installed packages, which may conflict with the set policy\&. +.RE +.PP +\fBSOLVER_FLAG_NO_AUTOTARGET\fR +.RS 4 +Do not enable auto\-targeting up update and distupgrade jobs\&. See the section on targeted updates for more information\&. +.RE +.sp +Basic rule types: +.PP +\fBSOLVER_RULE_UNKNOWN\fR +.RS 4 +A rule of an unknown class\&. You should never encounter those\&. +.RE +.PP +\fBSOLVER_RULE_RPM\fR +.RS 4 +A package dependency rule, called rpm rule for historical reasons\&. +.RE +.PP +\fBSOLVER_RULE_UPDATE\fR +.RS 4 +A rule to implement the update policy of installed packages\&. Every installed package has an update rule that consists of the packages that may replace the installed package\&. +.RE +.PP +\fBSOLVER_RULE_FEATURE\fR +.RS 4 +Feature rules are fallback rules used when a update rule is disabled\&. They include all packages that may replace the installed package ignoring the update policy, i\&.e\&. they contain downgrades, arch changes and so on\&. Without them, the solver would simply deinstall installed packages if their update rule gets disabled\&. +.RE +.PP +\fBSOLVER_RULE_JOB\fR +.RS 4 +Job rules implement the job given to the solver\&. +.RE +.PP +\fBSOLVER_RULE_DISTUPGRADE\fR +.RS 4 +This are simple negative assertions that make sure that only packages are kept that are also available in one of the repositories\&. +.RE +.PP +\fBSOLVER_RULE_INFARCH\fR +.RS 4 +Infarch rules are also negative assertions, they disallow the installation of packages when there are packages of the same name but with a better architecture\&. +.RE +.PP +\fBSOLVER_RULE_CHOICE\fR +.RS 4 +Choice rules are used to make sure that the solver preferes updating to installing different packages when some dependency is provided by multiple packages with different names\&. The solver may always break choice rules, so you will not see them when a problem is found\&. +.RE +.PP +\fBSOLVER_RULE_LEARNT\fR +.RS 4 +These rules are generated by the solver to keep it from running into the same problem multiple times when it has to backtrack\&. They are the main reason why a sat solver is faster then other dependency solver implementations\&. +.RE +.sp +Special dependency rule types: +.PP +\fBSOLVER_RULE_RPM_NOT_INSTALLABLE\fR +.RS 4 +This rule was added to prevent the installation of a package of an architecture that does not work on the system\&. +.RE +.PP +\fBSOLVER_RULE_RPM_NOTHING_PROVIDES_DEP\fR +.RS 4 +The package contanis a required dependency which was not provided by any package\&. +.RE +.PP +\fBSOLVER_RULE_RPM_PACKAGE_REQUIRES\fR +.RS 4 +Similar to SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP, but in this case some packages provided the dependency but none of them could be installed due to other dependency issues\&. +.RE +.PP +\fBSOLVER_RULE_RPM_SELF_CONFLICT\fR +.RS 4 +The package conflicts with itself\&. This is not allowed by older rpm versions\&. +.RE +.PP +\fBSOLVER_RULE_RPM_PACKAGE_CONFLICT\fR +.RS 4 +To fulfill the dependencies two packages need to be installed, but one of the packages contains a conflict with the other one\&. +.RE +.PP +\fBSOLVER_RULE_RPM_SAME_NAME\fR +.RS 4 +The dependencies can only be fulfilled by multiple versions of a package, but installing multiple versions of the same package is not allowed\&. +.RE +.PP +\fBSOLVER_RULE_RPM_PACKAGE_OBSOLETES\fR +.RS 4 +To fulfill the dependencies two packages need to be installed, but one of the packages obsoletes the other one\&. +.RE +.PP +\fBSOLVER_RULE_RPM_IMPLICIT_OBSOLETES\fR +.RS 4 +To fulfill the dependencies two packages need to be installed, but one of the packages has provides a dependency that is obsoleted by the other one\&. See the POOL_FLAG_IMPLICITOBSOLETEUSESPROVIDES flag\&. +.RE +.PP +\fBSOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES\fR +.RS 4 +To fulfill the dependencies a package needs to be installed that is obsoleted by an installed package\&. See the POOL_FLAG_NOINSTALLEDOBSOLETES flag\&. +.RE +.PP +\fBSOLVER_RULE_JOB_NOTHING_PROVIDES_DEP\fR +.RS 4 +The user asked for installation of a package providing a specific dependency, but no available package provides it\&. +.RE +.PP +\fBSOLVER_RULE_JOB_UNKNOWN_PACKAGE\fR +.RS 4 +The user asked for installation of a package with a specific name, but no available package has that name\&. +.RE +.PP +\fBSOLVER_RULE_JOB_PROVIDED_BY_SYSTEM\fR +.RS 4 +The user asked for the erasure of a dependency that is provided by the system (i\&.e\&. for special hardware or language dependencies), this cannot be done with a job\&. +.RE +.PP +\fBSOLVER_RULE_JOB_UNSUPPORTED\fR +.RS 4 +The user asked for something that is not yet implemented, e\&.g\&. the installation of all packages at once\&. +.RE +.sp +Policy error constants +.PP +\fBPOLICY_ILLEGAL_DOWNGRADE\fR +.RS 4 +The solver ask for permission before downgrading packages\&. +.RE +.PP +\fBPOLICY_ILLEGAL_ARCHCHANGE\fR +.RS 4 +The solver ask for permission before changing the architecture of installed packages\&. +.RE +.PP +\fBPOLICY_ILLEGAL_VENDORCHANGE\fR +.RS 4 +The solver ask for permission before changing the vendor of installed packages\&. +.RE +.PP +\fBPOLICY_ILLEGAL_NAMECHANGE\fR +.RS 4 +The solver ask for permission before replacing an installed packages with a packge that has a different name\&. +.RE +.sp +Solution element type constants +.PP +\fBSOLVER_SOLUTION_JOB\fR +.RS 4 +The problem can be solved by removing the specified job\&. +.RE +.PP +\fBSOLVER_SOLUTION_POOLJOB\fR +.RS 4 +The problem can be solved by removing the specified job that is defined in the pool\&. +.RE +.PP +\fBSOLVER_SOLUTION_INFARCH\fR +.RS 4 +The problem can be solved by allowing the installation of the specified package with an inferior architecture\&. +.RE +.PP +\fBSOLVER_SOLUTION_DISTUPGRADE\fR +.RS 4 +The problem can be solved by allowing to keep the specified package installed\&. +.RE +.PP +\fBSOLVER_SOLUTION_BEST\fR +.RS 4 +The problem can be solved by allowing to install the specified package that is not the best available package\&. +.RE +.PP +\fBSOLVER_SOLUTION_ERASE\fR +.RS 4 +The problem can be solved by allowing to erase the specified package\&. +.RE +.PP +\fBSOLVER_SOLUTION_REPLACE\fR +.RS 4 +The problem can be solved by allowing to replace the package with some other package\&. +.RE +.PP +\fBSOLVER_SOLUTION_REPLACE_DOWNGRADE\fR +.RS 4 +The problem can be solved by allowing to replace the package with some other package that has a lower version\&. +.RE +.PP +\fBSOLVER_SOLUTION_REPLACE_ARCHCHANGE\fR +.RS 4 +The problem can be solved by allowing to replace the package with some other package that has a different architecture\&. +.RE +.PP +\fBSOLVER_SOLUTION_REPLACE_VENDORCHANGE\fR +.RS 4 +The problem can be solved by allowing to replace the package with some other package that has a different vendor\&. +.RE +.PP +\fBSOLVER_SOLUTION_REPLACE_NAMECHANGE\fR +.RS 4 +The problem can be solved by allowing to replace the package with some other package that has a different name\&. +.RE +.SS "ATTRIBUTES" +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBPool *pool;\fR /* read only */ +\fI$job\fR\fB\->{\*(Aqpool\*(Aq}\fR +\fId\fR\fB\&.pool\fR +\fId\fR\fB\&.pool\fR +.fi +.if n \{\ +.RE +.\} +.sp +Back pointer to pool\&. +.SS "METHODS" +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBint set_flag(int\fR \fIflag\fR\fB, int\fR \fIvalue\fR\fB)\fR +my \fI$oldvalue\fR \fB=\fR \fI$pool\fR\fB\->set_flag(\fR\fI$flag\fR\fB,\fR \fI$value\fR\fB)\fR; +\fIoldvalue\fR \fB=\fR \fIpool\fR\fB\&.set_flag(\fR\fIflag\fR\fB,\fR \fIvalue\fR\fB)\fR +\fIoldvalue\fR \fB=\fR \fIpool\fR\fB\&.set_flag(\fR\fIflag\fR\fB,\fR \fIvalue\fR\fB)\fR +.fi +.if n \{\ +.RE +.\} +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBint get_flag(int\fR \fIflag\fR\fB)\fR +my \fI$value\fR \fB=\fR \fI$pool\fR\fB\->get_flag(\fR\fI$flag\fR\fB)\fR; +\fIvalue\fR \fB=\fR \fIpool\fR\fB\&.get_flag(\fR\fIflag\fR\fB)\fR +\fIvalue\fR \fB=\fR \fIpool\fR\fB\&.get_flag(\fR\fIflag\fR\fB)\fR +.fi +.if n \{\ +.RE +.\} +.sp +Set/get a solver specific flag\&. The flags define the policies the solver has to obey\&. The flags are explained in the CONSTANTS section of this class\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBProblem **solve(Job *\fR\fIjobs\fR\fB)\fR +my \fI@problems\fR \fB=\fR \fI$solver\fR\fB\->solve(\e\fR\fI@jobs\fR\fB)\fR; +\fIproblems\fR \fB=\fR \fIsolver\fR\fB\&.solve(\fR\fIjobs\fR\fB)\fR +\fIproblems\fR \fB=\fR \fIsolver\fR\fB\&.solve(\fR\fIjobs\fR\fB)\fR +.fi +.if n \{\ +.RE +.\} +.sp +Solve a problem specified in the job list (plus the jobs defined in the pool)\&. Returns an array of problems that need user interaction, or an empty array if no problems were encountered\&. See the Problem class on how to deal with problems\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBTransaction *transaction()\fR +my \fI$trans\fR \fB=\fR \fI$solver\fR\fB\->transaction()\fR; +\fItrans\fR \fB=\fR \fIsolver\fR\fB\&.transaction()\fR +\fItrans\fR \fB=\fR \fIsolver\fR\fB\&.transaction()\fR +.fi +.if n \{\ +.RE +.\} +.sp +Return the transaction to implement the calculated package changes\&. A transaction is available even if problems were found, this is useful for interactive user interfaces that show both the job result and the problems\&. +.SH "THE PROBLEM CLASS" +.sp +Problems are the way of the solver to interact with the user\&. You can simply list all problems and terminate your program, but a better way is to present solutions to the user and let him pick the ones he likes\&. +.SS "ATTRIBUTES" +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBSolver *solv;\fR /* read only */ +\fI$problem\fR\fB\->{\*(Aqsolv\*(Aq}\fR +\fIproblem\fR\fB\&.solv\fR +\fIproblem\fR\fB\&.solv\fR +.fi +.if n \{\ +.RE +.\} +.sp +Back pointer to solver object\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBId id;\fR /* read only */ +\fI$problem\fR\fB\->{\*(Aqid\*(Aq}\fR +\fIproblem\fR\fB\&.id\fR +\fIproblem\fR\fB\&.id\fR +.fi +.if n \{\ +.RE +.\} +.sp +Id of the problem\&. The first problem has Id 1, they are numbered consecutively\&. +.SS "METHODS" +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBRule *findproblemrule()\fR +my \fI$probrule\fR \fB=\fR \fI$problem\fR\fB\->findproblemrule()\fR; +\fIprobrule\fR \fB=\fR \fIproblem\fR\fB\&.findproblemrule()\fR +\fIprobrule\fR \fB=\fR \fIproblem\fR\fB\&.findproblemrule()\fR +.fi +.if n \{\ +.RE +.\} +.sp +Return the rule that caused the problem\&. Of cource in most situations there is no single responsible rule, but many rules that interconnect with each created the problem\&. Nevertheless, the solver uses some heuristic approch to find a rule that somewhat describes the problem best to the user\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBRule **findallproblemrules(bool\fR \fIunfiltered\fR \fB= 0)\fR +my \fI@probrules\fR \fB=\fR \fI$problem\fR\fB\->findallproblemrules()\fR; +\fIprobrules\fR \fB=\fR \fIproblem\fR\fB\&.findallproblemrule()\fR +\fIprobrules\fR \fB=\fR \fIproblem\fR\fB\&.findallproblemrule()\fR +.fi +.if n \{\ +.RE +.\} +.sp +Return all rules responsible for the problem\&. The returned set of rules contains all the needed information why there was a problem, but it\(cqs hard to present them to the user in a sensible way\&. The default is to filter out all update and job rules (unless the returned rules only consist of those types)\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBSolutions **solutions()\fR +my \fI@solutions\fR \fB=\fR \fI$problem\fR\fB\->solutions()\fR; +\fIsolutions\fR \fB=\fR \fIproblem\fR\fB\&.solutions()\fR +\fIsolutions\fR \fB=\fR \fIproblem\fR\fB\&.solutions()\fR +.fi +.if n \{\ +.RE +.\} +.sp +Return an array containing multiple possible solutions to fix the problem\&. See the solution class for more information\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBint solution_count()\fR +my \fI$cnt\fR \fB=\fR \fI$problem\fR\fB\->solution_count()\fR; +\fIcnt\fR \fB=\fR \fIproblem\fR\fB\&.solution_count()\fR +\fIcnt\fR \fB=\fR \fIproblem\fR\fB\&.solution_count()\fR +.fi +.if n \{\ +.RE +.\} +.sp +Return the number of solutions without creating solution objects\&. +.SH "THE RULE CLASS" +.sp +Rules are the basic block of sat solving\&. Each package dependency gets translated into one or multiple rules\&. +.SS "ATTRIBUTES" +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBSolver *solv;\fR /* read only */ +\fI$rule\fR\fB\->{\*(Aqsolv\*(Aq}\fR +\fIrule\fR\fB\&.solv\fR +\fIrule\fR\fB\&.solv\fR +.fi +.if n \{\ +.RE +.\} +.sp +Back pointer to solver object\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBId id;\fR /* read only */ +\fI$rule\fR\fB\->{\*(Aqid\*(Aq}\fR +\fIrule\fR\fB\&.id\fR +\fIrule\fR\fB\&.id\fR +.fi +.if n \{\ +.RE +.\} +.sp +The id of the rule\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBint type;\fR /* read only */ +\fI$rule\fR\fB\->{\*(Aqtype\*(Aq}\fR +\fIrule\fR\fB\&.type\fR +\fIrule\fR\fB\&.type\fR +.fi +.if n \{\ +.RE +.\} +.sp +The basic type of the rule\&. See the constant section of the solver class for the type list\&. +.SS "METHODS" +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBRuleinfo *info()\fR +my \fI$ruleinfo\fR \fB=\fR \fI$rule\fR\fB\->info()\fR; +\fIruleinfo\fR \fB=\fR \fIrule\fR\fB\&.info()\fR +\fIruleinfo\fR \fB=\fR \fIrule\fR\fB\&.info()\fR +.fi +.if n \{\ +.RE +.\} +.sp +Return a Ruleinfo object that contains information about why the rule was created\&. But see the allinfos() method below\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBRuleinfo **allinfos()\fR +my \fI@ruleinfos\fR \fB=\fR \fI$rule\fR\fB\->allinfos()\fR; +\fIruleinfos\fR \fB=\fR \fIrule\fR\fB\&.allinfos()\fR +\fIruleinfos\fR \fB=\fR \fIrule\fR\fB\&.allinfos()\fR +.fi +.if n \{\ +.RE +.\} .sp -xxx +As the same dependency rule can get created because of multiple dependencies, one Ruleinfo is not enough to describe the reason\&. Thus the allinfos() method returns an array of all infos about a rule\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fB\fR +\fBif (\fR\fI$rule1\fR \fB==\fR \fI$rule2\fR\fB)\fR +\fBif\fR \fIrule1\fR \fB==\fR \fIrule2\fR\fB:\fR +\fBif\fR \fIrule1\fR \fB==\fR \fIrule2\fR +.fi +.if n \{\ +.RE +.\} +.sp +Two rules are equal if they belong to the same solver and have the same id\&. +.SH "THE RULEINFO CLASS" +.sp +A Ruleinfo describes one reason why a rule was created\&. +.SS "ATTRIBUTES" +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBSolver *solv;\fR /* read only */ +\fI$ruleinfo\fR\fB\->{\*(Aqsolv\*(Aq}\fR +\fIruleinfo\fR\fB\&.solv\fR +\fIruleinfo\fR\fB\&.solv\fR +.fi +.if n \{\ +.RE +.\} +.sp +Back pointer to solver object\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBint type;\fR /* read only */ +\fI$ruleinfo\fR\fB\->{\*(Aqtype\*(Aq}\fR +\fIruleinfo\fR\fB\&.type\fR +\fIruleinfo\fR\fB\&.type\fR +.fi +.if n \{\ +.RE +.\} +.sp +The type of the ruleinfo\&. See the constant section of the solver class for the rule type list and the special type list\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBId dep;\fR /* read only */ +\fI$ruleinfo\fR\fB\->{\*(Aqdep\*(Aq}\fR +\fIruleinfo\fR\fB\&.dep\fR +\fIruleinfo\fR\fB\&.dep\fR +.fi +.if n \{\ +.RE +.\} +.sp +The id of the dependency leading to the creation of the rule, or zero\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBSolvable *solvable;\fR /* read only */ +\fI$ruleinfo\fR\fB\->{\*(Aqsolvable\*(Aq}\fR +\fIruleinfo\fR\fB\&.solvable\fR +\fIruleinfo\fR\fB\&.solvable\fR +.fi +.if n \{\ +.RE +.\} +.sp +The involved Solvable, e\&.g\&. the one containing the dependency\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBSolvable *othersolvable;\fR /* read only */ +\fI$ruleinfo\fR\fB\->{\*(Aqothersolvable\*(Aq}\fR +\fIruleinfo\fR\fB\&.othersolvable\fR +\fIruleinfo\fR\fB\&.othersolvable\fR +.fi +.if n \{\ +.RE +.\} +.sp +The other involved Solvable (if any), e\&.g\&. the one containing providing the dependency for conflicts\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBconst char *problemstr()\fR; +my \fI$str\fR \fB=\fR \fI$ruleinfo\fR\fB\->problemstr()\fR; +\fIstr\fR \fB=\fR \fIruleinfo\fR\fB\&.problemstr()\fR +\fIstr\fR \fB=\fR \fIruleinfo\fR\fB\&.problemstr()\fR +.fi +.if n \{\ +.RE +.\} +.sp +A string describing the ruleinfo from a problem perspective\&. This probably only makes sense if the rule is part of a problem\&. +.SH "THE SOLUTION CLASS" +.sp +A solution solves one specific problem\&. It consists of multiple solution elements that all need to be executed\&. +.SS "ATTRIBUTES" +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBSolver *solv;\fR /* read only */ +\fI$solution\fR\fB\->{\*(Aqsolv\*(Aq}\fR +\fIsolution\fR\fB\&.solv\fR +\fIsolution\fR\fB\&.solv\fR +.fi +.if n \{\ +.RE +.\} +.sp +Back pointer to solver object\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBId problemid;\fR /* read only */ +\fI$solution\fR\fB\->{\*(Aqproblemid\*(Aq}\fR +\fIsolution\fR\fB\&.problemid\fR +\fIsolution\fR\fB\&.problemid\fR +.fi +.if n \{\ +.RE +.\} +.sp +Id of the problem the solution solves\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBId id;\fR /* read only */ +\fI$solution\fR\fB\->{\*(Aqid\*(Aq}\fR +\fIsolution\fR\fB\&.id\fR +\fIsolution\fR\fB\&.id\fR +.fi +.if n \{\ +.RE +.\} +.sp +Id of the solution\&. The first solution has Id 1, they are numbered consecutively\&. +.SS "METHODS" +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBSolutionelement **elements(bool\fR \fIexpandreplaces\fR \fB= 0)\fR +my \fI@solutionelements\fR \fB=\fR \fI$solution\fR\fB\->elements()\fR; +\fIsolutionelements\fR \fB=\fR \fIsolution\fR\fB\&.elements()\fR +\fIsolutionelements\fR \fB=\fR \fIsolution\fR\fB\&.elements()\fR +.fi +.if n \{\ +.RE +.\} +.sp +Return an array containing the elements describing what neeeds to be done to implement the specific solution\&. If expandreplaces is true, elements of type SOLVER_SOLUTION_REPLACE will be replaced by one or more elements replace elements describing the policy mismatches\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBint element_count()\fR +my \fI$cnt\fR \fB=\fR \fI$solution\fR\fB\->solution_count()\fR; +\fIcnt\fR \fB=\fR \fIsolution\fR\fB\&.element_count()\fR +\fIcnt\fR \fB=\fR \fIsolution\fR\fB\&.element_count()\fR +.fi +.if n \{\ +.RE +.\} +.sp +Return the number of solution elements without creating objects\&. Note that the count does not match the number of objects returned by the elements() method of expandreplaces is set to true\&. +.SH "THE SOLUTIONELEMENT CLASS" +.sp +A solution element describes a single action of a solution\&. The action is always either to remove one specific job or to add a new job that installs or erases a single specific package\&. +.SS "ATTRIBUTES" +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBSolver *solv;\fR /* read only */ +\fI$solutionelement\fR\fB\->{\*(Aqsolv\*(Aq}\fR +\fIsolutionelement\fR\fB\&.solv\fR +\fIsolutionelement\fR\fB\&.solv\fR +.fi +.if n \{\ +.RE +.\} +.sp +Back pointer to solver object\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBId problemid;\fR /* read only */ +\fI$solutionelement\fR\fB\->{\*(Aqproblemid\*(Aq}\fR +\fIsolutionelement\fR\fB\&.problemid\fR +\fIsolutionelement\fR\fB\&.problemid\fR +.fi +.if n \{\ +.RE +.\} +.sp +Id of the problem the element (partly) solves\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBId solutionid;\fR /* read only */ +\fI$solutionelement\fR\fB\->{\*(Aqsolutionid\*(Aq}\fR +\fIsolutionelement\fR\fB\&.solutionid\fR +\fIsolutionelement\fR\fB\&.solutionid\fR +.fi +.if n \{\ +.RE +.\} +.sp +Id of the solution the element is a part of\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBId id;\fR /* read only */ +\fI$solutionelement\fR\fB\->{\*(Aqid\*(Aq}\fR +\fIsolutionelement\fR\fB\&.id\fR +\fIsolutionelement\fR\fB\&.id\fR +.fi +.if n \{\ +.RE +.\} +.sp +Id of the solution element\&. The first element has Id 1, they are numbered consecutively\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBId type;\fR /* read only */ +\fI$solutionelement\fR\fB\->{\*(Aqtype\*(Aq}\fR +\fIsolutionelement\fR\fB\&.type\fR +\fIsolutionelement\fR\fB\&.type\fR +.fi +.if n \{\ +.RE +.\} +.sp +Type of the solution element\&. See the constant section of the solver class for the existing types\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBSolvable *solvable;\fR /* read only */ +\fI$solutionelement\fR\fB\->{\*(Aqsolvable\*(Aq}\fR +\fIsolutionelement\fR\fB\&.solvable\fR +\fIsolutionelement\fR\fB\&.solvable\fR +.fi +.if n \{\ +.RE +.\} +.sp +The installed solvable that needs to be replaced for replacement elements\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBSolvable *replacement;\fR /* read only */ +\fI$solutionelement\fR\fB\->{\*(Aqreplacement\*(Aq}\fR +\fIsolutionelement\fR\fB\&.replacement\fR +\fIsolutionelement\fR\fB\&.replacement\fR +.fi +.if n \{\ +.RE +.\} +.sp +The solvable that needs to be installed to fix the problem\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBint jobidx;\fR /* read only */ +\fI$solutionelement\fR\fB\->{\*(Aqjobidx\*(Aq}\fR +\fIsolutionelement\fR\fB\&.jobidx\fR +\fIsolutionelement\fR\fB\&.jobidx\fR +.fi +.if n \{\ +.RE +.\} +.sp +The index of the job that needs to be removed to fix the problem, or \-1 if the element is of another type\&. Note that it\(cqs better to change the job to SOLVER_NOOP type so that the numbering of other elements does not get disturbed\&. This method works both for types SOLVER_SOLUTION_JOB and SOLVER_SOLUTION_POOLJOB\&. +.SS "METHODS" +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBSolutionelement **replaceelements()\fR +my \fI@solutionelements\fR \fB=\fR \fI$solutionelement\fR\fB\->replaceelements()\fR; +\fIsolutionelements\fR \fB=\fR \fIsolutionelement\fR\fB\&.replaceelements()\fR +\fIsolutionelements\fR \fB=\fR \fIsolutionelement\fR\fB\&.replaceelements()\fR +.fi +.if n \{\ +.RE +.\} +.sp +If the solution element is of type SOLVER_SOLUTION_REPLACE, return an array of elements describing the policy mismatches, otherwise return a copy of the element\&. See also the \(lqexpandreplaces\(rq option in the solution\(cqs elements() method\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBint illegalreplace()\fR +my \fI$illegal\fR \fB=\fR \fI$solutionelement\fR\fB\->illegalreplace()\fR; +\fIillegal\fR \fB=\fR \fIsolutionelement\fR\fB\&.illegalreplace()\fR +\fIillegal\fR \fB=\fR \fIsolutionelement\fR\fB\&.illegalreplace()\fR +.fi +.if n \{\ +.RE +.\} +.sp +Return an integer that contains the policy mismatch bits or\-ed together, or zero if there was no policy mismatch\&. See the policy error constants in the solver class\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBJob *Job()\fR +my \fI$job\fR \fB=\fR \fI$solutionelement\fR\fB\->Job()\fR; +\fIillegal\fR \fB=\fR \fIsolutionelement\fR\fB\&.Job()\fR +\fIillegal\fR \fB=\fR \fIsolutionelement\fR\fB\&.Job()\fR +.fi +.if n \{\ +.RE +.\} +.sp +Create a job that implements the solution element\&. Add this job to the array of jobs for all elements of type different to SOLVER_SOLUTION_JOB and SOLVER_SOLUTION_POOLJOB\&. For the later two, a SOLVER_NOOB Job is created, you should replace the old job with the new one\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBconst char *str()\fR +my \fI$str\fR \fB=\fR \fI$solutionelement\fR\fB\->str()\fR; +\fIstr\fR \fB=\fR \fIsolutionelement\fR\fB\&.str()\fR +\fIstr\fR \fB=\fR \fIsolutionelement\fR\fB\&.str()\fR +.fi +.if n \{\ +.RE +.\} +.sp +A string describing the change the solution element consists of\&. .SH "THE TRANSACTION CLASS" .sp xxx diff --git a/doc/libsolv-bindings.txt b/doc/libsolv-bindings.txt index 96b71d4b..3601d986 100644 --- a/doc/libsolv-bindings.txt +++ b/doc/libsolv-bindings.txt @@ -1448,7 +1448,7 @@ add operation. Add a raw element to the selection. Check the Job class for information about the how and what parameters. - Job *jobs(int action) + Job **jobs(int action) my @jobs = $sel->jobs($action); jobs = sel.jobs(action) jobs = sel.jobs(action) @@ -1457,7 +1457,7 @@ Convert a selection into an array of Job objects. The action parameter is or-ed to the ``how'' part of the job, it describes the type of job (e.g. install, erase). See the Job class for the action and action modifier constants. - Solvable *solvables() + Solvable **solvables() my @solvables = $sel->solvables(); solvables = sel.solvables() solvables = sel.solvables() @@ -1646,7 +1646,7 @@ selection part of the ``how'' attribute. === METHODS === - Solvable *solvables() + Solvable **solvables() my @solvables = $job->solvables(); solvables = job.solvables() solvables = job.solvables() @@ -1736,7 +1736,611 @@ automatically add SOLVER_SETARCH, and thus no problem will be reported. THE SOLVER CLASS ---------------- -xxx + +=== CONSTANTS === + +Flags to modify some of the solver's behaviour: + +*SOLVER_FLAG_ALLOW_DOWNGRADE*:: + Allow the solver to downgrade packages without asking for confirmation + (i.e. reporting a problem). + +*SOLVER_FLAG_ALLOW_ARCHCHANGE*:: + Allow the solver to change the architecture of an installed package + without asking for confirmation. Note that changes to/from noarch + are always considered to be allowed. + +*SOLVER_FLAG_ALLOW_VENDORCHANGE*:: + Allow the solver to change the vendor of an installed package + without asking for confirmation. Each vendor is part of one or more + vendor equivalence classes, normally installed packages may only + change their vendor if the new vendor shares at least one equivalence + class. + +*SOLVER_FLAG_ALLOW_NAMECHANGE*:: + Allow the solver to change the name of an installed package, i.e. + install a package with a different name that obsoletes the installed + package. This option is on by default. + +*SOLVER_FLAG_ALLOW_UNINSTALL*:: + Allow the solver to deinstall installed packages to fulfil the jobs. + This flag also includes the above flags. You may want to set this + flag if you only have SOLVER_ERASE jobs, as in that case it's + better for the user to check the transaction overview instead of + approving every single package that needs to be deinstalled. + +*SOLVER_FLAG_NO_UPDATEPROVIDE*:: + If multiple packages obsolete an installed package, the solver checks + the provides of every such package and ignores all packages that + do not provide the installed package name. Thus, you can have an + official update candidate that provides the old name, and other + packages that also obsolete the package but are not considered for + updating. If you cannot use this feature, you can turn it off + by setting this flag. + +*SOLVER_FLAG_SPLITPROVIDES*:: + Make the solver aware of special provides of the form + ``:'' used in SUSE systems to support package + splits. + +*SOLVER_FLAG_IGNORE_RECOMMENDED*:: + Do not process optional (aka weak) dependencies. + +*SOLVER_FLAG_ADD_ALREADY_RECOMMENDED*:: + Install recommened or supplemented packages even if they have no + connection to the current transaction. You can use this feature + to implement a simple way for the user to install new recommended + packages that were not available in the past. + +*SOLVER_FLAG_NO_INFARCHCHECK*:: + Turn off the inferior architecture checking that is normally done + by the solver. Normally, the solver allows only the installation + of packages from the "best" architecture if a package is available + for multiple architectures. + +*SOLVER_FLAG_BEST_OBEY_POLICY*:: + Make the SOLVER_FORCEBEST job option consider only packages that + meet the policies for installed packages, i.e. no downgrades, + no architecture change, no vendor change (see the first flags + of this section). If the flag is not specified, the solver will + enforce the installation of the best package ignoring the + installed packages, which may conflict with the set policy. + +*SOLVER_FLAG_NO_AUTOTARGET*:: + Do not enable auto-targeting up update and distupgrade jobs. See + the section on targeted updates for more information. + +Basic rule types: + +*SOLVER_RULE_UNKNOWN*:: + A rule of an unknown class. You should never encounter those. + +*SOLVER_RULE_RPM*:: + A package dependency rule, called rpm rule for historical reasons. + +*SOLVER_RULE_UPDATE*:: + A rule to implement the update policy of installed packages. Every + installed package has an update rule that consists of the packages + that may replace the installed package. + +*SOLVER_RULE_FEATURE*:: + Feature rules are fallback rules used when a update rule is disabled. + They include all packages that may replace the installed package + ignoring the update policy, i.e. they contain downgrades, arch + changes and so on. Without them, the solver would simply deinstall + installed packages if their update rule gets disabled. + +*SOLVER_RULE_JOB*:: + Job rules implement the job given to the solver. + +*SOLVER_RULE_DISTUPGRADE*:: + This are simple negative assertions that make sure that only packages + are kept that are also available in one of the repositories. + +*SOLVER_RULE_INFARCH*:: + Infarch rules are also negative assertions, they disallow the installation + of packages when there are packages of the same name but with a better + architecture. + +*SOLVER_RULE_CHOICE*:: + Choice rules are used to make sure that the solver preferes updating to + installing different packages when some dependency is provided by + multiple packages with different names. The solver may always break + choice rules, so you will not see them when a problem is found. + +*SOLVER_RULE_LEARNT*:: + These rules are generated by the solver to keep it from running into + the same problem multiple times when it has to backtrack. They are + the main reason why a sat solver is faster then other dependency solver + implementations. + +Special dependency rule types: + +*SOLVER_RULE_RPM_NOT_INSTALLABLE*:: + This rule was added to prevent the installation of a package of an + architecture that does not work on the system. + +*SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP*:: + The package contanis a required dependency which was not provided by + any package. + +*SOLVER_RULE_RPM_PACKAGE_REQUIRES*:: + Similar to SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP, but in this case + some packages provided the dependency but none of them could be + installed due to other dependency issues. + +*SOLVER_RULE_RPM_SELF_CONFLICT*:: + The package conflicts with itself. This is not allowed by older rpm + versions. + +*SOLVER_RULE_RPM_PACKAGE_CONFLICT*:: + To fulfill the dependencies two packages need to be installed, but + one of the packages contains a conflict with the other one. + +*SOLVER_RULE_RPM_SAME_NAME*:: + The dependencies can only be fulfilled by multiple versions of + a package, but installing multiple versions of the same package + is not allowed. + +*SOLVER_RULE_RPM_PACKAGE_OBSOLETES*:: + To fulfill the dependencies two packages need to be installed, but + one of the packages obsoletes the other one. + +*SOLVER_RULE_RPM_IMPLICIT_OBSOLETES*:: + To fulfill the dependencies two packages need to be installed, but + one of the packages has provides a dependency that is obsoleted + by the other one. See the POOL_FLAG_IMPLICITOBSOLETEUSESPROVIDES + flag. + +*SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES*:: + To fulfill the dependencies a package needs to be installed that is + obsoleted by an installed package. See the POOL_FLAG_NOINSTALLEDOBSOLETES + flag. + +*SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP*:: + The user asked for installation of a package providing a specific + dependency, but no available package provides it. + +*SOLVER_RULE_JOB_UNKNOWN_PACKAGE*:: + The user asked for installation of a package with a specific name, + but no available package has that name. + +*SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM*:: + The user asked for the erasure of a dependency that is provided by the + system (i.e. for special hardware or language dependencies), this + cannot be done with a job. + +*SOLVER_RULE_JOB_UNSUPPORTED*:: + The user asked for something that is not yet implemented, e.g. the + installation of all packages at once. + +Policy error constants + +*POLICY_ILLEGAL_DOWNGRADE*:: + The solver ask for permission before downgrading packages. + +*POLICY_ILLEGAL_ARCHCHANGE*:: + The solver ask for permission before changing the architecture of installed + packages. + +*POLICY_ILLEGAL_VENDORCHANGE*:: + The solver ask for permission before changing the vendor of installed + packages. + +*POLICY_ILLEGAL_NAMECHANGE*:: + The solver ask for permission before replacing an installed packages with + a packge that has a different name. + +Solution element type constants + +*SOLVER_SOLUTION_JOB*:: + The problem can be solved by removing the specified job. + +*SOLVER_SOLUTION_POOLJOB*:: + The problem can be solved by removing the specified job that is defined in the pool. + +*SOLVER_SOLUTION_INFARCH*:: + The problem can be solved by allowing the installation of the specified package + with an inferior architecture. + +*SOLVER_SOLUTION_DISTUPGRADE*:: + The problem can be solved by allowing to keep the specified package installed. + +*SOLVER_SOLUTION_BEST*:: + The problem can be solved by allowing to install the specified package that is + not the best available package. + +*SOLVER_SOLUTION_ERASE*:: + The problem can be solved by allowing to erase the specified package. + +*SOLVER_SOLUTION_REPLACE*:: + The problem can be solved by allowing to replace the package with some other + package. + +*SOLVER_SOLUTION_REPLACE_DOWNGRADE*:: + The problem can be solved by allowing to replace the package with some other + package that has a lower version. + +*SOLVER_SOLUTION_REPLACE_ARCHCHANGE*:: + The problem can be solved by allowing to replace the package with some other + package that has a different architecture. + +*SOLVER_SOLUTION_REPLACE_VENDORCHANGE*:: + The problem can be solved by allowing to replace the package with some other + package that has a different vendor. + +*SOLVER_SOLUTION_REPLACE_NAMECHANGE*:: + The problem can be solved by allowing to replace the package with some other + package that has a different name. + + +=== ATTRIBUTES === + + Pool *pool; /* read only */ + $job->{'pool'} + d.pool + d.pool + +Back pointer to pool. + +=== METHODS === + + int set_flag(int flag, int value) + my $oldvalue = $pool->set_flag($flag, $value); + oldvalue = pool.set_flag(flag, value) + oldvalue = pool.set_flag(flag, value) + + int get_flag(int flag) + my $value = $pool->get_flag($flag); + value = pool.get_flag(flag) + value = pool.get_flag(flag) + +Set/get a solver specific flag. The flags define the policies the solver has +to obey. The flags are explained in the CONSTANTS section of this class. + + Problem **solve(Job *jobs) + my @problems = $solver->solve(\@jobs); + problems = solver.solve(jobs) + problems = solver.solve(jobs) + +Solve a problem specified in the job list (plus the jobs defined in the pool). +Returns an array of problems that need user interaction, or an empty array +if no problems were encountered. See the Problem class on how to deal with +problems. + + Transaction *transaction() + my $trans = $solver->transaction(); + trans = solver.transaction() + trans = solver.transaction() + +Return the transaction to implement the calculated package changes. A transaction +is available even if problems were found, this is useful for interactive user +interfaces that show both the job result and the problems. + +THE PROBLEM CLASS +----------------- + +Problems are the way of the solver to interact with the user. You can simply list +all problems and terminate your program, but a better way is to present solutions to +the user and let him pick the ones he likes. + +=== ATTRIBUTES === + + Solver *solv; /* read only */ + $problem->{'solv'} + problem.solv + problem.solv + +Back pointer to solver object. + + Id id; /* read only */ + $problem->{'id'} + problem.id + problem.id + +Id of the problem. The first problem has Id 1, they are numbered consecutively. + +=== METHODS === + + Rule *findproblemrule() + my $probrule = $problem->findproblemrule(); + probrule = problem.findproblemrule() + probrule = problem.findproblemrule() + +Return the rule that caused the problem. Of cource in most situations there is no +single responsible rule, but many rules that interconnect with each created the +problem. Nevertheless, the solver uses some heuristic approch to find a rule +that somewhat describes the problem best to the user. + + Rule **findallproblemrules(bool unfiltered = 0) + my @probrules = $problem->findallproblemrules(); + probrules = problem.findallproblemrule() + probrules = problem.findallproblemrule() + +Return all rules responsible for the problem. The returned set of rules contains +all the needed information why there was a problem, but it's hard to present +them to the user in a sensible way. The default is to filter out all update and +job rules (unless the returned rules only consist of those types). + + Solutions **solutions() + my @solutions = $problem->solutions(); + solutions = problem.solutions() + solutions = problem.solutions() + +Return an array containing multiple possible solutions to fix the problem. See +the solution class for more information. + + int solution_count() + my $cnt = $problem->solution_count(); + cnt = problem.solution_count() + cnt = problem.solution_count() + +Return the number of solutions without creating solution objects. + +THE RULE CLASS +-------------- + +Rules are the basic block of sat solving. Each package dependency gets translated +into one or multiple rules. + +=== ATTRIBUTES === + + Solver *solv; /* read only */ + $rule->{'solv'} + rule.solv + rule.solv + +Back pointer to solver object. + + Id id; /* read only */ + $rule->{'id'} + rule.id + rule.id + +The id of the rule. + + int type; /* read only */ + $rule->{'type'} + rule.type + rule.type + +The basic type of the rule. See the constant section of the solver class for the type list. + +=== METHODS === + + Ruleinfo *info() + my $ruleinfo = $rule->info(); + ruleinfo = rule.info() + ruleinfo = rule.info() + +Return a Ruleinfo object that contains information about why the rule was created. But +see the allinfos() method below. + + Ruleinfo **allinfos() + my @ruleinfos = $rule->allinfos(); + ruleinfos = rule.allinfos() + ruleinfos = rule.allinfos() + +As the same dependency rule can get created because of multiple dependencies, one +Ruleinfo is not enough to describe the reason. Thus the allinfos() method returns +an array of all infos about a rule. + + + if ($rule1 == $rule2) + if rule1 == rule2: + if rule1 == rule2 + +Two rules are equal if they belong to the same solver and have the same id. + +THE RULEINFO CLASS +------------------ + +A Ruleinfo describes one reason why a rule was created. + +=== ATTRIBUTES === + + Solver *solv; /* read only */ + $ruleinfo->{'solv'} + ruleinfo.solv + ruleinfo.solv + +Back pointer to solver object. + + int type; /* read only */ + $ruleinfo->{'type'} + ruleinfo.type + ruleinfo.type + +The type of the ruleinfo. See the constant section of the solver class for the +rule type list and the special type list. + + Id dep; /* read only */ + $ruleinfo->{'dep'} + ruleinfo.dep + ruleinfo.dep + +The id of the dependency leading to the creation of the rule, or zero. + + Solvable *solvable; /* read only */ + $ruleinfo->{'solvable'} + ruleinfo.solvable + ruleinfo.solvable + +The involved Solvable, e.g. the one containing the dependency. + + Solvable *othersolvable; /* read only */ + $ruleinfo->{'othersolvable'} + ruleinfo.othersolvable + ruleinfo.othersolvable + +The other involved Solvable (if any), e.g. the one containing providing +the dependency for conflicts. + + const char *problemstr(); + my $str = $ruleinfo->problemstr(); + str = ruleinfo.problemstr() + str = ruleinfo.problemstr() + +A string describing the ruleinfo from a problem perspective. This probably +only makes sense if the rule is part of a problem. + +THE SOLUTION CLASS +------------------ + +A solution solves one specific problem. It consists of multiple solution elements +that all need to be executed. + +=== ATTRIBUTES === + + Solver *solv; /* read only */ + $solution->{'solv'} + solution.solv + solution.solv + +Back pointer to solver object. + + Id problemid; /* read only */ + $solution->{'problemid'} + solution.problemid + solution.problemid + +Id of the problem the solution solves. + + Id id; /* read only */ + $solution->{'id'} + solution.id + solution.id + +Id of the solution. The first solution has Id 1, they are numbered consecutively. + +=== METHODS === + + Solutionelement **elements(bool expandreplaces = 0) + my @solutionelements = $solution->elements(); + solutionelements = solution.elements() + solutionelements = solution.elements() + +Return an array containing the elements describing what neeeds to be done to +implement the specific solution. If expandreplaces is true, elements of type +SOLVER_SOLUTION_REPLACE will be replaced by one or more elements replace +elements describing the policy mismatches. + + int element_count() + my $cnt = $solution->solution_count(); + cnt = solution.element_count() + cnt = solution.element_count() + +Return the number of solution elements without creating objects. Note that the +count does not match the number of objects returned by the elements() method +of expandreplaces is set to true. + + +THE SOLUTIONELEMENT CLASS +------------------------- + +A solution element describes a single action of a solution. The action is always +either to remove one specific job or to add a new job that installs or erases +a single specific package. + +=== ATTRIBUTES === + + Solver *solv; /* read only */ + $solutionelement->{'solv'} + solutionelement.solv + solutionelement.solv + +Back pointer to solver object. + + Id problemid; /* read only */ + $solutionelement->{'problemid'} + solutionelement.problemid + solutionelement.problemid + +Id of the problem the element (partly) solves. + + Id solutionid; /* read only */ + $solutionelement->{'solutionid'} + solutionelement.solutionid + solutionelement.solutionid + +Id of the solution the element is a part of. + + Id id; /* read only */ + $solutionelement->{'id'} + solutionelement.id + solutionelement.id + +Id of the solution element. The first element has Id 1, they are numbered consecutively. + + Id type; /* read only */ + $solutionelement->{'type'} + solutionelement.type + solutionelement.type + +Type of the solution element. See the constant section of the solver class for the +existing types. + + Solvable *solvable; /* read only */ + $solutionelement->{'solvable'} + solutionelement.solvable + solutionelement.solvable + +The installed solvable that needs to be replaced for replacement elements. + + Solvable *replacement; /* read only */ + $solutionelement->{'replacement'} + solutionelement.replacement + solutionelement.replacement + +The solvable that needs to be installed to fix the problem. + + int jobidx; /* read only */ + $solutionelement->{'jobidx'} + solutionelement.jobidx + solutionelement.jobidx + +The index of the job that needs to be removed to fix the problem, or -1 if the +element is of another type. Note that it's better to change the job to SOLVER_NOOP +type so that the numbering of other elements does not get disturbed. This +method works both for types SOLVER_SOLUTION_JOB and SOLVER_SOLUTION_POOLJOB. + +=== METHODS === + + Solutionelement **replaceelements() + my @solutionelements = $solutionelement->replaceelements(); + solutionelements = solutionelement.replaceelements() + solutionelements = solutionelement.replaceelements() + +If the solution element is of type SOLVER_SOLUTION_REPLACE, return an array of +elements describing the policy mismatches, otherwise return a copy of the +element. See also the ``expandreplaces'' option in the solution's elements() +method. + + int illegalreplace() + my $illegal = $solutionelement->illegalreplace(); + illegal = solutionelement.illegalreplace() + illegal = solutionelement.illegalreplace() + +Return an integer that contains the policy mismatch bits or-ed together, or +zero if there was no policy mismatch. See the policy error constants in +the solver class. + + Job *Job() + my $job = $solutionelement->Job(); + illegal = solutionelement.Job() + illegal = solutionelement.Job() + +Create a job that implements the solution element. Add this job to the array +of jobs for all elements of type different to SOLVER_SOLUTION_JOB and +SOLVER_SOLUTION_POOLJOB. For the later two, a SOLVER_NOOB Job is created, +you should replace the old job with the new one. + + const char *str() + my $str = $solutionelement->str(); + str = solutionelement.str() + str = solutionelement.str() + +A string describing the change the solution element consists of. THE TRANSACTION CLASS ---------------------