Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: improve proof search in IndPredBelow #4840

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 19 additions & 15 deletions src/Lean/Meta/IndPredBelow.lean
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,11 @@ def mkBelowDecl (ctx : Context) : MetaM Declaration := do
partial def backwardsChaining (m : MVarId) (depth : Nat) : MetaM Bool := do
m.withContext do
let mTy ← m.getType
if depth = 0 then
trace[Meta.IndPredBelow.search] "searching for {mTy}: ran out of max depth"
return false
else
withTraceNodeBefore `Meta.IndPredBelow.search (do pure m!"searching for {mTy}") do
trace[Meta.IndPredBelow.search] "Search goal:{m}"
if depth = 0 then
trace[Meta.IndPredBelow.search] "ran out of max depth"
return false
let lctx ← getLCtx
let r ← lctx.anyM fun localDecl =>
if localDecl.isAuxDecl then
Expand All @@ -245,11 +246,12 @@ partial def backwardsChaining (m : MVarId) (depth : Nat) : MetaM Bool := do
commitWhen do
let (mvars, _, t) ← forallMetaTelescope localDecl.type
if (← isDefEq mTy t) then
trace[Meta.IndPredBelow.search] "searching for {mTy}: trying {mkFVar localDecl.fvarId} : {localDecl.type}"
m.assign (mkAppN localDecl.toExpr mvars)
mvars.allM fun v =>
v.mvarId!.isAssigned <||> backwardsChaining v.mvarId! (depth - 1)
else return false
withTraceNodeBefore `Meta.IndPredBelow.search (do pure m!"trying {mkFVar localDecl.fvarId} : {localDecl.type}") do
m.assign (mkAppN localDecl.toExpr mvars)
mvars.allM fun v =>
v.mvarId!.isAssigned <||> backwardsChaining v.mvarId! (depth - 1)
else
return false
unless r do
trace[Meta.IndPredBelow.search] "searching for {mTy} failed"
return r
Expand Down Expand Up @@ -303,10 +305,10 @@ where
args.back.withApp fun ctor _ => do
let ctorName := ctor.constName!.updatePrefix below.constName!
let ctor := mkConst ctorName below.constLevels!
let ctorInfogetConstInfoCtor ctorName
let (mvars, _, _) ← forallMetaTelescope ctorInfo.type
let ctor := mkAppN ctor mvars
m.apply ctor
let msm.apply ctor
trace[Meta.IndPredBelow] "new goals {ms}"
pure ms.reverse
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change broke some other tests, until I added the reverse here; now the existing tests succeed. 🤷

Note to my future self:

I wonder if this just means that for any order of mvars we’ll have examples where it fails, or if there is really a reason why this order is good™. I’ll have to come back to this and think about it some more.

Maybe I’ll also investigate if we avoid proof search here and build the necessary terms direct, relying on the structure of the .ibelow construction.


return mss.foldr List.append []

introNPRec (m : MVarId) : MetaM MVarId := do
Expand All @@ -322,12 +324,14 @@ where
def mkBrecOnDecl (ctx : Context) (idx : Nat) : MetaM Declaration := do
let type ← mkType
let indVal := ctx.typeInfos[idx]!
let name := indVal.name ++ .mkSimple brecOnSuffix
let name := mkBRecOnName indVal.name
let value ← proveBrecOn ctx indVal type
trace[Meta.IndPredBelow] "brecOn value: {value}"
return Declaration.thmDecl {
name := name
levelParams := indVal.levelParams
type := type
value := ←proveBrecOn ctx indVal type }
value := value}
where
mkType : MetaM Expr :=
forallTelescopeReducing ctx.headers[idx]! fun xs _ => do
Expand Down
8 changes: 8 additions & 0 deletions tests/lean/run/1672.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
inductive TransClosure (r : α → α → Prop) : α → α → Prop
| extends : r a b → TransClosure r a b
| trans_left : r a b → TransClosure r b c → TransClosure r a c

def trans' {a b c} : TransClosure r a b → TransClosure r b c → TransClosure r a c
| .extends h₁ => .trans_left h₁
| .trans_left h₁ h₂ => .trans_left h₁ ∘ trans' h₂
termination_by structural t => t
1 change: 1 addition & 0 deletions tests/lean/run/1674.lean
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ inductive T : Prop where
def inc: T → T
| T.nil n => T.nil (n+1)
| T.fn f => T.fn fun n => inc (f n)
termination_by structural t => t
2 changes: 1 addition & 1 deletion tests/lean/run/4751.lean
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
inductive F: Prop where
inductive F : Prop where
| base
| step (fn: Nat → F)

Expand Down
Loading