Constraint Evaluation #
@cite{erlewine-2016} @cite{kratzer-1991}
Unified framework for constraint-based candidate evaluation, supporting two comparison modes:
Lexicographic (Optimality Theory): constraints are strictly ranked; the first constraint where candidates differ determines the winner. Used in phonology (@cite{prince-smolensky-1993}/2004) and syntactic competition.
Subset inclusion (Satisfaction ordering): a candidate is at least as good as another iff it satisfies every criterion the other satisfies. Used in @cite{kratzer-1991}'s modal semantics (see
SatisfactionOrdering.lean).
Both select optimal candidates from a set. They differ in comparison:
LexLE yields a total preorder (OT always picks a winner); SatLE yields
a preorder (incomparable candidates possible, as in Kratzer's semantics).
Architecture #
Each comparison is a decidable Prop relation (LexLE, SatLE, LexLT).
Decidable instances are defined by structural recursion, delegating to
standard combinators (And.decidable, Or.decidable). Tableau C n
provides the Finset-based OT tableau with ViolationProfile n profiles;
study files use mkTableau (in Core.Constraint.OT) for concrete evaluation.
Algebraic Structure — Violation Semiring #
Following @cite{riggle-2009}, violation profiles form a commutative semiring (the "violation semiring") with two operations:
- ⊎ (merge): componentwise addition of violation counts — combining
violations from multiple constraints. This is the
AddCommMonoid. - ⊗ (choose winner):
minunder harmonic inequality — selecting the more harmonic candidate. This isminfrom theLinearOrder.
The compatibility axiom (add_le_add_left) is Riggle's distributivity:
adding violations to both candidates preserves which one wins. This is
the structural property that makes OT optimization decomposable — every
subpath of an optimal path is itself optimal (Dijkstra's principle).
ViolationProfile n carries a LinearOrder (the ⊗ operation), an
AddCommMonoid (the ⊎ operation), and IsOrderedAddMonoid (the
compatibility axiom). Together, these encode Riggle's violation semiring
as a standard mathlib ordered monoid.
Different OT variants correspond to different ordered monoids on the same carrier: classical OT uses lexicographic order; Harmonic Grammar uses weighted-sum order (the standard tropical semiring).
Order Instances #
Variable-length (LexProfile, SatProfile): wrap List Nat with
Preorder instances. These are the weakest correct structures — LexLE
on variable-length lists is a preorder but not a partial order
(trailing-zero ambiguity).
Fixed-length (ViolationProfile n, SatViolationProfile n): wrap
Fin n → Nat with full LinearOrder (lexicographic) or Preorder
(satisfaction). Fixing the length eliminates the trailing-zero ambiguity,
upgrading LexLE to a linear order: reflexive, transitive,
antisymmetric, and total.
Tableau C n is a Finset-based OT tableau with ViolationProfile n
profiles. Optimality always exists via Finset.exists_min_image.
Connection to SatisfactionOrdering #
Core.SatisfactionOrdering.SatisfactionOrdering is the special case where
violations are binary (0 = satisfied, ≥1 = violated) and comparison uses
subset inclusion (SatLE). A SatisfactionOrdering with criteria
[c₁,..., cₙ] induces the profile fun a => [if satisfies a c₁ then 0 else 1,..., if satisfies a cₙ then 0 else 1], and atLeastAsGood
coincides with SatLE on this profile.
Lexicographic ≤ on violation profiles.
LexLE a b holds iff a is at least as harmonic as b — at the first
position where profiles differ, a has fewer violations. Missing entries
are implicitly 0.
Equations
- Core.Constraint.Evaluation.LexLE [] x✝ = True
- Core.Constraint.Evaluation.LexLE (a :: as) [] = (a = 0 ∧ Core.Constraint.Evaluation.LexLE as [])
- Core.Constraint.Evaluation.LexLE (a :: as) (b :: bs) = (a < b ∨ a = b ∧ Core.Constraint.Evaluation.LexLE as bs)
Instances For
Subset-inclusion ≤ on violation profiles.
SatLE a b holds iff every constraint that b satisfies (has 0
violations), a also satisfies. This is a preorder (reflexive,
transitive) but not a partial order on List Nat — non-zero values
are interchangeable (e.g., SatLE [1] [2] and SatLE [2] [1] both
hold). On binary {0,1} profiles it becomes a partial order.
Unlike LexLE, SatLE is not total — incomparable candidates are
possible. This is @cite{kratzer-1991}'s ordering on worlds relative
to a premise set.
Equations
- Core.Constraint.Evaluation.SatLE [] x✝ = True
- Core.Constraint.Evaluation.SatLE (a :: as) [] = (a = 0 ∧ Core.Constraint.Evaluation.SatLE as [])
- Core.Constraint.Evaluation.SatLE (a :: as) (b :: bs) = ((b ≠ 0 ∨ a = 0) ∧ Core.Constraint.Evaluation.SatLE as bs)
Instances For
Strict lexicographic <.
Equations
Instances For
Equations
- Core.Constraint.Evaluation.instDecidableLexLE [] x✝ = isTrue ⋯
- Core.Constraint.Evaluation.instDecidableLexLE (a :: as) [] = Core.Constraint.Evaluation.instDecidableLexLE._aux_1 a as (Core.Constraint.Evaluation.instDecidableLexLE as [])
- Core.Constraint.Evaluation.instDecidableLexLE (a :: as) (b :: bs) = Core.Constraint.Evaluation.instDecidableLexLE._aux_3 a as b bs (Core.Constraint.Evaluation.instDecidableLexLE as bs)
Equations
- Core.Constraint.Evaluation.instDecidableSatLE [] x✝ = isTrue ⋯
- Core.Constraint.Evaluation.instDecidableSatLE (a :: as) [] = Core.Constraint.Evaluation.instDecidableSatLE._aux_1 a as (Core.Constraint.Evaluation.instDecidableSatLE as [])
- Core.Constraint.Evaluation.instDecidableSatLE (a :: as) (b :: bs) = Core.Constraint.Evaluation.instDecidableSatLE._aux_3 a as b bs (Core.Constraint.Evaluation.instDecidableSatLE as bs)
Lexicographic ≤ is reflexive.
Satisfaction ≤ is reflexive.
Lexicographic ≤ is total for equal-length profiles: OT always
determines a winner (modulo ties). Key difference from SatLE.
SatLE is NOT total: candidates can be incomparable when each
satisfies a constraint the other violates.
LexLE [] b holds for any b: the empty profile is vacuously
at least as harmonic as any profile.
Characterization of LexLE (x :: xs) []: all entries must be zero.
Lexicographic ≤ is transitive. Together with lexLE_refl and
lexLE_total, this makes LexLE a total preorder on
equal-length profiles — the correct algebraic structure for
OT harmony ordering.
Lexicographic < is irreflexive.
Lexicographic ≤ is antisymmetric on equal-length profiles: if two profiles of the same length are mutually ≤, they are equal.
This fails on List Nat in general (LexLE [] [0] and LexLE [0] []
both hold, but [] ≠ [0]) — the equal-length precondition eliminates
the trailing-zero ambiguity that makes LexLE merely a preorder.
A non-empty list has a minimum element under LexLE, provided all
profiles have equal length. This is the key ingredient for
optimal_nonempty: OT always picks at least one winner.
SatLE [] b holds for any b: the empty profile vacuously
satisfies the inclusion condition.
Characterization of SatLE (x :: xs) []: all entries must be zero.
Characterization of SatLE (x :: xs) (y :: ys): if y is satisfied
(zero) then x must also be satisfied, and the tails must be ordered.
Satisfaction ≤ is transitive. Together with satLE_refl, this
makes SatLE a preorder on violation profiles. Unlike LexLE,
SatLE is NOT antisymmetric on List Nat (see satLE_not_antisymm)
— it IS antisymmetric on binary {0,1} profiles, where it becomes a
partial order.
@cite{blutner-2000}'s blocking relation lives at maximum generality in
Core/Constraint/Superoptimal.lean as the Set-valued
Blocks profile S p (Prop, decidable on Finset witnesses via
Blocks.decidableOnFinset). The legacy List-based IsBlocked/blocked
pair was retired at 0.230.570 in favour of the Set/Finset substrate +
superoptimalSet/superoptimal API.
@cite{blutner-2000}'s superoptimality (weak BiOT, eq. 14) lives at
Core/Constraint/Superoptimal.lean as the dual API:
- **`superoptimalSet pairs profile`** — Set-valued, anchored in mathlib's
`OrderHom.gfp` over the `Set α` complete lattice. The abstract canonical
form for structural arguments (uniqueness, ranking-invariance across
BiOT variants, strong⊂weak meta-theorem).
- **`superoptimal pairs profile`** — Finset-native computable form,
consumer-facing for per-paper `decide` proofs. Bridge to the abstract
gfp via `superoptimal_coe_eq_set`.
Strong BiOT (eq. 9) is in the same file as `IsStrongOptimal` (Set-valued
Prop) + `strongOptimal` (Finset-native), with the structural
`isStrongOptimal_imp_mem_superoptimalSet` meta-theorem (Blutner p. 12)
proved coinductively against `OrderHom.gfp` — no algorithmic detour
through iterated removal.
Iterative removal (the algorithm equivalent to strong BiOT for typical
cases) is no longer formalized: `strongOptimal` IS the strong-BiOT
Finset, and `superoptimal` IS the weak-BiOT Finset. The illustrative
"iterative ≠ weak" point is captured directly by the existence of the
re-admission step in `superoptimalLoop`.
Violation profile ordered by lexicographic ≤ (OT harmony ordering).
Wraps List Nat so that ≤ means LexLE — the standard OT
comparison where the first differing constraint determines the winner.
This is a Preorder (reflexive, transitive) but not a PartialOrder
on List Nat: trailing zeros are invisible (LexLE [] [0] and
LexLE [0] [] both hold). For a LinearOrder on fixed-length profiles,
use ViolationProfile n.
- profile : List ℕ
Instances For
Equations
- Core.Constraint.Evaluation.instDecidableEqLexProfile.decEq { profile := a } { profile := b } = if h : a = b then h ▸ isTrue ⋯ else isFalse ⋯
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
Equations
- Core.Constraint.Evaluation.instLELexProfile = { le := fun (a b : Core.Constraint.Evaluation.LexProfile) => Core.Constraint.Evaluation.LexLE a.profile b.profile }
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Equations
- Core.Constraint.Evaluation.instDecidableLtLexProfile a b = instDecidableAnd
LexProfile.≤ is definitionally LexLE.
LexProfile.< is definitionally LexLT.
LexLE is total on equal-length profiles, expressed via LexProfile.
Violation profile ordered by satisfaction ≤ (Kratzer ordering).
Wraps List Nat so that ≤ means SatLE — a candidate is at least
as good as another iff it satisfies every constraint the other satisfies.
This is a Preorder (reflexive, transitive) but neither antisymmetric
(non-zero values are interchangeable) nor total (incomparable candidates
are possible).
- profile : List ℕ
Instances For
Equations
- Core.Constraint.Evaluation.instDecidableEqSatProfile.decEq { profile := a } { profile := b } = if h : a = b then h ▸ isTrue ⋯ else isFalse ⋯
Instances For
Equations
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Core.Constraint.Evaluation.instLESatProfile = { le := fun (a b : Core.Constraint.Evaluation.SatProfile) => Core.Constraint.Evaluation.SatLE a.profile b.profile }
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Equations
- Core.Constraint.Evaluation.instDecidableLtSatProfile a b = instDecidableAnd
SatProfile.≤ is definitionally SatLE.
SatLE is NOT total: incomparable candidates are possible.
Fixed-length violation profile: n constraints, each recording a natural
number of violations.
Defined as Lex (Fin n → Nat) — mathlib's type synonym that equips
Pi-types with lexicographic ordering. The three layers of structure are:
LinearOrder: fromPi.Lex— lexicographic comparison (min= Riggle's ⊗, choose winner)AddCommMonoid: componentwise addition of violation counts (Riggle's ⊎, merge violations)IsOrderedCancelAddMonoid: compatibility — adding violations preserves the harmony ordering (Riggle's distributivity, Dijkstra's principle)
Unlike LexProfile (which wraps List Nat and is only a Preorder),
ViolationProfile n is a full LinearOrder: reflexive, transitive,
antisymmetric, and total. The linear order guarantees that every
non-empty candidate set has a unique minimum (= the OT winner).
Equations
- Core.Constraint.Evaluation.ViolationProfile n = Lex (Fin n → ℕ)
Instances For
Pointwise addition on ViolationProfile n reduces componentwise.
The zero ViolationProfile n is pointwise zero.
Equations
- One or more equations did not get rendered due to their size.
ViolationProfile n is an ordered additive commutative monoid:
componentwise addition of violations preserves the lexicographic
ordering. This is @cite{riggle-2009}'s violation semiring — the
AddCommMonoid is the ⊎ (merge) operation, and min from the
LinearOrder is the ⊗ (choose winner) operation. Distributivity
of ⊗ over ⊎ is exactly add_le_add_left.
The proof works by transferring the lex existential witness: if
a < b at position i with all earlier positions equal, then
a + c < b + c at the same position i (Nat addition preserves
strict inequality).
Left cancellation for lexicographic ≤: if a + b ≤ a + c then b ≤ c.
This strengthens the ordered monoid to an ordered cancel monoid,
which is needed for the tropical semiring derivation.
Lexicographic ≤ on Fin n → Nat, defined by recursion on n.
This computable relation is the decision procedure for ≤ on
ViolationProfile n (see vpLE_iff_le).
Equations
- Core.Constraint.Evaluation.vpLE 0 x_3 x_4 = True
- Core.Constraint.Evaluation.vpLE n.succ a b = (a 0 < b 0 ∨ a 0 = b 0 ∧ Core.Constraint.Evaluation.vpLE n (a ∘ Fin.succ) (b ∘ Fin.succ))
Instances For
Equations
- One or more equations did not get rendered due to their size.
- Core.Constraint.Evaluation.instDecidableVpLE 0 x_3 x_4 = isTrue trivial
Bridge theorem: vpLE is equivalent to ≤ on ViolationProfile n.
This connects the computable recursive comparison (vpLE, defined by
structural recursion on n) to the algebraic LinearOrder on
ViolationProfile n (derived from Pi.Lex). The bridge enables
decidable ≤ on ViolationProfile n (see instDecidableVpProfileLE),
which in turn makes Tableau.optimal computable.
Decidable ≤ on ViolationProfile n, via vpLE.
This makes ViolationProfile n computationally comparable despite
the LinearOrder being noncomputable (from Pi.Lex). With this
instance, Tableau.optimal becomes computable: study files can use
by decide to verify OT winners on Tableau C n.
Equations
- Core.Constraint.Evaluation.instDecidableVpProfileLE a b = decidable_of_iff (Core.Constraint.Evaluation.vpLE n a b) ⋯
Decidable < on ViolationProfile n, from decidable ≤.
Equations
- Core.Constraint.Evaluation.instDecidableVpProfileLT a b = decidable_of_iff (¬b ≤ a) ⋯
Build a ViolationProfile n from n constraint evaluation functions.
Given constraints as Fin n → C → Nat (constraint i evaluated on
candidate c yields violation count constraints i c), produce the
fixed-length violation profile for candidate c.
This is the bridge between the study-file workflow (define individual
constraint functions) and the algebraic Tableau C n infrastructure.
Equations
- Core.Constraint.Evaluation.buildViolationProfile constraints c = toLex fun (i : Fin n) => constraints i c
Instances For
WithTop (ViolationProfile n) is a LinearOrderedAddCommMonoidWithTop:
it extends the ordered cancel monoid with a top element (V^∞ in Riggle's
notation) that absorbs addition. This is the final prerequisite for the
tropical semiring — mathlib's Tropical wrapper then gives us
CommSemiring (Tropical (WithTop (ViolationProfile n))) for free.
Equations
- One or more equations did not get rendered due to their size.
Pointwise satisfaction ≤ on Fin n → Nat: a ≤ b iff every constraint
that b satisfies (has 0 violations), a also satisfies.
This is a Preorder but not a PartialOrder: non-zero values are
interchangeable (e.g., [1] ≤ [2] and [2] ≤ [1] both hold).
Equations
- Core.Constraint.Evaluation.svpLE a b = ∀ (i : Fin n), b i = 0 → a i = 0
Instances For
Equations
- Core.Constraint.Evaluation.instDecidableSvpLE a b = Fintype.decidableForallFintype
Fixed-length violation profile ordered by satisfaction ≤
(Kratzer ordering). a ≤ b iff a satisfies every constraint that b
satisfies.
- val : Fin n → ℕ
Instances For
Equations
- Core.Constraint.Evaluation.instDecidableEqSatViolationProfile.decEq { val := a } { val := b } = if h : a = b then h ▸ isTrue ⋯ else isFalse ⋯
Instances For
Equations
- Core.Constraint.Evaluation.instLESatViolationProfile n = { le := fun (a b : Core.Constraint.Evaluation.SatViolationProfile n) => Core.Constraint.Evaluation.svpLE a.val b.val }
Equations
- Core.Constraint.Evaluation.instLTSatViolationProfile n = { lt := fun (a b : Core.Constraint.Evaluation.SatViolationProfile n) => a ≤ b ∧ ¬b ≤ a }
Equations
- One or more equations did not get rendered due to their size.
Equations
- Core.Constraint.Evaluation.instDecidableLtSatViolationProfile a b = instDecidableAnd
An OT tableau with n ranked constraints and candidate type C.
Uses Finset C for the candidate set (guaranteeing finiteness and
deduplication) and ViolationProfile n for fixed-length profiles with
decidable LinearOrder.
- candidates : Finset C
- profile : C → ViolationProfile n
- nonempty : self.candidates.Nonempty
Instances For
A candidate is optimal iff it belongs to the candidate set and its profile is ≤ every other candidate's profile.
Equations
- t.IsOptimal c = (c ∈ t.candidates ∧ ∀ c' ∈ t.candidates, t.profile c ≤ t.profile c')
Instances For
Every tableau has an optimal candidate. This is the structural
guarantee of OT: the LinearOrder on ViolationProfile n ensures
a minimum always exists in any non-empty finite set.
Proof delegates to Finset.exists_min_image — the general fact that
a linear-ordered image of a non-empty finset has a minimum.
Set of optimal candidates. Computable via instDecidableVpProfileLE:
the Finset.filter tests ∀ c' ∈ candidates, profile c ≤ profile c'
using the decidable ≤ on ViolationProfile n. Study files can verify
OT winners with by decide on concrete tableaux.
Equations
- t.optimal = {c ∈ t.candidates | ∀ c' ∈ t.candidates, t.profile c ≤ t.profile c'}
Instances For
The optimal set is always non-empty: OT always picks a winner.
Optimal candidates belong to the candidate set.
Check a Bool predicate for all elements of a Finset.
Computable via Finset.decidableBAll — avoids noncomputable
Finset.toList. Use this to verify properties of optimal candidates
in native_decide proofs.
Equations
- Core.Constraint.Evaluation.Finset.checkAll s p = decide (∀ c ∈ s, p c = true)
Instances For
Check a Bool predicate for some element of a Finset.
Computable via Finset.decidableBEx — avoids noncomputable
Finset.toList.
Equations
- Core.Constraint.Evaluation.Finset.checkAny s p = decide (∃ c ∈ s, p c = true)
Instances For
If a ≤ b lexicographically, then the first component satisfies
a 0 ≤ b 0. Extracting the first component is the algebraic
backbone of isOptimal_zero_first: if the first constraint has
0 violations for any candidate, all optimal candidates must also
have 0 violations on it.