A Formalization of Arrow's Impossibility Theorem
Arrow's Impossibility Theorem is one of the most celebrated results in social choice theory. Proved by Kenneth Arrow in 1951, it shows that no voting system with three or more alternatives can simultaneously satisfy three basic fairness conditions. This project contains a formal proof in Lean 4, following the one-shot proof of (Yu, 2012)Ning Neil Yu, 2012. “A one-shot proof of Arrow's impossibility theorem”. In Economic Theory..
Table of Contents
1. Preferences
In any social choice setting, each person holds a ranking of the available alternatives. We model this as a total preorder: a binary relation that is reflexive (everyone is at least as good as themselves), transitive (rankings chain consistently), and total (any two alternatives are always comparable in at least one direction).
/-- A total preorder: reflexive, transitive, and total. -/
structure Preorder' (α : Type) where
le : α → α → Prop
refl : ∀ a, le a a
trans : ∀ a b c, le a b → le b c → le a c
total : ∀ a b, le a b ∨ le b a
Note that le a b and le b a can both hold simultaneously — this captures indifference
between a and b. Strict preference, where one option is unambiguously ranked above the other,
is defined separately:
/-- Strict preference: `a` is strictly preferred to `b` iff `a ≤ b` but not `b ≤ a`. -/
@[simp]
def Preorder'.lt (p : Preorder' α) (a b : α) : Prop :=
p.le a b ∧ ¬p.le b a
So p.lt a b holds when a is weakly below b but b is not weakly below a.
The proof uses two notation shorthands throughout:
-- Notation: `a ≻[p] b` means voter with preference `p` strictly prefers `a` over `b`
notation a " ≻[" p "] " b => Preorder'.lt p b a
notation a " ≽[" p "] " b => Preorder'.le p b a
notation a " ≻[" p "] " b "≻ " c => (a ≻[p] b) ∧ b ≻[p] c
notation a " ≽[" p "] " b "≻ " c => (a ≽[p] b) ∧ b ≻[p] c
Notice the reversal: a ≻[p] b expands to Preorder'.lt p b a.
Since lt x y means "x is below y", to say "a is above b" we write lt b a.
The notation hides this reversal so the mathematical reading stays natural: a ≻[p] b means
"under preference p, alternative a is strictly preferred to b."
Several useful properties of lt are proved as lemmas: asymmetry (lt_asymm),
transitivity (lt_trans), and a mixed version (lt_of_lt_of_le) that upgrades
a strict preference followed by a weak preference into a strict one.
2. Social Welfare Functions
With N voters each holding a preference ordering over alternatives α,
a preference profile records everyone's ranking simultaneously:
/-- A preference profile assigns each voter `i ∈ Fin N` their preference ordering. -/
def Profile (α : Type) (N : ℕ) := Fin N → Preorder' αA Social Welfare Function (SWF) is a procedure that takes a preference profile and produces a single social preference ordering — a way of aggregating individual opinions into a collective verdict:
/-- A Social Welfare Function aggregates individual preferences into a social ordering. -/
def SWF (α : Type) (N : ℕ) := Profile α N → Preorder' α2.1. Arrow's Three Conditions
Arrow identified three normative requirements that any "fair" SWF should satisfy.
Unanimity (also called the Pareto condition):
if every voter strictly prefers a to b, then society must also strictly prefer a to b.
No SWF should override a unanimous opinion.
/-- **Unanimity** (Pareto): If all voters prefer `a` over `b`, so does society. -/
def Unanimity (R : SWF α N) : Prop :=
∀ (p: Profile α N) (a b: α), (∀ i: Fin N, a ≻[p i] b) → a ≻[R p] b
Independence of Irrelevant Alternatives (IIA):
the social ranking of any pair (a, b) must depend only on how individuals rank a against b,
and not on their opinions about unrelated alternatives c, d, etc.
To state this precisely, two profiles agree on (a, b) when every voter has identical
views on that pair in both profiles:
/-- Two profiles agree on `(a, b)` if every voter ranks `a` vs `b` the same way in both. -/
@[simp]
def AgreeOn (p q : Profile α N) (a b : α) : Prop :=
∀ i, ((a ≽[p i] b) ↔ a ≽[q i] b) ∧ ((b ≽[p i] a) ↔ b ≽[q i] a)
IIA then says that whenever two profiles agree on (a, b), the social output must too:
/-- **Independence of Irrelevant Alternatives**: The social ranking of `a` vs `b`
depends only on individual rankings of `a` vs `b`. -/
def IIA (R : SWF α N) : Prop :=
∀ (p q: Profile α N) (a b: α),
AgreeOn p q a b → ((a ≽[R p] b) ↔ a ≽[R q] b) ∧ ((b ≽[R p] a) ↔ b ≽[R q] a)
Non-Dictatorship:
there must be no single voter who always gets their way on every pair of alternatives.
Formally, voter k dictates the pair (a, b) if society always copies
voter k's strict preference on that pair, regardless of how everyone else votes:
/-- Voter `k` is a dictator for the pair `(a, b)` if whenever `k` prefers `a` over `b`,
society also prefers `a` over `b`. -/
def Dictates (R : SWF α N) (k : Fin N) (a b : α): Prop :=
∀ (p: Profile α N ), (a ≻[p k] b) → a ≻[R p] bA dictator is a voter who dictates every distinct pair. Non-Dictatorship rules this out:
/-- **Non-Dictatorship**: No single voter dictates the outcome for all pairs. -/
def NonDictatorship (R : SWF α N): Prop :=
¬ (∃ i: Fin N, ∀ (a b: α), (a ≠ b) → Dictates R i a b)3. Proof Overview
Arrow's theorem says these three conditions are mutually incompatible when there are at least three alternatives and at least one voter. The proof proceeds by contradiction: assume all three conditions hold, then construct an explicit dictator — violating Non-Dictatorship.
The central idea is the pivotal voter.
Fix two distinct alternatives a and b, and imagine flipping voters one by one
from preferring a ≻ b to preferring b ≻ a.
k=0 k=1 k=2 k=N
a≻b [0,1,...,N-1] [1,...,N-1] [2,...,N-1] ∅
b≻a ∅ {0} {0,1} [0,...,N-1]
When k = 0, everyone prefers a ≻ b, so by Unanimity, society prefers a ≻ b.
When k = N, everyone prefers b ≻ a, so by Unanimity, society prefers b ≻ a.
Somewhere along the way, the social preference must flip.
The pivotal voter is the first voter whose switch causes this flip.
The clever part: using IIA, one can show that this pivotal voter must dictate
every pair of alternatives — not just (a, b). This contradicts Non-Dictatorship.
4. Constructing Concrete Preferences
The proof needs to reason about specific profiles with known rankings.
To do this, it uses a helper function prefer that builds a Preorder'
from an explicit ordering of three alternatives.
First, a type for the three tie patterns:
/-- Where ties occur in a 3-element preference ranking -/
inductive Tie | Not | Top | Bot
Then prefer produces a Preorder' where a₀ is the top-ranked
alternative and a₂ is the bottom-ranked one, with tie controlling indifference:
/-- Construct a preference ordering with optional ties:
- `Tie.Not`: a₀ > a₁ > a₂ (strict ranking)
- `Tie.Top`: a₀ ~ a₁ > a₂ (top two tied)
- `Tie.Bot`: a₀ > a₁ ~ a₂ (bottom two tied) -/
def prefer (a₀ _a₁ a₂ : α) (tie : Tie) (h02 : a₀ ≠ a₂) : Preorder' α where
The proof only requires a₀ ≠ a₂ (the top and bottom are distinct); the middle
element can even be a duplicate of a₀ or a₂, which the proof exploits — for example,
prefer b b a .Not h effectively creates a ranking where b ≻ a with b duplicated.
5. The Canonical Swap
The central construction is a parametric family of profiles indexed by k ∈ Fin (N+1).
In profile canonicalSwap a b hab k, voters 0, …, k-1 all prefer b ≻ a
while voters k, …, N-1 all prefer a ≻ b:
/-- A family of profiles indexed by `k ∈ Fin (N+1)`:
voters `0..k-1` prefer `b ≻ a`, voters `k..N-1` prefer `a ≻ b`. -/
@[simp]
def canonicalSwap (a b : α) (hab : a ≠ b) : Fin (N+1) → Profile α N :=
fun k: Fin (N+1) =>
fun i: Fin N => if i < k.val
-- `prefer` takes 3 items, we duplicate middle as a workaround
then prefer b b a .Not (Ne.symm hab) -- b on top
else prefer a b b .Not hab -- a on top
At index k = 0, every voter prefers a ≻ b and society must follow by Unanimity.
At index k = N, every voter prefers b ≻ a and society must follow by Unanimity.
flipping records the event that society's preference has switched:
when the first k+1 voters have been flipped to prefer b ≻ a, society no longer
strictly prefers a ≻ b:
/-- `flipping R a b hab k` holds iff society prefers `b ≻ a` when voters `0..k` prefer `b ≻ a`. -/
def flipping (R : SWF α N) (a b : α) (hab : a ≠ b) :=
fun k: Fin N => ¬ a ≻[R (canonicalSwap a b hab k.succ)] b
The lemma flip_exists uses Unanimity to show that flipping must occur for some k.
6. The Pivotal Voter
The pivotal voter for the pair (a, b) is defined as the minimum
voter index at which flipping first occurs:
/-- The pivotal voter for `(a, b)`: the minimum `k` where society flips from `a ≻ b` to `b ≻ a`. -/
noncomputable def pivoter (a b : α) (hab : a ≠ b) (hu : Unanimity R) : Fin N :=
Fin.find (flipping R a b hab) (flip_exists R a b hab hu)Being the minimum, it satisfies two precise boundary conditions.
Before the pivot — for any voter i strictly earlier than the pivotal voter —
society still prefers a ≻ b when voters 0, …, i have been flipped:
/-- Before the pivotal voter, society still prefers `a ≻ b`. -/
lemma no_flip (a b : α) {hab : a ≠ b} (i : Fin N) {hu: Unanimity R}:
i < pivoter a b hab hu → a ≻[R (canonicalSwap a b hab i.succ)] b := α:TypeN:ℕinst✝:NeZero NR:SWF α Na:αb:αhab:a ≠ bi:Fin Nhu:Unanimity R⊢ i < pivoter a b hab hu → a ≻[R (canonicalSwap a b hab i.succ)] b
At the pivot itself, society has (at least weakly) switched to b ≽ a:
/-- At the pivotal voter, society flips to `b ≻ a`. -/
lemma flipped (a b : α) {hab : a ≠ b} {hu: Unanimity R}:
b ≽[R (canonicalSwap a b hab (pivoter a b hab hu).succ)] a := α:TypeN:ℕinst✝:NeZero NR:SWF α Na:αb:αhab:a ≠ bhu:Unanimity R⊢ b ≽[R (canonicalSwap a b hab (pivoter a b hab hu).succ)] a
Note that flipped gives a weak preference b ≽ a, not a strict one.
This is because pivoter is the first k where ¬(a ≻ b), which by not_lt is equivalent
to b ≽ a, but doesn't immediately imply b ≻ a.
Together, voter pivoter is precisely the tipping point: include one fewer voter and society
still prefers a; include the pivotal voter and society switches to weakly preferring b.
7. From Pivotal Voter to Dictator
7.1. The Key Lemma
The crux of the proof is the following: the pivotal voter for any pair (a, b) also
controls the social ranking of a third alternative c:
/-- The pivotal voter for `(a, b)` dictates the pair `(b, c)`. -/
lemma nab_dictate_bc (a b c: α)
(hab : a ≠ b) (hac : a ≠ c) (hbc : b ≠ c)
(hu: Unanimity R) (hIIA: IIA R)
: Dictates R (pivoter a b hab hu) b c := α:TypeN:ℕinst✝:NeZero NR:SWF α Na:αb:αc:αhab:a ≠ bhac:a ≠ chbc:b ≠ chu:Unanimity RhIIA:IIA R⊢ Dictates R (pivoter a b hab hu) b c
The proof is the most intricate part of the argument and uses two carefully crafted
"magic profiles" to leverage IIA.
Write n for pivoter a b hab hu.
Magic profile 1.The specific layout is chosen so that (a,b) and (b,c) can each be analyzed using the pivotal voter lemmas independently.
Voters 0, …, n-1 prefer b ≻ c ≻ a and voters n, …, N-1 prefer a ≻ b ≻ c.
In this profile:
-
Society prefers
a ≻ b: by IIA with the canonical swap, this profile's(a,b)rankings match a canonical swap profile whereno_flipapplies. -
Society prefers
b ≻ c: every single voter prefersb ≻ c, so Unanimity kicks in.
Therefore society prefers a ≻ b ≻ c in magic profile 1.
Magic profile 2.
Now take any profile pp where voter n strictly prefers b ≻ c.
Build a new profile that:
-
For voters
i < n: copiespp's ranking of(b, c)but ranks that block abovea. -
For voter
i = n: givesb ≻ a ≻ c. -
For voters
i > n: copiespp's ranking of(b, c)but ranksaat the top.
In this profile:
-
Society weakly prefers
b ≽ a: by IIA with the canonical swap and theflippedlemma. -
Society strictly prefers
a ≻ c: by IIA comparing with magic profile 1.
Combining: b ≽ a ≻ c, which by lt_of_lt_of_le gives b ≻ c.
Finally, profiles pp and magic profile 2 agree on (b, c) by construction,
so IIA transfers: society prefers b ≻ c in pp too.
Since pp was arbitrary (with voter n preferring b ≻ c), voter n dictates (b, c). ∎
7.2. Pivotal Voters Coincide
The proof next shows that the pivotal voter is the same for every pair of alternatives. It establishes two ordering inequalities between pivotal voters for different pairs.
nab_le_nbc — the pivotal voter for (a, b) comes no later than the one for (b, c):
/-- The pivotal voter for `(a, b)` comes no later than the one for `(b, c)`. -/
lemma nab_le_nbc (a b c: α)
(hab : a ≠ b) (hac : a ≠ c) (hbc : b ≠ c)
(hu: Unanimity R) (hIIA: IIA R)
: pivoter a b hab hu ≤ pivoter b c hbc hu := α:TypeN:ℕinst✝:NeZero NR:SWF α Na:αb:αc:αhab:a ≠ bhac:a ≠ chbc:b ≠ chu:Unanimity RhIIA:IIA R⊢ pivoter a b hab hu ≤ pivoter b c hbc hu
Proof by contradiction: if the (a,b) pivotal voter n_ab came after n_bc,
then in the canonical swap for (b,c) at step n_bc + 1,
voter n_ab already prefers b ≻ c.
By nab_dictate_bc, voter n_ab forces society to prefer b ≻ c there too.
But that profile is exactly where n_bc caused society to flip away from b,
giving a contradiction.
ncb_le_nab — the pivotal voter for (c, b) comes no later than the one for (a, b):
/-- The pivotal voter for `(c, b)` comes no later than the one for `(a, b)`. -/
lemma ncb_le_nab (a b c: α)
(hab : a ≠ b) (hac : a ≠ c) (hbc : b ≠ c)
(hu: Unanimity R) (hIIA: IIA R):
pivoter c b (Ne.symm hbc) hu ≤ pivoter a b hab hu := α:TypeN:ℕinst✝:NeZero NR:SWF α Na:αb:αc:αhab:a ≠ bhac:a ≠ chbc:b ≠ chu:Unanimity RhIIA:IIA R⊢ pivoter c b ⋯ hu ≤ pivoter a b hab hu
Proof by contradiction: if n_cb came after n_ab, then at step n_ab in the canonical swap
for (c,b), voter n_ab prefers b ≻ c.
By nab_dictate_bc, society also prefers b ≻ c.
But n_ab is before n_cb, so by no_flip, society should still prefer c ≻ b — contradiction.
Combining both inequalities cyclically (and applying them to (b,c) and (c,b) symmetrically),
all pivotal voters for pairs within {a, b, c} collapse to a single voter.
7.3. Dictating Every Pair
With all pivotal voters identified as the same voter n,
nab_dictate_xy extends dictatorship to every pair (x, y):
/-- The pivotal voter for any pair `(a, b)` dictates *every* pair `(x, y)`. -/
lemma nab_dictate_xy (a b c x y: α)
(hab : a ≠ b) (hac : a ≠ c) (hbc : b ≠ c) (hxy : x ≠ y)
(hu: Unanimity R) (hIIA: IIA R):
Dictates R (pivoter a b hab hu) x y := α:TypeN:ℕinst✝:NeZero NR:SWF α Na:αb:αc:αx:αy:αhab:a ≠ bhac:a ≠ chbc:b ≠ chxy:x ≠ yhu:Unanimity RhIIA:IIA R⊢ Dictates R (pivoter a b hab hu) x y
The proof is a case split on whether x and y lie in {b, c}.
Each case routes through one or two applications of nab_dictate_bc (with appropriate
bridging alternatives) and uses the pivotal-voter equality lemmas to transfer the
identity of the pivotal voter across pairs.
8. Arrow's Impossibility Theorem
Assembling all the pieces: if an SWF satisfies Unanimity and IIA, its pivotal voter for any pair dictates every other pair — making them a full dictator and contradicting Non-Dictatorship.
/-- **Arrow's Impossibility Theorem**: No SWF with ≥3 alternatives and ≥1 voters
can satisfy Unanimity, IIA, and Non-Dictatorship simultaneously. -/
theorem Impossibility [Fintype α] (ha : Fintype.card α ≥ 3):
¬ ∃ R : SWF α N, (Unanimity R) ∧ (IIA R) ∧ (NonDictatorship R) := α:TypeN:ℕinst✝¹:NeZero Ninst✝:Fintype αha:Fintype.card α ≥ 3⊢ ¬∃ R, Unanimity R ∧ IIA R ∧ NonDictatorship RThe proof:
-
Assume for contradiction that such an
Rexists withhu : Unanimity R,hIIA : IIA R, andhNonDictator : NonDictatorship R. -
Since
|α| ≥ 3, extract three distinct alternativesa,b,cusingFintype.two_lt_card_iff. -
Let
n = pivoter a b hab hu. -
By
nab_dictate_xy, voterndictates every distinct pair(x, y). -
This gives an explicit dictator, contradicting
hNonDictator. ∎
Index
D
P
- pivotal voter (0) (1)
- preference profile