summaryrefslogtreecommitdiff
path: root/src/Obs/Universe.idr
blob: 1517c4c4cb59a0844d3ab8e152cb1c04bb2b4809 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
||| Provides definitions of proof-relevance and type universes.
module Obs.Universe

import Data.Bool
import Data.Bool.Decidable
import Data.Nat
import Data.Nat.Order.Properties
import Data.So

import Decidable.Equality

import Text.PrettyPrint.Prettyprinter

%default total

-- Definition ------------------------------------------------------------------

||| Proof relevance of terms
public export
data Relevance = Irrelevant | Relevant

%name Relevance r, r'

||| Type universes.
public export
data Universe : Type where
  ||| Impredicative universe of strict propositions.
  Prop : Universe
  ||| Predicative hierarchy of universes.
  Set  : Nat -> Universe

%name Universe s, s', s'', s'''

||| Converts universes to naturals as a helper for writing implementations.
public export
toNat : Universe -> Nat
toNat Prop = 0
toNat (Set i) = S i

-- Interfaces ------------------------------------------------------------------

public export
Eq Relevance where
  Irrelevant == Irrelevant = True
  Relevant == Relevant = True
  _ == _ = False

export
Uninhabited (Irrelevant = Relevant) where uninhabited Refl impossible

export
Uninhabited (Relevant = Irrelevant) where uninhabited Refl impossible

export
DecEq Relevance where
  decEq Irrelevant Irrelevant = Yes Refl
  decEq Irrelevant Relevant = No absurd
  decEq Relevant Irrelevant = No absurd
  decEq Relevant Relevant = Yes Refl

public export
Eq Universe where
  (==) = (==) `on` toNat

public export
Ord Universe where
  compare = compare `on` toNat
  (<) = lt `on` toNat
  (>) = gt `on` toNat
  (<=) = lte `on` toNat
  (>=) = gte `on` toNat

  min Prop s' = Prop
  min (Set _) Prop = Prop
  min (Set i) (Set j) = Set (minimum i j)

  max Prop s' = s'
  max (Set i) s' = Set (maximum i (pred $ toNat s'))

export
Uninhabited (Prop = Set i) where uninhabited Refl impossible

export
Uninhabited (Set i = Prop) where uninhabited Refl impossible

export
Injective Set where
  injective Refl = Refl

public export
DecEq Universe where
  decEq Prop Prop = Yes Refl
  decEq Prop (Set _) = No absurd
  decEq (Set _) Prop = No absurd
  decEq (Set i) (Set j) = decEqCong $ decEq i j

export
Show Universe where
  showPrec d Prop = "Prop"
  showPrec d (Set 0) = "Set"
  showPrec d (Set (S i)) = showParens (d >= App) $ "Set \{show (S i)}"

export
Pretty Universe where
  prettyPrec d Prop = pretty "Prop"
  prettyPrec d (Set 0) = pretty "Set"
  prettyPrec d (Set (S i)) = parenthesise (d >= App) $ pretty "Set \{show (S i)}"

-- Operations ------------------------------------------------------------------

infixr 5 ~>

||| Computes the proof-relevance of a pair.
public export
pair : (fst, snd : Relevance) -> Relevance
pair Irrelevant = id
pair Relevant = const Relevant

||| Computes the proof-relevance of a function.
public export
function : (dom, cod : Relevance) -> Relevance
function = const id

||| Gets the proof-relevance of values in a universe.
public export
relevance : Universe -> Relevance
relevance Prop = Irrelevant
relevance (Set k) = Relevant

||| True if values in `s` are proof-irrelevant.
public export
isIrrelevant : (s : Universe) -> Bool
isIrrelevant = (Irrelevant ==) . relevance

||| True if values in `s` are proof-relevant.
public export
isRelevant : (s : Universe) -> Bool
isRelevant = (Relevant ==) . relevance

||| Returns the smallest universe containing `s`
||| @ s the universe to contain
public export
succ : (s : Universe) -> Universe
succ = Set . toNat

||| The universe of a dependent product.
||| @ dom the domain universe
||| @ cod the codomain universe
public export
(~>) : (dom, cod : Universe) -> Universe
dom ~> Prop    = Prop
dom ~> (Set k) = max (Set k) dom

-- Views -----------------------------------------------------------------------

namespace Predicates
  public export
  data IsIrrelevant : Universe -> Type where
    Prop : IsIrrelevant Prop

  public export
  data IsRelevant : Universe -> Type where
    Set : IsRelevant (Set k)

  export
  Uninhabited (IsIrrelevant (Set k)) where
    uninhabited _ impossible

  export
  Uninhabited (IsRelevant Prop) where
    uninhabited _ impossible

  export
  isIrrelevant : (s : Universe) -> Dec (IsIrrelevant s)
  isIrrelevant Prop = Yes Prop
  isIrrelevant (Set k) = No absurd

  export
  isRelevant : (s : Universe) -> Dec (IsRelevant s)
  isRelevant Prop = No absurd
  isRelevant (Set k) = Yes Set

-- Properties ------------------------------------------------------------------

export
pairRelevantRight : (fst : Relevance) -> pair fst Relevant = Relevant
pairRelevantRight Irrelevant = Refl
pairRelevantRight Relevant = Refl

succContains : (s : Universe) -> So (s < succ s)
succContains Prop = Oh
succContains (Set k) = eqToSo $ LteIslte k k reflexive

succLeast : (s, s' : Universe) -> So (s < s') -> So (succ s <= s')
succLeast s s' prf = prf

irrelevantReflection : (s : Universe) -> Reflects (IsIrrelevant s) (isIrrelevant s)
irrelevantReflection Prop = RTrue Prop
irrelevantReflection (Set k) = RFalse absurd

relevantReflection : (s : Universe) -> Reflects (IsRelevant s) (isRelevant s)
relevantReflection Prop = RFalse absurd
relevantReflection (Set k) = RTrue Set

export
forgetIsIrrelevant : IsIrrelevant s -> relevance s = Irrelevant
forgetIsIrrelevant Prop = Refl

export
forgetIsRelevant : IsRelevant s -> relevance s = Relevant
forgetIsRelevant Set = Refl

export
pairRelevance : (s, s' : Universe) -> relevance (max s s') = pair (relevance s) (relevance s')
pairRelevance Prop s' = Refl
pairRelevance (Set k) s' = Refl

export
functionRelevance : (s, s' : Universe) ->
  relevance (s ~> s') = function (relevance s) (relevance s')
functionRelevance s Prop = Refl
functionRelevance s (Set k) = Refl