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

Lax11.GraphEncoding

Compressed sparse row encoding of a graph

concepts/Lax11/GraphEncoding.lean · lax-11

definition

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 claimOpen claimDefinitionThis conceptRelated conceptA → B: B builds on A

    Definition

    A graph is handed to a word random access machine as a word of numbers in compressed sparse row form, the adjacency-array format every textbook assumes: the number n of vertices, the number m of edges, then n+1 offsets, then the target array. The target array lists, for each vertex in turn, the neighbors of that vertex; the offsets say where each vertex's block of neighbors begins, the first offset being 0 and the last one the length of the target array. So the neighbors of vertex u are the entries of the target array at the positions from the u-th offset up to, but excluding, the (u+1)-st.

    Lean source view on GitHub

    1import Mathlib.Combinatorics.SimpleGraph.Basic
    2
    3/-!
    4---
    5title: Compressed sparse row encoding of a graph
    6type: definition
    7---
    8A graph is handed to a word random access machine as a word of numbers
    9in compressed sparse row form, the adjacency-array format every
    10textbook assumes: the number *n* of vertices, the number *m* of edges, then
    11*n+1* offsets, then the target array. The target array lists, for each
    12vertex in turn, the neighbors of that vertex; the offsets say where
    13each vertex's block of neighbors begins, the first offset being 0 and
    14the last one the length of the target array. So the neighbors of vertex
    15*u* are the entries of the target array at the positions from the *u*-th
    16offset up to, but excluding, the *(u+1)*-st.
    17
    18# Formalization notes
    19
    20The encoding is deliberately dumb: it is exactly the input format,
    21with nothing precomputed that an algorithm would otherwise have to
    22compute. The word is required to have the right length, the offsets to
    23be nondecreasing with the right two endpoints, and every target entry
    24to be a vertex; beyond that the only condition is that each vertex's
    25block lists exactly its neighbors. In particular the blocks are not
    26required to be sorted and repetitions are not forbidden — the fewer
    27conditions the encoding imposes, the more inputs a claim about
    28programs reading it has to handle, so leaving them out strengthens
    29every such claim rather than weakening it. For the same reason `m` is
    30only the declared length of the target array (which is `2m`): it is at
    31least the number of edges, and equals it exactly when no block repeats
    32a neighbor. Nothing forces each edge to be listed from both of its
    33endpoints either — that is automatic, since adjacency in a simple
    34graph is symmetric.
    35
    36Cells are read with `List.getD`, which returns `0` outside the word;
    37the length condition pins down the word completely, so this default
    38value is never reached at any position the other conditions constrain.
    39The conditions are bundled as a structure so that each one is a named
    40obligation a reader can check off separately.
    41
    42Nothing here mentions the word length of the machine the encoding is
    43handed to. It does not have to: every entry of an encoding is a vertex
    44number, an offset into the target array, or one of the two header
    45numbers, and each of those is smaller than the length of the word
    46itself, so an encoding that a machine can address at all is one whose
    47entries fit into that machine's words. The condition that it does fit
    48belongs to the claims made about programs reading the encoding, and is
    49stated there, once, as an explicit inequality against `2 ^ w`.
    50-/
    51
    52namespace Lax11.GraphEncoding
    53
    54/-- The number of vertices declared by a word: its first entry. -/
    55def vertexCount (x : List ℕ) : ℕ := x.getD 0 0
    56
    57/-- The number of edges declared by a word: its second entry. -/
    58def edgeCount (x : List ℕ) : ℕ := x.getD 1 0
    59
    60/-- The `i`-th offset of a word: the `n+1` offsets follow the two
    61header entries. -/
    62def offset (x : List ℕ) (i : ℕ) : ℕ := x.getD (2 + i) 0
    63
    64/-- The `j`-th entry of the target array of a word, which follows the
    65header and the offsets. -/
    66def target (x : List ℕ) (j : ℕ) : ℕ := x.getD (3 + vertexCount x + j) 0
    67
    68/-- The word `x` is a compressed sparse row encoding of the graph `G`
    69on `n` vertices. -/
    70structure EncodesGraph (x : List ℕ) (n : ℕ) (G : SimpleGraph (Fin n)) :
    71 Prop where
    72 /-- The word declares `n` vertices. -/
    73 vertexCount_eq : vertexCount x = n
    74 /-- The word consists of the two header entries, the `n+1` offsets,
    75 and a target array of length twice the declared number of edges. -/
    76 length_eq : x.length = 3 + n + 2 * edgeCount x
    77 /-- The block of the first vertex begins at the start of the target
    78 array. -/
    79 offset_zero : offset x 0 = 0
    80 /-- The block of the last vertex ends at the end of the target
    81 array. -/
    82 offset_last : offset x n = 2 * edgeCount x
    83 /-- The offsets are nondecreasing, so they cut the target array into
    84 one block per vertex. -/
    85 offset_mono : ∀ i < n, offset x i ≤ offset x (i + 1)
    86 /-- Every entry of the target array is a vertex. -/
    87 target_lt : ∀ j < 2 * edgeCount x, target x j < n
    88 /-- The block of a vertex lists exactly its neighbors. -/
    89 adj_iff : ∀ u v : Fin n, G.Adj u v ↔
    90 ∃ j, offset x u ≤ j ∧ j < offset x (u + 1) ∧ target x j = v
    91
    92end Lax11.GraphEncoding
    93

    Formalization notes

    The encoding is deliberately dumb: it is exactly the input format, with nothing precomputed that an algorithm would otherwise have to compute. The word is required to have the right length, the offsets to be nondecreasing with the right two endpoints, and every target entry to be a vertex; beyond that the only condition is that each vertex's block lists exactly its neighbors. In particular the blocks are not required to be sorted and repetitions are not forbidden — the fewer conditions the encoding imposes, the more inputs a claim about programs reading it has to handle, so leaving them out strengthens every such claim rather than weakening it. For the same reason mm is only the declared length of the target array (which is 2m2m): it is at least the number of edges, and equals it exactly when no block repeats a neighbor. Nothing forces each edge to be listed from both of its endpoints either — that is automatic, since adjacency in a simple graph is symmetric.

    Cells are read with List.getDList.getD, which returns 00 outside the word; the length condition pins down the word completely, so this default value is never reached at any position the other conditions constrain. The conditions are bundled as a structure so that each one is a named obligation a reader can check off separately.

    Nothing here mentions the word length of the machine the encoding is handed to. It does not have to: every entry of an encoding is a vertex number, an offset into the target array, or one of the two header numbers, and each of those is smaller than the length of the word itself, so an encoding that a machine can address at all is one whose entries fit into that machine's words. The condition that it does fit belongs to the claims made about programs reading the encoding, and is stated there, once, as an explicit inequality against 2w2 ^ w.

    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…