Skip to content

Commit

Permalink
feat(algebra/big_operators): add finset.prod_comm' (#14257)
Browse files Browse the repository at this point in the history
* add a "dependent" version of `finset.prod_comm`;
* use it to prove the original lemma;
* slightly generalize `exists_eq_right_right` and `exists_eq_right_right'`;
* add two `simps` attributes.
  • Loading branch information
urkud committed May 21, 2022
1 parent 3fc6fbb commit d787d49
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 16 deletions.
34 changes: 22 additions & 12 deletions src/algebra/big_operators/basic.lean
Expand Up @@ -503,17 +503,6 @@ calc (∏ x in s.image g, f x) = ∏ x in s.image g, ∏ x in s.filter (λ c', g
lemma prod_mul_distrib : ∏ x in s, (f x * g x) = (∏ x in s, f x) * (∏ x in s, g x) :=
eq.trans (by rw one_mul; refl) fold_op_distrib

@[to_additive]
lemma prod_comm {s : finset γ} {t : finset α} {f : γ → α → β} :
(∏ x in s, ∏ y in t, f x y) = (∏ y in t, ∏ x in s, f x y) :=
begin
classical,
apply finset.induction_on s,
{ simp only [prod_empty, prod_const_one] },
{ intros _ _ H ih,
simp only [prod_insert H, prod_mul_distrib, ih] }
end

@[to_additive]
lemma prod_product {s : finset γ} {t : finset α} {f : γ×α → β} :
(∏ x in s.product t, f x) = ∏ x in s, ∏ y in t, f (x, y) :=
Expand All @@ -528,14 +517,35 @@ prod_product
@[to_additive]
lemma prod_product_right {s : finset γ} {t : finset α} {f : γ×α → β} :
(∏ x in s.product t, f x) = ∏ y in t, ∏ x in s, f (x, y) :=
by rw [prod_product, prod_comm]
prod_finset_product_right (s.product t) t (λ a, s) (λ p, mem_product.trans and.comm)

/-- An uncurried version of `finset.prod_product_right`. -/
@[to_additive "An uncurried version of `finset.prod_product_right`"]
lemma prod_product_right' {s : finset γ} {t : finset α} {f : γ → α → β} :
(∏ x in s.product t, f x.1 x.2) = ∏ y in t, ∏ x in s, f x y :=
prod_product_right

/-- Generalization of `finset.prod_comm` to the case when the inner `finset`s depend on the outer
variable. -/
@[to_additive "Generalization of `finset.sum_comm` to the case when the inner `finset`s depend on
the outer variable."]
lemma prod_comm' {s : finset γ} {t : γ → finset α} {t' : finset α} {s' : α → finset γ}
(h : ∀ x y, x ∈ s ∧ y ∈ t x ↔ x ∈ s' y ∧ y ∈ t') {f : γ → α → β} :
(∏ x in s, ∏ y in t x, f x y) = (∏ y in t', ∏ x in s' y, f x y) :=
begin
classical,
have : ∀ z : γ × α,
z ∈ s.bUnion (λ x, (t x).map $ function.embedding.sectr x _) ↔ z.1 ∈ s ∧ z.2 ∈ t z.1,
{ rintro ⟨x, y⟩, simp },
exact (prod_finset_product' _ _ _ this).symm.trans
(prod_finset_product_right' _ _ _ $ λ ⟨x, y⟩, (this _).trans ((h x y).trans and.comm))
end

@[to_additive]
lemma prod_comm {s : finset γ} {t : finset α} {f : γ → α → β} :
(∏ x in s, ∏ y in t, f x y) = (∏ y in t, ∏ x in s, f x y) :=
prod_comm' $ λ _ _, iff.rfl

@[to_additive]
lemma prod_hom_rel [comm_monoid γ] {r : β → γ → Prop} {f : α → β} {g : α → γ} {s : finset α}
(h₁ : r 1 1) (h₂ : ∀ a b c, r b c → r (f a * b) (g a * c)) : r (∏ x in s, f x) (∏ x in s, g x) :=
Expand Down
4 changes: 2 additions & 2 deletions src/logic/basic.lean
Expand Up @@ -1147,11 +1147,11 @@ by simp only [exists_unique, and_self, forall_eq', exists_eq']
(exists_congr $ by exact λ a, and.comm).trans exists_eq_left

@[simp] theorem exists_eq_right_right {a' : α} :
(∃ (a : α), p a ∧ b ∧ a = a') ↔ p a' ∧ b :=
(∃ (a : α), p a ∧ q a ∧ a = a') ↔ p a' ∧ q a' :=
⟨λ ⟨_, hp, hq, rfl⟩, ⟨hp, hq⟩, λ ⟨hp, hq⟩, ⟨a', hp, hq, rfl⟩⟩

@[simp] theorem exists_eq_right_right' {a' : α} :
(∃ (a : α), p a ∧ b ∧ a' = a) ↔ p a' ∧ b :=
(∃ (a : α), p a ∧ q a ∧ a' = a) ↔ p a' ∧ q a' :=
⟨λ ⟨_, hp, hq, rfl⟩, ⟨hp, hq⟩, λ ⟨hp, hq⟩, ⟨a', hp, hq, rfl⟩⟩

@[simp] theorem exists_apply_eq_apply (f : α → β) (a' : α) : ∃ a, f a = f a' := ⟨a', rfl⟩
Expand Down
4 changes: 2 additions & 2 deletions src/logic/embedding.lean
Expand Up @@ -194,11 +194,11 @@ def punit {β : Sort*} (b : β) : punit ↪ β :=
⟨λ _, b, by { rintros ⟨⟩ ⟨⟩ _, refl, }⟩

/-- Fixing an element `b : β` gives an embedding `α ↪ α × β`. -/
def sectl (α : Sort*) {β : Sort*} (b : β) : α ↪ α × β :=
@[simps] def sectl (α : Sort*) {β : Sort*} (b : β) : α ↪ α × β :=
⟨λ a, (a, b), λ a a' h, congr_arg prod.fst h⟩

/-- Fixing an element `a : α` gives an embedding `β ↪ α × β`. -/
def sectr {α : Sort*} (a : α) (β : Sort*): β ↪ α × β :=
@[simps] def sectr {α : Sort*} (a : α) (β : Sort*): β ↪ α × β :=
⟨λ b, (a, b), λ b b' h, congr_arg prod.snd h⟩

/-- Restrict the codomain of an embedding. -/
Expand Down

0 comments on commit d787d49

Please sign in to comment.