l3lab/ntp-mathlib huggingface dataset:
theorem nonuniformWitness_spec (h₁ : s ≠ t) (h₂ : ¬G.IsUniform ε s t) : ε ≤ |G.edgeDensity
    (G.nonuniformWitness ε s t) (G.nonuniformWitness ε t s) - G.edgeDensity s t| := by
  unfold nonuniformWitness
  rcases trichotomous_of WellOrderingRel s t with (lt | rfl | gt)
  · 

Proof state:
case inl
α : Type u_1
𝕜 : Type u_2
inst✝¹ : LinearOrderedField 𝕜
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
s t : Finset α
a b : α
h₁ : s ≠ t
h₂ : ¬IsUniform G ε s t
lt : WellOrderingRel s t
⊢ ε ≤
    ↑|edgeDensity G (if WellOrderingRel s t then (nonuniformWitnesses G ε s t).1 else (nonuniformWitnesses G ε t s).2)
            (if WellOrderingRel t s then (nonuniformWitnesses G ε t s).1 else (nonuniformWitnesses G ε s t).2) -
          edgeDensity G s t|

Next tactic:
rw [if_pos lt, if_neg (asymm lt)]
theorem nonuniformWitness_spec (h₁ : s ≠ t) (h₂ : ¬G.IsUniform ε s t) : ε ≤ |G.edgeDensity
    (G.nonuniformWitness ε s t) (G.nonuniformWitness ε t s) - G.edgeDensity s t| := by
  unfold nonuniformWitness
  rcases trichotomous_of WellOrderingRel s t with (lt | rfl | gt)
  · rw [if_pos lt, if_neg (asymm lt)]
    

Proof state:
case inl
α : Type u_1
𝕜 : Type u_2
inst✝¹ : LinearOrderedField 𝕜
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
s t : Finset α
a b : α
h₁ : s ≠ t
h₂ : ¬IsUniform G ε s t
lt : WellOrderingRel s t
⊢ ε ≤ ↑|edgeDensity G (nonuniformWitnesses G ε s t).1 (nonuniformWitnesses G ε s t).2 - edgeDensity G s t|

Next tactic:
exact G.nonuniformWitnesses_spec h₂
theorem nonuniformWitness_spec (h₁ : s ≠ t) (h₂ : ¬G.IsUniform ε s t) : ε ≤ |G.edgeDensity
    (G.nonuniformWitness ε s t) (G.nonuniformWitness ε t s) - G.edgeDensity s t| := by
  unfold nonuniformWitness
  rcases trichotomous_of WellOrderingRel s t with (lt | rfl | gt)
  · rw [if_pos lt, if_neg (asymm lt)]
    exact G.nonuniformWitnesses_spec h₂
  · 

Proof state:
case inr.inl
α : Type u_1
𝕜 : Type u_2
inst✝¹ : LinearOrderedField 𝕜
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
s : Finset α
a b : α
h₁ : s ≠ s
h₂ : ¬IsUniform G ε s s
⊢ ε ≤
    ↑|edgeDensity G (if WellOrderingRel s s then (nonuniformWitnesses G ε s s).1 else (nonuniformWitnesses G ε s s).2)
            (if WellOrderingRel s s then (nonuniformWitnesses G ε s s).1 else (nonuniformWitnesses G ε s s).2) -
          edgeDensity G s s|

Next tactic:
cases h₁ rfl
theorem nonuniformWitness_spec (h₁ : s ≠ t) (h₂ : ¬G.IsUniform ε s t) : ε ≤ |G.edgeDensity
    (G.nonuniformWitness ε s t) (G.nonuniformWitness ε t s) - G.edgeDensity s t| := by
  unfold nonuniformWitness
  rcases trichotomous_of WellOrderingRel s t with (lt | rfl | gt)
  · rw [if_pos lt, if_neg (asymm lt)]
    exact G.nonuniformWitnesses_spec h₂
  · cases h₁ rfl
  · 

