DiscrTree doesn't match lemmas with `OfNat.ofNat *` to nat literal keys
Nobody has claimed this yet.
- Dominant language
- Lean
- Stars
- 9.2k
- Forks
- 990
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 175
Description
Prerequisites
- Put an X between the brackets on this line if you have done all of the following:
- Check that your issue is not already filed.
- Reduce the issue to a minimal, self-contained, reproducible test case. Avoid dependencies to mathlib4 or std4.
Description
When a @[simp] lemma is ∀ (n : Nat), P (OfNat.ofNat n), simp fails to apply it to targets like P 2 due to a bug in DiscrTree.
Context
This has been requiring us to add no_index around every explicit invocation of OfNat.ofNat. e.g. https://github.com/leanprover-community/mathlib4/pull/8317
MWE
def MyProp (n : Nat) : Prop := False
-- DiscrTree key: [MyProp, OfNat.ofNat, Nat, *, *]
theorem myProp_ofNat (n : Nat) : MyProp (OfNat.ofNat n) := sorry
example : MyProp 0 := by simp [myProp_ofNat] -- fails. should succeed
example (n : Nat) : MyProp (OfNat.ofNat n) := by simp [myProp_ofNat] -- succeeds
-- DiscrTree key: [MyProp, *]
theorem myProp_ofNat' (n : Nat) : MyProp (no_index (OfNat.ofNat n)) := sorry
example : MyProp 0 := by simp [myProp_ofNat'] -- succeeds
Expected behavior: simp should be able to solve MyProp 0
Actual behavior: simp makes no progress
Versions
4.3.0-rc1
Additional Information
My diagnosis of the issue is that in DiscrTree, we are stripping off invocations of OfNat.ofNat on numerals, but not on variables.
Code stripping it off of numerals:
https://github.com/leanprover/lean4/blob/8cfcf7ce61bba328ed57d97bb12cf1a0fc40a0b9/src/Lean/Meta/DiscrTree.lean#L167-L173
It seems like the possible solutions are:
- (A) Treat
OfNat.ofNat nsimilarly ton + 1, and convert it to*when inserting in theDiscrTree. (Equivalent to placingno_indexaround everyOfNat.ofNatinvocation)- This is bad for performance in Mathlib because simp lemmas about
(OfNat.ofNat n : R)for an arbitrary ringRwill be tried for every single subexpression of the target
- This is bad for performance in Mathlib because simp lemmas about
- (B) Change the normal form of numerals like
(5 : R)in theDiscrTreeto[OfNat.ofNat, R, 5, *]rather than simply[5]- This would probably require additional handling to convert raw nat literals,
Nat.zero, andNat.succinto this normal form
- This would probably require additional handling to convert raw nat literals,
- (C) Add a special case when doing lookup of an expression whose key is
Key.lit (natVal _)to additionally search the tree forKey.const OfNat.ofNat 3and then traverse next few keys appropriately- This seems ugly, and I think it would result in false positives when the
OfNatresult types are different. e.g. Searching for lemmas about(5 : R)whereRis a variable would turn up results for specific rings(5 : Rat)
- This seems ugly, and I think it would result in false positives when the
Impact
Add 👍 to issues you consider important. If others are impacted by this issue, please ask them to add 👍 to it.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/Lean/Meta/DiscrTree.lean around lines 167–173 and reproduce the minimal example from the issue. Trace how DiscrTree keys are formed and looked up for OfNat.ofNat applied to variables versus literals. Done means simp solves MyProp 0 for the lemma shown without causing the noted false matches.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100