Skip to content

Commit 85d16d6

Browse files
Update lean-toolchain for leanprover/lean4#9932
2 parents cbf2c23 + 8a9e7f9 commit 85d16d6

File tree

4 files changed

+125
-95
lines changed

4 files changed

+125
-95
lines changed

Batteries/Data/Fin/Lemmas.lean

Lines changed: 121 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,26 @@ Authors: Mario Carneiro
55
-/
66
import Batteries.Data.Fin.Basic
77
import Batteries.Util.ProofWanted
8+
import Batteries.Tactic.Alias
89

910
namespace Fin
1011

1112
attribute [norm_cast] val_last
1213

14+
/-! ### foldl/foldr -/
15+
16+
theorem foldl_assoc {op : α → α → α} [ha : Std.Associative op] {f : Fin n → α} {a₁ a₂} :
17+
foldl n (fun x i => op x (f i)) (op a₁ a₂) = op a₁ (foldl n (fun x i => op x (f i)) a₂) := by
18+
induction n generalizing a₂ with
19+
| zero => rfl
20+
| succ n ih => simp only [foldl_succ, ha.assoc, ih]
21+
22+
theorem foldr_assoc {op : α → α → α} [ha : Std.Associative op] {f : Fin n → α} {a₁ a₂} :
23+
foldr n (fun i x => op (f i) x) (op a₁ a₂) = op (foldr n (fun i x => op (f i) x) a₁) a₂ := by
24+
induction n generalizing a₂ with
25+
| zero => rfl
26+
| succ n ih => simp only [foldr_succ, ha.assoc, ih]
27+
1328
/-! ### clamp -/
1429

1530
@[simp] theorem coe_clamp (n m : Nat) : (clamp n m : Nat) = min n m := rfl
@@ -21,14 +36,9 @@ attribute [norm_cast] val_last
2136
@[simp] theorem findSome?_one {f : Fin 1 → Option α} : findSome? f = f 0 := rfl
2237

2338
theorem findSome?_succ {f : Fin (n+1) → Option α} :
24-
findSome? f = (f 0 <|> findSome? fun i => f i.succ) := by
25-
simp only [findSome?, foldl_succ]
26-
cases f 0
27-
· rw [Option.orElse_eq_orElse, Option.orElse_none, Option.orElse_none]
28-
· simp only [Option.orElse_some, Option.orElse_eq_orElse, Option.orElse_none]
29-
induction n with
30-
| zero => rfl
31-
| succ n ih => rw [foldl_succ, Option.orElse_some, ih (f := fun i => f i.succ)]
39+
findSome? f = (f 0).or (findSome? fun i => f i.succ) := by
40+
simp only [findSome?, foldl_succ, Option.orElse_eq_orElse, Option.orElse_eq_or]
41+
exact Eq.trans (by cases (f 0) <;> rfl) foldl_assoc
3242

3343
theorem findSome?_succ_of_some {f : Fin (n+1) → Option α} (h : f 0 = some x) :
3444
findSome? f = some x := by simp [findSome?_succ, h]
@@ -42,68 +52,67 @@ theorem findSome?_succ_of_none {f : Fin (n+1) → Option α} (h : f 0 = none) :
4252
theorem findSome?_succ_of_isNone {f : Fin (n+1) → Option α} (h : (f 0).isNone) :
4353
findSome? f = findSome? fun i => f i.succ := by simp_all [findSome?_succ_of_none]
4454

45-
theorem exists_of_findSome?_eq_some {f : Fin n → Option α} (h : findSome? f = some x) :
46-
∃ i, f i = some x := by
55+
@[simp, grind =]
56+
theorem findSome?_eq_some_iff {f : Fin n → Option α} :
57+
findSome? f = some a ↔ ∃ i, f i = some a ∧ ∀ j < i, f j = none := by
4758
induction n with
48-
| zero => rw [findSome?_zero] at h; contradiction
59+
| zero =>
60+
simp only [findSome?_zero, (Option.some_ne_none _).symm, false_iff]
61+
exact fun ⟨i, _⟩ => i.elim0
4962
| succ n ih =>
50-
rw [findSome?_succ] at h
51-
match heq : f 0 with
52-
| some x =>
53-
rw [heq, Option.orElse_eq_orElse, Option.orElse_some] at h
54-
exists 0
55-
rw [heq, h]
56-
| none =>
57-
rw [heq, Option.orElse_eq_orElse, Option.orElse_none] at h
58-
match ih h with | ⟨i, _⟩ => exists i.succ
63+
simp only [findSome?_succ, Option.or_eq_some_iff, Fin.exists_fin_succ, Fin.forall_fin_succ,
64+
not_lt_zero, false_implies, implies_true, and_true, succ_lt_succ_iff, succ_pos,
65+
forall_const, ih, and_left_comm (b := f 0 = none), exists_and_left]
5966

