module CopatternsSolution where
open import Data.Nat.Base
open import Data.Bool.Base
open import Relation.Binary.PropositionalEquality
open import Size
module Streams where
record Stream (A : Set) : Set where
coinductive
field head : A
tail : Stream A
open Stream
cons : {A : Set} (a : A) (as : Stream A) → Stream A
head (cons a as) = a
tail (cons a as) = as
repeat : {A : Set} (a : A) → Stream A
head (repeat a) = a
tail (repeat a) = repeat a
zipWith : {A B C : Set} (f : A → B → C) (s : Stream A) (t : Stream B) → Stream C
head (zipWith f s t) = f (head s) (head t)
tail (zipWith f s t) = zipWith f (tail s) (tail t)
evil : Stream ℕ → Stream ℕ → Stream ℕ
evil s t = tail t
{-# TERMINATING #-}
fib : Stream ℕ
head fib = 0
head (tail fib) = 1
tail (tail fib) = zipWith (_+_) fib (tail fib)
module SizedStreams where
record Stream (i : Size) (A : Set) : Set where
coinductive
field head : A
tail : ∀{j : Size< i} → Stream j A
open Stream
cons : {i : Size} {A : Set} (a : A) (as : Stream i A) → Stream (↑ i) A
head (cons a as) = a
tail (cons a as) = as
repeat : {i : Size} {A : Set} (a : A) → Stream i A
head (repeat a) = a
tail (repeat {i} a) {j} = repeat {j} a
zipWith : ∀ {i A B C} (f : A → B → C) (s : Stream i A) (t : Stream i B) → Stream i C
head (zipWith f s t) = f (head s) (head t)
tail (zipWith {i} f s t) {j} = zipWith f (tail s {j}) (tail t {j})
fib : ∀{i} → Stream i ℕ
head fib = 0
head (tail fib) = 1
tail (tail (fib {i}) {j}) {k} = zipWith (_+_) (fib {k}) (tail (fib {j}))
module Languages where
record Lang (A : Set) : Set where
coinductive
field ν : Bool
δ : A → Lang A
open Lang
∅ : ∀{A} → Lang A
ν ∅ = false
δ ∅ a = ∅
ε : ∀{A} → Lang A
ν ε = true
δ ε x = ∅
infixl 4 _∪_
_∪_ : ∀{A} (l k : Lang A) → Lang A
ν (l ∪ k) = ν l ∨ ν k
δ (l ∪ k) x = δ l x ∪ δ k x
module SizedLanguages where
record Lang (i : Size) (A : Set) : Set where
coinductive
field ν : Bool
δ : ∀{j : Size< i} → A → Lang j A
open Lang
∅ : ∀{i A} → Lang i A
ν ∅ = false
δ ∅ a = ∅
ε : ∀{i A} → Lang i A
ν ε = true
δ ε x = ∅
infixl 4 _∪_
_∪_ : ∀{i A} (l k : Lang i A) → Lang i A
ν (l ∪ k) = ν l ∨ ν k
δ (l ∪ k) x = δ l x ∪ δ k x
infixl 6 _∙_
_∙_ : ∀{i A} (l k : Lang i A) → Lang i A
ν (l ∙ k) = ν l ∧ ν k
δ (l ∙ k) x = if ν l then δ l x ∙ k ∪ δ k x else δ l x ∙ k
infixr 15 _*
_* : ∀{i A} (l : Lang i A) → Lang i A
ν (l *) = true
δ (l *) x = δ l x ∙ l *