summaryrefslogtreecommitdiff
path: root/src/Codata/Musical
diff options
context:
space:
mode:
Diffstat (limited to 'src/Codata/Musical')
-rw-r--r--src/Codata/Musical/Cofin.agda47
-rw-r--r--src/Codata/Musical/Colist.agda535
-rw-r--r--src/Codata/Musical/Colist/Infinite-merge.agda213
-rw-r--r--src/Codata/Musical/Conat.agda86
-rw-r--r--src/Codata/Musical/Costring.agda22
-rw-r--r--src/Codata/Musical/Covec.agda166
-rw-r--r--src/Codata/Musical/M.agda45
-rw-r--r--src/Codata/Musical/M/Indexed.agda42
-rw-r--r--src/Codata/Musical/Notation.agda9
-rw-r--r--src/Codata/Musical/Stream.agda165
10 files changed, 1330 insertions, 0 deletions
diff --git a/src/Codata/Musical/Cofin.agda b/src/Codata/Musical/Cofin.agda
new file mode 100644
index 0000000..138641c
--- /dev/null
+++ b/src/Codata/Musical/Cofin.agda
@@ -0,0 +1,47 @@
+------------------------------------------------------------------------
+-- The Agda standard library
+--
+-- "Finite" sets indexed on coinductive "natural" numbers
+------------------------------------------------------------------------
+
+module Codata.Musical.Cofin where
+
+open import Codata.Musical.Notation
+open import Codata.Musical.Conat as Conat using (Coℕ; suc; ∞ℕ)
+open import Data.Nat.Base using (ℕ; zero; suc)
+open import Data.Fin using (Fin; zero; suc)
+open import Relation.Binary.PropositionalEquality using (_≡_ ; refl)
+open import Function
+
+------------------------------------------------------------------------
+-- The type
+
+-- Note that Cofin ∞ℕ is /not/ finite. Note also that this is not a
+-- coinductive type, but it is indexed on a coinductive type.
+
+data Cofin : Coℕ → Set where
+ zero : ∀ {n} → Cofin (suc n)
+ suc : ∀ {n} (i : Cofin (♭ n)) → Cofin (suc n)
+
+suc-injective : ∀ {m} {p q : Cofin (♭ m)} → (Cofin (suc m) ∋ suc p) ≡ suc q → p ≡ q
+suc-injective refl = refl
+
+------------------------------------------------------------------------
+-- Some operations
+
+fromℕ : ℕ → Cofin ∞ℕ
+fromℕ zero = zero
+fromℕ (suc n) = suc (fromℕ n)
+
+toℕ : ∀ {n} → Cofin n → ℕ
+toℕ zero = zero
+toℕ (suc i) = suc (toℕ i)
+
+fromFin : ∀ {n} → Fin n → Cofin (Conat.fromℕ n)
+fromFin zero = zero
+fromFin (suc i) = suc (fromFin i)
+
+toFin : ∀ n → Cofin (Conat.fromℕ n) → Fin n
+toFin zero ()
+toFin (suc n) zero = zero
+toFin (suc n) (suc i) = suc (toFin n i)
diff --git a/src/Codata/Musical/Colist.agda b/src/Codata/Musical/Colist.agda
new file mode 100644
index 0000000..3824ce3
--- /dev/null
+++ b/src/Codata/Musical/Colist.agda
@@ -0,0 +1,535 @@
+------------------------------------------------------------------------
+-- The Agda standard library
+--
+-- Coinductive lists
+------------------------------------------------------------------------
+
+module Codata.Musical.Colist where
+
+open import Category.Monad
+open import Codata.Musical.Notation
+open import Codata.Musical.Conat using (Coℕ; zero; suc)
+open import Data.Bool.Base using (Bool; true; false)
+open import Data.BoundedVec.Inefficient as BVec
+ using (BoundedVec; []; _∷_)
+open import Data.Empty using (⊥)
+open import Data.Maybe.Base using (Maybe; nothing; just; Is-just)
+open import Data.Nat.Base using (ℕ; zero; suc; _≥′_; ≤′-refl; ≤′-step)
+open import Data.Nat.Properties using (s≤′s)
+open import Data.List.Base using (List; []; _∷_)
+open import Data.List.NonEmpty using (List⁺; _∷_)
+open import Data.Product as Prod using (∃; _×_; _,_)
+open import Data.Sum as Sum using (_⊎_; inj₁; inj₂; [_,_]′)
+open import Function
+open import Function.Equality using (_⟨$⟩_)
+open import Function.Inverse as Inv using (_↔_; _↔̇_; Inverse; inverse)
+open import Level using (_⊔_)
+open import Relation.Binary
+import Relation.Binary.Construct.FromRel as Ind
+open import Relation.Binary.PropositionalEquality as P using (_≡_)
+open import Relation.Nullary
+open import Relation.Nullary.Negation
+
+module ¬¬Monad {p} where
+ open RawMonad (¬¬-Monad {p}) public
+open ¬¬Monad -- we don't want the RawMonad content to be opened publicly
+
+------------------------------------------------------------------------
+-- The type
+
+infixr 5 _∷_
+
+data Colist {a} (A : Set a) : Set a where
+ [] : Colist A
+ _∷_ : (x : A) (xs : ∞ (Colist A)) → Colist A
+
+{-# FOREIGN GHC
+ data AgdaColist a = Nil | Cons a (MAlonzo.RTE.Inf (AgdaColist a))
+ type AgdaColist' l a = AgdaColist a
+ #-}
+{-# COMPILE GHC Colist = data AgdaColist' (Nil | Cons) #-}
+{-# COMPILE UHC Colist = data __LIST__ (__NIL__ | __CONS__) #-}
+
+module Colist-injective {a} {A : Set a} where
+
+ ∷-injectiveˡ : ∀ {x y : A} {xs ys} → (Colist A ∋ x ∷ xs) ≡ y ∷ ys → x ≡ y
+ ∷-injectiveˡ P.refl = P.refl
+
+ ∷-injectiveʳ : ∀ {x y : A} {xs ys} → (Colist A ∋ x ∷ xs) ≡ y ∷ ys → xs ≡ ys
+ ∷-injectiveʳ P.refl = P.refl
+
+data Any {a p} {A : Set a} (P : A → Set p) :
+ Colist A → Set (a ⊔ p) where
+ here : ∀ {x xs} (px : P x) → Any P (x ∷ xs)
+ there : ∀ {x xs} (pxs : Any P (♭ xs)) → Any P (x ∷ xs)
+
+module _ {a p} {A : Set a} {P : A → Set p} where
+
+ here-injective : ∀ {x xs p q} → (Any P (x ∷ xs) ∋ here p) ≡ here q → p ≡ q
+ here-injective P.refl = P.refl
+
+ there-injective : ∀ {x xs p q} → (Any P (x ∷ xs) ∋ there p) ≡ there q → p ≡ q
+ there-injective P.refl = P.refl
+
+data All {a p} {A : Set a} (P : A → Set p) :
+ Colist A → Set (a ⊔ p) where
+ [] : All P []
+ _∷_ : ∀ {x xs} (px : P x) (pxs : ∞ (All P (♭ xs))) → All P (x ∷ xs)
+
+module All-injective {a p} {A : Set a} {P : A → Set p} where
+
+ ∷-injectiveˡ : ∀ {x xs} {px qx pxs qxs} →
+ (All P (x ∷ xs) ∋ px ∷ pxs) ≡ qx ∷ qxs → px ≡ qx
+ ∷-injectiveˡ P.refl = P.refl
+
+ ∷-injectiveʳ : ∀ {x xs} {px qx pxs qxs} →
+ (All P (x ∷ xs) ∋ px ∷ pxs) ≡ qx ∷ qxs → pxs ≡ qxs
+ ∷-injectiveʳ P.refl = P.refl
+
+------------------------------------------------------------------------
+-- Some operations
+
+null : ∀ {a} {A : Set a} → Colist A → Bool
+null [] = true
+null (_ ∷ _) = false
+
+length : ∀ {a} {A : Set a} → Colist A → Coℕ
+length [] = zero
+length (x ∷ xs) = suc (♯ length (♭ xs))
+
+map : ∀ {a b} {A : Set a} {B : Set b} → (A → B) → Colist A → Colist B
+map f [] = []
+map f (x ∷ xs) = f x ∷ ♯ map f (♭ xs)
+
+fromList : ∀ {a} {A : Set a} → List A → Colist A
+fromList [] = []
+fromList (x ∷ xs) = x ∷ ♯ fromList xs
+
+take : ∀ {a} {A : Set a} (n : ℕ) → Colist A → BoundedVec A n
+take zero xs = []
+take (suc n) [] = []
+take (suc n) (x ∷ xs) = x ∷ take n (♭ xs)
+
+replicate : ∀ {a} {A : Set a} → Coℕ → A → Colist A
+replicate zero x = []
+replicate (suc n) x = x ∷ ♯ replicate (♭ n) x
+
+lookup : ∀ {a} {A : Set a} → ℕ → Colist A → Maybe A
+lookup n [] = nothing
+lookup zero (x ∷ xs) = just x
+lookup (suc n) (x ∷ xs) = lookup n (♭ xs)
+
+infixr 5 _++_
+
+_++_ : ∀ {a} {A : Set a} → Colist A → Colist A → Colist A
+[] ++ ys = ys
+(x ∷ xs) ++ ys = x ∷ ♯ (♭ xs ++ ys)
+
+-- Interleaves the two colists (until the shorter one, if any, has
+-- been exhausted).
+
+infixr 5 _⋎_
+
+_⋎_ : ∀ {a} {A : Set a} → Colist A → Colist A → Colist A
+[] ⋎ ys = ys
+(x ∷ xs) ⋎ ys = x ∷ ♯ (ys ⋎ ♭ xs)
+
+concat : ∀ {a} {A : Set a} → Colist (List⁺ A) → Colist A
+concat [] = []
+concat ((x ∷ []) ∷ xss) = x ∷ ♯ concat (♭ xss)
+concat ((x ∷ (y ∷ xs)) ∷ xss) = x ∷ ♯ concat ((y ∷ xs) ∷ xss)
+
+[_] : ∀ {a} {A : Set a} → A → Colist A
+[ x ] = x ∷ ♯ []
+
+------------------------------------------------------------------------
+-- Any lemmas
+
+-- Any lemma for map.
+
+Any-map : ∀ {a b p} {A : Set a} {B : Set b} {P : B → Set p}
+ {f : A → B} {xs} →
+ Any P (map f xs) ↔ Any (P ∘ f) xs
+Any-map {P = P} {f} {xs} = inverse to from from∘to to∘from
+ where
+ to : ∀ {xs} → Any P (map f xs) → Any (P ∘ f) xs
+ to {[]} ()
+ to {x ∷ xs} (here px) = here px
+ to {x ∷ xs} (there p) = there (to p)
+
+ from : ∀ {xs} → Any (P ∘ f) xs → Any P (map f xs)
+ from (here px) = here px
+ from (there p) = there (from p)
+
+ from∘to : ∀ {xs} (p : Any P (map f xs)) → from (to p) ≡ p
+ from∘to {[]} ()
+ from∘to {x ∷ xs} (here px) = P.refl
+ from∘to {x ∷ xs} (there p) = P.cong there (from∘to p)
+
+ to∘from : ∀ {xs} (p : Any (P ∘ f) xs) → to (from p) ≡ p
+ to∘from (here px) = P.refl
+ to∘from (there p) = P.cong there (to∘from p)
+
+-- Any lemma for _⋎_. This lemma implies that every member of xs or ys
+-- is a member of xs ⋎ ys, and vice versa.
+
+Any-⋎ : ∀ {a p} {A : Set a} {P : A → Set p} xs {ys} →
+ Any P (xs ⋎ ys) ↔ (Any P xs ⊎ Any P ys)
+Any-⋎ {P = P} = λ xs → record
+ { to = P.→-to-⟶ (to xs)
+ ; from = P.→-to-⟶ (from xs)
+ ; inverse-of = record
+ { left-inverse-of = from∘to xs
+ ; right-inverse-of = to∘from xs
+ }
+ }
+ where
+ to : ∀ xs {ys} → Any P (xs ⋎ ys) → Any P xs ⊎ Any P ys
+ to [] p = inj₂ p
+ to (x ∷ xs) (here px) = inj₁ (here px)
+ to (x ∷ xs) (there p) = [ inj₂ , inj₁ ∘ there ]′ (to _ p)
+
+ mutual
+
+ from-left : ∀ {xs ys} → Any P xs → Any P (xs ⋎ ys)
+ from-left (here px) = here px
+ from-left {ys = ys} (there p) = there (from-right ys p)
+
+ from-right : ∀ xs {ys} → Any P ys → Any P (xs ⋎ ys)
+ from-right [] p = p
+ from-right (x ∷ xs) p = there (from-left p)
+
+ from : ∀ xs {ys} → Any P xs ⊎ Any P ys → Any P (xs ⋎ ys)
+ from xs = Sum.[ from-left , from-right xs ]
+
+ from∘to : ∀ xs {ys} (p : Any P (xs ⋎ ys)) → from xs (to xs p) ≡ p
+ from∘to [] p = P.refl
+ from∘to (x ∷ xs) (here px) = P.refl
+ from∘to (x ∷ xs) {ys = ys} (there p) with to ys p | from∘to ys p
+ from∘to (x ∷ xs) {ys = ys} (there .(from-left q)) | inj₁ q | P.refl = P.refl
+ from∘to (x ∷ xs) {ys = ys} (there .(from-right ys q)) | inj₂ q | P.refl = P.refl
+
+ mutual
+
+ to∘from-left : ∀ {xs ys} (p : Any P xs) →
+ to xs {ys = ys} (from-left p) ≡ inj₁ p
+ to∘from-left (here px) = P.refl
+ to∘from-left {ys = ys} (there p)
+ rewrite to∘from-right ys p = P.refl
+
+ to∘from-right : ∀ xs {ys} (p : Any P ys) →
+ to xs (from-right xs p) ≡ inj₂ p
+ to∘from-right [] p = P.refl
+ to∘from-right (x ∷ xs) {ys = ys} p
+ rewrite to∘from-left {xs = ys} {ys = ♭ xs} p = P.refl
+
+ to∘from : ∀ xs {ys} (p : Any P xs ⊎ Any P ys) → to xs (from xs p) ≡ p
+ to∘from xs = Sum.[ to∘from-left , to∘from-right xs ]
+
+------------------------------------------------------------------------
+-- Equality
+
+-- xs ≈ ys means that xs and ys are equal.
+
+infix 4 _≈_
+
+data _≈_ {a} {A : Set a} : (xs ys : Colist A) → Set a where
+ [] : [] ≈ []
+ _∷_ : ∀ x {xs ys} (xs≈ : ∞ (♭ xs ≈ ♭ ys)) → x ∷ xs ≈ x ∷ ys
+
+-- The equality relation forms a setoid.
+
+setoid : ∀ {ℓ} → Set ℓ → Setoid _ _
+setoid A = record
+ { Carrier = Colist A
+ ; _≈_ = _≈_
+ ; isEquivalence = record
+ { refl = refl
+ ; sym = sym
+ ; trans = trans
+ }
+ }
+ where
+ refl : Reflexive _≈_
+ refl {[]} = []
+ refl {x ∷ xs} = x ∷ ♯ refl
+
+ sym : Symmetric _≈_
+ sym [] = []
+ sym (x ∷ xs≈) = x ∷ ♯ sym (♭ xs≈)
+
+ trans : Transitive _≈_
+ trans [] [] = []
+ trans (x ∷ xs≈) (.x ∷ ys≈) = x ∷ ♯ trans (♭ xs≈) (♭ ys≈)
+
+module ≈-Reasoning where
+ import Relation.Binary.EqReasoning as EqR
+ private
+ open module R {a} {A : Set a} = EqR (setoid A) public
+
+-- map preserves equality.
+
+map-cong : ∀ {a b} {A : Set a} {B : Set b}
+ (f : A → B) → _≈_ =[ map f ]⇒ _≈_
+map-cong f [] = []
+map-cong f (x ∷ xs≈) = f x ∷ ♯ map-cong f (♭ xs≈)
+
+-- Any respects pointwise implication (for the predicate) and equality
+-- (for the colist).
+
+Any-resp : ∀ {a p q} {A : Set a} {P : A → Set p} {Q : A → Set q}
+ {xs ys} → (∀ {x} → P x → Q x) → xs ≈ ys →
+ Any P xs → Any Q ys
+Any-resp f (x ∷ xs≈) (here px) = here (f px)
+Any-resp f (x ∷ xs≈) (there p) = there (Any-resp f (♭ xs≈) p)
+
+-- Any maps pointwise isomorphic predicates and equal colists to
+-- isomorphic types.
+
+Any-cong : ∀ {a p q} {A : Set a} {P : A → Set p} {Q : A → Set q}
+ {xs ys} → P ↔̇ Q → xs ≈ ys → Any P xs ↔ Any Q ys
+Any-cong {A = A} {P} {Q} {xs} {ys} P↔Q xs≈ys = record
+ { to = P.→-to-⟶ (to xs≈ys)
+ ; from = P.→-to-⟶ (from xs≈ys)
+ ; inverse-of = record
+ { left-inverse-of = resp∘resp P↔Q xs≈ys (sym xs≈ys)
+ ; right-inverse-of = resp∘resp (Inv.sym P↔Q) (sym xs≈ys) xs≈ys
+ }
+ }
+ where
+ open Setoid (setoid _) using (sym)
+
+ to : ∀ {xs ys} → xs ≈ ys → Any P xs → Any Q ys
+ to xs≈ys = Any-resp (Inverse.to P↔Q ⟨$⟩_) xs≈ys
+
+ from : ∀ {xs ys} → xs ≈ ys → Any Q ys → Any P xs
+ from xs≈ys = Any-resp (Inverse.from P↔Q ⟨$⟩_) (sym xs≈ys)
+
+ resp∘resp : ∀ {p q} {P : A → Set p} {Q : A → Set q} {xs ys}
+ (P↔̇Q : P ↔̇ Q) (xs≈ys : xs ≈ ys) (ys≈xs : ys ≈ xs)
+ (p : Any P xs) →
+ Any-resp (Inverse.from P↔̇Q ⟨$⟩_) ys≈xs
+ (Any-resp (Inverse.to P↔̇Q ⟨$⟩_) xs≈ys p) ≡ p
+ resp∘resp P↔̇Q (x ∷ xs≈) (.x ∷ ys≈) (here px) =
+ P.cong here (Inverse.left-inverse-of P↔̇Q px)
+ resp∘resp P↔̇Q (x ∷ xs≈) (.x ∷ ys≈) (there p) =
+ P.cong there (resp∘resp P↔̇Q (♭ xs≈) (♭ ys≈) p)
+
+------------------------------------------------------------------------
+-- Indices
+
+-- Converts Any proofs to indices into the colist. The index can also
+-- be seen as the size of the proof.
+
+index : ∀ {a p} {A : Set a} {P : A → Set p} {xs} → Any P xs → ℕ
+index (here px) = zero
+index (there p) = suc (index p)
+
+-- The position returned by index is guaranteed to be within bounds.
+
+lookup-index : ∀ {a p} {A : Set a} {P : A → Set p} {xs} (p : Any P xs) →
+ Is-just (lookup (index p) xs)
+lookup-index (here px) = just _
+lookup-index (there p) = lookup-index p
+
+-- Any-resp preserves the index.
+
+index-Any-resp :
+ ∀ {a p q} {A : Set a} {P : A → Set p} {Q : A → Set q}
+ {f : ∀ {x} → P x → Q x} {xs ys}
+ (xs≈ys : xs ≈ ys) (p : Any P xs) →
+ index (Any-resp f xs≈ys p) ≡ index p
+index-Any-resp (x ∷ xs≈) (here px) = P.refl
+index-Any-resp (x ∷ xs≈) (there p) =
+ P.cong suc (index-Any-resp (♭ xs≈) p)
+
+-- The left-to-right direction of Any-⋎ returns a proof whose size is
+-- no larger than that of the input proof.
+
+index-Any-⋎ :
+ ∀ {a p} {A : Set a} {P : A → Set p} xs {ys} (p : Any P (xs ⋎ ys)) →
+ index p ≥′ [ index , index ]′ (Inverse.to (Any-⋎ xs) ⟨$⟩ p)
+index-Any-⋎ [] p = ≤′-refl
+index-Any-⋎ (x ∷ xs) (here px) = ≤′-refl
+index-Any-⋎ (x ∷ xs) {ys = ys} (there p)
+ with Inverse.to (Any-⋎ ys) ⟨$⟩ p | index-Any-⋎ ys p
+... | inj₁ q | q≤p = ≤′-step q≤p
+... | inj₂ q | q≤p = s≤′s q≤p
+
+------------------------------------------------------------------------
+-- Memberships, subsets, prefixes
+
+-- x ∈ xs means that x is a member of xs.
+
+infix 4 _∈_
+
+_∈_ : ∀ {a} → {A : Set a} → A → Colist A → Set a
+x ∈ xs = Any (_≡_ x) xs
+
+-- xs ⊆ ys means that xs is a subset of ys.
+
+infix 4 _⊆_
+
+_⊆_ : ∀ {a} → {A : Set a} → Colist A → Colist A → Set a
+xs ⊆ ys = ∀ {x} → x ∈ xs → x ∈ ys
+
+-- xs ⊑ ys means that xs is a prefix of ys.
+
+infix 4 _⊑_
+
+data _⊑_ {a} {A : Set a} : Colist A → Colist A → Set a where
+ [] : ∀ {ys} → [] ⊑ ys
+ _∷_ : ∀ x {xs ys} (p : ∞ (♭ xs ⊑ ♭ ys)) → x ∷ xs ⊑ x ∷ ys
+
+-- Any can be expressed using _∈_ (and vice versa).
+
+Any-∈ : ∀ {a p} {A : Set a} {P : A → Set p} {xs} →
+ Any P xs ↔ ∃ λ x → x ∈ xs × P x
+Any-∈ {P = P} = record
+ { to = P.→-to-⟶ to
+ ; from = P.→-to-⟶ (λ { (x , x∈xs , p) → from x∈xs p })
+ ; inverse-of = record
+ { left-inverse-of = from∘to
+ ; right-inverse-of = λ { (x , x∈xs , p) → to∘from x∈xs p }
+ }
+ }
+ where
+ to : ∀ {xs} → Any P xs → ∃ λ x → x ∈ xs × P x
+ to (here p) = _ , here P.refl , p
+ to (there p) = Prod.map id (Prod.map there id) (to p)
+
+ from : ∀ {x xs} → x ∈ xs → P x → Any P xs
+ from (here P.refl) p = here p
+ from (there x∈xs) p = there (from x∈xs p)
+
+ to∘from : ∀ {x xs} (x∈xs : x ∈ xs) (p : P x) →
+ to (from x∈xs p) ≡ (x , x∈xs , p)
+ to∘from (here P.refl) p = P.refl
+ to∘from (there x∈xs) p =
+ P.cong (Prod.map id (Prod.map there id)) (to∘from x∈xs p)
+
+ from∘to : ∀ {xs} (p : Any P xs) →
+ let (x , x∈xs , px) = to p in from x∈xs px ≡ p
+ from∘to (here _) = P.refl
+ from∘to (there p) = P.cong there (from∘to p)
+
+-- Prefixes are subsets.
+
+⊑⇒⊆ : ∀ {a} → {A : Set a} → _⊑_ {A = A} ⇒ _⊆_
+⊑⇒⊆ [] ()
+⊑⇒⊆ (x ∷ xs⊑ys) (here ≡x) = here ≡x
+⊑⇒⊆ (_ ∷ xs⊑ys) (there x∈xs) = there (⊑⇒⊆ (♭ xs⊑ys) x∈xs)
+
+-- The prefix relation forms a poset.
+
+⊑-Poset : ∀ {ℓ} → Set ℓ → Poset _ _ _
+⊑-Poset A = record
+ { Carrier = Colist A
+ ; _≈_ = _≈_
+ ; _≤_ = _⊑_
+ ; isPartialOrder = record
+ { isPreorder = record
+ { isEquivalence = Setoid.isEquivalence (setoid A)
+ ; reflexive = reflexive
+ ; trans = trans
+ }
+ ; antisym = antisym
+ }
+ }
+ where
+ reflexive : _≈_ ⇒ _⊑_
+ reflexive [] = []
+ reflexive (x ∷ xs≈) = x ∷ ♯ reflexive (♭ xs≈)
+
+ trans : Transitive _⊑_
+ trans [] _ = []
+ trans (x ∷ xs≈) (.x ∷ ys≈) = x ∷ ♯ trans (♭ xs≈) (♭ ys≈)
+
+ antisym : Antisymmetric _≈_ _⊑_
+ antisym [] [] = []
+ antisym (x ∷ p₁) (.x ∷ p₂) = x ∷ ♯ antisym (♭ p₁) (♭ p₂)
+
+module ⊑-Reasoning where
+ import Relation.Binary.PartialOrderReasoning as POR
+ private
+ open module R {a} {A : Set a} = POR (⊑-Poset A)
+ public renaming (_≤⟨_⟩_ to _⊑⟨_⟩_)
+
+-- The subset relation forms a preorder.
+
+⊆-Preorder : ∀ {ℓ} → Set ℓ → Preorder _ _ _
+⊆-Preorder A = Ind.preorder (setoid A) _∈_
+ (λ xs≈ys → ⊑⇒⊆ (⊑P.reflexive xs≈ys))
+ where module ⊑P = Poset (⊑-Poset A)
+
+module ⊆-Reasoning where
+ import Relation.Binary.PreorderReasoning as PreR
+ private
+ open module R {a} {A : Set a} = PreR (⊆-Preorder A)
+ public renaming (_∼⟨_⟩_ to _⊆⟨_⟩_)
+
+ infix 1 _∈⟨_⟩_
+
+ _∈⟨_⟩_ : ∀ {a} {A : Set a} (x : A) {xs ys} →
+ x ∈ xs → xs IsRelatedTo ys → x ∈ ys
+ x ∈⟨ x∈xs ⟩ xs⊆ys = (begin xs⊆ys) x∈xs
+
+-- take returns a prefix.
+
+take-⊑ : ∀ {a} {A : Set a} n (xs : Colist A) →
+ let toColist = fromList {a} ∘ BVec.toList in
+ toColist (take n xs) ⊑ xs
+take-⊑ zero xs = []
+take-⊑ (suc n) [] = []
+take-⊑ (suc n) (x ∷ xs) = x ∷ ♯ take-⊑ n (♭ xs)
+
+------------------------------------------------------------------------
+-- Finiteness and infiniteness
+
+-- Finite xs means that xs has finite length.
+
+data Finite {a} {A : Set a} : Colist A → Set a where
+ [] : Finite []
+ _∷_ : ∀ x {xs} (fin : Finite (♭ xs)) → Finite (x ∷ xs)
+
+module Finite-injective {a} {A : Set a} where
+
+ ∷-injective : ∀ {x : A} {xs p q} → (Finite (x ∷ xs) ∋ x ∷ p) ≡ x ∷ q → p ≡ q
+ ∷-injective P.refl = P.refl
+
+-- Infinite xs means that xs has infinite length.
+
+data Infinite {a} {A : Set a} : Colist A → Set a where
+ _∷_ : ∀ x {xs} (inf : ∞ (Infinite (♭ xs))) → Infinite (x ∷ xs)
+
+module Infinite-injective {a} {A : Set a} where
+
+ ∷-injective : ∀ {x : A} {xs p q} → (Infinite (x ∷ xs) ∋ x ∷ p) ≡ x ∷ q → p ≡ q
+ ∷-injective P.refl = P.refl
+
+-- Colists which are not finite are infinite.
+
+not-finite-is-infinite :
+ ∀ {a} {A : Set a} (xs : Colist A) → ¬ Finite xs → Infinite xs
+not-finite-is-infinite [] hyp with hyp []
+... | ()
+not-finite-is-infinite (x ∷ xs) hyp =
+ x ∷ ♯ not-finite-is-infinite (♭ xs) (hyp ∘ _∷_ x)
+
+-- Colists are either finite or infinite (classically).
+
+finite-or-infinite :
+ ∀ {a} {A : Set a} (xs : Colist A) → ¬ ¬ (Finite xs ⊎ Infinite xs)
+finite-or-infinite xs = helper <$> excluded-middle
+ where
+ helper : Dec (Finite xs) → Finite xs ⊎ Infinite xs
+ helper (yes fin) = inj₁ fin
+ helper (no ¬fin) = inj₂ $ not-finite-is-infinite xs ¬fin
+
+-- Colists are not both finite and infinite.
+
+not-finite-and-infinite :
+ ∀ {a} {A : Set a} {xs : Colist A} → Finite xs → Infinite xs → ⊥
+not-finite-and-infinite [] ()
+not-finite-and-infinite (x ∷ fin) (.x ∷ inf) =
+ not-finite-and-infinite fin (♭ inf)
diff --git a/src/Codata/Musical/Colist/Infinite-merge.agda b/src/Codata/Musical/Colist/Infinite-merge.agda
new file mode 100644
index 0000000..a2e1a37
--- /dev/null
+++ b/src/Codata/Musical/Colist/Infinite-merge.agda
@@ -0,0 +1,213 @@
+------------------------------------------------------------------------
+-- The Agda standard library
+--
+-- Infinite merge operation for coinductive lists
+------------------------------------------------------------------------
+
+module Codata.Musical.Colist.Infinite-merge where
+
+open import Codata.Musical.Notation
+open import Codata.Musical.Colist as Colist hiding (_⋎_)
+open import Data.Nat
+open import Data.Nat.Properties
+open import Data.Product as Prod
+open import Data.Sum
+open import Data.Sum.Properties
+open import Data.Sum.Relation.Pointwise
+open import Function
+open import Function.Equality using (_⟨$⟩_)
+open import Function.Inverse as Inv using (_↔_; Inverse; inverse)
+import Function.Related as Related
+open import Function.Related.TypeIsomorphisms
+open import Induction.Nat using (<′-wellFounded)
+import Induction.WellFounded as WF
+open import Relation.Binary.PropositionalEquality as P using (_≡_)
+
+------------------------------------------------------------------------
+-- Some code that is used to work around Agda's syntactic guardedness
+-- checker.
+
+private
+
+ infixr 5 _∷_ _⋎_
+
+ data ColistP {a} (A : Set a) : Set a where
+ [] : ColistP A
+ _∷_ : A → ∞ (ColistP A) → ColistP A
+ _⋎_ : ColistP A → ColistP A → ColistP A
+
+ data ColistW {a} (A : Set a) : Set a where
+ [] : ColistW A
+ _∷_ : A → ColistP A → ColistW A
+
+ program : ∀ {a} {A : Set a} → Colist A → ColistP A
+ program [] = []
+ program (x ∷ xs) = x ∷ ♯ program (♭ xs)
+
+ mutual
+
+ _⋎W_ : ∀ {a} {A : Set a} → ColistW A → ColistP A → ColistW A
+ [] ⋎W ys = whnf ys
+ (x ∷ xs) ⋎W ys = x ∷ (ys ⋎ xs)
+
+ whnf : ∀ {a} {A : Set a} → ColistP A → ColistW A
+ whnf [] = []
+ whnf (x ∷ xs) = x ∷ ♭ xs
+ whnf (xs ⋎ ys) = whnf xs ⋎W ys
+
+ mutual
+
+ ⟦_⟧P : ∀ {a} {A : Set a} → ColistP A → Colist A
+ ⟦ xs ⟧P = ⟦ whnf xs ⟧W
+
+ ⟦_⟧W : ∀ {a} {A : Set a} → ColistW A → Colist A
+ ⟦ [] ⟧W = []
+ ⟦ x ∷ xs ⟧W = x ∷ ♯ ⟦ xs ⟧P
+
+ mutual
+
+ ⋎-homP : ∀ {a} {A : Set a} (xs : ColistP A) {ys} →
+ ⟦ xs ⋎ ys ⟧P ≈ ⟦ xs ⟧P Colist.⋎ ⟦ ys ⟧P
+ ⋎-homP xs = ⋎-homW (whnf xs) _
+
+ ⋎-homW : ∀ {a} {A : Set a} (xs : ColistW A) ys →
+ ⟦ xs ⋎W ys ⟧W ≈ ⟦ xs ⟧W Colist.⋎ ⟦ ys ⟧P
+ ⋎-homW (x ∷ xs) ys = x ∷ ♯ ⋎-homP ys
+ ⋎-homW [] ys = begin ⟦ ys ⟧P ∎
+ where open ≈-Reasoning
+
+ ⟦program⟧P : ∀ {a} {A : Set a} (xs : Colist A) →
+ ⟦ program xs ⟧P ≈ xs
+ ⟦program⟧P [] = []
+ ⟦program⟧P (x ∷ xs) = x ∷ ♯ ⟦program⟧P (♭ xs)
+
+ Any-⋎P : ∀ {a p} {A : Set a} {P : A → Set p} xs {ys} →
+ Any P ⟦ program xs ⋎ ys ⟧P ↔ (Any P xs ⊎ Any P ⟦ ys ⟧P)
+ Any-⋎P {P = P} xs {ys} =
+ Any P ⟦ program xs ⋎ ys ⟧P ↔⟨ Any-cong Inv.id (⋎-homP (program xs)) ⟩
+ Any P (⟦ program xs ⟧P Colist.⋎ ⟦ ys ⟧P) ↔⟨ Any-⋎ _ ⟩
+ (Any P ⟦ program xs ⟧P ⊎ Any P ⟦ ys ⟧P) ↔⟨ Any-cong Inv.id (⟦program⟧P _) ⊎-cong (_ ∎) ⟩
+ (Any P xs ⊎ Any P ⟦ ys ⟧P) ∎
+ where open Related.EquationalReasoning
+
+ index-Any-⋎P :
+ ∀ {a p} {A : Set a} {P : A → Set p} xs {ys}
+ (p : Any P ⟦ program xs ⋎ ys ⟧P) →
+ index p ≥′ [ index , index ]′ (Inverse.to (Any-⋎P xs) ⟨$⟩ p)
+ index-Any-⋎P xs p
+ with Any-resp id (⋎-homW (whnf (program xs)) _) p
+ | index-Any-resp {f = id} (⋎-homW (whnf (program xs)) _) p
+ index-Any-⋎P xs p | q | q≡p
+ with Inverse.to (Any-⋎ ⟦ program xs ⟧P) ⟨$⟩ q
+ | index-Any-⋎ ⟦ program xs ⟧P q
+ index-Any-⋎P xs p | q | q≡p | inj₂ r | r≤q rewrite q≡p = r≤q
+ index-Any-⋎P xs p | q | q≡p | inj₁ r | r≤q
+ with Any-resp id (⟦program⟧P xs) r
+ | index-Any-resp {f = id} (⟦program⟧P xs) r
+ index-Any-⋎P xs p | q | q≡p | inj₁ r | r≤q | s | s≡r
+ rewrite s≡r | q≡p = r≤q
+
+------------------------------------------------------------------------
+-- Infinite variant of _⋎_.
+
+private
+
+ merge′ : ∀ {a} {A : Set a} → Colist (A × Colist A) → ColistP A
+ merge′ [] = []
+ merge′ ((x , xs) ∷ xss) = x ∷ ♯ (program xs ⋎ merge′ (♭ xss))
+
+merge : ∀ {a} {A : Set a} → Colist (A × Colist A) → Colist A
+merge xss = ⟦ merge′ xss ⟧P
+
+------------------------------------------------------------------------
+-- Any lemma for merge.
+
+module _ {a p} {A : Set a} {P : A → Set p} where
+
+ Any-merge : ∀ xss → Any P (merge xss) ↔ Any (λ { (x , xs) → P x ⊎ Any P xs }) xss
+ Any-merge xss = inverse (proj₁ ∘ to xss) from (proj₂ ∘ to xss) to∘from
+ where
+ open P.≡-Reasoning
+
+ -- The from function.
+
+ Q = λ { (x , xs) → P x ⊎ Any P xs }
+
+ from : ∀ {xss} → Any Q xss → Any P (merge xss)
+ from (here (inj₁ p)) = here p
+ from (here (inj₂ p)) = there (Inverse.from (Any-⋎P _) ⟨$⟩ inj₁ p)
+ from (there {x = _ , xs} p) = there (Inverse.from (Any-⋎P xs) ⟨$⟩ inj₂ (from p))
+
+ -- The from function is injective.
+
+ from-injective : ∀ {xss} (p₁ p₂ : Any Q xss) →
+ from p₁ ≡ from p₂ → p₁ ≡ p₂
+ from-injective (here (inj₁ p)) (here (inj₁ .p)) P.refl = P.refl
+ from-injective (here (inj₁ _)) (here (inj₂ _)) ()
+ from-injective (here (inj₂ _)) (here (inj₁ _)) ()
+ from-injective (here (inj₂ p₁)) (here (inj₂ p₂)) eq =
+ P.cong (here ∘ inj₂) $
+ inj₁-injective $
+ Inverse.injective (Inv.sym (Any-⋎P _)) {x = inj₁ p₁} {y = inj₁ p₂} $
+ there-injective eq
+ from-injective (here (inj₁ _)) (there _) ()
+ from-injective (here (inj₂ p₁)) (there p₂) eq
+ with Inverse.injective (Inv.sym (Any-⋎P _))
+ {x = inj₁ p₁} {y = inj₂ (from p₂)}
+ (there-injective eq)
+ ... | ()
+ from-injective (there _) (here (inj₁ _)) ()
+ from-injective (there p₁) (here (inj₂ p₂)) eq
+ with Inverse.injective (Inv.sym (Any-⋎P _))
+ {x = inj₂ (from p₁)} {y = inj₁ p₂}
+ (there-injective eq)
+ ... | ()
+ from-injective (there {x = _ , xs} p₁) (there p₂) eq =
+ P.cong there $
+ from-injective p₁ p₂ $
+ inj₂-injective $
+ Inverse.injective (Inv.sym (Any-⋎P xs))
+ {x = inj₂ (from p₁)} {y = inj₂ (from p₂)} $
+ there-injective eq
+
+ -- The to function (defined as a right inverse of from).
+
+ Input = ∃ λ xss → Any P (merge xss)
+
+ Pred : Input → Set _
+ Pred (xss , p) = ∃ λ (q : Any Q xss) → from q ≡ p
+
+ to : ∀ xss p → Pred (xss , p)
+ to = λ xss p →
+ WF.All.wfRec (WF.Inverse-image.wellFounded size <′-wellFounded) _
+ Pred step (xss , p)
+ where
+ size : Input → ℕ
+ size (_ , p) = index p
+
+ step : ∀ p → WF.WfRec (_<′_ on size) Pred p → Pred p
+ step ([] , ()) rec
+ step ((x , xs) ∷ xss , here p) rec = here (inj₁ p) , P.refl
+ step ((x , xs) ∷ xss , there p) rec
+ with Inverse.to (Any-⋎P xs) ⟨$⟩ p
+ | Inverse.left-inverse-of (Any-⋎P xs) p
+ | index-Any-⋎P xs p
+ ... | inj₁ q | P.refl | _ = here (inj₂ q) , P.refl
+ ... | inj₂ q | P.refl | q≤p =
+ Prod.map there
+ (P.cong (there ∘ _⟨$⟩_ (Inverse.from (Any-⋎P xs)) ∘ inj₂))
+ (rec (♭ xss , q) (s≤′s q≤p))
+
+ to∘from = λ p → from-injective _ _ (proj₂ (to xss (from p)))
+
+-- Every member of xss is a member of merge xss, and vice versa (with
+-- equal multiplicities).
+
+∈-merge : ∀ {a} {A : Set a} {y : A} xss →
+ y ∈ merge xss ↔ ∃₂ λ x xs → (x , xs) ∈ xss × (y ≡ x ⊎ y ∈ xs)
+∈-merge {y = y} xss =
+ y ∈ merge xss ↔⟨ Any-merge _ ⟩
+ Any (λ { (x , xs) → y ≡ x ⊎ y ∈ xs }) xss ↔⟨ Any-∈ ⟩
+ (∃ λ { (x , xs) → (x , xs) ∈ xss × (y ≡ x ⊎ y ∈ xs) }) ↔⟨ Σ-assoc ⟩
+ (∃₂ λ x xs → (x , xs) ∈ xss × (y ≡ x ⊎ y ∈ xs)) ∎
+ where open Related.EquationalReasoning
diff --git a/src/Codata/Musical/Conat.agda b/src/Codata/Musical/Conat.agda
new file mode 100644
index 0000000..ced828d
--- /dev/null
+++ b/src/Codata/Musical/Conat.agda
@@ -0,0 +1,86 @@
+------------------------------------------------------------------------
+-- The Agda standard library
+--
+-- Coinductive "natural" numbers
+------------------------------------------------------------------------
+
+module Codata.Musical.Conat where
+
+open import Codata.Musical.Notation
+open import Data.Nat.Base using (ℕ; zero; suc)
+open import Function
+open import Relation.Binary
+open import Relation.Binary.PropositionalEquality as P using (_≡_)
+
+------------------------------------------------------------------------
+-- The type
+
+data Coℕ : Set where
+ zero : Coℕ
+ suc : (n : ∞ Coℕ) → Coℕ
+
+module Coℕ-injective where
+
+ suc-injective : ∀ {m n} → (Coℕ ∋ suc m) ≡ suc n → m ≡ n
+ suc-injective P.refl = P.refl
+
+------------------------------------------------------------------------
+-- Some operations
+
+pred : Coℕ → Coℕ
+pred zero = zero
+pred (suc n) = ♭ n
+
+fromℕ : ℕ → Coℕ
+fromℕ zero = zero
+fromℕ (suc n) = suc (♯ fromℕ n)
+
+fromℕ-injective : ∀ {m n} → fromℕ m ≡ fromℕ n → m ≡ n
+fromℕ-injective {zero} {zero} eq = P.refl
+fromℕ-injective {zero} {suc n} ()
+fromℕ-injective {suc m} {zero} ()
+fromℕ-injective {suc m} {suc n} eq = P.cong suc (fromℕ-injective (P.cong pred eq))
+
+∞ℕ : Coℕ
+∞ℕ = suc (♯ ∞ℕ)
+
+infixl 6 _+_
+
+_+_ : Coℕ → Coℕ → Coℕ
+zero + n = n
+suc m + n = suc (♯ (♭ m + n))
+
+------------------------------------------------------------------------
+-- Equality
+
+data _≈_ : Coℕ → Coℕ → Set where
+ zero : zero ≈ zero
+ suc : ∀ {m n} (m≈n : ∞ (♭ m ≈ ♭ n)) → suc m ≈ suc n
+
+module ≈-injective where
+
+ suc-injective : ∀ {m n p q} → (suc m ≈ suc n ∋ suc p) ≡ suc q → p ≡ q
+ suc-injective P.refl = P.refl
+
+setoid : Setoid _ _
+setoid = record
+ { Carrier = Coℕ
+ ; _≈_ = _≈_
+ ; isEquivalence = record
+ { refl = refl
+ ; sym = sym
+ ; trans = trans
+ }
+ }
+ where
+ refl : Reflexive _≈_
+ refl {zero} = zero
+ refl {suc n} = suc (♯ refl)
+
+ sym : Symmetric _≈_
+ sym zero = zero
+ sym (suc m≈n) = suc (♯ sym (♭ m≈n))
+
+ trans : Transitive _≈_
+ trans zero zero = zero
+ trans (suc m≈n) (suc n≈k) = suc (♯ trans (♭ m≈n) (♭ n≈k))
diff --git a/src/Codata/Musical/Costring.agda b/src/Codata/Musical/Costring.agda
new file mode 100644
index 0000000..30092bf
--- /dev/null
+++ b/src/Codata/Musical/Costring.agda
@@ -0,0 +1,22 @@
+------------------------------------------------------------------------
+-- The Agda standard library
+--
+-- Costrings
+------------------------------------------------------------------------
+
+module Codata.Musical.Costring where
+
+open import Codata.Musical.Colist as Colist using (Colist)
+open import Data.Char using (Char)
+open import Data.String as String using (String)
+open import Function using (_∘_)
+
+-- Possibly infinite strings.
+
+Costring : Set
+Costring = Colist Char
+
+-- Methods
+
+toCostring : String → Costring
+toCostring = Colist.fromList ∘ String.toList
diff --git a/src/Codata/Musical/Covec.agda b/src/Codata/Musical/Covec.agda
new file mode 100644
index 0000000..bb9d586
--- /dev/null
+++ b/src/Codata/Musical/Covec.agda
@@ -0,0 +1,166 @@
+------------------------------------------------------------------------
+-- The Agda standard library
+--
+-- Coinductive vectors
+------------------------------------------------------------------------
+
+module Codata.Musical.Covec where
+
+open import Codata.Musical.Notation
+open import Codata.Musical.Conat as Coℕ using (Coℕ; zero; suc; _+_)
+open import Codata.Musical.Cofin using (Cofin; zero; suc)
+open import Codata.Musical.Colist as Colist using (Colist; []; _∷_)
+open import Data.Nat.Base using (ℕ; zero; suc)
+open import Data.Vec using (Vec; []; _∷_)
+open import Data.Product using (_,_)
+open import Function using (_∋_)
+open import Relation.Binary
+open import Relation.Binary.PropositionalEquality as P using (_≡_)
+
+------------------------------------------------------------------------
+-- The type
+
+infixr 5 _∷_
+data Covec {a} (A : Set a) : Coℕ → Set a where
+ [] : Covec A zero
+ _∷_ : ∀ {n} (x : A) (xs : ∞ (Covec A (♭ n))) → Covec A (suc n)
+
+module _ {a} {A : Set a} where
+
+ ∷-injectiveˡ : ∀ {a b} {n} {as bs} → (Covec A (suc n) ∋ a ∷ as) ≡ b ∷ bs → a ≡ b
+ ∷-injectiveˡ P.refl = P.refl
+
+ ∷-injectiveʳ : ∀ {a b} {n} {as bs} → (Covec A (suc n) ∋ a ∷ as) ≡ b ∷ bs → as ≡ bs
+ ∷-injectiveʳ P.refl = P.refl
+
+------------------------------------------------------------------------
+-- Some operations
+
+map : ∀ {a b} {A : Set a} {B : Set b} {n} → (A → B) → Covec A n → Covec B n
+map f [] = []
+map f (x ∷ xs) = f x ∷ ♯ map f (♭ xs)
+
+module _ {a} {A : Set a} where
+
+ fromVec : ∀ {n} → Vec A n → Covec A (Coℕ.fromℕ n)
+ fromVec [] = []
+ fromVec (x ∷ xs) = x ∷ ♯ fromVec xs
+
+ fromColist : (xs : Colist A) → Covec A (Colist.length xs)
+ fromColist [] = []
+ fromColist (x ∷ xs) = x ∷ ♯ fromColist (♭ xs)
+
+ take : ∀ m {n} → Covec A (m + n) → Covec A m
+ take zero xs = []
+ take (suc n) (x ∷ xs) = x ∷ ♯ take (♭ n) (♭ xs)
+
+ drop : ∀ m {n} → Covec A (Coℕ.fromℕ m + n) → Covec A n
+ drop zero xs = xs
+ drop (suc n) (x ∷ xs) = drop n (♭ xs)
+
+ replicate : ∀ n → A → Covec A n
+ replicate zero x = []
+ replicate (suc n) x = x ∷ ♯ replicate (♭ n) x
+
+ lookup : ∀ {n} → Cofin n → Covec A n → A
+ lookup zero (x ∷ xs) = x
+ lookup (suc n) (x ∷ xs) = lookup n (♭ xs)
+
+ infixr 5 _++_
+
+ _++_ : ∀ {m n} → Covec A m → Covec A n → Covec A (m + n)
+ [] ++ ys = ys
+ (x ∷ xs) ++ ys = x ∷ ♯ (♭ xs ++ ys)
+
+ [_] : A → Covec A (suc (♯ zero))
+ [ x ] = x ∷ ♯ []
+
+------------------------------------------------------------------------
+-- Equality and other relations
+
+-- xs ≈ ys means that xs and ys are equal.
+
+ infix 4 _≈_
+
+ data _≈_ : ∀ {n} (xs ys : Covec A n) → Set where
+ [] : [] ≈ []
+ _∷_ : ∀ {n} x {xs ys}
+ (xs≈ : ∞ (♭ xs ≈ ♭ ys)) → _≈_ {n = suc n} (x ∷ xs) (x ∷ ys)
+
+-- x ∈ xs means that x is a member of xs.
+
+ infix 4 _∈_
+
+ data _∈_ : ∀ {n} → A → Covec A n → Set where
+ here : ∀ {n x } {xs} → _∈_ {n = suc n} x (x ∷ xs)
+ there : ∀ {n x y} {xs} (x∈xs : x ∈ ♭ xs) → _∈_ {n = suc n} x (y ∷ xs)
+
+-- xs ⊑ ys means that xs is a prefix of ys.
+
+ infix 4 _⊑_
+
+ data _⊑_ : ∀ {m n} → Covec A m → Covec A n → Set where
+ [] : ∀ {n} {ys : Covec A n} → [] ⊑ ys
+ _∷_ : ∀ {m n} x {xs ys} (p : ∞ (♭ xs ⊑ ♭ ys)) →
+ _⊑_ {m = suc m} {suc n} (x ∷ xs) (x ∷ ys)
+
+------------------------------------------------------------------------
+-- Some proofs
+
+setoid : ∀ {a} → Set a → Coℕ → Setoid _ _
+setoid A n = record
+ { Carrier = Covec A n
+ ; _≈_ = _≈_
+ ; isEquivalence = record
+ { refl = refl
+ ; sym = sym
+ ; trans = trans
+ }
+ }
+ where
+ refl : ∀ {n} → Reflexive (_≈_ {n = n})
+ refl {x = []} = []
+ refl {x = x ∷ xs} = x ∷ ♯ refl
+
+ sym : ∀ {n} → Symmetric (_≈_ {A = A} {n})
+ sym [] = []
+ sym (x ∷ xs≈) = x ∷ ♯ sym (♭ xs≈)
+
+ trans : ∀ {n} → Transitive (_≈_ {A = A} {n})
+ trans [] [] = []
+ trans (x ∷ xs≈) (.x ∷ ys≈) = x ∷ ♯ trans (♭ xs≈) (♭ ys≈)
+
+poset : ∀ {a} → Set a → Coℕ → Poset _ _ _
+poset A n = record
+ { Carrier = Covec A n
+ ; _≈_ = _≈_
+ ; _≤_ = _⊑_
+ ; isPartialOrder = record
+ { isPreorder = record
+ { isEquivalence = Setoid.isEquivalence (setoid A n)
+ ; reflexive = reflexive
+ ; trans = trans
+ }
+ ; antisym = antisym
+ }
+ }
+ where
+ reflexive : ∀ {n} → _≈_ {n = n} ⇒ _⊑_
+ reflexive [] = []
+ reflexive (x ∷ xs≈) = x ∷ ♯ reflexive (♭ xs≈)
+
+ trans : ∀ {n} → Transitive (_⊑_ {n = n})
+ trans [] _ = []
+ trans (x ∷ xs≈) (.x ∷ ys≈) = x ∷ ♯ trans (♭ xs≈) (♭ ys≈)
+
+ antisym : ∀ {n} → Antisymmetric (_≈_ {n = n}) _⊑_
+ antisym [] [] = []
+ antisym (x ∷ p₁) (.x ∷ p₂) = x ∷ ♯ antisym (♭ p₁) (♭ p₂)
+
+map-cong : ∀ {a b} {A : Set a} {B : Set b} {n} (f : A → B) → _≈_ {n = n} =[ map f ]⇒ _≈_
+map-cong f [] = []
+map-cong f (x ∷ xs≈) = f x ∷ ♯ map-cong f (♭ xs≈)
+
+take-⊑ : ∀ {a} {A : Set a} m {n} (xs : Covec A (m + n)) → take m xs ⊑ xs
+take-⊑ zero xs = []
+take-⊑ (suc n) (x ∷ xs) = x ∷ ♯ take-⊑ (♭ n) (♭ xs)
diff --git a/src/Codata/Musical/M.agda b/src/Codata/Musical/M.agda
new file mode 100644
index 0000000..3ae867a
--- /dev/null
+++ b/src/Codata/Musical/M.agda
@@ -0,0 +1,45 @@
+------------------------------------------------------------------------
+-- The Agda standard library
+--
+-- M-types (the dual of W-types)
+------------------------------------------------------------------------
+
+module Codata.Musical.M where
+
+open import Codata.Musical.Notation
+open import Level
+open import Data.Product hiding (map)
+open import Data.Container.Core
+
+-- The family of M-types.
+
+data M {s p} (C : Container s p) : Set (s ⊔ p) where
+ inf : ⟦ C ⟧ (∞ (M C)) → M C
+
+-- Projections.
+
+module _ {s p} (C : Container s p) (open Container C) where
+
+ head : M C → Shape
+ head (inf (x , _)) = x
+
+ tail : (x : M C) → Position (head x) → M C
+ tail (inf (x , f)) b = ♭ (f b)
+
+-- map
+
+module _ {s₁ s₂ p₁ p₂} {C₁ : Container s₁ p₁} {C₂ : Container s₂ p₂}
+ (m : C₁ ⇒ C₂) where
+
+ map : M C₁ → M C₂
+ map (inf (x , f)) = inf (shape m x , λ p → ♯ map (♭ (f (position m p))))
+
+
+-- unfold
+
+module _ {s p ℓ} {C : Container s p} (open Container C)
+ {S : Set ℓ} (alg : S → ⟦ C ⟧ S) where
+
+ unfold : S → M C
+ unfold seed = let (x , f) = alg seed in
+ inf (x , λ p → ♯ unfold (f p))
diff --git a/src/Codata/Musical/M/Indexed.agda b/src/Codata/Musical/M/Indexed.agda
new file mode 100644
index 0000000..3455769
--- /dev/null
+++ b/src/Codata/Musical/M/Indexed.agda
@@ -0,0 +1,42 @@
+------------------------------------------------------------------------
+-- The Agda standard library
+--
+-- Indexed M-types (the dual of indexed W-types aka Petersson-Synek
+-- trees).
+------------------------------------------------------------------------
+
+module Codata.Musical.M.Indexed where
+
+open import Level
+open import Codata.Musical.Notation
+open import Data.Product
+open import Data.Container.Indexed.Core
+open import Function
+open import Relation.Unary
+
+-- The family of indexed M-types.
+
+module _ {ℓ c r} {O : Set ℓ} (C : Container O O c r) where
+
+ data M (o : O) : Set (ℓ ⊔ c ⊔ r) where
+ inf : ⟦ C ⟧ (∞ ∘ M) o → M o
+
+ open Container C
+
+ -- Projections.
+
+ head : M ⊆ Command
+ head (inf (c , _)) = c
+
+ tail : ∀ {o} (m : M o) (r : Response (head m)) → M (next (head m) r)
+ tail (inf (_ , k)) r = ♭ (k r)
+
+ force : M ⊆ ⟦ C ⟧ M
+ force (inf (c , k)) = c , λ r → ♭ (k r)
+
+ -- Coiteration.
+
+ coit : ∀ {ℓ} {X : Pred O ℓ} → X ⊆ ⟦ C ⟧ X → X ⊆ M
+ coit ψ x = inf (proj₁ cs , λ r → ♯ coit ψ (proj₂ cs r))
+ where
+ cs = ψ x
diff --git a/src/Codata/Musical/Notation.agda b/src/Codata/Musical/Notation.agda
new file mode 100644
index 0000000..c5d13f3
--- /dev/null
+++ b/src/Codata/Musical/Notation.agda
@@ -0,0 +1,9 @@
+------------------------------------------------------------------------
+-- The Agda standard library
+--
+-- Basic types related to coinduction
+------------------------------------------------------------------------
+
+module Codata.Musical.Notation where
+
+open import Agda.Builtin.Coinduction public
diff --git a/src/Codata/Musical/Stream.agda b/src/Codata/Musical/Stream.agda
new file mode 100644
index 0000000..de1dc9a
--- /dev/null
+++ b/src/Codata/Musical/Stream.agda
@@ -0,0 +1,165 @@
+------------------------------------------------------------------------
+-- The Agda standard library
+--
+-- Streams
+------------------------------------------------------------------------
+
+module Codata.Musical.Stream where
+
+open import Codata.Musical.Notation
+open import Codata.Musical.Colist using (Colist; []; _∷_)
+open import Data.Vec using (Vec; []; _∷_)
+open import Data.Nat.Base using (ℕ; zero; suc)
+open import Relation.Binary
+open import Relation.Binary.PropositionalEquality as P using (_≡_)
+
+------------------------------------------------------------------------
+-- The type
+
+infixr 5 _∷_
+
+data Stream {a} (A : Set a) : Set a where
+ _∷_ : (x : A) (xs : ∞ (Stream A)) → Stream A
+
+{-# FOREIGN GHC
+ data AgdaStream a = Cons a (MAlonzo.RTE.Inf (AgdaStream a))
+ type AgdaStream' l a = AgdaStream a
+ #-}
+{-# COMPILE GHC Stream = data AgdaStream' (Cons) #-}
+
+------------------------------------------------------------------------
+-- Some operations
+
+head : ∀ {a} {A : Set a} → Stream A → A
+head (x ∷ xs) = x
+
+tail : ∀ {a} {A : Set a} → Stream A → Stream A
+tail (x ∷ xs) = ♭ xs
+
+map : ∀ {a b} {A : Set a} {B : Set b} → (A → B) → Stream A → Stream B
+map f (x ∷ xs) = f x ∷ ♯ map f (♭ xs)
+
+zipWith : ∀ {a b c} {A : Set a} {B : Set b} {C : Set c} →
+ (A → B → C) → Stream A → Stream B → Stream C
+zipWith _∙_ (x ∷ xs) (y ∷ ys) = (x ∙ y) ∷ ♯ zipWith _∙_ (♭ xs) (♭ ys)
+
+take : ∀ {a} {A : Set a} n → Stream A → Vec A n
+take zero xs = []
+take (suc n) (x ∷ xs) = x ∷ take n (♭ xs)
+
+drop : ∀ {a} {A : Set a} → ℕ → Stream A → Stream A
+drop zero xs = xs
+drop (suc n) (x ∷ xs) = drop n (♭ xs)
+
+repeat : ∀ {a} {A : Set a} → A → Stream A
+repeat x = x ∷ ♯ repeat x
+
+iterate : ∀ {a} {A : Set a} → (A → A) → A → Stream A
+iterate f x = x ∷ ♯ iterate f (f x)
+
+-- Interleaves the two streams.
+
+infixr 5 _⋎_
+
+_⋎_ : ∀ {a} {A : Set a} → Stream A → Stream A → Stream A
+(x ∷ xs) ⋎ ys = x ∷ ♯ (ys ⋎ ♭ xs)
+
+mutual
+
+ -- Takes every other element from the stream, starting with the
+ -- first one.
+
+ evens : ∀ {a} {A : Set a} → Stream A → Stream A
+ evens (x ∷ xs) = x ∷ ♯ odds (♭ xs)
+
+ -- Takes every other element from the stream, starting with the
+ -- second one.
+
+ odds : ∀ {a} {A : Set a} → Stream A → Stream A
+ odds (x ∷ xs) = evens (♭ xs)
+
+toColist : ∀ {a} {A : Set a} → Stream A → Colist A
+toColist (x ∷ xs) = x ∷ ♯ toColist (♭ xs)
+
+lookup : ∀ {a} {A : Set a} → ℕ → Stream A → A
+lookup zero (x ∷ xs) = x
+lookup (suc n) (x ∷ xs) = lookup n (♭ xs)
+
+infixr 5 _++_
+
+_++_ : ∀ {a} {A : Set a} → Colist A → Stream A → Stream A
+[] ++ ys = ys
+(x ∷ xs) ++ ys = x ∷ ♯ (♭ xs ++ ys)
+
+------------------------------------------------------------------------
+-- Equality and other relations
+
+-- xs ≈ ys means that xs and ys are equal.
+
+infix 4 _≈_
+
+data _≈_ {a} {A : Set a} : Stream A → Stream A → Set a where
+ _∷_ : ∀ {x y xs ys}
+ (x≡ : x ≡ y) (xs≈ : ∞ (♭ xs ≈ ♭ ys)) → x ∷ xs ≈ y ∷ ys
+
+-- x ∈ xs means that x is a member of xs.
+
+infix 4 _∈_
+
+data _∈_ {a} {A : Set a} : A → Stream A → Set a where
+ here : ∀ {x xs} → x ∈ x ∷ xs
+ there : ∀ {x y xs} (x∈xs : x ∈ ♭ xs) → x ∈ y ∷ xs
+
+-- xs ⊑ ys means that xs is a prefix of ys.
+
+infix 4 _⊑_
+
+data _⊑_ {a} {A : Set a} : Colist A → Stream A → Set a where
+ [] : ∀ {ys} → [] ⊑ ys
+ _∷_ : ∀ x {xs ys} (p : ∞ (♭ xs ⊑ ♭ ys)) → x ∷ xs ⊑ x ∷ ys
+
+------------------------------------------------------------------------
+-- Some proofs
+
+setoid : ∀ {a} → Set a → Setoid _ _
+setoid A = record
+ { Carrier = Stream A
+ ; _≈_ = _≈_ {A = A}
+ ; isEquivalence = record
+ { refl = refl
+ ; sym = sym
+ ; trans = trans
+ }
+ }
+ where
+ refl : Reflexive _≈_
+ refl {_ ∷ _} = P.refl ∷ ♯ refl
+
+ sym : Symmetric _≈_
+ sym (x≡ ∷ xs≈) = P.sym x≡ ∷ ♯ sym (♭ xs≈)
+
+ trans : Transitive _≈_
+ trans (x≡ ∷ xs≈) (y≡ ∷ ys≈) = P.trans x≡ y≡ ∷ ♯ trans (♭ xs≈) (♭ ys≈)
+
+head-cong : ∀ {a} {A : Set a} {xs ys : Stream A} → xs ≈ ys → head xs ≡ head ys
+head-cong (x≡ ∷ _) = x≡
+
+tail-cong : ∀ {a} {A : Set a} {xs ys : Stream A} → xs ≈ ys → tail xs ≈ tail ys
+tail-cong (_ ∷ xs≈) = ♭ xs≈
+
+map-cong : ∀ {a b} {A : Set a} {B : Set b} (f : A → B) {xs ys} →
+ xs ≈ ys → map f xs ≈ map f ys
+map-cong f (x≡ ∷ xs≈) = P.cong f x≡ ∷ ♯ map-cong f (♭ xs≈)
+
+zipWith-cong : ∀ {a b c} {A : Set a} {B : Set b} {C : Set c}
+ (_∙_ : A → B → C) {xs xs′ ys ys′} →
+ xs ≈ xs′ → ys ≈ ys′ →
+ zipWith _∙_ xs ys ≈ zipWith _∙_ xs′ ys′
+zipWith-cong _∙_ (x≡ ∷ xs≈) (y≡ ∷ ys≈) =
+ P.cong₂ _∙_ x≡ y≡ ∷ ♯ zipWith-cong _∙_ (♭ xs≈) (♭ ys≈)
+
+infixr 5 _⋎-cong_
+
+_⋎-cong_ : ∀ {a} {A : Set a} {xs xs′ ys ys′ : Stream A} →
+ xs ≈ xs′ → ys ≈ ys′ → xs ⋎ ys ≈ xs′ ⋎ ys′
+(x ∷ xs≈) ⋎-cong ys≈ = x ∷ ♯ (ys≈ ⋎-cong ♭ xs≈)