60-
theorem eq_none_of_findSome?_eq_none {f : Fin n → Option α} (h : findSome? f = none) (i) :
61-
f i = none := by
67+
@[simp, grind =] theorem findSome?_eq_none_iff {f : Fin n → Option α} :
68+
findSome? f = none ↔ ∀ i, f i = none := by
6269
induction n with
63-
| zero => cases i; contradiction
70+
| zero =>
71+
simp only [findSome?_zero, true_iff]
72+
exact fun i => i.elim0
6473
| succ n ih =>
65-
rw [findSome?_succ] at h
66-
match heq : f 0 with
67-
| some x =>
68-
rw [heq, Option.orElse_eq_orElse, Option.orElse_some] at h
69-
contradiction
70-
| none =>
71-
rw [heq, Option.orElse_eq_orElse, Option.orElse_none] at h
72-
cases i using Fin.cases with
73-
| zero => exact heq
74-
| succ i => exact ih h i
75-
76-
@[simp] theorem findSome?_isSome_iff {f : Fin n → Option α} :
77-
(findSome? f).isSome ↔ ∃ i, (f i).isSome := by
78-
simp only [Option.isSome_iff_exists]
79-
constructor
80-
· intro ⟨x, hx⟩
81-
match exists_of_findSome?_eq_some hx with
82-
| ⟨i, hi⟩ => exists i, x
83-
· intro ⟨i, x, hix⟩
84-
match h : findSome? f with
85-
| some x => exists x
86-
| none => rw [eq_none_of_findSome?_eq_none h i] at hix; contradiction
87-
88-
@[simp] theorem findSome?_eq_none_iff {f : Fin n → Option α} :
89-
findSome? f = none ↔ ∀ i, f i = none := by
90-
constructor
91-
· exact eq_none_of_findSome?_eq_none
92-
· intro hf
93-
match h : findSome? f with
94-
| none => rfl
95-
| some x =>
96-
match exists_of_findSome?_eq_some h with
97-
| ⟨i, h⟩ => rw [hf] at h; contradiction
98-
99-
theorem findSome?_isNone_iff {f : Fin n → Option α} :
74+
simp only [findSome?_succ, Option.or_eq_none_iff, ih, forall_fin_succ]
75+
76+
theorem isNone_findSome?_iff {f : Fin n → Option α} :
10077
(findSome? f).isNone ↔ ∀ i, (f i).isNone := by simp
10178

79+
@[deprecated (since := "2025-09-28")]
80+
alias findSome?_isNone_iff := isNone_findSome?_iff
81+
82+
@[simp] theorem isSome_findSome?_iff {f : Fin n → Option α} :
83+
(findSome? f).isSome ↔ ∃ i, (f i).isSome := by
84+
cases h : findSome? f with (simp only [findSome?_eq_none_iff, findSome?_eq_some_iff] at h; grind)
85+
86+
@[deprecated (since := "2025-09-28")]
87+
alias findSome?_isSome_iff := isSome_findSome?_iff
88+
89+
theorem exists_minimal_of_findSome?_eq_some {f : Fin n → Option α}
90+
(h : findSome? f = some x) : ∃ i, f i = some x ∧ ∀ j < i, f j = none :=
91+
findSome?_eq_some_iff.1 h
92+
93+
theorem exists_eq_some_of_findSome?_eq_some {f : Fin n → Option α}
94+
(h : findSome? f = some x) : ∃ i, f i = some x := by grind
95+
96+
@[deprecated (since := "2025-09-28")]
97+
alias exists_of_findSome?_eq_some := exists_eq_some_of_findSome?_eq_some
98+
99+
theorem eq_none_of_findSome?_eq_none {f : Fin n → Option α} (h : findSome? f = none) (i) :
100+
f i = none := findSome?_eq_none_iff.1 h i
101+
102+
theorem exists_isSome_of_isSome_findSome? {f : Fin n → Option α} (h : (findSome? f).isSome) :
103+
∃ i, (f i).isSome := isSome_findSome?_iff.1 h
104+
105+
theorem isNone_of_isNone_findSome? {f : Fin n → Option α} (h : (findSome? f).isNone) :
106+
(f i).isNone := isNone_findSome?_iff.1 h i
107+
108+
theorem isSome_findSome?_of_isSome {f : Fin n → Option α} (h : (f i).isSome) :
109+
(findSome? f).isSome := isSome_findSome?_iff.2 ⟨_, h⟩
110+
102111
theorem map_findSome? (f : Fin n → Option α) (g : α → β) :
103-
(findSome? f).map g = findSome? (Option.map g ∘ f) := by
112+
(findSome? f).map g = findSome? (Option.map g <| f ·) := by
104113
induction n with
105114
| zero => rfl
106-
| succ n ih => simp [findSome?_succ, Function.comp_def, Option.map_or, ih]
115+
| succ n ih => simp [findSome?_succ, Option.map_or, ih]
107116

