Proofs: Incidence list
These are the human proofs of Incidence list, at full length.
The incidence-list operations keep the slot invariant and report the incident edges full
This proof shows: correctness.
We use the pseudocode of the page. An edge name is live when is true. The invariant is:
(I1) Each live occurs exactly once in , at index , and in no other list. (I2) Each live occurs exactly once in , at index , and in no other list. (I3) No list holds a name that is not live.
The empty structure, with no edge names and empty lists, meets (I1) to (I3) with nothing to check.
Lemma 1 (swap-remove). Let be a list in which the name occurs exactly once, at index , and in which each other name of occurs once at index . After SWAP-REMOVE, the list holds exactly the names of the old other than , each once, and is the index of for each of them.
Proof. Let be the index of the last cell and , and let . If , then , line L12 writes over itself, and line L13 removes the last cell, which holds the only copy of ; the other names keep their cells. If , then . Line L12 writes into cell and sets , so now occurs at cells and , and occurs nowhere. Line L13 removes cell . Now occurs once, at index , and each other name is in its old cell, which is below and is not cell . In both cases the claim holds.
ADD-EDGE. Line L1 picks , a name that no row of the table had, so by (I3) no list holds . Line L2 appends to and sets to its index; line L3 does the same in . So meets (I1) and (I2) with and . No other cell of any list moves, so (I1) and (I2) still hold for the other live edges, and (I3) holds because is live.
REMOVE-EDGE. Let be live, and . By (I1), the list meets the condition of Lemma 1 for and : each name in it is live by (I3), so each occurs once at its recorded index by (I1). By Lemma 1, after line L8 the list holds its old names without , at their recorded indices. Line L9 does the same for by (I2). These are the only lists that change, so (I1) and (I2) hold for each live edge other than . Line L10 makes not live, and is in no list: it was only in and , by (I1) and (I2), and it was removed from both. So (I3) holds. A self-loop, with , needs no special case, because and are two different lists.
INCIDENT. Let be a vertex of an undirected graph. The edges incident to are the live with or . By (I1) and (I3), holds exactly the live with , each once; by (I2) and (I3), holds exactly the live with , each once. Line L5 reports each of with its other end , and line L6 each of with its other end . So each non-loop edge at is reported once, and each self-loop at , which is in both lists, twice. The number of reports is , the degree with a self-loop counted twice. In a directed graph only line L5 runs, and it reports exactly the edges that leave , each once.
Sum of degrees. By (I1) to (I3), each live edge has exactly one cell in the lists and one in the lists, so , where is the number of live edges.
FIND-EDGE. In a directed graph, an edge from to is a live with and . By (I1) and (I3), each such is in , and by (I2) and (I3), each is in . So a scan of either list for a name with the right other end finds such an edge if and only if one exists. In an undirected graph an edge between and is incident to both, so by the INCIDENT case a scan of the incident edges of either end finds it if and only if it exists.
Cost. Lines L1 to L4 are a constant number of appends, each amortized for a dynamic array. Lines L7 to L13 are a constant number of array reads and writes, so REMOVE-EDGE is . INCIDENT does work for each of the cells it reads, plus . FIND-EDGE reads at most the length of the shorter list, plus . The structure has lists, cells and table rows, where is the number of names ever given; with no removals , and the space is .