-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: split on
match
-expressions in the grind
tactic (#6569)
This PR adds support for case splitting on `match`-expressions in `grind`. We still need to add support for resolving the antecedents of `match`-conditional equations.
- Loading branch information
1 parent
9040108
commit 00ef231
Showing
9 changed files
with
121 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/- | ||
Copyright (c) 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
Released under Apache 2.0 license as described in the file LICENSE. | ||
Authors: Leonardo de Moura | ||
-/ | ||
prelude | ||
import Lean.Meta.Tactic.Util | ||
import Lean.Meta.Tactic.Cases | ||
import Lean.Meta.Match.MatcherApp | ||
|
||
namespace Lean.Meta.Grind | ||
|
||
def casesMatch (mvarId : MVarId) (e : Expr) : MetaM (List MVarId) := mvarId.withContext do | ||
let some app ← matchMatcherApp? e | ||
| throwTacticEx `grind.casesMatch mvarId m!"`match`-expression expected{indentExpr e}" | ||
let (motive, eqRefls) ← mkMotiveAndRefls app | ||
let target ← mvarId.getType | ||
let mut us := app.matcherLevels | ||
if let some i := app.uElimPos? then | ||
us := us.set! i (← getLevel target) | ||
let splitterName := (← Match.getEquationsFor app.matcherName).splitterName | ||
let splitterApp := mkConst splitterName us.toList | ||
let splitterApp := mkAppN splitterApp app.params | ||
let splitterApp := mkApp splitterApp motive | ||
let splitterApp := mkAppN splitterApp app.discrs | ||
let (mvars, _, _) ← forallMetaBoundedTelescope (← inferType splitterApp) app.alts.size (kind := .syntheticOpaque) | ||
let splitterApp := mkAppN splitterApp mvars | ||
let val := mkAppN splitterApp eqRefls | ||
mvarId.assign val | ||
updateTags mvars | ||
return mvars.toList.map (·.mvarId!) | ||
where | ||
mkMotiveAndRefls (app : MatcherApp) : MetaM (Expr × Array Expr) := do | ||
let dummy := mkSort 0 | ||
let aux := mkApp (mkAppN e.getAppFn app.params) dummy | ||
forallBoundedTelescope (← inferType aux) app.discrs.size fun xs _ => do | ||
withNewEqs app.discrs xs fun eqs eqRefls => do | ||
let type ← mvarId.getType | ||
let type ← mkForallFVars eqs type | ||
let motive ← mkLambdaFVars xs type | ||
return (motive, eqRefls) | ||
|
||
updateTags (mvars : Array Expr) : MetaM Unit := do | ||
let tag ← mvarId.getTag | ||
if mvars.size == 1 then | ||
mvars[0]!.mvarId!.setTag tag | ||
else | ||
let mut idx := 1 | ||
for mvar in mvars do | ||
mvar.mvarId!.setTag (Name.num tag idx) | ||
idx := idx + 1 | ||
|
||
end Lean.Meta.Grind |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
def g (a : α) (as : List α) : List α := | ||
match as with | ||
| [] => [a] | ||
| b::bs => a::a::b::bs | ||
|
||
set_option trace.grind true in | ||
set_option trace.grind.assert true in | ||
example : ¬ (g a as).isEmpty := by | ||
unfold List.isEmpty | ||
unfold g | ||
grind | ||
|
||
def h (as : List Nat) := | ||
match as with | ||
| [] => 1 | ||
| [_] => 2 | ||
| _::_::_ => 3 | ||
|
||
/-- | ||
info: [grind] closed `grind.1` | ||
[grind] closed `grind.2` | ||
[grind] closed `grind.3` | ||
-/ | ||
#guard_msgs (info) in | ||
set_option trace.grind true in | ||
example : h as ≠ 0 := by | ||
unfold h | ||
grind |