Skip to content

Commit 759bba2

Browse files
authored
Add a recursive view of Fin n (#1923)
1 parent aac6ab8 commit 759bba2

File tree

4 files changed

+189
-0
lines changed

4 files changed

+189
-0
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -1585,6 +1585,11 @@ New modules
15851585
Data.Default
15861586
```
15871587

1588+
* A small library defining a structurally recursive view of `Fin n`:
1589+
```
1590+
Data.Fin.Relation.Unary.Top
1591+
```
1592+
15881593
* A small library for a non-empty fresh list:
15891594
```
15901595
Data.List.Fresh.NonEmpty
@@ -2146,6 +2151,8 @@ Additions to existing modules
21462151
cast-is-id : cast eq k ≡ k
21472152
subst-is-cast : subst Fin eq k ≡ cast eq k
21482153
cast-trans : cast eq₂ (cast eq₁ k) ≡ cast (trans eq₁ eq₂) k
2154+
2155+
fromℕ≢inject₁ : {i : Fin n} → fromℕ n ≢ inject₁ i
21492156
```
21502157

21512158
* Added new functions in `Data.Integer.Base`:
+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
------------------------------------------------------------------------
2+
-- The Agda standard library
3+
--
4+
-- Example use of the 'top' view of Fin
5+
--
6+
-- This is an example of a view of (elements of) a datatype,
7+
-- here i : Fin (suc n), which exhibits every such i as
8+
-- * either, i = fromℕ n
9+
-- * or, i = inject₁ j for a unique j : Fin n
10+
--
11+
-- Using this view, we can redefine certain operations in `Data.Fin.Base`,
12+
-- together with their corresponding properties in `Data.Fin.Properties`.
13+
------------------------------------------------------------------------
14+
15+
{-# OPTIONS --cubical-compatible --safe #-}
16+
17+
module README.Data.Fin.Relation.Unary.Top where
18+
19+
open import Data.Nat.Base using (ℕ; zero; suc; _∸_; _≤_)
20+
open import Data.Nat.Properties using (n∸n≡0; +-∸-assoc; ≤-reflexive)
21+
open import Data.Fin.Base using (Fin; zero; suc; toℕ; fromℕ; inject₁; _>_)
22+
open import Data.Fin.Properties using (toℕ-fromℕ; toℕ<n; toℕ-inject₁)
23+
open import Data.Fin.Induction hiding (>-weakInduction)
24+
open import Data.Fin.Relation.Unary.Top
25+
import Induction.WellFounded as WF
26+
open import Level using (Level)
27+
open import Relation.Binary.PropositionalEquality
28+
open import Relation.Unary using (Pred)
29+
30+
private
31+
variable
32+
: Level
33+
n :
34+
35+
------------------------------------------------------------------------
36+
-- Reimplementation of `Data.Fin.Base.opposite`, and its properties
37+
38+
-- Definition
39+
40+
opposite : Fin n Fin n
41+
opposite {suc n} i with view i
42+
... | ‵fromℕ = zero
43+
... | ‵inject₁ j = suc (opposite {n} j)
44+
45+
-- Properties
46+
47+
opposite-zero≡fromℕ : n opposite {suc n} zero ≡ fromℕ n
48+
opposite-zero≡fromℕ zero = refl
49+
opposite-zero≡fromℕ (suc n) = cong suc (opposite-zero≡fromℕ n)
50+
51+
opposite-fromℕ≡zero : n opposite {suc n} (fromℕ n) ≡ zero
52+
opposite-fromℕ≡zero n rewrite view-fromℕ n = refl
53+
54+
opposite-suc≡inject₁-opposite : (j : Fin n)
55+
opposite (suc j) ≡ inject₁ (opposite j)
56+
opposite-suc≡inject₁-opposite {suc n} i with view i
57+
... | ‵fromℕ = refl
58+
... | ‵inject₁ j = cong suc (opposite-suc≡inject₁-opposite {n} j)
59+
60+
opposite-involutive : (j : Fin n) opposite (opposite j) ≡ j
61+
opposite-involutive {suc n} zero
62+
rewrite opposite-zero≡fromℕ n
63+
| view-fromℕ n = refl
64+
opposite-involutive {suc n} (suc i)
65+
rewrite opposite-suc≡inject₁-opposite i
66+
| view-inject₁ (opposite i) = cong suc (opposite-involutive i)
67+
68+
opposite-suc : (j : Fin n) toℕ (opposite (suc j)) ≡ toℕ (opposite j)
69+
opposite-suc j = begin
70+
toℕ (opposite (suc j)) ≡⟨ cong toℕ (opposite-suc≡inject₁-opposite j) ⟩
71+
toℕ (inject₁ (opposite j)) ≡⟨ toℕ-inject₁ (opposite j) ⟩
72+
toℕ (opposite j) ∎ where open ≡-Reasoning
73+
74+
opposite-prop : (j : Fin n) toℕ (opposite j) ≡ n ∸ suc (toℕ j)
75+
opposite-prop {suc n} i with view i
76+
... | ‵fromℕ rewrite toℕ-fromℕ n | n∸n≡0 n = refl
77+
... | ‵inject₁ j = begin
78+
suc (toℕ (opposite j)) ≡⟨ cong suc (opposite-prop j) ⟩
79+
suc (n ∸ suc (toℕ j)) ≡˘⟨ +-∸-assoc 1 (toℕ<n j) ⟩
80+
n ∸ toℕ j ≡˘⟨ cong (n ∸_) (toℕ-inject₁ j) ⟩
81+
n ∸ toℕ (inject₁ j) ∎ where open ≡-Reasoning
82+
83+
------------------------------------------------------------------------
84+
-- Reimplementation of `Data.Fin.Induction.>-weakInduction`
85+
86+
open WF using (Acc; acc)
87+
88+
>-weakInduction : (P : Pred (Fin (suc n)) ℓ)
89+
P (fromℕ n)
90+
( i P (suc i) P (inject₁ i))
91+
i P i
92+
>-weakInduction P Pₙ Pᵢ₊₁⇒Pᵢ i = induct (>-wellFounded i)
93+
where
94+
induct : {i} Acc _>_ i P i
95+
induct {i} (acc rec) with view i
96+
... | ‵fromℕ = Pₙ
97+
... | ‵inject₁ j = Pᵢ₊₁⇒Pᵢ j (induct (rec _ inject₁[j]+1≤[j+1]))
98+
where
99+
inject₁[j]+1≤[j+1] : suc (toℕ (inject₁ j)) ≤ toℕ (suc j)
100+
inject₁[j]+1≤[j+1] = ≤-reflexive (toℕ-inject₁ (suc j))

src/Data/Fin/Properties.agda

+3
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,9 @@ toℕ-inject {i = suc i} (suc j) = cong suc (toℕ-inject j)
449449
-- inject₁
450450
------------------------------------------------------------------------
451451

452+
fromℕ≢inject₁ : fromℕ n ≢ inject₁ i
453+
fromℕ≢inject₁ {i = suc i} eq = fromℕ≢inject₁ {i = i} (suc-injective eq)
454+
452455
inject₁-injective : inject₁ i ≡ inject₁ j i ≡ j
453456
inject₁-injective {i = zero} {zero} i≡j = refl
454457
inject₁-injective {i = suc i} {suc j} i≡j =

src/Data/Fin/Relation/Unary/Top.agda

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
------------------------------------------------------------------------
2+
-- The Agda standard library
3+
--
4+
-- The 'top' view of Fin.
5+
--
6+
-- This is an example of a view of (elements of) a datatype,
7+
-- here i : Fin (suc n), which exhibits every such i as
8+
-- * either, i = fromℕ n
9+
-- * or, i = inject₁ j for a unique j : Fin n
10+
------------------------------------------------------------------------
11+
12+
{-# OPTIONS --cubical-compatible --safe #-}
13+
14+
module Data.Fin.Relation.Unary.Top where
15+
16+
open import Data.Nat.Base using (ℕ; zero; suc)
17+
open import Data.Fin.Base using (Fin; zero; suc; fromℕ; inject₁)
18+
open import Relation.Binary.PropositionalEquality.Core
19+
20+
private
21+
variable
22+
n :
23+
i : Fin n
24+
25+
------------------------------------------------------------------------
26+
-- The View, considered as a unary relation on Fin n
27+
28+
-- NB `Data.Fin.Properties.fromℕ≢inject₁` establishes that the following
29+
-- inductively defined family on `Fin n` has constructors which target
30+
-- *disjoint* instances of the family (moreover at indices `n = suc _`);
31+
-- hence the interpretations of the View constructors will also be disjoint.
32+
33+
data View : (i : Fin n) Set where
34+
‵fromℕ : View (fromℕ n)
35+
‵inj₁ : View i View (inject₁ i)
36+
37+
pattern ‵inject₁ i = ‵inj₁ {i = i} _
38+
39+
-- The view covering function, witnessing soundness of the view
40+
41+
view : (i : Fin n) View i
42+
view zero = view-zero where
43+
view-zero : View (zero {n})
44+
view-zero {n = zero} = ‵fromℕ
45+
view-zero {n = suc _} = ‵inj₁ view-zero
46+
view (suc i) with view i
47+
... | ‵fromℕ = ‵fromℕ
48+
... | ‵inject₁ i = ‵inj₁ (view (suc i))
49+
50+
-- Interpretation of the view constructors
51+
52+
⟦_⟧ : {i : Fin n} View i Fin n
53+
⟦ ‵fromℕ ⟧ = fromℕ _
54+
⟦ ‵inject₁ i ⟧ = inject₁ i
55+
56+
-- Completeness of the view
57+
58+
view-complete : (v : View i) ⟦ v ⟧ ≡ i
59+
view-complete ‵fromℕ = refl
60+
view-complete (‵inj₁ _) = refl
61+
62+
-- 'Computational' behaviour of the covering function
63+
64+
view-fromℕ : n view (fromℕ n) ≡ ‵fromℕ
65+
view-fromℕ zero = refl
66+
view-fromℕ (suc n) rewrite view-fromℕ n = refl
67+
68+
view-inject₁ : (i : Fin n) view (inject₁ i) ≡ ‵inj₁ (view i)
69+
view-inject₁ zero = refl
70+
view-inject₁ (suc i) rewrite view-inject₁ i = refl
71+
72+
-- Uniqueness of the view
73+
74+
view-unique : (v : View i) view i ≡ v
75+
view-unique ‵fromℕ = view-fromℕ _
76+
view-unique (‵inj₁ {i = i} v) = begin
77+
view (inject₁ i) ≡⟨ view-inject₁ i ⟩
78+
‵inj₁ (view i) ≡⟨ cong ‵inj₁ (view-unique v) ⟩
79+
‵inj₁ v ∎ where open ≡-Reasoning

0 commit comments

Comments
 (0)