|
| 1 | +/- |
| 2 | +Copyright (c) 2022 Yaël Dillies. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Yaël Dillies |
| 5 | +
|
| 6 | +! This file was ported from Lean 3 source module data.finset.finsupp |
| 7 | +! leanprover-community/mathlib commit 59694bd07f0a39c5beccba34bd9f413a160782bf |
| 8 | +! Please do not edit these lines, except to modify the commit id |
| 9 | +! if you have ported upstream changes. |
| 10 | +-/ |
| 11 | +import Mathlib.Algebra.BigOperators.Finsupp |
| 12 | +import Mathlib.Data.Finset.Pointwise |
| 13 | +import Mathlib.Data.Finsupp.Indicator |
| 14 | +import Mathlib.Data.Fintype.BigOperators |
| 15 | + |
| 16 | +/-! |
| 17 | +# Finitely supported product of finsets |
| 18 | +
|
| 19 | +This file defines the finitely supported product of finsets as a `Finset (ι →₀ α)`. |
| 20 | +
|
| 21 | +## Main declarations |
| 22 | +
|
| 23 | +* `Finset.finsupp`: Finitely supported product of finsets. `s.finset t` is the product of the `t i` |
| 24 | + over all `i ∈ s`. |
| 25 | +* `Finsupp.pi`: `f.pi` is the finset of `Finsupp`s whose `i`-th value lies in `f i`. This is the |
| 26 | + special case of `Finset.finsupp` where we take the product of the `f i` over the support of `f`. |
| 27 | +
|
| 28 | +## Implementation notes |
| 29 | +
|
| 30 | +We make heavy use of the fact that `0 : Finset α` is `{0}`. This scalar actions convention turns out |
| 31 | +to be precisely what we want here too. |
| 32 | +-/ |
| 33 | + |
| 34 | + |
| 35 | +noncomputable section |
| 36 | + |
| 37 | +open Finsupp |
| 38 | + |
| 39 | +open BigOperators Classical Pointwise |
| 40 | + |
| 41 | +variable {ι α : Type _} [Zero α] {s : Finset ι} {f : ι →₀ α} |
| 42 | + |
| 43 | +namespace Finset |
| 44 | + |
| 45 | +/-- Finitely supported product of finsets. -/ |
| 46 | +protected def finsupp (s : Finset ι) (t : ι → Finset α) : Finset (ι →₀ α) := |
| 47 | + (s.pi t).map ⟨indicator s, indicator_injective s⟩ |
| 48 | +#align finset.finsupp Finset.finsupp |
| 49 | + |
| 50 | +theorem mem_finsupp_iff {t : ι → Finset α} : f ∈ s.finsupp t ↔ f.support ⊆ s ∧ ∀ i ∈ s, f i ∈ t i := |
| 51 | + by |
| 52 | + refine' mem_map.trans ⟨_, _⟩ |
| 53 | + · rintro ⟨f, hf, rfl⟩ |
| 54 | + refine' ⟨support_indicator_subset _ _, fun i hi => _⟩ |
| 55 | + convert mem_pi.1 hf i hi |
| 56 | + exact indicator_of_mem hi _ |
| 57 | + · refine' fun h => ⟨fun i _ => f i, mem_pi.2 h.2, _⟩ |
| 58 | + ext i |
| 59 | + exact ite_eq_left_iff.2 fun hi => (not_mem_support_iff.1 fun H => hi <| h.1 H).symm |
| 60 | +#align finset.mem_finsupp_iff Finset.mem_finsupp_iff |
| 61 | + |
| 62 | +/-- When `t` is supported on `s`, `f ∈ s.finsupp t` precisely means that `f` is pointwise in `t`. -/ |
| 63 | +@[simp] |
| 64 | +theorem mem_finsupp_iff_of_support_subset {t : ι →₀ Finset α} (ht : t.support ⊆ s) : |
| 65 | + f ∈ s.finsupp t ↔ ∀ i, f i ∈ t i := by |
| 66 | + refine' |
| 67 | + mem_finsupp_iff.trans |
| 68 | + (forall_and.symm.trans <| |
| 69 | + forall_congr' fun i => |
| 70 | + ⟨fun h => _, fun h => |
| 71 | + ⟨fun hi => ht <| mem_support_iff.2 fun H => mem_support_iff.1 hi _, fun _ => h⟩⟩) |
| 72 | + · by_cases hi : i ∈ s |
| 73 | + · exact h.2 hi |
| 74 | + · rw [not_mem_support_iff.1 (mt h.1 hi), not_mem_support_iff.1 fun H => hi <| ht H] |
| 75 | + exact zero_mem_zero |
| 76 | + · rwa [H, mem_zero] at h |
| 77 | +#align finset.mem_finsupp_iff_of_support_subset Finset.mem_finsupp_iff_of_support_subset |
| 78 | + |
| 79 | +@[simp] |
| 80 | +theorem card_finsupp (s : Finset ι) (t : ι → Finset α) : |
| 81 | + (s.finsupp t).card = ∏ i in s, (t i).card := |
| 82 | + (card_map _).trans <| card_pi _ _ |
| 83 | +#align finset.card_finsupp Finset.card_finsupp |
| 84 | + |
| 85 | +end Finset |
| 86 | + |
| 87 | +open Finset |
| 88 | + |
| 89 | +namespace Finsupp |
| 90 | + |
| 91 | +/-- Given a finitely supported function `f : ι →₀ Finset α`, one can define the finset |
| 92 | +`f.pi` of all finitely supported functions whose value at `i` is in `f i` for all `i`. -/ |
| 93 | +def pi (f : ι →₀ Finset α) : Finset (ι →₀ α) := |
| 94 | + f.support.finsupp f |
| 95 | +#align finsupp.pi Finsupp.pi |
| 96 | + |
| 97 | +@[simp] |
| 98 | +theorem mem_pi {f : ι →₀ Finset α} {g : ι →₀ α} : g ∈ f.pi ↔ ∀ i, g i ∈ f i := |
| 99 | + mem_finsupp_iff_of_support_subset <| Subset.refl _ |
| 100 | +#align finsupp.mem_pi Finsupp.mem_pi |
| 101 | + |
| 102 | +@[simp] |
| 103 | +theorem card_pi (f : ι →₀ Finset α) : f.pi.card = f.prod fun i => (f i).card := by |
| 104 | + rw [pi, card_finsupp] |
| 105 | + exact Finset.prod_congr rfl fun i _ => by simp only [Pi.nat_apply, Nat.cast_id] |
| 106 | +#align finsupp.card_pi Finsupp.card_pi |
| 107 | + |
| 108 | +end Finsupp |
0 commit comments