This PR improves `match` generalization such that it abstracts metavariables in types of local variables and in the result type of the match over the match discriminants. Previously, a metavariable in the result type would silently default to the behavior of `generalizing := false`, and a metavariable in the type of a free variable would lead to an error (#8099). Example of a `match` that elaborates now but previously wouldn't: ```lean example (a : Nat) (ha : a = 37) := (match a with | 42 => by contradiction | n => n) = 37 ``` This is because the result type of the `match` is a metavariable that was not abstracted over `a` and hence generalization failed; the result is that `contradiction` cannot pick up the proof `ha : 42 = 37`. The old behavior can be recovered by passing `(generalizing := false)` to the `match`. Furthermore, programs such as the following can now be elaborated: ```lean example (n : Nat) : Id (Fin (n + 1)) := have jp : ?m := ?rhs match n with | 0 => ?jmp1 | n + 1 => ?jmp2 where finally case m => exact Fin (n + 1) → Id (Fin (n + 1)) case jmp1 => exact jp ⟨0, by decide⟩ case jmp2 => exact jp ⟨n, by omega⟩ case rhs => exact pure ``` This is useful for the `do` elaborator. Fixes #8099.
34 lines
1.1 KiB
Text
34 lines
1.1 KiB
Text
|
||
example : List Bool :=
|
||
let s : String := "test"
|
||
let l : List Nat := [1, 2, 3]
|
||
let r := match 1 with | _ => l.map (fun n => let (x) := s; true)
|
||
[]
|
||
|
||
example : List Bool :=
|
||
let p : String × String := ("test", "test")
|
||
let l : List Nat := [1, 2, 3]
|
||
let o : Option Nat := none
|
||
let r :=
|
||
match o with
|
||
| none => [false]
|
||
| some m => l.map (fun n => let (x, y) := p; true)
|
||
[]
|
||
|
||
-- Previously, the `contradiction` below would fail because the `match` would have been generalized.
|
||
-- That was because the expected type of the `match` was a metavariable that was not properly
|
||
-- abstracted over `a`; hence the `matchType` was type incorrect and generalization failed to
|
||
-- re-introduce `ha : 42 = 37`.
|
||
example (a : Nat) (ha : a = 37) :=
|
||
(match a with | 42 => by contradiction | n => n) = 37
|
||
|
||
example (n : Nat) : Id (Fin (n + 1)) :=
|
||
have jp : ?m := ?rhs
|
||
match n with
|
||
| 0 => ?jmp1
|
||
| n + 1 => ?jmp2
|
||
where finally
|
||
case m => exact Fin (n + 1) → Id (Fin (n + 1))
|
||
case jmp1 => exact jp ⟨0, by decide⟩
|
||
case jmp2 => exact jp ⟨n, by omega⟩
|
||
case rhs => exact pure
|