Skip to content

Commit a2fd24f

Browse files
committed
feat(Finset/{NAry,Pointwise}): add lemmas about Finset.sup etc (#8950)
1 parent f03d073 commit a2fd24f

File tree

4 files changed

+199
-21
lines changed

4 files changed

+199
-21
lines changed

Mathlib/Data/Finset/Image.lean

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,8 @@ theorem fin_map {n} {s : Finset ℕ} : (s.fin n).map Fin.valEmbedding = s.filter
818818
simp [Finset.fin, Finset.map_map]
819819
#align finset.fin_map Finset.fin_map
820820

821+
/-- If a `Finset` is a subset of the image of a `Set` under `f`,
822+
then it is equal to the `Finset.image` of a `Finset` subset of that `Set`. -/
821823
theorem subset_image_iff [DecidableEq β] {s : Set α} {t : Finset β} {f : α → β} :
822824
↑t ⊆ f '' s ↔ ∃ s' : Finset α, ↑s' ⊆ s ∧ s'.image f = t := by
823825
constructor; swap

Mathlib/Data/Finset/Lattice.lean

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -856,13 +856,13 @@ protected theorem sup'_comm {t : Finset γ} (hs : s.Nonempty) (ht : t.Nonempty)
856856
eq_of_forall_ge_iff fun a => by simpa using forall₂_swap
857857
#align finset.sup'_comm Finset.sup'_comm
858858

859-
theorem sup'_product_left {t : Finset γ} (hs : s.Nonempty) (ht : t.Nonempty) (f : β × γ → α) :
860-
(s ×ˢ t).sup' (hs.product ht) f = s.sup' hs fun i => t.sup' ht fun i' => f ⟨i, i'⟩ :=
859+
theorem sup'_product_left {t : Finset γ} (h : (s ×ˢ t).Nonempty) (f : β × γ → α) :
860+
(s ×ˢ t).sup' h f = s.sup' h.fst fun i => t.sup' h.snd fun i' => f ⟨i, i'⟩ :=
861861
eq_of_forall_ge_iff fun a => by simp [@forall_swap _ γ]
862862
#align finset.sup'_product_left Finset.sup'_product_left
863863

864-
theorem sup'_product_right {t : Finset γ} (hs : s.Nonempty) (ht : t.Nonempty) (f : β × γ → α) :
865-
(s ×ˢ t).sup' (hs.product ht) f = t.sup' ht fun i' => s.sup' hs fun i => f ⟨i, i'⟩ := by
864+
theorem sup'_product_right {t : Finset γ} (h : (s ×ˢ t).Nonempty) (f : β × γ → α) :
865+
(s ×ˢ t).sup' h f = t.sup' h.snd fun i' => s.sup' h.fst fun i => f ⟨i, i'⟩ := by
866866
rw [sup'_product_left, Finset.sup'_comm]
867867
#align finset.sup'_product_right Finset.sup'_product_right
868868

@@ -1035,14 +1035,14 @@ protected theorem inf'_comm {t : Finset γ} (hs : s.Nonempty) (ht : t.Nonempty)
10351035
@Finset.sup'_comm αᵒᵈ _ _ _ _ _ hs ht _
10361036
#align finset.inf'_comm Finset.inf'_comm
10371037

1038-
theorem inf'_product_left {t : Finset γ} (hs : s.Nonempty) (ht : t.Nonempty) (f : β × γ → α) :
1039-
(s ×ˢ t).inf' (hs.product ht) f = s.inf' hs fun i => t.inf' ht fun i' => f ⟨i, i'⟩ :=
1040-
@sup'_product_left αᵒᵈ _ _ _ _ _ hs ht _
1038+
theorem inf'_product_left {t : Finset γ} (h : (s ×ˢ t).Nonempty) (f : β × γ → α) :
1039+
(s ×ˢ t).inf' h f = s.inf' h.fst fun i => t.inf' h.snd fun i' => f ⟨i, i'⟩ :=
1040+
sup'_product_left (α := αᵒᵈ) h f
10411041
#align finset.inf'_product_left Finset.inf'_product_left
10421042

1043-
theorem inf'_product_right {t : Finset γ} (hs : s.Nonempty) (ht : t.Nonempty) (f : β × γ → α) :
1044-
(s ×ˢ t).inf' (hs.product ht) f = t.inf' ht fun i' => s.inf' hs fun i => f ⟨i, i'⟩ :=
1045-
@sup'_product_right αᵒᵈ _ _ _ _ _ hs ht _
1043+
theorem inf'_product_right {t : Finset γ} (h : (s ×ˢ t).Nonempty) (f : β × γ → α) :
1044+
(s ×ˢ t).inf' h f = t.inf' h.snd fun i' => s.inf' h.fst fun i => f ⟨i, i'⟩ :=
1045+
sup'_product_right (α := αᵒᵈ) h f
10461046
#align finset.inf'_product_right Finset.inf'_product_right
10471047

10481048
section Prod
@@ -1219,7 +1219,7 @@ theorem sup'_inf_distrib_right (f : ι → α) (a : α) : s.sup' hs f ⊓ a = s.
12191219

12201220
theorem sup'_inf_sup' (f : ι → α) (g : κ → α) :
12211221
s.sup' hs f ⊓ t.sup' ht g = (s ×ˢ t).sup' (hs.product ht) fun i => f i.1 ⊓ g i.2 := by
1222-
simp_rw [Finset.sup'_inf_distrib_right, Finset.sup'_inf_distrib_left, sup'_product_left hs ht]
1222+
simp_rw [Finset.sup'_inf_distrib_right, Finset.sup'_inf_distrib_left, sup'_product_left]
12231223
#align finset.sup'_inf_sup' Finset.sup'_inf_sup'
12241224

12251225
theorem inf'_sup_distrib_left (f : ι → α) (a : α) : a ⊔ s.inf' hs f = s.inf' hs fun i => a ⊔ f i :=

Mathlib/Data/Finset/NAry.lean

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -317,15 +317,12 @@ theorem image₂_mk_eq_product [DecidableEq α] [DecidableEq β] (s : Finset α)
317317

318318
@[simp]
319319
theorem image₂_curry (f : α × β → γ) (s : Finset α) (t : Finset β) :
320-
image₂ (curry f) s t = (s ×ˢ t).image f := by
321-
classical
322-
rw [← image₂_mk_eq_product, image_image₂]
323-
dsimp (config := { unfoldPartialApp := true }) [curry]
320+
image₂ (curry f) s t = (s ×ˢ t).image f := rfl
324321
#align finset.image₂_curry Finset.image₂_curry
325322

326323
@[simp]
327324
theorem image_uncurry_product (f : α → β → γ) (s : Finset α) (t : Finset β) :
328-
(s ×ˢ t).image (uncurry f) = image₂ f s t := by rw [← image₂_curry, curry_uncurry]
325+
(s ×ˢ t).image (uncurry f) = image₂ f s t := rfl
329326
#align finset.image_uncurry_product Finset.image_uncurry_product
330327

331328
theorem image₂_swap (f : α → β → γ) (s : Finset α) (t : Finset β) :
@@ -529,6 +526,8 @@ theorem card_dvd_card_image₂_left (hf : ∀ b ∈ t, Injective fun a => f a b)
529526
s.card ∣ (image₂ f s t).card := by rw [← image₂_swap]; exact card_dvd_card_image₂_right hf ht
530527
#align finset.card_dvd_card_image₂_left Finset.card_dvd_card_image₂_left
531528

529+
/-- If a `Finset` is a subset of the image of two `Set`s under a binary operation,
530+
then it is a subset of the `Finset.image₂` of two `Finset` subsets of these `Set`s. -/
532531
theorem subset_image₂ {s : Set α} {t : Set β} (hu : ↑u ⊆ image2 f s t) :
533532
∃ (s' : Finset α) (t' : Finset β), ↑s' ⊆ s ∧ ↑t' ⊆ t ∧ u ⊆ image₂ f s' t' := by
534533
rw [← Set.image_prod, subset_image_iff] at hu
@@ -540,6 +539,8 @@ theorem subset_image₂ {s : Set α} {t : Set β} (hu : ↑u ⊆ image2 f s t) :
540539
exact ⟨fun _ h ↦ (hu h).1, fun _ h ↦ (hu h).2, fun x hx ↦ mem_image₂_of_mem hx hx⟩
541540
#align finset.subset_image₂ Finset.subset_image₂
542541

542+
section UnionInter
543+
543544
variable [DecidableEq α] [DecidableEq β]
544545

545546
theorem image₂_inter_union_subset_union :
@@ -570,6 +571,80 @@ theorem image₂_union_inter_subset {f : α → α → β} {s t : Finset α} (hf
570571
exact image2_union_inter_subset hf
571572
#align finset.image₂_union_inter_subset Finset.image₂_union_inter_subset
572573

574+
end UnionInter
575+
576+
section SemilatticeSup
577+
578+
variable [SemilatticeSup δ]
579+
580+
@[simp (default + 1)] -- otherwise `simp` doesn't use `forall_image₂_iff`
581+
lemma sup'_image₂_le {g : γ → δ} {a : δ} (h : (image₂ f s t).Nonempty) :
582+
sup' (image₂ f s t) h g ≤ a ↔ ∀ x ∈ s, ∀ y ∈ t, g (f x y) ≤ a := by
583+
rw [sup'_le_iff, forall_image₂_iff]
584+
585+
lemma sup'_image₂_left (g : γ → δ) (h : (image₂ f s t).Nonempty) :
586+
sup' (image₂ f s t) h g =
587+
sup' s h.of_image₂_left fun x ↦ sup' t h.of_image₂_right (g <| f x ·) := by
588+
simp only [image₂, sup'_image, sup'_product_left]; rfl
589+
590+
lemma sup'_image₂_right (g : γ → δ) (h : (image₂ f s t).Nonempty) :
591+
sup' (image₂ f s t) h g =
592+
sup' t h.of_image₂_right fun y ↦ sup' s h.of_image₂_left (g <| f · y) := by
593+
simp only [image₂, sup'_image, sup'_product_right]; rfl
594+
595+
variable [OrderBot δ]
596+
597+
@[simp (default + 1)] -- otherwise `simp` doesn't use `forall_image₂_iff`
598+
lemma sup_image₂_le {g : γ → δ} {a : δ} :
599+
sup (image₂ f s t) g ≤ a ↔ ∀ x ∈ s, ∀ y ∈ t, g (f x y) ≤ a := by
600+
rw [Finset.sup_le_iff, forall_image₂_iff]
601+
602+
variable (s t)
603+
604+
lemma sup_image₂_left (g : γ → δ) : sup (image₂ f s t) g = sup s fun x ↦ sup t (g <| f x ·) := by
605+
simp only [image₂, sup_image, sup_product_left]; rfl
606+
607+
lemma sup_image₂_right (g : γ → δ) : sup (image₂ f s t) g = sup t fun y ↦ sup s (g <| f · y) := by
608+
simp only [image₂, sup_image, sup_product_right]; rfl
609+
610+
end SemilatticeSup
611+
612+
section SemilatticeInf
613+
614+
variable [SemilatticeInf δ]
615+
616+
@[simp (default + 1)] -- otherwise `simp` doesn't use `forall_image₂_iff`
617+
lemma le_inf'_image₂ {g : γ → δ} {a : δ} (h : (image₂ f s t).Nonempty) :
618+
a ≤ inf' (image₂ f s t) h g ↔ ∀ x ∈ s, ∀ y ∈ t, a ≤ g (f x y) := by
619+
rw [le_inf'_iff, forall_image₂_iff]
620+
621+
lemma inf'_image₂_left (g : γ → δ) (h : (image₂ f s t).Nonempty) :
622+
inf' (image₂ f s t) h g =
623+
inf' s h.of_image₂_left fun x ↦ inf' t h.of_image₂_right (g <| f x ·) :=
624+
sup'_image₂_left (δ := δᵒᵈ) g h
625+
626+
lemma inf'_image₂_right (g : γ → δ) (h : (image₂ f s t).Nonempty) :
627+
inf' (image₂ f s t) h g =
628+
inf' t h.of_image₂_right fun y ↦ inf' s h.of_image₂_left (g <| f · y) :=
629+
sup'_image₂_right (δ := δᵒᵈ) g h
630+
631+
variable [OrderTop δ]
632+
633+
@[simp (default + 1)] -- otherwise `simp` doesn't use `forall_image₂_iff`
634+
lemma le_inf_image₂ {g : γ → δ} {a : δ} :
635+
a ≤ inf (image₂ f s t) g ↔ ∀ x ∈ s, ∀ y ∈ t, a ≤ g (f x y) :=
636+
sup_image₂_le (δ := δᵒᵈ)
637+
638+
variable (s t)
639+
640+
lemma inf_image₂_left (g : γ → δ) : inf (image₂ f s t) g = inf s fun x ↦ inf t (g ∘ f x) :=
641+
sup_image₂_left (δ := δᵒᵈ) ..
642+
643+
lemma inf_image₂_right (g : γ → δ) : inf (image₂ f s t) g = inf t fun y ↦ inf s (g <| f · y) :=
644+
sup_image₂_right (δ := δᵒᵈ) ..
645+
646+
end SemilatticeInf
647+
573648
end Finset
574649

575650
open Finset

Mathlib/Data/Finset/Pointwise.lean

Lines changed: 106 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ namespace Finset
6565

6666
/-! ### `0`/`1` as finsets -/
6767

68-
6968
section One
7069

7170
variable [One α] {s : Finset α} {a : α}
@@ -169,18 +168,41 @@ theorem singletonOneHom_apply (a : α) : singletonOneHom a = {a} :=
169168

170169
/-- Lift a `OneHom` to `Finset` via `image`. -/
171170
@[to_additive (attr := simps) "Lift a `ZeroHom` to `Finset` via `image`"]
172-
def imageOneHom [DecidableEq β] [One β] [OneHomClass F α β] (f : F) : OneHom (Finset α) (Finset β)
173-
where
171+
def imageOneHom [DecidableEq β] [One β] [OneHomClass F α β] (f : F) :
172+
OneHom (Finset α) (Finset β) where
174173
toFun := Finset.image f
175174
map_one' := by rw [image_one, map_one, singleton_one]
176175
#align finset.image_one_hom Finset.imageOneHom
177176
#align finset.image_zero_hom Finset.imageZeroHom
178177

178+
@[to_additive (attr := simp)]
179+
lemma sup_one [SemilatticeSup β] [OrderBot β] (f : α → β) : sup 1 f = f 1 := sup_singleton
180+
181+
@[to_additive (attr := simp)]
182+
lemma sup'_one [SemilatticeSup β] (f : α → β) : sup' 1 one_nonempty f = f 1 := rfl
183+
184+
@[to_additive (attr := simp)]
185+
lemma inf_one [SemilatticeInf β] [OrderTop β] (f : α → β) : inf 1 f = f 1 := inf_singleton
186+
187+
@[to_additive (attr := simp)]
188+
lemma inf'_one [SemilatticeInf β] (f : α → β) : inf' 1 one_nonempty f = f 1 := rfl
189+
190+
@[to_additive (attr := simp)]
191+
lemma max_one [LinearOrder α] : (1 : Finset α).max = 1 := rfl
192+
193+
@[to_additive (attr := simp)]
194+
lemma min_one [LinearOrder α] : (1 : Finset α).min = 1 := rfl
195+
196+
@[to_additive (attr := simp)]
197+
lemma max'_one [LinearOrder α] : (1 : Finset α).max' one_nonempty = 1 := rfl
198+
199+
@[to_additive (attr := simp)]
200+
lemma min'_one [LinearOrder α] : (1 : Finset α).min' one_nonempty = 1 := rfl
201+
179202
end One
180203

181204
/-! ### Finset negation/inversion -/
182205

183-
184206
section Inv
185207

186208
variable [DecidableEq α] [Inv α] {s s₁ s₂ t t₁ t₂ u : Finset α} {a b : α}
@@ -260,6 +282,26 @@ theorem inv_insert (a : α) (s : Finset α) : (insert a s)⁻¹ = insert a⁻¹
260282
#align finset.inv_insert Finset.inv_insert
261283
#align finset.neg_insert Finset.neg_insert
262284

285+
@[to_additive (attr := simp)]
286+
lemma sup_inv [SemilatticeSup β] [OrderBot β] (s : Finset α) (f : α → β) :
287+
sup s⁻¹ f = sup s (f ·⁻¹) :=
288+
sup_image ..
289+
290+
@[to_additive (attr := simp)]
291+
lemma sup'_inv [SemilatticeSup β] {s : Finset α} (hs : s⁻¹.Nonempty) (f : α → β) :
292+
sup' s⁻¹ hs f = sup' s hs.of_inv (f ·⁻¹) :=
293+
sup'_image ..
294+
295+
@[to_additive (attr := simp)]
296+
lemma inf_inv [SemilatticeInf β] [OrderTop β] (s : Finset α) (f : α → β) :
297+
inf s⁻¹ f = inf s (f ·⁻¹) :=
298+
inf_image ..
299+
300+
@[to_additive (attr := simp)]
301+
lemma inf'_inv [SemilatticeInf β] {s : Finset α} (hs : s⁻¹.Nonempty) (f : α → β) :
302+
inf' s⁻¹ hs f = inf' s hs.of_inv (f ·⁻¹) :=
303+
inf'_image ..
304+
263305
@[to_additive] lemma image_op_inv (s : Finset α) : s⁻¹.image op = (s.image op)⁻¹ :=
264306
image_comm op_inv
265307

@@ -520,11 +562,40 @@ def imageMulHom : Finset α →ₙ* Finset β where
520562
#align finset.image_mul_hom Finset.imageMulHom
521563
#align finset.image_add_hom Finset.imageAddHom
522564

565+
@[to_additive (attr := simp (default + 1))]
566+
lemma sup_mul_le [SemilatticeSup β] [OrderBot β] {s t : Finset α} {f : α → β} {a : β} :
567+
sup (s * t) f ≤ a ↔ ∀ x ∈ s, ∀ y ∈ t, f (x * y) ≤ a :=
568+
sup_image₂_le
569+
570+
@[to_additive]
571+
lemma sup_mul_left [SemilatticeSup β] [OrderBot β] (s t : Finset α) (f : α → β) :
572+
sup (s * t) f = sup s fun x ↦ sup t (f <| x * ·) :=
573+
sup_image₂_left ..
574+
575+
@[to_additive]
576+
lemma sup_mul_right [SemilatticeSup β] [OrderBot β] (s t : Finset α) (f : α → β) :
577+
sup (s * t) f = sup t fun y ↦ sup s (f <| · * y) :=
578+
sup_image₂_right ..
579+
580+
@[to_additive (attr := simp (default + 1))]
581+
lemma le_inf_mul [SemilatticeInf β] [OrderTop β] {s t : Finset α} {f : α → β} {a : β} :
582+
a ≤ inf (s * t) f ↔ ∀ x ∈ s, ∀ y ∈ t, a ≤ f (x * y) :=
583+
le_inf_image₂
584+
585+
@[to_additive]
586+
lemma inf_mul_left [SemilatticeInf β] [OrderTop β] (s t : Finset α) (f : α → β) :
587+
inf (s * t) f = inf s fun x ↦ inf t (f <| x * ·) :=
588+
inf_image₂_left ..
589+
590+
@[to_additive]
591+
lemma inf_mul_right [SemilatticeInf β] [OrderTop β] (s t : Finset α) (f : α → β) :
592+
inf (s * t) f = inf t fun y ↦ inf s (f <| · * y) :=
593+
inf_image₂_right ..
594+
523595
end Mul
524596

525597
/-! ### Finset subtraction/division -/
526598

527-
528599
section Div
529600

530601
variable [DecidableEq α] [Div α] {s s₁ s₂ t t₁ t₂ u : Finset α} {a b : α}
@@ -709,6 +780,36 @@ theorem subset_div {s t : Set α} :
709780
#align finset.subset_div Finset.subset_div
710781
#align finset.subset_sub Finset.subset_sub
711782

783+
@[to_additive (attr := simp (default + 1))]
784+
lemma sup_div_le [SemilatticeSup β] [OrderBot β] {s t : Finset α} {f : α → β} {a : β} :
785+
sup (s / t) f ≤ a ↔ ∀ x ∈ s, ∀ y ∈ t, f (x / y) ≤ a :=
786+
sup_image₂_le
787+
788+
@[to_additive]
789+
lemma sup_div_left [SemilatticeSup β] [OrderBot β] (s t : Finset α) (f : α → β) :
790+
sup (s / t) f = sup s fun x ↦ sup t (f <| x / ·) :=
791+
sup_image₂_left ..
792+
793+
@[to_additive]
794+
lemma sup_div_right [SemilatticeSup β] [OrderBot β] (s t : Finset α) (f : α → β) :
795+
sup (s / t) f = sup t fun y ↦ sup s (f <| · / y) :=
796+
sup_image₂_right ..
797+
798+
@[to_additive (attr := simp (default + 1))]
799+
lemma le_inf_div [SemilatticeInf β] [OrderTop β] {s t : Finset α} {f : α → β} {a : β} :
800+
a ≤ inf (s / t) f ↔ ∀ x ∈ s, ∀ y ∈ t, a ≤ f (x / y) :=
801+
le_inf_image₂
802+
803+
@[to_additive]
804+
lemma inf_div_left [SemilatticeInf β] [OrderTop β] (s t : Finset α) (f : α → β) :
805+
inf (s / t) f = inf s fun x ↦ inf t (f <| x / ·) :=
806+
inf_image₂_left ..
807+
808+
@[to_additive]
809+
lemma inf_div_right [SemilatticeInf β] [OrderTop β] (s t : Finset α) (f : α → β) :
810+
inf (s / t) f = inf t fun y ↦ inf s (f <| · / y) :=
811+
inf_image₂_right ..
812+
712813
end Div
713814

714815
/-! ### Instances -/

0 commit comments

Comments
 (0)