Proofs: Compressed sparse column
These are the human proofs of Compressed sparse column, at full length.
BUILD-FROM-CSR makes a valid compressed sparse column array and the queries answer for the stored graph full
This proof shows: correctness, termination.
Let be a directed graph on with distinct edges, given by CSR arrays and : the row lists the heads of the edges out of , each once, and . Write for the number of edges into . The CSC arrays stand for the graph with an edge for each in the column . The invariant (K) is (K1) on the offsets and (K2) strictly sorted columns.
Lemma 1 (offsets). After line L3, for . So (K1) holds and the column of has slots.
Proof. Line L2 reads each of the entries of once, and each entry is the head of one edge, so afterwards . Line L3 then computes the prefix sums, so the claim follows by induction on , with and .
Lemma 2 (placement). After lines L5 to L7, the column of each holds exactly the tails of the edges into , in increasing order.
Proof. Lines L5 and L6 visit the CSR entries row by row, for , so they visit each edge once, in non-decreasing order of . We claim that before each visit, for each , , where is the number of edges into visited so far, and the slots hold their tails in the order of the visits. This holds after line L4 with , and line L7 keeps it by writing at slot and increasing . Since , each write stays within the column of by Lemma 1. At the end , so each column is full and holds exactly the tails of the edges into , in the order of the visits, which is non-decreasing in . The edges are distinct, so two edges into have different tails, and the column is strictly increasing. The loops run over rows and entries, so they stop.
So after BUILD-FROM-CSR, (K) holds and the stored graph is .
Theorem. With (K) holding, IN-NEIGHBORS outputs the tails of the edges into in increasing order, IN-DEGREE returns , and ADJACENT returns whether is an edge. Each of them stops.
Proof. IN-NEIGHBORS reads exactly the column of , which by Lemma 2 is the sorted list of the tails. IN-DEGREE returns the length of the column, which is by Lemma 1.
For ADJACENT, let and . The loop of lines L11 to L13 keeps the condition that , each entry of the column at an index in is less than , and each entry at an index in is at least . Line L10 makes it true with empty ranges. In a step, ; if then, as the column is sorted, all entries up to are less than , and keeps the condition; otherwise all entries from on are at least , and keeps it. Each step shrinks , so the loop stops with . Then , if it is in the column, can only be at index , so line L14 returns true exactly when is in the column of , that is, when is an edge.