Skip to content

Commit fbd5cf3

Browse files
committed
Addresses issue agda#2092
1 parent 759bba2 commit fbd5cf3

File tree

6 files changed

+312
-0
lines changed

6 files changed

+312
-0
lines changed

CHANGELOG.md

+13
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,19 @@ Major improvements
985985
* A new module `Algebra.Lattice.Bundles.Raw` is also introduced.
986986
* `RawLattice` has been moved from `Algebra.Lattice.Bundles` to this new module.
987987
988+
### Generalised the definition of `NonZero` from `Data.Nat.Base` to `NonNull` based on:
989+
990+
* A new module `Relation.Unary.Refinement` defining a general notion of refinement
991+
of a type wrt a `Bool`-valued predicate.
992+
993+
* A new module `Relation.Unary.Null` defining being able to test for `null`ity,
994+
based on a `Bool`-valued predicate `null`, using `Refinement`.
995+
996+
* Instances `Data.{Nat|List}.Relation.Unary.Null` of `Null` for `Nat` and `List`.
997+
998+
* Example uses in `README.Data.List.Relation.Unary.Null`
999+
1000+
9881001
Deprecated modules
9891002
------------------
9901003
+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
------------------------------------------------------------------------
2+
-- The Agda standard library
3+
--
4+
-- Illustration of the `NonNull predicate over `List`
5+
------------------------------------------------------------------------
6+
7+
module README.Data.List.Relation.Unary.Null where
8+
9+
open import Data.List.Base using (List; []; _∷_; head)
10+
open import Data.List.Relation.Unary.Null
11+
open import Data.Product.Base using (Σ; _,_; proj₁; proj₂)
12+
open import Level using (Level)
13+
open import Relation.Binary.PropositionalEquality
14+
open import Relation.Unary.Null
15+
open import Relation.Unary.Refinement
16+
17+
private
18+
variable
19+
20+
a b : Level
21+
A : Set a
22+
B : Set b
23+
x : A
24+
xs : List A
25+
ys : List B
26+
27+
------------------------------------------------------------------------
28+
-- Example deployment: a safe head function
29+
30+
safe-head : (xs : List A) .{{NonNull xs}} A
31+
safe-head (x ∷ _) = x
32+
33+
------------------------------------------------------------------------
34+
-- Example deployments: scans
35+
36+
-- ScanL
37+
38+
module ScanL (f : A B A) where
39+
40+
scanl : A List B List A
41+
scanl e [] = e ∷ []
42+
scanl e (x ∷ xs) = e ∷ scanl (f e x) xs
43+
44+
instance scanlNonNull : {e : A} {xs : List B} NonNull (scanl e xs)
45+
scanlNonNull {xs = []} = _
46+
scanlNonNull {xs = x ∷ xs} = _
47+
48+
scanl⁺ : A List B [ List A ]⁺
49+
scanl⁺ e xs = refine⁺ (scanl e xs)
50+
51+
52+
-- ScanR
53+
54+
module ScanRΣ (f : A B B) (e : B) where
55+
56+
-- design pattern: refinement types via Σ-types
57+
58+
scanrΣ : List A Σ (List B) NonNull
59+
scanrΣ [] = e ∷ [] , _
60+
scanrΣ (x ∷ xs) with ys@(y ∷ _) , _ scanrΣ xs = f x y ∷ ys , _
61+
62+
scanr : List A List B
63+
scanr xs = proj₁ (scanrΣ xs)
64+
65+
instance scanrNonNull : {xs : List A} NonNull (scanr xs)
66+
scanrNonNull {xs = xs} = proj₂ (scanrΣ xs)
67+
68+
unfold-scanr-∷ : xs
69+
let ys = scanr xs in
70+
let instance _ = scanrNonNull {xs = xs} in
71+
scanr (x ∷ xs) ≡ f x (safe-head ys) ∷ ys
72+
unfold-scanr-∷ xs with ys@(y ∷ _) , _ scanrΣ xs = refl
73+
74+
module ScanR (f : A B B) (e : B) where
75+
76+
-- design pattern: refinement types via mutual recursion
77+
78+
-- to simulate the refinement type { xs : List A | NonNull xs }
79+
-- define two functions by mutual recursion:
80+
-- `f` : the bare, 'extracted' underlying function
81+
-- `fNonNull` : the (irrelevant instance) witness to the refinement predicate
82+
83+
-- but for now, again we seem to have to go via a third function
84+
-- essentially `scanrΣ` but with an irrelevant instance field instead
85+
86+
scanr⁺ : List A [ List B ]⁺
87+
88+
refine⁻ (scanr⁺ []) = e ∷ []
89+
refined (scanr⁺ []) = _
90+
91+
scanr⁺ (x ∷ xs) with refine⁺ ys scanr⁺ xs with y ∷ _ ys
92+
= refine⁺ (f x y ∷ ys)
93+
94+
scanr : List A List B
95+
scanr xs = refine⁻ (scanr⁺ xs)
96+
97+
instance scanrNonNull : {xs : List A} NonNull (scanr xs)
98+
scanrNonNull {xs = xs} with refine⁺ ys scanr⁺ xs with y ∷ _ ys = _
99+
100+
unfold-scanr-∷ : xs
101+
let ys = scanr xs in
102+
let instance _ = scanrNonNull {xs = xs} in
103+
scanr (x ∷ xs) ≡ f x (safe-head ys) ∷ ys
104+
unfold-scanr-∷ xs with refine⁺ ys scanr⁺ xs with y ∷ _ ys = refl
105+
106+
107+
108+
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
------------------------------------------------------------------------
2+
-- The Agda standard library
3+
--
4+
-- Null instance for List
5+
------------------------------------------------------------------------
6+
7+
{-# OPTIONS --cubical-compatible --safe #-}
8+
9+
module Data.List.Relation.Unary.Null where
10+
11+
open import Data.Nat.Base as Nat using (_>_; z<s)
12+
open import Data.List.Base as List using (List; []; _∷_; length)
13+
open import Level
14+
open import Relation.Binary.PropositionalEquality using (_≢_; refl)
15+
open import Relation.Nullary.Negation.Core using (contradiction)
16+
open import Relation.Unary.Null
17+
18+
private
19+
variable
20+
a : Level
21+
A : Set a
22+
x : A
23+
xs : List A
24+
25+
26+
------------------------------------------------------------------------
27+
-- Instance
28+
29+
instance
30+
nullList : Null (List A)
31+
nullList = record { null = List.null }
32+
33+
------------------------------------------------------------------------
34+
-- NonNull
35+
36+
-- Instances
37+
38+
instance
39+
nonNull : NonNull (x ∷ xs)
40+
nonNull = _
41+
42+
-- Constructors
43+
44+
≢-nonNull : xs ≢ [] NonNull xs
45+
≢-nonNull {xs = []} []≢[] = contradiction refl []≢[]
46+
≢-nonNull {xs = _ ∷ _} xs≢[] = _
47+
48+
>-nonNull : length xs > 0 NonNull xs
49+
>-nonNull {xs = _ ∷ _} _ = _
50+
51+
-- Destructors
52+
53+
≢-nonNull⁻¹ : (xs : List A) .{{NonNull xs}} xs ≢ []
54+
≢-nonNull⁻¹ (_ ∷ _) ()
55+
56+
>-nonNull⁻¹ : (xs : List A) .{{NonNull xs}} length xs > 0
57+
>-nonNull⁻¹ (_ ∷ _) = z<s

src/Data/Nat/Relation/Unary/Null.agda

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
------------------------------------------------------------------------
2+
-- The Agda standard library
3+
--
4+
-- Null instance for ℕ
5+
------------------------------------------------------------------------
6+
7+
{-# OPTIONS --cubical-compatible --safe #-}
8+
9+
module Data.Nat.Relation.Unary.Null where
10+
11+
open import Data.Nat.Base using (ℕ; zero; suc; _≡ᵇ_; _>_; z<s)
12+
open import Level using (Level)
13+
open import Relation.Binary.PropositionalEquality using (_≢_; refl)
14+
open import Relation.Nullary.Negation.Core using (contradiction)
15+
open import Relation.Unary.Null
16+
17+
private
18+
variable
19+
n :
20+
21+
------------------------------------------------------------------------
22+
-- Instance
23+
24+
instance
25+
26+
nullℕ : Null ℕ
27+
nullℕ = record { null = _≡ᵇ 0 }
28+
29+
------------------------------------------------------------------------
30+
-- Simple predicates
31+
32+
-- Instances
33+
34+
instance
35+
nonZero : NonNull (suc n)
36+
nonZero = _
37+
38+
-- Constructors
39+
40+
≢-nonZero : n ≢ 0 NonNull n
41+
≢-nonZero {n = zero} 0≢0 = contradiction refl 0≢0
42+
≢-nonZero {n = suc _} n≢0 = _
43+
44+
>-nonZero : n > 0 NonNull n
45+
>-nonZero z<s = _
46+
47+
-- Destructors
48+
49+
≢-nonZero⁻¹ : n .{{NonNull n}} n ≢ 0
50+
≢-nonZero⁻¹ (suc n) ()
51+
52+
>-nonZero⁻¹ : n .{{NonNull n}} n > 0
53+
>-nonZero⁻¹ (suc n) = z<s
54+

src/Relation/Unary/Null.agda

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
------------------------------------------------------------------------
2+
-- The Agda standard library
3+
--
4+
-- The predicate of being able to decide `null`ity
5+
------------------------------------------------------------------------
6+
7+
{-# OPTIONS --cubical-compatible --safe #-}
8+
9+
module Relation.Unary.Null where
10+
11+
open import Data.Bool.Base using (Bool; not; T)
12+
open import Function.Base using (_∘_)
13+
open import Level
14+
open import Relation.Unary using (Pred)
15+
open import Relation.Unary.Refinement
16+
17+
private
18+
variable
19+
a : Level
20+
A : Set a
21+
22+
------------------------------------------------------------------------
23+
-- Definition
24+
25+
record Null (A : Set a) : Set a where
26+
27+
field
28+
29+
null : A Bool
30+
31+
not-null = not ∘ null
32+
33+
NonNull : {{Null A}} Pred A _
34+
NonNull {{nullA}} = T ∘ not-null where open Null nullA
35+
36+
[_]⁺ : (A : Set a) {{nA : Null A}} Set a
37+
[ A ]⁺ {{nullA}} = [ x ∈ A || not-null x ] where open Null nullA
38+

src/Relation/Unary/Refinement.agda

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
------------------------------------------------------------------------
2+
-- The Agda standard library
3+
--
4+
-- Design pattern: refinement types
5+
------------------------------------------------------------------------
6+
7+
{-# OPTIONS --cubical-compatible --safe #-}
8+
9+
module Relation.Unary.Refinement where
10+
11+
open import Data.Bool.Base using (Bool; T)
12+
open import Level
13+
14+
private
15+
variable
16+
a : Level
17+
18+
------------------------------------------------------------------------
19+
-- Refinement type [ x ∈ A || p ]: like Σ-type, but with irrelevant proj₂
20+
21+
record Refinement {A : Set a} (p : A Bool) : Set a where
22+
23+
constructor refine⁺
24+
25+
field
26+
27+
refine⁻ : A
28+
.{{refined}} : T (p refine⁻)
29+
30+
infix 2 RefinementSyntax
31+
32+
RefinementSyntax : (A : Set a) (p : A Bool) Set a
33+
RefinementSyntax A p = Refinement p
34+
35+
syntax RefinementSyntax A (λ x p) = [ x ∈ A || p ]
36+
37+
------------------------------------------------------------------------
38+
-- Export
39+
40+
open Refinement public
41+
42+

0 commit comments

Comments
 (0)