Skip to content

feat: extensible push_neg tactic#21769

Closed
JovanGerb wants to merge 55 commits intomasterfrom
push_neg-Finite
Closed

feat: extensible push_neg tactic#21769
JovanGerb wants to merge 55 commits intomasterfrom
push_neg-Finite

Conversation

@JovanGerb
Copy link
Copy Markdown
Contributor

@JovanGerb JovanGerb commented Feb 12, 2025

This was started by point (3) of https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Possible.20improvements.20to.20Lean.2FMathlib/near/499085779

To be able to use push_neg more generally, this PR reimplements the tactic so that it is extensible. So, users can tag lemmas to be used by push_neg.

This PR tags lemmas concerning empty/nonempty, subsingleton/nontrivial, and finite/infinite to be used in push_neg.

Additionally, the tactic is extended to be able to push any constant that you want to push, and push_neg is now a macro for push Not. So far, I've tried to add lemmas for pushing Real.log. I could imagine it could also be used for Real.exp, pow, mul, smul, or even Set.mem. (the Set.mem lemmas are mostly tagged with @[simp] already, but push_mem could be more readable than simp or dsimp). Or a combination of pushing Not and Set.compl could be useful.

The implementation is with the simp infrastructure, but instead of using post lemmas, like in simp, push uses pre lemmas, so we rewrite each expression before its subterms are rewritten. This is a more efficient way to "push" constants recursively. Most lemmas are added via the @[push] attribute, but a few cases require some special handling, so they are implemented "by hand" in a simproc that is tried after the push lemmas.

