diff --git a/src/Init/Data/Array/Lemmas.lean b/src/Init/Data/Array/Lemmas.lean index 0fea06d740f7..490fce71d658 100644 --- a/src/Init/Data/Array/Lemmas.lean +++ b/src/Init/Data/Array/Lemmas.lean @@ -7,6 +7,7 @@ prelude import Init.Data.Nat.MinMax import Init.Data.Nat.Lemmas import Init.Data.List.Monadic +import Init.Data.List.Nat.Range import Init.Data.Fin.Basic import Init.Data.Array.Mem import Init.TacticsExtra @@ -336,6 +337,10 @@ theorem not_mem_nil (a : α) : ¬ a ∈ #[] := nofun /-- # get lemmas -/ +theorem lt_of_getElem {x : α} {a : Array α} {idx : Nat} {hidx : idx < a.size} (_ : a[idx] = x) : + idx < a.size := + hidx + theorem getElem?_mem {l : Array α} {i : Fin l.size} : l[i] ∈ l := by erw [Array.mem_def, getElem_eq_data_getElem] apply List.get_mem @@ -505,6 +510,13 @@ theorem size_eq_length_data (as : Array α) : as.size = as.data.length := rfl simp only [mkEmpty_eq, size_push] at * omega +@[simp] theorem data_range (n : Nat) : (range n).data = List.range n := by + induction n <;> simp_all [range, Nat.fold, flip, List.range_succ] + +@[simp] +theorem getElem_range {n : Nat} {x : Nat} (h : x < (Array.range n).size) : (Array.range n)[x] = x := by + simp [getElem_eq_data_getElem] + set_option linter.deprecated false in @[simp] theorem reverse_data (a : Array α) : a.reverse.data = a.data.reverse := by let rec go (as : Array α) (i j hj) @@ -707,13 +719,22 @@ theorem mapIdx_spec (as : Array α) (f : Fin as.size → α → β) unfold modify modifyM Id.run split <;> simp -theorem get_modify {arr : Array α} {x i} (h : i < arr.size) : - (arr.modify x f).get ⟨i, by simp [h]⟩ = - if x = i then f (arr.get ⟨i, h⟩) else arr.get ⟨i, h⟩ := by - simp [modify, modifyM, Id.run]; split - · simp [get_set _ _ _ h]; split <;> simp [*] +theorem getElem_modify {as : Array α} {x i} (h : i < as.size) : + (as.modify x f)[i]'(by simp [h]) = if x = i then f as[i] else as[i] := by + simp only [modify, modifyM, get_eq_getElem, Id.run, Id.pure_eq] + split + · simp only [Id.bind_eq, get_set _ _ _ h]; split <;> simp [*] · rw [if_neg (mt (by rintro rfl; exact h) ‹_›)] +theorem getElem_modify_self {as : Array α} {i : Nat} (h : i < as.size) (f : α → α) : + (as.modify i f)[i]'(by simp [h]) = f as[i] := by + simp [getElem_modify h] + +theorem getElem_modify_of_ne {as : Array α} {i : Nat} (hj : j < as.size) + (f : α → α) (h : i ≠ j) : + (as.modify i f)[j]'(by rwa [size_modify]) = as[j] := by + simp [getElem_modify hj, h] + /-! ### filter -/ @[simp] theorem filter_data (p : α → Bool) (l : Array α) : diff --git a/src/Init/Data/Bool.lean b/src/Init/Data/Bool.lean index a2e8bb4b9f6c..f3de8ba4ad53 100644 --- a/src/Init/Data/Bool.lean +++ b/src/Init/Data/Bool.lean @@ -438,6 +438,24 @@ Added for confluence between `if_true_left` and `ite_false_same` on -/ @[simp] theorem eq_true_imp_eq_false : ∀(b:Bool), (b = true → b = false) ↔ (b = false) := by decide +/-! ### forall -/ + +theorem forall_bool' {p : Bool → Prop} (b : Bool) : (∀ x, p x) ↔ p b ∧ p !b := + ⟨fun h ↦ ⟨h _, h _⟩, fun ⟨h₁, h₂⟩ x ↦ by cases b <;> cases x <;> assumption⟩ + +@[simp] +theorem forall_bool {p : Bool → Prop} : (∀ b, p b) ↔ p false ∧ p true := + forall_bool' false + +/-! ### exists -/ + +theorem exists_bool' {p : Bool → Prop} (b : Bool) : (∃ x, p x) ↔ p b ∨ p !b := + ⟨fun ⟨x, hx⟩ ↦ by cases x <;> cases b <;> first | exact .inl ‹_› | exact .inr ‹_›, + fun h ↦ by cases h <;> exact ⟨_, ‹_›⟩⟩ + +@[simp] +theorem exists_bool {p : Bool → Prop} : (∃ b, p b) ↔ p false ∨ p true := + exists_bool' false /-! ### cond -/ diff --git a/src/Init/Data/Prod.lean b/src/Init/Data/Prod.lean index fd1b3814cf80..0882bde8dfdd 100644 --- a/src/Init/Data/Prod.lean +++ b/src/Init/Data/Prod.lean @@ -5,9 +5,18 @@ Author: Leonardo de Moura -/ prelude import Init.SimpLemmas +import Init.NotationExtra instance [BEq α] [BEq β] [LawfulBEq α] [LawfulBEq β] : LawfulBEq (α × β) where eq_of_beq {a b} (h : a.1 == b.1 && a.2 == b.2) := by cases a; cases b refine congr (congrArg _ (eq_of_beq ?_)) (eq_of_beq ?_) <;> simp_all rfl {a} := by cases a; simp [BEq.beq, LawfulBEq.rfl] + +@[simp] +protected theorem Prod.forall {p : α × β → Prop} : (∀ x, p x) ↔ ∀ a b, p (a, b) := + ⟨fun h a b ↦ h (a, b), fun h ⟨a, b⟩ ↦ h a b⟩ + +@[simp] +protected theorem Prod.exists {p : α × β → Prop} : (∃ x, p x) ↔ ∃ a b, p (a, b) := + ⟨fun ⟨⟨a, b⟩, h⟩ ↦ ⟨a, b, h⟩, fun ⟨a, b, h⟩ ↦ ⟨⟨a, b⟩, h⟩⟩