@@ -296,7 +296,9 @@ def simpProj (e : Expr) : SimpM Result := do
296296def simpConst (e : Expr) : SimpM Result :=
297297 return { expr := (← reduce e) }
298298
299- def simpLambda (e : Expr) : SimpM Result :=
299+ def simpLambda (e : Expr) : SimpM Result := do
300+ unless (← getConfig).underLambda do
301+ return { expr := e }
300302 withParent e <| lambdaTelescopeDSimp e fun xs e => withNewLemmas xs do
301303 let r ← simp e
302304 let eNew ← mkLambdaFVars xs r.expr
@@ -456,13 +458,32 @@ Auxiliary `dsimproc` for not visiting `Char` literal subterms.
456458-/
457459private def doNotVisitCharLit : DSimproc := doNotVisit isCharLit ``Char.ofNat
458460
461+ /-- The dsimp implementation of `underLambda := false` -/
462+ private def doNotVisitLambda : DSimproc := fun e => do
463+ if e.isLambda then
464+ return .done e
465+ if e.isApp && e.isAppOf ``ite then
466+ -- dsimp is using `Meta.transform`, which we cannot tell to only
467+ -- traverse into some subterms.
468+ -- So recurse into `dsimp` here. Unfortunately sets up a fresh transform cache.
469+ e.withApp fun f args => do
470+ let args' ← args.mapIdxM fun i a =>
471+ if i < 3 || i > 4 then
472+ dsimp a
473+ else
474+ pure a
475+ return .done (mkAppN f args')
476+ else
477+ return .continue
478+
459479@[export lean_dsimp]
460480private partial def dsimpImpl (e : Expr) : SimpM Expr := do
461481 let cfg ← getConfig
462482 unless cfg.dsimp do
463483 return e
464484 let m ← getMethods
465485 let pre := m.dpre >> doNotVisitOfNat >> doNotVisitOfScientific >> doNotVisitCharLit
486+ let pre := if cfg.underLambda then pre else doNotVisitLambda >> pre
466487 let post := m.dpost >> dsimpReduce
467488 withInDSimp do
468489 transform (usedLetOnly := cfg.zeta || cfg.zetaUnused) e (pre := pre) (post := post)
@@ -490,7 +511,10 @@ def congrDefault (e : Expr) : SimpM Result := do
490511
491512/-- Process the given congruence theorem hypothesis. Return true if it made "progress". -/
492513def processCongrHypothesis (h : Expr) : SimpM Bool := do
514+ trace[Debug.Meta.Tactic.simp.congr] "Processing {h} of type {←inferType h}"
493515 forallTelescopeReducing (← inferType h) fun xs hType => withNewLemmas xs do
516+ unless (← getConfig).underLambda || xs.isEmpty do
517+ return false
494518 let lhs ← instantiateMVars hType.appFn!.appArg!
495519 let r ← simp lhs
496520 let rhs := hType.appArg!
@@ -546,6 +570,7 @@ def trySimpCongrTheorem? (c : SimpCongrTheorem) (e : Expr) : SimpM (Option Resul
546570 let x := xs[i]!
547571 try
548572 if (← processCongrHypothesis x) then
573+ trace[Debug.Meta.Tactic.simp.congr] "modified!"
549574 modified := true
550575 catch _ =>
551576 trace[Meta.Tactic.simp.congr] "processCongrHypothesis {c.theoremName} failed {← inferType x}"
0 commit comments