Skip to content

Commit

Permalink
Merge main into nightly-testing
Browse files Browse the repository at this point in the history
  • Loading branch information
leanprover-community-mathlib4-bot committed Nov 1, 2023
2 parents 7b3a210 + 123e2f1 commit cf03e8b
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
55 changes: 55 additions & 0 deletions Std/Data/List/Lemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -2167,3 +2167,58 @@ theorem reverse_range' : ∀ s n : Nat, reverse (range' s n) = map (s + n - 1 -

@[simp] theorem enum_map_fst (l : List α) : map Prod.fst (enum l) = range l.length := by
simp only [enum, enumFrom_map_fst, range_eq_range']

/-! ### minimum? -/

@[simp] theorem minimum?_nil [Min α] : ([] : List α).minimum? = none := rfl

-- We don't put `@[simp]` on `minimum?_cons`,
-- because the definition in terms of `foldl` is not useful for proofs.
theorem minimum?_cons [Min α] {xs : List α} : (x :: xs).minimum? = foldl min x xs := rfl

@[simp] theorem minimum?_eq_none_iff {xs : List α} [Min α] : xs.minimum? = none ↔ xs = [] := by
cases xs <;> simp [minimum?]

theorem minimum?_mem [Min α] (min_eq_or : ∀ a b : α, min a b = a ∨ min a b = b) :
{xs : List α} → xs.minimum? = some a → a ∈ xs
| nil => by simp
| cons x xs => by
rw [minimum?]; rintro ⟨⟩
induction xs generalizing x with simp at *
| cons y xs ih =>
rcases ih (min x y) with h | h <;> simp [h]
simp [← or_assoc, min_eq_or x y]

theorem le_minimum?_iff [Min α] [LE α]
(le_min_iff : ∀ a b c : α, a ≤ min b c ↔ a ≤ b ∧ a ≤ c) :
{xs : List α} → xs.minimum? = some a → ∀ x, x ≤ a ↔ ∀ b ∈ xs, x ≤ b
| nil => by simp
| cons x xs => by
rw [minimum?]; rintro ⟨⟩ y
induction xs generalizing x with
| nil => simp
| cons y xs ih => simp [ih, le_min_iff, and_assoc]

-- This could be refactored by designing appropriate typeclasses to replace `le_refl`, `min_eq_or`,
-- and `le_min_iff`.
theorem minimum?_eq_some_iff [Min α] [LE α] [anti : Antisymm ((· : α) ≤ ·)]
(le_refl : ∀ a : α, a ≤ a)
(min_eq_or : ∀ a b : α, min a b = a ∨ min a b = b)
(le_min_iff : ∀ a b c : α, a ≤ min b c ↔ a ≤ b ∧ a ≤ c) {xs : List α} :
xs.minimum? = some a ↔ a ∈ xs ∧ ∀ b ∈ xs, a ≤ b := by
refine ⟨fun h => ⟨minimum?_mem min_eq_or h, (le_minimum?_iff le_min_iff h _).1 (le_refl _)⟩, ?_⟩
intro ⟨h₁, h₂⟩
cases xs with
| nil => simp at h₁
| cons x xs =>
exact congrArg some <| anti.1
((le_minimum?_iff le_min_iff (xs := x::xs) rfl _).1 (le_refl _) _ h₁)
(h₂ _ (minimum?_mem min_eq_or (xs := x::xs) rfl))

-- A specialization of `minimum?_eq_some_iff` to Nat.
theorem minimum?_eq_some_iff' {xs : List Nat} :
xs.minimum? = some a ↔ (a ∈ xs ∧ ∀ b ∈ xs, a ≤ b) :=
minimum?_eq_some_iff
(le_refl := Nat.le_refl)
(min_eq_or := fun _ _ => Nat.min_def .. ▸ by split <;> simp)
(le_min_iff := fun _ _ _ => Nat.le_min)
6 changes: 6 additions & 0 deletions Std/Logic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ theorem imp_iff_not (hb : ¬b) : a → b ↔ ¬a := imp_congr_right fun _ => iff
/-- Non-dependent eliminator for `And`. -/
abbrev And.elim (f : a → b → α) (h : a ∧ b) : α := f h.1 h.2

-- TODO: rename and_self to and_self_eq
theorem and_self_iff : a ∧ a ↔ a := and_self _ ▸ .rfl

theorem And.symm : a ∧ b → b ∧ a | ⟨ha, hb⟩ => ⟨hb, ha⟩

theorem And.imp (f : a → c) (g : b → d) (h : a ∧ b) : c ∧ d := ⟨f h.1, g h.2
Expand Down Expand Up @@ -244,6 +247,9 @@ theorem not_and_self_iff (a : Prop) : ¬a ∧ a ↔ False := iff_false_intro not

theorem not_not_em (a : Prop) : ¬¬(a ∨ ¬a) := fun h => h (.inr (h ∘ .inl))

-- TODO: rename or_self to or_self_eq
theorem or_self_iff : a ∨ a ↔ a := or_self _ ▸ .rfl

theorem Or.symm : a ∨ b → b ∨ a := .rec .inr .inl

theorem Or.imp (f : a → c) (g : b → d) (h : a ∨ b) : c ∨ d := h.elim (inl ∘ f) (inr ∘ g)
Expand Down

0 comments on commit cf03e8b

Please sign in to comment.