Proof state:
case inr.inr
α : Type u_1
𝕜 : Type u_2
inst✝¹ : LinearOrderedField 𝕜
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
s t : Finset α
a b : α
h₁ : s ≠ t
h₂ : ¬IsUniform G ε s t
gt : WellOrderingRel t s
⊢ ε ≤
    ↑|edgeDensity G (if WellOrderingRel s t then (nonuniformWitnesses G ε s t).1 else (nonuniformWitnesses G ε t s).2)
            (if WellOrderingRel t s then (nonuniformWitnesses G ε t s).1 else (nonuniformWitnesses G ε s t).2) -
          edgeDensity G s t|

Next tactic:
rw [if_neg (asymm gt), if_pos gt, edgeDensity_comm, edgeDensity_comm _ s]
theorem nonuniformWitness_spec (h₁ : s ≠ t) (h₂ : ¬G.IsUniform ε s t) : ε ≤ |G.edgeDensity
    (G.nonuniformWitness ε s t) (G.nonuniformWitness ε t s) - G.edgeDensity s t| := by
  unfold nonuniformWitness
  rcases trichotomous_of WellOrderingRel s t with (lt | rfl | gt)
  · rw [if_pos lt, if_neg (asymm lt)]
    exact G.nonuniformWitnesses_spec h₂
  · cases h₁ rfl
  · rw [if_neg (asymm gt), if_pos gt, edgeDensity_comm, edgeDensity_comm _ s]
    

Proof state:
case inr.inr
α : Type u_1
𝕜 : Type u_2
inst✝¹ : LinearOrderedField 𝕜
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
s t : Finset α
a b : α
h₁ : s ≠ t
h₂ : ¬IsUniform G ε s t
gt : WellOrderingRel t s
⊢ ε ≤ ↑|edgeDensity G (nonuniformWitnesses G ε t s).1 (nonuniformWitnesses G ε t s).2 - edgeDensity G t s|

Next tactic:
apply G.nonuniformWitnesses_spec fun i => h₂ i.symm
theorem mk_mem_nonUniforms_iff (u v : Finset α) (ε : 𝕜) :
    (u, v) ∈ P.nonUniforms G ε ↔ u ∈ P.parts ∧ v ∈ P.parts ∧ u ≠ v ∧ ¬G.IsUniform ε u v := by
  

Proof state:
α : Type u_1
𝕜 : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
A : Finset α
P : Finpartition A
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε✝ : 𝕜
u v : Finset α
ε : 𝕜
⊢ (u, v) ∈ nonUniforms P G ε ↔ u ∈ P.parts ∧ v ∈ P.parts ∧ u ≠ v ∧ ¬SimpleGraph.IsUniform G ε u v

Next tactic:
rw [nonUniforms, mem_filter, mem_offDiag, and_assoc, and_assoc]
theorem nonUniforms_bot (hε : 0 < ε) : (⊥ : Finpartition A).nonUniforms G ε = ∅ := by
  

Proof state:
α : Type u_1
𝕜 : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
A : Finset α
P : Finpartition A
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
hε : 0 < ε
⊢ nonUniforms ⊥ G ε = ∅

Next tactic:
rw [eq_empty_iff_forall_not_mem]
theorem nonUniforms_bot (hε : 0 < ε) : (⊥ : Finpartition A).nonUniforms G ε = ∅ := by
  rw [eq_empty_iff_forall_not_mem]
  

Proof state:
α : Type u_1
𝕜 : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
A : Finset α
P : Finpartition A
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
hε : 0 < ε
⊢ ∀ (x : Finset α × Finset α), x ∉ nonUniforms ⊥ G ε

Next tactic:
rintro ⟨u, v⟩
theorem nonUniforms_bot (hε : 0 < ε) : (⊥ : Finpartition A).nonUniforms G ε = ∅ := by
  rw [eq_empty_iff_forall_not_mem]
  rintro ⟨u, v⟩
  

Proof state:
case mk
α : Type u_1
𝕜 : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
A : Finset α
P : Finpartition A
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
hε : 0 < ε
u v : Finset α
⊢ (u, v) ∉ nonUniforms ⊥ G ε

Next tactic:
simp only [Finpartition.mk_mem_nonUniforms_iff, Finpartition.parts_bot, mem_map, not_and,
    Classical.not_not, exists_imp]
