Skip to content

Commit 19312b5

Browse files
authored
refactor: satisfier search result cleanup (#96)
1 parent cd91684 commit 19312b5

File tree

2 files changed

+40
-67
lines changed

2 files changed

+40
-67
lines changed

src/internal/core.rs

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ use std::collections::HashSet as Set;
88
use crate::error::PubGrubError;
99
use crate::internal::arena::Arena;
1010
use crate::internal::incompatibility::{IncompId, Incompatibility, Relation};
11-
use crate::internal::partial_solution::Assignment::{Decision, Derivation};
11+
use crate::internal::partial_solution::SatisfierSearch::{
12+
DifferentDecisionLevels, SameDecisionLevels,
13+
};
1214
use crate::internal::partial_solution::{DecisionLevel, PartialSolution};
1315
use crate::internal::small_vec::SmallVec;
1416
use crate::package::Package;
@@ -168,39 +170,30 @@ impl<P: Package, V: Version> State<P, V> {
168170
self.build_derivation_tree(current_incompat_id),
169171
));
170172
} else {
171-
let (satisfier, satisfier_level, previous_satisfier_level) = self
172-
.partial_solution
173-
.find_satisfier_and_previous_satisfier_level(
174-
&self.incompatibility_store[current_incompat_id],
175-
&self.incompatibility_store,
176-
);
177-
match satisfier {
178-
Decision { package, .. } => {
173+
let (package, satisfier_search_result) = self.partial_solution.satisfier_search(
174+
&self.incompatibility_store[current_incompat_id],
175+
&self.incompatibility_store,
176+
);
177+
match satisfier_search_result {
178+
DifferentDecisionLevels {
179+
previous_satisfier_level,
180+
} => {
179181
self.backtrack(
180182
current_incompat_id,
181183
current_incompat_changed,
182184
previous_satisfier_level,
183185
);
184186
return Ok((package, current_incompat_id));
185187
}
186-
Derivation { cause, package } => {
187-
if previous_satisfier_level != satisfier_level {
188-
self.backtrack(
189-
current_incompat_id,
190-
current_incompat_changed,
191-
previous_satisfier_level,
192-
);
193-
return Ok((package, current_incompat_id));
194-
} else {
195-
let prior_cause = Incompatibility::prior_cause(
196-
current_incompat_id,
197-
cause,
198-
&package,
199-
&self.incompatibility_store,
200-
);
201-
current_incompat_id = self.incompatibility_store.alloc(prior_cause);
202-
current_incompat_changed = true;
203-
}
188+
SameDecisionLevels { satisfier_cause } => {
189+
let prior_cause = Incompatibility::prior_cause(
190+
current_incompat_id,
191+
satisfier_cause,
192+
&package,
193+
&self.incompatibility_store,
194+
);
195+
current_incompat_id = self.incompatibility_store.alloc(prior_cause);
196+
current_incompat_changed = true;
204197
}
205198
}
206199
}

src/internal/partial_solution.rs

Lines changed: 20 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -56,25 +56,13 @@ enum AssignmentsIntersection<V: Version> {
5656
Derivations(Term<V>),
5757
}
5858

59-
/// An assignment is either a decision: a chosen version for a package,
60-
/// or a derivation : a term specifying compatible versions for a package.
61-
/// We also record the incompatibility at the origin of a derivation, called its cause.
62-
/// TODO: Remove. I only added that to not change the code in core.rs (except reference &).
63-
#[derive(Clone, PartialEq, Debug)]
64-
pub enum Assignment<P: Package, V: Version> {
65-
/// The decision.
66-
Decision {
67-
/// The package corresponding to the decision.
68-
package: P,
69-
/// The decided version.
70-
version: V,
59+
#[derive(Clone, Debug)]
60+
pub enum SatisfierSearch<P: Package, V: Version> {
61+
DifferentDecisionLevels {
62+
previous_satisfier_level: DecisionLevel,
7163
},
72-
/// The derivation.
73-
Derivation {
74-
/// The package corresponding to the derivation.
75-
package: P,
76-
/// Incompatibility cause of the derivation.
77-
cause: IncompId<P, V>,
64+
SameDecisionLevels {
65+
satisfier_cause: IncompId<P, V>,
7866
},
7967
}
8068

@@ -286,12 +274,12 @@ impl<P: Package, V: Version> PartialSolution<P, V> {
286274
.map(|pa| pa.assignments_intersection.term())
287275
}
288276

289-
/// Find satisfier and previous satisfier decision level.
290-
pub fn find_satisfier_and_previous_satisfier_level(
277+
/// Figure out if the satisfier and previous satisfier are of different decision levels.
278+
pub fn satisfier_search(
291279
&self,
292280
incompat: &Incompatibility<P, V>,
293281
store: &Arena<Incompatibility<P, V>>,
294-
) -> (Assignment<P, V>, DecisionLevel, DecisionLevel) {
282+
) -> (P, SatisfierSearch<P, V>) {
295283
let satisfied_map = Self::find_satisfier(incompat, &self.package_assignments, store);
296284
let (satisfier_package, &(satisfier_index, _, satisfier_decision_level)) = satisfied_map
297285
.iter()
@@ -305,27 +293,19 @@ impl<P: Package, V: Version> PartialSolution<P, V> {
305293
&self.package_assignments,
306294
store,
307295
);
308-
let satisfier_pa = self.package_assignments.get(&satisfier_package).unwrap();
309-
let satisfier_assignment = if satisfier_index == satisfier_pa.dated_derivations.len() {
310-
match &satisfier_pa.assignments_intersection {
311-
AssignmentsIntersection::Decision((_, version, _)) => Assignment::Decision {
312-
package: satisfier_package,
313-
version: version.clone(),
314-
},
315-
AssignmentsIntersection::Derivations(_) => panic!("Must be a decision"),
316-
}
296+
if previous_satisfier_level < satisfier_decision_level {
297+
let search_result = SatisfierSearch::DifferentDecisionLevels {
298+
previous_satisfier_level,
299+
};
300+
(satisfier_package, search_result)
317301
} else {
302+
let satisfier_pa = self.package_assignments.get(&satisfier_package).unwrap();
318303
let dd = &satisfier_pa.dated_derivations[satisfier_index];
319-
Assignment::Derivation {
320-
package: satisfier_package,
321-
cause: dd.cause,
322-
}
323-
};
324-
(
325-
satisfier_assignment,
326-
satisfier_decision_level,
327-
previous_satisfier_level,
328-
)
304+
let search_result = SatisfierSearch::SameDecisionLevels {
305+
satisfier_cause: dd.cause,
306+
};
307+
(satisfier_package, search_result)
308+
}
329309
}
330310

331311
/// A satisfier is the earliest assignment in partial solution such that the incompatibility

0 commit comments

Comments
 (0)