@@ -31,6 +31,7 @@ pub fn resolve(deps: Vec<Dependency>, registry: &[Summary]) -> CargoResult<Vec<P
31
31
resolve_with_global_context ( deps, registry, & GlobalContext :: default ( ) . unwrap ( ) )
32
32
}
33
33
34
+ // Verify that the resolution of cargo resolver can pass the verification of SAT
34
35
pub fn resolve_and_validated (
35
36
deps : Vec < Dependency > ,
36
37
registry : & [ Summary ] ,
@@ -198,6 +199,9 @@ fn log_bits(x: usize) -> usize {
198
199
( num_bits :: < usize > ( ) as u32 - x. leading_zeros ( ) ) as usize
199
200
}
200
201
202
+ // At this point is possible to select every version of every package.
203
+ // So we need to mark certain versions as incompatible with each other.
204
+ // We could add a clause not A, not B for all A and B that are incompatible,
201
205
fn sat_at_most_one ( solver : & mut impl varisat:: ExtendFormula , vars : & [ varisat:: Var ] ) {
202
206
if vars. len ( ) <= 1 {
203
207
return ;
@@ -210,6 +214,8 @@ fn sat_at_most_one(solver: &mut impl varisat::ExtendFormula, vars: &[varisat::Va
210
214
solver. add_clause ( & [ vars[ 1 ] . negative ( ) , vars[ 2 ] . negative ( ) ] ) ;
211
215
return ;
212
216
}
217
+ // There are more efficient ways to do it for large numbers of versions.
218
+ //
213
219
// use the "Binary Encoding" from
214
220
// https://www.it.uu.se/research/group/astra/ModRef10/papers/Alan%20M.%20Frisch%20and%20Paul%20A.%20Giannoros.%20SAT%20Encodings%20of%20the%20At-Most-k%20Constraint%20-%20ModRef%202010.pdf
215
221
let bits: Vec < varisat:: Var > = solver. new_var_iter ( log_bits ( vars. len ( ) ) ) . collect ( ) ;
@@ -257,6 +263,7 @@ struct SatResolveInner {
257
263
impl SatResolve {
258
264
pub fn new ( registry : & [ Summary ] ) -> Self {
259
265
let mut cnf = varisat:: CnfFormula :: new ( ) ;
266
+ // That represents each package version which is set to "true" if the packages in the lock file and "false" if it is unused.
260
267
let var_for_is_packages_used: HashMap < PackageId , varisat:: Var > = registry
261
268
. iter ( )
262
269
. map ( |s| ( s. package_id ( ) , cnf. new_var ( ) ) )
@@ -290,6 +297,10 @@ impl SatResolve {
290
297
291
298
let empty_vec = vec ! [ ] ;
292
299
300
+ // Now different versions can conflict, but dependencies might not be selected.
301
+ // So we need to add clauses that ensure that if a package is selected for each dependency a version
302
+ // that satisfies that dependency is selected.
303
+ //
293
304
// active packages need each of there `deps` to be satisfied
294
305
for p in registry. iter ( ) {
295
306
for dep in p. dependencies ( ) {
0 commit comments