Skip to content

Instantly share code, notes, and snippets.

@josh-hs-ko
Last active July 23, 2018 03:59
Show Gist options
  • Save josh-hs-ko/3a0ea16a225ca4efbd01428c06b8fdba to your computer and use it in GitHub Desktop.
Save josh-hs-ko/3a0ea16a225ca4efbd01428c06b8fdba to your computer and use it in GitHub Desktop.
-- programming
data Nat : Set where
zero : Nat
suc : Nat → Nat
_+_ : Nat → Nat → Nat
zero + n = n
suc m + n = suc (m + n)
data List (A : Set) : Set where
[] : List A
_∷_ : A → List A → List A
sum : List Nat → Nat
sum [] = zero
sum (x ∷ xs) = x + sum xs
map : {A B : Set} → (A → B) → List A → List B
map f [] = []
map f (x ∷ xs) = f x ∷ map f xs
-- proving
rapp : {A B : Set} → A → (A → B) → B
rapp x f = f x
data _∧_ (A B : Set) : Set where
_,_ : A → B → A ∧ B
data _∨_ (A B : Set) : Set where
left : A → A ∨ B
right : B → A ∨ B
distr : {A B C : Set} → A ∧ (B ∨ C) → (A ∧ B) ∨ (A ∧ C)
distr (x , left y) = left (x , y)
distr (x , right z) = right (x , z)
data ⊥ : Set where
⊥-elim : {A : Set} → ⊥ → A
⊥-elim ()
¬_ : Set → Set
¬ A = A → ⊥
ex1 : {A : Set} → ¬ ¬ (¬ ¬ A → A)
ex1 x = x (λ y → ⊥-elim (y (λ z → x (λ _ → z))))
ex2 : {A B C : Set} → ¬ ¬ (A ∨ B) → (¬ ¬ A → ¬ ¬ C) → (¬ ¬ B → ¬ ¬ C) → ¬ ¬ C
ex2 x y z w = x (λ { (left u) → y (λ z₁ → z₁ u) w; (right v) → z (λ z₁ → z₁ v) w })
-- equality
data _≡_ {A : Set} (x : A) : A → Set where
refl : x ≡ x
pm : (suc zero + suc zero) ≡ suc (suc zero)
pm = refl
arith-contradiction : ¬ (zero ≡ suc zero)
arith-contradiction ()
sym : {A : Set} {x y : A} → x ≡ y → y ≡ x
sym refl = refl
trans : {A : Set} {x y z : A} → x ≡ y → y ≡ z → x ≡ z
trans refl eq = eq
cong : {A B : Set} (f : A → B) {x y : A} → x ≡ y → f x ≡ f y
cong f refl = refl
_∘_ : {A B C : Set} → (B → C) → (A → B) → (A → C)
(f ∘ g) x = f (g x)
map-functorial : {A B C : Set} (f : B → C) (g : A → B) → (xs : List A) → map (f ∘ g) xs ≡ map f (map g xs)
map-functorial f g [] = refl
map-functorial f g (x ∷ xs) = cong (f (g x) ∷_) (map-functorial f g xs)
-- equational reasoning
_≡[_]_ : {A : Set} (x : A) {y z : A} → x ≡ y → y ≡ z → x ≡ z
x ≡[ eq ] eq' = trans eq eq'
_∎ : {A : Set} (x : A) → x ≡ x
x ∎ = refl
infixr 1 _≡[_]_
infix 2 _∎
map-functorial' : {A B C : Set} (f : B → C) (g : A → B) → (xs : List A) → map (f ∘ g) xs ≡ map f (map g xs)
map-functorial' f g [] =
map (f ∘ g) []
≡[ refl ]
[]
≡[ refl ]
map f []
≡[ refl ]
map f (map g [])
map-functorial' f g (x ∷ xs) =
map (f ∘ g) (x ∷ xs)
≡[ refl ]
(f ∘ g) x ∷ map (f ∘ g) xs
≡[ refl ]
f (g x) ∷ map (f ∘ g) xs
≡[ cong (f (g x) ∷_) (map-functorial' f g xs) ]
f (g x) ∷ map f (map g xs)
≡[ refl ]
map f (g x ∷ map g xs)
≡[ refl ]
map f (map g (x ∷ xs))
-- indexed datatypes
{-# BUILTIN NATURAL Nat #-}
data Vec (A : Set) : Nat → Set where
[] : Vec A 0
_∷_ : A → {n : Nat} → Vec A n → Vec A (suc n)
vec3 : Vec Nat 3
vec3 = 0 ∷ (1 ∷ (2 ∷ []))
_++_ : {A : Set} {m n : Nat} → Vec A m → Vec A n → Vec A (m + n)
[] ++ ys = ys
(x ∷ xs) ++ ys = x ∷ (xs ++ ys)
data SumList : Nat → Set where
[] : SumList 0
_∷_ : (m : Nat) {n : Nat} → SumList n → SumList (m + n)
slist15 : SumList 15
slist15 = 3 ∷ (9 ∷ (2 ∷ (1 ∷ (0 ∷ []))))
expand : {n : Nat} → SumList n → Vec Nat n
expand [] = []
expand (x ∷ xs) = aux x ++ expand xs
where
aux : (y : Nat) → Vec Nat y
aux zero = []
aux (suc y) = y ∷ aux y
-- metamorphisms (0.625₁₀ = 0.101₂)
-- coinductive lists
mutual
record CoList (B : Set) : Set where
coinductive
field
decon : CoListF B
data CoListF (B : Set) : Set where
[] : CoListF B
_∷_ : B → CoList B → CoListF B
downFrom : Nat → CoList Nat
CoList.decon (downFrom zero ) = []
CoList.decon (downFrom (suc n)) = n ∷ downFrom n
upFrom : Nat → CoList Nat
CoList.decon (upFrom n) = n ∷ upFrom (suc n)
take : {B : Set} → Nat → CoList B → List B
take zero xs = []
take (suc n) xs with CoList.decon xs
take (suc n) xs | [] = []
take (suc n) xs | b ∷ xs' = b ∷ take n xs'
data Maybe (A : Set) : Set where
nothing : Maybe A
just : A → Maybe A
unfoldr : {B S : Set} (g : S → Maybe (B ∧ S)) → S → CoList B
CoList.decon (unfoldr g s) with g s
CoList.decon (unfoldr g s) | nothing = []
CoList.decon (unfoldr g s) | just (b , s') = b ∷ unfoldr g s'
downFrom' : Nat → CoList Nat
downFrom' = unfoldr (λ { zero → nothing; (suc n) → just (n , n) })
upFrom' : Nat → CoList Nat
upFrom' = unfoldr (λ n → just (n , suc n))
-- foldl as foldr
foldr : {A S : Set} → (A → S → S) → S → List A → S
foldr f e [] = e
foldr f e (x ∷ xs) = f x (foldr f e xs)
foldl : {A S : Set} → (S → A → S) → S → List A → S
foldl f e [] = e
foldl f e (x ∷ xs) = foldl f (f e x) xs
flip : {A B C : Set} → (A → B → C) → (B → A → C)
flip f y x = f x y
fromLeftAlg : {A S : Set} → (S → A → S) → (A → (S → S) → (S → S))
fromLeftAlg f a t = t ∘ flip f a
id : {A : Set} → A → A
id x = x
foldl-as-foldr : {A S : Set} {f : S → A → S} {e : S} (xs : List A) → foldl f e xs ≡ foldr (fromLeftAlg f) id xs e
foldl-as-foldr [] = refl
foldl-as-foldr (x ∷ xs) = foldl-as-foldr xs
-- algebraic and coalgebraic lists
data AlgList (A : Set) {S : Set} (f : A → S → S) (e : S) : S → Set where
[] : AlgList A f e e
_∷_ : (a : A) → {s : S} → AlgList A f e s → AlgList A f e (f a s)
vec3' : AlgList Nat (λ _ n → suc n) 0 3
vec3' = 0 ∷ (1 ∷ (2 ∷ []))
slist15' : AlgList Nat _+_ 0 15
slist15' = 3 ∷ (9 ∷ (2 ∷ (1 ∷ (0 ∷ []))))
mutual
record CoalgList (B : Set) {S : Set} (g : S → Maybe (B ∧ S)) (s : S) : Set where
coinductive
field
decon : CoalgListF B g s
data CoalgListF (B : Set) {S : Set} (g : S → Maybe (B ∧ S)) : S → Set where
⟨_⟩ : {s : S} → g s ≡ nothing → CoalgListF B g s
_∷⟨_⟩_ : (b : B) → {s s' : S} → g s ≡ just (b , s') → CoalgList B g s' → CoalgListF B g s
open CoalgList
single : CoalgList Nat (λ { zero → nothing; (suc n) → just (n , n) }) 1
CoalgList.decon single = 0 ∷⟨ refl ⟩ none
where
none : CoalgList Nat _ 0
CoalgList.decon none = ⟨ refl ⟩
-- metamorphic algorithms
data Inspect {A B : Set} (f : A → B) (x : A) (y : B) : Set where
[[_]] : f x ≡ y → Inspect f x y
inspect : {A B : Set} (f : A → B) (x : A) → Inspect f x (f x)
inspect f x = [[ refl ]]
module _ {A B S : Set} (f : S → A → S) (g : S → Maybe (B ∧ S)) where
meta : {h : S → S} → AlgList A (fromLeftAlg f) id h → (s : S) → CoalgList B g (h s)
decon (meta [] s) with g s | inspect g s
decon (meta [] s) | nothing | [[ eq ]] = ⟨ eq ⟩
decon (meta [] s) | just (b , s') | [[ eq ]] = b ∷⟨ eq ⟩ meta [] s'
decon (meta (a ∷ as) s) = decon (meta as (f s a))
module _ {A B S : Set} (f : S → A → S) (g : S → Maybe (B ∧ S))
(streaming-condition : {a : A} {b : B} {s s' : S} → g s ≡ just (b , s') → g (f s a) ≡ just (b , f s' a)) where
lemma : {s : S} {b : B} {s' : S} {h : S → S} →
AlgList A (fromLeftAlg f) id h →
g s ≡ just (b , s') → g (h s) ≡ just (b , h s')
lemma [] eq = eq
lemma (a ∷ as) eq = lemma as (streaming-condition eq)
stream : {h : S → S} → AlgList A (fromLeftAlg f) id h → (s : S) → CoalgList B g (h s)
decon (stream as s) with g s | inspect g s
decon (stream [] s) | nothing | [[ eq ]] = ⟨ eq ⟩
decon (stream (a ∷ as) s) | nothing | [[ eq ]] = decon (stream as (f s a))
decon (stream as s) | just (b , s') | [[ eq ]] = b ∷⟨ lemma as eq ⟩ stream as s'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment