File: Mathlib/Data/Finset/Fold.lean

full_name: Finset.«_aux_Mathlib_Data_Finset_Fold___macroRules_Finset_term_*__1»
code: local notation a " * " b => op a b
goal: Lean.Macro

full_name: Finset.fold
code: /-- `fold op b f s` folds the commutative associative operation `op` over the
  `f`-image of `s`, i.e. `fold (+) b f {1,2,3} = f 1 + f 2 + f 3 + b`. -/
def fold (b : β) (f : α → β) (s : Finset α) : β 
goal: β

full_name: Finset.fold_empty
code: @[simp]
theorem fold_empty : (∅ : Finset α).fold op b f = b 
goal: Finset.fold op b f ∅ = b

full_name: Finset.fold_cons
code: @[simp]
theorem fold_cons (h : a ∉ s) : (cons a s h).fold op b f = f a * s.fold op b f 
goal: Finset.fold op b f (Finset.cons a s h) = op (f a) (Finset.fold op b f s)

full_name: Finset.fold_insert
code: @[simp]
theorem fold_insert [DecidableEq α] (h : a ∉ s) :
    (insert a s).fold op b f = f a * s.fold op b f 
goal: Finset.fold op b f (insert a s) = op (f a) (Finset.fold op b f s)

full_name: Finset.fold_singleton
code: @[simp]
theorem fold_singleton : ({a} : Finset α).fold op b f = f a * b 
goal: Finset.fold op b f {a} = op (f a) b

full_name: Finset.fold_map
code: @[simp]
theorem fold_map {g : γ ↪ α} {s : Finset γ} : (s.map g).fold op b f = s.fold op b (f ∘ g) 
goal: Finset.fold op b f (Finset.map g s) = Finset.fold op b (f ∘ ⇑g) s

full_name: Finset.fold_image
code: @[simp]
theorem fold_image [DecidableEq α] {g : γ → α} {s : Finset γ}
    (H : ∀ x ∈ s, ∀ y ∈ s, g x = g y → x = y) : (s.image g).fold op b f = s.fold op b (f ∘ g) 
goal: Finset.fold op b f (Finset.image g s) = Finset.fold op b (f ∘ g) s

full_name: Finset.fold_congr
code: @[congr]
theorem fold_congr {g : α → β} (H : ∀ x ∈ s, f x = g x) : s.fold op b f = s.fold op b g 
goal: Finset.fold op b f s = Finset.fold op b g s

full_name: Finset.fold_op_distrib
code: theorem fold_op_distrib {f g : α → β} {b₁ b₂ : β} :
    (s.fold op (b₁ * b₂) fun x => f x * g x) = s.fold op b₁ f * s.fold op b₂ g 
goal: Finset.fold op (op b₁ b₂) (fun x => op (f x) (g x)) s = op (Finset.fold op b₁ f s) (Finset.fold op b₂ g s)

full_name: Finset.fold_const
code: theorem fold_const [hd : Decidable (s = ∅)] (c : β) (h : op c (op b c) = op b c) :
    Finset.fold op b (fun _ => c) s = if s = ∅ then b else op b c 
goal: Finset.fold op b (fun x => c) s = if s = ∅ then b else op b c

