Zulip Chat Archive
Stream: Is there code for X?
Topic: Computably extending an embedding
Eric Wieser (May 20 2025 at 22:15):
Do we have something like this?
import Mathlib
variable {m n : Type*} [DecidableEq n] [Fintype m]
def Function.Embedding.equivSumRangeCompl (f : m ↪ n) : n ≃ m ⊕ ↥(Set.range f)ᶜ where
toFun i :=
-- TODO: this iterates twice rather than once
if h : i ∈ Set.range f then .inl (f.invOfMemRange ⟨i, h⟩) else .inr ⟨i, h⟩
invFun := Sum.elim f Subtype.val
left_inv i := by
dsimp
split <;> simp
right_inv
| .inl i => by simp
| .inr ⟨j, h⟩ => by
rw [Set.mem_compl_iff] at h
simp_all
Antoine Chambert-Loir (May 21 2025 at 06:29):
(to iterate only once, can you use docs#Nat.find?)
Eric Wieser (May 21 2025 at 20:49):
How do I produce the existential though?
Eric Wieser (May 21 2025 at 20:50):
To be clear, I say the above loops twice because the first is if h : i ∈ Set.range f, and the second is invOfMemRange.
Yakov Pechersky (May 21 2025 at 21:02):
Can you think of n as (Set.range f) ⊕ ((Set.range f)ᶜ : Set n) and have the equiv be using that, and then use a nasty Eq based cast Equiv to show that's the same a n?
Eric Wieser (May 21 2025 at 21:37):
I don't see what Eq you're going to use there, the range is not Eq to the domain
Eric Wieser (May 21 2025 at 21:37):
Certainly I can build the optimal version by using the Finset recursor, but this feels close to something we may already have
Eric Wieser (May 22 2025 at 00:12):
Maybe
/-- `invOfMemRange`, but returns `None` outside of the range-/
def Function.Embedding.invOption {m n : Type*} [DecidableEq n] [Fintype m] (f : m ↪ n) (i : n) : Option m :=
aux
where
aux : Option {j : m // f j = i} :=
Finset.univ.val.rec (C := fun _ : Multiset m => Option _) none
(fun x xs acc => acc <|> if h : f x = i then some ⟨x, h⟩ else none)
(fun x₁ x₂ xs acc => heq_of_eq <| by
dsimp at *
obtain _ | ⟨x, h⟩ := acc <;> aesop)
is the building block here
Bhavik Mehta (May 22 2025 at 21:16):
You could also do it like
def Finset.toOption {m : Type*} (s : Finset m) (h : (s : Set m).Subsingleton) : Option m :=
if hs : ∃ x ∈ s, True then some (s.choose (fun _ ↦ True) (existsUnique_of_exists_of_unique hs (by aesop))) else none
def Function.Embedding.invOption {m n : Type*} [DecidableEq n] [Fintype m] (f : m ↪ n) (i : n) : Option m :=
Finset.toOption {j | f j = i} <| by aesop (add simp Set.Subsingleton)
but I haven't checked if this traverses once or twice
Eric Wieser (May 22 2025 at 21:20):
That would surely also be twice
Eric Wieser (May 22 2025 at 21:21):
Oh, I guess it's once on the full list, then twice on the singleton
Bhavik Mehta (May 22 2025 at 21:29):
Right, that was my exact hope
Last updated: Dec 20 2025 at 21:32 UTC