Dependent Case Theory #
@cite{marantz-1991} @cite{baker-2015}
The dependent case algorithm: case is determined by the structural configuration of NPs within a Spell-Out domain, applied via a disjunctive priority hierarchy:
- Lexical case: assigned by a particular head (P, V) — highest priority
- Dependent case: assigned to an NP that stands in a c-command
relation with another caseless NP in the same domain
- Accusative languages: lower NP gets ACC
- Ergative languages: higher NP gets ERG
- Tripartite languages: higher NP gets ERG and lower gets ACC
- Unmarked case: default for any NP still without case
- Accusative languages: NOM
- Ergative languages: ABS
- Tripartite languages: ABS
This file is the theory — the language-typology enum, the configural
rules, and the case-assignment algorithm. Empirical applications,
cross-linguistic validation, and competing analyses live in
Phenomena/Case/Studies/.
Where to Find What #
Studies/Marantz1991.lean— the original proposal: abstract vs. morphological case, Georgian split-ergative spellout, the case realization hierarchy as the parallel to the agreement accessibility hierarchyStudies/Baker2015.lean— the typological survey: cross-linguistic derivations across accusative (German, Turkish), ergative (Basque), and split-ergative (Hindi, Georgian) columnsStudies/BakerVinokurova2010.lean— the Sakha case study, including the dependent-case-with-Agree hybridStudies/Woolford1997.lean— four-way case systems (Nez Perce): ERG-as-inherent challenges the dependent-case derivation of ergativeStudies/Scott2023.lean— voice-based case in Mam: a sibling theory in which Voice and Infl assign case directly by argument position, withdependent_case_ignores_voicestaging the contrastStudies/Ozaki2026.lean— Japanese departure verbs: dependent ACC on the source of dyadic unaccusatives, with lexical ABL from kara bleeding dependent caseStudies/Caha2009.lean— typological prediction at the inventory level, using thePartialOrder Core.Caseinstance fromCore/Case/Order.leanand theRespectsCahaContainmentpredicate now defined inCaha2009.leanitself. The dependent case algorithm produces values inCore.Case; their relative ranking is the canonical containment order, which Caha's *ABA constraint applies to.
Companion Infrastructure #
Theories/Syntax/Minimalism/Voice.lean— Voice flavors and phase-hood, used by the Agree-based competitor and by Voice-based case (Scott 2023)Theories/Syntax/Minimalism/CaseFilter.lean— the Agree-based licensing requirement that every DP must receive CaseTheories/Syntax/Case/Licensing.lean— Kalin's hybrid licensing framework: one obligatory primary licenser per clause + secondary licensers as a last-resort response to convergence failure, deriving DOM patterns as the surface signature of secondary-licenser activationCore/Case/Order.lean— the containment hierarchy (PartialOrder Core.Case);Core/Case/Allomorphy.lean— the framework-neutralAllomorphyPatternand *ABA substrate;Phenomena/Case/Studies/ Caha2009.lean— the Caha-specificRespectsCahaContainmentpredicate that consumesCore.Casevalues
The source of case assignment, ordered by priority. Lexical case (assigned by P, V) takes priority over dependent case, which takes priority over unmarked (default) case.
- lexical : CaseSource
- dependent : CaseSource
- unmarked : CaseSource
- agree : CaseSource
Instances For
Equations
- Syntax.Case.instDecidableEqCaseSource x✝ y✝ = if h : x✝.ctorIdx = y✝.ctorIdx then isTrue ⋯ else isFalse ⋯
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Syntax.Case.instReprCaseSource = { reprPrec := Syntax.Case.instReprCaseSource.repr }
Language type determines which dependent and unmarked cases are used.
- Accusative: dependent = ACC (on lower NP), unmarked = NOM
- Ergative: dependent = ERG (on higher NP), unmarked = ABS
- Tripartite: dependent = ERG (on higher) + ACC (on lower), unmarked = ABS (@cite{scott-2023}: SJA Mam; cf. Nez Perce)
- accusative : CaseLanguageType
- ergative : CaseLanguageType
- tripartite : CaseLanguageType
Instances For
Equations
- Syntax.Case.instDecidableEqCaseLanguageType x✝ y✝ = if h : x✝.ctorIdx = y✝.ctorIdx then isTrue ⋯ else isFalse ⋯
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
An NP within a Spell-Out domain, before case assignment. List position encodes structural height: earlier = higher = c-commands later.
If a P head (e.g., Japanese kara) assigns lexical case to the NP,
lexicalCase is some c; otherwise it is none.
- label : String
Label identifying this NP
- lexicalCase : Option Core.Case
Lexical case pre-assigned by a P or V head (e.g., ABL from kara)
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Syntax.Case.instReprNPInDomain = { reprPrec := Syntax.Case.instReprNPInDomain.repr }
Result of case assignment: an NP with its case value and source.
- label : String
- case : Core.Case
- source : CaseSource
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Syntax.Case.instReprCasedNP = { reprPrec := Syntax.Case.instReprCasedNP.repr }
Look up the assigned case for an NP by label.
Equations
- Syntax.Case.getCaseOf label results = Option.map (fun (x : Syntax.Case.CasedNP) => x.case) (List.find? (fun (x : Syntax.Case.CasedNP) => x.label == label) results)
Instances For
Look up the case source for an NP by label.
Equations
- Syntax.Case.getSourceOf label results = Option.map (fun (x : Syntax.Case.CasedNP) => x.source) (List.find? (fun (x : Syntax.Case.CasedNP) => x.label == label) results)
Instances For
Does any NP in the list lack lexical case? Used to check whether a dependent case competitor exists.
Equations
- Syntax.Case.anyLacksCaseIn nps = nps.any fun (x : Syntax.Case.NPInDomain) => x.lexicalCase.isNone
Instances For
Dependent accusative: assigned to an NP that is c-commanded by another caseless NP in the same domain.
In our list representation, NP at index i is c-commanded by all NPs at index j < i. So NP_i gets ACC if it has no lexical case and some NP before it also has no lexical case.
Equations
- Syntax.Case.dependentAccusative higherNPs np = if (np.lexicalCase.isNone && Syntax.Case.anyLacksCaseIn higherNPs) = true then some UD.Case.acc else none
Instances For
Dependent ergative: assigned to an NP that c-commands another caseless NP. NP_i gets ERG if it has no lexical case and some NP after it also has no lexical case.
Equations
- Syntax.Case.dependentErgative np lowerNPs = if (np.lexicalCase.isNone && Syntax.Case.anyLacksCaseIn lowerNPs) = true then some UD.Case.erg else none
Instances For
Unmarked (default) case for a given language type.
- Accusative languages: NOM
- Ergative languages: ABS
- Tripartite languages: ABS (only intransitive S gets unmarked case)
Equations
Instances For
Assign case to a single NP given the NPs structurally above and below it. Applies the three-step priority: lexical → dependent → unmarked.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Assign case to all NPs in a Spell-Out domain. Processes the list left-to-right, maintaining context of higher NPs and remaining lower NPs for each position.
Equations
- Syntax.Case.assignCasesAux lang higher [] = []
- Syntax.Case.assignCasesAux lang higher (np :: rest) = Syntax.Case.assignOneCase lang higher rest np :: Syntax.Case.assignCasesAux lang (higher ++ [np]) rest
Instances For
Top-level case assignment for a list of NPs in a Spell-Out domain. List order encodes structural height: first = highest = c-commands all others.
Equations
- Syntax.Case.assignCases lang nps = Syntax.Case.assignCasesAux lang [] nps
Instances For
ACC Variant #
"Taro-ga mura-o hanare-ta" (Taro-NOM village-ACC leave-PAST)
Two bare NPs in the TP Spell-Out domain:
- Leaver NP (higher, raised to Spec-TP)
- Source NP (lower, complement of V)
- Source gets dependent ACC; Leaver gets unmarked NOM
Equations
- Syntax.Case.accVariantNPs = [{ label := "leaver", lexicalCase := none }, { label := "source", lexicalCase := none }]
Instances For
ABL Variant #
"Taro-ga mura-kara hanare-ta" (Taro-NOM village-from leave-PAST)
One bare NP + one PP (lexical ABL from kara):
- Leaver NP (higher, raised to Spec-TP)
- Source PP (lower, kara assigns lexical ABL)
- Source has lexical ABL (bleeds dependent case); Leaver gets unmarked NOM
Equations
- Syntax.Case.ablVariantNPs = [{ label := "leaver", lexicalCase := none }, { label := "source", lexicalCase := some UD.Case.abl }]
Instances For
Lexical case bleeds dependent case: an NP with lexical case is never assigned dependent case, regardless of structural configuration.
ACC variant: source (lower NP) gets dependent accusative.
ACC variant: source case is dependent (not lexical or unmarked).
ACC variant: leaver (higher NP) gets unmarked nominative.
ACC variant: leaver case is unmarked.
ABL variant: source gets lexical ablative (from kara).
ABL variant: source case is lexical (from P head kara).
ABL variant: leaver gets unmarked nominative.
Dependent ACC does not require agentive Voice — it only requires two caseless NPs in the same Spell-Out domain. The Voice head's flavor is irrelevant to the case algorithm.
All NPs receive case in the ACC variant.
All NPs receive case in the ABL variant.
Tripartite: Theory-Level Properties #
In a tripartite system, both dependent ergative and dependent accusative
are active simultaneously: the higher NP gets ERG, the lower gets ACC,
and an NP with no case competitor gets unmarked ABS. These are properties
of the algorithm, not of any particular language. Language-specific
derivations (e.g., SJA Mam) belong in Phenomena/Case/Bridge/.
Tripartite transitive: higher NP gets dependent ERG.
Tripartite transitive: lower NP gets dependent ACC.
Tripartite intransitive: sole NP gets unmarked ABS.
All three cases are distinct — the defining property of tripartite. ERG ≠ ACC ≠ ABS, derived purely from the algorithm.
Tripartite subsumes both ergative and accusative dependent case: ERG on the higher NP matches pure ergative; ACC on the lower NP matches pure accusative.
ACC and ABL are mutually exclusive on the source: the same structural position receives exactly one of ACC (dependent) or ABL (lexical), never both. This follows from the priority ordering — lexical case preempts dependent case entirely.
The leaver gets NOM in both variants. The alternation affects only the source argument; the subject case is invariant.
Ergative mirror: in an ergative language with two caseless NPs, the higher NP gets dependent ERG and the lower gets unmarked ABS. This is the typological inverse of the accusative pattern.
A single caseless NP in an accusative language gets NOM — the standard intransitive case. No dependent case arises because there is no case competitor.
Case is purely configural: two NPs with identical labels but different lexical case inputs produce different outputs. The algorithm is sensitive only to the NP inventory, not to verb type or Voice flavor.
The structural (non-lexical) cases that the dependent case algorithm
can assign for each language type. These are exactly the cases that
appear in the none (no lexical case) branch of assignOneCase.
Equations
- Syntax.Case.structuralCasesFor Syntax.Case.CaseLanguageType.accusative = [UD.Case.nom, UD.Case.acc]
- Syntax.Case.structuralCasesFor Syntax.Case.CaseLanguageType.ergative = [UD.Case.abs, UD.Case.erg]
- Syntax.Case.structuralCasesFor Syntax.Case.CaseLanguageType.tripartite = [UD.Case.abs, UD.Case.erg, UD.Case.acc]
Instances For
In an accusative language, any NP without lexical case receives either NOM (unmarked) or ACC (dependent).
In an ergative language, any NP without lexical case receives either ABS (unmarked) or ERG (dependent).
In a tripartite language, any NP without lexical case receives ABS (unmarked), ERG (dependent on a lower NP), or ACC (dependent on a higher NP).
How nominative case is assigned in a language. @cite{baker-vinokurova-2010}: in Sakha (and Mongolian, per @cite{gong-2022}), NOM is assigned by finite T via Agree, not as an unmarked default. This distinction matters for Wholesale Late Merger: Agree-based NOM is tied to a specific functional head, while unmarked NOM is a last-resort default.
- agreeT : NomAssignment
- unmarkedDefault : NomAssignment
Instances For
Equations
- Syntax.Case.instDecidableEqNomAssignment x✝ y✝ = if h : x✝.ctorIdx = y✝.ctorIdx then isTrue ⋯ else isFalse ⋯
Equations
- Syntax.Case.instReprNomAssignment = { reprPrec := Syntax.Case.instReprNomAssignment.repr }
Equations
- One or more equations did not get rendered due to their size.
Instances For
How dative case is assigned. @cite{gong-2022}: DAT is nonstructural in Mongolian — it does not participate in dependent case competition and is not available at intermediate scrambling positions for WLM.
- nonstructural : DatAssignment
- dependent : DatAssignment
Instances For
Equations
- Syntax.Case.instDecidableEqDatAssignment x✝ y✝ = if h : x✝.ctorIdx = y✝.ctorIdx then isTrue ⋯ else isFalse ⋯
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Syntax.Case.instReprDatAssignment = { reprPrec := Syntax.Case.instReprDatAssignment.repr }
How accusative case is assigned. @cite{baker-vinokurova-2010}: in Sakha (and Mongolian, per @cite{gong-2022}), ACC is dependent case (Marantz-style); the standard Chomskyan alternative is that ACC is assigned by v/Voice via Agree (often paired with Burzio's Generalization).
- dependent : AccAssignment
- agreeV : AccAssignment
Instances For
Equations
- Syntax.Case.instDecidableEqAccAssignment x✝ y✝ = if h : x✝.ctorIdx = y✝.ctorIdx then isTrue ⋯ else isFalse ⋯
Equations
- Syntax.Case.instReprAccAssignment = { reprPrec := Syntax.Case.instReprAccAssignment.repr }
Equations
- One or more equations did not get rendered due to their size.
Instances For
How genitive case is assigned. @cite{baker-vinokurova-2010}: in Sakha, GEN is assigned by D via Agree to the possessor (parallel to T-Agree NOM at the clausal level). Russian numeric and partitive GEN is nonstructural.
- agreeD : GenAssignment
- nonstructural : GenAssignment
Instances For
Equations
- Syntax.Case.instDecidableEqGenAssignment x✝ y✝ = if h : x✝.ctorIdx = y✝.ctorIdx then isTrue ⋯ else isFalse ⋯
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Syntax.Case.instReprGenAssignment = { reprPrec := Syntax.Case.instReprGenAssignment.repr }
A language-specific case system configuration. Bundles the alignment type with the per-case mechanism choices.
Each of the four structural cases (NOM, GEN, ACC, DAT) gets an independent mechanism plug-in. Marantz's purely-configurational picture, Chomsky's purely-Agree picture, and B&V's two-modality Sakha grammar all fall out as parameterizations of this single structure:
| Theory | nom | gen | acc | dat |
|---|---|---|---|---|
| Marantz pure | unmarkedDefault | (—) | dependent | dependent |
| Chomsky pure | agreeT | agreeD | agreeV | nonstructural |
| Sakha (B&V) | agreeT | agreeD | dependent | dependent |
| Mongolian | agreeT | agreeD | dependent | nonstructural |
accMode and genMode default to the most common values across the
library so that existing instances need not specify them.
- langType : CaseLanguageType
- nomMode : NomAssignment
- datMode : DatAssignment
- accMode : AccAssignment
- genMode : GenAssignment
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
Phased case assignment #
@cite{baker-vinokurova-2010} formalize Sakha case as cycling over two phases: VP (the smaller phase) and CP. Two configurational rules apply (paper (4a)/(4b), restated as (85)):
- (4a) DAT rule: if NP1 c-commands NP2 in the same VP-phase, value NP1 as DAT unless NP2 is already marked.
- (4b) ACC rule: if NP1 c-commands NP2 in the same phase, value NP2 as ACC unless NP1 is already marked.
(4a) bleeds (4b) on the VP cycle by Elsewhere ordering — its context (one specific phase) is more restrictive than (4b)'s (any phase).
After dependent case has applied, Agree (paper (5)/(86)) values remaining unvalued NPs:
- T agrees with the highest unvalued NP visible at CP, valuing NOM.
- D agrees with its dependent NP inside a DP, valuing GEN.
Each NP carries a basePhase (where it was merged) and a
shifted flag (did it move to a higher phase before evaluation).
PIC: NPs that stayed inside VP are not visible on the CP cycle.
Cycle in the @cite{baker-vinokurova-2010} two-phase model.
Distinct from the more articulated Minimalist.Phase structure
in Phase.lean; this is just the binary VP-vs-CP distinction
that the case algorithm cycles over.
Instances For
Equations
- Syntax.Case.instDecidableEqCasePhase x✝ y✝ = if h : x✝.ctorIdx = y✝.ctorIdx then isTrue ⋯ else isFalse ⋯
Equations
- Syntax.Case.instReprCasePhase = { reprPrec := Syntax.Case.instReprCasePhase.repr }
Equations
- Syntax.Case.instReprCasePhase.repr Syntax.Case.CasePhase.vp prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Syntax.Case.CasePhase.vp")).group prec✝
- Syntax.Case.instReprCasePhase.repr Syntax.Case.CasePhase.cp prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Syntax.Case.CasePhase.cp")).group prec✝
Instances For
An NP equipped with phase information.
basePhase records where the NP was merged; shifted marks
NPs that have moved to a higher phase before case evaluation.
isArgumental flags whether the NP bears a θ-role w.r.t. some
case-assigning head — only argumental NPs are case competitors
for rules (4a)/(4b). Bare-NP adverbs (e.g., 'yesterday', 'two
kilometers') are non-argumental. @cite{baker-vinokurova-2010}
(8)–(9) and footnote 5.
inDP flags NPs that participate only in DP-internal case
assignment (possessors): these are skipped by every clausal pass
and are valued by applyGenAgree when genMode := .agreeD.
- label : String
- lexicalCase : Option Core.Case
- basePhase : CasePhase
- shifted : Bool
- isArgumental : Bool
- inDP : Bool
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Syntax.Case.instReprPhasedNP = { reprPrec := Syntax.Case.instReprPhasedNP.repr }
Equations
- One or more equations did not get rendered due to their size.
Instances For
Visible on the VP cycle: NPs whose basePhase is vp.
Even shifted NPs are visible at this point — shift happens at
the boundary between cycles.
Equations
- p.visibleOnVP = (p.basePhase == Syntax.Case.CasePhase.vp)
Instances For
Visible on the CP cycle: NPs in cp, plus VP-base NPs that
shifted out of VP. Unshifted VP NPs were transferred (PIC).
Equations
- p.visibleOnCP = (p.basePhase == Syntax.Case.CasePhase.cp || p.shifted)
Instances For
Mutable state during phased case assignment. case = none
means "not yet valued"; lexical case starts with the value
pre-set.
- np : PhasedNP
- case : Option (Core.Case × CaseSource)
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Syntax.Case.instReprPhasedState = { reprPrec := Syntax.Case.instReprPhasedState.repr }
An NP is "marked" iff its case has been valued (lexically, by dependent rule, or by agreement). The "unless...marked" clauses of (4a)/(4b) check this.
Instances For
Initialize: pre-fill lexical case from the NP's lexicalCase
field; everything else starts unvalued.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Replace the case of the NP at index i with (c, src).
Equations
- One or more equations did not get rendered due to their size.
Instances For
The eligibility predicate used by unmarkedVisible: a state is
eligible iff it is visible on the cycle, argumental, not DP-
internal, and not yet marked. Factored out so structural proofs
(e.g. applyAccRule_preserves_marked_at) can manipulate the
condition without unfolding pattern lambdas.
Equations
- Syntax.Case.unmarkedEligible Syntax.Case.CasePhase.vp s = (s.np.visibleOnVP && s.np.isArgumental && !s.np.inDP && !s.marked)
- Syntax.Case.unmarkedEligible Syntax.Case.CasePhase.cp s = (s.np.visibleOnCP && s.np.isArgumental && !s.np.inDP && !s.marked)
Instances For
Indices of unmarked, argumental, clause-level NPs visible on a given cycle, in c-command order (highest first, since list-position encodes height). Non-argumental NPs (bare-NP adverbs) and DP- internal NPs (possessors) are filtered out: per @cite{baker-vinokurova-2010} (8)–(9), rules (4a)/(4b) apply only between argumental NPs at the clausal level.
Equations
- Syntax.Case.unmarkedVisible cycle states = List.filterMap (fun (p : Syntax.Case.PhasedState × ℕ) => if Syntax.Case.unmarkedEligible cycle p.1 = true then some p.2 else none) states.zipIdx
Instances For
Apply the DAT rule (4a) on the VP cycle: if there are at least two unmarked NPs visible at vP, mark the highest as DAT.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Apply the ACC rule (4b) on a given cycle: if there are at least two unmarked NPs visible, mark the lowest as ACC.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Apply v-Agree: the lowest CP-visible unmarked argumental NP gets
ACC via Agree. This is the standard Chomskyan picture
(@cite{chomsky-2000}; @cite{chomsky-2001}): v probes downward into
its complement and Agrees with the closest goal. The dependent-
accusative algorithm (applyAccRule) is the alternative to this
pass; the two are mutually exclusive on a given grammar via the
accMode parameter.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Apply T-Agree (paper (5)/(86)): the highest unmarked NP visible on the CP cycle gets NOM via Agree.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Apply D-Agree (paper (5)/(86)): every unmarked DP-internal NP
(possessor) is valued GEN by its dominating D head. The clausal
algorithm sees DP-internals as opaque (filtered from
unmarkedVisible); this pass is the DP-internal counterpart to
applyNomAgree. The Russian numeric/partitive GEN, by contrast,
is .nonstructural and lives in lexicalCase.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Default case for any NP still unmarked at the end of the
derivation. Uses unmarkedCaseFor from § 6.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Materialize a PhasedState as a CasedNP (or omit if no case
was ever assigned — caller should ensure applyDefault ran).
Equations
Instances For
The B&V phased algorithm: VP cycle (DAT then ACC), CP cycle (ACC),
v-Agree → ACC (only when accMode := .agreeV), T-Agree → NOM,
D-Agree → GEN, then a default sweep.
applyAccRule and applyAccAgree are mutually exclusive on the
cases they touch (gated by accMode), so their relative order
only matters when neither fires. The order chosen — dependent
rules first, then Agree — mirrors the standard Chomskyan picture
where v probes after VP-internal structure has been built.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Length preservation (one CasedNP per input PhasedNP) and totality
(every input NP receives exactly one case) are the key well-formedness
properties of assignCasesPhased. They fall out structurally:
each per-pass operation preserves list length, and applyDefault
guarantees no state escapes uncased.
After the final default sweep, every state's case is valued.
Soundness (length preservation). The phased algorithm produces
exactly one CasedNP per input PhasedNP. No NP is dropped or
duplicated; the algorithm is total.
The Elsewhere ordering of (4a) over (4b) on the VP cycle is not a
stipulated rule-ordering preference: it falls out from the fact that
unmarkedVisible filters out marked NPs, so any pass that only
modifies indices in unmarkedVisible cannot overwrite a previously-
valued NP. We prove this once for applyAccRule (it never overwrites
a marked state) and use it to derive the bleeding theorem for
arbitrary inputs.
(4b) ACC never overwrites a marked NP. This is the structural
content of the Elsewhere ordering: once a state has been valued
(lexically, by (4a) DAT, or by Agree), unmarkedVisible no
longer includes its index, so applyAccRule cannot touch it.
v-Agree, like (4b), only touches unmarkedVisible indices and so
cannot overwrite a marked NP.
T-Agree only touches unmarkedVisible .cp indices.
D-Agree only modifies unmarked DP-internal states.
The default sweep only modifies unmarked states.
DAT bleeds ACC on the VP cycle, structurally. For every input
state list, the NP marked DAT by applyDatRule keeps its DAT case
through the subsequent VP-cycle applyAccRule call.
DAT marking persists all the way through assignCasesPhased.
Whatever NP applyDatRule values DAT survives every subsequent
pass — both ACC cycles, both Agree probes, and the default sweep —
because each pass only modifies states it sees as unmarked. The
Sakha-specific empirical theorem ditrans_goal_dat follows from
this structural fact applied to the ditransitive input.