Skip to content

Commit

Permalink
Trigger CI for leanprover/lean4#6205
Browse files Browse the repository at this point in the history
  • Loading branch information
leanprover-community-mathlib4-bot committed Nov 28, 2024
2 parents 4617c76 + aab9422 commit 20770fc
Show file tree
Hide file tree
Showing 21 changed files with 576 additions and 575 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/labels-from-status.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
if: github.event.pull_request.state == 'closed'
uses: actions-ecosystem/action-remove-labels@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
labels: |
WIP
awaiting-author
Expand All @@ -48,6 +49,7 @@ jobs:
! contains(github.event.pull_request.labels.*.name, 'WIP')
uses: actions-ecosystem/action-add-labels@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
labels: WIP

- name: Label unlabeled other PR as awaiting-review
Expand All @@ -59,4 +61,5 @@ jobs:
! contains(github.event.pull_request.labels.*.name, 'WIP')
uses: actions-ecosystem/action-add-labels@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
labels: awaiting-review
38 changes: 3 additions & 35 deletions Batteries/Data/Array/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -137,43 +137,11 @@ This will perform the update destructively provided that `a` has a reference cou
abbrev setN (a : Array α) (i : Nat) (x : α) (h : i < a.size := by get_elem_tactic) : Array α :=
a.set i x

/--
`swapN a i j hi hj` swaps two `Nat` indexed entries in an `Array α`.
Uses `get_elem_tactic` to supply a proof that the indices are in range.
`hi` and `hj` are both given a default argument `by get_elem_tactic`.
This will perform the update destructively provided that `a` has a reference count of 1 when called.
-/
abbrev swapN (a : Array α) (i j : Nat)
(hi : i < a.size := by get_elem_tactic) (hj : j < a.size := by get_elem_tactic) : Array α :=
Array.swap a ⟨i,hi⟩ ⟨j, hj⟩
@[deprecated (since := "2024-11-24")] alias swapN := swap

/--
`swapAtN a i h x` swaps the entry with index `i : Nat` in the vector for a new entry `x`.
The old entry is returned alongwith the modified vector.
Automatically generates proof of `i < a.size` with `get_elem_tactic` where feasible.
-/
abbrev swapAtN (a : Array α) (i : Nat) (x : α) (h : i < a.size := by get_elem_tactic) :
α × Array α := swapAt a ⟨i,h⟩ x
@[deprecated (since := "2024-11-24")] alias swapAtN := swapAt

/--
`eraseIdxN a i h` Removes the element at position `i` from a vector of length `n`.
`h : i < a.size` has a default argument `by get_elem_tactic` which tries to supply a proof
that the index is valid.
This function takes worst case O(n) time because it has to backshift all elements at positions
greater than i.
-/
abbrev eraseIdxN (a : Array α) (i : Nat) (h : i < a.size := by get_elem_tactic) : Array α :=
a.feraseIdx ⟨i, h⟩

/--
Remove the element at a given index from an array, panics if index is out of bounds.
-/
def eraseIdx! (a : Array α) (i : Nat) : Array α :=
if h : i < a.size then
a.feraseIdx ⟨i, h⟩
else
have : Inhabited (Array α) := ⟨a⟩
panic! s!"index {i} out of bounds"
@[deprecated (since := "2024-11-20")] alias eraseIdxN := eraseIdx

end Array

Expand Down
238 changes: 133 additions & 105 deletions Batteries/Data/Array/Lemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mario Carneiro, Gabriel Ebner
-/
import Batteries.Data.List.Lemmas
import Batteries.Data.List.FinRange
import Batteries.Data.Array.Basic
import Batteries.Tactic.SeqFocus
import Batteries.Util.ProofWanted
Expand All @@ -25,14 +26,6 @@ theorem forIn_eq_forIn_toList [Monad m]
@[deprecated (since := "2024-09-09")] alias data_zipWith := toList_zipWith
@[deprecated (since := "2024-08-13")] alias zipWith_eq_zipWith_data := data_zipWith

@[simp] theorem size_zipWith (as : Array α) (bs : Array β) (f : α → β → γ) :
(as.zipWith bs f).size = min as.size bs.size := by
rw [size_eq_length_toList, toList_zipWith, List.length_zipWith]

@[simp] theorem size_zip (as : Array α) (bs : Array β) :
(as.zip bs).size = min as.size bs.size :=
as.size_zipWith bs Prod.mk

/-! ### filter -/

theorem size_filter_le (p : α → Bool) (l : Array α) :
Expand Down Expand Up @@ -71,118 +64,153 @@ where
@[simp] proof_wanted toList_erase [BEq α] {l : Array α} {a : α} :
(l.erase a).toList = l.toList.erase a

