l3lab/ntp-mathlib huggingface dataset:
theorem card_commonNeighbors_le_degree_right [DecidableRel G.Adj] (v w : V) :
    Fintype.card (G.commonNeighbors v w) ≤ G.degree w := by
  

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
v w : V
⊢ Fintype.card ↑(commonNeighbors G v w) ≤ degree G w

Next tactic:
simp_rw [commonNeighbors_symm _ v w, card_commonNeighbors_le_degree_left]
/-- If the condition `G.Adj v w` fails, then `card_commonNeighbors_le_degree` is
the best we can do in general. -/
theorem Adj.card_commonNeighbors_lt_degree {G : SimpleGraph V} [DecidableRel G.Adj] {v w : V}
    (h : G.Adj v w) : Fintype.card (G.commonNeighbors v w) < G.degree v := by
  

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
G : SimpleGraph V
inst✝ : DecidableRel G.Adj
v w : V
h : Adj G v w
⊢ Fintype.card ↑(commonNeighbors G v w) < degree G v

Next tactic:
classical
  erw [← Set.toFinset_card]
  apply Finset.card_lt_card
  rw [Finset.ssubset_iff]
  use w
  constructor
  · rw [Set.mem_toFinset]
    apply not_mem_commonNeighbors_right
  · rw [Finset.insert_subset_iff]
    constructor
    · simpa
    · rw [neighborFinset, Set.toFinset_subset_toFinset]
      exact G.commonNeighbors_subset_neighborSet_left _ _
/-- If the condition `G.Adj v w` fails, then `card_commonNeighbors_le_degree` is
the best we can do in general. -/
theorem Adj.card_commonNeighbors_lt_degree {G : SimpleGraph V} [DecidableRel G.Adj] {v w : V}
    (h : G.Adj v w) : Fintype.card (G.commonNeighbors v w) < G.degree v := by
  classical
  

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
G : SimpleGraph V
inst✝ : DecidableRel G.Adj
v w : V
h : Adj G v w
⊢ Fintype.card ↑(commonNeighbors G v w) < degree G v

Next tactic:
erw [← Set.toFinset_card]
/-- If the condition `G.Adj v w` fails, then `card_commonNeighbors_le_degree` is
the best we can do in general. -/
theorem Adj.card_commonNeighbors_lt_degree {G : SimpleGraph V} [DecidableRel G.Adj] {v w : V}
    (h : G.Adj v w) : Fintype.card (G.commonNeighbors v w) < G.degree v := by
  classical
  erw [← Set.toFinset_card]
  

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
G : SimpleGraph V
inst✝ : DecidableRel G.Adj
v w : V
h : Adj G v w
⊢ card (Set.toFinset (commonNeighbors G v w)) < degree G v

Next tactic:
apply Finset.card_lt_card
/-- If the condition `G.Adj v w` fails, then `card_commonNeighbors_le_degree` is
the best we can do in general. -/
theorem Adj.card_commonNeighbors_lt_degree {G : SimpleGraph V} [DecidableRel G.Adj] {v w : V}
    (h : G.Adj v w) : Fintype.card (G.commonNeighbors v w) < G.degree v := by
  classical
  erw [← Set.toFinset_card]
  apply Finset.card_lt_card
  

Proof state:
case h
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
G : SimpleGraph V
inst✝ : DecidableRel G.Adj
v w : V
h : Adj G v w
⊢ Set.toFinset (commonNeighbors G v w) ⊂ neighborFinset G v

Next tactic:
rw [Finset.ssubset_iff]
/-- If the condition `G.Adj v w` fails, then `card_commonNeighbors_le_degree` is
the best we can do in general. -/
theorem Adj.card_commonNeighbors_lt_degree {G : SimpleGraph V} [DecidableRel G.Adj] {v w : V}
    (h : G.Adj v w) : Fintype.card (G.commonNeighbors v w) < G.degree v := by
  classical
  erw [← Set.toFinset_card]
  apply Finset.card_lt_card
  rw [Finset.ssubset_iff]
  

