Skip to content

Commit e992840

Browse files
committed
chore: move ExistsUnique, Xor' out of Init.Logic (#16691)
As well as deprecate another unused lemma.
1 parent cb6040d commit e992840

File tree

10 files changed

+158
-152
lines changed

10 files changed

+158
-152
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3113,6 +3113,7 @@ import Mathlib.Logic.Equiv.Pairwise
31133113
import Mathlib.Logic.Equiv.PartialEquiv
31143114
import Mathlib.Logic.Equiv.Set
31153115
import Mathlib.Logic.Equiv.TransferInstance
3116+
import Mathlib.Logic.ExistsUnique
31163117
import Mathlib.Logic.Function.Basic
31173118
import Mathlib.Logic.Function.CompTypeclasses
31183119
import Mathlib.Logic.Function.Conjugate

Mathlib/Data/Bool/Basic.lean

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ Copyright (c) 2014 Microsoft Corporation. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Leonardo de Moura, Jeremy Avigad
55
-/
6-
import Batteries.Tactic.Init
6+
import Mathlib.Logic.Basic
77
import Mathlib.Logic.Function.Defs
8-
import Mathlib.Order.Defs
98

109
/-!
1110
# Booleans
@@ -228,7 +227,10 @@ theorem ofNat_toNat (b : Bool) : ofNat (toNat b) = b := by
228227
theorem injective_iff {α : Sort*} {f : Bool → α} : Function.Injective f ↔ f false ≠ f true :=
229228
fun Hinj Heq ↦ false_ne_true (Hinj Heq), fun H x y hxy ↦ by
230229
cases x <;> cases y
231-
exacts [rfl, (H hxy).elim, (H hxy.symm).elim, rfl]⟩
230+
· rfl
231+
· exact (H hxy).elim
232+
· exact (H hxy.symm).elim
233+
· rfl⟩
232234

233235
/-- **Kaminski's Equation** -/
234236
theorem apply_apply_apply (f : Bool → Bool) (x : Bool) : f (f (f x)) = f x := by

Mathlib/Data/Vector3.lean

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Mario Carneiro
55
-/
66
import Mathlib.Data.Fin.Fin2
7-
import Mathlib.Init.Logic
87
import Mathlib.Util.Notation3
98
import Mathlib.Tactic.TypeStar
109

Mathlib/Init/Logic.lean

Lines changed: 3 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,16 @@ theorem eq_rec_compose {α β φ : Sort u} :
5656
(Eq.recOn p₁ (Eq.recOn p₂ a : β) : φ) = Eq.recOn (Eq.trans p₂ p₁) a
5757
| rfl, rfl, _ => rfl
5858

59-
/- xor -/
60-
61-
variable {a b c d : Prop}
62-
63-
def Xor' (a b : Prop) := (a ∧ ¬ b) ∨ (b ∧ ¬ a)
59+
variable {a b : Prop}
6460

6561
/- iff -/
6662

6763
attribute [refl] Iff.refl
6864
attribute [trans] Iff.trans
6965
attribute [symm] Iff.symm
7066

71-
alias ⟨not_of_not_not_not, _⟩ := not_not_not
67+
-- unused in Mathlib
68+
@[deprecated (since := "2024-09-11")] alias ⟨not_of_not_not_not, _⟩ := not_not_not
7269

7370
variable (p)
7471

@@ -94,93 +91,6 @@ theorem false_iff_iff : (False ↔ a) ↔ ¬a := iff_of_eq (false_iff _)
9491

9592
theorem iff_self_iff (a : Prop) : (a ↔ a) ↔ True := iff_of_eq (iff_self _)
9693

