Module docstring
{"Remark: land/lor can be defined without using (% n), but we are trying to minimize the number of Nat theorems needed to bootstrap Lean. "}
{"Remark: land/lor can be defined without using (% n), but we are trying to minimize the number of Nat theorems needed to bootstrap Lean. "}
Fin.coeToNat
instance
: CoeOut (Fin n) Nat
instance coeToNat : CoeOut (Fin n) Nat :=
⟨fun v => v.val⟩
Fin.elim0
definition
{α : Sort u} : Fin 0 → α
/--
The type `Fin 0` is uninhabited, so it can be used to derive any result whatsoever.
This is similar to `Empty.elim`. It can be thought of as a compiler-checked assertion that a code
path is unreachable, or a logical contradiction from which `False` and thus anything else could be
derived.
-/
def elim0.{u} {α : Sort u} : Fin 0 → α
| ⟨_, h⟩ => absurd h (not_lt_zero _)
Fin.succ
definition
: Fin n → Fin (n + 1)
Fin.ofNat'
definition
(n : Nat) [NeZero n] (a : Nat) : Fin n
Fin.ofNat
definition
{n : Nat} (a : Nat) : Fin (n + 1)
/--
Returns `a` modulo `n + 1` as a `Fin n.succ`.
-/
@[deprecated Fin.ofNat' (since := "2024-11-27")]
protected def ofNat {n : Nat} (a : Nat) : Fin (n + 1) :=
⟨a % (n+1), Nat.mod_lt _ (Nat.zero_lt_succ _)⟩
Fin.toNat
definition
(i : Fin n) : Nat
Fin.toNat_eq_val
theorem
{i : Fin n} : i.toNat = i.val
@[simp] theorem toNat_eq_val {i : Fin n} : i.toNat = i.val := rfl
Fin.add
definition
: Fin n → Fin n → Fin n
Fin.mul
definition
: Fin n → Fin n → Fin n
/--
Multiplication modulo `n`, usually invoked via the `*` operator.
Examples:
* `(2 : Fin 10) * (2 : Fin 10) = (4 : Fin 10)`
* `(2 : Fin 10) * (7 : Fin 10) = (4 : Fin 10)`
* `(3 : Fin 10) * (7 : Fin 10) = (1 : Fin 10)`
-/
protected def mul : Fin n → Fin n → Fin n
| ⟨a, h⟩, ⟨b, _⟩ => ⟨(a * b) % n, mlt h⟩
Fin.sub
definition
: Fin n → Fin n → Fin n
/--
Subtraction modulo `n`, usually invoked via the `-` operator.
Examples:
* `(5 : Fin 11) - (3 : Fin 11) = (2 : Fin 11)`
* `(3 : Fin 11) - (5 : Fin 11) = (9 : Fin 11)`
-/
protected def sub : Fin n → Fin n → Fin n
/-
The definition of `Fin.sub` has been updated to improve performance.
The right-hand-side of the following `match` was originally
```
⟨(a + (n - b)) % n, mlt h⟩
```
This caused significant performance issues when testing definitional equality,
such as `x =?= x - 1` where `x : Fin n` and `n` is a big number,
as Lean spent a long time reducing
```
((n - 1) + x.val) % n
```
For example, this was an issue for `Fin 2^64` (i.e., `UInt64`).
This change improves performance by leveraging the fact that `Nat.add` is defined
using recursion on the second argument.
See issue #4413.
-/
| ⟨a, h⟩, ⟨b, _⟩ => ⟨((n - b) + a) % n, mlt h⟩
Fin.mod
definition
: Fin n → Fin n → Fin n
Fin.div
definition
: Fin n → Fin n → Fin n
/--
Division of bounded numbers, usually invoked via the `/` operator.
The resulting value is that computed by the `/` operator on `Nat`. In particular, the result of
division by `0` is `0`.
Examples:
* `(5 : Fin 10) / (2 : Fin 10) = (2 : Fin 10)`
* `(5 : Fin 10) / (0 : Fin 10) = (0 : Fin 10)`
* `(5 : Fin 10) / (7 : Fin 10) = (0 : Fin 10)`
-/
protected def div : Fin n → Fin n → Fin n
| ⟨a, h⟩, ⟨b, _⟩ => ⟨a / b, Nat.lt_of_le_of_lt (Nat.div_le_self _ _) h⟩
Fin.modn
definition
: Fin n → Nat → Fin n
Fin.land
definition
: Fin n → Fin n → Fin n
Fin.lor
definition
: Fin n → Fin n → Fin n
Fin.xor
definition
: Fin n → Fin n → Fin n
Fin.shiftLeft
definition
: Fin n → Fin n → Fin n
/--
Bitwise left shift of bounded numbers, with wraparound on overflow.
Examples:
* `(1 : Fin 10) <<< (1 : Fin 10) = (2 : Fin 10)`
* `(1 : Fin 10) <<< (3 : Fin 10) = (8 : Fin 10)`
* `(1 : Fin 10) <<< (4 : Fin 10) = (6 : Fin 10)`
-/
def shiftLeft : Fin n → Fin n → Fin n
| ⟨a, h⟩, ⟨b, _⟩ => ⟨(a <<< b) % n, mlt h⟩
Fin.shiftRight
definition
: Fin n → Fin n → Fin n
/--
Bitwise right shift of bounded numbers.
This operator corresponds to logical rather than arithmetic bit shifting. The new bits are always
`0`.
Examples:
* `(15 : Fin 16) >>> (1 : Fin 16) = (7 : Fin 16)`
* `(15 : Fin 16) >>> (2 : Fin 16) = (3 : Fin 16)`
* `(15 : Fin 17) >>> (2 : Fin 17) = (3 : Fin 17)`
-/
def shiftRight : Fin n → Fin n → Fin n
| ⟨a, h⟩, ⟨b, _⟩ => ⟨(a >>> b) % n, mlt h⟩
Fin.instAdd
instance
: Add (Fin n)
Fin.instSub
instance
: Sub (Fin n)
Fin.instMul
instance
: Mul (Fin n)
Fin.instMod
instance
: Mod (Fin n)
Fin.instDiv
instance
: Div (Fin n)
Fin.instAndOp
instance
: AndOp (Fin n)
Fin.instOrOp
instance
: OrOp (Fin n)
Fin.instXor
instance
: Xor (Fin n)
Fin.instShiftLeft
instance
: ShiftLeft (Fin n)
instance : ShiftLeft (Fin n) where
shiftLeft := Fin.shiftLeft
Fin.instShiftRight
instance
: ShiftRight (Fin n)
instance : ShiftRight (Fin n) where
shiftRight := Fin.shiftRight
Fin.instOfNat
instance
{n : Nat} [NeZero n] {i : Nat} : OfNat (Fin n) i
Fin.instInhabited
instance
{n : Nat} [NeZero n] : Inhabited (Fin n)
instance instInhabited {n : Nat} [NeZero n] : Inhabited (Fin n) where
default := 0
Fin.zero_eta
theorem
: (⟨0, Nat.zero_lt_succ _⟩ : Fin (n + 1)) = 0
@[simp] theorem zero_eta : (⟨0, Nat.zero_lt_succ _⟩ : Fin (n + 1)) = 0 := rfl
Fin.ne_of_val_ne
theorem
{i j : Fin n} (h : val i ≠ val j) : i ≠ j
theorem ne_of_val_ne {i j : Fin n} (h : valval i ≠ val j) : i ≠ j :=
fun h' => absurd (val_eq_of_eq h') h
Fin.val_ne_of_ne
theorem
{i j : Fin n} (h : i ≠ j) : val i ≠ val j
theorem val_ne_of_ne {i j : Fin n} (h : i ≠ j) : valval i ≠ val j :=
fun h' => absurd (eq_of_val_eq h') h
Fin.modn_lt
theorem
: ∀ {m : Nat} (i : Fin n), m > 0 → (modn i m).val < m
Fin.val_lt_of_le
theorem
(i : Fin b) (h : b ≤ n) : i.val < n
theorem val_lt_of_le (i : Fin b) (h : b ≤ n) : i.val < n :=
Nat.lt_of_lt_of_le i.isLt h
Fin.pos
theorem
(i : Fin n) : 0 < n
/-- If you actually have an element of `Fin n`, then the `n` is always positive -/
protected theorem pos (i : Fin n) : 0 < n :=
Nat.lt_of_le_of_lt (Nat.zero_le _) i.2
Fin.last
definition
(n : Nat) : Fin (n + 1)
/--
The greatest value of `Fin (n+1)`, namely `n`.
Examples:
* `Fin.last 4 = (4 : Fin 5)`
* `(Fin.last 0).val = (0 : Nat)`
-/
@[inline] def last (n : Nat) : Fin (n + 1) := ⟨n, n.lt_succ_self⟩
Fin.castLT
definition
(i : Fin m) (h : i.1 < n) : Fin n
/--
Replaces the bound with another that is suitable for the value.
The proof embedded in `i` can be used to cast to a larger bound even if the concrete value is not
known.
Examples:
```lean example
example : Fin 12 := (7 : Fin 10).castLT (by decide : 7 < 12)
```
```lean example
example (i : Fin 10) : Fin 12 :=
i.castLT <| by
cases i; simp; omega
```
-/
@[inline] def castLT (i : Fin m) (h : i.1 < n) : Fin n := ⟨i.1, h⟩
Fin.castLE
definition
(h : n ≤ m) (i : Fin n) : Fin m
/--
Coarsens a bound to one at least as large.
See also `Fin.castAdd` for a version that represents the larger bound with addition rather than an
explicit inequality proof.
-/
@[inline] def castLE (h : n ≤ m) (i : Fin n) : Fin m := ⟨i, Nat.lt_of_lt_of_le i.2 h⟩
Fin.cast
definition
(eq : n = m) (i : Fin n) : Fin m
/--
Uses a proof that two bounds are equal to allow a value bounded by one to be used with the other.
In other words, when `eq : n = m`, `Fin.cast eq i` converts `i : Fin n` into a `Fin m`.
-/
@[inline] protected def cast (eq : n = m) (i : Fin n) : Fin m := ⟨i, eq ▸ i.2⟩
Fin.castAdd
definition
(m) : Fin n → Fin (n + m)
/--
Coarsens a bound to one at least as large.
See also `Fin.natAdd` and `Fin.addNat` for addition functions that increase the bound, and
`Fin.castLE` for a version that uses an explicit inequality proof.
-/
@[inline] def castAdd (m) : Fin n → Fin (n + m) :=
castLE <| Nat.le_add_right n m
Fin.castSucc
definition
: Fin n → Fin (n + 1)
Fin.addNat
definition
(i : Fin n) (m) : Fin (n + m)
/--
Adds a natural number to a `Fin`, increasing the bound.
This is a generalization of `Fin.succ`.
`Fin.natAdd` is a version of this function that takes its `Nat` parameter first.
Examples:
* `Fin.addNat (5 : Fin 8) 3 = (8 : Fin 11)`
* `Fin.addNat (0 : Fin 8) 1 = (1 : Fin 9)`
* `Fin.addNat (1 : Fin 8) 2 = (3 : Fin 10)`
-/
def addNat (i : Fin n) (m) : Fin (n + m) := ⟨i + m, Nat.add_lt_add_right i.2 _⟩
Fin.natAdd
definition
(n) (i : Fin m) : Fin (n + m)
/--
Adds a natural number to a `Fin`, increasing the bound.
This is a generalization of `Fin.succ`.
`Fin.addNat` is a version of this function that takes its `Nat` parameter second.
Examples:
* `Fin.natAdd 3 (5 : Fin 8) = (8 : Fin 11)`
* `Fin.natAdd 1 (0 : Fin 8) = (1 : Fin 9)`
* `Fin.natAdd 1 (2 : Fin 8) = (3 : Fin 9)`
-/
def natAdd (n) (i : Fin m) : Fin (n + m) := ⟨n + i, Nat.add_lt_add_left i.2 _⟩
Fin.rev
definition
(i : Fin n) : Fin n
/--
Replaces a value with its difference from the largest value in the type.
Considering the values of `Fin n` as a sequence `0`, `1`, …, `n-2`, `n-1`, `Fin.rev` finds the
corresponding element of the reversed sequence. In other words, it maps `0` to `n-1`, `1` to `n-2`,
..., and `n-1` to `0`.
Examples:
* `(5 : Fin 6).rev = (0 : Fin 6)`
* `(0 : Fin 6).rev = (5 : Fin 6)`
* `(2 : Fin 5).rev = (2 : Fin 5)`
-/
@[inline] def rev (i : Fin n) : Fin n := ⟨n - (i + 1), Nat.sub_lt i.pos (Nat.succ_pos _)⟩
Fin.subNat
definition
(m) (i : Fin (n + m)) (h : m ≤ i) : Fin n
/--
Subtraction of a natural number from a `Fin`, with the bound narrowed.
This is a generalization of `Fin.pred`. It is guaranteed to not underflow or wrap around.
Examples:
* `(5 : Fin 9).subNat 2 (by decide) = (3 : Fin 7)`
* `(5 : Fin 9).subNat 0 (by decide) = (5 : Fin 9)`
* `(3 : Fin 9).subNat 3 (by decide) = (0 : Fin 6)`
-/
@[inline] def subNat (m) (i : Fin (n + m)) (h : m ≤ i) : Fin n :=
⟨i - m, Nat.sub_lt_right_of_lt_add h i.2⟩
Fin.pred
definition
{n : Nat} (i : Fin (n + 1)) (h : i ≠ 0) : Fin n
/--
The predecessor of a non-zero element of `Fin (n+1)`, with the bound decreased.
Examples:
* `(4 : Fin 8).pred (by decide) = (3 : Fin 7)`
* `(1 : Fin 2).pred (by decide) = (0 : Fin 1)`
-/
@[inline] def pred {n : Nat} (i : Fin (n + 1)) (h : i ≠ 0) : Fin n :=
subNat 1 i <| Nat.pos_of_ne_zero <| mt (Fin.eq_of_val_eq (j := 0)) h
Fin.val_inj
theorem
{a b : Fin n} : a.1 = b.1 ↔ a = b
theorem val_inj {a b : Fin n} : a.1 = b.1 ↔ a = b := ⟨Fin.eq_of_val_eq, Fin.val_eq_of_eq⟩
Fin.val_congr
theorem
{n : Nat} {a b : Fin n} (h : a = b) : (a : Nat) = (b : Nat)
Fin.val_le_of_le
theorem
{n : Nat} {a b : Fin n} (h : a ≤ b) : (a : Nat) ≤ (b : Nat)
theorem val_le_of_le {n : Nat} {a b : Fin n} (h : a ≤ b) : (a : Nat) ≤ (b : Nat) := h
Fin.val_le_of_ge
theorem
{n : Nat} {a b : Fin n} (h : a ≥ b) : (b : Nat) ≤ (a : Nat)
theorem val_le_of_ge {n : Nat} {a b : Fin n} (h : a ≥ b) : (b : Nat) ≤ (a : Nat) := h
Fin.val_add_one_le_of_lt
theorem
{n : Nat} {a b : Fin n} (h : a < b) : (a : Nat) + 1 ≤ (b : Nat)
theorem val_add_one_le_of_lt {n : Nat} {a b : Fin n} (h : a < b) : (a : Nat) + 1 ≤ (b : Nat) := h
Fin.val_add_one_le_of_gt
theorem
{n : Nat} {a b : Fin n} (h : a > b) : (b : Nat) + 1 ≤ (a : Nat)
theorem val_add_one_le_of_gt {n : Nat} {a b : Fin n} (h : a > b) : (b : Nat) + 1 ≤ (a : Nat) := h
Fin.exists_iff
theorem
{p : Fin n → Prop} : (Exists fun i => p i) ↔ Exists fun i => Exists fun h => p ⟨i, h⟩
theorem exists_iff {p : Fin n → Prop} : (Exists fun i => p i) ↔ Exists fun i => Exists fun h => p ⟨i, h⟩ :=
⟨fun ⟨⟨i, hi⟩, hpi⟩ => ⟨i, hi, hpi⟩, fun ⟨i, hi, hpi⟩ => ⟨⟨i, hi⟩, hpi⟩⟩