simon-git: tilings (main): Simon Tatham
Commits to Tartarus hosted VCS
tartarus-commits at lists.tartarus.org
Wed Aug 20 13:01:32 BST 2025
TL;DR:
9952675 Give more detail of mismatches in --check.
86ebf5d Fix overenthusiastic raising of transducer.NonClosure.
64c7d25 Report transducer non-closure more usefully.
3a5d3c6 Allow specifying a base layer when building automata.
5b215c6 Fix bug when adjmatcher is slow to get started.
c8abd6d Generate output tiles for Ammann-Beenker.
Repository: https://git.tartarus.org/simon/tilings.git
On the web: https://git.tartarus.org/?p=simon/tilings.git
Branch updated: main
Committer: Simon Tatham <anakin at pobox.com>
Date: 2025-08-20 13:01:32
commit 995267512b07e2f8143b8a133e058d7cc0acabd4
web diff https://git.tartarus.org/?p=simon/tilings.git;a=commitdiff;h=995267512b07e2f8143b8a133e058d7cc0acabd4;hp=35e22684ea6d8ccc336a2968539c041a51f435b3
Author: Simon Tatham <anakin at pobox.com>
Date: Fri Aug 15 17:21:42 2025 +0100
Give more detail of mismatches in --check.
When identifying the mismatching edges, it's helpful to say the types
of the tiles and edges as well as where in the expansion diagram they
appear.
toplevel.sage | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
commit 86ebf5d518cfd5c9f8ee7532e864d7999684e1c5
web diff https://git.tartarus.org/?p=simon/tilings.git;a=commitdiff;h=86ebf5d518cfd5c9f8ee7532e864d7999684e1c5;hp=995267512b07e2f8143b8a133e058d7cc0acabd4
Author: Simon Tatham <anakin at pobox.com>
Date: Wed Aug 20 09:02:00 2025 +0100
Fix overenthusiastic raising of transducer.NonClosure.
It turns out that ammann-beenker.tl _does_ admit a transducer, and the
only thing making me think it didn't was this bug: check_empty_loops()
was _wrongly_ identifying a case where (it thought) the half-built
transducer DFA had returned to the same state having done nothing but
buffer more output.
I'll quote the transducer.NonClosure exception dump in full. It said:
(
frozenset({
(8, (('triangleplus', 1),)),
(10, (('triangleplus', 0),)),
(19, (('rhombus', 2),)),
(20, (('rhombus', 0),)),
}),
frozenset({
(8, (('rhombus', 0), ('triangleplus', 3))),
(10, (('rhombus', 2), ('triangleplus', 4))),
(19, (('rhombus', 0), ('rhombus', 0))),
(20, (('rhombus', 0), ('rhombus', 1))),
}),
[('rhombus', 1)],
)
The two frozensets correspond to DFA states of the half-built
transducer, and the final list of coordinates (actually just one
coordinate) shows the input that made the DFA transition from one to
the other. The NonClosure exception was thrown because the two
frozensets correspond to the same set of NFA (adjacency matcher)
states, and no output was emitted on the way from one to the other.
The theory is that this means you can just carry on round the cycle
buffering more and more output and not making progress.
But it's not true, in this case, because note that the first symbols
of the buffered output aren't the same. In the first set, we had a
triangleplus buffered in state 8 and a triangleminus in state 10, but
no NFA transition was able to make progress from either, so those
options were _discarded_. So we haven't come back to the same state
with the _same_ output buffered: we discarded some options for what
the first output coordinate might be, and that is progress.
So now we have only two options for the first output symbol: it's
either (rhombus,0) or (rhombus,2). And note that (rhombus,2) is the
one that led to the next symbol being triangleplus, so if we get
another (rhombus,1) symbol, that option will again fail to make
progress, and we'll rule out all possible first output symbols
except (rhombus,0). Hence, another trip round the same cycle _will_
make progress and generate output!
In this patch I adjust vertex_core() â used to identify pairs of DFA
states that look suspiciously similar â to include the first symbol of
the buffered output for each state. Now we avoid throwing that
exception, and the transducer construction for Ammann-Beenker
completes successfully.
toplevel.sage | 2 +-
transducer.sage | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
commit 64c7d25e47cdb5797373e689f43540a89866d1d3
web diff https://git.tartarus.org/?p=simon/tilings.git;a=commitdiff;h=64c7d25e47cdb5797373e689f43540a89866d1d3;hp=86ebf5d518cfd5c9f8ee7532e864d7999684e1c5
Author: Simon Tatham <anakin at pobox.com>
Date: Wed Aug 20 12:38:49 2025 +0100
Report transducer non-closure more usefully.
Now, in --transducer mode, we actually catch the transducer.NonClosure
exception, and print a dump of the details in a more legible format
than a repr() of a Python tuple.
Also, we don't just print the details previously stored in the
exception object. I've also added a path from the DFA root to the
cycle, so that it's possible to read off the _whole_ coordinate
string that leads to a problem, and all the possible strings it might
be adjacent to.
toplevel.sage | 6 +++++-
transducer.sage | 35 +++++++++++++++++++++++++++++++++--
2 files changed, 38 insertions(+), 3 deletions(-)
commit 3a5d3c6a84c650da70d05d64209f136313c3964c
web diff https://git.tartarus.org/?p=simon/tilings.git;a=commitdiff;h=3a5d3c6a84c650da70d05d64209f136313c3964c;hp=64c7d25e47cdb5797373e689f43540a89866d1d3
Author: Simon Tatham <anakin at pobox.com>
Date: Wed Aug 20 12:43:26 2025 +0100
Allow specifying a base layer when building automata.
args.base_layer was ignored in both --adjmatcher and --transducer
mode. Now it's honoured. This is particularly useful in getting a
useful description of a transducer failure â it saves tracking through
the expansion diagrams of some lower layer (like hats) to figure out
which tile edges are significant at the layer involved in the cycle.
toplevel.sage | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
commit 5b215c65471acf88ccba85916670a7d9b8d73ac0
web diff https://git.tartarus.org/?p=simon/tilings.git;a=commitdiff;h=5b215c65471acf88ccba85916670a7d9b8d73ac0;hp=3a5d3c6a84c650da70d05d64209f136313c3964c
Author: Simon Tatham <anakin at pobox.com>
Date: Wed Aug 20 12:52:23 2025 +0100
Fix bug when adjmatcher is slow to get started.
In a tiling change I'm about to commit, no successful transition _at
all_ can be generated by builder.make_paths(depth=2). So after the
first pass of the loop in am.generate(), we haven't even created a
start state in the NFA yet, and then confusion happens. The easy
solution is to go round again at a higher depth until we do have a
start state.
dsf.py | 2 ++
transducer.sage | 2 ++
2 files changed, 4 insertions(+)
commit c8abd6d094644290dbbae6ac393af977c1e9b1bc
web diff https://git.tartarus.org/?p=simon/tilings.git;a=commitdiff;h=c8abd6d094644290dbbae6ac393af977c1e9b1bc;hp=5b215c65471acf88ccba85916670a7d9b8d73ac0
Author: Simon Tatham <anakin at pobox.com>
Date: Wed Aug 20 12:53:44 2025 +0100
Generate output tiles for Ammann-Beenker.
We _generate_ the tiling using the two half-square tiles triangleplus
and triangleminus, but it's better to glue those back together into a
single square tile for output.
Instead of trying to make this change in the substitution system at
every level, Ã la p2-whole.tl, I've simply redesignated the existing
three-tile system as the 'meta' layer, and introduced 'tiles' below it
which does a one-off mapping in which triangleplus turns into a whole
square and triangleminus turns into nothing at all.
This system still admits a transducer, but only after the bug fix in
the previous commit, which prevented making even an adjacency matcher!
ammann-beenker.tl | 88 +++++++++++++++++++++++++++++++++++++------------------
1 file changed, 59 insertions(+), 29 deletions(-)
More information about the tartarus-commits
mailing list