133 lines
4.4 KiB
Text
133 lines
4.4 KiB
Text
/-
|
||
Copyright (c) 2017 Microsoft Corporation. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
Authors: Leonardo de Moura, Mario Carneiro
|
||
-/
|
||
prelude
|
||
import init.data.nat
|
||
universes u w
|
||
|
||
structure array (α : Type u) (n : nat) :=
|
||
(data : fin n → α)
|
||
|
||
def mk_array {α} (n) (v : α) : array α n :=
|
||
{data := λ _, v}
|
||
|
||
namespace array
|
||
variables {α : Type u} {β : Type w} {n : nat}
|
||
|
||
def nil {α} : array α 0 :=
|
||
{data := λ ⟨x, h⟩, absurd h (nat.not_lt_zero x)}
|
||
|
||
def read (a : array α n) (i : fin n) : α :=
|
||
a.data i
|
||
|
||
def read' [inhabited α] (a : array α n) (i : nat) : α :=
|
||
if h : i < n then a.read ⟨i,h⟩ else default α
|
||
|
||
def write (a : array α n) (i : fin n) (v : α) : array α n :=
|
||
{data := λ j, if i = j then v else a.read j}
|
||
|
||
def write' (a : array α n) (i : nat) (v : α) : array α n :=
|
||
if h : i < n then a.write ⟨i, h⟩ v else a
|
||
|
||
lemma read_eq_read' [inhabited α] (a : array α n) (i : nat) (h : i < n) : read a ⟨i, h⟩ = read' a i :=
|
||
by unfold read'; rw [dif_pos h]
|
||
|
||
lemma write_eq_write' (a : array α n) (i : nat) (h : i < n) (v : α) : write a ⟨i, h⟩ v = write' a i v :=
|
||
by unfold write'; rw [dif_pos h]
|
||
|
||
lemma push_back_idx {j n} (h₁ : j < n + 1) (h₂ : j ≠ n) : j < n :=
|
||
nat.lt_of_le_and_ne (nat.le_of_lt_succ h₁) h₂
|
||
|
||
def push_back (a : array α n) (v : α) : array α (n+1) :=
|
||
{data := λ ⟨j, h₁⟩, if h₂ : j = n then v else a.read ⟨j, push_back_idx h₁ h₂⟩}
|
||
|
||
lemma pop_back_idx {j n} (h : j < n) : j < n + 1 :=
|
||
nat.lt.step h
|
||
|
||
def pop_back (a : array α (n+1)) : array α n :=
|
||
{data := λ ⟨j, h⟩, a.read ⟨j, pop_back_idx h⟩}
|
||
|
||
lemma lt_aux_1 {a b c : nat} (h : a + c < b) : a < b :=
|
||
lt_of_le_of_lt (nat.le_add_right a c) h
|
||
|
||
lemma lt_aux_2 {n} (h : n > 0) : n - 1 < n :=
|
||
have h₁ : 1 > 0, from dec_trivial,
|
||
nat.sub_lt h h₁
|
||
|
||
lemma lt_aux_3 {n i} (h : i + 1 < n) : n - 2 - i < n :=
|
||
have n > 0, from lt.trans (nat.zero_lt_succ i) h,
|
||
have n - 2 < n, from nat.sub_lt this (dec_trivial),
|
||
lt_of_le_of_lt (nat.sub_le _ _) this
|
||
|
||
@[elab_as_eliminator]
|
||
theorem write_ind (a : array α n) (i : fin n) (v : α) (C : fin n → α → Sort w)
|
||
(Hi : C i v) (Hj : ∀j, i ≠ j → C j (a.read j)) (j) : C j ((a.write i v).read j) :=
|
||
show C j (if i = j then v else read a j), from
|
||
if h : i = j then by rwa [if_pos h, ← h]
|
||
else by rw [if_neg h]; exact Hj j h
|
||
|
||
def iterate_aux (a : array α n) (f : fin n → α → β → β) : Π (i : nat), i ≤ n → β → β
|
||
| 0 h b := b
|
||
| (j+1) h b :=
|
||
let i : fin n := ⟨j, h⟩ in
|
||
f i (a.read i) (iterate_aux j (le_of_lt h) b)
|
||
|
||
def iterate (a : array α n) (b : β) (fn : fin n → α → β → β) : β :=
|
||
iterate_aux a fn n (le_refl _) b
|
||
|
||
def foreach (a : array α n) (f : fin n → α → α) : array α n :=
|
||
iterate a a (λ i v a', a'.write i (f i v))
|
||
|
||
def map (f : α → α) (a : array α n) : array α n :=
|
||
foreach a (λ _, f)
|
||
|
||
def map₂ (f : α → α → α) (a b : array α n) : array α n :=
|
||
foreach b (λ i, f (a.read i))
|
||
|
||
def foldl (a : array α n) (b : β) (f : α → β → β) : β :=
|
||
iterate a b (λ _, f)
|
||
|
||
def rev_list (a : array α n) : list α :=
|
||
a.foldl [] (λ v l, v :: l)
|
||
|
||
def foldl_eq_aux (a : array α n) (b : β) (f : α → β → β) :
|
||
Π (i : nat) (h : i ≤ n), iterate_aux a (λ _, f) i h b = (iterate_aux a (λ _ v l, v :: l) i h []).foldr f b
|
||
| 0 h := rfl
|
||
| (j+1) h := congr_arg (f (read a ⟨j, h⟩)) (foldl_eq_aux j _)
|
||
|
||
def foldl_eq (a : array α n) (b : β) (f : α → β → β) : a.foldl b f = a.rev_list.foldr f b :=
|
||
foldl_eq_aux a b f _ _
|
||
|
||
def rev_iterate_aux (a : array α n) (f : fin n → α → β → β) : Π (i : nat), i ≤ n → β → β
|
||
| 0 h b := b
|
||
| (j+1) h b :=
|
||
let i : fin n := ⟨j, h⟩ in
|
||
rev_iterate_aux j (le_of_lt h) (f i (a.read i) b)
|
||
|
||
def rev_iterate (a : array α n) (b : β) (fn : fin n → α → β → β) : β :=
|
||
rev_iterate_aux a fn n (le_refl _) b
|
||
|
||
def to_list (a : array α n) : list α :=
|
||
a.rev_iterate [] (λ _ v l, v :: l)
|
||
|
||
protected def mem (v : α) (a : array α n) : Prop := ∃i, read a i = v
|
||
|
||
instance : has_mem α (array α n) := ⟨array.mem⟩
|
||
|
||
theorem read_mem (a : array α n) (i) : read a i ∈ a := exists.intro i rfl
|
||
|
||
instance [has_repr α] : has_repr (array α n) :=
|
||
⟨repr ∘ to_list⟩
|
||
|
||
meta instance [has_to_format α] : has_to_format (array α n) :=
|
||
⟨to_fmt ∘ to_list⟩
|
||
|
||
meta instance [has_to_tactic_format α] : has_to_tactic_format (array α n) :=
|
||
⟨tactic.pp ∘ to_list⟩
|
||
|
||
end array
|
||
|
||
def list.to_array {α} (l : list α) : array α l.length :=
|
||
{data := λ v, l.nth_le v.1 v.2}
|