File: Mathlib/Data/SetLike/Basic.lean

full_name: SetLike.coe_injective'
code: /-- A class to indicate that there is a canonical injection between `A` and `Set B`.

This has the effect of giving terms of `A` elements of type `B` (through a `Membership`
instance) and a compatible coercion to `Type*` as a subtype.

Note: if `SetLike.coe` is a projection, implementers should create a simp lemma such as
```
@[simp] lemma mem_carrier {p : MySubobject X} : x ∈ p.carrier ↔ x ∈ (p : Set X) := Iff.rfl
```
to normalize terms.

If you declare an unbundled subclass of `SetLike`, for example:
```
class MulMemClass (S : Type*) (M : Type*) [Mul M] [SetLike S M] where
  ...
```
Then you should *not* repeat the `outParam` declaration so `SetLike` will supply the value instead.
This ensures your subclass will not have issues with synthesis of the `[Mul M]` parameter starting
before the value of `M` is known.
-/
@[notation_class * carrier Simps.findCoercionArgs]
class SetLike (A : Type*) (B : outParam Type*) where
  /-- The coercion from a term of a `SetLike` to its corresponding `Set`. -/
  protected coe : A → Set B
  /-- The coercion from a term of a `SetLike` to its corresponding `Set` is injective. -/
  protected coe_injective' : Function.Injective coe
goal: Function.Injective SetLike.coe

full_name: SetLike
code: /-- A class to indicate that there is a canonical injection between `A` and `Set B`.

This has the effect of giving terms of `A` elements of type `B` (through a `Membership`
instance) and a compatible coercion to `Type*` as a subtype.

Note: if `SetLike.coe` is a projection, implementers should create a simp lemma such as
```
@[simp] lemma mem_carrier {p : MySubobject X} : x ∈ p.carrier ↔ x ∈ (p : Set X) := Iff.rfl
```
to normalize terms.

If you declare an unbundled subclass of `SetLike`, for example:
```
class MulMemClass (S : Type*) (M : Type*) [Mul M] [SetLike S M] where
  ...
```
Then you should *not* repeat the `outParam` declaration so `SetLike` will supply the value instead.
This ensures your subclass will not have issues with synthesis of the `[Mul M]` parameter starting
before the value of `M` is known.
-/
@[notation_class * carrier Simps.findCoercionArgs]
class SetLike (A : Type*) (B : outParam Type*) where
  /-- The coercion from a term of a `SetLike` to its corresponding `Set`. -/
  protected coe : A → Set B
  /-- The coercion from a term of a `SetLike` to its corresponding `Set` is injective. -/
  protected coe_injective' : Function.Injective coe
goal: Type (max u_1 u_2)

full_name: SetLike.coe
code: /-- A class to indicate that there is a canonical injection between `A` and `Set B`.

This has the effect of giving terms of `A` elements of type `B` (through a `Membership`
instance) and a compatible coercion to `Type*` as a subtype.

Note: if `SetLike.coe` is a projection, implementers should create a simp lemma such as
```
@[simp] lemma mem_carrier {p : MySubobject X} : x ∈ p.carrier ↔ x ∈ (p : Set X) := Iff.rfl
```
to normalize terms.

If you declare an unbundled subclass of `SetLike`, for example:
```
class MulMemClass (S : Type*) (M : Type*) [Mul M] [SetLike S M] where
  ...
```
Then you should *not* repeat the `outParam` declaration so `SetLike` will supply the value instead.
This ensures your subclass will not have issues with synthesis of the `[Mul M]` parameter starting
before the value of `M` is known.
-/
@[notation_class * carrier Simps.findCoercionArgs]
class SetLike (A : Type*) (B : outParam Type*) where
  /-- The coercion from a term of a `SetLike` to its corresponding `Set`. -/
  protected coe : A → Set B
  /-- The coercion from a term of a `SetLike` to its corresponding `Set` is injective. -/
  protected coe_injective' : Function.Injective coe
goal: A → Set B

full_name: SetLike.instCoeTCSet
code: instance : CoeTC A (Set B) 
goal: CoeTC A (Set B)

full_name: SetLike.instMembership
code: instance (priority := 100) instMembership : Membership B A 
goal: Membership B A

full_name: SetLike.instCoeSortType
code: instance (priority := 100) : CoeSort A (Type _) 
goal: CoeSort A (Type u_2)

full_name: SetLike.delabSubtypeSetLike
code: /-- For terms that match the `CoeSort` instance's body, pretty print as `↥S`
rather than as `{ x // x ∈ S }`. The discriminating feature is that membership
uses the `SetLike.instMembership` instance. -/
@[delab app.Subtype]
def delabSubtypeSetLike : Delab 
goal: Lean.PrettyPrinter.Delaborator.Delab

full_name: SetLike.coe_sort_coe
code: @[simp, norm_cast]
theorem coe_sort_coe : ((p : Set B) : Type _) = p 
goal: ↑↑p = ↥p

