l3lab/ntp-mathlib huggingface dataset:
/-- A sum version of Vieta's formula for `MvPolynomial`: viewing `X i` as variables,
the product of linear terms `λ + X i` is equal to a linear combination of
the symmetric polynomials `esymm σ R j`. -/
theorem MvPolynomial.prod_C_add_X_eq_sum_esymm :
    (∏ i : σ, (Polynomial.X + Polynomial.C (MvPolynomial.X i))) =
      ∑ j in range (card σ + 1), Polynomial.C
        (MvPolynomial.esymm σ R j) * Polynomial.X ^ (card σ - j) := by
  let s := Finset.univ.val.map fun i : σ => (MvPolynomial.X i : MvPolynomial σ R)
  have : Fintype.card σ = Multiset.card s := by
    rw [Multiset.card_map, ← Finset.card_univ, Finset.card_def]
  simp_rw [this, MvPolynomial.esymm_eq_multiset_esymm σ R, Finset.prod_eq_multiset_prod]
  

Proof state:
R : Type u_1
σ : Type u_2
inst✝¹ : CommSemiring R
inst✝ : Fintype σ
s : Multiset (MvPolynomial σ R) := Multiset.map (fun i => X i) univ.val
this : Fintype.card σ = Multiset.card s
⊢ Multiset.prod (Multiset.map (fun i => Polynomial.X + Polynomial.C (X i)) univ.val) =
    ∑ x in range (Multiset.card (Multiset.map (fun i => X i) univ.val) + 1),
      Polynomial.C (Multiset.esymm (Multiset.map X univ.val) x) *
        Polynomial.X ^ (Multiset.card (Multiset.map (fun i => X i) univ.val) - x)

Next tactic:
convert Multiset.prod_X_add_C_eq_sum_esymm s
/-- A sum version of Vieta's formula for `MvPolynomial`: viewing `X i` as variables,
the product of linear terms `λ + X i` is equal to a linear combination of
the symmetric polynomials `esymm σ R j`. -/
theorem MvPolynomial.prod_C_add_X_eq_sum_esymm :
    (∏ i : σ, (Polynomial.X + Polynomial.C (MvPolynomial.X i))) =
      ∑ j in range (card σ + 1), Polynomial.C
        (MvPolynomial.esymm σ R j) * Polynomial.X ^ (card σ - j) := by
  let s := Finset.univ.val.map fun i : σ => (MvPolynomial.X i : MvPolynomial σ R)
  have : Fintype.card σ = Multiset.card s := by
    rw [Multiset.card_map, ← Finset.card_univ, Finset.card_def]
  simp_rw [this, MvPolynomial.esymm_eq_multiset_esymm σ R, Finset.prod_eq_multiset_prod]
  convert Multiset.prod_X_add_C_eq_sum_esymm s
  

Proof state:
case h.e'_2.h.e'_3
R : Type u_1
σ : Type u_2
inst✝¹ : CommSemiring R
inst✝ : Fintype σ
s : Multiset (MvPolynomial σ R) := Multiset.map (fun i => X i) univ.val
this : Fintype.card σ = Multiset.card s
⊢ Multiset.map (fun i => Polynomial.X + Polynomial.C (X i)) univ.val =
    Multiset.map (fun r => Polynomial.X + Polynomial.C r) s

Next tactic:
simp_rw [Multiset.map_map, Function.comp_apply]
theorem MvPolynomial.prod_X_add_C_coeff (k : ℕ) (h : k ≤ card σ) :
    (∏ i : σ, (Polynomial.X + Polynomial.C (MvPolynomial.X i)) : Polynomial _).coeff k =
    MvPolynomial.esymm σ R (card σ - k) := by
  

Proof state:
R : Type u_1
σ : Type u_2
inst✝¹ : CommSemiring R
inst✝ : Fintype σ
k : ℕ
h : k ≤ Fintype.card σ
⊢ Polynomial.coeff (∏ i : σ, (Polynomial.X + Polynomial.C (X i))) k = esymm σ R (Fintype.card σ - k)

