Documentation

TauCeti.KnotTheory.PDCode.Basic

PD-codes #

A PD-code records finite combinatorial crossing data for a link. The halfEdge permutation lists the four half-edges at each crossing, while the perfect matching edgePair joins the two half-edges at the ends of each arc. Opposite slots form the two local strands, one of which is selected by overPair. Crossing-free components are recorded separately.

OrientedPDCode decorates this data with compatible directions on the arcs and crossing-free components. FramedOrientedPDCode further assigns an integer framing to every component. The forgetful maps between these three presentation layers let results use only the data they need.

This is a code-level presentation: PDCode neither imposes planarity nor provides a geometric realization, so these must be supplied separately. Keeping the code finite and explicit avoids choosing a privileged geometric embedding.

The PD-code encoding adapts M. Mastin, Links and Planar Diagram Codes, Definitions 2--3, which develops the Bar-Natan/KnotTheory PD convention. Mastin lists, at each crossing, the labels of the four incident arcs counterclockwise from the incoming under-edge. Here halfEdge labels half-edges rather than arcs, the four slots of a crossing are read counterclockwise from any starting slot, the over-strand is recorded by the separate bit overPair, and crossing-free components are counted separately. The diagram and crossing-sign conventions follow W. B. R. Lickorish, An Introduction to Knot Theory, GTM 175, Chapter 1. The framing convention follows R. Gompf and A. Stipsicz, 4-Manifolds and Kirby Calculus, GSM 20, Section 4.5, especially Proposition 4.5.8.

Main definitions #

Main results #

The standard equivalence between crossing-slot pairs and the 4 * n half-edge positions.

