l3lab/ntp-mathlib huggingface dataset:
@[simp] theorem not_xor (P Q : Prop) : ¬Xor' P Q ↔ (P ↔ Q) := by
  

Proof state:
P Q : Prop
⊢ ¬Xor' P Q ↔ (P ↔ Q)

Next tactic:
simp only [not_and, Xor', not_or, not_not, ← iff_iff_implies_and_implies]
theorem xor_iff_iff_not : Xor' a b ↔ (a ↔ ¬b) := by 

Proof state:
a b : Prop
⊢ Xor' a b ↔ (a ↔ ¬b)

Next tactic:
simp only [← @xor_not_right a, not_not]
theorem xor_iff_not_iff' : Xor' a b ↔ (¬a ↔ b) := by 

Proof state:
a b : Prop
⊢ Xor' a b ↔ (¬a ↔ b)

Next tactic:
simp only [← @xor_not_left _ b, not_not]
theorem cast_eq_iff_heq : cast e a = a' ↔ HEq a a' :=
  ⟨heq_of_cast_eq _, fun h ↦ by 

Proof state:
a✝¹ a✝ : Sort u_1
e : a✝¹ = a✝
a : a✝¹
a' : a✝
h : HEq a a'
⊢ cast e a = a'

Next tactic:
cases h
theorem cast_eq_iff_heq : cast e a = a' ↔ HEq a a' :=
  ⟨heq_of_cast_eq _, fun h ↦ by cases h; 

Proof state:
case refl
a✝ : Sort u_1
a : a✝
e : a✝ = a✝
⊢ cast e a = a

Next tactic:
rfl
theorem Eq.rec_eq_cast {α : Sort _} {P : α → Sort _} {x y : α} (h : x = y) (z : P x) :
    h ▸ z = cast (congr_arg P h) z := by 

Proof state:
α : Sort u_1
P : α → Sort u_2
x y : α
h : x = y
z : P x
⊢ h ▸ z = cast (_ : P x = P y) z

Next tactic:
induction h
theorem Eq.rec_eq_cast {α : Sort _} {P : α → Sort _} {x y : α} (h : x = y) (z : P x) :
    h ▸ z = cast (congr_arg P h) z := by induction h; 

Proof state:
case refl
α : Sort u_1
P : α → Sort u_2
x y : α
z : P x
⊢ (_ : x = x) ▸ z = cast (_ : P x = P x) z

Next tactic:
rfl
theorem eqRec_heq' {α : Sort u_1} {a' : α} {motive : (a : α) → a' = a → Sort u}
    (p : motive a' (rfl : a' = a')) {a : α} (t : a' = a) :
    HEq (@Eq.rec α a' motive p a t) p :=
  by 

Proof state:
α : Sort u_1
a' : α
motive : (a : α) → a' = a → Sort u
p : motive a' (_ : a' = a')
a : α
t : a' = a
⊢ HEq (t ▸ p) p

Next tactic:
subst t
theorem eqRec_heq' {α : Sort u_1} {a' : α} {motive : (a : α) → a' = a → Sort u}
    (p : motive a' (rfl : a' = a')) {a : α} (t : a' = a) :
    HEq (@Eq.rec α a' motive p a t) p :=
  by subst t; 

Proof state:
α : Sort u_1
a' : α
motive : (a : α) → a' = a → Sort u
p : motive a' (_ : a' = a')
⊢ HEq ((_ : a' = a') ▸ p) p

Next tactic:
rfl
theorem rec_heq_of_heq {C : α → Sort*} {x : C a} {y : β} (e : a = b) (h : HEq x y) :
    HEq (e ▸ x) y := by 

Proof state:
α : Sort u_2
a : α
β : Sort u_1
b : α
C : α → Sort u_1
x : C a
y : β
e : a = b
h : HEq x y
⊢ HEq (e ▸ x) y

Next tactic:
subst e
theorem rec_heq_of_heq {C : α → Sort*} {x : C a} {y : β} (e : a = b) (h : HEq x y) :
    HEq (e ▸ x) y := by subst e; 

Proof state:
α : Sort u_2
a : α
β : Sort u_1
C : α → Sort u_1
x : C a
y : β
h : HEq x y
⊢ HEq ((_ : a = a) ▸ x) y

Next tactic:
exact h
theorem rec_heq_iff_heq {C : α → Sort*} {x : C a} {y : β} {e : a = b} :
    HEq (e ▸ x) y ↔ HEq x y := by 

Proof state:
α : Sort u_2
a : α
β : Sort u_1
b : α
C : α → Sort u_1
x : C a
y : β
e : a = b
⊢ HEq (e ▸ x) y ↔ HEq x y

Next tactic:
subst e
theorem rec_heq_iff_heq {C : α → Sort*} {x : C a} {y : β} {e : a = b} :
    HEq (e ▸ x) y ↔ HEq x y := by subst e; 

Proof state:
α : Sort u_2
a : α
β : Sort u_1
C : α → Sort u_1
x : C a
y : β
⊢ HEq ((_ : a = a) ▸ x) y ↔ HEq x y

Next tactic:
rfl
theorem heq_rec_iff_heq {C : α → Sort*} {x : β} {y : C a} {e : a = b} :
    HEq x (e ▸ y) ↔ HEq x y := by 

Proof state:
α : Sort u_2
β : Sort u_1
a b : α
C : α → Sort u_1
x : β
y : C a
e : a = b
⊢ HEq x (e ▸ y) ↔ HEq x y

Next tactic:
subst e
theorem heq_rec_iff_heq {C : α → Sort*} {x : β} {y : C a} {e : a = b} :
    HEq x (e ▸ y) ↔ HEq x y := by subst e; 

Proof state:
α : Sort u_2
β : Sort u_1
a : α
C : α → Sort u_1
x : β
y : C a
⊢ HEq x ((_ : a = a) ▸ y) ↔ HEq x y

Next tactic:
rfl
protected theorem Eq.congr (h₁ : x₁ = y₁) (h₂ : x₂ = y₂) : x₁ = x₂ ↔ y₁ = y₂ := by
  

Proof state:
α✝ : Sort u_1
x₁ y₁ x₂ y₂ : α✝
h₁ : x₁ = y₁
h₂ : x₂ = y₂
⊢ x₁ = x₂ ↔ y₁ = y₂

Next tactic:
subst h₁
protected theorem Eq.congr (h₁ : x₁ = y₁) (h₂ : x₂ = y₂) : x₁ = x₂ ↔ y₁ = y₂ := by
  subst h₁; 

Proof state:
α✝ : Sort u_1
x₁ x₂ y₂ : α✝
h₂ : x₂ = y₂
⊢ x₁ = x₂ ↔ x₁ = y₂

Next tactic:
subst h₂
protected theorem Eq.congr (h₁ : x₁ = y₁) (h₂ : x₂ = y₂) : x₁ = x₂ ↔ y₁ = y₂ := by
  subst h₁; subst h₂; 

Proof state:
α✝ : Sort u_1
x₁ x₂ : α✝
⊢ x₁ = x₂ ↔ x₁ = x₂

Next tactic:
rfl
theorem Eq.congr_left {x y z : α} (h : x = y) : x = z ↔ y = z := by 

Proof state:
α : Sort u_1
x y z : α
h : x = y
⊢ x = z ↔ y = z

Next tactic:
rw [h]
theorem Eq.congr_right {x y z : α} (h : x = y) : z = x ↔ z = y := by 

Proof state:
α : Sort u_1
x y z : α
h : x = y
⊢ z = x ↔ z = y

Next tactic:
rw [h]
lemma forall_or_exists_not (P : α → Prop) : (∀ a, P a) ∨ ∃ a, ¬ P a := by
  

Proof state:
ι : Sort ?u.13170
α : Sort u_2
κ : ι → Sort u_1
p q P : α → Prop
⊢ (∀ (a : α), P a) ∨ ∃ a, ¬P a

Next tactic:
rw [← not_forall]
lemma forall_or_exists_not (P : α → Prop) : (∀ a, P a) ∨ ∃ a, ¬ P a := by
  rw [← not_forall]; 

Proof state:
ι : Sort ?u.13170
α : Sort u_2
κ : ι → Sort u_1
p q P : α → Prop
⊢ (∀ (a : α), P a) ∨ ¬∀ (x : α), P x

Next tactic:
exact em _
lemma exists_or_forall_not (P : α → Prop) : (∃ a, P a) ∨ ∀ a, ¬ P a := by
  

Proof state:
ι : Sort ?u.13245
α : Sort u_2
κ : ι → Sort u_1
p q P : α → Prop
⊢ (∃ a, P a) ∨ ∀ (a : α), ¬P a

Next tactic:
rw [← not_exists]
lemma exists_or_forall_not (P : α → Prop) : (∃ a, P a) ∨ ∀ a, ¬ P a := by
  rw [← not_exists]; 

Proof state:
ι : Sort ?u.13245
α : Sort u_2
κ : ι → Sort u_1
p q P : α → Prop
⊢ (∃ a, P a) ∨ ¬∃ x, P x

Next tactic:
exact em _
theorem forall_imp_iff_exists_imp [ha : Nonempty α] : (∀ x, p x) → b ↔ ∃ x, p x → b := by
  

Proof state:
ι : Sort ?u.13317
α : Sort u_2
κ : ι → Sort u_1
p q : α → Prop
b : Prop
ha : Nonempty α
⊢ (∀ (x : α), p x) → b ↔ ∃ x, p x → b

Next tactic:
let ⟨a⟩ := ha
theorem forall_imp_iff_exists_imp [ha : Nonempty α] : (∀ x, p x) → b ↔ ∃ x, p x → b := by
  let ⟨a⟩ := ha
  

Proof state:
ι : Sort ?u.13317
α : Sort u_2
κ : ι → Sort u_1
p q : α → Prop
b : Prop
ha : Nonempty α
a : α
⊢ (∀ (x : α), p x) → b ↔ ∃ x, p x → b

Next tactic:
refine ⟨fun h ↦ not_forall_not.1 fun h' ↦ ?_, fun ⟨x, hx⟩ h ↦ hx (h x)⟩
theorem forall_imp_iff_exists_imp [ha : Nonempty α] : (∀ x, p x) → b ↔ ∃ x, p x → b := by
  let ⟨a⟩ := ha
  refine ⟨fun h ↦ not_forall_not.1 fun h' ↦ ?_, fun ⟨x, hx⟩ h ↦ hx (h x)⟩
  

Proof state:
ι : Sort ?u.13317
α : Sort u_2
κ : ι → Sort u_1
p q : α → Prop
b : Prop
ha : Nonempty α
a : α
h : (∀ (x : α), p x) → b
h' : ∀ (x : α), ¬(p x → b)
⊢ False

Next tactic:
exact if hb : b then h' a fun _ ↦ hb else hb <| h fun x ↦ (not_imp.1 (h' x)).1
theorem forall₂_true_iff {β : α → Sort*} : (∀ a, β a → True) ↔ True := by 

Proof state:
ι : Sort ?u.13744
α : Sort ?u.13749
κ : ι → Sort u_1
p q : α → Prop
β : α → Sort u_2
⊢ (∀ (a : α), β a → True) ↔ True

Next tactic:
simp
theorem forall₃_true_iff {β : α → Sort*} {γ : ∀ a, β a → Sort*} :
    (∀ (a) (b : β a), γ a b → True) ↔ True := by 

Proof state:
ι : Sort ?u.14012
α : Sort ?u.14017
κ : ι → Sort u_1
p q : α → Prop
β : α → Sort u_2
γ : (a : α) → β a → Sort u_3
⊢ (∀ (a : α) (b : β a), γ a b → True) ↔ True

Next tactic:
simp
theorem exists_unique_const (α) [i : Nonempty α] [Subsingleton α] :
    (∃! _ : α, b) ↔ b := by 

Proof state:
ι : Sort ?u.14553
α✝ : Sort ?u.14558
κ : ι → Sort u_1
p q : α✝ → Prop
b : Prop
α : Sort u_2
i : Nonempty α
inst✝ : Subsingleton α
⊢ (∃! x, b) ↔ b

Next tactic:
simp
theorem Decidable.and_forall_ne [DecidableEq α] (a : α) {p : α → Prop} :
    (p a ∧ ∀ b, b ≠ a → p b) ↔ ∀ b, p b := by
  

Proof state:
ι : Sort ?u.14759
α : Sort u_2
κ : ι → Sort u_1
p✝ q : α → Prop
inst✝ : DecidableEq α
a : α
p : α → Prop
⊢ (p a ∧ ∀ (b : α), b ≠ a → p b) ↔ ∀ (b : α), p b

Next tactic:
simp only [← @forall_eq _ p a, ← forall_and, ← or_imp, Decidable.em, forall_const]
@[simp] theorem exists_unique_eq {a' : α} : ∃! a, a = a' := by
  

Proof state:
ι : Sort ?u.15332
α : Sort u_2
κ : ι → Sort u_1
p q : α → Prop
a' : α
⊢ ∃! a, a = a'

Next tactic:
simp only [eq_comm, ExistsUnique, and_self, forall_eq', exists_eq']
@[simp] theorem exists_unique_eq' {a' : α} : ∃! a, a' = a := by
  

Proof state:
ι : Sort ?u.15700
α : Sort u_2
κ : ι → Sort u_1
p q : α → Prop
a' : α
⊢ ∃! a, a' = a

Next tactic:
simp only [ExistsUnique, and_self, forall_eq', exists_eq']
theorem forall_apply_eq_imp_iff' {f : α → β} {p : β → Prop} :
    (∀ a b, f a = b → p b) ↔ ∀ a, p (f a) := by 

Proof state:
ι : Sort ?u.18410
α : Sort ?u.18415
κ : ι → Sort u_1
p✝ q : α → Prop
β : Sort u_2
f : α → β
p : β → Prop
⊢ (∀ (a : α) (b : β), f a = b → p b) ↔ ∀ (a : α), p (f a)

Next tactic:
simp
theorem forall_eq_apply_imp_iff' {f : α → β} {p : β → Prop} :
    (∀ a b, b = f a → p b) ↔ ∀ a, p (f a) := by 

Proof state:
ι : Sort ?u.18845
α : Sort ?u.18850
κ : ι → Sort u_1
p✝ q : α → Prop
β : Sort u_2
f : α → β
p : β → Prop
⊢ (∀ (a : α) (b : β), b = f a → p b) ↔ ∀ (a : α), p (f a)

Next tactic:
simp
@[simp] theorem exists_eq_right' {a' : α} : (∃ a, p a ∧ a' = a) ↔ p a' := by 

Proof state:
ι : Sort ?u.19274
α : Sort u_2
κ : ι → Sort u_1
p q : α → Prop
a' : α
⊢ (∃ a, p a ∧ a' = a) ↔ p a'

Next tactic:
simp [@eq_comm _ a']
theorem exists₂_comm {κ₁ : ι₁ → Sort*} {κ₂ : ι₂ → Sort*} {p : ∀ i₁, κ₁ i₁ → ∀ i₂, κ₂ i₂ → Prop} :
    (∃ i₁ j₁ i₂ j₂, p i₁ j₁ i₂ j₂) ↔ ∃ i₂ j₂ i₁ j₁, p i₁ j₁ i₂ j₂ := by
  

Proof state:
ι : Sort ?u.19636
α : Sort ?u.19641
κ : ι → Sort u_1
p✝ q : α → Prop
ι₁ : Sort u_4
ι₂ : Sort u_5
κ₁ : ι₁ → Sort u_2
κ₂ : ι₂ → Sort u_3
p : (i₁ : ι₁) → κ₁ i₁ → (i₂ : ι₂) → κ₂ i₂ → Prop
⊢ (∃ i₁ j₁ i₂ j₂, p i₁ j₁ i₂ j₂) ↔ ∃ i₂ j₂ i₁ j₁, p i₁ j₁ i₂ j₂

Next tactic:
simp only [@exists_comm (κ₁ _), @exists_comm ι₁]
protected theorem Decidable.forall_or_right {q} {p : α → Prop} [Decidable q] :
    (∀ x, p x ∨ q) ↔ (∀ x, p x) ∨ q := by 

Proof state:
ι : Sort ?u.20779
α : Sort ?u.20784
κ : ι → Sort u_1
p✝ q✝ : α → Prop
q : Prop
p : α → Prop
inst✝ : Decidable q
⊢ (∀ (x : α), p x ∨ q) ↔ (∀ (x : α), p x) ∨ q

Next tactic:
simp [or_comm, Decidable.forall_or_left]
theorem exists_unique_prop {p q : Prop} : (∃! _ : p, q) ↔ p ∧ q := by 

Proof state:
ι : Sort ?u.21186
α : Sort ?u.21191
κ : ι → Sort u_1
p✝ q✝ : α → Prop
p q : Prop
⊢ (∃! x, q) ↔ p ∧ q

Next tactic:
simp
theorem Prop.exists_iff {p : Prop → Prop} : (∃ h, p h) ↔ p False ∨ p True :=
  ⟨fun ⟨h₁, h₂⟩ ↦ by_cases (fun H : h₁ ↦ .inr <| by 

Proof state:
ι : Sort ?u.22019
α : Sort ?u.22024
κ : ι → Sort u_1
p✝ q : α → Prop
p : Prop → Prop
x✝ : ∃ h, p h
h₁ : Prop
h₂ : p h₁
H : h₁
⊢ p True

Next tactic:
simpa only [H] using h₂
theorem Prop.exists_iff {p : Prop → Prop} : (∃ h, p h) ↔ p False ∨ p True :=
  ⟨fun ⟨h₁, h₂⟩ ↦ by_cases (fun H : h₁ ↦ .inr <| by simpa only [H] using h₂)
    (fun H ↦ .inl <| by 

Proof state:
ι : Sort ?u.22019
α : Sort ?u.22024
κ : ι → Sort u_1
p✝ q : α → Prop
p : Prop → Prop
x✝ : ∃ h, p h
h₁ : Prop
h₂ : p h₁
H : ¬h₁
⊢ p False

Next tactic:
simpa only [H] using h₂
theorem Prop.forall_iff {p : Prop → Prop} : (∀ h, p h) ↔ p False ∧ p True :=
  ⟨fun H ↦ ⟨H _, H _⟩, fun ⟨h₁, h₂⟩ h ↦ by 

Proof state:
ι : Sort ?u.22278
α : Sort ?u.22283
κ : ι → Sort u_1
p✝ q : α → Prop
p : Prop → Prop
x✝ : p False ∧ p True
h : Prop
h₁ : p False
h₂ : p True
⊢ p h

Next tactic:
by_cases H : h
theorem Prop.forall_iff {p : Prop → Prop} : (∀ h, p h) ↔ p False ∧ p True :=
  ⟨fun H ↦ ⟨H _, H _⟩, fun ⟨h₁, h₂⟩ h ↦ by by_cases H : h <;> 

Proof state:
case pos
ι : Sort ?u.22278
α : Sort ?u.22283
κ : ι → Sort u_1
p✝ q : α → Prop
p : Prop → Prop
x✝ : p False ∧ p True
h : Prop
h₁ : p False
h₂ : p True
H : h
⊢ p h

Next tactic:
simpa only [H]
theorem Prop.forall_iff {p : Prop → Prop} : (∀ h, p h) ↔ p False ∧ p True :=
  ⟨fun H ↦ ⟨H _, H _⟩, fun ⟨h₁, h₂⟩ h ↦ by by_cases H : h <;> 

Proof state:
case neg
ι : Sort ?u.22278
α : Sort ?u.22283
κ : ι → Sort u_1
p✝ q : α → Prop
p : Prop → Prop
x✝ : p False ∧ p True
h : Prop
h₁ : p False
h₂ : p True
H : ¬h
⊢ p h

Next tactic:
simpa only [H]
theorem ExistsUnique.elim₂ {α : Sort*} {p : α → Sort*} [∀ x, Subsingleton (p x)]
    {q : ∀ (x) (_ : p x), Prop} {b : Prop} (h₂ : ∃! (x : _) (h : p x), q x h)
    (h₁ : ∀ (x) (h : p x), q x h → (∀ (y) (hy : p y), q y hy → y = x) → b) : b := by
  

Proof state:
ι : Sort ?u.23516
α✝ : Sort ?u.23521
κ : ι → Sort u_1
p✝ q✝ : α✝ → Prop
α : Sort u_2
p : α → Sort u_3
inst✝ : ∀ (x : α), Subsingleton (p x)
q : (x : α) → p x → Prop
b : Prop
h₂ : ∃! x h, q x h
h₁ : ∀ (x : α) (h : p x), q x h → (∀ (y : α) (hy : p y), q y hy → y = x) → b
⊢ b

Next tactic:
simp only [exists_unique_iff_exists] at h₂
theorem ExistsUnique.elim₂ {α : Sort*} {p : α → Sort*} [∀ x, Subsingleton (p x)]
    {q : ∀ (x) (_ : p x), Prop} {b : Prop} (h₂ : ∃! (x : _) (h : p x), q x h)
    (h₁ : ∀ (x) (h : p x), q x h → (∀ (y) (hy : p y), q y hy → y = x) → b) : b := by
  simp only [exists_unique_iff_exists] at h₂
  

Proof state:
ι : Sort ?u.23516
α✝ : Sort ?u.23521
κ : ι → Sort u_1
p✝ q✝ : α✝ → Prop
α : Sort u_2
p : α → Sort u_3
inst✝ : ∀ (x : α), Subsingleton (p x)
q : (x : α) → p x → Prop
b : Prop
h₁ : ∀ (x : α) (h : p x), q x h → (∀ (y : α) (hy : p y), q y hy → y = x) → b
h₂ : ∃! x, ∃ h, q x h
⊢ b

Next tactic:
apply h₂.elim
theorem ExistsUnique.elim₂ {α : Sort*} {p : α → Sort*} [∀ x, Subsingleton (p x)]
    {q : ∀ (x) (_ : p x), Prop} {b : Prop} (h₂ : ∃! (x : _) (h : p x), q x h)
    (h₁ : ∀ (x) (h : p x), q x h → (∀ (y) (hy : p y), q y hy → y = x) → b) : b := by
  simp only [exists_unique_iff_exists] at h₂
  apply h₂.elim
  

Proof state:
ι : Sort ?u.23516
α✝ : Sort ?u.23521
κ : ι → Sort u_1
p✝ q✝ : α✝ → Prop
α : Sort u_2
p : α → Sort u_3
inst✝ : ∀ (x : α), Subsingleton (p x)
q : (x : α) → p x → Prop
b : Prop
h₁ : ∀ (x : α) (h : p x), q x h → (∀ (y : α) (hy : p y), q y hy → y = x) → b
h₂ : ∃! x, ∃ h, q x h
⊢ ∀ (x : α), (∃ h, q x h) → (∀ (y : α), (∃ h, q y h) → y = x) → b

Next tactic:
exact fun x ⟨hxp, hxq⟩ H ↦ h₁ x hxp hxq fun y hyp hyq ↦ H y ⟨hyp, hyq⟩
theorem ExistsUnique.intro₂ {α : Sort*} {p : α → Sort*} [∀ x, Subsingleton (p x)]
    {q : ∀ (x : α) (_ : p x), Prop} (w : α) (hp : p w) (hq : q w hp)
    (H : ∀ (y) (hy : p y), q y hy → y = w) : ∃! (x : _) (hx : p x), q x hx := by
  

Proof state:
ι : Sort ?u.23929
α✝ : Sort ?u.23934
κ : ι → Sort u_1
p✝ q✝ : α✝ → Prop
α : Sort u_2
p : α → Sort u_3
inst✝ : ∀ (x : α), Subsingleton (p x)
q : (x : α) → p x → Prop
w : α
hp : p w
hq : q w hp
H : ∀ (y : α) (hy : p y), q y hy → y = w
⊢ ∃! x hx, q x hx

Next tactic:
simp only [exists_unique_iff_exists]
theorem ExistsUnique.intro₂ {α : Sort*} {p : α → Sort*} [∀ x, Subsingleton (p x)]
    {q : ∀ (x : α) (_ : p x), Prop} (w : α) (hp : p w) (hq : q w hp)
    (H : ∀ (y) (hy : p y), q y hy → y = w) : ∃! (x : _) (hx : p x), q x hx := by
  simp only [exists_unique_iff_exists]
  

Proof state:
ι : Sort ?u.23929
α✝ : Sort ?u.23934
κ : ι → Sort u_1
p✝ q✝ : α✝ → Prop
α : Sort u_2
p : α → Sort u_3
inst✝ : ∀ (x : α), Subsingleton (p x)
q : (x : α) → p x → Prop
w : α
hp : p w
hq : q w hp
H : ∀ (y : α) (hy : p y), q y hy → y = w
⊢ ∃! x, ∃ hx, q x hx

Next tactic:
exact ExistsUnique.intro w ⟨hp, hq⟩ fun y ⟨hyp, hyq⟩ ↦ H y hyp hyq
theorem ExistsUnique.unique₂ {α : Sort*} {p : α → Sort*} [∀ x, Subsingleton (p x)]
    {q : ∀ (x : α) (_ : p x), Prop} (h : ∃! (x : _) (hx : p x), q x hx) {y₁ y₂ : α}
    (hpy₁ : p y₁) (hqy₁ : q y₁ hpy₁) (hpy₂ : p y₂) (hqy₂ : q y₂ hpy₂) : y₁ = y₂ := by
  

Proof state:
ι : Sort ?u.24428
α✝ : Sort ?u.24433
κ : ι → Sort u_1
p✝ q✝ : α✝ → Prop
α : Sort u_2
p : α → Sort u_3
inst✝ : ∀ (x : α), Subsingleton (p x)
q : (x : α) → p x → Prop
h : ∃! x hx, q x hx
y₁ y₂ : α
hpy₁ : p y₁
hqy₁ : q y₁ hpy₁
hpy₂ : p y₂
hqy₂ : q y₂ hpy₂
⊢ y₁ = y₂

Next tactic:
simp only [exists_unique_iff_exists] at h
theorem ExistsUnique.unique₂ {α : Sort*} {p : α → Sort*} [∀ x, Subsingleton (p x)]
    {q : ∀ (x : α) (_ : p x), Prop} (h : ∃! (x : _) (hx : p x), q x hx) {y₁ y₂ : α}
    (hpy₁ : p y₁) (hqy₁ : q y₁ hpy₁) (hpy₂ : p y₂) (hqy₂ : q y₂ hpy₂) : y₁ = y₂ := by
  simp only [exists_unique_iff_exists] at h
  

Proof state:
ι : Sort ?u.24428
α✝ : Sort ?u.24433
κ : ι → Sort u_1
p✝ q✝ : α✝ → Prop
α : Sort u_2
p : α → Sort u_3
inst✝ : ∀ (x : α), Subsingleton (p x)
q : (x : α) → p x → Prop
y₁ y₂ : α
hpy₁ : p y₁
hqy₁ : q y₁ hpy₁
hpy₂ : p y₂
hqy₂ : q y₂ hpy₂
h : ∃! x, ∃ hx, q x hx
⊢ y₁ = y₂

Next tactic:
exact h.unique ⟨hpy₁, hqy₁⟩ ⟨hpy₂, hqy₂⟩
/-- Any prop `p` is decidable classically. A shorthand for `Classical.propDecidable`. -/
noncomputable def dec (p : Prop) : Decidable p := by 

Proof state:
α : Sort ?u.24723
p✝ : α → Prop
p : Prop
⊢ Decidable p

Next tactic:
infer_instance
/-- Any predicate `p` is decidable classically. -/
noncomputable def decPred (p : α → Prop) : DecidablePred p := by 

Proof state:
α : Sort ?u.24747
p✝ p : α → Prop
⊢ DecidablePred p

Next tactic:
infer_instance
/-- Any relation `p` is decidable classically. -/
noncomputable def decRel (p : α → α → Prop) : DecidableRel p := by 

Proof state:
α : Sort ?u.24791
p✝ : α → Prop
p : α → α → Prop
⊢ DecidableRel p

Next tactic:
infer_instance
/-- Any type `α` has decidable equality classically. -/
noncomputable def decEq (α : Sort u) : DecidableEq α := by 

Proof state:
α✝ : Sort ?u.24850
p : α✝ → Prop
α : Sort u
⊢ DecidableEq α

Next tactic:
infer_instance
theorem bex_eq_left {a : α} : (∃ (x : _) (_ : x = a), p x) ↔ p a := by
  

Proof state:
α : Sort u_1
r p q : α → Prop
P Q : (x : α) → p x → Prop
b : Prop
a : α
⊢ (∃ x x_1, p x) ↔ p a

Next tactic:
simp only [exists_prop, exists_eq_left]
theorem bex_imp : (∃ x h, P x h) → b ↔ ∀ x h, P x h → b := by 

Proof state:
α : Sort u_1
r p q : α → Prop
P Q : (x : α) → p x → Prop
b : Prop
⊢ (∃ x h, P x h) → b ↔ ∀ (x : α) (h : p x), P x h → b

Next tactic:
simp
theorem bex_or_left :
    (∃ (x : _) (_ : p x ∨ q x), r x) ↔ (∃ (x : _) (_ : p x), r x) ∨ ∃ (x : _) (_ : q x), r x := by
  

Proof state:
α : Sort u_1
r p q : α → Prop
P Q : (x : α) → p x → Prop
b : Prop
⊢ (∃ x x_1, r x) ↔ (∃ x x_1, r x) ∨ ∃ x x_1, r x

Next tactic:
simp only [exists_prop]
theorem bex_or_left :
    (∃ (x : _) (_ : p x ∨ q x), r x) ↔ (∃ (x : _) (_ : p x), r x) ∨ ∃ (x : _) (_ : q x), r x := by
  simp only [exists_prop]
  

Proof state:
α : Sort u_1
r p q : α → Prop
P Q : (x : α) → p x → Prop
b : Prop
⊢ (∃ x, (p x ∨ q x) ∧ r x) ↔ (∃ x, p x ∧ r x) ∨ ∃ x, q x ∧ r x

Next tactic:
exact Iff.trans (exists_congr fun x ↦ or_and_right) exists_or
theorem dite_eq_iff : dite P A B = c ↔ (∃ h, A h = c) ∨ ∃ h, B h = c := by
  

Proof state:
α : Sort u_2
β : Sort ?u.30821
σ : α → Sort u_1
f : α → β
P Q : Prop
inst✝¹ : Decidable P
inst✝ : Decidable Q
a b c : α
A : P → α
B : ¬P → α
⊢ dite P A B = c ↔ (∃ h, A h = c) ∨ ∃ h, B h = c

Next tactic:
by_cases P
theorem dite_eq_iff : dite P A B = c ↔ (∃ h, A h = c) ∨ ∃ h, B h = c := by
  by_cases P <;> 

Proof state:
case pos
α : Sort u_2
β : Sort ?u.30821
σ : α → Sort u_1
f : α → β
P Q : Prop
inst✝¹ : Decidable P
inst✝ : Decidable Q
a b c : α
A : P → α
B : ¬P → α
h✝ : P
⊢ dite P A B = c ↔ (∃ h, A h = c) ∨ ∃ h, B h = c

Next tactic:
simp [*, exists_prop_of_true, exists_prop_of_false]
theorem dite_eq_iff : dite P A B = c ↔ (∃ h, A h = c) ∨ ∃ h, B h = c := by
  by_cases P <;> 

Proof state:
case neg
α : Sort u_2
β : Sort ?u.30821
σ : α → Sort u_1
f : α → β
P Q : Prop
inst✝¹ : Decidable P
inst✝ : Decidable Q
a b c : α
A : P → α
B : ¬P → α
h✝ : ¬P
⊢ dite P A B = c ↔ (∃ h, A h = c) ∨ ∃ h, B h = c

Next tactic:
simp [*, exists_prop_of_true, exists_prop_of_false]
theorem ite_eq_iff : ite P a b = c ↔ P ∧ a = c ∨ ¬P ∧ b = c :=
  dite_eq_iff.trans <| by 

Proof state:
α : Sort u_2
β : Sort ?u.31326
σ : α → Sort u_1
f : α → β
P Q : Prop
inst✝¹ : Decidable P
inst✝ : Decidable Q
a b c : α
A : P → α
B : ¬P → α
⊢ ((∃ h, (fun x => a) h = c) ∨ ∃ h, (fun x => b) h = c) ↔ P ∧ a = c ∨ ¬P ∧ b = c

Next tactic:
simp only
theorem ite_eq_iff : ite P a b = c ↔ P ∧ a = c ∨ ¬P ∧ b = c :=
  dite_eq_iff.trans <| by simp only; 

Proof state:
α : Sort u_2
β : Sort ?u.31326
σ : α → Sort u_1
f : α → β
P Q : Prop
inst✝¹ : Decidable P
inst✝ : Decidable Q
a b c : α
A : P → α
B : ¬P → α
⊢ ((∃ h, a = c) ∨ ∃ h, b = c) ↔ P ∧ a = c ∨ ¬P ∧ b = c

Next tactic:
rw [exists_prop, exists_prop]
theorem dite_ne_left_iff : dite P (fun _ ↦ a) B ≠ a ↔ ∃ h, a ≠ B h := by
  

Proof state:
α : Sort u_2
β : Sort ?u.32339
σ : α → Sort u_1
f : α → β
P Q : Prop
inst✝¹ : Decidable P
inst✝ : Decidable Q
a b c : α
A : P → α
B : ¬P → α
⊢ dite P (fun x => a) B ≠ a ↔ ∃ h, a ≠ B h

Next tactic:
rw [Ne.def, dite_eq_left_iff, not_forall]
theorem dite_ne_left_iff : dite P (fun _ ↦ a) B ≠ a ↔ ∃ h, a ≠ B h := by
  rw [Ne.def, dite_eq_left_iff, not_forall]
  

Proof state:
α : Sort u_2
β : Sort ?u.32339
σ : α → Sort u_1
f : α → β
P Q : Prop
inst✝¹ : Decidable P
inst✝ : Decidable Q
a b c : α
A : P → α
B : ¬P → α
⊢ (∃ x, ¬B x = a) ↔ ∃ h, a ≠ B h

Next tactic:
exact exists_congr fun h ↦ by rw [ne_comm]
theorem dite_ne_left_iff : dite P (fun _ ↦ a) B ≠ a ↔ ∃ h, a ≠ B h := by
  rw [Ne.def, dite_eq_left_iff, not_forall]
  exact exists_congr fun h ↦ by 

Proof state:
α : Sort u_2
β : Sort ?u.32339
σ : α → Sort u_1
f : α → β
P Q : Prop
inst✝¹ : Decidable P
inst✝ : Decidable Q
a b c : α
A : P → α
B : ¬P → α
h : ¬P
⊢ ¬B h = a ↔ a ≠ B h

Next tactic:
rw [ne_comm]
theorem dite_ne_right_iff : (dite P A fun _ ↦ b) ≠ b ↔ ∃ h, A h ≠ b := by
  

Proof state:
α : Sort u_2
β : Sort ?u.32661
σ : α → Sort u_1
f : α → β
P Q : Prop
inst✝¹ : Decidable P
inst✝ : Decidable Q
a b c : α
A : P → α
B : ¬P → α
⊢ (dite P A fun x => b) ≠ b ↔ ∃ h, A h ≠ b

Next tactic:
simp only [Ne.def, dite_eq_right_iff, not_forall]
theorem ite_ne_left_iff : ite P a b ≠ a ↔ ¬P ∧ a ≠ b :=
  dite_ne_left_iff.trans <| by 

Proof state:
α : Sort u_2
β : Sort ?u.33159
σ : α → Sort u_1
f : α → β
P Q : Prop
inst✝¹ : Decidable P
inst✝ : Decidable Q
a b c : α
A : P → α
B : ¬P → α
⊢ (∃ h, a ≠ (fun x => b) h) ↔ ¬P ∧ a ≠ b

Next tactic:
simp only
theorem ite_ne_left_iff : ite P a b ≠ a ↔ ¬P ∧ a ≠ b :=
  dite_ne_left_iff.trans <| by simp only; 

Proof state:
α : Sort u_2
β : Sort ?u.33159
σ : α → Sort u_1
f : α → β
P Q : Prop
inst✝¹ : Decidable P
inst✝ : Decidable Q
a b c : α
A : P → α
B : ¬P → α
⊢ (∃ h, a ≠ b) ↔ ¬P ∧ a ≠ b

Next tactic:
rw [exists_prop]
theorem ite_ne_right_iff : ite P a b ≠ b ↔ P ∧ a ≠ b :=
  dite_ne_right_iff.trans <| by 

Proof state:
α : Sort u_2
β : Sort ?u.33432
σ : α → Sort u_1
f : α → β
P Q : Prop
inst✝¹ : Decidable P
inst✝ : Decidable Q
a b c : α
A : P → α
B : ¬P → α
⊢ (∃ h, (fun x => a) h ≠ b) ↔ P ∧ a ≠ b

Next tactic:
simp only
theorem ite_ne_right_iff : ite P a b ≠ b ↔ P ∧ a ≠ b :=
  dite_ne_right_iff.trans <| by simp only; 

Proof state:
α : Sort u_2
β : Sort ?u.33432
σ : α → Sort u_1
f : α → β
P Q : Prop
inst✝¹ : Decidable P
inst✝ : Decidable Q
a b c : α
A : P → α
B : ¬P → α
⊢ (∃ h, a ≠ b) ↔ P ∧ a ≠ b

Next tactic:
rw [exists_prop]
/-- A two-argument function applied to two `dite`s is a `dite` of that two-argument function
applied to each of the branches. -/
theorem apply_dite₂ (f : α → β → γ) (P : Prop) [Decidable P] (a : P → α) (b : ¬P → α)
    (c : P → β) (d : ¬P → β) :
    f (dite P a b) (dite P c d) = dite P (fun h ↦ f (a h) (c h)) fun h ↦ f (b h) (d h) := by
  

Proof state:
α : Sort u_3
β : Sort u_4
σ : α → Sort u_1
f✝ : α → β
P✝ Q : Prop
inst✝² : Decidable P✝
inst✝¹ : Decidable Q
a✝ b✝ c✝ : α
A : P✝ → α
B : ¬P✝ → α
γ : Sort u_2
f : α → β → γ
P : Prop
inst✝ : Decidable P
a : P → α
b : ¬P → α
c : P → β
d : ¬P → β
⊢ f (dite P a b) (dite P c d) = if h : P then f (a h) (c h) else f (b h) (d h)

Next tactic:
by_cases h : P
/-- A two-argument function applied to two `dite`s is a `dite` of that two-argument function
applied to each of the branches. -/
theorem apply_dite₂ (f : α → β → γ) (P : Prop) [Decidable P] (a : P → α) (b : ¬P → α)
    (c : P → β) (d : ¬P → β) :
    f (dite P a b) (dite P c d) = dite P (fun h ↦ f (a h) (c h)) fun h ↦ f (b h) (d h) := by
  by_cases h : P <;> 

Proof state:
case pos
α : Sort u_3
β : Sort u_4
σ : α → Sort u_1
f✝ : α → β
P✝ Q : Prop
inst✝² : Decidable P✝
inst✝¹ : Decidable Q
a✝ b✝ c✝ : α
A : P✝ → α
B : ¬P✝ → α
γ : Sort u_2
f : α → β → γ
P : Prop
inst✝ : Decidable P
a : P → α
b : ¬P → α
c : P → β
d : ¬P → β
h : P
⊢ f (dite P a b) (dite P c d) = if h : P then f (a h) (c h) else f (b h) (d h)

Next tactic:
simp [h]