Documentation

Linglib.Theories.Semantics.Dynamic.Generics

Generics: Dynamic Semantics with Horizon Expansion #

@cite{kirkpatrick-2024}

James Ravi Kirkpatrick, "The Dynamics of Generics." Journal of Semantics 40(4), 2024. 523–548.

Core idea #

Generics expand a "modal horizon" — the set of salient individuals — as a side effect of assertion. When processing a generic Gen[φ][ψ]:

  1. Check whether the horizon already contains restrictor-satisfying individuals
  2. If not, expand the horizon to include normal restrictor-satisfying ones
  3. Evaluate truth: all restrictor-satisfying individuals on the expanded horizon must satisfy the scope

This cumulative expansion explains why generic Sobel sequences ("Ravens are black; but albino ravens aren't") are consistent while their reverses ("#Albino ravens aren't black; but ravens are") are not: the evaluation order determines which individuals are salient.

Static as special case #

Discourse-initial evaluation (evalGeneric []) reduces to static truth conditions (evalGeneric_empty_eq_static). The fromPredicate constructor builds a GenericSentence from the same primitives as traditionalGEN (Lexical/Noun/Kind/Generics.lean), and fromPredicate_static proves the evaluations agree. Static GEN is the zero-context special case.

Formal components #

What's not here #

This formalizes the single-world case of Kirkpatrick's theory. The full multi-world version (definition 24, with dispositional orbits DO(w) and per-world modal horizons σ : W → ℘(W × Eⁿ)) quantifies over accessible worlds. The single-world simplification suffices for all the paper's examples about Sobel sequences.

A generic sentence: restrictor, scope, and normal instances.

The normalInstances field packages the output of applying a normality restriction to the restrictor class. In a full implementation these would be computed from a NormalityOrder via optimal; here they are provided directly to keep the model computable and the theorems decidable.

Kirkpatrick's contextual variable C (the set of alternatives to the matrix-clause property) is incorporated into the restrictor: the full restrictor is kind(x) ∧ C(x). Different generics about the same kind can have different C values, yielding different restrictors. This is how mixed generic sequences ("Lions have manes and lions give birth") avoid mutual interference (§5.3).

  • restrictor : EBool
  • scope : EBool
  • normalInstances : List E
