Graphs and nice tree decompositions as words
Lax117284.GraphWords · concepts/Lax117284/GraphWords.lean · lax-117284
No public endorsements yet.
Loading review…
Sign in with ORCIDNatural Language Statement
Definition
A tree decomposition of a graph is a tree whose nodes carry bags of vertices such that every vertex and every edge lies in a bag and the nodes whose bags contain a fixed vertex form a connected subtree; its width is the largest bag size minus one, and the treewidth of the graph is the least width of a decomposition (the archive's ). A tree decomposition is nice if its root and its leaves have empty bags and every other node is either an introduce node, whose bag is the bag of its single child plus one vertex, a forget node, whose bag is the bag of its single child minus one vertex, or a join node, with two children whose bags equal its own. This is the form dynamic programs over tree decompositions consume; it is due to Kloks.
Concept map
In the paper
- page 5 of this submission's paper
Lean source view on GitHub
| 1 | import Mathlib.Combinatorics.SimpleGraph.Acyclic |
| 2 | import Mathlib.Combinatorics.SimpleGraph.Connectivity.Connected |
| 3 | import Lax228581.Treewidth |
| 4 | |
| 5 | /-! |
| 6 | --- |
| 7 | title: Graphs and nice tree decompositions as words |
| 8 | type: definition |
| 9 | --- |
| 10 | A *tree decomposition* of a graph is a tree whose nodes carry bags of vertices such that every |
| 11 | vertex and every edge lies in a bag and the nodes whose bags contain a fixed vertex form a |
| 12 | connected subtree; its width is the largest bag size minus one, and the *treewidth* of the |
| 13 | graph is the least width of a decomposition (the archive's `Lax228581.Treewidth`). A tree |
| 14 | decomposition is *nice* if its root and its leaves have empty bags and every other node is |
| 15 | either an *introduce* node, whose bag is the bag of its single child plus one vertex, a |
| 16 | *forget* node, whose bag is the bag of its single child minus one vertex, or a *join* node, |
| 17 | with two children whose bags equal its own. This is the form dynamic programs over tree |
| 18 | decompositions consume; it is due to Kloks. |
| 19 | |
| 20 | # Formalization notes |
| 21 | |
| 22 | The word RAM of the archive reads and writes lists of natural numbers, so this module fixes |
| 23 | how a graph and a nice tree decomposition are written as one. |
| 24 | |
| 25 | A graph on the vertices `0 … n - 1` is written as `n` followed by its adjacency matrix row by |
| 26 | row, each entry `1` for adjacent and `0` for not: `1 + n * n` numbers. The matrix rather |
| 27 | than an edge list, so that a program which fills a table indexed by pairs of vertices reads an |
| 28 | entry in one instruction; the length of the word is then quadratic in the number of vertices, |
| 29 | and the running times below are polynomial in it, not linear. |
| 30 | |
| 31 | A nice tree decomposition is a word `N` followed by `N` records of three numbers, one for each |
| 32 | node, in an order in which every node comes after its children: the kind of the node (`0` |
| 33 | leaf, `1` introduce, `2` forget, `3` join), a vertex (for an introduce or a forget node) and a |
| 34 | node (the second child of a join node). The first child of a node that is not a leaf is the node |
| 35 | just before it, and the last node is the root. Bags are not written: they are determined from |
| 36 | the leaves upward, a leaf having the empty bag. Listed in this order, the nodes describe a rooted tree in which each |
| 37 | node has at most two children. |
| 38 | `NiceDecomposition G w D` says that `D` describes a tree, that the bags it determines cover the |
| 39 | vertices and the edges of `G`, that they are connected as required, and that they have at most |
| 40 | `w + 1` vertices. It is the archive's tree decomposition written out for words. |
| 41 | |
| 42 | The root is *not* required to have an empty bag: every consumer of a nice decomposition only |
| 43 | uses that each vertex is introduced once along each path and forgotten after its last edge, |
| 44 | and the root's bag can be emptied by forget nodes at the cost of a linear number of further |
| 45 | nodes. A word with a nonempty root bag is still a nice tree decomposition here. |
| 46 | -/ |
| 47 | |
| 48 | namespace Lax117284.GraphWords |
| 49 | |
| 50 | open Lax228581.Treewidth |
| 51 | |
| 52 | -- The word of a decomposition. |
| 53 | |
| 54 | /-- The number of nodes of the decomposition word `D`: its first entry. -/ |
| 55 | def nodeCount (D : List ℕ) : ℕ := D.getD 0 0 |
| 56 | |
| 57 | /-- The kind of node `i`: `0` leaf, `1` introduce, `2` forget, `3` join. -/ |
| 58 | def kind (D : List ℕ) (i : ℕ) : ℕ := D.getD (1 + 3 * i) 0 |
| 59 | |
| 60 | /-- The vertex of node `i`, for an introduce or a forget node. -/ |
| 61 | def vertex (D : List ℕ) (i : ℕ) : ℕ := D.getD (2 + 3 * i) 0 |
| 62 | |
| 63 | /-- The second child of node `i`, for a join node. -/ |
| 64 | def other (D : List ℕ) (i : ℕ) : ℕ := D.getD (3 + 3 * i) 0 |
| 65 | |
| 66 | /-- The bag of node `i` among the vertices `0 … n - 1`, from the leaves up: the empty bag at a |
| 67 | leaf, the child's bag plus the vertex at an introduce node, minus it at a forget node, and the |
| 68 | child's bag at a join node. The first child of node `i + 1` is node `i`. -/ |
| 69 | def bagAt (n : ℕ) (D : List ℕ) : ℕ → Finset (Fin n) |
| 70 | | 0 => ∅ |
| 71 | | i + 1 => |
| 72 | if kind D (i + 1) = 1 then |
| 73 | if h : vertex D (i + 1) < n then insert ⟨vertex D (i + 1), h⟩ (bagAt n D i) |
| 74 | else bagAt n D i |
| 75 | else if kind D (i + 1) = 2 then |
| 76 | if h : vertex D (i + 1) < n then (bagAt n D i).erase ⟨vertex D (i + 1), h⟩ |
| 77 | else bagAt n D i |
| 78 | else if kind D (i + 1) = 3 then bagAt n D i |
| 79 | else ∅ |
| 80 | |
| 81 | /-- Node `c` is a child of node `p`. -/ |
| 82 | def IsChild (D : List ℕ) (c p : ℕ) : Prop := |
| 83 | p < nodeCount D ∧ |
| 84 | ((kind D p = 1 ∨ kind D p = 2) ∧ c + 1 = p ∨ kind D p = 3 ∧ (c + 1 = p ∨ c = other D p)) |
| 85 | |
| 86 | /-- The graph on the nodes `0 … N - 1` whose edges join a node to its children. -/ |
| 87 | def treeGraph (D : List ℕ) : SimpleGraph (Fin (nodeCount D)) where |
| 88 | Adj a b := a ≠ b ∧ (IsChild D a.val b.val ∨ IsChild D b.val a.val) |
| 89 | symm := ⟨fun _ _ h => ⟨h.1.symm, h.2.symm⟩⟩ |
| 90 | loopless := ⟨fun _ h => h.1 rfl⟩ |
| 91 | |
| 92 | /-- **`D` is the word of a nice tree decomposition of `G` of width at most `w`.** -/ |
| 93 | structure NiceDecomposition {n : ℕ} (G : SimpleGraph (Fin n)) (w : ℕ) (D : List ℕ) : Prop where |
| 94 | /-- The word is `N` followed by three numbers for each of the `N` nodes. -/ |
| 95 | length_eq : D.length = 1 + 3 * nodeCount D |
| 96 | /-- There is a node. -/ |
| 97 | nonempty : 0 < nodeCount D |
| 98 | /-- Every node is a leaf, or an introduce node over the node before it whose vertex is not in |
| 99 | that node's bag, or a forget node over the node before it whose vertex is in that node's bag, |
| 100 | or a join node whose two children, the node before it and an earlier node, have its bag. -/ |
| 101 | shape : ∀ i, i < nodeCount D → |
| 102 | kind D i = 0 ∨ |
| 103 | (0 < i ∧ kind D i = 1 ∧ vertex D i < n ∧ |
| 104 | ∀ h : vertex D i < n, (⟨vertex D i, h⟩ : Fin n) ∉ bagAt n D (i - 1)) ∨ |
| 105 | (0 < i ∧ kind D i = 2 ∧ vertex D i < n ∧ |
| 106 | ∀ h : vertex D i < n, (⟨vertex D i, h⟩ : Fin n) ∈ bagAt n D (i - 1)) ∨ |
| 107 | (0 < i ∧ kind D i = 3 ∧ other D i + 1 < i ∧ |
| 108 | bagAt n D (other D i) = bagAt n D (i - 1)) |
| 109 | /-- Every node other than the last has exactly one parent. -/ |
| 110 | parent : ∀ c, c + 1 < nodeCount D → ∃! p, IsChild D c p |
| 111 | /-- The nodes form a tree. -/ |
| 112 | isTree : (treeGraph D).IsTree |
| 113 | /-- Every vertex is in a bag. -/ |
| 114 | covers : ∀ v : Fin n, ∃ i, i < nodeCount D ∧ v ∈ bagAt n D i |
| 115 | /-- Every two adjacent vertices are in a bag together. -/ |
| 116 | edges : ∀ u v : Fin n, G.Adj u v → |
| 117 | ∃ i, i < nodeCount D ∧ u ∈ bagAt n D i ∧ v ∈ bagAt n D i |
| 118 | /-- The nodes whose bags contain a fixed vertex form a connected subtree. -/ |
| 119 | connected : ∀ v : Fin n, |
| 120 | ((treeGraph D).induce {i : Fin (nodeCount D) | v ∈ bagAt n D i}).Connected |
| 121 | /-- Every bag has at most `w + 1` vertices. -/ |
| 122 | width : ∀ i, i < nodeCount D → (bagAt n D i).card ≤ w + 1 |
| 123 | |
| 124 | open Classical in |
| 125 | /-- **`g` is the word of the graph `G`**: the number of vertices, then the adjacency matrix row |
| 126 | by row. -/ |
| 127 | structure EncodesGraph {n : ℕ} (g : List ℕ) (G : SimpleGraph (Fin n)) : Prop where |
| 128 | /-- The word is the count followed by the matrix. -/ |
| 129 | length_eq : g.length = 1 + n * n |
| 130 | /-- The first entry is the number of vertices. -/ |
| 131 | head_eq : g.getD 0 0 = n |
| 132 | /-- The entry of the row `u` and column `v` is `1` when the two vertices are adjacent and `0` |
| 133 | otherwise. -/ |
| 134 | adj_eq : ∀ u v : Fin n, g.getD (1 + u.val * n + v.val) 0 = if G.Adj u v then 1 else 0 |
| 135 | |
| 136 | end Lax117284.GraphWords |
| 137 |
Formalization notes
The word RAM of the archive reads and writes lists of natural numbers, so this module fixes how a graph and a nice tree decomposition are written as one.
A graph on the vertices is written as followed by its adjacency matrix row by row, each entry for adjacent and for not: numbers. The matrix rather than an edge list, so that a program which fills a table indexed by pairs of vertices reads an entry in one instruction; the length of the word is then quadratic in the number of vertices, and the running times below are polynomial in it, not linear.
A nice tree decomposition is a word followed by records of three numbers, one for each node, in an order in which every node comes after its children: the kind of the node ( leaf, introduce, forget, join), a vertex (for an introduce or a forget node) and a node (the second child of a join node). The first child of a node that is not a leaf is the node just before it, and the last node is the root. Bags are not written: they are determined from the leaves upward, a leaf having the empty bag. Listed in this order, the nodes describe a rooted tree in which each node has at most two children. says that describes a tree, that the bags it determines cover the vertices and the edges of , that they are connected as required, and that they have at most vertices. It is the archive's tree decomposition written out for words.
The root is not required to have an empty bag: every consumer of a nice decomposition only uses that each vertex is introduced once along each path and forgotten after its last edge, and the root's bag can be emptied by forget nodes at the cost of a linear number of further nodes. A word with a nonempty root bag is still a nice tree decomposition here.
Discussion
Ask a question or add context. Endorsements and structured flags are kept in the review panel above.
0 comments