[CSStep] Conjunction: Propagate fix and hole scores to outer solution

While producing a combined solution, let's reflect the number of
fixes and holes discovered in the conjunction, that way it would
be possible to filter solutions and keep track of the fact that
there were issues in the conjunction.
This commit is contained in:
Pavel Yaskevich
2022-05-12 17:51:43 -07:00
committed by Pavel Yaskevich
parent dfadee3731
commit 4debf30f58
2 changed files with 36 additions and 19 deletions

View File

@@ -942,13 +942,10 @@ StepResult ConjunctionStep::resume(bool prevFailed) {
// and scoring information.
Snapshot.reset();
// Restore original scores of outer context before
// trying to produce a combined solution.
restoreOriginalScores();
// Apply all of the information deduced from the
// conjunction (up to the point of ambiguity)
// back to the outer context and form a joined solution.
unsigned numSolutions = 0;
for (auto &solution : Solutions) {
ConstraintSystem::SolverScope scope(CS);
@@ -958,34 +955,47 @@ StepResult ConjunctionStep::resume(bool prevFailed) {
// of the constraint system, so they have to be
// restored right afterwards because score of the
// element does contribute to the overall score.
restoreOriginalScores();
restoreBestScore();
restoreCurrentScore(solution.getFixedScore());
// Transform all of the unbound outer variables into
// placeholders since we are not going to solve for
// each ambguous solution.
for (auto *typeVar : CS.getTypeVariables()) {
if (!typeVar->getImpl().hasRepresentativeOrFixed()) {
CS.assignFixedType(
typeVar, PlaceholderType::get(CS.getASTContext(), typeVar));
{
unsigned numHoles = 0;
for (auto *typeVar : CS.getTypeVariables()) {
if (!typeVar->getImpl().hasRepresentativeOrFixed()) {
CS.assignFixedType(
typeVar, PlaceholderType::get(CS.getASTContext(), typeVar));
++numHoles;
}
}
CS.increaseScore(SK_Hole, numHoles);
}
if (CS.worseThanBestSolution())
continue;
// Note that `worseThanBestSolution` isn't checked
// here because `Solutions` were pre-filtered, and
// outer score is the same for all of them.
OuterSolutions.push_back(CS.finalize());
++numSolutions;
}
return done(/*isSuccess=*/true);
return done(/*isSuccess=*/numSolutions > 0);
}
auto solution = Solutions.pop_back_val();
auto score = solution.getFixedScore();
// Restore outer type variables and prepare to solve
// constraints associated with outer context together
// with information deduced from the conjunction.
Snapshot->setupOuterContext(Solutions.pop_back_val());
Snapshot->setupOuterContext(std::move(solution));
// Pretend that conjunction never happened.
restoreOuterState();
restoreOuterState(score);
// Now that all of the information from the conjunction has
// been applied, let's attempt to solve the outer scope.
@@ -997,10 +1007,11 @@ StepResult ConjunctionStep::resume(bool prevFailed) {
return take(prevFailed);
}
void ConjunctionStep::restoreOuterState() const {
void ConjunctionStep::restoreOuterState(const Score &solutionScore) const {
// Restore best/current score, since upcoming step is going to
// work with outer scope in relation to the conjunction.
restoreOriginalScores();
restoreBestScore();
restoreCurrentScore(solutionScore);
// Active all of the previously out-of-scope constraints
// because conjunction can propagate type information up