Skip to content

Commit 6dc0886

Browse files
Add boolean builtins in Nat (#1262)
* Add boolean builtins in `Nat` and update dependencies for compatibility * add reference to an example of how to use `UsingEq` in a with-abstraction * remove `UsingEq` where not needed, remove case split on `m` and `n` on `discreteℕ` * remove unnecessary case split on `m` and `n` in the definition of `_≟_` * add comment about `inspect`
1 parent 86485a5 commit 6dc0886

File tree

7 files changed

+154
-32
lines changed

7 files changed

+154
-32
lines changed

Cubical/Algebra/DirectSum/Equiv-DSHIT-DSFun.agda

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ module Equiv-Properties
386386
lemmakk zero a = cong (base 0) (transportRefl a)
387387
lemmakk (suc k) a with (discreteℕ (suc k) (suc k)) | (discreteℕ k k)
388388
... | yes p | yes q = cong₂ _add_
389-
(sym (constSubstCommSlice G (⊕HIT ℕ G Gstr) base (cong suc q) a))
389+
(sym (constSubstCommSlice G (⊕HIT ℕ G Gstr) base p a))
390390
(lemmaSkk (suc k) a k ≤-refl)
391391
∙ +⊕HIT-IdR _
392392
... | yes p | no ¬q = ⊥.rec (¬q refl)

Cubical/Algebra/Semilattice/Instances/NatMax.agda

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,22 @@ isSemilattice maxSemilatticeStr = makeIsSemilattice isSetℕ maxAssoc maxRId max
3535
maxAssoc : (x y z : ℕ) max x (max y z) ≡ max (max x y) z
3636
maxAssoc zero y z = refl
3737
maxAssoc (suc x) zero z = refl
38-
maxAssoc (suc x) (suc y) zero = refl
39-
maxAssoc (suc x) (suc y) (suc z) = cong suc (maxAssoc x y z)
38+
maxAssoc (suc x) (suc y) zero = maxSuc ∙ cong (λ p max p _) (sym (maxSuc {x} {y}))
39+
maxAssoc (suc x) (suc y) (suc z) =
40+
max (suc x) (max (suc y) (suc z)) ≡⟨ cong (max _) (maxSuc {y} {z}) ⟩
41+
max (suc x) (suc (max y z)) ≡⟨ maxSuc ⟩
42+
suc (max x (max y z)) ≡⟨ cong suc (maxAssoc x y z) ⟩
43+
suc (max (max x y) z) ≡⟨ sym maxSuc ⟩
44+
max (suc (max x y)) (suc z) ≡⟨ cong (λ p max p _) (sym (maxSuc {x} {y})) ⟩
45+
max (max (suc x) (suc y)) (suc z) ∎
4046

4147
maxRId : (x : ℕ) max x 0 ≡ x
4248
maxRId zero = refl
4349
maxRId (suc x) = refl
4450

4551
maxIdem : (x : ℕ) max x x ≡ x
4652
maxIdem zero = refl
47-
maxIdem (suc x) = cong suc (maxIdem x)
48-
53+
maxIdem (suc x) = maxSuc ∙ cong suc (maxIdem x)
4954

5055

5156
--characterisation of inequality
@@ -54,13 +59,13 @@ open JoinSemilattice (ℕ , maxSemilatticeStr) renaming (_≤_ to _≤max_)
5459
≤max→≤ℕ : x y x ≤max y x ≤ℕ y
5560
≤max→≤ℕ zero y _ = zero-≤
5661
≤max→≤ℕ (suc x) zero p = ⊥.rec (snotz p)
57-
≤max→≤ℕ (suc x) (suc y) p = let (k , q) = ≤max→≤ℕ x y (cong predℕ p) in
62+
≤max→≤ℕ (suc x) (suc y) p = let (k , q) = ≤max→≤ℕ x y (cong predℕ (sym maxSuc ∙ p)) in
5863
k , +-suc k x ∙ cong suc q
5964

6065
≤ℕ→≤max : x y x ≤ℕ y x ≤max y
6166
≤ℕ→≤max zero y _ = refl
6267
≤ℕ→≤max (suc x) zero p = ⊥.rec (¬-<-zero p)
63-
≤ℕ→≤max (suc x) (suc y) (k , p) = cong suc (≤ℕ→≤max x y (k , q))
68+
≤ℕ→≤max (suc x) (suc y) (k , p) = maxSuc ∙ cong suc (≤ℕ→≤max x y (k , q))
6469
where
6570
q : k +ℕ x ≡ y
6671
q = cong predℕ (sym (+-suc k x) ∙ p)

Cubical/Data/Nat/Base.agda

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module Cubical.Data.Nat.Base where
33

44
open import Agda.Builtin.Nat public
55
using (zero; suc; _+_)
6-
renaming (Nat to ℕ; _-_ to _∸_; _*_ to _·_)
6+
renaming (Nat to ℕ; _-_ to _∸_; _*_ to _·_ ; _<_ to _<ᵇ_ ; _==_ to _≡ᵇ_)
77

88
open import Cubical.Data.Nat.Literals public
99
open import Cubical.Data.Bool.Base

Cubical/Data/Nat/Order.agda

Lines changed: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ open import Cubical.Data.Empty as ⊥
1010
open import Cubical.Data.Sigma
1111
open import Cubical.Data.Sum as ⊎
1212

13+
open import Cubical.Data.Bool.Base hiding (_≟_)
14+
1315
open import Cubical.Data.Nat.Base
1416
open import Cubical.Data.Nat.Properties
1517

@@ -258,22 +260,59 @@ predℕ-≤-predℕ {suc m} {suc n} ineq = pred-≤-pred ineq
258260
left-≤-max : m ≤ max m n
259261
left-≤-max {zero} {n} = zero-≤
260262
left-≤-max {suc m} {zero} = ≤-refl
261-
left-≤-max {suc m} {suc n} = suc-≤-suc left-≤-max
263+
left-≤-max {suc m} {suc n} = subst (_ ≤_) (sym maxSuc) $ suc-≤-suc $ left-≤-max {m} {n}
262264

263265
right-≤-max : n ≤ max m n
264266
right-≤-max {zero} {m} = zero-≤
265267
right-≤-max {suc n} {zero} = ≤-refl
266-
right-≤-max {suc n} {suc m} = suc-≤-suc right-≤-max
268+
right-≤-max {suc n} {suc m} = subst (_ ≤_) (sym maxSuc) $ suc-≤-suc $ right-≤-max {n} {m}
267269

268270
min-≤-left : min m n ≤ m
269271
min-≤-left {zero} {n} = ≤-refl
270272
min-≤-left {suc m} {zero} = zero-≤
271-
min-≤-left {suc m} {suc n} = suc-≤-suc min-≤-left
273+
min-≤-left {suc m} {suc n} = subst (_≤ _) (sym minSuc) $ suc-≤-suc $ min-≤-left {m} {n}
272274

273275
min-≤-right : min m n ≤ n
274276
min-≤-right {zero} {n} = zero-≤
275277
min-≤-right {suc m} {zero} = ≤-refl
276-
min-≤-right {suc m} {suc n} = suc-≤-suc min-≤-right
278+
min-≤-right {suc m} {suc n} = subst (_≤ _) (sym minSuc) $ suc-≤-suc $ min-≤-right {m} {n}
279+
280+
-- Boolean order relations and their conversions to/from ≤ and <
281+
282+
_≤ᵇ_ : Bool
283+
m ≤ᵇ n = m <ᵇ suc n
284+
285+
_≥ᵇ_ : Bool
286+
m ≥ᵇ n = n ≤ᵇ m
287+
288+
_>ᵇ_ : Bool
289+
m >ᵇ n = n <ᵇ m
290+
291+
private
292+
≤ᵇ-∸-+-cancel : m n Bool→Type (m ≤ᵇ n) (n ∸ m) + m ≡ n
293+
≤ᵇ-∸-+-cancel zero zero t = refl
294+
≤ᵇ-∸-+-cancel zero (suc n) t = +-zero (suc n)
295+
≤ᵇ-∸-+-cancel (suc m) (suc n) t = +-suc (n ∸ m) m ∙ cong suc (≤ᵇ-∸-+-cancel m n t)
296+
297+
<ᵇ→< : Bool→Type (m <ᵇ n) m < n
298+
<ᵇ→< {m} {suc n} t .fst = n ∸ m
299+
<ᵇ→< {m} {suc n} t .snd =
300+
n ∸ m + suc m ≡⟨ +-suc (n ∸ m) m ⟩
301+
suc (n ∸ m + m) ≡⟨ cong suc (≤ᵇ-∸-+-cancel m n t) ⟩
302+
suc n ∎
303+
304+
<→<ᵇ : m < n Bool→Type (m <ᵇ n)
305+
<→<ᵇ {m} {zero} m<0 = ¬-<-zero m<0
306+
<→<ᵇ {zero} {suc n} 0<sn = tt
307+
<→<ᵇ {suc m} {suc n} sm<sn = <→<ᵇ (pred-≤-pred sm<sn)
308+
309+
≤ᵇ→≤ : Bool→Type (m ≤ᵇ n) m ≤ n
310+
≤ᵇ→≤ {zero} {n} t = zero-≤
311+
≤ᵇ→≤ {suc m} {suc n} t = <ᵇ→< t
312+
313+
≤→≤ᵇ : m ≤ n Bool→Type (m ≤ᵇ n)
314+
≤→≤ᵇ {zero} {n} 0≤n = tt
315+
≤→≤ᵇ {suc m} {n} sm≤n = <→<ᵇ sm≤n
277316

278317
≤Dec : m n Dec (m ≤ n)
279318
≤Dec zero n = yes (n , +-zero _)
@@ -296,11 +335,27 @@ Trichotomy-suc (lt m<n) = lt (suc-≤-suc m<n)
296335
Trichotomy-suc (eq m=n) = eq (cong suc m=n)
297336
Trichotomy-suc (gt n<m) = gt (suc-≤-suc n<m)
298337

338+
private
339+
∸→>ᵇ : m n caseNat ⊥.⊥ Unit (m ∸ n) Bool→Type (m >ᵇ n)
340+
∸→>ᵇ (suc m) zero t = tt
341+
∸→>ᵇ (suc m) (suc n) t = ∸→>ᵇ m n t
342+
299343
_≟_ : m n Trichotomy m n
300-
zero ≟ zero = eq refl
301-
zero ≟ suc n = lt (n , +-comm n 1)
302-
suc m ≟ zero = gt (m , +-comm m 1)
303-
suc m ≟ suc n = Trichotomy-suc (m ≟ n)
344+
m ≟ n with m ∸ n UsingEq | n ∸ m UsingEq
345+
... | zero , p | zero , q = eq (∸≡0→≡ p q)
346+
... | zero , p | suc _ , q = lt (<ᵇ→< $ ∸→>ᵇ n m $ subst (caseNat ⊥.⊥ Unit) (sym q) tt)
347+
... | suc _ , p | zero , q = gt (<ᵇ→< $ ∸→>ᵇ m n $ subst (caseNat ⊥.⊥ Unit) (sym p) tt)
348+
... | suc _ , p | suc _ , q = ⊥.rec $ ¬m<m {m} $ <-trans
349+
(<ᵇ→< $ ∸→>ᵇ n m $ subst (caseNat ⊥.⊥ Unit) (sym q) tt)
350+
(<ᵇ→< $ ∸→>ᵇ m n $ subst (caseNat ⊥.⊥ Unit) (sym p) tt)
351+
352+
-- Alternative version of ≟, defined without builtin primitives
353+
354+
_≟'_ : m n Trichotomy m n
355+
zero ≟' zero = eq refl
356+
zero ≟' suc n = lt (n , +-comm n 1)
357+
suc m ≟' zero = gt (m , +-comm m 1)
358+
suc m ≟' suc n = Trichotomy-suc (m ≟' n)
304359