Next tactic:
let s := Finset.univ.val.map fun i => (MvPolynomial.X i : MvPolynomial σ R)
theorem MvPolynomial.prod_X_add_C_coeff (k : ℕ) (h : k ≤ card σ) :
    (∏ i : σ, (Polynomial.X + Polynomial.C (MvPolynomial.X i)) : Polynomial _).coeff k =
    MvPolynomial.esymm σ R (card σ - k) := by
  let s := Finset.univ.val.map fun i => (MvPolynomial.X i : MvPolynomial σ R)
  

Proof state:
R : Type u_1
σ : Type u_2
inst✝¹ : CommSemiring R
inst✝ : Fintype σ
k : ℕ
h : k ≤ Fintype.card σ
s : Multiset (MvPolynomial σ R) := Multiset.map (fun i => X i) univ.val
⊢ Polynomial.coeff (∏ i : σ, (Polynomial.X + Polynomial.C (X i))) k = esymm σ R (Fintype.card σ - k)

Next tactic:
have : Fintype.card σ = Multiset.card s := by
    rw [Multiset.card_map, ← Finset.card_univ, Finset.card_def]
theorem MvPolynomial.prod_X_add_C_coeff (k : ℕ) (h : k ≤ card σ) :
    (∏ i : σ, (Polynomial.X + Polynomial.C (MvPolynomial.X i)) : Polynomial _).coeff k =
    MvPolynomial.esymm σ R (card σ - k) := by
  let s := Finset.univ.val.map fun i => (MvPolynomial.X i : MvPolynomial σ R)
  have : Fintype.card σ = Multiset.card s := by
    

Proof state:
R : Type u_1
σ : Type u_2
inst✝¹ : CommSemiring R
inst✝ : Fintype σ
k : ℕ
h : k ≤ Fintype.card σ
s : Multiset (MvPolynomial σ R) := Multiset.map (fun i => X i) univ.val
⊢ Fintype.card σ = Multiset.card s

Next tactic:
rw [Multiset.card_map, ← Finset.card_univ, Finset.card_def]
theorem MvPolynomial.prod_X_add_C_coeff (k : ℕ) (h : k ≤ card σ) :
    (∏ i : σ, (Polynomial.X + Polynomial.C (MvPolynomial.X i)) : Polynomial _).coeff k =
    MvPolynomial.esymm σ R (card σ - k) := by
  let s := Finset.univ.val.map fun i => (MvPolynomial.X i : MvPolynomial σ R)
  have : Fintype.card σ = Multiset.card s := by
    rw [Multiset.card_map, ← Finset.card_univ, Finset.card_def]
  

Proof state:
R : Type u_1
σ : Type u_2
inst✝¹ : CommSemiring R
inst✝ : Fintype σ
k : ℕ
h : k ≤ Fintype.card σ
s : Multiset (MvPolynomial σ R) := Multiset.map (fun i => X i) univ.val
this : Fintype.card σ = Multiset.card s
⊢ Polynomial.coeff (∏ i : σ, (Polynomial.X + Polynomial.C (X i))) k = esymm σ R (Fintype.card σ - k)

Next tactic:
rw [this] at h ⊢
theorem MvPolynomial.prod_X_add_C_coeff (k : ℕ) (h : k ≤ card σ) :
    (∏ i : σ, (Polynomial.X + Polynomial.C (MvPolynomial.X i)) : Polynomial _).coeff k =
    MvPolynomial.esymm σ R (card σ - k) := by
  let s := Finset.univ.val.map fun i => (MvPolynomial.X i : MvPolynomial σ R)
  have : Fintype.card σ = Multiset.card s := by
    rw [Multiset.card_map, ← Finset.card_univ, Finset.card_def]
  rw [this] at h ⊢
  

Proof state:
R : Type u_1
σ : Type u_2
inst✝¹ : CommSemiring R
inst✝ : Fintype σ
k : ℕ
s : Multiset (MvPolynomial σ R) := Multiset.map (fun i => X i) univ.val
h : k ≤ Multiset.card s
this : Fintype.card σ = Multiset.card s
⊢ Polynomial.coeff (∏ i : σ, (Polynomial.X + Polynomial.C (X i))) k = esymm σ R (Multiset.card s - k)

