Add full medial tire graph generator and n=9 atlas

Name A(T) the "annular cycle" (Thm 3.3, Def 3.4); clarify the bite-face
condition in Remark 3.8 to count down-tooth apexes interior to each face;
add the non-incidence stipulation for bite edges to Def 3.7.

Add an exhaustive generator over |A(T)| enforcing the 3.1-3.9 properties
(tooth word, non-crossing non-incident bites, >=3 up teeth, bite-face
condition), plus a plotting script and the n=9 atlas (81 dihedral classes).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-11 12:23:57 -04:00
parent 4062e87c61
commit 8cc94fb6b9
12 changed files with 1002 additions and 103 deletions
@@ -0,0 +1,312 @@
"""Exhaustive generator for full medial tire graphs, indexed by |A(T)|.
Model (Definitions/Remarks 3.1--3.9 of the medial tire decompositions paper).
* The annular medial vertices induce a cycle A(T), the *annular cycle*
(Theorem 3.3). Write n = |A(T)| for its number of vertices = number of
annular faces = number of annular edges e_0,...,e_{n-1}.
* Each edge e_i of A(T) carries exactly one tooth (a triangle of M(T))
whose third vertex is a non-annular apex (Definition 3.4). A tooth is an
*up tooth* (apex in the outer region) or a *down tooth* (apex in the inner
region). We record the tooth types as a word in {U, D}^n.
* No two up teeth share an apex; at most two down teeth share an apex
(Remark 3.5). Two down teeth sharing an apex form a *bite* (Definition
3.7). So the down teeth are partitioned into singletons and bite pairs.
A bite pairs two down-edges and is drawn as an apex inside the disk with
spokes to the four endpoints; bites must be mutually non-crossing, i.e.
the bite pairs form a non-crossing (laminar) matching of the down-edges.
The two annular edges of a bite must be non-incident (Definition 3.7):
they share no annular vertex, so cyclically adjacent edges cannot pair.
* There are at least three up teeth (Remark 3.6).
* Bite-face condition (Remark 3.8). Let B(T) = A(T) together with the bite
apexes. Its interior non-tooth faces are the root face plus one inner-gap
face per bite. A singleton down tooth lies in the innermost bite enclosing
its edge (or in the root face if none). For every interior non-tooth face
the number of down-tooth apexes lying in that face must be 0 or at least 3.
Equivalently: no face holds exactly one or two singleton down teeth.
The generator enumerates, for a given n, every (tooth word, bite matching)
pair satisfying these properties and emits the resulting full medial tire
graph as an explicit vertex/edge structure. Configurations may optionally be
reduced modulo the dihedral symmetry of the cycle.
"""
from __future__ import annotations
import argparse
import itertools
from collections import defaultdict
from dataclasses import dataclass
from functools import lru_cache
from typing import Iterator
# A bite is an unordered pair of down-edge indices (i, j) with i < j.
Bite = tuple[int, int]
Matching = frozenset[Bite]
# ---------------------------------------------------------------------------
# Non-crossing (laminar) matchings of the down edges.
# ---------------------------------------------------------------------------
@lru_cache(maxsize=None)
def noncrossing_matchings(positions: tuple[int, ...]) -> tuple[Matching, ...]:
"""All non-crossing partial matchings of ``positions`` (sorted ascending).
Bite pairs drawn inside the disk are non-crossing iff, read in cyclic
order, no two pairs interleave. Cutting the cycle at the gap before the
first edge turns this into ordinary non-crossing interval matchings, which
obey the Catalan recursion below.
"""
if not positions:
return (frozenset(),)
head, *rest = positions
out: list[Matching] = []
# head left unmatched (a singleton down tooth, if its edge is down)
for tail in noncrossing_matchings(tuple(rest)):
out.append(tail)
# head matched with positions[k]; the strictly-enclosed block must be
# matched within itself to stay non-crossing.
for k in range(1, len(positions)):
partner = positions[k]
inside = tuple(positions[1:k])
outside = tuple(positions[k + 1:])
for m_in in noncrossing_matchings(inside):
for m_out in noncrossing_matchings(outside):
out.append(frozenset({(head, partner)}) | m_in | m_out)
return tuple(out)
# ---------------------------------------------------------------------------
# The bite-face condition (Remark 3.8).
# ---------------------------------------------------------------------------
def incident_edges(i: int, j: int, n: int) -> bool:
"""Whether annular edges i and j share an annular vertex on the n-cycle."""
return (j - i) % n == 1 or (i - j) % n == 1
def has_incident_bite(bites: Matching, n: int) -> bool:
"""Whether any bite pairs two incident (cyclically adjacent) edges."""
return any(incident_edges(i, j, n) for i, j in bites)
def innermost_bite(edge: int, bites: Matching) -> Bite | None:
"""The minimal-span bite whose open interval contains ``edge``, or None."""
enclosing = [b for b in bites if b[0] < edge < b[1]]
if not enclosing:
return None
return min(enclosing, key=lambda b: b[1] - b[0])
def face_singleton_counts(
tooth_word: str, bites: Matching
) -> dict[Bite | None, int]:
"""Down-singletons per interior non-tooth face of B(T).
The key ``None`` is the root face; a bite key is that bite's inner-gap
face. Faces with no singletons are simply absent from the result.
"""
matched = {edge for pair in bites for edge in pair}
counts: dict[Bite | None, int] = defaultdict(int)
for edge, tooth in enumerate(tooth_word):
if tooth != "D" or edge in matched:
continue # only singleton down teeth contribute apexes
counts[innermost_bite(edge, bites)] += 1
return dict(counts)
def satisfies_bite_face_condition(tooth_word: str, bites: Matching) -> bool:
"""Remark 3.8: every non-tooth face holds 0 or >=3 down-tooth apexes."""
return all(count >= 3 for count in face_singleton_counts(tooth_word, bites).values())
# ---------------------------------------------------------------------------
# The full medial tire graph as an explicit object.
# ---------------------------------------------------------------------------
@dataclass(frozen=True)
class FullMedialTireGraph:
"""A full medial tire graph M(T) determined by its combinatorial data.
Vertices are named:
a{k} annular medial vertex k (k = 0..n-1), forming A(T);
u{i} apex of the up tooth on edge i;
d{i} apex of the singleton down tooth on edge i;
p{i}_{j} apex of the bite pairing edges i and j (i < j).
"""
n: int
tooth_word: str
bites: Matching
@property
def up_edges(self) -> tuple[int, ...]:
return tuple(i for i, t in enumerate(self.tooth_word) if t == "U")
@property
def down_edges(self) -> tuple[int, ...]:
return tuple(i for i, t in enumerate(self.tooth_word) if t == "D")
@property
def bite_edges(self) -> frozenset[int]:
return frozenset(edge for pair in self.bites for edge in pair)
@property
def singleton_down_edges(self) -> tuple[int, ...]:
bite = self.bite_edges
return tuple(i for i in self.down_edges if i not in bite)
def apex_of_edge(self, edge: int) -> str:
if self.tooth_word[edge] == "U":
return f"u{edge}"
for i, j in self.bites:
if edge in (i, j):
return f"p{i}_{j}"
return f"d{edge}"
def vertices(self) -> list[str]:
verts = [f"a{k}" for k in range(self.n)]
for i in self.up_edges:
verts.append(f"u{i}")
for i in self.singleton_down_edges:
verts.append(f"d{i}")
for i, j in sorted(self.bites):
verts.append(f"p{i}_{j}")
return verts
def edges(self) -> list[tuple[str, str]]:
n = self.n
out: list[tuple[str, str]] = []
# annular cycle A(T)
for k in range(n):
out.append((f"a{k}", f"a{(k + 1) % n}"))
# singleton teeth (up and down): two spokes each
for i in self.up_edges:
out += [(f"u{i}", f"a{i}"), (f"u{i}", f"a{(i + 1) % n}")]
for i in self.singleton_down_edges:
out += [(f"d{i}", f"a{i}"), (f"d{i}", f"a{(i + 1) % n}")]
# bites: a shared apex with four spokes
for i, j in sorted(self.bites):
apex = f"p{i}_{j}"
for edge in (i, j):
out += [(apex, f"a{edge}"), (apex, f"a{(edge + 1) % n}")]
return [tuple(sorted(e)) for e in out]
def canonical_key(self) -> tuple:
"""Representative under the dihedral group of the cycle (rotations and
reflections), so symmetric configurations collapse to one key."""
n = self.n
best: tuple | None = None
for a in (1, -1):
for b in range(n):
relabel = lambda i: (a * i + b) % n
word = [""] * n
for i, t in enumerate(self.tooth_word):
word[relabel(i)] = t
mapped = tuple(sorted(
tuple(sorted((relabel(i), relabel(j)))) for i, j in self.bites
))
key = (tuple(word), mapped)
if best is None or key < best:
best = key
return best
# ---------------------------------------------------------------------------
# Enumeration.
# ---------------------------------------------------------------------------
def generate(
n: int, min_up_teeth: int = 3, dedup: bool = False
) -> Iterator[FullMedialTireGraph]:
"""Yield every full medial tire graph whose annular cycle has size ``n``.
``min_up_teeth`` defaults to 3 (Remark 3.6). With ``dedup`` set, only one
representative per dihedral symmetry class is returned.
"""
seen: set[tuple] = set()
for word_tuple in itertools.product("UD", repeat=n):
tooth_word = "".join(word_tuple)
if tooth_word.count("U") < min_up_teeth:
continue
down = tuple(i for i, t in enumerate(tooth_word) if t == "D")
for bites in noncrossing_matchings(down):
if has_incident_bite(bites, n):
continue
if not satisfies_bite_face_condition(tooth_word, bites):
continue
graph = FullMedialTireGraph(n=n, tooth_word=tooth_word, bites=bites)
if dedup:
key = graph.canonical_key()
if key in seen:
continue
seen.add(key)
yield graph
# ---------------------------------------------------------------------------
# CLI.
# ---------------------------------------------------------------------------
def figure_one() -> FullMedialTireGraph:
"""The example graph of Figure 1 (Remark 3.8): 12 edges, one bite (0,6)."""
return FullMedialTireGraph(
n=12,
tooth_word="DDDDDUDUUUUU", # edges 0-4,6 down; 5,7,8,9,10,11 up
bites=frozenset({(0, 6)}),
)
def describe(graph: FullMedialTireGraph) -> str:
counts = face_singleton_counts(graph.tooth_word, graph.bites)
face_strs = []
for face, c in sorted(counts.items(), key=lambda kv: (kv[0] is not None, kv[0])):
name = "root" if face is None else f"bite{face}"
face_strs.append(f"{name}:{c}")
bites = ",".join(f"({i},{j})" for i, j in sorted(graph.bites)) or "-"
faces = " ".join(face_strs) or "-"
return (
f"word={graph.tooth_word} up={len(graph.up_edges)} "
f"down={len(graph.down_edges)} bites={bites} faces[{faces}]"
)
def run(args: argparse.Namespace) -> None:
if args.check_figure:
g = figure_one()
print("Figure 1 check:")
print(f" {describe(g)}")
ok = satisfies_bite_face_condition(g.tooth_word, g.bites)
print(f" satisfies Remark 3.8: {ok} (expect True; faces 4 and 0)")
print()
for n in range(args.min_n, args.max_n + 1):
graphs = list(generate(n, min_up_teeth=args.min_up, dedup=args.dedup))
label = "classes" if args.dedup else "graphs"
print(f"n={n}: {len(graphs)} {label}")
if args.show:
for g in graphs[: args.show]:
print(f" {describe(g)}")
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--min-n", type=int, default=3)
parser.add_argument("--max-n", type=int, default=8)
parser.add_argument("--min-up", type=int, default=3, help="Remark 3.6 bound")
parser.add_argument("--dedup", action="store_true",
help="reduce modulo dihedral symmetry of the cycle")
parser.add_argument("--show", type=int, default=0,
help="print up to this many graphs per n")
parser.add_argument("--check-figure", action="store_true",
help="verify the Figure 1 example against Remark 3.8")
run(parser.parse_args())
if __name__ == "__main__":
main()
Binary file not shown.

