81 lines
1.8 KiB
Plaintext
81 lines
1.8 KiB
Plaintext
import Mathlib.Algebra.Group.Defs
|
||
import Mathlib.Data.Nat.Basic
|
||
import Mathlib.Tactic.NormNum
|
||
|
||
/-! # Common.List.NonEmpty
|
||
|
||
A `List` with at least one member.
|
||
-/
|
||
|
||
namespace List
|
||
|
||
structure NonEmpty (α : Type _) : Type _ where
|
||
head : α
|
||
tail : List α
|
||
|
||
instance : Coe (NonEmpty α) (List α) where
|
||
coe (xs : NonEmpty α) := xs.head :: xs.tail
|
||
|
||
instance : CoeDep (List α) (cons x xs : List α) (NonEmpty α) where
|
||
coe := { head := x, tail := xs }
|
||
|
||
namespace NonEmpty
|
||
|
||
/--
|
||
The length of a `List.NonEmpty`.
|
||
-/
|
||
def length (xs : NonEmpty α) : Nat := 1 + xs.tail.length
|
||
|
||
/--
|
||
The length of a `List.NonEmpty` is always one plus the length of its tail.
|
||
-/
|
||
theorem length_self_eq_one_add_length_tail (xs : NonEmpty α)
|
||
: xs.length = 1 + xs.tail.length := rfl
|
||
|
||
/--
|
||
A proof that an index is within the bounds of the `List.NonEmpty`.
|
||
-/
|
||
abbrev inBounds (xs : NonEmpty α) (i : Nat) : Prop :=
|
||
i < xs.length
|
||
|
||
/--
|
||
Retrieves the member of the `List.NonEmpty` at the specified index.
|
||
-/
|
||
def get (xs : NonEmpty α) : (i : Nat) → (h : xs.inBounds i) → α
|
||
| 0, _ => xs.head
|
||
| n + 1, h =>
|
||
have : n < xs.tail.length := by
|
||
unfold inBounds at h
|
||
rw [length_self_eq_one_add_length_tail, add_comm] at h
|
||
norm_num at h
|
||
exact h
|
||
xs.tail[n]
|
||
|
||
/--
|
||
Variant of `get` that returns an `Option α` in the case of an invalid index.
|
||
-/
|
||
def get? : NonEmpty α → Nat → Option α
|
||
| xs, 0 => some xs.head
|
||
| xs, n + 1 => xs.tail.get? n
|
||
|
||
/--
|
||
Type class instance for allowing direct indexing notation.
|
||
-/
|
||
instance : GetElem (NonEmpty α) Nat α inBounds where
|
||
getElem := get
|
||
|
||
/--
|
||
Convert a `List.NonEmpty` into a plain `List`.
|
||
-/
|
||
def toList (xs : NonEmpty α) : List α := xs
|
||
|
||
/--
|
||
Retrieve the last member of the `List.NonEmpty`.
|
||
-/
|
||
def last : NonEmpty α → α
|
||
| ⟨head, []⟩ => head
|
||
| ⟨_, cons x xs⟩ => last (cons x xs)
|
||
|
||
end NonEmpty
|
||
|
||
end List |