Zulip Chat Archive
Stream: Is there code for X?
Topic: monotone functions from finset
Heather Macbeth (Aug 18 2023 at 14:31):
I couldn't find in mathlib the following characterization of monotone functions with domain a Finset
, anyone recognize it?
import Mathlib.Data.Finset.Basic
open Finset
example {α β : Type _} [DecidableEq α] [Preorder β] (f : Finset α → β) :
Monotone f ↔ ∀ s : Finset α, ∀ i, f s ≤ f (insert i s) := by
refine ⟨fun h s i ↦ ?_, fun h ↦ ?_⟩
· exact h (Finset.subset_insert i s)
· intro s
suffices : ∀ t, f s ≤ f (s ∪ t)
· intro v huv
calc f s ≤ f (s ∪ (v \ s)) := this _
_ = f v := by rw [union_sdiff_of_subset huv]
intro t
induction' t using Finset.induction with i t _hit ih
· simp
· calc f s ≤ f (s ∪ t) := ih
_ ≤ f (insert i (s ∪ t)) := h _ _
_ = f (s ∪ (insert i t)) := by rw [Finset.union_insert]
Eric Wieser (Aug 18 2023 at 14:42):
I think it should follow from some result about docs#Covby ?
Anatole Dedecker (Aug 18 2023 at 14:46):
I don't see why it would, because this really only true because you can get to any finset by a finite sequence of insertion. For example the result is false for Set
(take f s = 1
if s
is finite and f s = 0
otherwise)
Anatole Dedecker (Aug 18 2023 at 14:49):
The mathematical result is that the order on Finset
is the smallest order relation such that s ⊆ insert i s
, but I don't think we have that nor a good way to use it.
Eric Wieser (Aug 18 2023 at 14:50):
I think the version I want is
import Mathlib.Data.Finset.Basic
import Mathlib.Order.Cover
import Mathlib.Order.LocallyFinite
open Finset
lemma monotone_iff_forall_covby {α β : Type*} [Preorder α] [LocallyFiniteOrder α] [Preorder β] (f : α → β) :
Monotone f ↔ ∀ a b : α, a ⋖ b → f a ≤ f b := by
refine ⟨fun hf a b h ↦ ?_, fun h ↦ ?_⟩
· exact hf h.le
· intro a b h
-- iterate over a chain between `a` and `b`
sorry
Anatole Dedecker (Aug 18 2023 at 14:51):
Oh okay with LocallyFiniteOrder
that would work
Eric Wieser (Aug 18 2023 at 14:57):
Where the other two missing pieces are:
lemma Finset.covby_cons {α} {a : α} {s : Finset α} (h : a ∉ s) : s ⋖ cons a s h :=
⟨Finset.ssubset_cons h, fun t (hst : s ⊂ t) (hts : t ⊂ _) => sorry⟩
lemma Finset.covby_iff_eq_cons {s t : Finset α} : s ⋖ t ↔ ∃ a h, t = cons a s h :=
⟨fun h => sorry, fun ⟨a, h, h'⟩ => h' ▸ Finset.covby_cons h⟩
Heather Macbeth (Aug 18 2023 at 15:05):
By the way, while using my brand new lemma, I realised that the more convenient version is to put an extra condition i ∉ s
on the index:
theorem Finset.monotone_iff {α β : Type _} [Preorder β] (f : Finset α → β) :
Monotone f ↔ ∀ s : Finset α, ∀ {i} (hi : i ∉ s), f s ≤ f (insert i s) := by
Jireh Loreaux (Aug 18 2023 at 15:19):
Just to be clear, that makes it exactly (up to propositional equality) Covby
.
Anatole Dedecker (Aug 18 2023 at 15:23):
Eric Wieser said:
I think the version I want is
import Mathlib.Data.Finset.Basic import Mathlib.Order.Cover import Mathlib.Order.LocallyFinite open Finset lemma monotone_iff_forall_covby {α β : Type*} [Preorder α] [LocallyFiniteOrder α] [Preorder β] (f : α → β) : Monotone f ↔ ∀ a b : α, a ⋖ b → f a ≤ f b := by refine ⟨fun hf a b h ↦ ?_, fun h ↦ ?_⟩ · exact hf h.le · intro a b h -- iterate over a chain between `a` and `b` sorry
I claim that the right way to prove this is to start with:
import Mathlib.Data.Finset.Basic
import Mathlib.Order.Cover
import Mathlib.Order.LocallyFinite
open Finset
lemma foo {α : Type*} [Preorder α] [LocallyFiniteOrder α] (x y : α) :
x ≤ y ↔ Relation.ReflTransGen (· ⋖ ·) x y := by
sorry
Anatole Dedecker (Aug 18 2023 at 15:24):
Then things like docs#Relation.ReflTransGen.lift should get the monotonicity result
Anatole Dedecker (Aug 18 2023 at 15:25):
Note that we have docs#List.relationReflTransGen_of_exists_chain
Eric Wieser (Aug 18 2023 at 15:54):
Heather Macbeth said:
By the way, while using my brand new lemma, I realised that the more convenient version is to put an extra condition
i ∉ s
on the index
At that point you may as well use cons
instead of insert
, which also saves you from needing [DecidableEq α]
Yaël Dillies (Aug 18 2023 at 16:11):
btw I have a big PR with a bunch of relevant lemmas
Anatole Dedecker (Aug 18 2023 at 16:12):
What a surprise!
Jireh Loreaux (Aug 18 2023 at 16:20):
But Yaël, the key question is: is it Lean 3 or Lean 4? :smiley:
Jireh Loreaux (Aug 18 2023 at 17:37):
@Anatole Dedecker I don't think your lemma foo
is true unless you assume α
is a PartialOrder
, because if x ≠ y
but x ≤ y
and y ≤ x
, then Relation.ReflTransGen (· ⋖ ·) x y
is false because there is no strictly increasing chain from x
to y
.
Anatole Dedecker (Aug 18 2023 at 17:48):
Ah right. That problem doesn’t arise if we use docs#Wcovby though, right? But restricting to partial orders is probably fine anyway
Jireh Loreaux (Aug 18 2023 at 18:55):
Let the golfing begin, I am totally unfamiliar with this end of the library:
import Mathlib.Data.Finset.LocallyFinite
import Mathlib.Order.Cover
import Mathlib.Order.LocallyFinite
open Finset
lemma foo {α : Type*} [Preorder α] [LocallyFiniteOrder α] (x y : α) :
x ≤ y ↔ Relation.ReflTransGen (· ⩿ ·) x y := by
refine ⟨?_, fun h ↦ ?_⟩
· suffices ∀ n : ℕ, ∀ x y : α,
x ≤ y → (Icc x y).card = n → Relation.ReflTransGen (· ⩿ ·) x y by
exact fun a ↦ this (card (Icc x y)) x y a rfl
intro n
induction n using Nat.strong_induction_on with
| @h n hn =>
match n with
| 0 => exact fun x y hx h ↦ (Icc_eq_empty_iff.mp (by simpa using h) hx).elim
| 1 =>
intro x y hxy h
rw [card_eq_one] at h
obtain ⟨a, ha⟩ := h
have hx := mem_singleton.mp <| ha ▸ left_mem_Icc.mpr hxy
have hy := mem_singleton.mp <| ha ▸ right_mem_Icc.mpr hxy
substs hx hy
rfl
| k + 2 =>
intro x y hxy h
have : (Ico x y).card < k + 2 := h ▸ (card_lt_card <|
⟨Ico_subset_Icc_self, not_subset.mpr ⟨y, ⟨right_mem_Icc.mpr hxy, right_not_mem_Ico⟩⟩⟩)
by_cases hxy' : y ≤ x
· exact Relation.ReflTransGen.single
⟨hxy, fun c hxc hcy ↦ lt_irrefl c <| (hcy.trans_le hxy').trans hxc⟩
· have h_non : (Ico x y).Nonempty := ⟨x, mem_Ico.mpr ⟨le_rfl, lt_of_le_not_le hxy hxy'⟩⟩
obtain ⟨z, z_mem, hz⟩ := (Ico x y).exists_maximal h_non
have z_card : (Icc x z).card < k + 2 := calc
(Icc x z).card ≤ (Ico x y).card :=
card_le_of_subset fun w hw ↦ Icc_subset_Ico_right (mem_Ico.mp z_mem).2 hw
_ < k + 2 := this
have h₁ := hn (Icc x z).card z_card x z (mem_Ico.mp z_mem).1 rfl
have h₂ : z ⩿ y := by
refine ⟨(mem_Ico.mp z_mem).2.le, fun c hzc hcy ↦ hz c ?_ hzc⟩
exact mem_Ico.mpr <| ⟨(mem_Ico.mp z_mem).1.trans hzc.le, hcy⟩
exact Relation.ReflTransGen.tail h₁ h₂
· induction h with
| refl => rfl
| tail _ h₁ h₂ => exact h₂.trans h₁.le
Jireh Loreaux (Aug 18 2023 at 19:38):
One place I feel like there should be obvious room for improvement: I did strong induction on the cardinality of Finset.Icc x y
, but it would have been nicer if I could have used some sort of direct induction principle; I couldn't see how to make things like docs#Finset.induction_on apply in this situation though.
Anatole Dedecker (Aug 18 2023 at 20:28):
I think you really have to use cardinality here though, because you don’t know how much you decrease the cardinality at each step, so you have to use some kind of well-foundedness. Probably you could also use well foundedness of \subset
on Finset
, but I can’t think of anything else
Jireh Loreaux (Aug 18 2023 at 21:28):
Yes, the well-foundedness of ⊆
on Finset
was the kind of thing I was thinking, but I guess it's not too important.
Jireh Loreaux (Aug 18 2023 at 23:15):
@Heather Macbeth I've added a bit more below, but I haven't yet added the glue that connects covby to insert for Finset
. If you would like to clean it up and PR it, that's fine, but if you want me to I can probably do it sometime this weekend.
Heather Macbeth (Aug 18 2023 at 23:33):
@Jireh Loreaux Thank you for this nice lemma! I won't get to PR'ing it this weekend, but if you also don't I will put it on my to-do list.
Jireh Loreaux (Aug 21 2023 at 19:53):
@Heather Macbeth, @Eric Wieser, @Anatole Dedecker : #6709
Yaël Dillies (Aug 22 2023 at 06:53):
Jireh Loreaux said:
But Yaël, the key question is: is it Lean 3 or Lean 4? :smiley:
Currently Lean 3, haven't had time to port anything in the past month.
Last updated: Dec 20 2023 at 11:08 UTC