fix: make sure we can match pattern inside binders

This commit fixes issue reported at
https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Pattern.20matching.20lambda.20body.20in.20conv/near/256890867
This commit is contained in:
Leonardo de Moura 2021-10-10 14:52:29 -07:00
parent 2860ba96f5
commit e8bdb66dda
3 changed files with 13 additions and 3 deletions

View file

@ -21,7 +21,10 @@ private def getContext : MetaM Simp.Context := do
config.decide := false
}
private def pre (pattern : Expr) (found? : IO.Ref (Option Expr)) (e : Expr) : SimpM Simp.Step := do
private def pre (pattern : AbstractMVarsResult) (found? : IO.Ref (Option Expr)) (e : Expr) : SimpM Simp.Step := do
/- TODO: check whether the following is a performance bottleneck. If it is, recall that we used `AbstractMVarsResult` to make
sure we can match the pattern inside of binders. So, it is not needed in most cases. -/
let (_, _, pattern) ← openAbstractMVarsResult pattern
if (← withReducible <| isDefEqGuarded pattern e) then
let (rhs, newGoal) ← mkConvGoalFor e
found?.set newGoal
@ -29,7 +32,7 @@ private def pre (pattern : Expr) (found? : IO.Ref (Option Expr)) (e : Expr) : Si
else
return Simp.Step.visit { expr := e }
private def findPattern? (pattern : Expr) (e : Expr) : MetaM (Option (MVarId × Simp.Result)) := do
private def findPattern? (pattern : AbstractMVarsResult) (e : Expr) : MetaM (Option (MVarId × Simp.Result)) := do
let found? ← IO.mkRef none
let result ← Simp.main e (← getContext) (methods := { pre := pre pattern found? })
if let some newGoal ← found?.get then
@ -41,8 +44,9 @@ private def findPattern? (pattern : Expr) (e : Expr) : MetaM (Option (MVarId ×
match stx with
| `(conv| pattern $p) =>
let pattern ← Term.withoutPending <| Term.elabTerm p none
let patternA ← abstractMVars pattern
let lhs ← getLhs
match (← findPattern? pattern lhs) with
match (← findPattern? patternA lhs) with
| none => throwError "'pattern' conv tactic failed, pattern was not found{indentExpr pattern}"
| some (mvarId', result) =>
updateLhs result.expr (← result.getProof)

View file

@ -0,0 +1,4 @@
def test : (λ x : Nat => id (id x)) = λ x => x := by
conv in (id _) =>
trace_state
simp

View file

@ -0,0 +1,2 @@
x : Nat
⊢ id (id x)