l3lab/ntp-mathlib huggingface dataset:
theorem hom_eq_iff_not_disjoint (C : G.ComponentCompl L) (h : K ⊆ L) (D : G.ComponentCompl K) :
    C.hom h = D ↔ ¬Disjoint (C : Set V) (D : Set V) := by
  rw [Set.not_disjoint_iff]
  constructor
  · rintro rfl
    refine C.ind fun x xnL => ?_
    exact ⟨x, ⟨xnL, rfl⟩, ⟨fun xK => xnL (h xK), rfl⟩⟩
  · refine C.ind fun x xnL => ?_
    

Proof state:
case mpr
V : Type u
G : SimpleGraph V
K L L' M : Set V
C : ComponentCompl G L
h : K ⊆ L
D : ComponentCompl G K
x : V
xnL : x ∉ L
⊢ (∃ x_1 ∈ ↑(componentComplMk G xnL), x_1 ∈ ↑D) → hom h (componentComplMk G xnL) = D

Next tactic:
rintro ⟨x, ⟨_, e₁⟩, _, rfl⟩
theorem hom_eq_iff_not_disjoint (C : G.ComponentCompl L) (h : K ⊆ L) (D : G.ComponentCompl K) :
    C.hom h = D ↔ ¬Disjoint (C : Set V) (D : Set V) := by
  rw [Set.not_disjoint_iff]
  constructor
  · rintro rfl
    refine C.ind fun x xnL => ?_
    exact ⟨x, ⟨xnL, rfl⟩, ⟨fun xK => xnL (h xK), rfl⟩⟩
  · refine C.ind fun x xnL => ?_
    rintro ⟨x, ⟨_, e₁⟩, _, rfl⟩
    

Proof state:
case mpr.intro.intro.intro.intro
V : Type u
G : SimpleGraph V
K L L' M : Set V
C : ComponentCompl G L
h : K ⊆ L
x✝ : V
xnL : x✝ ∉ L
x : V
w✝¹ : x ∉ L
e₁ : componentComplMk G w✝¹ = componentComplMk G xnL
w✝ : x ∉ K
⊢ hom h (componentComplMk G xnL) = componentComplMk G w✝

Next tactic:
rw [← e₁]
theorem hom_eq_iff_not_disjoint (C : G.ComponentCompl L) (h : K ⊆ L) (D : G.ComponentCompl K) :
    C.hom h = D ↔ ¬Disjoint (C : Set V) (D : Set V) := by
  rw [Set.not_disjoint_iff]
  constructor
  · rintro rfl
    refine C.ind fun x xnL => ?_
    exact ⟨x, ⟨xnL, rfl⟩, ⟨fun xK => xnL (h xK), rfl⟩⟩
  · refine C.ind fun x xnL => ?_
    rintro ⟨x, ⟨_, e₁⟩, _, rfl⟩
    rw [← e₁]
    

Proof state:
case mpr.intro.intro.intro.intro
V : Type u
G : SimpleGraph V
K L L' M : Set V
C : ComponentCompl G L
h : K ⊆ L
x✝ : V
xnL : x✝ ∉ L
x : V
w✝¹ : x ∉ L
e₁ : componentComplMk G w✝¹ = componentComplMk G xnL
w✝ : x ∉ K
⊢ hom h (componentComplMk G w✝¹) = componentComplMk G w✝

Next tactic:
rfl
theorem hom_refl (C : G.ComponentCompl L) : C.hom (subset_refl L) = C := by
  

Proof state:
V : Type u
G : SimpleGraph V
K L L' M : Set V
C : ComponentCompl G L
⊢ hom (_ : L ⊆ L) C = C

Next tactic:
change C.map _ = C
theorem hom_refl (C : G.ComponentCompl L) : C.hom (subset_refl L) = C := by
  change C.map _ = C
  

Proof state:
V : Type u
G : SimpleGraph V
K L L' M : Set V
C : ComponentCompl G L
⊢ ConnectedComponent.map (induceHom Hom.id (_ : Lᶜ ⊆ Lᶜ)) C = C

