Skip to content

Commit

Permalink
Trigger CI for leanprover/lean4#6188
Browse files Browse the repository at this point in the history
  • Loading branch information
leanprover-community-mathlib4-bot committed Dec 1, 2024
2 parents 556ac15 + ec36ffd commit e7421bd
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 91 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/docs-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ jobs:
- name: Release Docs
uses: softprops/action-gh-release@v2
with:
prerelease: ${{ contains(github.ref, 'rc') }}
make_latest: ${{ !contains(github.ref, 'rc') }}
files: |
docs/docs-${{ github.ref_name }}.tar.gz
docs/docs-${{ github.ref_name }}.zip
Expand Down
32 changes: 32 additions & 0 deletions Batteries/Data/List/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -1032,3 +1032,35 @@ where
loop : List α → List α → List α
| [], r => reverseAux (a :: r) [] -- Note: `reverseAux` is tail recursive.
| b :: l, r => bif p b then reverseAux (a :: r) (b :: l) else loop l (b :: r)

/-- `dropPrefix? l p` returns
`some r` if `l = p' ++ r` for some `p'` which is paiwise `==` to `p`,
and `none` otherwise. -/
def dropPrefix? [BEq α] : List α → List α → Option (List α)
| list, [] => some list
| [], _ :: _ => none
| a :: as, b :: bs => if a == b then dropPrefix? as bs else none