@[simp] theorem eraseIdx!_eq_eraseIdx (a : Array α) (i : Nat) :
a.eraseIdx! i = a.eraseIdx i := rfl

@[simp] theorem size_eraseIdx (a : Array α) (i : Nat) :
(a.eraseIdx i).size = if i < a.size then a.size-1 else a.size := by
simp only [eraseIdx]; split; simp; rfl
@[simp] theorem size_eraseIdxIfInBounds (a : Array α) (i : Nat) :
(a.eraseIdxIfInBounds i).size = if i < a.size then a.size-1 else a.size := by
simp only [eraseIdxIfInBounds]; split; simp; rfl

/-! ### set -/

theorem size_set! (a : Array α) (i v) : (a.set! i v).size = a.size := by simp

/-! ### map -/

theorem mapM_empty [Monad m] (f : α → m β) : mapM f #[] = pure #[] := by
rw [mapM, mapM.map]; rfl

theorem map_empty (f : α → β) : map f #[] = #[] := mapM_empty f

/-! ### mem -/

theorem mem_singleton : a ∈ #[b] ↔ a = b := by simp

/-! ### insertAt -/

private theorem size_insertAt_loop (as : Array α) (i : Fin (as.size+1)) (j : Fin bs.size) :
(insertAt.loop as i bs j).size = bs.size := by
unfold insertAt.loop
@[simp] private theorem size_insertIdx_loop (as : Array α) (i : Nat) (j : Fin as.size) :
(insertIdx.loop i as j).size = as.size := by
unfold insertIdx.loop
split
· rw [size_insertAt_loop, size_swap]
· rw [size_insertIdx_loop, size_swap]
· rfl

@[simp] theorem size_insertAt (as : Array α) (i : Fin (as.size+1)) (v : α) :
(as.insertAt i v).size = as.size + 1 := by
rw [insertAt, size_insertAt_loop, size_push]

private theorem get_insertAt_loop_lt (as : Array α) (i : Fin (as.size+1)) (j : Fin bs.size)
(k) (hk : k < (insertAt.loop as i bs j).size) (h : k < i) :
(insertAt.loop as i bs j)[k] = bs[k]'(size_insertAt_loop .. ▸ hk) := by
unfold insertAt.loop
split
· have h1 : k ≠ j - 1 := by omega
have h2 : k ≠ j := by omega
rw [get_insertAt_loop_lt, getElem_swap, if_neg h1, if_neg h2]
exact h
@[simp] theorem size_insertIdx (as : Array α) (i : Nat) (h : i ≤ as.size) (v : α) :
(as.insertIdx i v).size = as.size + 1 := by
rw [insertIdx, size_insertIdx_loop, size_push]

@[deprecated size_insertIdx (since := "2024-11-20")] alias size_insertAt := size_insertIdx

theorem getElem_insertIdx_loop_lt {as : Array α} {i : Nat} {j : Fin as.size} {k : Nat} {h}
(w : k < i) :
(insertIdx.loop i as j)[k] = as[k]'(by simpa using h) := by
unfold insertIdx.loop
split <;> rename_i h₁
· simp only
rw [getElem_insertIdx_loop_lt w]
rw [getElem_swap]
split <;> rename_i h₂
· simp_all
omega
· split <;> rename_i h₃
· omega
· simp_all
· rfl

private theorem get_insertAt_loop_gt (as : Array α) (i : Fin (as.size+1)) (j : Fin bs.size)
(k) (hk : k < (insertAt.loop as i bs j).size) (hgt : j < k) :
(insertAt.loop as i bs j)[k] = bs[k]'(size_insertAt_loop .. ▸ hk) := by
unfold insertAt.loop
split
· have h1 : k ≠ j - 1 := by omega
have h2 : k ≠ j := by omega
rw [get_insertAt_loop_gt, getElem_swap, if_neg h1, if_neg h2]
exact Nat.lt_of_le_of_lt (Nat.pred_le _) hgt
· rfl

private theorem get_insertAt_loop_eq (as : Array α) (i : Fin (as.size+1)) (j : Fin bs.size)
(k) (hk : k < (insertAt.loop as i bs j).size) (heq : i = k) (h : i.val ≤ j.val) :
(insertAt.loop as i bs j)[k] = bs[j] := by
unfold insertAt.loop
split
· next h =>
rw [get_insertAt_loop_eq, Fin.getElem_fin, getElem_swap, if_pos rfl]
exact heq
exact Nat.le_pred_of_lt h
· congr; omega

