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

fix: remove special handling of numerals in DiscrTree #3684

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 24 additions & 30 deletions src/Lean/Meta/DiscrTree.lean
Original file line number Diff line number Diff line change
Expand Up @@ -198,30 +198,27 @@ private partial def isNumeral (e : Expr) : Bool :=
else if fName == ``Nat.zero && e.getAppNumArgs == 0 then true
else false

private partial def toNatLit? (e : Expr) : Option Literal :=
if isNumeral e then
if let some n := loop e then
some (.natVal n)
else
none
/-- Returns `some k` if `e` consists of `Nat.zero` followed by `k` applications of `Nat.succ`.-/
private partial def natConst? (e : Expr) : Option Nat :=
match_expr e with
| Nat.zero => some 0
| Nat.succ e' => (· + 1) <$> natConst? e'
| _ => none

/-- If `e` consists of `Nat.zero` followed by `k` applications of `Nat.succ`,
returns `OfNat.ofNat (nat_lit k)`. Otherwise, returns `e` unchanged.

Remark:
We need to ensure that `Nat.zero` and `0` (i.e. `OfNat.ofNat (nat_lit 0)`) are keyed the same way
because unification sometimes converts the former into the latter.

For example, the unification problem `Nat.zero =?= ?n + 0` is resolved by setting `?n := 0`,
*not* `?n := Nat.zero`-/
private def normalizeNatConst (e : Expr) : Expr :=
if let some n := natConst? e then
mkNatLit n
else
none
where
loop (e : Expr) : OptionT Id Nat := do
let f := e.getAppFn
match f with
| .lit (.natVal n) => return n
| .const fName .. =>
if fName == ``Nat.succ && e.getAppNumArgs == 1 then
let r ← loop e.appArg!
return r+1
else if fName == ``OfNat.ofNat && e.getAppNumArgs == 3 then
loop (e.getArg! 1)
else if fName == ``Nat.zero && e.getAppNumArgs == 0 then
return 0
else
failure
| _ => failure
e

private def isNatType (e : Expr) : MetaM Bool :=
return (← whnf e).isConstOf ``Nat
Expand Down Expand Up @@ -310,7 +307,10 @@ where

/-- whnf for the discrimination tree module -/
def reduceDT (e : Expr) (root : Bool) (config : WhnfCoreConfig) : MetaM Expr :=
if root then reduceUntilBadKey e config else reduce e config
if root then
reduceUntilBadKey e config
else
normalizeNatConst <$> reduce e config

/- Remark: we use `shouldAddAsStar` only for nested terms, and `root == false` for nested terms -/

Expand Down Expand Up @@ -350,8 +350,6 @@ private def pushArgs (root : Bool) (todo : Array Expr) (e : Expr) (config : Whnf
return (.lit v, todo)
| .const c _ =>
unless root do
if let some v := toNatLit? e then
return (.lit v, todo)
if (← shouldAddAsStar c e) then
return (.star, todo)
let nargs := e.getAppNumArgs
Expand Down Expand Up @@ -468,10 +466,6 @@ def insertIfSpecific [BEq α] (d : DiscrTree α) (e : Expr) (v : α) (config : W

private def getKeyArgs (e : Expr) (isMatch root : Bool) (config : WhnfCoreConfig) : MetaM (Key × Array Expr) := do
let e ← reduceDT e root config
unless root do
-- See pushArgs
if let some v := toNatLit? e then
return (.lit v, #[])
match e.getAppFn with
| .lit v => return (.lit v, #[])
| .const c _ =>
Expand Down
4 changes: 4 additions & 0 deletions stage0/src/CMakeLists.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion stage0/stdlib/Init/Data/Nat.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion stage0/stdlib/Init/Data/Nat/Bitwise/Lemmas.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions stage0/stdlib/Init/Data/Nat/Simproc.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

80 changes: 41 additions & 39 deletions stage0/stdlib/Init/Data/String/Basic.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading