Built with
doc-gen4, running Lean4.
Bubbles (
) indicate interactive fragments: hover for details, tap to reveal contents.
Use
Ctrl+↑Ctrl+↓to navigate,
Ctrl+🖱️to focus.
On Mac, use
Cmdinstead of
Ctrl.
/-
Copyright (c) 2021 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Arthur Paulino, Floris van Doorn, Jannis Limperg
-/
import Std.Data.Array.Init.Basic
import Std.Data.Ord
/-!
## Definitions on Arrays
This file contains various definitions on `Array`. It does not contain
proofs about these definitions, those are contained in other files in `Std.Data.Array`.
-/
namespace Array
/-- The array `#[0, 1, ..., n - 1]`. -/
def range (n : Nat) : Array Nat :=
n.fold: {α : Type ?u.7} → (Nat → α → α) → Nat → α → α
fold (flip: {α : Sort ?u.15} → {β : Sort ?u.14} → {φ : Sort ?u.13} → (α → β → φ) → β → α → φ
flip Array.push) #[]
/-- Drop `none`s from a Array, and replace each remaining `some a` with `a`. -/
def reduceOption (l : Array (Option α)) : Array α :=
l.filterMap id: {α : Sort ?u.114} → α → α
id
/-- Turns `#[#[a₁, a₂, ⋯], #[b₁, b₂, ⋯], ⋯]` into `#[a₁, a₂, ⋯, b₁, b₂, ⋯]` -/
def flatten (arr : Array (Array α)) : Array α :=
arr.foldl (init := #[]) fun acc a => acc.append a
/-- Turns `#[a, b]` into `#[(a, 0), (b, 1)]`. -/
def zipWithIndex (arr : Array α) : Array (α × Nat) :=
arr.mapIdx fun i a => (a, i)
/--
Check whether `xs` and `ys` are equal as sets, i.e. they contain the same
elements when disregarding order and duplicates. `O(n*m)`! If your element type
has an `Ord` instance, it is asymptotically more efficient to sort the two
arrays, remove duplicates and then compare them elementwise.
-/
def equalSet [BEq α] (xs ys : Array α) : Bool :=
xs.all (ys.contains ·) && ys.all (xs.contains ·)
set_option linter.unusedVariables.funArgs false in
/--
Sort an array using `compare` to compare elements.
-/
def qsortOrd [ord : Ord α] (xs : Array α) : Array α :=
xs.qsort λ x y => compare x y |>.isLT
set_option linter.unusedVariables.funArgs false in
/--
Find the first minimal element of an array. If the array is empty, `d` is
returned. If `start` and `stop` are given, only the subarray `xs[start:stop]` is
considered.
-/
@[inline]
protected def minD [ord : Ord α]
(xs : Array α) (d : α) (start := 0) (stop := xs.size) : α :=
xs.foldl (init := d) (start := start) (stop := stop) λ min x =>
if compare x min |>.isLT then x else min
set_option linter.unusedVariables.funArgs false in
/--
Find the first minimal element of an array. If the array is empty, `none` is
returned. If `start` and `stop` are given, only the subarray `xs[start:stop]` is
considered.
-/
@[inline]
protected def min? [ord : Ord α]
(xs : Array α) (start := 0) (stop := xs.size) : Option α :=
if h : start < xs.size then
some $ xs.minD (xs.get ⟨start, h⟩) start stop
else
none
set_option linter.unusedVariables.funArgs false in
/--
Find the first minimal element of an array. If the array is empty, `default` is
returned. If `start` and `stop` are given, only the subarray `xs[start:stop]` is
considered.
-/
@[inline]
protected def minI [ord : Ord α] [Inhabited: Sort ?u.2190 → Sort (max1?u.2190)
Inhabited α]
(xs : Array α) (start := 0) (stop := xs.size) : α :=
xs.minD default start stop
set_option linter.unusedVariables.funArgs false in
/--
Find the first maximal element of an array. If the array is empty, `d` is
returned. If `start` and `stop` are given, only the subarray `xs[start:stop]` is
considered.
-/
@[inline]
protected def maxD [ord : Ord α]
(xs : Array α) (d : α) (start := 0) (stop := xs.size) : α :=
xs.minD (ord := ord.opposite) d start stop
set_option linter.unusedVariables.funArgs false in
/--
Find the first maximal element of an array. If the array is empty, `none` is
returned. If `start` and `stop` are given, only the subarray `xs[start:stop]` is
considered.
-/
@[inline]
protected def max? [ord : Ord α]
(xs : Array α) (start := 0) (stop := xs.size) : Option α :=
xs.min? (ord := ord.opposite) start stop
set_option linter.unusedVariables.funArgs false in
/--
Find the first maximal element of an array. If the array is empty, `default` is
returned. If `start` and `stop` are given, only the subarray `xs[start:stop]` is
considered.
-/
@[inline]
protected def maxI [ord : Ord α] [Inhabited: Sort ?u.2741 → Sort (max1?u.2741)
Inhabited α]
(xs : Array α) (start := 0) (stop := xs.size) : α :=
xs.minI (ord := ord.opposite) start stop
end Array
namespace Subarray
/--
The empty subarray.
-/
protected def empty : Subarray α where
as := #[]
start := 0
stop := 0
h₁ := Nat.le_refl: ∀ (n : Nat), n ≤ n
Nat.le_refl 0
h₂ := Nat.le_refl: ∀ (n : Nat), n ≤ n
Nat.le_refl 0
instance : EmptyCollection: Type ?u.3052 → Type ?u.3052
EmptyCollection (Subarray α) :=
⟨Subarray.empty⟩
instance : Inhabited: Sort ?u.3118 → Sort (max1?u.3118)
Inhabited (Subarray α) :=
⟨{}⟩
/--
Check whether a subarray is empty.
-/
@[inline]
def isEmpty (as : Subarray α) : Bool :=
as.start == as.stop
/--
Check whether a subarray contains an element.
-/
@[inline]
def contains [BEq α] (as : Subarray α) (a : α) : Bool :=
as.any (· == a)
/--
Remove the first element of a subarray. Returns the element and the remaining
subarray, or `none` if the subarray is empty.
-/
def popHead? (as : Subarray α) : Option (α × Subarray α) :=
if h : as.start < as.stop
then
let head := as.as.get ⟨as.start, Nat.lt_of_lt_of_le: ∀ {n m k : Nat}, n < m → m ≤ k → n < k
Nat.lt_of_lt_of_le h as.h₂⟩
let tail :=
{ as with
start := as.start + 1
h₁ := Nat.le_of_lt_succ $ Nat.succ_lt_succ h }
some (head, tail)
else
none
end Subarray