Next tactic:
rw [MvPolynomial.esymm_eq_multiset_esymm σ R, Finset.prod_eq_multiset_prod]
theorem MvPolynomial.prod_X_add_C_coeff (k : ℕ) (h : k ≤ card σ) :
    (∏ i : σ, (Polynomial.X + Polynomial.C (MvPolynomial.X i)) : Polynomial _).coeff k =
    MvPolynomial.esymm σ R (card σ - k) := by
  let s := Finset.univ.val.map fun i => (MvPolynomial.X i : MvPolynomial σ R)
  have : Fintype.card σ = Multiset.card s := by
    rw [Multiset.card_map, ← Finset.card_univ, Finset.card_def]
  rw [this] at h ⊢
  rw [MvPolynomial.esymm_eq_multiset_esymm σ R, Finset.prod_eq_multiset_prod]
  

Proof state:
R : Type u_1
σ : Type u_2
inst✝¹ : CommSemiring R
inst✝ : Fintype σ
k : ℕ
s : Multiset (MvPolynomial σ R) := Multiset.map (fun i => X i) univ.val
h : k ≤ Multiset.card s
this : Fintype.card σ = Multiset.card s
⊢ Polynomial.coeff (Multiset.prod (Multiset.map (fun i => Polynomial.X + Polynomial.C (X i)) univ.val)) k =
    Multiset.esymm (Multiset.map X univ.val) (Multiset.card s - k)

Next tactic:
convert Multiset.prod_X_add_C_coeff s h
theorem MvPolynomial.prod_X_add_C_coeff (k : ℕ) (h : k ≤ card σ) :
    (∏ i : σ, (Polynomial.X + Polynomial.C (MvPolynomial.X i)) : Polynomial _).coeff k =
    MvPolynomial.esymm σ R (card σ - k) := by
  let s := Finset.univ.val.map fun i => (MvPolynomial.X i : MvPolynomial σ R)
  have : Fintype.card σ = Multiset.card s := by
    rw [Multiset.card_map, ← Finset.card_univ, Finset.card_def]
  rw [this] at h ⊢
  rw [MvPolynomial.esymm_eq_multiset_esymm σ R, Finset.prod_eq_multiset_prod]
  convert Multiset.prod_X_add_C_coeff s h
  

Proof state:
case h.e'_2.h.e'_3.h.e'_3
R : Type u_1
σ : Type u_2
inst✝¹ : CommSemiring R
inst✝ : Fintype σ
k : ℕ
s : Multiset (MvPolynomial σ R) := Multiset.map (fun i => X i) univ.val
h : k ≤ Multiset.card s
this : Fintype.card σ = Multiset.card s
⊢ Multiset.map (fun i => Polynomial.X + Polynomial.C (X i)) univ.val =
    Multiset.map (fun r => Polynomial.X + Polynomial.C r) s

Next tactic:
dsimp
theorem MvPolynomial.prod_X_add_C_coeff (k : ℕ) (h : k ≤ card σ) :
    (∏ i : σ, (Polynomial.X + Polynomial.C (MvPolynomial.X i)) : Polynomial _).coeff k =
    MvPolynomial.esymm σ R (card σ - k) := by
  let s := Finset.univ.val.map fun i => (MvPolynomial.X i : MvPolynomial σ R)
  have : Fintype.card σ = Multiset.card s := by
    rw [Multiset.card_map, ← Finset.card_univ, Finset.card_def]
  rw [this] at h ⊢
  rw [MvPolynomial.esymm_eq_multiset_esymm σ R, Finset.prod_eq_multiset_prod]
  convert Multiset.prod_X_add_C_coeff s h
  dsimp
  

Proof state:
case h.e'_2.h.e'_3.h.e'_3
R : Type u_1
σ : Type u_2
inst✝¹ : CommSemiring R
inst✝ : Fintype σ
k : ℕ
s : Multiset (MvPolynomial σ R) := Multiset.map (fun i => X i) univ.val
h : k ≤ Multiset.card s
this : Fintype.card σ = Multiset.card s
⊢ Multiset.map (fun i => Polynomial.X + Polynomial.C (X i)) univ.val =
    Multiset.map (fun r => Polynomial.X + Polynomial.C r) (Multiset.map (fun i => X i) univ.val)

