<feed xmlns='http://www.w3.org/2005/Atom'>
<title>puzzles/unfinished, branch rockbox</title>
<subtitle>My sgt-puzzles tree</subtitle>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/'/>
<entry>
<title>Add method for frontends to query the backend's cursor location.</title>
<updated>2020-12-07T19:40:06+00:00</updated>
<author>
<name>Franklin Wei</name>
<email>franklin@rockbox.org</email>
</author>
<published>2020-07-07T02:06:30+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=78bc9ea7f79f379634f822d5f95242900f5716b9'/>
<id>78bc9ea7f79f379634f822d5f95242900f5716b9</id>
<content type='text'>
The Rockbox frontend allows games to be displayed in a "zoomed-in"
state targets with small displays. Currently we use a modal interface
-- a "viewing" mode in which the cursor keys are used to pan around
the rendered bitmap; and an "interaction" mode that actually sends
keys to the game.

This commit adds a midend_get_cursor_location() function to allow the
frontend to retrieve the backend's cursor location or other "region of
interest" -- such as the player location in Cube or Inertia.

With this information, the Rockbox frontend can now intelligently
follow the cursor around in the zoomed-in state, eliminating the need
for a modal interface.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The Rockbox frontend allows games to be displayed in a "zoomed-in"
state targets with small displays. Currently we use a modal interface
-- a "viewing" mode in which the cursor keys are used to pan around
the rendered bitmap; and an "interaction" mode that actually sends
keys to the game.

This commit adds a midend_get_cursor_location() function to allow the
frontend to retrieve the backend's cursor location or other "region of
interest" -- such as the player location in Cube or Inertia.

With this information, the Rockbox frontend can now intelligently
follow the cursor around in the zoomed-in state, eliminating the need
for a modal interface.
</pre>
</div>
</content>
</entry>
<entry>
<title>Group: fix assertion failure in Unreasonable generation.</title>
<updated>2020-06-09T13:38:33+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2020-06-09T13:22:31+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=9aa7b7cdfb2bcd200f45941a58d6ae698882a2d4'/>
<id>9aa7b7cdfb2bcd200f45941a58d6ae698882a2d4</id>
<content type='text'>
Generating the game id 6dui#12345 would cause an assertion failure in
a call to latin_solver_place that should never have happened in the
first place, because the "return -1" that ought to have prevented it
was accidentally inside #ifdef STANDALONE_SOLVER.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Generating the game id 6dui#12345 would cause an assertion failure in
a call to latin_solver_place that should never have happened in the
first place, because the "return -1" that ought to have prevented it
was accidentally inside #ifdef STANDALONE_SOLVER.
</pre>
</div>
</content>
</entry>
<entry>
<title>Group: hard-mode identity deduction.</title>
<updated>2020-05-23T08:08:25+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2020-05-22T17:57:15+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=6285c44610cda5146b11fb1fcda45e488a5504de'/>
<id>6285c44610cda5146b11fb1fcda45e488a5504de</id>
<content type='text'>
This fills in the deduction feature I mentioned in commit 7acc554805,
of determining the identity by elimination, having ruled out all other
candidates.

In fact, it goes further: as soon as we know that an element can't be
the group identity, we rule out every possible entry in its row and
column which would involve it acting as a left- or right-identity for
any individual element.

This noticeably increases the number of puzzles that can be solved at
Hard mode without resorting to Unreasonable-level recursion. In a test
of 100 Hard puzzles generated with this change, 80 of them are
reported as Unreasonable by the previous solver.

(One of those puzzles is 12i:m12b9a1zd9i6d10c3y2l11q4r , the example
case that exposed the latin.c validation bug described by the previous
two commits. That was reported as ambiguous with the validation bug,
as Unreasonable with the validation bug fixed, and now it's merely
Hard, because this identity-based deduction eliminates the need for
recursion.)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This fills in the deduction feature I mentioned in commit 7acc554805,
of determining the identity by elimination, having ruled out all other
candidates.

In fact, it goes further: as soon as we know that an element can't be
the group identity, we rule out every possible entry in its row and
column which would involve it acting as a left- or right-identity for
any individual element.

This noticeably increases the number of puzzles that can be solved at
Hard mode without resorting to Unreasonable-level recursion. In a test
of 100 Hard puzzles generated with this change, 80 of them are
reported as Unreasonable by the previous solver.