private theorem get_insertAt_loop_gt_le (as : Array α) (i : Fin (as.size+1)) (j : Fin bs.size)
(k) (hk : k < (insertAt.loop as i bs j).size) (hgt : i < k) (hle : k ≤ j) :
(insertAt.loop as i bs j)[k] = bs[k-1] := by
unfold insertAt.loop
split
· next h =>
if h0 : k = j then
cases h0
have h1 : j.val ≠ j - 1 := by omega
rw [get_insertAt_loop_gt, getElem_swap, if_neg h1, if_pos rfl]; rfl
exact Nat.pred_lt_of_lt hgt
else
have h1 : k - 1 ≠ j - 1 := by omega
have h2 : k - 1 ≠ j := by omega
rw [get_insertAt_loop_gt_le, getElem_swap, if_neg h1, if_neg h2]
apply Nat.le_of_lt_add_one
rw [Nat.sub_one_add_one]
exact Nat.lt_of_le_of_ne hle h0
exact Nat.not_eq_zero_of_lt h
exact hgt
· next h =>
absurd h
exact Nat.lt_of_lt_of_le hgt hle

theorem getElem_insertAt_lt (as : Array α) (i : Fin (as.size+1)) (v : α)
(k) (hlt : k < i.val) {hk : k < (as.insertAt i v).size} {hk' : k < as.size} :
(as.insertAt i v)[k] = as[k] := by
simp only [insertAt]
rw [get_insertAt_loop_lt, getElem_push, dif_pos hk']
exact hlt

theorem getElem_insertAt_gt (as : Array α) (i : Fin (as.size+1)) (v : α)
(k) (hgt : k > i.val) {hk : k < (as.insertAt i v).size} {hk' : k - 1 < as.size} :
(as.insertAt i v)[k] = as[k - 1] := by
simp only [insertAt]
rw [get_insertAt_loop_gt_le, getElem_push, dif_pos hk']
exact hgt
rw [size_insertAt] at hk
exact Nat.le_of_lt_succ hk

theorem getElem_insertAt_eq (as : Array α) (i : Fin (as.size+1)) (v : α)
(k) (heq : i.val = k) {hk : k < (as.insertAt i v).size} :
(as.insertAt i v)[k] = v := by
simp only [insertAt]
rw [get_insertAt_loop_eq, Fin.getElem_fin, getElem_push_eq]
exact heq
exact Nat.le_of_lt_succ i.is_lt
theorem getElem_insertIdx_loop_eq {as : Array α} {i : Nat} {j : Nat} {hj : j < as.size} {h} :
(insertIdx.loop i as ⟨j, hj⟩)[i] = if i ≤ j then as[j] else as[i]'(by simpa using h) := by
unfold insertIdx.loop
split <;> rename_i h₁
· simp at h₁
have : j - 1 < j := by omega
rw [getElem_insertIdx_loop_eq]
rw [getElem_swap]
simp
split <;> rename_i h₂
· rw [if_pos (by omega)]
· omega
· simp at h₁
by_cases h' : i = j
· simp [h']
· have t : ¬ i ≤ j := by omega
simp [t]

theorem getElem_insertIdx_loop_gt {as : Array α} {i : Nat} {j : Nat} {hj : j < as.size}
{k : Nat} {h} (w : i < k) :
(insertIdx.loop i as ⟨j, hj⟩)[k] =
if k ≤ j then as[k-1]'(by simp at h; omega) else as[k]'(by simpa using h) := by
unfold insertIdx.loop
split <;> rename_i h₁
· simp only
simp only at h₁
have : j - 1 < j := by omega
rw [getElem_insertIdx_loop_gt w]
rw [getElem_swap]
split <;> rename_i h₂
· rw [if_neg (by omega), if_neg (by omega)]
have t : k ≤ j := by omega
simp [t]
· rw [getElem_swap]
rw [if_neg (by omega)]
split <;> rename_i h₃
· simp [h₃]
· have t : ¬ k ≤ j := by omega
simp [t]
· simp only at h₁
have t : ¬ k ≤ j := by omega
simp [t]

theorem getElem_insertIdx_loop {as : Array α} {i : Nat} {j : Nat} {hj : j < as.size} {k : Nat} {h} :
(insertIdx.loop i as ⟨j, hj⟩)[k] =
if h₁ : k < i then
as[k]'(by simpa using h)
else
if h₂ : k = i then
if i ≤ j then as[j] else as[i]'(by simpa [h₂] using h)
else
if k ≤ j then as[k-1]'(by simp at h; omega) else as[k]'(by simpa using h) := by
split <;> rename_i h₁
· rw [getElem_insertIdx_loop_lt h₁]
· split <;> rename_i h₂
· subst h₂
rw [getElem_insertIdx_loop_eq]
· rw [getElem_insertIdx_loop_gt (by omega)]

theorem getElem_insertIdx (as : Array α) (i : Nat) (h : i ≤ as.size) (v : α)
(k) (h' : k < (as.insertIdx i v).size) :
(as.insertIdx i v)[k] =
if h₁ : k < i then
as[k]'(by omega)
else
if h₂ : k = i then
v
else
as[k - 1]'(by simp at h'; omega) := by
unfold insertIdx
rw [getElem_insertIdx_loop]
simp only [size_insertIdx] at h'
replace h' : k ≤ as.size := by omega
simp only [getElem_push, h, ↓reduceIte, Nat.lt_irrefl, ↓reduceDIte, h', dite_eq_ite]
split <;> rename_i h₁
· rw [dif_pos (by omega)]
· split <;> rename_i h₂
· simp [h₂]
· split <;> rename_i h₃
· rfl
· omega

theorem getElem_insertIdx_lt (as : Array α) (i : Nat) (h : i ≤ as.size) (v : α)
(k) (h' : k < (as.insertIdx i v).size) (h : k < i) :
(as.insertIdx i v)[k] = as[k] := by
simp [getElem_insertIdx, h]

@[deprecated getElem_insertIdx_lt (since := "2024-11-20")] alias getElem_insertAt_lt :=
getElem_insertIdx_lt

theorem getElem_insertIdx_eq (as : Array α) (i : Nat) (h : i ≤ as.size) (v : α) :
(as.insertIdx i v)[i]'(by simp; omega) = v := by
simp [getElem_insertIdx, h]

@[deprecated getElem_insertIdx_eq (since := "2024-11-20")] alias getElem_insertAt_eq :=
getElem_insertIdx_eq

theorem getElem_insertIdx_gt (as : Array α) (i : Nat) (h : i ≤ as.size) (v : α)
(k) (h' : k < (as.insertIdx i v).size) (h : i < k) :
(as.insertIdx i v)[k] = as[k-1]'(by simp at h'; omega) := by
rw [getElem_insertIdx]
rw [dif_neg (by omega), dif_neg (by omega)]

@[deprecated getElem_insertIdx_gt (since := "2024-11-20")] alias getElem_insertAt_gt :=
getElem_insertIdx_gt
10 changes: 5 additions & 5 deletions Batteries/Data/BinaryHeap.lean
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ def heapifyUp (lt : α → α → Bool) (a : Vector α sz) (i : Fin sz) :
match i with
| ⟨0, _⟩ => a
| ⟨i'+1, hi⟩ =>
let j := i'/2, by get_elem_tactic⟩
let j := i'/2
if lt a[j] a[i] then
heapifyUp lt (a.swap i j) j
heapifyUp lt (a.swap i j) ⟨j, by get_elem_tactic⟩
else a

/-- `O(1)`. Build a new empty heap. -/
Expand Down Expand Up @@ -107,7 +107,7 @@ def popMax (self : BinaryHeap α lt) : BinaryHeap α lt :=
if h0 : self.size = 0 then self else
have hs : self.size - 1 < self.size := Nat.pred_lt h0
have h0 : 0 < self.size := Nat.zero_lt_of_ne_zero h0
let v := self.vector.swap ⟨_, h0⟩ ⟨_, hs⟩ |>.pop
let v := self.vector.swap _ _ h0 hs |>.pop
if h : 0 < self.size - 1 then
⟨heapifyDown lt v ⟨0, h⟩ |>.toArray⟩
else
Expand Down Expand Up @@ -136,7 +136,7 @@ def insertExtractMax (self : BinaryHeap α lt) (x : α) : α × BinaryHeap α lt
| none => (x, self)
| some m =>
if lt x m then
let v := self.vector.set 0, size_pos_of_max e⟩ x
let v := self.vector.set 0 x (size_pos_of_max e)
(m, ⟨heapifyDown lt v ⟨0, size_pos_of_max e⟩ |>.toArray⟩)
else (x, self)

Expand All @@ -145,7 +145,7 @@ def replaceMax (self : BinaryHeap α lt) (x : α) : Option α × BinaryHeap α l
match e : self.max with
| none => (none, ⟨self.vector.push x |>.toArray⟩)
| some m =>
let v := self.vector.set 0, size_pos_of_max e⟩ x
let v := self.vector.set 0 x (size_pos_of_max e)
(some m, ⟨heapifyDown lt v ⟨0, size_pos_of_max e⟩ |>.toArray⟩)

/-- `O(log n)`. Replace the value at index `i` by `x`. Assumes that `x ≤ self.get i`. -/
Expand Down
1 change: 1 addition & 0 deletions Batteries/Data/Fin.lean
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import Batteries.Data.Fin.Basic
import Batteries.Data.Fin.Fold
import Batteries.Data.Fin.Lemmas
Loading

0 comments on commit 20770fc

Please sign in to comment.