/-- `dropSuffix? l s` returns
`some r` if `l = r ++ s'` for some `s'` which is paiwise `==` to `s`,
and `none` otherwise. -/
def dropSuffix? [BEq α] (l s : List α) : Option (List α) :=
let (r, s') := l.splitAt (l.length - s.length)
if s' == s then some r else none

/-- `dropInfix? l i` returns
`some (p, s)` if `l = p ++ i' ++ s` for some `i'` which is paiwise `==` to `i`,
and `none` otherwise.
Note that this is an inefficient implementation, and if computation time is a concern you should be
using the Knuth-Morris-Pratt algorithm as implemented in `Batteries.Data.List.Matcher`.
-/
def dropInfix? [BEq α] (l i : List α) : Option (List α × List α) :=
go l []
where
/-- Inner loop for `dropInfix?`. -/
go : List α → List α → Option (List α × List α)
| [], acc => if i.isEmpty then some (acc.reverse, []) else none
| a :: as, acc => match (a :: as).dropPrefix? i with
| none => go as (a :: acc)
| some s => (acc.reverse, s)
125 changes: 125 additions & 0 deletions Batteries/Data/List/Lemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,131 @@ theorem insertP_loop (a : α) (l r : List α) :
induction l with simp [insertP, insertP.loop, cond]
| cons _ _ ih => split <;> simp [insertP_loop, ih]

/-! ### dropPrefix?, dropSuffix?, dropInfix?-/

open Option

@[simp] theorem dropPrefix?_nil [BEq α] {p : List α} : dropPrefix? p [] = some p := by
simp [dropPrefix?]

theorem dropPrefix?_eq_some_iff [BEq α] {l p s : List α} :
dropPrefix? l p = some s ↔ ∃ p', l = p' ++ s ∧ p' == p := by
unfold dropPrefix?
split
· simp
· simp
· rename_i a as b bs
simp only [ite_none_right_eq_some]
constructor
· rw [dropPrefix?_eq_some_iff]
rintro ⟨w, p', rfl, h⟩
refine ⟨a :: p', by simp_all⟩
· rw [dropPrefix?_eq_some_iff]
rintro ⟨p, h, w⟩
rw [cons_eq_append_iff] at h
obtain (⟨rfl, rfl⟩ | ⟨a', rfl, rfl⟩) := h
· simp at w
· simp only [cons_beq_cons, Bool.and_eq_true] at w
refine ⟨w.1, a', rfl, w.2

theorem dropPrefix?_append_of_beq [BEq α] {l₁ l₂ : List α} (p : List α) (h : l₁ == l₂) :
dropPrefix? (l₁ ++ p) l₂ = some p := by
simp [dropPrefix?_eq_some_iff, h]

theorem dropSuffix?_eq_some_iff [BEq α] {l p s : List α} :
dropSuffix? l s = some p ↔ ∃ s', l = p ++ s' ∧ s' == s := by
unfold dropSuffix?
rw [splitAt_eq]
simp only [ite_none_right_eq_some, some.injEq]
constructor
· rintro ⟨w, rfl⟩
refine ⟨_, by simp, w⟩
· rintro ⟨s', rfl, w⟩
simp [length_eq_of_beq w, w]

@[simp] theorem dropSuffix?_nil [BEq α] {s : List α} : dropSuffix? s [] = some s := by
simp [dropSuffix?_eq_some_iff]

theorem dropInfix?_go_eq_some_iff [BEq α] {i l acc p s : List α} :
dropInfix?.go i l acc = some (p, s) ↔ ∃ p',
p = acc.reverse ++ p' ∧
-- `i` is an infix up to `==`
(∃ i', l = p' ++ i' ++ s ∧ i' == i) ∧
-- and there is no shorter prefix for which that is the case
(∀ p'' i'' s'', l = p'' ++ i'' ++ s'' → i'' == i → p''.length ≥ p'.length) := by
unfold dropInfix?.go
split
· simp only [isEmpty_eq_true, ite_none_right_eq_some, some.injEq, Prod.mk.injEq, nil_eq,
append_assoc, append_eq_nil, ge_iff_le, and_imp]
constructor
· rintro ⟨rfl, rfl, rfl⟩
simp
· rintro ⟨p', rfl, ⟨_, ⟨rfl, rfl, rfl⟩, h⟩, w⟩
simp_all
· rename_i a t
split <;> rename_i h
· rw [dropInfix?_go_eq_some_iff]
constructor
· rintro ⟨p', rfl, ⟨i', rfl, h₂⟩, w⟩
refine ⟨a :: p', ?_⟩
simp [h₂]
intro p'' i'' s'' h₁ h₂
rw [cons_eq_append_iff] at h₁
obtain (⟨rfl, h₁⟩ | ⟨p'', rfl, h₁⟩) := h₁
· rw [append_assoc, ← h₁] at h
have := dropPrefix?_append_of_beq s'' h₂
simp_all
· simpa using w p'' i'' s'' (by simpa using h₁) h₂
· rintro ⟨p', rfl, ⟨i', h₁, h₂⟩, w⟩
rw [cons_eq_append_iff] at h₁
simp at h₁
obtain (⟨⟨rfl, rfl⟩, rfl⟩ | ⟨a', h₁, rfl⟩) := h₁
· simp only [nil_beq_iff, isEmpty_eq_true] at h₂
simp only [h₂] at h
simp at h
· rw [append_eq_cons_iff] at h₁
obtain (⟨rfl, rfl⟩ | ⟨p', rfl, rfl⟩) := h₁
· rw [← cons_append] at h
have := dropPrefix?_append_of_beq s h₂
simp_all
· refine ⟨p', ?_⟩
simp only [reverse_cons, append_assoc, singleton_append, append_cancel_left_eq,
append_cancel_right_eq, exists_eq_left', ge_iff_le, true_and]
refine ⟨h₂, ?_⟩
intro p'' i'' s'' h₃ h₄
rw [← append_assoc] at h₃
rw [h₃] at w
simpa using w (a :: p'') i'' s'' (by simp) h₄
· rename_i s'
simp only [some.injEq, Prod.mk.injEq, append_assoc, ge_iff_le]
rw [dropPrefix?_eq_some_iff] at h
obtain ⟨p', h, w⟩ := h
constructor
· rintro ⟨rfl, rfl⟩
simpa using ⟨p', by simp_all⟩
· rintro ⟨p'', rfl, ⟨i', h₁, h₂⟩, w'⟩
specialize w' [] p' s' (by simpa using h) w
simp at w'
simp [w'] at h₁ ⊢
rw [h] at h₁
apply append_inj_right h₁
replace w := length_eq_of_beq w
replace h₂ := length_eq_of_beq h₂
simp_all

theorem dropInfix?_eq_some_iff [BEq α] {l i p s : List α} :
dropInfix? l i = some (p, s) ↔
-- `i` is an infix up to `==`
(∃ i', l = p ++ i' ++ s ∧ i' == i) ∧
-- and there is no shorter prefix for which that is the case
(∀ p' i' s', l = p' ++ i' ++ s' → i' == i → p'.length ≥ p.length) := by
unfold dropInfix?
rw [dropInfix?_go_eq_some_iff]
simp

@[simp] theorem dropInfix?_nil [BEq α] {s : List α} : dropInfix? s [] = some ([], s) := by
simp [dropInfix?_eq_some_iff]

/-! ### deprecations -/

@[deprecated (since := "2024-08-15")] alias isEmpty_iff_eq_nil := isEmpty_iff
Expand Down
90 changes: 0 additions & 90 deletions Batteries/Data/UInt.lean
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ import Batteries.Classes.Order
@[ext] theorem UInt8.ext : {x y : UInt8} → x.toNat = y.toNat → x = y
| ⟨⟨_,_⟩⟩, ⟨⟨_,_⟩⟩, rfl => rfl

@[simp] theorem UInt8.val_val_eq_toNat (x : UInt8) : x.val.val = x.toNat := rfl

@[simp] theorem UInt8.toNat_ofNat (n) :
(no_index (OfNat.ofNat n) : UInt8).toNat = n % UInt8.size := rfl

theorem UInt8.toNat_lt (x : UInt8) : x.toNat < 2 ^ 8 := x.val.isLt

@[simp] theorem UInt8.toUInt16_toNat (x : UInt8) : x.toUInt16.toNat = x.toNat := rfl
Expand All @@ -23,19 +18,6 @@ theorem UInt8.toNat_lt (x : UInt8) : x.toNat < 2 ^ 8 := x.val.isLt

@[simp] theorem UInt8.toUInt64_toNat (x : UInt8) : x.toUInt64.toNat = x.toNat := rfl

theorem UInt8.toNat_add (x y : UInt8) : (x + y).toNat = (x.toNat + y.toNat) % UInt8.size := rfl

theorem UInt8.toNat_sub (x y : UInt8) :
(x - y).toNat = (UInt8.size - y.toNat + x.toNat) % UInt8.size := rfl

theorem UInt8.toNat_mul (x y : UInt8) : (x * y).toNat = (x.toNat * y.toNat) % UInt8.size := rfl

theorem UInt8.le_antisymm_iff {x y : UInt8} : x = y ↔ x ≤ y ∧ y ≤ x :=
UInt8.ext_iff.trans Nat.le_antisymm_iff

theorem UInt8.le_antisymm {x y : UInt8} (h1 : x ≤ y) (h2 : y ≤ x) : x = y :=
UInt8.le_antisymm_iff.2 ⟨h1, h2⟩

instance : Batteries.LawfulOrd UInt8 := .compareOfLessAndEq
(fun _ => Nat.lt_irrefl _) Nat.lt_trans Nat.not_lt UInt8.le_antisymm

Expand All @@ -44,11 +26,6 @@ instance : Batteries.LawfulOrd UInt8 := .compareOfLessAndEq
@[ext] theorem UInt16.ext : {x y : UInt16} → x.toNat = y.toNat → x = y
| ⟨⟨_,_⟩⟩, ⟨⟨_,_⟩⟩, rfl => rfl

@[simp] theorem UInt16.val_val_eq_toNat (x : UInt16) : x.val.val = x.toNat := rfl

@[simp] theorem UInt16.toNat_ofNat (n) :
(no_index (OfNat.ofNat n) : UInt16).toNat = n % UInt16.size := rfl

theorem UInt16.toNat_lt (x : UInt16) : x.toNat < 2 ^ 16 := x.val.isLt

@[simp] theorem UInt16.toUInt8_toNat (x : UInt16) : x.toUInt8.toNat = x.toNat % 2 ^ 8 := rfl
Expand All @@ -57,19 +34,6 @@ theorem UInt16.toNat_lt (x : UInt16) : x.toNat < 2 ^ 16 := x.val.isLt

@[simp] theorem UInt16.toUInt64_toNat (x : UInt16) : x.toUInt64.toNat = x.toNat := rfl

theorem UInt16.toNat_add (x y : UInt16) : (x + y).toNat = (x.toNat + y.toNat) % UInt16.size := rfl

theorem UInt16.toNat_sub (x y : UInt16) :
(x - y).toNat = (UInt16.size - y.toNat + x.toNat) % UInt16.size := rfl

theorem UInt16.toNat_mul (x y : UInt16) : (x * y).toNat = (x.toNat * y.toNat) % UInt16.size := rfl

theorem UInt16.le_antisymm_iff {x y : UInt16} : x = y ↔ x ≤ y ∧ y ≤ x :=
UInt16.ext_iff.trans Nat.le_antisymm_iff

theorem UInt16.le_antisymm {x y : UInt16} (h1 : x ≤ y) (h2 : y ≤ x) : x = y :=
UInt16.le_antisymm_iff.2 ⟨h1, h2⟩

instance : Batteries.LawfulOrd UInt16 := .compareOfLessAndEq
(fun _ => Nat.lt_irrefl _) Nat.lt_trans Nat.not_lt UInt16.le_antisymm

Expand All @@ -78,11 +42,6 @@ instance : Batteries.LawfulOrd UInt16 := .compareOfLessAndEq
@[ext] theorem UInt32.ext : {x y : UInt32} → x.toNat = y.toNat → x = y
| ⟨⟨_,_⟩⟩, ⟨⟨_,_⟩⟩, rfl => rfl

@[simp] theorem UInt32.val_val_eq_toNat (x : UInt32) : x.val.val = x.toNat := rfl

@[simp] theorem UInt32.toNat_ofNat (n) :
(no_index (OfNat.ofNat n) : UInt32).toNat = n % UInt32.size := rfl

theorem UInt32.toNat_lt (x : UInt32) : x.toNat < 2 ^ 32 := x.val.isLt

@[simp] theorem UInt32.toUInt8_toNat (x : UInt32) : x.toUInt8.toNat = x.toNat % 2 ^ 8 := rfl
Expand All @@ -91,19 +50,6 @@ theorem UInt32.toNat_lt (x : UInt32) : x.toNat < 2 ^ 32 := x.val.isLt

@[simp] theorem UInt32.toUInt64_toNat (x : UInt32) : x.toUInt64.toNat = x.toNat := rfl

theorem UInt32.toNat_add (x y : UInt32) : (x + y).toNat = (x.toNat + y.toNat) % UInt32.size := rfl

theorem UInt32.toNat_sub (x y : UInt32) :
(x - y).toNat = (UInt32.size - y.toNat + x.toNat) % UInt32.size := rfl

theorem UInt32.toNat_mul (x y : UInt32) : (x * y).toNat = (x.toNat * y.toNat) % UInt32.size := rfl

theorem UInt32.le_antisymm_iff {x y : UInt32} : x = y ↔ x ≤ y ∧ y ≤ x :=
UInt32.ext_iff.trans Nat.le_antisymm_iff

theorem UInt32.le_antisymm {x y : UInt32} (h1 : x ≤ y) (h2 : y ≤ x) : x = y :=
UInt32.le_antisymm_iff.2 ⟨h1, h2⟩

instance : Batteries.LawfulOrd UInt32 := .compareOfLessAndEq
(fun _ => Nat.lt_irrefl _) Nat.lt_trans Nat.not_lt UInt32.le_antisymm

Expand All @@ -112,11 +58,6 @@ instance : Batteries.LawfulOrd UInt32 := .compareOfLessAndEq
@[ext] theorem UInt64.ext : {x y : UInt64} → x.toNat = y.toNat → x = y
| ⟨⟨_,_⟩⟩, ⟨⟨_,_⟩⟩, rfl => rfl

@[simp] theorem UInt64.val_val_eq_toNat (x : UInt64) : x.val.val = x.toNat := rfl

@[simp] theorem UInt64.toNat_ofNat (n) :
(no_index (OfNat.ofNat n) : UInt64).toNat = n % UInt64.size := rfl

theorem UInt64.toNat_lt (x : UInt64) : x.toNat < 2 ^ 64 := x.val.isLt

@[simp] theorem UInt64.toUInt8_toNat (x : UInt64) : x.toUInt8.toNat = x.toNat % 2 ^ 8 := rfl
Expand All @@ -125,19 +66,6 @@ theorem UInt64.toNat_lt (x : UInt64) : x.toNat < 2 ^ 64 := x.val.isLt

@[simp] theorem UInt64.toUInt32_toNat (x : UInt64) : x.toUInt32.toNat = x.toNat % 2 ^ 32 := rfl

theorem UInt64.toNat_add (x y : UInt64) : (x + y).toNat = (x.toNat + y.toNat) % UInt64.size := rfl

theorem UInt64.toNat_sub (x y : UInt64) :
(x - y).toNat = (UInt64.size - y.toNat + x.toNat) % UInt64.size := rfl

theorem UInt64.toNat_mul (x y : UInt64) : (x * y).toNat = (x.toNat * y.toNat) % UInt64.size := rfl

theorem UInt64.le_antisymm_iff {x y : UInt64} : x = y ↔ x ≤ y ∧ y ≤ x :=
UInt64.ext_iff.trans Nat.le_antisymm_iff

theorem UInt64.le_antisymm {x y : UInt64} (h1 : x ≤ y) (h2 : y ≤ x) : x = y :=
UInt64.le_antisymm_iff.2 ⟨h1, h2⟩

instance : Batteries.LawfulOrd UInt64 := .compareOfLessAndEq
(fun _ => Nat.lt_irrefl _) Nat.lt_trans Nat.not_lt UInt64.le_antisymm

Expand All @@ -146,11 +74,6 @@ instance : Batteries.LawfulOrd UInt64 := .compareOfLessAndEq
@[ext] theorem USize.ext : {x y : USize} → x.toNat = y.toNat → x = y
| ⟨⟨_,_⟩⟩, ⟨⟨_,_⟩⟩, rfl => rfl

@[simp] theorem USize.val_val_eq_toNat (x : USize) : x.val.val = x.toNat := rfl

@[simp] theorem USize.toNat_ofNat (n) :
(no_index (OfNat.ofNat n) : USize).toNat = n % USize.size := rfl

theorem USize.size_eq : USize.size = 2 ^ System.Platform.numBits := by
rw [USize.size]

Expand All @@ -172,18 +95,5 @@ theorem USize.toNat_lt (x : USize) : x.toNat < 2 ^ System.Platform.numBits := by

@[simp] theorem UInt32.toUSize_toNat (x : UInt32) : x.toUSize.toNat = x.toNat := rfl

theorem USize.toNat_add (x y : USize) : (x + y).toNat = (x.toNat + y.toNat) % USize.size := rfl

theorem USize.toNat_sub (x y : USize) :
(x - y).toNat = (USize.size - y.toNat + x.toNat) % USize.size := rfl

theorem USize.toNat_mul (x y : USize) : (x * y).toNat = (x.toNat * y.toNat) % USize.size := rfl

theorem USize.le_antisymm_iff {x y : USize} : x = y ↔ x ≤ y ∧ y ≤ x :=
USize.ext_iff.trans Nat.le_antisymm_iff

theorem USize.le_antisymm {x y : USize} (h1 : x ≤ y) (h2 : y ≤ x) : x = y :=
USize.le_antisymm_iff.2 ⟨h1, h2⟩

instance : Batteries.LawfulOrd USize := .compareOfLessAndEq
(fun _ => Nat.lt_irrefl _) Nat.lt_trans Nat.not_lt USize.le_antisymm
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Or add the following to your `lakefile.toml`:
[[require]]
name = "batteries"
scope = "leanprover-community"
version = "main"
rev = "main"
```

Additionally, please make sure that you're using the version of Lean that the current version of `batteries` expects. The easiest way to do this is to copy the [`lean-toolchain`](./lean-toolchain) file from this repository to your project. Once you've added the dependency declaration, the command `lake update` checks out the current version of `batteries` and writes it the Lake manifest file. Don't run this command again unless you're prepared to potentially also update your Lean compiler version, as it will retrieve the latest version of dependencies and add them to the manifest.
Expand Down

0 comments on commit e7421bd

Please sign in to comment.