theorem nonUniforms_bot (hε : 0 < ε) : (⊥ : Finpartition A).nonUniforms G ε = ∅ := by
  rw [eq_empty_iff_forall_not_mem]
  rintro ⟨u, v⟩
  simp only [Finpartition.mk_mem_nonUniforms_iff, Finpartition.parts_bot, mem_map, not_and,
    Classical.not_not, exists_imp]; 

Proof state:
case mk
α : Type u_1
𝕜 : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
A : Finset α
P : Finpartition A
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
hε : 0 < ε
u v : Finset α
⊢ ∀ (x : α),
    x ∈ A ∧ { toFun := singleton, inj' := (_ : Function.Injective singleton) } x = u →
      ∀ (x : α),
        x ∈ A ∧ { toFun := singleton, inj' := (_ : Function.Injective singleton) } x = v →
          u ≠ v → SimpleGraph.IsUniform G ε u v

Next tactic:
dsimp
theorem nonUniforms_bot (hε : 0 < ε) : (⊥ : Finpartition A).nonUniforms G ε = ∅ := by
  rw [eq_empty_iff_forall_not_mem]
  rintro ⟨u, v⟩
  simp only [Finpartition.mk_mem_nonUniforms_iff, Finpartition.parts_bot, mem_map, not_and,
    Classical.not_not, exists_imp]; dsimp
  

Proof state:
case mk
α : Type u_1
𝕜 : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
A : Finset α
P : Finpartition A
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
hε : 0 < ε
u v : Finset α
⊢ ∀ (x : α), x ∈ A ∧ {x} = u → ∀ (x : α), x ∈ A ∧ {x} = v → ¬u = v → SimpleGraph.IsUniform G ε u v

Next tactic:
rintro x ⟨_,xu⟩ y ⟨_,yv⟩ _
theorem nonUniforms_bot (hε : 0 < ε) : (⊥ : Finpartition A).nonUniforms G ε = ∅ := by
  rw [eq_empty_iff_forall_not_mem]
  rintro ⟨u, v⟩
  simp only [Finpartition.mk_mem_nonUniforms_iff, Finpartition.parts_bot, mem_map, not_and,
    Classical.not_not, exists_imp]; dsimp
  rintro x ⟨_,xu⟩ y ⟨_,yv⟩ _
  

Proof state:
case mk.intro.intro
α : Type u_1
𝕜 : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
A : Finset α
P : Finpartition A
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
hε : 0 < ε
u v : Finset α
x : α
left✝¹ : x ∈ A
xu : {x} = u
y : α
left✝ : y ∈ A
yv : {y} = v
a✝ : ¬u = v
⊢ SimpleGraph.IsUniform G ε u v

Next tactic:
rw [← xu, ← yv]
theorem nonUniforms_bot (hε : 0 < ε) : (⊥ : Finpartition A).nonUniforms G ε = ∅ := by
  rw [eq_empty_iff_forall_not_mem]
  rintro ⟨u, v⟩
  simp only [Finpartition.mk_mem_nonUniforms_iff, Finpartition.parts_bot, mem_map, not_and,
    Classical.not_not, exists_imp]; dsimp
  rintro x ⟨_,xu⟩ y ⟨_,yv⟩ _
  rw [← xu, ← yv]
  

Proof state:
case mk.intro.intro
α : Type u_1
𝕜 : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
A : Finset α
P : Finpartition A
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
hε : 0 < ε
u v : Finset α
x : α
left✝¹ : x ∈ A
xu : {x} = u
y : α
left✝ : y ∈ A
yv : {y} = v
a✝ : ¬u = v
⊢ SimpleGraph.IsUniform G ε {x} {y}

Next tactic:
exact G.isUniform_singleton hε
theorem botIsUniform (hε : 0 < ε) : (⊥ : Finpartition A).IsUniform G ε := by
  

Proof state:
α : Type u_1
𝕜 : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
A : Finset α
P : Finpartition A
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
hε : 0 < ε
⊢ IsUniform ⊥ G ε

Next tactic:
rw [Finpartition.IsUniform, Finpartition.card_bot, nonUniforms_bot _ hε, Finset.card_empty,
    Nat.cast_zero]
theorem botIsUniform (hε : 0 < ε) : (⊥ : Finpartition A).IsUniform G ε := by
  rw [Finpartition.IsUniform, Finpartition.card_bot, nonUniforms_bot _ hε, Finset.card_empty,
    Nat.cast_zero]
  

Proof state:
α : Type u_1
𝕜 : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
A : Finset α
P : Finpartition A
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
hε : 0 < ε
⊢ 0 ≤ ↑(card A * (card A - 1)) * ε

Next tactic:
exact mul_nonneg (Nat.cast_nonneg _) hε.le
theorem isUniformOne : P.IsUniform G (1 : 𝕜) := by
  

Proof state:
α : Type u_1
𝕜 : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
A : Finset α
P : Finpartition A
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
⊢ IsUniform P G 1

Next tactic:
rw [IsUniform, mul_one, Nat.cast_le]
theorem isUniformOne : P.IsUniform G (1 : 𝕜) := by
  rw [IsUniform, mul_one, Nat.cast_le]
  

Proof state:
α : Type u_1
𝕜 : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
A : Finset α
P : Finpartition A
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
⊢ card (nonUniforms P G 1) ≤ card P.parts * (card P.parts - 1)

Next tactic:
refine' (card_filter_le _
    (fun uv => ¬SimpleGraph.IsUniform G 1 (Prod.fst uv) (Prod.snd uv))).trans _
theorem isUniformOne : P.IsUniform G (1 : 𝕜) := by
  rw [IsUniform, mul_one, Nat.cast_le]
  refine' (card_filter_le _
    (fun uv => ¬SimpleGraph.IsUniform G 1 (Prod.fst uv) (Prod.snd uv))).trans _
  