(One of those puzzles is 12i:m12b9a1zd9i6d10c3y2l11q4r , the example
case that exposed the latin.c validation bug described by the previous
two commits. That was reported as ambiguous with the validation bug,
as Unreasonable with the validation bug fixed, and now it's merely
Hard, because this identity-based deduction eliminates the need for
recursion.)
</pre>
</div>
</content>
</entry>
<entry>
<title>Group: fill in the latin.c validator function.</title>
<updated>2020-05-23T08:08:08+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2020-05-23T07:41:43+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=31cb5227e6df543a077910d0f3e7c7e169e7c01e'/>
<id>31cb5227e6df543a077910d0f3e7c7e169e7c01e</id>
<content type='text'>
This actually fixes the example game id mentioned in the previous
commit. Now 12i:m12b9a1zd9i6d10c3y2l11q4r is reported as Unreasonable
rather than ambiguous, on the basis that although the solver still
recurses and finds two filled grids, the validator throws out the
nonsense one at the last minute, leaving only one that's actually
legal.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This actually fixes the example game id mentioned in the previous
commit. Now 12i:m12b9a1zd9i6d10c3y2l11q4r is reported as Unreasonable
rather than ambiguous, on the basis that although the solver still
recurses and finds two filled grids, the validator throws out the
nonsense one at the last minute, leaving only one that's actually
legal.
</pre>
</div>
</content>
</entry>
<entry>
<title>latin.c: call a user-provided validator function. [NFC]</title>
<updated>2020-05-23T08:08:08+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2020-05-23T07:34:58+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=f21d3e4c74b23380f397a7ee0416928ee971a15d'/>
<id>f21d3e4c74b23380f397a7ee0416928ee971a15d</id>
<content type='text'>
I've only just realised that there's a false-positive bug in the
latin.c solver framework.

It's designed to solve puzzles in which the solution is a latin square
but with some additional constraints provided by the individual
puzzle, and so during solving, it runs a mixture of its own standard
deduction functions that apply to any latin-square puzzle and extra
functions provided by the client puzzle to do deductions based on the
extra clues or constraints.

But what happens if the _last_ move in the solving process is
performed by one of the latin.c built-in methods, and it causes a
violation of the client puzzle's extra constraints? Nothing will ever
notice, and so the solver will report that the puzzle has a solution
when it actually has none.

An example is the Group game id 12i:m12b9a1zd9i6d10c3y2l11q4r . This
was reported by 'groupsolver -g' as being ambiguous. But if you look
at the two 'solutions' reported in the verbose diagnostics, one of
them is arrant nonsense: it has no identity element at all, and
therefore, it fails associativity all over the place. Actually that
puzzle _does_ have a unique solution.

This bug has been around for ages, and nobody has reported a problem.
For recursive solving, that's not much of a surprise, because it would
cause a spurious accusation of ambiguity, so that at generation time
some valid puzzles would be wrongly discarded, and you'd never see
them. But at non-recursive levels, I can't see a reason why this bug
_couldn't_ have led one of the games to present an actually impossible
puzzle believing it to be soluble.

Possibly this never came up because the other clients of latin.c are
more forgiving of this error in some way. For example, they might all
be very likely to use their extra clues early in the solving process,
so that the requirements are already baked in by the time the final
grid square is filled. I don't know!

Anyway. The fix is to introduce last-minute client-side validation:
whenever the centralised latin_solver thinks it's come up with a
filled grid, it should present it to a puzzle-specific validator
function and check that it's _really_ a legal solution.

This commit does the plumbing for all of that: it introduces the new
validator function as one of the many parameters to latin_solver, and
arranges to call it in an appropriate way during the solving process.
But all the per-puzzle validation functions are empty, for the moment.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
I've only just realised that there's a false-positive bug in the
latin.c solver framework.

It's designed to solve puzzles in which the solution is a latin square
but with some additional constraints provided by the individual
puzzle, and so during solving, it runs a mixture of its own standard
deduction functions that apply to any latin-square puzzle and extra
functions provided by the client puzzle to do deductions based on the
extra clues or constraints.

But what happens if the _last_ move in the solving process is
performed by one of the latin.c built-in methods, and it causes a
violation of the client puzzle's extra constraints? Nothing will ever
notice, and so the solver will report that the puzzle has a solution
when it actually has none.

