The Obligatory Contour Principle #
The Obligatory Contour Principle (OCP) bans two identical adjacent autosegments on one tier.
Here it is categorical and bans strict identity, either on the tier itself (IsClean, after
Leben and McCarthy) or on a projection of it (IsCleanOn, after Chandlee and Jardine). Fusion,
collapse, repairs a violation by merging each run of identical elements into one; it is
List.destutter (· ≠ ·), a retraction onto the clean tiers. mergeAppend concatenates two
words and merges identical elements at the seam only; the collapse of a concatenation is the
merging append of the collapses. The run index runIdx tracks where each position lands under
fusion. Phonology/Subregular/OCP.lean shows that the
constraint is tier-based strictly local and that fusion is input strictly local.
The gradient OCP of Frisch, Pierrehumbert and Broe, which scales with the similarity of the two consonants, is a different object and lives in that paper's study.
Main definitions #
OCP.IsClean,OCP.IsCleanOn: no two identical adjacent elements, on the tier or on a projection of it.OCP.collapse: the fusion repair.OCP.mergeAppend: concatenation that merges identical elements at the seam.OCP.runIdx: the index of the run containing a position.
Main statements #
OCP.collapse_eq_self_iff:collapsefixes exactly the clean tiers.OCP.collapse_append: the collapse of a concatenation is the merging append of the collapses.OCP.runIdx_append_left,OCP.runIdx_append_right: the run indices of a concatenation.
References #
The constraint #
A tier is OCP-clean when no two adjacent elements are identical. This is weaker than
List.Nodup, since [1, 2, 1] is clean. It is a reducible alias of List.IsChain (· ≠ ·), so
that API applies.
Equations
- OCP.IsClean xs = List.IsChain (fun (x1 x2 : α) => x1 ≠ x2) xs
Instances For
The OCP on the tier projected from xs by keeping the p-elements and reading them
through proj. Flat IsClean is the case p = ⊤, proj = id.
Equations
- OCP.IsCleanOn p proj xs = OCP.IsClean (List.map proj (List.filter (fun (a : α) => decide (p a)) xs))
Instances For
Equations
- OCP.decidableIsClean xs = xs.instDecidableIsChainOfDecidableRel
Equations
- OCP.decidableIsCleanOn p proj x✝ = OCP.decidableIsCleanOn._aux_1 p proj x✝
The fusion repair #
The fusion repair merges each maximal run of identical adjacent elements into one.
Equations
- OCP.collapse xs = List.destutter (fun (x1 x2 : α) => x1 ≠ x2) xs
Instances For
collapse fuses a constant run into its single autosegment.
collapse fixes exactly the OCP-clean tiers, so with collapse_clean it is a retraction
onto them.
Normal-form lemmas #
The output of the fusion repair is a sublist of its input.
Merging at a seam #
Appending with the seam merged drops the head of the second word when it repeats the last element of the first; this is Jardine and Heinz's concatenation on a single tier. On clean words it is the collapse of the concatenation, and the collapse of any concatenation is the merging append of the collapses.
Append ys to xs, dropping the head of ys when it repeats the last element of xs.
Equations
- OCP.mergeAppend xs ys = if xs.getLast? = ys.head? then xs ++ ys.tail else xs ++ ys
Instances For
The position at which ys starts in mergeAppend xs ys.
Equations
- OCP.mergeOffset xs ys = if xs.getLast? = ys.head? then xs.length - 1 else xs.length
Instances For
The position in mergeAppend xs ys of position p of xs ++ ys.
Equations
- OCP.mergeIdx xs ys p = if p < xs.length then p else OCP.mergeOffset xs ys + (p - xs.length)
Instances For
On clean words, merging at the seam is collapsing the concatenation.
The OCP congruence. The collapse of a concatenation is the merging append of the collapses.
Merging at the seam keeps clean words clean.
The run-index map #
The run index of position k in xs is the 0-based index of the run of identical
elements containing it, one less than the number of runs in xs.take (k + 1).
Equations
- OCP.runIdx xs k = (OCP.collapse (List.take (k + 1) xs)).length - 1
Instances For
Later positions sit in the same or later runs.
An in-bounds position has an in-bounds run index in the collapsed tier.
On a constant tier every position lies in the single run.
Run indices of a concatenation #
A position of xs ++ ys keeps its run index in xs when it lies in xs; a position in ys
moves to its run index in ys, offset by where collapse ys starts in the merging append of
the collapses.
The run index of a prefix position is unaffected by a right append.
The run index of a suffix position is its run index in the suffix, offset by where the collapsed suffix starts in the merging append of the collapses.