Theorem: SimpleGraph.isTree_iff_existsUnique_path
File: Mathlib/Combinatorics/SimpleGraph/Acyclic.lean

tactic: rw [isTree_iff, isAcyclic_iff_path_unique]
state_before: V : Type u
G : SimpleGraph V
⊢ G.IsTree ↔ Nonempty V ∧ ∀ (v w : V), ∃! p, p.IsPath
state_after: V : Type u
G : SimpleGraph V
⊢ (G.Connected ∧ ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q) ↔ Nonempty V ∧ ∀ (v w : V), ∃! p, p.IsPath

tactic: constructor
state_before: V : Type u
G : SimpleGraph V
⊢ (G.Connected ∧ ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q) ↔ Nonempty V ∧ ∀ (v w : V), ∃! p, p.IsPath
state_after: case mp
V : Type u
G : SimpleGraph V
⊢ (G.Connected ∧ ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q) → Nonempty V ∧ ∀ (v w : V), ∃! p, p.IsPath

case mpr
V : Type u
G : SimpleGraph V
⊢ (Nonempty V ∧ ∀ (v w : V), ∃! p, p.IsPath) → G.Connected ∧ ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q

tactic: rintro ⟨hc, hu⟩
state_before: case mp
V : Type u
G : SimpleGraph V
⊢ (G.Connected ∧ ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q) → Nonempty V ∧ ∀ (v w : V), ∃! p, p.IsPath
state_after: case mp.intro
V : Type u
G : SimpleGraph V
hc : G.Connected
hu : ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
⊢ Nonempty V ∧ ∀ (v w : V), ∃! p, p.IsPath

tactic: refine ⟨hc.nonempty, ?_⟩
state_before: case mp.intro
V : Type u
G : SimpleGraph V
hc : G.Connected
hu : ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
⊢ Nonempty V ∧ ∀ (v w : V), ∃! p, p.IsPath
state_after: case mp.intro
V : Type u
G : SimpleGraph V
hc : G.Connected
hu : ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
⊢ ∀ (v w : V), ∃! p, p.IsPath

tactic: intro v w
state_before: case mp.intro
V : Type u
G : SimpleGraph V
hc : G.Connected
hu : ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
⊢ ∀ (v w : V), ∃! p, p.IsPath
state_after: case mp.intro
V : Type u
G : SimpleGraph V
hc : G.Connected
hu : ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
v w : V
⊢ ∃! p, p.IsPath

tactic: let q := (hc v w).some.toPath
state_before: case mp.intro
V : Type u
G : SimpleGraph V
hc : G.Connected
hu : ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
v w : V
⊢ ∃! p, p.IsPath
state_after: case mp.intro
V : Type u
G : SimpleGraph V
hc : G.Connected
hu : ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
v w : V
q : G.Path v w := (Nonempty.some ⋯).toPath
⊢ ∃! p, p.IsPath

tactic: use q
state_before: case mp.intro
V : Type u
G : SimpleGraph V
hc : G.Connected
hu : ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
v w : V
q : G.Path v w := (Nonempty.some ⋯).toPath
⊢ ∃! p, p.IsPath
state_after: case h
V : Type u
G : SimpleGraph V
hc : G.Connected
hu : ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
v w : V
q : G.Path v w := (Nonempty.some ⋯).toPath
⊢ (fun p => p.IsPath) ↑q ∧ ∀ (y : G.Walk v w), (fun p => p.IsPath) y → y = ↑q

tactic: simp only [true_and_iff, Path.isPath]
state_before: case h
V : Type u
G : SimpleGraph V
hc : G.Connected
hu : ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
v w : V
q : G.Path v w := (Nonempty.some ⋯).toPath
⊢ (fun p => p.IsPath) ↑q ∧ ∀ (y : G.Walk v w), (fun p => p.IsPath) y → y = ↑q
state_after: case h
V : Type u
G : SimpleGraph V
hc : G.Connected
hu : ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
v w : V
q : G.Path v w := (Nonempty.some ⋯).toPath
⊢ ∀ (y : G.Walk v w), y.IsPath → y = ↑q

tactic: intro p hp
state_before: case h
V : Type u
G : SimpleGraph V
hc : G.Connected
hu : ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
v w : V
q : G.Path v w := (Nonempty.some ⋯).toPath
⊢ ∀ (y : G.Walk v w), y.IsPath → y = ↑q
state_after: case h
V : Type u
G : SimpleGraph V
hc : G.Connected
hu : ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
v w : V
q : G.Path v w := (Nonempty.some ⋯).toPath
p : G.Walk v w
hp : p.IsPath
⊢ p = ↑q