Proof state:
case h
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
G : SimpleGraph V
inst✝ : DecidableRel G.Adj
v w : V
h : Adj G v w
⊢ ∃ a ∉ Set.toFinset (commonNeighbors G v w), insert a (Set.toFinset (commonNeighbors G v w)) ⊆ neighborFinset G v

Next tactic:
use w
/-- If the condition `G.Adj v w` fails, then `card_commonNeighbors_le_degree` is
the best we can do in general. -/
theorem Adj.card_commonNeighbors_lt_degree {G : SimpleGraph V} [DecidableRel G.Adj] {v w : V}
    (h : G.Adj v w) : Fintype.card (G.commonNeighbors v w) < G.degree v := by
  classical
  erw [← Set.toFinset_card]
  apply Finset.card_lt_card
  rw [Finset.ssubset_iff]
  use w
  

Proof state:
case h
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
G : SimpleGraph V
inst✝ : DecidableRel G.Adj
v w : V
h : Adj G v w
⊢ w ∉ Set.toFinset (commonNeighbors G v w) ∧ insert w (Set.toFinset (commonNeighbors G v w)) ⊆ neighborFinset G v

Next tactic:
constructor
/-- If the condition `G.Adj v w` fails, then `card_commonNeighbors_le_degree` is
the best we can do in general. -/
theorem Adj.card_commonNeighbors_lt_degree {G : SimpleGraph V} [DecidableRel G.Adj] {v w : V}
    (h : G.Adj v w) : Fintype.card (G.commonNeighbors v w) < G.degree v := by
  classical
  erw [← Set.toFinset_card]
  apply Finset.card_lt_card
  rw [Finset.ssubset_iff]
  use w
  constructor
  · 

Proof state:
case h.left
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
G : SimpleGraph V
inst✝ : DecidableRel G.Adj
v w : V
h : Adj G v w
⊢ w ∉ Set.toFinset (commonNeighbors G v w)

Next tactic:
rw [Set.mem_toFinset]
/-- If the condition `G.Adj v w` fails, then `card_commonNeighbors_le_degree` is
the best we can do in general. -/
theorem Adj.card_commonNeighbors_lt_degree {G : SimpleGraph V} [DecidableRel G.Adj] {v w : V}
    (h : G.Adj v w) : Fintype.card (G.commonNeighbors v w) < G.degree v := by
  classical
  erw [← Set.toFinset_card]
  apply Finset.card_lt_card
  rw [Finset.ssubset_iff]
  use w
  constructor
  · rw [Set.mem_toFinset]
    

Proof state:
case h.left
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
G : SimpleGraph V
inst✝ : DecidableRel G.Adj
v w : V
h : Adj G v w
⊢ w ∉ commonNeighbors G v w

Next tactic:
apply not_mem_commonNeighbors_right
/-- If the condition `G.Adj v w` fails, then `card_commonNeighbors_le_degree` is
the best we can do in general. -/
theorem Adj.card_commonNeighbors_lt_degree {G : SimpleGraph V} [DecidableRel G.Adj] {v w : V}
    (h : G.Adj v w) : Fintype.card (G.commonNeighbors v w) < G.degree v := by
  classical
  erw [← Set.toFinset_card]
  apply Finset.card_lt_card
  rw [Finset.ssubset_iff]
  use w
  constructor
  · rw [Set.mem_toFinset]
    apply not_mem_commonNeighbors_right
  · 

Proof state:
case h.right
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
G : SimpleGraph V
inst✝ : DecidableRel G.Adj
v w : V
h : Adj G v w
⊢ insert w (Set.toFinset (commonNeighbors G v w)) ⊆ neighborFinset G v

Next tactic:
rw [Finset.insert_subset_iff]
/-- If the condition `G.Adj v w` fails, then `card_commonNeighbors_le_degree` is
the best we can do in general. -/
theorem Adj.card_commonNeighbors_lt_degree {G : SimpleGraph V} [DecidableRel G.Adj] {v w : V}
    (h : G.Adj v w) : Fintype.card (G.commonNeighbors v w) < G.degree v := by
  classical
  erw [← Set.toFinset_card]
  apply Finset.card_lt_card
  rw [Finset.ssubset_iff]
  use w
  constructor
  · rw [Set.mem_toFinset]
    apply not_mem_commonNeighbors_right
  · rw [Finset.insert_subset_iff]
    