Equations
Instances For
    @[simp]
    theorem TauCeti.PDCode.crossingSlotEquiv_apply_val {n : ℕ} (i : Fin n) (slot : Fin 4) :
    ↑((crossingSlotEquiv n) (i, slot)) = ↑slot + 4 * ↑i

    The crossing-slot equivalence numbers slot s at crossing i by s + 4 * i.

    def TauCeti.PDCode.halfEdgeSuccEquiv (n : ℕ) :
    Fin (4 * n) ⊕ Fin 4 ≃ Fin (4 * (n + 1))

    The half-edge positions of a code with one crossing more: the 4 * n positions of the first n crossings, followed by the four slots of the new last crossing.

    Equations
    Instances For
      @[simp]

      A slot of one of the first n crossings keeps its half-edge position when a crossing is added last.

      @[simp]

      The slots of the last crossing occupy the last four half-edge positions.

      theorem TauCeti.PDCode.crossingSlotEquiv_apply_val_mod_four {n : ℕ} (i : Fin n) (slot : Fin 4) :
      ↑((crossingSlotEquiv n) (i, slot)) % 4 = ↑slot

      The slot of a half-edge is recovered from its position modulo four.

      @[simp]

      A half-edge position of the first n crossings keeps its value when a crossing is added.

      @[simp]
      theorem TauCeti.PDCode.halfEdgeSuccEquiv_apply_inr_val {n : ℕ} (slot : Fin 4) :
      ↑((halfEdgeSuccEquiv n) (Sum.inr slot)) = ↑slot + 4 * n

      The slots of the added crossing follow the 4 * n positions of the first n crossings.

      The slot opposite a given slot in the cyclic order at a crossing.

      Equations
      Instances For

        The opposite crossing slot is obtained by adding two cyclically.

        @[simp]

        The value of the opposite crossing slot.

        The opposite-slot permutation swaps slots 0, 2 and slots 1, 3.

        Exactly one of a slot and its opposite slot is one of the last two slots 2, 3.

        @[simp]

        Taking the opposite crossing slot twice returns to the original slot.

        The two smoothings of the four slots at a crossing, indexed by an over-pair indicator. slotSmoothing false pairs slot 0 with slot 3 and slot 1 with slot 2, and slotSmoothing true pairs slot 0 with slot 1 and slot 2 with slot 3: in both cases each slot of the pair indicated is joined to the slot preceding it in the counterclockwise order. Applied to D.overPair i it is therefore the A-smoothing at crossing i, the one turning left off the over-strand, and applied to !D.overPair i the B-smoothing.

        Equations
        Instances For
          @[simp]

          The true smoothing pairs slots 0-1 and 2-3.

          @[simp]

          The false smoothing pairs slots 0-3 and 1-2.

          @[simp]
          theorem TauCeti.PDCode.slotSmoothing_apply_apply (b : Bool) (slot : Fin 4) :
          (slotSmoothing b) ((slotSmoothing b) slot) = slot

          A local smoothing is an involution of the four slots.

          theorem TauCeti.PDCode.slotSmoothing_ne (b : Bool) (slot : Fin 4) :
          (slotSmoothing b) slot ≠ slot

          A local smoothing moves every slot: it pairs the four slots off into two arcs.

          The opposite crossing slot is different from the original slot.

          structure TauCeti.PDCode (n : ℕ) :

          A finite unoriented PD-code with n crossings.

          The 4 * n half-edges are grouped into four slots for each crossing by halfEdge, listed counterclockwise around the crossing. The perfect matching edgePair joins the two half-edges at the ends of each arc. Slots 0 and 2 form one local strand, while slots 1 and 3 form the other. crossinglessComponentCount counts circle components which meet no crossing. overPair i = false selects the 0-2 strand as over, while true selects the 1-3 strand.

          • halfEdge : Equiv.Perm (Fin (4 * n))

            The half-edge labels occupying the four slots of each crossing.

          • edgePair : PerfectMatching (Fin (4 * n))

            The perfect matching pairing the two half-edges at the ends of each arc.

          • crossinglessComponentCount : ℕ

            The number of circle components which meet no crossing.

          • overPair : Fin n → Bool

            Which of the two opposite-slot strands is over at each crossing.

          Instances For
            theorem TauCeti.PDCode.ext {n : ℕ} {x y : PDCode n} (halfEdge : x.halfEdge = y.halfEdge) (edgePair : x.edgePair = y.edgePair) (crossinglessComponentCount : x.crossinglessComponentCount = y.crossinglessComponentCount) (overPair : x.overPair = y.overPair) :
            x = y
            structure TauCeti.OrientedPDCode (n : ℕ) extends TauCeti.PDCode n :

            An oriented PD-code, consisting of an unoriented code and compatible component directions.

            Instances For
              theorem TauCeti.OrientedPDCode.ext {n : ℕ} {x y : OrientedPDCode n} (toPDCode : x.toPDCode = y.toPDCode) (orientation : x.orientation = y.orientation) (crossinglessComponents : x.crossinglessComponents = y.crossinglessComponents) :
              x = y

              A framed oriented PD-code.

              On a component meeting a crossing, framing is an integer constant along arc pairings and local strands. For crossing-free components, crossinglessFramings keeps each orientation paired with its framing integer. These integers measure the chosen framing relative to the Seifert (0-) framing. The diagram's blackboard framing instead has coefficient equal to the component writhe.

              Instances For
                theorem TauCeti.FramedOrientedPDCode.ext {n : ℕ} {x y : FramedOrientedPDCode n} (toOrientedPDCode : x.toOrientedPDCode = y.toOrientedPDCode) (framing : x.framing = y.framing) (crossinglessFramings : x.crossinglessFramings = y.crossinglessFramings) :
                x = y
                def TauCeti.PDCode.crossing {n : ℕ} (D : PDCode n) (i : Fin n) (slot : Fin 4) :
                Fin (4 * n)

                The four half-edge labels at a crossing, in counterclockwise cyclic order.

                Equations
                Instances For
                  @[simp]
                  theorem TauCeti.PDCode.crossing_apply {n : ℕ} (D : PDCode n) (i : Fin n) (slot : Fin 4) :
                  D.crossing i slot = D.halfEdge ((crossingSlotEquiv n) (i, slot))

                  The explicit formula for the half-edge in a specified crossing slot.

                  theorem TauCeti.PDCode.eq_permCongr_sumCongr_of_halfEdge_eq {n : ℕ} {D : PDCode n} {D' : PDCode (n + 1)} (hD : D'.halfEdge = (halfEdgeSuccEquiv n).permCongr (D.halfEdge.sumCongr 1)) {σ : Equiv.Perm (Fin (4 * n))} {τ : Equiv.Perm (Fin (4 * (n + 1)))} (f : Fin (n + 1) → Equiv.Perm (Fin 4)) (hσ : ∀ (i : Fin n) (slot : Fin 4), σ (D.halfEdge ((crossingSlotEquiv n) (i, slot))) = D.crossing i ((f i.castSucc) slot)) (hτ : ∀ (i : Fin (n + 1)) (slot : Fin 4), τ (D'.halfEdge ((crossingSlotEquiv (n + 1)) (i, slot))) = D'.crossing i ((f i) slot)) :

                  Let D' be a code with one crossing more than D, whose first n crossings keep the half-edges of D and whose last crossing takes the four new half-edge positions. A permutation of the half-edges of D' that acts at each crossing i by the local permutation f i of its slots is the permutation of the half-edges of D acting at each crossing i by f i.castSucc, together with f (Fin.last n) on the four new slots.

                  def TauCeti.PDCode.isOver {n : ℕ} (D : PDCode n) (i : Fin n) (slot : Fin 4) :

                  Whether a slot belongs to the over-strand at its crossing.

                  Equations
                  Instances For
                    theorem TauCeti.PDCode.isOver_def {n : ℕ} (D : PDCode n) (i : Fin n) (slot : Fin 4) :
                    D.isOver i slot = (D.overPair i == decide (slot = 1 ∨ slot = 3))

                    The defining equation for the over-strand indicator of a slot: it compares the over-pair indicator with the parity of the slot.

                    @[simp]
                    theorem TauCeti.PDCode.isOver_zero {n : ℕ} (D : PDCode n) (i : Fin n) :
                    D.isOver i 0 = !D.overPair i

                    Slot zero is over exactly when the second opposite-slot pair was not selected.

                    @[simp]
                    theorem TauCeti.PDCode.isOver_one {n : ℕ} (D : PDCode n) (i : Fin n) :
                    D.isOver i 1 = D.overPair i

                    Slot one is over exactly when the second opposite-slot pair was selected.

                    @[simp]
                    theorem TauCeti.PDCode.isOver_two {n : ℕ} (D : PDCode n) (i : Fin n) :
                    D.isOver i 2 = !D.overPair i

                    Slot two is over exactly when the second opposite-slot pair was not selected.

                    @[simp]
                    theorem TauCeti.PDCode.isOver_three {n : ℕ} (D : PDCode n) (i : Fin n) :
                    D.isOver i 3 = D.overPair i

                    Slot three is over exactly when the second opposite-slot pair was selected.

                    @[simp]
                    theorem TauCeti.PDCode.isOver_oppositeCrossingSlot {n : ℕ} (D : PDCode n) (i : Fin n) (slot : Fin 4) :
                    D.isOver i (oppositeCrossingSlot slot) = D.isOver i slot

                    Opposite slots belong to the same over- or under-strand.

                    def TauCeti.PDCode.mirror {n : ℕ} (D : PDCode n) :

                    Reflect a diagram by swapping the over- and under-strands.

                    Equations
                    Instances For
                      @[simp]

                      Reflection leaves the half-edge order unchanged.

                      @[simp]

                      Reflection leaves the arc matching unchanged.

                      @[simp]

                      Reflection preserves the number of crossing-free components.

                      @[simp]
                      theorem TauCeti.PDCode.mirror_overPair {n : ℕ} (D : PDCode n) (i : Fin n) :

                      Reflection complements each over-strand choice.

                      theorem TauCeti.PDCode.crossing_mirror {n : ℕ} (D : PDCode n) (i : Fin n) (slot : Fin 4) :
                      D.mirror.crossing i slot = D.crossing i slot

                      Reflection leaves every labelled crossing slot unchanged.

                      @[simp]
                      theorem TauCeti.PDCode.isOver_mirror {n : ℕ} (D : PDCode n) (i : Fin n) (slot : Fin 4) :
                      D.mirror.isOver i slot = !D.isOver i slot

                      Reflection interchanges over- and under-slots.

                      @[simp]

                      Reflecting a PD-code twice gives the original code.

                      @[simp]

                      Reflection fixes every PD-code without crossings.

                      def TauCeti.PDCode.reconnect {n : ℕ} (D : PDCode n) (p q : Fin (4 * n)) :

                      Reconnecting two arcs. Cut the arc of D ending at the half-edge p and the arc ending at q, and join p to q and the other end D.edgePair.val p of the first arc to the other end D.edgePair.val q of the second (TauCeti.PerfectMatching.reconnect). The crossings, their over-strands and the crossing-free circles are unchanged. This is how a smoothing of a crossing added by TauCeti.PDCode.insertCrossing reconnects the cut arcs. The two arcs are distinct when q ≠ p and q ≠ D.edgePair.val p; when q = D.edgePair.val p both choices name the same arc and the code is left unchanged.

                      Equations
                      Instances For
                        @[simp]
                        theorem TauCeti.PDCode.reconnect_halfEdge {n : ℕ} (D : PDCode n) (p q : Fin (4 * n)) :

                        Reconnecting arcs keeps the half-edges at the crossings.

                        @[simp]
                        theorem TauCeti.PDCode.reconnect_overPair {n : ℕ} (D : PDCode n) (p q : Fin (4 * n)) :

                        Reconnecting arcs keeps the over-strands.

                        @[simp]

                        Reconnecting arcs keeps the crossing-free circles.

                        @[simp]
                        theorem TauCeti.PDCode.reconnect_edgePair {n : ℕ} (D : PDCode n) (p q : Fin (4 * n)) :

                        Reconnecting arcs of the code reconnects its perfect matching of half-edges.

                        @[simp]
                        theorem TauCeti.PDCode.reconnect_partner {n : ℕ} (D : PDCode n) (p : Fin (4 * n)) :
                        D.reconnect p (↑D.edgePair p) = D

                        Reconnecting the two ends of one arc leaves the code unchanged.

                        @[simp]
                        theorem TauCeti.PDCode.reconnect_self {n : ℕ} (D : PDCode n) (p : Fin (4 * n)) :
                        D.reconnect p p = D

                        Reconnecting a half-edge with itself leaves the code unchanged.

                        theorem TauCeti.PDCode.reconnect_edgePair_val {n : ℕ} (D : PDCode n) (p q : Fin (4 * n)) :

                        The arcs of the reconnected code are the old arcs conjugated by the transposition of D.edgePair.val p with q.

                        @[simp]
                        theorem TauCeti.PDCode.mirror_reconnect {n : ℕ} (D : PDCode n) (p q : Fin (4 * n)) :

                        Mirroring commutes with reconnecting arcs.

                        def TauCeti.PDCode.crossingBlockEquiv {n m : ℕ} (cross : Fin n ≃ Fin m) :
                        Fin (4 * n) ≃ Fin (4 * m)

                        The equivalence of half-edge positions induced by an equivalence of crossing names. It changes the crossing coordinate and preserves the slot coordinate.

                        Equations
                        Instances For
                          @[simp]
                          theorem TauCeti.PDCode.crossingBlockEquiv_apply_crossingSlotEquiv {n m : ℕ} (cross : Fin n ≃ Fin m) (i : Fin n) (slot : Fin 4) :
                          (crossingBlockEquiv cross) ((crossingSlotEquiv n) (i, slot)) = (crossingSlotEquiv m) (cross i, slot)

                          A crossing-block equivalence changes the crossing coordinate and preserves its slot.

                          @[simp]

                          The inverse of a crossing-block equivalence is induced by the inverse crossing equivalence.

                          @[simp]

                          The identity equivalence of crossing names induces the identity equivalence of half-edges.

                          @[simp]
                          theorem TauCeti.PDCode.crossingBlockEquiv_trans {n m r : ℕ} (cross₁ : Fin n ≃ Fin m) (cross₂ : Fin m ≃ Fin r) :
                          crossingBlockEquiv (cross₁.trans cross₂) = (crossingBlockEquiv cross₁).trans (crossingBlockEquiv cross₂)

                          Crossing-block equivalences preserve composition.

                          def TauCeti.PDCode.relabel {n m : ℕ} (D : PDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) :

                          Relabel the half-edges and crossings of a code along equivalences of their index types: the half-edge h becomes half h and the crossing j becomes cross j. Slots are kept, so the half-edge in slot s of crossing cross j is half of the half-edge in slot s of crossing j; arcs join the images of the half-edges they joined, the over-strand choice at cross j is the one at j, and the number of crossing-free components is unchanged. The half-edge equivalence need not be the one induced by the crossing equivalence.

                          Equations
                          • One or more equations did not get rendered due to their size.
                          Instances For
                            @[simp]
                            theorem TauCeti.PDCode.relabel_halfEdge {n m : ℕ} (D : PDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) :
                            (D.relabel half cross).halfEdge = ((crossingBlockEquiv cross).equivCongr half) D.halfEdge

                            The half-edge permutation of a relabelled code is half ∘ D.halfEdge ∘ (crossingBlockEquiv cross).symm: the half-edge in slot s of crossing cross j is half of the half-edge of D in slot s of crossing j.

                            @[simp]
                            theorem TauCeti.PDCode.relabel_edgePair {n m : ℕ} (D : PDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) :

                            Relabelling transports the perfect matching along the half-edge equivalence.

                            @[simp]

                            Relabelling preserves the number of crossing-free components.

                            @[simp]
                            theorem TauCeti.PDCode.relabel_overPair {n m : ℕ} (D : PDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) (i : Fin m) :
                            (D.relabel half cross).overPair i = D.overPair (cross.symm i)

                            Relabelling reads the over-strand choice at the old crossing name.

                            theorem TauCeti.PDCode.crossing_relabel {n m : ℕ} (D : PDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) (i : Fin m) (slot : Fin 4) :
                            (D.relabel half cross).crossing i slot = half (D.crossing (cross.symm i) slot)

                            Relabelling transports every crossing block together with its slot order.

                            @[simp]
                            theorem TauCeti.PDCode.isOver_relabel {n m : ℕ} (D : PDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) (i : Fin m) (slot : Fin 4) :
                            (D.relabel half cross).isOver i slot = D.isOver (cross.symm i) slot

                            The over/under status after relabelling is read at the old crossing name.

                            @[simp]
                            theorem TauCeti.PDCode.relabel_refl {n : ℕ} (D : PDCode n) :
                            D.relabel (Equiv.refl (Fin (4 * n))) (Equiv.refl (Fin n)) = D

                            Relabelling by identity equivalences does nothing.

                            @[simp]
                            theorem TauCeti.PDCode.relabel_relabel {n m : ℕ} (D : PDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) {r : ℕ} (half₂ : Fin (4 * m) ≃ Fin (4 * r)) (cross₂ : Fin m ≃ Fin r) :
                            (D.relabel half cross).relabel half₂ cross₂ = D.relabel (half.trans half₂) (cross.trans cross₂)

                            Consecutive relabellings compose their half-edge and crossing equivalences.

                            @[simp]
                            theorem TauCeti.PDCode.mirror_relabel {n m : ℕ} (D : PDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) :
                            (D.relabel half cross).mirror = D.mirror.relabel half cross

                            Reflection commutes with relabelling.

                            The one-crossing knot diagram: a single kink. Its single crossing has the slot pair 1-3 as its over-strand, and its two arcs join slot 0 to slot 1 and slot 2 to slot 3, so the strand doubles back on itself, as in the first Reidemeister move.

                            Equations
                            • One or more equations did not get rendered due to their size.
                            Instances For
                              @[simp]

                              The kink numbers its half-edges by their crossing slots.

                              @[simp]

                              The kink has no crossing-free component.

                              @[simp]

                              The over-strand of the kink is the slot pair 1-3.

                              The half-edge of the kink in a given crossing slot is that slot.

                              @[simp]

                              The two arcs of the kink join each slot of the over-pair to the slot preceding it.

                              theorem TauCeti.OrientedPDCode.orientation_crossing_of_add_two_eq {n : ℕ} (D : OrientedPDCode n) (i : Fin n) {s t : Fin 4} (hst : s + 2 = t) :

                              The orientation reverses between two opposite slots s and t = s + 2 of a crossing.

                              The sign of crossing i:1 if the crossing is right-handed and -1 if it is left-handed, as in Lickorish, Chapter 1. The slots are read counterclockwise in the oriented plane and orientation is true at the half-edges where the strands leave the crossing. The crossing is right-handed when a counterclockwise quarter turn takes the direction of the over-strand to that of the under-strand; in terms of the code, the sign is 1 exactly when overPair i records whether the orientations at slots 0 and 1 differ.

                              Equations
                              Instances For

                                The defining equation for an oriented crossing sign.

                                @[simp]

                                A crossing is positive exactly when its orientation parity agrees with its over-strand.

                                @[simp]

                                A crossing is negative exactly when its orientation parity disagrees with its over-strand.

                                Every crossing sign is either positive or negative.

                                The writhe of an oriented code is the sum of its crossing signs.

                                Equations
                                Instances For

                                  Expand the writhe as the sum of the crossing signs.

                                  Reverse every component orientation while preserving the underlying unoriented code.

                                  Equations
                                  • One or more equations did not get rendered due to their size.
                                  Instances For
                                    @[simp]

                                    Forgetting orientation after reversal leaves the underlying code unchanged.

                                    @[simp]

                                    Reversal complements the direction at every half-edge.

                                    @[simp]

                                    Reversal complements the orientations of all crossing-free components.

                                    @[simp]

                                    Reversing every component orientation preserves each crossing sign.

                                    @[simp]

                                    Reversing every component orientation twice gives the original code.

                                    Reflect an oriented diagram, preserving all component orientations.

                                    Equations
                                    • One or more equations did not get rendered due to their size.
                                    Instances For
                                      @[simp]

                                      Forgetting orientation after reflection gives reflection of the underlying code.

                                      @[simp]

                                      Reflection preserves the orientation of every arc.

                                      @[simp]

                                      Reflection preserves the oriented crossing-free components.

                                      @[simp]

                                      Reflection reverses the sign of every crossing.

                                      @[simp]

                                      Reflecting an oriented PD-code twice gives the original code.

                                      def TauCeti.OrientedPDCode.relabel {n m : ℕ} (D : OrientedPDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) :

                                      Relabel half-edges and crossings along equivalences of their finite index types.

                                      Equations
                                      • One or more equations did not get rendered due to their size.
                                      Instances For
                                        @[simp]
                                        theorem TauCeti.OrientedPDCode.relabel_toPDCode {n m : ℕ} (D : OrientedPDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) :
                                        (D.relabel half cross).toPDCode = D.relabel half cross

                                        Forgetting orientation after relabelling gives relabelling of the underlying code.

                                        @[simp]
                                        theorem TauCeti.OrientedPDCode.relabel_orientation {n m : ℕ} (D : OrientedPDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) (h : Fin (4 * m)) :
                                        (D.relabel half cross).orientation h = D.orientation (half.symm h)

                                        Relabelling transports arc orientations along the half-edge equivalence.

                                        @[simp]

                                        Relabelling leaves crossing-free oriented components unchanged.

                                        @[simp]
                                        theorem TauCeti.OrientedPDCode.crossingSign_relabel {n m : ℕ} (D : OrientedPDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) (i : Fin m) :
                                        (D.relabel half cross).crossingSign i = D.crossingSign (cross.symm i)

                                        The crossing sign after relabelling is read at the old crossing name.

                                        @[simp]

                                        Relabelling by identity equivalences does nothing.

                                        @[simp]
                                        theorem TauCeti.OrientedPDCode.relabel_relabel {n m : ℕ} (D : OrientedPDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) {r : ℕ} (half₂ : Fin (4 * m) ≃ Fin (4 * r)) (cross₂ : Fin m ≃ Fin r) :
                                        (D.relabel half cross).relabel half₂ cross₂ = D.relabel (half.trans half₂) (cross.trans cross₂)

                                        Consecutive relabellings compose their half-edge and crossing equivalences.

                                        @[simp]
                                        theorem TauCeti.OrientedPDCode.writhe_relabel {n m : ℕ} (D : OrientedPDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) :
                                        (D.relabel half cross).writhe = D.writhe

                                        Relabelling matches the crossings bijectively, so it preserves the writhe.

                                        @[simp]

                                        Reflection negates the writhe.

                                        @[simp]

                                        Reversing every component orientation preserves the writhe.

                                        @[simp]

                                        Reflection and orientation reversal commute.

                                        @[simp]
                                        theorem TauCeti.OrientedPDCode.mirror_relabel {n m : ℕ} (D : OrientedPDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) :
                                        (D.relabel half cross).mirror = D.mirror.relabel half cross

                                        Reflection commutes with relabelling.

                                        @[simp]
                                        theorem TauCeti.OrientedPDCode.reverse_relabel {n m : ℕ} (D : OrientedPDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) :
                                        (D.relabel half cross).reverse = D.reverse.relabel half cross

                                        Orientation reversal commutes with relabelling.

                                        Reflect a framed oriented diagram, negating its Seifert-relative framing coefficients.

                                        Equations
                                        • One or more equations did not get rendered due to their size.
                                        Instances For
                                          @[simp]

                                          Forgetting framing after reflection gives reflection of the underlying oriented code.

                                          @[simp]

                                          Reflection negates the Seifert-relative framing coefficient at every half-edge.

                                          @[simp]

                                          Reflection preserves orientation and negates framing on every crossing-free component.

                                          @[simp]

                                          Reflecting a framed oriented PD-code twice gives the original code.

                                          def TauCeti.FramedOrientedPDCode.relabel {n m : ℕ} (D : FramedOrientedPDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) :

                                          Relabel half-edges and crossings along equivalences of their finite index types while transporting the framing function.

                                          Equations
                                          • One or more equations did not get rendered due to their size.
                                          Instances For
                                            @[simp]
                                            theorem TauCeti.FramedOrientedPDCode.relabel_toOrientedPDCode {n m : ℕ} (D : FramedOrientedPDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) :
                                            (D.relabel half cross).toOrientedPDCode = D.relabel half cross

                                            Forgetting framing after relabelling gives relabelling of the underlying oriented code.

                                            @[simp]
                                            theorem TauCeti.FramedOrientedPDCode.relabel_framing {n m : ℕ} (D : FramedOrientedPDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) (h : Fin (4 * m)) :
                                            (D.relabel half cross).framing h = D.framing (half.symm h)

                                            Relabelling transports framing values along the half-edge equivalence.

                                            @[simp]

                                            Relabelling preserves all crossing-free orientation-framing pairs.

                                            @[simp]

                                            Relabelling by identity equivalences does nothing to a framed oriented code.

                                            @[simp]
                                            theorem TauCeti.FramedOrientedPDCode.relabel_relabel {n m : ℕ} (D : FramedOrientedPDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) {r : ℕ} (half₂ : Fin (4 * m) ≃ Fin (4 * r)) (cross₂ : Fin m ≃ Fin r) :
                                            (D.relabel half cross).relabel half₂ cross₂ = D.relabel (half.trans half₂) (cross.trans cross₂)

                                            Consecutive framed relabellings compose their half-edge and crossing equivalences.

                                            Reverse every component orientation of a framed code, preserving all framing integers.

                                            Equations
                                            • One or more equations did not get rendered due to their size.
                                            Instances For
                                              @[simp]

                                              Forgetting framing after reversal gives reversal of the underlying oriented code.

                                              @[simp]

                                              Reversal preserves the framing at every half-edge.

                                              @[simp]

                                              Reversal complements only the orientation in each crossing-free framing pair.

                                              @[simp]

                                              Reversing every component orientation twice gives the original framed code.

                                              @[simp]

                                              Reflection and orientation reversal commute.

                                              @[simp]
                                              theorem TauCeti.FramedOrientedPDCode.mirror_relabel {n m : ℕ} (D : FramedOrientedPDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) :
                                              (D.relabel half cross).mirror = D.mirror.relabel half cross

                                              Reflection commutes with relabelling.

                                              @[simp]
                                              theorem TauCeti.FramedOrientedPDCode.reverse_relabel {n m : ℕ} (D : FramedOrientedPDCode n) (half : Fin (4 * n) ≃ Fin (4 * m)) (cross : Fin n ≃ Fin m) :
                                              (D.relabel half cross).reverse = D.reverse.relabel half cross

                                              Orientation reversal commutes with relabelling.

                                              Multisets of orientations are equivalent to zero-crossing oriented PD-codes.

                                              Equations
                                              • One or more equations did not get rendered due to their size.
                                              Instances For
                                                @[simp]

                                                The inverse of unlinkEquiv reads off the orientations of the crossing-free components.

                                                @[simp]

                                                The empty diagram has no crossing-free components.

                                                A crossing-free oriented unknot with the specified choice of orientation.

                                                Equations
                                                Instances For
                                                  @[simp]

                                                  The oriented unknot retains its specified component orientation.

                                                  theorem TauCeti.OrientedPDCode.unknot_ne_empty (orientation : Bool) :
                                                  unknot orientation ≠ empty

                                                  A crossing-free oriented circle is distinct from the empty diagram.

                                                  Distinct orientation choices give distinct crossing-free circle presentations.

                                                  @[simp]

                                                  Reflection fixes every zero-crossing oriented PD-code.

                                                  The kink TauCeti.PDCode.kink, oriented so that its crossing is positive.

                                                  This concrete code is a semantic witness that the presentation permits a genuine positive crossing, not only crossing-free links.

                                                  Equations
                                                  • One or more equations did not get rendered due to their size.
                                                  Instances For
                                                    @[simp]

                                                    The arcs of positiveKink point away from the crossing exactly at slots 1 and 2.

                                                    @[simp]

                                                    The positive kink has no crossing-free components.

                                                    @[simp]

                                                    The crossing of positiveKink has positive sign.