tactic: specialize hu ⟨p, hp⟩ q
state_before: case h
V : Type u
G : SimpleGraph V
hc : G.Connected
hu : ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
v w : V
q : G.Path v w := (Nonempty.some ⋯).toPath
p : G.Walk v w
hp : p.IsPath
⊢ p = ↑q
state_after: case h
V : Type u
G : SimpleGraph V
hc : G.Connected
v w : V
q : G.Path v w := (Nonempty.some ⋯).toPath
p : G.Walk v w
hp : p.IsPath
hu : ⟨p, hp⟩ = q
⊢ p = ↑q

tactic: exact Subtype.ext_iff.mp hu
state_before: case h
V : Type u
G : SimpleGraph V
hc : G.Connected
v w : V
q : G.Path v w := (Nonempty.some ⋯).toPath
p : G.Walk v w
hp : p.IsPath
hu : ⟨p, hp⟩ = q
⊢ p = ↑q
state_after: no goals

tactic: rintro ⟨hV, h⟩
state_before: case mpr
V : Type u
G : SimpleGraph V
⊢ (Nonempty V ∧ ∀ (v w : V), ∃! p, p.IsPath) → G.Connected ∧ ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
state_after: case mpr.intro
V : Type u
G : SimpleGraph V
hV : Nonempty V
h : ∀ (v w : V), ∃! p, p.IsPath
⊢ G.Connected ∧ ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q

tactic: refine ⟨Connected.mk ?_, ?_⟩
state_before: case mpr.intro
V : Type u
G : SimpleGraph V
hV : Nonempty V
h : ∀ (v w : V), ∃! p, p.IsPath
⊢ G.Connected ∧ ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
state_after: case mpr.intro.refine_1
V : Type u
G : SimpleGraph V
hV : Nonempty V
h : ∀ (v w : V), ∃! p, p.IsPath
⊢ G.Preconnected

case mpr.intro.refine_2
V : Type u
G : SimpleGraph V
hV : Nonempty V
h : ∀ (v w : V), ∃! p, p.IsPath
⊢ ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q

tactic: intro v w
state_before: case mpr.intro.refine_1
V : Type u
G : SimpleGraph V
hV : Nonempty V
h : ∀ (v w : V), ∃! p, p.IsPath
⊢ G.Preconnected
state_after: case mpr.intro.refine_1
V : Type u
G : SimpleGraph V
hV : Nonempty V
h : ∀ (v w : V), ∃! p, p.IsPath
v w : V
⊢ G.Reachable v w

tactic: obtain ⟨p, _⟩ := h v w
state_before: case mpr.intro.refine_1
V : Type u
G : SimpleGraph V
hV : Nonempty V
h : ∀ (v w : V), ∃! p, p.IsPath
v w : V
⊢ G.Reachable v w
state_after: case mpr.intro.refine_1.intro
V : Type u
G : SimpleGraph V
hV : Nonempty V
h : ∀ (v w : V), ∃! p, p.IsPath
v w : V
p : G.Walk v w
h✝ : (fun p => p.IsPath) p ∧ ∀ (y : G.Walk v w), (fun p => p.IsPath) y → y = p
⊢ G.Reachable v w

tactic: exact p.reachable
state_before: case mpr.intro.refine_1.intro
V : Type u
G : SimpleGraph V
hV : Nonempty V
h : ∀ (v w : V), ∃! p, p.IsPath
v w : V
p : G.Walk v w
h✝ : (fun p => p.IsPath) p ∧ ∀ (y : G.Walk v w), (fun p => p.IsPath) y → y = p
⊢ G.Reachable v w
state_after: no goals

tactic: rintro v w ⟨p, hp⟩ ⟨q, hq⟩
state_before: case mpr.intro.refine_2
V : Type u
G : SimpleGraph V
hV : Nonempty V
h : ∀ (v w : V), ∃! p, p.IsPath
⊢ ∀ ⦃v w : V⦄ (p q : G.Path v w), p = q
state_after: case mpr.intro.refine_2.mk.mk
V : Type u
G : SimpleGraph V
hV : Nonempty V
h : ∀ (v w : V), ∃! p, p.IsPath
v w : V
p : G.Walk v w
hp : p.IsPath
q : G.Walk v w
hq : q.IsPath
⊢ ⟨p, hp⟩ = ⟨q, hq⟩

tactic: simp only [ExistsUnique.unique (h v w) hp hq]
state_before: case mpr.intro.refine_2.mk.mk
V : Type u
G : SimpleGraph V
hV : Nonempty V
h : ∀ (v w : V), ∃! p, p.IsPath
v w : V
p : G.Walk v w
hp : p.IsPath
q : G.Walk v w
hq : q.IsPath
⊢ ⟨p, hp⟩ = ⟨q, hq⟩
state_after: no goals