Zulip Chat Archive
Stream: new members
Topic: idioms : f p = f (p.fst, p.snd), etc.
Jean Lo (Aug 23 2020 at 13:03):
Today I encountered the surprising-but-not-really fact that the following proof is not refl
:
variables (f : α × β → β) (p : α × β)
example : f p = f (p.fst, p.snd) := congr_arg _ $ prod.ext rfl rfl
This does not seem incredibly awful, but it also comes up often enough that I'm finding it hard to believe that I haven't overlooked a lemma/tactic somewhere that will take care of it. Have I? What is the right way to go about this?
More context, possibly distracting: I'm attempting to write down some things about dynamical systems as an exercise, and the f : α × β → β
business comes from the following definition obtained by naïvely copying out of a book:
(to_fun : ℝ × X → X)
(cont : continuous to_fun)
(map_zero : ∀ x, to_fun (0, x) = x)
(map_add : ∀ x t₁ t₂, to_fun (t₁ + t₂, x) = to_fun (t₂, to_fun (t₁, x)))
(It does not invoke the relatively-recent mathlib add_torsor
in part because I think it would be desirable to ultimately have a version of this for local flows, and it stops being a group action. Then again I don't know what the definition for the local version should look like either — carry around a U : set ℝ × X
on which the function is defined, and qualify all the other fields with ∀ (x, t) ∈ U
? Make the signature X → ℝ →. X
instead and wrangle a lot of roption
s? A lot of this seems vaguely familiar from struggles with homotopies circa #1160, and I was hoping I could maybe get some insights as to what people have learnt since.)
Patrick Massot (Aug 23 2020 at 13:11):
This issue is sadly well-known.
Kenny Lau (Aug 23 2020 at 13:12):
@Jean Lo why not use R -> X -> X
Patrick Massot (Aug 23 2020 at 13:12):
and I was writing what Kenny wrote.
Jean Lo (Aug 23 2020 at 13:13):
ℝ × X → X
and continuous (uncurry to_fun)
?
Kenny Lau (Aug 23 2020 at 13:14):
oh, continuity
Kenny Lau (Aug 23 2020 at 13:14):
let's look at how topological_group
does this then
Kenny Lau (Aug 23 2020 at 13:16):
src/topology/algebra/group.lean L33
class topological_group (α : Type*) [topological_space α] [group α]
extends has_continuous_mul α : Prop :=
(continuous_inv : continuous (λa:α, a⁻¹))
src/topology/algebra/monoid.lean L27
class has_continuous_mul (α : Type*) [topological_space α] [has_mul α] : Prop :=
(continuous_mul : continuous (λp:α×α, p.1 * p.2))
Jean Lo (Aug 23 2020 at 13:16):
oh gee
class has_continuous_add (α : Type*) [topological_space α] [has_add α] : Prop :=
(continuous_add : continuous (λp:α×α, p.1 + p.2))
Kenny Lau (Aug 23 2020 at 13:16):
yay I'm still faster
Kenny Lau (Aug 23 2020 at 13:18):
src/topology/algebra/module.lean L43
class topological_semimodule (R : Type u) (M : Type v)
[semiring R] [topological_space R]
[topological_space M] [add_comm_monoid M]
[semimodule R M] : Prop :=
(continuous_smul : continuous (λp : R × M, p.1 • p.2))
Kenny Lau (Aug 23 2020 at 13:18):
I think you need topological_mul_action
Kenny Lau (Aug 23 2020 at 13:18):
that is topological_semimodule
restricted to mul_action
Patrick Massot (Aug 23 2020 at 13:18):
You could use has_uncurry
here, but I think the PR got lost somehow.
Patrick Massot (Aug 23 2020 at 13:19):
https://github.com/leanprover-community/mathlib/pull/3694
Patrick Massot (Aug 23 2020 at 13:26):
It got stuck with Mario requiring mysterious priorities to be set (at don't know where or to what values), but you can still use it:
import topology.instances.real
section uncurry
variables {α β γ δ : Type*}
/-- Records a way to turn an element of `α` into a function from `β` to `γ`. -/
class has_uncurry (α : Type*) (β : out_param Type*) (γ : out_param Type*) := (uncurry : α → (β → γ))
notation `↿`:max x:max := has_uncurry.uncurry x
instance has_uncurry_base : has_uncurry (α → β) α β := ⟨id⟩
instance has_uncurry_induction [has_uncurry β γ δ] : has_uncurry (α → β) (α × γ) δ :=
⟨λ f p, ↿(f p.1) p.2⟩
end uncurry
structure flow (X : Type*) [topological_space X] :=
(to_fun : ℝ → X → X)
(cont : continuous ↿to_fun)
(map_zero : ∀ x, to_fun 0 x = x)
(map_add : ∀ x t₁ t₂, to_fun (t₁ + t₂) x = to_fun t₂ (to_fun t₁ x))
Patrick Massot (Aug 23 2020 at 13:30):
And now let's play with has_uncurry
's real magic: how do you talk about a continuous family of flows of X
parametrized by a topological space Y
?
Patrick Massot (Aug 23 2020 at 13:30):
variables {X Y : Type*} [topological_space X] [topological_space Y]
instance has_uncurry_flow : has_uncurry (flow X) (ℝ × X) X := ⟨λ f p, f.to_fun p.1 p.2⟩
variable (f : Y → flow X)
#check continuous ↿f
Patrick Massot (Aug 23 2020 at 13:34):
Let's check it does its magic properly:
example : continuous ↿f ↔ continuous (λ z : Y × ℝ × X, (f z.1).to_fun z.2.1 z.2.2) :=
iff.rfl
Jean Lo (Aug 23 2020 at 13:39):
ooh, this is very cool. thanks for the pointers!
Maybe this even just works™ with the X → ℝ →. X
signature, with pcontinuous
instead of continuous
?
Kenny Lau said:
I think you need
topological_mul_action
oh, hmm. The Mathlib Generality version of this is probably, like, a not-necessarily-continuous semigroup act (but also not really, because partial functions)? and sometimes I want that semigroup to be additive (ℝ
)? Additionally, I don't expect to use the +
notation. After half an attempt I've not managed to convince myself that reusing the instances helps that much.
Kenny Lau (Aug 23 2020 at 13:46):
I guess you need to make the priority of has_uncurry_base
less than that of has_uncurry_induction
?
Kenny Lau (Aug 23 2020 at 13:46):
otherwise Lean will use has_uncurry_base
for A -> B -> C
to turn it into, well, A -> B -> C
Reid Barton (Aug 23 2020 at 13:49):
By the way, shouldn't it be has_curry
? a -> b -> c
is the curried form: docs#function.curry
Kenny Lau (Aug 23 2020 at 13:50):
yeah so uncurry turns A -> B -> C into A x B -> C
Kenny Lau (Aug 23 2020 at 13:50):
which is what Patrick intended
Jean Lo (Aug 23 2020 at 13:59):
Kenny Lau
reacted with:point_right:
(what is the meaning of this?)
Kenny Lau (Aug 23 2020 at 14:02):
"thanks for the pointers"
Patrick Massot (Aug 23 2020 at 14:08):
It's funny how people think there is a priority issue here, even when they see it working flawlessly.
Reid Barton (Aug 23 2020 at 16:11):
oh I see. Maybe the variable names are unhelpful or something but I find this confusing for some reason...
Last updated: Dec 20 2023 at 11:08 UTC