305360
Dichotomyℕ : (n m : ℕ) (n ≤ m) ⊎ (n > m)
306361
Dichotomyℕ n m with (n ≟ m)
@@ -331,7 +386,10 @@ splitℕ-< m n with m ≟ n
331386
<-split : m < suc n (m < n) ⊎ (m ≡ n)
332387
<-split {n = zero} = inr ∘ snd ∘ m+n≡0→m≡0×n≡0 ∘ snd ∘ pred-≤-pred
333388
<-split {zero} {suc n} = λ _ inl (suc-≤-suc zero-≤)
334-
<-split {suc m} {suc n} = ⊎.map suc-≤-suc (cong suc) ∘ <-split ∘ pred-≤-pred
389+
<-split {suc m} {suc n} sm<ssn with m ≟ n
390+
... | lt m<n = inl (suc-≤-suc m<n)
391+
... | eq m≡n = inr (cong suc m≡n)
392+
... | gt n<m = ⊥.rec $ ¬m<m {suc (suc n)} $ ≤-trans (suc-≤-suc (suc-≤-suc n<m)) sm<ssn
335393

336394
≤-split : m ≤ n (m < n) ⊎ (m ≡ n)
337395
≤-split p = <-split (suc-≤-suc p)

Cubical/Data/Nat/Properties.agda

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ open import Cubical.Data.Empty as ⊥
1212
open import Cubical.Data.Sigma
1313
open import Cubical.Data.Sum.Base
1414