full_name: SetLike.exists
code: protected theorem «exists» {q : p → Prop} : (∃ x, q x) ↔ ∃ (x : B) (h : x ∈ p), q ⟨x, ‹_›⟩ 
goal: (∃ x, q x) ↔ ∃ x, ∃ (h : x ∈ p), q ⟨x, h⟩

full_name: SetLike.forall
code: protected theorem «forall» {q : p → Prop} : (∀ x, q x) ↔ ∀ (x : B) (h : x ∈ p), q ⟨x, ‹_›⟩ 
goal: (∀ (x : ↥p), q x) ↔ ∀ (x : B) (h : x ∈ p), q ⟨x, h⟩

full_name: SetLike.coe_injective
code: theorem coe_injective : Function.Injective (SetLike.coe : A → Set B) 
goal: Function.Injective SetLike.coe

full_name: SetLike.coe_set_eq
code: @[simp, norm_cast]
theorem coe_set_eq : (p : Set B) = q ↔ p = q 
goal: ↑p = ↑q ↔ p = q

full_name: SetLike.coe_ne_coe
code: @[norm_cast] lemma coe_ne_coe : (p : Set B) ≠ q ↔ p ≠ q 
goal: ↑p ≠ ↑q ↔ p ≠ q

full_name: SetLike.ext'
code: theorem ext' (h : (p : Set B) = q) : p = q 
goal: p = q

full_name: SetLike.ext'_iff
code: theorem ext'_iff : p = q ↔ (p : Set B) = q 
goal: p = q ↔ ↑p = ↑q

full_name: SetLike.ext
code: /-- Note: implementers of `SetLike` must copy this lemma in order to tag it with `@[ext]`. -/
theorem ext (h : ∀ x, x ∈ p ↔ x ∈ q) : p = q 
goal: p = q

full_name: SetLike.ext_iff
code: theorem ext_iff : p = q ↔ ∀ x, x ∈ p ↔ x ∈ q 
goal: p = q ↔ ∀ (x : B), x ∈ p ↔ x ∈ q

full_name: SetLike.mem_coe
code: @[simp]
theorem mem_coe {x : B} : x ∈ (p : Set B) ↔ x ∈ p 
goal: x ∈ ↑p ↔ x ∈ p

full_name: SetLike.coe_eq_coe
code: @[simp, norm_cast]
theorem coe_eq_coe {x y : p} : (x : B) = y ↔ x = y 
goal: ↑x = ↑y ↔ x = y

full_name: SetLike.coe_mem
code: @[simp]
theorem coe_mem (x : p) : (x : B) ∈ p 
goal: ↑x ∈ p

full_name: SetLike.mem_of_subset
code: @[aesop 5% apply (rule_sets := [SetLike])]
lemma mem_of_subset {s : Set B} (hp : s ⊆ p) {x : B} (hx : x ∈ s) : x ∈ p 
goal: x ∈ p

full_name: SetLike.eta
code: protected theorem eta (x : p) (hx : (x : B) ∈ p) : (⟨x, hx⟩ : p) = x 
goal: ⟨↑x, hx⟩ = x

full_name: SetLike.instPartialOrder
code: instance (priority := 100) instPartialOrder : PartialOrder A 
goal: PartialOrder A

full_name: SetLike.le_def
code: theorem le_def {S T : A} : S ≤ T ↔ ∀ ⦃x : B⦄, x ∈ S → x ∈ T 
goal: S ≤ T ↔ ∀ ⦃x : B⦄, x ∈ S → x ∈ T

full_name: SetLike.coe_subset_coe
code: @[simp, norm_cast]
theorem coe_subset_coe {S T : A} : (S : Set B) ⊆ T ↔ S ≤ T 
goal: ↑S ⊆ ↑T ↔ S ≤ T

full_name: SetLike.coe_mono
code: @[mono]
theorem coe_mono : Monotone (SetLike.coe : A → Set B) 
goal: Monotone SetLike.coe

full_name: SetLike.coe_ssubset_coe
code: @[simp, norm_cast]
theorem coe_ssubset_coe {S T : A} : (S : Set B) ⊂ T ↔ S < T 
goal: ↑S ⊂ ↑T ↔ S < T

full_name: SetLike.coe_strictMono
code: @[mono]
theorem coe_strictMono : StrictMono (SetLike.coe : A → Set B) 
goal: StrictMono SetLike.coe

full_name: SetLike.not_le_iff_exists
code: theorem not_le_iff_exists : ¬p ≤ q ↔ ∃ x ∈ p, x ∉ q 
goal: ¬p ≤ q ↔ ∃ x ∈ p, x ∉ q

full_name: SetLike.exists_of_lt
code: theorem exists_of_lt : p < q → ∃ x ∈ q, x ∉ p 
goal: p < q → ∃ x ∈ q, x ∉ p

full_name: SetLike.lt_iff_le_and_exists
code: theorem lt_iff_le_and_exists : p < q ↔ p ≤ q ∧ ∃ x ∈ q, x ∉ p 
goal: p < q ↔ p ≤ q ∧ ∃ x ∈ q, x ∉ p