A round of clean-up for the context of the functional induction principle cases. * Already previously, with `match e with | p => …`, functional induction would ensure that `h : e = p` is in scope, but it wouldn’t work in dependent cases. Now it introduces heterogeneous equality where needed (fixes #4146) * These equalities are now added always (previously we omitted them when the discriminant was a variable that occurred in the goal, on the grounds that the goal gets refined through the match, but it’s more consistent to introduce the equality in any case) * We no longer use `MVarId.cleanup` to clean up the goal; it was sometimes too aggressive (fixes #5347) * Instead, we clean up more carefully and with a custom strategy: * First, we substitute all variables without a user-accessible name, if we can. * Then, we substitute all variable, if we can, outside in. * As we do that, we look for `HEq`s that we can turn into `Eq`s to substitute some more * We substitute unused `let`s. **Breaking change**: In some cases leads to a different functional induction principle (different names and order of assumptions, for example).
17 lines
477 B
Text
17 lines
477 B
Text
def f (x: Nat): Option Nat :=
|
|
if x > 10 then some 0 else none
|
|
|
|
def test (x: Nat): Nat :=
|
|
match f x, x with
|
|
| some k, _ => k
|
|
| none, 0 => 0
|
|
| none, n + 1 => test n
|
|
|
|
-- set_option trace.Meta.FunInd true
|
|
|
|
/--
|
|
info: test.induct (motive : Nat → Prop) (case1 : ∀ (t k : Nat), f t = some k → motive t) (case2 : f 0 = none → motive 0)
|
|
(case3 : ∀ (n : Nat), f n.succ = none → motive n → motive n.succ) (x : Nat) : motive x
|
|
-/
|
|
#guard_msgs in
|
|
#check test.induct
|