Zulip Chat Archive
Stream: new members
Topic: Forward Reasoning
Josh Cohen (Oct 31 2025 at 14:38):
Is there a way to easily apply implications in hypotheses? e.g. I have hypotheses H: P -> Q and H1: P and I want a hypothesis Q. In Rocq, this would be apply H in H1 but something similar does not appear to exist in Lean. I know I can do have H2 := H H1 but this gets very verbose with long definition names and many arguments. Is there some tactic that does this that I am missing? Thanks
Kenny Lau (Oct 31 2025 at 14:39):
specialize H H1apply H at H1replace H := H H1
Josh Cohen (Oct 31 2025 at 14:46):
The second option (apply...at...) gives me an error, Lean seems to ignore the at entirely and attempt to apply H to the goal
Riccardo Brasca (Oct 31 2025 at 14:48):
It's a mathlib tactic, you probably need to import it.
Kenny Lau (Oct 31 2025 at 14:48):
import Mathlib.Tactic.ApplyAt
example (P Q : Prop) (H : P → Q) (H1 : P) : Q := by
apply H at H1
exact H1
@Josh Cohen you need to import Mathlib.Tactic.ApplyAt
Josh Cohen (Oct 31 2025 at 14:49):
Is it possible to put this tactic in vanilla Lean? It seems useful enough to be used in non-mathlib contexts
Kenny Lau (Oct 31 2025 at 14:49):
(also for future purposes, it would be more helpful to include #mwe like I just did)
Josh Cohen (Oct 31 2025 at 14:51):
For context, I am working on a project where I cannot add a mathlib dependency, so it is somewhat frustrating when useful Lean capabilities are found only in mathlib.
Kenny Lau (Oct 31 2025 at 14:53):
but you can still use specialize
Kenny Lau (Oct 31 2025 at 14:53):
and also you can just copy the code of apply_at to your project
Riccardo Brasca (Oct 31 2025 at 14:53):
You can open an issue, but honestly it seems unlikely, there is already specialize.
Kenny Lau (Oct 31 2025 at 14:54):
@Josh Cohen is there any reason why you prefer apply_at over specialize?
Riccardo Brasca (Oct 31 2025 at 14:55):
In fact most of the time one can write H H1 directly, without even using specialize.
Kenny Lau (Oct 31 2025 at 14:55):
presumably they want it to be reusable
but this gets very verbose with long definition names and many arguments
Josh Cohen (Oct 31 2025 at 15:10):
Kenny Lau said:
Josh Cohen is there any reason why you prefer apply_at over specialize?
Experimenting a bit more, I think specialize should suffice, thank you both for your help. However, I am now wondering what apply...at does that is different than specialize (as in, why was it created separately?)
Kenny Lau (Oct 31 2025 at 15:11):
@Josh Cohen they change different things
Kenny Lau (Oct 31 2025 at 15:11):
specialize H H1 modifies H, while apply H at H1 modifies H1
Kenny Lau (Oct 31 2025 at 15:14):
@Josh Cohen in general you will find it useful to read the docstrings of tactics, which you can access by hovering your mouse over said tactics in a working code
Josh Cohen (Oct 31 2025 at 15:14):
In Rocq, if I had a quantified hypothesis H: \forall (x: A) (y: B), P x y -> Q x y and hypothesis H1: P a b, apply H in H1 would produce H1: Q a b, whereas I would need to use specialize (H _ _ H1) (or else instantiate x and y explicitly). In other words, apply will infer parameters. This was my original motivation for preferring apply. But maybe this is not similar in Lean.
Josh Cohen (Oct 31 2025 at 15:15):
Kenny Lau said:
Josh Cohen in general you will find it useful to read the docstrings of tactics, which you can access by hovering your mouse over said tactics in a working code
Yes, I have found that useful. I think my primary problem has been discovering tactics; the Lean Tactic Reference is useful but it is sometimes difficult to know what to look for.
Kenny Lau (Oct 31 2025 at 15:17):
that's why #new members exists!
Kenny Lau (Oct 31 2025 at 15:17):
Josh Cohen said:
In Rocq, if I had a quantified hypothesis
H: \forall (x: A) (y: B), P x y -> Q x yand hypothesisH1: P a b,apply H in H1would produceH1: Q a b, whereas I would need to usespecialize (H _ _ H1)(or else instantiatexandyexplicitly). In other words,applywill infer parameters. This was my original motivation for preferringapply. But maybe this is not similar in Lean.
according to the docstrings, apply_at does exactly that
Josh Cohen (Oct 31 2025 at 15:37):
The other advantage of apply is that it works even if I do not have the implication in the context. Given a separate theorem foo: P -> Q and hypothesis H: P, I would like to be able to say apply foo in H. Unless I am mistaken, with specialize, I would need to first add foo to the context (which is annoying if foo has a long name or lots of implicit arguments). Is this correct?
Aaron Liu (Oct 31 2025 at 15:39):
You could also just have := foo H
Last updated: Dec 20 2025 at 21:32 UTC