```typ
#import "@preview/fletcher:0.5.8" as fletcher: diagram, node, edge
#set page(width: auto, height: auto, margin: 5mm, fill: white)
// Straight arrow: the target is a special case of the source.
#let quad(a, b, label, paint, ..args) = {
paint = paint.darken(25%)
edge(a, b, text(paint, label), "-|>", stroke: paint, label-side: center, ..args)
}
// Arrow through extra corner points, with rounded corners.
// dashed: true → "is used to build" rather than "is a special case of".
#let route(..vertices, label, paint, dashed: false) = {
paint = paint.darken(25%)
edge(
..vertices,
text(paint, label),
if dashed { "--|>" } else { "-|>" },
stroke: paint, label-side: center, corner-radius: 6pt,
)
}
#diagram(
node-defocus: 0,
spacing: (1cm, 2cm),
edge-stroke: 1pt,
crossing-thickness: 5,
mark-scale: 70%,
node-fill: luma(97%),
node-outset: 3pt,
// ═════════════════════════════════════════════════════════
// 1. group
// ═════════════════════════════════════════════════════════
node(( 0,0), "magma"),
node((-1,1), "semigroup"),
node(( 0,1), "unital magma"),
node((+1,1), "quasigroup"),
node((-1,2), "monoid"),
node(( 0,2), "inverse semigroup"),
node((+1,2), "loop"),
node(( 0,3), "group"),
node(( 0,4), "abelian group"),
quad((0,0), (-1,1), "Assoc", blue),
quad((0,1), (-1,2), "Assoc", blue, label-pos: 0.3),
quad((1,2), (0,3), "Assoc", blue),
quad((0,0), (0,1), "Id", red),
quad((-1,1), (-1,2), "Id", red, label-pos: 0.3),
quad((+1,1), (+1,2), "Id", red, label-pos: 0.3),
quad((0,2), (0,3), "Id", red),
quad((0,0), (1,1), "Div", green),
quad((-1,1), (0,2), "Div", green, label-pos: 0.3, "crossing"),
quad((-1,2), (0,3), "Inv", gray),
quad((0,1), (+1,2), "Inv", gray, label-pos: 0.3),
quad((1,1), (0,2), "Assoc", blue, label-pos: 0.3, "crossing"),
quad((0,3), (0,4), "Comm", purple),
// ═════════════════════════════════════════════════════════
// 2. Many objects (partial operation)
// ═════════════════════════════════════════════════════════
node((-3,0), "set"),
node((-2.15,0), "magmoid"),
node((-2.15,1), "semigroupoid"),
node((-2.15,2), "category"),
node((-2.15,3), "groupoid"),
quad((-3,0), (-2.15,0), "Operation", black),
quad((-2.15,0), (-2.15,1), "Assoc", blue),
quad((-2.15,1), (-2.15,2), "Id", red),
quad((-2.15,2), (-2.15,3), "Inv", green),
quad((-2.15,0), (0,0), "One object", black),
quad((-2.15,1), (-1,1), "One object", black),
quad((-2.15,2), (-1,2), "One object", black),
quad((-2.15,3), (0,3), "One object", black, label-pos: 0.3),
// ═════════════════════════════════════════════════════════
// 3. ring
// ═════════════════════════════════════════════════════════
node((-2,5), "ring"),
node((-3,6), "commutative ring"),
node((-2,6), "domain"),
node((-1,6), "Artinian ring"),
node((-3,7), "integral domain"),
node((-2,7), "commutative Artinian ring"),
node((-1,7), "division ring"),
node((-2,8), "field"),
// monoid's line drops onto abelian group's line, and both run into ring
route((-1,2), (-1,3.5), (-2,3.5), (-2,4), (-2,5), "2nd operation", orange, label-pos: (1, 0.475), crossing: true),
route((0,4), (-2,4), (-2,5), "1st operation", orange, label-pos: (0, 0.3)),
quad((-2,5), (-3,6), "Comm", purple),
quad((-2,5), (-2,6), "NoZD", teal),
quad((-2,5), (-1,6), "DCC", yellow),
quad((-3,6), (-3,7), "NoZD", teal, label-pos: 0.3),
quad((-2,6), (-3,7), "Comm", purple, label-pos: 0.3),
quad((-3,6), (-2,7), "DCC", yellow, label-pos: 0.3, "crossing"),
quad((-2,6), (-1,7), "Inv", gray, label-pos: 0.3),
quad((-1,6), (-2,7), "Comm", purple, label-pos: 0.3, "crossing"),
quad((-1,6), (-1,7), "NoZD", teal, label-pos: 0.3),
quad((-3,7), (-2,8), "Inv", gray),
quad((-2,7), (-2,8), "NoZD", teal),
quad((-1,7), (-2,8), "Comm", purple),
// ═════════════════════════════════════════════════════════
// 4. module
// ═════════════════════════════════════════════════════════
node((2,5), "module"),
node((1,6), "vector space"),
node((2,6), "algebra over a ring"),
node((3,6), "finitely generated module"),
node((1,7), "algebra over a field"),
node((2,7), "finite-dimensional vector space"),
node((3,7), "finitely generated algebra over a ring"),
node((2,8), "finite-dimensional algebra"),
route((0,4), (2,4), (2,5), "Structure", eastern, label-pos: (0, 0.5)),
route((-2,5), (2,5), "scalar", gray, dashed: true),
route((-2,8), (0,8), (0,6), (1,6), "scalar", gray, dashed: true),
quad((2,5), (1,6), "FS", maroon),
quad((2,5), (2,6), "Exterior structure", orange),
quad((2,5), (3,6), "FG", olive),
quad((1,6), (1,7), "Exterior structure", orange, label-pos: 0.3),
quad((2,6), (1,7), "FS", maroon, label-pos: 0.3),
quad((1,6), (2,7), "FG", olive, label-pos: 0.3, "crossing"),
quad((2,6), (3,7), "FG", olive, label-pos: 0.3),
quad((3,6), (2,7), "FS", maroon, label-pos: 0.3, "crossing"),
quad((3,6), (3,7), "Exterior structure", orange, label-pos: 0.3),
quad((1,7), (2,8), "FG", olive),
quad((2,7), (2,8), "Exterior structure", orange),
quad((3,7), (2,8), "FS", maroon),
)
```