Proof state:
case h.right
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
G : SimpleGraph V
inst✝ : DecidableRel G.Adj
v w : V
h : Adj G v w
⊢ w ∈ neighborFinset G v ∧ Set.toFinset (commonNeighbors G v w) ⊆ neighborFinset G v

Next tactic:
constructor
/-- If the condition `G.Adj v w` fails, then `card_commonNeighbors_le_degree` is
the best we can do in general. -/
theorem Adj.card_commonNeighbors_lt_degree {G : SimpleGraph V} [DecidableRel G.Adj] {v w : V}
    (h : G.Adj v w) : Fintype.card (G.commonNeighbors v w) < G.degree v := by
  classical
  erw [← Set.toFinset_card]
  apply Finset.card_lt_card
  rw [Finset.ssubset_iff]
  use w
  constructor
  · rw [Set.mem_toFinset]
    apply not_mem_commonNeighbors_right
  · rw [Finset.insert_subset_iff]
    constructor
    · 

Proof state:
case h.right.left
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
G : SimpleGraph V
inst✝ : DecidableRel G.Adj
v w : V
h : Adj G v w
⊢ w ∈ neighborFinset G v

Next tactic:
simpa
/-- If the condition `G.Adj v w` fails, then `card_commonNeighbors_le_degree` is
the best we can do in general. -/
theorem Adj.card_commonNeighbors_lt_degree {G : SimpleGraph V} [DecidableRel G.Adj] {v w : V}
    (h : G.Adj v w) : Fintype.card (G.commonNeighbors v w) < G.degree v := by
  classical
  erw [← Set.toFinset_card]
  apply Finset.card_lt_card
  rw [Finset.ssubset_iff]
  use w
  constructor
  · rw [Set.mem_toFinset]
    apply not_mem_commonNeighbors_right
  · rw [Finset.insert_subset_iff]
    constructor
    · simpa
    · 

Proof state:
case h.right.right
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
G : SimpleGraph V
inst✝ : DecidableRel G.Adj
v w : V
h : Adj G v w
⊢ Set.toFinset (commonNeighbors G v w) ⊆ neighborFinset G v

Next tactic:
rw [neighborFinset, Set.toFinset_subset_toFinset]
/-- If the condition `G.Adj v w` fails, then `card_commonNeighbors_le_degree` is
the best we can do in general. -/
theorem Adj.card_commonNeighbors_lt_degree {G : SimpleGraph V} [DecidableRel G.Adj] {v w : V}
    (h : G.Adj v w) : Fintype.card (G.commonNeighbors v w) < G.degree v := by
  classical
  erw [← Set.toFinset_card]
  apply Finset.card_lt_card
  rw [Finset.ssubset_iff]
  use w
  constructor
  · rw [Set.mem_toFinset]
    apply not_mem_commonNeighbors_right
  · rw [Finset.insert_subset_iff]
    constructor
    · simpa
    · rw [neighborFinset, Set.toFinset_subset_toFinset]
      

Proof state:
case h.right.right
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
G : SimpleGraph V
inst✝ : DecidableRel G.Adj
v w : V
h : Adj G v w
⊢ commonNeighbors G v w ⊆ neighborSet G v

Next tactic:
exact G.commonNeighbors_subset_neighborSet_left _ _
theorem card_commonNeighbors_top [DecidableEq V] {v w : V} (h : v ≠ w) :
    Fintype.card ((⊤ : SimpleGraph V).commonNeighbors v w) = Fintype.card V - 2 := by
  

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
inst✝ : DecidableEq V
v w : V
h : v ≠ w
⊢ Fintype.card ↑(commonNeighbors ⊤ v w) = Fintype.card V - 2

