Skip to content

Commit ca9f13c

Browse files
committed
Revert "Playing around with cases not failing with index mismatch"
This reverts commit 9fb68c1.
1 parent 9fb68c1 commit ca9f13c

File tree

4 files changed

+26
-47
lines changed

4 files changed

+26
-47
lines changed

src/Lean/Meta/Match/Match.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ private def processConstructor (p : Problem) : MetaM (Array Problem) := do
513513
let subgoals? ← commitWhenSome? do
514514
let subgoals ←
515515
try
516-
p.mvarId.cases x.fvarId! (mayLeaveEquations := true)
516+
p.mvarId.cases x.fvarId!
517517
catch ex =>
518518
if p.alts.isEmpty then
519519
/- If we have no alternatives and dependent pattern matching fails, then a "missing cases" error is better than a "stuck" error message. -/

src/Lean/Meta/Tactic/Cases.lean

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -226,20 +226,19 @@ private def toCasesSubgoals (s : Array InductionSubgoal) (ctorNames : Array Name
226226
{ ctorName := ctorName,
227227
toInductionSubgoal := s }
228228

229-
partial def unifyEqs? (numEqs : Nat) (mvarId : MVarId) (subst : FVarSubst)
230-
(caseName? : Option Name := none) (mayFail : Bool := false) : MetaM (Option (MVarId × FVarSubst)) := withIncRecDepth do
229+
partial def unifyEqs? (numEqs : Nat) (mvarId : MVarId) (subst : FVarSubst) (caseName? : Option Name := none): MetaM (Option (MVarId × FVarSubst)) := withIncRecDepth do
231230
if numEqs == 0 then
232231
return some (mvarId, subst)
233232
else
234233
let (eqFVarId, mvarId) ← mvarId.intro1
235-
if let some { mvarId, subst, numNewEqs } ← unifyEq? mvarId eqFVarId subst MVarId.acyclic caseName? (mayFail := mayFail) then
236-
unifyEqs? (numEqs - 1 + numNewEqs) mvarId subst caseName? (mayFail := mayFail)
234+
if let some { mvarId, subst, numNewEqs } ← unifyEq? mvarId eqFVarId subst MVarId.acyclic caseName? then
235+
unifyEqs? (numEqs - 1 + numNewEqs) mvarId subst caseName?
237236
else
238237
return none
239238

240-
private def unifyCasesEqs (numEqs : Nat) (subgoals : Array CasesSubgoal) (mayFail := false) : MetaM (Array CasesSubgoal) :=
239+
private def unifyCasesEqs (numEqs : Nat) (subgoals : Array CasesSubgoal) : MetaM (Array CasesSubgoal) :=
241240
subgoals.filterMapM fun s => do
242-
match (← unifyEqs? numEqs s.mvarId s.subst s.ctorName (mayFail := mayFail)) with
241+
match (← unifyEqs? numEqs s.mvarId s.subst s.ctorName) with
243242
| none => pure none
244243
| some (mvarId, subst) =>
245244
return some { s with
@@ -259,7 +258,7 @@ private def inductionCasesOn (mvarId : MVarId) (majorFVarId : FVarId) (givenName
259258
let s ← mvarId.induction majorFVarId casesOn givenNames
260259
return toCasesSubgoals s ctors majorFVarId us params
261260

262-
def cases (mvarId : MVarId) (majorFVarId : FVarId) (givenNames : Array AltVarNames := #[]) (useNatCasesAuxOn : Bool := false) (mayLeaveEquations := false) : MetaM (Array CasesSubgoal) := do
261+
def cases (mvarId : MVarId) (majorFVarId : FVarId) (givenNames : Array AltVarNames := #[]) (useNatCasesAuxOn : Bool := false) : MetaM (Array CasesSubgoal) := do
263262
try
264263
mvarId.withContext do
265264
mvarId.checkNotAssigned `cases
@@ -278,7 +277,7 @@ def cases (mvarId : MVarId) (majorFVarId : FVarId) (givenNames : Array AltVarNam
278277
trace[Meta.Tactic.cases] "after generalizeIndices\n{MessageData.ofGoal s₁.mvarId}"
279278
let s₂ ← inductionCasesOn s₁.mvarId s₁.fvarId givenNames ctx
280279
let s₂ ← elimAuxIndices s₁ s₂
281-
unifyCasesEqs s₁.numEqs s₂ (mayFail := mayLeaveEquations)
280+
unifyCasesEqs s₁.numEqs s₂
282281
catch ex =>
283282
throwNestedTacticEx `cases ex
284283

@@ -293,9 +292,8 @@ Apply `casesOn` using the free variable `majorFVarId` as the major premise (aka
293292
It enables using `Nat.casesAuxOn` instead of `Nat.casesOn`,
294293
which causes case splits on `n : Nat` to be represented as `0` and `n' + 1` rather than as `Nat.zero` and `Nat.succ n'`.
295294
-/
296-
def _root_.Lean.MVarId.cases (mvarId : MVarId) (majorFVarId : FVarId)
297-
(givenNames : Array AltVarNames := #[]) (useNatCasesAuxOn : Bool := false) (mayLeaveEquations := false) : MetaM (Array CasesSubgoal) :=
298-
Cases.cases mvarId majorFVarId givenNames (useNatCasesAuxOn := useNatCasesAuxOn) (mayLeaveEquations := mayLeaveEquations)
295+
def _root_.Lean.MVarId.cases (mvarId : MVarId) (majorFVarId : FVarId) (givenNames : Array AltVarNames := #[]) (useNatCasesAuxOn : Bool := false) : MetaM (Array CasesSubgoal) :=
296+
Cases.cases mvarId majorFVarId givenNames (useNatCasesAuxOn := useNatCasesAuxOn)
299297

300298
/--
301299
Keep applying `cases` on any hypothesis that satisfies `p`.

src/Lean/Meta/Tactic/UnifyEq.lean

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -46,22 +46,13 @@ private def toOffset? (e : Expr) : MetaM (Option (Expr × Nat)) := do
4646
-/
4747
def unifyEq? (mvarId : MVarId) (eqFVarId : FVarId) (subst : FVarSubst := {})
4848
(acyclic : MVarId → Expr → MetaM Bool := fun _ _ => return false)
49-
(caseName? : Option Name := none) (mayFail : Bool := false)
49+
(caseName? : Option Name := none)
5050
: MetaM (Option UnifyEqResult) := do
5151
mvarId.withContext do
5252
let eqDecl ← eqFVarId.getDecl
53-
trace[Meta.Tactic.cases] "unifyEq? {mkFVar eqDecl.fvarId} : {eqDecl.type}"
5453
if eqDecl.type.isHEq then
55-
let (varId, mvarId) ← heqToEq mvarId eqDecl.fvarId
56-
if varId == eqDecl.fvarId then
57-
-- heqToEq failed
58-
if mayFail then
59-
return some { mvarId, subst }
60-
else
61-
throwError "Dependent elimination failed: Failed to convert heterogeneous equality{indentExpr eqDecl.type} to homogeneous equality"
62-
else
63-
let (_, mvarId) ← mvarId.revert #[varId]
64-
return some { mvarId, subst, numNewEqs := 1 }
54+
let mvarId ← heqToEq' mvarId eqDecl
55+
return some { mvarId, subst, numNewEqs := 1 }
6556
else match eqDecl.type.eq? with
6657
| none => throwError "Expected an equality, but found{indentExpr eqDecl.type}"
6758
| some (_, a, b) =>
@@ -86,10 +77,7 @@ def unifyEq? (mvarId : MVarId) (eqFVarId : FVarId) (subst : FVarSubst := {})
8677
else if (← acyclic mvarId (mkFVar eqFVarId)) then
8778
return none -- this alternative has been solved
8879
else
89-
if mayFail then
90-
return some { mvarId, subst }
91-
else
92-
throwError "Dependent elimination failed: Failed to solve equation{indentExpr eqDecl.type}"
80+
throwError "Dependent elimination failed: Failed to solve equation{indentExpr eqDecl.type}"
9381
/- Special support for offset equalities -/
9482
let injectionOffset? (a b : Expr) := do
9583
unless (← getEnv).contains ``Nat.elimOffset do return none
@@ -130,12 +118,9 @@ def unifyEq? (mvarId : MVarId) (eqFVarId : FVarId) (subst : FVarSubst := {})
130118
let mvarId ← mvarId.clear eqFVarId
131119
return some { mvarId, subst, numNewEqs := 1 }
132120
else
133-
if mayFail then
134-
return some { mvarId, subst }
135-
else
136-
match caseName? with
137-
| none => throwError "Dependent elimination failed: Failed to solve equation{indentExpr eqDecl.type}"
138-
| some caseName => throwError "Dependent elimination failed: Failed to solve equation{indentExpr eqDecl.type}\nat case `{.ofConstName caseName}`"
121+
match caseName? with
122+
| none => throwError "Dependent elimination failed: Failed to solve equation{indentExpr eqDecl.type}"
123+
| some caseName => throwError "Dependent elimination failed: Failed to solve equation{indentExpr eqDecl.type}\nat case `{.ofConstName caseName}`"
139124
let a ← instantiateMVars a
140125
let b ← instantiateMVars b
141126
match a, b with

tests/lean/run/matchOverlapInaccesible.lean

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,23 +54,19 @@ def parity (n : MyNat) : Parity n := sorry
5454
-- set_option trace.Meta.Match.match true
5555

5656
/--
57-
error: Dependent match elimination failed: Could not solve constraints
58-
a✝.succ ≋ n✝ + n✝
57+
error: Tactic `cases` failed with a nested error:
58+
Dependent elimination failed: Failed to solve equation
59+
a✝.succ = n✝.add n✝
60+
at case `Parity.even` after processing
61+
(succ _), _
62+
the dependent pattern matcher can solve the following kinds of equations
63+
- <var> = <term> and <term> = <var>
64+
- <term> = <term> where the terms are definitionally equal
65+
- <constructor> = <constructor>, examples: List.cons x xs = List.cons y ys, and List.cons x xs = List.nil
5966
-/
6067
#guard_msgs(pass trace, all) in
6168
partial def myNatToBinBad (n : MyNat) : List Bool :=
6269
match n, parity n with
6370
| zero, _ => []
6471
| _, Parity.even j => false :: myNatToBinBad j
6572
| _, Parity.odd j => true :: myNatToBinBad j
66-
67-
set_option trace.Meta.Tactic.cases true
68-
/--
69-
error: Tactic `cases` failed with a nested error:
70-
Dependent elimination failed: Failed to solve equation
71-
n.succ = n✝.add n✝
72-
at case `Parity.even`
73-
-/
74-
#guard_msgs(pass trace, all) in
75-
example (h : Parity (MyNat.succ n)) : false := by
76-
rcases h

0 commit comments

Comments
 (0)