97-
/- exists unique -/
98-
99-
def ExistsUnique (p : α → Prop) := ∃ x, p x ∧ ∀ y, p y → y = x
100-
101-
namespace Mathlib.Notation
102-
open Lean
103-
104-
/--
105-
Checks to see that `xs` has only one binder.
106-
-/
107-
def isExplicitBinderSingular (xs : TSyntax ``explicitBinders) : Bool :=
108-
match xs with
109-
| `(explicitBinders| $_:binderIdent $[: $_]?) => true
110-
| `(explicitBinders| ($_:binderIdent : $_)) => true
111-
| _ => false
112-
113-
open TSyntax.Compat in
114-
/--
115-
`∃! x : α, p x` means that there exists a unique `x` in `α` such that `p x`.
116-
This is notation for `ExistsUnique (fun (x : α) ↦ p x)`.
117-
118-
This notation does not allow multiple binders like `∃! (x : α) (y : β), p x y`
119-
as a shorthand for `∃! (x : α), ∃! (y : β), p x y` since it is liable to be misunderstood.
120-
Often, the intended meaning is instead `∃! q : α × β, p q.1 q.2`.
121-
-/
122-
macro "∃!" xs:explicitBinders ", " b:term : term => do
123-
if !isExplicitBinderSingular xs then
124-
Macro.throwErrorAt xs "\
125-
The `ExistsUnique` notation should not be used with more than one binder.\n\
126-
\n\
127-
The reason for this is that `∃! (x : α), ∃! (y : β), p x y` has a completely different \
128-
meaning from `∃! q : α × β, p q.1 q.2`. \
129-
To prevent confusion, this notation requires that you be explicit \
130-
and use one with the correct interpretation."
131-
expandExplicitBinders ``ExistsUnique xs b
132-
133-
/--
134-
Pretty-printing for `ExistsUnique`, following the same pattern as pretty printing for `Exists`.
135-
However, it does *not* merge binders.
136-
-/
137-
@[app_unexpander ExistsUnique] def unexpandExistsUnique : Lean.PrettyPrinter.Unexpander
138-
| `($(_) fun $x:ident ↦ $b) => `(∃! $x:ident, $b)
139-
| `($(_) fun ($x:ident : $t) ↦ $b) => `(∃! $x:ident : $t, $b)
140-
| _ => throw ()
141-
142-
/--
143-
`∃! x ∈ s, p x` means `∃! x, x ∈ s ∧ p x`, which is to say that there exists a unique `x ∈ s`
144-
such that `p x`.
145-
Similarly, notations such as `∃! x ≤ n, p n` are supported,
146-
using any relation defined using the `binder_predicate` command.
147-
-/
148-
syntax "∃! " binderIdent binderPred ", " term : term
149-
150-
macro_rules
151-
| `(∃! $x:ident $p:binderPred, $b) => `(∃! $x:ident, satisfies_binder_pred% $x $p ∧ $b)
152-
| `(∃! _ $p:binderPred, $b) => `(∃! x, satisfies_binder_pred% x $p ∧ $b)
153-
154-
end Mathlib.Notation
155-
156-
-- @[intro] -- TODO
157-
theorem ExistsUnique.intro {p : α → Prop} (w : α)
158-
(h₁ : p w) (h₂ : ∀ y, p y → y = w) : ∃! x, p x := ⟨w, h₁, h₂⟩
159-
160-
theorem ExistsUnique.elim {α : Sort u} {p : α → Prop} {b : Prop}
161-
(h₂ : ∃! x, p x) (h₁ : ∀ x, p x → (∀ y, p y → y = x) → b) : b :=
162-
Exists.elim h₂ (fun w hw ↦ h₁ w (And.left hw) (And.right hw))
163-
164-
theorem exists_unique_of_exists_of_unique {α : Sort u} {p : α → Prop}
165-
(hex : ∃ x, p x) (hunique : ∀ y₁ y₂, p y₁ → p y₂ → y₁ = y₂) : ∃! x, p x :=
166-
Exists.elim hex (fun x px ↦ ExistsUnique.intro x px (fun y (h : p y) ↦ hunique y x h px))
167-
168-
theorem ExistsUnique.exists {p : α → Prop} : (∃! x, p x) → ∃ x, p x | ⟨x, h, _⟩ => ⟨x, h⟩
169-
170-
theorem ExistsUnique.unique {α : Sort u} {p : α → Prop}
171-
(h : ∃! x, p x) {y₁ y₂ : α} (py₁ : p y₁) (py₂ : p y₂) : y₁ = y₂ :=
172-
let ⟨_, _, hy⟩ := h; (hy _ py₁).trans (hy _ py₂).symm
173-
174-
/- exists, forall, exists unique congruences -/
175-
176-
-- TODO
177-
-- attribute [congr] forall_congr'
178-
-- attribute [congr] exists_congr'
179-
180-
-- @[congr]
181-
theorem existsUnique_congr {p q : α → Prop} (h : ∀ a, p a ↔ q a) : (∃! a, p a) ↔ ∃! a, q a :=
182-
exists_congr fun _ ↦ and_congr (h _) <| forall_congr' fun _ ↦ imp_congr_left (h _)
183-
18494
/- decidable -/
18595

