mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
Solo: remove some overzealous assertions in the solver.
There were a couple of places where we enforced by assertion that our solver state had not become inconsistent, on the assumption that some previous piece of solver would have detected that the puzzle was impossible before getting to that place in the code. But in fact the combination of Killer and Unreasonable modes falsified at least two of those assumptions: 'solo --test-solve --generate 100 3x3kdu#12345' triggered an assertion failure in solver_set, and with that one fixed, the same command triggered a second failure in solver_killer_sums. In both cases, the fix is simply to return -1 for 'puzzle is inconsistent', which will cause the Unreasonable recursive solver to abandon that branch of its search tree, backtrack, and try a different guess at some previous square. Thanks to Anders Höglund for the report.
This commit is contained in:
30
solo.c
30
solo.c
@ -1013,12 +1013,23 @@ static int solver_set(struct solver_usage *usage,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If count == 0, then there's a row with no 1s at all and
|
* If count == 0, then there's a row with no 1s at all and
|
||||||
* the puzzle is internally inconsistent. However, we ought
|
* the puzzle is internally inconsistent.
|
||||||
* to have caught this already during the simpler reasoning
|
|
||||||
* methods, so we can safely fail an assertion if we reach
|
|
||||||
* this point here.
|
|
||||||
*/
|
*/
|
||||||
assert(count > 0);
|
if (count == 0) {
|
||||||
|
#ifdef STANDALONE_SOLVER
|
||||||
|
if (solver_show_working) {
|
||||||
|
va_list ap;
|
||||||
|
printf("%*s", solver_recurse_depth*4,
|
||||||
|
"");
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vprintf(fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
printf(":\n%*s solver_set: impossible on entry\n",
|
||||||
|
solver_recurse_depth*4, "");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (count == 1)
|
if (count == 1)
|
||||||
rowidx[i] = colidx[first] = FALSE;
|
rowidx[i] = colidx[first] = FALSE;
|
||||||
}
|
}
|
||||||
@ -1465,7 +1476,14 @@ static int solver_killer_sums(struct solver_usage *usage, int b,
|
|||||||
assert(nsquares == 0);
|
assert(nsquares == 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
assert(nsquares > 0);
|
if (nsquares == 0) {
|
||||||
|
#ifdef STANDALONE_SOLVER
|
||||||
|
if (solver_show_working)
|
||||||
|
printf("%*skiller: cage has no usable squares left\n",
|
||||||
|
solver_recurse_depth*4, "");
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (nsquares < 2 || nsquares > 4)
|
if (nsquares < 2 || nsquares > 4)
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user