An example is the Group game id 12i:m12b9a1zd9i6d10c3y2l11q4r . This
was reported by 'groupsolver -g' as being ambiguous. But if you look
at the two 'solutions' reported in the verbose diagnostics, one of
them is arrant nonsense: it has no identity element at all, and
therefore, it fails associativity all over the place. Actually that
puzzle _does_ have a unique solution.

This bug has been around for ages, and nobody has reported a problem.
For recursive solving, that's not much of a surprise, because it would
cause a spurious accusation of ambiguity, so that at generation time
some valid puzzles would be wrongly discarded, and you'd never see
them. But at non-recursive levels, I can't see a reason why this bug
_couldn't_ have led one of the games to present an actually impossible
puzzle believing it to be soluble.

Possibly this never came up because the other clients of latin.c are
more forgiving of this error in some way. For example, they might all
be very likely to use their extra clues early in the solving process,
so that the requirements are already baked in by the time the final
grid square is filled. I don't know!

Anyway. The fix is to introduce last-minute client-side validation:
whenever the centralised latin_solver thinks it's come up with a
filled grid, it should present it to a puzzle-specific validator
function and check that it's _really_ a legal solution.

This commit does the plumbing for all of that: it introduces the new
validator function as one of the many parameters to latin_solver, and
arranges to call it in an appropriate way during the solving process.
But all the per-puzzle validation functions are empty, for the moment.
</pre>
</div>
</content>
</entry>
<entry>
<title>groupsolver: show working when using -v on ambiguous puzzles.</title>
<updated>2020-05-22T18:01:52+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2020-05-22T18:00:01+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=8629ef8974aa379e578531c4b75ebe8c045286c8'/>
<id>8629ef8974aa379e578531c4b75ebe8c045286c8</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Group: fix loop bounds in the solver.</title>
<updated>2020-05-20T20:02:04+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2020-05-19T20:02:50+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=7acc554805a471103bef0a74e4d64fef945dddb9'/>
<id>7acc554805a471103bef0a74e4d64fef945dddb9</id>
<content type='text'>
Applications of the associativity rule were iterating over only n-1 of
the group elements, because I started the loops at 1 rather than 0. So
the solver was a bit underpowered, and would have had trouble with
some perfectly good unambiguous game ids such as 6i:2a5i4a6a1s .

