@@ -3,14 +3,29 @@ Copyright (c) 2017 Johannes Hölzl. All rights reserved.
3
3
Released under Apache 2.0 license as described in the file LICENSE.
4
4
Authors: Johannes Hölzl
5
5
-/
6
- import tactic.lint
7
6
import tactic.ext
7
+ import tactic.lint
8
8
import tactic.simps
9
9
10
+ /-!
11
+ # Subtypes
12
+
13
+ This file provides basic API for subtypes, which are defined in core.
14
+
15
+ A subtype is a type made from restricting another type, say `α`, to its elements that satisfy some
16
+ predicate, say `p : α → Prop`. Specifically, it is the type of pairs `⟨val, property⟩` where
17
+ `val : α` and `property : p val`. It is denoted `subtype p` and notation `{val : α // p val}` is
18
+ available.
19
+
20
+ A subtype has a natural coercion to the parent type, by coercing `⟨val, property⟩` to `val`. As
21
+ such, subtypes can be thought of as bundled sets, the difference being that elements of a set are
22
+ still of type `α` while elements of a subtype aren't.
23
+ -/
24
+
10
25
open function
11
26
12
27
namespace subtype
13
- variables {α : Sort *} {β : Sort *} { γ : Sort *} {p : α → Prop } { q : α → Prop }
28
+ variables {α β γ : Sort *} {p q : α → Prop }
14
29
15
30
/-- See Note [custom simps projection] -/
16
31
def simps.coe (x : subtype p) : α := x
@@ -29,7 +44,7 @@ lemma prop (x : subtype p) : p x := x.2
29
44
30
45
/-- An alternative version of `subtype.forall`. This one is useful if Lean cannot figure out `q`
31
46
when using `subtype.forall` from right to left. -/
32
- protected theorem forall' {q : ∀x, p x → Prop } :
47
+ protected theorem forall' {q : ∀ x, p x → Prop } :
33
48
(∀ x h, q x h) ↔ (∀ x : {a // p a}, q x x.2 ) :=
34
49
(@subtype.forall _ _ (λ x, q x.1 x.2 )).symm
35
50
@@ -76,10 +91,10 @@ theorem val_injective : injective (@val _ p) :=
76
91
coe_injective
77
92
78
93
/-- Restrict a (dependent) function to a subtype -/
79
- def restrict {α} {β : α → Type *} (f : Πx , β x) (p : α → Prop ) (x : subtype p) : β x.1 :=
94
+ def restrict {α} {β : α → Type *} (f : Π x , β x) (p : α → Prop ) (x : subtype p) : β x.1 :=
80
95
f x
81
96
82
- lemma restrict_apply {α} {β : α → Type *} (f : Πx , β x) (p : α → Prop ) (x : subtype p) :
97
+ lemma restrict_apply {α} {β : α → Type *} (f : Π x , β x) (p : α → Prop ) (x : subtype p) :
83
98
restrict f p x = f x.1 :=
84
99
by refl
85
100
@@ -91,39 +106,39 @@ lemma restrict_injective {α β} {f : α → β} (p : α → Prop) (h : injectiv
91
106
h.comp coe_injective
92
107
93
108
/-- Defining a map into a subtype, this can be seen as an "coinduction principle" of `subtype`-/
94
- @[simps] def coind {α β} (f : α → β) {p : β → Prop } (h : ∀a, p (f a)) : α → subtype p :=
109
+ @[simps] def coind {α β} (f : α → β) {p : β → Prop } (h : ∀ a, p (f a)) : α → subtype p :=
95
110
λ a, ⟨f a, h a⟩
96
111
97
- theorem coind_injective {α β} {f : α → β} {p : β → Prop } (h : ∀a, p (f a))
112
+ theorem coind_injective {α β} {f : α → β} {p : β → Prop } (h : ∀ a, p (f a))
98
113
(hf : injective f) : injective (coind f h) :=
99
114
λ x y hxy, hf $ by apply congr_arg subtype.val hxy
100
115
101
- theorem coind_surjective {α β} {f : α → β} {p : β → Prop } (h : ∀a, p (f a))
116
+ theorem coind_surjective {α β} {f : α → β} {p : β → Prop } (h : ∀ a, p (f a))
102
117
(hf : surjective f) : surjective (coind f h) :=
103
118
λ x, let ⟨a, ha⟩ := hf x in ⟨a, coe_injective ha⟩
104
119
105
- theorem coind_bijective {α β} {f : α → β} {p : β → Prop } (h : ∀a, p (f a))
120
+ theorem coind_bijective {α β} {f : α → β} {p : β → Prop } (h : ∀ a, p (f a))
106
121
(hf : bijective f) : bijective (coind f h) :=
107
122
⟨coind_injective h hf.1 , coind_surjective h hf.2 ⟩
108
123
109
124
/-- Restriction of a function to a function on subtypes. -/
110
- @[simps] def map {p : α → Prop } {q : β → Prop } (f : α → β) (h : ∀a, p a → q (f a)) :
125
+ @[simps] def map {p : α → Prop } {q : β → Prop } (f : α → β) (h : ∀ a, p a → q (f a)) :
111
126
subtype p → subtype q :=
112
127
λ x, ⟨f x, h x x.prop⟩
113
128
114
129
theorem map_comp {p : α → Prop } {q : β → Prop } {r : γ → Prop } {x : subtype p}
115
- (f : α → β) (h : ∀a, p a → q (f a)) (g : β → γ) (l : ∀a, q a → r (g a)) :
130
+ (f : α → β) (h : ∀ a, p a → q (f a)) (g : β → γ) (l : ∀ a, q a → r (g a)) :
116
131
map g l (map f h x) = map (g ∘ f) (assume a ha, l (f a) $ h a ha) x :=
117
132
rfl
118
133
119
- theorem map_id {p : α → Prop } {h : ∀a, p a → p (id a)} : map (@id α) h = id :=
134
+ theorem map_id {p : α → Prop } {h : ∀ a, p a → p (id a)} : map (@id α) h = id :=
120
135
funext $ assume ⟨v, h⟩, rfl
121
136
122
- lemma map_injective {p : α → Prop } {q : β → Prop } {f : α → β} (h : ∀a, p a → q (f a))
137
+ lemma map_injective {p : α → Prop } {q : β → Prop } {f : α → β} (h : ∀ a, p a → q (f a))
123
138
(hf : injective f) : injective (map f h) :=
124
139
coind_injective _ $ hf.comp coe_injective
125
140
126
- lemma map_involutive {p : α → Prop } {f : α → α} (h : ∀a, p a → p (f a))
141
+ lemma map_involutive {p : α → Prop } {f : α → α} (h : ∀ a, p a → p (f a))
127
142
(hf : involutive f) : involutive (map f h) :=
128
143
λ x, subtype.ext (hf x)
129
144
@@ -155,7 +170,7 @@ end subtype
155
170
156
171
namespace subtype
157
172
/-! Some facts about sets, which require that `α` is a type. -/
158
- variables {α : Type *} {β : Type *} { γ : Type *} {p : α → Prop }
173
+ variables {α β γ : Type *} {p : α → Prop }
159
174
160
175
@[simp] lemma coe_prop {S : set α} (a : {a // a ∈ S}) : ↑a ∈ S := a.prop
161
176
0 commit comments