Proof state:
α : Type u_1
𝕜 : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
A : Finset α
P : Finpartition A
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
⊢ card (offDiag P.parts) ≤ card P.parts * (card P.parts - 1)

Next tactic:
rw [offDiag_card, Nat.mul_sub_left_distrib, mul_one]
theorem IsUniform.mono {ε ε' : 𝕜} (hP : P.IsUniform G ε) (h : ε ≤ ε') : P.IsUniform G ε' :=
  ((Nat.cast_le.2 <| card_le_of_subset <| P.nonUniforms_mono G h).trans hP).trans <| by 

Proof state:
α : Type u_1
𝕜 : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
A : Finset α
P : Finpartition A
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε✝ ε ε' : 𝕜
hP : IsUniform P G ε
h : ε ≤ ε'
⊢ ↑(card P.parts * (card P.parts - 1)) * ε ≤ ↑(card P.parts * (card P.parts - 1)) * ε'

Next tactic:
gcongr
theorem isUniformOfEmpty (hP : P.parts = ∅) : P.IsUniform G ε := by
  

Proof state:
α : Type u_1
𝕜 : Type u_2
inst✝² : LinearOrderedField 𝕜
inst✝¹ : DecidableEq α
A : Finset α
P : Finpartition A
G : SimpleGraph α
inst✝ : DecidableRel G.Adj
ε : 𝕜
hP : P.parts = ∅
⊢ IsUniform P G ε

Next tactic:
simp [IsUniform, hP, nonUniforms]
/-- A clique is a set of vertices whose induced graph is complete. -/
theorem isClique_iff_induce_eq : G.IsClique s ↔ G.induce s = ⊤ := by
  

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s t : Set α
⊢ IsClique G s ↔ induce s G = ⊤

Next tactic:
rw [isClique_iff]
/-- A clique is a set of vertices whose induced graph is complete. -/
theorem isClique_iff_induce_eq : G.IsClique s ↔ G.induce s = ⊤ := by
  rw [isClique_iff]
  

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s t : Set α
⊢ Set.Pairwise s G.Adj ↔ induce s G = ⊤

Next tactic:
constructor
/-- A clique is a set of vertices whose induced graph is complete. -/
theorem isClique_iff_induce_eq : G.IsClique s ↔ G.induce s = ⊤ := by
  rw [isClique_iff]
  constructor
  · 

