lean4-htt/tests/lean/run/lcnfCastIssue.lean
Kyle Miller 45fccc5906
feat: custom eliminators for induction and cases tactics, and beautiful eliminators for Nat (#3629)
Replaces `@[eliminator]` with two attributes `@[induction_eliminator]`
and `@[cases_eliminator]` for defining custom eliminators for the
`induction` and `cases` tactics, respectively.

Adds `Nat.recAux` and `Nat.casesAuxOn`, which are eliminators that are
defeq to `Nat.rec` and `Nat.casesOn`, but these use `0` and `n + 1`
rather than `Nat.zero` and `Nat.succ n`.

For example, using `induction` to prove that the factorial function is
positive now has the following goal states (thanks also to #3616 for the
goal state after unfolding).
```lean
example : 0 < fact x := by
  induction x with
  | zero => decide
  | succ x ih =>
    /-
    x : Nat
    ih : 0 < fact x
    ⊢ 0 < fact (x + 1)
    -/
    unfold fact
    /-
    ...
    ⊢ 0 < (x + 1) * fact x
    -/
    simpa using ih
```

Thanks to @adamtopaz for initial work on splitting the `@[eliminator]`
attribute.
2024-03-09 15:31:51 +00:00

39 lines
1 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

namespace MWE
universe u v w
inductive Id {A : Type u} : A → A → Type u
| refl {a : A} : Id a a
attribute [induction_eliminator] Id.casesOn
infix:50 (priority := high) " = " => Id
inductive Unit : Type u
| star : Unit
attribute [induction_eliminator] Unit.casesOn
notation "𝟏" => Unit
notation "★" => Unit.star
notation "" => Nat
def vect (A : Type u) : → Type u
| Nat.zero => 𝟏
| Nat.succ n => A × vect A n
def vect.const {A : Type u} (a : A) : ∀ n, vect A n
| Nat.zero => ★
| Nat.succ n => (a, const a n)
def vect.map {A : Type u} {B : Type v} (f : A → B) :
∀ {n : }, vect A n → vect B n
| Nat.zero => λ _ => ★
| Nat.succ n => λ v => (f v.1, map f v.2)
def transport {A : Type u} (B : A → Type v) {a b : A} (p : a = b) : B a → B b :=
by { induction p; apply id }
def vect.subst {A B : Type u} (p : A = B) (f : B → A) {n : } (v : vect A n) :
vect.map f (transport (vect · n) p v) = vect.map (f ∘ transport id p) v :=
by { induction p; apply Id.refl }