For example the simproc simplifies ¬∀ n, p∃ n, ¬p, but, this is overridden by the push lemma that rewrites ¬(p → q)p ∧ ¬q (which doesn't apply at every forall)


Open in Gitpod

@github-actions github-actions bot added the large-import Automatically added label for PRs with a significant increase in transitive imports label Feb 12, 2025
@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 12, 2025

PR summary a7bfbd40d3

Import changes exceeding 2%

% File
+3.48% Mathlib.Algebra.Group.Pi.Basic
+5.56% Mathlib.Logic.IsEmpty
+2.70% Mathlib.Logic.Nontrivial.Defs
+2.22% Mathlib.Order.Defs.LinearOrder

Import changes for modified files

Dependency changes

File Base Count Head Count Change
Mathlib.Tactic.PushNeg 62 0 -62 (-100.00%)
Mathlib.Tactic.Contrapose 63 45 -18 (-28.57%)
Mathlib.Tactic.ByContra 64 46 -18 (-28.12%)
Mathlib.Logic.IsEmpty 72 76 +4 (+5.56%)
Mathlib.Algebra.Group.Pi.Basic 115 119 +4 (+3.48%)
Mathlib.Tactic.Common 241 239 -2 (-0.83%)
Import changes for all files
Files Import difference
There are 5500 files with changed transitive imports taking up over 232079 characters: this is too many to display!
You can run scripts/import_trans_difference.sh all locally to see the whole output.

Declarations diff

+ Head
+ Head.isHeadOf
+ Nat.not_nonneg_iff_eq_zero
+ PushSimpConfig
+ elabHead
+ elabPush
+ elabPushConv
+ mem_compl
+ nonempty_iff_empty_ne'
+ not_finite
+ not_imp
+ not_not
+ not_one_lt_iff_eq_one
+ not_zero_lt_iff
+ pushCore
+ pushStep
++ nonempty_iff_empty_ne
+-+ not_iff
- elabPushNegConv
- empty_ne_eq_nonempty
- ne_empty_eq_nonempty
- not_ge_eq
- not_gt_eq
- not_implies_eq
- not_le_eq
- not_lt_eq
- not_ne_eq
- not_nonempty_eq
- not_not_eq
- not_or_eq
- pushNegCore
- transformNegationStep

You can run this locally as follows
## summary with just the declaration names:
./scripts/declarations_diff.sh <optional_commit>

## more verbose report:
./scripts/declarations_diff.sh long <optional_commit>

The doc-module for script/declarations_diff.sh contains some details about this script.


No changes to technical debt.

You can run this locally as

./scripts/technical-debt-metrics.sh pr_summary
  • The relative value is the weighted sum of the differences with weight given by the inverse of the current value of the statistic.
  • The absolute value is the relative value divided by the total sum of the inverses of the current values (i.e. the weighted average of the differences).

@grunweg
Copy link
Copy Markdown
Contributor

grunweg commented Feb 12, 2025

Thanks a lot for starting this discussion! I for one believe a push_neg attribute would be rather nice (but I don't know how hard this would make it to write this tactic).

@JovanGerb JovanGerb changed the title feat: let push_neg replace ¬Finite with Infinite feat: extenisble push_neg tactic Feb 13, 2025
@leanprover-community-bot-assistant leanprover-community-bot-assistant added the merge-conflict The PR has a merge conflict with master, and needs manual merging. (this label is managed by a bot) label Feb 17, 2025
@mathlib4-dependent-issues-bot mathlib4-dependent-issues-bot added the blocked-by-other-PR This PR depends on another PR (this label is automatically managed by a bot) label Apr 5, 2025
mathlib-bors bot pushed a commit that referenced this pull request Sep 22, 2025
This PR defines the `push` and `pull` tactics, and makes `push_neg` a macro for `push Not`. The tactics are also available in `conv` mode.

For tagging, there is only the `@[push]` attribute, which adds the reverse rewrite for the `pull` tactic when relevant. In the future, we may also need a separate `@[pull X]` attribute for pulling `X`.

Thanks to this change, we will be able to make `push_neg` into a more powerful tactic by tagging more lemmas. It also means that about 60 files now don't need to import `LinearOrder`/`PartialOrder`. This will be especially useful when we get the `@[to_dual]` attribute.

This work originally started in #21769. There is now the follow up PR #29000 which adds `push` tags and tests for them.

The `@[push]` attribute is defined in `Mathlib.Tactic.Push.Attr` and the main implementation of `push` and `pull` is in `Mathlib.Tactic.Push`.

Some proofs need to be fixed because the new simp-based `push_neg` can see through more reducible definitions.

Zulip conversation: [#mathlib4 > I made an extensible &#96;push&#96; tactic generalizing &#96;push_neg&#96;](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/I.20made.20an.20extensible.20.60push.60.20tactic.20generalizing.20.60push_neg.60)

closes #21841
mathlib-bors bot pushed a commit that referenced this pull request Sep 23, 2025
This PR defines the `push` and `pull` tactics, and makes `push_neg` a macro for `push Not`. The tactics are also available in `conv` mode.

For tagging, there is only the `@[push]` attribute, which adds the reverse rewrite for the `pull` tactic when relevant. In the future, we may also need a separate `@[pull X]` attribute for pulling `X`.

Thanks to this change, we will be able to make `push_neg` into a more powerful tactic by tagging more lemmas. It also means that about 60 files now don't need to import `LinearOrder`/`PartialOrder`. This will be especially useful when we get the `@[to_dual]` attribute.

This work originally started in #21769. There is now the follow up PR #29000 which adds `push` tags and tests for them.

The `@[push]` attribute is defined in `Mathlib.Tactic.Push.Attr` and the main implementation of `push` and `pull` is in `Mathlib.Tactic.Push`.

Some proofs need to be fixed because the new simp-based `push_neg` can see through more reducible definitions.

Zulip conversation: [#mathlib4 > I made an extensible &#96;push&#96; tactic generalizing &#96;push_neg&#96;](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/I.20made.20an.20extensible.20.60push.60.20tactic.20generalizing.20.60push_neg.60)

closes #21841
@mathlib4-dependent-issues-bot mathlib4-dependent-issues-bot removed the blocked-by-other-PR This PR depends on another PR (this label is automatically managed by a bot) label Sep 23, 2025
@mathlib4-dependent-issues-bot
Copy link
Copy Markdown
Collaborator

This PR/issue depends on:

@JovanGerb JovanGerb closed this Sep 23, 2025
joelriou pushed a commit to joelriou/mathlib4 that referenced this pull request Oct 2, 2025
This PR defines the `push` and `pull` tactics, and makes `push_neg` a macro for `push Not`. The tactics are also available in `conv` mode.

For tagging, there is only the `@[push]` attribute, which adds the reverse rewrite for the `pull` tactic when relevant. In the future, we may also need a separate `@[pull X]` attribute for pulling `X`.

Thanks to this change, we will be able to make `push_neg` into a more powerful tactic by tagging more lemmas. It also means that about 60 files now don't need to import `LinearOrder`/`PartialOrder`. This will be especially useful when we get the `@[to_dual]` attribute.

This work originally started in leanprover-community#21769. There is now the follow up PR leanprover-community#29000 which adds `push` tags and tests for them.

The `@[push]` attribute is defined in `Mathlib.Tactic.Push.Attr` and the main implementation of `push` and `pull` is in `Mathlib.Tactic.Push`.

Some proofs need to be fixed because the new simp-based `push_neg` can see through more reducible definitions.

Zulip conversation: [#mathlib4 > I made an extensible &leanprover-community#96;push&leanprover-community#96; tactic generalizing &leanprover-community#96;push_neg&leanprover-community#96;](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/I.20made.20an.20extensible.20.60push.60.20tactic.20generalizing.20.60push_neg.60)

closes leanprover-community#21841
zhuyizheng pushed a commit to zhuyizheng/mathlib4 that referenced this pull request Oct 2, 2025
This PR defines the `push` and `pull` tactics, and makes `push_neg` a macro for `push Not`. The tactics are also available in `conv` mode.

For tagging, there is only the `@[push]` attribute, which adds the reverse rewrite for the `pull` tactic when relevant. In the future, we may also need a separate `@[pull X]` attribute for pulling `X`.

Thanks to this change, we will be able to make `push_neg` into a more powerful tactic by tagging more lemmas. It also means that about 60 files now don't need to import `LinearOrder`/`PartialOrder`. This will be especially useful when we get the `@[to_dual]` attribute.

This work originally started in leanprover-community#21769. There is now the follow up PR leanprover-community#29000 which adds `push` tags and tests for them.

The `@[push]` attribute is defined in `Mathlib.Tactic.Push.Attr` and the main implementation of `push` and `pull` is in `Mathlib.Tactic.Push`.

Some proofs need to be fixed because the new simp-based `push_neg` can see through more reducible definitions.

Zulip conversation: [#mathlib4 > I made an extensible &leanprover-community#96;push&leanprover-community#96; tactic generalizing &leanprover-community#96;push_neg&leanprover-community#96;](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/I.20made.20an.20extensible.20.60push.60.20tactic.20generalizing.20.60push_neg.60)

closes leanprover-community#21841
@YaelDillies YaelDillies deleted the push_neg-Finite branch October 13, 2025 07:55
BeibeiX0 pushed a commit to BeibeiX0/mathlib4 that referenced this pull request Nov 7, 2025
This PR defines the `push` and `pull` tactics, and makes `push_neg` a macro for `push Not`. The tactics are also available in `conv` mode.

For tagging, there is only the `@[push]` attribute, which adds the reverse rewrite for the `pull` tactic when relevant. In the future, we may also need a separate `@[pull X]` attribute for pulling `X`.

Thanks to this change, we will be able to make `push_neg` into a more powerful tactic by tagging more lemmas. It also means that about 60 files now don't need to import `LinearOrder`/`PartialOrder`. This will be especially useful when we get the `@[to_dual]` attribute.

This work originally started in leanprover-community#21769. There is now the follow up PR leanprover-community#29000 which adds `push` tags and tests for them.

The `@[push]` attribute is defined in `Mathlib.Tactic.Push.Attr` and the main implementation of `push` and `pull` is in `Mathlib.Tactic.Push`.

Some proofs need to be fixed because the new simp-based `push_neg` can see through more reducible definitions.

Zulip conversation: [#mathlib4 > I made an extensible &leanprover-community#96;push&leanprover-community#96; tactic generalizing &leanprover-community#96;push_neg&leanprover-community#96;](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/I.20made.20an.20extensible.20.60push.60.20tactic.20generalizing.20.60push_neg.60)

closes leanprover-community#21841
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

large-import Automatically added label for PRs with a significant increase in transitive imports merge-conflict The PR has a merge conflict with master, and needs manual merging. (this label is managed by a bot) t-meta Tactics, attributes or user commands

Projects

None yet

Development

Successfully merging this pull request may close these issues.

push tactic that generalizes push_neg from neg to any def.

6 participants