Next tactic:
simp_rw [Multiset.map_map, Function.comp_apply]
/-- The one-edge subgraph. -/
@[simps]
def subgraphOfAdj (G : SimpleGraph V) {v w : V} (hvw : G.Adj v w) : G.Subgraph where
  verts := {v, w}
  Adj a b := ⟦(v, w)⟧ = ⟦(a, b)⟧
  adj_sub h := by
    

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
v w : V
hvw : Adj G v w
v✝ w✝ : V
h : (fun a b => ⟦(v, w)⟧ = ⟦(a, b)⟧) v✝ w✝
⊢ Adj G v✝ w✝

Next tactic:
rw [← G.mem_edgeSet, ← h]
/-- The one-edge subgraph. -/
@[simps]
def subgraphOfAdj (G : SimpleGraph V) {v w : V} (hvw : G.Adj v w) : G.Subgraph where
  verts := {v, w}
  Adj a b := ⟦(v, w)⟧ = ⟦(a, b)⟧
  adj_sub h := by
    rw [← G.mem_edgeSet, ← h]
    

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
v w : V
hvw : Adj G v w
v✝ w✝ : V
h : (fun a b => ⟦(v, w)⟧ = ⟦(a, b)⟧) v✝ w✝
⊢ ⟦(v, w)⟧ ∈ edgeSet G

Next tactic:
exact hvw
/-- The one-edge subgraph. -/
@[simps]
def subgraphOfAdj (G : SimpleGraph V) {v w : V} (hvw : G.Adj v w) : G.Subgraph where
  verts := {v, w}
  Adj a b := ⟦(v, w)⟧ = ⟦(a, b)⟧
  adj_sub h := by
    rw [← G.mem_edgeSet, ← h]
    exact hvw
  edge_vert {a b} h := by
    

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
v w : V
hvw : Adj G v w
a b : V
h : (fun a b => ⟦(v, w)⟧ = ⟦(a, b)⟧) a b
⊢ a ∈ {v, w}

Next tactic:
apply_fun fun e ↦ a ∈ e at h
/-- The one-edge subgraph. -/
@[simps]
def subgraphOfAdj (G : SimpleGraph V) {v w : V} (hvw : G.Adj v w) : G.Subgraph where
  verts := {v, w}
  Adj a b := ⟦(v, w)⟧ = ⟦(a, b)⟧
  adj_sub h := by
    rw [← G.mem_edgeSet, ← h]
    exact hvw
  edge_vert {a b} h := by
    apply_fun fun e ↦ a ∈ e at h
    

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
v w : V
hvw : Adj G v w
a b : V
h : (a ∈ ⟦(v, w)⟧) = (a ∈ ⟦(a, b)⟧)
⊢ a ∈ {v, w}

Next tactic:
simp only [Sym2.mem_iff, true_or, eq_iff_iff, iff_true] at h
/-- The one-edge subgraph. -/
@[simps]
def subgraphOfAdj (G : SimpleGraph V) {v w : V} (hvw : G.Adj v w) : G.Subgraph where
  verts := {v, w}
  Adj a b := ⟦(v, w)⟧ = ⟦(a, b)⟧
  adj_sub h := by
    rw [← G.mem_edgeSet, ← h]
    exact hvw
  edge_vert {a b} h := by
    apply_fun fun e ↦ a ∈ e at h
    simp only [Sym2.mem_iff, true_or, eq_iff_iff, iff_true] at h
    

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
v w : V
hvw : Adj G v w
a b : V
h : a = v ∨ a = w
⊢ a ∈ {v, w}

Next tactic:
exact h
theorem spanningCoe_inj : G₁.spanningCoe = G₂.spanningCoe ↔ G₁.Adj = G₂.Adj := by
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
⊢ Subgraph.spanningCoe G₁ = Subgraph.spanningCoe G₂ ↔ G₁.Adj = G₂.Adj

Next tactic:
simp [Subgraph.spanningCoe]
theorem mem_verts_if_mem_edge {G' : Subgraph G} {e : Sym2 V} {v : V} (he : e ∈ G'.edgeSet)
    (hv : v ∈ e) : v ∈ G'.verts := by
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
G' : Subgraph G
e : Sym2 V
v : V
he : e ∈ edgeSet G'
hv : v ∈ e
⊢ v ∈ G'.verts

