Zulip Chat Archive

Stream: new members

Topic: controlling how ext introduces variables


Paul Nelson (Jan 12 2024 at 08:35):

With the following code, ext v introduces two goals, one with v : V₁, the other with v : V₂. Is there a simple way to get it to introduce just one goal, with v : (V₁ × V₂)?

import Mathlib

example
  (R : Type) [Ring R]
  (V₁ : Type) [AddCommGroup V₁] [Module R V₁]
  (V₂ : Type) [AddCommGroup V₂] [Module R V₂]
  (f : (V₁ × V₂) →ₗ[R] R)
  : f = f := by
  ext v
  sorry

Ruben Van de Velde (Jan 12 2024 at 08:43):

  -- ext picks
  -- refine LinearMap.prod_ext ?hl ?hr
  refine LinearMap.ext fun v => ?_

Paul Nelson (Jan 12 2024 at 08:59):

thanks

Kyle Miller (Jan 12 2024 at 16:24):

The canonical way is ext1 v

Kyle Miller (Jan 12 2024 at 16:38):

std4#525 adjusts the docstrings of these tactics so that you can find ext1 from ext

Paul Nelson (Jan 12 2024 at 17:04):

import Mathlib

example
  (R : Type) [Ring R]
  (V₁ : Type) [AddCommGroup V₁] [Module R V₁]
  (V₂ : Type) [AddCommGroup V₂] [Module R V₂]
  (f : (V₁ × V₂) →ₗ[R] R)
  : f = f := by
  ext1 v -- tactic 'introN' failed, insufficient number of binders
  sorry

Kyle Miller (Jan 12 2024 at 17:10):

Huh, I should have tested it. Maybe you need multiple ext1s. There's also ext v : 2 I believe for limiting the iterations (to two in this example). I'm on my phone, so haven't tested these.

Paul Nelson (Jan 12 2024 at 17:14):

ext v : 2 behaves like ext v here (and ext v : 1 gives an error)

Ruben Van de Velde (Jan 12 2024 at 17:48):

It's not about iterations

Ruben Van de Velde (Jan 12 2024 at 17:48):

It's prod_ext being an ext lemma

Kyle Miller (Jan 12 2024 at 17:49):

How do you mean? Isn't the point that in iteration one ext applies LinearMap.ext and then in iteration two it applies prod_ext?

Ruben Van de Velde (Jan 12 2024 at 17:51):

No, prod_ext applies in the first iteration

Kyle Miller (Jan 12 2024 at 17:52):

Oh, you mean LinearMap.prod_ext, not Prod.ext

Kyle Miller (Jan 12 2024 at 17:53):

This seems like a bad @[ext] lemma... I would have never expected the very first step of ext with a linear map to create two goals.

Ruben Van de Velde (Jan 12 2024 at 18:57):

Perhaps so, yeah

Eric Wieser (Jan 13 2024 at 10:09):

It's a very useful ext lemma for when equating terms of the form (A ⊗ B) × C →ₗ D

Eric Wieser (Jan 13 2024 at 10:09):

As without it you can't apply the tensor product ext

Eric Wieser (Jan 13 2024 at 10:10):

Perhaps we should have ext (simple := true) or something that bypasses these more unusual ext lemmas

Kyle Miller (Jan 13 2024 at 19:00):

It makes sense as an ext lemma, but a reason I worry about this as an @[ext] lemma is that it conditionally applies different ext lemmas depending on the domain. My own expectation is that ext sees that it's a linear map and then applies the standard linear map ext lemma.

Extending your idea @Eric Wieser, maybe there should be "ext sets" kind of like simp sets, or maybe specialized ext lemmas for different circumstances. It seems to me that LinearMap.prod_ext lives in a categorical world, where you "evaluate" by pre-composing with other morphisms, and in particular you wouldn't necessarily apply the pointwise ext lemma. Or maybe you would as a last resort, since you're precomposing with an arbitrary linear map from the ground field.

Paul Nelson (Jan 15 2024 at 09:26):

Ruben Van de Velde said:

  -- ext picks
  -- refine LinearMap.prod_ext ?hl ?hr
  refine LinearMap.ext fun v => ?_

Is there a way to get Lean to report which ext lemma is being used by ext?

Eric Wieser (Jan 15 2024 at 09:41):

show_term ext

Paul Nelson (Jan 15 2024 at 09:44):

oh wow, that looks super useful (more broadly). thanks


Last updated: May 02 2025 at 03:31 UTC