l3lab/ntp-mathlib huggingface dataset:
/-- Constructor for simple graphs using a symmetric irreflexive boolean function. -/
@[simps]
def SimpleGraph.mk' {V : Type u} :
    {adj : V → V → Bool // (∀ x y, adj x y = adj y x) ∧ (∀ x, ¬ adj x x)} ↪ SimpleGraph V where
  toFun x := ⟨fun v w ↦ x.1 v w, fun v w ↦ by simp [x.2.1], fun v ↦ by simp [x.2.2]⟩
  inj' := by
    rintro ⟨adj, _⟩ ⟨adj', _⟩
    simp only [mk.injEq, Subtype.mk.injEq]
    

Proof state:
case mk.mk
V : Type u
adj : V → V → Bool
property✝¹ : (∀ (x y : V), adj x y = adj y x) ∧ ∀ (x : V), ¬adj x x = true
adj' : V → V → Bool
property✝ : (∀ (x y : V), adj' x y = adj' y x) ∧ ∀ (x : V), ¬adj' x x = true
⊢ ((fun v w => adj v w = true) = fun v w => adj' v w = true) → adj = adj'

Next tactic:
intro h
/-- Constructor for simple graphs using a symmetric irreflexive boolean function. -/
@[simps]
def SimpleGraph.mk' {V : Type u} :
    {adj : V → V → Bool // (∀ x y, adj x y = adj y x) ∧ (∀ x, ¬ adj x x)} ↪ SimpleGraph V where
  toFun x := ⟨fun v w ↦ x.1 v w, fun v w ↦ by simp [x.2.1], fun v ↦ by simp [x.2.2]⟩
  inj' := by
    rintro ⟨adj, _⟩ ⟨adj', _⟩
    simp only [mk.injEq, Subtype.mk.injEq]
    intro h
    

Proof state:
case mk.mk
V : Type u
adj : V → V → Bool
property✝¹ : (∀ (x y : V), adj x y = adj y x) ∧ ∀ (x : V), ¬adj x x = true
adj' : V → V → Bool
property✝ : (∀ (x y : V), adj' x y = adj' y x) ∧ ∀ (x : V), ¬adj' x x = true
h : (fun v w => adj v w = true) = fun v w => adj' v w = true
⊢ adj = adj'

Next tactic:
funext v w
/-- Constructor for simple graphs using a symmetric irreflexive boolean function. -/
@[simps]
def SimpleGraph.mk' {V : Type u} :
    {adj : V → V → Bool // (∀ x y, adj x y = adj y x) ∧ (∀ x, ¬ adj x x)} ↪ SimpleGraph V where
  toFun x := ⟨fun v w ↦ x.1 v w, fun v w ↦ by simp [x.2.1], fun v ↦ by simp [x.2.2]⟩
  inj' := by
    rintro ⟨adj, _⟩ ⟨adj', _⟩
    simp only [mk.injEq, Subtype.mk.injEq]
    intro h
    funext v w
    

Proof state:
case mk.mk.h.h
V : Type u
adj : V → V → Bool
property✝¹ : (∀ (x y : V), adj x y = adj y x) ∧ ∀ (x : V), ¬adj x x = true
adj' : V → V → Bool
property✝ : (∀ (x y : V), adj' x y = adj' y x) ∧ ∀ (x : V), ¬adj' x x = true
h : (fun v w => adj v w = true) = fun v w => adj' v w = true
v w : V
⊢ adj v w = adj' v w

Next tactic:
simpa [Bool.coe_iff_coe] using congr_fun₂ h v w
/-- We can enumerate simple graphs by enumerating all functions `V → V → Bool`
and filtering on whether they are symmetric and irreflexive. -/
instance {V : Type u} [Fintype V] [DecidableEq V] : Fintype (SimpleGraph V) where
  elems := Finset.univ.map SimpleGraph.mk'
  complete := by
    

Proof state:
V : Type u
inst✝¹ : Fintype V
inst✝ : DecidableEq V
⊢ ∀ (x : SimpleGraph V), x ∈ map SimpleGraph.mk' univ

Next tactic:
classical
    rintro ⟨Adj, hs, hi⟩
    simp only [mem_map, mem_univ, true_and, Subtype.exists, Bool.not_eq_true]
    refine ⟨fun v w ↦ Adj v w, ⟨?_, ?_⟩, ?_⟩
    · simp [hs.iff]
    · intro v; simp [hi v]
    · ext
      simp
/-- We can enumerate simple graphs by enumerating all functions `V → V → Bool`
and filtering on whether they are symmetric and irreflexive. -/
instance {V : Type u} [Fintype V] [DecidableEq V] : Fintype (SimpleGraph V) where
  elems := Finset.univ.map SimpleGraph.mk'
  complete := by
    classical
    

Proof state:
V : Type u
inst✝¹ : Fintype V
inst✝ : DecidableEq V
⊢ ∀ (x : SimpleGraph V), x ∈ map SimpleGraph.mk' univ

Next tactic:
rintro ⟨Adj, hs, hi⟩
/-- We can enumerate simple graphs by enumerating all functions `V → V → Bool`
and filtering on whether they are symmetric and irreflexive. -/
instance {V : Type u} [Fintype V] [DecidableEq V] : Fintype (SimpleGraph V) where
  elems := Finset.univ.map SimpleGraph.mk'
  complete := by
    classical
    rintro ⟨Adj, hs, hi⟩
    

Proof state:
case mk
V : Type u
inst✝¹ : Fintype V
inst✝ : DecidableEq V
Adj : V → V → Prop
hs : Symmetric Adj
hi : Irreflexive Adj
⊢ SimpleGraph.mk Adj ∈ map SimpleGraph.mk' univ

Next tactic:
simp only [mem_map, mem_univ, true_and, Subtype.exists, Bool.not_eq_true]
/-- We can enumerate simple graphs by enumerating all functions `V → V → Bool`
and filtering on whether they are symmetric and irreflexive. -/
instance {V : Type u} [Fintype V] [DecidableEq V] : Fintype (SimpleGraph V) where
  elems := Finset.univ.map SimpleGraph.mk'
  complete := by
    classical
    rintro ⟨Adj, hs, hi⟩
    simp only [mem_map, mem_univ, true_and, Subtype.exists, Bool.not_eq_true]
    

Proof state:
case mk
V : Type u
inst✝¹ : Fintype V
inst✝ : DecidableEq V
Adj : V → V → Prop
hs : Symmetric Adj
hi : Irreflexive Adj
⊢ ∃ a,
    ∃ (h : (∀ (x y : V), a x y = a y x) ∧ ∀ (x : V), a x x = false),
      SimpleGraph.mk' { val := a, property := (_ : (∀ (x y : V), a x y = a y x) ∧ ∀ (x : V), ¬a x x = true) } =
        SimpleGraph.mk Adj

Next tactic:
refine ⟨fun v w ↦ Adj v w, ⟨?_, ?_⟩, ?_⟩
/-- We can enumerate simple graphs by enumerating all functions `V → V → Bool`
and filtering on whether they are symmetric and irreflexive. -/
instance {V : Type u} [Fintype V] [DecidableEq V] : Fintype (SimpleGraph V) where
  elems := Finset.univ.map SimpleGraph.mk'
  complete := by
    classical
    rintro ⟨Adj, hs, hi⟩
    simp only [mem_map, mem_univ, true_and, Subtype.exists, Bool.not_eq_true]
    refine ⟨fun v w ↦ Adj v w, ⟨?_, ?_⟩, ?_⟩
    · 

Proof state:
case mk.refine_1
V : Type u
inst✝¹ : Fintype V
inst✝ : DecidableEq V
Adj : V → V → Prop
hs : Symmetric Adj
hi : Irreflexive Adj
⊢ ∀ (x y : V), (fun v w => decide (Adj v w)) x y = (fun v w => decide (Adj v w)) y x

Next tactic:
simp [hs.iff]
/-- We can enumerate simple graphs by enumerating all functions `V → V → Bool`
and filtering on whether they are symmetric and irreflexive. -/
instance {V : Type u} [Fintype V] [DecidableEq V] : Fintype (SimpleGraph V) where
  elems := Finset.univ.map SimpleGraph.mk'
  complete := by
    classical
    rintro ⟨Adj, hs, hi⟩
    simp only [mem_map, mem_univ, true_and, Subtype.exists, Bool.not_eq_true]
    refine ⟨fun v w ↦ Adj v w, ⟨?_, ?_⟩, ?_⟩
    · simp [hs.iff]
    · 

Proof state:
case mk.refine_2
V : Type u
inst✝¹ : Fintype V
inst✝ : DecidableEq V
Adj : V → V → Prop
hs : Symmetric Adj
hi : Irreflexive Adj
⊢ ∀ (x : V), (fun v w => decide (Adj v w)) x x = false

Next tactic:
intro v
/-- We can enumerate simple graphs by enumerating all functions `V → V → Bool`
and filtering on whether they are symmetric and irreflexive. -/
instance {V : Type u} [Fintype V] [DecidableEq V] : Fintype (SimpleGraph V) where
  elems := Finset.univ.map SimpleGraph.mk'
  complete := by
    classical
    rintro ⟨Adj, hs, hi⟩
    simp only [mem_map, mem_univ, true_and, Subtype.exists, Bool.not_eq_true]
    refine ⟨fun v w ↦ Adj v w, ⟨?_, ?_⟩, ?_⟩
    · simp [hs.iff]
    · intro v; 

Proof state:
case mk.refine_2
V : Type u
inst✝¹ : Fintype V
inst✝ : DecidableEq V
Adj : V → V → Prop
hs : Symmetric Adj
hi : Irreflexive Adj
v : V
⊢ (fun v w => decide (Adj v w)) v v = false

Next tactic:
simp [hi v]
/-- We can enumerate simple graphs by enumerating all functions `V → V → Bool`
and filtering on whether they are symmetric and irreflexive. -/
instance {V : Type u} [Fintype V] [DecidableEq V] : Fintype (SimpleGraph V) where
  elems := Finset.univ.map SimpleGraph.mk'
  complete := by
    classical
    rintro ⟨Adj, hs, hi⟩
    simp only [mem_map, mem_univ, true_and, Subtype.exists, Bool.not_eq_true]
    refine ⟨fun v w ↦ Adj v w, ⟨?_, ?_⟩, ?_⟩
    · simp [hs.iff]
    · intro v; simp [hi v]
    · 

Proof state:
case mk.refine_3
V : Type u
inst✝¹ : Fintype V
inst✝ : DecidableEq V
Adj : V → V → Prop
hs : Symmetric Adj
hi : Irreflexive Adj
⊢ SimpleGraph.mk'
      { val := fun v w => decide (Adj v w),
        property :=
          (_ :
            (∀ (x y : V), (fun v w => decide (Adj v w)) x y = (fun v w => decide (Adj v w)) y x) ∧
              ∀ (x : V), ¬(fun v w => decide (Adj v w)) x x = true) } =
    SimpleGraph.mk Adj

Next tactic:
ext
/-- We can enumerate simple graphs by enumerating all functions `V → V → Bool`
and filtering on whether they are symmetric and irreflexive. -/
instance {V : Type u} [Fintype V] [DecidableEq V] : Fintype (SimpleGraph V) where
  elems := Finset.univ.map SimpleGraph.mk'
  complete := by
    classical
    rintro ⟨Adj, hs, hi⟩
    simp only [mem_map, mem_univ, true_and, Subtype.exists, Bool.not_eq_true]
    refine ⟨fun v w ↦ Adj v w, ⟨?_, ?_⟩, ?_⟩
    · simp [hs.iff]
    · intro v; simp [hi v]
    · ext
      

Proof state:
case mk.refine_3.Adj.h.h.a
V : Type u
inst✝¹ : Fintype V
inst✝ : DecidableEq V
Adj : V → V → Prop
hs : Symmetric Adj
hi : Irreflexive Adj
x✝¹ x✝ : V
⊢ SimpleGraph.Adj
      (SimpleGraph.mk'
        { val := fun v w => decide (Adj v w),
          property :=
            (_ :
              (∀ (x y : V), (fun v w => decide (Adj v w)) x y = (fun v w => decide (Adj v w)) y x) ∧
                ∀ (x : V), ¬(fun v w => decide (Adj v w)) x x = true) })
      x✝¹ x✝ ↔
    SimpleGraph.Adj (SimpleGraph.mk Adj) x✝¹ x✝

Next tactic:
simp
/-- Two vertices are adjacent in the complete bipartite graph on two vertex types
if and only if they are not from the same side.
Any bipartite graph may be regarded as a subgraph of one of these. -/
@[simps]
def completeBipartiteGraph (V W : Type*) : SimpleGraph (Sum V W) where
  Adj v w := v.isLeft ∧ w.isRight ∨ v.isRight ∧ w.isLeft
  symm v w := by 

Proof state:
V : Type u_1
W : Type u_2
v w : V ⊕ W
⊢ (fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) v w →
    (fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) w v

Next tactic:
cases v
/-- Two vertices are adjacent in the complete bipartite graph on two vertex types
if and only if they are not from the same side.
Any bipartite graph may be regarded as a subgraph of one of these. -/
@[simps]
def completeBipartiteGraph (V W : Type*) : SimpleGraph (Sum V W) where
  Adj v w := v.isLeft ∧ w.isRight ∨ v.isRight ∧ w.isLeft
  symm v w := by cases v <;> 

Proof state:
case inl
V : Type u_1
W : Type u_2
w : V ⊕ W
val✝ : V
⊢ (fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) (Sum.inl val✝)
      w →
    (fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) w
      (Sum.inl val✝)

Next tactic:
cases w
/-- Two vertices are adjacent in the complete bipartite graph on two vertex types
if and only if they are not from the same side.
Any bipartite graph may be regarded as a subgraph of one of these. -/
@[simps]
def completeBipartiteGraph (V W : Type*) : SimpleGraph (Sum V W) where
  Adj v w := v.isLeft ∧ w.isRight ∨ v.isRight ∧ w.isLeft
  symm v w := by cases v <;> 

Proof state:
case inr
V : Type u_1
W : Type u_2
w : V ⊕ W
val✝ : W
⊢ (fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) (Sum.inr val✝)
      w →
    (fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) w
      (Sum.inr val✝)

Next tactic:
cases w
/-- Two vertices are adjacent in the complete bipartite graph on two vertex types
if and only if they are not from the same side.
Any bipartite graph may be regarded as a subgraph of one of these. -/
@[simps]
def completeBipartiteGraph (V W : Type*) : SimpleGraph (Sum V W) where
  Adj v w := v.isLeft ∧ w.isRight ∨ v.isRight ∧ w.isLeft
  symm v w := by cases v <;> cases w <;> 

Proof state:
case inl.inl
V : Type u_1
W : Type u_2
val✝¹ val✝ : V
⊢ (fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) (Sum.inl val✝¹)
      (Sum.inl val✝) →
    (fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) (Sum.inl val✝)
      (Sum.inl val✝¹)

Next tactic:
simp
/-- Two vertices are adjacent in the complete bipartite graph on two vertex types
if and only if they are not from the same side.
Any bipartite graph may be regarded as a subgraph of one of these. -/
@[simps]
def completeBipartiteGraph (V W : Type*) : SimpleGraph (Sum V W) where
  Adj v w := v.isLeft ∧ w.isRight ∨ v.isRight ∧ w.isLeft
  symm v w := by cases v <;> cases w <;> 

Proof state:
case inl.inr
V : Type u_1
W : Type u_2
val✝¹ : V
val✝ : W
⊢ (fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) (Sum.inl val✝¹)
      (Sum.inr val✝) →
    (fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) (Sum.inr val✝)
      (Sum.inl val✝¹)

Next tactic:
simp
/-- Two vertices are adjacent in the complete bipartite graph on two vertex types
if and only if they are not from the same side.
Any bipartite graph may be regarded as a subgraph of one of these. -/
@[simps]
def completeBipartiteGraph (V W : Type*) : SimpleGraph (Sum V W) where
  Adj v w := v.isLeft ∧ w.isRight ∨ v.isRight ∧ w.isLeft
  symm v w := by cases v <;> cases w <;> 

Proof state:
case inr.inl
V : Type u_1
W : Type u_2
val✝¹ : W
val✝ : V
⊢ (fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) (Sum.inr val✝¹)
      (Sum.inl val✝) →
    (fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) (Sum.inl val✝)
      (Sum.inr val✝¹)

Next tactic:
simp
/-- Two vertices are adjacent in the complete bipartite graph on two vertex types
if and only if they are not from the same side.
Any bipartite graph may be regarded as a subgraph of one of these. -/
@[simps]
def completeBipartiteGraph (V W : Type*) : SimpleGraph (Sum V W) where
  Adj v w := v.isLeft ∧ w.isRight ∨ v.isRight ∧ w.isLeft
  symm v w := by cases v <;> cases w <;> 

Proof state:
case inr.inr
V : Type u_1
W : Type u_2
val✝¹ val✝ : W
⊢ (fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) (Sum.inr val✝¹)
      (Sum.inr val✝) →
    (fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) (Sum.inr val✝)
      (Sum.inr val✝¹)

Next tactic:
simp
/-- Two vertices are adjacent in the complete bipartite graph on two vertex types
if and only if they are not from the same side.
Any bipartite graph may be regarded as a subgraph of one of these. -/
@[simps]
def completeBipartiteGraph (V W : Type*) : SimpleGraph (Sum V W) where
  Adj v w := v.isLeft ∧ w.isRight ∨ v.isRight ∧ w.isLeft
  symm v w := by cases v <;> cases w <;> simp
  loopless v := by 

Proof state:
V : Type u_1
W : Type u_2
v : V ⊕ W
⊢ ¬(fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) v v

Next tactic:
cases v
/-- Two vertices are adjacent in the complete bipartite graph on two vertex types
if and only if they are not from the same side.
Any bipartite graph may be regarded as a subgraph of one of these. -/
@[simps]
def completeBipartiteGraph (V W : Type*) : SimpleGraph (Sum V W) where
  Adj v w := v.isLeft ∧ w.isRight ∨ v.isRight ∧ w.isLeft
  symm v w := by cases v <;> cases w <;> simp
  loopless v := by cases v <;> 

Proof state:
case inl
V : Type u_1
W : Type u_2
val✝ : V
⊢ ¬(fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) (Sum.inl val✝)
      (Sum.inl val✝)

Next tactic:
simp
/-- Two vertices are adjacent in the complete bipartite graph on two vertex types
if and only if they are not from the same side.
Any bipartite graph may be regarded as a subgraph of one of these. -/
@[simps]
def completeBipartiteGraph (V W : Type*) : SimpleGraph (Sum V W) where
  Adj v w := v.isLeft ∧ w.isRight ∨ v.isRight ∧ w.isLeft
  symm v w := by cases v <;> cases w <;> simp
  loopless v := by cases v <;> 

Proof state:
case inr
V : Type u_1
W : Type u_2
val✝ : W
⊢ ¬(fun v w => Sum.isLeft v = true ∧ Sum.isRight w = true ∨ Sum.isRight v = true ∧ Sum.isLeft w = true) (Sum.inr val✝)
      (Sum.inr val✝)

Next tactic:
simp
theorem ne_of_adj (h : G.Adj a b) : a ≠ b := 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 : Adj G a b
⊢ a ≠ b

Next tactic:
rintro rfl
theorem ne_of_adj (h : G.Adj a b) : a ≠ b := by
  rintro rfl
  

Proof state:
ι : Sort u_1
𝕜 : Type u_2
V : Type u
W : Type v
X : Type w
G : SimpleGraph V
G' : SimpleGraph W
a c u v w : V
e : Sym2 V
h : Adj G a a
⊢ False

Next tactic:
exact G.irrefl h
/-- The supremum of two graphs `x ⊔ y` has edges where either `x` or `y` have edges. -/
instance : Sup (SimpleGraph V) where
  sup x y :=
    { Adj := x.Adj ⊔ y.Adj
      symm := fun v w h => 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
x y : SimpleGraph V
v w : V
h : (x.Adj ⊔ y.Adj) v w
⊢ (x.Adj ⊔ y.Adj) w v

Next tactic:
rwa [Pi.sup_apply, Pi.sup_apply, x.adj_comm, y.adj_comm]
/-- The infimum of two graphs `x ⊓ y` has edges where both `x` and `y` have edges. -/
instance : Inf (SimpleGraph V) where
  inf x y :=
    { Adj := x.Adj ⊓ y.Adj
      symm := fun v w h => 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
x y : SimpleGraph V
v w : V
h : (x.Adj ⊓ y.Adj) v w
⊢ (x.Adj ⊓ y.Adj) w v

Next tactic:
rwa [Pi.inf_apply, Pi.inf_apply, x.adj_comm, y.adj_comm]
/-- We define `Gᶜ` to be the `SimpleGraph V` such that no two adjacent vertices in `G`
are adjacent in the complement, and every nonadjacent pair of vertices is adjacent
(still ensuring that vertices are not adjacent to themselves). -/
instance hasCompl : HasCompl (SimpleGraph V) where
  compl G :=
    { Adj := fun v w => v ≠ w ∧ ¬G.Adj v w
      symm := fun v w ⟨hne, _⟩ => ⟨hne.symm, 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 V
v w : V
x✝ : (fun v w => v ≠ w ∧ ¬Adj G v w) v w
hne : v ≠ w
right✝ : ¬Adj G v w
⊢ ¬Adj G w v

Next tactic:
rwa [adj_comm]
/-- The difference of two graphs `x \ y` has the edges of `x` with the edges of `y` removed. -/
instance sdiff : SDiff (SimpleGraph V) where
  sdiff x y :=
    { Adj := x.Adj \ y.Adj
      symm := fun v w h => 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
x y : SimpleGraph V
v w : V
h : (x.Adj \ y.Adj) v w
⊢ (x.Adj \ y.Adj) w v

Next tactic:
change x.Adj w v ∧ ¬y.Adj w v
/-- The difference of two graphs `x \ y` has the edges of `x` with the edges of `y` removed. -/
instance sdiff : SDiff (SimpleGraph V) where
  sdiff x y :=
    { Adj := x.Adj \ y.Adj
      symm := fun v w h => by change x.Adj w v ∧ ¬y.Adj w v; 

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
x y : SimpleGraph V
v w : V
h : (x.Adj \ y.Adj) v w
⊢ Adj x w v ∧ ¬Adj y w v

Next tactic:
rwa [x.adj_comm, y.adj_comm]
instance supSet : SupSet (SimpleGraph V) where
  sSup s :=
    { Adj := fun a b => ∃ G ∈ s, Adj G a b
      symm := fun a b => Exists.imp $ fun _ => And.imp_right Adj.symm
      loopless := 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
s : Set (SimpleGraph V)
⊢ Irreflexive fun a b => ∃ G ∈ s, Adj G a b

Next tactic:
rintro a ⟨G, _, ha⟩
instance supSet : SupSet (SimpleGraph V) where
  sSup s :=
    { Adj := fun a b => ∃ G ∈ s, Adj G a b
      symm := fun a b => Exists.imp $ fun _ => And.imp_right Adj.symm
      loopless := by
        rintro a ⟨G, _, ha⟩
        

Proof state:
case intro.intro
ι : 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
s : Set (SimpleGraph V)
a : V
G : SimpleGraph V
left✝ : G ∈ s
ha : Adj G a a
⊢ False

Next tactic:
exact ha.ne rfl
@[simp]
theorem iSup_adj {f : ι → SimpleGraph V} : (⨆ i, f i).Adj a b ↔ ∃ i, (f i).Adj a b := 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
f : ι → SimpleGraph V
⊢ Adj (⨆ i, f i) a b ↔ ∃ i, Adj (f i) a b

Next tactic:
simp [iSup]
@[simp]
theorem iInf_adj {f : ι → SimpleGraph V} : (⨅ i, f i).Adj a b ↔ (∀ i, (f i).Adj a b) ∧ a ≠ b := 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
f : ι → SimpleGraph V
⊢ Adj (⨅ i, f i) a b ↔ (∀ (i : ι), Adj (f i) a b) ∧ a ≠ b

Next tactic:
simp [iInf]
theorem sInf_adj_of_nonempty {s : Set (SimpleGraph V)} (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
𝕜 : 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
s : Set (SimpleGraph V)
hs : Set.Nonempty s
⊢ (∀ G ∈ s, Adj G a b) → a ≠ b

Next tactic:
obtain ⟨G, hG⟩ := hs
theorem sInf_adj_of_nonempty {s : Set (SimpleGraph V)} (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
𝕜 : 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
s : Set (SimpleGraph V)
G : SimpleGraph V
hG : G ∈ s
⊢ (∀ G ∈ s, Adj G a b) → a ≠ b

Next tactic:
exact fun h => (h _ hG).ne
theorem iInf_adj_of_nonempty [Nonempty ι] {f : ι → SimpleGraph V} :
    (⨅ i, f i).Adj a b ↔ ∀ i, (f i).Adj a b := 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✝ : Nonempty ι
f : ι → SimpleGraph V
⊢ Adj (⨅ i, f i) a b ↔ ∀ (i : ι), Adj (f i) a b

Next tactic:
rw [iInf, sInf_adj_of_nonempty (Set.range_nonempty _), Set.forall_range_iff]
instance completeAtomicBooleanAlgebra : CompleteAtomicBooleanAlgebra (SimpleGraph V) :=
  { SimpleGraph.distribLattice with
    le := (· ≤ ·)
    sup := (· ⊔ ·)
    inf := (· ⊓ ·)
    compl := HasCompl.compl
    sdiff := (· \ ·)
    top := completeGraph V
    bot := emptyGraph V
    le_top := fun x v w h => x.ne_of_adj h
    bot_le := fun x v w h => h.elim
    sdiff_eq := fun x y => by
      ext v w
      refine' ⟨fun h => ⟨h.1, ⟨_, h.2⟩⟩, fun h => ⟨h.1, h.2.2⟩⟩
      rintro rfl
      exact x.irrefl h.1
    inf_compl_le_bot := fun G v w h => False.elim <| h.2.2 h.1
    top_le_sup_compl := fun G v w hvw => by
      by_cases h : G.Adj v w
      · exact Or.inl h
      · exact Or.inr ⟨hvw, h⟩
    sSup := sSup
    le_sSup := fun s G hG a b hab => ⟨G, hG, hab⟩
    sSup_le := fun s G hG a b => 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
src✝ : DistribLattice (SimpleGraph V) := distribLattice
s : Set (SimpleGraph V)
G : SimpleGraph V
hG : ∀ b ∈ s, b ≤ G
a b : V
⊢ Adj (sSup s) a b → Adj G a b

Next tactic:
rintro ⟨H, hH, hab⟩
instance completeAtomicBooleanAlgebra : CompleteAtomicBooleanAlgebra (SimpleGraph V) :=
  { SimpleGraph.distribLattice with
    le := (· ≤ ·)
    sup := (· ⊔ ·)
    inf := (· ⊓ ·)
    compl := HasCompl.compl
    sdiff := (· \ ·)
    top := completeGraph V
    bot := emptyGraph V
    le_top := fun x v w h => x.ne_of_adj h
    bot_le := fun x v w h => h.elim
    sdiff_eq := fun x y => by
      ext v w
      refine' ⟨fun h => ⟨h.1, ⟨_, h.2⟩⟩, fun h => ⟨h.1, h.2.2⟩⟩
      rintro rfl
      exact x.irrefl h.1
    inf_compl_le_bot := fun G v w h => False.elim <| h.2.2 h.1
    top_le_sup_compl := fun G v w hvw => by
      by_cases h : G.Adj v w
      · exact Or.inl h
      · exact Or.inr ⟨hvw, h⟩
    sSup := sSup
    le_sSup := fun s G hG a b hab => ⟨G, hG, hab⟩
    sSup_le := fun s G hG a b => by
      rintro ⟨H, hH, hab⟩
      

Proof state:
case intro.intro
ι : 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
src✝ : DistribLattice (SimpleGraph V) := distribLattice
s : Set (SimpleGraph V)
G : SimpleGraph V
hG : ∀ b ∈ s, b ≤ G
a b : V
H : SimpleGraph V
hH : H ∈ s
hab : Adj H a b
⊢ Adj G a b

Next tactic:
exact hG _ hH hab