Next tactic:
revert hv
theorem mem_verts_if_mem_edge {G' : Subgraph G} {e : Sym2 V} {v : V} (he : e ∈ G'.edgeSet)
    (hv : v ∈ e) : v ∈ G'.verts := by
  revert hv
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
G' : Subgraph G
e : Sym2 V
v : V
he : e ∈ edgeSet G'
⊢ v ∈ e → v ∈ G'.verts

Next tactic:
refine' Sym2.ind (fun v w he ↦ _) e he
theorem mem_verts_if_mem_edge {G' : Subgraph G} {e : Sym2 V} {v : V} (he : e ∈ G'.edgeSet)
    (hv : v ∈ e) : v ∈ G'.verts := by
  revert hv
  refine' Sym2.ind (fun v w he ↦ _) e he
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
G' : Subgraph G
e : Sym2 V
v✝ : V
he✝ : e ∈ edgeSet G'
v w : V
he : ⟦(v, w)⟧ ∈ edgeSet G'
⊢ v✝ ∈ ⟦(v, w)⟧ → v✝ ∈ G'.verts

Next tactic:
intro hv
theorem mem_verts_if_mem_edge {G' : Subgraph G} {e : Sym2 V} {v : V} (he : e ∈ G'.edgeSet)
    (hv : v ∈ e) : v ∈ G'.verts := by
  revert hv
  refine' Sym2.ind (fun v w he ↦ _) e he
  intro hv
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
G' : Subgraph G
e : Sym2 V
v✝ : V
he✝ : e ∈ edgeSet G'
v w : V
he : ⟦(v, w)⟧ ∈ edgeSet G'
hv : v✝ ∈ ⟦(v, w)⟧
⊢ v✝ ∈ G'.verts

Next tactic:
rcases Sym2.mem_iff.mp hv with (rfl | rfl)
theorem mem_verts_if_mem_edge {G' : Subgraph G} {e : Sym2 V} {v : V} (he : e ∈ G'.edgeSet)
    (hv : v ∈ e) : v ∈ G'.verts := by
  revert hv
  refine' Sym2.ind (fun v w he ↦ _) e he
  intro hv
  rcases Sym2.mem_iff.mp hv with (rfl | rfl)
  · 

Proof state:
case inl
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
G' : Subgraph G
e : Sym2 V
v : V
he✝ : e ∈ edgeSet G'
w : V
he : ⟦(v, w)⟧ ∈ edgeSet G'
hv : v ∈ ⟦(v, w)⟧
⊢ v ∈ G'.verts

Next tactic:
exact G'.edge_vert he
theorem mem_verts_if_mem_edge {G' : Subgraph G} {e : Sym2 V} {v : V} (he : e ∈ G'.edgeSet)
    (hv : v ∈ e) : v ∈ G'.verts := by
  revert hv
  refine' Sym2.ind (fun v w he ↦ _) e he
  intro hv
  rcases Sym2.mem_iff.mp hv with (rfl | rfl)
  · exact G'.edge_vert he
  · 

Proof state:
case inr
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
G' : Subgraph G
e : Sym2 V
v✝ : V
he✝ : e ∈ edgeSet G'
v : V
he : ⟦(v, v✝)⟧ ∈ edgeSet G'
hv : v✝ ∈ ⟦(v, v✝)⟧
⊢ v✝ ∈ G'.verts

