Floating autosegmental form (Goldsmith) #
Goldsmith-style autosegmental representation: tier elements (tones,
floating segments, features) sit on a tier above the segmental backbone,
connected by association lines (links). Multiple tier elements can
associate to one backbone position (forming contours); a tier element
with no associations is floating. Generic over both backbone type
S (the lower tier) and tier-value type T (the upper tier); tonal use
instantiates T := TRN, while non-tonal autosegmental work
([LK26]'s floating consonants, [Lie83]'s floating
features, [Zim17]'s floating moras and prosodic nodes)
chooses other T values.
Main definitions #
Link— an autosegmental link(tier-index, backbone-index).TierSpec T,SegSpec S— tier and backbone elements carrying morpheme membership viaMorphology.WordStructure.Morpheme(re-exported into this namespace).FloatingForm S T— autosegmental form with underlying/surface split.FloatingForm.IsAlive,IsLinked,IsFloating,IsTautomorphemic,Crosses— decidable predicates on tier elements and links.FloatingForm.deleteTierElem,insertLink,deleteLink— atomic GEN operations (paper subset).FloatingForm.gen— one-step GEN as aFinsetof candidate forms.FloatingForm.floatIndicator,linksTo,tierValues— indicator vectors for constraint evaluation.
Main results #
FloatingForm.gen_preserves_isPlanar— GEN is closed on the no-crossing WFC ([Gol76] / [Pul86]): every one-step candidate of a planar surface graph is itself planar.
Implementation notes #
A FloatingForm carries an immutable underlying state (the inherited
Graph: lower, upper, links) and a mutable surface state
(deletedTier, surfaceLinks); GEN modifies only the surface. A tier element
is floating iff it is alive (not deleted) and no surface link references it.
This multi-element-per-position encoding (vs. the prior tonalOverwrite) is what
[McPL26]'s *CROWD / *FALL constraints require.
gen is a paper-subset (delete tier element, insert/delete link; no
insert-and-associate or shift), filtered for no-crossing ([Gol76]). A
link is tautomorphemic when its tier element and backbone share a morpheme
(*TAUTDOCK, after [Wol07]).
Tier and link primitives #
Index into the upper tier.
Equations
Instances For
Index into the lower tier.
Equations
Instances For
An autosegmental link: tier element fst is associated to
backbone-position snd.
Equations
Instances For
Equations
- Autosegmental.instDecidableEqTierSpec.decEq { value := a, morpheme := a_1 } { value := b, morpheme := b_1 } = if h : a = b then h ▸ if h : a_1 = b_1 then h ▸ isTrue ⋯ else isFalse ⋯ else isFalse ⋯
Instances For
Equations
- Autosegmental.instReprTierSpec = { reprPrec := Autosegmental.instReprTierSpec.repr }
Equations
- One or more equations did not get rendered due to their size.
Instances For
A segmental backbone element: segment plus morpheme membership.
Generic over the segment type S.
- seg : S
- morpheme : Morpheme
Instances For
Equations
- Autosegmental.instDecidableEqSegSpec.decEq { seg := a, morpheme := a_1 } { seg := b, morpheme := b_1 } = if h : a = b then h ▸ if h : a_1 = b_1 then h ▸ isTrue ⋯ else isFalse ⋯ else isFalse ⋯
Instances For
Equations
- Autosegmental.instReprSegSpec = { reprPrec := Autosegmental.instReprSegSpec.repr }
Equations
- One or more equations did not get rendered due to their size.
Instances For
FloatingForm #
FloatingForm S T is an autosegmental form with segmental backbone
of type S and tier-value type T. Tonal use chooses T := TRN;
non-tonal autosegmental work chooses other T values
([LK26], [Lie83]). The OT-style
bookkeeping (deletedTier, surfaceLinks vs underlying links) is
language-independent.
An autosegmental form: extends Graph (TierSpec T) (SegSpec S)
with OT-style surface bookkeeping. The inherited Graph is the
underlying representation; deletedTier and surfaceLinks
track the surface state separately.
- upper : LabeledTuple (TierSpec T)
- lower : LabeledTuple (SegSpec S)
- links : Finset (ℕ × ℕ)
- deletedTier : Finset TierIdx
SURFACE deletion set on the upper tier (current state).
- surfaceLinks : Finset Link
SURFACE association lines (current state). May differ from the inherited
links(the underlying associations).
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Hides the Finset fields (mathlib's Finset.Repr is unsafe) and
prints only segments and underlying tier elements; debug-only.
Equations
- One or more equations did not get rendered due to their size.
Surface graph (derived view) #
The surface graph: same tiers as the underlying graph but with
surfaceLinks in place of links. Makes the underlying/surface
duality explicit — both states are Graphs sharing tier data.
Equations
- f.surfaceGraph = { upper := f.upper, lower := f.lower, links := f.surfaceLinks }
Instances For
Construction #
Construct an input form: surface state mirrors underlying state, nothing deleted, all underlying links intact.
Equations
- Autosegmental.FloatingForm.mkInput lower upper links = { upper := LabeledTuple.ofList upper, lower := LabeledTuple.ofList lower, links := links, deletedTier := ∅, surfaceLinks := links }
Instances For
Morphemic structure #
The morpheme of the k-th upper-tier element, or none if out of range.
Equations
- f.upperMorpheme? k = Option.map Autosegmental.TierSpec.morpheme (f.upper.get? k)
Instances For
The morpheme of the i-th lower-tier element, or none if out of range.
Equations
- f.lowerMorpheme? i = Option.map Autosegmental.SegSpec.morpheme (f.lower.get? i)
Instances For
Every morpheme occurring on either tier.
Equations
- f.morphemes = (List.map Autosegmental.SegSpec.morpheme f.lower.toList).toFinset ∪ (List.map Autosegmental.TierSpec.morpheme f.upper.toList).toFinset
Instances For
Predicates on tier elements and links #
The upper-tier element at index k is alive (not deleted). The structural
primitive; IsDeleted is its negation.
Equations
- f.IsAlive k = (k ∉ f.deletedTier)
Instances For
The upper-tier element at index k is deleted. Sugar for ¬ IsAlive.
Instances For
The upper-tier element at index k is linked to a backbone position
on the surface.
Equations
- f.IsLinked k = ∃ l ∈ f.surfaceLinks, l.1 = k
Instances For
The upper-tier element at index k is floating: in-bounds, alive (not
deleted), and unlinked. The in-bounds guard mirrors the substrate's
Graph.IsFloatingUpper, so out-of-range indices are not spuriously
floating.
Instances For
A surface link (k, i) is tautomorphemic iff its upper- and lower-tier
endpoints share a morpheme. Out-of-range indices on either side make this
false.
Equations
- f.IsTautomorphemic l = (f.upperMorpheme? l.1 = f.lowerMorpheme? l.2 ∧ (f.upper.get? l.1).isSome = true)
Instances For
Faithfulness: surface vs underlying #
A surface link absent underlyingly — inserted by GEN (DEP / *TAUTDOCK source).
Equations
- f.IsInsertedLink l = (l ∈ f.surfaceLinks ∧ l ∉ f.links)
Instances For
An underlying link absent on the surface — deleted by GEN (MAX source).
Equations
- f.IsDeletedLink l = (l ∈ f.links ∧ l ∉ f.surfaceLinks)
Instances For
Atomic GEN operations #
Delete the underlying upper-tier element at index k. Cascades to remove
any surface link referencing it.
Equations
- f.deleteTierElem k = { toGraph := f.toGraph, deletedTier := insert k f.deletedTier, surfaceLinks := {l ∈ f.surfaceLinks | l.1 ≠ k} }
Instances For
Insert a surface link (k, i).
Equations
- f.insertLink k i = { toGraph := f.toGraph, deletedTier := f.deletedTier, surfaceLinks := insert (k, i) f.surfaceLinks }
Instances For
Delete the surface link (k, i).
Equations
- f.deleteLink k i = { toGraph := f.toGraph, deletedTier := f.deletedTier, surfaceLinks := f.surfaceLinks.erase (k, i) }
Instances For
Well-formedness: no crossing lines #
A candidate link (k, i) would cross an existing surface link.
Wraps the substrate IndexCrosses on the candidate link (k, i);
IsNonCrossing (via mathlib's MonovaryOn) provides the set-level
NCC and inherits mathlib's lemma library.
Equations
- f.Crosses k i = Autosegmental.IndexCrosses f.surfaceLinks (k, i)
Instances For
GEN: one-step candidate generation #
One-step GEN: the faithful candidate, deleting each alive tone, and (for each FLOATING tone) inserting a link to each TBU that doesn't cross an existing link. One operation per step, after [McCMS12]; a subset of [McPL26]'s operation set (omits insert-and-associate and shift). The no-crossing filter ([Gol76]) enforces well-formedness: without it a floating tone could dock across an intervening linked tone.
Equations
- One or more equations did not get rendered due to their size.
Instances For
GEN preserves the no-crossing WFC ([Gol76] / [Pul86]).
If the surface graph is planar, every one-step GEN candidate is too: deletes
shrink the surface link set (IsNonCrossing.subset), and each inserted link
passed the ¬ Crosses filter (IsNonCrossing.insert_of_not_indexCrosses).
So gen is closed on the structural well-formedness condition.
Indicator vectors for constraint evaluation #
Indicator vector of floating upper-tier elements, in tier order: entry k
is 1 iff upper[k] is currently floating, else 0. Drives directional
floating constraints (e.g. *FLOAT).
Equations
- f.floatIndicator = List.map (fun (k : Autosegmental.TierIdx) => if f.IsFloating k then 1 else 0) (List.range f.upper.len)
Instances For
Upper-tier elements surface-linked to backbone position i, in tier order
(smallest index first). List.range-based so the result is naturally sorted
and reduces under kernel decide (avoiding Finset.sort, which doesn't
unfold structurally).
Equations
- f.linksTo i = List.filter (fun (k : Autosegmental.TierIdx) => decide ((k, i) ∈ f.surfaceLinks)) (List.range f.upper.len)
Instances For
Sequence of tier values linked to backbone position i, in tier
order.
Equations
- f.tierValues i = List.filterMap (fun (k : ℕ) => Option.map Autosegmental.TierSpec.value (f.upper.get? k)) (f.linksTo i)
Instances For
Tier and morpheme subsequences #
Indices of alive (non-deleted) underlying upper-tier elements, in tier
order; List.range-based so it reduces under kernel decide.
Equations
- f.aliveTierIdxs = List.filter (fun (k : Autosegmental.TierIdx) => decide (f.IsAlive k)) (List.range f.upper.len)
Instances For
Lower-tier (backbone) indices belonging to morpheme m, in order.
Out-of-range indices are excluded by construction.
Equations
- f.segsOfMorpheme m = List.filter (fun (i : Autosegmental.SegIdx) => decide (f.lowerMorpheme? i = some m)) (List.range f.lower.len)
Instances For
Position counts #
Count upper-tier positions satisfying decidable p. List.range-based so it
reduces under kernel decide (avoiding Finset pipelines).
Equations
- f.countUpper p = List.countP (fun (k : Autosegmental.TierIdx) => decide (p k)) (List.range f.upper.len)
Instances For
Count lower-tier (backbone) positions satisfying decidable p.
Equations
- f.countLower p = List.countP (fun (i : Autosegmental.SegIdx) => decide (p i)) (List.range f.lower.len)