Optimality Theory — Core Vocabulary #
OT-specific vocabulary layered on Core.Constraint.Evaluation. Provides
named constraints with a faithfulness/markedness distinction, convenience
constructors for building tableaux from ranked constraint lists, and factorial
typology computation.
Connection to Evaluation #
Core.Constraint.Evaluation provides the generic engine (LexLE, Tableau,
Tableau.optimal). This module adds OT-specific structure: constraint
families, named constraints, mkTableau for building tableaux from ranked
constraint lists, and factorial typology computation.
Constraint families in OT.
- faithfulness : ConstraintFamily
Faithfulness: penalizes deviation from the input.
- markedness : ConstraintFamily
Markedness: penalizes marked structures in the output.
Instances For
Equations
- Core.Constraint.OT.instDecidableEqConstraintFamily x✝ y✝ = if h : x✝.ctorIdx = y✝.ctorIdx then isTrue ⋯ else isFalse ⋯
Equations
Equations
- One or more equations did not get rendered due to their size.
Instances For
A named OT constraint with family classification.
eval c returns the number of violations candidate c incurs.
The name field is purely documentary — no evaluation function reads it.
It defaults to "" so constraints can be defined without a name when
the string label adds no information.
- name : String
- family : ConstraintFamily
- eval : C → ℕ
Instances For
Build a binary markedness constraint (violated → 1, otherwise 0).
Takes a Prop-valued predicate with [DecidablePred] so that callers
can use propositional equality (=) and other Prop predicates rather
than Bool-valued operators (==). Decidability is required to evaluate
the constraint on a candidate.
Equations
- Core.Constraint.OT.mkMark name P = { name := name, family := Core.Constraint.OT.ConstraintFamily.markedness, eval := fun (c : C) => if P c then 1 else 0 }
Instances For
Build a binary faithfulness constraint (violated → 1, otherwise 0).
Takes a Prop-valued predicate with [DecidablePred] so that callers
can use propositional equality (=) and other Prop predicates rather
than Bool-valued operators (==).
Equations
- Core.Constraint.OT.mkFaith name P = { name := name, family := Core.Constraint.OT.ConstraintFamily.faithfulness, eval := fun (c : C) => if P c then 1 else 0 }
Instances For
Build a gradient markedness constraint with a Nat-valued violation count.
Equations
- Core.Constraint.OT.mkMarkGrad name violations = { name := name, family := Core.Constraint.OT.ConstraintFamily.markedness, eval := violations }
Instances For
Build a gradient faithfulness constraint with a Nat-valued violation count.
Equations
- Core.Constraint.OT.mkFaithGrad name violations = { name := name, family := Core.Constraint.OT.ConstraintFamily.faithfulness, eval := violations }
Instances For
Pull a NamedConstraint D back along a candidate map f : C → D. The
name and family are inherited; the new eval composes the original
with the projection. Lets paper-specific carrier types reuse a
constraint defined on a more general carrier.
Equations
Instances For
The zero-violation set of a NamedConstraint over list candidates,
viewed as a Language α. Lets the OT-side eval = 0 predicate compose
with mathlib's Language.IsRegular and the project's
IsTierStrictlyLocal/IsBTC classifiers. The dot-notation form
c.zeroSet is the canonical access pattern.
Instances For
Build a ViolationProfile ranking.length from a ranked list of named
constraints. This is the fixed-length analog of the profile computation
inside mkTableau — use it to inspect or compare violation counts
outside a tableau context.
Equations
- Core.Constraint.OT.mkProfile ranking c = Core.Constraint.Evaluation.buildViolationProfile (fun (i : Fin ranking.length) (c : C) => (ranking.get i).eval c) c
Instances For
Create a ViolationProfile n from a List Nat literal.
The length proof defaults to by decide, so study files can write
readable profile comparisons without an explicit proof:
theorem t24a_profile : mkProfile ranking c = vpOfList [2, 2, 0] := by native_decide
Equations
- Core.Constraint.OT.vpOfList vs h = toLex fun (i : Fin n) => vs.get ⟨↑i, ⋯⟩
Instances For
All permutations of a list.
Equations
- Core.Constraint.OT.permutations [] = [[]]
- Core.Constraint.OT.permutations (x_1 :: xs) = List.flatMap (Core.Constraint.OT.insertEverywhere✝ x_1) (Core.Constraint.OT.permutations xs)
Instances For
Elements of any permutation of l are elements of l.
A permutation of constraints has the same elements, so any
con ∈ ranking for ranking ∈ permutations constraints satisfies
con ∈ constraints.
Build a Tableau C ranking.length from a candidate list and ranking.
Candidates are deduplicated via List.toFinset; profiles are
fixed-length ViolationProfile n built via buildViolationProfile.
Study files use this as:
(mkTableau candidates ranking h).optimal = {.winner}
where {.winner} is a Finset literal.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Candidates in mkTableau ... .optimal belong to the original list.
If any candidate has 0 violations on the top-ranked constraint, then every optimal candidate has 0 violations on it.
This is the structural backbone of constraint dominance: once a
faithfulness constraint (like MxBM-C) is promoted to the top of
the ranking, it forces all winners to satisfy it perfectly. Uses
ViolationProfile.le_apply_zero to extract the first component
of the lexicographic comparison.
∈ .optimal version of mkTableau_isOptimal_zero_first.
The zero ViolationProfile n is the minimum: 0 ≤ p for all p.
This is the structural reason that a candidate with zero violations
on every constraint wins under any ranking.
Proof: 0 ≤ p iff ¬(p < 0). Under Pi.Lex, p < 0 requires
∃ i, p i < 0 i, but 0 i = 0 and Nat has no negative values.
If a candidate in mkTableau has 0 violations on every constraint,
it is optimal.
If a candidate has 0 violations on every constraint in a set, it is optimal under every permutation of those constraints.
This is the structural backbone of adj_always_initial in Marco &
Rasin (2026): the uniform-initial adjective paradigm has [0,0,0,0]
on all four OP constraints, so it wins regardless of ranking. The
proof reduces to mkTableau_zero_isOptimal after using
permutations_subset to show that elements of a permutation are
elements of the original list.
For each permutation of constraints, compute the set of optimal
candidates as a Finset. Return the list of distinct optimal sets.
This is the core of OT factorial typology: the number of distinct optimal sets equals the number of language types predicted by the constraint set.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Number of distinct language types predicted by the factorial typology.
Equals |mkFactorialOptima|.
Equations
- Core.Constraint.OT.mkFactorialTypologySize candidates constraints h = (Core.Constraint.OT.mkFactorialOptima candidates constraints h).length