Next tactic:
simp only [commonNeighbors_top_eq, ← Set.toFinset_card, Set.toFinset_diff]
theorem card_commonNeighbors_top [DecidableEq V] {v w : V} (h : v ≠ w) :
    Fintype.card ((⊤ : SimpleGraph V).commonNeighbors v w) = Fintype.card V - 2 := by
  simp only [commonNeighbors_top_eq, ← Set.toFinset_card, Set.toFinset_diff]
  

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
inst✝ : DecidableEq V
v w : V
h : v ≠ w
⊢ card (Set.toFinset Set.univ \ Set.toFinset {v, w}) = Fintype.card V - 2

Next tactic:
rw [Finset.card_sdiff]
theorem card_commonNeighbors_top [DecidableEq V] {v w : V} (h : v ≠ w) :
    Fintype.card ((⊤ : SimpleGraph V).commonNeighbors v w) = Fintype.card V - 2 := by
  simp only [commonNeighbors_top_eq, ← Set.toFinset_card, Set.toFinset_diff]
  rw [Finset.card_sdiff]
  · 

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
inst✝ : DecidableEq V
v w : V
h : v ≠ w
⊢ card (Set.toFinset Set.univ) - card (Set.toFinset {v, w}) = Fintype.card V - 2

Next tactic:
simp [Finset.card_univ, h]
theorem card_commonNeighbors_top [DecidableEq V] {v w : V} (h : v ≠ w) :
    Fintype.card ((⊤ : SimpleGraph V).commonNeighbors v w) = Fintype.card V - 2 := by
  simp only [commonNeighbors_top_eq, ← Set.toFinset_card, Set.toFinset_diff]
  rw [Finset.card_sdiff]
  · simp [Finset.card_univ, h]
  · 

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
inst✝¹ : Fintype V
inst✝ : DecidableEq V
v w : V
h : v ≠ w
⊢ Set.toFinset {v, w} ⊆ Set.toFinset Set.univ

Next tactic:
simp only [Set.toFinset_subset_toFinset, Set.subset_univ]
theorem mapEdgeSet.injective (hinj : Function.Injective f) : Function.Injective f.mapEdgeSet := by
  

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v w : V
e : Sym2 V
G₁ G₂ : SimpleGraph V
H : SimpleGraph W
f : G →g G'
hinj : Injective ⇑f
⊢ Injective (mapEdgeSet f)

Next tactic:
rintro ⟨e₁, h₁⟩ ⟨e₂, h₂⟩
theorem mapEdgeSet.injective (hinj : Function.Injective f) : Function.Injective f.mapEdgeSet := by
  rintro ⟨e₁, h₁⟩ ⟨e₂, h₂⟩
  

Proof state:
case mk.mk
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v w : V
e : Sym2 V
G₁ G₂ : SimpleGraph V
H : SimpleGraph W
f : G →g G'
hinj : Injective ⇑f
e₁ : Sym2 V
h₁ : e₁ ∈ edgeSet G
e₂ : Sym2 V
h₂ : e₂ ∈ edgeSet G
⊢ mapEdgeSet f { val := e₁, property := h₁ } = mapEdgeSet f { val := e₂, property := h₂ } →
    { val := e₁, property := h₁ } = { val := e₂, property := h₂ }

Next tactic:
dsimp [Hom.mapEdgeSet]
theorem mapEdgeSet.injective (hinj : Function.Injective f) : Function.Injective f.mapEdgeSet := by
  rintro ⟨e₁, h₁⟩ ⟨e₂, h₂⟩
  dsimp [Hom.mapEdgeSet]
  