108117
theorem findSome?_guard {p : Fin n → Bool} : findSome? (Option.guard p) = find? p := rfl
109118

@@ -123,38 +132,62 @@ theorem findSome?_eq_findSome?_finRange (f : Fin n → Option α) :
123132

124133
theorem find?_succ {p : Fin (n+1) → Bool} :
125134
find? p = if p 0 then some 0 else (find? fun i => p i.succ).map Fin.succ := by
126-
simp only [find?, findSome?_succ, Option.guard]
127-
split <;> simp [map_findSome?, Function.comp_def, Option.guard]
135+
simp only [find?, findSome?_succ, Option.guard, fun a => apply_ite (Option.or · a),
136+
Option.some_or, Option.none_or, map_findSome?, Option.map_if]
128137

129-
theorem eq_true_of_find?_eq_some {p : Fin n → Bool} (h : find? p = some i) : p i = true := by
130-
match exists_of_findSome?_eq_some h with
131-
| ⟨i, hi⟩ =>
132-
simp only [Option.guard] at hi
133-
split at hi
134-
· cases hi; assumption
135-
· contradiction
138+
@[simp, grind =]
139+
theorem find?_eq_some_iff {p : Fin n → Bool} :
140+
find? p = some i ↔ p i ∧ ∀ j, j < i → p j = false := by simp [find?, and_assoc]
136141

137-
theorem eq_false_of_find?_eq_none {p : Fin n → Bool} (h : find? p = none) (i) : p i = false := by
138-
have hi := eq_none_of_findSome?_eq_none h i
139-
simp only [Option.guard] at hi
140-
split at hi
141-
· contradiction
142-
· simp [*]
142+
theorem isSome_find?_iff {p : Fin n → Bool} :
143+
(find? p).isSome ↔ ∃ i, p i := by simp [find?]
143144

144-
theorem find?_isSome_iff {p : Fin n → Bool} : (find? p).isSome ↔ ∃ i, p i := by
145-
simp [find?]
145+
@[deprecated (since := "2025-09-28")]
146+
alias find?_isSome_iff := isSome_find?_iff
146147

147-
theorem find?_isNone_iff {p : Fin n → Bool} : (find? p).isNone ↔ ∀ i, ¬ p i := by
148-
simp [find?]
148+
@[simp, grind =]
149+
theorem find?_eq_none_iff {p : Fin n → Bool} : find? p = none ↔ ∀ i, p i = false := by simp [find?]
149150

150-
proof_wanted find?_eq_some_iff {p : Fin n → Bool} : find? p = some i ↔ p i ∧ ∀ j, j < i → ¬ p j
151+
theorem isNone_find?_iff {p : Fin n → Bool} : (find? p).isNone ↔ ∀ i, p i = false := by simp [find?]
151152

152-
theorem find?_eq_none_iff {p : Fin n → Bool} : find? p = none ↔ ∀ i, ¬ p i := by
153-
rw [← find?_isNone_iff, Option.isNone_iff_eq_none]
153+
@[deprecated (since := "2025-09-28")]
154+
alias find?_isNone_iff := isNone_find?_iff
154155

