The push, push_neg and pull tactics #
The push tactic pushes a given constant inside expressions: it can be applied to goals as well
as local hypotheses and also works as a conv tactic. push_neg is a macro for push Not.
The pull tactic does the reverse: it pulls the given constant towards the head of the expression.
Function elaborating Push.Config.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The simp configuration used in push.
Instances For
Try to rewrite using a push lemma.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Common entry point to the implementation of push.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Try to rewrite using a pull lemma.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Common entry point to the implementation of pull.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Return true if stx is an underscore, i.e. _ or fun $_ => _/fun $_ ↦ _.
Equations
- One or more equations did not get rendered due to their size.
Instances For
resolvePushId? is a version of resolveId? that also supports notations like _ ∈ _,
∃ x, _ and ∑ x, _.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Elaborator for the argument passed to push. It accepts a constant, or a function
Equations
- One or more equations did not get rendered due to their size.
Instances For
Elaborate the (disch := ...) syntax for a simp-like tactic.
Equations
- Mathlib.Tactic.Push.elabDischarger stx = (fun (x : IO.Ref Lean.Elab.Term.State × Lean.Meta.Simp.Discharge) => x.snd) <$> Lean.Elab.Tactic.tacticToDischarge stx.raw[3]
Instances For
Run the push tactic.
Equations
- One or more equations did not get rendered due to their size.
Instances For
push c rewrites the goal by pushing the constant c deeper into an expression.
For instance, push _ ∈ _ rewrites x ∈ {y} ∪ zᶜ into x = y ∨ ¬ x ∈ z.
More precisely, the push tactic repeatedly rewrites an expression by applying lemmas
of the form c ... = ... (c ...) (where c can appear 0 or more times on the right hand side).
To extend the push tactic, you can tag a lemma of this form with the @[push] attribute.
To instead move a constant closer to the head of the expression, use the pull tactic.
push works as both a tactic and a conv tactic.
push _ ~ _pushes the (binary) operator~,push ~ _pushes the (unary) operator~.push c at l1 l2 ...rewrites at the given locations.push c at *rewrites at all hypotheses and the goal.push (disch := tac) cuses the tactictacto discharge any hypotheses for@[push]lemmas.
Examples:
push _ ∈ _rewritesx ∈ {y} ∪ zᶜintox = y ∨ ¬ x ∈ z.push (disch := positivity) Real.logrewriteslog (a * b ^ 2)intolog a + 2 * log b.push ¬ _is the same aspush_negorpush Not, and it rewrites¬ ∀ ε > 0, ∃ δ > 0, δ < εinto∃ ε > 0, ∀ δ > 0, ε ≤ δ.push fun _ ↦ _rewritesfun x => f x ^ 2 + 5intof ^ 2 + 5push ∀ _, _rewrites∀ a, p a ∧ q ainto(∀ a, p a) ∧ (∀ a, q a).
Equations
- One or more equations did not get rendered due to their size.
Instances For
push_neg rewrites the goal by pushing negations deeper into an expression.
For instance, the goal ¬ ∀ x, ∃ y, x ≤ y will be transformed by push_neg into
∃ x, ∀ y, y < x. Binder names are preserved (contrary to what would happen with simp
using the relevant lemmas). push_neg works as both a tactic and a conv tactic.
push_neg is a special case of the more general push tactic, namely push Not.
The push tactic can be extended using the @[push] attribute. push has special-casing
built in for push Not.
Tactics that introduce a negation usually have a version that automatically calls push_neg on
that negation. These include by_cases!, contrapose! and by_contra!.
push_neg at l1 l2 ...rewrites at the given locations.push_neg at *rewrites at each hypothesis and the goal.push_neg +distribrewrites¬ (p ∧ q)into¬ p ∨ ¬ q(by default, the tactic rewrites it intop → ¬ qinstead).
Example:
example (h : ¬ ∀ ε > 0, ∃ δ > 0, ∀ x, |x - x₀| ≤ δ → |f x - y₀| ≤ ε) :
∃ ε > 0, ∀ δ > 0, ∃ x, |x - x₀| ≤ δ ∧ ε < |f x - y₀| := by
push_neg at h
-- Now we have the hypothesis `h : ∃ ε > 0, ∀ δ > 0, ∃ x, |x - x₀| ≤ δ ∧ ε < |f x - y₀|`
exact h
Equations
- One or more equations did not get rendered due to their size.
Instances For
pull c rewrites the goal by pulling the constant c closer to the head of the expression.
For instance, pull _ ∈ _ rewrites x ∈ y ∨ ¬ x ∈ z into x ∈ y ∪ zᶜ.
More precisely, the pull tactic repeatedly rewrites an expression by applying lemmas
of the form ... (c ...) = c ... (where c can appear 1 or more times on the left hand side).
pull is the inverse tactic to push. To extend the pull tactic, you can tag a lemma
with the @[push] attribute. pull works as both a tactic and a conv tactic.
A lemma is considered a pull lemma if its reverse direction is a push lemma
that actually moves the given constant away from the head. For example
not_or : ¬ (p ∨ q) ↔ ¬ p ∧ ¬ qis apulllemma, butnot_not : ¬ ¬ p ↔ pis not.log_mul : log (x * y) = log x + log yis apulllemma, butlog_abs : log |x| = log xis not.Pi.mul_def : f * g = fun (i : ι) => f i * g iandPi.one_def : 1 = fun (x : ι) => 1are bothpulllemmas forfun, because everypush fun _ ↦ _lemma is also considered apulllemma.
TODO: define a @[pull] attribute for tagging pull lemmas that are not push lemmas.
pull _ ~ _pulls the operator or relation~.pull c at l1 l2 ...rewrites at the given locations.pull c at *rewrites at all hypotheses and the goal.pull (disch := tac) cuses the tactictacto discharge any hypotheses for@[push]lemmas.
Examples:
pull _ ∈ _rewritesx ∈ y ∨ ¬ x ∈ zintox ∈ y ∪ zᶜ.pull (disch := positivity) Real.logrewriteslog a + 2 * log bintolog (a * b ^ 2).pull fun _ ↦ _rewritesf ^ 2 + 5intofun x => f x ^ 2 + 5wherefis a function.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A simproc variant of push fun _ ↦ _, to be used as simp [↓pushFun].
Instances For
A simproc variant of pull fun _ ↦ _, to be used as simp [pullFun].
Instances For
push c rewrites the goal by pushing the constant c deeper into an expression.
For instance, push _ ∈ _ rewrites x ∈ {y} ∪ zᶜ into x = y ∨ ¬ x ∈ z.
More precisely, the push tactic repeatedly rewrites an expression by applying lemmas
of the form c ... = ... (c ...) (where c can appear 0 or more times on the right hand side).
To extend the push tactic, you can tag a lemma of this form with the @[push] attribute.
To instead move a constant closer to the head of the expression, use the pull tactic.
push works as both a tactic and a conv tactic.
push _ ~ _pushes the (binary) operator~,push ~ _pushes the (unary) operator~.push c at l1 l2 ...rewrites at the given locations.push c at *rewrites at all hypotheses and the goal.push (disch := tac) cuses the tactictacto discharge any hypotheses for@[push]lemmas.
Examples:
push _ ∈ _rewritesx ∈ {y} ∪ zᶜintox = y ∨ ¬ x ∈ z.push (disch := positivity) Real.logrewriteslog (a * b ^ 2)intolog a + 2 * log b.push ¬ _is the same aspush_negorpush Not, and it rewrites¬ ∀ ε > 0, ∃ δ > 0, δ < εinto∃ ε > 0, ∀ δ > 0, ε ≤ δ.push fun _ ↦ _rewritesfun x => f x ^ 2 + 5intof ^ 2 + 5push ∀ _, _rewrites∀ a, p a ∧ q ainto(∀ a, p a) ∧ (∀ a, q a).
Equations
- One or more equations did not get rendered due to their size.
Instances For
push_neg rewrites the goal by pushing negations deeper into an expression.
For instance, the goal ¬ ∀ x, ∃ y, x ≤ y will be transformed by push_neg into
∃ x, ∀ y, y < x. Binder names are preserved (contrary to what would happen with simp
using the relevant lemmas). push_neg works as both a tactic and a conv tactic.
push_neg is a special case of the more general push tactic, namely push Not.
The push tactic can be extended using the @[push] attribute. push has special-casing
built in for push Not.
Tactics that introduce a negation usually have a version that automatically calls push_neg on
that negation. These include by_cases!, contrapose! and by_contra!.
push_neg at l1 l2 ...rewrites at the given locations.push_neg at *rewrites at each hypothesis and the goal.push_neg +distribrewrites¬ (p ∧ q)into¬ p ∨ ¬ q(by default, the tactic rewrites it intop → ¬ qinstead).
Example:
example (h : ¬ ∀ ε > 0, ∃ δ > 0, ∀ x, |x - x₀| ≤ δ → |f x - y₀| ≤ ε) :
∃ ε > 0, ∀ δ > 0, ∃ x, |x - x₀| ≤ δ ∧ ε < |f x - y₀| := by
push_neg at h
-- Now we have the hypothesis `h : ∃ ε > 0, ∀ δ > 0, ∃ x, |x - x₀| ≤ δ ∧ ε < |f x - y₀|`
exact h
Equations
- One or more equations did not get rendered due to their size.
Instances For
#push head e, where head is a constant and e is an expression,
prints the push head form of e.
#push understands local variables, so you can use them to introduce parameters.
Equations
- One or more equations did not get rendered due to their size.
Instances For
#push_neg e, where e is an expression,
prints the push_neg form of e.
#push_neg understands local variables, so you can use them to introduce parameters.
Equations
- One or more equations did not get rendered due to their size.
Instances For
pull c rewrites the goal by pulling the constant c closer to the head of the expression.
For instance, pull _ ∈ _ rewrites x ∈ y ∨ ¬ x ∈ z into x ∈ y ∪ zᶜ.
More precisely, the pull tactic repeatedly rewrites an expression by applying lemmas
of the form ... (c ...) = c ... (where c can appear 1 or more times on the left hand side).
pull is the inverse tactic to push. To extend the pull tactic, you can tag a lemma
with the @[push] attribute. pull works as both a tactic and a conv tactic.
A lemma is considered a pull lemma if its reverse direction is a push lemma
that actually moves the given constant away from the head. For example
not_or : ¬ (p ∨ q) ↔ ¬ p ∧ ¬ qis apulllemma, butnot_not : ¬ ¬ p ↔ pis not.log_mul : log (x * y) = log x + log yis apulllemma, butlog_abs : log |x| = log xis not.Pi.mul_def : f * g = fun (i : ι) => f i * g iandPi.one_def : 1 = fun (x : ι) => 1are bothpulllemmas forfun, because everypush fun _ ↦ _lemma is also considered apulllemma.
TODO: define a @[pull] attribute for tagging pull lemmas that are not push lemmas.
pull _ ~ _pulls the operator or relation~.pull c at l1 l2 ...rewrites at the given locations.pull c at *rewrites at all hypotheses and the goal.pull (disch := tac) cuses the tactictacto discharge any hypotheses for@[push]lemmas.
Examples:
pull _ ∈ _rewritesx ∈ y ∨ ¬ x ∈ zintox ∈ y ∪ zᶜ.pull (disch := positivity) Real.logrewriteslog a + 2 * log bintolog (a * b ^ 2).pull fun _ ↦ _rewritesf ^ 2 + 5intofun x => f x ^ 2 + 5wherefis a function.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The syntax is #pull head e, where head is a constant and e is an expression,
which will print the pull head form of e.
#pull understands local variables, so you can use them to introduce parameters.
Equations
- One or more equations did not get rendered due to their size.