Proof state:
case mk.mk
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v w : V
e : Sym2 V
G₁ G₂ : SimpleGraph V
H : SimpleGraph W
f : G →g G'
hinj : Injective ⇑f
e₁ : Sym2 V
h₁ : e₁ ∈ edgeSet G
e₂ : Sym2 V
h₂ : e₂ ∈ edgeSet G
⊢ { val := Sym2.map (⇑f) e₁, property := (_ : Sym2.map ⇑f ↑{ val := e₁, property := h₁ } ∈ edgeSet G') } =
      { val := Sym2.map (⇑f) e₂, property := (_ : Sym2.map ⇑f ↑{ val := e₂, property := h₂ } ∈ edgeSet G') } →
    { val := e₁, property := h₁ } = { val := e₂, property := h₂ }

Next tactic:
repeat' rw [Subtype.mk_eq_mk]
theorem mapEdgeSet.injective (hinj : Function.Injective f) : Function.Injective f.mapEdgeSet := by
  rintro ⟨e₁, h₁⟩ ⟨e₂, h₂⟩
  dsimp [Hom.mapEdgeSet]
  repeat' 

Proof state:
case mk.mk
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v w : V
e : Sym2 V
G₁ G₂ : SimpleGraph V
H : SimpleGraph W
f : G →g G'
hinj : Injective ⇑f
e₁ : Sym2 V
h₁ : e₁ ∈ edgeSet G
e₂ : Sym2 V
h₂ : e₂ ∈ edgeSet G
⊢ { val := Sym2.map (⇑f) e₁, property := (_ : Sym2.map ⇑f ↑{ val := e₁, property := h₁ } ∈ edgeSet G') } =
      { val := Sym2.map (⇑f) e₂, property := (_ : Sym2.map ⇑f ↑{ val := e₂, property := h₂ } ∈ edgeSet G') } →
    { val := e₁, property := h₁ } = { val := e₂, property := h₂ }

Next tactic:
rw [Subtype.mk_eq_mk]
theorem mapEdgeSet.injective (hinj : Function.Injective f) : Function.Injective f.mapEdgeSet := by
  rintro ⟨e₁, h₁⟩ ⟨e₂, h₂⟩
  dsimp [Hom.mapEdgeSet]
  repeat' 

Proof state:
case mk.mk
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v w : V
e : Sym2 V
G₁ G₂ : SimpleGraph V
H : SimpleGraph W
f : G →g G'
hinj : Injective ⇑f
e₁ : Sym2 V
h₁ : e₁ ∈ edgeSet G
e₂ : Sym2 V
h₂ : e₂ ∈ edgeSet G
⊢ Sym2.map (⇑f) e₁ = Sym2.map (⇑f) e₂ → { val := e₁, property := h₁ } = { val := e₂, property := h₂ }

Next tactic:
rw [Subtype.mk_eq_mk]
theorem mapEdgeSet.injective (hinj : Function.Injective f) : Function.Injective f.mapEdgeSet := by
  rintro ⟨e₁, h₁⟩ ⟨e₂, h₂⟩
  dsimp [Hom.mapEdgeSet]
  repeat' 

Proof state:
case mk.mk
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v w : V
e : Sym2 V
G₁ G₂ : SimpleGraph V
H : SimpleGraph W
f : G →g G'
hinj : Injective ⇑f
e₁ : Sym2 V
h₁ : e₁ ∈ edgeSet G
e₂ : Sym2 V
h₂ : e₂ ∈ edgeSet G
⊢ Sym2.map (⇑f) e₁ = Sym2.map (⇑f) e₂ → e₁ = e₂

Next tactic:
rw [Subtype.mk_eq_mk]
theorem mapEdgeSet.injective (hinj : Function.Injective f) : Function.Injective f.mapEdgeSet := by
  rintro ⟨e₁, h₁⟩ ⟨e₂, h₂⟩
  dsimp [Hom.mapEdgeSet]
  repeat' rw [Subtype.mk_eq_mk]
  

Proof state:
case mk.mk
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v w : V
e : Sym2 V
G₁ G₂ : SimpleGraph V
H : SimpleGraph W
f : G →g G'
hinj : Injective ⇑f
e₁ : Sym2 V
h₁ : e₁ ∈ edgeSet G
e₂ : Sym2 V
h₂ : e₂ ∈ edgeSet G
⊢ Sym2.map (⇑f) e₁ = Sym2.map (⇑f) e₂ → e₁ = e₂

Next tactic:
apply Sym2.map.injective hinj
/-- Every graph homomorphism from a complete graph is injective. -/
theorem injective_of_top_hom (f : (⊤ : SimpleGraph V) →g G') : Function.Injective f := by
  

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v w : V
e : Sym2 V
G₁ G₂ : SimpleGraph V
H : SimpleGraph W
f✝ : G →g G'
f : ⊤ →g G'
⊢ Injective ⇑f

Next tactic:
intro v w h
/-- Every graph homomorphism from a complete graph is injective. -/
theorem injective_of_top_hom (f : (⊤ : SimpleGraph V) →g G') : Function.Injective f := by
  intro v w h
  

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
G₁ G₂ : SimpleGraph V
H : SimpleGraph W
f✝ : G →g G'
f : ⊤ →g G'
v w : V
h : f v = f w
⊢ v = w

Next tactic:
contrapose! h
/-- Every graph homomorphism from a complete graph is injective. -/
theorem injective_of_top_hom (f : (⊤ : SimpleGraph V) →g G') : Function.Injective f := by
  intro v w h
  contrapose! h
  

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w✝ : V
e : Sym2 V
G₁ G₂ : SimpleGraph V
H : SimpleGraph W
f✝ : G →g G'
f : ⊤ →g G'
v w : V
h : v ≠ w
⊢ f v ≠ f w

Next tactic:
exact G'.ne_of_adj (map_adj _ ((top_adj _ _).mpr h))
/-- There is a homomorphism to a graph from a comapped graph.
When the function is injective, this is an embedding (see `SimpleGraph.Embedding.comap`). -/
@[simps]
protected def comap (f : V → W) (G : SimpleGraph W) : G.comap f →g G where
  toFun := f
  map_rel' := by 

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v w : V
e : Sym2 V
G₁ G₂ : SimpleGraph V
H : SimpleGraph W
f✝ : G✝ →g G'
f : V → W
G : SimpleGraph W
⊢ ∀ {a b : V}, Adj (SimpleGraph.comap f G) a b → Adj G (f a) (f b)

Next tactic:
simp
/-- A graph embedding induces an embedding of neighbor sets. -/
@[simps]
def mapNeighborSet (v : V) : G.neighborSet v ↪ G'.neighborSet (f v)
    where
  toFun w := ⟨f w, f.apply_mem_neighborSet_iff.mpr w.2⟩
  inj' := by
    

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w : V
e : Sym2 V
H : SimpleGraph W
f : G ↪g G'
v : V
⊢ Injective fun w => { val := f ↑w, property := (_ : f ↑w ∈ neighborSet G' (f v)) }

Next tactic:
rintro ⟨w₁, h₁⟩ ⟨w₂, h₂⟩ h
/-- A graph embedding induces an embedding of neighbor sets. -/
@[simps]
def mapNeighborSet (v : V) : G.neighborSet v ↪ G'.neighborSet (f v)
    where
  toFun w := ⟨f w, f.apply_mem_neighborSet_iff.mpr w.2⟩
  inj' := by
    rintro ⟨w₁, h₁⟩ ⟨w₂, h₂⟩ h
    

Proof state:
case mk.mk
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w : V
e : Sym2 V
H : SimpleGraph W
f : G ↪g G'
v w₁ : V
h₁ : w₁ ∈ neighborSet G v
w₂ : V
h₂ : w₂ ∈ neighborSet G v
h :
  (fun w => { val := f ↑w, property := (_ : f ↑w ∈ neighborSet G' (f v)) }) { val := w₁, property := h₁ } =
    (fun w => { val := f ↑w, property := (_ : f ↑w ∈ neighborSet G' (f v)) }) { val := w₂, property := h₂ }
⊢ { val := w₁, property := h₁ } = { val := w₂, property := h₂ }

Next tactic:
rw [Subtype.mk_eq_mk] at h ⊢
/-- A graph embedding induces an embedding of neighbor sets. -/
@[simps]
def mapNeighborSet (v : V) : G.neighborSet v ↪ G'.neighborSet (f v)
    where
  toFun w := ⟨f w, f.apply_mem_neighborSet_iff.mpr w.2⟩
  inj' := by
    rintro ⟨w₁, h₁⟩ ⟨w₂, h₂⟩ h
    rw [Subtype.mk_eq_mk] at h ⊢
    

Proof state:
case mk.mk
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v✝ w : V
e : Sym2 V
H : SimpleGraph W
f : G ↪g G'
v w₁ : V
h₁ : w₁ ∈ neighborSet G v
w₂ : V
h₂ : w₂ ∈ neighborSet G v
h : f ↑{ val := w₁, property := h₁ } = f ↑{ val := w₂, property := h₂ }
⊢ w₁ = w₂

Next tactic:
exact f.inj' h
/-- Given an injective function, there is an embedding from the comapped graph into the original
graph. -/
-- porting note: @[simps] does not work here since `f` is not a constructor application.
-- `@[simps toEmbedding]` could work, but Floris suggested writing `comap_apply` for now.
protected def comap (f : V ↪ W) (G : SimpleGraph W) : G.comap f ↪g G :=
  { f with map_rel_iff' := by 

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v w : V
e : Sym2 V
H : SimpleGraph W
f✝ : G✝ ↪g G'
f : V ↪ W
G : SimpleGraph W
⊢ ∀ {a b : V},
    Adj G ({ toFun := f.toFun, inj' := (_ : Injective f.toFun) } a)
        ({ toFun := f.toFun, inj' := (_ : Injective f.toFun) } b) ↔
      Adj (SimpleGraph.comap (⇑f) G) a b

Next tactic:
simp
/-- Given an injective function, there is an embedding from a graph into the mapped graph. -/
-- porting note: @[simps] does not work here since `f` is not a constructor application.
-- `@[simps toEmbedding]` could work, but Floris suggested writing `map_apply` for now.
protected def map (f : V ↪ W) (G : SimpleGraph V) : G ↪g G.map f :=
  { f with map_rel_iff' := by 

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v w : V
e : Sym2 V
H : SimpleGraph W
f✝ : G✝ ↪g G'
f : V ↪ W
G : SimpleGraph V
⊢ ∀ {a b : V},
    Adj (SimpleGraph.map f G) ({ toFun := f.toFun, inj' := (_ : Injective f.toFun) } a)
        ({ toFun := f.toFun, inj' := (_ : Injective f.toFun) } b) ↔
      Adj G a b

Next tactic:
simp
/-- Embeddings of types induce embeddings of complete graphs on those types. -/
protected def completeGraph {α β : Type*} (f : α ↪ β) :
    (⊤ : SimpleGraph α) ↪g (⊤ : SimpleGraph β) :=
  { f with map_rel_iff' := by 

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a b c u v w : V
e : Sym2 V
H : SimpleGraph W
f✝ : G ↪g G'
α : Type u_3
β : Type u_4
f : α ↪ β
⊢ ∀ {a b : α},
    Adj ⊤ ({ toFun := f.toFun, inj' := (_ : Injective f.toFun) } a)
        ({ toFun := f.toFun, inj' := (_ : Injective f.toFun) } b) ↔
      Adj ⊤ a b

Next tactic:
simp
@[simp] lemma induceHom_id (G : SimpleGraph V) (s) :
    induceHom (Hom.id : G →g G) (Set.mapsTo_id s) = Hom.id := by
  

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v w : V
e : Sym2 V
G'' : SimpleGraph X
s✝ : Set V
t : Set W
r : Set X
φ : G✝ →g G'
φst : Set.MapsTo (⇑φ) s✝ t
ψ : G' →g G''
ψtr : Set.MapsTo (⇑ψ) t r
G : SimpleGraph V
s : Set V
⊢ induceHom Hom.id (_ : Set.MapsTo id s s) = Hom.id

Next tactic:
ext x
@[simp] lemma induceHom_id (G : SimpleGraph V) (s) :
    induceHom (Hom.id : G →g G) (Set.mapsTo_id s) = Hom.id := by
  ext x
  

Proof state:
case h.a
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G✝ : SimpleGraph V
G' : SimpleGraph W
a b c u v w : V
e : Sym2 V
G'' : SimpleGraph X
s✝ : Set V
t : Set W
r : Set X
φ : G✝ →g G'
φst : Set.MapsTo (⇑φ) s✝ t
ψ : G' →g G''
ψtr : Set.MapsTo (⇑ψ) t r
G : SimpleGraph V
s : Set V
x : ↑s
⊢ ↑((induceHom Hom.id (_ : Set.MapsTo id s s)) x) = ↑(Hom.id x)

Next tactic:
rfl