Skip to content

Commit b032df6

Browse files
committed
Use combine_with_priorities when combining answers from cycles as well
1 parent 77f262f commit b032df6

File tree

1 file changed

+47
-26
lines changed

1 file changed

+47
-26
lines changed

chalk-solve/src/recursive.rs

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -294,28 +294,25 @@ impl<'me, I: Interner> Solver<'me, I> {
294294
return *minimums;
295295
}
296296

297+
let old_answer = &self.context.search_graph[dfn].solution;
298+
let old_prio = self.context.search_graph[dfn].solution_priority;
299+
300+
let (current_answer, current_prio) = combine_with_priorities_for_goal(
301+
self.program.interner(),
302+
&canonical_goal.canonical.value.goal,
303+
old_answer.clone(),
304+
old_prio,
305+
current_answer,
306+
current_prio,
307+
);
308+
297309
// Some of our subgoals depended on us. We need to re-run
298310
// with the current answer.
299311
if self.context.search_graph[dfn].solution == current_answer {
300312
// Reached a fixed point.
301313
return *minimums;
302314
}
303315

304-
if (
305-
self.context.search_graph[dfn].solution_priority,
306-
current_prio,
307-
) == (ClausePriority::High, ClausePriority::Low)
308-
&& self.context.search_graph[dfn].solution.is_ok()
309-
{
310-
// TODO check solution inputs?
311-
// Not replacing the current answer, so we're at a fixed point?
312-
debug!(
313-
"solve_new_subgoal: new answer has lower priority (old answer: {:?})",
314-
self.context.search_graph[dfn].solution
315-
);
316-
return *minimums;
317-
}
318-
319316
let current_answer_is_ambig = match &current_answer {
320317
Ok(s) => s.is_ambig(),
321318
Err(_) => false,
@@ -378,7 +375,7 @@ impl<'me, I: Interner> Solver<'me, I> {
378375
None => (solution, priority),
379376
Some((cur, cur_priority)) => combine_with_priorities(
380377
self.program.interner(),
381-
canonical_goal,
378+
&canonical_goal.canonical.value.goal,
382379
cur,
383380
cur_priority,
384381
solution,
@@ -397,7 +394,7 @@ impl<'me, I: Interner> Solver<'me, I> {
397394
None => (solution, priority),
398395
Some((cur, cur_priority)) => combine_with_priorities(
399396
self.program.interner(),
400-
canonical_goal,
397+
&canonical_goal.canonical.value.goal,
401398
cur,
402399
cur_priority,
403400
solution,
@@ -466,23 +463,47 @@ impl<'me, I: Interner> Solver<'me, I> {
466463

467464
fn calculate_inputs<I: Interner>(
468465
interner: &I,
469-
canonical_goal: &UCanonical<InEnvironment<DomainGoal<I>>>,
466+
domain_goal: &DomainGoal<I>,
470467
solution: &Solution<I>,
471468
) -> Vec<Parameter<I>> {
472469
if let Some(subst) = solution.constrained_subst() {
473-
let subst_goal = subst
474-
.value
475-
.subst
476-
.apply(&canonical_goal.canonical.value.goal, interner);
470+
let subst_goal = subst.value.subst.apply(&domain_goal, interner);
477471
subst_goal.inputs(interner)
478472
} else {
479-
canonical_goal.canonical.value.goal.inputs(interner)
473+
domain_goal.inputs(interner)
474+
}
475+
}
476+
477+
fn combine_with_priorities_for_goal<I: Interner>(
478+
interner: &I,
479+
goal: &Goal<I>,
480+
a: Fallible<Solution<I>>,
481+
prio_a: ClausePriority,
482+
b: Fallible<Solution<I>>,
483+
prio_b: ClausePriority,
484+
) -> (Fallible<Solution<I>>, ClausePriority) {
485+
let domain_goal = match goal.data(interner) {
486+
GoalData::DomainGoal(domain_goal) => domain_goal,
487+
_ => {
488+
// non-domain goals currently have no priorities, so we always take the new solution here
489+
return (b, prio_b);
490+
}
491+
};
492+
match (a, b) {
493+
(Ok(a), Ok(b)) => {
494+
let (solution, prio) =
495+
combine_with_priorities(interner, domain_goal, a, prio_a, b, prio_b);
496+
(Ok(solution), prio)
497+
}
498+
(Ok(solution), Err(_)) => (Ok(solution), prio_a),
499+
(Err(_), Ok(solution)) => (Ok(solution), prio_b),
500+
(Err(_), Err(e)) => (Err(e), prio_b),
480501
}
481502
}
482503

483504
fn combine_with_priorities<I: Interner>(
484505
interner: &I,
485-
canonical_goal: &UCanonical<InEnvironment<DomainGoal<I>>>,
506+
domain_goal: &DomainGoal<I>,
486507
a: Solution<I>,
487508
prio_a: ClausePriority,
488509
b: Solution<I>,
@@ -491,8 +512,8 @@ fn combine_with_priorities<I: Interner>(
491512
match (prio_a, prio_b, a, b) {
492513
(ClausePriority::High, ClausePriority::Low, higher, lower)
493514
| (ClausePriority::Low, ClausePriority::High, lower, higher) => {
494-
let inputs_higher = calculate_inputs(interner, canonical_goal, &higher);
495-
let inputs_lower = calculate_inputs(interner, canonical_goal, &lower);
515+
let inputs_higher = calculate_inputs(interner, domain_goal, &higher);
516+
let inputs_lower = calculate_inputs(interner, domain_goal, &lower);
496517
if inputs_higher == inputs_lower {
497518
debug!(
498519
"preferring solution: {:?} over {:?} because of higher prio",

0 commit comments

Comments
 (0)