Next tactic:
erw [induceHom_id G Lᶜ, ConnectedComponent.map_id]
theorem hom_trans (C : G.ComponentCompl L) (h : K ⊆ L) (h' : M ⊆ K) :
    C.hom (h'.trans h) = (C.hom h).hom h' := by
  

Proof state:
V : Type u
G : SimpleGraph V
K L L' M : Set V
C : ComponentCompl G L
h : K ⊆ L
h' : M ⊆ K
⊢ hom (_ : M ⊆ L) C = hom h' (hom h C)

Next tactic:
change C.map _ = (C.map _).map _
theorem hom_trans (C : G.ComponentCompl L) (h : K ⊆ L) (h' : M ⊆ K) :
    C.hom (h'.trans h) = (C.hom h).hom h' := by
  change C.map _ = (C.map _).map _
  

Proof state:
V : Type u
G : SimpleGraph V
K L L' M : Set V
C : ComponentCompl G L
h : K ⊆ L
h' : M ⊆ K
⊢ ConnectedComponent.map (induceHom Hom.id (_ : Lᶜ ⊆ Mᶜ)) C =
    ConnectedComponent.map (induceHom Hom.id (_ : Kᶜ ⊆ Mᶜ)) (ConnectedComponent.map (induceHom Hom.id (_ : Lᶜ ⊆ Kᶜ)) C)

Next tactic:
erw [ConnectedComponent.map_comp, induceHom_comp]
theorem hom_trans (C : G.ComponentCompl L) (h : K ⊆ L) (h' : M ⊆ K) :
    C.hom (h'.trans h) = (C.hom h).hom h' := by
  change C.map _ = (C.map _).map _
  erw [ConnectedComponent.map_comp, induceHom_comp]
  

Proof state:
V : Type u
G : SimpleGraph V
K L L' M : Set V
C : ComponentCompl G L
h : K ⊆ L
h' : M ⊆ K
⊢ ConnectedComponent.map (induceHom Hom.id (_ : Lᶜ ⊆ Mᶜ)) C =
    ConnectedComponent.map (induceHom (Hom.comp Hom.id Hom.id) (_ : Set.MapsTo (⇑Hom.id ∘ fun x => Hom.id x) Lᶜ Mᶜ)) C

Next tactic:
rfl
theorem infinite_iff_in_all_ranges {K : Finset V} (C : G.ComponentCompl K) :
    C.supp.Infinite ↔ ∀ (L) (h : K ⊆ L), ∃ D : G.ComponentCompl L, D.hom h = C := by
  

Proof state:
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
K : Finset V
C : ComponentCompl G ↑K
⊢ Set.Infinite (supp C) ↔ ∀ (L : Finset V) (h : K ⊆ L), ∃ D, hom h D = C

Next tactic:
classical
    constructor
    · rintro Cinf L h
      obtain ⟨v, ⟨vK, rfl⟩, vL⟩ := Set.Infinite.nonempty (Set.Infinite.diff Cinf L.finite_toSet)
      exact ⟨componentComplMk _ vL, rfl⟩
    · rintro h Cfin
      obtain ⟨D, e⟩ := h (K ∪ Cfin.toFinset) (Finset.subset_union_left K Cfin.toFinset)
      obtain ⟨v, vD⟩ := D.nonempty
      let Ddis := D.disjoint_right
      simp_rw [Finset.coe_union, Set.Finite.coe_toFinset, Set.disjoint_union_left,
        Set.disjoint_iff] at Ddis
      exact Ddis.right ⟨(ComponentCompl.hom_eq_iff_le _ _ _).mp e vD, vD⟩
theorem infinite_iff_in_all_ranges {K : Finset V} (C : G.ComponentCompl K) :
    C.supp.Infinite ↔ ∀ (L) (h : K ⊆ L), ∃ D : G.ComponentCompl L, D.hom h = C := by
  classical
    

Proof state:
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
K : Finset V
C : ComponentCompl G ↑K
⊢ Set.Infinite (supp C) ↔ ∀ (L : Finset V) (h : K ⊆ L), ∃ D, hom h D = C

Next tactic:
constructor
theorem infinite_iff_in_all_ranges {K : Finset V} (C : G.ComponentCompl K) :
    C.supp.Infinite ↔ ∀ (L) (h : K ⊆ L), ∃ D : G.ComponentCompl L, D.hom h = C := by
  classical
    constructor
    · 

Proof state:
case mp
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
K : Finset V
C : ComponentCompl G ↑K
⊢ Set.Infinite (supp C) → ∀ (L : Finset V) (h : K ⊆ L), ∃ D, hom h D = C

Next tactic:
rintro Cinf L h
theorem infinite_iff_in_all_ranges {K : Finset V} (C : G.ComponentCompl K) :
    C.supp.Infinite ↔ ∀ (L) (h : K ⊆ L), ∃ D : G.ComponentCompl L, D.hom h = C := by
  classical
    constructor
    · rintro Cinf L h
      

Proof state:
case mp
V : Type u
G : SimpleGraph V
K✝ L✝ L' M : Set V
K : Finset V
C : ComponentCompl G ↑K
Cinf : Set.Infinite (supp C)
L : Finset V
h : K ⊆ L
⊢ ∃ D, hom h D = C

Next tactic:
obtain ⟨v, ⟨vK, rfl⟩, vL⟩ := Set.Infinite.nonempty (Set.Infinite.diff Cinf L.finite_toSet)
theorem infinite_iff_in_all_ranges {K : Finset V} (C : G.ComponentCompl K) :
    C.supp.Infinite ↔ ∀ (L) (h : K ⊆ L), ∃ D : G.ComponentCompl L, D.hom h = C := by
  classical
    constructor
    · rintro Cinf L h
      obtain ⟨v, ⟨vK, rfl⟩, vL⟩ := Set.Infinite.nonempty (Set.Infinite.diff Cinf L.finite_toSet)
      

Proof state:
case mp.intro.intro.intro
V : Type u
G : SimpleGraph V
K✝ L✝ L' M : Set V
K L : Finset V
h : K ⊆ L
v : V
vL : v ∉ ↑L
vK : v ∉ ↑K
Cinf : Set.Infinite (supp (componentComplMk G vK))
⊢ ∃ D, hom h D = componentComplMk G vK

Next tactic:
exact ⟨componentComplMk _ vL, rfl⟩
theorem infinite_iff_in_all_ranges {K : Finset V} (C : G.ComponentCompl K) :
    C.supp.Infinite ↔ ∀ (L) (h : K ⊆ L), ∃ D : G.ComponentCompl L, D.hom h = C := by
  classical
    constructor
    · rintro Cinf L h
      obtain ⟨v, ⟨vK, rfl⟩, vL⟩ := Set.Infinite.nonempty (Set.Infinite.diff Cinf L.finite_toSet)
      exact ⟨componentComplMk _ vL, rfl⟩
    · 

Proof state:
case mpr
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
K : Finset V
C : ComponentCompl G ↑K
⊢ (∀ (L : Finset V) (h : K ⊆ L), ∃ D, hom h D = C) → Set.Infinite (supp C)

Next tactic:
rintro h Cfin
theorem infinite_iff_in_all_ranges {K : Finset V} (C : G.ComponentCompl K) :
    C.supp.Infinite ↔ ∀ (L) (h : K ⊆ L), ∃ D : G.ComponentCompl L, D.hom h = C := by
  classical
    constructor
    · rintro Cinf L h
      obtain ⟨v, ⟨vK, rfl⟩, vL⟩ := Set.Infinite.nonempty (Set.Infinite.diff Cinf L.finite_toSet)
      exact ⟨componentComplMk _ vL, rfl⟩
    · rintro h Cfin
      

Proof state:
case mpr
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
K : Finset V
C : ComponentCompl G ↑K
h : ∀ (L : Finset V) (h : K ⊆ L), ∃ D, hom h D = C
Cfin : Set.Finite (supp C)
⊢ False

Next tactic:
obtain ⟨D, e⟩ := h (K ∪ Cfin.toFinset) (Finset.subset_union_left K Cfin.toFinset)
theorem infinite_iff_in_all_ranges {K : Finset V} (C : G.ComponentCompl K) :
    C.supp.Infinite ↔ ∀ (L) (h : K ⊆ L), ∃ D : G.ComponentCompl L, D.hom h = C := by
  classical
    constructor
    · rintro Cinf L h
      obtain ⟨v, ⟨vK, rfl⟩, vL⟩ := Set.Infinite.nonempty (Set.Infinite.diff Cinf L.finite_toSet)
      exact ⟨componentComplMk _ vL, rfl⟩
    · rintro h Cfin
      obtain ⟨D, e⟩ := h (K ∪ Cfin.toFinset) (Finset.subset_union_left K Cfin.toFinset)
      

Proof state:
case mpr.intro
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
K : Finset V
C : ComponentCompl G ↑K
h : ∀ (L : Finset V) (h : K ⊆ L), ∃ D, hom h D = C
Cfin : Set.Finite (supp C)
D : ComponentCompl G ↑(K ∪ Set.Finite.toFinset Cfin)
e : hom (_ : K ⊆ K ∪ Set.Finite.toFinset Cfin) D = C
⊢ False

Next tactic:
obtain ⟨v, vD⟩ := D.nonempty
theorem infinite_iff_in_all_ranges {K : Finset V} (C : G.ComponentCompl K) :
    C.supp.Infinite ↔ ∀ (L) (h : K ⊆ L), ∃ D : G.ComponentCompl L, D.hom h = C := by
  classical
    constructor
    · rintro Cinf L h
      obtain ⟨v, ⟨vK, rfl⟩, vL⟩ := Set.Infinite.nonempty (Set.Infinite.diff Cinf L.finite_toSet)
      exact ⟨componentComplMk _ vL, rfl⟩
    · rintro h Cfin
      obtain ⟨D, e⟩ := h (K ∪ Cfin.toFinset) (Finset.subset_union_left K Cfin.toFinset)
      obtain ⟨v, vD⟩ := D.nonempty
      

Proof state:
case mpr.intro.intro
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
K : Finset V
C : ComponentCompl G ↑K
h : ∀ (L : Finset V) (h : K ⊆ L), ∃ D, hom h D = C
Cfin : Set.Finite (supp C)
D : ComponentCompl G ↑(K ∪ Set.Finite.toFinset Cfin)
e : hom (_ : K ⊆ K ∪ Set.Finite.toFinset Cfin) D = C
v : V
vD : v ∈ ↑D
⊢ False

Next tactic:
let Ddis := D.disjoint_right
theorem infinite_iff_in_all_ranges {K : Finset V} (C : G.ComponentCompl K) :
    C.supp.Infinite ↔ ∀ (L) (h : K ⊆ L), ∃ D : G.ComponentCompl L, D.hom h = C := by
  classical
    constructor
    · rintro Cinf L h
      obtain ⟨v, ⟨vK, rfl⟩, vL⟩ := Set.Infinite.nonempty (Set.Infinite.diff Cinf L.finite_toSet)
      exact ⟨componentComplMk _ vL, rfl⟩
    · rintro h Cfin
      obtain ⟨D, e⟩ := h (K ∪ Cfin.toFinset) (Finset.subset_union_left K Cfin.toFinset)
      obtain ⟨v, vD⟩ := D.nonempty
      let Ddis := D.disjoint_right
      

Proof state:
case mpr.intro.intro
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
K : Finset V
C : ComponentCompl G ↑K
h : ∀ (L : Finset V) (h : K ⊆ L), ∃ D, hom h D = C
Cfin : Set.Finite (supp C)
D : ComponentCompl G ↑(K ∪ Set.Finite.toFinset Cfin)
e : hom (_ : K ⊆ K ∪ Set.Finite.toFinset Cfin) D = C
v : V
vD : v ∈ ↑D
Ddis : Disjoint ↑(K ∪ Set.Finite.toFinset Cfin) ↑D := ComponentCompl.disjoint_right D
⊢ False

Next tactic:
simp_rw [Finset.coe_union, Set.Finite.coe_toFinset, Set.disjoint_union_left,
        Set.disjoint_iff] at Ddis
theorem infinite_iff_in_all_ranges {K : Finset V} (C : G.ComponentCompl K) :
    C.supp.Infinite ↔ ∀ (L) (h : K ⊆ L), ∃ D : G.ComponentCompl L, D.hom h = C := by
  classical
    constructor
    · rintro Cinf L h
      obtain ⟨v, ⟨vK, rfl⟩, vL⟩ := Set.Infinite.nonempty (Set.Infinite.diff Cinf L.finite_toSet)
      exact ⟨componentComplMk _ vL, rfl⟩
    · rintro h Cfin
      obtain ⟨D, e⟩ := h (K ∪ Cfin.toFinset) (Finset.subset_union_left K Cfin.toFinset)
      obtain ⟨v, vD⟩ := D.nonempty
      let Ddis := D.disjoint_right
      simp_rw [Finset.coe_union, Set.Finite.coe_toFinset, Set.disjoint_union_left,
        Set.disjoint_iff] at Ddis
      

Proof state:
case mpr.intro.intro
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
K : Finset V
C : ComponentCompl G ↑K
h : ∀ (L : Finset V) (h : K ⊆ L), ∃ D, hom h D = C
Cfin : Set.Finite (supp C)
D : ComponentCompl G ↑(K ∪ Set.Finite.toFinset Cfin)
e : hom (_ : K ⊆ K ∪ Set.Finite.toFinset Cfin) D = C
v : V
vD : v ∈ ↑D
Ddis : ↑K ∩ ↑D ⊆ ∅ ∧ supp C ∩ ↑D ⊆ ∅
⊢ False

Next tactic:
exact Ddis.right ⟨(ComponentCompl.hom_eq_iff_le _ _ _).mp e vD, vD⟩
instance componentCompl_finite [LocallyFinite G] [Gpc : Fact G.Preconnected] (K : Finset V) :
    Finite (G.ComponentCompl K) := by
  

Proof state:
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
inst✝ : LocallyFinite G
Gpc : Fact (Preconnected G)
K : Finset V
⊢ Finite (ComponentCompl G ↑K)

Next tactic:
classical
  rcases K.eq_empty_or_nonempty with rfl | h
  -- If K is empty, then removing K doesn't change the graph, which is connected, hence has a
  -- single connected component
  · dsimp [ComponentCompl]
    rw [Finset.coe_empty, Set.compl_empty]
    have := Gpc.out.subsingleton_connectedComponent
    exact Finite.of_equiv _ (induceUnivIso G).connectedComponentEquiv.symm
  -- Otherwise, we consider the function `touch` mapping a connected component to one of its
  -- vertices adjacent to `K`.
  · let touch (C : G.ComponentCompl K) : {v : V | ∃ k : V, k ∈ K ∧ G.Adj k v} :=
      let p := C.exists_adj_boundary_pair Gpc.out h
      ⟨p.choose.1, p.choose.2, p.choose_spec.2.1, p.choose_spec.2.2.symm⟩
    -- `touch` is injective
    have touch_inj : touch.Injective := fun C D h' => ComponentCompl.pairwise_disjoint.eq
      (Set.not_disjoint_iff.mpr ⟨touch C, (C.exists_adj_boundary_pair Gpc.out h).choose_spec.1,
                                 h'.symm ▸ (D.exists_adj_boundary_pair Gpc.out h).choose_spec.1⟩)
    -- `touch` has finite range
    have : Finite (Set.range touch) := by
      refine @Subtype.finite _ (Set.Finite.to_subtype ?_) _
      apply Set.Finite.ofFinset (K.biUnion (fun v => G.neighborFinset v))
      simp only [Finset.mem_biUnion, mem_neighborFinset, Set.mem_setOf_eq, implies_true]
    -- hence `touch` has a finite domain
    apply Finite.of_injective_finite_range touch_inj
instance componentCompl_finite [LocallyFinite G] [Gpc : Fact G.Preconnected] (K : Finset V) :
    Finite (G.ComponentCompl K) := by
  classical
  

Proof state:
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
inst✝ : LocallyFinite G
Gpc : Fact (Preconnected G)
K : Finset V
⊢ Finite (ComponentCompl G ↑K)

Next tactic:
rcases K.eq_empty_or_nonempty with rfl | h
instance componentCompl_finite [LocallyFinite G] [Gpc : Fact G.Preconnected] (K : Finset V) :
    Finite (G.ComponentCompl K) := by
  classical
  rcases K.eq_empty_or_nonempty with rfl | h
  -- If K is empty, then removing K doesn't change the graph, which is connected, hence has a
  -- single connected component
  · 

Proof state:
case inl
V : Type u
G : SimpleGraph V
K L L' M : Set V
inst✝ : LocallyFinite G
Gpc : Fact (Preconnected G)
⊢ Finite (ComponentCompl G ↑∅)

Next tactic:
dsimp [ComponentCompl]
instance componentCompl_finite [LocallyFinite G] [Gpc : Fact G.Preconnected] (K : Finset V) :
    Finite (G.ComponentCompl K) := by
  classical
  rcases K.eq_empty_or_nonempty with rfl | h
  -- If K is empty, then removing K doesn't change the graph, which is connected, hence has a
  -- single connected component
  · dsimp [ComponentCompl]
    

Proof state:
case inl
V : Type u
G : SimpleGraph V
K L L' M : Set V
inst✝ : LocallyFinite G
Gpc : Fact (Preconnected G)
⊢ Finite (ConnectedComponent (induce (↑∅)ᶜ G))

Next tactic:
rw [Finset.coe_empty, Set.compl_empty]
instance componentCompl_finite [LocallyFinite G] [Gpc : Fact G.Preconnected] (K : Finset V) :
    Finite (G.ComponentCompl K) := by
  classical
  rcases K.eq_empty_or_nonempty with rfl | h
  -- If K is empty, then removing K doesn't change the graph, which is connected, hence has a
  -- single connected component
  · dsimp [ComponentCompl]
    rw [Finset.coe_empty, Set.compl_empty]
    

Proof state:
case inl
V : Type u
G : SimpleGraph V
K L L' M : Set V
inst✝ : LocallyFinite G
Gpc : Fact (Preconnected G)
⊢ Finite (ConnectedComponent (induce Set.univ G))

Next tactic:
have := Gpc.out.subsingleton_connectedComponent
instance componentCompl_finite [LocallyFinite G] [Gpc : Fact G.Preconnected] (K : Finset V) :
    Finite (G.ComponentCompl K) := by
  classical
  rcases K.eq_empty_or_nonempty with rfl | h
  -- If K is empty, then removing K doesn't change the graph, which is connected, hence has a
  -- single connected component
  · dsimp [ComponentCompl]
    rw [Finset.coe_empty, Set.compl_empty]
    have := Gpc.out.subsingleton_connectedComponent
    

Proof state:
case inl
V : Type u
G : SimpleGraph V
K L L' M : Set V
inst✝ : LocallyFinite G
Gpc : Fact (Preconnected G)
this : Subsingleton (ConnectedComponent G)
⊢ Finite (ConnectedComponent (induce Set.univ G))

Next tactic:
exact Finite.of_equiv _ (induceUnivIso G).connectedComponentEquiv.symm
instance componentCompl_finite [LocallyFinite G] [Gpc : Fact G.Preconnected] (K : Finset V) :
    Finite (G.ComponentCompl K) := by
  classical
  rcases K.eq_empty_or_nonempty with rfl | h
  -- If K is empty, then removing K doesn't change the graph, which is connected, hence has a
  -- single connected component
  · dsimp [ComponentCompl]
    rw [Finset.coe_empty, Set.compl_empty]
    have := Gpc.out.subsingleton_connectedComponent
    exact Finite.of_equiv _ (induceUnivIso G).connectedComponentEquiv.symm
  -- Otherwise, we consider the function `touch` mapping a connected component to one of its
  -- vertices adjacent to `K`.
  · 

Proof state:
case inr
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
inst✝ : LocallyFinite G
Gpc : Fact (Preconnected G)
K : Finset V
h : Finset.Nonempty K
⊢ Finite (ComponentCompl G ↑K)

Next tactic:
let touch (C : G.ComponentCompl K) : {v : V | ∃ k : V, k ∈ K ∧ G.Adj k v} :=
      let p := C.exists_adj_boundary_pair Gpc.out h
      ⟨p.choose.1, p.choose.2, p.choose_spec.2.1, p.choose_spec.2.2.symm⟩
instance componentCompl_finite [LocallyFinite G] [Gpc : Fact G.Preconnected] (K : Finset V) :
    Finite (G.ComponentCompl K) := by
  classical
  rcases K.eq_empty_or_nonempty with rfl | h
  -- If K is empty, then removing K doesn't change the graph, which is connected, hence has a
  -- single connected component
  · dsimp [ComponentCompl]
    rw [Finset.coe_empty, Set.compl_empty]
    have := Gpc.out.subsingleton_connectedComponent
    exact Finite.of_equiv _ (induceUnivIso G).connectedComponentEquiv.symm
  -- Otherwise, we consider the function `touch` mapping a connected component to one of its
  -- vertices adjacent to `K`.
  · let touch (C : G.ComponentCompl K) : {v : V | ∃ k : V, k ∈ K ∧ G.Adj k v} :=
      let p := C.exists_adj_boundary_pair Gpc.out h
      ⟨p.choose.1, p.choose.2, p.choose_spec.2.1, p.choose_spec.2.2.symm⟩
    -- `touch` is injective
    

Proof state:
case inr
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
inst✝ : LocallyFinite G
Gpc : Fact (Preconnected G)
K : Finset V
h : Finset.Nonempty K
touch : ComponentCompl G ↑K → ↑{v | ∃ k ∈ K, Adj G k v} :=
  fun C =>
    let p := (_ : ∃ ck, ck.1 ∈ C ∧ (ck.2 ∈ fun x => x ∈ K.val) ∧ Adj G ck.1 ck.2);
    { val := (Exists.choose p).1, property := (_ : ∃ k ∈ K, Adj G k (Exists.choose p).1) }
⊢ Finite (ComponentCompl G ↑K)

Next tactic:
have touch_inj : touch.Injective := fun C D h' => ComponentCompl.pairwise_disjoint.eq
      (Set.not_disjoint_iff.mpr ⟨touch C, (C.exists_adj_boundary_pair Gpc.out h).choose_spec.1,
                                 h'.symm ▸ (D.exists_adj_boundary_pair Gpc.out h).choose_spec.1⟩)
instance componentCompl_finite [LocallyFinite G] [Gpc : Fact G.Preconnected] (K : Finset V) :
    Finite (G.ComponentCompl K) := by
  classical
  rcases K.eq_empty_or_nonempty with rfl | h
  -- If K is empty, then removing K doesn't change the graph, which is connected, hence has a
  -- single connected component
  · dsimp [ComponentCompl]
    rw [Finset.coe_empty, Set.compl_empty]
    have := Gpc.out.subsingleton_connectedComponent
    exact Finite.of_equiv _ (induceUnivIso G).connectedComponentEquiv.symm
  -- Otherwise, we consider the function `touch` mapping a connected component to one of its
  -- vertices adjacent to `K`.
  · let touch (C : G.ComponentCompl K) : {v : V | ∃ k : V, k ∈ K ∧ G.Adj k v} :=
      let p := C.exists_adj_boundary_pair Gpc.out h
      ⟨p.choose.1, p.choose.2, p.choose_spec.2.1, p.choose_spec.2.2.symm⟩
    -- `touch` is injective
    have touch_inj : touch.Injective := fun C D h' => ComponentCompl.pairwise_disjoint.eq
      (Set.not_disjoint_iff.mpr ⟨touch C, (C.exists_adj_boundary_pair Gpc.out h).choose_spec.1,
                                 h'.symm ▸ (D.exists_adj_boundary_pair Gpc.out h).choose_spec.1⟩)
    -- `touch` has finite range
    

Proof state:
case inr
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
inst✝ : LocallyFinite G
Gpc : Fact (Preconnected G)
K : Finset V
h : Finset.Nonempty K
touch : ComponentCompl G ↑K → ↑{v | ∃ k ∈ K, Adj G k v} :=
  fun C =>
    let p := (_ : ∃ ck, ck.1 ∈ C ∧ (ck.2 ∈ fun x => x ∈ K.val) ∧ Adj G ck.1 ck.2);
    { val := (Exists.choose p).1, property := (_ : ∃ k ∈ K, Adj G k (Exists.choose p).1) }
touch_inj : Function.Injective touch
⊢ Finite (ComponentCompl G ↑K)

Next tactic:
have : Finite (Set.range touch) := by
      refine @Subtype.finite _ (Set.Finite.to_subtype ?_) _
      apply Set.Finite.ofFinset (K.biUnion (fun v => G.neighborFinset v))
      simp only [Finset.mem_biUnion, mem_neighborFinset, Set.mem_setOf_eq, implies_true]
instance componentCompl_finite [LocallyFinite G] [Gpc : Fact G.Preconnected] (K : Finset V) :
    Finite (G.ComponentCompl K) := by
  classical
  rcases K.eq_empty_or_nonempty with rfl | h
  -- If K is empty, then removing K doesn't change the graph, which is connected, hence has a
  -- single connected component
  · dsimp [ComponentCompl]
    rw [Finset.coe_empty, Set.compl_empty]
    have := Gpc.out.subsingleton_connectedComponent
    exact Finite.of_equiv _ (induceUnivIso G).connectedComponentEquiv.symm
  -- Otherwise, we consider the function `touch` mapping a connected component to one of its
  -- vertices adjacent to `K`.
  · let touch (C : G.ComponentCompl K) : {v : V | ∃ k : V, k ∈ K ∧ G.Adj k v} :=
      let p := C.exists_adj_boundary_pair Gpc.out h
      ⟨p.choose.1, p.choose.2, p.choose_spec.2.1, p.choose_spec.2.2.symm⟩
    -- `touch` is injective
    have touch_inj : touch.Injective := fun C D h' => ComponentCompl.pairwise_disjoint.eq
      (Set.not_disjoint_iff.mpr ⟨touch C, (C.exists_adj_boundary_pair Gpc.out h).choose_spec.1,
                                 h'.symm ▸ (D.exists_adj_boundary_pair Gpc.out h).choose_spec.1⟩)
    -- `touch` has finite range
    have : Finite (Set.range touch) := by
      

Proof state:
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
inst✝ : LocallyFinite G
Gpc : Fact (Preconnected G)
K : Finset V
h : Finset.Nonempty K
touch : ComponentCompl G ↑K → ↑{v | ∃ k ∈ K, Adj G k v} :=
  fun C =>
    let p := (_ : ∃ ck, ck.1 ∈ C ∧ (ck.2 ∈ fun x => x ∈ K.val) ∧ Adj G ck.1 ck.2);
    { val := (Exists.choose p).1, property := (_ : ∃ k ∈ K, Adj G k (Exists.choose p).1) }
touch_inj : Function.Injective touch
⊢ Finite ↑(Set.range touch)

Next tactic:
refine @Subtype.finite _ (Set.Finite.to_subtype ?_) _
instance componentCompl_finite [LocallyFinite G] [Gpc : Fact G.Preconnected] (K : Finset V) :
    Finite (G.ComponentCompl K) := by
  classical
  rcases K.eq_empty_or_nonempty with rfl | h
  -- If K is empty, then removing K doesn't change the graph, which is connected, hence has a
  -- single connected component
  · dsimp [ComponentCompl]
    rw [Finset.coe_empty, Set.compl_empty]
    have := Gpc.out.subsingleton_connectedComponent
    exact Finite.of_equiv _ (induceUnivIso G).connectedComponentEquiv.symm
  -- Otherwise, we consider the function `touch` mapping a connected component to one of its
  -- vertices adjacent to `K`.
  · let touch (C : G.ComponentCompl K) : {v : V | ∃ k : V, k ∈ K ∧ G.Adj k v} :=
      let p := C.exists_adj_boundary_pair Gpc.out h
      ⟨p.choose.1, p.choose.2, p.choose_spec.2.1, p.choose_spec.2.2.symm⟩
    -- `touch` is injective
    have touch_inj : touch.Injective := fun C D h' => ComponentCompl.pairwise_disjoint.eq
      (Set.not_disjoint_iff.mpr ⟨touch C, (C.exists_adj_boundary_pair Gpc.out h).choose_spec.1,
                                 h'.symm ▸ (D.exists_adj_boundary_pair Gpc.out h).choose_spec.1⟩)
    -- `touch` has finite range
    have : Finite (Set.range touch) := by
      refine @Subtype.finite _ (Set.Finite.to_subtype ?_) _
      

Proof state:
V : Type u
G : SimpleGraph V
K✝ L L' M : Set V
inst✝ : LocallyFinite G
Gpc : Fact (Preconnected G)
K : Finset V
h : Finset.Nonempty K
touch : ComponentCompl G ↑K → ↑{v | ∃ k ∈ K, Adj G k v} :=
  fun C =>
    let p := (_ : ∃ ck, ck.1 ∈ C ∧ (ck.2 ∈ fun x => x ∈ K.val) ∧ Adj G ck.1 ck.2);
    { val := (Exists.choose p).1, property := (_ : ∃ k ∈ K, Adj G k (Exists.choose p).1) }
touch_inj : Function.Injective touch
⊢ Set.Finite {v | ∃ k ∈ K, Adj G k v}

Next tactic:
apply Set.Finite.ofFinset (K.biUnion (fun v => G.neighborFinset v))