This PR fixes another issue at the `congr_simp` theorems that was affecting Mathlib. Many thanks to Johan Commelin for creating the mwe. closes #9466
757 lines
19 KiB
Text
757 lines
19 KiB
Text
import Lean.Elab.Term
|
||
|
||
/-!
|
||
# Turán's theorem
|
||
-/
|
||
|
||
set_option warn.sorry false
|
||
|
||
section Mathlib.Tactic.TypeStar
|
||
|
||
open Lean
|
||
|
||
elab "Sort*" : term => do
|
||
let u ← Lean.Meta.mkFreshLevelMVar
|
||
Elab.Term.levelMVarToParam (.sort u)
|
||
|
||
elab "Type*" : term => do
|
||
let u ← Lean.Meta.mkFreshLevelMVar
|
||
Elab.Term.levelMVarToParam (.sort (.succ u))
|
||
|
||
end Mathlib.Tactic.TypeStar
|
||
|
||
section Mathlib.Data.Set.Defs
|
||
|
||
universe u
|
||
variable {α : Type u}
|
||
|
||
/-- A set is a collection of elements of some type `α`.
|
||
|
||
Although `Set` is defined as `α → Prop`, this is an implementation detail which should not be
|
||
relied on. Instead, `setOf` and membership of a set (`∈`) should be used to convert between sets
|
||
and predicates.
|
||
-/
|
||
def Set (α : Type u) := α → Prop
|
||
|
||
/-- Turn a predicate `p : α → Prop` into a set, also written as `{x | p x}` -/
|
||
def setOf {α : Type u} (p : α → Prop) : Set α :=
|
||
p
|
||
|
||
namespace Set
|
||
|
||
/-- Membership in a set -/
|
||
protected def Mem (s : Set α) (a : α) : Prop :=
|
||
s a
|
||
|
||
instance : Membership α (Set α) :=
|
||
⟨Set.Mem⟩
|
||
|
||
end Set
|
||
|
||
end Mathlib.Data.Set.Defs
|
||
|
||
section Mathlib.Order.Defs.Unbundled
|
||
|
||
variable {α : Sort*} (r : α → α → Prop)
|
||
|
||
/-- `IsSymm` as a definition, suitable for use in proofs. -/
|
||
def Symmetric := ∀ ⦃x y⦄, r x y → r y x
|
||
|
||
end Mathlib.Order.Defs.Unbundled
|
||
|
||
section Mathlib.Data.List.Defs
|
||
|
||
namespace List
|
||
|
||
variable {α : Type*}
|
||
|
||
section Choose
|
||
|
||
variable (p : α → Prop) [DecidablePred p] (l : List α)
|
||
|
||
/-- Given a decidable predicate `p` and a proof of existence of `a ∈ l` such that `p a`,
|
||
choose the first element with this property. This version returns both `a` and proofs
|
||
of `a ∈ l` and `p a`. -/
|
||
def chooseX : ∀ l : List α, ∀ _ : ∃ a, a ∈ l ∧ p a, { a // a ∈ l ∧ p a }
|
||
| [], hp => False.elim (Exists.elim hp fun _ h => not_mem_nil h.left)
|
||
| l :: ls, hp =>
|
||
if pl : p l then ⟨l, ⟨mem_cons.mpr <| Or.inl rfl, pl⟩⟩
|
||
else
|
||
-- pattern matching on `hx` too makes this not reducible!
|
||
let ⟨a, ha⟩ :=
|
||
chooseX ls
|
||
(hp.imp fun _ ⟨o, h₂⟩ => ⟨(mem_cons.mp o).resolve_left fun e => pl <| e ▸ h₂, h₂⟩)
|
||
⟨a, mem_cons.mpr <| Or.inr ha.1, ha.2⟩
|
||
|
||
end Choose
|
||
|
||
end List
|
||
|
||
end Mathlib.Data.List.Defs
|
||
|
||
section Mathlib.Data.Set.CoeSort
|
||
|
||
namespace Set
|
||
|
||
universe u v w
|
||
|
||
variable {α : Type u} {β : Type v} {γ : Type w}
|
||
|
||
/-- Given the set `s`, `Elem s` is the `Type` of element of `s`.
|
||
|
||
It is currently an abbreviation so that instance coming from `Subtype` are available.
|
||
If you're interested in making it a `def`, as it probably should be,
|
||
you'll then need to create additional instances (and possibly prove lemmas about them).
|
||
See e.g. `Mathlib/Data/Set/Order.lean`.
|
||
-/
|
||
@[coe, reducible] def Elem (s : Set α) : Type u := {x // x ∈ s}
|
||
|
||
/-- Coercion from a set to the corresponding subtype. -/
|
||
instance : CoeSort (Set α) (Type u) := ⟨Elem⟩
|
||
|
||
end Set
|
||
|
||
end Mathlib.Data.Set.CoeSort
|
||
|
||
section Mathlib.Data.Multiset.Defs
|
||
|
||
universe v
|
||
|
||
open List Subtype Nat Function
|
||
|
||
variable {α : Type*} {β : Type v} {γ : Type*}
|
||
|
||
/-- `Multiset α` is the quotient of `List α` by list permutation. The result
|
||
is a type of finite sets with duplicates allowed. -/
|
||
def Multiset.{u} (α : Type u) : Type u :=
|
||
Quotient (List.isSetoid α)
|
||
|
||
namespace Multiset
|
||
|
||
/-- The quotient map from `List α` to `Multiset α`. -/
|
||
def ofList : List α → Multiset α :=
|
||
Quot.mk _
|
||
|
||
section Mem
|
||
|
||
/-- `a ∈ s` means that `a` has nonzero multiplicity in `s`. -/
|
||
def Mem (s : Multiset α) (a : α) : Prop :=
|
||
Quot.liftOn s (fun l => a ∈ l) fun l₁ l₂ (e : l₁ ~ l₂) => propext <| e.mem_iff
|
||
|
||
instance : Membership α (Multiset α) :=
|
||
⟨Mem⟩
|
||
|
||
instance decidableMem [DecidableEq α] (a : α) (s : Multiset α) : Decidable (a ∈ s) :=
|
||
Quot.recOnSubsingleton s fun l ↦ inferInstanceAs (Decidable (a ∈ l))
|
||
|
||
end Mem
|
||
|
||
/-- The cardinality of a multiset is the sum of the multiplicities
|
||
of all its elements, or simply the length of the underlying list. -/
|
||
def card : Multiset α → Nat := Quot.lift length sorry
|
||
|
||
/-- Lift of the list `pmap` operation. Map a partial function `f` over a multiset
|
||
`s` whose elements are all in the domain of `f`. -/
|
||
nonrec def pmap {p : α → Prop} (f : ∀ a, p a → β) (s : Multiset α) : (∀ a ∈ s, p a) → Multiset β :=
|
||
Quot.recOn s (fun l H => ofList (pmap f l H)) sorry
|
||
|
||
end Multiset
|
||
|
||
end Mathlib.Data.Multiset.Defs
|
||
|
||
section Mathlib.Data.Multiset.ZeroCons
|
||
|
||
universe v
|
||
|
||
open List Subtype Nat Function
|
||
|
||
variable {α : Type*} {β : Type v} {γ : Type*}
|
||
|
||
namespace Multiset
|
||
|
||
/-- `0 : Multiset α` is the empty set -/
|
||
protected def zero : Multiset α :=
|
||
ofList (@nil α)
|
||
|
||
instance : Zero (Multiset α) :=
|
||
⟨Multiset.zero⟩
|
||
|
||
end Multiset
|
||
|
||
end Mathlib.Data.Multiset.ZeroCons
|
||
|
||
section Mathlib.Data.Multiset.Basic
|
||
|
||
universe v
|
||
|
||
open List Subtype Nat Function
|
||
|
||
variable {α : Type*} {β : Type v} {γ : Type*}
|
||
|
||
namespace Multiset
|
||
|
||
section Choose
|
||
|
||
variable (p : α → Prop) [DecidablePred p] (l : Multiset α)
|
||
|
||
/-- Given a proof `hp` that there exists a unique `a ∈ l` such that `p a`, `chooseX p l hp` returns
|
||
that `a` together with proofs of `a ∈ l` and `p a`. -/
|
||
def chooseX : ∀ _hp : ∃ a, a ∈ l ∧ p a, { a // a ∈ l ∧ p a } :=
|
||
Quotient.recOn l (fun l' h => List.chooseX p l' h) sorry
|
||
|
||
end Choose
|
||
|
||
end Multiset
|
||
|
||
end Mathlib.Data.Multiset.Basic
|
||
|
||
section Mathlib.Data.Multiset.MapFold
|
||
|
||
variable {α β : Type*}
|
||
|
||
namespace Multiset
|
||
|
||
/-- `map f s` is the lift of the list `map` operation. The multiplicity
|
||
of `b` in `map f s` is the number of `a ∈ s` (counting multiplicity)
|
||
such that `f a = b`. -/
|
||
def map (f : α → β) (s : Multiset α) : Multiset β :=
|
||
Quot.liftOn s (fun l : List α => ofList <| l.map f) sorry
|
||
|
||
end Multiset
|
||
|
||
end Mathlib.Data.Multiset.MapFold
|
||
|
||
section Mathlib.Data.Multiset.Filter
|
||
|
||
variable {α : Type*}
|
||
|
||
namespace Multiset
|
||
|
||
variable (p : α → Prop) [DecidablePred p]
|
||
|
||
/-- `Filter p s` returns the elements in `s` (with the same multiplicities)
|
||
which satisfy `p`, and removes the rest. -/
|
||
def filter (s : Multiset α) : Multiset α :=
|
||
Quot.liftOn s (fun l => ofList <| List.filter p l) sorry
|
||
|
||
end Multiset
|
||
|
||
end Mathlib.Data.Multiset.Filter
|
||
|
||
section Mathlib.Data.Finset.Defs
|
||
|
||
universe u
|
||
|
||
variable {α : Type*} {β : Type*} {γ : Type*}
|
||
|
||
/-- `Finset α` is the type of finite sets of elements of `α`. It is implemented
|
||
as a multiset (a list up to permutation) which has no duplicate elements. -/
|
||
structure Finset (α : Type*) where
|
||
/-- The underlying multiset -/
|
||
val : Multiset α
|
||
|
||
namespace Finset
|
||
|
||
theorem val_inj {s t : Finset α} : s.1 = t.1 ↔ s = t := sorry
|
||
|
||
instance : Membership α (Finset α) :=
|
||
⟨fun s a => a ∈ s.1⟩
|
||
|
||
instance decidableMem [_h : DecidableEq α] (a : α) (s : Finset α) : Decidable (a ∈ s) :=
|
||
Multiset.decidableMem _ _
|
||
|
||
end Finset
|
||
|
||
end Mathlib.Data.Finset.Defs
|
||
|
||
section Mathlib.Data.Finset.Dedup
|
||
|
||
universe u
|
||
|
||
variable {α : Type*} {β : Type*} {γ : Type*}
|
||
|
||
namespace Finset
|
||
|
||
end Finset
|
||
|
||
/-! ### dedup on list and multiset -/
|
||
|
||
namespace Multiset
|
||
|
||
variable [DecidableEq α] {s t : Multiset α}
|
||
|
||
/-- `toFinset s` removes duplicates from the multiset `s` to produce a finset. -/
|
||
def toFinset (s : Multiset α) : Finset α := ⟨s⟩
|
||
|
||
end Multiset
|
||
|
||
end Mathlib.Data.Finset.Dedup
|
||
|
||
section Mathlib.Data.Finset.Empty
|
||
|
||
universe u
|
||
|
||
variable {α : Type*} {β : Type*} {γ : Type*}
|
||
|
||
namespace Finset
|
||
|
||
section Empty
|
||
|
||
variable {s : Finset α}
|
||
|
||
/-- The empty finset -/
|
||
protected def empty : Finset α := ⟨0⟩
|
||
|
||
end Empty
|
||
end Finset
|
||
|
||
end Mathlib.Data.Finset.Empty
|
||
|
||
section Mathlib.Data.Finset.Filter
|
||
|
||
variable {α : Type*}
|
||
|
||
namespace Finset
|
||
|
||
section Filter
|
||
|
||
variable (p : α → Prop) [DecidablePred p]
|
||
|
||
/-- `Finset.filter p s` is the set of elements of `s` that satisfy `p`.
|
||
For example, one can use `s.filter (· ∈ t)` to get the intersection of `s` with `t : Set α`
|
||
as a `Finset α` (when a `DecidablePred (· ∈ t)` instance is available). -/
|
||
def filter (s : Finset α) : Finset α :=
|
||
⟨s.1.filter p⟩
|
||
|
||
end Finset.Filter
|
||
|
||
end Mathlib.Data.Finset.Filter
|
||
|
||
section Mathlib.Data.Finset.Basic
|
||
|
||
variable {α : Type*}
|
||
|
||
namespace Finset
|
||
|
||
section Choose
|
||
|
||
variable (p : α → Prop) [DecidablePred p] (l : Finset α)
|
||
|
||
/-- Given a finset `l` and a predicate `p`, associate to a proof that there is a unique element of
|
||
`l` satisfying `p` this unique element, as an element of the corresponding subtype. -/
|
||
def chooseX (hp : ∃ a, a ∈ l ∧ p a) : { a // a ∈ l ∧ p a } :=
|
||
Multiset.chooseX p l.val hp
|
||
|
||
/-- Given a finset `l` and a predicate `p`, associate to a proof that there is a unique element of
|
||
`l` satisfying `p` this unique element, as an element of the ambient type. -/
|
||
def choose (hp : ∃ a, a ∈ l ∧ p a) : α :=
|
||
chooseX p l hp
|
||
|
||
end Choose
|
||
|
||
end Finset
|
||
|
||
end Mathlib.Data.Finset.Basic
|
||
|
||
section Mathlib.Data.Finset.Image
|
||
|
||
variable {α β γ : Type*}
|
||
|
||
namespace Finset
|
||
|
||
section Map
|
||
|
||
/-- When `f` is an embedding of `α` in `β` and `s` is a finset in `α`, then `s.map f` is the image
|
||
finset in `β`. The embedding condition guarantees that there are no duplicates in the image. -/
|
||
def map (f : α → β) (s : Finset α) : Finset β := ⟨s.1.map f⟩
|
||
|
||
end Map
|
||
|
||
section Image
|
||
|
||
variable [DecidableEq β]
|
||
|
||
/-- `image f s` is the forward image of `s` under `f`. -/
|
||
def image (f : α → β) (s : Finset α) : Finset β :=
|
||
(s.1.map f).toFinset
|
||
|
||
end Image
|
||
|
||
end Finset
|
||
|
||
end Mathlib.Data.Finset.Image
|
||
|
||
section Mathlib.Data.Finset.Card
|
||
|
||
variable {α β R : Type*}
|
||
|
||
namespace Finset
|
||
|
||
variable {s t : Finset α} {a b : α}
|
||
|
||
/-- `s.card` is the number of elements of `s`, aka its cardinality.
|
||
The notation `#s` can be accessed in the `Finset` locale. -/
|
||
def card (s : Finset α) : Nat :=
|
||
Multiset.card s.1
|
||
|
||
end Finset
|
||
|
||
end Mathlib.Data.Finset.Card
|
||
|
||
section Mathlib.Data.Fintype.Defs
|
||
|
||
variable {α β γ : Type*}
|
||
|
||
/-- `Fintype α` means that `α` is finite, i.e. there are only
|
||
finitely many distinct elements of type `α`. The evidence of this
|
||
is a finset `elems` (a list up to permutation without duplicates),
|
||
together with a proof that everything of type `α` is in the list. -/
|
||
class Fintype (α : Type*) where
|
||
/-- The `Finset` containing all elements of a `Fintype` -/
|
||
elems : Finset α
|
||
|
||
namespace Finset
|
||
|
||
variable [Fintype α] {s t : Finset α}
|
||
|
||
/-- `univ` is the universal finite set of type `Finset α` implied from
|
||
the assumption `Fintype α`. -/
|
||
def univ : Finset α := @Fintype.elems α _
|
||
|
||
end Finset
|
||
|
||
namespace Fintype
|
||
|
||
/-- Given a predicate that can be represented by a finset, the subtype
|
||
associated to the predicate is a fintype. -/
|
||
protected def subtype {p : α → Prop} (s : Finset α) (H : ∀ x : α, x ∈ s ↔ p x) :
|
||
Fintype { x // p x } :=
|
||
⟨⟨s.1.pmap Subtype.mk fun x => (H x).1⟩⟩
|
||
|
||
end Fintype
|
||
|
||
end Mathlib.Data.Fintype.Defs
|
||
|
||
section Mathlib.Data.Fintype.Sets
|
||
|
||
variable {α β γ : Type*}
|
||
|
||
open Finset
|
||
|
||
namespace Set
|
||
|
||
variable {s t : Set α}
|
||
|
||
/-- Construct a finset enumerating a set `s`, given a `Fintype` instance. -/
|
||
def toFinset (s : Set α) [Fintype s] : Finset α :=
|
||
(@Finset.univ s _).map <| Subtype.val
|
||
|
||
end Set
|
||
|
||
instance Subtype.fintype (p : α → Prop) [DecidablePred p] [Fintype α] : Fintype { x // p x } :=
|
||
Fintype.subtype (univ.filter p) sorry
|
||
|
||
end Mathlib.Data.Fintype.Sets
|
||
|
||
section Mathlib.Data.Sym.Sym2
|
||
|
||
open Function
|
||
|
||
universe u
|
||
|
||
variable {α β γ : Type*}
|
||
|
||
namespace Sym2
|
||
|
||
/-- This is the relation capturing the notion of pairs equivalent up to permutations. -/
|
||
inductive Rel (α : Type u) : α × α → α × α → Prop
|
||
| refl (x y : α) : Rel _ (x, y) (x, y)
|
||
| swap (x y : α) : Rel _ (x, y) (y, x)
|
||
|
||
end Sym2
|
||
|
||
/-- `Sym2 α` is the symmetric square of `α`, which, in other words, is the
|
||
type of unordered pairs. -/
|
||
abbrev Sym2 (α : Type u) := Quot (Sym2.Rel α)
|
||
|
||
/-- Constructor for `Sym2`. This is the quotient map `α × α → Sym2 α`. -/
|
||
protected abbrev Sym2.mk {α : Type*} (p : α × α) : Sym2 α := Quot.mk (Sym2.Rel α) p
|
||
|
||
namespace Sym2
|
||
|
||
/-- The universal property of `Sym2`; symmetric functions of two arguments are equivalent to
|
||
functions from `Sym2`. Note that when `β` is `Prop`, it can sometimes be more convenient to use
|
||
`Sym2.fromRel` instead. -/
|
||
def lift : { f : α → α → β // ∀ a₁ a₂, f a₁ a₂ = f a₂ a₁ } → (Sym2 α → β) :=
|
||
fun f => Quot.lift (uncurry f) <| by sorry
|
||
|
||
section Relations
|
||
|
||
variable {r : α → α → Prop}
|
||
|
||
/-- Symmetric relations define a set on `Sym2 α` by taking all those pairs
|
||
of elements that are related.
|
||
-/
|
||
def fromRel (sym : Symmetric r) : Set (Sym2 α) :=
|
||
setOf (lift ⟨r, fun _ _ => propext ⟨(sym ·), (sym ·)⟩⟩)
|
||
|
||
instance fromRel.decidablePred (sym : Symmetric r) [h : DecidableRel r] :
|
||
DecidablePred (· ∈ Sym2.fromRel sym) := fun z => z.recOnSubsingleton fun _ => h _ _
|
||
|
||
end Relations
|
||
|
||
end Sym2
|
||
|
||
end Mathlib.Data.Sym.Sym2
|
||
|
||
section Mathlib.Data.List.Sym
|
||
|
||
namespace List
|
||
|
||
variable {α β : Type*}
|
||
|
||
section Sym2
|
||
|
||
/-- `xs.sym2` is a list of all unordered pairs of elements from `xs`.
|
||
If `xs` has no duplicates then neither does `xs.sym2`. -/
|
||
protected def sym2 : List α → List (Sym2 α)
|
||
| [] => []
|
||
| x :: xs => (x :: xs).map (fun y => .mk (x, y)) ++ xs.sym2
|
||
|
||
end Sym2
|
||
|
||
end List
|
||
|
||
end Mathlib.Data.List.Sym
|
||
|
||
section Mathlib.Data.Multiset.Sym
|
||
|
||
namespace Multiset
|
||
|
||
variable {α β : Type*}
|
||
|
||
section Sym2
|
||
|
||
/-- `m.sym2` is the multiset of all unordered pairs of elements from `m`, with multiplicity.
|
||
If `m` has no duplicates then neither does `m.sym2`. -/
|
||
protected def sym2 (m : Multiset α) : Multiset (Sym2 α) :=
|
||
m.liftOn (fun xs => ofList xs.sym2) fun _ _ h => sorry
|
||
|
||
end Sym2
|
||
|
||
end Multiset
|
||
|
||
end Mathlib.Data.Multiset.Sym
|
||
|
||
section Mathlib.Data.Finset.Sym
|
||
|
||
namespace Finset
|
||
|
||
variable {α β : Type*}
|
||
|
||
protected def sym2 (s : Finset α) : Finset (Sym2 α) := ⟨s.1.sym2⟩
|
||
|
||
section
|
||
variable {s t : Finset α} {a b : α}
|
||
|
||
instance _root_.Sym2.instFintype [Fintype α] : Fintype (Sym2 α) where
|
||
elems := Finset.univ.sym2
|
||
|
||
end
|
||
|
||
end Finset
|
||
|
||
end Mathlib.Data.Finset.Sym
|
||
|
||
section Mathlib.Combinatorics.SimpleGraph.Basic
|
||
|
||
open Function
|
||
|
||
universe u v w
|
||
|
||
/-- A simple graph is an irreflexive symmetric relation `Adj` on a vertex type `V`.
|
||
The relation describes which pairs of vertices are adjacent.
|
||
There is exactly one edge for every pair of adjacent vertices;
|
||
see `SimpleGraph.edgeSet` for the corresponding edge set.
|
||
-/
|
||
structure SimpleGraph (V : Type u) where
|
||
/-- The adjacency relation of a simple graph. -/
|
||
Adj : V → V → Prop
|
||
|
||
namespace SimpleGraph
|
||
|
||
variable {ι : Sort*} {V : Type u} (G : SimpleGraph V) {a b c u v w : V} {e : Sym2 V}
|
||
|
||
section EdgeSet
|
||
|
||
variable {G₁ G₂ : SimpleGraph V}
|
||
|
||
/-- The edges of G consist of the unordered pairs of vertices related by
|
||
`G.Adj`. This is the order embedding; for the edge set of a particular graph, see
|
||
`SimpleGraph.edgeSet`.
|
||
|
||
The way `edgeSet` is defined is such that `mem_edgeSet` is proved by `Iff.rfl`.
|
||
(That is, `s(v, w) ∈ G.edgeSet` is definitionally equal to `G.Adj v w`.)
|
||
-/
|
||
-- Porting note: We need a separate definition so that dot notation works.
|
||
def edgeSetEmbedding (V : Type*) : SimpleGraph V → Set (Sym2 V) :=
|
||
fun G => Sym2.fromRel (r := G.1) sorry
|
||
|
||
/-- `G.edgeSet` is the edge set for `G`.
|
||
This is an abbreviation for `edgeSetEmbedding G` that permits dot notation. -/
|
||
abbrev edgeSet (G : SimpleGraph V) : Set (Sym2 V) := edgeSetEmbedding V G
|
||
|
||
variable (G₁ G₂)
|
||
|
||
instance decidableMemEdgeSet [DecidableRel G.Adj] : DecidablePred (· ∈ G.edgeSet) :=
|
||
Sym2.fromRel.decidablePred sorry
|
||
|
||
end EdgeSet
|
||
|
||
end SimpleGraph
|
||
|
||
end Mathlib.Combinatorics.SimpleGraph.Basic
|
||
|
||
section Mathlib.Combinatorics.SimpleGraph.Finite
|
||
namespace SimpleGraph
|
||
|
||
variable {V : Type*} (G : SimpleGraph V) {e : Sym2 V}
|
||
variable {G₁ G₂ : SimpleGraph V} [Fintype G.edgeSet] [Fintype G₁.edgeSet] [Fintype G₂.edgeSet]
|
||
|
||
/-- The `edgeSet` of the graph as a `Finset`. -/
|
||
abbrev edgeFinset : Finset (Sym2 V) := Set.toFinset G.edgeSet
|
||
|
||
end SimpleGraph
|
||
end Mathlib.Combinatorics.SimpleGraph.Finite
|
||
|
||
section Mathlib.Combinatorics.SimpleGraph.Clique
|
||
|
||
namespace SimpleGraph
|
||
|
||
variable {α β : Type*} (G H : SimpleGraph α)
|
||
|
||
/-! ### `n`-cliques -/
|
||
|
||
section NClique
|
||
|
||
variable {n : Nat} {s : Finset α}
|
||
|
||
/-- An `n`-clique in a graph is a set of `n` vertices which are pairwise connected. -/
|
||
structure IsNClique (G : SimpleGraph α) (n : Nat) (s : Finset α) : Prop where
|
||
|
||
end NClique
|
||
|
||
/-! ### Graphs without cliques -/
|
||
|
||
|
||
section CliqueFree
|
||
|
||
variable {m n : Nat}
|
||
|
||
/-- `G.CliqueFree n` means that `G` has no `n`-cliques. -/
|
||
def CliqueFree (n : Nat) : Prop :=
|
||
∀ t, ¬G.IsNClique n t
|
||
|
||
end CliqueFree
|
||
|
||
end SimpleGraph
|
||
end Mathlib.Combinatorics.SimpleGraph.Clique
|
||
|
||
section Mathlib.Order.Partition.Finpartition
|
||
open Finset
|
||
|
||
variable {α : Type*}
|
||
|
||
/-- A finite partition of `a : α` is a pairwise disjoint finite set of elements whose supremum is
|
||
`a`. We forbid `⊥` as a part. -/
|
||
structure Finpartition (a : α) where
|
||
/-- The elements of the finite partition of `a` -/
|
||
parts : Finset α
|
||
|
||
/-! ### Finite partitions of finsets -/
|
||
|
||
namespace Finpartition
|
||
|
||
variable [DecidableEq α] {s t u : Finset α} (P : Finpartition s) {a : α}
|
||
|
||
theorem existsUnique_mem (ha : a ∈ s) : ∃ t, t ∈ P.parts ∧ a ∈ t := by sorry
|
||
|
||
/-- The part of the finpartition that `a` lies in. -/
|
||
def part (a : α) : Finset α := if ha : a ∈ s then choose (hp := P.existsUnique_mem ha) else .empty
|
||
|
||
section SetSetoid
|
||
|
||
/-- A setoid over a finite type induces a finpartition of the type's elements,
|
||
where the parts are the setoid's equivalence classes. -/
|
||
def ofSetSetoid (s : Setoid α) (x : Finset α) [DecidableRel s.r] : Finpartition x where
|
||
parts := x.image fun a ↦ x.filter (s.r a ·)
|
||
|
||
end SetSetoid
|
||
|
||
section Setoid
|
||
|
||
variable [Fintype α]
|
||
|
||
/-- A setoid over a finite type induces a finpartition of the type's elements,
|
||
where the parts are the setoid's equivalence classes. -/
|
||
def ofSetoid (s : Setoid α) [DecidableRel s.r] : Finpartition (univ : Finset α) :=
|
||
ofSetSetoid s univ
|
||
|
||
end Setoid
|
||
|
||
end Finpartition
|
||
|
||
end Mathlib.Order.Partition.Finpartition
|
||
|
||
open Finset
|
||
|
||
namespace SimpleGraph
|
||
|
||
variable {V : Type*} [Fintype V] {G : SimpleGraph V} [DecidableRel G.Adj] {n r : Nat}
|
||
|
||
variable (G) in
|
||
/-- An `r + 1`-cliquefree graph is `r`-Turán-maximal if any other `r + 1`-cliquefree graph on
|
||
the same vertex set has the same or fewer number of edges. -/
|
||
def IsTuranMaximal (r : Nat) : Prop :=
|
||
G.CliqueFree (r + 1) ∧ ∀ (H : SimpleGraph V) [DecidableRel H.Adj],
|
||
H.CliqueFree (r + 1) → H.edgeFinset.card ≤ G.edgeFinset.card
|
||
|
||
namespace IsTuranMaximal
|
||
|
||
variable {s t u : V}
|
||
|
||
variable (h : G.IsTuranMaximal r)
|
||
include h
|
||
|
||
/-- In a Turán-maximal graph, non-adjacency is an equivalence relation. -/
|
||
theorem equivalence_not_adj : Equivalence (¬G.Adj · ·) where
|
||
refl := sorry
|
||
symm := sorry
|
||
trans := sorry
|
||
|
||
/-- The non-adjacency setoid over the vertices of a Turán-maximal graph
|
||
induced by `equivalence_not_adj`. -/
|
||
def setoid : Setoid V := ⟨_, h.equivalence_not_adj⟩
|
||
|
||
instance : DecidableRel h.setoid.r :=
|
||
inferInstanceAs <| DecidableRel (¬G.Adj · ·)
|
||
|
||
/-- The finpartition derived from `h.setoid`. -/
|
||
def finpartition [DecidableEq V] : Finpartition (univ : Finset V) := Finpartition.ofSetoid h.setoid
|
||
|
||
theorem not_adj_iff_part_eq [DecidableEq V] :
|
||
¬G.Adj s t ↔ h.finpartition.part s = h.finpartition.part t := by sorry
|
||
|
||
theorem card_parts_extracted_1_11 [DecidableEq V] :
|
||
let fp := h.finpartition;
|
||
fp.parts.card < (Finset.univ (α := V)).card ∧ fp.parts.card < r →
|
||
∀ (x y : V),
|
||
x ≠ y → fp.part x = fp.part y →
|
||
∀ ⦃z : Finset V⦄, z.card = r → ∃ x ∈ ↑z, ∃ y ∈ ↑z, x ≠ y ∧ ¬G.Adj x y := by
|
||
intro fp l x y hn he z zc
|
||
simp [h.not_adj_iff_part_eq] ---- should work
|
||
sorry
|
||
|
||
end IsTuranMaximal
|
||
|
||
end SimpleGraph
|