14 | Coforest : Type -> Type
18 | record Cotree (a : Type) where
19 | constructor MkCotree
21 | forest : Inf (Coforest a)
23 | Coforest = Colist . Cotree
26 | singleton : a -> Cotree a
27 | singleton a = MkCotree a Nil
30 | unfold : (f : b -> (a,Colist b)) -> b -> Cotree a
33 | in MkCotree va $
unfoldF bs
36 | unfoldF : Colist b -> Coforest a
38 | unfoldF (h :: t) = unfold f h :: unfoldF t
41 | iterate : (f : a -> Colist a) -> a -> Cotree a
42 | iterate f a = unfold (\v => (v, f v)) a
45 | expand : (a -> Colist a) -> Cotree a -> Cotree a
46 | expand f (MkCotree v vs) =
47 | let MkCotree v2 vs2 := iterate f v
48 | in MkCotree v2 (run vs vs2)
51 | run : Coforest a -> Coforest a -> Coforest a
53 | run (x :: xs) ys = expand f x :: run xs ys
60 | fromTree : Tree a -> Cotree a
61 | fromTree (MkTree v fo) = MkCotree v (fromForest fo)
64 | fromForest : Forest a -> Coforest a
66 | fromForest (x :: xs) = fromTree x :: fromForest xs
72 | toTree : (maxDepth : Nat) -> (maxWidth : Nat) -> Cotree a -> Tree a
73 | toTree 0 _ (MkCotree v fo) = MkTree v []
74 | toTree (S k) mw (MkCotree v fo) = MkTree v (toForest mw fo)
77 | toForest : Nat -> Coforest a -> Forest a
79 | toForest (S n) [] = []
80 | toForest (S n) (t :: ts) = toTree k mw t :: toForest n ts
87 | mapCotree : (a -> b) -> Cotree a -> Cotree b
88 | mapCotree f (MkCotree v vs) = MkCotree (f v) (mapForest vs)
91 | mapForest : Coforest a -> Coforest b
93 | mapForest (h :: t) = mapCotree f h :: mapForest t
96 | interleave : Cotree (a -> b) -> Cotree a -> Cotree b
97 | interleave tf@(MkCotree vf fs) ta@(MkCotree va as) =
98 | MkCotree (vf va) (interleaveFs fs)
101 | interleaveAs : Coforest a -> Coforest b
102 | interleaveAs [] = []
103 | interleaveAs (h :: t) = interleave tf h :: interleaveAs t
105 | interleaveFs : Coforest (a -> b) -> Coforest b
106 | interleaveFs [] = interleaveAs as
107 | interleaveFs (h :: t) = interleave h ta :: interleaveFs t
110 | bind : Cotree a -> (a -> Cotree b) -> Cotree b
111 | bind (MkCotree v vs) f =
112 | let MkCotree w ws := f v
113 | in MkCotree w (run vs ws)
116 | run : Coforest a -> Coforest b -> Coforest b
118 | run (x :: xs) ys = bind x f :: run xs ys
121 | bindMaybe : Cotree (Maybe a) -> (a -> Cotree (Maybe b)) -> Cotree (Maybe b)
122 | bindMaybe (MkCotree mv tas) f =
124 | Nothing => MkCotree Nothing (run tas Nil)
125 | Just (MkCotree mb tbs) => MkCotree mb (run tas tbs)
128 | run : Coforest (Maybe a) -> Coforest (Maybe b) -> Coforest (Maybe b)
130 | run (x :: xs) ys = bindMaybe x f :: run xs ys
137 | shrink : (maxSteps : Nat) -> Cotree (Maybe a) -> List a
138 | shrink maxSteps x = run maxSteps [x]
141 | run : Nat -> Coforest (Maybe a) -> List a
144 | run (S k) (h :: t) =
146 | Just a => a :: run k h.forest
150 | mapShrink : (maxSteps : Nat) -> (a -> Maybe b) -> Cotree a -> List b
151 | mapShrink ms f = shrink ms . mapCotree f
154 | shrinkIf : (maxSteps : Nat) -> (a -> Bool) -> Cotree a -> List a
155 | shrinkIf ms p = mapShrink ms (\a => if p a then Just a else Nothing)
159 | pruneTo : (width : Nat) -> (depth : Nat) -> Cotree a -> Cotree a
160 | pruneTo _ 0 (MkCotree v _ ) = MkCotree v Nil
161 | pruneTo w (S d) (MkCotree v vs) = MkCotree v $
(map (pruneTo w d) $
keep w vs)
164 | keep : Nat -> Colist t -> Colist t
167 | keep (S k) (x :: xs) = x :: keep k xs
171 | prune : Cotree a -> Cotree a
172 | prune = pruneTo 0 0
179 | Functor Cotree where
183 | Applicative Cotree where
192 | takeUntil : (a -> Bool) -> Cotree a -> Cotree a
193 | takeUntil f (MkCotree v vs) =
196 | else MkCotree v (takeUntilF vs)
199 | takeUntilF : Coforest a -> Coforest a
201 | takeUntilF (MkCotree x xs :: ts) =
203 | then [MkCotree x []]
204 | else MkCotree x (takeUntilF xs) :: takeUntilF ts
207 | takeBeforeNothing : Cotree (Maybe a) -> Maybe (Cotree a)
208 | takeBeforeNothing (MkCotree Nothing _) = Nothing
209 | takeBeforeNothing (MkCotree (Just v) vs) = Just (MkCotree v (run vs))
212 | run : Coforest (Maybe a) -> Coforest a
214 | run ((MkCotree Nothing _) :: _) = []
215 | run ((MkCotree (Just v) vs) :: ts) = MkCotree v (run vs) :: run ts
218 | takeBefore : (a -> Bool) -> Cotree a -> Maybe (Cotree a)
219 | takeBefore f = takeBeforeNothing . map (\a => toMaybe (f a) a)
221 | public export %inline
222 | takeWhile : (a -> Bool) -> Cotree a -> Maybe (Cotree a)
223 | takeWhile f = takeBefore (not . f)
225 | public export %inline
226 | mapMaybe : (a -> Maybe b) -> Cotree a -> Maybe (Cotree b)
227 | mapMaybe f = takeBeforeNothing . map f