Skip to content

Commit 1c4e480

Browse files
committed
compute transitive closure more carefully
1 parent 9d0f0af commit 1c4e480

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

src/Lean/Elab/App.lean

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -981,23 +981,24 @@ where
981981
getElabAsElimExtraArgsPos (elimInfo : ElimInfo) : MetaM (Array Nat) := do
982982
forallTelescope elimInfo.elimType fun xs type => do
983983
let targets := type.getAppArgs
984+
/- Compute transitive closure of fvars appearing in the motive and the targets. -/
985+
let initMotiveFVars : CollectFVars.State := targets.foldl (init := {}) collectFVars
986+
let motiveFVars ← xs.size.foldRevM (init := initMotiveFVars) fun i s => do
987+
let x := xs[i]!
988+
if elimInfo.motivePos == i || elimInfo.targetsPos.contains i || s.fvarSet.contains x.fvarId! then
989+
return collectFVars s (← inferType x)
990+
else
991+
return s
992+
/- Collect the extra argument positions -/
984993
let mut extraArgsPos := #[]
985-
/- Transitive closure of fvars appearing in the motive and the targets. -/
986-
let mut motiveFVars : CollectFVars.State := collectFVars {} xs[elimInfo.motivePos]!
987-
for arg in targets do
988-
motiveFVars := collectFVars (collectFVars motiveFVars arg) (← inferType arg)
989-
/- Process arguments in reverse order to transitively collect extra args positions -/
990-
for i' in [:xs.size] do
991-
let i := xs.size - 1 - i'
994+
for i in [:xs.size] do
992995
let x := xs[i]!
993996
let xType ← x.fvarId!.getType
994997
unless elimInfo.motivePos == i || elimInfo.targetsPos.contains i do
995-
if motiveFVars.fvarSet.contains x.fvarId! then
996-
extraArgsPos := extraArgsPos.push i
997-
motiveFVars := collectFVars motiveFVars xType
998-
else if isFirstOrder xType
999-
&& Option.isSome (xType.find? fun e => e.isFVar && motiveFVars.fvarSet.contains e.fvarId!) then
1000-
/- We only consider "first-order" types because we can reliably "extract" information from them. -/
998+
/- We only consider "first-order" types because we can reliably "extract" information from them. -/
999+
if motiveFVars.fvarSet.contains x.fvarId!
1000+
|| (isFirstOrder xType
1001+
&& Option.isSome (xType.find? fun e => e.isFVar && motiveFVars.fvarSet.contains e.fvarId!)) then
10011002
extraArgsPos := extraArgsPos.push i
10021003
return extraArgsPos
10031004

0 commit comments

Comments
 (0)