15+
open import Cubical.Data.Bool.Base
16+
1517
open import Cubical.Relation.Nullary
1618

1719
private
@@ -21,24 +23,44 @@ private
2123
min :
2224
min zero m = zero
2325
min (suc n) zero = zero
24-
min (suc n) (suc m) = suc (min n m)
26+
min (suc n) (suc m) with n <ᵇ m
27+
... | false = suc m
28+
... | true = suc n
29+
30+
minSuc : min (suc n) (suc m) ≡ suc (min n m)
31+
minSuc {zero} {zero} = refl
32+
minSuc {zero} {suc m} = refl
33+
minSuc {suc n} {zero} = refl
34+
minSuc {suc n} {suc m} with suc n <ᵇ suc m
35+
... | false = refl
36+
... | true = refl
2537

2638
minComm : (n m : ℕ) min n m ≡ min m n
2739
minComm zero zero = refl
2840
minComm zero (suc m) = refl
2941
minComm (suc n) zero = refl
30-
minComm (suc n) (suc m) = cong suc (minComm n m)
42+
minComm (suc n) (suc m) = minSuc ∙∙ cong suc (minComm n m) ∙∙ sym minSuc
3143

3244
max :
3345
max zero m = m
3446
max (suc n) zero = suc n
35-
max (suc n) (suc m) = suc (max n m)
47+
max (suc n) (suc m) with n <ᵇ m
48+
... | false = suc n
49+
... | true = suc m
50+
51+
maxSuc : max (suc n) (suc m) ≡ suc (max n m)
52+
maxSuc {zero} {zero} = refl
53+
maxSuc {zero} {suc m} = refl
54+
maxSuc {suc n} {zero} = refl
55+
maxSuc {suc n} {suc m} with suc n <ᵇ suc m
56+
... | false = refl
57+
... | true = refl
3658