Instances For

    Process a single generic against a horizon.

    Expansion rule (definition 24a): if no restrictor-satisfying individual is currently salient, expand the horizon to include the normal restrictor-satisfying individuals.

    Truth rule (definition 24b): all restrictor-satisfying individuals on the (possibly expanded) horizon must satisfy the scope.

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For

      Process a sequence of generics left-to-right, threading the horizon. Returns the list of truth values in order.

      Equations
      Instances For
        Equations
        Instances For

          A generic sequence is consistent iff every generic evaluates to true.

          Equations
          Instances For
            theorem Semantics.Dynamic.Generics.evalGeneric_horizon_superset {E : Type} (horizon : List E) (g : GenericSentence E) (e : E) (he : e horizon) :
            e (evalGeneric horizon g).fst

            Horizon expansion is monotone: every individual on the input horizon remains on the output horizon.

            theorem Semantics.Dynamic.Generics.sobel_pair_consistent {E : Type} (general exception : GenericSentence E) (hgs : ∀ (e : E), e general.normalInstancesgeneral.scope e = true) (hdis : ∀ (e : E), e general.normalInstancesexception.restrictor e = false) (her : ∀ (e : E), e exception.normalInstancesexception.restrictor e = true) (hes : ∀ (e : E), e exception.normalInstancesexception.scope e = true) :
            isConsistent [general, exception] = true

            General Sobel sequence consistency (§5.1).

            If two generics form a Sobel pair — the general's normal instances satisfy the general scope, the exception's normal instances satisfy their restrictor and scope, and the general's normal instances are disjoint from the exception's restrictor — then the Sobel sequence [general, exception] is consistent.

            theorem Semantics.Dynamic.Generics.reverse_sobel_pair_inconsistent {E : Type} (general exception : GenericSentence E) (her : ∀ (e : E), e exception.normalInstancesexception.restrictor e = true) (hes : ∀ (e : E), e exception.normalInstancesexception.scope e = true) (hsub : ∀ (e : E), exception.restrictor e = truegeneral.restrictor e = true) (hcounter : ∀ (e : E), e exception.normalInstancesgeneral.scope e = false) (hne : exception.normalInstances []) :
            isConsistent [exception, general] = false

            General reverse Sobel inconsistency (§5.2).

            If exception normal instances satisfy the exception restrictor and scope, the exception restrictor implies the general restrictor (subset), all exception normal instances violate the general scope (genuine counterexamples), and the exception class is nonempty, then the reverse sequence [exception, general] is inconsistent.

            This is the paper's key novel prediction: the dynamic theory explains why reverse Sobel sequences are infelicitous, which static theories cannot account for.

            Discourse-initial evaluation reduces to static truth conditions.

            When the horizon is empty, evalGeneric expands with normalInstances and then checks whether all restrictor-satisfying normal instances satisfy the scope. This is exactly traditionalGEN with situations = normalInstances, normal = fun _ => true: a restricted universal over normal instances.

            This theorem connects Kirkpatrick's dynamic semantics to the static GEN operator in Lexical/Noun/Kind/Generics.lean: in discourse-initial position (before any horizon expansion has occurred), the dynamic theory makes the same predictions as the static theory. The dynamic theory diverges only in multi-sentence discourse, where prior generics have expanded the horizon.

            Structural characterization of horizon evolution #

            The horizon-step function is the state-transition component of evalGeneric: it describes how the set of salient individuals evolves as generics are processed. The step has exactly two behaviors, controlled by a conditional test:

            The Sobel asymmetry arises because the subset relation between restrictors (exception ⊆ general) makes this conditional test asymmetric: in the forward direction both expansions fire (general normals don't satisfy the exception restrictor); in the reverse direction the exception's expansion blocks the general's (exception normals DO satisfy the general restrictor).

            The horizon-step function: how evalGeneric updates the horizon (ignoring the truth value). This is the state-transition component of the generic CCP.

            Equations
            Instances For
              @[simp]

              Empty horizon always expands: the output is exactly normalInstances.

              theorem Semantics.Dynamic.Generics.horizonStep_expand {E : Type} (g : GenericSentence E) (horizon : List E) (h : ∀ (e : E), e horizong.restrictor e = false) :
              horizonStep g horizon = horizon ++ g.normalInstances

              Expansion: when no horizon element satisfies the restrictor, the normal instances are appended to the horizon.

              theorem Semantics.Dynamic.Generics.horizonStep_blocked {E : Type} (g : GenericSentence E) (horizon : List E) {e : E} (he : e horizon) (hr : g.restrictor e = true) :
              horizonStep g horizon = horizon

              Blocking: when some horizon element satisfies the restrictor, the horizon is unchanged — no expansion occurs.

              This is the mechanism that creates the Sobel asymmetry: exception individuals made salient by a prior generic block the expansion of a subsequent general generic, because (by the subset condition) they satisfy the general's restrictor.

              Closure operator analysis #

              horizonStep satisfies two of the three axioms of a closure operator (Mathlib: Order.ClosureOperator):

              1. Extensive (horizonStep_subset): horizon ⊆ horizonStep g horizon
              2. Idempotent (horizonStep_idempotent): horizonStep g (horizonStep g h) = horizonStep g h (under the natural hypothesis that normal instances satisfy the restrictor)

              But it fails the third axiom:

              1. NOT monotone (horizonStep_not_monotone): ∃ g h₁ h₂, h₁ ⊆ h₂ but horizonStep g h₁ ⊄ horizonStep g h₂

              This is structurally interesting: eliminative updates (assertion, test) ARE monotone (updateFromSat_monotone in Core/CCP.lean), so they form closure operators on the dual lattice. Expansive generic updates fail monotonicity precisely because a LARGER input can BLOCK expansion that a smaller input would trigger — a phenomenon impossible in eliminative semantics.

              theorem Semantics.Dynamic.Generics.horizonStep_subset {E : Type} (g : GenericSentence E) (horizon : List E) :
              horizon horizonStep g horizon

              horizonStep is extensive: the input horizon is always a subset of the output. Together with idempotency, this gives two of the three closure operator axioms.

              theorem Semantics.Dynamic.Generics.horizonStep_idempotent {E : Type} (g : GenericSentence E) (hnr : ∀ (e : E), e g.normalInstancesg.restrictor e = true) (hne : g.normalInstances []) (horizon : List E) :
              horizonStep g (horizonStep g horizon) = horizonStep g horizon

              horizonStep is idempotent when normal instances satisfy their own restrictor: applying it twice gives the same result as applying it once.

              The hypothesis hnr ensures that after the first application, the horizon contains restrictor-satisfying elements. The second application therefore sees these elements and triggers the blocking branch — no further expansion occurs.

              Together with horizonStep_subset, this establishes that horizonStep satisfies 2/3 closure operator axioms.

              horizonStep is NOT monotone: there exist g, h₁ ⊆ h₂ such that horizonStep g h₁ ⊄ horizonStep g h₂.

              Witness: g = ⟨id, id, [false]⟩ over Bool. Then h₁ = [] triggers expansion (producing [false]), but h₂ = [true] triggers blocking (because id true = true satisfies the restrictor). So false ∈ horizonStep g [] but false ∉ horizonStep g [true].

              This contrasts with eliminative updates, which ARE monotone (updateFromSat_monotone in Core/CCP.lean): for eliminative semantics, s ⊆ t → u(s) ⊆ u(t). The failure of monotonicity for expansive updates is what prevents horizonStep from being a closure operator (Order.ClosureOperator in Mathlib), despite satisfying extensiveness and idempotency.

              theorem Semantics.Dynamic.Generics.sobel_forward_horizons {E : Type} (general exception : GenericSentence E) (hdis : ∀ (e : E), e general.normalInstancesexception.restrictor e = false) :
              horizonStep exception (horizonStep general []) = general.normalInstances ++ exception.normalInstances

              Forward Sobel: both expansions fire.

              In the forward sequence [general, exception], the general's normal instances don't satisfy the exception restrictor (disjointness), so the exception's expansion is not blocked. The final horizon contains both sets of normal instances.

              theorem Semantics.Dynamic.Generics.sobel_reverse_horizons {E : Type} (general exception : GenericSentence E) (her : ∀ (e : E), e exception.normalInstancesexception.restrictor e = true) (hsub : ∀ (e : E), exception.restrictor e = truegeneral.restrictor e = true) (hne : exception.normalInstances []) :
              horizonStep general (horizonStep exception []) = exception.normalInstances

              Reverse Sobel: the general's expansion is blocked.

              In the reverse sequence [exception, general], the exception's normal instances satisfy the general restrictor (by the subset condition), so the general's conditional expansion test finds restrictor-satisfying individuals already on the horizon. The general does NOT expand — its normal instances never become salient. The final horizon contains only the exception's normal instances.

              This is the structural reason for the reverse Sobel's inconsistency: the general is evaluated against a horizon containing only counterexamples (exception normals that violate the general scope).

              theorem Semantics.Dynamic.Generics.sobel_horizon_noncommutative {E : Type} (general exception : GenericSentence E) (hdis : ∀ (e : E), e general.normalInstancesexception.restrictor e = false) (her : ∀ (e : E), e exception.normalInstancesexception.restrictor e = true) (hsub : ∀ (e : E), exception.restrictor e = truegeneral.restrictor e = true) (hne : exception.normalInstances []) (hne_gen : general.normalInstances []) :
              horizonStep exception (horizonStep general []) horizonStep general (horizonStep exception [])

              Horizon non-commutativity under Sobel conditions.

              The forward and reverse horizons are structurally different: the forward horizon is general.normalInstances ++ exception.normalInstances while the reverse is just exception.normalInstances. Since the general has nonempty normal instances, these lists have different lengths.

              This is the structural content of the Sobel asymmetry: horizon evolution is non-commutative precisely because the restrictor subset relation is asymmetric — exception normals satisfy the general restrictor but general normals do not satisfy the exception restrictor.

              theorem Semantics.Dynamic.Generics.disjoint_pair_consistent {E : Type} (g₁ g₂ : GenericSentence E) (h₁r : ∀ (e : E), e g₁.normalInstancesg₁.restrictor e = true) (h₁s : ∀ (e : E), e g₁.normalInstancesg₁.scope e = true) (h₂r : ∀ (e : E), e g₂.normalInstancesg₂.restrictor e = true) (h₂s : ∀ (e : E), e g₂.normalInstancesg₂.scope e = true) (hdis₁₂ : ∀ (e : E), e g₁.normalInstancesg₂.restrictor e = false) (hdis₂₁ : ∀ (e : E), e g₂.normalInstancesg₁.restrictor e = false) :

              Non-interference for disjoint restrictors (§5.3).

              When two generics have disjoint restrictors — neither's normal instances satisfy the other's restrictor — both orders are consistent, provided each generic's normal instances satisfy their own restrictor and scope.

              This is the structural explanation for why mixed generic sequences like "Lions have manes and lions give birth to live young" are felicitous in both orders: the two generics use different contextual variables C, making their restrictors disjoint.

              Note that this follows directly from sobel_pair_consistent applied symmetrically — the disjointness conditions play the same role as the Sobel pair's hdis hypothesis, but in both directions.

              Appendix A: Why @cite{veltman-1996} cannot model the asymmetry #

              @cite{kirkpatrick-2024} Appendix A (pp. 544–548) shows that @cite{veltman-1996}'s update semantics predicts both generic Sobel sequences and their reverses are consistent, because Veltman's normallyUpdate is commutative (normallyUpdate_comm in UpdateSemantics/Default.lean): the final expectation state σ₁ = σ₂ regardless of processing order, since the expectation frame π₁ = π₂.

              The theorem commutative_implies_equal_verdicts generalizes this: ANY commutative state-transformer forces any state-dependent predicate to agree on both orders. Combined with sobel_horizon_noncommutative, this establishes that Kirkpatrick's theory escapes the impossibility precisely because horizon evolution is non-commutative.

              theorem Semantics.Dynamic.Generics.commutative_implies_equal_verdicts {G S : Type} (process : GSS) (P : SProp) (hcomm : ∀ (a b : G) (s : S), process a (process b s) = process b (process a s)) (init : S) (g₁ g₂ : G) :
              P (process g₂ (process g₁ init)) P (process g₁ (process g₂ init))

              Commutativity forces equal verdicts (Appendix A, abstract form).

              If the state-transformation function commutes, then any predicate on the final state gives the same truth value in both orders.

              This is the formal content of Kirkpatrick's argument against Veltman: since normallyUpdate commutes, the consistency predicate cannot distinguish σ[φ₁][φ₂] from σ[φ₂][φ₁]. In particular, if a Sobel sequence is consistent under Veltman's semantics, its reverse must be too — contrary to empirical judgment.

              The proof is trivial (congruence under commutativity), but the theorem is substantive: it rules out an entire class of theories from modeling order-sensitive phenomena.

              theorem Semantics.Dynamic.Generics.sobel_asymmetry_rules_out_commutativity {G S : Type} (process : GSS) (P : SProp) (init : S) (g₁ g₂ : G) (hfwd : P (process g₂ (process g₁ init))) (hrev : ¬P (process g₁ (process g₂ init))) :
              (a : G), (b : G), (s : S), process a (process b s) process b (process a s)

              Contrapositive: if a pair exhibits the Sobel asymmetry for any predicate P, then the processing function is not commutative.

              Horizon expansion as presupposition-triggered accommodation #

              @cite{kirkpatrick-2024} §4.2 (fn. 23) credits @cite{von-fintel-2001} and @cite{gillies-2007}: the expansion mechanism adapts their dynamic semantics for counterfactuals. Both use presupposition failure to trigger context adjustment, but in opposite directions:

              Both share the same abstract structure:

              1. A presupposition test: does the context already satisfy a condition?
              2. On success: no change (the context already works)
              3. On failure: adjust the context minimally to satisfy the condition
              4. Idempotent: once satisfied, further applications are no-ops

              The key divergence: eliminative accommodation is monotone (larger contexts yield larger results); expansive accommodation is NOT (horizonStep_not_monotone), because a larger horizon can BLOCK expansion that a smaller one triggers.

              def Semantics.Dynamic.Generics.horizonPresupposition {E : Type} (restrictor : EBool) (horizon : List E) :

              The horizon presupposition: restrictor-satisfying individuals are already salient. When this holds, no expansion occurs.

              Equations
              Instances For

                Presupposition success → no expansion. Delegates to horizonStep_blocked.

                Presupposition failure → expansion fires. Delegates to horizonStep_expand.

                Constructors for GenericSentence #

                The normalInstances field of GenericSentence is a stipulation — the constructors below derive it from different theoretical primitives:

                Why no fromThreshold? Threshold semantics (Cohen's prevalence > θ) measures the proportion of restrictor-satisfying cases where scope holds. This is a single Boolean judgment — it doesn't decompose into "select normal instances, then universally quantify." The GenericSentence shape (restrict → select normals → ∀) captures the normality-based family of theories; threshold semantics is a genuinely different algebraic shape. See CovertQuantifier.reduces_to_threshold for the threshold ↔ GEN eliminability result.

                def Semantics.Dynamic.Generics.GenericSentence.fromPredicate {E : Type} (restrictor scope : EBool) (domain : List E) (normal : EBool) :

                Construct a GenericSentence from a binary normalcy predicate.

                This is the direct bridge to traditionalGEN: the normal instances are exactly those domain elements satisfying both restrictor and normalcy. Discourse-initial evaluation of the result equals traditionalGEN.

                Equations
                • One or more equations did not get rendered due to their size.
                Instances For
                  theorem Semantics.Dynamic.Generics.fromPredicate_static {E : Type} (restrictor scope : EBool) (domain : List E) (normal : EBool) :
                  (evalGeneric [] (GenericSentence.fromPredicate restrictor scope domain normal)).snd = domain.all fun (d : E) => !(restrictor d && normal d) || scope d

                  Discourse-initial evaluation of fromPredicate equals the static traditionalGEN — a restricted universal over normal situations.

                  This connects Kirkpatrick's dynamic framework back to the classical static GEN: in discourse-initial position, the dynamic theory with a binary normalcy predicate makes the same prediction as traditionalGEN. The two diverge only in multi-sentence discourse, where prior generics have expanded the horizon.

                  def Semantics.Dynamic.Generics.GenericSentence.fromOrder {E : Type} (restrictor scope : EBool) (domain : List E) (leB : EEBool) :

                  Compute a GenericSentence from a decidable normality ordering.

                  leB e₁ e₂ = true means e₁ is at least as normal as e₂, matching NormalityOrder.le. The normal instances are the optimal restrictor-satisfying entities: those not strictly dominated by any other restrictor-satisfying entity in the domain.

                  This is the computable realization of @cite{kirkpatrick-2024} Definition 21's N_n functors: N(P)(w) = { a ∈ P(w) | ∀ b ∈ P(w), b ≤ a → a ≤ b }.

                  Equations
                  • One or more equations did not get rendered due to their size.
                  Instances For