Non-crossing constraint for two-layer association lines #
A Finset (ι × κ) of links between two ordered tiers is non-crossing
when k₁ < k₂ → i₁ ≤ i₂ for any two links (k₁, i₁), (k₂, i₂) — i.e. the
index coordinates monovary, which in a two-layer drawing is exactly the
absence of crossing segments; equivalently (over linear tiers), the
componentwise order is total on the link set, [YJ15]'s edge-order
axiom. This is the discrete-index
[Gol76] / [Sag86] No-Crossing Constraint ([Sag88] derives
it from association-as-temporal-overlap) and the canonical
filter on autosegmental GEN.
Main definitions #
IsNonCrossing links: the link set monovaries ([Preorder]-general).Crosses a b/IndexCrosses links p: two links cross;pcrosses some link already inlinks— the decidable GEN filter.leftBound links m/rightBound links m/window links m: the nearest index linked on either side of an upper nodem, and the interval between them.
Main results #
isNonCrossing_insert_iff_not_indexCrosses: a candidate may be added iff it crosses nothing (IsNonCrossing.insert_of_not_indexCrossesis the GEN direction).isNonCrossing_image/IsNonCrossing.image_monotone:IsNonCrossingcommutes withFinset.image, and survives monotone reindexing of the upper coordinate.isNonCrossing_insert_iff_mem_window: a candidate may be added iff its index lies in its node's window;IsNonCrossing.union_of_leftBound/union_of_rightBound: spreading to the nearest index on one side never crosses.
References #
Set-level non-crossing property (via mathlib MonovaryOn) #
The link set has no crossings: its two index coordinates monovary.
Equations
- Autosegmental.IsNonCrossing links = MonovaryOn Prod.snd Prod.fst ↑links
Instances For
IsNonCrossing in elementary form.
A pair is non-crossing iff its two links agree in tier- and backbone-order.
A subset of a non-crossing link set is non-crossing.
Inserting p keeps non-crossing iff p crosses no existing link: the
insert-algebra form, Set.pairwise_insert specialised to IsNonCrossing
via monovaryOn_insert.
A union is non-crossing iff each part is and no link of one crosses a link of the
other, the Set.pairwise_union shape.
Equations
- Autosegmental.instDecidableIsNonCrossingOfDecidableLTOfDecidableLE = decidable_of_iff (∀ l₁ ∈ links, ∀ l₂ ∈ links, l₁.1 < l₂.1 → l₁.2 ≤ l₂.2) ⋯
Reindexing along Finset.image #
IsNonCrossing transports across a Finset.image: the image link set is
non-crossing iff the index coordinates monovary after reindexing by f. The
Finset companion of monovaryOn_image, and the single place the definition
is unfolded against an image.
Pushing a non-crossing link set forward along a monotone map on the upper
(first) coordinate keeps it non-crossing: the autosegmental analogue of
SimpleGraph.map along a monotone vertex map. The upper index needs a
LinearOrder (the run-collapse domain is ℕ) so that ρ reflects <.
Relational composition through a shared tier #
Association relations compose through a shared middle tier — the Finset
companion of SetRel.comp. Non-crossing is not closed under composition:
fan-in followed by fan-out at a single middle position (an autosegment
multiply-linked from above whose position multiply-links onward) composes to a
crossing — see the counterexample below. It is closed when the middle tier does
not fan through, in either direction: IsNonCrossing.relComp_of_injOn_fst
(no fan-out) and IsNonCrossing.relComp_of_injOn_snd (no fan-in).
Relational composition of link sets through a shared middle tier.
Equations
- Autosegmental.relComp R S = Finset.image (fun (p : (ι × κ) × κ × μ) => (p.1.1, p.2.2)) ({p ∈ R ×ˢ S | p.1.2 = p.2.1})
Instances For
Composition preserves non-crossing when the middle tier does not fan out:
S is functional on middle positions (Set.InjOn Prod.fst), so a middle tie
forces equal outputs.
Composition preserves non-crossing when the middle tier does not fan in:
R is injective onto middle positions (Set.InjOn Prod.snd), so a middle tie
contradicts the strict order on inputs.
The crossing relation and the GEN filter #
Two links cross: as a pair they fail to be non-crossing (equivalently their
endpoints straddle in opposite tier- and backbone-order — crosses_iff).
Equations
- Autosegmental.Crosses a b = ¬Autosegmental.IsNonCrossing {a, b}
Instances For
p crosses some link already in links — the decidable GEN filter.
Equations
- Autosegmental.IndexCrosses links p = ∃ l ∈ links, Autosegmental.Crosses p l
Instances For
Equations
- Autosegmental.instDecidableCrossesOfDecidableLTOfDecidableLE = { decide := !decide (Autosegmental.IsNonCrossing {a, b}), reflects_decide := ⋯ }
Equations
- Autosegmental.instDecidableIndexCrossesOfDecidableLTOfDecidableLE = { decide := decide (∃ (a : ι × κ) (_ : a ∈ links), Autosegmental.Crosses p a), reflects_decide := ⋯ }
p crosses nothing iff it is pairwise non-crossing with every existing link.
Adding p keeps non-crossing iff it crosses no existing link: the GEN-filter
form of isNonCrossing_insert_iff.
GEN direction of isNonCrossing_insert_iff_not_indexCrosses.
Two links cross iff one link's endpoints straddle the other's in opposite order.
IndexCrosses in elementary index-ordering form.
The window of a node #
For an upper node m, leftIndices and rightIndices are the lower indices linked from
nodes left and right of m. In a non-crossing set every left index lies at or before every
right index, so the indices m may link to without crossing form an interval, its
window, from the nearest left index leftBound to the nearest right index rightBound:
isNonCrossing_insert_iff_mem_window is the GEN filter as an interval, and
IsNonCrossing.union_of_leftBound / union_of_rightBound are local spreading, to the
nearest linked index on one side, which never crosses.
The indices linked from nodes left of m.
Equations
- Autosegmental.leftIndices links m = Finset.image (fun (x : ι × κ) => x.2) ({x ∈ links | x.1 < m})
Instances For
The indices linked from nodes right of m.
Equations
- Autosegmental.rightIndices links m = Finset.image (fun (x : ι × κ) => x.2) ({x ∈ links | m < x.1})
Instances For
The nearest index linked from a node left of m.
Equations
- Autosegmental.leftBound links m = (Autosegmental.leftIndices links m).max
Instances For
The nearest index linked from a node right of m.
Equations
- Autosegmental.rightBound links m = (Autosegmental.rightIndices links m).min
Instances For
The indices m may link to without crossing.
Equations
- Autosegmental.window links m = {j : κ | Autosegmental.leftBound links m ≤ ↑j ∧ ↑j ≤ Autosegmental.rightBound links m}
Instances For
Equations
- Autosegmental.instDecidablePredMemSetWindow j = { decide := decide (Autosegmental.leftBound links m ≤ ↑j) && decide (↑j ≤ Autosegmental.rightBound links m), reflects_decide := ⋯ }
The GEN filter is membership in the window.
In a non-crossing set the window is an interval: every index linked left of m lies at
or before every index linked right of it.
The nearest left index lies in the window.
The nearest right index lies in the window.
Lines from any nodes to the nearest index linked left of each cross neither one another nor the links of a non-crossing set, so local spreading to the left is safe.
Lines from any nodes to the nearest index linked right of each cross neither one another nor the links of a non-crossing set, so local spreading to the right is safe.