Zulip Chat Archive
Stream: new members
Topic: Avoiding tactic mode
jsodd (Aug 27 2024 at 15:01):
I'm trying to figure out some of the ways term mode proofs work, and I found a spot where I cannot avoid using "by". I know that it's always possible to avoid it, so I decided to ask here.
example (f : X → Y) (g : Y → Z) : Injective (g ∘ f) → Injective f :=
fun h a₁ a₂ H ↦ h (by rw [comp_apply, comp_apply]; congr)
P.S. The motivation for this question is pure curiosity, just trying to understand the language better.
Luigi Massacci (Aug 27 2024 at 15:14):
example (f : X → Y) (g : Y → Z) : Injective (g ∘ f) → Injective f :=
fun h a₁ a₂ H ↦ h <| congrArg g H
Luigi Massacci (Aug 27 2024 at 15:16):
In this case I just guessed it, but remember you can always use docs#Lean.Parser.Tactic.showTerm to see what the tactics have created (though in general it will be a horrible mess)
jsodd (Aug 27 2024 at 15:24):
Thanks! I was also trying to guess how to use this with Exists
, as here:
example (f : X → Y) (g : Y → Z) : Surjective (g ∘ f) → Surjective g :=
fun h a ↦ _
jsodd (Aug 27 2024 at 15:25):
I use show_term
a lot! It frequently gives overcomplicated feedback, but still very useful
Luigi Massacci (Aug 27 2024 at 15:43):
example (f : X → Y) (g : Y → Z) : Surjective (g ∘ f) → Surjective g :=
fun h a ↦ Exists.elim (h a) (fun x hx ↦ Exists.intro (f x) hx)
Luigi Massacci (Aug 27 2024 at 15:43):
Here maybe a look at #tpil might be useful for you
Luigi Massacci (Aug 27 2024 at 15:44):
More in general you need to look at what are the constructors / destructors for these types
jsodd (Aug 27 2024 at 15:45):
Thank you again! This is what I'm trying to understand better, yes.
Kevin Buzzard (Aug 28 2024 at 12:40):
Using dot notation and anonymous constructors golfs it to
example (f : X → Y) (g : Y → Z) : Surjective (g ∘ f) → Surjective g :=
fun h a ↦ (h a).elim (fun x hx ↦ ⟨f x, hx⟩)
(Just mentioning these as more term mode tips).
Last updated: May 02 2025 at 03:31 UTC