Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 93be74b

Browse files
committed
feat(combinatorics/simple_graph/prod): Box product (#14867)
Define `simple_graph.box_prod`, the box product of simple graphs. Show that it's commutative and associative, and prove its connectivity properties.
1 parent 7c070c4 commit 93be74b

File tree

2 files changed

+167
-1
lines changed

2 files changed

+167
-1
lines changed

src/combinatorics/simple_graph/connectivity.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1047,7 +1047,7 @@ exactly one connected component.
10471047
10481048
There is a `has_coe_to_fun` instance so that `h u v` can be used instead
10491049
of `h.preconnected u v`. -/
1050-
@[protect_proj]
1050+
@[protect_proj, mk_iff]
10511051
structure connected : Prop :=
10521052
(preconnected : G.preconnected)
10531053
[nonempty : nonempty V]
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/-
2+
Copyright (c) 2022 George Peter Banyard, Yaël Dillies, Kyle Miller. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: George Peter Banyard, Yaël Dillies, Kyle Miller
5+
-/
6+
import combinatorics.simple_graph.connectivity
7+
8+
/-!
9+
# Graph products
10+
11+
This file defines the box product of graphs and other product constructions. The box product of `G`
12+
and `H` is the graph on the product of the vertices such that `x` and `y` are related iff they agree
13+
on one component and the other one is related via either `G` or `H`. For example, the box product of
14+
two edges is a square.
15+
16+
## Main declarations
17+
18+
* `simple_graph.box_prod`: The box product.
19+
20+
## Notation
21+
22+
* `G □ H`: The box product of `G` and `H`.
23+
24+
## TODO
25+
26+
Define all other graph products!
27+
-/
28+
29+
variables {α β γ : Type*}
30+
31+
namespace simple_graph
32+
variables {G : simple_graph α} {H : simple_graph β} {I : simple_graph γ} {a a₁ a₂ : α} {b b₁ b₂ : β}
33+
{x y : α × β}
34+
35+
/-- Box product of simple graphs. It relates `(a₁, b)` and `(a₂, b)` if `G` relates `a₁` and `a₂`,
36+
and `(a, b₁)` and `(a, b₂)` if `H` relates `b₁` and `b₂`. -/
37+
def box_prod (G : simple_graph α) (H : simple_graph β) : simple_graph (α × β) :=
38+
{ adj := λ x y, G.adj x.1 y.1 ∧ x.2 = y.2 ∨ H.adj x.2 y.2 ∧ x.1 = y.1,
39+
symm := λ x y, by simp [and_comm, or_comm, eq_comm, adj_comm],
40+
loopless := λ x, by simp }
41+
42+
infix ` □ `:70 := box_prod
43+
44+
lemma box_prod_adj : (G □ H).adj x y ↔ G.adj x.1 y.1 ∧ x.2 = y.2 ∨ H.adj x.2 y.2 ∧ x.1 = y.1 :=
45+
iff.rfl
46+
47+
@[simp] lemma box_prod_adj_left : (G □ H).adj (a₁, b) (a₂, b) ↔ G.adj a₁ a₂ :=
48+
by rw [box_prod_adj, and_iff_left rfl, or_iff_left (λ h : H.adj b b ∧ _, h.1.ne rfl)]
49+
50+
@[simp] lemma box_prod_adj_right : (G □ H).adj (a, b₁) (a, b₂) ↔ H.adj b₁ b₂ :=
51+
by rw [box_prod_adj, and_iff_left rfl, or_iff_right (λ h : G.adj a a ∧ _, h.1.ne rfl)]
52+
53+
variables (G H I)
54+
55+
/-- The box product is commutative up to isomorphism. `equiv.prod_comm` as a graph isomorphism. -/
56+
@[simps] def box_prod_comm : G □ H ≃g H □ G := ⟨equiv.prod_comm _ _, λ x y, or_comm _ _⟩
57+
58+
/-- The box product is associative up to isomorphism. `equiv.prod_assoc` as a graph isomorphism. -/
59+
@[simps] def box_prod_assoc : (G □ H) □ I ≃g G □ (H □ I) :=
60+
⟨equiv.prod_assoc _ _ _, λ x y, by simp only [box_prod_adj, equiv.prod_assoc_apply,
61+
or_and_distrib_right, or_assoc, prod.ext_iff, and_assoc, @and.comm (x.1.1 = _)]⟩
62+
63+
/-- The embedding of `G` into `G □ H` given by `b`. -/
64+
@[simps] def box_prod_left (b : β) : G ↪g G □ H :=
65+
{ to_fun := λ a, (a , b),
66+
inj' := λ a₁ a₂, congr_arg prod.fst,
67+
map_rel_iff' := λ a₁ a₂, box_prod_adj_left }
68+
69+
/-- The embedding of `H` into `G □ H` given by `a`. -/
70+
@[simps] def box_prod_right (a : α) : H ↪g G □ H :=
71+
{ to_fun := prod.mk a,
72+
inj' := λ b₁ b₂, congr_arg prod.snd,
73+
map_rel_iff' := λ b₁ b₂, box_prod_adj_right }
74+
75+
namespace walk
76+
variables {G}
77+
78+
/-- Turn a walk on `G` into a walk on `G □ H`. -/
79+
protected def box_prod_left (b : β) : G.walk a₁ a₂ → (G □ H).walk (a₁, b) (a₂, b) :=
80+
walk.map (G.box_prod_left H b).to_hom
81+
82+
variables (G) {H}
83+
84+
/-- Turn a walk on `H` into a walk on `G □ H`. -/
85+
protected def box_prod_right (a : α) : H.walk b₁ b₂ → (G □ H).walk (a, b₁) (a, b₂) :=
86+
walk.map (G.box_prod_right H a).to_hom
87+
88+
variables {G} [decidable_eq α] [decidable_eq β] [decidable_rel G.adj] [decidable_rel H.adj]
89+
90+
/-- Project a walk on `G □ H` to a walk on `G` by discarding the moves in the direction of `H`. -/
91+
def of_box_prod_left : Π {x y : α × β}, (G □ H).walk x y → G.walk x.1 y.1
92+
| _ _ nil := nil
93+
| x z (cons h w) := or.by_cases h (λ hG, w.of_box_prod_left.cons hG.1)
94+
(λ hH, show G.walk x.1 z.1, by rw hH.2; exact w.of_box_prod_left)
95+
96+
/-- Project a walk on `G □ H` to a walk on `H` by discarding the moves in the direction of `G`. -/
97+
def of_box_prod_right : Π {x y : α × β}, (G □ H).walk x y → H.walk x.2 y.2
98+
| _ _ nil := nil
99+
| x z (cons h w) := (or.symm h).by_cases (λ hH, w.of_box_prod_right.cons hH.1)
100+
(λ hG, show H.walk x.2 z.2, by rw hG.2; exact w.of_box_prod_right)
101+
102+
@[simp] lemma of_box_prod_left_box_prod_left :
103+
∀ {a₁ a₂ : α} (w : G.walk a₁ a₂), (w.box_prod_left H b).of_box_prod_left = w
104+
| _ _ nil := rfl
105+
| _ _ (cons' x y z h w) := begin
106+
rw [walk.box_prod_left, map_cons, of_box_prod_left, or.by_cases, dif_pos, ←walk.box_prod_left,
107+
of_box_prod_left_box_prod_left],
108+
exacts [rfl, ⟨h, rfl⟩],
109+
end
110+
111+
@[simp] lemma of_box_prod_left_box_prod_right :
112+
∀ {b₁ b₂ : α} (w : G.walk b₁ b₂), (w.box_prod_right G a).of_box_prod_right = w
113+
| _ _ nil := rfl
114+
| _ _ (cons' x y z h w) := begin
115+
rw [walk.box_prod_right, map_cons, of_box_prod_right, or.by_cases, dif_pos, ←walk.box_prod_right,
116+
of_box_prod_left_box_prod_right],
117+
exacts [rfl, ⟨h, rfl⟩],
118+
end
119+
120+
end walk
121+
122+
variables {G H}
123+
124+
protected lemma preconnected.box_prod (hG : G.preconnected) (hH : H.preconnected) :
125+
(G □ H).preconnected :=
126+
begin
127+
rintro x y,
128+
obtain ⟨w₁⟩ := hG x.1 y.1,
129+
obtain ⟨w₂⟩ := hH x.2 y.2,
130+
rw [←@prod.mk.eta _ _ x, ←@prod.mk.eta _ _ y],
131+
exact ⟨(w₁.box_prod_left _ _).append (w₂.box_prod_right _ _)⟩,
132+
end
133+
134+
protected lemma preconnected.of_box_prod_left [nonempty β] (h : (G □ H).preconnected) :
135+
G.preconnected :=
136+
begin
137+
classical,
138+
rintro a₁ a₂,
139+
obtain ⟨w⟩ := h (a₁, classical.arbitrary _) (a₂, classical.arbitrary _),
140+
exact ⟨w.of_box_prod_left⟩,
141+
end
142+
143+
protected lemma preconnected.of_box_prod_right [nonempty α] (h : (G □ H).preconnected) :
144+
H.preconnected :=
145+
begin
146+
classical,
147+
rintro b₁ b₂,
148+
obtain ⟨w⟩ := h (classical.arbitrary _, b₁) (classical.arbitrary _, b₂),
149+
exact ⟨w.of_box_prod_right⟩,
150+
end
151+
152+
protected lemma connected.box_prod (hG : G.connected) (hH : H.connected) : (G □ H).connected :=
153+
by { haveI := hG.nonempty, haveI := hH.nonempty, exact ⟨hG.preconnected.box_prod hH.preconnected⟩ }
154+
155+
protected lemma connected.of_box_prod_left (h : (G □ H).connected) : G.connected :=
156+
by { haveI := (nonempty_prod.1 h.nonempty).1, haveI := (nonempty_prod.1 h.nonempty).2,
157+
exact ⟨h.preconnected.of_box_prod_left⟩ }
158+
159+
protected lemma connected.of_box_prod_right (h : (G □ H).connected) : H.connected :=
160+
by { haveI := (nonempty_prod.1 h.nonempty).1, haveI := (nonempty_prod.1 h.nonempty).2,
161+
exact ⟨h.preconnected.of_box_prod_right⟩ }
162+
163+
@[simp] lemma box_prod_connected : (G □ H).connected ↔ G.connected ∧ H.connected :=
164+
⟨λ h, ⟨h.of_box_prod_left, h.of_box_prod_right⟩, λ h, h.1.box_prod h.2
165+
166+
end simple_graph

0 commit comments

Comments
 (0)