]> git.ipfire.org Git - people/ms/pakfire.git/blame - python/src/solver.c
Implement distro-sync.
[people/ms/pakfire.git] / python / src / solver.c
CommitLineData
b792d887
MT
1/*#############################################################################
2# #
3# Pakfire - The IPFire package management system #
4# Copyright (C) 2011 Pakfire development team #
5# #
6# This program is free software: you can redistribute it and/or modify #
7# it under the terms of the GNU General Public License as published by #
8# the Free Software Foundation, either version 3 of the License, or #
9# (at your option) any later version. #
10# #
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 #
14# GNU General Public License for more details. #
15# #
16# You should have received a copy of the GNU General Public License #
17# along with this program. If not, see <http://www.gnu.org/licenses/>. #
18# #
19#############################################################################*/
c605d735
MT
20
21#include "pool.h"
22#include "problem.h"
23#include "request.h"
24#include "solver.h"
25
45f5a3d9 26#include <solv/solverdebug.h>
c605d735
MT
27
28PyTypeObject SolverType = {
29 PyObject_HEAD_INIT(NULL)
30 tp_name: "_pakfire.Solver",
31 tp_basicsize: sizeof(SolverObject),
32 tp_flags: Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
33 tp_new : Solver_new,
34 tp_dealloc: (destructor) Solver_dealloc,
35 tp_doc: "Sat Solver objects",
36};
37
38PyObject* Solver_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
39 SolverObject *self;
40
41 PoolObject *pool;
42
43 if (!PyArg_ParseTuple(args, "O", &pool)) {
44 /* XXX raise exception */
45 }
46
47 self = (SolverObject *)type->tp_alloc(type, 0);
48 if (self != NULL) {
49 self->_solver = solver_create(pool->_pool);
50 if (self->_solver == NULL) {
51 Py_DECREF(self);
52 return NULL;
53 }
54 }
55
9b68f47c
MT
56 /* enable splitprovides by default */
57 solver_set_flag(self->_solver, SOLVER_FLAG_SPLITPROVIDES, 1);
58
d314d72b
MT
59 /* keep explicit obsoletes */
60 solver_set_flag(self->_solver, SOLVER_FLAG_KEEP_EXPLICIT_OBSOLETES, 1);
61
c605d735
MT
62 return (PyObject *)self;
63}
64
65PyObject *Solver_dealloc(SolverObject *self) {
66 solver_free(self->_solver);
67 self->ob_type->tp_free((PyObject *)self);
4069d10c
MT
68
69 Py_RETURN_NONE;
c605d735
MT
70}
71
9b68f47c
MT
72PyObject *Solver_get_flag(SolverObject *self, PyObject *args) {
73 int flag = 0;
74
75 if (!PyArg_ParseTuple(args, "i", &flag)) {
76 return NULL;
77 }
78
79 int val = solver_get_flag(self->_solver, flag);
80 return Py_BuildValue("i", val);
35d89fd7
MT
81}
82
9b68f47c
MT
83PyObject *Solver_set_flag(SolverObject *self, PyObject *args) {
84 int flag = 0, val = 0;
35d89fd7 85
9b68f47c
MT
86 if (!PyArg_ParseTuple(args, "ii", &flag, &val)) {
87 return NULL;
35d89fd7
MT
88 }
89
9b68f47c 90 solver_set_flag(self->_solver, flag, val);
35d89fd7
MT
91 Py_RETURN_NONE;
92}
93
c605d735 94PyObject *Solver_get_allow_downgrade(SolverObject *self, PyObject *args) {
9b68f47c
MT
95 int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_DOWNGRADE);
96
97 return Py_BuildValue("i", val);
c605d735
MT
98}
99
100PyObject *Solver_set_allow_downgrade(SolverObject *self, PyObject *args) {
101 int val;
102
103 if (!PyArg_ParseTuple(args, "i", &val)) {
9b68f47c 104 return NULL;
c605d735
MT
105 }
106
9b68f47c 107 solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_DOWNGRADE, val);
c605d735
MT
108 Py_RETURN_NONE;
109}
110
111PyObject *Solver_get_allow_archchange(SolverObject *self, PyObject *args) {
9b68f47c
MT
112 int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_ARCHCHANGE);
113
114 return Py_BuildValue("i", val);
c605d735
MT
115}
116
117PyObject *Solver_set_allow_archchange(SolverObject *self, PyObject *args) {
118 int val;
119
120 if (!PyArg_ParseTuple(args, "i", &val)) {
9b68f47c 121 return NULL;
c605d735
MT
122 }
123
9b68f47c 124 solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_ARCHCHANGE, val);
c605d735
MT
125 Py_RETURN_NONE;
126}
127
128PyObject *Solver_get_allow_vendorchange(SolverObject *self, PyObject *args) {
9b68f47c
MT
129 int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_VENDORCHANGE);
130
131 return Py_BuildValue("i", val);
c605d735
MT
132}
133
134PyObject *Solver_set_allow_vendorchange(SolverObject *self, PyObject *args) {
135 int val;
136
137 if (!PyArg_ParseTuple(args, "i", &val)) {
9b68f47c 138 return NULL;
c605d735
MT
139 }
140
9b68f47c 141 solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_VENDORCHANGE, val);
c605d735
MT
142 Py_RETURN_NONE;
143}
144
145PyObject *Solver_get_allow_uninstall(SolverObject *self, PyObject *args) {
9b68f47c
MT
146 int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_UNINSTALL);
147
148 return Py_BuildValue("i", val);
c605d735
MT
149}
150
151PyObject *Solver_set_allow_uninstall(SolverObject *self, PyObject *args) {
152 int val;
153
154 if (!PyArg_ParseTuple(args, "i", &val)) {
9b68f47c 155 return NULL;
c605d735
MT
156 }
157
9b68f47c 158 solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_UNINSTALL, val);
c605d735
MT
159 Py_RETURN_NONE;
160}
161
162PyObject *Solver_get_updatesystem(SolverObject *self, PyObject *args) {
9b68f47c
MT
163 //return Py_BuildValue("i", self->_solver->updatesystem);
164 Py_RETURN_NONE;
c605d735
MT
165}
166
167PyObject *Solver_set_updatesystem(SolverObject *self, PyObject *args) {
9b68f47c 168 /*int val;
c605d735
MT
169
170 if (!PyArg_ParseTuple(args, "i", &val)) {
9b68f47c 171 return NULL;
c605d735
MT
172 }
173
9b68f47c 174 self->_solver->updatesystem = val; */
c605d735
MT
175
176 Py_RETURN_NONE;
177}
178
6c395339 179PyObject *Solver_get_do_split_provides(SolverObject *self, PyObject *args) {
9b68f47c
MT
180 int val = solver_get_flag(self->_solver, SOLVER_FLAG_SPLITPROVIDES);
181
182 return Py_BuildValue("i", val);
6c395339
MT
183}
184
185PyObject *Solver_set_do_split_provides(SolverObject *self, PyObject *args) {
186 int val;
187
188 if (!PyArg_ParseTuple(args, "i", &val)) {
9b68f47c 189 return NULL;
6c395339
MT
190 }
191
9b68f47c 192 solver_set_flag(self->_solver, SOLVER_FLAG_SPLITPROVIDES, val);
6c395339
MT
193 Py_RETURN_NONE;
194}
195
c605d735
MT
196PyObject *Solver_solve(SolverObject *self, PyObject *args) {
197 RequestObject *request;
d314d72b 198 int force_best = 0;
9b68f47c 199 int res = 0;
c605d735 200
d314d72b 201 if (!PyArg_ParseTuple(args, "O|i", &request, &force_best)) {
9b68f47c 202 return NULL;
c605d735
MT
203 }
204
205 // Make sure, the pool is prepared.
206 _Pool_prepare(self->_solver->pool);
207
d314d72b
MT
208 /* Force best solution. */
209 if (force_best) {
210 for (int i = 0; i < request->_queue.count; i += 2)
211 request->_queue.elements[i] |= SOLVER_FORCEBEST;
212 }
213
9b68f47c 214 res = solver_solve(self->_solver, &request->_queue);
c605d735 215
5168e648 216#ifdef DEBUG
c605d735 217 solver_printallsolutions(self->_solver);
5168e648 218#endif
c605d735 219
9b68f47c 220 if (res == 0) {
c605d735
MT
221 Py_RETURN_TRUE;
222 }
c605d735
MT
223 Py_RETURN_FALSE;
224}
225
226PyObject *Solver_get_problems(SolverObject *self, PyObject *args) {
227 RequestObject *request;
228
229 if (!PyArg_ParseTuple(args, "O", &request)) {
5168e648 230 return NULL;
c605d735
MT
231 }
232
233 PyObject *list = PyList_New(0);
234
235 ProblemObject *problem;
5168e648
MT
236 Id p = 0;
237 while ((p = solver_next_problem(self->_solver, p)) != 0) {
c605d735 238 problem = PyObject_New(ProblemObject, &ProblemType);
5168e648
MT
239
240 problem->_pool = self->_solver->pool;
c605d735 241 problem->_solver = self->_solver;
5168e648
MT
242 problem->_id = p;
243 Problem_init(problem);
c605d735
MT
244
245 PyList_Append(list, (PyObject *)problem);
246 }
247
5168e648 248 return list;
c605d735 249}