3759
maxComm : (n m : ℕ) max n m ≡ max m n
3860
maxComm zero zero = refl
3961
maxComm zero (suc m) = refl
4062
maxComm (suc n) zero = refl
41-
maxComm (suc n) (suc m) = cong suc (maxComm n m)
63+
maxComm (suc n) (suc m) = maxSuc ∙∙ cong suc (maxComm n m) ∙∙ sym maxSuc
4264

4365
znots : ¬ (0 ≡ suc n)
4466
znots eq = subst (caseNat ℕ ⊥) eq 0
@@ -122,14 +144,22 @@ decodeℕ (suc n) (suc m) = λ r → cong suc (decodeℕ n m r)
122144
retr : (n m : ℕ) (p : n ≡ m) decodeℕ n m (compute-eqℕ n m p) ≡ p
123145
retr n m p = J (λ m p decodeℕ n m (compute-eqℕ n m p) ≡ p) (reflRetr n) p
124146

147+
-- Conversions between boolean equality (≡ᵇ) and path equality (≡)
148+
149+
≡ᵇ→≡ : Bool→Type (m ≡ᵇ n) m ≡ n
150+
≡ᵇ→≡ {zero} {zero} t = refl
151+
≡ᵇ→≡ {suc m} {suc n} t = cong suc (≡ᵇ→≡ t)
152+
153+
≡→≡ᵇ : m ≡ n Bool→Type (m ≡ᵇ n)
154+
≡→≡ᵇ {zero} {zero} _ = tt
155+
≡→≡ᵇ {zero} {suc n} p = ⊥.rec (znots p)
156+
≡→≡ᵇ {suc m} {zero} p = ⊥.rec (snotz p)
157+
≡→≡ᵇ {suc m} {suc n} p = ≡→≡ᵇ {m} {n} (cong predℕ p)
125158