Proof state:
case mp
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s t : Set α
⊢ Set.Pairwise s G.Adj → induce s G = ⊤

Next tactic:
intro h
/-- A clique is a set of vertices whose induced graph is complete. -/
theorem isClique_iff_induce_eq : G.IsClique s ↔ G.induce s = ⊤ := by
  rw [isClique_iff]
  constructor
  · intro h
    

Proof state:
case mp
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s t : Set α
h : Set.Pairwise s G.Adj
⊢ induce s G = ⊤

Next tactic:
ext ⟨v, hv⟩ ⟨w, hw⟩
/-- A clique is a set of vertices whose induced graph is complete. -/
theorem isClique_iff_induce_eq : G.IsClique s ↔ G.induce s = ⊤ := by
  rw [isClique_iff]
  constructor
  · intro h
    ext ⟨v, hv⟩ ⟨w, hw⟩
    

Proof state:
case mp.Adj.h.mk.h.mk.a
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s t : Set α
h : Set.Pairwise s G.Adj
v : α
hv : v ∈ s
w : α
hw : w ∈ s
⊢ Adj (induce s G) { val := v, property := hv } { val := w, property := hw } ↔
    Adj ⊤ { val := v, property := hv } { val := w, property := hw }

Next tactic:
simp only [comap_adj, Subtype.coe_mk, top_adj, Ne.def, Subtype.mk_eq_mk]
/-- A clique is a set of vertices whose induced graph is complete. -/
theorem isClique_iff_induce_eq : G.IsClique s ↔ G.induce s = ⊤ := by
  rw [isClique_iff]
  constructor
  · intro h
    ext ⟨v, hv⟩ ⟨w, hw⟩
    simp only [comap_adj, Subtype.coe_mk, top_adj, Ne.def, Subtype.mk_eq_mk]
    

Proof state:
case mp.Adj.h.mk.h.mk.a
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s t : Set α
h : Set.Pairwise s G.Adj
v : α
hv : v ∈ s
w : α
hw : w ∈ s
⊢ Adj G ((Embedding.subtype fun x => x ∈ s) { val := v, property := hv })
      ((Embedding.subtype fun x => x ∈ s) { val := w, property := hw }) ↔
    ¬v = w

Next tactic:
exact ⟨Adj.ne, h hv hw⟩
/-- A clique is a set of vertices whose induced graph is complete. -/
theorem isClique_iff_induce_eq : G.IsClique s ↔ G.induce s = ⊤ := by
  rw [isClique_iff]
  constructor
  · intro h
    ext ⟨v, hv⟩ ⟨w, hw⟩
    simp only [comap_adj, Subtype.coe_mk, top_adj, Ne.def, Subtype.mk_eq_mk]
    exact ⟨Adj.ne, h hv hw⟩
  · 

Proof state:
case mpr
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s t : Set α
⊢ induce s G = ⊤ → Set.Pairwise s G.Adj

Next tactic:
intro h v hv w hw hne
/-- A clique is a set of vertices whose induced graph is complete. -/
theorem isClique_iff_induce_eq : G.IsClique s ↔ G.induce s = ⊤ := by
  rw [isClique_iff]
  constructor
  · intro h
    ext ⟨v, hv⟩ ⟨w, hw⟩
    simp only [comap_adj, Subtype.coe_mk, top_adj, Ne.def, Subtype.mk_eq_mk]
    exact ⟨Adj.ne, h hv hw⟩
  · intro h v hv w hw hne
    

Proof state:
case mpr
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s t : Set α
h : induce s G = ⊤
v : α
hv : v ∈ s
w : α
hw : w ∈ s
hne : v ≠ w
⊢ Adj G v w

Next tactic:
have h2 : (G.induce s).Adj ⟨v, hv⟩ ⟨w, hw⟩ = _ := rfl
/-- A clique is a set of vertices whose induced graph is complete. -/
theorem isClique_iff_induce_eq : G.IsClique s ↔ G.induce s = ⊤ := by
  rw [isClique_iff]
  constructor
  · intro h
    ext ⟨v, hv⟩ ⟨w, hw⟩
    simp only [comap_adj, Subtype.coe_mk, top_adj, Ne.def, Subtype.mk_eq_mk]
    exact ⟨Adj.ne, h hv hw⟩
  · intro h v hv w hw hne
    have h2 : (G.induce s).Adj ⟨v, hv⟩ ⟨w, hw⟩ = _ := rfl
    

