Agda-2.3.2.2: examples/AIM5/PolyDep/Homogenous/Base.agda
{-# OPTIONS --no-positivity-check --no-termination-check #-}
module Homogenous.Base where
-- module Homogenous.Base(Arity, Sig, T, Intro) where
import TYPE
import PolyDepPrelude
open PolyDepPrelude using
( Absurd
; Unit; unit
; Nat; zero; suc
; List; nil; _::_
; Either; left; right
; Pair; pair)
-- A homogenous algebra can be represented by a list of arities
-- (natural numbers)
Arity : Set
Arity = Nat
Sig : Set
Sig = List Arity
-- Many definitions below come in pairs - one for Arity and one for
-- Sig - where name of the first one ends in a (as in Arity) :
-- funa : Arity -> ...
-- fun : Sig -> ...
-- (Fa n,Fa1 n) is the functor "n-tuple of same type" or
-- "vector of length n" or "(^n)"
Fa : (n : Arity) -> Set -> Set
Fa (zero) X = Unit
Fa (suc m) X = Pair X (Fa m X)
----------------------------------------------------------------
Fa1 : (n : Arity) -> {a b : Set} -> (a -> b) -> Fa n a -> Fa n b
Fa1 (zero) f (unit) = unit
Fa1 (suc m) f (pair fst snd) = pair (f fst) (Fa1 m f snd)
-- (F fi, F1 fi) is the pattern functor for a homogenous algebra
F : (fi : Sig)(X : Set) -> Set
F (nil) X = Absurd
F (n :: fi') X = Either (Fa n X) (F fi' X)
F1 : (fi : Sig){a b : Set}(f : a -> b)(x : F fi a) -> F fi b
F1 (nil) f () -- empty
F1 (n :: ns) f (left t) = left (Fa1 n f t)
F1 (n :: ns) f (right y) = right (F1 ns f y)
-- For the definition of the recursor R we need family-level
-- variants of F and F1 : FIH and Fmap. As usual we define these first
-- for arities (with a postfix 'a' in the name) and then for signatures.
FIHa : (n : Arity){X : Set}(C : X -> Set)(x : Fa n X) -> Set
FIHa (zero) C unit = Unit
FIHa (suc m) C (pair fst snd) = Pair (C fst) (FIHa m C snd)
FIH : (fi : Sig){X : Set}(C : X -> Set)(x : F fi X) -> Set
FIH (nil) C () -- empty
FIH (n :: ns) C (left t) = FIHa n C t
FIH (n :: ns) C (right y) = FIH ns C y
Fmapa : (n : Arity){X : Set}{C : X -> Set}(h : (x : X) -> C x)(u : Fa n X)
-> FIHa n C u
Fmapa (zero) h (unit) = unit
Fmapa (suc m) h (pair fst snd) = pair (h fst) (Fmapa m h snd)
Fmap : (fi : Sig){X : Set}{C : X -> Set}(h : (x : X) -> C x)(u : F fi X)
-> FIH fi C u
Fmap (nil) h () -- empty
Fmap (n :: ns) h (left x) = Fmapa n h x
Fmap (n :: ns) h (right y) = Fmap ns h y
-- Finally the homogenous algebra construction itself - for each code
-- fi there is a datatype T fi and an iterator It fi
data T (fi : Sig) : Set where
Intro : F fi (T fi) -> T fi
It : (fi : Sig){C : Set}(d : F fi C -> C) -> T fi -> C
It fi d (Intro i) = d (F1 fi (It fi d) i)
-- Mendler style iterator is also straight forward
MIt : (fi : Sig){C : Set}(s : {X : Set} -> (X -> C) -> F fi X -> C)
-> T fi -> C
MIt fi s (Intro i) = s (MIt fi s) i
R : (fi : Sig)
{C : T fi -> Set}
(d : (y : F fi (T fi)) -> FIH fi C y -> C (Intro y))
(x : T fi) -> C x
R fi d (Intro i) = d i (Fmap fi (R fi d) i)
-- Special case of FIH
FIHs : (fi : Sig) -> (T fi -> Set) -> F fi (T fi) -> Set
FIHs fi = FIH fi
-- A simple example : the inverse of Intro
out : (fi : Sig) -> T fi -> F fi (T fi)
out fi = R fi (\y p -> y)
----------------------------------------------------------------
-- Now for the Type level : define FIHa, FIH, Fmapa, Fmap again
-- (universe polymorphism, please!)
FIHaT : (n : Arity)(X : Set)(C : X -> Set1)(x : Fa n X) -> Set1
FIHaT (zero) X C (unit) = TYPE.Unit
FIHaT (suc m) X C (pair fst snd) = TYPE.Pair (C fst) (FIHaT m X C snd)
FIHT : (fi : Sig)(X : Set)(C : X -> Set1)(x : F fi X) -> Set1
FIHT (nil) X C () -- empty
FIHT (n :: ns) X C (left t) = FIHaT n X C t
FIHT (n :: ns) X C (right y) = FIHT ns X C y
FIHsT : (fi : Sig)(C : T fi -> Set1)(x : F fi (T fi)) -> Set1
FIHsT fi C x = FIHT fi (T fi) C x
FmapaT : (n : Arity){X : Set}{C : X -> Set1}(h : (x : X) -> C x)(u : Fa n X)
-> FIHaT n X C u
FmapaT (zero) h (unit) = TYPE.unit
FmapaT (suc m) h (pair fst snd) = TYPE.pair (h fst) (FmapaT m h snd)
FmapT : (fi : Sig){X : Set}{C : X -> Set1}(h : (x : X) -> C x)(u : F fi X)
-> FIHT fi X C u
FmapT (nil) h () -- empty
FmapT (n :: ns) h (left x') = FmapaT n h x'
FmapT (n :: ns) h (right y) = FmapT ns h y
RT : (fi : Sig)
{C : T fi -> Set1}
(d : (y : F fi (T fi)) -> FIHT fi (T fi) C y -> C (Intro y))
(x : T fi) -> C x
RT fi d (Intro i) = d i (FmapT fi (RT fi d) i)