126159
discreteℕ : Discrete ℕ
127-
discreteℕ zero zero = yes refl
128-
discreteℕ zero (suc n) = no znots
129-
discreteℕ (suc m) zero = no snotz
130-
discreteℕ (suc m) (suc n) with discreteℕ m n
131-
... | yes p = yes (cong suc p)
132-
... | no p = no (λ x p (injSuc x))
160+
discreteℕ m n with m ≡ᵇ n UsingEq
161+
... | false , p = no (subst Bool→Type p ∘ ≡→≡ᵇ)
162+
... | true , p = yes (≡ᵇ→≡ (subst Bool→Type (sym p) tt))
133163

134164
separatedℕ : Separated ℕ
135165
separatedℕ = Discrete→Separated discreteℕ
@@ -270,6 +300,12 @@ n∸n (suc n) = n∸n n
270300
∸-distribʳ zero (suc n) k = sym (zero∸ (k + n · k))
271301
∸-distribʳ (suc m) (suc n) k = ∸-distribʳ m n k ∙ sym (∸-cancelˡ k (m · k) (n · k))
272302

303+
∸≡0→≡ : m ∸ n ≡ 0 n ∸ m ≡ 0 m ≡ n
304+
∸≡0→≡ {zero} {zero} _ _ = refl
305+
∸≡0→≡ {zero} {suc n} _ q = ⊥.rec (snotz q)
306+
∸≡0→≡ {suc m} {zero} p _ = ⊥.rec (snotz p)
307+
∸≡0→≡ {suc m} {suc n} p q = cong suc (∸≡0→≡ {m} {n} p q)
308+
273309
infix 6 _!
274310
infix 7 _choose_
275311

Cubical/Foundations/Prelude.agda

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,20 @@ isContrSinglP A a .fst = _ , transport-filler (λ i → A i) a
498498
isContrSinglP A a .snd (x , p) i =
499499
_ , λ j fill A (λ j λ {(i = i0) transport-filler (λ i A i) a j; (i = i1) p j}) (inS a) j
500500

501+
-- Helpers for carrying equalities into with-abstractions
502+
-- see `discreteℕ` in Data.Nat.Properties for an example of usage
503+
504+
infixl 0 _UsingEq
505+
infixl 0 _i0:>_UsingEqP
506+
507+
-- Similar to `inspect`, but more convenient when `a` is not a function
508+
-- application, or when the applied function is not relevant
509+
_UsingEq : (a : A) singl a
510+
a UsingEq = isContrSingl a .fst
511+
512+
_i0:>_UsingEqP : (A : I Type ℓ) (a : A i0) singlP A a
513+
A i0:> a UsingEqP = isContrSinglP A a .fst
514+
501515
-- Higher cube types
502516

