-- Mathlib/Data/Setoid/Partition.lean
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)

Proof state:
ι : Type u_1
α : Type u_2
s : ι → Set α
hs : IndexedPartition s
β : Type u_3
f : ι → α → β
h_injOn : ∀ (i : ι), InjOn (f i) (s i)
h_disjoint : univ.PairwiseDisjoint fun i => f i '' s i
x y : α
h : hs.piecewise f x = hs.piecewise f y
this : hs.index x = hs.index y
⊢ x = y

Tactic:
apply h_injOn (hs.index x) (hs.mem_index x) (this ▸ hs.mem_index y)

Result:
ι : Type u_1
α : Type u_2
s : ι → Set α
hs : IndexedPartition s
β : Type u_3
f : ι → α → β
h_injOn : ∀ (i : ι), InjOn (f i) (s i)
h_disjoint : univ.PairwiseDisjoint fun i => f i '' s i
x y : α
h : hs.piecewise f x = hs.piecewise f y
this : hs.index x = hs.index y
⊢ f (hs.index x) x = f (hs.index x) y

Proof state:
ι : Type u_1
α : Type u_2
s : ι → Set α
hs : IndexedPartition s
β : Type u_3
f : ι → α → β
h_injOn : ∀ (i : ι), InjOn (f i) (s i)
h_disjoint : univ.PairwiseDisjoint fun i => f i '' s i
x y : α
h : hs.piecewise f x = hs.piecewise f y
⊢ hs.index x = hs.index y

Tactic:
apply h_disjoint.elim trivial trivial

Result:
ι : Type u_1
α : Type u_2
s : ι → Set α
hs : IndexedPartition s
β : Type u_3
f : ι → α → β
h_injOn : ∀ (i : ι), InjOn (f i) (s i)
h_disjoint : univ.PairwiseDisjoint fun i => f i '' s i
x y : α
h : hs.piecewise f x = hs.piecewise f y
⊢ ¬Disjoint (f (hs.index x) '' s (hs.index x)) (f (hs.index y) '' s (hs.index y))

Proof state:
ι : Type u_1
α : Type u_2
s : ι → Set α
hs : IndexedPartition s
β : Type u_3
f : ι → α → β
h_injOn : ∀ (i : ι), InjOn (f i) (s i)
h_disjoint : univ.PairwiseDisjoint fun i => f i '' s i
x y : α
h : Disjoint (f (hs.index x) '' s (hs.index x)) (f (hs.index y) '' s (hs.index y))
⊢ hs.piecewise f x ≠ hs.piecewise f y

Tactic:
exact h.ne_of_mem (mem_image_of_mem _ (hs.mem_index x)) (mem_image_of_mem _ (hs.mem_index y))

Result:
no goals

Proof state:
ι : Type u_1
α : Type u_2
s : ι → Set α
hs : IndexedPartition s
β : Type u_3
f : ι → α → β
h_injOn : ∀ (i : ι), InjOn (f i) (s i)
h_disjoint : univ.PairwiseDisjoint fun i => f i '' s i
x y : α
h : hs.piecewise f x = hs.piecewise f y
⊢ x = y

Tactic:
suffices hs.index x = hs.index y by
  apply h_injOn (hs.index x) (hs.mem_index x) (this ▸ hs.mem_index y)
  simpa only [piecewise_apply, this] using h

Result:
ι : Type u_1
α : Type u_2
s : ι → Set α
hs : IndexedPartition s
β : Type u_3
f : ι → α → β
h_injOn : ∀ (i : ι), InjOn (f i) (s i)
h_disjoint : univ.PairwiseDisjoint fun i => f i '' s i
x y : α
h : hs.piecewise f x = hs.piecewise f y
⊢ hs.index x = hs.index y

Proof state:
ι : Type u_1
α : Type u_2
s : ι → Set α
hs : IndexedPartition s
β : Type u_3
f : ι → α → β
h_injOn : ∀ (i : ι), InjOn (f i) (s i)
h_disjoint : univ.PairwiseDisjoint fun i => f i '' s i
⊢ Injective (hs.piecewise f)

Tactic:
intro x y h

Result:
ι : Type u_1
α : Type u_2
s : ι → Set α
hs : IndexedPartition s
β : Type u_3
f : ι → α → β
h_injOn : ∀ (i : ι), InjOn (f i) (s i)
h_disjoint : univ.PairwiseDisjoint fun i => f i '' s i
x y : α
h : hs.piecewise f x = hs.piecewise f y
⊢ x = y

Proof state:
ι : Type u_1
α : Type u_2
s : ι → Set α
hs : IndexedPartition s
β : Type u_3
f : ι → α → β
h_injOn : ∀ (i : ι), InjOn (f i) (s i)
h_disjoint : univ.PairwiseDisjoint fun i => f i '' s i
x y : α
h : hs.piecewise f x = hs.piecewise f y
this : hs.index x = hs.index y
⊢ f (hs.index x) x = f (hs.index x) y

Tactic:
simpa only [piecewise_apply, this] using h

Result:
no goals

Proof state:
ι : Type u_1
α : Type u_2
s : ι → Set α
hs : IndexedPartition s
β : Type u_3
f : ι → α → β
h_injOn : ∀ (i : ι), InjOn (f i) (s i)
h_disjoint : univ.PairwiseDisjoint fun i => f i '' s i
x y : α
h : hs.piecewise f x = hs.piecewise f y
⊢ ¬Disjoint (f (hs.index x) '' s (hs.index x)) (f (hs.index y) '' s (hs.index y))

Tactic:
contrapose! h

Result:
ι : Type u_1
α : Type u_2
s : ι → Set α
hs : IndexedPartition s
β : Type u_3
f : ι → α → β
h_injOn : ∀ (i : ι), InjOn (f i) (s i)
h_disjoint : univ.PairwiseDisjoint fun i => f i '' s i
x y : α
h : Disjoint (f (hs.index x) '' s (hs.index x)) (f (hs.index y) '' s (hs.index y))
⊢ hs.piecewise f x ≠ hs.piecewise f y