(The latin.c system is very confusing for this, because for historical
reasons due to its ancestry in Solo, grid coordinates run from 0 to
n-1 inclusive, but grid _contents_ run from 1 to n, using 0 as the
'unknown' value. So there's a constant risk of getting confused as to
which kind of value you're dealing with.)

This solver weakness only affects puzzles in 'identity hidden' mode,
because in normal mode, the omitted row and column are those of the
group identity, and applications of associativity involving the
identity never generate anything interesting.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Applications of the associativity rule were iterating over only n-1 of
the group elements, because I started the loops at 1 rather than 0. So
the solver was a bit underpowered, and would have had trouble with
some perfectly good unambiguous game ids such as 6i:2a5i4a6a1s .

(The latin.c system is very confusing for this, because for historical
reasons due to its ancestry in Solo, grid coordinates run from 0 to
n-1 inclusive, but grid _contents_ run from 1 to n, using 0 as the
'unknown' value. So there's a constant risk of getting confused as to
which kind of value you're dealing with.)

This solver weakness only affects puzzles in 'identity hidden' mode,
because in normal mode, the omitted row and column are those of the
group identity, and applications of associativity involving the
identity never generate anything interesting.
</pre>
</div>
</content>
</entry>
<entry>
<title>Group: add a special deduction about the group identity.</title>
<updated>2020-05-20T20:02:04+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2020-05-19T20:02:36+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=432590a05c17b8220efb97ffa038120f1102f5d8'/>
<id>432590a05c17b8220efb97ffa038120f1102f5d8</id>
<content type='text'>
In identity-hidden mode, as soon as you find any table entry that
matches the element indexing its row or column (i.e. a product of
group elements of the form ab=a or ab=b), then you immediately know
which element is the group identity, and you can fill in the rest of
its row and column trivially.

But the Group solver was not actually able to do this deduction.
Proof: it couldn't solve the game id 4i:1d1d1d1, which is trivial if
you take this into account. (a^2=a, so a is the identity, and once you
fill in ax=xa=x for all x, the rest of the grid is forced.)

So I've added dedicated piece of logic to spot the group identity as
soon as anything in its row and column is filled in. Now that puzzle
can be solved.

(A thing that I _haven't_ done here is the higher-level deduction of
determining the identity by elimination. Any table entry that
_doesn't_ match either its row or column rules out both the row and
the column from being the group identity - so as soon as you have
enough table entries to rule out all but one element, you know the
identity must be the remaining one. At the moment, this is just doing
the simple version of the deduction where a single table entry tells
you what _is_ the identity.)

One slightly tricky part is that because this new identity inference
deduction fills in multiple grid entries at a time, it has to be
careful to avoid triggering an assertion failure if the puzzle is
inconsistent - before filling in each entry, it has to make sure the
value it wants to fill in has not been ruled out by something it
filled in already. Without that care, an insoluble puzzle can cause
the solver to crash - and worse, the same can happen on an insoluble
_branch_ of the guesswork-and-backtracking tree in Unreasonable mode.
In both cases, the answer is to make sure you detect the problem
before hitting the assertion, and return -1 for 'inconsistent puzzle'
if you spot it. Then any guesswork branch that ends up in this
situation is cleanly abandoned, and we move on to another one.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In identity-hidden mode, as soon as you find any table entry that
matches the element indexing its row or column (i.e. a product of
group elements of the form ab=a or ab=b), then you immediately know
which element is the group identity, and you can fill in the rest of
its row and column trivially.

But the Group solver was not actually able to do this deduction.
Proof: it couldn't solve the game id 4i:1d1d1d1, which is trivial if
you take this into account. (a^2=a, so a is the identity, and once you
fill in ax=xa=x for all x, the rest of the grid is forced.)

So I've added dedicated piece of logic to spot the group identity as
soon as anything in its row and column is filled in. Now that puzzle
can be solved.

(A thing that I _haven't_ done here is the higher-level deduction of
determining the identity by elimination. Any table entry that
_doesn't_ match either its row or column rules out both the row and
the column from being the group identity - so as soon as you have
enough table entries to rule out all but one element, you know the
identity must be the remaining one. At the moment, this is just doing
the simple version of the deduction where a single table entry tells
you what _is_ the identity.)

One slightly tricky part is that because this new identity inference
deduction fills in multiple grid entries at a time, it has to be
careful to avoid triggering an assertion failure if the puzzle is
inconsistent - before filling in each entry, it has to make sure the
value it wants to fill in has not been ruled out by something it
filled in already. Without that care, an insoluble puzzle can cause
the solver to crash - and worse, the same can happen on an insoluble
_branch_ of the guesswork-and-backtracking tree in Unreasonable mode.
In both cases, the answer is to make sure you detect the problem
before hitting the assertion, and return -1 for 'inconsistent puzzle'
if you spot it. Then any guesswork branch that ends up in this
situation is cleanly abandoned, and we move on to another one.
</pre>
</div>
</content>
</entry>
<entry>
<title>unfinished/path: some jottings towards a solver.</title>
<updated>2020-05-12T21:05:52+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2020-05-12T21:05:52+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=c9b3c3896ca54681d03bd6c25e433affd9809860'/>
<id>c9b3c3896ca54681d03bd6c25e433affd9809860</id>
<content type='text'>
I still don't actually have a solver design, but a recent conversation
sent my brain in some more useful directions than I've come up with
before, so I might as well at least note it all down.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
I still don't actually have a solver design, but a recent conversation
sent my brain in some more useful directions than I've come up with
before, so I might as well at least note it all down.
</pre>
</div>
</content>
</entry>
<entry>
<title>Unruly, Group: reference-count the 'immutable' array.</title>
<updated>2018-11-13T21:58:14+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2018-11-13T21:58:14+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=47cec547e59ac8c5012f6091394dcb4304d64fc3'/>
<id>47cec547e59ac8c5012f6091394dcb4304d64fc3</id>
<content type='text'>
I noticed this during the bool trawl: both of these games have an
array of flags indicating which grid squares are immutable starting
clues, and copy it in every call to dup_game, which is completely
unnecessary because it doesn't change during play. So now each one
lives in a reference-counted structure, as per my usual practice in
similar cases elsewhere.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
I noticed this during the bool trawl: both of these games have an
array of flags indicating which grid squares are immutable starting
clues, and copy it in every call to dup_game, which is completely
unnecessary because it doesn't change during play. So now each one
lives in a reference-counted structure, as per my usual practice in
similar cases elsewhere.
</pre>
</div>
</content>
</entry>
</feed>
