Zulip Chat Archive
Stream: lean4
Topic: Manifold-related typeclass resolution issue
Geoffrey Irving (Sep 22 2023 at 13:21):
Does anyone know the source of this typeclass resolution issue? MWE generated from some ComplexManifold code:
-- Typeclass resolution issue
def uncurry {α β φ : Type} : (α → β → φ) → α × β → φ := fun f a => f a.1 a.2
structure Model (H : Type) where
def Model.prod {A B : Type} (_ : Model A) (_ : Model B) : Model (A × B) where
class Manifold {H : Type} (I : Model H) (M : Type)
instance Manifold.prod {A B M N : Type} {I : Model A} {J : Model B} [Manifold I M] [Manifold J N] :
Manifold (I.prod J) (M × N) where
def NiceAt {A B M N : Type} (I : Model A) (J : Model B) [Manifold I M] [Manifold J N]
(_ : M → N) (_ : M) := True
theorem NiceAt.comp {A B C M N O : Type}
{I : Model A} [Manifold I M]
{J : Model B} [Manifold J N]
{K : Model C} [Manifold K O]
{f : N → O} {g : M → N} {x : M}
(_ : NiceAt J K f (g x)) (_ : NiceAt I J g x) :
NiceAt I K (fun x => f (g x)) x := True.intro
theorem NiceAt.prod {A B C M N O : Type}
{I : Model A} [Manifold I M]
{J : Model B} [Manifold J N]
{K : Model C} [Manifold K O]
{f : M → N} {g : M → O} {x : M}
(_ : NiceAt I J f x) (_ : NiceAt I K g x) :
NiceAt I (J.prod K) (fun x => (f x, g x)) x := True.intro
theorem Good {A M : Type} {I : Model A} [cm : Manifold I M]
{h : M → M → M} {f : M → M} {g : M → M} {x : M}
(ha : NiceAt (I.prod I) I (uncurry h) (f x, g x)) (fa : NiceAt I I f x) (ga : NiceAt I I g x) :
NiceAt I I (fun x => h (f x) (g x)) x :=
@NiceAt.comp A (A × A) A M (M × M) M I cm (I.prod I) _ I cm _ _ _ ha (fa.prod ga)
theorem Bad {A M : Type} {I : Model A} [cm : Manifold I M]
{h : M → M → M} {f : M → M} {g : M → M} {x : M}
(ha : NiceAt (I.prod I) I (uncurry h) (f x, g x)) (fa : NiceAt I I f x) (ga : NiceAt I I g x) :
NiceAt I I (fun x => h (f x) (g x)) x :=
ha.comp (fa.prod ga)
Geoffrey Irving (Sep 22 2023 at 13:22):
The Bad
theorem produces
typeclass instance problem is stuck, it is often due to metavariables
Manifold (?m.1279 ha fa ga) M
Good
works, and is Bad
with lots of implicit arguments filled in.
Eric Wieser (Sep 22 2023 at 13:38):
A shorter version of Good
that works is ha.comp (I := I) (fa.prod ga)
Geoffrey Irving (Sep 22 2023 at 13:42):
I
should be fixed by either ha
or fa.prod ga
, though, right? Probably I have a poor mental model for how inference works.
Eric Wieser (Sep 22 2023 at 13:52):
ha.comp (g := fun _ => (_, _)) (fa.prod ga)
also works
Eric Wieser (Sep 22 2023 at 13:52):
I think Lean can't do the higher-order unification needed to work out g
Geoffrey Irving (Sep 22 2023 at 13:53):
Well, Lean 4 can't. Lean 3 could. :)
(I think. This was minimized from a porting issue.)
Eric Wieser (Sep 22 2023 at 13:55):
There's a tactic which means "create side goals for typeclass issues rather than failing", but I forget its name
Floris van Doorn (Sep 23 2023 at 16:18):
Lean 3 definitely also had similar issues with these kinds of issues - composing maps where the intermediate type is a product (though perhaps not this exact issue):
https://leanprover-community.github.io/mathlib_docs/notes.html#continuity%20lemma%20statement
Last updated: Dec 20 2023 at 11:08 UTC