155-
theorem find?_eq_find?_finRange {p : Fin n → Bool} : find? p = (List.finRange n).find? p := by
156-
induction n with
157-
| zero => rfl
158-
| succ n ih =>
159-
rw [find?_succ, List.finRange_succ, List.find?_cons]
160-
split <;> simp [Function.comp_def, *]
156+
theorem eq_true_of_find?_eq_some {p : Fin n → Bool} (h : find? p = some i) : p i :=
157+
(find?_eq_some_iff.mp h).1
158+
159+
theorem eq_false_of_find?_eq_some_of_lt {p : Fin n → Bool} (h : find? p = some i) :
160+
∀ j < i, p j = false := (find?_eq_some_iff.mp h).2
161+
162+
theorem eq_false_of_find?_eq_none {p : Fin n → Bool} (h : find? p = none) (i) :
163+
p i = false := find?_eq_none_iff.1 h i
164+
165+
theorem exists_eq_true_of_isSome_find? {p : Fin n → Bool} (h : (find? p).isSome) :
166+
∃ i, p i := isSome_find?_iff.1 h
167+
168+
theorem eq_false_of_isNone_find? {p : Fin n → Bool} (h : (find? p).isNone) : p i = false :=
169+
isNone_find?_iff.1 h i
170+
171+
theorem isSome_find?_of_eq_true {p : Fin n → Bool} (h : p i) :
172+
(find? p).isSome := isSome_find?_iff.2 ⟨_, h⟩
173+
174+
theorem get_find?_eq_true {p : Fin n → Bool} (h : (find? p).isSome) : p ((find? p).get h) :=
175+
eq_true_of_find?_eq_some (Option.some_get _).symm
176+
177+
theorem get_find?_minimal {p : Fin n → Bool} (h : (find? p).isSome) :
178+
∀ j, j < (find? p).get h → p j = false :=
179+
eq_false_of_find?_eq_some_of_lt (Option.some_get _).symm
180+
181+
theorem find?_eq_find?_finRange {p : Fin n → Bool} : find? p = (List.finRange n).find? p :=
182+
(findSome?_eq_findSome?_finRange _).trans (List.findSome?_guard)
183+
184+
/-! ### exists -/
185+
186+
theorem exists_eq_true_iff_exists_minimal_eq_true (p : Fin n → Bool):
187+
(∃ i, p i) ↔ ∃ i, p i ∧ ∀ j < i, p j = false := by
188+
cases h : find? p <;> grind
189+
190+
theorem exists_iff_exists_minimal (p : Fin n → Prop) [DecidablePred p] :
191+
(∃ i, p i) ↔ ∃ i, p i ∧ ∀ j < i, ¬ p j := by
192+
simpa only [decide_eq_true_iff, decide_eq_false_iff_not] using
193+
exists_eq_true_iff_exists_minimal_eq_true (p ·)

Batteries/Data/String/Lemmas.lean

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ theorem Valid.le_endPos : ∀ {s p}, Valid s p → p ≤ endPos s
133133
end Pos
134134

135135
theorem endPos_eq_zero (s : String) : endPos s = 0 ↔ s = "" := by
136-
simp [String.ext_iff, ← utf8Len_eq_zero, Pos.ext_iff, endPos]
136+
simp [Pos.ext_iff, endPos]
137137

138138
theorem isEmpty_iff (s : String) : isEmpty s ↔ s = "" :=
139139
(beq_iff_eq ..).trans (endPos_eq_zero _)
@@ -793,10 +793,6 @@ theorem takeWhileAux_of_valid (p : Char → Bool) : ∀ l m r,
793793
cases p c <;> simp
794794
simpa [← Nat.add_assoc, Nat.add_right_comm] using takeWhileAux_of_valid p (l++[c]) m r
795795

796-
@[simp]
797-
theorem data_eq_nil_iff (s : String) : s.data = [] ↔ s = "" :=
798-
fun h => ext (id h), congrArg data⟩
799-
800796
@[simp]
801797
theorem map_eq_empty_iff (s : String) (f : Char → Char) : (s.map f) = "" ↔ s = "" := by
802798
simp only [map_eq, ← data_eq_nil_iff, String.mk_eq_asString, List.data_asString,

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,13 @@ Batteries PRs often affect Mathlib, a key component of the Lean ecosystem.
7575
When Batteries changes in a significant way, Mathlib must adapt promptly.
7676
When necessary, Batteries contributors are expected to either create an adaptation PR on Mathlib, or ask for assistance for and to collaborate with this necessary process.
7777

78-
Every Batteries PR has an automatically created Mathlib branch called `batteries-pr-testing-N` where `N` is the number of the Batteries PR.
78+
Every Batteries PR has an automatically created [Mathlib Nightly Testing](https://github.com/leanprover-community/mathlib4-nightly-testing/) branch called `batteries-pr-testing-N` where `N` is the number of the Batteries PR.
7979
This is a clone of Mathlib where the Batteries requirement points to the Batteries PR branch instead of the main branch.
8080
Batteries uses this branch to check whether the Batteries PR needs Mathlib adaptations.
8181
A tag `builds-mathlib` will be issued when this branch needs no adaptation; a tag `breaks-mathlib` will be issued when the branch does need an adaptation.
8282

8383
The first step in creating an adaptation PR is to switch to the `batteries-pr-testing-N` branch and push changes to that branch until the Mathlib CI process works.
84+
You may need to ask for write access to [Mathlib Nightly Testing](https://github.com/leanprover-community/mathlib4-nightly-testing/) to do that.
8485
Changes to the Batteries PR will be integrated automatically as you work on this process.
8586
Do not redirect the Batteries requirement to main until the Batteries PR is merged.
8687
Please ask questions to Batteries and Mathlib maintainers if you run into issues with this process.

lean-toolchain

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
leanprover/lean4-pr-releases:pr-release-9932-1c79aac
1+
leanprover/lean4-pr-releases:pr-release-9932-843181b

0 commit comments

Comments
 (0)