|
| 1 | +/- |
| 2 | +Copyright (c) 2020 Aaron Anderson, Jalex Stark, Kyle Miller. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Author: Aaron Anderson, Jalex Stark, Kyle Miller. |
| 5 | +-/ |
| 6 | +import data.fintype.basic |
| 7 | +import data.sym2 |
| 8 | +/-! |
| 9 | +# Simple graphs |
| 10 | +
|
| 11 | +This module defines simple graphs on a vertex type `V` as an |
| 12 | +irreflexive symmetric relation. |
| 13 | +
|
| 14 | +There is a basic API for locally finite graphs and for graphs with |
| 15 | +finitely many vertices. |
| 16 | +
|
| 17 | +## Main definitions |
| 18 | +
|
| 19 | +* `simple_graph` is a structure for symmetric, irreflexive relations |
| 20 | +
|
| 21 | +* `neighbor_set` is the `set` of vertices adjacent to a given vertex |
| 22 | +
|
| 23 | +* `neighbor_finset` is the `finset` of vertices adjacent to a given vertex, |
| 24 | + if `neighbor_set` is finite |
| 25 | +
|
| 26 | +## Implementation notes |
| 27 | +
|
| 28 | +* A locally finite graph is one with instances `∀ v, fintype (G.neighbor_set v)`. |
| 29 | +
|
| 30 | +* Given instances `decidable_rel G.adj` and `fintype V`, then the graph |
| 31 | +is locally finite, too. |
| 32 | +
|
| 33 | +TODO: This is the simplest notion of an unoriented graph. This should |
| 34 | +eventually fit into a more complete combinatorics hierarchy which |
| 35 | +includes multigraphs and directed graphs. We begin with simple graphs |
| 36 | +in order to start learning what the combinatorics hierarchy should |
| 37 | +look like. |
| 38 | +
|
| 39 | +TODO: Part of this would include defining, for example, subgraphs of a |
| 40 | +simple graph. |
| 41 | +
|
| 42 | +-/ |
| 43 | +open finset |
| 44 | +universe u |
| 45 | + |
| 46 | +/-- |
| 47 | +A simple graph is an irreflexive symmetric relation `adj` on a vertex type `V`. |
| 48 | +The relation describes which pairs of vertices are adjacent. |
| 49 | +There is exactly one edge for every pair of adjacent edges; |
| 50 | +see `simple_graph.edge_set` for the corresponding edge set. |
| 51 | +-/ |
| 52 | +structure simple_graph (V : Type u) := |
| 53 | +(adj : V → V → Prop) |
| 54 | +(sym : symmetric adj . obviously) |
| 55 | +(loopless : irreflexive adj . obviously) |
| 56 | + |
| 57 | +/-- |
| 58 | +The complete graph on a type `V` is the simple graph with all pairs of distinct vertices adjacent. |
| 59 | +-/ |
| 60 | +def complete_graph (V : Type u) : simple_graph V := |
| 61 | +{ adj := ne } |
| 62 | + |
| 63 | +instance (V : Type u) : inhabited (simple_graph V) := |
| 64 | +⟨complete_graph V⟩ |
| 65 | + |
| 66 | +instance complete_graph_adj_decidable (V : Type u) [decidable_eq V] : |
| 67 | + decidable_rel (complete_graph V).adj := |
| 68 | +by { dsimp [complete_graph], apply_instance } |
| 69 | + |
| 70 | +namespace simple_graph |
| 71 | +variables {V : Type u} (G : simple_graph V) |
| 72 | + |
| 73 | +/-- `G.neighbor_set v` is the set of vertices adjacent to `v` in `G`. -/ |
| 74 | +def neighbor_set (v : V) : set V := set_of (G.adj v) |
| 75 | + |
| 76 | +lemma ne_of_adj {a b : V} (hab : G.adj a b) : a ≠ b := |
| 77 | +by { rintro rfl, exact G.loopless a hab } |
| 78 | + |
| 79 | +/-- |
| 80 | +The edges of G consist of the unordered pairs of vertices related by |
| 81 | +`G.adj`. |
| 82 | +-/ |
| 83 | +def edge_set : set (sym2 V) := sym2.from_rel G.sym |
| 84 | + |
| 85 | +@[simp] |
| 86 | +lemma mem_edge_set {v w : V} : ⟦(v, w)⟧ ∈ G.edge_set ↔ G.adj v w := |
| 87 | +by refl |
| 88 | + |
| 89 | +/-- |
| 90 | +Two vertices are adjacent iff there is an edge between them. The |
| 91 | +condition `v ≠ w` ensures they are different endpoints of the edge, |
| 92 | +which is necessary since when `v = w` the existential |
| 93 | +`∃ (e ∈ G.edge_set), v ∈ e ∧ w ∈ e` is satisfied by every edge |
| 94 | +incident to `v`. |
| 95 | +-/ |
| 96 | +lemma adj_iff_exists_edge {v w : V} : |
| 97 | + G.adj v w ↔ v ≠ w ∧ ∃ (e ∈ G.edge_set), v ∈ e ∧ w ∈ e := |
| 98 | +begin |
| 99 | + split, { intro, split, { exact G.ne_of_adj a, }, {use ⟦(v,w)⟧, simpa} }, |
| 100 | + { rintro ⟨hne, e, he, hv⟩, |
| 101 | + rw sym2.elems_iff_eq hne at hv, |
| 102 | + subst e, |
| 103 | + rwa mem_edge_set at he, } |
| 104 | +end |
| 105 | + |
| 106 | +lemma edge_other_ne {e : sym2 V} (he : e ∈ G.edge_set) {v : V} (h : v ∈ e) : h.other ≠ v := |
| 107 | +begin |
| 108 | + erw [← sym2.mem_other_spec h, sym2.eq_swap] at he, |
| 109 | + exact G.ne_of_adj he, |
| 110 | +end |
| 111 | + |
| 112 | +instance edges_fintype [decidable_eq V] [fintype V] [decidable_rel G.adj] : |
| 113 | + fintype G.edge_set := by { dunfold edge_set, exact subtype.fintype _ } |
| 114 | + |
| 115 | +/-- |
| 116 | +The `edge_set` of the graph as a `finset`. |
| 117 | +-/ |
| 118 | +def edge_finset [decidable_eq V] [fintype V] [decidable_rel G.adj] : finset (sym2 V) := |
| 119 | +set.to_finset G.edge_set |
| 120 | + |
| 121 | +@[simp] lemma mem_edge_finset [decidable_eq V] [fintype V] [decidable_rel G.adj] (e : sym2 V) : |
| 122 | + e ∈ G.edge_finset ↔ e ∈ G.edge_set := |
| 123 | +by { dunfold edge_finset, simp } |
| 124 | + |
| 125 | +@[simp] lemma irrefl {v : V} : ¬G.adj v v := G.loopless v |
| 126 | + |
| 127 | +@[symm] lemma edge_symm (u v : V) : G.adj u v ↔ G.adj v u := ⟨λ x, G.sym x, λ x, G.sym x⟩ |
| 128 | + |
| 129 | +@[simp] lemma mem_neighbor_set (v w : V) : w ∈ G.neighbor_set v ↔ G.adj v w := |
| 130 | +by tauto |
| 131 | + |
| 132 | +section finite_at |
| 133 | + |
| 134 | +/-! |
| 135 | +## Finiteness at a vertex |
| 136 | +
|
| 137 | +This section contains definitions and lemmas concerning vertices that |
| 138 | +have finitely many adjacent vertices. We denote this condition by |
| 139 | +`fintype (G.neighbor_set v)`. |
| 140 | +
|
| 141 | +We define `G.neighbor_finset v` to be the `finset` version of `G.neighbor_set v`. |
| 142 | +Use `neighbor_finset_eq_filter` to rewrite this definition as a `filter`. |
| 143 | +-/ |
| 144 | + |
| 145 | +variables (v : V) [fintype (G.neighbor_set v)] |
| 146 | +/-- |
| 147 | +`G.neighbors v` is the `finset` version of `G.adj v` in case `G` is |
| 148 | +locally finite at `v`. |
| 149 | +-/ |
| 150 | +def neighbor_finset : finset V := (G.neighbor_set v).to_finset |
| 151 | + |
| 152 | +@[simp] lemma mem_neighbor_finset (w : V) : |
| 153 | + w ∈ G.neighbor_finset v ↔ G.adj v w := |
| 154 | +by simp [neighbor_finset] |
| 155 | + |
| 156 | +/-- |
| 157 | +`G.degree v` is the number of vertices adjacent to `v`. |
| 158 | +-/ |
| 159 | +def degree : ℕ := (G.neighbor_finset v).card |
| 160 | + |
| 161 | +@[simp] |
| 162 | +lemma card_neighbor_set_eq_degree : fintype.card (G.neighbor_set v) = G.degree v := |
| 163 | +by simp [degree, neighbor_finset] |
| 164 | + |
| 165 | +end finite_at |
| 166 | + |
| 167 | +section locally_finite |
| 168 | + |
| 169 | +/-- |
| 170 | +A graph is locally finite if every vertex has a finite neighbor set. |
| 171 | +-/ |
| 172 | +@[reducible] |
| 173 | +def locally_finite := Π (v : V), fintype (G.neighbor_set v) |
| 174 | + |
| 175 | +variable [locally_finite G] |
| 176 | + |
| 177 | +/-- |
| 178 | +A locally finite simple graph is regular of degree `d` if every vertex has degree `d`. |
| 179 | +-/ |
| 180 | +def is_regular_of_degree (d : ℕ) : Prop := ∀ (v : V), G.degree v = d |
| 181 | + |
| 182 | +end locally_finite |
| 183 | + |
| 184 | +section finite |
| 185 | + |
| 186 | +variables [fintype V] |
| 187 | + |
| 188 | +instance neighbor_set_fintype [decidable_rel G.adj] (v : V) : fintype (G.neighbor_set v) := |
| 189 | +@subtype.fintype _ _ (by { simp_rw mem_neighbor_set, apply_instance }) _ |
| 190 | + |
| 191 | +lemma neighbor_finset_eq_filter {v : V} [decidable_rel G.adj] : |
| 192 | + G.neighbor_finset v = finset.univ.filter (G.adj v) := |
| 193 | +by { ext, simp } |
| 194 | + |
| 195 | +@[simp] |
| 196 | +lemma complete_graph_degree [decidable_eq V] (v : V) : |
| 197 | + (complete_graph V).degree v = fintype.card V - 1 := |
| 198 | +begin |
| 199 | + convert univ.card.pred_eq_sub_one, |
| 200 | + erw [degree, neighbor_finset_eq_filter, filter_ne, card_erase_of_mem (mem_univ v)], |
| 201 | +end |
| 202 | + |
| 203 | +lemma complete_graph_is_regular [decidable_eq V] : |
| 204 | + (complete_graph V).is_regular_of_degree (fintype.card V - 1) := |
| 205 | +by { intro v, simp } |
| 206 | + |
| 207 | +end finite |
| 208 | + |
| 209 | +end simple_graph |
0 commit comments