Skip to content

Commit 528fe0b

Browse files
authored
fix: FunInd: clean up packed arguments more throughly (#8356)
This PR tries harder to clean internals of the argument packing of n-ary functions from the functional induction theorem, in particular the unfolding variant
1 parent 01dbbee commit 528fe0b

File tree

1 file changed

+32
-7
lines changed

1 file changed

+32
-7
lines changed

src/Lean/Meta/Tactic/FunInd.lean

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,17 +1091,20 @@ In the type of `value`, reduces
10911091
* `PSum.casesOn (PSum.inl x) k₁ k₂ --> k₁ x`
10921092
* `foo._unary (PSum.inl (PSigma.mk a b)) --> foo a b`
10931093
and then wraps `value` in an appropriate type hint.
1094+
1095+
(The implementation is repetitive and verbose, and should be cleaned up when convenient.)
10941096
-/
10951097
def cleanPackedArgs (eqnInfo : WF.EqnInfo) (value : Expr) : MetaM Expr := do
10961098
let type ← inferType value
1097-
let cleanType ← Meta.transform type (skipConstInApp := true) (pre := fun e => do
1099+
let cleanType ← Meta.transform type (skipConstInApp := true) (post := fun e => do
10981100
-- Need to beta-reduce first
10991101
let e' := e.headBeta
11001102
if e' != e then
11011103
return .visit e'
1104+
1105+
e.withApp fun f args => do
11021106
-- Look for PSigma redexes
1103-
if e.isAppOf ``PSigma.casesOn then
1104-
let args := e.getAppArgs
1107+
if f.isConstOf ``PSigma.casesOn then
11051108
if 5 ≤ args.size then
11061109
let scrut := args[3]!
11071110
let k := args[4]!
@@ -1110,9 +1113,32 @@ def cleanPackedArgs (eqnInfo : WF.EqnInfo) (value : Expr) : MetaM Expr := do
11101113
let #[_, _, x, y] := scrut.getAppArgs | unreachable!
11111114
let e' := (k.beta #[x, y]).beta extra
11121115
return .visit e'
1116+
-- Look for PSigma projection
1117+
if f.isConstOf ``PSigma.fst then
1118+
if h : 3 ≤ args.size then
1119+
let scrut := args[2]
1120+
let extra := args[3:]
1121+
if scrut.isAppOfArity ``PSigma.mk 4 then
1122+
let #[_, _, x, _y] := scrut.getAppArgs | unreachable!
1123+
let e' := x.beta extra
1124+
return .visit e'
1125+
if f.isConstOf ``PSigma.snd then
1126+
if h : 3 ≤ args.size then
1127+
let scrut := args[2]
1128+
let extra := args[3:]
1129+
if scrut.isAppOfArity ``PSigma.mk 4 then
1130+
let #[_, _, _x, y] := scrut.getAppArgs | unreachable!
1131+
let e' := y.beta extra
1132+
return .visit e'
1133+
if f.isProj then
1134+
let scrut := e.projExpr!
1135+
if scrut.isAppOfArity ``PSigma.mk 4 then
1136+
let #[_, _, x, y] := scrut.getAppArgs | unreachable!
1137+
let e' := (if e.projIdx! = 0 then x else y).beta args
1138+
return .visit e'
1139+
11131140
-- Look for PSum redexes
1114-
if e.isAppOf ``PSum.casesOn then
1115-
let args := e.getAppArgs
1141+
if f.isConstOf ``PSum.casesOn then
11161142
if 6 ≤ args.size then
11171143
let scrut := args[3]!
11181144
let k₁ := args[4]!
@@ -1125,8 +1151,7 @@ def cleanPackedArgs (eqnInfo : WF.EqnInfo) (value : Expr) : MetaM Expr := do
11251151
let e' := (k₂.beta #[scrut.appArg!]).beta extra
11261152
return .visit e'
11271153
-- Look for _unary redexes
1128-
if e.isAppOf eqnInfo.declNameNonRec then
1129-
let args := e.getAppArgs
1154+
if f.isConstOf eqnInfo.declNameNonRec then
11301155
if h : args.size ≥ eqnInfo.fixedParamPerms.numFixed + 1 then
11311156
let xs := args[:eqnInfo.fixedParamPerms.numFixed]
11321157
let packedArg := args[eqnInfo.fixedParamPerms.numFixed]

0 commit comments

Comments
 (0)