Built with
doc-gen4 , running Lean4.
Bubbles (
) indicate interactive fragments: hover for details, tap to reveal contents.
Use
Ctrl+β Ctrl+β to navigate,
Ctrl+π±οΈ to focus.
On Mac, use
Cmd instead of
Ctrl .
/-
Copyright (c) 2021 Eric Wieser. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Eric Wieser
! This file was ported from Lean 3 source module data.set_like.basic
! leanprover-community/mathlib commit feb99064803fd3108e37c18b0f77d0a8344677a3
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathlib.Data.Set.Basic
import Mathlib.Tactic.Monotonicity.Attr
/-!
# Typeclass for types with a set-like extensionality property
The `Membership` typeclass is used to let terms of a type have elements.
Many instances of `Membership` have a set-like extensionality property:
things are equal iff they have the same elements. The `SetLike`
typeclass provides a unified interface to define a `Membership` that is
extensional in this way.
The main use of `SetLike` is for algebraic subobjects (such as
`Submonoid` and `Submodule`), whose non-proof data consists only of a
carrier set. In such a situation, the projection to the carrier set
is injective.
In general, a type `A` is `SetLike` with elements of type `B` if it
has an injective map to `Set B`. This module provides standard
boilerplate for every `SetLike`: a `coe_sort`, a `coe` to set, a
`PartialOrder`, and various extensionality and simp lemmas.
A typical subobject should be declared as:
```
structure MySubobject (X : Type _) [ObjectTypeclass X] :=
(carrier : Set X)
(op_mem' : β {x : X}, x β carrier β sorry β carrier)
namespace MySubobject
variables {X : Type _} [ObjectTypeclass X] {x : X}
instance : SetLike (MySubobject X) X :=
β¨MySubobject.carrier, Ξ» p q h, by cases p; cases q; congr'β©
@[simp] lemma mem_carrier {p : MySubobject X} : x β p.carrier β x β (p : Set X) := Iff.rfl
@[ext] theorem ext {p q : MySubobject X} (h : β x, x β p β x β q) : p = q := SetLike.ext h
/-- Copy of a `MySubobject` with a new `carrier` equal to the old one. Useful to fix definitional
equalities. See Note [range copy pattern]. -/
protected def copy (p : MySubobject X) (s : Set X) (hs : s = βp) : MySubobject X :=
{ carrier := s,
op_mem' := hs.symm βΈ p.op_mem' }
@[simp] lemma coe_copy (p : MySubobject X) (s : Set X) (hs : s = βp) :
(p.copy s hs : Set X) = s := rfl
lemma copy_eq (p : MySubobject X) (s : Set X) (hs : s = βp) : p.copy s hs = p :=
SetLike.coe_injective hs
end MySubobject
```
An alternative to `SetLike` could have been an extensional `Membership` typeclass:
```
class ExtMembership (Ξ± : out_param $ Type u) (Ξ² : Type v) extends Membership Ξ± Ξ² :=
(ext_iff : β {s t : Ξ²}, s = t β β (x : Ξ±), x β s β x β t)
```
While this is equivalent, `SetLike` conveniently uses a carrier set projection directly.
## Tags
subobjects
-/
/-- 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 : {Ξ± : Sort ?u.18} β {Ξ² : Sort ?u.17} β (Ξ± β Ξ² ) β Prop Function.Injective coe
#align set_like SetLike
attribute [ coe ] SetLike.coe
namespace SetLike
variable { A : Type _ } { B : Type _ } [ i : SetLike A B ]
instance : CoeTC : Sort ?u.205 β Sort ?u.204 β Sort (max(max1?u.205)?u.204) CoeTC A ( Set B ) where coe := SetLike.coe
instance ( priority := 100) : Membership B A :=
β¨ fun x p => x β ( p : Set B )β©
instance ( priority := 100) : CoeSort A ( Type _ ) :=
β¨ fun p => { x : B // x β p }β©
variable ( p q : A )
@[ simp , norm_cast ]
theorem coe_sort_coe : β {A : Type u_2} {B : Type u_1} [i : SetLike A B ] (p : A ), ββp = { x // x β p } coe_sort_coe : (( p : Set B ) : Type _ ) = p :=
rfl : β {Ξ± : Sort ?u.1068} {a : Ξ± }, a = a rfl
#align set_like.coe_sort_coe SetLike.coe_sort_coe : β {A : Type u_2} {B : Type u_1} [i : SetLike A B ] (p : A ), ββp = { x // x β p } SetLike.coe_sort_coe
variable { p q }
protected theorem Β«existsΒ» : β {q : { x // x β p } β Prop }, (β x , q x ) β β x h , q { val := x , property := h } Β«existsΒ» { q : p β Prop } : (β x , q x ) β β ( x : B ) ( h : x β p ), q β¨ x , βΉ_βΊβ© :=
SetCoe.exists : β {Ξ± : Type ?u.1310} {s : Set Ξ± } {p : βs β Prop }, (β x , p x ) β β x h , p { val := x , property := h } SetCoe.exists
#align set_like.exists SetLike.exists : β {A : Type u_2} {B : Type u_1} [i : SetLike A B ] {p : A } {q : { x // x β p } β Prop },
(β x , q x ) β β x h , q { val := x , property := h } SetLike.exists
protected theorem Β«forallΒ» : β {A : Type u_2} {B : Type u_1} [i : SetLike A B ] {p : A } {q : { x // x β p } β Prop },
(β (x : { x // x β p } ), q x ) β β (x : B ) (h : x β p ), q { val := x , property := h } Β«forallΒ» { q : p β Prop } : (β x , q x ) β β ( x : B ) ( h : x β p ), q β¨ x , βΉ_βΊβ© :=
SetCoe.forall : β {Ξ± : Type ?u.1467} {s : Set Ξ± } {p : βs β Prop },
(β (x : βs ), p x ) β β (x : Ξ± ) (h : x β s ), p { val := x , property := h } SetCoe.forall
#align set_like.forall SetLike.forall : β {A : Type u_2} {B : Type u_1} [i : SetLike A B ] {p : A } {q : { x // x β p } β Prop },
(β (x : { x // x β p } ), q x ) β β (x : B ) (h : x β p ), q { val := x , property := h } SetLike.forall
theorem coe_injective : Function.Injective : {Ξ± : Sort ?u.1529} β {Ξ² : Sort ?u.1528} β (Ξ± β Ξ² ) β Prop Function.Injective ( SetLike.coe : A β Set B ) := fun _ _ h =>
SetLike.coe_injective' h
#align set_like.coe_injective SetLike.coe_injective
@[ simp , norm_cast ]
theorem coe_set_eq : βp = βq β p = q coe_set_eq : ( p : Set B ) = q β p = q :=
coe_injective . eq_iff
#align set_like.coe_set_eq SetLike.coe_set_eq : β {A : Type u_2} {B : Type u_1} [i : SetLike A B ] {p q : A }, βp = βq β p = q SetLike.coe_set_eq
theorem ext' : βp = βq β p = q ext' ( h : ( p : Set B ) = q ) : p = q :=
coe_injective h
#align set_like.ext' SetLike.ext' : β {A : Type u_2} {B : Type u_1} [i : SetLike A B ] {p q : A }, βp = βq β p = q SetLike.ext'
theorem ext'_iff : p = q β βp = βq ext'_iff : p = q β ( p : Set B ) = q :=
coe_set_eq : β {A : Type ?u.2478} {B : Type ?u.2477} [i : SetLike A B ] {p q : A }, βp = βq β p = q coe_set_eq. symm
#align set_like.ext'_iff SetLike.ext'_iff : β {A : Type u_1} {B : Type u_2} [i : SetLike A B ] {p q : A }, p = q β βp = βq SetLike.ext'_iff
/-- 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 :=
coe_injective <| Set.ext : β {Ξ± : Type ?u.2598} {a b : Set Ξ± }, (β (x : Ξ± ), x β a β x β b ) β a = b Set.ext h
#align set_like.ext SetLike.ext
theorem ext_iff : p = q β β x , x β p β x β q :=
coe_injective . eq_iff . symm . trans Set.ext_iff
#align set_like.ext_iff SetLike.ext_iff
@[ simp ]
theorem mem_coe { x : B } : x β ( p : Set B ) β x β p :=
Iff.rfl
#align set_like.mem_coe SetLike.mem_coe
@[ simp , norm_cast ]
theorem coe_eq_coe : β {x y : { x // x β p } }, βx = βy β x = y coe_eq_coe { x y : p } : ( x : B ) = y β x = y :=
Subtype.ext_iff_val : β {Ξ± : Sort ?u.3259} {p : Ξ± β Prop } {a1 a2 : { x // p x } }, a1 = a2 β βa1 = βa2 Subtype.ext_iff_val. symm
#align set_like.coe_eq_coe SetLike.coe_eq_coe : β {A : Type u_2} {B : Type u_1} [i : SetLike A B ] {p : A } {x y : { x // x β p } }, βx = βy β x = y SetLike.coe_eq_coe
-- porting note: this is not necessary anymore due to the way coercions work
#noalign set_like.coe_mk
@[ simp ]
theorem coe_mem ( x : p ) : ( x : B ) β p :=
x . 2
#align set_like.coe_mem SetLike.coe_mem : β {A : Type u_2} {B : Type u_1} [i : SetLike A B ] {p : A } (x : { x // x β p } ), βx β p SetLike.coe_mem
-- porting note: removed `@[simp]` because `simpNF` linter complained
protected theorem eta : β {A : Type u_2} {B : Type u_1} [i : SetLike A B ] {p : A } (x : { x // x β p } ) (hx : βx β p ),
{ val := βx , property := hx } = x eta ( x : p ) ( hx : ( x : B ) β p ) : (β¨ x , hx β© : p ) = x := rfl : β {Ξ± : Sort ?u.3840} {a : Ξ± }, a = a rfl
#align set_like.eta SetLike.eta : β {A : Type u_2} {B : Type u_1} [i : SetLike A B ] {p : A } (x : { x // x β p } ) (hx : βx β p ),
{ val := βx , property := hx } = x SetLike.eta
instance ( priority := 100) : PartialOrder : Type ?u.3869 β Type ?u.3869 PartialOrder A :=
{ PartialOrder.lift ( SetLike.coe : A β Set B ) coe_injective with
le := fun H K => β β¦ x β¦, x β H β x β K }
theorem le_def : β {S T : A }, S β€ T β β β¦x : B β¦, x β S β x β T le_def { S T : A } : S β€ T β β β¦ x : B β¦, x β S β x β T :=
Iff.rfl
#align set_like.le_def SetLike.le_def
@[ simp , norm_cast ]
theorem coe_subset_coe : β {S T : A }, βS β βT β S β€ T coe_subset_coe { S T : A } : ( S : Set B ) β T β S β€ T :=
Iff.rfl
#align set_like.coe_subset_coe SetLike.coe_subset_coe
@[ mono ]
theorem coe_mono : Monotone ( SetLike.coe : A β Set B ) := fun _ _ => coe_subset_coe . mpr : β {a b : Prop }, (a β b ) β b β a mpr
#align set_like.coe_mono SetLike.coe_mono
@[ simp , norm_cast ]
theorem coe_ssubset_coe : β {S T : A }, βS β βT β S < T coe_ssubset_coe { S T : A } : ( S : Set B ) β T β S < T :=
Iff.rfl
#align set_like.coe_ssubset_coe SetLike.coe_ssubset_coe
@[ mono ]
theorem coe_strictMono : StrictMono ( SetLike.coe : A β Set B ) := fun _ _ => coe_ssubset_coe . mpr : β {a b : Prop }, (a β b ) β b β a mpr
#align set_like.coe_strict_mono SetLike.coe_strictMono
theorem not_le_iff_exists : Β¬ p β€ q β β x β p , x β q :=
Set.not_subset
#align set_like.not_le_iff_exists SetLike.not_le_iff_exists
theorem exists_of_lt : p < q β β x β q , x β p :=
Set.exists_of_ssubset
#align set_like.exists_of_lt SetLike.exists_of_lt
theorem lt_iff_le_and_exists : p < q β p β€ q β§ β x β q , x β p := by
rw [ lt_iff_le_not_le , not_le_iff_exists ]
#align set_like.lt_iff_le_and_exists SetLike.lt_iff_le_and_exists
end SetLike