@@ -235,10 +235,10 @@ pub struct SatResolve {
235
235
236
236
impl SatResolve {
237
237
pub fn new ( registry : & [ Summary ] ) -> Self {
238
- let mut solver = varisat:: Solver :: new ( ) ;
238
+ let mut cnf = varisat:: CnfFormula :: new ( ) ;
239
239
let var_for_is_packages_used: HashMap < PackageId , varisat:: Var > = registry
240
240
. iter ( )
241
- . map ( |s| ( s. package_id ( ) , solver . new_var ( ) ) )
241
+ . map ( |s| ( s. package_id ( ) , cnf . new_var ( ) ) )
242
242
. collect ( ) ;
243
243
244
244
// no two packages with the same links set
@@ -252,7 +252,7 @@ impl SatResolve {
252
252
}
253
253
}
254
254
for link in by_links. values ( ) {
255
- sat_at_most_one ( & mut solver , link) ;
255
+ sat_at_most_one ( & mut cnf , link) ;
256
256
}
257
257
258
258
// no two semver compatible versions of the same package
@@ -264,7 +264,7 @@ impl SatResolve {
264
264
. push ( var_for_is_packages_used[ & p. package_id ( ) ] )
265
265
}
266
266
for key in by_activations_keys. values ( ) {
267
- sat_at_most_one ( & mut solver , key) ;
267
+ sat_at_most_one ( & mut cnf , key) ;
268
268
}
269
269
270
270
let mut by_name: HashMap < & ' static str , Vec < PackageId > > = HashMap :: new ( ) ;
@@ -288,6 +288,9 @@ impl SatResolve {
288
288
for p in registry. iter ( ) {
289
289
graph. add ( p. package_id ( ) ) ;
290
290
for dep in p. dependencies ( ) {
291
+ // This can more easily be written as:
292
+ // !is_active(p) or one of the things that match dep is_active
293
+ // All the complexity, from here to the end, is to support public and private dependencies!
291
294
let mut by_key: HashMap < _ , Vec < varisat:: Lit > > = HashMap :: new ( ) ;
292
295
for & m in by_name
293
296
. get ( dep. package_name ( ) . as_str ( ) )
@@ -300,21 +303,21 @@ impl SatResolve {
300
303
. or_default ( )
301
304
. push ( var_for_is_packages_used[ & m] . positive ( ) ) ;
302
305
}
303
- let keys: HashMap < _ , _ > = by_key. keys ( ) . map ( |& k| ( k, solver . new_var ( ) ) ) . collect ( ) ;
306
+ let keys: HashMap < _ , _ > = by_key. keys ( ) . map ( |& k| ( k, cnf . new_var ( ) ) ) . collect ( ) ;
304
307
305
308
// if `p` is active then we need to select one of the keys
306
309
let matches: Vec < _ > = keys
307
310
. values ( )
308
311
. map ( |v| v. positive ( ) )
309
312
. chain ( Some ( var_for_is_packages_used[ & p. package_id ( ) ] . negative ( ) ) )
310
313
. collect ( ) ;
311
- solver . add_clause ( & matches) ;
314
+ cnf . add_clause ( & matches) ;
312
315
313
316
// if a key is active then we need to select one of the versions
314
317
for ( key, vars) in by_key. iter ( ) {
315
318
let mut matches = vars. clone ( ) ;
316
319
matches. push ( keys[ key] . negative ( ) ) ;
317
- solver . add_clause ( & matches) ;
320
+ cnf . add_clause ( & matches) ;
318
321
}
319
322
320
323
version_selected_for
@@ -336,8 +339,8 @@ impl SatResolve {
336
339
. entry ( key)
337
340
. or_default ( )
338
341
. entry ( key)
339
- . or_insert_with ( || solver . new_var ( ) ) ;
340
- solver . add_clause ( & [ var. positive ( ) ] ) ;
342
+ . or_insert_with ( || cnf . new_var ( ) ) ;
343
+ cnf . add_clause ( & [ var. positive ( ) ] ) ;
341
344
}
342
345
343
346
// if a `dep` is public then `p` `publicly_exports` all the things that the selected version `publicly_exports`
@@ -350,8 +353,8 @@ impl SatResolve {
350
353
. entry ( p. as_activations_key ( ) )
351
354
. or_default ( )
352
355
. entry ( export_pid)
353
- . or_insert_with ( || solver . new_var ( ) ) ;
354
- solver . add_clause ( & [
356
+ . or_insert_with ( || cnf . new_var ( ) ) ;
357
+ cnf . add_clause ( & [
355
358
sel. negative ( ) ,
356
359
export_var. negative ( ) ,
357
360
our_var. positive ( ) ,
@@ -373,8 +376,8 @@ impl SatResolve {
373
376
. entry ( p)
374
377
. or_default ( )
375
378
. entry ( export_pid)
376
- . or_insert_with ( || solver . new_var ( ) ) ;
377
- solver . add_clause ( & [ export_var. negative ( ) , our_var. positive ( ) ] ) ;
379
+ . or_insert_with ( || cnf . new_var ( ) ) ;
380
+ cnf . add_clause ( & [ export_var. negative ( ) , our_var. positive ( ) ] ) ;
378
381
}
379
382
}
380
383
@@ -387,8 +390,8 @@ impl SatResolve {
387
390
. entry ( p. as_activations_key ( ) )
388
391
. or_default ( )
389
392
. entry ( export_pid)
390
- . or_insert_with ( || solver . new_var ( ) ) ;
391
- solver . add_clause ( & [
393
+ . or_insert_with ( || cnf . new_var ( ) ) ;
394
+ cnf . add_clause ( & [
392
395
sel. negative ( ) ,
393
396
export_var. negative ( ) ,
394
397
our_var. positive ( ) ,
@@ -405,9 +408,17 @@ impl SatResolve {
405
408
by_name. entry ( name. as_str ( ) ) . or_default ( ) . push ( var) ;
406
409
}
407
410
for same_name in by_name. values ( ) {
408
- sat_at_most_one ( & mut solver , same_name) ;
411
+ sat_at_most_one ( & mut cnf , same_name) ;
409
412
}
410
413
}
414
+ let mut solver = varisat:: Solver :: new ( ) ;
415
+ solver. add_formula ( & cnf) ;
416
+
417
+ // We dont need to `solve` now. We know that "use nothing" will satisfy all the clauses so far.
418
+ // But things run faster if we let it spend some time figuring out how the constraints interact before we add assumptions.
419
+ solver
420
+ . solve ( )
421
+ . expect ( "docs say it can't error in default config" ) ;
411
422
412
423
SatResolve {
413
424
solver,
@@ -450,9 +461,7 @@ impl SatResolve {
450
461
451
462
self . solver
452
463
. solve ( )
453
- . expect ( "docs say it can't error in default config" ) ;
454
-
455
- self . solver . model ( ) . is_some ( )
464
+ . expect ( "docs say it can't error in default config" )
456
465
}
457
466
}
458
467
0 commit comments