Next tactic:
exact G'.edge_vert (G'.symm he)
instance : SupSet G.Subgraph where
  sSup s :=
    { verts := ⋃ G' ∈ s, verts G'
      Adj := fun a b => ∃ G' ∈ s, Adj G' a b
      adj_sub := by
        

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
s : Set (Subgraph G)
⊢ ∀ {v w : V}, (fun a b => ∃ G' ∈ s, Adj G' a b) v w → SimpleGraph.Adj G v w

Next tactic:
rintro a b ⟨G', -, hab⟩
instance : SupSet G.Subgraph where
  sSup s :=
    { verts := ⋃ G' ∈ s, verts G'
      Adj := fun a b => ∃ G' ∈ s, Adj G' a b
      adj_sub := by
        rintro a b ⟨G', -, hab⟩
        

Proof state:
case intro.intro
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a✝ b✝ : V
s : Set (Subgraph G)
a b : V
G' : Subgraph G
hab : Adj G' a b
⊢ SimpleGraph.Adj G a b

Next tactic:
exact G'.adj_sub hab
instance : SupSet G.Subgraph where
  sSup s :=
    { verts := ⋃ G' ∈ s, verts G'
      Adj := fun a b => ∃ G' ∈ s, Adj G' a b
      adj_sub := by
        rintro a b ⟨G', -, hab⟩
        exact G'.adj_sub hab
      edge_vert := by
        

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
s : Set (Subgraph G)
⊢ ∀ {v w : V}, (fun a b => ∃ G' ∈ s, Adj G' a b) v w → v ∈ ⋃ G' ∈ s, G'.verts

Next tactic:
rintro a b ⟨G', hG', hab⟩
instance : SupSet G.Subgraph where
  sSup s :=
    { verts := ⋃ G' ∈ s, verts G'
      Adj := fun a b => ∃ G' ∈ s, Adj G' a b
      adj_sub := by
        rintro a b ⟨G', -, hab⟩
        exact G'.adj_sub hab
      edge_vert := by
        rintro a b ⟨G', hG', hab⟩
        

Proof state:
case intro.intro
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a✝ b✝ : V
s : Set (Subgraph G)
a b : V
G' : Subgraph G
hG' : G' ∈ s
hab : Adj G' a b
⊢ a ∈ ⋃ G' ∈ s, G'.verts

Next tactic:
exact Set.mem_iUnion₂_of_mem hG' (G'.edge_vert hab)
instance : SupSet G.Subgraph where
  sSup s :=
    { verts := ⋃ G' ∈ s, verts G'
      Adj := fun a b => ∃ G' ∈ s, Adj G' a b
      adj_sub := by
        rintro a b ⟨G', -, hab⟩
        exact G'.adj_sub hab
      edge_vert := by
        rintro a b ⟨G', hG', hab⟩
        exact Set.mem_iUnion₂_of_mem hG' (G'.edge_vert hab)
      symm := fun a b h => by 

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a✝ b✝ : V
s : Set (Subgraph G)
a b : V
h : (fun a b => ∃ G' ∈ s, Adj G' a b) a b
⊢ (fun a b => ∃ G' ∈ s, Adj G' a b) b a

Next tactic:
simpa [adj_comm] using h
@[simp]
theorem iSup_adj {f : ι → G.Subgraph} : (⨆ i, f i).Adj a b ↔ ∃ i, (f i).Adj a b := by
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
f : ι → Subgraph G
⊢ Adj (⨆ i, f i) a b ↔ ∃ i, Adj (f i) a b

Next tactic:
simp [iSup]
@[simp]
theorem iInf_adj {f : ι → G.Subgraph} : (⨅ i, f i).Adj a b ↔ (∀ i, (f i).Adj a b) ∧ G.Adj a b := by
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
f : ι → Subgraph G
⊢ Adj (⨅ i, f i) a b ↔ (∀ (i : ι), Adj (f i) a b) ∧ SimpleGraph.Adj G a b

Next tactic:
simp [iInf]
theorem sInf_adj_of_nonempty {s : Set G.Subgraph} (hs : s.Nonempty) :
    (sInf s).Adj a b ↔ ∀ G' ∈ s, Adj G' a b :=
  sInf_adj.trans <|
    and_iff_left_of_imp <| by
      

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
s : Set (Subgraph G)
hs : Set.Nonempty s
⊢ (∀ G' ∈ s, Adj G' a b) → SimpleGraph.Adj G a b

Next tactic:
obtain ⟨G', hG'⟩ := hs
theorem sInf_adj_of_nonempty {s : Set G.Subgraph} (hs : s.Nonempty) :
    (sInf s).Adj a b ↔ ∀ G' ∈ s, Adj G' a b :=
  sInf_adj.trans <|
    and_iff_left_of_imp <| by
      obtain ⟨G', hG'⟩ := hs
      

Proof state:
case intro
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
s : Set (Subgraph G)
G' : Subgraph G
hG' : G' ∈ s
⊢ (∀ G' ∈ s, Adj G' a b) → SimpleGraph.Adj G a b

Next tactic:
exact fun h => G'.adj_sub (h _ hG')
theorem iInf_adj_of_nonempty [Nonempty ι] {f : ι → G.Subgraph} :
    (⨅ i, f i).Adj a b ↔ ∀ i, (f i).Adj a b := by
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
inst✝ : Nonempty ι
f : ι → Subgraph G
⊢ Adj (⨅ i, f i) a b ↔ ∀ (i : ι), Adj (f i) a b

Next tactic:
rw [iInf, sInf_adj_of_nonempty (Set.range_nonempty _)]
theorem iInf_adj_of_nonempty [Nonempty ι] {f : ι → G.Subgraph} :
    (⨅ i, f i).Adj a b ↔ ∀ i, (f i).Adj a b := by
  rw [iInf, sInf_adj_of_nonempty (Set.range_nonempty _)]
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
inst✝ : Nonempty ι
f : ι → Subgraph G
⊢ (∀ G' ∈ Set.range fun i => f i, Adj G' a b) ↔ ∀ (i : ι), Adj (f i) a b

Next tactic:
simp
@[simp]
theorem verts_iSup {f : ι → G.Subgraph} : (⨆ i, f i).verts = ⋃ i, (f i).verts := by 

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
f : ι → Subgraph G
⊢ (⨆ i, f i).verts = ⋃ i, (f i).verts

Next tactic:
simp [iSup]
@[simp]
theorem verts_iInf {f : ι → G.Subgraph} : (⨅ i, f i).verts = ⋂ i, (f i).verts := by 

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
f : ι → Subgraph G
⊢ (⨅ i, f i).verts = ⋂ i, (f i).verts

Next tactic:
simp [iInf]
theorem verts_spanningCoe_injective :
    (fun G' : Subgraph G => (G'.verts, G'.spanningCoe)).Injective := by
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
⊢ Function.Injective fun G' => (G'.verts, Subgraph.spanningCoe G')

Next tactic:
intro G₁ G₂ h
theorem verts_spanningCoe_injective :
    (fun G' : Subgraph G => (G'.verts, G'.spanningCoe)).Injective := by
  intro G₁ G₂ h
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁✝ G₂✝ : Subgraph G
a b : V
G₁ G₂ : Subgraph G
h : (fun G' => (G'.verts, Subgraph.spanningCoe G')) G₁ = (fun G' => (G'.verts, Subgraph.spanningCoe G')) G₂
⊢ G₁ = G₂

Next tactic:
rw [Prod.ext_iff] at h
theorem verts_spanningCoe_injective :
    (fun G' : Subgraph G => (G'.verts, G'.spanningCoe)).Injective := by
  intro G₁ G₂ h
  rw [Prod.ext_iff] at h
  

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁✝ G₂✝ : Subgraph G
a b : V
G₁ G₂ : Subgraph G
h :
  ((fun G' => (G'.verts, Subgraph.spanningCoe G')) G₁).1 = ((fun G' => (G'.verts, Subgraph.spanningCoe G')) G₂).1 ∧
    ((fun G' => (G'.verts, Subgraph.spanningCoe G')) G₁).2 = ((fun G' => (G'.verts, Subgraph.spanningCoe G')) G₂).2
⊢ G₁ = G₂

Next tactic:
exact Subgraph.ext _ _ h.1 (spanningCoe_inj.1 h.2)
instance : CompletelyDistribLattice G.Subgraph :=
  { Subgraph.distribLattice with
    le := (· ≤ ·)
    sup := (· ⊔ ·)
    inf := (· ⊓ ·)
    top := ⊤
    bot := ⊥
    le_top := fun G' => ⟨Set.subset_univ _, fun a b => G'.adj_sub⟩
    bot_le := fun G' => ⟨Set.empty_subset _, fun a b => False.elim⟩
    sSup := sSup
    -- porting note: needed `apply` here to modify elaboration; previously the term itself was fine.
    le_sSup := fun s G' hG' => ⟨by 

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
src✝ : DistribLattice (Subgraph G) := distribLattice
s : Set (Subgraph G)
G' : Subgraph G
hG' : G' ∈ s
⊢ G'.verts ⊆ (sSup s).verts

Next tactic:
apply Set.subset_iUnion₂ G' hG'
instance : CompletelyDistribLattice G.Subgraph :=
  { Subgraph.distribLattice with
    le := (· ≤ ·)
    sup := (· ⊔ ·)
    inf := (· ⊓ ·)
    top := ⊤
    bot := ⊥
    le_top := fun G' => ⟨Set.subset_univ _, fun a b => G'.adj_sub⟩
    bot_le := fun G' => ⟨Set.empty_subset _, fun a b => False.elim⟩
    sSup := sSup
    -- porting note: needed `apply` here to modify elaboration; previously the term itself was fine.
    le_sSup := fun s G' hG' => ⟨by apply Set.subset_iUnion₂ G' hG', fun a b hab => ⟨G', hG', hab⟩⟩
    sSup_le := fun s G' hG' =>
      ⟨Set.iUnion₂_subset fun H hH => (hG' _ hH).1, by
        

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
src✝ : DistribLattice (Subgraph G) := distribLattice
s : Set (Subgraph G)
G' : Subgraph G
hG' : ∀ b ∈ s, b ≤ G'
⊢ ∀ ⦃v w : V⦄, Adj (sSup s) v w → Adj G' v w

Next tactic:
rintro a b ⟨H, hH, hab⟩
instance : CompletelyDistribLattice G.Subgraph :=
  { Subgraph.distribLattice with
    le := (· ≤ ·)
    sup := (· ⊔ ·)
    inf := (· ⊓ ·)
    top := ⊤
    bot := ⊥
    le_top := fun G' => ⟨Set.subset_univ _, fun a b => G'.adj_sub⟩
    bot_le := fun G' => ⟨Set.empty_subset _, fun a b => False.elim⟩
    sSup := sSup
    -- porting note: needed `apply` here to modify elaboration; previously the term itself was fine.
    le_sSup := fun s G' hG' => ⟨by apply Set.subset_iUnion₂ G' hG', fun a b hab => ⟨G', hG', hab⟩⟩
    sSup_le := fun s G' hG' =>
      ⟨Set.iUnion₂_subset fun H hH => (hG' _ hH).1, by
        rintro a b ⟨H, hH, hab⟩
        

Proof state:
case intro.intro
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a✝ b✝ : V
src✝ : DistribLattice (Subgraph G) := distribLattice
s : Set (Subgraph G)
G' : Subgraph G
hG' : ∀ b ∈ s, b ≤ G'
a b : V
H : Subgraph G
hH : H ∈ s
hab : Adj H a b
⊢ Adj G' a b

Next tactic:
exact (hG' _ hH).2 hab
instance : CompletelyDistribLattice G.Subgraph :=
  { Subgraph.distribLattice with
    le := (· ≤ ·)
    sup := (· ⊔ ·)
    inf := (· ⊓ ·)
    top := ⊤
    bot := ⊥
    le_top := fun G' => ⟨Set.subset_univ _, fun a b => G'.adj_sub⟩
    bot_le := fun G' => ⟨Set.empty_subset _, fun a b => False.elim⟩
    sSup := sSup
    -- porting note: needed `apply` here to modify elaboration; previously the term itself was fine.
    le_sSup := fun s G' hG' => ⟨by apply Set.subset_iUnion₂ G' hG', fun a b hab => ⟨G', hG', hab⟩⟩
    sSup_le := fun s G' hG' =>
      ⟨Set.iUnion₂_subset fun H hH => (hG' _ hH).1, by
        rintro a b ⟨H, hH, hab⟩
        exact (hG' _ hH).2 hab⟩
    sInf := sInf
    sInf_le := fun s G' hG' => ⟨Set.iInter₂_subset G' hG', fun a b hab => hab.1 hG'⟩
    le_sInf := fun s G' hG' =>
      ⟨Set.subset_iInter₂ fun H hH => (hG' _ hH).1, fun a b hab =>
        ⟨fun H hH => (hG' _ hH).2 hab, G'.adj_sub hab⟩⟩
    iInf_iSup_eq := fun f => Subgraph.ext _ _ (by 

Proof state:
ι : Sort u_1
V : Type u
W : Type v
G : SimpleGraph V
G₁ G₂ : Subgraph G
a b : V
src✝ : DistribLattice (Subgraph G) := distribLattice
ι✝ : Type u
κ✝ : ι✝ → Type u
f : (a : ι✝) → κ✝ a → Subgraph G
⊢ (⨅ a, ⨆ b, f a b).verts = (⨆ g, ⨅ a, f a (g a)).verts

Next tactic:
simpa using iInf_iSup_eq