Now the elab-as-elim procedure allows eliminators whose result is an
arbitrary application of the motive. For example, the following is now
accepted. It will generalize `Int.natAbs _` from the expected type.
```lean
@[elab_as_elim]
theorem natAbs_elim {motive : Nat → Prop} (i : Int)
(hpos : ∀ (n : Nat), i = n → motive n)
(hneg : ∀ (n : Nat), i = -↑n → motive n) :
motive (Int.natAbs i) := by sorry
```
This change simplifies the elaborator, since it no longer needs to keep
track of discriminants (which can easily be read off from the return
type of the eliminator) or the difference between "targets" and "extra
arguments" (which are now both "major arguments" that should be eagerly
elaborated).
Closes #4086
39 lines
1.2 KiB
Text
39 lines
1.2 KiB
Text
/-!
|
|
# Generalize `elab_as_elim` to allow arbitrary motive applications
|
|
-/
|
|
|
|
/-!
|
|
The following eliminator isn't valid for `induction`/`cases` since the return type
|
|
has `motive` applied to `Int.natAbs i`, which isn't a parameter,
|
|
but this is not a problem for `elab_as_elim`.
|
|
-/
|
|
|
|
@[elab_as_elim]
|
|
theorem natAbs_elim {motive : Nat → Prop} (i : Int)
|
|
(hpos : ∀ (n : Nat), i = n → motive n)
|
|
(hneg : ∀ (n : Nat), i = -↑n → motive n) :
|
|
motive (Int.natAbs i) := by sorry
|
|
|
|
example (x : Int) (y : Nat) : x.natAbs < y := by
|
|
refine natAbs_elim x ?_ ?_
|
|
· guard_target = ∀ (n : Nat), x = ↑n → n < y
|
|
sorry
|
|
· guard_target = ∀ (n : Nat), x = -↑n → n < y
|
|
sorry
|
|
|
|
example (x : Int) (y : Nat) : (x + 1).natAbs + 1 < y := by
|
|
refine natAbs_elim (x + 1) ?_ ?_
|
|
· guard_target = ∀ (n : Nat), x + 1 = ↑n → n + 1 < y
|
|
sorry
|
|
· guard_target = ∀ (n : Nat), x + 1 = -↑n → n + 1 < y
|
|
sorry
|
|
|
|
/-!
|
|
The target can be inferred from the expected type.
|
|
-/
|
|
example (x : Int) (y : Nat) : (x + 1).natAbs < y := by
|
|
refine natAbs_elim _ ?_ ?_
|
|
· guard_target = ∀ (n : Nat), x + 1 = ↑n → n < y
|
|
sorry
|
|
· guard_target = ∀ (n : Nat), x + 1 = -↑n → n < y
|
|
sorry
|