Skip to content

Commit 2ca8446

Browse files
authored
refactor: satisfier search in a helper method (#97)
1 parent 19312b5 commit 2ca8446

File tree

1 file changed

+57
-79
lines changed

1 file changed

+57
-79
lines changed

src/internal/partial_solution.rs

Lines changed: 57 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -325,45 +325,10 @@ impl<P: Package, V: Version> PartialSolution<P, V> {
325325
let mut satisfied = SmallMap::Empty;
326326
for (package, incompat_term) in incompat.iter() {
327327
let pa = package_assignments.get(package).expect("Must exist");
328-
// Term where we accumulate intersections until incompat_term is satisfied.
329-
let mut accum_term = Term::any();
330-
// Indicate if we found a satisfier in the list of derivations, otherwise it will be the decision.
331-
let mut derivation_satisfier_index = None;
332-
for (idx, dated_derivation) in pa.dated_derivations.iter().enumerate() {
333-
let this_term = store[dated_derivation.cause].get(package).unwrap().negate();
334-
accum_term = accum_term.intersection(&this_term);
335-
if accum_term.subset_of(incompat_term) {
336-
// We found the derivation causing satisfaction.
337-
derivation_satisfier_index = Some((
338-
idx,
339-
dated_derivation.global_index,
340-
dated_derivation.decision_level,
341-
));
342-
break;
343-
}
344-
}
345-
match derivation_satisfier_index {
346-
Some(indices) => {
347-
satisfied.insert(package.clone(), indices);
348-
}
349-
// If it wasn't found in the derivations,
350-
// it must be the decision which is last (if called in the right context).
351-
None => match pa.assignments_intersection {
352-
AssignmentsIntersection::Decision((global_index, _, _)) => {
353-
satisfied.insert(
354-
package.clone(),
355-
(
356-
pa.dated_derivations.len(),
357-
global_index,
358-
pa.highest_decision_level,
359-
),
360-
);
361-
}
362-
AssignmentsIntersection::Derivations(_) => {
363-
panic!("This must be a decision")
364-
}
365-
},
366-
};
328+
satisfied.insert(
329+
package.clone(),
330+
pa.satisfier(package, incompat_term, Term::any(), store),
331+
);
367332
}
368333
satisfied
369334
}
@@ -380,51 +345,26 @@ impl<P: Package, V: Version> PartialSolution<P, V> {
380345
) -> DecisionLevel {
381346
// First, let's retrieve the previous derivations and the initial accum_term.
382347
let satisfier_pa = package_assignments.get(satisfier_package).unwrap();
383-
let (satisfier_index, ref mut _satisfier_global_idx, ref mut _satisfier_decision_level) =
384-
satisfied_map.get_mut(satisfier_package).unwrap();
385-
// *satisfier_global_idx = 0; // Changes behavior
386-
// *satisfier_decision_level = DecisionLevel(0); // Changes behavior
387-
388-
let (previous_derivations, mut accum_term) =
389-
if *satisfier_index == satisfier_pa.dated_derivations.len() {
390-
match &satisfier_pa.assignments_intersection {
391-
AssignmentsIntersection::Derivations(_) => panic!("must be a decision"),
392-
AssignmentsIntersection::Decision((_, _, term)) => {
393-
(satisfier_pa.dated_derivations.as_slice(), term.clone())
394-
}
395-
}
396-
} else {
397-
let dd = &satisfier_pa.dated_derivations[*satisfier_index];
398-
(
399-
&satisfier_pa.dated_derivations[..=*satisfier_index], // [..satisfier_idx] to change behavior
400-
store[dd.cause].get(satisfier_package).unwrap().negate(),
401-
)
402-
};
348+
let (satisfier_index, _gidx, _dl) = satisfied_map.get_mut(satisfier_package).unwrap();
349+
350+
let accum_term = if *satisfier_index == satisfier_pa.dated_derivations.len() {
351+
match &satisfier_pa.assignments_intersection {
352+
AssignmentsIntersection::Derivations(_) => panic!("must be a decision"),
353+
AssignmentsIntersection::Decision((_, _, term)) => term.clone(),
354+
}
355+
} else {
356+
let dd = &satisfier_pa.dated_derivations[*satisfier_index];
357+
store[dd.cause].get(satisfier_package).unwrap().negate()
358+
};
403359

404360
let incompat_term = incompat
405361
.get(satisfier_package)
406362
.expect("satisfier package not in incompat");
407363

408-
for (idx, dated_derivation) in previous_derivations.iter().enumerate() {
409-
// Check if that incompat term is satisfied by our accumulated terms intersection.
410-
let this_term = store[dated_derivation.cause]
411-
.get(satisfier_package)
412-
.unwrap()
413-
.negate();
414-
accum_term = accum_term.intersection(&this_term);
415-
// Check if we have found the satisfier
416-
if accum_term.subset_of(incompat_term) {
417-
satisfied_map.insert(
418-
satisfier_package.clone(),
419-
(
420-
idx,
421-
dated_derivation.global_index,
422-
dated_derivation.decision_level,
423-
),
424-
);
425-
break;
426-
}
427-
}
364+
satisfied_map.insert(
365+
satisfier_package.clone(),
366+
satisfier_pa.satisfier(satisfier_package, incompat_term, accum_term, store),
367+
);
428368

429369
// Finally, let's identify the decision level of that previous satisfier.
430370
let (_, &(_, _, decision_level)) = satisfied_map
@@ -435,6 +375,44 @@ impl<P: Package, V: Version> PartialSolution<P, V> {
435375
}
436376
}
437377

378+
impl<P: Package, V: Version> PackageAssignments<P, V> {
379+
fn satisfier(
380+
&self,
381+
package: &P,
382+
incompat_term: &Term<V>,
383+
start_term: Term<V>,
384+
store: &Arena<Incompatibility<P, V>>,
385+
) -> (usize, u32, DecisionLevel) {
386+
// Term where we accumulate intersections until incompat_term is satisfied.
387+
let mut accum_term = start_term;
388+
// Indicate if we found a satisfier in the list of derivations, otherwise it will be the decision.
389+
for (idx, dated_derivation) in self.dated_derivations.iter().enumerate() {
390+
let this_term = store[dated_derivation.cause].get(package).unwrap().negate();
391+
accum_term = accum_term.intersection(&this_term);
392+
if accum_term.subset_of(incompat_term) {
393+
// We found the derivation causing satisfaction.
394+
return (
395+
idx,
396+
dated_derivation.global_index,
397+
dated_derivation.decision_level,
398+
);
399+
}
400+
}
401+
// If it wasn't found in the derivations,
402+
// it must be the decision which is last (if called in the right context).
403+
match self.assignments_intersection {
404+
AssignmentsIntersection::Decision((global_index, _, _)) => (
405+
self.dated_derivations.len(),
406+
global_index,
407+
self.highest_decision_level,
408+
),
409+
AssignmentsIntersection::Derivations(_) => {
410+
panic!("This must be a decision")
411+
}
412+
}
413+
}
414+
}
415+
438416
impl<V: Version> AssignmentsIntersection<V> {
439417
/// Returns the term intersection of all assignments (decision included).
440418
fn term(&self) -> &Term<V> {

0 commit comments

Comments
 (0)