full_name: Finset.fold_hom
code: theorem fold_hom {op' : γ → γ → γ} [Std.Commutative op'] [Std.Associative op'] {m : β → γ}
    (hm : ∀ x y, m (op x y) = op' (m x) (m y)) :
    (s.fold op' (m b) fun x => m (f x)) = m (s.fold op b f) 
goal: Finset.fold op' (m b) (fun x => m (f x)) s = m (Finset.fold op b f s)

full_name: Finset.fold_disjUnion
code: theorem fold_disjUnion {s₁ s₂ : Finset α} {b₁ b₂ : β} (h) :
    (s₁.disjUnion s₂ h).fold op (b₁ * b₂) f = s₁.fold op b₁ f * s₂.fold op b₂ f 
goal: Finset.fold op (op b₁ b₂) f (s₁.disjUnion s₂ h) = op (Finset.fold op b₁ f s₁) (Finset.fold op b₂ f s₂)

full_name: Finset.fold_disjiUnion
code: theorem fold_disjiUnion {ι : Type*} {s : Finset ι} {t : ι → Finset α} {b : ι → β} {b₀ : β} (h) :
    (s.disjiUnion t h).fold op (s.fold op b₀ b) f = s.fold op b₀ fun i => (t i).fold op (b i) f 
goal: Finset.fold op (Finset.fold op b₀ b s) f (s.disjiUnion t h) =
  Finset.fold op b₀ (fun i => Finset.fold op (b i) f (t i)) s

full_name: Finset.fold_union_inter
code: theorem fold_union_inter [DecidableEq α] {s₁ s₂ : Finset α} {b₁ b₂ : β} :
    ((s₁ ∪ s₂).fold op b₁ f * (s₁ ∩ s₂).fold op b₂ f) = s₁.fold op b₂ f * s₂.fold op b₁ f 
goal: op (Finset.fold op b₁ f (s₁ ∪ s₂)) (Finset.fold op b₂ f (s₁ ∩ s₂)) =
  op (Finset.fold op b₂ f s₁) (Finset.fold op b₁ f s₂)

full_name: Finset.fold_insert_idem
code: @[simp]
theorem fold_insert_idem [DecidableEq α] [hi : Std.IdempotentOp op] :
    (insert a s).fold op b f = f a * s.fold op b f 
goal: Finset.fold op b f (insert a s) = op (f a) (Finset.fold op b f s)

full_name: Finset.fold_image_idem
code: theorem fold_image_idem [DecidableEq α] {g : γ → α} {s : Finset γ} [hi : Std.IdempotentOp op] :
    (image g s).fold op b f = s.fold op b (f ∘ g) 
goal: Finset.fold op b f (Finset.image g s) = Finset.fold op b (f ∘ g) s

full_name: Finset.fold_ite'
code: /-- A stronger version of `Finset.fold_ite`, but relies on
an explicit proof of idempotency on the seed element, rather
than relying on typeclass idempotency over the whole type. -/
theorem fold_ite' {g : α → β} (hb : op b b = b) (p : α → Prop) [DecidablePred p] :
    Finset.fold op b (fun i => ite (p i) (f i) (g i)) s =
      op (Finset.fold op b f (s.filter p)) (Finset.fold op b g (s.filter fun i => ¬p i)) 
goal: Finset.fold op b (fun i => if p i then f i else g i) s =
  op (Finset.fold op b f (Finset.filter p s)) (Finset.fold op b g (Finset.filter (fun i => ¬p i) s))

full_name: Finset.fold_ite
code: /-- A weaker version of `Finset.fold_ite'`,
relying on typeclass idempotency over the whole type,
instead of solely on the seed element.
However, this is easier to use because it does not generate side goals. -/
theorem fold_ite [Std.IdempotentOp op] {g : α → β} (p : α → Prop) [DecidablePred p] :
    Finset.fold op b (fun i => ite (p i) (f i) (g i)) s =
      op (Finset.fold op b f (s.filter p)) (Finset.fold op b g (s.filter fun i => ¬p i)) 
goal: Finset.fold op b (fun i => if p i then f i else g i) s =
  op (Finset.fold op b f (Finset.filter p s)) (Finset.fold op b g (Finset.filter (fun i => ¬p i) s))

full_name: Finset.fold_op_rel_iff_and
code: theorem fold_op_rel_iff_and {r : β → β → Prop} (hr : ∀ {x y z}, r x (op y z) ↔ r x y ∧ r x z)
    {c : β} : r c (s.fold op b f) ↔ r c b ∧ ∀ x ∈ s, r c (f x) 
goal: r c (Finset.fold op b f s) ↔ r c b ∧ ∀ x ∈ s, r c (f x)

full_name: Finset.fold_op_rel_iff_or
code: theorem fold_op_rel_iff_or {r : β → β → Prop} (hr : ∀ {x y z}, r x (op y z) ↔ r x y ∨ r x z)
    {c : β} : r c (s.fold op b f) ↔ r c b ∨ ∃ x ∈ s, r c (f x) 
goal: r c (Finset.fold op b f s) ↔ r c b ∨ ∃ x ∈ s, r c (f x)

full_name: Finset.fold_union_empty_singleton
code: @[simp]
theorem fold_union_empty_singleton [DecidableEq α] (s : Finset α) :
    Finset.fold (· ∪ ·) ∅ singleton s = s 
goal: Finset.fold (fun x x_1 => x ∪ x_1) ∅ singleton s = s

full_name: Finset.fold_sup_bot_singleton
code: theorem fold_sup_bot_singleton [DecidableEq α] (s : Finset α) :
    Finset.fold (· ⊔ ·) ⊥ singleton s = s 
goal: Finset.fold (fun x x_1 => x ⊔ x_1) ⊥ singleton s = s

full_name: Finset.le_fold_min
code: theorem le_fold_min : c ≤ s.fold min b f ↔ c ≤ b ∧ ∀ x ∈ s, c ≤ f x 
goal: c ≤ Finset.fold min b f s ↔ c ≤ b ∧ ∀ x ∈ s, c ≤ f x

full_name: Finset.fold_min_le
code: theorem fold_min_le : s.fold min b f ≤ c ↔ b ≤ c ∨ ∃ x ∈ s, f x ≤ c 
goal: Finset.fold min b f s ≤ c ↔ b ≤ c ∨ ∃ x ∈ s, f x ≤ c

full_name: Finset.lt_fold_min
code: theorem lt_fold_min : c < s.fold min b f ↔ c < b ∧ ∀ x ∈ s, c < f x 
goal: c < Finset.fold min b f s ↔ c < b ∧ ∀ x ∈ s, c < f x

full_name: Finset.fold_min_lt
code: theorem fold_min_lt : s.fold min b f < c ↔ b < c ∨ ∃ x ∈ s, f x < c 
goal: Finset.fold min b f s < c ↔ b < c ∨ ∃ x ∈ s, f x < c

full_name: Finset.fold_max_le
code: theorem fold_max_le : s.fold max b f ≤ c ↔ b ≤ c ∧ ∀ x ∈ s, f x ≤ c 
goal: Finset.fold max b f s ≤ c ↔ b ≤ c ∧ ∀ x ∈ s, f x ≤ c

full_name: Finset.le_fold_max
code: theorem le_fold_max : c ≤ s.fold max b f ↔ c ≤ b ∨ ∃ x ∈ s, c ≤ f x 
goal: c ≤ Finset.fold max b f s ↔ c ≤ b ∨ ∃ x ∈ s, c ≤ f x

full_name: Finset.fold_max_lt
code: theorem fold_max_lt : s.fold max b f < c ↔ b < c ∧ ∀ x ∈ s, f x < c 
goal: Finset.fold max b f s < c ↔ b < c ∧ ∀ x ∈ s, f x < c

full_name: Finset.lt_fold_max
code: theorem lt_fold_max : c < s.fold max b f ↔ c < b ∨ ∃ x ∈ s, c < f x 
goal: c < Finset.fold max b f s ↔ c < b ∨ ∃ x ∈ s, c < f x

full_name: Finset.fold_max_add
code: theorem fold_max_add [Add β] [CovariantClass β β (Function.swap (· + ·)) (· ≤ ·)] (n : WithBot β)
    (s : Finset α) : (s.fold max ⊥ fun x : α => ↑(f x) + n) = s.fold max ⊥ ((↑) ∘ f) + n 
goal: Finset.fold max ⊥ (fun x => ↑(f x) + n) s = Finset.fold max ⊥ (WithBot.some ∘ f) s + n