Proof state:
case mpr
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s t : Set α
h : induce s G = ⊤
v : α
hv : v ∈ s
w : α
hw : w ∈ s
hne : v ≠ w
h2 :
  Adj (induce s G) { val := v, property := hv } { val := w, property := hw } =
    Adj (induce s G) { val := v, property := hv } { val := w, property := hw }
⊢ Adj G v w

Next tactic:
conv_lhs at h2 => rw [h]
/-- A clique is a set of vertices whose induced graph is complete. -/
theorem isClique_iff_induce_eq : G.IsClique s ↔ G.induce s = ⊤ := by
  rw [isClique_iff]
  constructor
  · intro h
    ext ⟨v, hv⟩ ⟨w, hw⟩
    simp only [comap_adj, Subtype.coe_mk, top_adj, Ne.def, Subtype.mk_eq_mk]
    exact ⟨Adj.ne, h hv hw⟩
  · intro h v hv w hw hne
    have h2 : (G.induce s).Adj ⟨v, hv⟩ ⟨w, hw⟩ = _ := rfl
    conv_lhs at h2 => 

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s t : Set α
h : induce s G = ⊤
v : α
hv : v ∈ s
w : α
hw : w ∈ s
hne : v ≠ w
h2 :
  Adj (induce s G) { val := v, property := hv } { val := w, property := hw } =
    Adj (induce s G) { val := v, property := hv } { val := w, property := hw }
| Adj (induce s G) { val := v, property := hv } { val := w, property := hw }

Next tactic:
rw [h]
/-- A clique is a set of vertices whose induced graph is complete. -/
theorem isClique_iff_induce_eq : G.IsClique s ↔ G.induce s = ⊤ := by
  rw [isClique_iff]
  constructor
  · intro h
    ext ⟨v, hv⟩ ⟨w, hw⟩
    simp only [comap_adj, Subtype.coe_mk, top_adj, Ne.def, Subtype.mk_eq_mk]
    exact ⟨Adj.ne, h hv hw⟩
  · intro h v hv w hw hne
    have h2 : (G.induce s).Adj ⟨v, hv⟩ ⟨w, hw⟩ = _ := rfl
    conv_lhs at h2 => rw [h]
    

Proof state:
case mpr
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s t : Set α
h : induce s G = ⊤
v : α
hv : v ∈ s
w : α
hw : w ∈ s
hne : v ≠ w
h2 :
  Adj ⊤ { val := v, property := hv } { val := w, property := hw } =
    Adj (induce s G) { val := v, property := hv } { val := w, property := hw }
⊢ Adj G v w

Next tactic:
simp only [top_adj, ne_eq, Subtype.mk.injEq, eq_iff_iff] at h2
/-- A clique is a set of vertices whose induced graph is complete. -/
theorem isClique_iff_induce_eq : G.IsClique s ↔ G.induce s = ⊤ := by
  rw [isClique_iff]
  constructor
  · intro h
    ext ⟨v, hv⟩ ⟨w, hw⟩
    simp only [comap_adj, Subtype.coe_mk, top_adj, Ne.def, Subtype.mk_eq_mk]
    exact ⟨Adj.ne, h hv hw⟩
  · intro h v hv w hw hne
    have h2 : (G.induce s).Adj ⟨v, hv⟩ ⟨w, hw⟩ = _ := rfl
    conv_lhs at h2 => rw [h]
    simp only [top_adj, ne_eq, Subtype.mk.injEq, eq_iff_iff] at h2
    

Proof state:
case mpr
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s t : Set α
h : induce s G = ⊤
v : α
hv : v ∈ s
w : α
hw : w ∈ s
hne : v ≠ w
h2 : ¬v = w ↔ Adj (induce s G) { val := v, property := hv } { val := w, property := hw }
⊢ Adj G v w

