csci8980-f21/extra/Modules.lagda.md
2019-08-15 17:26:21 +01:00

3.9 KiB
Raw Permalink Blame History

title layout permalink
Modules: Modules and List Examples page /Modules/

** Turn this into a Setoid example. Copy equivalence relation and setoid from the standard library. **

module plfa.Modules where

This chapter introduces modules as a way of structuring proofs, and proves some general results which will be useful later.

Imports

import Relation.Binary.PropositionalEquality as Eq
open Eq using (_≡_; refl; sym; trans; cong)
open Eq.≡-Reasoning
open import Data.Nat using (; zero; suc; _+_; _*_; _∸_; _≤_; s≤s; z≤n)
open import Relation.Nullary using (¬_)
open import Data.Product using (_×_) renaming (_,_ to ⟨_,_⟩)
open import Function using (_∘_)
open import Level using (Level)
open import Data.Maybe using (Maybe; just; nothing)
open import Data.List using (List; []; _∷_; _++_; map; foldr; downFrom)
open import Data.List.All using (All; []; _∷_)
open import Data.List.Any using (Any; here; there)
open import plfa.Isomorphism using (_≃_; extensionality)

Modules

Let's say we want to prove some standard results about collections of elements of a given type at a given universe level with a given equivalence relation for equality. One way to do so is to begin every signature with a suitable sequence of implicit parameters. Here are some definitions, where we represent collections as lists. (We would call collections sets, save that the name Set already plays a special role in Agda.)

Coll : ∀ { : Level} → Set  → Set 
Coll A  =  List A

_∈_ : ∀ { : Level} {A : Set } {_≈_ : A → A → Set } → A → Coll A → Set 
_∈_ {_≈_ = _≈_} x xs  =  All (x ≈_) xs

_⊆_ : ∀ { : Level} {A : Set } {_≈_ : A → A → Set } → Coll A → Coll A → Set 
_⊆_ {_≈_ = _≈_} xs ys  =  ∀ {w} → _∈_  {_≈_ = _≈_} w xs → _∈_ {_≈_ = _≈_} w ys

This rapidly gets tired. Passing around the equivalence relation _≈_ takes a lot of space, hinders the use of infix notation, and obscures the essence of the definitions.

Instead, we can define a module parameterised by the desired concepts, which are then available throughout.

module Collection { : Level} (A : Set ) (_≈_ : A → A → Set ) where

  Coll : ∀ { : Level} → Set  → Set 
  Coll A  =  List A

  _∈_ : A → Coll A → Set 
  x ∈ xs  =  Any (x ≈_) xs

  _⊆_ : Coll A → Coll A → Set 
  xs ⊆ ys  =  ∀ {w} → w ∈ xs → w ∈ ys

Use of a module

open Collection () (_≡_)

pattern [_] x  =  x ∷ []
pattern [_,_] x y  =  x ∷ y ∷ []
pattern [_,_,_] x y z  =  x ∷ y ∷ z ∷ []

ex : [ 1 , 3 ] ⊆ [ 1 , 2 , 3 ]
ex (here refl)          =  here refl
ex (there (here refl))  =  there (there (here refl))
ex (there (there ()))

Abstract types

Say I want to define a type of stacks, with operations push and pop. I can define stacks in terms of lists, but hide the definitions from the rest of the program.

abstract

  Stack : Set → Set
  Stack A = List A

  empty : ∀ {A} → Stack A
  empty = []

  push : ∀ {A} → A → Stack A → Stack A
  push x xs  =  x ∷ xs

  pop : ∀ {A} → Stack A → Maybe (A × Stack A)
  pop []        =  nothing
  pop (x ∷ xs)  =  just ⟨ x , xs ⟩

  lemma-pop-push : ∀ {A} {x : A} {xs} → pop (push x xs) ≡ just ⟨ x , xs ⟩
  lemma-pop-push = refl

  lemma-pop-empty : ∀ {A} → pop {A} empty ≡ nothing
  lemma-pop-empty = refl

Standard Library

Definitions similar to those in this chapter can be found in the standard library.

-- EDIT

The standard library version of IsMonoid differs from the one given here, in that it is also parameterised on an equivalence relation.

Unicode

This chapter uses the following unicode.

EDIT
∷  U+2237  PROPORTION  (\::)
⊗  U+2297  CIRCLED TIMES  (\otimes)
∈  U+2208  ELEMENT OF  (\in)
∉  U+2209  NOT AN ELEMENT OF  (\inn)