L-System for Aperiodic Tilings with Hat Monotile

aperiodic-tilingfractalsmg.metric-geometryplane-geometrytiling

Most aperiodic tilings of the plane, except possibly for spiral tilings like the Voderberg tiling, exhibit a fractal pattern of self-similarity. This is no exception for the recently discovered "hat" monotile.

Now, in Figure 2.12 of that paper, reproduced here for convenience,

enter image description here
the union of all tiles which belong to a so-called fylfot enter image description here (the ones colored in gray, or black for that matter) appears to be simply connected and shows a striking similarity to the well known Gosper curve (see for instance the first example here upon scrolling down 2-3 screens), as constructed e.g. by an L-system.

(In a precise sense, we are of course not talking about the fractals themselves, rather about the iterations approximating them. But for both the iterative construction of the hat covering via metatiles and the iterations towards the very Gosper fractal, the steps correspond nicely.)

Look at the following coloring of the two regions separated by the Gosper curve and compare the appearance.
enter image description here

If we imagine the blue part a third wider and the black part a third narrower, the resemblance is even more striking. (Note that up to boundary effects, in the hat tiling on the right, the union of all the dark blue, light blue and white tiles also appears to be a simply connected region with the same "fractal quality" as the black/grey one, topologically equivalent so to say, just twice as "thick".)

All this is to introduce my main question, as I am sure from this that tilings by the hat monotile can also be represented (at least locally) by an L-system, which might in turn provide more information about the nature of the hat tilings.

How to come up with L-system rules to formalize/generate the structure of this pattern?

Note that the two rules for the Gosper curve,

$A=A-B–B+A++AA+B-$
$B=+A-BB–B-A++A+B$

are obtained from each other by reversing and switching everything, which I would of course expect to be similar for the hat tiling pattern.

Best Answer

(a second answer because this one is an answer)

So, I misled myself staring at the H8 in Smith et al. The way to solve this is to look at the F-supertile. That tile has 5 edges, and 4 of them are F-tiles that make up the fractal (at the next expansion level). So if we just ignore other parts of the F-supertile, it will expand to form at least part of the fractal.

The F-tiles surrounding the F-supertile each belong to a fylfot (3 F-tiles). By carefully including those F-tiles as well during the expansion, you get a curve which never draws the same edge twice.

  • $A \to +A[+F]-BA[+F]-C+$
  • $B \to -D+[--F]BA[-F]+B-$
  • $C \to -D+[--F]BA$
  • $D \to BA[+F]-C+$
  • $F \to -D+[--F]BA[-F]+BA[-F]+F$

Where at level 0 symbols $C$ and $D$ are lines 1 unit long, $A$, $B$, and $F$ are lines $\dfrac{\phi}{\sqrt{2}}$ long, $-$ and $+$ are left and right turns by $\dfrac{\pi}{3}$, $[$ is stack push, and $]$ is stack pop.

Running code: https://trinket.io/python/df6f9fa4db

import turtle
import math

# use the simpler 'Golden Key' f-tile from
# Socolar, 'Quasicrystalline structure of the Smith monotile tilings'
# https://arxiv.org/pdf/2305.01174.pdf
phi = (1 + math.sqrt(5))/2
root2 = math.sqrt(2)

def expand(order, a, stack, s0, s1):
  for op in s0 if order <= 0 else s1:
    mono_op_map[op](order - 1, a, stack)    
    
def op_push(stack):
  stack.append([turtle.pos(), turtle.heading()])
  
def op_pop(stack):
  pos, hd = stack.pop()
  turtle.up()
  turtle.setpos(pos)
  turtle.setheading(hd)
  turtle.down()

# The F-supertile in Smith et al has 5 sides, 4 of which are F-tiles.
# to get an L-system for the F-tile fractal, we just expand those.
# Choosing rules carefully avoids repeating any edge.
mono_op_map = {
  "a": lambda o, a, s: turtle.forward(a*phi/root2),
  "b": lambda o, a, s: turtle.forward(a),
  "A": lambda o, a, s: expand(o, a, s, "a", "+A[+F]-BA[+F]-C+"),
  "B": lambda o, a, s: expand(o, a, s, "a", "-D+[--F]BA[-F]+B-"),
  "C": lambda o, a, s: expand(o, a, s, "b", "-D+[--F]BA"),
  "D": lambda o, a, s: expand(o, a, s, "b", "BA[+F]-C+"),
  # A free edge from a fylfot, allowed to branch everywhere.
  # Use 'B' instead of 'F' above to get a sponge.
  "F": lambda o, a, s: expand(o, a, s, "a", "-D+[--F]BA[-F]+BA[-F]+F"),
  "+": lambda o, a, s: turtle.right(60),
  "-": lambda o, a, s: turtle.left(60),
  "[": lambda o, a, s: op_push(s),
  "]": lambda o, a, s: op_pop(s),
}
stack = []
start = "A"
order = 6
size = 70/(order*order)
turtle.speed("fastest")
# this system is super slow, disable animation entirely
#turtle.hideturtle()
turtle.tracer(0, 0)
expand(order, size, stack, start, start)
turtle.update()

F-supertile from Smith et al Generated curve

Related Question