503517
SquareP :

Cubical/HITs/Truncation/Properties.agda

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,24 +213,33 @@ isOfHLevelMin→isOfHLevel {n = suc n} {m = zero} h = (isContr→isOfHLevel (suc
213213
isOfHLevelMin→isOfHLevel {A = A} {n = suc n} {m = suc m} h =
214214
subst (λ x isOfHLevel x A) (helper n m)
215215
(isOfHLevelPlus (suc n ∸ (suc (min n m))) h)
216-
, subst (λ x isOfHLevel x A) ((λ i m ∸ (minComm n m i) + suc (minComm n m i)) ∙ helper m n)
216+
, subst (λ x isOfHLevel x A) ((λ i m ∸ (minComm n m i) + (minComm (suc n) (suc m) i)) ∙ helper m n)
217217
(isOfHLevelPlus (suc m ∸ (suc (min n m))) h)
218218
where
219-
helper : (n m : ℕ) n ∸ min n m + suc (min n m) ≡ suc n
219+
helper : (n m : ℕ) n ∸ min n m + min (suc n) (suc m) ≡ suc n
220220
helper zero zero = refl
221221
helper zero (suc m) = refl
222222
helper (suc n) zero = cong suc (+-comm n 1)
223-
helper (suc n) (suc m) = +-suc _ _ ∙ cong suc (helper n m)
223+
helper (suc n) (suc m) =
224+
suc n ∸ min (suc n) (suc m) + min (suc (suc n)) (suc (suc m)) ≡⟨ step0 ⟩
225+
suc n ∸ suc (min n m) + suc (min (suc n) (suc m)) ≡⟨⟩
226+
n ∸ min n m + suc (min (suc n) (suc m)) ≡⟨ step1 ⟩
227+
suc (n ∸ min n m + min (suc n) (suc m)) ≡⟨ step2 ⟩
228+
suc (suc n) ∎
229+
where
230+
step0 = cong₂ (λ p suc n ∸ p +_) (minSuc {n}) minSuc
231+
step1 = +-suc _ _
232+
step2 = cong suc (helper n m)
224233

225234
ΣTruncElim : {ℓ ℓ' ℓ''} {A : Type ℓ} {n m : ℕ}
226235
{B : (x : ∥ A ∥ n) Type ℓ'}
227236
{C : (Σ[ a ∈ (∥ A ∥ n) ] (∥ B a ∥ m)) Type ℓ''}
228237
((x : (Σ[ a ∈ (∥ A ∥ n) ] (∥ B a ∥ m))) isOfHLevel (min n m) (C x))
229238
((a : A) (b : B (∣ a ∣ₕ)) C (∣ a ∣ₕ , ∣ b ∣ₕ))
230239
(x : (Σ[ a ∈ (∥ A ∥ n) ] (∥ B a ∥ m))) C x
231-
ΣTruncElim hB g (a , b) =
240+
ΣTruncElim {n = n} hB g (a , b) =
232241
elim (λ x isOfHLevelΠ _ λ b isOfHLevelMin→isOfHLevel (hB (x , b)) .fst )
233-
(λ a elim (λ _ isOfHLevelMin→isOfHLevel (hB (∣ a ∣ₕ , _)) .snd) λ b g a b)
242+
(λ a elim (λ _ isOfHLevelMin→isOfHLevel {n = n} (hB (∣ a ∣ₕ , _)) .snd) λ b g a b)
234243
a b
235244

236245
truncIdempotentIso : (n : ℕ) isOfHLevel n A Iso (∥ A ∥ n) A

0 commit comments

Comments
 (0)