Next tactic:
exact h2.1 hne
lemma isClique_empty : G.IsClique ∅ := by 

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s t : Set α
a b : α
⊢ IsClique G ∅

Next tactic:
simp
lemma isClique_singleton (a : α) : G.IsClique {a} := by 

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s t : Set α
a✝ b a : α
⊢ IsClique G {a}

Next tactic:
simp
protected theorem IsClique.map {s : Set α} (h : G.IsClique s) {f : α ↪ β} :
    (G.map f).IsClique (f '' s) := by
  

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s✝ t : Set α
a b : α
s : Set α
h : IsClique G s
f : α ↪ β
⊢ IsClique (SimpleGraph.map f G) (⇑f '' s)

Next tactic:
rintro _ ⟨a, ha, rfl⟩ _ ⟨b, hb, rfl⟩ hab
protected theorem IsClique.map {s : Set α} (h : G.IsClique s) {f : α ↪ β} :
    (G.map f).IsClique (f '' s) := by
  rintro _ ⟨a, ha, rfl⟩ _ ⟨b, hb, rfl⟩ hab
  

Proof state:
case intro.intro.intro.intro
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s✝ t : Set α
a✝ b✝ : α
s : Set α
h : IsClique G s
f : α ↪ β
a : α
ha : a ∈ s
b : α
hb : b ∈ s
hab : f a ≠ f b
⊢ Adj (SimpleGraph.map f G) (f a) (f b)

Next tactic:
exact ⟨a, b, h ha hb <| ne_of_apply_ne _ hab, rfl, rfl⟩
@[simp] lemma isNClique_empty : G.IsNClique n ∅ ↔ n = 0 := by 

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
n : ℕ
s : Finset α
a b c : α
⊢ IsNClique G n ∅ ↔ n = 0

Next tactic:
simp [isNClique_iff, eq_comm]
@[simp]
lemma isNClique_singleton : G.IsNClique n {a} ↔ n = 1 := by 

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
n : ℕ
s : Finset α
a b c : α
⊢ IsNClique G n {a} ↔ n = 1

Next tactic:
simp [isNClique_iff, eq_comm]
theorem IsNClique.mono (h : G ≤ H) : G.IsNClique n s → H.IsNClique n s := by
  

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
n : ℕ
s : Finset α
a b c : α
h : G ≤ H
⊢ IsNClique G n s → IsNClique H n s

Next tactic:
simp_rw [isNClique_iff]
theorem IsNClique.mono (h : G ≤ H) : G.IsNClique n s → H.IsNClique n s := by
  simp_rw [isNClique_iff]
  

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
n : ℕ
s : Finset α
a b c : α
h : G ≤ H
⊢ IsClique G ↑s ∧ Finset.card s = n → IsClique H ↑s ∧ Finset.card s = n

Next tactic:
exact And.imp_left (IsClique.mono h)
protected theorem IsNClique.map (h : G.IsNClique n s) {f : α ↪ β} :
    (G.map f).IsNClique n (s.map f) :=
  ⟨by 

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
n : ℕ
s : Finset α
a b c : α
h : IsNClique G n s
f : α ↪ β
⊢ IsClique (SimpleGraph.map f G) ↑(map f s)

Next tactic:
rw [coe_map]
protected theorem IsNClique.map (h : G.IsNClique n s) {f : α ↪ β} :
    (G.map f).IsNClique n (s.map f) :=
  ⟨by rw [coe_map]; 

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
n : ℕ
s : Finset α
a b c : α
h : IsNClique G n s
f : α ↪ β
⊢ IsClique (SimpleGraph.map f G) (⇑f '' ↑s)

Next tactic:
exact h.1.map
@[simp]
theorem isNClique_bot_iff : (⊥ : SimpleGraph α).IsNClique n s ↔ n ≤ 1 ∧ s.card = n := by
  

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
n : ℕ
s : Finset α
a b c : α
⊢ IsNClique ⊥ n s ↔ n ≤ 1 ∧ Finset.card s = n

