ref: refs/heads/master
commit f78e56487b579cbfb6b0e40e050fbdfba12dbfc9
Author: Klaus Kämpf
Date: Mon Jun 22 17:13:11 2009 +0200
Make problem/solution handling less ZyPPish and more satsolver-ish
(Unfinished)
---
applayer/applayer.c | 2 +-
applayer/applayer.h | 2 +-
applayer/job.c | 2 +-
applayer/job.h | 4 +-
applayer/problem.c | 21 ++++++++++++
applayer/problem.h | 3 ++
applayer/ruleinfo.c | 8 ++--
applayer/ruleinfo.h | 8 ++--
applayer/xsolvable.c | 23 +-------------
applayer/xsolvable.h | 4 +-
bindings/problem.i | 38 +++++-----------------
bindings/relation.i | 4 +-
bindings/ruby/tests/problems.rb | 34 +------------------
bindings/ruby/tests/solutions.rb | 65 --------------------------------------
bindings/rule.i | 34 --------------------
bindings/ruleinfo.i | 31 ++++++++++++++++++
bindings/satsolver.i | 3 +-
bindings/solution.i | 33 -------------------
18 files changed, 86 insertions(+), 233 deletions(-)
diff --git a/applayer/applayer.c b/applayer/applayer.c
index 6aeef6a..81e2d9c 100644
--- a/applayer/applayer.c
+++ b/applayer/applayer.c
@@ -47,7 +47,7 @@ pool_xsolvables_count( const Pool *pool )
}
void
-pool_xsolvables_iterate( const Pool *pool, int (*callback)(const XSolvable *xs, void *user_data), void *user_data)
+pool_xsolvables_iterate( Pool *pool, int (*callback)(const XSolvable *xs, void *user_data), void *user_data)
{
const Solvable *s;
Id p;
diff --git a/applayer/applayer.h b/applayer/applayer.h
index a097270..cfcb911 100644
--- a/applayer/applayer.h
+++ b/applayer/applayer.h
@@ -33,6 +33,6 @@ const char *my_id2str( const Pool *pool, Id id );
*/
unsigned int pool_xsolvables_count( const Pool *pool );
-void pool_xsolvables_iterate( const Pool *pool, int (*callback)(const XSolvable *xs, void *user_data), void *user_data);
+void pool_xsolvables_iterate( Pool *pool, int (*callback)(const XSolvable *xs, void *user_data), void *user_data);
#endif /* SATSOLVER_APPLAYER_H */
diff --git a/applayer/job.c b/applayer/job.c
index d7e9b20..2a4a6f5 100644
--- a/applayer/job.c
+++ b/applayer/job.c
@@ -18,7 +18,7 @@
#include "applayer.h"
Job *
-job_new( const Pool *pool, Id cmd, Id id )
+job_new( Pool *pool, Id cmd, Id id )
{
Job *job = (Job *)malloc( sizeof( Job ));
job->pool = pool;
diff --git a/applayer/job.h b/applayer/job.h
index d1fd677..e787ded 100644
--- a/applayer/job.h
+++ b/applayer/job.h
@@ -26,13 +26,13 @@
#include "relation.h"
typedef struct _Job {
- const Pool *pool;
+ Pool *pool;
int cmd; /* solver queue command */
Id id; /* Id of Name, Relation, or Solvable */
} Job;
-Job *job_new( const Pool *pool, int cmd, Id id );
+Job *job_new( Pool *pool, int cmd, Id id );
void job_free( Job *j );
diff --git a/applayer/problem.c b/applayer/problem.c
index a211aa1..514b69a 100644
--- a/applayer/problem.c
+++ b/applayer/problem.c
@@ -57,6 +57,27 @@ solver_problems_iterate( Solver *solver, Request *t, int (*callback)(const Probl
void
+problem_ruleinfos_iterate( Problem *problem, int (*callback)( const Ruleinfo *ri, void *user_data), void *user_data )
+{
+ Queue rules;
+ Id rule;
+ queue_init(&rules);
+
+ solver_findallproblemrules(problem->solver, problem->id, &rules);
+ while ((rule = queue_shift(&rules)))
+ {
+ int result;
+ Ruleinfo *ri = ruleinfo_new( problem->solver, rule );
+ result = callback( ri, user_data );
+ ruleinfo_free(ri);
+ if (result)
+ break;
+ }
+ return;
+}
+
+
+void
problem_solutions_iterate( Problem *problem, int (*callback)( const Solution *s, void *user_data ), void *user_data )
{
if (!callback) /* no use to iterate without callback */
diff --git a/applayer/problem.h b/applayer/problem.h
index 25f0d2f..7447989 100644
--- a/applayer/problem.h
+++ b/applayer/problem.h
@@ -20,6 +20,7 @@
#include "solver.h"
#include "job.h"
+#include "ruleinfo.h"
#include "request.h"
@@ -34,6 +35,8 @@ void problem_free( Problem *p );
void solver_problems_iterate( Solver *solver, Request *t, int (*callback)( const Problem *p, void *user_data ), void *user_data );
+void problem_ruleinfos_iterate( Problem *problem, int (*callback)( const Ruleinfo *ri, void *user_data), void *user_data );
+
/* loop over Jobs leading to the problem */
void problem_jobs_iterate( Problem *p, int (*callback)( const Job *j, void *user_data ), void *user_data );
diff --git a/applayer/ruleinfo.c b/applayer/ruleinfo.c
index 3fa45a8..90a9fff 100644
--- a/applayer/ruleinfo.c
+++ b/applayer/ruleinfo.c
@@ -37,28 +37,28 @@ ruleinfo_free( Ruleinfo *ri )
int
-command(const Ruleinfo *ri)
+ruleinfo_command(const Ruleinfo *ri)
{
return ri->cmd;
}
XSolvable *
-source(const Ruleinfo *ri)
+ruleinfo_source(const Ruleinfo *ri)
{
return ri->source ? xsolvable_new( ri->solver->pool, ri->source ) : NULL;
}
XSolvable *
-target(const Ruleinfo *ri)
+ruleinfo_target(const Ruleinfo *ri)
{
return ri->target ? xsolvable_new( ri->solver->pool, ri->target ) : NULL;
}
Relation *
-relation(const Ruleinfo *ri)
+ruleinfo_relation(const Ruleinfo *ri)
{
return ri->dep ? relation_new( ri->solver->pool, ri->dep ) : NULL;
}
diff --git a/applayer/ruleinfo.h b/applayer/ruleinfo.h
index 1f24093..69674f7 100644
--- a/applayer/ruleinfo.h
+++ b/applayer/ruleinfo.h
@@ -34,9 +34,9 @@ typedef struct _Ruleinfo {
Ruleinfo *ruleinfo_new( const Solver *solver, Id rule );
void ruleinfo_free( Ruleinfo *ri );
-int command(const Ruleinfo *ri);
-XSolvable *source(const Ruleinfo *ri);
-XSolvable *target(const Ruleinfo *ri);
-Relation *relation(const Ruleinfo *ri);
+int ruleinfo_command(const Ruleinfo *ri);
+XSolvable *ruleinfo_source(const Ruleinfo *ri);
+XSolvable *ruleinfo_target(const Ruleinfo *ri);
+Relation *ruleinfo_relation(const Ruleinfo *ri);
#endif /* SATSOLVER_RULEINFO_H */
diff --git a/applayer/xsolvable.c b/applayer/xsolvable.c
index ed1ca08..cababe4 100644
--- a/applayer/xsolvable.c
+++ b/applayer/xsolvable.c
@@ -26,7 +26,7 @@
XSolvable *
-xsolvable_new( const Pool *pool, Id id )
+xsolvable_new( Pool *pool, Id id )
{
if (id) {
XSolvable *xsolvable = (XSolvable *)malloc( sizeof( XSolvable ));
@@ -183,27 +183,6 @@ xsolvable_find( Pool *pool, const char *name, const Repo *repo )
/*
- * get solvable by index (0..size-1)
- * If repo == NULL, index is relative to pool
- * If repo != NULL, index is relative to repo
- *
- * index is _not_ the internal id, but used as an array index
- */
-
-XSolvable *
-xsolvable_get( const Pool *pool, int i, const Repo *repo )
-{
- if (repo == NULL)
- i += 2; /* adapt to internal Id, see size() above */
- if (i < 0)
- return NULL;
- if (i >= (repo ? repo->nsolvables : pool->nsolvables))
- return NULL;
- return xsolvable_new( repo ? repo->pool : pool, repo ? repo->start + i : i );
-}
-
-
-/*
* Iterate over all installs
*/
diff --git a/applayer/xsolvable.h b/applayer/xsolvable.h
index 28875da..8fc989d 100644
--- a/applayer/xsolvable.h
+++ b/applayer/xsolvable.h
@@ -28,7 +28,7 @@
*/
typedef struct _xsolvable {
- const Pool *pool;
+ Pool *pool;
Id id;
unsigned int kind; /* one of KIND_xxx */
} XSolvable;
@@ -36,7 +36,7 @@ typedef struct _xsolvable {
/*
* Create a new XSolvable in pool from Solvable id
*/
-XSolvable *xsolvable_new( const Pool *pool, Id id );
+XSolvable *xsolvable_new( Pool *pool, Id id );
/*
* Create a new XSolvable in pool from name, evr, arch
diff --git a/bindings/problem.i b/bindings/problem.i
index 4c3829d..ddfca10 100644
--- a/bindings/problem.i
+++ b/bindings/problem.i
@@ -18,11 +18,11 @@
*/
static int
-problem_rules_iterate_callback(const Rule *r, void *user_data)
+problem_ruleinfo_iterate_callback(const Ruleinfo *ri, void *user_data)
{
#if defined(SWIGRUBY)
/* FIXME: how to pass 'break' back to the caller ? */
- rb_yield( SWIG_NewPointerObj((void*) r, SWIGTYPE_p__Rule, 0) );
+ rb_yield( SWIG_NewPointerObj((void*)ri, SWIGTYPE_p__Ruleinfo, 0) );
#endif
return 0;
}
@@ -79,35 +79,15 @@ typedef struct _Problem {} Problem;
{ return $self->solver; }
/*
- * The Request causing the Problem
- */
- Request *request()
- { return $self->request; }
-
- /*
- * The reason for the problem. One of +Satsolver::SOLVER_RULE_*+
+ * An iterator providing information on the rules leading to the
+ * problem.
+ *
+ * call-seq:
+ * problem.each_ruleinfo { |ruleinfo| ... }
*
*/
- int reason()
- { return $self->reason; }
-
- /*
- * The Solvable causing the problem
- */
- XSolvable *source()
- { return xsolvable_new( $self->solver->pool, $self->source ); }
-
- /*
- * The affected relation
- */
- Relation *relation()
- { return relation_new( $self->solver->pool, $self->relation ); }
-
- /*
- * The Solvable affected by the problem
- */
- XSolvable *target()
- { return xsolvable_new( $self->solver->pool, $self->target ); }
+ void each_ruleinfo()
+ { problem_ruleinfos_iterate( $self, problem_ruleinfo_iterate_callback, NULL ); }
/*
* Number of available solutions for problem
diff --git a/bindings/relation.i b/bindings/relation.i
index 127845f..5683aa1 100644
--- a/bindings/relation.i
+++ b/bindings/relation.i
@@ -67,9 +67,9 @@ typedef struct _Relation {} Relation;
* String representation of this Relation
*/
const char *string()
- { return strdup(dep2str( $self->pool, $self->id )); }
+ { return strdup(dep2str( (Pool *)$self->pool, $self->id )); }
- Pool *pool()
+ const Pool *pool()
{ return $self->pool; }
/*
diff --git a/bindings/ruby/tests/problems.rb b/bindings/ruby/tests/problems.rb
index d2af244..ae86c55 100644
--- a/bindings/ruby/tests/problems.rb
+++ b/bindings/ruby/tests/problems.rb
@@ -2,42 +2,12 @@
# In case the Solver cannot find a solution (Solver.problems? true),
# it reports Problems through Solver.each_problem.
#
-# There is no 'problem count' provided by the Solver, only the
-# existance of problems is reported via Solver.problems?
+# A problem is always related to a solver rule.
#
# Linked to each problem is a set of solutions, accessible
# through Problem.each_solution
#
-# Each problem contains
-# - a problem identifier (Problem.id)
-# - a reason code (Problem.reason)
-# see below
-# - a source identifier
-# - a relation identifier
-# - a target identifier
-#
-# The identifiers can have various meanings (name, relation, solvable), depending
-# on the reason.
-#
-# The following reasons are defined
-# SOLVER_PROBLEM_UPDATE_RULE
-# problem with installed source
-# SOLVER_PROBLEM_JOB_RULE
-# conflicting requests
-# SOLVER_PROBLEM_JOB_NOTHING_PROVIDES_DEP
-# nothing provides requested relation
-# SOLVER_PROBLEM_NOT_INSTALLABLE
-# source not installable
-# SOLVER_PROBLEM_NOTHING_PROVIDES_DEP
-# nothing provides relation required by source
-# SOLVER_PROBLEM_SAME_NAME
-# cannot install both source and target
-# SOLVER_PROBLEM_PACKAGE_CONFLICT
-# source conflicts with relation provided by target
-# SOLVER_PROBLEM_PACKAGE_OBSOLETES
-# source obsoletes relation provided by target
-# SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE
-# source requires relation but no providers are installable
+# A solution is a set of elements, each suggesting changes to the initial request.
#
$:.unshift "../../../build/bindings/ruby"
diff --git a/bindings/ruby/tests/solutions.rb b/bindings/ruby/tests/solutions.rb
index 72a693a..7c3f68a 100644
--- a/bindings/ruby/tests/solutions.rb
+++ b/bindings/ruby/tests/solutions.rb
@@ -53,70 +53,5 @@ class SolutionTest < Test::Unit::TestCase
assert solver.problems?
puts "Problems found"
i = 0
- solver.each_problem( request ) { |p|
- i += 1
- case p.reason
- when Satsolver::SOLVER_PROBLEM_UPDATE_RULE
- reason = "problem with installed"
- when Satsolver::SOLVER_PROBLEM_JOB_RULE
- reason = "conflicting requests"
- when Satsolver::SOLVER_PROBLEM_JOB_NOTHING_PROVIDES_DEP
- reason = "nothing provides requested"
- when Satsolver::SOLVER_PROBLEM_NOT_INSTALLABLE
- reason = "not installable"
- when Satsolver::SOLVER_PROBLEM_NOTHING_PROVIDES_DEP
- reason = "nothing provides rel required by source"
- when Satsolver::SOLVER_PROBLEM_SAME_NAME
- reason = "cannot install both"
- when Satsolver::SOLVER_PROBLEM_PACKAGE_CONFLICT
- reason = "source conflicts with rel provided by target"
- when Satsolver::SOLVER_PROBLEM_PACKAGE_OBSOLETES
- reason = "source obsoletes rel provided by target"
- when Satsolver::SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE
- reason = "source requires rel but no providers are installable"
- else
- reason = "**unknown**"
- end
- puts "#{i}: [#{reason}] Source #{p.source}, Rel #{p.relation}, Target #{p.target}"
- j = 0
- p.each_solution { |s|
- j += 1
- case s.solution
- when Satsolver::SOLUTION_UNKNOWN
- solution = "None available"
- when Satsolver::SOLUTION_NOKEEP_INSTALLED
- solution = "dont keep installed"
- when Satsolver::SOLUTION_NOINSTALL_SOLV
- solution = "dont install solvable"
- when Satsolver::SOLUTION_NOREMOVE_SOLV
- solution = "dont remove solvable"
- when Satsolver::SOLUTION_NOFORBID_INSTALL
- solution = "dont forbid install"
- when Satsolver::SOLUTION_NOINSTALL_NAME
- solution = "dont install name"
- when Satsolver::SOLUTION_NOREMOVE_NAME
- solution = "dont remove name"
- when Satsolver::SOLUTION_NOINSTALL_REL
- solution = "dont install relation"
- when Satsolver::SOLUTION_NOREMOVE_REL
- solution = "dont remove relation"
- when Satsolver::SOLUTION_NOUPDATE
- solution = "dont update"
- when Satsolver::SOLUTION_ALLOW_DOWNGRADE
- solution = "allow downgrade"
- when Satsolver::SOLUTION_ALLOW_ARCHCHANGE
- solution = "allow architecture change"
- when Satsolver::SOLUTION_ALLOW_VENDORCHANGE
- solution = "allow vendor change"
- when Satsolver::SOLUTION_ALLOW_REPLACEMENT
- solution = "allow replacement"
- when Satsolver::SOLUTION_ALLOW_REMOVE
- solution = "allow removal"
- else
- solution = "**UNKNOWN**"
- end
- puts " #{j}: [#{solution}] #{s.s1}"
- }
- }
end
end
diff --git a/bindings/rule.i b/bindings/rule.i
deleted file mode 100644
index f63e7c3..0000000
--- a/bindings/rule.i
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Document-class: Rule
- *
- * A rule is the internal representation of the _working_ _queue_ of the
- * solver. Each job item and each dependency is converted to a
- * rule the solver operates on.
- *
- * Rules are useful to traceback a decision or a problem.
- *
- * === Constructor
- * There is no constructor for Rule. Rules are embedded in the Solver
- *
- */
-
-%nodefault rule;
-%rename(Rule) rule;
-typedef struct rule {} Rule;
-
-
-%extend Rule {
-
- int p()
- { return $self->p; }
-
- int d()
- { return $self->d; }
-
- int w1()
- { return $self->w1; }
-
- int w2()
- { return $self->w2; }
-
-}
diff --git a/bindings/ruleinfo.i b/bindings/ruleinfo.i
new file mode 100644
index 0000000..3b535c9
--- /dev/null
+++ b/bindings/ruleinfo.i
@@ -0,0 +1,31 @@
+/*
+ * Document-class: Ruleinfo
+ *
+ * Ruleinfos are useful to traceback a decision or a problem.
+ *
+ * === Constructor
+ * There is no constructor for Ruleinfo. Ruleinfos are created when
+ * iterating over problems
+ *
+ */
+
+%nodefault _Ruleinfo;
+%rename(Ruleinfo) _Ruleinfo;
+typedef struct _Ruleinfo {} Ruleinfo;
+
+
+%extend Ruleinfo {
+
+ int command()
+ { return $self->cmd; }
+
+ XSolvable *source()
+ { return ruleinfo_source($self); }
+
+ XSolvable *target()
+ { return ruleinfo_target($self); }
+
+ Relation *relation()
+ { return ruleinfo_relation($self); }
+
+}
diff --git a/bindings/satsolver.i b/bindings/satsolver.i
index 562a94e..a586637 100644
--- a/bindings/satsolver.i
+++ b/bindings/satsolver.i
@@ -157,6 +157,7 @@ SWIGINTERNINLINE SV *SWIG_FromCharPtr(const char *cptr);
#include "problem.h"
#include "solution.h"
#include "covenant.h"
+#include "ruleinfo.h"
#if defined(SWIGRUBY)
@@ -403,6 +404,6 @@ typedef unsigned int Offset;
%include "problem.i"
%include "solution.i"
%include "covenant.i"
-%include "rule.i"
+%include "ruleinfo.i"
%include "solver.i"
%include "dataiterator.i"
diff --git a/bindings/solution.i b/bindings/solution.i
index 599a437..508b23a 100644
--- a/bindings/solution.i
+++ b/bindings/solution.i
@@ -21,41 +21,8 @@ typedef struct _Solution {} Solution;
%extend Solution {
- %constant int SOLUTION_UNKNOWN = SOLUTION_UNKNOWN;
- %constant int SOLUTION_NOKEEP_INSTALLED = SOLUTION_NOKEEP_INSTALLED;
- %constant int SOLUTION_NOINSTALL_SOLV = SOLUTION_NOINSTALL_SOLV;
- %constant int SOLUTION_NOREMOVE_SOLV = SOLUTION_NOREMOVE_SOLV;
- %constant int SOLUTION_NOFORBID_INSTALL = SOLUTION_NOFORBID_INSTALL;
- %constant int SOLUTION_NOINSTALL_NAME = SOLUTION_NOINSTALL_NAME;
- %constant int SOLUTION_NOREMOVE_NAME = SOLUTION_NOREMOVE_NAME;
- %constant int SOLUTION_NOINSTALL_REL = SOLUTION_NOINSTALL_REL;
- %constant int SOLUTION_NOREMOVE_REL = SOLUTION_NOREMOVE_REL;
- %constant int SOLUTION_NOUPDATE = SOLUTION_NOUPDATE;
- %constant int SOLUTION_ALLOW_DOWNGRADE = SOLUTION_ALLOW_DOWNGRADE;
- %constant int SOLUTION_ALLOW_ARCHCHANGE = SOLUTION_ALLOW_ARCHCHANGE;
- %constant int SOLUTION_ALLOW_VENDORCHANGE = SOLUTION_ALLOW_VENDORCHANGE;
- %constant int SOLUTION_ALLOW_REPLACEMENT = SOLUTION_ALLOW_REPLACEMENT;
- %constant int SOLUTION_ALLOW_REMOVE = SOLUTION_ALLOW_REMOVE;
~Solution()
{ solution_free ($self); }
- int solution()
- { return $self->solution; }
- /* without the %rename, swig converts it to 's_1'. Ouch! */
- %rename( "s1" ) s1( );
- XSolvable *s1()
- { return xsolvable_new( $self->pool, $self->s1 ); }
- %rename( "n1" ) n1( );
- const char *n1()
- { return id2str( $self->pool, $self->n1 ); }
- %rename( "r1" ) r1( );
- Relation *r1()
- { return relation_new( $self->pool, $self->n1 ); }
- %rename( "s2" ) s2( );
- XSolvable *s2()
- { return xsolvable_new( $self->pool, $self->s2 ); }
- %rename( "n2" ) n2( );
- const char *n2()
- { return id2str( $self->pool, $self->n2 ); }
}
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org