18696
@[deprecated (since := "2024-09-03")] -- unused in Mathlib
@@ -214,9 +124,6 @@ end Decidable
214124
@[deprecated (since := "2024-09-03")] alias decidableTrue := instDecidableTrue
215125
@[deprecated (since := "2024-09-03")] alias decidableFalse := instDecidableFalse
216126

217-
instance {q : Prop} [Decidable p] [Decidable q] : Decidable (Xor' p q) :=
218-
inferInstanceAs (Decidable (Or ..))
219-
220127
@[deprecated (since := "2024-09-03")] -- unused in Mathlib
221128
def IsDecEq {α : Sort u} (p : α → α → Bool) : Prop := ∀ ⦃x y : α⦄, p x y = true → x = y
222129
@[deprecated (since := "2024-09-03")] -- unused in Mathlib

Mathlib/Logic/Basic.lean

Lines changed: 5 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ lemma Iff.ne_right {α β : Sort*} {a b : α} {c d : β} : (a ≠ b ↔ c = d)
234234

235235
/-! ### Declarations about `Xor'` -/
236236

237+
/-- `Xor' a b` is the exclusive-or of propositions. -/
238+
def Xor' (a b : Prop) := (a ∧ ¬b) ∨ (b ∧ ¬a)
239+
240+
instance [Decidable a] [Decidable b] : Decidable (Xor' a b) := inferInstanceAs (Decidable (Or ..))
241+
237242
@[simp] theorem xor_true : Xor' True = Not := by
238243
simp (config := { unfoldPartialApp := true }) [Xor']
239244

@@ -505,15 +510,6 @@ theorem forall₂_true_iff {β : α → Sort*} : (∀ a, β a → True) ↔ True
505510
theorem forall₃_true_iff {β : α → Sort*} {γ : ∀ a, β a → Sort*} :
506511
(∀ (a) (b : β a), γ a b → True) ↔ True := by simp
507512

508-
@[simp] theorem exists_unique_iff_exists [Subsingleton α] {p : α → Prop} :
509-
(∃! x, p x) ↔ ∃ x, p x :=
510-
fun h ↦ h.exists, Exists.imp fun x hx ↦ ⟨hx, fun y _ ↦ Subsingleton.elim y x⟩⟩
511-
512-
-- forall_forall_const is no longer needed
513-
514-
theorem exists_unique_const {b : Prop} (α : Sort*) [i : Nonempty α] [Subsingleton α] :
515-
(∃! _ : α, b) ↔ b := by simp
516-
517513
theorem Decidable.and_forall_ne [DecidableEq α] (a : α) {p : α → Prop} :
518514
(p a ∧ ∀ b, b ≠ a → p b) ↔ ∀ b, p b := by
519515
simp only [← @forall_eq _ p a, ← forall_and, ← or_imp, Decidable.em, forall_const]
@@ -524,12 +520,6 @@ theorem and_forall_ne (a : α) : (p a ∧ ∀ b, b ≠ a → p b) ↔ ∀ b, p b
524520
theorem Ne.ne_or_ne {x y : α} (z : α) (h : x ≠ y) : x ≠ z ∨ y ≠ z :=
525521
not_and_or.1 <| mt (and_imp.2 (· ▸ ·)) h.symm
526522

527-
@[simp] theorem exists_unique_eq {a' : α} : ∃! a, a = a' := by
528-
simp only [eq_comm, ExistsUnique, and_self, forall_eq', exists_eq']
529-
530-
@[simp] theorem exists_unique_eq' {a' : α} : ∃! a, a' = a := by
531-
simp only [ExistsUnique, and_self, forall_eq', exists_eq']
532-
533523
@[simp]
534524
theorem exists_apply_eq_apply' (f : α → β) (a' : α) : ∃ a, f a' = f a := ⟨a', rfl⟩
535525

@@ -608,10 +598,6 @@ protected theorem Decidable.forall_or_right {q} {p : α → Prop} [Decidable q]
608598
theorem forall_or_right {q} {p : α → Prop} : (∀ x, p x ∨ q) ↔ (∀ x, p x) ∨ q :=
609599
Decidable.forall_or_right
610600

611-
theorem exists_unique_prop {p q : Prop} : (∃! _ : p, q) ↔ p ∧ q := by simp
612-
613-
@[simp] theorem exists_unique_false : ¬∃! _ : α, False := fun ⟨_, h, _⟩ ↦ h
614-
615601
theorem Exists.fst {b : Prop} {p : b → Prop} : Exists p → b
616602
| ⟨h, _⟩ => h
617603

@@ -628,9 +614,6 @@ theorem Prop.forall_iff {p : Prop → Prop} : (∀ h, p h) ↔ p False ∧ p Tru
628614
theorem exists_iff_of_forall {p : Prop} {q : p → Prop} (h : ∀ h, q h) : (∃ h, q h) ↔ p :=
629615
⟨Exists.fst, fun H ↦ ⟨H, h H⟩⟩
630616

631-
theorem exists_unique_prop_of_true {p : Prop} {q : p → Prop} (h : p) : (∃! h' : p, q h') ↔ q h :=
632-
@exists_unique_const (q h) p ⟨h⟩ _
633-
634617
theorem exists_prop_of_false {p : Prop} {q : p → Prop} : ¬p → ¬∃ h' : p, q h' :=
635618
mt Exists.fst
636619

@@ -669,29 +652,6 @@ lemma iff_eq_eq {a b : Prop} : (a ↔ b) = (a = b) := propext ⟨propext, Eq.to_
669652
@[simp] theorem forall_true_left (p : True → Prop) : (∀ x, p x) ↔ p True.intro :=
670653
forall_prop_of_true _
671654

672-
theorem ExistsUnique.elim₂ {α : Sort*} {p : α → Sort*} [∀ x, Subsingleton (p x)]
673-
{q : ∀ (x) (_ : p x), Prop} {b : Prop} (h₂ : ∃! x, ∃! h : p x, q x h)
674-
(h₁ : ∀ (x) (h : p x), q x h → (∀ (y) (hy : p y), q y hy → y = x) → b) : b := by
675-
simp only [exists_unique_iff_exists] at h₂
676-
apply h₂.elim
677-
exact fun x ⟨hxp, hxq⟩ H ↦ h₁ x hxp hxq fun y hyp hyq ↦ H y ⟨hyp, hyq⟩
678-
679-
theorem ExistsUnique.intro₂ {α : Sort*} {p : α → Sort*} [∀ x, Subsingleton (p x)]
680-
{q : ∀ (x : α) (_ : p x), Prop} (w : α) (hp : p w) (hq : q w hp)
681-
(H : ∀ (y) (hy : p y), q y hy → y = w) : ∃! x, ∃! hx : p x, q x hx := by
682-
simp only [exists_unique_iff_exists]
683-
exact ExistsUnique.intro w ⟨hp, hq⟩ fun y ⟨hyp, hyq⟩ ↦ H y hyp hyq
684-
685-
theorem ExistsUnique.exists₂ {α : Sort*} {p : α → Sort*} {q : ∀ (x : α) (_ : p x), Prop}
686-
(h : ∃! x, ∃! hx : p x, q x hx) : ∃ (x : _) (hx : p x), q x hx :=
687-
h.exists.imp fun _ hx ↦ hx.exists
688-
689-
theorem ExistsUnique.unique₂ {α : Sort*} {p : α → Sort*} [∀ x, Subsingleton (p x)]
690-
{q : ∀ (x : α) (_ : p x), Prop} (h : ∃! x, ∃! hx : p x, q x hx) {y₁ y₂ : α}
691-
(hpy₁ : p y₁) (hqy₁ : q y₁ hpy₁) (hpy₂ : p y₂) (hqy₂ : q y₂ hpy₂) : y₁ = y₂ := by
692-
simp only [exists_unique_iff_exists] at h
693-
exact h.unique ⟨hpy₁, hqy₁⟩ ⟨hpy₂, hqy₂⟩
694-
695655
end Quantifiers
696656

697657
/-! ### Classical lemmas -/

Mathlib/Logic/ExistsUnique.lean

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/-
2+
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Leonardo de Moura, Jeremy Avigad, Floris van Doorn
5+
-/
6+
import Mathlib.Tactic.TypeStar
7+
8+
/-!
9+
# `ExistsUnique`
10+
11+
This file defines the `ExistsUnique` predicate, notated as `∃!`, and proves some of its
12+
basic properties.
13+
-/
14+
15+
variable {α : Sort*}
16+
17+
/-- For `p : α → Prop`, `ExistsUnique p` means that there exists a unique `x : α` with `p x`. -/
18+
def ExistsUnique (p : α → Prop) := ∃ x, p x ∧ ∀ y, p y → y = x
19+
20+
namespace Mathlib.Notation
21+
open Lean
22+
23+
/-- Checks to see that `xs` has only one binder. -/
24+
def isExplicitBinderSingular (xs : TSyntax ``explicitBinders) : Bool :=
25+
match xs with
26+
| `(explicitBinders| $_:binderIdent $[: $_]?) => true
27+
| `(explicitBinders| ($_:binderIdent : $_)) => true
28+
| _ => false
29+
30+
open TSyntax.Compat in
31+
/--
32+
`∃! x : α, p x` means that there exists a unique `x` in `α` such that `p x`.
33+
This is notation for `ExistsUnique (fun (x : α) ↦ p x)`.
34+
35+
This notation does not allow multiple binders like `∃! (x : α) (y : β), p x y`
36+
as a shorthand for `∃! (x : α), ∃! (y : β), p x y` since it is liable to be misunderstood.
37+
Often, the intended meaning is instead `∃! q : α × β, p q.1 q.2`.
38+
-/
39+
macro "∃!" xs:explicitBinders ", " b:term : term => do
40+
if !isExplicitBinderSingular xs then
41+
Macro.throwErrorAt xs "\
42+
The `ExistsUnique` notation should not be used with more than one binder.\n\
43+
\n\
44+
The reason for this is that `∃! (x : α), ∃! (y : β), p x y` has a completely different \
45+
meaning from `∃! q : α × β, p q.1 q.2`. \
46+
To prevent confusion, this notation requires that you be explicit \
47+
and use one with the correct interpretation."
48+
expandExplicitBinders ``ExistsUnique xs b
49+
50+
/--
51+
Pretty-printing for `ExistsUnique`, following the same pattern as pretty printing for `Exists`.
52+
However, it does *not* merge binders.
53+
-/
54+
@[app_unexpander ExistsUnique] def unexpandExistsUnique : Lean.PrettyPrinter.Unexpander
55+
| `($(_) fun $x:ident ↦ $b) => `(∃! $x:ident, $b)
56+
| `($(_) fun ($x:ident : $t) ↦ $b) => `(∃! $x:ident : $t, $b)
57+
| _ => throw ()
58+
59+
/--
60+
`∃! x ∈ s, p x` means `∃! x, x ∈ s ∧ p x`, which is to say that there exists a unique `x ∈ s`
61+
such that `p x`.
62+
Similarly, notations such as `∃! x ≤ n, p n` are supported,
63+
using any relation defined using the `binder_predicate` command.
64+
-/
65+
syntax "∃! " binderIdent binderPred ", " term : term
66+
67+
macro_rules
68+
| `(∃! $x:ident $p:binderPred, $b) => `(∃! $x:ident, satisfies_binder_pred% $x $p ∧ $b)
69+
| `(∃! _ $p:binderPred, $b) => `(∃! x, satisfies_binder_pred% x $p ∧ $b)
70+
71+
end Mathlib.Notation
72+
73+
-- @[intro] -- TODO
74+
theorem ExistsUnique.intro {p : α → Prop} (w : α)
75+
(h₁ : p w) (h₂ : ∀ y, p y → y = w) : ∃! x, p x := ⟨w, h₁, h₂⟩
76+
77+
theorem ExistsUnique.elim {p : α → Prop} {b : Prop}
78+
(h₂ : ∃! x, p x) (h₁ : ∀ x, p x → (∀ y, p y → y = x) → b) : b :=
79+
Exists.elim h₂ (fun w hw ↦ h₁ w (And.left hw) (And.right hw))
80+
81+
theorem exists_unique_of_exists_of_unique {p : α → Prop}
82+
(hex : ∃ x, p x) (hunique : ∀ y₁ y₂, p y₁ → p y₂ → y₁ = y₂) : ∃! x, p x :=
83+
Exists.elim hex (fun x px ↦ ExistsUnique.intro x px (fun y (h : p y) ↦ hunique y x h px))
84+
85+
theorem ExistsUnique.exists {p : α → Prop} : (∃! x, p x) → ∃ x, p x | ⟨x, h, _⟩ => ⟨x, h⟩
86+
87+
theorem ExistsUnique.unique {p : α → Prop}
88+
(h : ∃! x, p x) {y₁ y₂ : α} (py₁ : p y₁) (py₂ : p y₂) : y₁ = y₂ :=
89+
let ⟨_, _, hy⟩ := h; (hy _ py₁).trans (hy _ py₂).symm
90+
91+
-- TODO
92+
-- attribute [congr] forall_congr'
93+
-- attribute [congr] exists_congr'
94+
95+
-- @[congr]
96+
theorem existsUnique_congr {p q : α → Prop} (h : ∀ a, p a ↔ q a) : (∃! a, p a) ↔ ∃! a, q a :=
97+
exists_congr fun _ ↦ and_congr (h _) <| forall_congr' fun _ ↦ imp_congr_left (h _)
98+
99+
@[simp] theorem exists_unique_iff_exists [Subsingleton α] {p : α → Prop} :
100+
(∃! x, p x) ↔ ∃ x, p x :=
101+
fun h ↦ h.exists, Exists.imp fun x hx ↦ ⟨hx, fun y _ ↦ Subsingleton.elim y x⟩⟩
102+
103+
theorem exists_unique_const {b : Prop} (α : Sort*) [i : Nonempty α] [Subsingleton α] :
104+
(∃! _ : α, b) ↔ b := by simp
105+
106+
@[simp] theorem exists_unique_eq {a' : α} : ∃! a, a = a' := by
107+
simp only [eq_comm, ExistsUnique, and_self, forall_eq', exists_eq']
108+
109+
@[simp] theorem exists_unique_eq' {a' : α} : ∃! a, a' = a := by
110+
simp only [ExistsUnique, and_self, forall_eq', exists_eq']
111+
112+
theorem exists_unique_prop {p q : Prop} : (∃! _ : p, q) ↔ p ∧ q := by simp
113+
114+
@[simp] theorem exists_unique_false : ¬∃! _ : α, False := fun ⟨_, h, _⟩ ↦ h
115+
116+
theorem exists_unique_prop_of_true {p : Prop} {q : p → Prop} (h : p) : (∃! h' : p, q h') ↔ q h :=
117+
@exists_unique_const (q h) p ⟨h⟩ _
118+
119+
theorem ExistsUnique.elim₂ {p : α → Sort*} [∀ x, Subsingleton (p x)]
120+
{q : ∀ (x) (_ : p x), Prop} {b : Prop} (h₂ : ∃! x, ∃! h : p x, q x h)
121+
(h₁ : ∀ (x) (h : p x), q x h → (∀ (y) (hy : p y), q y hy → y = x) → b) : b := by
122+
simp only [exists_unique_iff_exists] at h₂
123+
apply h₂.elim
124+
exact fun x ⟨hxp, hxq⟩ H ↦ h₁ x hxp hxq fun y hyp hyq ↦ H y ⟨hyp, hyq⟩
125+
126+
theorem ExistsUnique.intro₂ {p : α → Sort*} [∀ x, Subsingleton (p x)]
127+
{q : ∀ (x : α) (_ : p x), Prop} (w : α) (hp : p w) (hq : q w hp)
128+
(H : ∀ (y) (hy : p y), q y hy → y = w) : ∃! x, ∃! hx : p x, q x hx := by
129+
simp only [exists_unique_iff_exists]
130+
exact ExistsUnique.intro w ⟨hp, hq⟩ fun y ⟨hyp, hyq⟩ ↦ H y hyp hyq
131+
132+
theorem ExistsUnique.exists₂ {p : α → Sort*} {q : ∀ (x : α) (_ : p x), Prop}
133+
(h : ∃! x, ∃! hx : p x, q x hx) : ∃ (x : _) (hx : p x), q x hx :=
134+
h.exists.imp fun _ hx ↦ hx.exists
135+
136+
theorem ExistsUnique.unique₂ {p : α → Sort*} [∀ x, Subsingleton (p x)]
137+
{q : ∀ (x : α) (_ : p x), Prop} (h : ∃! x, ∃! hx : p x, q x hx) {y₁ y₂ : α}
138+
(hpy₁ : p y₁) (hqy₁ : q y₁ hpy₁) (hpy₂ : p y₂) (hqy₂ : q y₂ hpy₂) : y₁ = y₂ := by
139+
simp only [exists_unique_iff_exists] at h
140+
exact h.unique ⟨hpy₁, hqy₁⟩ ⟨hpy₂, hqy₂⟩

0 commit comments

Comments
 (0)