Compare commits

...

1 Commits

Author SHA1 Message Date
Leonardo de Moura
b10f1c0420 fix: missing condition in isMatchCondCandidate
This PR fixes a bug in `isMatchCondCandidate` used in `grind`. The
missing condition was causing a "not internalized term" `grind`
internal error.
2025-11-11 16:09:16 -08:00
2 changed files with 54 additions and 4 deletions

View File

@@ -13,10 +13,40 @@ import Lean.Meta.Tactic.Grind.Simp
public section
namespace Lean.Meta.Grind
/-- Returns `true` if `e` is of the form `∀ ..., _ = _ ... -> False` -/
def isMatchCondCandidate (e : Expr) : Bool :=
-- TODO: see comment at the beginning of `MatchCond.lean`.
Simp.isEqnThmHypothesis e
/--
Returns `true` if `e` is of the form `∀ ..., _ = _ ... -> False`.
The lhs of each equation must not have loose bound variables.
Recall that the `lhs` should correspond to variables in a given alternative.
For example, the given match-condition
```
∀ (head : Nat) (tail : List Nat), a = 1 → as = head :: tail → False
```
is generated for the second alternative at
```
def f : List Nat → List Nat → Nat
| _, 1 :: _ :: _ => ...
| _, a :: as => ...
| _, _ => ...
```
That is, `a` must be different from `1`, or `as` must not be of the form `_ :: _`. That is,
they must not be a match for the first alternative.
**Note**: We were *not* previously checking whether the `lhs` did not have loose bound variables.
This missing check caused a panic at `tryToProveFalse` function at `MatchCond.lean` because
it assumes the `lhs` does not have loose bound variables.
**Note**: This function is an approximation. It may return `true` for terms that do not
correspond to match-conditions.
-/
partial def isMatchCondCandidate (e : Expr) : Bool :=
e.isForall && go e
where
go (e : Expr) : Bool :=
if let .forallE _ d b _ := e then
match_expr d with
| Eq _ lhs _ => !lhs.hasLooseBVars && go b
| HEq _ lhs _ _ => !lhs.hasLooseBVars && go b
| _ => b.hasLooseBVar 0 && go b
else
e.isFalse
/--
Given a splitter alternative, annotate the terms that are `match`-expression

View File

@@ -0,0 +1,20 @@
/--
error: `grind` failed
case grind.2.2.1.1
n m a : Nat
ih : ∀ {a : Nat}, ¬a ^ 2 = 4 ^ m * n
h : a ^ 2 = 4 ^ (m + 1) * n
h_1 : ¬4 * 4 ^ m = 4 ^ m
h_2 : ¬4 * 4 ^ m = 4 ^ m
h_3 : n = 4 ^ m
h_4 : ↑a = 4
⊢ False
-/
#guard_msgs in
example {n m a : Nat} (ih : {a : Nat}, a ^ 2 = 4 ^ m * n False)
(h : a ^ 2 = 4 ^ (m + 1) * n) : False := by
grind -verbose
example {n m a : Nat} (ih : {a : Nat}, a ^ 2 = 4 ^ m * n False)
(h : a ^ 2 = 4 ^ m * n) : False := by
grind