Skip to content

Commit dcd3666

Browse files
authored
[ new ] Codata.Guarded.Stream.Properties (#1717)
1 parent 732d438 commit dcd3666

File tree

7 files changed

+488
-62
lines changed

7 files changed

+488
-62
lines changed

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,13 @@ Non-backwards compatible changes
437437
```
438438
* `Opₗ` and `Opᵣ` have moved from `Algebra.Core` to `Algebra.Module.Core`.
439439

440+
* In `Data.Nat.GeneralisedArithmetic`, the `s` and `z` arguments to the following
441+
functions have been made explicit:
442+
* `fold-+`
443+
* `fold-k`
444+
* `fold-*`
445+
* `fold-pull`
446+
440447
Major improvements
441448
------------------
442449

@@ -725,6 +732,7 @@ New modules
725732
* A definition of infinite streams using coinductive records:
726733
```
727734
Codata.Guarded.Stream
735+
Codata.Guarded.Stream.Properties
728736
Codata.Guarded.Stream.Relation.Binary.Pointwise
729737
Codata.Guarded.Stream.Relation.Unary.All
730738
Codata.Guarded.Stream.Relation.Unary.Any
@@ -1191,6 +1199,8 @@ Other minor changes
11911199
foldr′ : (A → B → B) → B → Vec A n → B
11921200
foldl′ : (B → A → B) → B → Vec A n → B
11931201
1202+
iterate : (A → A) → A → Vec A n
1203+
11941204
diagonal : Vec (Vec A n) n → Vec A n
11951205
DiagonalBind._>>=_ : Vec A n → (A → Vec B n) → Vec B n
11961206
_ʳ++_ : Vec A m → Vec A n → Vec A (m + n)
@@ -1654,3 +1664,9 @@ This is a full list of proofs that have changed form to use irrelevant instance
16541664
map-cong : f ≗ g → map f ≗ map g
16551665
map-compose : map (g ∘ f) ≗ map g ∘ map f
16561666
```
1667+
1668+
* Added new functions and proofs in `Data.Nat.GeneralisedArithmetic`:
1669+
```agda
1670+
iterate : (A → A) → A → ℕ → A
1671+
iterate-is-fold : ∀ (z : A) s m → fold z s m ≡ iterate s z m
1672+
```

src/Codata/Guarded/Stream.agda

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,13 @@ interleave⁺ {A = A} (xs ∷ xss) = go [] xs xss
126126
tail (go rev xs (ys ∷ yss)) = go (tail xs ∷ rev) ys yss
127127

128128
cycle : List⁺ A Stream A
129-
cycle {A = A} (x ∷ xs) = cycleAux List.[]
130-
where
129+
cycle {A = A} (x ∷ xs) = cycleAux []
130+
module Cycle where
131131
cycleAux : List A Stream A
132132
head (cycleAux []) = x
133133
tail (cycleAux []) = cycleAux xs
134134
head (cycleAux (x ∷ xs)) = x
135135
tail (cycleAux (x ∷ xs)) = cycleAux xs
136-
137136

138137
cantor : Stream (Stream A) Stream A
139138
cantor ls = zig (head ls ∷ []) (tail ls)
Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
------------------------------------------------------------------------
2+
-- The Agda standard library
3+
--
4+
-- Properties of infinite streams defined as coinductive records
5+
------------------------------------------------------------------------
6+
7+
{-# OPTIONS --safe --without-K --guardedness #-}
8+
9+
module Codata.Guarded.Stream.Properties where
10+
11+
open import Codata.Guarded.Stream
12+
open import Codata.Guarded.Stream.Relation.Binary.Pointwise
13+
as B using (_≈_; head; tail; module ≈-Reasoning)
14+
15+
open import Data.List.Base as List using (List; []; _∷_)
16+
open import Data.List.NonEmpty as List⁺ using (_∷_)
17+
open import Data.Nat.Base using (ℕ; zero; suc; _+_; _*_)
18+
import Data.Nat.GeneralisedArithmetic as ℕ
19+
open import Data.Product as Prod using (_×_; _,_; proj₁; proj₂)
20+
open import Data.Vec.Base as Vec using (Vec; _∷_)
21+
open import Function.Base using (const; flip; id; _∘′_; _$′_; _⟨_⟩_; _∘₂′_)
22+
open import Level using (Level)
23+
open import Relation.Binary.PropositionalEquality as P using (_≡_; cong; cong₂)
24+
25+
private
26+
variable
27+
a b c d : Level
28+
A : Set a
29+
B : Set b
30+
C : Set c
31+
D : Set d
32+
33+
------------------------------------------------------------------------
34+
-- Congruence
35+
36+
cong-lookup : n {as bs : Stream A} as ≈ bs lookup n as ≡ lookup n bs
37+
cong-lookup = B.lookup
38+
39+
cong-take : n {as bs : Stream A} as ≈ bs take n as ≡ take n bs
40+
cong-take zero as≈bs = P.refl
41+
cong-take (suc n) as≈bs = cong₂ _∷_ (as≈bs .head) (cong-take n (as≈bs .tail))
42+
43+
cong-drop : n {as bs : Stream A} as ≈ bs drop n as ≈ drop n bs
44+
cong-drop = B.drop⁺
45+
46+
-- This is not map⁺ because the propositional equality relation is
47+
-- not the same on the input and output
48+
cong-map : (f : A B) {as bs} as ≈ bs map f as ≈ map f bs
49+
cong-map f as≈bs .head = cong f (as≈bs .head)
50+
cong-map f as≈bs .tail = cong-map f (as≈bs .tail)
51+
52+
cong-zipWith : (f : A B C) {as bs cs ds} as ≈ bs cs ≈ ds
53+
zipWith f as cs ≈ zipWith f bs ds
54+
cong-zipWith f as≈bs cs≈ds .head = cong₂ f (as≈bs .head) (cs≈ds .head)
55+
cong-zipWith f as≈bs cs≈ds .tail = cong-zipWith f (as≈bs .tail) (cs≈ds .tail)
56+
57+
cong-interleave : {as bs cs ds : Stream A} as ≈ bs cs ≈ ds
58+
interleave as cs ≈ interleave bs ds
59+
cong-interleave as≈bs cs≈ds .head = as≈bs .head
60+
cong-interleave as≈bs cs≈ds .tail = cong-interleave cs≈ds (as≈bs .tail)
61+
62+
cong-chunksOf : n {as bs : Stream A} as ≈ bs chunksOf n as ≈ chunksOf n bs
63+
cong-chunksOf n as≈bs .head = cong-take n as≈bs
64+
cong-chunksOf n as≈bs .tail = cong-chunksOf n (cong-drop n as≈bs)
65+
66+
------------------------------------------------------------------------
67+
-- Properties of repeat
68+
69+
lookup-repeat : n (a : A) lookup n (repeat a) ≡ a
70+
lookup-repeat zero a = P.refl
71+
lookup-repeat (suc n) a = lookup-repeat n a
72+
73+
splitAt-repeat : n (a : A) splitAt n (repeat a) ≡ (Vec.replicate a , repeat a)
74+
splitAt-repeat zero a = P.refl
75+
splitAt-repeat (suc n) a = cong (Prod.map₁ (a ∷_)) (splitAt-repeat n a)
76+
77+
take-repeat : n (a : A) take n (repeat a) ≡ Vec.replicate a
78+
take-repeat n a = cong proj₁ (splitAt-repeat n a)
79+
80+
drop-repeat : n (a : A) drop n (repeat a) ≡ repeat a
81+
drop-repeat n a = cong proj₂ (splitAt-repeat n a)
82+
83+
map-repeat : (f : A B) a map f (repeat a) ≈ repeat (f a)
84+
map-repeat f a .head = P.refl
85+
map-repeat f a .tail = map-repeat f a
86+
87+
ap-repeat : (f : A B) a ap (repeat f) (repeat a) ≈ repeat (f a)
88+
ap-repeat f a .head = P.refl
89+
ap-repeat f a .tail = ap-repeat f a
90+
91+
ap-repeatˡ : (f : A B) as ap (repeat f) as ≈ map f as
92+
ap-repeatˡ f as .head = P.refl
93+
ap-repeatˡ f as .tail = ap-repeatˡ f (as .tail)
94+
95+
ap-repeatʳ : (fs : Stream (A B)) a ap fs (repeat a) ≈ map (_$′ a) fs
96+
ap-repeatʳ fs a .head = P.refl
97+
ap-repeatʳ fs a .tail = ap-repeatʳ (fs .tail) a
98+
99+
interleave-repeat : (a : A) interleave (repeat a) (repeat a) ≈ repeat a
100+
interleave-repeat a .head = P.refl
101+
interleave-repeat a .tail = interleave-repeat a
102+
103+
zipWith-repeat : (f : A B C) a b
104+
zipWith f (repeat a) (repeat b) ≈ repeat (f a b)
105+
zipWith-repeat f a b .head = P.refl
106+
zipWith-repeat f a b .tail = zipWith-repeat f a b
107+
108+
chunksOf-repeat : n (a : A) chunksOf n (repeat a) ≈ repeat (Vec.replicate a)
109+
chunksOf-repeat n a = begin go where
110+
111+
open ≈-Reasoning
112+
113+
go : chunksOf n (repeat a) ≈∞ repeat (Vec.replicate a)
114+
go .head = take-repeat n a
115+
go .tail =
116+
chunksOf n (drop n (repeat a)) ≡⟨ P.cong (chunksOf n) (drop-repeat n a) ⟩
117+
chunksOf n (repeat a) ↺⟨ go ⟩
118+
repeat (Vec.replicate a) ∎
119+
120+
------------------------------------------------------------------------
121+
-- Properties of map
122+
123+
map-const : (a : A) (bs : Stream B) map (const a) bs ≈ repeat a
124+
map-const a bs .head = P.refl
125+
map-const a bs .tail = map-const a (bs .tail)
126+
127+
map-identity : (as : Stream A) map id as ≈ as
128+
map-identity as .head = P.refl
129+
map-identity as .tail = map-identity (as .tail)
130+
131+
map-fusion : (g : B C) (f : A B) as map g (map f as) ≈ map (g ∘′ f) as
132+
map-fusion g f as .head = P.refl
133+
map-fusion g f as .tail = map-fusion g f (as .tail)
134+
135+
map-unfold : (g : B C) (f : A A × B) a
136+
map g (unfold f a) ≈ unfold (Prod.map₂ g ∘′ f) a
137+
map-unfold g f a .head = P.refl
138+
map-unfold g f a .tail = map-unfold g f (proj₁ (f a))
139+
140+
map-drop : (f : A B) n as map f (drop n as) ≡ drop n (map f as)
141+
map-drop f zero as = P.refl
142+
map-drop f (suc n) as = map-drop f n (as .tail)
143+
144+
map-zipWith : (g : C D) (f : A B C) as bs
145+
map g (zipWith f as bs) ≈ zipWith (g ∘₂′ f) as bs
146+
map-zipWith g f as bs .head = P.refl
147+
map-zipWith g f as bs .tail = map-zipWith g f (as .tail) (bs .tail)
148+
149+
map-interleave : (f : A B) as bs
150+
map f (interleave as bs) ≈ interleave (map f as) (map f bs)
151+
map-interleave f as bs .head = P.refl
152+
map-interleave f as bs .tail = map-interleave f bs (as .tail)
153+
154+
map-cycle : (f : A B) as map f (cycle as) ≈ cycle (List⁺.map f as)
155+
map-cycle f (a ∷ as) = go [] where
156+
157+
open Cycle
158+
go : acc map f (cycleAux a as acc) ≈ cycleAux (f a) (List.map f as) (List.map f acc)
159+
go [] .head = P.refl
160+
go [] .tail = go as
161+
go (x ∷ xs) .head = P.refl
162+
go (x ∷ xs) .tail = go xs
163+
164+
------------------------------------------------------------------------
165+
-- Properties of lookup
166+
167+
lookup-drop : m n (as : Stream A) lookup n (drop m as) ≡ lookup (m + n) as
168+
lookup-drop zero n as = P.refl
169+
lookup-drop (suc m) n as = lookup-drop m n (as .tail)
170+
171+
lookup-map : n (f : A B) as lookup n (map f as) ≡ f (lookup n as)
172+
lookup-map zero f as = P.refl
173+
lookup-map (suc n) f as = lookup-map n f (as . tail)
174+
175+
lookup-iterate : n f (x : A) lookup n (iterate f x) ≡ ℕ.iterate f x n
176+
lookup-iterate zero f x = P.refl
177+
lookup-iterate (suc n) f x = lookup-iterate n f (f x)
178+
179+
lookup-zipWith : n (f : A B C) as bs
180+
lookup n (zipWith f as bs) ≡ f (lookup n as) (lookup n bs)
181+
lookup-zipWith zero f as bs = P.refl
182+
lookup-zipWith (suc n) f as bs = lookup-zipWith n f (as .tail) (bs .tail)
183+
184+
lookup-unfold : n (f : A A × B) a
185+
lookup n (unfold f a) ≡ proj₂ (f (ℕ.iterate (proj₁ ∘′ f) a n))
186+
lookup-unfold zero f a = P.refl
187+
lookup-unfold (suc n) f a = lookup-unfold n f (proj₁ (f a))
188+
189+
lookup-tabulate : n (f : A) lookup n (tabulate f) ≡ f n
190+
lookup-tabulate zero f = P.refl
191+
lookup-tabulate (suc n) f = lookup-tabulate n (f ∘′ suc)
192+
193+
lookup-tails : n (as : Stream A) lookup n (tails as) ≈ ℕ.iterate tail as n
194+
lookup-tails zero as = B.refl
195+
lookup-tails (suc n) as = lookup-tails n (as .tail)
196+
197+
lookup-evens : n (as : Stream A) lookup n (evens as) ≡ lookup (n * 2) as
198+
lookup-evens zero as = P.refl
199+
lookup-evens (suc n) as = lookup-evens n (as .tail .tail)
200+
201+
lookup-odds : n (as : Stream A) lookup n (odds as) ≡ lookup (suc (n * 2)) as
202+
lookup-odds zero as = P.refl
203+
lookup-odds (suc n) as = lookup-odds n (as .tail .tail)
204+
205+
lookup-interleave-even : n (as bs : Stream A)
206+
lookup (n * 2) (interleave as bs) ≡ lookup n as
207+
lookup-interleave-even zero as bs = P.refl
208+
lookup-interleave-even (suc n) as bs = lookup-interleave-even n (as .tail) (bs .tail)
209+
210+
lookup-interleave-odd : n (as bs : Stream A)
211+
lookup (suc (n * 2)) (interleave as bs) ≡ lookup n bs
212+
lookup-interleave-odd zero as bs = P.refl
213+
lookup-interleave-odd (suc n) as bs = lookup-interleave-odd n (as .tail) (bs .tail)
214+
215+
------------------------------------------------------------------------
216+
-- Properties of take
217+
218+
take-iterate : n f (x : A) take n (iterate f x) ≡ Vec.iterate f x
219+
take-iterate zero f x = P.refl
220+
take-iterate (suc n) f x = cong (x ∷_) (take-iterate n f (f x))
221+
222+
take-zipWith : n (f : A B C) as bs
223+
take n (zipWith f as bs) ≡ Vec.zipWith f (take n as) (take n bs)
224+
take-zipWith zero f as bs = P.refl
225+
take-zipWith (suc n) f as bs =
226+
cong (f (as .head) (bs .head) ∷_) (take-zipWith n f (as .tail) (bs . tail))
227+
228+
------------------------------------------------------------------------
229+
-- Properties of drop
230+
231+
drop-fusion : m n (as : Stream A) drop n (drop m as) ≡ drop (m + n) as
232+
drop-fusion zero n as = P.refl
233+
drop-fusion (suc m) n as = drop-fusion m n (as .tail)
234+
235+
drop-zipWith : n (f : A B C) as bs
236+
drop n (zipWith f as bs) ≡ zipWith f (drop n as) (drop n bs)
237+
drop-zipWith zero f as bs = P.refl
238+
drop-zipWith (suc n) f as bs = drop-zipWith n f (as .tail) (bs .tail)
239+
240+
drop-ap : n (fs : Stream (A B)) as
241+
drop n (ap fs as) ≡ ap (drop n fs) (drop n as)
242+
drop-ap zero fs as = P.refl
243+
drop-ap (suc n) fs as = drop-ap n (fs .tail) (as .tail)
244+
245+
drop-iterate : n f (x : A) drop n (iterate f x) ≡ iterate f (ℕ.iterate f x n)
246+
drop-iterate zero f x = P.refl
247+
drop-iterate (suc n) f x = drop-iterate n f (f x)
248+
249+
------------------------------------------------------------------------
250+
-- Properties of zipWith
251+
252+
zipWith-defn : (f : A B C) as bs
253+
zipWith f as bs ≈ (repeat f ⟨ ap ⟩ as ⟨ ap ⟩ bs)
254+
zipWith-defn f as bs .head = P.refl
255+
zipWith-defn f as bs .tail = zipWith-defn f (as .tail) (bs .tail)
256+
257+
zipWith-const : (as : Stream A) (bs : Stream B)
258+
zipWith const as bs ≈ as
259+
zipWith-const as bs .head = P.refl
260+
zipWith-const as bs .tail = zipWith-const (as .tail) (bs .tail)
261+
262+
zipWith-flip : (f : A B C) as bs
263+
zipWith (flip f) as bs ≈ zipWith f bs as
264+
zipWith-flip f as bs .head = P.refl
265+
zipWith-flip f as bs .tail = zipWith-flip f (as .tail) (bs. tail)
266+
267+
------------------------------------------------------------------------
268+
-- Properties of interleave
269+
270+
interleave-evens-odds : (as : Stream A) interleave (evens as) (odds as) ≈ as
271+
interleave-evens-odds as .head = P.refl
272+
interleave-evens-odds as .tail .head = P.refl
273+
interleave-evens-odds as .tail .tail = interleave-evens-odds (as .tail .tail)

0 commit comments

Comments
 (0)