simon-git: tilings (main): Simon Tatham
Commits to Tartarus hosted VCS
tartarus-commits at lists.tartarus.org
Sun Aug 24 09:15:28 BST 2025
TL;DR:
98a2159 Honour --base-layer in --test-recurse mode.
ad2b638 Add a dump method to tilingdef.
f60a100 New --refine mode for making tilings transducer-capable.
9a9e40b Rewrite the refiner using an extendable query list.
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-24 09:15:28
commit 98a21598d610c392f3546e3a5505e6f48345beaa
web diff https://git.tartarus.org/?p=simon/tilings.git;a=commitdiff;h=98a21598d610c392f3546e3a5505e6f48345beaa;hp=e09b7222a7951390970551b195a72d812eb73f13
Author: Simon Tatham <anakin at pobox.com>
Date: Sat Aug 23 08:29:33 2025 +0100
Honour --base-layer in --test-recurse mode.
toplevel.sage | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
commit ad2b638ac17e72124acfc5d0ed796639d4bb0edc
web diff https://git.tartarus.org/?p=simon/tilings.git;a=commitdiff;h=ad2b638ac17e72124acfc5d0ed796639d4bb0edc;hp=98a21598d610c392f3546e3a5505e6f48345beaa
Author: Simon Tatham <anakin at pobox.com>
Date: Sat Aug 23 08:58:00 2025 +0100
Add a dump method to tilingdef.
This turns the internal tiling data structure back into a .tl file, or
at least a best-effort attempt at one. In simple cases the result is
legal Sage syntax and can be fed immediately back into this code. But
in cases where there's a nontrivial algebraic number involved in the
tile edge specifications (e.g. the Ï in the Penrose tilings, the â3 in
hat tile edges, or the â2 in Ammann-Beenker), I haven't found a way to
dump that number in a way that Sage can re-consume. (Shame on you,
Sage, that's what __repr__ is supposed to be for.)
Additionally, if the input tiling was parametrised, the parameters
aren't replicated in the output. So this won't do what you really
wanted in all cases. But it's at least a starting point for
hand-editing. And it will be useful in the shiny new feature coming up
in the next commit.
tilingdef.sage | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 78 insertions(+)
commit f60a100cba73c65e900c6d67bc5aa3499c3674c2
web diff https://git.tartarus.org/?p=simon/tilings.git;a=commitdiff;h=f60a100cba73c65e900c6d67bc5aa3499c3674c2;hp=ad2b638ac17e72124acfc5d0ed796639d4bb0edc
Author: Simon Tatham <anakin at pobox.com>
Date: Sun Aug 24 08:26:34 2025 +0100
New --refine mode for making tilings transducer-capable.
This is a more finished version of the thing I mentioned working on in
commit e09b7222a795139.
The idea is to first clone every tile type into subtypes,
distinguished by their _neighbourhood_ in the tiling, that is, what
type of tile is on the other side of each edge, and which way round it
is. (This isn't self-referential, or iterating to a fixed point: the
new subtypes are distinguished by what _original_ tiles are on the
other side of each edge.)
The motivation is that, in a tiling which doesn't admit a transducer,
there's some infinite supertile boundary with two possibilities for
the far side. So some tile on the near side of the boundary has two
possible immediate neighbours on the far side. Augmenting that tile
with information about which neighbour that is should disambiguate the
possibilities. But we don't know in advance which tiles will be
involved in which supertile boundaries, so we augment every tile with
all its neighbours.
Once you know a tile's subtype, it ought to be possible to work out
the subtypes of all its children. So the original expansion rules can
be refined into the new ones by simply adding subtype information to
each one.
This generates an absurdly large number of tile subtypes. But they can
be reduced again by finding pairs of tile types which have identical
expansion diagrams and re-merging them.
This works well enough that it's able to refine _all_ the tilings
currently in this code's self-test suite which don't already admit a
transducer. I've added that to the test suite to make sure it carries
on working.
(The output of this refinement isn't _proven_ to produce a
substitution system that admits a transducer, however. It's just
worked in every case currently known to this code.)
Moreover, the refinements look pretty tight: I don't have a proof of
minimality, but in cases where we already had a refinement of a
tiling, this at least matches it - hat HTPF becomes exactly my
HHTPFFF, and the Spectre H7/H8 system divides the non-Mystic tile into
8 subtypes to give a 9-tile system exactly corresponding to the 9-hex
system from the Spectre paper.
An even more interesting case is that the hat H7/H8 system refines
into a transducer-capable substitution with only _eight_ tile types in
total. I'd expected 10, matching Bowen Ping and Brad Klee's 10-hex
system, but this code has apparently beaten it! It looks as if the
difference is that it's merged the B,C tiles into one, and G,J into
another. My theory is that this is because, if you stick with hat
shapes instead of trying to simplify to hexes, you don't get a ton of
different edge types with different complicated expansions - and
that's how the B,C hexes differ in the hat10 substitution, and
similarly G,J.
Practicalities: if you just run 'tilings --refine foo.tl', then you
get an infodump on standard output saying which tiles were cloned into
how many subtypes, and giving the missing details of each expansion
diagram. But if you also add '-o output.tl' then the tool will output
an actual file containing the refined tiling, via the dump method
introduced in the previous commit. (So it may still need hand-editing
to be a valid input file, but it avoids having to manually transcribe
all the new expansion rules at least!)
refine.py | 4 +
refine.sage | 269 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
toplevel.sage | 95 +++++++++++++++------
util.sage | 19 +++++
4 files changed, 360 insertions(+), 27 deletions(-)
commit 9a9e40bedfab49f30bd968d543b12987b541312a
web diff https://git.tartarus.org/?p=simon/tilings.git;a=commitdiff;h=9a9e40bedfab49f30bd968d543b12987b541312a;hp=f60a100cba73c65e900c6d67bc5aa3499c3674c2
Author: Simon Tatham <anakin at pobox.com>
Date: Sun Aug 24 08:43:37 2025 +0100
Rewrite the refiner using an extendable query list.
The refinement code in the previous commit was based on the idea that
you classify a tile type into subtypes by asking what (original) tile
type, and what edge of that tile, it's adjacent to along each edge.
Then we use that information to decide on the subtype of every tile in
the expansion of every new subtyped tile.
But that isn't guaranteed to work. If _all_ you know about a supertile
is that it has these immediate neighbours along each edge, it doesn't
necessarily follow that you know the same thing about every subtile.
What if one of the _logical_ immediate neighbours is actually a zero-
thickness spur, and you need to know what's on the far side of that?
Then the answer to "what's on the other edge of this subtile?" might
depend on the type of a supertile _not_ edge-adjacent to the parent.
This rewrite enhances the refiner to cope even in that situation, by
having an extendable list of 'queries' â questions it wants to ask
about a tile before it can decide which subtype it is. Initially the
query list is simply "what's on the other side of each edge?", as
before, but now when we try to answer that question for the child
tiles we notice if we're depending on information not answered by the
current query set, and try again from scratch having appended an extra
query, which will be of the form "If the tile on the other side of
edge N of the original tile was edge M of tile T, then what's on the
other side of edge K of that T?" or perhaps even a second-order
question making yet another step further away from the original tile.
Whenever we discover a new query has to be added to the determination
of tile types, we restart the analysis from the beginning,
reclassifying all tile types using the new query.
In this commit I add a new substitution system 'awkward-squares.tl',
which I designed to be precisely a test case for this: it expands one
square into four squares in what looks like a simple way, but the edge
mappings cause the expanded squares to be in a skew layout, so that
you need to know a supertile's diagonal neighbour to know all its
subtiles' immediate neighbours.
It turns out that the Awkward Squares substitution is more awkward
even than I had guessed, because after the rewritten refiner has
refined it, it _still_ doesn't admit a transducer! But running the
same refinement algorithm a second time _does_ make it admit a
transducer. So I've had to modify the test suite to expect that.
(This isn't a bug in the refinement algorithm, at least by my
definition. Refinement doesn't promise anything about transducers. It
just says "include information in each tile type about its immediate
neighbours". Refining twice has the effect of including information
about the _second_-order neighbours.)
awkward-squares.tl | 39 ++++++++++++
refine.sage | 174 +++++++++++++++++++++++++++++++++++++++--------------
toplevel.sage | 56 ++++++++---------
3 files changed, 192 insertions(+), 77 deletions(-)
More information about the tartarus-commits
mailing list