0 | module Data.Container.Base.Properties.Instances
4 | import Data.List.Quantifiers
5 | import Decidable.Equality
6 | import Data.Fin.Split
9 | import Data.Container.Base.Object.Definition
10 | import Data.Container.Base.Morphism.Definition
11 | import Data.Container.Base.Extension.Definition
12 | import Data.Container.Base.Properties.Definition
13 | import Data.Container.Base.Endofunctor.Definition
14 | import Data.Container.Base.Product.Definition
16 | import Data.Container.Base.Object.Instances
17 | import Data.Container.Base.Extension.Instances
18 | import Data.Container.Base.Morphism.Instances
21 | import Data.Functor.Products
22 | import Data.Functor.Algebra
24 | import Data.Container.Base.TreeUtils
28 | %hide Data.Vect.fromList
29 | %hide Prelude.toList
38 | EmptyExt : {0 c : Cont} -> IsNaperian c => Ext c Unit
39 | EmptyExt @{Via _} = () <| \_ => ()
42 | liftA2ConstCont : IsNaperian c => Ext c a -> Ext c b -> Ext c (a, b)
43 | liftA2ConstCont @{Via _} ea eb = () <| (\x => (index ea x, index eb x))
49 | IsNaperian c => Applicative (Ext c) where
50 | pure @{Via _} a = () <| \_ => a
51 | (<*>) fs xs @{Via _} = uncurry ($) <$> liftA2ConstCont fs xs
53 | namespace CompositionTensorInteraction
57 | compToTensor : IsNaperian d =>
59 | compToTensor @{(Via dPos)} = !% \(cShp <| content) =>
60 | (
(cShp,()) ** \(cPos, dPos) => (
cPos ** dPos))
63 | compToTensor2 : IsFlat c =>
65 | compToTensor2 @{(Via cShp)} = !% \(cShp <| dShp) =>
66 | (
(cShp, dShp ()) ** \((), dPos') => (
() ** dPos'))
70 | transposeLens : IsNaperian c => IsNaperian d => c >@ d =%> d >@ c
71 | transposeLens @{Via _} @{Via _} = !% \(() <| _) =>
72 | (
() <| (\_ => ()) ** \(
dInd ** cInd)
=> (
cInd ** dInd))
75 | transpose : IsNaperian c => IsNaperian d =>
76 | Tensor [c, d] =%> Tensor [d, c]
77 | transpose @{Via _} @{Via _} = wrapIntoMatrix transposeLens
95 | namespace CubicalHelpers
98 | cubicalShapeHelper : All IsCubical shape -> List Nat
99 | cubicalShapeHelper [] = []
100 | cubicalShapeHelper (ic :: ics) = dimHelper ic :: cubicalShapeHelper ics
104 | cubicalShape : (0 shape : List Cont) -> All IsCubical shape => List Nat
105 | cubicalShape _ @{ac} = cubicalShapeHelper ac
109 | size : (0 shape : List Cont) -> All IsCubical shape => Nat
110 | size shape = prod (cubicalShape shape)
114 | flattenCubical : {shape : List Cont} ->
115 | (ac : All IsCubical shape) =>
117 | Tensor shape =%> Vect (size shape)
118 | flattenCubical {shape = [], ac=[]} _ = !% \() => (
() ** \FZ => ())
119 | flattenCubical {shape = (_ :: ss), ac=(Via n :: as)} lo
120 | = !% \(() <| t) => (
() ** \idx =>
121 | let (!% recBackward) = flattenCubical {shape = ss} lo
122 | (i, rest) = splitFinProd lo idx
123 | (
_ ** backRec)
= recBackward (t i)
124 | in (
i ** backRec rest))
128 | unflattenCubical : {shape : List Cont} ->
129 | (ac : All IsCubical shape) =>
131 | Vect (size shape) =%> Tensor shape
132 | unflattenCubical {shape = [], ac=[]} lo = !% \() => (
() ** \() => FZ)
133 | unflattenCubical {shape = (_ :: ss), ac=((Via n) :: as)} lo =
134 | let (!% f) = unflattenCubical {shape = ss} lo
135 | (
innerShape ** innerBack)
= f ()
136 | in !% \() => (
(() <| \_ => innerShape) ** (\(
cp ** restPos)
=>
137 | indexFinProd lo cp (innerBack restPos)))
141 | recastFlattenedTensor : {oldShape, newShape : List Cont} ->
142 | (oldAc : All IsCubical oldShape) => (newAc : All IsCubical newShape) =>
143 | {auto prf : size oldShape = size newShape} ->
144 | Vect (size oldShape) =%> Vect (size newShape)
145 | recastFlattenedTensor = !% \() => (
() ** \i => rewrite prf in i)
151 | reshape : {oldShape, newShape : List Cont} ->
152 | (oldAc : All IsCubical oldShape) => (newAc : All IsCubical newShape) =>
154 | {auto prf : size oldShape = size newShape} ->
155 | Tensor oldShape =%> Tensor newShape
156 | reshape lo = flattenCubical lo
157 | %>> recastFlattenedTensor
158 | %>> unflattenCubical lo
161 | namespace TransformIntoHancockTensor
163 | hancockTensorNaperianShape : {shape : List Cont} ->
164 | (allNap : All IsNaperian shape) =>
165 | (HancockTensor shape).Shp
166 | hancockTensorNaperianShape {shape = []} = ()
167 | hancockTensorNaperianShape {allNap = ((Via _) :: _)}
168 | = ((), hancockTensorNaperianShape)
172 | tensorNaperianShape : {shape : List Cont} ->
173 | (allNap : All IsNaperian shape) =>
175 | tensorNaperianShape {shape = []} = ()
176 | tensorNaperianShape {shape = (_ :: ss), allNap = ((Via _) :: ns)}
177 | = () <| \_ => tensorNaperianShape {shape = ss} @{ns}
183 | hancockTensorPosEq : {shape : List Cont} ->
184 | (allNap : All IsNaperian shape) =>
185 | {0 x, y : (HancockTensor shape).Shp} ->
186 | (HancockTensor shape).Pos x = (HancockTensor shape).Pos y
187 | hancockTensorPosEq {allNap = []} = Refl
188 | hancockTensorPosEq {allNap = ((Via _) :: _)} = cong2 Pair
189 | (naperianPosEq @{Via _} {x=()} {y=()})
195 | transformToHancock : {shape : List Cont} ->
196 | All IsNaperian shape =>
197 | Tensor shape =%> HancockTensor shape
198 | transformToHancock {shape = []} = id
199 | transformToHancock {shape = (_ :: _)} @{((Via _) :: _)}
200 | = !% \(() <| content) => (
((), hancockTensorNaperianShape) **
202 | let (
_ ** recBack)
= (%!) transformToHancock (content p)
203 | in (
p ** recBack $
replace {p = id} hancockTensorPosEq restPos))
206 | transformFromHancock : {shape : List Cont} ->
207 | All IsNaperian shape =>
208 | HancockTensor shape =%> Tensor shape
209 | transformFromHancock {shape = []} = id
210 | transformFromHancock {shape = (Nap s :: ss)} @{((Via s) :: _)}
211 | = !% \((), hShp) =>
212 | let (
tShp ** recBack)
= (%!) transformFromHancock hShp
213 | in (
() <| (\_ => tShp) ** \(
p ** restPos)
=> (p, recBack restPos))
216 | IsConcrete Scalar where
218 | functorInstance = MkFunctor id
219 | fromConcreteTy x = () <| \_ => x
220 | toConcreteTy (() <| f) = f ()
223 | IsConcrete UnitCont where
225 | functorInstance = MkFunctor (\f, () => ())
226 | fromConcreteTy () = () <| absurd
227 | toConcreteTy _ = ()
230 | IsConcrete Maybe where
232 | functorInstance = %search
234 | fromConcreteTy Nothing = False <| absurd
235 | fromConcreteTy (Just x) = True <| \() => x
237 | toConcreteTy (False <| _) = Nothing
238 | toConcreteTy (True <| f) = Just (f ())
241 | IsConcrete Pair where
242 | func = \a => Pair a a
243 | functorInstance = MkFunctor $
\f, (x, y) => (f x, f y)
244 | fromConcreteTy (x, y) = () <| \case False => x;
True => y
245 | toConcreteTy (() <| f) = (f False, f True)
252 | lambdaNap : {s : Type} -> IsConcrete (Nap s)
253 | lambdaNap = MkIsConcrete
256 | (\content => () <| content)
257 | (\(() <| content) => content)
260 | (icc : IsConcrete c) => (icd : IsConcrete d) => IsConcrete (c >< d) where
261 | func = func @{icc} >< func @{icd}
262 | functorInstance = ?functorInstanceHancockProduct
263 | fromConcreteTy = ?fromConcreteTyHancockProduct
264 | toConcreteTy = ?toConcreteTyHancockProduct
267 | (icc : IsConcrete c) => (icd : IsConcrete d) => IsConcrete (c >@ d) where
268 | func = func @{icc} . func @{icd}
269 | functorInstance = MkFunctor $
\f => ?functorInstanceCompositionProduct
270 | fromConcreteTy = ?fromConcreteTyCompositionProduct
271 | toConcreteTy = ?toConcreteTyCompositionProduct
278 | IsConcrete List where
280 | functorInstance = %search
281 | fromConcreteTy = fromList
282 | toConcreteTy = toList
294 | {n : Nat} -> IsConcrete (Vect n) where
296 | functorInstance = %search
297 | fromConcreteTy = fromVect
298 | toConcreteTy = toVect
302 | {h, w : Nat} -> IsConcrete (Grid (h, w)) where
303 | func a = (Fin h, Fin w) -> a
304 | functorInstance = MkFunctor (.)
305 | fromConcreteTy content = ((), ()) <| content
306 | toConcreteTy (((), ()) <| content) = content
308 | namespace BinTreeSame
310 | IsConcrete BinTree where
312 | functorInstance = %search
313 | fromConcreteTy = fromBinTreeSame
314 | toConcreteTy = toBinTreeSame
316 | namespace BinTreeNode
318 | IsConcrete BinTreeNode where
320 | functorInstance = %search
321 | fromConcreteTy = fromBinTreeNode
322 | toConcreteTy = toBinTreeNode
324 | namespace BinTreeLeaf
326 | IsConcrete BinTreeLeaf where
328 | functorInstance = %search
329 | fromConcreteTy = fromBinTreeLeaf
330 | toConcreteTy = toBinTreeLeaf
336 | maybeIsDecidable : IsDecidable Maybe
337 | maybeIsDecidable = MkI decPos
338 | where decPos : (b : Bool) -> DecEq (if b then Unit else Void)
339 | decPos False = %search
340 | decPos True = %search
344 | maybeTwoIsDecidable : IsDecidable MaybeTwo
345 | maybeTwoIsDecidable = MkI decPos
346 | where decPos : (b : Bool) -> DecEq (if b then Fin 2 else Void)
347 | decPos False = %search
348 | decPos True = %search
351 | compositionIsDecidable : IsDecidable c => IsDecidable d => IsDecidable (c >@ d)
352 | compositionIsDecidable @{cd} @{dd} = MkI $
\ex => DecEqDPair
353 | @{GetInterface cd (shapeExt ex)} @{\cp => GetInterface dd (index ex cp)}
357 | hancockIsDecidable : IsDecidable c => IsDecidable d => IsDecidable (c >< d)
358 | hancockIsDecidable @{cd} @{dd} = MkI $
\ss =>
359 | let decC = GetInterface cd (fst ss)
360 | decD = GetInterface dd (snd ss)
365 | cartesianIsDecidable : IsDecidable c => IsDecidable d => IsDecidable (c >*< d)
366 | cartesianIsDecidable @{cd} @{dd} = MkI $
\ss =>
367 | let decC = GetInterface cd (fst ss)
368 | decD = GetInterface dd (snd ss)
373 | coproductIsDecidable : IsDecidable c => IsDecidable d => IsDecidable (c >+< d)
374 | coproductIsDecidable @{cd} @{dd} = MkI decPos
375 | where decPos : (es : Either c.Shp d.Shp) -> DecEq (either c.Pos d.Pos es)
376 | decPos (Left s) = GetInterface cd s
377 | decPos (Right s) = GetInterface dd s
382 | tensorIsDecidable : All IsDecidable cs => IsDecidable (Tensor cs)
383 | tensorIsDecidable @{[]} = %search
384 | tensorIsDecidable @{cd :: cds}
385 | = compositionIsDecidable @{cd} @{tensorIsDecidable @{cds}}
407 | IsFoldable c => Foldable (Ext c) where
408 | foldr @{Along toL} f z e = foldr
409 | (\p, acc => f (index e p) acc)
411 | (tabulate (toL.bwd (shapeExt e)))
416 | enumerableIsFoldable : IsEnumerable c => IsFoldable c
417 | enumerableIsFoldable @{MkIsEnum e} = Along (!% (%! ((:%) e)))
422 | listIsEnumerable : IsEnumerable List
423 | listIsEnumerable = MkIsEnum (!: \n => (
n ** idIso)
)
427 | list1IsEnumerable : IsEnumerable List1
428 | list1IsEnumerable = MkIsEnum (!: \n => (
S n ** idIso)
)
432 | vectIsEnumerable : {n : Nat} -> IsEnumerable (Vect n)
433 | vectIsEnumerable = MkIsEnum (!: \() => (
n ** idIso)
)
437 | forgetOrder : List =%> Bag
438 | forgetOrder = !% \n => (
n ** toFin)
443 | foldableIsSummable : IsFoldable c => IsSummable c
444 | foldableIsSummable @{Along toL} = Along (toL %>> forgetOrder)
448 | foldableAt : IsFoldable c => (s : c.Shp) -> IsFoldable (At c s)
449 | foldableAt s = Along (atShape s %>> mapToList)
453 | index : IsFoldable c => Pick c a =%> List
454 | index = pick %>> mapToList
461 | binTreeLeafIsEnumerable : IsEnumerable BinTreeLeaf
462 | binTreeLeafIsEnumerable = MkIsEnum (!: \b => (
numLeaves b ** MkIso
463 | ?inorderForward_binTreeLeaf
(BinTreeLeaf.inorderBackward b)
464 | ?inorderForwardBackward_binTreeLeaf ?inorderBackwardForward_binTreeLeaf)
)
468 | binTreeNodeIsEnumerable : IsEnumerable BinTreeNode
469 | binTreeNodeIsEnumerable = MkIsEnum (!: \b => (
numNodes b ** MkIso
470 | ?inorderForward_binTreeNode
(BinTreeNode.inorderBackward b)
471 | ?inorderForwardBackward_binTreeNode ?inorderBackwardForward_binTreeNode)
)
475 | binTreeIsEnumerable : IsEnumerable BinTree
476 | binTreeIsEnumerable = MkIsEnum (!: \b => (
numNodesAndLeaves b ** MkIso
477 | ?inorderForward_binTree
(BinTree.inorderBackward b)
478 | ?inorderForwardBackward_binTree ?inorderBackwardForward_binTree)
)
482 | algebraFoldable : {f : Type -> Type} ->
483 | Foldable f => Num a => Algebra f a
484 | algebraFoldable = MkAlgebra sum
489 | IsFoldable c => Num a => Algebra (Ext c) a where
493 | argmax : Ord a => (isF : IsFoldable c) => (ne : IsNonEmpty c) =>
494 | (e : Ext c a) -> c.Pos (shapeExt e)
496 | (\p, best => if index e p >= index e best then p else best)
497 | (GetInterface ne (shapeExt e))
503 | IsEnumerable c => Traversable (Ext c) where
504 | traverse f (sh <| ind) =
505 | let (
n ** iso)
= (:!) enumerate sh
506 | in (\v => sh <| index (fromVect v) . iso.forward)
507 | <$> traverse f (toVect (() <| ind . iso.backward))