5 | module Data.Description.Regular
13 | data Desc : (p : Type -> Type) -> Type where
21 | Const : (0 s : Type) -> (prop : p s) -> Desc p
23 | (*) : (d1, d2 : Desc p) -> Desc p
25 | (+) : (d1, d2 : Desc p) -> Desc p
29 | 0 Elem : Desc p -> Type -> Type
33 | Elem (Const s _) x = s
34 | Elem (d1 * d2) x = (Elem d1 x, Elem d2 x)
35 | Elem (d1 + d2) x = Either (Elem d1 x) (Elem d2 x)
39 | map : (d : Desc p) -> (a -> b) -> Elem d a -> Elem d b
40 | map d f = go d where
42 | go : (d : Desc p) -> Elem d a -> Elem d b
46 | go (Const s _) v = v
47 | go (d1 * d2) (v, w) = (go d1 v, go d2 w)
48 | go (d1 + d2) (Left v) = Left (go d1 v)
49 | go (d1 + d2) (Right v) = Right (go d2 v)
56 | data Fix : Desc p -> Type where
57 | MkFix : assert_total (Elem d (Fix d)) -> Fix d
61 | ListD : Type -> Desc (const ())
62 | ListD a = One + (Const a () * Id)
64 | RList : Type -> Type
65 | RList a = Fix (ListD a)
68 | Nil = MkFix (Left ())
70 | (::) : a -> RList a -> RList a
71 | x :: xs = MkFix (Right (x, xs))
75 | fold : {d : Desc p} -> (Elem d x -> x) -> Fix d -> x
76 | fold alg (MkFix v) = alg (assert_total $
map d (fold alg) v)
82 | 0 Memo : (e : Desc p) -> ((a -> Type) -> Type) -> (Elem e a -> Type) -> Type
86 | Memo (Const s prop) x b = (v : s) -> b v
87 | Memo (d1 * d2) x b = Memo d1 x $
\ v1 => Memo d2 x $
\ v2 => b (v1, v2)
88 | Memo (d1 + d2) x b = (Memo d1 x (b . Left), Memo d2 x (b . Right))
94 | record (~>) {p : Type -> Type} (d : Desc p) (b : Fix d -> Type) where
96 | getMemo : assert_total (Memo d (\ x => Inf (d ~> x)) (b . MkFix))
99 | trie : {d : Desc p} -> {0 b : Fix d -> Type} -> ((x : Fix d) -> b x) -> d ~> b
100 | trie f = MkMemo (go d (\ t => f (MkFix t))) where
102 | go : (e : Desc p) ->
103 | {0 b' : Elem e (Fix d) -> Type} ->
104 | (f : (x : Elem e (Fix d)) -> b' x) ->
105 | Memo e (\ x => Inf (d ~> x)) b'
108 | go Id f = assert_total trie f
109 | go (Const s prop) f = f
110 | go (d1 * d2) f = go d1 $
\ v1 => go d2 $
\ v2 => f (v1, v2)
111 | go (d1 + d2) f = (go d1 (\ v => f (Left v)), go d2 (\ v => f (Right v)))
114 | untrie : {d : Desc p} -> {0 b : Fix d -> Type} -> d ~> b -> ((x : Fix d) -> b x)
115 | untrie (MkMemo f) (MkFix t) = go d f t where
117 | go : (e : Desc p) ->
118 | {0 b' : Elem e (Fix d) -> Type} ->
119 | Memo e (\ x => Inf (d ~> x)) b' ->
120 | (x : Elem e (Fix d)) -> b' x
121 | go Zero mem x = absurd x
122 | go One mem () = mem
123 | go Id mem x = untrie mem x
124 | go (Const s prop) mem x = mem x
125 | go (d1 * d2) mem (x, y) = go d2 (go d1 mem x) y
126 | go (d1 + d2) mem (Left x) = go d1 (fst mem) x
127 | go (d1 + d2) mem (Right x) = go d2 (snd mem) x
130 | memo : {d : Desc p} -> (0 b : Fix d -> Type) ->
131 | ((x : Fix d) -> b x) -> ((x : Fix d) -> b x)
132 | memo b f = untrie (trie f)