Draft — mutable and not usable as a dependency; its citation marks the draft state.

Lax11.ConnectedComponents

Connected components in linear time

concepts/Lax11/ConnectedComponents.lean · lax-11

proven

Loading review…

Sign in with ORCID

Community review

Flags

Each flag is tied to a public ORCID identity and explains why this concept may be incorrect.

No flags have been submitted.

    Community review

    Flag this concept

    State precisely what appears incorrect. This explanation will be public under your ORCID name.

    No source line selected.

    Concept map

    Proven claimDefinitionThis conceptRelated conceptA → B: B builds on A

    Evidence

    Each proof establishes this claim relative to its assumptions.

    Theorem

    The connected components of a graph can be computed in linear time. Label every vertex by the least vertex of its connected component; then there is one word RAM program and one constant c such that, at every word length, given any graph in compressed sparse row form as a word x for which c(|x|+1) is at most 2w2 ^ w, the program halts within c(|x|+1) steps with the labels of all vertices, in vertex order, as its output.

    Lean source view on GitHub

    1import Lax67.RamComputes
    2import Lax11.GraphEncoding
    3import Mathlib.Combinatorics.SimpleGraph.Connectivity.Connected
    4import Mathlib.Data.Nat.Lattice
    5
    6/-!
    7---
    8title: Connected components in linear time
    9type: theorem
    10---
    11The connected components of a graph can be computed in linear time.
    12Label every vertex by the least vertex of its connected component; then
    13there is one word RAM program and one constant *c* such that, at every
    14word length, given any graph in compressed sparse row form as a word
    15*x* for which *c*(|x|+1) is at most `2 ^ w`, the program halts within
    16*c*(|x|+1) steps with the labels of all vertices, in vertex order, as
    17its output.
    18
    19# Formalization notes
    20
    21Labelling a vertex by the least vertex reachable from it makes the
    22output a *function* of the graph, so the statement is about computing a
    23function and needs no convention for choosing representatives. Any
    24other canonical choice would do; what matters is that the answer is
    25determined, since a program that may return any of several correct
    26answers would be a weaker claim dressed up as this one.
    27
    28The least vertex is the infimum of the set of numbers of vertices
    29reachable from `v`. That set contains `v` itself, so the value is a
    30genuine minimum and the convention `sInf ∅ = 0` for natural numbers is
    31never exercised. The labelling of the whole graph is the list of these
    32values in vertex order, so its length is the number of vertices.
    33
    34The order of quantifiers is the content of the theorem: the program and
    35the constant come first, the graph next and the word length last, so
    36one program with one constant serves every graph at every word length.
    37Quantifying the program before the word length is what makes it an
    38algorithm rather than a family of them — a program chosen after `w`
    39could hide an arbitrary amount of information in its literals — and it
    40is the strong form of uniformity the model supports, since a program
    41can measure `w` for itself.
    42
    43The bound is linear in the length of the input word — the number of
    44entries actually handed to the machine, namely `3 + n + 2m` — which is
    45the input size in the sense the model charges for. Reading the input
    46alone takes that many steps, so the bound is tight up to the constant.
    47The `+ 1` only keeps the bound from being vacuous on inputs of length
    480, of which there are none valid.
    49
    50One constant does both jobs. An encoding is admissible at word length
    51`w` when `c * (|x| + 1) ≤ 2 ^ w`, that is, when `2 ^ w` is at least
    52the very number of steps the claim allows; this is the "the word is
    53wide enough for the input" hypothesis of the word-RAM literature, written
    54out as an explicit inequality against `2 ^ w` rather than through a
    55logarithm. Nothing further need be asked of the entries: an encoding's
    56entries are vertex numbers, offsets and the two header numbers, all
    57smaller than its own length, so a word length that admits an encoding
    58also holds every number in it.
    59
    60The fitting condition is a condition on the admissible inputs and not a
    61hypothesis of the claim, because as a hypothesis it would be empty. A
    62graph with an edge has encodings of every length, since a block may
    63list a neighbour repeatedly, so no word length accommodates all
    64encodings of a fixed graph at once and "if every encoding of `G` fits
    65into a word" would never be satisfied. Restricting the inputs instead
    66says what is meant: at every word length, every encoding that fits is
    67computed within the bound.
    68
    69Only encodings of `G` are admitted as inputs; the program may behave
    70arbitrarily on words that encode nothing, and on words too long for its
    71word length.
    72-/
    73
    74namespace Lax11.ConnectedComponents
    75
    76open Lax67.Ram Lax67.RamComputes Lax11.GraphEncoding
    77
    78/-- The label of a vertex: the least vertex of its connected
    79component. -/
    80noncomputable def label {n : ℕ} (G : SimpleGraph (Fin n)) (v : Fin n) : ℕ :=
    81 sInf (Fin.val '' {u : Fin n | G.Reachable u v})
    82
    83/-- The component labelling of a graph: the labels of all vertices, in
    84vertex order. -/
    85noncomputable def ccLabels {n : ℕ} (G : SimpleGraph (Fin n)) : List ℕ :=
    86 List.ofFn (label G)
    87
    88/-- Connected components can be computed in linear time on a word
    89random access machine: one program labels the vertices of every graph
    90given in compressed sparse row form by the least vertex of their
    91component, within a constant multiple of the length of the input, at
    92every word length `w` with that constant multiple at most `2 ^ w`. -/
    93axiom exists_linearTime_program_ccLabels :
    94 ∃ (p : Program) (c : ℕ), ∀ (n : ℕ) (G : SimpleGraph (Fin n)) (w : ℕ),
    95 ComputesInTime w p {x | EncodesGraph x n G ∧ c * (x.length + 1) ≤ 2 ^ w}
    96 (fun _ => ccLabels G) (fun x => c * (x.length + 1))
    97
    98end Lax11.ConnectedComponents
    99
    Show Proof

    Formalization notes

    Labelling a vertex by the least vertex reachable from it makes the output a function of the graph, so the statement is about computing a function and needs no convention for choosing representatives. Any other canonical choice would do; what matters is that the answer is determined, since a program that may return any of several correct answers would be a weaker claim dressed up as this one.

    The least vertex is the infimum of the set of numbers of vertices reachable from vv. That set contains vv itself, so the value is a genuine minimum and the convention sInf=0sInf ∅ = 0 for natural numbers is never exercised. The labelling of the whole graph is the list of these values in vertex order, so its length is the number of vertices.

    The order of quantifiers is the content of the theorem: the program and the constant come first, the graph next and the word length last, so one program with one constant serves every graph at every word length. Quantifying the program before the word length is what makes it an algorithm rather than a family of them — a program chosen after ww could hide an arbitrary amount of information in its literals — and it is the strong form of uniformity the model supports, since a program can measure ww for itself.

    The bound is linear in the length of the input word — the number of entries actually handed to the machine, namely 3+n+2m3 + n + 2m — which is the input size in the sense the model charges for. Reading the input alone takes that many steps, so the bound is tight up to the constant. The +1+ 1 only keeps the bound from being vacuous on inputs of length 0, of which there are none valid.

    One constant does both jobs. An encoding is admissible at word length ww when c(x+1)2wc * (|x| + 1) ≤ 2 ^ w, that is, when 2w2 ^ w is at least the very number of steps the claim allows; this is the "the word is wide enough for the input" hypothesis of the word-RAM literature, written out as an explicit inequality against 2w2 ^ w rather than through a logarithm. Nothing further need be asked of the entries: an encoding's entries are vertex numbers, offsets and the two header numbers, all smaller than its own length, so a word length that admits an encoding also holds every number in it.

    The fitting condition is a condition on the admissible inputs and not a hypothesis of the claim, because as a hypothesis it would be empty. A graph with an edge has encodings of every length, since a block may list a neighbour repeatedly, so no word length accommodates all encodings of a fixed graph at once and "if every encoding of GG fits into a word" would never be satisfied. Restricting the inputs instead says what is meant: at every word length, every encoding that fits is computed within the bound.

    Only encodings of GG are admitted as inputs; the program may behave arbitrarily on words that encode nothing, and on words too long for its word length.

    Community review

    Discussion

    Ask a question or add context. Endorsements and structured flags are kept in the review panel above; your ORCID profile must share a public name.

    0 comments

    Loading discussion…