File: Mathlib/Data/Setoid/Partition.lean

full_name: Setoid.eq_of_mem_eqv_class
code: /-- If x ∈ α is in 2 elements of a set of sets partitioning α, those 2 sets are equal. -/
theorem eq_of_mem_eqv_class {c : Set (Set α)} (H : ∀ a, ∃! b ∈ c, a ∈ b) {x b b'}
    (hc : b ∈ c) (hb : x ∈ b) (hc' : b' ∈ c) (hb' : x ∈ b') : b = b' 
goal: b = b'

full_name: Setoid.mkClasses
code: /-- Makes an equivalence relation from a set of sets partitioning α. -/
def mkClasses (c : Set (Set α)) (H : ∀ a, ∃! b ∈ c, a ∈ b) : Setoid α 
goal: Setoid α

full_name: Setoid.classes
code: /-- Makes the equivalence classes of an equivalence relation. -/
def classes (r : Setoid α) : Set (Set α) 
goal: Set (Set α)

full_name: Setoid.mem_classes
code: theorem mem_classes (r : Setoid α) (y) : { x | r.Rel x y } ∈ r.classes 
goal: {x | r.Rel x y} ∈ r.classes

full_name: Setoid.classes_ker_subset_fiber_set
code: theorem classes_ker_subset_fiber_set {β : Type*} (f : α → β) :
    (Setoid.ker f).classes ⊆ Set.range fun y => { x | f x = y } 
goal: (Setoid.ker f).classes ⊆ Set.range fun y => {x | f x = y}

full_name: Setoid.finite_classes_ker
code: theorem finite_classes_ker {α β : Type*} [Finite β] (f : α → β) : (Setoid.ker f).classes.Finite 
goal: (Setoid.ker f).classes.Finite

full_name: Setoid.card_classes_ker_le
code: theorem card_classes_ker_le {α β : Type*} [Fintype β] (f : α → β)
    [Fintype (Setoid.ker f).classes] : Fintype.card (Setoid.ker f).classes ≤ Fintype.card β 
goal: Fintype.card ↑(Setoid.ker f).classes ≤ Fintype.card β

full_name: Setoid.eq_iff_classes_eq
code: /-- Two equivalence relations are equal iff all their equivalence classes are equal. -/
theorem eq_iff_classes_eq {r₁ r₂ : Setoid α} :
    r₁ = r₂ ↔ ∀ x, { y | r₁.Rel x y } = { y | r₂.Rel x y } 
goal: r₁ = r₂ ↔ ∀ (x : α), {y | r₁.Rel x y} = {y | r₂.Rel x y}

full_name: Setoid.rel_iff_exists_classes
code: theorem rel_iff_exists_classes (r : Setoid α) {x y} : r.Rel x y ↔ ∃ c ∈ r.classes, x ∈ c ∧ y ∈ c 
goal: r.Rel x y ↔ ∃ c ∈ r.classes, x ∈ c ∧ y ∈ c

full_name: Setoid.classes_inj
code: /-- Two equivalence relations are equal iff their equivalence classes are equal. -/
theorem classes_inj {r₁ r₂ : Setoid α} : r₁ = r₂ ↔ r₁.classes = r₂.classes 
goal: r₁ = r₂ ↔ r₁.classes = r₂.classes

full_name: Setoid.empty_not_mem_classes
code: /-- The empty set is not an equivalence class. -/
theorem empty_not_mem_classes {r : Setoid α} : ∅ ∉ r.classes 
goal: ∅ ∉ r.classes

full_name: Setoid.classes_eqv_classes
code: /-- Equivalence classes partition the type. -/
theorem classes_eqv_classes {r : Setoid α} (a) : ∃! b ∈ r.classes, a ∈ b 
goal: ∃! b, b ∈ r.classes ∧ a ∈ b

full_name: Setoid.eq_of_mem_classes
code: /-- If x ∈ α is in 2 equivalence classes, the equivalence classes are equal. -/
theorem eq_of_mem_classes {r : Setoid α} {x b} (hc : b ∈ r.classes) (hb : x ∈ b) {b'}
    (hc' : b' ∈ r.classes) (hb' : x ∈ b') : b = b' 
goal: b = b'

full_name: Setoid.eq_eqv_class_of_mem
code: /-- The elements of a set of sets partitioning α are the equivalence classes of the
    equivalence relation defined by the set of sets. -/
theorem eq_eqv_class_of_mem {c : Set (Set α)} (H : ∀ a, ∃! b ∈ c, a ∈ b) {s y}
    (hs : s ∈ c) (hy : y ∈ s) : s = { x | (mkClasses c H).Rel x y } 
goal: s = {x | (Setoid.mkClasses c H).Rel x y}

full_name: Setoid.eqv_class_mem
code: /-- The equivalence classes of the equivalence relation defined by a set of sets
    partitioning α are elements of the set of sets. -/
theorem eqv_class_mem {c : Set (Set α)} (H : ∀ a, ∃! b ∈ c, a ∈ b) {y} :
    { x | (mkClasses c H).Rel x y } ∈ c 
goal: {x | (Setoid.mkClasses c H).Rel x y} ∈ c

full_name: Setoid.eqv_class_mem'
code: theorem eqv_class_mem' {c : Set (Set α)} (H : ∀ a, ∃! b ∈ c, a ∈ b) {x} :
    { y : α | (mkClasses c H).Rel x y } ∈ c 
goal: {y | (Setoid.mkClasses c H).Rel x y} ∈ c

full_name: Setoid.eqv_classes_disjoint
code: /-- Distinct elements of a set of sets partitioning α are disjoint. -/
theorem eqv_classes_disjoint {c : Set (Set α)} (H : ∀ a, ∃! b ∈ c, a ∈ b) :
    c.PairwiseDisjoint id 
goal: c.PairwiseDisjoint id

full_name: Setoid.eqv_classes_of_disjoint_union
code: /-- A set of disjoint sets covering α partition α (classical). -/
theorem eqv_classes_of_disjoint_union {c : Set (Set α)} (hu : Set.sUnion c = @Set.univ α)
    (H : c.PairwiseDisjoint id) (a) : ∃! b ∈ c, a ∈ b 
goal: ∃! b, b ∈ c ∧ a ∈ b

full_name: Setoid.setoidOfDisjointUnion
code: /-- Makes an equivalence relation from a set of disjoints sets covering α. -/
def setoidOfDisjointUnion {c : Set (Set α)} (hu : Set.sUnion c = @Set.univ α)
    (H : c.PairwiseDisjoint id) : Setoid α 
goal: Setoid α

full_name: Setoid.mkClasses_classes
code: /-- The equivalence relation made from the equivalence classes of an equivalence
    relation r equals r. -/
theorem mkClasses_classes (r : Setoid α) : mkClasses r.classes classes_eqv_classes = r 
goal: Setoid.mkClasses r.classes ⋯ = r

full_name: Setoid.sUnion_classes
code: @[simp]
theorem sUnion_classes (r : Setoid α) : ⋃₀ r.classes = Set.univ 
goal: ⋃₀ r.classes = Set.univ

full_name: Setoid.quotientEquivClasses
code: /-- The equivalence between the quotient by an equivalence relation and its
type of equivalence classes. -/
noncomputable def quotientEquivClasses (r : Setoid α) : Quotient r ≃ Setoid.classes r 
goal: Quotient r ≃ ↑r.classes

full_name: Setoid.quotientEquivClasses_mk_eq
code: @[simp]
lemma quotientEquivClasses_mk_eq (r : Setoid α) (a : α) :
    (quotientEquivClasses r (Quotient.mk r a) : Set α) = { x | r.Rel x a } 
goal: ↑(r.quotientEquivClasses ⟦a⟧) = {x | r.Rel x a}

full_name: Setoid.IsPartition
code: /-- A collection `c : Set (Set α)` of sets is a partition of `α` into pairwise
disjoint sets if `∅ ∉ c` and each element `a : α` belongs to a unique set `b ∈ c`. -/
def IsPartition (c : Set (Set α)) 
goal: Prop

full_name: Setoid.nonempty_of_mem_partition
code: /-- A partition of `α` does not contain the empty set. -/
theorem nonempty_of_mem_partition {c : Set (Set α)} (hc : IsPartition c) {s} (h : s ∈ c) :
    s.Nonempty 
goal: s.Nonempty

full_name: Setoid.isPartition_classes
code: theorem isPartition_classes (r : Setoid α) : IsPartition r.classes 
goal: Setoid.IsPartition r.classes

full_name: Setoid.IsPartition.pairwiseDisjoint
code: theorem IsPartition.pairwiseDisjoint {c : Set (Set α)} (hc : IsPartition c) :
    c.PairwiseDisjoint id 
goal: c.PairwiseDisjoint id

full_name: Set.PairwiseDisjoint.isPartition_of_exists_of_ne_empty
code: lemma _root_.Set.PairwiseDisjoint.isPartition_of_exists_of_ne_empty {α : Type*} {s : Set (Set α)}
    (h₁ : s.PairwiseDisjoint id) (h₂ : ∀ a : α, ∃ x ∈ s, a ∈ x) (h₃ : ∅ ∉ s) :
    Setoid.IsPartition s 
goal: Setoid.IsPartition s

full_name: Setoid.IsPartition.sUnion_eq_univ
code: theorem IsPartition.sUnion_eq_univ {c : Set (Set α)} (hc : IsPartition c) : ⋃₀ c = Set.univ 
goal: ⋃₀ c = Set.univ

full_name: Setoid.exists_of_mem_partition
code: /-- All elements of a partition of α are the equivalence class of some y ∈ α. -/
theorem exists_of_mem_partition {c : Set (Set α)} (hc : IsPartition c) {s} (hs : s ∈ c) :
    ∃ y, s = { x | (mkClasses c hc.2).Rel x y } 
goal: ∃ y, s = {x | (Setoid.mkClasses c ⋯).Rel x y}

full_name: Setoid.classes_mkClasses
code: /-- The equivalence classes of the equivalence relation defined by a partition of α equal
    the original partition. -/
theorem classes_mkClasses (c : Set (Set α)) (hc : IsPartition c) :
    (mkClasses c hc.2).classes = c 
goal: (Setoid.mkClasses c ⋯).classes = c

full_name: Setoid.Partition.le
code: /-- Defining `≤` on partitions as the `≤` defined on their induced equivalence relations. -/
instance Partition.le : LE (Subtype (@IsPartition α)) 
goal: LE (Subtype Setoid.IsPartition)

full_name: Setoid.Partition.partialOrder
code: /-- Defining a partial order on partitions as the partial order on their induced
    equivalence relations. -/
instance Partition.partialOrder : PartialOrder (Subtype (@IsPartition α)) 
goal: PartialOrder (Subtype Setoid.IsPartition)

full_name: Setoid.Partition.orderIso
code: /-- The order-preserving bijection between equivalence relations on a type `α`, and
  partitions of `α` into subsets. -/
protected def Partition.orderIso : Setoid α ≃o { C : Set (Set α) // IsPartition C } 
goal: Setoid α ≃o { C // Setoid.IsPartition C }

full_name: Setoid.Partition.completeLattice
code: /-- A complete lattice instance for partitions; there is more infrastructure for the
    equivalent complete lattice on equivalence relations. -/
instance Partition.completeLattice : CompleteLattice (Subtype (@IsPartition α)) 
goal: CompleteLattice (Subtype Setoid.IsPartition)

full_name: Setoid.IsPartition.finpartition_parts
code: /-- A finite setoid partition furnishes a finpartition -/
@[simps]
def IsPartition.finpartition {c : Finset (Set α)} (hc : Setoid.IsPartition (c : Set (Set α))) :
    Finpartition (Set.univ : Set α) 
goal: hc.finpartition.parts = c

full_name: Setoid.IsPartition.finpartition
code: /-- A finite setoid partition furnishes a finpartition -/
@[simps]
def IsPartition.finpartition {c : Finset (Set α)} (hc : Setoid.IsPartition (c : Set (Set α))) :
    Finpartition (Set.univ : Set α) 
goal: Finpartition Set.univ

full_name: Finpartition.isPartition_parts
code: /-- A finpartition gives rise to a setoid partition -/
theorem Finpartition.isPartition_parts {α} (f : Finpartition (Set.univ : Set α)) :
    Setoid.IsPartition (f.parts : Set (Set α)) 
goal: Setoid.IsPartition ↑f.parts

full_name: IndexedPartition.eq_of_mem
code: /-- Constructive information associated with a partition of a type `α` indexed by another type `ι`,
`s : ι → Set α`.

`IndexedPartition.index` sends an element to its index, while `IndexedPartition.some` sends
an index to an element of the corresponding set.

This type is primarily useful for definitional control of `s` - if this is not needed, then
`Setoid.ker index` by itself may be sufficient. -/
structure IndexedPartition {ι α : Type*} (s : ι → Set α) where
  /-- two indexes are equal if they are equal in membership  -/
  eq_of_mem : ∀ {x i j}, x ∈ s i → x ∈ s j → i = j
  /-- sends an index to an element of the corresponding set-/
  some : ι → α
  /-- membership invariance for `some`-/
  some_mem : ∀ i, some i ∈ s i
  /-- index for type `α`-/
  index : α → ι
  /-- membership invariance for `index`-/
  mem_index : ∀ x, x ∈ s (index x)
goal: x ∈ s i → x ∈ s j → i = j

full_name: IndexedPartition.some_mem
code: /-- Constructive information associated with a partition of a type `α` indexed by another type `ι`,
`s : ι → Set α`.

`IndexedPartition.index` sends an element to its index, while `IndexedPartition.some` sends
an index to an element of the corresponding set.

This type is primarily useful for definitional control of `s` - if this is not needed, then
`Setoid.ker index` by itself may be sufficient. -/
structure IndexedPartition {ι α : Type*} (s : ι → Set α) where
  /-- two indexes are equal if they are equal in membership  -/
  eq_of_mem : ∀ {x i j}, x ∈ s i → x ∈ s j → i = j
  /-- sends an index to an element of the corresponding set-/
  some : ι → α
  /-- membership invariance for `some`-/
  some_mem : ∀ i, some i ∈ s i
  /-- index for type `α`-/
  index : α → ι
  /-- membership invariance for `index`-/
  mem_index : ∀ x, x ∈ s (index x)
goal: self.some i ∈ s i

full_name: IndexedPartition.index
code: /-- Constructive information associated with a partition of a type `α` indexed by another type `ι`,
`s : ι → Set α`.

`IndexedPartition.index` sends an element to its index, while `IndexedPartition.some` sends
an index to an element of the corresponding set.

This type is primarily useful for definitional control of `s` - if this is not needed, then
`Setoid.ker index` by itself may be sufficient. -/
structure IndexedPartition {ι α : Type*} (s : ι → Set α) where
  /-- two indexes are equal if they are equal in membership  -/
  eq_of_mem : ∀ {x i j}, x ∈ s i → x ∈ s j → i = j
  /-- sends an index to an element of the corresponding set-/
  some : ι → α
  /-- membership invariance for `some`-/
  some_mem : ∀ i, some i ∈ s i
  /-- index for type `α`-/
  index : α → ι
  /-- membership invariance for `index`-/
  mem_index : ∀ x, x ∈ s (index x)
goal: α → ι

full_name: IndexedPartition
code: /-- Constructive information associated with a partition of a type `α` indexed by another type `ι`,
`s : ι → Set α`.

`IndexedPartition.index` sends an element to its index, while `IndexedPartition.some` sends
an index to an element of the corresponding set.

This type is primarily useful for definitional control of `s` - if this is not needed, then
`Setoid.ker index` by itself may be sufficient. -/
structure IndexedPartition {ι α : Type*} (s : ι → Set α) where
  /-- two indexes are equal if they are equal in membership  -/
  eq_of_mem : ∀ {x i j}, x ∈ s i → x ∈ s j → i = j
  /-- sends an index to an element of the corresponding set-/
  some : ι → α
  /-- membership invariance for `some`-/
  some_mem : ∀ i, some i ∈ s i
  /-- index for type `α`-/
  index : α → ι
  /-- membership invariance for `index`-/
  mem_index : ∀ x, x ∈ s (index x)
goal: Type (max u_1 u_2)

full_name: IndexedPartition.mem_index
code: /-- Constructive information associated with a partition of a type `α` indexed by another type `ι`,
`s : ι → Set α`.

`IndexedPartition.index` sends an element to its index, while `IndexedPartition.some` sends
an index to an element of the corresponding set.

This type is primarily useful for definitional control of `s` - if this is not needed, then
`Setoid.ker index` by itself may be sufficient. -/
structure IndexedPartition {ι α : Type*} (s : ι → Set α) where
  /-- two indexes are equal if they are equal in membership  -/
  eq_of_mem : ∀ {x i j}, x ∈ s i → x ∈ s j → i = j
  /-- sends an index to an element of the corresponding set-/
  some : ι → α
  /-- membership invariance for `some`-/
  some_mem : ∀ i, some i ∈ s i
  /-- index for type `α`-/
  index : α → ι
  /-- membership invariance for `index`-/
  mem_index : ∀ x, x ∈ s (index x)
goal: x ∈ s (self.index x)

full_name: IndexedPartition.some
code: /-- Constructive information associated with a partition of a type `α` indexed by another type `ι`,
`s : ι → Set α`.

`IndexedPartition.index` sends an element to its index, while `IndexedPartition.some` sends
an index to an element of the corresponding set.

This type is primarily useful for definitional control of `s` - if this is not needed, then
`Setoid.ker index` by itself may be sufficient. -/
structure IndexedPartition {ι α : Type*} (s : ι → Set α) where
  /-- two indexes are equal if they are equal in membership  -/
  eq_of_mem : ∀ {x i j}, x ∈ s i → x ∈ s j → i = j
  /-- sends an index to an element of the corresponding set-/
  some : ι → α
  /-- membership invariance for `some`-/
  some_mem : ∀ i, some i ∈ s i
  /-- index for type `α`-/
  index : α → ι
  /-- membership invariance for `index`-/
  mem_index : ∀ x, x ∈ s (index x)
goal: ι → α

full_name: IndexedPartition.mk'
code: /-- The non-constructive constructor for `IndexedPartition`. -/
noncomputable def IndexedPartition.mk' {ι α : Type*} (s : ι → Set α)
    (dis : Pairwise fun i j => Disjoint (s i) (s j)) (nonempty : ∀ i, (s i).Nonempty)
    (ex : ∀ x, ∃ i, x ∈ s i) : IndexedPartition s 
goal: IndexedPartition s

full_name: IndexedPartition.instInhabitedUnivOfUnique
code: /-- On a unique index set there is the obvious trivial partition -/
instance [Unique ι] [Inhabited α] : Inhabited (IndexedPartition fun _i : ι => (Set.univ : Set α)) 
goal: Inhabited (IndexedPartition fun _i => Set.univ)

full_name: IndexedPartition.exists_mem
code: theorem exists_mem (x : α) : ∃ i, x ∈ s i 
goal: ∃ i, x ∈ s i

full_name: IndexedPartition.iUnion
code: theorem iUnion : ⋃ i, s i = univ 
goal: ⋃ i, s i = Set.univ

full_name: IndexedPartition.disjoint
code: theorem disjoint : Pairwise fun i j => Disjoint (s i) (s j) 
goal: Pairwise fun i j => Disjoint (s i) (s j)

full_name: IndexedPartition.mem_iff_index_eq
code: theorem mem_iff_index_eq {x i} : x ∈ s i ↔ hs.index x = i 
goal: x ∈ s i ↔ hs.index x = i

full_name: IndexedPartition.eq
code: theorem eq (i) : s i = { x | hs.index x = i } 
goal: s i = {x | hs.index x = i}

full_name: IndexedPartition.setoid
code: /-- The equivalence relation associated to an indexed partition. Two
elements are equivalent if they belong to the same set of the partition. -/
protected abbrev setoid (hs : IndexedPartition s) : Setoid α 
goal: Setoid α

full_name: IndexedPartition.index_some
code: @[simp]
theorem index_some (i : ι) : hs.index (hs.some i) = i 
goal: hs.index (hs.some i) = i

full_name: IndexedPartition.some_index
code: theorem some_index (x : α) : hs.setoid.Rel (hs.some (hs.index x)) x 
goal: hs.setoid.Rel (hs.some (hs.index x)) x

full_name: IndexedPartition.Quotient
code: /-- The quotient associated to an indexed partition. -/
protected def Quotient 
goal: Type u_2

full_name: IndexedPartition.proj
code: /-- The projection onto the quotient associated to an indexed partition. -/
def proj : α → hs.Quotient 
goal: α → hs.Quotient

full_name: IndexedPartition.instInhabitedQuotient
code: instance [Inhabited α] : Inhabited hs.Quotient 
goal: Inhabited hs.Quotient

full_name: IndexedPartition.proj_eq_iff
code: theorem proj_eq_iff {x y : α} : hs.proj x = hs.proj y ↔ hs.index x = hs.index y 
goal: hs.proj x = hs.proj y ↔ hs.index x = hs.index y

full_name: IndexedPartition.proj_some_index
code: @[simp]
theorem proj_some_index (x : α) : hs.proj (hs.some (hs.index x)) = hs.proj x 
goal: hs.proj (hs.some (hs.index x)) = hs.proj x

full_name: IndexedPartition.equivQuotient
code: /-- The obvious equivalence between the quotient associated to an indexed partition and
the indexing type. -/
def equivQuotient : ι ≃ hs.Quotient 
goal: ι ≃ hs.Quotient

full_name: IndexedPartition.equivQuotient_index_apply
code: @[simp]
theorem equivQuotient_index_apply (x : α) : hs.equivQuotient (hs.index x) = hs.proj x 
goal: hs.equivQuotient (hs.index x) = hs.proj x

full_name: IndexedPartition.equivQuotient_symm_proj_apply
code: @[simp]
theorem equivQuotient_symm_proj_apply (x : α) : hs.equivQuotient.symm (hs.proj x) = hs.index x 
goal: hs.equivQuotient.symm (hs.proj x) = hs.index x

full_name: IndexedPartition.equivQuotient_index
code: theorem equivQuotient_index : hs.equivQuotient ∘ hs.index = hs.proj 
goal: ⇑hs.equivQuotient ∘ hs.index = hs.proj

full_name: IndexedPartition.out
code: /-- A map choosing a representative for each element of the quotient associated to an indexed
partition. This is a computable version of `Quotient.out'` using `IndexedPartition.some`. -/
def out : hs.Quotient ↪ α 
goal: hs.Quotient ↪ α

full_name: IndexedPartition.out_proj
code: /-- This lemma is analogous to `Quotient.mk_out'`. -/
@[simp]
theorem out_proj (x : α) : hs.out (hs.proj x) = hs.some (hs.index x) 
goal: hs.out (hs.proj x) = hs.some (hs.index x)

full_name: IndexedPartition.index_out'
code: /-- The indices of `Quotient.out'` and `IndexedPartition.out` are equal. -/
theorem index_out' (x : hs.Quotient) : hs.index x.out' = hs.index (hs.out x) 
goal: hs.index (Quotient.out' x) = hs.index (hs.out x)

full_name: IndexedPartition.proj_out
code: /-- This lemma is analogous to `Quotient.out_eq'`. -/
@[simp]
theorem proj_out (x : hs.Quotient) : hs.proj (hs.out x) = x 
goal: hs.proj (hs.out x) = x

full_name: IndexedPartition.class_of
code: theorem class_of {x : α} : setOf (hs.setoid.Rel x) = s (hs.index x) 
goal: setOf (hs.setoid.Rel x) = s (hs.index x)

full_name: IndexedPartition.proj_fiber
code: theorem proj_fiber (x : hs.Quotient) : hs.proj ⁻¹' {x} = s (hs.equivQuotient.symm x) 
goal: hs.proj ⁻¹' {x} = s (hs.equivQuotient.symm x)

full_name: IndexedPartition.piecewise
code: /-- Combine functions with disjoint domains into a new function.
You can use the regular expression `def.*piecewise` to search for
other ways to define piecewise functions in mathlib4. -/
def piecewise {β : Type*} (f : ι → α → β) : α → β 
goal: α → β

full_name: IndexedPartition.piecewise_apply
code: lemma piecewise_apply {β : Type*} {f : ι → α → β} (x : α) : hs.piecewise f x = f (hs.index x) x 
goal: hs.piecewise f x = f (hs.index x) x

full_name: IndexedPartition.piecewise_inj
code: /-- A family of injective functions with pairwise disjoint
domains and pairwise disjoint ranges can be glued together
to form an injective function. -/
theorem piecewise_inj {β : Type*} {f : ι → α → β}
    (h_injOn : ∀ i, InjOn (f i) (s i))
    (h_disjoint : PairwiseDisjoint (univ : Set ι) fun i => (f i) '' (s i)) :
    Injective (piecewise hs f) 
goal: Function.Injective (hs.piecewise f)

full_name: IndexedPartition.piecewise_bij
code: /-- A family of bijective functions with pairwise disjoint
domains and pairwise disjoint ranges can be glued together
to form a bijective function. -/
theorem piecewise_bij {β : Type*} {f : ι → α → β}
    {t : ι → Set β} (ht : IndexedPartition t)
    (hf : ∀ i, BijOn (f i) (s i) (t i)) :
    Bijective (piecewise hs f) 
goal: Function.Bijective (hs.piecewise f)