Zulip Chat Archive
Stream: Is there code for X?
Topic: Convert functions between subsets to functions between types
Wen Yang (Oct 01 2023 at 12:36):
I find it more convenient to work on types than subtypes in Lean. However, some functions are naturally defined on subsets, which are defined as subtypes. Therefore, I hope there is a natural way to convert these functions to functions defined on types. I don't know if there is already a solution in mathlib4, at least I didn't find one. So I wrote one and submitted a PR. The main definition is as follows:
import Mathlib.Topology.ContinuousOn
set_option autoImplicit true
open Set Function
variable {s : Set α} {t : Set β} [Nonempty ↑t] [DecidablePred (· ∈ s)]
noncomputable def Function.toval (f : s → t) [DecidablePred (· ∈ s)] : α → β := by
have ht : Set.Nonempty t := by rw [← @nonempty_coe_sort]; assumption
let y := ht.some
exact fun x =>
if hx : x ∈ s then (f ⟨x, hx⟩).val
else y
See https://github.com/leanprover-community/mathlib4/pull/7449 for more details.
I wonder if we could add this to mathlib4.
Yaël Dillies (Oct 01 2023 at 12:39):
You could use docs#Function.extend. Precisely, Function.toval f = Function.extend f fun _ ↦ (Set.nonempty_coe_sort.1 ‹_›).some
.
Wen Yang (Oct 01 2023 at 13:17):
Thanks, Yaël Dillies. Unfortunately, Function.extend f fun _ ↦ (Set.nonempty_coe_sort.1 ‹_›).some
did not work. I think it's not intuitive to use Function.extend
here.
Yaël Dillies (Oct 01 2023 at 13:29):
Ah sorry I just forgot an argument to Function.extend
. Replace Function
extend f
by Function.extend Subtype.val f
.
Yaël Dillies (Oct 01 2023 at 13:30):
I wonder why it's not intuitive though. You want to extend a function defined on s
to a function defined on the full domain α
. Is that not intuitive?
Wen Yang (Oct 01 2023 at 13:34):
Maybe I'm just not used to it yet. This works:
import Mathlib.Data.Set.Basic
set_option autoImplicit true
open Set Function
variable {s : Set α} {t : Set β} [Nonempty ↑t]
noncomputable def Function.toval (f : s → t) : α → β :=
extend Subtype.val
(Subtype.val ∘ f)
(fun _ ↦ (Set.nonempty_coe_sort.1 ‹_›).some)
Wen Yang (Oct 01 2023 at 13:36):
I'll try to see if I can build the APIs for this.
Wen Yang (Oct 02 2023 at 12:32):
I have modified the definition of Function.toval
. However, I don't know how to work with Function.extend
, so I give up. I don't even know how to prove that the two definitions are the same:
import Mathlib.Data.Set.Function
set_option autoImplicit true
open Set Function
variable {s : Set α} {t : Set β} [Nonempty β]
noncomputable def Function.toval (f : s → t) : α → β :=
fun x =>
haveI : Decidable (x ∈ s) := Classical.propDecidable _
if hx : x ∈ s then (f ⟨x, hx⟩).val
else Classical.choice ‹_›
theorem toval_eqOn_extend {f : s → t} : EqOn
f.toval
(extend Subtype.val
(Subtype.val ∘ f)
(fun _ ↦ Classical.choice ‹_›))
s := by sorry
Yaël Dillies (Oct 02 2023 at 16:45):
Here's a proof:
import Mathlib.Data.Set.Function
set_option autoImplicit true
open Set Function
variable {s : Set α} [Nonempty β]
noncomputable def Function.toval (f : s → β) : α → β :=
fun x =>
haveI : Decidable (x ∈ s) := Classical.propDecidable _
if hx : x ∈ s then f ⟨x, hx⟩
else Classical.choice ‹_›
theorem toval_eq_extend {f : s → β} :
extend Subtype.val f (fun _ ↦ Classical.choice ‹_›) = f.toval := by
ext a
unfold toval
split_ifs with ha
· exact Subtype.val_injective.extend_apply _ _ (⟨a, ha⟩ : s)
· refine extend_apply' _ _ _ ?_
rintro ⟨a, rfl⟩
exact ha a.2
Wen Yang (Oct 03 2023 at 09:27):
@Yaël Dillies Thank you very much! I have submitted a PR that includes your proof: https://github.com/leanprover-community/mathlib4/pull/7482
Last updated: Dec 20 2023 at 11:08 UTC