Next tactic:
rw [isNClique_iff, isClique_bot_iff]
@[simp]
theorem isNClique_bot_iff : (⊥ : SimpleGraph α).IsNClique n s ↔ n ≤ 1 ∧ s.card = n := by
  rw [isNClique_iff, isClique_bot_iff]
  

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
n : ℕ
s : Finset α
a b c : α
⊢ Set.Subsingleton ↑s ∧ Finset.card s = n ↔ n ≤ 1 ∧ Finset.card s = n

Next tactic:
refine' and_congr_left _
@[simp]
theorem isNClique_bot_iff : (⊥ : SimpleGraph α).IsNClique n s ↔ n ≤ 1 ∧ s.card = n := by
  rw [isNClique_iff, isClique_bot_iff]
  refine' and_congr_left _
  

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
n : ℕ
s : Finset α
a b c : α
⊢ Finset.card s = n → (Set.Subsingleton ↑s ↔ n ≤ 1)

Next tactic:
rintro rfl
@[simp]
theorem isNClique_bot_iff : (⊥ : SimpleGraph α).IsNClique n s ↔ n ≤ 1 ∧ s.card = n := by
  rw [isNClique_iff, isClique_bot_iff]
  refine' and_congr_left _
  rintro rfl
  

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
s : Finset α
a b c : α
⊢ Set.Subsingleton ↑s ↔ Finset.card s ≤ 1

Next tactic:
exact card_le_one.symm
@[simp]
theorem isNClique_zero : G.IsNClique 0 s ↔ s = ∅ := by
  

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
n : ℕ
s : Finset α
a b c : α
⊢ IsNClique G 0 s ↔ s = ∅

Next tactic:
simp only [isNClique_iff, Finset.card_eq_zero, and_iff_right_iff_imp]
@[simp]
theorem isNClique_zero : G.IsNClique 0 s ↔ s = ∅ := by
  simp only [isNClique_iff, Finset.card_eq_zero, and_iff_right_iff_imp]; 

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
n : ℕ
s : Finset α
a b c : α
⊢ s = ∅ → IsClique G ↑s

Next tactic:
rintro rfl
@[simp]
theorem isNClique_zero : G.IsNClique 0 s ↔ s = ∅ := by
  simp only [isNClique_iff, Finset.card_eq_zero, and_iff_right_iff_imp]; rintro rfl; 

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
n : ℕ
a b c : α
⊢ IsClique G ↑∅

Next tactic:
simp
@[simp]
theorem isNClique_one : G.IsNClique 1 s ↔ ∃ a, s = {a} := by
  

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
n : ℕ
s : Finset α
a b c : α
⊢ IsNClique G 1 s ↔ ∃ a, s = {a}

Next tactic:
simp only [isNClique_iff, card_eq_one, and_iff_right_iff_imp]
@[simp]
theorem isNClique_one : G.IsNClique 1 s ↔ ∃ a, s = {a} := by
  simp only [isNClique_iff, card_eq_one, and_iff_right_iff_imp]; 

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
n : ℕ
s : Finset α
a b c : α
⊢ (∃ a, s = {a}) → IsClique G ↑s

Next tactic:
rintro ⟨a, rfl⟩
@[simp]
theorem isNClique_one : G.IsNClique 1 s ↔ ∃ a, s = {a} := by
  simp only [isNClique_iff, card_eq_one, and_iff_right_iff_imp]; rintro ⟨a, rfl⟩; 

Proof state:
case intro
α : Type u_1
β : Type u_2
G H : SimpleGraph α
n : ℕ
a✝ b c a : α
⊢ IsClique G ↑{a}

Next tactic:
simp
theorem IsNClique.insert (hs : G.IsNClique n s) (h : ∀ b ∈ s, G.Adj a b) :
    G.IsNClique (n + 1) (insert a s) := by
  

Proof state:
α : Type u_1
β : Type u_2
G H : SimpleGraph α
n : ℕ
s : Finset α
a b c : α
inst✝ : DecidableEq α
hs : IsNClique G n s
h : ∀ b ∈ s, Adj G a b
⊢ IsNClique G (n + 1) (Insert.insert a s)

Next tactic:
constructor