Skip to content

Commit

Permalink
feat(data/finset/basic, lattice): Simple lemmas (#9723)
Browse files Browse the repository at this point in the history
This proves lemmas about `finset.sup`/`finset.inf` and `finset.singleton`.
  • Loading branch information
YaelDillies committed Oct 16, 2021
1 parent bf34d9b commit e744033
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 6 deletions.
29 changes: 28 additions & 1 deletion src/data/finset/basic.lean
Expand Up @@ -402,8 +402,11 @@ theorem not_mem_singleton {a b : α} : a ∉ ({b} : finset α) ↔ a ≠ b := no

theorem mem_singleton_self (a : α) : a ∈ ({a} : finset α) := or.inl rfl

lemma singleton_injective : injective (singleton : α → finset α) :=
λ a b h, mem_singleton.1 (h ▸ mem_singleton_self _)

theorem singleton_inj {a b : α} : ({a} : finset α) = {b} ↔ a = b :=
⟨λ h, mem_singleton.1 (h ▸ mem_singleton_self _), congr_arg _⟩
singleton_injective.eq_iff

@[simp] theorem singleton_nonempty (a : α) : ({a} : finset α).nonempty := ⟨a, mem_singleton_self a⟩

Expand Down Expand Up @@ -644,6 +647,21 @@ theorem induction_on' {α : Type*} {p : finset α → Prop} [decidable_eq α]
@finset.induction_on α (λ T, T ⊆ S → p T) _ S (λ _, h₁) (λ a s has hqs hs,
let ⟨hS, sS⟩ := finset.insert_subset.1 hs in h₂ hS sS has (hqs sS)) (finset.subset.refl S)

/-- To prove a proposition about a nonempty `s : finset α`, it suffices to show it holds for all
singletons and that if it holds for `t : finset α`, then it also holds for the `finset` obtained by
inserting an element in `t`. -/
@[elab_as_eliminator]
lemma nonempty.cons_induction {α : Type*} {s : finset α} (hs : s.nonempty) {p : finset α → Prop}
(h₀ : ∀ a, p {a}) (h₁ : ∀ ⦃a⦄ s (h : a ∉ s), p s → p (finset.cons a s h)) :
p s :=
begin
induction s using finset.cons_induction with a t ha h,
{ exact (not_nonempty_empty hs).elim, },
obtain rfl | ht := t.eq_empty_or_nonempty,
{ exact h₀ a },
{ exact h₁ t ha (h ht) }
end

/-- Inserting an element to a finite set is equivalent to the option type. -/
def subtype_insert_equiv_option {t : finset α} {x : α} (h : x ∉ t) :
{i // i ∈ insert x t} ≃ option {i // i ∈ t} :=
Expand Down Expand Up @@ -2170,6 +2188,8 @@ card_eq_zero.trans val_eq_zero
theorem card_pos {s : finset α} : 0 < card s ↔ s.nonempty :=
pos_iff_ne_zero.trans $ (not_congr card_eq_zero).trans nonempty_iff_ne_empty.symm

alias finset.card_pos ↔ _ finset.nonempty.card_pos

theorem card_ne_zero_of_mem {s : finset α} {a : α} (h : a ∈ s) : card s ≠ 0 :=
(not_congr card_eq_zero).2 (ne_empty_of_mem h)

Expand Down Expand Up @@ -2794,6 +2814,13 @@ by rw [disjoint.comm, disjoint_left]
theorem disjoint_iff_ne {s t : finset α} : disjoint s t ↔ ∀ a ∈ s, ∀ b ∈ t, a ≠ b :=
by simp only [disjoint_left, imp_not_comm, forall_eq']

lemma not_disjoint_iff {s t : finset α} :
¬disjoint s t ↔ ∃ a, a ∈ s ∧ a ∈ t :=
not_forall.trans $ exists_congr $ λ a, begin
rw [finset.inf_eq_inter, finset.mem_inter],
exact not_not,
end

theorem disjoint_of_subset_left {s t u : finset α} (h : s ⊆ u) (d : disjoint u t) : disjoint s t :=
disjoint_left.2 (λ x m₁, (disjoint_left.1 d) (h m₁))

Expand Down
79 changes: 74 additions & 5 deletions src/data/finset/lattice.lean
Expand Up @@ -25,7 +25,7 @@ variables [semilattice_sup_bot α]
/-- Supremum of a finite set: `sup {a, b, c} f = f a ⊔ f b ⊔ f c` -/
def sup (s : finset β) (f : β → α) : α := s.fold (⊔) ⊥ f

variables {s s₁ s₂ : finset β} {f : β → α}
variables {s s₁ s₂ : finset β} {f g : β → α}

lemma sup_def : s.sup f = (s.1.map f).sup := rfl

Expand All @@ -38,7 +38,7 @@ fold_cons h
@[simp] lemma sup_insert [decidable_eq β] {b : β} : (insert b s : finset β).sup f = f b ⊔ s.sup f :=
fold_insert_idem

lemma sup_image [decidable_eq β] (s : finset γ) (f : γ → β) (g : β → α):
lemma sup_image [decidable_eq β] (s : finset γ) (f : γ → β) (g : β → α) :
(s.image f).sup g = s.sup (g ∘ f) :=
fold_image_idem

Expand All @@ -53,6 +53,14 @@ lemma sup_union [decidable_eq β] : (s₁ ∪ s₂).sup f = s₁.sup f ⊔ s₂.
finset.induction_on s₁ (by rw [empty_union, sup_empty, bot_sup_eq]) $ λ a s has ih,
by rw [insert_union, sup_insert, sup_insert, ih, sup_assoc]

lemma sup_sup : s.sup (f ⊔ g) = s.sup f ⊔ s.sup g :=
begin
refine finset.cons_induction_on s _ (λ b t _ h, _),
{ rw [sup_empty, sup_empty, sup_empty, bot_sup_eq] },
{ rw [sup_cons, sup_cons, sup_cons, h],
exact sup_sup_sup_comm _ _ _ _ }
end

theorem sup_congr {f g : β → α} (hs : s₁ = s₂) (hfg : ∀a∈s₂, f a = g a) : s₁.sup f = s₂.sup g :=
by subst hs; exact finset.fold_congr hfg

Expand Down Expand Up @@ -98,6 +106,26 @@ sup_le $ assume b hb, le_sup (h hb)
(λ h, ⟨c, or.inl rfl, h⟩) (λ h, let ⟨b, hb, hlt⟩ := ih h in ⟨b, or.inr hb, hlt⟩)),
(λ ⟨b, hb, hlt⟩, lt_of_lt_of_le hlt (le_sup hb))⟩

@[simp] lemma sup_attach (s : finset β) (f : β → α) : s.attach.sup (λ x, f x) = s.sup f :=
(s.attach.sup_map (function.embedding.subtype _) f).symm.trans $ congr_arg _ attach_map_val

@[simp] lemma sup_erase_bot [decidable_eq α] (s : finset α) : (s.erase ⊥).sup id = s.sup id :=
begin
refine (sup_mono (s.erase_subset _)).antisymm (finset.sup_le_iff.2 $ λ a ha, _),
obtain rfl | ha' := eq_or_ne a ⊥,
{ exact bot_le },
{ exact le_sup (mem_erase.2 ⟨ha', ha⟩) }
end

lemma sup_sdiff_right {α β : Type*} [generalized_boolean_algebra α] (s : finset β) (f : β → α)
(a : α) :
s.sup (λ b, f b \ a) = s.sup f \ a :=
begin
refine finset.cons_induction_on s _ (λ b t _ h, _),
{ rw [sup_empty, sup_empty, bot_sdiff] },
{ rw [sup_cons, sup_cons, h, sup_sdiff] }
end

lemma comp_sup_eq_sup_comp [semilattice_sup_bot γ] {s : finset β}
{f : β → α} (g : α → γ) (g_sup : ∀ x y, g (x ⊔ y) = g x ⊔ g y) (bot : g ⊥ = ⊥) :
g (s.sup f) = s.sup (g ∘ f) :=
Expand Down Expand Up @@ -137,7 +165,7 @@ begin
end

lemma sup_le_of_le_directed {α : Type*} [semilattice_sup_bot α] (s : set α)
(hs : s.nonempty) (hdir : directed_on (≤) s) (t : finset α):
(hs : s.nonempty) (hdir : directed_on (≤) s) (t : finset α) :
(∀ x ∈ t, ∃ y ∈ s, x ≤ y) → ∃ x, x ∈ s ∧ t.sup id ≤ x :=
begin
classical,
Expand Down Expand Up @@ -188,7 +216,7 @@ variables [semilattice_inf_top α]
/-- Infimum of a finite set: `inf {a, b, c} f = f a ⊓ f b ⊓ f c` -/
def inf (s : finset β) (f : β → α) : α := s.fold (⊓) ⊤ f

variables {s s₁ s₂ : finset β} {f : β → α}
variables {s s₁ s₂ : finset β} {f g : β → α}

lemma inf_def : s.inf f = (s.1.map f).inf := rfl

Expand All @@ -201,7 +229,7 @@ fold_empty
@[simp] lemma inf_insert [decidable_eq β] {b : β} : (insert b s : finset β).inf f = f b ⊓ s.inf f :=
fold_insert_idem

lemma inf_image [decidable_eq β] (s : finset γ) (f : γ → β) (g : β → α):
lemma inf_image [decidable_eq β] (s : finset γ) (f : γ → β) (g : β → α) :
(s.image f).inf g = s.inf (g ∘ f) :=
fold_image_idem

Expand All @@ -215,6 +243,9 @@ inf_singleton
lemma inf_union [decidable_eq β] : (s₁ ∪ s₂).inf f = s₁.inf f ⊓ s₂.inf f :=
@sup_union (order_dual α) _ _ _ _ _ _

lemma inf_inf : s.inf (f ⊓ g) = s.inf f ⊓ s.inf g :=
@sup_sup (order_dual α) _ _ _ _ _

theorem inf_congr {f g : β → α} (hs : s₁ = s₂) (hfg : ∀a∈s₂, f a = g a) : s₁.inf f = s₂.inf g :=
by subst hs; exact finset.fold_congr hfg

Expand Down Expand Up @@ -249,6 +280,38 @@ le_inf $ assume b hb, inf_le (h hb)
@[simp] lemma inf_lt_iff [is_total α (≤)] {a : α} : s.inf f < a ↔ (∃ b ∈ s, f b < a) :=
@lt_sup_iff (order_dual α) _ _ _ _ _ _

lemma inf_attach (s : finset β) (f : β → α) : s.attach.inf (λ x, f x) = s.inf f :=
@sup_attach (order_dual α) _ _ _ _

@[simp] lemma inf_erase_top [decidable_eq α] (s : finset α) : (s.erase ⊤).inf id = s.inf id :=
@sup_erase_bot (order_dual α) _ _ _

lemma sup_sdiff_left {α β : Type*} [boolean_algebra α] (s : finset β) (f : β → α) (a : α) :
s.sup (λ b, a \ f b) = a \ s.inf f :=
begin
refine finset.cons_induction_on s _ (λ b t _ h, _),
{ rw [sup_empty, inf_empty, sdiff_top] },
{ rw [sup_cons, inf_cons, h, sdiff_inf] }
end

lemma inf_sdiff_left {α β : Type*} [boolean_algebra α] {s : finset β} (hs : s.nonempty) (f : β → α)
(a : α) :
s.inf (λ b, a \ f b) = a \ s.sup f :=
begin
refine hs.cons_induction (λ b, _) (λ b t _ h, _),
{ rw [sup_singleton, inf_singleton] },
{ rw [sup_cons, inf_cons, h, sdiff_sup] }
end

lemma inf_sdiff_right {α β : Type*} [boolean_algebra α] {s : finset β} (hs : s.nonempty) (f : β → α)
(a : α) :
s.inf (λ b, f b \ a) = s.inf f \ a :=
begin
refine hs.cons_induction (λ b, _) (λ b t _ h, _),
{ rw [inf_singleton, inf_singleton] },
{ rw [inf_cons, inf_cons, h, inf_sdiff] }
end

lemma comp_inf_eq_inf_comp [semilattice_inf_top γ] {s : finset β}
{f : β → α} (g : α → γ) (g_inf : ∀ x y, g (x ⊓ y) = g x ⊓ g y) (top : g ⊤ = ⊤) :
g (s.inf f) = s.inf (g ∘ f) :=
Expand Down Expand Up @@ -892,6 +955,12 @@ lemma sup_eq_bUnion {α β} [decidable_eq β] (s : finset α) (t : α → finset
s.sup t = s.bUnion t :=
by { ext, rw [mem_sup, mem_bUnion], }

@[simp] lemma sup_singleton' [decidable_eq α] (s : finset α) : s.sup singleton = s :=
begin
refine (finset.sup_le $ λ a, _).antisymm (λ a ha, mem_sup.2 ⟨a, ha, mem_singleton_self a⟩),
exact singleton_subset_iff.2,
end

end finset

section lattice
Expand Down
6 changes: 6 additions & 0 deletions src/order/lattice.lean
Expand Up @@ -234,6 +234,9 @@ by rw [← sup_assoc, ← sup_assoc, @sup_comm α _ a]
lemma sup_right_comm (a b c : α) : a ⊔ b ⊔ c = a ⊔ c ⊔ b :=
by rw [sup_assoc, sup_assoc, @sup_comm _ _ b]

lemma sup_sup_sup_comm (a b c d : α) : a ⊔ b ⊔ (c ⊔ d) = a ⊔ c ⊔ (b ⊔ d) :=
by rw [sup_assoc, sup_left_comm b, ←sup_assoc]

lemma forall_le_or_exists_lt_sup (a : α) : (∀b, b ≤ a) ∨ (∃b, a < b) :=
suffices (∃b, ¬b ≤ a) → (∃b, a < b),
by rwa [or_iff_not_imp_left, not_forall],
Expand Down Expand Up @@ -389,6 +392,9 @@ lemma inf_left_comm (a b c : α) : a ⊓ (b ⊓ c) = b ⊓ (a ⊓ c) :=
lemma inf_right_comm (a b c : α) : a ⊓ b ⊓ c = a ⊓ c ⊓ b :=
@sup_right_comm (order_dual α) _ a b c

lemma inf_inf_inf_comm (a b c d : α) : a ⊓ b ⊓ (c ⊓ d) = a ⊓ c ⊓ (b ⊓ d) :=
@sup_sup_sup_comm (order_dual α) _ _ _ _ _

lemma forall_le_or_exists_lt_inf (a : α) : (∀b, a ≤ b) ∨ (∃b, b < a) :=
@forall_le_or_exists_lt_sup (order_dual α) _ a

Expand Down

0 comments on commit e744033

Please sign in to comment.