feat: pp.analyze improve heuristics for fun binders

This commit is contained in:
Daniel Selsam 2021-08-11 12:56:58 -07:00 committed by Sebastian Ullrich
parent 638d0ca8ed
commit 5952a857cd
2 changed files with 53 additions and 3 deletions

View file

@ -334,6 +334,7 @@ structure App.Context where
structure App.State where
bottomUps : Array Bool
higherOrders : Array Bool
funBinders : Array Bool
provideds : Array Bool
namedArgs : Array Name := #[]
@ -397,7 +398,8 @@ mutual
analyzeAppStagedCore ⟨f, fType, args, mvars, bInfos, forceRegularApp⟩ |>.run' {
bottomUps := mkArray args.size false,
higherOrders := mkArray args.size false,
provideds := mkArray args.size false
provideds := mkArray args.size false,
funBinders := mkArray args.size false
}
if not rest.isEmpty then
@ -453,6 +455,7 @@ mutual
hBinOpHeuristic
collectTrivialBottomUps
discard <| processPostponed (mayPostpone := true)
applyFunBinderHeuristic
analyzeFn
for i in [:(← read).args.size] do analyzeArg i
maybeSetExplicit
@ -500,6 +503,31 @@ mutual
tryUnify args[i] mvars[i]
modify fun s => { s with bottomUps := s.bottomUps.set! i true }
applyFunBinderHeuristic := do
let ⟨f, _, args, mvars, bInfos, _⟩ ← read
let rec core (argIdx : Nat) (mvarType : Expr) : AnalyzeAppM Bool := do
match ← getExpr, mvarType with
| Expr.lam _ _ _ .., Expr.forallE n t b .. =>
let mut annotated := false
for i in [:argIdx] do
if ← bInfos[i] == BinderInfo.implicit <&&> valUnknown mvars[i] <&&> withNewMCtxDepth (checkpointDefEq t mvars[i]) then
annotateBool `pp.funBinderTypes
tryUnify args[i] mvars[i]
-- Note: currently we always analyze the lambda binding domains in `analyzeLam`
-- (so we don't need to analyze it again here)
annotated := true
break
let annotatedBody ← withBindingBody Name.anonymous (core argIdx b)
return annotated || annotatedBody
| _, _ => return false
for i in [:args.size] do
if ← bInfos[i] == BinderInfo.default then
let b ← withNaryArg i (core i (← inferType mvars[i]))
if b then modify fun s => { s with funBinders := s.funBinders.set! i true }
analyzeFn := do
-- Now, if this is the first staging, analyze the n-ary function without expected type
let ⟨f, fType, _, _, _, forceRegularApp⟩ ← read
@ -511,7 +539,7 @@ mutual
analyzeArg (i : Nat) := do
let ⟨f, _, args, mvars, bInfos, forceRegularApp⟩ ← read
let ⟨bottomUps, higherOrders,_, _⟩ ← get
let ⟨bottomUps, higherOrders, funBinders, _, _⟩ ← get
let arg := args[i]
let argType ← inferType arg
@ -527,7 +555,7 @@ mutual
match bInfos[i] with
| BinderInfo.default =>
if ← !(← valUnknown mvars[i]) <&&> !(← readThe Context).inBottomUp <&&> !(← isFunLike arg) <&&> checkpointDefEq mvars[i] arg then
if ← !(← valUnknown mvars[i]) <&&> !(← readThe Context).inBottomUp <&&> !(← isFunLike arg) <&&> !funBinders[i] <&&> checkpointDefEq mvars[i] arg then
annotateBool `pp.analysis.hole
else
modify fun s => { s with provideds := s.provideds.set! i true }

View file

@ -278,6 +278,28 @@ set_option pp.proofs.withType false in
let ctxCore ← readThe Core.Context
pure ctxCore.currNamespace
structure SubtypeLike1 {α : Sort u} (p : α → Prop) where
#testDelab SubtypeLike1 fun (x : Nat) => x < 10
expecting SubtypeLike1 fun (x : Nat) => x < 10
#eval "prevent comment from parsing as part of previous expression"
--Note: currently we do not try "bottom-upping" inside lambdas
--(so we will always annotate the binder type)
#testDelab SubtypeLike1 fun (x : Nat) => Nat.succ x = x
expecting SubtypeLike1 fun (x : Nat) => Nat.succ x = x
structure SubtypeLike3 {α β γ : Sort u} (p : α → β → γ → Prop) where
#testDelab SubtypeLike3 fun (x y z : Nat) => x + y < z
expecting SubtypeLike3 fun (x y z : Nat) => x + y < z
structure SubtypeLike3Double {α β γ : Sort u} (p₁ : α → β → Prop) (p₂ : β → γ → Prop) where
#testDelab SubtypeLike3Double (fun (x y : Nat) => x = y) (fun (y z : Nat) => y = z)
expecting SubtypeLike3Double (fun (x y : Nat) => x = y) fun y (z : Nat) => y = z
def takesStricts ⦃α : Type⦄ {β : Type} ⦃γ : Type⦄ : Unit := ()
#testDelab takesStricts expecting takesStricts
#testDelab @takesStricts expecting takesStricts