Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: extensible push_neg tactic #21769

Open
wants to merge 55 commits into
base: master
Choose a base branch
from
Open

feat: extensible push_neg tactic #21769

wants to merge 55 commits into from

Conversation

JovanGerb
Copy link
Collaborator

@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
Copy link

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
Collaborator

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
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.
5 participants