{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Array.Knead.Shape (
   C(..), Index,
   Size,
   value,
   paramWith,
   load,
   intersect,
   offset,

   ZeroBased(ZeroBased), zeroBased, zeroBasedSize,

   Range(Range), range, rangeFrom, rangeTo,
   Shifted(Shifted), shifted, shiftedOffset, shiftedSize,
   Cyclic(Cyclic), cyclic, cyclicSize,

   Enumeration(Enumeration), EnumBounded(..),

   Scalar(..),
   Sequence(..),
   ) where

import qualified Data.Array.Knead.Expression as Expr
import Data.Array.Knead.Shape.Orphan
         (zeroBased, zeroBasedSize, cyclic, cyclicSize,
          singletonRange, unzipRange, singletonShifted, unzipShifted)
import Data.Array.Knead.Expression (Exp, )

import qualified Data.Array.Comfort.Shape as Shape
import Data.Array.Comfort.Shape
         (Index, ZeroBased, Range(Range), Shifted(Shifted), Cyclic,
          Enumeration(Enumeration))
import Data.Ix (Ix)

import qualified LLVM.DSL.Parameter as Param

import qualified LLVM.Extra.Multi.Value.Marshal as Marshal
import qualified LLVM.Extra.Multi.Value as MultiValue
import qualified LLVM.Extra.Multi.Iterator as IterMV
import qualified LLVM.Extra.Tuple as Tuple
import qualified LLVM.Extra.Memory as Memory
import qualified LLVM.Extra.Iterator as Iter
import qualified LLVM.Extra.ScalarOrVector as SoV
import qualified LLVM.Extra.Arithmetic as A
import LLVM.Extra.Multi.Value (atom)

import qualified LLVM.Core as LLVM

import qualified Data.Enum.Storable as Enum
import Data.Tagged (Tagged)
import Data.Tuple.HT (mapSnd)
import Data.Word (Word8, Word16, Word32, Word64, Word)
import Data.Int (Int8, Int16, Int32, Int64)

import qualified Control.Monad.HT as Monad
import Control.Applicative ((<$>))

import Prelude2010
import Prelude ()


type Size = Word

value :: (C sh, Expr.Value val) => sh -> val sh
value :: forall sh (val :: * -> *). (C sh, Value val) => sh -> val sh
value = T sh -> val sh
forall a. T a -> val a
forall (val :: * -> *) a. Value val => T a -> val a
Expr.lift0 (T sh -> val sh) -> (sh -> T sh) -> sh -> val sh
forall b c a. (b -> c) -> (a -> b) -> a -> c
. sh -> T sh
forall a. C a => a -> T a
MultiValue.cons

paramWith ::
   (Marshal.C b) =>
   Param.T p b ->
   (forall parameters.
    (Marshal.C parameters) =>
    (p -> parameters) ->
    (forall val. (Expr.Value val) =>
     MultiValue.T parameters -> val b) ->
    a) ->
   a
paramWith :: forall b p a.
C b =>
T p b
-> (forall parameters.
    C parameters =>
    (p -> parameters)
    -> (forall (val :: * -> *). Value val => T parameters -> val b)
    -> a)
-> a
paramWith T p b
p forall parameters.
C parameters =>
(p -> parameters)
-> (forall (val :: * -> *). Value val => T parameters -> val b)
-> a
f =
   T p b
-> (forall parameters.
    C parameters =>
    (p -> parameters) -> (T parameters -> T b) -> a)
-> a
forall b p a.
C b =>
T p b
-> (forall parameters.
    C parameters =>
    (p -> parameters) -> (T parameters -> T b) -> a)
-> a
Param.withMulti T p b
p (\p -> parameters
get T parameters -> T b
val -> (p -> parameters)
-> (forall (val :: * -> *). Value val => T parameters -> val b)
-> a
forall parameters.
C parameters =>
(p -> parameters)
-> (forall (val :: * -> *). Value val => T parameters -> val b)
-> a
f p -> parameters
get (T b -> val b
forall a. T a -> val a
forall (val :: * -> *) a. Value val => T a -> val a
Expr.lift0 (T b -> val b) -> (T parameters -> T b) -> T parameters -> val b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T parameters -> T b
val))

load ::
   (Marshal.C sh) =>
   f sh -> LLVM.Value (LLVM.Ptr (Marshal.Struct sh)) ->
   LLVM.CodeGenFunction r (MultiValue.T sh)
load :: forall sh (f :: * -> *) r.
C sh =>
f sh -> Value (Ptr (Struct sh)) -> CodeGenFunction r (T sh)
load f sh
_ = Value (Ptr (Struct (Repr sh))) -> CodeGenFunction r (T sh)
Value (Ptr (Struct (T sh))) -> CodeGenFunction r (T sh)
forall llvmValue r.
C llvmValue =>
Value (Ptr (Struct llvmValue)) -> CodeGenFunction r llvmValue
forall r. Value (Ptr (Struct (T sh))) -> CodeGenFunction r (T sh)
Memory.load

intersect :: (C sh) => Exp sh -> Exp sh -> Exp sh
intersect :: forall sh. C sh => Exp sh -> Exp sh -> Exp sh
intersect = (forall r. T sh -> T sh -> CodeGenFunction r (T sh))
-> Exp sh -> Exp sh -> Exp sh
forall ae am be bm c.
(Aggregate ae am, Aggregate be bm) =>
(forall r. am -> bm -> CodeGenFunction r (T c))
-> ae -> be -> Exp c
Expr.liftM2 T sh -> T sh -> CodeGenFunction r (T sh)
forall r. T sh -> T sh -> CodeGenFunction r (T sh)
forall sh r. C sh => T sh -> T sh -> CodeGenFunction r (T sh)
intersectCode

offset ::
   (C sh) =>
   MultiValue.T sh -> MultiValue.T (Index sh) ->
   LLVM.CodeGenFunction r (LLVM.Value Size)
offset :: forall sh r.
C sh =>
T sh -> T (Index sh) -> CodeGenFunction r (Value Size)
offset T sh
sh T (Index sh)
ix = ((T (Index sh) -> CodeGenFunction r (Value Size))
-> T (Index sh) -> CodeGenFunction r (Value Size)
forall a b. (a -> b) -> a -> b
$ T (Index sh)
ix) ((T (Index sh) -> CodeGenFunction r (Value Size))
 -> CodeGenFunction r (Value Size))
-> ((Value Size, T (Index sh) -> CodeGenFunction r (Value Size))
    -> T (Index sh) -> CodeGenFunction r (Value Size))
-> (Value Size, T (Index sh) -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (Value Size)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Value Size, T (Index sh) -> CodeGenFunction r (Value Size))
-> T (Index sh) -> CodeGenFunction r (Value Size)
forall a b. (a, b) -> b
snd ((Value Size, T (Index sh) -> CodeGenFunction r (Value Size))
 -> CodeGenFunction r (Value Size))
-> CodeGenFunction
     r (Value Size, T (Index sh) -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (Value Size)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< T sh
-> CodeGenFunction
     r (Value Size, T (Index sh) -> CodeGenFunction r (Value Size))
forall sh ix r.
(C sh, Index sh ~ ix) =>
T sh
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall ix r.
(Index sh ~ ix) =>
T sh
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
sizeOffset T sh
sh

class (MultiValue.C sh, MultiValue.C (Index sh), Shape.Indexed sh) => C sh where
   {-
   It would be better to restrict zipWith to matching shapes
   and turn shape intersection into a bound check.
   -}
   intersectCode ::
      MultiValue.T sh -> MultiValue.T sh ->
      LLVM.CodeGenFunction r (MultiValue.T sh)
   size :: MultiValue.T sh -> LLVM.CodeGenFunction r (LLVM.Value Size)
   {- |
   Result is @(size, offset)@.
   @size@ must equal the result of 'size'.
   We use this for sharing intermediate results.
   -}
   sizeOffset ::
      (Index sh ~ ix) =>
      MultiValue.T sh ->
      LLVM.CodeGenFunction r
         (LLVM.Value Size,
          MultiValue.T ix -> LLVM.CodeGenFunction r (LLVM.Value Size))
   iterator :: (Index sh ~ ix) => MultiValue.T sh -> Iter.T r (MultiValue.T ix)
   loop ::
      (Index sh ~ ix, Tuple.Phi state) =>
      (MultiValue.T ix -> state -> LLVM.CodeGenFunction r state) ->
      MultiValue.T sh -> state -> LLVM.CodeGenFunction r state
   loop T ix -> state -> CodeGenFunction r state
f T sh
sh = (T ix -> state -> CodeGenFunction r state)
-> T r (T ix) -> state -> CodeGenFunction r state
forall t a r.
Phi t =>
(a -> t -> CodeGenFunction r t)
-> T r a -> t -> CodeGenFunction r t
Iter.mapState_ T ix -> state -> CodeGenFunction r state
f (T sh -> T r (T ix)
forall sh ix r. (C sh, Index sh ~ ix) => T sh -> T r (T ix)
forall ix r. (Index sh ~ ix) => T sh -> T r (T ix)
iterator T sh
sh)


instance C () where
   intersectCode :: forall r. T () -> T () -> CodeGenFunction r (T ())
intersectCode T ()
_ T ()
_ = T () -> CodeGenFunction r (T ())
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return (T () -> CodeGenFunction r (T ()))
-> T () -> CodeGenFunction r (T ())
forall a b. (a -> b) -> a -> b
$ () -> T ()
forall a. C a => a -> T a
MultiValue.cons ()
   size :: forall r. T () -> CodeGenFunction r (Value Size)
size T ()
_ = Value Size -> CodeGenFunction r (Value Size)
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return Value Size
forall a. IntegerConstant a => a
A.one
   sizeOffset :: forall ix r.
(Index () ~ ix) =>
T ()
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
sizeOffset T ()
_ = (Value Size, T ix -> CodeGenFunction r (Value Size))
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value Size
forall a. IntegerConstant a => a
A.one, \T ix
_ -> Value Size -> CodeGenFunction r (Value Size)
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return Value Size
forall a. Additive a => a
A.zero)
   iterator :: forall ix r. (Index () ~ ix) => T () -> T r (T ix)
iterator = T () -> T r (T ix)
T () -> T r (T ())
forall a r. a -> T r a
Iter.singleton
   loop :: forall ix state r.
(Index () ~ ix, Phi state) =>
(T ix -> state -> CodeGenFunction r state)
-> T () -> state -> CodeGenFunction r state
loop = (T ix -> state -> CodeGenFunction r state)
-> T ix -> state -> CodeGenFunction r state
(T ix -> state -> CodeGenFunction r state)
-> T () -> state -> CodeGenFunction r state
forall a. a -> a
id


class C sh => Scalar sh where
   scalar :: (Expr.Value val) => val sh
   zeroIndex :: (Expr.Value val) => f sh -> val (Index sh)

instance Scalar () where
   scalar :: forall (val :: * -> *). Value val => val ()
scalar = T () -> val ()
forall a. T a -> val a
forall (val :: * -> *) a. Value val => T a -> val a
Expr.lift0 (T () -> val ()) -> T () -> val ()
forall a b. (a -> b) -> a -> b
$ Repr () -> T ()
forall a. Repr a -> T a
MultiValue.Cons ()
   zeroIndex :: forall (val :: * -> *) (f :: * -> *).
Value val =>
f () -> val (Index ())
zeroIndex f ()
_ = T (Index ()) -> val (Index ())
forall a. T a -> val a
forall (val :: * -> *) a. Value val => T a -> val a
Expr.lift0 (T (Index ()) -> val (Index ())) -> T (Index ()) -> val (Index ())
forall a b. (a -> b) -> a -> b
$ Repr () -> T ()
forall a. Repr a -> T a
MultiValue.Cons ()


class
   (C sh,
    MultiValue.IntegerConstant (Index sh),
    MultiValue.Additive (Index sh)) =>
      Sequence sh where
   sequenceShapeFromIndex ::
      MultiValue.T (Index sh) -> LLVM.CodeGenFunction r (MultiValue.T sh)


class
   (MultiValue.Additive n, MultiValue.Real n, MultiValue.IntegerConstant n) =>
      ToSize n where
   toSize :: MultiValue.T n -> LLVM.CodeGenFunction r (LLVM.Value Size)

instance ToSize Word8  where toSize :: forall r. T Word8 -> CodeGenFunction r (Value Size)
toSize (MultiValue.Cons Repr Word8
n) = Value Word8 -> CodeGenFunction r (Value Size)
forall (value :: * -> *) a b r.
(ValueCons value, IsInteger a, IsInteger b, ShapeOf a ~ ShapeOf b,
 Signed a ~ Signed b, IsSized a, IsSized b,
 SizeOf a :<: SizeOf b) =>
value a -> CodeGenFunction r (value b)
LLVM.ext Repr Word8
Value Word8
n
instance ToSize Word16 where toSize :: forall r. T Word16 -> CodeGenFunction r (Value Size)
toSize (MultiValue.Cons Repr Word16
n) = Value Word16 -> CodeGenFunction r (Value Size)
forall (value :: * -> *) a b r.
(ValueCons value, IsInteger a, IsInteger b, ShapeOf a ~ ShapeOf b,
 Signed a ~ Signed b, IsSized a, IsSized b,
 SizeOf a :<: SizeOf b) =>
value a -> CodeGenFunction r (value b)
LLVM.ext Repr Word16
Value Word16
n
instance ToSize Word32 where toSize :: forall r. T Word32 -> CodeGenFunction r (Value Size)
toSize (MultiValue.Cons Repr Word32
n) = Value Word32 -> CodeGenFunction r (Value Size)
forall (value :: * -> *) a b r.
(ValueCons value, IsInteger a, IsInteger b, ShapeOf a ~ ShapeOf b,
 Signed a ~ Signed b) =>
value a -> CodeGenFunction r (value b)
LLVM.adapt Repr Word32
Value Word32
n
instance ToSize Word64 where toSize :: forall r. T Word64 -> CodeGenFunction r (Value Size)
toSize (MultiValue.Cons Repr Word64
n) = Value Word64 -> CodeGenFunction r (Value Size)
forall (value :: * -> *) a b r.
(ValueCons value, IsInteger a, IsInteger b, ShapeOf a ~ ShapeOf b,
 Signed a ~ Signed b) =>
value a -> CodeGenFunction r (value b)
LLVM.adapt Repr Word64
Value Word64
n
instance ToSize Word   where toSize :: forall r. T Size -> CodeGenFunction r (Value Size)
toSize (MultiValue.Cons Repr Size
n) = Value Size -> CodeGenFunction r (Value Size)
forall (value :: * -> *) a b r.
(ValueCons value, IsInteger a, IsInteger b, ShapeOf a ~ ShapeOf b,
 Signed a ~ Signed b) =>
value a -> CodeGenFunction r (value b)
LLVM.adapt Repr Size
Value Size
n
instance ToSize Int8  where toSize :: forall r. T Int8 -> CodeGenFunction r (Value Size)
toSize (MultiValue.Cons Repr Int8
n) = Value Int8 -> CodeGenFunction r (Value Size)
forall (value :: * -> *) a b r.
(ValueCons value, IsInteger a, IsInteger b, ShapeOf a ~ ShapeOf b,
 IsSized a, IsSized b, SizeOf a :<: SizeOf b) =>
value a -> CodeGenFunction r (value b)
LLVM.zext Repr Int8
Value Int8
n
instance ToSize Int16 where toSize :: forall r. T Int16 -> CodeGenFunction r (Value Size)
toSize (MultiValue.Cons Repr Int16
n) = Value Int16 -> CodeGenFunction r (Value Size)
forall (value :: * -> *) a b r.
(ValueCons value, IsInteger a, IsInteger b, ShapeOf a ~ ShapeOf b,
 IsSized a, IsSized b, SizeOf a :<: SizeOf b) =>
value a -> CodeGenFunction r (value b)
LLVM.zext Repr Int16
Value Int16
n
instance ToSize Int32 where toSize :: forall r. T Int32 -> CodeGenFunction r (Value Size)
toSize (MultiValue.Cons Repr Int32
n) = Value Int32 -> CodeGenFunction r (Value Size)
forall (value :: * -> *) a b r.
(ValueCons value, IsInteger a, IsInteger b,
 ShapeOf a ~ ShapeOf b) =>
value a -> CodeGenFunction r (value b)
LLVM.zadapt Repr Int32
Value Int32
n
instance ToSize Int64 where toSize :: forall r. T Int64 -> CodeGenFunction r (Value Size)
toSize (MultiValue.Cons Repr Int64
n) = Value Int64 -> CodeGenFunction r (Value Size)
forall (value :: * -> *) a b r.
(ValueCons value, IsInteger a, IsInteger b,
 ShapeOf a ~ ShapeOf b) =>
value a -> CodeGenFunction r (value b)
LLVM.zadapt Repr Int64
Value Int64
n
instance ToSize Int   where toSize :: forall r. T Int -> CodeGenFunction r (Value Size)
toSize (MultiValue.Cons Repr Int
n) = Value Int -> CodeGenFunction r (Value Size)
forall (value :: * -> *) a b r.
(ValueCons value, IsInteger a, IsInteger b,
 ShapeOf a ~ ShapeOf b) =>
value a -> CodeGenFunction r (value b)
LLVM.zadapt Repr Int
Value Int
n


{- |
Array dimensions and indexes cannot be negative,
but computations in indices may temporarily yield negative values
or we want to add negative values to indices.

So maybe, we would better have type Index (ZeroBased Word64) = Int64.
This is not possible.
Maybe we need an additional ZeroBased type for unsigned array sizes.
-}
instance
      (Integral n, ToSize n, MultiValue.Comparison n) => C (ZeroBased n) where
   intersectCode :: forall r.
T (ZeroBased n)
-> T (ZeroBased n) -> CodeGenFunction r (T (ZeroBased n))
intersectCode T (ZeroBased n)
sha T (ZeroBased n)
shb =
      T n -> T (ZeroBased n)
forall (val :: * -> *) n. Value val => val n -> val (ZeroBased n)
zeroBased (T n -> T (ZeroBased n))
-> CodeGenFunction r (T n) -> CodeGenFunction r (T (ZeroBased n))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> T n -> T n -> CodeGenFunction r (T n)
forall a r. Real a => T a -> T a -> CodeGenFunction r (T a)
forall r. T n -> T n -> CodeGenFunction r (T n)
MultiValue.min (T (ZeroBased n) -> T n
forall (val :: * -> *) n. Value val => val (ZeroBased n) -> val n
zeroBasedSize T (ZeroBased n)
sha) (T (ZeroBased n) -> T n
forall (val :: * -> *) n. Value val => val (ZeroBased n) -> val n
zeroBasedSize T (ZeroBased n)
shb)
   size :: forall r. T (ZeroBased n) -> CodeGenFunction r (Value Size)
size = T n -> CodeGenFunction r (Value Size)
forall r. T n -> CodeGenFunction r (Value Size)
forall n r. ToSize n => T n -> CodeGenFunction r (Value Size)
toSize (T n -> CodeGenFunction r (Value Size))
-> (T (ZeroBased n) -> T n)
-> T (ZeroBased n)
-> CodeGenFunction r (Value Size)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T (ZeroBased n) -> T n
forall (val :: * -> *) n. Value val => val (ZeroBased n) -> val n
zeroBasedSize
   sizeOffset :: forall ix r.
(Index (ZeroBased n) ~ ix) =>
T (ZeroBased n)
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
sizeOffset T (ZeroBased n)
sh = (Value Size
 -> (T ix -> CodeGenFunction r (Value Size))
 -> (Value Size, T ix -> CodeGenFunction r (Value Size)))
-> CodeGenFunction r (Value Size)
-> CodeGenFunction r (T ix -> CodeGenFunction r (Value Size))
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall (m :: * -> *) a b r.
Monad m =>
(a -> b -> r) -> m a -> m b -> m r
Monad.lift2 (,) (T n -> CodeGenFunction r (Value Size)
forall r. T n -> CodeGenFunction r (Value Size)
forall n r. ToSize n => T n -> CodeGenFunction r (Value Size)
toSize (T n -> CodeGenFunction r (Value Size))
-> T n -> CodeGenFunction r (Value Size)
forall a b. (a -> b) -> a -> b
$ T (ZeroBased n) -> T n
forall (val :: * -> *) n. Value val => val (ZeroBased n) -> val n
zeroBasedSize T (ZeroBased n)
sh) ((T ix -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (T ix -> CodeGenFunction r (Value Size))
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return T ix -> CodeGenFunction r (Value Size)
forall r. T ix -> CodeGenFunction r (Value Size)
forall n r. ToSize n => T n -> CodeGenFunction r (Value Size)
toSize)
   iterator :: forall ix r.
(Index (ZeroBased n) ~ ix) =>
T (ZeroBased n) -> T r (T ix)
iterator T (ZeroBased n)
sh =
      T n -> T r (T ix) -> T r (T ix)
forall i r a.
(Additive i, Comparison i, IntegerConstant i) =>
T i -> T r a -> T r a
IterMV.take (T (ZeroBased n) -> T n
forall (val :: * -> *) n. Value val => val (ZeroBased n) -> val n
zeroBasedSize T (ZeroBased n)
sh) (T r (T ix) -> T r (T ix)) -> T r (T ix) -> T r (T ix)
forall a b. (a -> b) -> a -> b
$
      (T ix -> CodeGenFunction r (T ix)) -> T ix -> T r (T ix)
forall a r.
(Phi a, Undefined a) =>
(a -> CodeGenFunction r a) -> a -> T r a
Iter.iterate T ix -> CodeGenFunction r (T ix)
forall i r.
(Additive i, IntegerConstant i) =>
T i -> CodeGenFunction r (T i)
MultiValue.inc T ix
forall a. C a => T a
MultiValue.zero

instance
   (Integral n, ToSize n, MultiValue.Comparison n) =>
      Sequence (ZeroBased n) where
   sequenceShapeFromIndex :: forall r.
T (Index (ZeroBased n)) -> CodeGenFunction r (T (ZeroBased n))
sequenceShapeFromIndex = T (ZeroBased n) -> CodeGenFunction r (T (ZeroBased n))
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return (T (ZeroBased n) -> CodeGenFunction r (T (ZeroBased n)))
-> (T n -> T (ZeroBased n))
-> T n
-> CodeGenFunction r (T (ZeroBased n))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T n -> T (ZeroBased n)
forall (val :: * -> *) n. Value val => val n -> val (ZeroBased n)
zeroBased


rangeSize ::
   (ToSize n) =>
   Range (MultiValue.T n) -> LLVM.CodeGenFunction r (LLVM.Value Size)
rangeSize :: forall n r.
ToSize n =>
Range (T n) -> CodeGenFunction r (Value Size)
rangeSize (Range T n
from T n
to) =
   T n -> CodeGenFunction r (Value Size)
forall r. T n -> CodeGenFunction r (Value Size)
forall n r. ToSize n => T n -> CodeGenFunction r (Value Size)
toSize (T n -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (T n) -> CodeGenFunction r (Value Size)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< T n -> CodeGenFunction r (T n)
forall i r.
(Additive i, IntegerConstant i) =>
T i -> CodeGenFunction r (T i)
MultiValue.inc (T n -> CodeGenFunction r (T n))
-> CodeGenFunction r (T n) -> CodeGenFunction r (T n)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< T n -> T n -> CodeGenFunction r (T n)
forall a r. Additive a => T a -> T a -> CodeGenFunction r (T a)
forall r. T n -> T n -> CodeGenFunction r (T n)
MultiValue.sub T n
to T n
from


rangeFrom :: (Expr.Value val) => val (Range n) -> val n
rangeFrom :: forall (val :: * -> *) n. Value val => val (Range n) -> val n
rangeFrom = (T (Range n) -> T n) -> val (Range n) -> val n
forall a b. (T a -> T b) -> val a -> val b
forall (val :: * -> *) a b.
Value val =>
(T a -> T b) -> val a -> val b
Expr.lift1 ((T (Range n) -> T n) -> val (Range n) -> val n)
-> (T (Range n) -> T n) -> val (Range n) -> val n
forall a b. (a -> b) -> a -> b
$ Range (T n) -> T n
forall n. Range n -> n
Shape.rangeFrom (Range (T n) -> T n)
-> (T (Range n) -> Range (T n)) -> T (Range n) -> T n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T (Range n) -> Range (T n)
forall n. T (Range n) -> Range (T n)
unzipRange

rangeTo :: (Expr.Value val) => val (Range n) -> val n
rangeTo :: forall (val :: * -> *) n. Value val => val (Range n) -> val n
rangeTo = (T (Range n) -> T n) -> val (Range n) -> val n
forall a b. (T a -> T b) -> val a -> val b
forall (val :: * -> *) a b.
Value val =>
(T a -> T b) -> val a -> val b
Expr.lift1 ((T (Range n) -> T n) -> val (Range n) -> val n)
-> (T (Range n) -> T n) -> val (Range n) -> val n
forall a b. (a -> b) -> a -> b
$ Range (T n) -> T n
forall n. Range n -> n
Shape.rangeTo (Range (T n) -> T n)
-> (T (Range n) -> Range (T n)) -> T (Range n) -> T n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T (Range n) -> Range (T n)
forall n. T (Range n) -> Range (T n)
unzipRange

range :: (Expr.Value val) => val n -> val n -> val (Range n)
range :: forall (val :: * -> *) n.
Value val =>
val n -> val n -> val (Range n)
range =
   (T n -> T n -> T (Range n)) -> val n -> val n -> val (Range n)
forall a b c. (T a -> T b -> T c) -> val a -> val b -> val c
forall (val :: * -> *) a b c.
Value val =>
(T a -> T b -> T c) -> val a -> val b -> val c
Expr.lift2 ((T n -> T n -> T (Range n)) -> val n -> val n -> val (Range n))
-> (T n -> T n -> T (Range n)) -> val n -> val n -> val (Range n)
forall a b. (a -> b) -> a -> b
$
      \(MultiValue.Cons Repr n
from) (MultiValue.Cons Repr n
to) ->
         Repr (Range n) -> T (Range n)
forall a. Repr a -> T a
MultiValue.Cons (Repr n -> Repr n -> Range (Repr n)
forall n. n -> n -> Range n
Range Repr n
from Repr n
to)

instance (Ix n, ToSize n, MultiValue.Comparison n) => C (Range n) where
   intersectCode :: forall r.
T (Range n) -> T (Range n) -> CodeGenFunction r (T (Range n))
intersectCode =
      Range (Atom n)
-> Range (Atom n)
-> (Decomposed T (Range (Atom n))
    -> Decomposed T (Range (Atom n))
    -> CodeGenFunction r (Range (T n)))
-> T (PatternTuple (Range (Atom n)))
-> T (PatternTuple (Range (Atom n)))
-> CodeGenFunction r (T (Composed (Range (T n))))
forall a patternA patternB (f :: * -> *).
(Compose a, Decompose patternA, Decompose patternB, Functor f) =>
patternA
-> patternB
-> (Decomposed T patternA -> Decomposed T patternB -> f a)
-> T (PatternTuple patternA)
-> T (PatternTuple patternB)
-> f (T (Composed a))
MultiValue.modifyF2 (Atom n -> Range (Atom n)
forall n. n -> Range n
singletonRange Atom n
forall a. Atom a
atom) (Atom n -> Range (Atom n)
forall n. n -> Range n
singletonRange Atom n
forall a. Atom a
atom) ((Decomposed T (Range (Atom n))
  -> Decomposed T (Range (Atom n))
  -> CodeGenFunction r (Range (T n)))
 -> T (PatternTuple (Range (Atom n)))
 -> T (PatternTuple (Range (Atom n)))
 -> CodeGenFunction r (T (Composed (Range (T n)))))
-> (Decomposed T (Range (Atom n))
    -> Decomposed T (Range (Atom n))
    -> CodeGenFunction r (Range (T n)))
-> T (PatternTuple (Range (Atom n)))
-> T (PatternTuple (Range (Atom n)))
-> CodeGenFunction r (T (Composed (Range (T n))))
forall a b. (a -> b) -> a -> b
$
            \(Range T n
fromN T n
toN) (Range T n
fromM T n
toM) ->
         (T n -> T n -> Range (T n))
-> CodeGenFunction r (T n)
-> CodeGenFunction r (T n)
-> CodeGenFunction r (Range (T n))
forall (m :: * -> *) a b r.
Monad m =>
(a -> b -> r) -> m a -> m b -> m r
Monad.lift2 T n -> T n -> Range (T n)
forall n. n -> n -> Range n
Range (T n -> T n -> CodeGenFunction r (T n)
forall a r. Real a => T a -> T a -> CodeGenFunction r (T a)
forall r. T n -> T n -> CodeGenFunction r (T n)
MultiValue.max T n
fromN T n
fromM) (T n -> T n -> CodeGenFunction r (T n)
forall a r. Real a => T a -> T a -> CodeGenFunction r (T a)
forall r. T n -> T n -> CodeGenFunction r (T n)
MultiValue.min T n
toN T n
toM)
   size :: forall r. T (Range n) -> CodeGenFunction r (Value Size)
size = Range (T n) -> CodeGenFunction r (Value Size)
forall n r.
ToSize n =>
Range (T n) -> CodeGenFunction r (Value Size)
rangeSize (Range (T n) -> CodeGenFunction r (Value Size))
-> (T (Range n) -> Range (T n))
-> T (Range n)
-> CodeGenFunction r (Value Size)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T (Range n) -> Range (T n)
forall n. T (Range n) -> Range (T n)
unzipRange
   sizeOffset :: forall ix r.
(Index (Range n) ~ ix) =>
T (Range n)
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
sizeOffset T (Range n)
rngValue =
      case T (Range n) -> Range (T n)
forall n. T (Range n) -> Range (T n)
unzipRange T (Range n)
rngValue of
         rng :: Range (T n)
rng@(Range T n
from T n
_to) ->
            (Value Size
 -> (T ix -> CodeGenFunction r (Value Size))
 -> (Value Size, T ix -> CodeGenFunction r (Value Size)))
-> CodeGenFunction r (Value Size)
-> CodeGenFunction r (T ix -> CodeGenFunction r (Value Size))
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall (m :: * -> *) a b r.
Monad m =>
(a -> b -> r) -> m a -> m b -> m r
Monad.lift2 (,) (Range (T n) -> CodeGenFunction r (Value Size)
forall n r.
ToSize n =>
Range (T n) -> CodeGenFunction r (Value Size)
rangeSize Range (T n)
rng)
               ((T ix -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (T ix -> CodeGenFunction r (Value Size))
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return ((T ix -> CodeGenFunction r (Value Size))
 -> CodeGenFunction r (T ix -> CodeGenFunction r (Value Size)))
-> (T ix -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (T ix -> CodeGenFunction r (Value Size))
forall a b. (a -> b) -> a -> b
$ \T ix
i -> T ix -> CodeGenFunction r (Value Size)
forall r. T ix -> CodeGenFunction r (Value Size)
forall n r. ToSize n => T n -> CodeGenFunction r (Value Size)
toSize (T ix -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (T ix) -> CodeGenFunction r (Value Size)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< T ix -> T ix -> CodeGenFunction r (T ix)
forall a r. Additive a => T a -> T a -> CodeGenFunction r (T a)
forall r. T ix -> T ix -> CodeGenFunction r (T ix)
MultiValue.sub T ix
i T n
T ix
from)
   iterator :: forall ix r. (Index (Range n) ~ ix) => T (Range n) -> T r (T ix)
iterator T (Range n)
rngValue =
      case Range (Atom n)
-> T (PatternTuple (Range (Atom n)))
-> Decomposed T (Range (Atom n))
forall pattern.
Decompose pattern =>
pattern -> T (PatternTuple pattern) -> Decomposed T pattern
MultiValue.decompose (Atom n -> Range (Atom n)
forall n. n -> Range n
singletonRange Atom n
forall a. Atom a
atom) T (Range n)
T (PatternTuple (Range (Atom n)))
rngValue of
         Range T ix
from T ix
to ->
            (T ix -> CodeGenFunction r (T Bool)) -> T r (T ix) -> T r (T ix)
forall a r. (a -> CodeGenFunction r (T Bool)) -> T r a -> T r a
IterMV.takeWhile (CmpPredicate -> T ix -> T ix -> CodeGenFunction r (T Bool)
forall r.
CmpPredicate -> T ix -> T ix -> CodeGenFunction r (T Bool)
forall a r.
Comparison a =>
CmpPredicate -> T a -> T a -> CodeGenFunction r (T Bool)
MultiValue.cmp CmpPredicate
LLVM.CmpGE T ix
to) (T r (T ix) -> T r (T ix)) -> T r (T ix) -> T r (T ix)
forall a b. (a -> b) -> a -> b
$
            (T ix -> CodeGenFunction r (T ix)) -> T ix -> T r (T ix)
forall a r.
(Phi a, Undefined a) =>
(a -> CodeGenFunction r a) -> a -> T r a
Iter.iterate T ix -> CodeGenFunction r (T ix)
forall i r.
(Additive i, IntegerConstant i) =>
T i -> CodeGenFunction r (T i)
MultiValue.inc T ix
from



shiftedOffset :: (Expr.Value val) => val (Shifted n) -> val n
shiftedOffset :: forall (val :: * -> *) n. Value val => val (Shifted n) -> val n
shiftedOffset = (T (Shifted n) -> T n) -> val (Shifted n) -> val n
forall a b. (T a -> T b) -> val a -> val b
forall (val :: * -> *) a b.
Value val =>
(T a -> T b) -> val a -> val b
Expr.lift1 ((T (Shifted n) -> T n) -> val (Shifted n) -> val n)
-> (T (Shifted n) -> T n) -> val (Shifted n) -> val n
forall a b. (a -> b) -> a -> b
$ Shifted (T n) -> T n
forall n. Shifted n -> n
Shape.shiftedOffset (Shifted (T n) -> T n)
-> (T (Shifted n) -> Shifted (T n)) -> T (Shifted n) -> T n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T (Shifted n) -> Shifted (T n)
forall n. T (Shifted n) -> Shifted (T n)
unzipShifted

shiftedSize :: (Expr.Value val) => val (Shifted n) -> val n
shiftedSize :: forall (val :: * -> *) n. Value val => val (Shifted n) -> val n
shiftedSize = (T (Shifted n) -> T n) -> val (Shifted n) -> val n
forall a b. (T a -> T b) -> val a -> val b
forall (val :: * -> *) a b.
Value val =>
(T a -> T b) -> val a -> val b
Expr.lift1 ((T (Shifted n) -> T n) -> val (Shifted n) -> val n)
-> (T (Shifted n) -> T n) -> val (Shifted n) -> val n
forall a b. (a -> b) -> a -> b
$ Shifted (T n) -> T n
forall n. Shifted n -> n
Shape.shiftedSize (Shifted (T n) -> T n)
-> (T (Shifted n) -> Shifted (T n)) -> T (Shifted n) -> T n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T (Shifted n) -> Shifted (T n)
forall n. T (Shifted n) -> Shifted (T n)
unzipShifted

shifted :: (Expr.Value val) => val n -> val n -> val (Shifted n)
shifted :: forall (val :: * -> *) n.
Value val =>
val n -> val n -> val (Shifted n)
shifted =
   (T n -> T n -> T (Shifted n)) -> val n -> val n -> val (Shifted n)
forall a b c. (T a -> T b -> T c) -> val a -> val b -> val c
forall (val :: * -> *) a b c.
Value val =>
(T a -> T b -> T c) -> val a -> val b -> val c
Expr.lift2 ((T n -> T n -> T (Shifted n))
 -> val n -> val n -> val (Shifted n))
-> (T n -> T n -> T (Shifted n))
-> val n
-> val n
-> val (Shifted n)
forall a b. (a -> b) -> a -> b
$
      \(MultiValue.Cons Repr n
from) (MultiValue.Cons Repr n
to) ->
         Repr (Shifted n) -> T (Shifted n)
forall a. Repr a -> T a
MultiValue.Cons (Repr n -> Repr n -> Shifted (Repr n)
forall n. n -> n -> Shifted n
Shifted Repr n
from Repr n
to)


instance (Integral n, ToSize n, MultiValue.Comparison n) => C (Shifted n) where
   intersectCode :: forall r.
T (Shifted n) -> T (Shifted n) -> CodeGenFunction r (T (Shifted n))
intersectCode =
      Shifted (Atom n)
-> Shifted (Atom n)
-> (Decomposed T (Shifted (Atom n))
    -> Decomposed T (Shifted (Atom n))
    -> CodeGenFunction r (Shifted (T n)))
-> T (PatternTuple (Shifted (Atom n)))
-> T (PatternTuple (Shifted (Atom n)))
-> CodeGenFunction r (T (Composed (Shifted (T n))))
forall a patternA patternB (f :: * -> *).
(Compose a, Decompose patternA, Decompose patternB, Functor f) =>
patternA
-> patternB
-> (Decomposed T patternA -> Decomposed T patternB -> f a)
-> T (PatternTuple patternA)
-> T (PatternTuple patternB)
-> f (T (Composed a))
MultiValue.modifyF2 (Atom n -> Shifted (Atom n)
forall n. n -> Shifted n
singletonShifted Atom n
forall a. Atom a
atom) (Atom n -> Shifted (Atom n)
forall n. n -> Shifted n
singletonShifted Atom n
forall a. Atom a
atom) ((Decomposed T (Shifted (Atom n))
  -> Decomposed T (Shifted (Atom n))
  -> CodeGenFunction r (Shifted (T n)))
 -> T (PatternTuple (Shifted (Atom n)))
 -> T (PatternTuple (Shifted (Atom n)))
 -> CodeGenFunction r (T (Composed (Shifted (T n)))))
-> (Decomposed T (Shifted (Atom n))
    -> Decomposed T (Shifted (Atom n))
    -> CodeGenFunction r (Shifted (T n)))
-> T (PatternTuple (Shifted (Atom n)))
-> T (PatternTuple (Shifted (Atom n)))
-> CodeGenFunction r (T (Composed (Shifted (T n))))
forall a b. (a -> b) -> a -> b
$
            \(Shifted T n
startN T n
lenN) (Shifted T n
startM T n
lenM) -> do
         T n
start <- T n -> T n -> CodeGenFunction r (T n)
forall a r. Real a => T a -> T a -> CodeGenFunction r (T a)
forall r. T n -> T n -> CodeGenFunction r (T n)
MultiValue.max T n
startN T n
startM
         T n
endN <- T n -> T n -> CodeGenFunction r (T n)
forall a r. Additive a => T a -> T a -> CodeGenFunction r (T a)
forall r. T n -> T n -> CodeGenFunction r (T n)
MultiValue.add T n
startN T n
lenN
         T n
endM <- T n -> T n -> CodeGenFunction r (T n)
forall a r. Additive a => T a -> T a -> CodeGenFunction r (T a)
forall r. T n -> T n -> CodeGenFunction r (T n)
MultiValue.add T n
startM T n
lenM
         T n
end <- T n -> T n -> CodeGenFunction r (T n)
forall a r. Real a => T a -> T a -> CodeGenFunction r (T a)
forall r. T n -> T n -> CodeGenFunction r (T n)
MultiValue.min T n
endN T n
endM
         T n -> T n -> Shifted (T n)
forall n. n -> n -> Shifted n
Shifted T n
start (T n -> Shifted (T n))
-> CodeGenFunction r (T n) -> CodeGenFunction r (Shifted (T n))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> T n -> T n -> CodeGenFunction r (T n)
forall a r. Additive a => T a -> T a -> CodeGenFunction r (T a)
forall r. T n -> T n -> CodeGenFunction r (T n)
MultiValue.sub T n
end T n
start
   size :: forall r. T (Shifted n) -> CodeGenFunction r (Value Size)
size = T n -> CodeGenFunction r (Value Size)
forall r. T n -> CodeGenFunction r (Value Size)
forall n r. ToSize n => T n -> CodeGenFunction r (Value Size)
toSize (T n -> CodeGenFunction r (Value Size))
-> (T (Shifted n) -> T n)
-> T (Shifted n)
-> CodeGenFunction r (Value Size)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T (Shifted n) -> T n
forall (val :: * -> *) n. Value val => val (Shifted n) -> val n
shiftedSize
   sizeOffset :: forall ix r.
(Index (Shifted n) ~ ix) =>
T (Shifted n)
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
sizeOffset T (Shifted n)
shapeValue =
      case T (Shifted n) -> Shifted (T n)
forall n. T (Shifted n) -> Shifted (T n)
unzipShifted T (Shifted n)
shapeValue of
         Shifted T n
start T n
len ->
            (Value Size
 -> (T ix -> CodeGenFunction r (Value Size))
 -> (Value Size, T ix -> CodeGenFunction r (Value Size)))
-> CodeGenFunction r (Value Size)
-> CodeGenFunction r (T ix -> CodeGenFunction r (Value Size))
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall (m :: * -> *) a b r.
Monad m =>
(a -> b -> r) -> m a -> m b -> m r
Monad.lift2 (,) (T n -> CodeGenFunction r (Value Size)
forall r. T n -> CodeGenFunction r (Value Size)
forall n r. ToSize n => T n -> CodeGenFunction r (Value Size)
toSize T n
len)
               ((T ix -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (T ix -> CodeGenFunction r (Value Size))
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return ((T ix -> CodeGenFunction r (Value Size))
 -> CodeGenFunction r (T ix -> CodeGenFunction r (Value Size)))
-> (T ix -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (T ix -> CodeGenFunction r (Value Size))
forall a b. (a -> b) -> a -> b
$ \T ix
i -> T ix -> CodeGenFunction r (Value Size)
forall r. T ix -> CodeGenFunction r (Value Size)
forall n r. ToSize n => T n -> CodeGenFunction r (Value Size)
toSize (T ix -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (T ix) -> CodeGenFunction r (Value Size)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< T ix -> T ix -> CodeGenFunction r (T ix)
forall a r. Additive a => T a -> T a -> CodeGenFunction r (T a)
forall r. T ix -> T ix -> CodeGenFunction r (T ix)
MultiValue.sub T ix
i T n
T ix
start)
   iterator :: forall ix r.
(Index (Shifted n) ~ ix) =>
T (Shifted n) -> T r (T ix)
iterator T (Shifted n)
rngValue =
      case Shifted (Atom n)
-> T (PatternTuple (Shifted (Atom n)))
-> Decomposed T (Shifted (Atom n))
forall pattern.
Decompose pattern =>
pattern -> T (PatternTuple pattern) -> Decomposed T pattern
MultiValue.decompose (Atom n -> Shifted (Atom n)
forall n. n -> Shifted n
singletonShifted Atom n
forall a. Atom a
atom) T (Shifted n)
T (PatternTuple (Shifted (Atom n)))
rngValue of
         Shifted T ix
from T ix
len ->
            T ix -> T r (T ix) -> T r (T ix)
forall i r a.
(Additive i, Comparison i, IntegerConstant i) =>
T i -> T r a -> T r a
IterMV.take T ix
len (T r (T ix) -> T r (T ix)) -> T r (T ix) -> T r (T ix)
forall a b. (a -> b) -> a -> b
$ (T ix -> CodeGenFunction r (T ix)) -> T ix -> T r (T ix)
forall a r.
(Phi a, Undefined a) =>
(a -> CodeGenFunction r a) -> a -> T r a
Iter.iterate T ix -> CodeGenFunction r (T ix)
forall i r.
(Additive i, IntegerConstant i) =>
T i -> CodeGenFunction r (T i)
MultiValue.inc T ix
from


instance
      (Integral n, ToSize n, MultiValue.Comparison n) => C (Cyclic n) where
   intersectCode :: forall r.
T (Cyclic n) -> T (Cyclic n) -> CodeGenFunction r (T (Cyclic n))
intersectCode T (Cyclic n)
sha T (Cyclic n)
shb =
      T n -> T (Cyclic n)
forall (val :: * -> *) n. Value val => val n -> val (Cyclic n)
cyclic (T n -> T (Cyclic n))
-> CodeGenFunction r (T n) -> CodeGenFunction r (T (Cyclic n))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> T n -> T n -> CodeGenFunction r (T n)
forall a r. Real a => T a -> T a -> CodeGenFunction r (T a)
forall r. T n -> T n -> CodeGenFunction r (T n)
MultiValue.min (T (Cyclic n) -> T n
forall (val :: * -> *) n. Value val => val (Cyclic n) -> val n
cyclicSize T (Cyclic n)
sha) (T (Cyclic n) -> T n
forall (val :: * -> *) n. Value val => val (Cyclic n) -> val n
cyclicSize T (Cyclic n)
shb)
   size :: forall r. T (Cyclic n) -> CodeGenFunction r (Value Size)
size = T n -> CodeGenFunction r (Value Size)
forall r. T n -> CodeGenFunction r (Value Size)
forall n r. ToSize n => T n -> CodeGenFunction r (Value Size)
toSize (T n -> CodeGenFunction r (Value Size))
-> (T (Cyclic n) -> T n)
-> T (Cyclic n)
-> CodeGenFunction r (Value Size)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T (Cyclic n) -> T n
forall (val :: * -> *) n. Value val => val (Cyclic n) -> val n
cyclicSize
   sizeOffset :: forall ix r.
(Index (Cyclic n) ~ ix) =>
T (Cyclic n)
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
sizeOffset T (Cyclic n)
sh = (Value Size
 -> (T ix -> CodeGenFunction r (Value Size))
 -> (Value Size, T ix -> CodeGenFunction r (Value Size)))
-> CodeGenFunction r (Value Size)
-> CodeGenFunction r (T ix -> CodeGenFunction r (Value Size))
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall (m :: * -> *) a b r.
Monad m =>
(a -> b -> r) -> m a -> m b -> m r
Monad.lift2 (,) (T n -> CodeGenFunction r (Value Size)
forall r. T n -> CodeGenFunction r (Value Size)
forall n r. ToSize n => T n -> CodeGenFunction r (Value Size)
toSize (T n -> CodeGenFunction r (Value Size))
-> T n -> CodeGenFunction r (Value Size)
forall a b. (a -> b) -> a -> b
$ T (Cyclic n) -> T n
forall (val :: * -> *) n. Value val => val (Cyclic n) -> val n
cyclicSize T (Cyclic n)
sh) ((T ix -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (T ix -> CodeGenFunction r (Value Size))
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return T ix -> CodeGenFunction r (Value Size)
forall r. T ix -> CodeGenFunction r (Value Size)
forall n r. ToSize n => T n -> CodeGenFunction r (Value Size)
toSize)
   iterator :: forall ix r. (Index (Cyclic n) ~ ix) => T (Cyclic n) -> T r (T ix)
iterator T (Cyclic n)
sh =
      T n -> T r (T ix) -> T r (T ix)
forall i r a.
(Additive i, Comparison i, IntegerConstant i) =>
T i -> T r a -> T r a
IterMV.take (T (Cyclic n) -> T n
forall (val :: * -> *) n. Value val => val (Cyclic n) -> val n
cyclicSize T (Cyclic n)
sh) (T r (T ix) -> T r (T ix)) -> T r (T ix) -> T r (T ix)
forall a b. (a -> b) -> a -> b
$
      (T ix -> CodeGenFunction r (T ix)) -> T ix -> T r (T ix)
forall a r.
(Phi a, Undefined a) =>
(a -> CodeGenFunction r a) -> a -> T r a
Iter.iterate T ix -> CodeGenFunction r (T ix)
forall i r.
(Additive i, IntegerConstant i) =>
T i -> CodeGenFunction r (T i)
MultiValue.inc T ix
forall a. C a => T a
MultiValue.zero


class (IterMV.Enum enum, MultiValue.Bounded enum) => EnumBounded enum where
   enumOffset :: MultiValue.T enum -> LLVM.CodeGenFunction r (LLVM.Value Size)

instance
   (ToSize w, MultiValue.Additive w,
    LLVM.IsInteger w, SoV.IntegerConstant w, Num w,
    MultiValue.Repr w ~ LLVM.Value w,
    LLVM.CmpRet w, LLVM.IsPrimitive w,
    Enum e, Bounded e) =>
      EnumBounded (Enum.T w e) where
   enumOffset :: forall r. T (T w e) -> CodeGenFunction r (Value Size)
enumOffset T (T w e)
ix =
      T w -> CodeGenFunction r (Value Size)
forall r. T w -> CodeGenFunction r (Value Size)
forall n r. ToSize n => T n -> CodeGenFunction r (Value Size)
toSize (T w -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (T w) -> CodeGenFunction r (Value Size)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      T w -> T w -> CodeGenFunction r (T w)
forall a r. Additive a => T a -> T a -> CodeGenFunction r (T a)
forall r. T w -> T w -> CodeGenFunction r (T w)
MultiValue.sub
         (T (T w e) -> T w
forall w e. (Repr w ~ Value w) => T (T w e) -> T w
MultiValue.fromEnum T (T w e)
ix)
         (T (T w e) -> T w
forall w e. (Repr w ~ Value w) => T (T w e) -> T w
MultiValue.fromEnum (T (T w e) -> T w) -> T (T w e) -> T w
forall a b. (a -> b) -> a -> b
$ T (T w e)
forall a. Bounded a => T a
MultiValue.minBound T (T w e) -> T (T w e) -> T (T w e)
forall a. a -> a -> a
`asTypeOf` T (T w e)
ix)

instance
      (Enum enum, Bounded enum, EnumBounded enum) => C (Enumeration enum) where
   intersectCode :: forall r.
T (Enumeration enum)
-> T (Enumeration enum) -> CodeGenFunction r (T (Enumeration enum))
intersectCode T (Enumeration enum)
_sha T (Enumeration enum)
shb = T (Enumeration enum) -> CodeGenFunction r (T (Enumeration enum))
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return T (Enumeration enum)
shb
   size :: forall r. T (Enumeration enum) -> CodeGenFunction r (Value Size)
size = Value Size -> CodeGenFunction r (Value Size)
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value Size -> CodeGenFunction r (Value Size))
-> (T (Enumeration enum) -> Value Size)
-> T (Enumeration enum)
-> CodeGenFunction r (Value Size)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Value Size
forall a. IntegerConstant a => Integer -> a
A.fromInteger' (Integer -> Value Size)
-> (T (Enumeration enum) -> Integer)
-> T (Enumeration enum)
-> Value Size
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int -> Integer)
-> (T (Enumeration enum) -> Int) -> T (Enumeration enum) -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Enumeration enum -> Int
forall sh. C sh => sh -> Int
Shape.size (Enumeration enum -> Int)
-> (T (Enumeration enum) -> Enumeration enum)
-> T (Enumeration enum)
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T (Enumeration enum) -> Enumeration enum
forall (val :: * -> *) enum.
val (Enumeration enum) -> Enumeration enum
plainEnumeration
   sizeOffset :: forall ix r.
(Index (Enumeration enum) ~ ix) =>
T (Enumeration enum)
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
sizeOffset T (Enumeration enum)
sh = do
      Value Size
sz <- T (Enumeration enum) -> CodeGenFunction r (Value Size)
forall r. T (Enumeration enum) -> CodeGenFunction r (Value Size)
forall sh r. C sh => T sh -> CodeGenFunction r (Value Size)
size T (Enumeration enum)
sh
      (Value Size, T ix -> CodeGenFunction r (Value Size))
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return (Value Size
sz, T ix -> CodeGenFunction r (Value Size)
forall r. T ix -> CodeGenFunction r (Value Size)
forall enum r.
EnumBounded enum =>
T enum -> CodeGenFunction r (Value Size)
enumOffset)
   iterator :: forall ix r.
(Index (Enumeration enum) ~ ix) =>
T (Enumeration enum) -> T r (T ix)
iterator T (Enumeration enum)
_ = T ix -> T ix -> T r (T ix)
forall r. T ix -> T ix -> T r (T ix)
forall a r. Enum a => T a -> T a -> T r (T a)
IterMV.enumFromTo T ix
forall a. Bounded a => T a
MultiValue.minBound T ix
forall a. Bounded a => T a
MultiValue.maxBound

plainEnumeration :: val (Enumeration enum) -> Enumeration enum
plainEnumeration :: forall (val :: * -> *) enum.
val (Enumeration enum) -> Enumeration enum
plainEnumeration val (Enumeration enum)
_ = Enumeration enum
forall n. Enumeration n
Enumeration


instance (C sh) => C (Tagged tag sh) where
   intersectCode :: forall r.
T (Tagged tag sh)
-> T (Tagged tag sh) -> CodeGenFunction r (T (Tagged tag sh))
intersectCode = (T sh -> T sh -> CodeGenFunction r (T sh))
-> T (Tagged tag sh)
-> T (Tagged tag sh)
-> CodeGenFunction r (T (Tagged tag sh))
forall (m :: * -> *) a b c tag.
Monad m =>
(T a -> T b -> m (T c))
-> T (Tagged tag a) -> T (Tagged tag b) -> m (T (Tagged tag c))
MultiValue.liftTaggedM2 T sh -> T sh -> CodeGenFunction r (T sh)
forall r. T sh -> T sh -> CodeGenFunction r (T sh)
forall sh r. C sh => T sh -> T sh -> CodeGenFunction r (T sh)
intersectCode
   size :: forall r. T (Tagged tag sh) -> CodeGenFunction r (Value Size)
size = T sh -> CodeGenFunction r (Value Size)
forall r. T sh -> CodeGenFunction r (Value Size)
forall sh r. C sh => T sh -> CodeGenFunction r (Value Size)
size (T sh -> CodeGenFunction r (Value Size))
-> (T (Tagged tag sh) -> T sh)
-> T (Tagged tag sh)
-> CodeGenFunction r (Value Size)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T (Tagged tag sh) -> T sh
forall tag a. T (Tagged tag a) -> T a
MultiValue.untag
   sizeOffset :: forall ix r.
(Index (Tagged tag sh) ~ ix) =>
T (Tagged tag sh)
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
sizeOffset =
      ((Value Size, T (Index sh) -> CodeGenFunction r (Value Size))
 -> (Value Size, T ix -> CodeGenFunction r (Value Size)))
-> CodeGenFunction
     r (Value Size, T (Index sh) -> CodeGenFunction r (Value Size))
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall a b. (a -> b) -> CodeGenFunction r a -> CodeGenFunction r b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((T (Index sh) -> CodeGenFunction r (Value Size))
 -> T ix -> CodeGenFunction r (Value Size))
-> (Value Size, T (Index sh) -> CodeGenFunction r (Value Size))
-> (Value Size, T ix -> CodeGenFunction r (Value Size))
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd ((T (Index sh) -> CodeGenFunction r (Value Size))
-> (T ix -> T (Index sh)) -> T ix -> CodeGenFunction r (Value Size)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T ix -> T (Index sh)
T (Tagged tag (Index sh)) -> T (Index sh)
forall tag a. T (Tagged tag a) -> T a
MultiValue.untag)) (CodeGenFunction
   r (Value Size, T (Index sh) -> CodeGenFunction r (Value Size))
 -> CodeGenFunction
      r (Value Size, T ix -> CodeGenFunction r (Value Size)))
-> (T (Tagged tag sh)
    -> CodeGenFunction
         r (Value Size, T (Index sh) -> CodeGenFunction r (Value Size)))
-> T (Tagged tag sh)
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T sh
-> CodeGenFunction
     r (Value Size, T (Index sh) -> CodeGenFunction r (Value Size))
forall sh ix r.
(C sh, Index sh ~ ix) =>
T sh
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall ix r.
(Index sh ~ ix) =>
T sh
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
sizeOffset (T sh
 -> CodeGenFunction
      r (Value Size, T (Index sh) -> CodeGenFunction r (Value Size)))
-> (T (Tagged tag sh) -> T sh)
-> T (Tagged tag sh)
-> CodeGenFunction
     r (Value Size, T (Index sh) -> CodeGenFunction r (Value Size))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T (Tagged tag sh) -> T sh
forall tag a. T (Tagged tag a) -> T a
MultiValue.untag
   iterator :: forall ix r.
(Index (Tagged tag sh) ~ ix) =>
T (Tagged tag sh) -> T r (T ix)
iterator = (T (Index sh) -> T ix) -> T r (T (Index sh)) -> T r (T ix)
forall a b. (a -> b) -> T r a -> T r b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap T (Index sh) -> T ix
T (Index sh) -> T (Tagged tag (Index sh))
forall a tag. T a -> T (Tagged tag a)
MultiValue.tag (T r (T (Index sh)) -> T r (T ix))
-> (T (Tagged tag sh) -> T r (T (Index sh)))
-> T (Tagged tag sh)
-> T r (T ix)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T sh -> T r (T (Index sh))
forall sh ix r. (C sh, Index sh ~ ix) => T sh -> T r (T ix)
forall ix r. (Index sh ~ ix) => T sh -> T r (T ix)
iterator (T sh -> T r (T (Index sh)))
-> (T (Tagged tag sh) -> T sh)
-> T (Tagged tag sh)
-> T r (T (Index sh))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T (Tagged tag sh) -> T sh
forall tag a. T (Tagged tag a) -> T a
MultiValue.untag


instance (C n, C m) => C (n,m) where
   intersectCode :: forall r. T (n, m) -> T (n, m) -> CodeGenFunction r (T (n, m))
intersectCode T (n, m)
a T (n, m)
b =
      case (T (n, m) -> (T n, T m)
forall a b. T (a, b) -> (T a, T b)
MultiValue.unzip T (n, m)
a, T (n, m) -> (T n, T m)
forall a b. T (a, b) -> (T a, T b)
MultiValue.unzip T (n, m)
b) of
         ((T n
an,T m
am), (T n
bn,T m
bm)) ->
            (T n -> T m -> T (n, m))
-> CodeGenFunction r (T n)
-> CodeGenFunction r (T m)
-> CodeGenFunction r (T (n, m))
forall (m :: * -> *) a b r.
Monad m =>
(a -> b -> r) -> m a -> m b -> m r
Monad.lift2 T n -> T m -> T (n, m)
forall a b. T a -> T b -> T (a, b)
MultiValue.zip
               (T n -> T n -> CodeGenFunction r (T n)
forall r. T n -> T n -> CodeGenFunction r (T n)
forall sh r. C sh => T sh -> T sh -> CodeGenFunction r (T sh)
intersectCode T n
an T n
bn)
               (T m -> T m -> CodeGenFunction r (T m)
forall r. T m -> T m -> CodeGenFunction r (T m)
forall sh r. C sh => T sh -> T sh -> CodeGenFunction r (T sh)
intersectCode T m
am T m
bm)
   size :: forall r. T (n, m) -> CodeGenFunction r (Value Size)
size T (n, m)
nm =
      case T (n, m) -> (T n, T m)
forall a b. T (a, b) -> (T a, T b)
MultiValue.unzip T (n, m)
nm of
         (T n
n,T m
m) -> (Value Size -> Value Size -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (Value Size)
-> CodeGenFunction r (Value Size)
-> CodeGenFunction r (Value Size)
forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> m c) -> m a -> m b -> m c
Monad.liftJoin2 Value Size -> Value Size -> CodeGenFunction r (Value Size)
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
forall r.
Value Size -> Value Size -> CodeGenFunction r (Value Size)
A.mul (T n -> CodeGenFunction r (Value Size)
forall r. T n -> CodeGenFunction r (Value Size)
forall sh r. C sh => T sh -> CodeGenFunction r (Value Size)
size T n
n) (T m -> CodeGenFunction r (Value Size)
forall r. T m -> CodeGenFunction r (Value Size)
forall sh r. C sh => T sh -> CodeGenFunction r (Value Size)
size T m
m)
   sizeOffset :: forall ix r.
(Index (n, m) ~ ix) =>
T (n, m)
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
sizeOffset T (n, m)
nm =
      case T (n, m) -> (T n, T m)
forall a b. T (a, b) -> (T a, T b)
MultiValue.unzip T (n, m)
nm of
         (T n
n,T m
m) -> do
            (Value Size
ns, T (Index n) -> CodeGenFunction r (Value Size)
iOffset) <- T n
-> CodeGenFunction
     r (Value Size, T (Index n) -> CodeGenFunction r (Value Size))
forall sh ix r.
(C sh, Index sh ~ ix) =>
T sh
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall ix r.
(Index n ~ ix) =>
T n
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
sizeOffset T n
n
            (Value Size
ms, T (Index m) -> CodeGenFunction r (Value Size)
jOffset) <- T m
-> CodeGenFunction
     r (Value Size, T (Index m) -> CodeGenFunction r (Value Size))
forall sh ix r.
(C sh, Index sh ~ ix) =>
T sh
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall ix r.
(Index m ~ ix) =>
T m
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
sizeOffset T m
m
            Value Size
sz <- Value Size -> Value Size -> CodeGenFunction r (Value Size)
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
forall r.
Value Size -> Value Size -> CodeGenFunction r (Value Size)
A.mul Value Size
ns Value Size
ms
            (Value Size, T ix -> CodeGenFunction r (Value Size))
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return
               (Value Size
sz,
                \T ix
ij ->
                  case T (Index n, Index m) -> (T (Index n), T (Index m))
forall a b. T (a, b) -> (T a, T b)
MultiValue.unzip T ix
T (Index n, Index m)
ij of
                     (T (Index n)
i,T (Index m)
j) -> do
                        Value Size
il <- T (Index n) -> CodeGenFunction r (Value Size)
iOffset T (Index n)
i
                        Value Size
jl <- T (Index m) -> CodeGenFunction r (Value Size)
jOffset T (Index m)
j
                        Value Size -> Value Size -> CodeGenFunction r (Value Size)
forall a r. Additive a => a -> a -> CodeGenFunction r a
forall r.
Value Size -> Value Size -> CodeGenFunction r (Value Size)
A.add Value Size
jl (Value Size -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (Value Size) -> CodeGenFunction r (Value Size)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Value Size -> Value Size -> CodeGenFunction r (Value Size)
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
forall r.
Value Size -> Value Size -> CodeGenFunction r (Value Size)
A.mul Value Size
ms Value Size
il)
   iterator :: forall ix r. (Index (n, m) ~ ix) => T (n, m) -> T r (T ix)
iterator T (n, m)
nm =
      case T (n, m) -> (T n, T m)
forall a b. T (a, b) -> (T a, T b)
MultiValue.unzip T (n, m)
nm of
         (T n
n,T m
m) ->
            (T (Index n) -> T (Index m) -> T ix)
-> (T (Index n), T (Index m)) -> T ix
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry T (Index n) -> T (Index m) -> T ix
T (Index n) -> T (Index m) -> T (Index n, Index m)
forall a b. T a -> T b -> T (a, b)
MultiValue.zip ((T (Index n), T (Index m)) -> T ix)
-> T r (T (Index n), T (Index m)) -> T r (T ix)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
            T r (T (Index n))
-> T r (T (Index m)) -> T r (T (Index n), T (Index m))
forall a b r.
(Phi a, Phi b, Undefined a, Undefined b) =>
T r a -> T r b -> T r (a, b)
Iter.cartesian (T n -> T r (T (Index n))
forall sh ix r. (C sh, Index sh ~ ix) => T sh -> T r (T ix)
forall ix r. (Index n ~ ix) => T n -> T r (T ix)
iterator T n
n) (T m -> T r (T (Index m))
forall sh ix r. (C sh, Index sh ~ ix) => T sh -> T r (T ix)
forall ix r. (Index m ~ ix) => T m -> T r (T ix)
iterator T m
m)
   loop :: forall ix state r.
(Index (n, m) ~ ix, Phi state) =>
(T ix -> state -> CodeGenFunction r state)
-> T (n, m) -> state -> CodeGenFunction r state
loop T ix -> state -> CodeGenFunction r state
code T (n, m)
nm =
      case T (n, m) -> (T n, T m)
forall a b. T (a, b) -> (T a, T b)
MultiValue.unzip T (n, m)
nm of
         (T n
n,T m
m) -> (T (Index n) -> state -> CodeGenFunction r state)
-> T n -> state -> CodeGenFunction r state
forall sh ix state r.
(C sh, Index sh ~ ix, Phi state) =>
(T ix -> state -> CodeGenFunction r state)
-> T sh -> state -> CodeGenFunction r state
forall ix state r.
(Index n ~ ix, Phi state) =>
(T ix -> state -> CodeGenFunction r state)
-> T n -> state -> CodeGenFunction r state
loop (\T (Index n)
i -> (T (Index m) -> state -> CodeGenFunction r state)
-> T m -> state -> CodeGenFunction r state
forall sh ix state r.
(C sh, Index sh ~ ix, Phi state) =>
(T ix -> state -> CodeGenFunction r state)
-> T sh -> state -> CodeGenFunction r state
forall ix state r.
(Index m ~ ix, Phi state) =>
(T ix -> state -> CodeGenFunction r state)
-> T m -> state -> CodeGenFunction r state
loop (\T (Index m)
j -> T ix -> state -> CodeGenFunction r state
code (T (Index n) -> T (Index m) -> T (Index n, Index m)
forall a b. T a -> T b -> T (a, b)
MultiValue.zip T (Index n)
i T (Index m)
j)) T m
m) T n
n

instance (C n, C m, C l) => C (n,m,l) where
   intersectCode :: forall r.
T (n, m, l) -> T (n, m, l) -> CodeGenFunction r (T (n, m, l))
intersectCode T (n, m, l)
a T (n, m, l)
b =
      case (T (n, m, l) -> (T n, T m, T l)
forall a b c. T (a, b, c) -> (T a, T b, T c)
MultiValue.unzip3 T (n, m, l)
a, T (n, m, l) -> (T n, T m, T l)
forall a b c. T (a, b, c) -> (T a, T b, T c)
MultiValue.unzip3 T (n, m, l)
b) of
         ((T n
ai,T m
aj,T l
ak), (T n
bi,T m
bj,T l
bk)) ->
            (T n -> T m -> T l -> T (n, m, l))
-> CodeGenFunction r (T n)
-> CodeGenFunction r (T m)
-> CodeGenFunction r (T l)
-> CodeGenFunction r (T (n, m, l))
forall (m :: * -> *) a b c r.
Monad m =>
(a -> b -> c -> r) -> m a -> m b -> m c -> m r
Monad.lift3 T n -> T m -> T l -> T (n, m, l)
forall a b c. T a -> T b -> T c -> T (a, b, c)
MultiValue.zip3
               (T n -> T n -> CodeGenFunction r (T n)
forall r. T n -> T n -> CodeGenFunction r (T n)
forall sh r. C sh => T sh -> T sh -> CodeGenFunction r (T sh)
intersectCode T n
ai T n
bi)
               (T m -> T m -> CodeGenFunction r (T m)
forall r. T m -> T m -> CodeGenFunction r (T m)
forall sh r. C sh => T sh -> T sh -> CodeGenFunction r (T sh)
intersectCode T m
aj T m
bj)
               (T l -> T l -> CodeGenFunction r (T l)
forall r. T l -> T l -> CodeGenFunction r (T l)
forall sh r. C sh => T sh -> T sh -> CodeGenFunction r (T sh)
intersectCode T l
ak T l
bk)
   size :: forall r. T (n, m, l) -> CodeGenFunction r (Value Size)
size T (n, m, l)
nml =
      case T (n, m, l) -> (T n, T m, T l)
forall a b c. T (a, b, c) -> (T a, T b, T c)
MultiValue.unzip3 T (n, m, l)
nml of
         (T n
n,T m
m,T l
l) ->
            (Value Size -> Value Size -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (Value Size)
-> CodeGenFunction r (Value Size)
-> CodeGenFunction r (Value Size)
forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> m c) -> m a -> m b -> m c
Monad.liftJoin2 Value Size -> Value Size -> CodeGenFunction r (Value Size)
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
forall r.
Value Size -> Value Size -> CodeGenFunction r (Value Size)
A.mul (T n -> CodeGenFunction r (Value Size)
forall r. T n -> CodeGenFunction r (Value Size)
forall sh r. C sh => T sh -> CodeGenFunction r (Value Size)
size T n
n) (CodeGenFunction r (Value Size) -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (Value Size) -> CodeGenFunction r (Value Size)
forall a b. (a -> b) -> a -> b
$
            (Value Size -> Value Size -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (Value Size)
-> CodeGenFunction r (Value Size)
-> CodeGenFunction r (Value Size)
forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> m c) -> m a -> m b -> m c
Monad.liftJoin2 Value Size -> Value Size -> CodeGenFunction r (Value Size)
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
forall r.
Value Size -> Value Size -> CodeGenFunction r (Value Size)
A.mul (T m -> CodeGenFunction r (Value Size)
forall r. T m -> CodeGenFunction r (Value Size)
forall sh r. C sh => T sh -> CodeGenFunction r (Value Size)
size T m
m) (T l -> CodeGenFunction r (Value Size)
forall r. T l -> CodeGenFunction r (Value Size)
forall sh r. C sh => T sh -> CodeGenFunction r (Value Size)
size T l
l)
   sizeOffset :: forall ix r.
(Index (n, m, l) ~ ix) =>
T (n, m, l)
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
sizeOffset T (n, m, l)
nml =
      case T (n, m, l) -> (T n, T m, T l)
forall a b c. T (a, b, c) -> (T a, T b, T c)
MultiValue.unzip3 T (n, m, l)
nml of
         (T n
n,T m
m,T l
l) -> do
            (Value Size
ns, T (Index n) -> CodeGenFunction r (Value Size)
iOffset) <- T n
-> CodeGenFunction
     r (Value Size, T (Index n) -> CodeGenFunction r (Value Size))
forall sh ix r.
(C sh, Index sh ~ ix) =>
T sh
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall ix r.
(Index n ~ ix) =>
T n
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
sizeOffset T n
n
            (Value Size
ms, T (Index m) -> CodeGenFunction r (Value Size)
jOffset) <- T m
-> CodeGenFunction
     r (Value Size, T (Index m) -> CodeGenFunction r (Value Size))
forall sh ix r.
(C sh, Index sh ~ ix) =>
T sh
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall ix r.
(Index m ~ ix) =>
T m
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
sizeOffset T m
m
            (Value Size
ls, T (Index l) -> CodeGenFunction r (Value Size)
kOffset) <- T l
-> CodeGenFunction
     r (Value Size, T (Index l) -> CodeGenFunction r (Value Size))
forall sh ix r.
(C sh, Index sh ~ ix) =>
T sh
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall ix r.
(Index l ~ ix) =>
T l
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
sizeOffset T l
l
            Value Size
sz <- Value Size -> Value Size -> CodeGenFunction r (Value Size)
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
forall r.
Value Size -> Value Size -> CodeGenFunction r (Value Size)
A.mul Value Size
ns (Value Size -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (Value Size) -> CodeGenFunction r (Value Size)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Value Size -> Value Size -> CodeGenFunction r (Value Size)
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
forall r.
Value Size -> Value Size -> CodeGenFunction r (Value Size)
A.mul Value Size
ms Value Size
ls
            (Value Size, T ix -> CodeGenFunction r (Value Size))
-> CodeGenFunction
     r (Value Size, T ix -> CodeGenFunction r (Value Size))
forall a. a -> CodeGenFunction r a
forall (m :: * -> *) a. Monad m => a -> m a
return
               (Value Size
sz,
                \T ix
ijk ->
                  case T (Index n, Index m, Index l)
-> (T (Index n), T (Index m), T (Index l))
forall a b c. T (a, b, c) -> (T a, T b, T c)
MultiValue.unzip3 T ix
T (Index n, Index m, Index l)
ijk of
                     (T (Index n)
i,T (Index m)
j,T (Index l)
k) -> do
                        Value Size
il <- T (Index n) -> CodeGenFunction r (Value Size)
iOffset T (Index n)
i
                        Value Size
jl <- T (Index m) -> CodeGenFunction r (Value Size)
jOffset T (Index m)
j
                        Value Size
kl <- T (Index l) -> CodeGenFunction r (Value Size)
kOffset T (Index l)
k
                        Value Size -> Value Size -> CodeGenFunction r (Value Size)
forall a r. Additive a => a -> a -> CodeGenFunction r a
forall r.
Value Size -> Value Size -> CodeGenFunction r (Value Size)
A.add Value Size
kl (Value Size -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (Value Size) -> CodeGenFunction r (Value Size)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Value Size -> Value Size -> CodeGenFunction r (Value Size)
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
forall r.
Value Size -> Value Size -> CodeGenFunction r (Value Size)
A.mul Value Size
ls (Value Size -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (Value Size) -> CodeGenFunction r (Value Size)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Value Size -> Value Size -> CodeGenFunction r (Value Size)
forall a r. Additive a => a -> a -> CodeGenFunction r a
forall r.
Value Size -> Value Size -> CodeGenFunction r (Value Size)
A.add Value Size
jl (Value Size -> CodeGenFunction r (Value Size))
-> CodeGenFunction r (Value Size) -> CodeGenFunction r (Value Size)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Value Size -> Value Size -> CodeGenFunction r (Value Size)
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
forall r.
Value Size -> Value Size -> CodeGenFunction r (Value Size)
A.mul Value Size
ms Value Size
il)
   iterator :: forall ix r. (Index (n, m, l) ~ ix) => T (n, m, l) -> T r (T ix)
iterator T (n, m, l)
nml =
      case T (n, m, l) -> (T n, T m, T l)
forall a b c. T (a, b, c) -> (T a, T b, T c)
MultiValue.unzip3 T (n, m, l)
nml of
         (T n
n,T m
m,T l
l) ->
            ((T (Index n), (T (Index m), T (Index l))) -> T ix)
-> T r (T (Index n), (T (Index m), T (Index l))) -> T r (T ix)
forall a b. (a -> b) -> T r a -> T r b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(T (Index n)
a,(T (Index m)
b,T (Index l)
c)) -> T (Index n)
-> T (Index m) -> T (Index l) -> T (Index n, Index m, Index l)
forall a b c. T a -> T b -> T c -> T (a, b, c)
MultiValue.zip3 T (Index n)
a T (Index m)
b T (Index l)
c) (T r (T (Index n), (T (Index m), T (Index l))) -> T r (T ix))
-> T r (T (Index n), (T (Index m), T (Index l))) -> T r (T ix)
forall a b. (a -> b) -> a -> b
$
            T r (T (Index n))
-> T r (T (Index m), T (Index l))
-> T r (T (Index n), (T (Index m), T (Index l)))
forall a b r.
(Phi a, Phi b, Undefined a, Undefined b) =>
T r a -> T r b -> T r (a, b)
Iter.cartesian (T n -> T r (T (Index n))
forall sh ix r. (C sh, Index sh ~ ix) => T sh -> T r (T ix)
forall ix r. (Index n ~ ix) => T n -> T r (T ix)
iterator T n
n) (T r (T (Index m), T (Index l))
 -> T r (T (Index n), (T (Index m), T (Index l))))
-> T r (T (Index m), T (Index l))
-> T r (T (Index n), (T (Index m), T (Index l)))
forall a b. (a -> b) -> a -> b
$
            T r (T (Index m))
-> T r (T (Index l)) -> T r (T (Index m), T (Index l))
forall a b r.
(Phi a, Phi b, Undefined a, Undefined b) =>
T r a -> T r b -> T r (a, b)
Iter.cartesian (T m -> T r (T (Index m))
forall sh ix r. (C sh, Index sh ~ ix) => T sh -> T r (T ix)
forall ix r. (Index m ~ ix) => T m -> T r (T ix)
iterator T m
m) (T l -> T r (T (Index l))
forall sh ix r. (C sh, Index sh ~ ix) => T sh -> T r (T ix)
forall ix r. (Index l ~ ix) => T l -> T r (T ix)
iterator T l
l)
   loop :: forall ix state r.
(Index (n, m, l) ~ ix, Phi state) =>
(T ix -> state -> CodeGenFunction r state)
-> T (n, m, l) -> state -> CodeGenFunction r state
loop T ix -> state -> CodeGenFunction r state
code T (n, m, l)
nml =
      case T (n, m, l) -> (T n, T m, T l)
forall a b c. T (a, b, c) -> (T a, T b, T c)
MultiValue.unzip3 T (n, m, l)
nml of
         (T n
n,T m
m,T l
l) ->
            (T (Index n) -> state -> CodeGenFunction r state)
-> T n -> state -> CodeGenFunction r state
forall sh ix state r.
(C sh, Index sh ~ ix, Phi state) =>
(T ix -> state -> CodeGenFunction r state)
-> T sh -> state -> CodeGenFunction r state
forall ix state r.
(Index n ~ ix, Phi state) =>
(T ix -> state -> CodeGenFunction r state)
-> T n -> state -> CodeGenFunction r state
loop (\T (Index n)
i -> (T (Index m) -> state -> CodeGenFunction r state)
-> T m -> state -> CodeGenFunction r state
forall sh ix state r.
(C sh, Index sh ~ ix, Phi state) =>
(T ix -> state -> CodeGenFunction r state)
-> T sh -> state -> CodeGenFunction r state
forall ix state r.
(Index m ~ ix, Phi state) =>
(T ix -> state -> CodeGenFunction r state)
-> T m -> state -> CodeGenFunction r state
loop (\T (Index m)
j -> (T (Index l) -> state -> CodeGenFunction r state)
-> T l -> state -> CodeGenFunction r state
forall sh ix state r.
(C sh, Index sh ~ ix, Phi state) =>
(T ix -> state -> CodeGenFunction r state)
-> T sh -> state -> CodeGenFunction r state
forall ix state r.
(Index l ~ ix, Phi state) =>
(T ix -> state -> CodeGenFunction r state)
-> T l -> state -> CodeGenFunction r state
loop (\T (Index l)
k ->
               T ix -> state -> CodeGenFunction r state
code (T (Index n)
-> T (Index m) -> T (Index l) -> T (Index n, Index m, Index l)
forall a b c. T a -> T b -> T c -> T (a, b, c)
MultiValue.zip3 T (Index n)
i T (Index m)
j T (Index l)
k))
            T l
l) T m
m) T n
n