l3lab/ntp-mathlib huggingface dataset:
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (

Proof state:
case neg
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
inst✝¹ : (a' : α) → Decidable (a' = a)
x y : α
h₁ : ¬x = a
h₅ : ¬y = a
h : f a = f y
inst✝ : (a' : α) → Decidable (f a' = f x)
h₆ : ¬f y = f x
⊢ x = y

Next tactic:
try simp only [f.injective.eq_iff, not_true_eq_false] at *
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (try 

Proof state:
case neg
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
inst✝¹ : (a' : α) → Decidable (a' = a)
x y : α
h₁ : ¬x = a
h₅ : ¬y = a
h : f a = f y
inst✝ : (a' : α) → Decidable (f a' = f x)
h₆ : ¬f y = f x
⊢ x = y

Next tactic:
simp only [f.injective.eq_iff, not_true_eq_false] at *
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (

Proof state:
case pos
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
inst✝¹ : (a' : α) → Decidable (a' = a)
x y : α
h₁ : ¬x = a
h✝ : y = a
inst✝ : (a' : α) → Decidable (f a' = f x)
_ : ¬f x = f x
⊢ x = y

Next tactic:
try simp only [f.injective.eq_iff, not_true_eq_false] at *
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (try 

Proof state:
case pos
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
inst✝¹ : (a' : α) → Decidable (a' = a)
x y : α
h₁ : ¬x = a
h✝ : y = a
inst✝ : (a' : α) → Decidable (f a' = f x)
_ : ¬f x = f x
⊢ x = y

Next tactic:
simp only [f.injective.eq_iff, not_true_eq_false] at *
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (

Proof state:
case pos
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
inst✝¹ : (a' : α) → Decidable (a' = a)
x y : α
h₁ : ¬x = a
h✝ : ¬y = a
h : f x = f a
inst✝ : (a' : α) → Decidable (f a' = f y)
_ : ¬f x = f y
⊢ x = y

Next tactic:
try simp only [f.injective.eq_iff, not_true_eq_false] at *
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (try 

Proof state:
case pos
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
inst✝¹ : (a' : α) → Decidable (a' = a)
x y : α
h₁ : ¬x = a
h✝ : ¬y = a
h : f x = f a
inst✝ : (a' : α) → Decidable (f a' = f y)
_ : ¬f x = f y
⊢ x = y

Next tactic:
simp only [f.injective.eq_iff, not_true_eq_false] at *
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (

Proof state:
case neg
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
b : β
inst✝¹ : (a' : α) → Decidable (a' = a)
inst✝ : (a' : α) → Decidable (f a' = b)
x y : α
h₁ : ¬x = a
_ : ¬f x = b
h✝¹ : ¬y = a
h✝ : ¬f y = b
h : f x = f y
⊢ x = y

Next tactic:
try simp only [f.injective.eq_iff, not_true_eq_false] at *
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (try 

Proof state:
case neg
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
b : β
inst✝¹ : (a' : α) → Decidable (a' = a)
inst✝ : (a' : α) → Decidable (f a' = b)
x y : α
h₁ : ¬x = a
_ : ¬f x = b
h✝¹ : ¬y = a
h✝ : ¬f y = b
h : f x = f y
⊢ x = y

Next tactic:
simp only [f.injective.eq_iff, not_true_eq_false] at *
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (try simp only [f.injective.eq_iff, not_true_eq_false] at *)
    · 

Proof state:
case pos
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
b : β
inst✝¹ : (a' : α) → Decidable (a' = a)
inst✝ : (a' : α) → Decidable (f a' = b)
x y : α
h₁ : x = a
h₂ : y = a
h : True
⊢ x = y

Next tactic:
rw[h₁,h₂]
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (try simp only [f.injective.eq_iff, not_true_eq_false] at *)
    · rw[h₁,h₂]
    · 

Proof state:
case pos
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
inst✝¹ : (a' : α) → Decidable (a' = a)
x y : α
h₁ : x = a
h₂ : ¬y = a
inst✝ : (a' : α) → Decidable (f a' = f y)
h : y = a
⊢ x = y

Next tactic:
rw[h₁,h]
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (try simp only [f.injective.eq_iff, not_true_eq_false] at *)
    · rw[h₁,h₂]
    · rw[h₁,h]
    · 

Proof state:
case pos
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
inst✝¹ : (a' : α) → Decidable (a' = a)
x y : α
h₁ : ¬x = a
h₅ : y = a
inst✝ : (a' : α) → Decidable (f a' = f x)
h : a = x
⊢ x = y

Next tactic:
rw[h₅, ← h]
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (try simp only [f.injective.eq_iff, not_true_eq_false] at *)
    · rw[h₁,h₂]
    · rw[h₁,h]
    · rw[h₅, ← h]
    · 

Proof state:
case pos
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
inst✝¹ : (a' : α) → Decidable (a' = a)
x y : α
h₁ : ¬x = a
h₅ : ¬y = a
inst✝ : (a' : α) → Decidable (f a' = f x)
h : True
h₆ : y = x
⊢ x = y

Next tactic:
exact h₆.symm
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (try simp only [f.injective.eq_iff, not_true_eq_false] at *)
    · rw[h₁,h₂]
    · rw[h₁,h]
    · rw[h₅, ← h]
    · exact h₆.symm
    · 

Proof state:
case neg
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
inst✝¹ : (a' : α) → Decidable (a' = a)
x y : α
h₁ : ¬x = a
h₅ : ¬y = a
inst✝ : (a' : α) → Decidable (f a' = f x)
h : a = y
h₆ : ¬y = x
⊢ x = y

Next tactic:
exfalso
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (try simp only [f.injective.eq_iff, not_true_eq_false] at *)
    · rw[h₁,h₂]
    · rw[h₁,h]
    · rw[h₅, ← h]
    · exact h₆.symm
    · exfalso; 

Proof state:
case neg.h
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
inst✝¹ : (a' : α) → Decidable (a' = a)
x y : α
h₁ : ¬x = a
h₅ : ¬y = a
inst✝ : (a' : α) → Decidable (f a' = f x)
h : a = y
h₆ : ¬y = x
⊢ False

Next tactic:
exact h₅ h.symm
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (try simp only [f.injective.eq_iff, not_true_eq_false] at *)
    · rw[h₁,h₂]
    · rw[h₁,h]
    · rw[h₅, ← h]
    · exact h₆.symm
    · exfalso; exact h₅ h.symm
    · 

Proof state:
case pos
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
inst✝¹ : (a' : α) → Decidable (a' = a)
x y : α
h₁ : ¬x = a
h✝ : ¬y = a
inst✝ : (a' : α) → Decidable (f a' = f y)
h : x = a
_ : ¬x = y
⊢ x = y

Next tactic:
exfalso
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (try simp only [f.injective.eq_iff, not_true_eq_false] at *)
    · rw[h₁,h₂]
    · rw[h₁,h]
    · rw[h₅, ← h]
    · exact h₆.symm
    · exfalso; exact h₅ h.symm
    · exfalso; 

Proof state:
case pos.h
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
inst✝¹ : (a' : α) → Decidable (a' = a)
x y : α
h₁ : ¬x = a
h✝ : ¬y = a
inst✝ : (a' : α) → Decidable (f a' = f y)
h : x = a
_ : ¬x = y
⊢ False

Next tactic:
exact h₁ h
/-- Change the value of an embedding `f` at one point. If the prescribed image
is already occupied by some `f a'`, then swap the values at these two points. -/
def setValue {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : α ↪ β :=
  ⟨fun a' => if a' = a then b else if f a' = b then f a else f a', by
    intro x y (h : ite _ _ _ = ite _ _ _)
    -- TODO: once we have `cc` we can avoid all the manual cases below by doing
    -- split_ifs at h <;> (try subst b) <;> (try simp only [f.injective.eq_iff] at *) <;> cc
    split_ifs at h with h₁ h₂ _ _ h₅ h₆ <;>
        (try subst b) <;>
        (try simp only [f.injective.eq_iff, not_true_eq_false] at *)
    · rw[h₁,h₂]
    · rw[h₁,h]
    · rw[h₅, ← h]
    · exact h₆.symm
    · exfalso; exact h₅ h.symm
    · exfalso; exact h₁ h
    · 

Proof state:
case neg
α : Sort ?u.14158
β : Sort ?u.14159
f : α ↪ β
a : α
b : β
inst✝¹ : (a' : α) → Decidable (a' = a)
inst✝ : (a' : α) → Decidable (f a' = b)
x y : α
h₁ : ¬x = a
_ : ¬f x = b
h✝¹ : ¬y = a
h✝ : ¬f y = b
h : x = y
⊢ x = y

Next tactic:
exact h
theorem setValue_eq {α β} (f : α ↪ β) (a : α) (b : β) [∀ a', Decidable (a' = a)]
    [∀ a', Decidable (f a' = b)] : setValue f a b a = b := by
  

Proof state:
α : Sort u_1
β : Sort u_2
f : α ↪ β
a : α
b : β
inst✝¹ : (a' : α) → Decidable (a' = a)
inst✝ : (a' : α) → Decidable (f a' = b)
⊢ (setValue f a b) a = b

Next tactic:
simp [setValue]
/-- Choosing an element `b : β` gives an embedding of `PUnit` into `β`. -/
def punit {β : Sort*} (b : β) : PUnit ↪ β :=
  ⟨fun _ => b, by
    

Proof state:
β : Sort u_1
b : β
⊢ Injective fun x => b

Next tactic:
rintro ⟨⟩ ⟨⟩ _
/-- Choosing an element `b : β` gives an embedding of `PUnit` into `β`. -/
def punit {β : Sort*} (b : β) : PUnit ↪ β :=
  ⟨fun _ => b, by
    rintro ⟨⟩ ⟨⟩ _
    

Proof state:
case unit.unit
β : Sort u_1
b : β
a✝ : (fun x => b) PUnit.unit = (fun x => b) PUnit.unit
⊢ PUnit.unit = PUnit.unit

Next tactic:
rfl
/-- An embedding `e : α ↪ β` defines an embedding `(α → γ) ↪ (β → γ)` for any inhabited type `γ`.
This embedding sends each `f : α → γ` to a function `g : β → γ` such that `g ∘ e = f` and
`g y = default` whenever `y ∉ range e`. -/
noncomputable def arrowCongrLeft {α : Sort u} {β : Sort v} {γ : Sort w} [Inhabited γ] (e : α ↪ β) :
    (α → γ) ↪ β → γ :=
  ⟨fun f => extend e f default, fun f₁ f₂ h =>
    funext fun x => by 

Proof state:
α : Sort u
β : Sort v
γ : Sort w
inst✝ : Inhabited γ
e : α ↪ β
f₁ f₂ : α → γ
h : (fun f => extend (⇑e) f default) f₁ = (fun f => extend (⇑e) f default) f₂
x : α
⊢ f₁ x = f₂ x

Next tactic:
simpa only [e.injective.extend_apply] using congr_fun h (e x)
/-- If `α₁ ≃ α₂` and `β₁ ≃ β₂`, then the type of embeddings `α₁ ↪ β₁`
is equivalent to the type of embeddings `α₂ ↪ β₂`. -/
@[simps apply]
def embeddingCongr {α β γ δ : Sort*} (h : α ≃ β) (h' : γ ≃ δ) : (α ↪ γ) ≃ (β ↪ δ) where
  toFun f := f.congr h h'
  invFun f := f.congr h.symm h'.symm
  left_inv x := by
    

Proof state:
α : Sort u_1
β : Sort u_2
γ : Sort u_3
δ : Sort u_4
h : α ≃ β
h' : γ ≃ δ
x : α ↪ γ
⊢ (fun f => Embedding.congr h.symm h'.symm f) ((fun f => Embedding.congr h h' f) x) = x

Next tactic:
ext
/-- If `α₁ ≃ α₂` and `β₁ ≃ β₂`, then the type of embeddings `α₁ ↪ β₁`
is equivalent to the type of embeddings `α₂ ↪ β₂`. -/
@[simps apply]
def embeddingCongr {α β γ δ : Sort*} (h : α ≃ β) (h' : γ ≃ δ) : (α ↪ γ) ≃ (β ↪ δ) where
  toFun f := f.congr h h'
  invFun f := f.congr h.symm h'.symm
  left_inv x := by
    ext
    

Proof state:
case h
α : Sort u_1
β : Sort u_2
γ : Sort u_3
δ : Sort u_4
h : α ≃ β
h' : γ ≃ δ
x : α ↪ γ
x✝ : α
⊢ ((fun f => Embedding.congr h.symm h'.symm f) ((fun f => Embedding.congr h h' f) x)) x✝ = x x✝

Next tactic:
simp
/-- If `α₁ ≃ α₂` and `β₁ ≃ β₂`, then the type of embeddings `α₁ ↪ β₁`
is equivalent to the type of embeddings `α₂ ↪ β₂`. -/
@[simps apply]
def embeddingCongr {α β γ δ : Sort*} (h : α ≃ β) (h' : γ ≃ δ) : (α ↪ γ) ≃ (β ↪ δ) where
  toFun f := f.congr h h'
  invFun f := f.congr h.symm h'.symm
  left_inv x := by
    ext
    simp
  right_inv x := by
    

Proof state:
α : Sort u_1
β : Sort u_2
γ : Sort u_3
δ : Sort u_4
h : α ≃ β
h' : γ ≃ δ
x : β ↪ δ
⊢ (fun f => Embedding.congr h h' f) ((fun f => Embedding.congr h.symm h'.symm f) x) = x

Next tactic:
ext
/-- If `α₁ ≃ α₂` and `β₁ ≃ β₂`, then the type of embeddings `α₁ ↪ β₁`
is equivalent to the type of embeddings `α₂ ↪ β₂`. -/
@[simps apply]
def embeddingCongr {α β γ δ : Sort*} (h : α ≃ β) (h' : γ ≃ δ) : (α ↪ γ) ≃ (β ↪ δ) where
  toFun f := f.congr h h'
  invFun f := f.congr h.symm h'.symm
  left_inv x := by
    ext
    simp
  right_inv x := by
    ext
    

Proof state:
case h
α : Sort u_1
β : Sort u_2
γ : Sort u_3
δ : Sort u_4
h : α ≃ β
h' : γ ≃ δ
x : β ↪ δ
x✝ : β
⊢ ((fun f => Embedding.congr h h' f) ((fun f => Embedding.congr h.symm h'.symm f) x)) x✝ = x x✝

Next tactic:
simp
theorem embeddingCongr_apply_trans {α₁ β₁ γ₁ α₂ β₂ γ₂ : Sort*} (ea : α₁ ≃ α₂) (eb : β₁ ≃ β₂)
    (ec : γ₁ ≃ γ₂) (f : α₁ ↪ β₁) (g : β₁ ↪ γ₁) :
    Equiv.embeddingCongr ea ec (f.trans g) =
      (Equiv.embeddingCongr ea eb f).trans (Equiv.embeddingCongr eb ec g) := by
  

Proof state:
α₁ : Sort u_1
β₁ : Sort u_2
γ₁ : Sort u_3
α₂ : Sort u_4
β₂ : Sort u_5
γ₂ : Sort u_6
ea : α₁ ≃ α₂
eb : β₁ ≃ β₂
ec : γ₁ ≃ γ₂
f : α₁ ↪ β₁
g : β₁ ↪ γ₁
⊢ (embeddingCongr ea ec) (Embedding.trans f g) = Embedding.trans ((embeddingCongr ea eb) f) ((embeddingCongr eb ec) g)

Next tactic:
ext
theorem embeddingCongr_apply_trans {α₁ β₁ γ₁ α₂ β₂ γ₂ : Sort*} (ea : α₁ ≃ α₂) (eb : β₁ ≃ β₂)
    (ec : γ₁ ≃ γ₂) (f : α₁ ↪ β₁) (g : β₁ ↪ γ₁) :
    Equiv.embeddingCongr ea ec (f.trans g) =
      (Equiv.embeddingCongr ea eb f).trans (Equiv.embeddingCongr eb ec g) := by
  ext
  

Proof state:
case h
α₁ : Sort u_1
β₁ : Sort u_2
γ₁ : Sort u_3
α₂ : Sort u_4
β₂ : Sort u_5
γ₂ : Sort u_6
ea : α₁ ≃ α₂
eb : β₁ ≃ β₂
ec : γ₁ ≃ γ₂
f : α₁ ↪ β₁
g : β₁ ↪ γ₁
x✝ : α₂
⊢ ((embeddingCongr ea ec) (Embedding.trans f g)) x✝ =
    (Embedding.trans ((embeddingCongr ea eb) f) ((embeddingCongr eb ec) g)) x✝

Next tactic:
simp
/-- A subtype `{x // p x ∨ q x}` over a disjunction of `p q : α → Prop` can be injectively split
into a sum of subtypes `{x // p x} ⊕ {x // q x}` such that `¬ p x` is sent to the right. -/
def subtypeOrLeftEmbedding (p q : α → Prop) [DecidablePred p] :
    { x // p x ∨ q x } ↪ Sum { x // p x } { x // q x } :=
  ⟨fun x => if h : p x then Sum.inl ⟨x, h⟩ else Sum.inr ⟨x, x.prop.resolve_left h⟩, by
    

Proof state:
α : Type u_1
p q : α → Prop
inst✝ : DecidablePred p
⊢ Function.Injective fun x =>
    if h : p ↑x then Sum.inl { val := ↑x, property := h } else Sum.inr { val := ↑x, property := (_ : q ↑x) }

Next tactic:
intro x y
/-- A subtype `{x // p x ∨ q x}` over a disjunction of `p q : α → Prop` can be injectively split
into a sum of subtypes `{x // p x} ⊕ {x // q x}` such that `¬ p x` is sent to the right. -/
def subtypeOrLeftEmbedding (p q : α → Prop) [DecidablePred p] :
    { x // p x ∨ q x } ↪ Sum { x // p x } { x // q x } :=
  ⟨fun x => if h : p x then Sum.inl ⟨x, h⟩ else Sum.inr ⟨x, x.prop.resolve_left h⟩, by
    intro x y
    

Proof state:
α : Type u_1
p q : α → Prop
inst✝ : DecidablePred p
x y : { x // p x ∨ q x }
⊢ (fun x => if h : p ↑x then Sum.inl { val := ↑x, property := h } else Sum.inr { val := ↑x, property := (_ : q ↑x) })
        x =
      (fun x =>
          if h : p ↑x then Sum.inl { val := ↑x, property := h } else Sum.inr { val := ↑x, property := (_ : q ↑x) })
        y →
    x = y

Next tactic:
dsimp only
/-- A subtype `{x // p x ∨ q x}` over a disjunction of `p q : α → Prop` can be injectively split
into a sum of subtypes `{x // p x} ⊕ {x // q x}` such that `¬ p x` is sent to the right. -/
def subtypeOrLeftEmbedding (p q : α → Prop) [DecidablePred p] :
    { x // p x ∨ q x } ↪ Sum { x // p x } { x // q x } :=
  ⟨fun x => if h : p x then Sum.inl ⟨x, h⟩ else Sum.inr ⟨x, x.prop.resolve_left h⟩, by
    intro x y
    dsimp only
    

Proof state:
α : Type u_1
p q : α → Prop
inst✝ : DecidablePred p
x y : { x // p x ∨ q x }
⊢ ((if h : p ↑x then Sum.inl { val := ↑x, property := h } else Sum.inr { val := ↑x, property := (_ : q ↑x) }) =
      if h : p ↑y then Sum.inl { val := ↑y, property := h } else Sum.inr { val := ↑y, property := (_ : q ↑y) }) →
    x = y

Next tactic:
split_ifs