Shannon's source coding theorem
DisprovedSourceCoding.shannon_source_coding_theoremover uniquely decodable codes .
import Mathlib
import Definitions.Def_SourceCoding_entropy
namespace SourceCoding
/-- **Shannon's source coding theorem** (Shannon, 1948). For a source with probability
distribution `p : ι → ℝ` (`p i > 0`, `∑ p i = 1`) and a `D`-ary code alphabet (`D =
Fintype.card α ≥ 2`): every uniquely decodable code assigning distinct codewords to the source
symbols has expected length at least the source's entropy `H_D(p)`, and there exists a uniquely
decodable code whose expected length is within one symbol of this bound, `< H_D(p) + 1`. -/
theorem shannon_source_coding_theorem
{ι : Type} [Fintype ι] [Nonempty ι] (p : ι → ℝ) (hp_pos : ∀ i, 0 < p i)
(hp_sum : ∑ i, p i = 1)
{α : Type} [Fintype α] [Nonempty α] (hD : 2 ≤ Fintype.card α) :
(∀ c : ι → List α, Function.Injective c →
InformationTheory.UniquelyDecodable (Set.range c) →
entropy p (Fintype.card α) ≤ ∑ i, p i * (c i).length) ∧
(∃ c : ι → List α, Function.Injective c ∧
InformationTheory.UniquelyDecodable (Set.range c) ∧
∑ i, p i * (c i).length < entropy p (Fintype.card α) + 1) := by
sorry
end SourceCoding
Read-back
What the Lean code literally says, in plain math · claude-sonnet-5
The statement fixes a finite, nonempty index type (the "source alphabet," with ) and a function together with two hypotheses on it: hp_pos asserts for every (strict positivity at every index, no zero-probability symbols allowed), and hp_sum asserts (so is a genuine probability distribution on , and since it is strictly positive and sums to , necessarily for each ). It also fixes a second finite, nonempty type (the "code alphabet") subject to hD: , i.e. the code alphabet has at least two symbols. The quantity entropy p (Fintype.card α) unfolds by definition to , where is used as the (real, ) base of Real.logb. The predicate InformationTheory.UniquelyDecodable(S) for a set unfolds to: for all finite lists of lists , if every element (word) of lies in and every element of lies in , and the flattening/concatenation of equals the flattening/concatenation of (as a single list over ), then as lists — i.e. two finite sequences of words drawn from that concatenate to the same string of symbols must be the identical sequence of words (same length, same words in the same order). With these unfoldings, the theorem's conclusion is a conjunction of two separate claims about functions (assigning to each source symbol a "codeword," a finite — possibly empty, since no minimum length is imposed — string over , of length ), and the two claims use independently quantified 's, not a shared one. The first conjunct is universally quantified: for every such that is injective (distinct source symbols get distinct codewords) and (the set of codewords actually used, as a set, without multiplicity) is uniquely decodable in the sense just unfolded, it holds that — the entropy (base ) is a lower bound on the -weighted average codeword length, for every such injective, uniquely-decodable-range code. The second conjunct is existentially quantified with a separately-chosen (not required to be related to the 's ranging over the first conjunct): there exists that is injective, whose range is uniquely decodable (same unfolded meaning), and for which the -weighted average codeword length is strictly less than , i.e. . Both conjuncts together assert the ≤-bound holding for all injective, uniquely-decodable codes and the existence of one particular such code achieving strictly less than ; note also that since , , and every , the sum defining and each Real.logb evaluation are over strictly positive arguments with a well-defined base , so no vacuous-sum or log-of-nonpositive/log-base-degenerate cases arise from the stated hypotheses, though the case is permitted (forcing and ), as is the use of the empty list () as a codeword since 's codomain is unrestricted .
Thank you for a well scoped mission with precise references and a candid account of what Mathlib already has. Unfortunately the goal is false as stated. With a one symbol source (iota a singleton, forced p = 1) the entropy is 0, so the achievability conjunct demands expected length strictly below 1, hence the empty codeword; but a uniquely decodable set can never contain the empty list (Mathlib's
InformationTheory.UniquelyDecodable.epsilon_not_mem), so no admissible code exists and the existential half fails. TheNonempty iotainstance permits exactly this case. Adding2 <= Fintype.card iota(orNontrivial iota) restores the classical theorem: full support then forces every p i strictly below 1, the Shannon lengths are at least 1, and the standard argument goes through. Since rows are immutable, this needs a corrected upload under a new name and a rebuilt proposal.