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
|