{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeOperators #-}
module Data.Array.Knead.Symbolic (
   Core.Array,
   Core.C(..),
   Exp,
   fix,
   shape,
   (Core.!),
   Core.the,
   Core.fromScalar,
   Core.fill,
   gather,
   backpermute,
   Core.backpermute2,
   Core.id,
   Core.map,
   Core.mapWithIndex,
   zipWith,
   zipWith3,
   zipWith4,
   zip,
   zip3,
   zip4,
   Core.fold1,
   Core.fold1All,
   Core.findAll,
   ) where

import qualified Data.Array.Knead.Symbolic.ShapeDependent as ShapeDep
import qualified Data.Array.Knead.Symbolic.Private as Core
import Data.Array.Knead.Symbolic.Private (Array, shape, gather, )

import qualified Data.Array.Knead.Shape as Shape
import qualified Data.Array.Knead.Expression as Expr
import Data.Array.Knead.Expression (Exp, )

import qualified LLVM.Extra.Multi.Value as MultiValue

import Data.Function.HT (Id)

import Prelude hiding (zipWith, zipWith3, zip, zip3, replicate, )


fix :: Id (Array sh a)
fix :: forall sh a. Id (Array sh a)
fix = Array sh a -> Array sh a
forall a. a -> a
id

backpermute ::
   (Shape.C sh0, Shape.Index sh0 ~ ix0,
    Shape.C sh1, Shape.Index sh1 ~ ix1,
    MultiValue.C a) =>
   Exp sh1 ->
   (Exp ix1 -> Exp ix0) ->
   Array sh0 a ->
   Array sh1 a
backpermute :: forall sh0 ix0 sh1 ix1 a.
(C sh0, Index sh0 ~ ix0, C sh1, Index sh1 ~ ix1, C a) =>
Exp sh1 -> (Exp ix1 -> Exp ix0) -> Array sh0 a -> Array sh1 a
backpermute Exp sh1
sh1 Exp ix1 -> Exp ix0
f = Array sh1 ix0 -> Array sh0 a -> Array sh1 a
forall (array :: * -> * -> *) sh0 ix0 sh1 ix1 a.
(C array, C sh0, Index sh0 ~ ix0, C sh1, Index sh1 ~ ix1, C a) =>
array sh1 ix0 -> array sh0 a -> array sh1 a
gather ((Exp ix1 -> Exp ix0) -> Array sh1 ix1 -> Array sh1 ix0
forall (array :: * -> * -> *) sh a b.
(C array, C sh) =>
(Exp a -> Exp b) -> array sh a -> array sh b
Core.map Exp ix1 -> Exp ix0
f (Exp sh1 -> Array sh1 ix1
forall (array :: * -> * -> *) sh ix.
(C array, C sh, Index sh ~ ix) =>
Exp sh -> array sh ix
Core.id Exp sh1
sh1))

zipWith ::
   (Core.C array, Shape.C sh) =>
   (Exp a -> Exp b -> Exp c) ->
   array sh a -> array sh b -> array sh c
zipWith :: forall (array :: * -> * -> *) sh a b c.
(C array, C sh) =>
(Exp a -> Exp b -> Exp c) -> array sh a -> array sh b -> array sh c
zipWith = (Exp sh -> Exp sh -> Exp sh)
-> (Exp (Index sh) -> Exp (Index sh))
-> (Exp (Index sh) -> Exp (Index sh))
-> (Exp a -> Exp b -> Exp c)
-> array sh a
-> array sh b
-> array sh c
forall (array :: * -> * -> *) sh0 ix0 sh1 ix1 sh ix a b c.
(C array, C sh0, Index sh0 ~ ix0, C sh1, Index sh1 ~ ix1, C sh,
 Index sh ~ ix) =>
(Exp sh0 -> Exp sh1 -> Exp sh)
-> (Exp ix -> Exp ix0)
-> (Exp ix -> Exp ix1)
-> (Exp a -> Exp b -> Exp c)
-> array sh0 a
-> array sh1 b
-> array sh c
ShapeDep.backpermute2 Exp sh -> Exp sh -> Exp sh
forall sh. C sh => Exp sh -> Exp sh -> Exp sh
Shape.intersect Exp (Index sh) -> Exp (Index sh)
forall a. a -> a
id Exp (Index sh) -> Exp (Index sh)
forall a. a -> a
id

zipWith3 ::
   (Core.C array, Shape.C sh) =>
   (Exp a -> Exp b -> Exp c -> Exp d) ->
   array sh a -> array sh b -> array sh c -> array sh d
zipWith3 :: forall (array :: * -> * -> *) sh a b c d.
(C array, C sh) =>
(Exp a -> Exp b -> Exp c -> Exp d)
-> array sh a -> array sh b -> array sh c -> array sh d
zipWith3 Exp a -> Exp b -> Exp c -> Exp d
f array sh a
a array sh b
b array sh c
c =
   (Exp (a, b) -> Exp c -> Exp d)
-> array sh (a, b) -> array sh c -> array sh d
forall (array :: * -> * -> *) sh a b c.
(C array, C sh) =>
(Exp a -> Exp b -> Exp c) -> array sh a -> array sh b -> array sh c
zipWith (\Exp (a, b)
ab -> (Exp a -> Exp b -> Exp c -> Exp d)
-> (Exp a, Exp b) -> Exp c -> Exp d
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Exp a -> Exp b -> Exp c -> Exp d
f (Exp (a, b) -> (Exp a, Exp b)
forall (val :: * -> *) a b.
Value val =>
val (a, b) -> (val a, val b)
Expr.unzip Exp (a, b)
ab)) ((Exp a -> Exp b -> Exp (a, b))
-> array sh a -> array sh b -> array sh (a, b)
forall (array :: * -> * -> *) sh a b c.
(C array, C sh) =>
(Exp a -> Exp b -> Exp c) -> array sh a -> array sh b -> array sh c
zipWith Exp a -> Exp b -> Exp (a, b)
forall (val :: * -> *) a b.
Value val =>
val a -> val b -> val (a, b)
Expr.zip array sh a
a array sh b
b) array sh c
c

zipWith4 ::
   (Core.C array, Shape.C sh) =>
   (Exp a -> Exp b -> Exp c -> Exp d -> Exp e) ->
   array sh a -> array sh b -> array sh c -> array sh d -> array sh e
zipWith4 :: forall (array :: * -> * -> *) sh a b c d e.
(C array, C sh) =>
(Exp a -> Exp b -> Exp c -> Exp d -> Exp e)
-> array sh a
-> array sh b
-> array sh c
-> array sh d
-> array sh e
zipWith4 Exp a -> Exp b -> Exp c -> Exp d -> Exp e
f array sh a
a array sh b
b array sh c
c array sh d
d =
   (Exp (a, b) -> Exp c -> Exp d -> Exp e)
-> array sh (a, b) -> array sh c -> array sh d -> array sh e
forall (array :: * -> * -> *) sh a b c d.
(C array, C sh) =>
(Exp a -> Exp b -> Exp c -> Exp d)
-> array sh a -> array sh b -> array sh c -> array sh d
zipWith3 (\Exp (a, b)
ab -> (Exp a -> Exp b -> Exp c -> Exp d -> Exp e)
-> (Exp a, Exp b) -> Exp c -> Exp d -> Exp e
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Exp a -> Exp b -> Exp c -> Exp d -> Exp e
f (Exp (a, b) -> (Exp a, Exp b)
forall (val :: * -> *) a b.
Value val =>
val (a, b) -> (val a, val b)
Expr.unzip Exp (a, b)
ab)) ((Exp a -> Exp b -> Exp (a, b))
-> array sh a -> array sh b -> array sh (a, b)
forall (array :: * -> * -> *) sh a b c.
(C array, C sh) =>
(Exp a -> Exp b -> Exp c) -> array sh a -> array sh b -> array sh c
zipWith Exp a -> Exp b -> Exp (a, b)
forall (val :: * -> *) a b.
Value val =>
val a -> val b -> val (a, b)
Expr.zip array sh a
a array sh b
b) array sh c
c array sh d
d


zip ::
   (Core.C array, Shape.C sh) =>
   array sh a -> array sh b -> array sh (a,b)
zip :: forall (array :: * -> * -> *) sh a b.
(C array, C sh) =>
array sh a -> array sh b -> array sh (a, b)
zip = (Exp a -> Exp b -> Exp (a, b))
-> array sh a -> array sh b -> array sh (a, b)
forall (array :: * -> * -> *) sh a b c.
(C array, C sh) =>
(Exp a -> Exp b -> Exp c) -> array sh a -> array sh b -> array sh c
zipWith ((T a -> T b -> T (a, b)) -> Exp a -> Exp b -> Exp (a, b)
forall a b c. (T a -> T b -> T c) -> Exp a -> Exp b -> Exp c
forall (val :: * -> *) a b c.
Value val =>
(T a -> T b -> T c) -> val a -> val b -> val c
Expr.lift2 T a -> T b -> T (a, b)
forall a b. T a -> T b -> T (a, b)
MultiValue.zip)

zip3 ::
   (Core.C array, Shape.C sh) =>
   array sh a -> array sh b -> array sh c -> array sh (a,b,c)
zip3 :: forall (array :: * -> * -> *) sh a b c.
(C array, C sh) =>
array sh a -> array sh b -> array sh c -> array sh (a, b, c)
zip3 = (Exp a -> Exp b -> Exp c -> Exp (a, b, c))
-> array sh a -> array sh b -> array sh c -> array sh (a, b, c)
forall (array :: * -> * -> *) sh a b c d.
(C array, C sh) =>
(Exp a -> Exp b -> Exp c -> Exp d)
-> array sh a -> array sh b -> array sh c -> array sh d
zipWith3 ((T a -> T b -> T c -> T (a, b, c))
-> Exp a -> Exp b -> Exp c -> Exp (a, b, c)
forall (val :: * -> *) a b c d.
Value val =>
(T a -> T b -> T c -> T d) -> val a -> val b -> val c -> val d
Expr.lift3 T a -> T b -> T c -> T (a, b, c)
forall a b c. T a -> T b -> T c -> T (a, b, c)
MultiValue.zip3)

zip4 ::
   (Core.C array, Shape.C sh) =>
   array sh a -> array sh b -> array sh c -> array sh d ->
   array sh (a,b,c,d)
zip4 :: forall (array :: * -> * -> *) sh a b c d.
(C array, C sh) =>
array sh a
-> array sh b -> array sh c -> array sh d -> array sh (a, b, c, d)
zip4 = (Exp a -> Exp b -> Exp c -> Exp d -> Exp (a, b, c, d))
-> array sh a
-> array sh b
-> array sh c
-> array sh d
-> array sh (a, b, c, d)
forall (array :: * -> * -> *) sh a b c d e.
(C array, C sh) =>
(Exp a -> Exp b -> Exp c -> Exp d -> Exp e)
-> array sh a
-> array sh b
-> array sh c
-> array sh d
-> array sh e
zipWith4 ((T a -> T b -> T c -> T d -> T (a, b, c, d))
-> Exp a -> Exp b -> Exp c -> Exp d -> Exp (a, b, c, d)
forall (val :: * -> *) a b c d e.
Value val =>
(T a -> T b -> T c -> T d -> T e)
-> val a -> val b -> val c -> val d -> val e
Expr.lift4 T a -> T b -> T c -> T d -> T (a, b, c, d)
forall a b c d. T a -> T b -> T c -> T d -> T (a, b, c, d)
MultiValue.zip4)