After

Width:  |  Height:  |  Size: 469 KiB

@@ -0,0 +1,69 @@
# Atlas of full medial tire graphs with |A(T)| = 9
This note collects every full medial tire graph whose annular cycle `A(T)` has
nine vertices, generated exhaustively from the structural properties in
Definitions/Remarks 3.13.9 of `paper.tex`.
## What is being enumerated
A full medial tire graph of size `n = |A(T)|` is determined by:
- a tooth word in `{U, D}^n` — one up (`U`) or down (`D`) tooth per annular
edge (Def. 3.4), with **at least three up teeth** (Rem. 3.6);
- a **non-crossing matching** of the down edges into *bites* — pairs of down
teeth sharing an apex (Rem. 3.5, Def. 3.7); unmatched down teeth are
singletons. The two annular edges of a bite must be **non-incident**
(Def. 3.7): they share no annular vertex, so cyclically adjacent edges
cannot pair;
- subject to the **bite-face condition** (Rem. 3.8): in `B(T) = A(T) + bite
apexes`, every interior non-tooth face must contain `0` or `≥ 3`
down-tooth apexes in its interior (equivalently, no face holds exactly one
or two singleton down teeth).
Graphs are identified up to the dihedral symmetry of the annular cycle
(rotations and reflections), since these give isomorphic plane graphs.
## The atlas
![All full medial tire graphs with |A(T)| = 9](full_medial_tire_n9.png)
High-resolution vector copy: [`full_medial_tire_n9.pdf`](full_medial_tire_n9.pdf).
Full textual index: [`full_medial_tire_n9_index.txt`](full_medial_tire_n9_index.txt).
In each diagram the thick black ring is `A(T)`; **blue** outer apexes are up
teeth, **red** inner apexes are singleton down teeth, and a **dark-red** inner
apex with four spokes is a bite (its two paired annular edges). The label under
each diagram is the tooth word and the bite pairs (edge indices).
## Counts
There are **81** classes for `n = 9` (cf. `3:1, 4:1, 5:2, 6:6, 7:13, 8:36,
9:81` for `n = 3..9`, with the non-incidence stipulation in force). Breakdown
of the 81 classes:
| down teeth | classes | | bites | classes | | up teeth | classes |
|-----------:|--------:|---|------:|--------:|---|---------:|--------:|
| 0 | 1 | | 0 | 35 | | 3 | 23 |
| 2 | 3 | | 1 | 35 | | 4 | 29 |
| 3 | 7 | | 2 | 8 | | 5 | 18 |
| 4 | 18 | | 3 | 3 | | 6 | 7 |
| 5 | 29 | | | | | 7 | 3 |
| 6 | 23 | | | | | 9 | 1 |
46 of the 81 classes contain at least one bite. (Every singleton down tooth
must sit in a face holding `≥ 3` of them, so e.g. words with exactly one or two
down teeth only survive when those down teeth are paired into a bite — and now
only when the paired edges are non-incident, which is why the counts fall
sharply from the unrestricted `n = 9` total of 159.)
## Reproduce
```sh
# from this directory, using the repo .venv
../../../.venv/bin/python plot_full_medial_tire_n9.py # figure + index
python full_medial_tire_generator.py --min-n 9 --max-n 9 --dedup --show 5
```
`full_medial_tire_generator.py` is the generator (`generate(n, dedup=True)`
yields `FullMedialTireGraph` objects); `plot_full_medial_tire_n9.py` draws the
atlas.
@@ -0,0 +1,81 @@
0 word=UUUUUUUUU up=9 down=0 bites=-
1 word=UUUUUUDUD up=7 down=2 bites=(6,8)
2 word=UUUUUUDDD up=6 down=3 bites=-
3 word=UUUUUDUUD up=7 down=2 bites=(5,8)
4 word=UUUUUDUDD up=6 down=3 bites=-
5 word=UUUUUDDDD up=5 down=4 bites=-
6 word=UUUUDUUUD up=7 down=2 bites=(4,8)
7 word=UUUUDUUDD up=6 down=3 bites=-
8 word=UUUUDUDUD up=6 down=3 bites=-
9 word=UUUUDUDDD up=5 down=4 bites=-
10 word=UUUUDDUDD up=5 down=4 bites=-
11 word=UUUUDDUDD up=5 down=4 bites=(4,8),(5,7)
12 word=UUUUDDDDD up=4 down=5 bites=-
13 word=UUUUDDDDD up=4 down=5 bites=(4,8)
14 word=UUUDUUUDD up=6 down=3 bites=-
15 word=UUUDUUDUD up=6 down=3 bites=-
16 word=UUUDUUDDD up=5 down=4 bites=-
17 word=UUUDUDUDD up=5 down=4 bites=-
18 word=UUUDUDUDD up=5 down=4 bites=(3,8),(5,7)
19 word=UUUDUDDUD up=5 down=4 bites=-
20 word=UUUDUDDUD up=5 down=4 bites=(3,5),(6,8)
21 word=UUUDUDDDD up=4 down=5 bites=-
22 word=UUUDUDDDD up=4 down=5 bites=(3,5)
23 word=UUUDUDDDD up=4 down=5 bites=(3,8)
24 word=UUUDDUUDD up=5 down=4 bites=-
25 word=UUUDDUUDD up=5 down=4 bites=(3,8),(4,7)
26 word=UUUDDUDDD up=4 down=5 bites=-
27 word=UUUDDUDDD up=4 down=5 bites=(4,6)
28 word=UUUDDUDDD up=4 down=5 bites=(3,8)
29 word=UUUDDDDDD up=3 down=6 bites=-
30 word=UUUDDDDDD up=3 down=6 bites=(3,8)
31 word=UUDUUDUUD up=6 down=3 bites=-
32 word=UUDUUDUDD up=5 down=4 bites=-
33 word=UUDUUDUDD up=5 down=4 bites=(2,8),(5,7)
34 word=UUDUUDDDD up=4 down=5 bites=-
35 word=UUDUUDDDD up=4 down=5 bites=(2,5)
36 word=UUDUDUUDD up=5 down=4 bites=-
37 word=UUDUDUUDD up=5 down=4 bites=(2,8),(4,7)
38 word=UUDUDUDUD up=5 down=4 bites=-
39 word=UUDUDUDUD up=5 down=4 bites=(2,4),(6,8)
40 word=UUDUDUDUD up=5 down=4 bites=(2,8),(4,6)
41 word=UUDUDUDDD up=4 down=5 bites=-
42 word=UUDUDUDDD up=4 down=5 bites=(4,6)
43 word=UUDUDUDDD up=4 down=5 bites=(2,4)
44 word=UUDUDUDDD up=4 down=5 bites=(2,8)
45 word=UUDUDDUDD up=4 down=5 bites=-
46 word=UUDUDDUDD up=4 down=5 bites=(5,7)
47 word=UUDUDDUDD up=4 down=5 bites=(2,4)
48 word=UUDUDDUDD up=4 down=5 bites=(2,8)
49 word=UUDUDDDUD up=4 down=5 bites=-
50 word=UUDUDDDUD up=4 down=5 bites=(6,8)
51 word=UUDUDDDUD up=4 down=5 bites=(2,8)
52 word=UUDUDDDDD up=3 down=6 bites=-
53 word=UUDUDDDDD up=3 down=6 bites=(2,4)
54 word=UUDUDDDDD up=3 down=6 bites=(2,8)
55 word=UUDDUUDDD up=4 down=5 bites=-
56 word=UUDDUUDDD up=4 down=5 bites=(3,6)
57 word=UUDDUDUDD up=4 down=5 bites=-
58 word=UUDDUDUDD up=4 down=5 bites=(5,7)
59 word=UUDDUDUDD up=4 down=5 bites=(2,8)
60 word=UUDDUDDDD up=3 down=6 bites=-
61 word=UUDDUDDDD up=3 down=6 bites=(3,5)
62 word=UUDDUDDDD up=3 down=6 bites=(2,8)
63 word=UUDDDUDDD up=3 down=6 bites=-
64 word=UUDDDUDDD up=3 down=6 bites=(4,6)
65 word=UUDDDUDDD up=3 down=6 bites=(2,8)
66 word=UUDDDUDDD up=3 down=6 bites=(2,8),(3,7),(4,6)
67 word=UDUDUDUDD up=4 down=5 bites=-
68 word=UDUDUDUDD up=4 down=5 bites=(5,7)
69 word=UDUDUDUDD up=4 down=5 bites=(3,5)
70 word=UDUDUDDDD up=3 down=6 bites=-
71 word=UDUDUDDDD up=3 down=6 bites=(3,5)
72 word=UDUDUDDDD up=3 down=6 bites=(1,3)
73 word=UDUDDUDDD up=3 down=6 bites=-
74 word=UDUDDUDDD up=3 down=6 bites=(4,6)
75 word=UDUDDUDDD up=3 down=6 bites=(1,3)
76 word=UDUDDUDDD up=3 down=6 bites=(1,8)
77 word=UDUDDUDDD up=3 down=6 bites=(1,8),(3,7),(4,6)
78 word=UDDUDDUDD up=3 down=6 bites=-
79 word=UDDUDDUDD up=3 down=6 bites=(5,7)
80 word=UDDUDDUDD up=3 down=6 bites=(1,8),(2,4),(5,7)
@@ -0,0 +1,139 @@
"""Draw every full medial tire graph with |A(T)| = 9.
Generates the dihedral-symmetry classes from ``full_medial_tire_generator`` and
draws each one in the tooth style of the paper figures: the annular cycle A(T)
as a thick ring of black vertices, up teeth pointing outward (blue apexes),
singleton down teeth pointing inward (red apexes), and bites as a single inner
apex (dark red) with four spokes to the two paired annular edges.
Output is a single grid figure (PNG + PDF) plus a text index of the classes.
"""
from __future__ import annotations
import argparse
import math
import os
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from full_medial_tire_generator import FullMedialTireGraph, generate
HERE = os.path.dirname(os.path.abspath(__file__))
def vertex_xy(k: int, n: int, radius: float) -> tuple[float, float]:
"""Annular vertex k, placed clockwise from the top of the unit circle."""
angle = math.pi / 2 - 2 * math.pi * k / n
return radius * math.cos(angle), radius * math.sin(angle)
def edge_midpoint_angle(i: int, n: int) -> float:
return math.pi / 2 - 2 * math.pi * (i + 0.5) / n
def draw_graph(ax, g: FullMedialTireGraph) -> None:
n = g.n
ann = [vertex_xy(k, n, 1.0) for k in range(n)]
matched = g.bite_edges
# annular cycle A(T)
cyc_x = [p[0] for p in ann] + [ann[0][0]]
cyc_y = [p[1] for p in ann] + [ann[0][1]]
ax.plot(cyc_x, cyc_y, color="black", lw=1.6, zorder=2)
# up teeth (outer apexes) and singleton down teeth (inner apexes)
for i, tooth in enumerate(g.tooth_word):
if tooth == "U":
r, color = 1.42, "#2b6cb0"
elif i not in matched: # singleton down tooth
r, color = 0.58, "#c53030"
else:
continue
ang = edge_midpoint_angle(i, n)
apex = (r * math.cos(ang), r * math.sin(ang))
a0, a1 = ann[i], ann[(i + 1) % n]
ax.plot([apex[0], a0[0]], [apex[1], a0[1]], color="#9a9a9a", lw=0.5, zorder=1)
ax.plot([apex[0], a1[0]], [apex[1], a1[1]], color="#9a9a9a", lw=0.5, zorder=1)
ax.scatter([apex[0]], [apex[1]], s=14, color=color, zorder=3)
# bites: one shared inner apex with four spokes
for i, j in sorted(g.bites):
corners = [ann[i], ann[(i + 1) % n], ann[j], ann[(j + 1) % n]]
cx = sum(p[0] for p in corners) / 4.0
cy = sum(p[1] for p in corners) / 4.0
# pull slightly toward the centre so nested bites stay distinguishable
apex = (cx * 0.82, cy * 0.82)
for corner in corners:
ax.plot([apex[0], corner[0]], [apex[1], corner[1]],
color="#9a9a9a", lw=0.5, zorder=1)
ax.scatter([apex[0]], [apex[1]], s=26, color="#7b1f1f",
edgecolors="black", linewidths=0.4, zorder=4)
# annular vertices on top
ax.scatter([p[0] for p in ann], [p[1] for p in ann],
s=10, color="black", zorder=5)
bites = ",".join(f"{i}{j}" for i, j in sorted(g.bites)) or "-"
ax.set_title(f"{g.tooth_word}\n{bites}", fontsize=5.5, pad=1.5)
ax.set_xlim(-1.6, 1.6)
ax.set_ylim(-1.6, 1.6)
ax.set_aspect("equal")
ax.axis("off")
def run(args: argparse.Namespace) -> None:
graphs = list(generate(args.n, min_up_teeth=args.min_up, dedup=True))
print(f"n={args.n}: {len(graphs)} dihedral classes")
cols = args.cols
rows = math.ceil(len(graphs) / cols)
fig, axes = plt.subplots(rows, cols, figsize=(cols * 1.45, rows * 1.6))
axes = axes.reshape(rows, cols)
for idx in range(rows * cols):
ax = axes[idx // cols][idx % cols]
if idx < len(graphs):
draw_graph(ax, graphs[idx])
else:
ax.axis("off")
fig.suptitle(
f"All full medial tire graphs with $|A(T)|={args.n}$ "
f"({len(graphs)} classes up to dihedral symmetry)",
fontsize=12, y=0.997,
)
fig.tight_layout(rect=(0, 0, 1, 0.985))
png = os.path.join(HERE, f"full_medial_tire_n{args.n}.png")
pdf = os.path.join(HERE, f"full_medial_tire_n{args.n}.pdf")
fig.savefig(png, dpi=200)
fig.savefig(pdf)
print(f"wrote {png}")
print(f"wrote {pdf}")
if args.index:
index_path = os.path.join(HERE, f"full_medial_tire_n{args.n}_index.txt")
with open(index_path, "w") as fh:
for idx, g in enumerate(graphs):
bites = ",".join(f"({i},{j})" for i, j in sorted(g.bites)) or "-"
fh.write(
f"{idx:3d} word={g.tooth_word} up={len(g.up_edges)} "
f"down={len(g.down_edges)} bites={bites}\n"
)
print(f"wrote {index_path}")
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--n", type=int, default=9)
parser.add_argument("--min-up", type=int, default=3)
parser.add_argument("--cols", type=int, default=12)
parser.add_argument("--index", action="store_true", default=True)
run(parser.parse_args())
if __name__ == "__main__":
main()
@@ -11,23 +11,30 @@
\@writefile{toc}{\contentsline {section}{\tocsection {}{3}{Medial tire pieces}}{2}{}\protected@file@percent }
\newlabel{def:full-medial-tire}{{3.1}{2}}
\newlabel{thm:annular-medial-colour-bound}{{3.3}{3}}
\newlabel{def:boundary-medial-vertices}{{3.4}{3}}
\newlabel{def:medial-restriction-relation}{{3.5}{3}}
\newlabel{def:annular-teeth}{{3.4}{3}}
\newlabel{rem:teeth-sharing}{{3.5}{3}}
\newlabel{rem:up-teeth-count}{{3.6}{3}}
\newlabel{def:bite}{{3.7}{4}}
\newlabel{rem:bite-face-count}{{3.8}{4}}
\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces A full medial tire graph $\mathsf {M}(T)$ illustrating the tooth terminology. The thick cycle is the annular medial cycle $A(T)$, whose black vertices are the annular medial vertices. Each edge of $A(T)$ carries one tooth: up teeth (blue apexes, outer-boundary medial vertices) point into the outer region, and down teeth (red apexes, inner-boundary medial vertices) point into the inner region. The two down teeth meeting at the central shared apex (larger red vertex) form a bite; that shared apex splits the inner region into two faces, one with four down teeth on its boundary and one with none.}}{4}{}\protected@file@percent }
\newlabel{fig:medial-teeth-example}{{1}{4}}
\newlabel{def:boundary-medial-vertices}{{3.9}{4}}
\citation{bauerfeld-nested-tire-decompositions}
\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Three six-face full medial tire graphs found by the boundary-state restriction search. Black vertices are annular medial vertices; blue vertices are outer boundary medial vertices and red vertices are inner boundary medial vertices. The word below each diagram records the outer/inner type of the six annular faces in cyclic order. Boundary states are identified only up to colour permutation, not by rotation or reflection of the boundary order.}}{5}{}\protected@file@percent }
\newlabel{fig:medial-restriction-worst-cases}{{2}{5}}
\@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces A proper vertex $3$-colouring of the full medial graph of the first seven-vertex counterexample found by the experiment. The medial vertex labelled $ij$ corresponds to the edge $(i,j)$ of the triangulation. For the vertex-source decomposition at source $1$, the highlighted annular medial cycle has colour counts $(2,2,2)$, so it is not coloured with two colours except at at most one vertex.}}{5}{}\protected@file@percent }
\newlabel{fig:medial-annular-cycle-counterexample}{{3}{5}}
\newlabel{def:medial-restriction-relation}{{3.10}{5}}
\citation{bauerfeld-nested-tire-decompositions}
\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Three six-face full medial tire graphs found by the boundary-state restriction search. Black vertices are annular medial vertices; blue vertices are outer boundary medial vertices and red vertices are inner boundary medial vertices. The word below each diagram records the outer/inner type of the six annular faces in cyclic order. Boundary states are identified only up to colour permutation, not by rotation or reflection of the boundary order.}}{4}{}\protected@file@percent }
\newlabel{fig:medial-restriction-worst-cases}{{1}{4}}
\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces A proper vertex $3$-colouring of the full medial graph of the first seven-vertex counterexample found by the experiment. The medial vertex labelled $ij$ corresponds to the edge $(i,j)$ of the triangulation. For the vertex-source decomposition at source $1$, the highlighted annular medial cycle has colour counts $(2,2,2)$, so it is not coloured with two colours except at at most one vertex.}}{4}{}\protected@file@percent }
\newlabel{fig:medial-annular-cycle-counterexample}{{2}{4}}
\@writefile{toc}{\contentsline {section}{\tocsection {}{4}{Decomposition}}{4}{}\protected@file@percent }
\newlabel{cor:medial-tire-decomposition}{{4.1}{4}}
\newlabel{def:compatible-family}{{4.2}{5}}
\newlabel{prop:gluing-criterion}{{4.3}{5}}
\@writefile{toc}{\contentsline {section}{\tocsection {}{5}{A medial pigeonhole programme}}{5}{}\protected@file@percent }
\newlabel{def:medial-boundary-state}{{5.1}{5}}
\newlabel{conj:medial-chain-pigeonhole}{{5.2}{5}}
\newlabel{conj:medial-route-fct}{{5.3}{6}}
\@writefile{toc}{\contentsline {subsection}{\tocsubsection {}{5.1}{Kempe-cycle conservation across medial tires}}{6}{}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\tocsection {}{4}{Decomposition}}{6}{}\protected@file@percent }
\newlabel{cor:medial-tire-decomposition}{{4.1}{6}}
\newlabel{def:compatible-family}{{4.2}{6}}
\newlabel{prop:gluing-criterion}{{4.3}{6}}
\@writefile{toc}{\contentsline {section}{\tocsection {}{5}{A medial pigeonhole programme}}{6}{}\protected@file@percent }
\newlabel{def:medial-boundary-state}{{5.1}{6}}
\newlabel{conj:medial-chain-pigeonhole}{{5.2}{7}}
\newlabel{conj:medial-route-fct}{{5.3}{7}}
\@writefile{toc}{\contentsline {subsection}{\tocsubsection {}{5.1}{Kempe-cycle conservation across medial tires}}{7}{}\protected@file@percent }
\bibcite{bauerfeld-nested-tire-decompositions}{1}
\bibcite{tait-original}{2}
\newlabel{tocindent-1}{0pt}
@@ -35,5 +42,5 @@
\newlabel{tocindent1}{17.77782pt}
\newlabel{tocindent2}{29.38873pt}
\newlabel{tocindent3}{0pt}
\@writefile{toc}{\contentsline {section}{\tocsection {}{}{References}}{8}{}\protected@file@percent }
\gdef \@abspage@last{8}
\@writefile{toc}{\contentsline {section}{\tocsection {}{}{References}}{10}{}\protected@file@percent }
\gdef \@abspage@last{10}
@@ -1,6 +1,5 @@
# Fdb version 3
["pdflatex"] 1780957013 "/Users/didericis/Code/math-research/papers/medial_tire_decompositions_of_plane_triangulations/paper.tex" "paper.pdf" "paper" 1780957014
"/Users/didericis/Code/math-research/papers/medial_tire_decompositions_of_plane_triangulations/paper.tex" 1780957012 31877 e1531fb82c355208b5b7c8e57cfb6e8a ""
["pdflatex"] 1781194762 "paper.tex" "paper.pdf" "paper" 1781194763
"/usr/local/texlive/2022/texmf-dist/fonts/map/fontname/texfonts.map" 1577235249 3524 cb3e574dea2d1052e39280babc910dc8 ""
"/usr/local/texlive/2022/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex7.tfm" 1246382020 1004 54797486969f23fa377b128694d548df ""
"/usr/local/texlive/2022/texmf-dist/fonts/tfm/public/amsfonts/cmextra/cmex8.tfm" 1246382020 988 bdf658c3bfc2d96d3c8b02cfc1c94c20 ""
@@ -133,8 +132,8 @@
"/usr/local/texlive/2022/texmf-var/fonts/map/pdftex/updmap/pdftex.map" 1647878959 4410336 7d30a02e9fa9a16d7d1f8d037ba69641 ""
"/usr/local/texlive/2022/texmf-var/web2c/pdftex/pdflatex.fmt" 1665017617 2826443 7e98410c533054b636c6470db83a27bc ""
"/usr/local/texlive/2022/texmf.cnf" 1647878952 577 209b46be99c9075fd74d4c0369380e8c ""
"paper.aux" 1780957014 3096 87a6f727fdb250a8819be3b4fc862d4e "pdflatex"
"paper.tex" 1780957012 31877 e1531fb82c355208b5b7c8e57cfb6e8a ""
"paper.aux" 1781194763 4035 146533a306519cb8688d4e85db1d3f80 "pdflatex"
"paper.tex" 1781194559 37363 b7b005cfaefc0e3a582f756b993a034e ""
(generated)
"paper.aux"
"paper.log"
@@ -2,7 +2,7 @@ PWD /Users/didericis/Code/math-research/papers/medial_tire_decompositions_of_pla
INPUT /usr/local/texlive/2022/texmf.cnf
INPUT /usr/local/texlive/2022/texmf-dist/web2c/texmf.cnf
INPUT /usr/local/texlive/2022/texmf-var/web2c/pdftex/pdflatex.fmt
INPUT /Users/didericis/Code/math-research/papers/medial_tire_decompositions_of_plane_triangulations/paper.tex
INPUT paper.tex
OUTPUT paper.log
INPUT /usr/local/texlive/2022/texmf-dist/tex/latex/amscls/amsart.cls
INPUT /usr/local/texlive/2022/texmf-dist/tex/latex/amscls/amsart.cls
@@ -1,12 +1,12 @@
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 8 JUN 2026 18:16
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 11 JUN 2026 12:19
entering extended mode
restricted \write18 enabled.
file:line:error style messages enabled.
%&-line parsing enabled.
**/Users/didericis/Code/math-research/papers/medial_tire_decompositions_of_plane_triangulations/paper.tex
(/Users/didericis/Code/math-research/papers/medial_tire_decompositions_of_plane_triangulations/paper.tex
**paper.tex
(./paper.tex
LaTeX2e <2021-11-15> patch level 1
L3 programming layer <2022-02-24> (/usr/local/texlive/2022/texmf-dist/tex/latex/amscls/amsart.cls
L3 programming layer <2022-02-24>
(/usr/local/texlive/2022/texmf-dist/tex/latex/amscls/amsart.cls
Document Class: amsart 2020/05/29 v2.20.6
\linespacing=\dimen138
\normalparindent=\dimen139
@@ -18,14 +18,17 @@ Package: amsmath 2021/10/15 v2.17l AMS math features
For additional information on amsmath, use the `?' option.
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amstext.sty
Package: amstext 2021/08/26 v2.01 AMS text
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amsgen.sty
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amsgen.sty
File: amsgen.sty 1999/11/30 v2.0 generic functions
\@emptytoks=\toks16
\ex@=\dimen140
)) (/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amsbsy.sty
))
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amsbsy.sty
Package: amsbsy 1999/11/29 v1.2d Bold Symbols
\pmbraise@=\dimen141
) (/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amsopn.sty
)
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amsopn.sty
Package: amsopn 2021/08/26 v2.02 operator names
)
\inf@bad=\count185
@@ -66,10 +69,13 @@ LaTeX Font Info: Redeclaring font encoding OMS on input line 744.
LaTeX Info: Redefining \[ on input line 2938.
LaTeX Info: Redefining \] on input line 2939.
)
LaTeX Font Info: Trying to load font information for U+msa on input line 397.
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/umsa.fd
LaTeX Font Info: Trying to load font information for U+msa on input line 397
.
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/umsa.fd
File: umsa.fd 2013/01/14 v3.01 AMS symbols A
) (/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/amsfonts.sty
)
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/amsfonts.sty
Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support
\symAMSa=\mathgroup4
\symAMSb=\mathgroup5
@@ -100,42 +106,63 @@ LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold'
\thm@postskip=\skip55
\thm@headsep=\skip56
\dth@everypar=\toks26
) (/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/amssymb.sty
)
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/amssymb.sty
Package: amssymb 2013/01/14 v3.01 AMS font symbols
) (/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/graphicx.sty
)
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/graphicx.sty
Package: graphicx 2021/09/16 v1.2d Enhanced LaTeX Graphics (DPC,SPQR)
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/keyval.sty
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/keyval.sty
Package: keyval 2014/10/28 v1.15 key=value parser (DPC)
\KV@toks@=\toks27
) (/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/graphics.sty
)
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/graphics.sty
Package: graphics 2021/03/04 v1.4d Standard LaTeX Graphics (DPC,SPQR)
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/trig.sty
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/trig.sty
Package: trig 2021/08/11 v1.11 sin cos tan (DPC)
) (/usr/local/texlive/2022/texmf-dist/tex/latex/graphics-cfg/graphics.cfg
)
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics-cfg/graphics.cfg
File: graphics.cfg 2016/06/04 v1.11 sample graphics configuration
)
Package graphics Info: Driver file: pdftex.def on input line 107.
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics-def/pdftex.def
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics-def/pdftex.def
File: pdftex.def 2020/10/05 v1.2a Graphics/color driver for pdftex
))
\Gin@req@height=\dimen150
\Gin@req@width=\dimen151
) (/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/frontendlayer/tikz.sty (/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/basiclayer/pgf.sty (/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/utilities/pgfrcs.sty (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/frontendlayer/tikz.sty
(/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/basiclayer/pgf.sty
(/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/utilities/pgfrcs.sty
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.te
x
\pgfutil@everybye=\toks28
\pgfutil@tempdima=\dimen152
\pgfutil@tempdimb=\dimen153
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/utilities/pgfutil-common-lists.tex)) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/utilities/pgfutil-latex.def
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/utilities/pgfutil-common-li
sts.tex))
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/utilities/pgfutil-latex.def
\pgfutil@abb=\box53
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/utilities/pgfrcs.code.tex (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/pgf.revision.tex)
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/utilities/pgfrcs.code.tex
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/pgf.revision.tex)
Package: pgfrcs 2021/05/15 v3.1.9a (3.1.9a)
))
Package: pgf 2021/05/15 v3.1.9a (3.1.9a)
(/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/basiclayer/pgfcore.sty (/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/systemlayer/pgfsys.sty (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/systemlayer/pgfsys.code.tex
(/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/basiclayer/pgfcore.sty
(/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/systemlayer/pgfsys.sty
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/systemlayer/pgfsys.code.tex
Package: pgfsys 2021/05/15 v3.1.9a (3.1.9a)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex
\pgfkeys@pathtoks=\toks29
\pgfkeys@temptoks=\toks30
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.c
ode.tex
\pgfkeys@tmptoks=\toks31
))
\pgf@x=\dimen154
@@ -158,23 +185,33 @@ Package: pgfsys 2021/05/15 v3.1.9a (3.1.9a)
\t@pgf@tokb=\toks33
\t@pgf@tokc=\toks34
\pgf@sys@id@count=\count276
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/systemlayer/pgf.cfg
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/systemlayer/pgf.cfg
File: pgf.cfg 2021/05/15 v3.1.9a (3.1.9a)
)
Driver file for pgf: pgfsys-pdftex.def
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-pdftex.def
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-pdftex.d
ef
File: pgfsys-pdftex.def 2021/05/15 v3.1.9a (3.1.9a)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf.def
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-p
df.def
File: pgfsys-common-pdf.def 2021/05/15 v3.1.9a (3.1.9a)
))) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/systemlayer/pgfsyssoftpath.code.tex
)))
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/systemlayer/pgfsyssoftpath.
code.tex
File: pgfsyssoftpath.code.tex 2021/05/15 v3.1.9a (3.1.9a)
\pgfsyssoftpath@smallbuffer@items=\count277
\pgfsyssoftpath@bigbuffer@items=\count278
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/systemlayer/pgfsysprotocol.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/systemlayer/pgfsysprotocol.
code.tex
File: pgfsysprotocol.code.tex 2021/05/15 v3.1.9a (3.1.9a)
)) (/usr/local/texlive/2022/texmf-dist/tex/latex/xcolor/xcolor.sty
Package: xcolor 2021/10/31 v2.13 LaTeX color extensions (UK)
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics-cfg/color.cfg
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics-cfg/color.cfg
File: color.cfg 2016/01/02 v1.6 sample color configuration
)
Package xcolor Info: Driver file: pdftex.def on input line 227.
@@ -187,18 +224,43 @@ Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1372.
Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1373.
Package xcolor Info: Model `Gray' substituted by `gray' on input line 1374.
Package xcolor Info: Model `wave' substituted by `hsb' on input line 1375.
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcore.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcore.code.tex
Package: pgfcore 2021/05/15 v3.1.9a (3.1.9a)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathcalc.code.tex (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathutil.code.tex) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathcalc.code.tex
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathutil.code.tex)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex
\pgfmath@dimen=\dimen164
\pgfmath@count=\count279
\pgfmath@box=\box54
\pgfmath@toks=\toks35
\pgfmath@stack@operand=\toks36
\pgfmath@stack@operation=\toks37
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.code.tex (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.trigonometric.code.tex) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.random.code.tex) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.comparison.code.tex) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.base.code.tex) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.round.code.tex) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.misc.code.tex) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.integerarithmetics.code.tex))) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfloat.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.code.
tex
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.basic
.code.tex)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.trigo
nometric.code.tex)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.rando
m.code.tex)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.compa
rison.code.tex)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.base.
code.tex)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.round
.code.tex)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.misc.
code.tex)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.integ
erarithmetics.code.tex)))
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmathfloat.code.tex
\c@pgfmathroundto@lastzeros=\count280
)) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfint.code.tex) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex
)) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfint.code.tex)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.co
de.tex
File: pgfcorepoints.code.tex 2021/05/15 v3.1.9a (3.1.9a)
\pgf@picminx=\dimen165
\pgf@picmaxx=\dimen166
@@ -214,76 +276,127 @@ File: pgfcorepoints.code.tex 2021/05/15 v3.1.9a (3.1.9a)
\pgf@yy=\dimen176
\pgf@zx=\dimen177
\pgf@zy=\dimen178
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathconst
ruct.code.tex
File: pgfcorepathconstruct.code.tex 2021/05/15 v3.1.9a (3.1.9a)
\pgf@path@lastx=\dimen179
\pgf@path@lasty=\dimen180
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathusage.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathusage
.code.tex
File: pgfcorepathusage.code.tex 2021/05/15 v3.1.9a (3.1.9a)
\pgf@shorten@end@additional=\dimen181
\pgf@shorten@start@additional=\dimen182
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorescopes.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorescopes.co
de.tex
File: pgfcorescopes.code.tex 2021/05/15 v3.1.9a (3.1.9a)
\pgfpic=\box55
\pgf@hbox=\box56
\pgf@layerbox@main=\box57
\pgf@picture@serial@count=\count281
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcoregraphicst
ate.code.tex
File: pgfcoregraphicstate.code.tex 2021/05/15 v3.1.9a (3.1.9a)
\pgflinewidth=\dimen183
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransformations.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransform
ations.code.tex
File: pgfcoretransformations.code.tex 2021/05/15 v3.1.9a (3.1.9a)
\pgf@pt@x=\dimen184
\pgf@pt@y=\dimen185
\pgf@pt@temp=\dimen186
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorequick.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorequick.cod
e.tex
File: pgfcorequick.code.tex 2021/05/15 v3.1.9a (3.1.9a)
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreobjects.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreobjects.c
ode.tex
File: pgfcoreobjects.code.tex 2021/05/15 v3.1.9a (3.1.9a)
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathproce
ssing.code.tex
File: pgfcorepathprocessing.code.tex 2021/05/15 v3.1.9a (3.1.9a)
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.co
de.tex
File: pgfcorearrows.code.tex 2021/05/15 v3.1.9a (3.1.9a)
\pgfarrowsep=\dimen187
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreshade.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreshade.cod
e.tex
File: pgfcoreshade.code.tex 2021/05/15 v3.1.9a (3.1.9a)
\pgf@max=\dimen188
\pgf@sys@shading@range@num=\count282
\pgf@shadingcount=\count283
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreimage.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreimage.cod
e.tex
File: pgfcoreimage.code.tex 2021/05/15 v3.1.9a (3.1.9a)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreexternal.code.tex
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreexternal.
code.tex
File: pgfcoreexternal.code.tex 2021/05/15 v3.1.9a (3.1.9a)
\pgfexternal@startupbox=\box58
)) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorelayers.code.tex
))
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorelayers.co
de.tex
File: pgfcorelayers.code.tex 2021/05/15 v3.1.9a (3.1.9a)
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransparency.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretranspare
ncy.code.tex
File: pgfcoretransparency.code.tex 2021/05/15 v3.1.9a (3.1.9a)
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepatterns.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepatterns.
code.tex
File: pgfcorepatterns.code.tex 2021/05/15 v3.1.9a (3.1.9a)
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorerdf.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/basiclayer/pgfcorerdf.code.
tex
File: pgfcorerdf.code.tex 2021/05/15 v3.1.9a (3.1.9a)
))) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex
)))
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.cod
e.tex
File: pgfmoduleshapes.code.tex 2021/05/15 v3.1.9a (3.1.9a)
\pgfnodeparttextbox=\box59
) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex
)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.
tex
File: pgfmoduleplot.code.tex 2021/05/15 v3.1.9a (3.1.9a)
) (/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/compatibility/pgfcomp-version-0-65.sty
)
(/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/compatibility/pgfcomp-version
-0-65.sty
Package: pgfcomp-version-0-65 2021/05/15 v3.1.9a (3.1.9a)
\pgf@nodesepstart=\dimen189
\pgf@nodesepend=\dimen190
) (/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/compatibility/pgfcomp-version-1-18.sty
)
(/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/compatibility/pgfcomp-version
-1-18.sty
Package: pgfcomp-version-1-18 2021/05/15 v3.1.9a (3.1.9a)
)) (/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/utilities/pgffor.sty (/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/utilities/pgfkeys.sty (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex)) (/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/math/pgfmath.sty (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex)) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/utilities/pgffor.code.tex
))
(/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/utilities/pgffor.sty
(/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/utilities/pgfkeys.sty
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex)
) (/usr/local/texlive/2022/texmf-dist/tex/latex/pgf/math/pgfmath.sty
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex))
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/utilities/pgffor.code.tex
Package: pgffor 2021/05/15 v3.1.9a (3.1.9a)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex)
\pgffor@iter=\dimen191
\pgffor@skip=\dimen192
\pgffor@stack=\toks38
\pgffor@toks=\toks39
)) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex
))
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/frontendlayer/tikz/tikz.cod
e.tex
Package: tikz 2021/05/15 v3.1.9a (3.1.9a)
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/libraries/pgflibraryplothandlers.code.tex
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/libraries/pgflibraryplothan
dlers.code.tex
File: pgflibraryplothandlers.code.tex 2021/05/15 v3.1.9a (3.1.9a)
\pgf@plot@mark@count=\count284
\pgfplotmarksize=\dimen193
@@ -304,26 +417,34 @@ File: pgflibraryplothandlers.code.tex 2021/05/15 v3.1.9a (3.1.9a)
\tikznumberofchildren=\count286
\tikznumberofcurrentchild=\count287
\tikz@fig@count=\count288
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.cod
e.tex
File: pgfmodulematrix.code.tex 2021/05/15 v3.1.9a (3.1.9a)
\pgfmatrixcurrentrow=\count289
\pgfmatrixcurrentcolumn=\count290
\pgf@matrix@numberofcolumns=\count291
)
\tikz@expandcount=\count292
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarytopaths.code.tex
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/frontendlayer/tikz/librarie
s/tikzlibrarytopaths.code.tex
File: tikzlibrarytopaths.code.tex 2021/05/15 v3.1.9a (3.1.9a)
))) (/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex
)))
(/usr/local/texlive/2022/texmf-dist/tex/generic/pgf/frontendlayer/tikz/librarie
s/tikzlibrarybackgrounds.code.tex
File: tikzlibrarybackgrounds.code.tex 2021/05/15 v3.1.9a (3.1.9a)
\pgf@layerbox@background=\box64
\pgf@layerboxsaved@background=\box65
)
\c@theorem=\count293
(/usr/local/texlive/2022/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def
(/usr/local/texlive/2022/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def
File: l3backend-pdftex.def 2022-02-07 L3 backend support: PDF output (pdfTeX)
\l__color_backend_stack_int=\count294
\l__pdf_internal_box=\box66
) (./paper.aux)
)
(./paper.aux)
\openout1 = `paper.aux'.
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 29.
@@ -341,13 +462,17 @@ LaTeX Font Info: ... okay on input line 29.
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 29.
LaTeX Font Info: ... okay on input line 29.
LaTeX Font Info: Trying to load font information for U+msa on input line 29.
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/umsa.fd
File: umsa.fd 2013/01/14 v3.01 AMS symbols A
)
LaTeX Font Info: Trying to load font information for U+msb on input line 29.
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/umsb.fd
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/umsb.fd
File: umsb.fd 2013/01/14 v3.01 AMS symbols B
) (/usr/local/texlive/2022/texmf-dist/tex/context/base/mkii/supp-pdf.mkii
)
(/usr/local/texlive/2022/texmf-dist/tex/context/base/mkii/supp-pdf.mkii
[Loading MPS to PDF converter (version 2006.09.02).]
\scratchcounter=\count295
\scratchdimen=\dimen259
@@ -362,30 +487,58 @@ File: umsb.fd 2013/01/14 v3.01 AMS symbols B
\everyMPtoPDFconversion=\toks41
) (/usr/local/texlive/2022/texmf-dist/tex/latex/epstopdf-pkg/epstopdf-base.sty
Package: epstopdf-base 2020-01-24 v2.11 Base part for package epstopdf
Package epstopdf-base Info: Redefining graphics rule for `.eps' on input line 485.
(/usr/local/texlive/2022/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg
File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Live
)) [1{/usr/local/texlive/2022/texmf-var/fonts/map/pdftex/updmap/pdftex.map}] [2]
Package epstopdf-base Info: Redefining graphics rule for `.eps' on input line 4
85.
(/usr/local/texlive/2022/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg
File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Liv
e
))
[1{/usr/local/texlive/2022/texmf-var/fonts/map/pdftex/updmap/pdftex.map}]
[2] [3]
Overfull \hbox (62.13657pt too wide) in paragraph at lines 363--372
[][]
[]
LaTeX Warning: `h' float specifier changed to `ht'.
LaTeX Warning: `h' float specifier changed to `ht'.
[3] [4] [5] [6] [7] [8] (./paper.aux) )
[4] [5] [6] [7] [8] [9] [10] (./paper.aux) )
Here is how much of TeX's memory you used:
14159 strings out of 478268
280330 string characters out of 5846347
592946 words of memory out of 5000000
31987 multiletter control sequences out of 15000+600000
14415 strings out of 478268
283664 string characters out of 5846347
609309 words of memory out of 5000000
32244 multiletter control sequences out of 15000+600000
477048 words of font info for 58 fonts, out of 8000000 for 9000
1302 hyphenation exceptions out of 8191
84i,8n,89p,676b,841s stack positions out of 10000i,1000n,20000p,200000b,200000s
</usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmcsc10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi5.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi7.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr7.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmss10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy5.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy6.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy7.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmti10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmti8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmtt8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/symbols/msam10.pfb>
Output written on paper.pdf (8 pages, 265030 bytes).
84i,8n,89p,736b,838s stack positions out of 10000i,1000n,20000p,200000b,200000s
</usr/local/texlive/2022/texmf-dist
/fonts/type1/public/amsfonts/cm/cmbx10.pfb></usr/local/texlive/2022/texmf-dist/
fonts/type1/public/amsfonts/cm/cmbx8.pfb></usr/local/texlive/2022/texmf-dist/fo
nts/type1/public/amsfonts/cm/cmcsc10.pfb></usr/local/texlive/2022/texmf-dist/fo
nts/type1/public/amsfonts/cm/cmmi10.pfb></usr/local/texlive/2022/texmf-dist/fon
ts/type1/public/amsfonts/cm/cmmi5.pfb></usr/local/texlive/2022/texmf-dist/fonts
/type1/public/amsfonts/cm/cmmi7.pfb></usr/local/texlive/2022/texmf-dist/fonts/t
ype1/public/amsfonts/cm/cmmi8.pfb></usr/local/texlive/2022/texmf-dist/fonts/typ
e1/public/amsfonts/cm/cmr10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1
/public/amsfonts/cm/cmr7.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/pu
blic/amsfonts/cm/cmr8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/publi
c/amsfonts/cm/cmss10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public
/amsfonts/cm/cmsy10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/
amsfonts/cm/cmsy5.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/am
sfonts/cm/cmsy6.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsf
onts/cm/cmsy7.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfon
ts/cm/cmti10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfont
s/cm/cmti8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/
cm/cmtt8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/sy
mbols/msam10.pfb>
Output written on paper.pdf (10 pages, 272876 bytes).
PDF statistics:
129 PDF objects out of 1000 (max. 8388607)
80 compressed objects within 1 object stream
135 PDF objects out of 1000 (max. 8388607)
84 compressed objects within 1 object stream
0 named destinations out of 1000 (max. 500000)
13 words of extra memory for PDF output out of 10000 (max. 10000000)
@@ -195,8 +195,8 @@ Let $T = (B_{\mathrm{out}}, O, E_{\mathrm{ann}})$ be a tire tread with
non-degenerate boundaries and simple inner boundary $B_{\mathrm{in}}$.
Let $A(T)$ be the subgraph of $\mathsf{M}(T)$ induced by the annular
medial vertices. For a graph $H$, write $\operatorname{Col}_3(H)$ for
the set of proper $3$-vertex-colourings of $H$. Then $A(T)$ is a cycle
and
the set of proper $3$-vertex-colourings of $H$. Then $A(T)$ is a
cycle---the \emph{annular cycle} of $T$---and
\[
|\operatorname{Col}_3(\mathsf{M}(T))|
\;\leq\; |\operatorname{Col}_3(A(T))|.
@@ -234,6 +234,145 @@ same restriction to $A(T)$ are identical, so the restriction map is
injective. The stated inequality follows.
\end{proof}
\begin{definition}[Annular teeth]
\label{def:annular-teeth}
By Theorem~\ref{thm:annular-medial-colour-bound} the annular medial
vertices induce the cycle $A(T)$ in $\mathsf{M}(T)$, the annular cycle, so
the edges of $\mathsf{M}(T)$ joining two annular medial vertices are
exactly the edges of $A(T)$. Each such edge lies in exactly one triangle ($3$-cycle) of
$\mathsf{M}(T)$, and the third vertex of that triangle is necessarily
non-annular, since $A(T)$ has no chords. We call this triangle an
\emph{annular tooth} and its non-annular vertex the \emph{apex} of the
tooth.
The cycle $A(T)$ separates the plane into two regions: the \emph{outer
region}, which contains the outer-boundary medial vertices, and the
\emph{inner region}, which contains the inner-boundary medial vertices.
An annular tooth is an \emph{up tooth} if its apex lies in the outer
region, and a \emph{down tooth} if its apex lies in the inner region.
\end{definition}
\begin{remark}
\label{rem:teeth-sharing}
The apexes of annular teeth satisfy two sharing bounds: no two up teeth
share an apex, and at most two down teeth share an apex.
\end{remark}
\begin{remark}
\label{rem:up-teeth-count}
The number of up teeth in $\mathsf{M}(T)$ is at least three.
\end{remark}
\begin{definition}[Bites]
\label{def:bite}
By Remark~\ref{rem:teeth-sharing} an apex is shared by at most two down
teeth. When two down teeth share an apex, the pair is called a
\emph{bite}, and their common apex is the \emph{apex of the bite}. A down
tooth that belongs to a bite is a \emph{bite tooth}. We further require the
two annular edges carrying the teeth of a bite to be \emph{non-incident}:
they share no annular vertex of $A(T)$. Equivalently, the two bite teeth
meet only at their common apex.
\end{definition}
\begin{remark}
\label{rem:bite-face-count}
Let $B(T)$ be the subgraph of $\mathsf{M}(T)$ consisting of $A(T)$
together with all bite apexes (equivalently, $A(T)$ together with all
bite teeth), drawn as a plane graph. For every interior face of $B(T)$
that is not a bite tooth, the number of down teeth whose apex lies in
the interior of that face is either $0$ or at least $3$. Such an apex is
necessarily that of a singleton down tooth: every bite apex is a vertex
of $B(T)$, so it lies on a face boundary rather than in any face
interior.
\end{remark}
\begin{figure}[h]
\centering
\begin{tikzpicture}[scale=2.3,
ann/.style={circle, fill=black, inner sep=1.1pt},
upv/.style={circle, draw=blue!70!black, fill=blue!15, inner sep=1.5pt},
downv/.style={circle, draw=red!70!black, fill=red!15, inner sep=1.5pt},
bitev/.style={circle, draw=red!70!black, fill=red!35, inner sep=1.9pt},
cyc/.style={black, line width=1.0pt},
tth/.style={black!55, line width=0.45pt},
lbl/.style={font=\scriptsize},
lead/.style={black!55, line width=0.3pt}]
% annular medial vertices forming the cycle A(T)
\foreach \k/\a in {0/105,1/75,2/45,3/15,4/-15,5/-45,6/-75,7/-105,8/-135,9/-165,10/165,11/135}
\coordinate (v\k) at (\a:1);
% down-tooth apexes (inner region)
\coordinate (d1) at (60:0.60);
\coordinate (d2) at (30:0.60);
\coordinate (d3) at (0:0.60);
\coordinate (d4) at (-30:0.60);
% shared apex of the bite
\coordinate (p) at (0,0);
% up-tooth apexes (outer region)
\coordinate (u1) at (-60:1.35);
\coordinate (u2) at (-120:1.35);
\coordinate (u3) at (-150:1.35);
\coordinate (u4) at (180:1.35);
\coordinate (u5) at (150:1.35);
\coordinate (u6) at (120:1.35);
% annular medial cycle
\draw[cyc] (v0)--(v1)--(v2)--(v3)--(v4)--(v5)--(v6)--(v7)--(v8)--(v9)--(v10)--(v11)--cycle;
% down teeth into the right inner region
\draw[tth] (d1)--(v1) (d1)--(v2);
\draw[tth] (d2)--(v2) (d2)--(v3);
\draw[tth] (d3)--(v3) (d3)--(v4);
\draw[tth] (d4)--(v4) (d4)--(v5);
% up teeth
\draw[tth] (u1)--(v5) (u1)--(v6);
\draw[tth] (u2)--(v7) (u2)--(v8);
\draw[tth] (u3)--(v8) (u3)--(v9);
\draw[tth] (u4)--(v9) (u4)--(v10);
\draw[tth] (u5)--(v10) (u5)--(v11);
\draw[tth] (u6)--(v11) (u6)--(v0);
% the bite: two down teeth sharing the apex p
\draw[tth] (p)--(v0) (p)--(v1) (p)--(v6) (p)--(v7);
% vertices
\foreach \k in {0,...,11} \node[ann] at (v\k) {};
\foreach \u in {u1,u2,u3,u4,u5,u6} \node[upv] at (\u) {};
\foreach \dd in {d1,d2,d3,d4} \node[downv] at (\dd) {};
\node[bitev] at (p) {};
% annotations
\node[lbl, anchor=west] at (42:1.78) (Ldt) {down tooth};
\draw[lead] (Ldt.west) -- (30:0.74);
\node[lbl, anchor=east] at (150:1.86) (Lut) {up tooth};
\draw[lead] (Lut.east) -- (150:1.22);
\node[lbl] at (90:1.62) (Lbite) {bite};
\draw[lead] (Lbite.south) -- (0,0.08);
\node[lbl, anchor=west] at (-12:1.78) (L4) {region with 4 down teeth};
\draw[lead] (L4.west) -- (-9:0.80);
\node[lbl, anchor=east] at (192:1.86) (L0) {region with 0 down teeth};
\draw[lead] (L0.east) -- (180:0.45);
\end{tikzpicture}
\caption{A full medial tire graph $\mathsf{M}(T)$ illustrating the tooth
terminology. The thick cycle is the annular medial cycle $A(T)$, whose
black vertices are the annular medial vertices. Each edge of $A(T)$
carries one tooth: up teeth (blue apexes, outer-boundary medial vertices)
point into the outer region, and down teeth (red apexes, inner-boundary
medial vertices) point into the inner region. The two down teeth meeting
at the central shared apex (larger red vertex) form a bite; that shared
apex splits the inner region into two faces, one with four down teeth on
its boundary and one with none.}
\label{fig:medial-teeth-example}
\end{figure}
\begin{figure}[h]
\centering
\begin{tikzpicture}[scale=0.82,