@@ -4319,23 +4319,17 @@ end countP
4319
4319
4320
4320
section count
4321
4321
4322
- variable [DecidableEq α]
4322
+ variable [BEq α]
4323
4323
4324
4324
@[simp] theorem count_nil (a : α) : count a [] = 0 := rfl
4325
4325
4326
4326
theorem count_cons (a b : α) (l : List α) :
4327
- count a (b :: l) = count a l + if a = b then 1 else 0 := by
4328
- simp [count, countP_cons, eq_comm (a := a)]
4329
-
4330
- @[simp] theorem count_cons_self (a : α) (l : List α) : count a (a :: l) = count a l + 1 := by
4331
- simp [count_cons]
4332
-
4333
- @[simp] theorem count_cons_of_ne (h : a ≠ b) (l : List α) : count a (b :: l) = count a l := by
4334
- simp [count_cons, h]
4327
+ count a (b :: l) = count a l + if b == a then 1 else 0 := by
4328
+ simp [count, countP_cons]
4335
4329
4336
4330
theorem count_tail : ∀ (l : List α) (a : α) (h : l ≠ []),
4337
- l.tail.count a = l.count a - if a = l.head h then 1 else 0
4338
- | head :: tail, a, h => by simp [count_cons]
4331
+ l.tail.count a = l.count a - if l.head h == a then 1 else 0
4332
+ | head :: tail, a, _ => by simp [count_cons]
4339
4333
4340
4334
theorem count_le_length (a : α) (l : List α) : count a l ≤ l.length := countP_le_length _
4341
4335
@@ -4344,14 +4338,25 @@ theorem Sublist.count_le (h : l₁ <+ l₂) (a : α) : count a l₁ ≤ count a
4344
4338
theorem count_le_count_cons (a b : α) (l : List α) : count a l ≤ count a (b :: l) :=
4345
4339
(sublist_cons_self _ _).count_le _
4346
4340
4347
- theorem count_singleton_self (a : α) : count a [a] = 1 := by simp
4348
-
4349
- theorem count_singleton (a b : α) : count a [b] = if a = b then 1 else 0 := by simp [count_cons]
4341
+ theorem count_singleton (a b : α) : count a [b] = if b == a then 1 else 0 := by
4342
+ simp [count_cons]
4350
4343
4351
4344
@[simp] theorem count_append (a : α) : ∀ l₁ l₂, count a (l₁ ++ l₂) = count a l₁ + count a l₂ :=
4352
4345
countP_append _
4353
4346
4354
- theorem count_concat_self (a : α) (l : List α) : count a (concat l a) = (count a l) + 1 := by simp
4347
+ variable [LawfulBEq α]
4348
+
4349
+ @[simp] theorem count_cons_self (a : α) (l : List α) : count a (a :: l) = count a l + 1 := by
4350
+ simp [count_cons]
4351
+
4352
+ @[simp] theorem count_cons_of_ne (h : a ≠ b) (l : List α) : count a (b :: l) = count a l := by
4353
+ simp only [count_cons, cond_eq_if, beq_iff_eq]
4354
+ split <;> simp_all
4355
+
4356
+ theorem count_singleton_self (a : α) : count a [a] = 1 := by simp
4357
+
4358
+ theorem count_concat_self (a : α) (l : List α) :
4359
+ count a (concat l a) = (count a l) + 1 := by simp
4355
4360
4356
4361
@[simp]
4357
4362
theorem count_pos_iff_mem {a : α} {l : List α} : 0 < count a l ↔ a ∈ l := by
@@ -4375,29 +4380,21 @@ theorem count_eq_length {l : List α} : count a l = l.length ↔ ∀ b ∈ l, a
4375
4380
@[simp] theorem count_replicate_self (a : α) (n : Nat) : count a (replicate n a) = n :=
4376
4381
(count_eq_length.2 <| fun _ h => (eq_of_mem_replicate h).symm).trans (length_replicate ..)
4377
4382
4378
- theorem count_replicate (a b : α) (n : Nat) : count a (replicate n b) = if a = b then n else 0 := by
4379
- split
4380
- · exact ‹a = b › ▸ count_replicate_self ..
4381
- · exact count_eq_zero.2 <| mt eq_of_mem_replicate ‹a ≠ b›
4383
+ theorem count_replicate (a b : α) (n : Nat) : count a (replicate n b) = if b == a then n else 0 := by
4384
+ split <;> (rename_i h; simp only [beq_iff_eq] at h)
4385
+ · exact ‹b = a › ▸ count_replicate_self ..
4386
+ · exact count_eq_zero.2 <| mt eq_of_mem_replicate (Ne.symm h)
4382
4387
4383
4388
theorem filter_beq (l : List α) (a : α) : l.filter (· == a) = replicate (count a l) a := by
4384
4389
simp only [count, countP_eq_length_filter, eq_replicate, mem_filter, beq_iff_eq]
4385
4390
exact ⟨trivial, fun _ h => h.2 ⟩
4386
4391
4387
- theorem filter_eq (l : List α) (a : α) : l.filter (· = a) = replicate (count a l) a :=
4392
+ theorem filter_eq {α} [DecidableEq α] (l : List α) (a : α) : l.filter (· = a) = replicate (count a l) a :=
4388
4393
filter_beq l a
4389
4394
4390
- @[deprecated filter_eq (since := "2023-12-14")]
4391
- theorem filter_eq' (l : List α) (a : α) : l.filter (a = ·) = replicate (count a l) a := by
4392
- simpa only [eq_comm] using filter_eq l a
4393
-
4394
- @[deprecated filter_beq (since := "2023-12-14")]
4395
- theorem filter_beq' (l : List α) (a : α) : l.filter (a == ·) = replicate (count a l) a := by
4396
- simpa only [eq_comm (b := a)] using filter_eq l a
4397
-
4398
4395
theorem le_count_iff_replicate_sublist {l : List α} : n ≤ count a l ↔ replicate n a <+ l := by
4399
4396
refine ⟨fun h => ?_, fun h => ?_⟩
4400
- · exact ((replicate_sublist_replicate a).2 h).trans <| filter_eq l a ▸ filter_sublist _
4397
+ · exact ((replicate_sublist_replicate a).2 h).trans <| filter_beq l a ▸ filter_sublist _
4401
4398
· simpa only [count_replicate_self] using h.count_le a
4402
4399
4403
4400
theorem replicate_count_eq_of_count_eq_length {l : List α} (h : count a l = length l) :
@@ -4407,7 +4404,6 @@ theorem replicate_count_eq_of_count_eq_length {l : List α} (h : count a l = len
4407
4404
4408
4405
@[simp] theorem count_filter {l : List α} (h : p a) : count a (filter p l) = count a l := by
4409
4406
rw [count, countP_filter]; congr; funext b
4410
- rw [(by rfl : (b == a) = decide (b = a)), decide_eq_decide]
4411
4407
simp; rintro rfl; exact h
4412
4408
4413
4409
theorem count_le_count_map [DecidableEq β] (l : List α) (f : α → β) (x : α) :
@@ -4416,7 +4412,7 @@ theorem count_le_count_map [DecidableEq β] (l : List α) (f : α → β) (x :
4416
4412
apply countP_mono_left; simp (config := { contextual := true })
4417
4413
4418
4414
theorem count_erase (a b : α) :
4419
- ∀ l : List α, count a (l.erase b) = count a l - if a = b then 1 else 0
4415
+ ∀ l : List α, count a (l.erase b) = count a l - if b == a then 1 else 0
4420
4416
| [] => by simp
4421
4417
| c :: l => by
4422
4418
rw [erase_cons]
@@ -4426,17 +4422,17 @@ theorem count_erase (a b : α) :
4426
4422
else
4427
4423
have hc_beq := beq_false_of_ne hc
4428
4424
simp only [hc_beq, if_false, count_cons, count_cons, count_erase a b l]
4429
- if ha : a = b then
4430
- rw [← ha, eq_comm] at hc
4431
- rw [if_pos ha , if_neg hc , Nat.add_zero, Nat.add_zero]
4425
+ if ha : b = a then
4426
+ rw [ha, eq_comm] at hc
4427
+ rw [if_pos ((beq_iff_eq _ _). 2 ha) , if_neg ( by simpa using Ne.symm hc) , Nat.add_zero, Nat.add_zero]
4432
4428
else
4433
- rw [if_neg ha , Nat.sub_zero, Nat.sub_zero]
4429
+ rw [if_neg ( by simpa using ha) , Nat.sub_zero, Nat.sub_zero]
4434
4430
4435
4431
@[simp] theorem count_erase_self (a : α) (l : List α) :
4436
- count a (List.erase l a) = count a l - 1 := by rw [count_erase, if_pos rfl ]
4432
+ count a (List.erase l a) = count a l - 1 := by rw [count_erase, if_pos ( by simp) ]
4437
4433
4438
4434
@[simp] theorem count_erase_of_ne (ab : a ≠ b) (l : List α) : count a (l.erase b) = count a l := by
4439
- rw [count_erase, if_neg ab , Nat.sub_zero]
4435
+ rw [count_erase, if_neg ( by simpa using ab.symm) , Nat.sub_zero]
4440
4436
4441
4437
end count
4442
4438
@@ -5124,3 +5120,224 @@ theorem mapM'_eq_mapM [Monad m] [LawfulMonad m] (f : α → m β) (l : List α)
5124
5120
induction l₁ <;> simp [*]
5125
5121
5126
5122
end List
5123
+
5124
+
5125
+ namespace List
5126
+
5127
+ /-! ### Pairwise -/
5128
+
5129
+ theorem rel_of_pairwise_cons (p : (a :: l).Pairwise R) : ∀ {a'}, a' ∈ l → R a a' :=
5130
+ (pairwise_cons.1 p).1 _
5131
+
5132
+ theorem Pairwise.of_cons (p : (a :: l).Pairwise R) : Pairwise R l :=
5133
+ (pairwise_cons.1 p).2
5134
+
5135
+ theorem Pairwise.tail : ∀ {l : List α} (_p : Pairwise R l), Pairwise R l.tail
5136
+ | [], h => h
5137
+ | _ :: _, h => h.of_cons
5138
+
5139
+ theorem Pairwise.drop : ∀ {l : List α} {n : Nat}, List.Pairwise R l → List.Pairwise R (l.drop n)
5140
+ | _, 0 , h => h
5141
+ | [], _ + 1 , _ => List.Pairwise.nil
5142
+ | _ :: _, n + 1 , h => Pairwise.drop (n := n) (pairwise_cons.mp h).right
5143
+
5144
+ theorem Pairwise.imp_of_mem {S : α → α → Prop }
5145
+ (H : ∀ {a b}, a ∈ l → b ∈ l → R a b → S a b) (p : Pairwise R l) : Pairwise S l := by
5146
+ induction p with
5147
+ | nil => constructor
5148
+ | @cons a l r _ ih =>
5149
+ constructor
5150
+ · exact fun x h => H (mem_cons_self ..) (mem_cons_of_mem _ h) <| r x h
5151
+ · exact ih fun m m' => H (mem_cons_of_mem _ m) (mem_cons_of_mem _ m')
5152
+
5153
+ theorem Pairwise.and (hR : Pairwise R l) (hS : Pairwise S l) :
5154
+ l.Pairwise fun a b => R a b ∧ S a b := by
5155
+ induction hR with
5156
+ | nil => simp only [Pairwise.nil]
5157
+ | cons R1 _ IH =>
5158
+ simp only [Pairwise.nil, pairwise_cons] at hS ⊢
5159
+ exact ⟨fun b bl => ⟨R1 b bl, hS.1 b bl⟩, IH hS.2 ⟩
5160
+
5161
+ theorem pairwise_and_iff : l.Pairwise (fun a b => R a b ∧ S a b) ↔ Pairwise R l ∧ Pairwise S l :=
5162
+ ⟨fun h => ⟨h.imp fun h => h.1 , h.imp fun h => h.2 ⟩, fun ⟨hR, hS⟩ => hR.and hS⟩
5163
+
5164
+ theorem Pairwise.imp₂ (H : ∀ a b, R a b → S a b → T a b)
5165
+ (hR : Pairwise R l) (hS : l.Pairwise S) : l.Pairwise T :=
5166
+ (hR.and hS).imp fun ⟨h₁, h₂⟩ => H _ _ h₁ h₂
5167
+
5168
+ theorem Pairwise.iff_of_mem {S : α → α → Prop } {l : List α}
5169
+ (H : ∀ {a b}, a ∈ l → b ∈ l → (R a b ↔ S a b)) : Pairwise R l ↔ Pairwise S l :=
5170
+ ⟨Pairwise.imp_of_mem fun m m' => (H m m').1 , Pairwise.imp_of_mem fun m m' => (H m m').2 ⟩
5171
+
5172
+ theorem Pairwise.iff {S : α → α → Prop } (H : ∀ a b, R a b ↔ S a b) {l : List α} :
5173
+ Pairwise R l ↔ Pairwise S l :=
5174
+ Pairwise.iff_of_mem fun _ _ => H ..
5175
+
5176
+ theorem pairwise_of_forall {l : List α} (H : ∀ x y, R x y) : Pairwise R l := by
5177
+ induction l <;> simp [*]
5178
+
5179
+ theorem Pairwise.and_mem {l : List α} :
5180
+ Pairwise R l ↔ Pairwise (fun x y => x ∈ l ∧ y ∈ l ∧ R x y) l :=
5181
+ Pairwise.iff_of_mem <| by simp (config := { contextual := true })
5182
+
5183
+ theorem Pairwise.imp_mem {l : List α} :
5184
+ Pairwise R l ↔ Pairwise (fun x y => x ∈ l → y ∈ l → R x y) l :=
5185
+ Pairwise.iff_of_mem <| by simp (config := { contextual := true })
5186
+
5187
+ theorem Pairwise.forall_of_forall_of_flip (h₁ : ∀ x ∈ l, R x x) (h₂ : Pairwise R l)
5188
+ (h₃ : l.Pairwise (flip R)) : ∀ ⦃x⦄, x ∈ l → ∀ ⦃y⦄, y ∈ l → R x y := by
5189
+ induction l with
5190
+ | nil => exact forall_mem_nil _
5191
+ | cons a l ih =>
5192
+ rw [pairwise_cons] at h₂ h₃
5193
+ simp only [mem_cons]
5194
+ rintro x (rfl | hx) y (rfl | hy)
5195
+ · exact h₁ _ (l.mem_cons_self _)
5196
+ · exact h₂.1 _ hy
5197
+ · exact h₃.1 _ hx
5198
+ · exact ih (fun x hx => h₁ _ <| mem_cons_of_mem _ hx) h₂.2 h₃.2 hx hy
5199
+
5200
+ theorem pairwise_singleton (R) (a : α) : Pairwise R [a] := by simp
5201
+
5202
+ theorem pairwise_pair {a b : α} : Pairwise R [a, b] ↔ R a b := by simp
5203
+
5204
+ theorem pairwise_append_comm {R : α → α → Prop } (s : ∀ {x y}, R x y → R y x) {l₁ l₂ : List α} :
5205
+ Pairwise R (l₁ ++ l₂) ↔ Pairwise R (l₂ ++ l₁) := by
5206
+ have (l₁ l₂ : List α) (H : ∀ x : α, x ∈ l₁ → ∀ y : α, y ∈ l₂ → R x y)
5207
+ (x : α) (xm : x ∈ l₂) (y : α) (ym : y ∈ l₁) : R x y := s (H y ym x xm)
5208
+ simp only [pairwise_append, and_left_comm]; rw [Iff.intro (this l₁ l₂) (this l₂ l₁)]
5209
+
5210
+ theorem pairwise_middle {R : α → α → Prop } (s : ∀ {x y}, R x y → R y x) {a : α} {l₁ l₂ : List α} :
5211
+ Pairwise R (l₁ ++ a :: l₂) ↔ Pairwise R (a :: (l₁ ++ l₂)) := by
5212
+ show Pairwise R (l₁ ++ ([a] ++ l₂)) ↔ Pairwise R ([a] ++ l₁ ++ l₂)
5213
+ rw [← append_assoc, pairwise_append, @pairwise_append _ _ ([a] ++ l₁), pairwise_append_comm s]
5214
+ simp only [mem_append, or_comm]
5215
+
5216
+ theorem Pairwise.of_map {S : β → β → Prop } (f : α → β) (H : ∀ a b : α, S (f a) (f b) → R a b)
5217
+ (p : Pairwise S (map f l)) : Pairwise R l :=
5218
+ (pairwise_map.1 p).imp (H _ _)
5219
+
5220
+ theorem Pairwise.map {S : β → β → Prop } (f : α → β) (H : ∀ a b : α, R a b → S (f a) (f b))
5221
+ (p : Pairwise R l) : Pairwise S (map f l) :=
5222
+ pairwise_map.2 <| p.imp (H _ _)
5223
+
5224
+ theorem pairwise_filterMap (f : β → Option α) {l : List β} :
5225
+ Pairwise R (filterMap f l) ↔ Pairwise (fun a a' : β => ∀ b ∈ f a, ∀ b' ∈ f a', R b b') l := by
5226
+ let _S (a a' : β) := ∀ b ∈ f a, ∀ b' ∈ f a', R b b'
5227
+ simp only [Option.mem_def]
5228
+ induction l with
5229
+ | nil => simp only [filterMap, Pairwise.nil]
5230
+ | cons a l IH => ?_
5231
+ match e : f a with
5232
+ | none =>
5233
+ rw [filterMap_cons_none e, pairwise_cons]
5234
+ simp only [e, false_implies, implies_true, true_and, IH]
5235
+ | some b =>
5236
+ rw [filterMap_cons_some e]
5237
+ simpa [IH, e] using fun _ =>
5238
+ ⟨fun h a ha b hab => h _ _ ha hab, fun h a b ha hab => h _ ha _ hab⟩
5239
+
5240
+ theorem Pairwise.filter_map {S : β → β → Prop } (f : α → Option β)
5241
+ (H : ∀ a a' : α, R a a' → ∀ b ∈ f a, ∀ b' ∈ f a', S b b') {l : List α} (p : Pairwise R l) :
5242
+ Pairwise S (filterMap f l) :=
5243
+ (pairwise_filterMap _).2 <| p.imp (H _ _)
5244
+
5245
+ theorem pairwise_filter (p : α → Prop ) [DecidablePred p] {l : List α} :
5246
+ Pairwise R (filter p l) ↔ Pairwise (fun x y => p x → p y → R x y) l := by
5247
+ rw [← filterMap_eq_filter, pairwise_filterMap]
5248
+ simp
5249
+
5250
+ theorem Pairwise.filter (p : α → Bool) : Pairwise R l → Pairwise R (filter p l) :=
5251
+ Pairwise.sublist (filter_sublist _)
5252
+
5253
+ theorem pairwise_join {L : List (List α)} :
5254
+ Pairwise R (join L) ↔
5255
+ (∀ l ∈ L, Pairwise R l) ∧ Pairwise (fun l₁ l₂ => ∀ x ∈ l₁, ∀ y ∈ l₂, R x y) L := by
5256
+ induction L with
5257
+ | nil => simp
5258
+ | cons l L IH =>
5259
+ simp only [join, pairwise_append, IH, mem_join, exists_imp, and_imp, forall_mem_cons,
5260
+ pairwise_cons, and_assoc, and_congr_right_iff]
5261
+ rw [and_comm, and_congr_left_iff]
5262
+ intros; exact ⟨fun h a b c d e => h c d e a b, fun h c d e a b => h a b c d e⟩
5263
+
5264
+ theorem pairwise_bind {R : β → β → Prop } {l : List α} {f : α → List β} :
5265
+ List.Pairwise R (l.bind f) ↔
5266
+ (∀ a ∈ l, Pairwise R (f a)) ∧ Pairwise (fun a₁ a₂ => ∀ x ∈ f a₁, ∀ y ∈ f a₂, R x y) l := by
5267
+ simp [List.bind, pairwise_join, pairwise_map]
5268
+
5269
+ theorem pairwise_iff_forall_sublist : l.Pairwise R ↔ (∀ {a b}, [a,b] <+ l → R a b) := by
5270
+ induction l with
5271
+ | nil => simp
5272
+ | cons hd tl IH =>
5273
+ rw [List.pairwise_cons]
5274
+ constructor <;> intro h
5275
+ · intro
5276
+ | a, b, .cons _ hab => exact IH.mp h.2 hab
5277
+ | _, b, .cons₂ _ hab => refine h.1 _ (hab.subset ?_); simp
5278
+ · constructor
5279
+ · intro x hx
5280
+ apply h
5281
+ rw [List.cons_sublist_cons, List.singleton_sublist]
5282
+ exact hx
5283
+ · apply IH.mpr
5284
+ intro a b hab
5285
+ apply h; exact hab.cons _
5286
+
5287
+
5288
+ /-- given a list `is` of monotonically increasing indices into `l`, getting each index
5289
+ produces a sublist of `l`. -/
5290
+ theorem map_get_sublist {l : List α} {is : List (Fin l.length)} (h : is.Pairwise (·.val < ·.val)) :
5291
+ is.map (get l) <+ l := by
5292
+ suffices ∀ n l', l' = l.drop n → (∀ i ∈ is, n ≤ i) → map (get l) is <+ l'
5293
+ from this 0 l (by simp) (by simp)
5294
+ intro n l' hl' his
5295
+ induction is generalizing n l' with
5296
+ | nil => simp
5297
+ | cons hd tl IH =>
5298
+ simp; cases hl'
5299
+ have := IH h.of_cons (hd+1 ) _ rfl (pairwise_cons.mp h).1
5300
+ specialize his hd (.head _)
5301
+ have := (drop_eq_getElem_cons ..).symm ▸ this.cons₂ (get l hd)
5302
+ have := Sublist.append (nil_sublist (take hd l |>.drop n)) this
5303
+ rwa [nil_append, ← (drop_append_of_le_length ?_), take_append_drop] at this
5304
+ simp [Nat.min_eq_left (Nat.le_of_lt hd.isLt), his]
5305
+
5306
+ /-- given a sublist `l' <+ l`, there exists a list of indices `is` such that
5307
+ `l' = map (get l) is`. -/
5308
+ theorem sublist_eq_map_get (h : l' <+ l) : ∃ is : List (Fin l.length),
5309
+ l' = map (get l) is ∧ is.Pairwise (· < ·) := by
5310
+ induction h with
5311
+ | slnil => exact ⟨[], by simp⟩
5312
+ | cons _ _ IH =>
5313
+ let ⟨is, IH⟩ := IH
5314
+ refine ⟨is.map (·.succ), ?_⟩
5315
+ simp [comp, pairwise_map]
5316
+ exact IH
5317
+ | cons₂ _ _ IH =>
5318
+ rcases IH with ⟨is,IH⟩
5319
+ refine ⟨⟨0 , by simp [Nat.zero_lt_succ]⟩ :: is.map (·.succ), ?_⟩
5320
+ simp [comp_def, pairwise_map, IH, ← get_eq_getElem]
5321
+
5322
+ theorem pairwise_iff_getElem : Pairwise R l ↔
5323
+ ∀ (i j : Nat) (_hi : i < l.length) (_hj : j < l.length) (_hij : i < j), R l[i] l[j] := by
5324
+ rw [pairwise_iff_forall_sublist]
5325
+ constructor <;> intro h
5326
+ · intros i j hi hj h'
5327
+ apply h
5328
+ simpa [h'] using map_get_sublist (is := [⟨i, hi⟩, ⟨j, hj⟩])
5329
+ · intros a b h'
5330
+ have ⟨is, h', hij⟩ := sublist_eq_map_get h'
5331
+ rcases is with ⟨⟩ | ⟨a', ⟨⟩ | ⟨b', ⟨⟩⟩⟩ <;> simp at h'
5332
+ rcases h' with ⟨rfl, rfl⟩
5333
+ apply h; simpa using hij
5334
+
5335
+ theorem pairwise_iff_get : Pairwise R l ↔ ∀ (i j) (_hij : i < j), R (get l i) (get l j) := by
5336
+ rw [pairwise_iff_getElem]
5337
+ constructor <;> intro h
5338
+ · intros i j h'
5339
+ exact h _ _ _ _ h'
5340
+ · intros i j hi hj h'
5341
+ exact h ⟨i, hi⟩ ⟨j, hj⟩ h'
5342
+
5343
+ end List
0 commit comments