fix: avoid unnecessary matcheApp.addArgs at BRecOn and Fix
It fixes the following two cases from #998 ``` attribute [simp] Lean.Export.exportName attribute [simp] Lean.Export.exportLevel ```
This commit is contained in:
parent
8692225432
commit
2ef0146140
4 changed files with 118 additions and 17 deletions
|
|
@ -80,6 +80,21 @@ private partial def toBelow (below : Expr) (numIndParams : Nat) (recArg : Expr)
|
|||
withBelowDict below numIndParams fun C belowDict =>
|
||||
toBelowAux C belowDict recArg below
|
||||
|
||||
/--
|
||||
This method is used after `matcherApp.addArg arg` to check whether the new type of `arg` has been "refined/modified"
|
||||
in at least one alternative.
|
||||
-/
|
||||
def refinedArgType (matcherApp : MatcherApp) (arg : Expr) : MetaM Bool := do
|
||||
let argType ← inferType arg
|
||||
(Array.zip matcherApp.alts matcherApp.altNumParams).anyM fun (alt, numParams) =>
|
||||
lambdaTelescope alt fun xs altBody => do
|
||||
if xs.size >= numParams then
|
||||
let refinedArg := xs[numParams - 1]
|
||||
trace[Meta.debug] "refinedArgType {argType} =?= {← inferType refinedArg}"
|
||||
return !(← isDefEq (← inferType refinedArg) argType)
|
||||
else
|
||||
return false
|
||||
|
||||
private partial def replaceRecApps (recFnName : Name) (recArgInfo : RecArgInfo) (below : Expr) (e : Expr) : M Expr :=
|
||||
let rec loop (below : Expr) (e : Expr) : M Expr := do
|
||||
match e with
|
||||
|
|
@ -146,14 +161,17 @@ private partial def replaceRecApps (recFnName : Name) (recArgInfo : RecArgInfo)
|
|||
this may generate weird error messages, when it doesn't work. -/
|
||||
trace[Elab.definition.structural] "below before matcherApp.addArg: {below} : {← inferType below}"
|
||||
let matcherApp ← mapError (matcherApp.addArg below) (fun msg => "failed to add `below` argument to 'matcher' application" ++ indentD msg)
|
||||
let altsNew ← (Array.zip matcherApp.alts matcherApp.altNumParams).mapM fun (alt, numParams) =>
|
||||
lambdaTelescope alt fun xs altBody => do
|
||||
trace[Elab.definition.structural] "altNumParams: {numParams}, xs: {xs}"
|
||||
unless xs.size >= numParams do
|
||||
throwError "unexpected matcher application alternative{indentExpr alt}\nat application{indentExpr e}"
|
||||
let belowForAlt := xs[numParams - 1]
|
||||
mkLambdaFVars xs (← loop belowForAlt altBody)
|
||||
pure { matcherApp with alts := altsNew }.toExpr
|
||||
if !(← refinedArgType matcherApp below) then
|
||||
processApp e
|
||||
else
|
||||
let altsNew ← (Array.zip matcherApp.alts matcherApp.altNumParams).mapM fun (alt, numParams) =>
|
||||
lambdaTelescope alt fun xs altBody => do
|
||||
trace[Elab.definition.structural] "altNumParams: {numParams}, xs: {xs}"
|
||||
unless xs.size >= numParams do
|
||||
throwError "unexpected matcher application alternative{indentExpr alt}\nat application{indentExpr e}"
|
||||
let belowForAlt := xs[numParams - 1]
|
||||
mkLambdaFVars xs (← loop belowForAlt altBody)
|
||||
pure { matcherApp with alts := altsNew }.toExpr
|
||||
| none => processApp e
|
||||
| e => ensureNoRecFn recFnName e
|
||||
loop below e
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import Lean.Elab.Tactic.Basic
|
|||
import Lean.Elab.RecAppSyntax
|
||||
import Lean.Elab.PreDefinition.Basic
|
||||
import Lean.Elab.PreDefinition.Structural.Basic
|
||||
import Lean.Elab.PreDefinition.Structural.BRecOn
|
||||
|
||||
namespace Lean.Elab.WF
|
||||
open Meta
|
||||
|
|
@ -62,13 +63,16 @@ private partial def replaceRecApps (recFnName : Name) (decrTactic? : Option Synt
|
|||
processApp e
|
||||
else
|
||||
let matcherApp ← mapError (matcherApp.addArg F) (fun msg => "failed to add functional argument to 'matcher' application" ++ indentD msg)
|
||||
let altsNew ← (Array.zip matcherApp.alts matcherApp.altNumParams).mapM fun (alt, numParams) =>
|
||||
lambdaTelescope alt fun xs altBody => do
|
||||
unless xs.size >= numParams do
|
||||
throwError "unexpected matcher application alternative{indentExpr alt}\nat application{indentExpr e}"
|
||||
let FAlt := xs[numParams - 1]
|
||||
mkLambdaFVars xs (← loop FAlt altBody)
|
||||
return { matcherApp with alts := altsNew, discrs := (← matcherApp.discrs.mapM (loop F)) }.toExpr
|
||||
if !(← Structural.refinedArgType matcherApp F) then
|
||||
processApp e
|
||||
else
|
||||
let altsNew ← (Array.zip matcherApp.alts matcherApp.altNumParams).mapM fun (alt, numParams) =>
|
||||
lambdaTelescope alt fun xs altBody => do
|
||||
unless xs.size >= numParams do
|
||||
throwError "unexpected matcher application alternative{indentExpr alt}\nat application{indentExpr e}"
|
||||
let FAlt := xs[numParams - 1]
|
||||
mkLambdaFVars xs (← loop FAlt altBody)
|
||||
return { matcherApp with alts := altsNew, discrs := (← matcherApp.discrs.mapM (loop F)) }.toExpr
|
||||
| none => processApp e
|
||||
| e => Structural.ensureNoRecFn recFnName e
|
||||
loop F e
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@ attribute [simp] Lean.Elab.Term.resolveLocalName.loop
|
|||
-- Mathlib
|
||||
-- attribute [simp] BinaryHeap.heapifyDown
|
||||
-- attribute [simp] ByteSlice.forIn.loop
|
||||
-- attribute [simp] Lean.Export.exportName
|
||||
-- attribute [simp] Lean.Export.exportLevel
|
||||
-- attribute [simp] Lean.Export.exportName -- Fixed see 998Export.lean
|
||||
-- attribute [simp] Lean.Export.exportLevel -- Fixed see 998Export.lean
|
||||
-- attribute [simp] Array.heapSort.loop
|
||||
|
|
|
|||
79
tests/lean/run/998Export.lean
Normal file
79
tests/lean/run/998Export.lean
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
import Lean
|
||||
open Lean
|
||||
open Std (HashMap HashSet)
|
||||
|
||||
inductive Entry
|
||||
| name (n : Name)
|
||||
| level (n : Level)
|
||||
| expr (n : Expr)
|
||||
| defn (n : Name)
|
||||
deriving Inhabited
|
||||
|
||||
structure Alloc (α) [BEq α] [Hashable α] where
|
||||
map : HashMap α Nat
|
||||
next : Nat
|
||||
deriving Inhabited
|
||||
|
||||
namespace Export
|
||||
|
||||
structure State where
|
||||
names : Alloc Name := ⟨HashMap.empty.insert Name.anonymous 0, 1⟩
|
||||
levels : Alloc Level := ⟨HashMap.empty.insert levelZero 0, 1⟩
|
||||
exprs : Alloc Expr
|
||||
defs : HashSet Name
|
||||
stk : Array (Bool × Entry)
|
||||
deriving Inhabited
|
||||
|
||||
class OfState (α : Type) [BEq α] [Hashable α] where
|
||||
get : State → Alloc α
|
||||
modify : (Alloc α → Alloc α) → State → State
|
||||
|
||||
instance : OfState Name where
|
||||
get s := s.names
|
||||
modify f s := { s with names := f s.names }
|
||||
|
||||
instance : OfState Level where
|
||||
get s := s.levels
|
||||
modify f s := { s with levels := f s.levels }
|
||||
|
||||
instance : OfState Expr where
|
||||
get s := s.exprs
|
||||
modify f s := { s with exprs := f s.exprs }
|
||||
|
||||
end Export
|
||||
|
||||
abbrev ExportM := StateT Export.State CoreM
|
||||
|
||||
namespace Export
|
||||
|
||||
def alloc {α} [BEq α] [Hashable α] [OfState α] (a : α) : ExportM Nat := do
|
||||
let n := (OfState.get (α := α) (← get)).next
|
||||
modify $ OfState.modify (α := α) fun s => {map := s.map.insert a n, next := n+1}
|
||||
pure n
|
||||
|
||||
def exportName (n : Name) : ExportM Nat := do
|
||||
match (← get).names.map.find? n with
|
||||
| some i => pure i
|
||||
| none => match n with
|
||||
| Name.anonymous => pure 0
|
||||
| Name.num p a _ => let i ← alloc n; IO.println s!"{i} #NI {← exportName p} {a}"; pure i
|
||||
| Name.str p s _ => let i ← alloc n; IO.println s!"{i} #NS {← exportName p} {s}"; pure i
|
||||
|
||||
attribute [simp] exportName
|
||||
|
||||
def exportLevel (L : Level) : ExportM Nat := do
|
||||
match (← get).levels.map.find? L with
|
||||
| some i => pure i
|
||||
| none => match L with
|
||||
| Level.zero _ => pure 0
|
||||
| Level.succ l _ =>
|
||||
let i ← alloc L; IO.println s!"{i} #US {← exportLevel l}"; pure i
|
||||
| Level.max l₁ l₂ _ =>
|
||||
let i ← alloc L; IO.println s!"{i} #UM {← exportLevel l₁} {← exportLevel l₂}"; pure i
|
||||
| Level.imax l₁ l₂ _ =>
|
||||
let i ← alloc L; IO.println s!"{i} #UIM {← exportLevel l₁} {← exportLevel l₂}"; pure i
|
||||
| Level.param n _ =>
|
||||
let i ← alloc L; IO.println s!"{i} #UP {← exportName n}"; pure i
|
||||
| Level.mvar n _ => unreachable!
|
||||
|
||||
attribute [simp] exportLevel
|
||||
Loading…
Add table
Reference in a new issue