{-# LANGUAGE AllowAmbiguousTypes   #-}
{-# LANGUAGE CPP                   #-}
{-# LANGUAGE DataKinds             #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE GADTs                 #-}
{-# LANGUAGE LambdaCase            #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE TemplateHaskell       #-}
{-# LANGUAGE TypeApplications      #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE TypeOperators         #-}
{-# OPTIONS_HADDOCK hide #-}
-- |
-- Module      : Data.Array.Accelerate.Smart
-- Copyright   : [2008..2020] The Accelerate Team
-- License     : BSD3
--
-- Maintainer  : Trevor L. McDonell <trevor.mcdonell@gmail.com>
-- Stability   : experimental
-- Portability : non-portable (GHC extensions)
--
-- This modules defines the AST of the user-visible embedded language using more
-- convenient higher-order abstract syntax (instead of de Bruijn indices).
-- Moreover, it defines smart constructors to construct programs.
--

module Data.Array.Accelerate.Smart (

  -- * HOAS AST
  -- ** Array computations
  Acc(..), SmartAcc(..), PreSmartAcc(..),
  Level, Direction(..),

  -- ** Scalar expressions
  Exp(..), SmartExp(..), PreSmartExp(..),
  Stencil(..),
  Boundary(..), PreBoundary(..),
  PrimBool,
  PrimMaybe,

  -- ** Extracting type information
  HasArraysR(..),
  HasTypeR(..),

  -- ** Smart constructors for literals
  constant, undef,

  -- ** Smart destructors for shapes
  indexHead, indexTail,

  -- ** Smart constructors for constants
  mkMinBound, mkMaxBound, mkPi,
  mkSin, mkCos, mkTan,
  mkAsin, mkAcos, mkAtan,
  mkSinh, mkCosh, mkTanh,
  mkAsinh, mkAcosh, mkAtanh,
  mkExpFloating, mkSqrt, mkLog,
  mkFPow, mkLogBase,
  mkTruncate, mkRound, mkFloor, mkCeiling,
  mkAtan2,

  -- ** Smart constructors for primitive functions
  mkAdd, mkSub, mkMul, mkNeg, mkAbs, mkSig, mkQuot, mkRem, mkQuotRem, mkIDiv, mkMod, mkDivMod,
  mkBAnd, mkBOr, mkBXor, mkBNot, mkBShiftL, mkBShiftR, mkBRotateL, mkBRotateR, mkPopCount, mkCountLeadingZeros, mkCountTrailingZeros,
  mkFDiv, mkRecip, mkLt, mkGt, mkLtEq, mkGtEq, mkEq, mkNEq, mkMax, mkMin,
  mkLAnd, mkLOr, mkLNot, mkIsNaN, mkIsInfinite,

  -- ** Smart constructors for type coercion functions
  mkFromIntegral, mkToFloating, mkBitcast, mkCoerce, Coerce(..),

  -- ** Auxiliary functions
  ($$), ($$$), ($$$$), ($$$$$),
  ApplyAcc(..),
  unAcc, unAccFunction, mkExp, unExp, unExpFunction, unExpBinaryFunction, unPair, mkPairToTuple,

  -- ** Miscellaneous
  showPreAccOp,
  showPreExpOp,

) where


import Data.Array.Accelerate.AST.Idx
import Data.Array.Accelerate.Error
import Data.Array.Accelerate.Representation.Array
import Data.Array.Accelerate.Representation.Elt
import Data.Array.Accelerate.Representation.Shape
import Data.Array.Accelerate.Representation.Slice
import Data.Array.Accelerate.Representation.Stencil                 hiding ( StencilR, stencilR )
import Data.Array.Accelerate.Representation.Tag
import Data.Array.Accelerate.Representation.Type
import Data.Array.Accelerate.Representation.Vec
import Data.Array.Accelerate.Sugar.Array                            ( Arrays )
import Data.Array.Accelerate.Sugar.Elt
import Data.Array.Accelerate.Sugar.Foreign
import Data.Array.Accelerate.Sugar.Shape                            ( (:.)(..) )
import Data.Array.Accelerate.Type
import qualified Data.Array.Accelerate.Representation.Stencil       as R
import qualified Data.Array.Accelerate.Sugar.Array                  as Sugar
import qualified Data.Array.Accelerate.Sugar.Shape                  as Sugar

import Data.Array.Accelerate.AST                                    ( Direction(..)
                                                                    , PrimBool, PrimMaybe
                                                                    , PrimFun(..), primFunType
                                                                    , PrimConst(..), primConstType )
import Data.Primitive.Vec

import Data.Kind
import Prelude

import GHC.TypeLits


-- Array computations
-- ------------------

-- | Accelerate is an /embedded language/ that distinguishes between vanilla
-- arrays (e.g. in Haskell memory on the CPU) and embedded arrays (e.g. in
-- device memory on a GPU), as well as the computations on both of these. Since
-- Accelerate is an embedded language, programs written in Accelerate are not
-- compiled by the Haskell compiler (GHC). Rather, each Accelerate backend is
-- a /runtime compiler/ which generates and executes parallel SIMD code of the
-- target language at application /runtime/.
--
-- The type constructor 'Acc' represents embedded collective array operations.
-- A term of type @Acc a@ is an Accelerate program which, once executed, will
-- produce a value of type 'a' (an 'Array' or a tuple of 'Arrays'). Collective
-- operations of type @Acc a@ comprise many /scalar expressions/, wrapped in
-- type constructor 'Exp', which will be executed in parallel. Although
-- collective operations comprise many scalar operations executed in parallel,
-- scalar operations /cannot/ initiate new collective operations: this
-- stratification between scalar operations in 'Exp' and array operations in
-- 'Acc' helps statically exclude /nested data parallelism/, which is difficult
-- to execute efficiently on constrained hardware such as GPUs.
--
-- [/A simple example/]
--
-- As a simple example, to compute a vector dot product we can write:
--
-- > dotp :: Num a => Vector a -> Vector a -> Acc (Scalar a)
-- > dotp xs ys =
-- >   let
-- >       xs' = use xs
-- >       ys' = use ys
-- >   in
-- >   fold (+) 0 ( zipWith (*) xs' ys' )
--
-- The function @dotp@ consumes two one-dimensional arrays ('Vector's) of
-- values, and produces a single ('Scalar') result as output. As the return type
-- is wrapped in the type 'Acc', we see that it is an embedded Accelerate
-- computation - it will be evaluated in the /object/ language of dynamically
-- generated parallel code, rather than the /meta/ language of vanilla Haskell.
--
-- As the arguments to @dotp@ are plain Haskell arrays, to make these available
-- to Accelerate computations they must be embedded with the
-- 'Data.Array.Accelerate.Language.use' function.
--
-- An Accelerate backend is used to evaluate the embedded computation and return
-- the result back to vanilla Haskell. Calling the 'run' function of a backend
-- will generate code for the target architecture, compile, and execute it. For
-- example, the following backends are available:
--
--  * <http://hackage.haskell.org/package/accelerate-llvm-native accelerate-llvm-native>: for execution on multicore CPUs
--  * <http://hackage.haskell.org/package/accelerate-llvm-ptx accelerate-llvm-ptx>: for execution on NVIDIA CUDA-capable GPUs
--
-- See also 'Exp', which encapsulates embedded /scalar/ computations.
--
-- [/Avoiding nested parallelism/]
--
-- As mentioned above, embedded scalar computations of type 'Exp' can not
-- initiate further collective operations.
--
-- Suppose we wanted to extend our above @dotp@ function to matrix-vector
-- multiplication. First, let's rewrite our @dotp@ function to take 'Acc' arrays
-- as input (which is typically what we want):
--
-- > dotp :: Num a => Acc (Vector a) -> Acc (Vector a) -> Acc (Scalar a)
-- > dotp xs ys = fold (+) 0 ( zipWith (*) xs ys )
--
-- We might then be inclined to lift our dot-product program to the following
-- (incorrect) matrix-vector product, by applying @dotp@ to each row of the
-- input matrix:
--
-- > mvm_ndp :: Num a => Acc (Matrix a) -> Acc (Vector a) -> Acc (Vector a)
-- > mvm_ndp mat vec =
-- >   let Z :. rows :. cols  = unlift (shape mat)  :: Z :. Exp Int :. Exp Int
-- >   in  generate (index1 rows)
-- >                (\row -> the $ dotp vec (slice mat (lift (row :. All))))
--
-- Here, we use 'Data.Array.Accelerate.generate' to create a one-dimensional
-- vector by applying at each index a function to 'Data.Array.Accelerate.slice'
-- out the corresponding @row@ of the matrix to pass to the @dotp@ function.
-- However, since both 'Data.Array.Accelerate.generate' and
-- 'Data.Array.Accelerate.slice' are data-parallel operations, and moreover that
-- 'Data.Array.Accelerate.slice' /depends on/ the argument @row@ given to it by
-- the 'Data.Array.Accelerate.generate' function, this definition requires
-- nested data-parallelism, and is thus not permitted. The clue that this
-- definition is invalid is that in order to create a program which will be
-- accepted by the type checker, we must use the function
-- 'Data.Array.Accelerate.the' to retrieve the result of the @dotp@ operation,
-- effectively concealing that @dotp@ is a collective array computation in order
-- to match the type expected by 'Data.Array.Accelerate.generate', which is that
-- of scalar expressions. Additionally, since we have fooled the type-checker,
-- this problem will only be discovered at program runtime.
--
-- In order to avoid this problem, we can make use of the fact that operations
-- in Accelerate are /rank polymorphic/. The 'Data.Array.Accelerate.fold'
-- operation reduces along the innermost dimension of an array of arbitrary
-- rank, reducing the rank (dimensionality) of the array by one. Thus, we can
-- 'Data.Array.Accelerate.replicate' the input vector to as many @rows@ there
-- are in the input matrix, and perform the dot-product of the vector with every
-- row simultaneously:
--
-- > mvm :: A.Num a => Acc (Matrix a) -> Acc (Vector a) -> Acc (Vector a)
-- > mvm mat vec =
-- >   let Z :. rows :. cols = unlift (shape mat) :: Z :. Exp Int :. Exp Int
-- >       vec'              = A.replicate (lift (Z :. rows :. All)) vec
-- >   in
-- >   A.fold (+) 0 ( A.zipWith (*) mat vec' )
--
-- Note that the intermediate, replicated array @vec'@ is never actually created
-- in memory; it will be fused directly into the operation which consumes it. We
-- discuss fusion next.
--
-- [/Fusion/]
--
-- Array computations of type 'Acc' will be subject to /array fusion/;
-- Accelerate will combine individual 'Acc' computations into a single
-- computation, which reduces the number of traversals over the input data and
-- thus improves performance. As such, it is often useful to have some intuition
-- on when fusion should occur.
--
-- The main idea is to first partition array operations into two categories:
--
--   1. Element-wise operations, such as 'Data.Array.Accelerate.map',
--      'Data.Array.Accelerate.generate', and
--      'Data.Array.Accelerate.backpermute'. Each element of these operations
--      can be computed independently of all others.
--
--   2. Collective operations such as 'Data.Array.Accelerate.fold',
--      'Data.Array.Accelerate.scanl', and 'Data.Array.Accelerate.stencil'. To
--      compute each output element of these operations requires reading
--      multiple elements from the input array(s).
--
-- Element-wise operations fuse together whenever the consumer operation uses
-- a single element of the input array. Element-wise operations can both fuse
-- their inputs into themselves, as well be fused into later operations. Both
-- these examples should fuse into a single loop:
--
-- <<images/fusion_example_1.png>>
--
-- <<images/fusion_example_2.png>>
--
-- If the consumer operation uses more than one element of the input array
-- (typically, via 'Data.Array.Accelerate.generate' indexing an array multiple
-- times), then the input array will be completely evaluated first; no fusion
-- occurs in this case, because fusing the first operation into the second
-- implies duplicating work.
--
-- On the other hand, collective operations can fuse their input arrays into
-- themselves, but on output always evaluate to an array; collective operations
-- will not be fused into a later step. For example:
--
-- <<images/fusion_example_3.png>>
--
-- Here the element-wise sequence ('Data.Array.Accelerate.use'
-- + 'Data.Array.Accelerate.generate' + 'Data.Array.Accelerate.zipWith') will
-- fuse into a single operation, which then fuses into the collective
-- 'Data.Array.Accelerate.fold' operation. At this point in the program the
-- 'Data.Array.Accelerate.fold' must now be evaluated. In the final step the
-- 'Data.Array.Accelerate.map' reads in the array produced by
-- 'Data.Array.Accelerate.fold'. As there is no fusion between the
-- 'Data.Array.Accelerate.fold' and 'Data.Array.Accelerate.map' steps, this
-- program consists of two "loops"; one for the 'Data.Array.Accelerate.use'
-- + 'Data.Array.Accelerate.generate' + 'Data.Array.Accelerate.zipWith'
-- + 'Data.Array.Accelerate.fold' step, and one for the final
-- 'Data.Array.Accelerate.map' step.
--
-- You can see how many operations will be executed in the fused program by
-- 'Show'-ing the 'Acc' program, or by using the debugging option @-ddump-dot@
-- to save the program as a graphviz DOT file.
--
-- As a special note, the operations 'Data.Array.Accelerate.unzip' and
-- 'Data.Array.Accelerate.reshape', when applied to a real array, are executed
-- in constant time, so in this situation these operations will not be fused.
--
-- [/Tips/]
--
--  * Since 'Acc' represents embedded computations that will only be executed
--    when evaluated by a backend, we can programatically generate these
--    computations using the meta language Haskell; for example, unrolling loops
--    or embedding input values into the generated code.
--
--  * It is usually best to keep all intermediate computations in 'Acc', and
--    only 'run' the computation at the very end to produce the final result.
--    This enables optimisations between intermediate results (e.g. array
--    fusion) and, if the target architecture has a separate memory space, as is
--    the case of GPUs, to prevent excessive data transfers.
--
newtype Acc a = Acc (SmartAcc (Sugar.ArraysR a))

newtype SmartAcc a = SmartAcc (PreSmartAcc SmartAcc SmartExp a)


-- The level of lambda-bound variables. The root has level 0; then it
-- increases with each bound variable — i.e., it is the same as the size of
-- the environment at the defining occurrence.
--
type Level = Int

-- | Array-valued collective computations without a recursive knot
--
data PreSmartAcc acc exp as where
    -- Needed for conversion to de Bruijn form
  Atag          :: ArraysR as
                -> Level                        -- environment size at defining occurrence
                -> PreSmartAcc acc exp as

  Pipe          :: ArraysR as
                -> ArraysR bs
                -> ArraysR cs
                -> (SmartAcc as -> acc bs)
                -> (SmartAcc bs -> acc cs)
                -> acc as
                -> PreSmartAcc acc exp cs

  Aforeign      :: Foreign asm
                => ArraysR bs
                -> asm (as -> bs)
                -> (SmartAcc as -> SmartAcc bs)
                -> acc as
                -> PreSmartAcc acc exp bs

  Acond         :: exp PrimBool
                -> acc as
                -> acc as
                -> PreSmartAcc acc exp as

  Awhile        :: ArraysR arrs
                -> (SmartAcc arrs -> acc (Scalar PrimBool))
                -> (SmartAcc arrs -> acc arrs)
                -> acc arrs
                -> PreSmartAcc acc exp arrs

  Anil          :: PreSmartAcc acc exp ()

  Apair         :: acc arrs1
                -> acc arrs2
                -> PreSmartAcc acc exp (arrs1, arrs2)

  Aprj          :: PairIdx (arrs1, arrs2) arrs
                -> acc (arrs1, arrs2)
                -> PreSmartAcc acc exp arrs

  Use           :: ArrayR (Array sh e)
                -> Array sh e
                -> PreSmartAcc acc exp (Array sh e)

  Unit          :: TypeR e
                -> exp e
                -> PreSmartAcc acc exp (Scalar e)

  Generate      :: ArrayR (Array sh e)
                -> exp sh
                -> (SmartExp sh -> exp e)
                -> PreSmartAcc acc exp (Array sh e)

  Reshape       :: ShapeR sh
                -> exp sh
                -> acc (Array sh' e)
                -> PreSmartAcc acc exp (Array sh e)

  Replicate     :: SliceIndex slix sl co sh
                -> exp slix
                -> acc                 (Array sl e)
                -> PreSmartAcc acc exp (Array sh e)

  Slice         :: SliceIndex slix sl co sh
                -> acc                 (Array sh e)
                -> exp slix
                -> PreSmartAcc acc exp (Array sl e)

  Map           :: TypeR e
                -> TypeR e'
                -> (SmartExp e -> exp e')
                -> acc (Array sh e)
                -> PreSmartAcc acc exp (Array sh e')

  ZipWith       :: TypeR e1
                -> TypeR e2
                -> TypeR e3
                -> (SmartExp e1 -> SmartExp e2 -> exp e3)
                -> acc (Array sh e1)
                -> acc (Array sh e2)
                -> PreSmartAcc acc exp (Array sh e3)

  Fold          :: TypeR e
                -> (SmartExp e -> SmartExp e -> exp e)
                -> Maybe (exp e)
                -> acc (Array (sh, Int) e)
                -> PreSmartAcc acc exp (Array sh e)

  FoldSeg       :: IntegralType i
                -> TypeR e
                -> (SmartExp e -> SmartExp e -> exp e)
                -> Maybe (exp e)
                -> acc (Array (sh, Int) e)
                -> acc (Segments i)
                -> PreSmartAcc acc exp (Array (sh, Int) e)

  Scan          :: Direction
                -> TypeR e
                -> (SmartExp e -> SmartExp e -> exp e)
                -> Maybe (exp e)
                -> acc (Array (sh, Int) e)
                -> PreSmartAcc acc exp (Array (sh, Int) e)

  Scan'         :: Direction
                -> TypeR e
                -> (SmartExp e -> SmartExp e -> exp e)
                -> exp e
                -> acc (Array (sh, Int) e)
                -> PreSmartAcc acc exp (Array (sh, Int) e, Array sh e)

  Permute       :: ArrayR (Array sh e)
                -> (SmartExp e -> SmartExp e -> exp e)
                -> acc (Array sh' e)
                -> (SmartExp sh -> exp (PrimMaybe sh'))
                -> acc (Array sh e)
                -> PreSmartAcc acc exp (Array sh' e)

  Backpermute   :: ShapeR sh'
                -> exp sh'
                -> (SmartExp sh' -> exp sh)
                -> acc (Array sh e)
                -> PreSmartAcc acc exp (Array sh' e)

  Stencil       :: R.StencilR sh a stencil
                -> TypeR b
                -> (SmartExp stencil -> exp b)
                -> PreBoundary acc exp (Array sh a)
                -> acc (Array sh a)
                -> PreSmartAcc acc exp (Array sh b)

  Stencil2      :: R.StencilR sh a stencil1
                -> R.StencilR sh b stencil2
                -> TypeR c
                -> (SmartExp stencil1 -> SmartExp stencil2 -> exp c)
                -> PreBoundary acc exp (Array sh a)
                -> acc (Array sh a)
                -> PreBoundary acc exp (Array sh b)
                -> acc (Array sh b)
                -> PreSmartAcc acc exp (Array sh c)


-- Embedded expressions of the surface language
-- --------------------------------------------

-- HOAS expressions mirror the constructors of 'AST.OpenExp', but with the 'Tag'
-- constructor instead of variables in the form of de Bruijn indices.
--

-- | The type 'Exp' represents embedded scalar expressions. The collective
-- operations of Accelerate 'Acc' consist of many scalar expressions executed in
-- data-parallel.
--
-- Note that scalar expressions can not initiate new collective operations:
-- doing so introduces /nested data parallelism/, which is difficult to execute
-- efficiently on constrained hardware such as GPUs, and is thus currently
-- unsupported.
--
newtype Exp t = Exp (SmartExp (EltR t))
newtype SmartExp t = SmartExp (PreSmartExp SmartAcc SmartExp t)

-- | Scalar expressions to parametrise collective array operations, themselves parameterised over
-- the type of collective array operations.
--
data PreSmartExp acc exp t where
  -- Needed for conversion to de Bruijn form
  Tag           :: TypeR t
                -> Level                        -- environment size at defining occurrence
                -> PreSmartExp acc exp t

  -- Needed for embedded pattern matching
  Match         :: TagR t
                -> exp t
                -> PreSmartExp acc exp t

  -- All the same constructors as 'AST.Exp', plus projection
  Const         :: ScalarType t
                -> t
                -> PreSmartExp acc exp t

  Nil           :: PreSmartExp acc exp ()

  Pair          :: exp t1
                -> exp t2
                -> PreSmartExp acc exp (t1, t2)

  Prj           :: PairIdx (t1, t2) t
                -> exp (t1, t2)
                -> PreSmartExp acc exp t

  VecPack       :: KnownNat n
                => VecR n s tup
                -> exp tup
                -> PreSmartExp acc exp (Vec n s)

  VecUnpack     :: KnownNat n
                => VecR n s tup
                -> exp (Vec n s)
                -> PreSmartExp acc exp tup

  ToIndex       :: ShapeR sh
                -> exp sh
                -> exp sh
                -> PreSmartExp acc exp Int

  FromIndex     :: ShapeR sh
                -> exp sh
                -> exp Int
                -> PreSmartExp acc exp sh

  Case          :: exp a
                -> [(TagR a, exp b)]
                -> PreSmartExp acc exp b

  Cond          :: exp PrimBool
                -> exp t
                -> exp t
                -> PreSmartExp acc exp t

  While         :: TypeR t
                -> (SmartExp t -> exp PrimBool)
                -> (SmartExp t -> exp t)
                -> exp t
                -> PreSmartExp acc exp t

  PrimConst     :: PrimConst t
                -> PreSmartExp acc exp t

  PrimApp       :: PrimFun (a -> r)
                -> exp a
                -> PreSmartExp acc exp r

  Index         :: TypeR t
                -> acc (Array sh t)
                -> exp sh
                -> PreSmartExp acc exp t

  LinearIndex   :: TypeR t
                -> acc (Array sh t)
                -> exp Int
                -> PreSmartExp acc exp t

  Shape         :: ShapeR sh
                -> acc (Array sh e)
                -> PreSmartExp acc exp sh

  ShapeSize     :: ShapeR sh
                -> exp sh
                -> PreSmartExp acc exp Int

  Foreign       :: Foreign asm
                => TypeR y
                -> asm (x -> y)
                -> (SmartExp x -> SmartExp y) -- RCE: Using SmartExp instead of exp to aid in sharing recovery.
                -> exp x
                -> PreSmartExp acc exp y

  Undef         :: ScalarType t
                -> PreSmartExp acc exp t

  Coerce        :: BitSizeEq a b
                => ScalarType a
                -> ScalarType b
                -> exp a
                -> PreSmartExp acc exp b


-- Smart constructors for stencils
-- -------------------------------

-- | Boundary condition specification for stencil operations
--
data Boundary t where
  Boundary  :: PreBoundary SmartAcc SmartExp (Array (EltR sh) (EltR e))
            -> Boundary (Sugar.Array sh e)

data PreBoundary acc exp t where
  Clamp     :: PreBoundary acc exp t
  Mirror    :: PreBoundary acc exp t
  Wrap      :: PreBoundary acc exp t

  Constant  :: e
            -> PreBoundary acc exp (Array sh e)

  Function  :: (SmartExp sh -> exp e)
            -> PreBoundary acc exp (Array sh e)


-- Stencil reification
-- -------------------
--
-- In the AST representation, we turn the stencil type from nested tuples
-- of Accelerate expressions into an Accelerate expression whose type is
-- a tuple nested in the same manner. This enables us to represent the
-- stencil function as a unary function (which also only needs one de
-- Bruijn index). The various positions in the stencil are accessed via
-- tuple indices (i.e., projections).
--
class Stencil sh e stencil where
  type StencilR sh stencil :: Type

  stencilR   :: R.StencilR (EltR sh) (EltR e) (StencilR sh stencil)
  stencilPrj :: SmartExp (StencilR sh stencil) -> stencil

-- DIM1
instance Elt e => Stencil Sugar.DIM1 e (Exp e, Exp e, Exp e) where
  type StencilR Sugar.DIM1 (Exp e, Exp e, Exp e)
    = EltR (e, e, e)
  stencilR :: StencilR (EltR DIM1) (EltR e) (StencilR DIM1 (Exp e, Exp e, Exp e))
stencilR = TypeR (EltR e)
-> StencilR DIM1 (EltR e) (Tup3 (EltR e) (EltR e) (EltR e))
forall e. TypeR e -> StencilR DIM1 e (Tup3 e e e)
StencilRunit3 @(EltR e) (TypeR (EltR e)
 -> StencilR DIM1 (EltR e) (Tup3 (EltR e) (EltR e) (EltR e)))
-> TypeR (EltR e)
-> StencilR DIM1 (EltR e) (Tup3 (EltR e) (EltR e) (EltR e))
forall a b. (a -> b) -> a -> b
$ Elt e => TypeR (EltR e)
forall a. Elt a => TypeR (EltR a)
eltR @e
  stencilPrj :: SmartExp (StencilR DIM1 (Exp e, Exp e, Exp e))
-> (Exp e, Exp e, Exp e)
stencilPrj SmartExp (StencilR DIM1 (Exp e, Exp e, Exp e))
s = (SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp (Tup3 (EltR e) (EltR e) (EltR e)) -> SmartExp (EltR e)
forall t a s1 s0. SmartExp (((t, a), s1), s0) -> SmartExp a
prj2 SmartExp (Tup3 (EltR e) (EltR e) (EltR e))
SmartExp (StencilR DIM1 (Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp (Tup3 (EltR e) (EltR e) (EltR e)) -> SmartExp (EltR e)
forall t a s0. SmartExp ((t, a), s0) -> SmartExp a
prj1 SmartExp (Tup3 (EltR e) (EltR e) (EltR e))
SmartExp (StencilR DIM1 (Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp (Tup3 (EltR e) (EltR e) (EltR e)) -> SmartExp (EltR e)
forall t a. SmartExp (t, a) -> SmartExp a
prj0 SmartExp (Tup3 (EltR e) (EltR e) (EltR e))
SmartExp (StencilR DIM1 (Exp e, Exp e, Exp e))
s)

instance Elt e => Stencil Sugar.DIM1 e (Exp e, Exp e, Exp e, Exp e, Exp e) where
  type StencilR Sugar.DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e)
    = EltR (e, e, e, e, e)
  stencilR :: StencilR
  (EltR DIM1)
  (EltR e)
  (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e))
stencilR = TypeR (EltR e)
-> StencilR
     DIM1 (EltR e) (Tup5 (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
forall e. TypeR e -> StencilR DIM1 e (Tup5 e e e e e)
StencilRunit5 (TypeR (EltR e)
 -> StencilR
      DIM1 (EltR e) (Tup5 (EltR e) (EltR e) (EltR e) (EltR e) (EltR e)))
-> TypeR (EltR e)
-> StencilR
     DIM1 (EltR e) (Tup5 (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
forall a b. (a -> b) -> a -> b
$ Elt e => TypeR (EltR e)
forall a. Elt a => TypeR (EltR a)
eltR @e
  stencilPrj :: SmartExp (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e))
-> (Exp e, Exp e, Exp e, Exp e, Exp e)
stencilPrj SmartExp (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e))
s = (SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp (Tup5 (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
-> SmartExp (EltR e)
forall t a s3 s2 s1 s0.
SmartExp (((((t, a), s3), s2), s1), s0) -> SmartExp a
prj4 SmartExp (Tup5 (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
SmartExp (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp (Tup5 (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
-> SmartExp (EltR e)
forall t a s2 s1 s0.
SmartExp ((((t, a), s2), s1), s0) -> SmartExp a
prj3 SmartExp (Tup5 (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
SmartExp (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp (Tup5 (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
-> SmartExp (EltR e)
forall t a s1 s0. SmartExp (((t, a), s1), s0) -> SmartExp a
prj2 SmartExp (Tup5 (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
SmartExp (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp (Tup5 (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
-> SmartExp (EltR e)
forall t a s0. SmartExp ((t, a), s0) -> SmartExp a
prj1 SmartExp (Tup5 (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
SmartExp (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp (Tup5 (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
-> SmartExp (EltR e)
forall t a. SmartExp (t, a) -> SmartExp a
prj0 SmartExp (Tup5 (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
SmartExp (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e))
s)

instance Elt e => Stencil Sugar.DIM1 e (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e) where
  type StencilR Sugar.DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e)
    = EltR (e, e, e, e, e, e, e)
  stencilR :: StencilR
  (EltR DIM1)
  (EltR e)
  (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
stencilR = TypeR (EltR e)
-> StencilR
     DIM1
     (EltR e)
     (Tup7
        (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
forall e. TypeR e -> StencilR DIM1 e (Tup7 e e e e e e e)
StencilRunit7 (TypeR (EltR e)
 -> StencilR
      DIM1
      (EltR e)
      (Tup7
         (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e)))
-> TypeR (EltR e)
-> StencilR
     DIM1
     (EltR e)
     (Tup7
        (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
forall a b. (a -> b) -> a -> b
$ Elt e => TypeR (EltR e)
forall a. Elt a => TypeR (EltR a)
eltR @e
  stencilPrj :: SmartExp
  (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
-> (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e)
stencilPrj SmartExp
  (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s = (SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup7
     (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
-> SmartExp (EltR e)
forall t a s5 s4 s3 s2 s1 s0.
SmartExp (((((((t, a), s5), s4), s3), s2), s1), s0) -> SmartExp a
prj6 SmartExp
  (Tup7
     (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
SmartExp
  (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup7
     (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
-> SmartExp (EltR e)
forall t a s4 s3 s2 s1 s0.
SmartExp ((((((t, a), s4), s3), s2), s1), s0) -> SmartExp a
prj5 SmartExp
  (Tup7
     (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
SmartExp
  (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup7
     (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
-> SmartExp (EltR e)
forall t a s3 s2 s1 s0.
SmartExp (((((t, a), s3), s2), s1), s0) -> SmartExp a
prj4 SmartExp
  (Tup7
     (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
SmartExp
  (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup7
     (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
-> SmartExp (EltR e)
forall t a s2 s1 s0.
SmartExp ((((t, a), s2), s1), s0) -> SmartExp a
prj3 SmartExp
  (Tup7
     (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
SmartExp
  (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup7
     (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
-> SmartExp (EltR e)
forall t a s1 s0. SmartExp (((t, a), s1), s0) -> SmartExp a
prj2 SmartExp
  (Tup7
     (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
SmartExp
  (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup7
     (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
-> SmartExp (EltR e)
forall t a s0. SmartExp ((t, a), s0) -> SmartExp a
prj1 SmartExp
  (Tup7
     (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
SmartExp
  (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup7
     (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
-> SmartExp (EltR e)
forall t a. SmartExp (t, a) -> SmartExp a
prj0 SmartExp
  (Tup7
     (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e) (EltR e))
SmartExp
  (StencilR DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s)

instance Elt e => Stencil Sugar.DIM1 e (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e)
  where
  type StencilR Sugar.DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e)
    = EltR (e, e, e, e, e, e, e, e, e)
  stencilR :: StencilR
  (EltR DIM1)
  (EltR e)
  (StencilR
     DIM1
     (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
stencilR = TypeR (EltR e)
-> StencilR
     DIM1
     (EltR e)
     (Tup9
        (EltR e)
        (EltR e)
        (EltR e)
        (EltR e)
        (EltR e)
        (EltR e)
        (EltR e)
        (EltR e)
        (EltR e))
forall e. TypeR e -> StencilR DIM1 e (Tup9 e e e e e e e e e)
StencilRunit9 (TypeR (EltR e)
 -> StencilR
      DIM1
      (EltR e)
      (Tup9
         (EltR e)
         (EltR e)
         (EltR e)
         (EltR e)
         (EltR e)
         (EltR e)
         (EltR e)
         (EltR e)
         (EltR e)))
-> TypeR (EltR e)
-> StencilR
     DIM1
     (EltR e)
     (Tup9
        (EltR e)
        (EltR e)
        (EltR e)
        (EltR e)
        (EltR e)
        (EltR e)
        (EltR e)
        (EltR e)
        (EltR e))
forall a b. (a -> b) -> a -> b
$ Elt e => TypeR (EltR e)
forall a. Elt a => TypeR (EltR a)
eltR @e
  stencilPrj :: SmartExp
  (StencilR
     DIM1
     (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
-> (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e)
stencilPrj SmartExp
  (StencilR
     DIM1
     (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s = (SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
-> SmartExp (EltR e)
forall t a s7 s6 s5 s4 s3 s2 s1 s0.
SmartExp (((((((((t, a), s7), s6), s5), s4), s3), s2), s1), s0)
-> SmartExp a
prj8 SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
SmartExp
  (StencilR
     DIM1
     (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
-> SmartExp (EltR e)
forall t a s6 s5 s4 s3 s2 s1 s0.
SmartExp ((((((((t, a), s6), s5), s4), s3), s2), s1), s0)
-> SmartExp a
prj7 SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
SmartExp
  (StencilR
     DIM1
     (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
-> SmartExp (EltR e)
forall t a s5 s4 s3 s2 s1 s0.
SmartExp (((((((t, a), s5), s4), s3), s2), s1), s0) -> SmartExp a
prj6 SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
SmartExp
  (StencilR
     DIM1
     (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
-> SmartExp (EltR e)
forall t a s4 s3 s2 s1 s0.
SmartExp ((((((t, a), s4), s3), s2), s1), s0) -> SmartExp a
prj5 SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
SmartExp
  (StencilR
     DIM1
     (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
-> SmartExp (EltR e)
forall t a s3 s2 s1 s0.
SmartExp (((((t, a), s3), s2), s1), s0) -> SmartExp a
prj4 SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
SmartExp
  (StencilR
     DIM1
     (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
-> SmartExp (EltR e)
forall t a s2 s1 s0.
SmartExp ((((t, a), s2), s1), s0) -> SmartExp a
prj3 SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
SmartExp
  (StencilR
     DIM1
     (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
-> SmartExp (EltR e)
forall t a s1 s0. SmartExp (((t, a), s1), s0) -> SmartExp a
prj2 SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
SmartExp
  (StencilR
     DIM1
     (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
-> SmartExp (EltR e)
forall t a s0. SmartExp ((t, a), s0) -> SmartExp a
prj1 SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
SmartExp
  (StencilR
     DIM1
     (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s,
                  SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
-> SmartExp (EltR e)
forall t a. SmartExp (t, a) -> SmartExp a
prj0 SmartExp
  (Tup9
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e)
     (EltR e))
SmartExp
  (StencilR
     DIM1
     (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e))
s)

-- DIM(n+1)
instance (Stencil (sh:.Int) a row2,
          Stencil (sh:.Int) a row1,
          Stencil (sh:.Int) a row0) => Stencil (sh:.Int:.Int) a (row2, row1, row0) where
  type StencilR (sh:.Int:.Int) (row2, row1, row0)
    = Tup3 (StencilR (sh:.Int) row2) (StencilR (sh:.Int) row1) (StencilR (sh:.Int) row0)
  stencilR :: StencilR
  (EltR ((sh :. Int) :. Int))
  (EltR a)
  (StencilR ((sh :. Int) :. Int) (row2, row1, row0))
stencilR = StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row2)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row1)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row0)
-> StencilR
     ((EltR sh, Int), Int)
     (EltR a)
     (Tup3
        (StencilR (sh :. Int) row2)
        (StencilR (sh :. Int) row1)
        (StencilR (sh :. Int) row0))
forall sh e pat1 sh pat3.
StencilR sh e pat1
-> StencilR sh e sh
-> StencilR sh e pat3
-> StencilR (sh, Int) e (Tup3 pat1 sh pat3)
StencilRtup3 (Stencil (sh :. Int) a row2 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row2)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row2) (Stencil (sh :. Int) a row1 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row1)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row1) (Stencil (sh :. Int) a row0 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row0)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row0)
  stencilPrj :: SmartExp (StencilR ((sh :. Int) :. Int) (row2, row1, row0))
-> (row2, row1, row0)
stencilPrj SmartExp (StencilR ((sh :. Int) :. Int) (row2, row1, row0))
s = (forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row2) -> row2)
-> SmartExp (StencilR (sh :. Int) row2) -> row2
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup3
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row2)
forall t a s1 s0. SmartExp (((t, a), s1), s0) -> SmartExp a
prj2 SmartExp
  (Tup3
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp (StencilR ((sh :. Int) :. Int) (row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row1) -> row1)
-> SmartExp (StencilR (sh :. Int) row1) -> row1
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup3
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row1)
forall t a s0. SmartExp ((t, a), s0) -> SmartExp a
prj1 SmartExp
  (Tup3
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp (StencilR ((sh :. Int) :. Int) (row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row0) -> row0)
-> SmartExp (StencilR (sh :. Int) row0) -> row0
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup3
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row0)
forall t a. SmartExp (t, a) -> SmartExp a
prj0 SmartExp
  (Tup3
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp (StencilR ((sh :. Int) :. Int) (row2, row1, row0))
s)

instance (Stencil (sh:.Int) a row4,
          Stencil (sh:.Int) a row3,
          Stencil (sh:.Int) a row2,
          Stencil (sh:.Int) a row1,
          Stencil (sh:.Int) a row0) => Stencil (sh:.Int:.Int) a (row4, row3, row2, row1, row0) where
  type StencilR (sh:.Int:.Int) (row4, row3, row2, row1, row0)
    = Tup5 (StencilR (sh:.Int) row4) (StencilR (sh:.Int) row3) (StencilR (sh:.Int) row2)
       (StencilR (sh:.Int) row1) (StencilR (sh:.Int) row0)
  stencilR :: StencilR
  (EltR ((sh :. Int) :. Int))
  (EltR a)
  (StencilR ((sh :. Int) :. Int) (row4, row3, row2, row1, row0))
stencilR = StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row4)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row3)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row2)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row1)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row0)
-> StencilR
     ((EltR sh, Int), Int)
     (EltR a)
     (Tup5
        (StencilR (sh :. Int) row4)
        (StencilR (sh :. Int) row3)
        (StencilR (sh :. Int) row2)
        (StencilR (sh :. Int) row1)
        (StencilR (sh :. Int) row0))
forall sh e pat1 pat2 sh pat4 pat5.
StencilR sh e pat1
-> StencilR sh e pat2
-> StencilR sh e sh
-> StencilR sh e pat4
-> StencilR sh e pat5
-> StencilR (sh, Int) e (Tup5 pat1 pat2 sh pat4 pat5)
StencilRtup5 (Stencil (sh :. Int) a row4 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row4)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row4) (Stencil (sh :. Int) a row3 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row3)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row3)
                  (Stencil (sh :. Int) a row2 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row2)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row2) (Stencil (sh :. Int) a row1 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row1)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row1) (Stencil (sh :. Int) a row0 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row0)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row0)
  stencilPrj :: SmartExp
  (StencilR ((sh :. Int) :. Int) (row4, row3, row2, row1, row0))
-> (row4, row3, row2, row1, row0)
stencilPrj SmartExp
  (StencilR ((sh :. Int) :. Int) (row4, row3, row2, row1, row0))
s = (forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row4) -> row4)
-> SmartExp (StencilR (sh :. Int) row4) -> row4
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup5
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row4)
forall t a s3 s2 s1 s0.
SmartExp (((((t, a), s3), s2), s1), s0) -> SmartExp a
prj4 SmartExp
  (Tup5
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR ((sh :. Int) :. Int) (row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row3) -> row3)
-> SmartExp (StencilR (sh :. Int) row3) -> row3
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup5
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row3)
forall t a s2 s1 s0.
SmartExp ((((t, a), s2), s1), s0) -> SmartExp a
prj3 SmartExp
  (Tup5
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR ((sh :. Int) :. Int) (row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row2) -> row2)
-> SmartExp (StencilR (sh :. Int) row2) -> row2
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup5
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row2)
forall t a s1 s0. SmartExp (((t, a), s1), s0) -> SmartExp a
prj2 SmartExp
  (Tup5
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR ((sh :. Int) :. Int) (row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row1) -> row1)
-> SmartExp (StencilR (sh :. Int) row1) -> row1
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup5
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row1)
forall t a s0. SmartExp ((t, a), s0) -> SmartExp a
prj1 SmartExp
  (Tup5
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR ((sh :. Int) :. Int) (row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row0) -> row0)
-> SmartExp (StencilR (sh :. Int) row0) -> row0
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup5
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row0)
forall t a. SmartExp (t, a) -> SmartExp a
prj0 SmartExp
  (Tup5
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR ((sh :. Int) :. Int) (row4, row3, row2, row1, row0))
s)

instance (Stencil (sh:.Int) a row6,
          Stencil (sh:.Int) a row5,
          Stencil (sh:.Int) a row4,
          Stencil (sh:.Int) a row3,
          Stencil (sh:.Int) a row2,
          Stencil (sh:.Int) a row1,
          Stencil (sh:.Int) a row0)
  => Stencil (sh:.Int:.Int) a (row6, row5, row4, row3, row2, row1, row0) where
  type StencilR (sh:.Int:.Int) (row6, row5, row4, row3, row2, row1, row0)
    = Tup7 (StencilR (sh:.Int) row6) (StencilR (sh:.Int) row5) (StencilR (sh:.Int) row4)
       (StencilR (sh:.Int) row3) (StencilR (sh:.Int) row2) (StencilR (sh:.Int) row1)
       (StencilR (sh:.Int) row0)
  stencilR :: StencilR
  (EltR ((sh :. Int) :. Int))
  (EltR a)
  (StencilR
     ((sh :. Int) :. Int) (row6, row5, row4, row3, row2, row1, row0))
stencilR = StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row6)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row5)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row4)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row3)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row2)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row1)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row0)
-> StencilR
     ((EltR sh, Int), Int)
     (EltR a)
     (Tup7
        (StencilR (sh :. Int) row6)
        (StencilR (sh :. Int) row5)
        (StencilR (sh :. Int) row4)
        (StencilR (sh :. Int) row3)
        (StencilR (sh :. Int) row2)
        (StencilR (sh :. Int) row1)
        (StencilR (sh :. Int) row0))
forall sh e pat1 pat2 pat3 sh pat5 pat6 pat7.
StencilR sh e pat1
-> StencilR sh e pat2
-> StencilR sh e pat3
-> StencilR sh e sh
-> StencilR sh e pat5
-> StencilR sh e pat6
-> StencilR sh e pat7
-> StencilR (sh, Int) e (Tup7 pat1 pat2 pat3 sh pat5 pat6 pat7)
StencilRtup7 (Stencil (sh :. Int) a row6 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row6)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row6)
                  (Stencil (sh :. Int) a row5 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row5)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row5) (Stencil (sh :. Int) a row4 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row4)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row4) (Stencil (sh :. Int) a row3 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row3)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row3)
                  (Stencil (sh :. Int) a row2 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row2)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row2) (Stencil (sh :. Int) a row1 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row1)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row1) (Stencil (sh :. Int) a row0 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row0)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row0)
  stencilPrj :: SmartExp
  (StencilR
     ((sh :. Int) :. Int) (row6, row5, row4, row3, row2, row1, row0))
-> (row6, row5, row4, row3, row2, row1, row0)
stencilPrj SmartExp
  (StencilR
     ((sh :. Int) :. Int) (row6, row5, row4, row3, row2, row1, row0))
s = (forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row6) -> row6)
-> SmartExp (StencilR (sh :. Int) row6) -> row6
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup7
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row6)
forall t a s5 s4 s3 s2 s1 s0.
SmartExp (((((((t, a), s5), s4), s3), s2), s1), s0) -> SmartExp a
prj6 SmartExp
  (Tup7
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR
     ((sh :. Int) :. Int) (row6, row5, row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row5) -> row5)
-> SmartExp (StencilR (sh :. Int) row5) -> row5
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup7
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row5)
forall t a s4 s3 s2 s1 s0.
SmartExp ((((((t, a), s4), s3), s2), s1), s0) -> SmartExp a
prj5 SmartExp
  (Tup7
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR
     ((sh :. Int) :. Int) (row6, row5, row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row4) -> row4)
-> SmartExp (StencilR (sh :. Int) row4) -> row4
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup7
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row4)
forall t a s3 s2 s1 s0.
SmartExp (((((t, a), s3), s2), s1), s0) -> SmartExp a
prj4 SmartExp
  (Tup7
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR
     ((sh :. Int) :. Int) (row6, row5, row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row3) -> row3)
-> SmartExp (StencilR (sh :. Int) row3) -> row3
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup7
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row3)
forall t a s2 s1 s0.
SmartExp ((((t, a), s2), s1), s0) -> SmartExp a
prj3 SmartExp
  (Tup7
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR
     ((sh :. Int) :. Int) (row6, row5, row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row2) -> row2)
-> SmartExp (StencilR (sh :. Int) row2) -> row2
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup7
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row2)
forall t a s1 s0. SmartExp (((t, a), s1), s0) -> SmartExp a
prj2 SmartExp
  (Tup7
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR
     ((sh :. Int) :. Int) (row6, row5, row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row1) -> row1)
-> SmartExp (StencilR (sh :. Int) row1) -> row1
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup7
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row1)
forall t a s0. SmartExp ((t, a), s0) -> SmartExp a
prj1 SmartExp
  (Tup7
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR
     ((sh :. Int) :. Int) (row6, row5, row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row0) -> row0)
-> SmartExp (StencilR (sh :. Int) row0) -> row0
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup7
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row0)
forall t a. SmartExp (t, a) -> SmartExp a
prj0 SmartExp
  (Tup7
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR
     ((sh :. Int) :. Int) (row6, row5, row4, row3, row2, row1, row0))
s)

instance (Stencil (sh:.Int) a row8,
          Stencil (sh:.Int) a row7,
          Stencil (sh:.Int) a row6,
          Stencil (sh:.Int) a row5,
          Stencil (sh:.Int) a row4,
          Stencil (sh:.Int) a row3,
          Stencil (sh:.Int) a row2,
          Stencil (sh:.Int) a row1,
          Stencil (sh:.Int) a row0)
  => Stencil (sh:.Int:.Int) a (row8, row7, row6, row5, row4, row3, row2, row1, row0) where
  type StencilR (sh:.Int:.Int) (row8, row7, row6, row5, row4, row3, row2, row1, row0)
    = Tup9 (StencilR (sh:.Int) row8) (StencilR (sh:.Int) row7) (StencilR (sh:.Int) row6)
       (StencilR (sh:.Int) row5) (StencilR (sh:.Int) row4) (StencilR (sh:.Int) row3)
       (StencilR (sh:.Int) row2) (StencilR (sh:.Int) row1) (StencilR (sh:.Int) row0)
  stencilR :: StencilR
  (EltR ((sh :. Int) :. Int))
  (EltR a)
  (StencilR
     ((sh :. Int) :. Int)
     (row8, row7, row6, row5, row4, row3, row2, row1, row0))
stencilR = StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row8)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row7)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row6)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row5)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row4)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row3)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row2)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row1)
-> StencilR (EltR sh, Int) (EltR a) (StencilR (sh :. Int) row0)
-> StencilR
     ((EltR sh, Int), Int)
     (EltR a)
     (Tup9
        (StencilR (sh :. Int) row8)
        (StencilR (sh :. Int) row7)
        (StencilR (sh :. Int) row6)
        (StencilR (sh :. Int) row5)
        (StencilR (sh :. Int) row4)
        (StencilR (sh :. Int) row3)
        (StencilR (sh :. Int) row2)
        (StencilR (sh :. Int) row1)
        (StencilR (sh :. Int) row0))
forall sh e pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9.
StencilR sh e pat1
-> StencilR sh e pat2
-> StencilR sh e pat3
-> StencilR sh e pat4
-> StencilR sh e pat5
-> StencilR sh e pat6
-> StencilR sh e pat7
-> StencilR sh e pat8
-> StencilR sh e pat9
-> StencilR
     (sh, Int) e (Tup9 pat1 pat2 pat3 pat4 pat5 pat6 pat7 pat8 pat9)
StencilRtup9
                  (Stencil (sh :. Int) a row8 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row8)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row8) (Stencil (sh :. Int) a row7 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row7)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row7) (Stencil (sh :. Int) a row6 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row6)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row6)
                  (Stencil (sh :. Int) a row5 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row5)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row5) (Stencil (sh :. Int) a row4 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row4)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row4) (Stencil (sh :. Int) a row3 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row3)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row3)
                  (Stencil (sh :. Int) a row2 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row2)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row2) (Stencil (sh :. Int) a row1 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row1)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row1) (Stencil (sh :. Int) a row0 =>
StencilR (EltR (sh :. Int)) (EltR a) (StencilR (sh :. Int) row0)
forall sh e stencil.
Stencil sh e stencil =>
StencilR (EltR sh) (EltR e) (StencilR sh stencil)
stencilR @(sh:.Int) @a @row0)
  stencilPrj :: SmartExp
  (StencilR
     ((sh :. Int) :. Int)
     (row8, row7, row6, row5, row4, row3, row2, row1, row0))
-> (row8, row7, row6, row5, row4, row3, row2, row1, row0)
stencilPrj SmartExp
  (StencilR
     ((sh :. Int) :. Int)
     (row8, row7, row6, row5, row4, row3, row2, row1, row0))
s = (forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row8) -> row8)
-> SmartExp (StencilR (sh :. Int) row8) -> row8
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row8)
forall t a s7 s6 s5 s4 s3 s2 s1 s0.
SmartExp (((((((((t, a), s7), s6), s5), s4), s3), s2), s1), s0)
-> SmartExp a
prj8 SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR
     ((sh :. Int) :. Int)
     (row8, row7, row6, row5, row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row7) -> row7)
-> SmartExp (StencilR (sh :. Int) row7) -> row7
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row7)
forall t a s6 s5 s4 s3 s2 s1 s0.
SmartExp ((((((((t, a), s6), s5), s4), s3), s2), s1), s0)
-> SmartExp a
prj7 SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR
     ((sh :. Int) :. Int)
     (row8, row7, row6, row5, row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row6) -> row6)
-> SmartExp (StencilR (sh :. Int) row6) -> row6
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row6)
forall t a s5 s4 s3 s2 s1 s0.
SmartExp (((((((t, a), s5), s4), s3), s2), s1), s0) -> SmartExp a
prj6 SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR
     ((sh :. Int) :. Int)
     (row8, row7, row6, row5, row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row5) -> row5)
-> SmartExp (StencilR (sh :. Int) row5) -> row5
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row5)
forall t a s4 s3 s2 s1 s0.
SmartExp ((((((t, a), s4), s3), s2), s1), s0) -> SmartExp a
prj5 SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR
     ((sh :. Int) :. Int)
     (row8, row7, row6, row5, row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row4) -> row4)
-> SmartExp (StencilR (sh :. Int) row4) -> row4
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row4)
forall t a s3 s2 s1 s0.
SmartExp (((((t, a), s3), s2), s1), s0) -> SmartExp a
prj4 SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR
     ((sh :. Int) :. Int)
     (row8, row7, row6, row5, row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row3) -> row3)
-> SmartExp (StencilR (sh :. Int) row3) -> row3
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row3)
forall t a s2 s1 s0.
SmartExp ((((t, a), s2), s1), s0) -> SmartExp a
prj3 SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR
     ((sh :. Int) :. Int)
     (row8, row7, row6, row5, row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row2) -> row2)
-> SmartExp (StencilR (sh :. Int) row2) -> row2
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row2)
forall t a s1 s0. SmartExp (((t, a), s1), s0) -> SmartExp a
prj2 SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR
     ((sh :. Int) :. Int)
     (row8, row7, row6, row5, row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row1) -> row1)
-> SmartExp (StencilR (sh :. Int) row1) -> row1
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row1)
forall t a s0. SmartExp ((t, a), s0) -> SmartExp a
prj1 SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR
     ((sh :. Int) :. Int)
     (row8, row7, row6, row5, row4, row3, row2, row1, row0))
s,
                  forall stencil.
Stencil (sh :. Int) a stencil =>
SmartExp (StencilR (sh :. Int) stencil) -> stencil
forall sh e stencil.
Stencil sh e stencil =>
SmartExp (StencilR sh stencil) -> stencil
stencilPrj @(sh:.Int) @a (SmartExp (StencilR (sh :. Int) row0) -> row0)
-> SmartExp (StencilR (sh :. Int) row0) -> row0
forall a b. (a -> b) -> a -> b
$ SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
-> SmartExp (StencilR (sh :. Int) row0)
forall t a. SmartExp (t, a) -> SmartExp a
prj0 SmartExp
  (Tup9
     (StencilR (sh :. Int) row8)
     (StencilR (sh :. Int) row7)
     (StencilR (sh :. Int) row6)
     (StencilR (sh :. Int) row5)
     (StencilR (sh :. Int) row4)
     (StencilR (sh :. Int) row3)
     (StencilR (sh :. Int) row2)
     (StencilR (sh :. Int) row1)
     (StencilR (sh :. Int) row0))
SmartExp
  (StencilR
     ((sh :. Int) :. Int)
     (row8, row7, row6, row5, row4, row3, row2, row1, row0))
s)

prjTail :: SmartExp (t, a) -> SmartExp t
prjTail :: SmartExp (t, a) -> SmartExp t
prjTail = PreSmartExp SmartAcc SmartExp t -> SmartExp t
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp t -> SmartExp t)
-> (SmartExp (t, a) -> PreSmartExp SmartAcc SmartExp t)
-> SmartExp (t, a)
-> SmartExp t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairIdx (t, a) t
-> SmartExp (t, a) -> PreSmartExp SmartAcc SmartExp t
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (t, a) t
forall a b. PairIdx (a, b) a
PairIdxLeft

prj0 :: SmartExp (t, a) -> SmartExp a
prj0 :: SmartExp (t, a) -> SmartExp a
prj0 = PreSmartExp SmartAcc SmartExp a -> SmartExp a
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp a -> SmartExp a)
-> (SmartExp (t, a) -> PreSmartExp SmartAcc SmartExp a)
-> SmartExp (t, a)
-> SmartExp a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairIdx (t, a) a
-> SmartExp (t, a) -> PreSmartExp SmartAcc SmartExp a
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (t, a) a
forall a b. PairIdx (a, b) b
PairIdxRight

prj1 :: SmartExp ((t, a), s0) -> SmartExp a
prj1 :: SmartExp ((t, a), s0) -> SmartExp a
prj1 = SmartExp (t, a) -> SmartExp a
forall t a. SmartExp (t, a) -> SmartExp a
prj0 (SmartExp (t, a) -> SmartExp a)
-> (SmartExp ((t, a), s0) -> SmartExp (t, a))
-> SmartExp ((t, a), s0)
-> SmartExp a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SmartExp ((t, a), s0) -> SmartExp (t, a)
forall t a. SmartExp (t, a) -> SmartExp t
prjTail

prj2 :: SmartExp (((t, a), s1), s0) -> SmartExp a
prj2 :: SmartExp (((t, a), s1), s0) -> SmartExp a
prj2 = SmartExp ((t, a), s1) -> SmartExp a
forall t a s0. SmartExp ((t, a), s0) -> SmartExp a
prj1 (SmartExp ((t, a), s1) -> SmartExp a)
-> (SmartExp (((t, a), s1), s0) -> SmartExp ((t, a), s1))
-> SmartExp (((t, a), s1), s0)
-> SmartExp a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SmartExp (((t, a), s1), s0) -> SmartExp ((t, a), s1)
forall t a. SmartExp (t, a) -> SmartExp t
prjTail

prj3 :: SmartExp ((((t, a), s2), s1), s0) -> SmartExp a
prj3 :: SmartExp ((((t, a), s2), s1), s0) -> SmartExp a
prj3 = SmartExp (((t, a), s2), s1) -> SmartExp a
forall t a s1 s0. SmartExp (((t, a), s1), s0) -> SmartExp a
prj2 (SmartExp (((t, a), s2), s1) -> SmartExp a)
-> (SmartExp ((((t, a), s2), s1), s0)
    -> SmartExp (((t, a), s2), s1))
-> SmartExp ((((t, a), s2), s1), s0)
-> SmartExp a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SmartExp ((((t, a), s2), s1), s0) -> SmartExp (((t, a), s2), s1)
forall t a. SmartExp (t, a) -> SmartExp t
prjTail

prj4 :: SmartExp (((((t, a), s3), s2), s1), s0) -> SmartExp a
prj4 :: SmartExp (((((t, a), s3), s2), s1), s0) -> SmartExp a
prj4 = SmartExp ((((t, a), s3), s2), s1) -> SmartExp a
forall t a s2 s1 s0.
SmartExp ((((t, a), s2), s1), s0) -> SmartExp a
prj3 (SmartExp ((((t, a), s3), s2), s1) -> SmartExp a)
-> (SmartExp (((((t, a), s3), s2), s1), s0)
    -> SmartExp ((((t, a), s3), s2), s1))
-> SmartExp (((((t, a), s3), s2), s1), s0)
-> SmartExp a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SmartExp (((((t, a), s3), s2), s1), s0)
-> SmartExp ((((t, a), s3), s2), s1)
forall t a. SmartExp (t, a) -> SmartExp t
prjTail

prj5 :: SmartExp ((((((t, a), s4), s3), s2), s1), s0) -> SmartExp a
prj5 :: SmartExp ((((((t, a), s4), s3), s2), s1), s0) -> SmartExp a
prj5 = SmartExp (((((t, a), s4), s3), s2), s1) -> SmartExp a
forall t a s3 s2 s1 s0.
SmartExp (((((t, a), s3), s2), s1), s0) -> SmartExp a
prj4 (SmartExp (((((t, a), s4), s3), s2), s1) -> SmartExp a)
-> (SmartExp ((((((t, a), s4), s3), s2), s1), s0)
    -> SmartExp (((((t, a), s4), s3), s2), s1))
-> SmartExp ((((((t, a), s4), s3), s2), s1), s0)
-> SmartExp a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SmartExp ((((((t, a), s4), s3), s2), s1), s0)
-> SmartExp (((((t, a), s4), s3), s2), s1)
forall t a. SmartExp (t, a) -> SmartExp t
prjTail

prj6 :: SmartExp (((((((t, a), s5), s4), s3), s2), s1), s0) -> SmartExp a
prj6 :: SmartExp (((((((t, a), s5), s4), s3), s2), s1), s0) -> SmartExp a
prj6 = SmartExp ((((((t, a), s5), s4), s3), s2), s1) -> SmartExp a
forall t a s4 s3 s2 s1 s0.
SmartExp ((((((t, a), s4), s3), s2), s1), s0) -> SmartExp a
prj5 (SmartExp ((((((t, a), s5), s4), s3), s2), s1) -> SmartExp a)
-> (SmartExp (((((((t, a), s5), s4), s3), s2), s1), s0)
    -> SmartExp ((((((t, a), s5), s4), s3), s2), s1))
-> SmartExp (((((((t, a), s5), s4), s3), s2), s1), s0)
-> SmartExp a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SmartExp (((((((t, a), s5), s4), s3), s2), s1), s0)
-> SmartExp ((((((t, a), s5), s4), s3), s2), s1)
forall t a. SmartExp (t, a) -> SmartExp t
prjTail

prj7 :: SmartExp ((((((((t, a), s6), s5), s4), s3), s2), s1), s0) -> SmartExp a
prj7 :: SmartExp ((((((((t, a), s6), s5), s4), s3), s2), s1), s0)
-> SmartExp a
prj7 = SmartExp (((((((t, a), s6), s5), s4), s3), s2), s1) -> SmartExp a
forall t a s5 s4 s3 s2 s1 s0.
SmartExp (((((((t, a), s5), s4), s3), s2), s1), s0) -> SmartExp a
prj6 (SmartExp (((((((t, a), s6), s5), s4), s3), s2), s1) -> SmartExp a)
-> (SmartExp ((((((((t, a), s6), s5), s4), s3), s2), s1), s0)
    -> SmartExp (((((((t, a), s6), s5), s4), s3), s2), s1))
-> SmartExp ((((((((t, a), s6), s5), s4), s3), s2), s1), s0)
-> SmartExp a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SmartExp ((((((((t, a), s6), s5), s4), s3), s2), s1), s0)
-> SmartExp (((((((t, a), s6), s5), s4), s3), s2), s1)
forall t a. SmartExp (t, a) -> SmartExp t
prjTail

prj8 :: SmartExp (((((((((t, a), s7), s6), s5), s4), s3), s2), s1), s0) -> SmartExp a
prj8 :: SmartExp (((((((((t, a), s7), s6), s5), s4), s3), s2), s1), s0)
-> SmartExp a
prj8 = SmartExp ((((((((t, a), s7), s6), s5), s4), s3), s2), s1)
-> SmartExp a
forall t a s6 s5 s4 s3 s2 s1 s0.
SmartExp ((((((((t, a), s6), s5), s4), s3), s2), s1), s0)
-> SmartExp a
prj7 (SmartExp ((((((((t, a), s7), s6), s5), s4), s3), s2), s1)
 -> SmartExp a)
-> (SmartExp (((((((((t, a), s7), s6), s5), s4), s3), s2), s1), s0)
    -> SmartExp ((((((((t, a), s7), s6), s5), s4), s3), s2), s1))
-> SmartExp (((((((((t, a), s7), s6), s5), s4), s3), s2), s1), s0)
-> SmartExp a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SmartExp (((((((((t, a), s7), s6), s5), s4), s3), s2), s1), s0)
-> SmartExp ((((((((t, a), s7), s6), s5), s4), s3), s2), s1)
forall t a. SmartExp (t, a) -> SmartExp t
prjTail


-- Extracting type information
-- ---------------------------

class HasArraysR f where
  arraysR :: f a -> ArraysR a

instance HasArraysR SmartAcc where
  arraysR :: SmartAcc a -> ArraysR a
arraysR (SmartAcc PreSmartAcc SmartAcc SmartExp a
e) = PreSmartAcc SmartAcc SmartExp a -> ArraysR a
forall (f :: * -> *) a. HasArraysR f => f a -> ArraysR a
arraysR PreSmartAcc SmartAcc SmartExp a
e

arrayR :: HasArraysR f => f (Array sh e) -> ArrayR (Array sh e)
arrayR :: f (Array sh e) -> ArrayR (Array sh e)
arrayR f (Array sh e)
acc = case f (Array sh e) -> ArraysR (Array sh e)
forall (f :: * -> *) a. HasArraysR f => f a -> ArraysR a
arraysR f (Array sh e)
acc of
  TupRsingle ArrayR (Array sh e)
repr -> ArrayR (Array sh e)
repr

instance HasArraysR acc => HasArraysR (PreSmartAcc acc exp) where
  arraysR :: PreSmartAcc acc exp a -> ArraysR a
arraysR = \case
    Atag ArraysR a
repr Int
_               -> ArraysR a
repr
    Pipe ArraysR as
_ ArraysR bs
_ ArraysR a
repr  SmartAcc as -> acc bs
_ SmartAcc bs -> acc a
_ acc as
_      -> ArraysR a
repr
    Aforeign ArraysR a
repr asm (as -> a)
_ SmartAcc as -> SmartAcc a
_ acc as
_       -> ArraysR a
repr
    Acond exp PrimBool
_ acc a
a acc a
_               -> acc a -> ArraysR a
forall (f :: * -> *) a. HasArraysR f => f a -> ArraysR a
arraysR acc a
a
    Awhile ArraysR a
_ SmartAcc a -> acc (Scalar PrimBool)
_ SmartAcc a -> acc a
_ acc a
a            -> acc a -> ArraysR a
forall (f :: * -> *) a. HasArraysR f => f a -> ArraysR a
arraysR acc a
a
    PreSmartAcc acc exp a
Anil                      -> ArraysR a
forall (s :: * -> *). TupR s ()
TupRunit
    Apair acc arrs1
a1 acc arrs2
a2               -> acc arrs1 -> ArraysR arrs1
forall (f :: * -> *) a. HasArraysR f => f a -> ArraysR a
arraysR acc arrs1
a1 ArraysR arrs1 -> TupR ArrayR arrs2 -> TupR ArrayR (arrs1, arrs2)
forall (s :: * -> *) a b. TupR s a -> TupR s b -> TupR s (a, b)
`TupRpair` acc arrs2 -> TupR ArrayR arrs2
forall (f :: * -> *) a. HasArraysR f => f a -> ArraysR a
arraysR acc arrs2
a2
    Aprj PairIdx (arrs1, arrs2) a
idx acc (arrs1, arrs2)
a | TupRpair TupR ArrayR a
t1 TupR ArrayR b
t2 <- acc (arrs1, arrs2) -> TupR ArrayR (arrs1, arrs2)
forall (f :: * -> *) a. HasArraysR f => f a -> ArraysR a
arraysR acc (arrs1, arrs2)
a
                              -> case PairIdx (arrs1, arrs2) a
idx of
                                   PairIdx (arrs1, arrs2) a
PairIdxLeft  -> ArraysR a
TupR ArrayR a
t1
                                   PairIdx (arrs1, arrs2) a
PairIdxRight -> ArraysR a
TupR ArrayR b
t2
    Aprj PairIdx (arrs1, arrs2) a
_ acc (arrs1, arrs2)
_                  -> [Char] -> ArraysR a
forall a. HasCallStack => [Char] -> a
error [Char]
"Ejector seat? You're joking!"
    Use ArrayR (Array sh e)
repr Array sh e
_                -> ArrayR (Array sh e) -> TupR ArrayR (Array sh e)
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle ArrayR (Array sh e)
repr
    Unit TypeR e
tp exp e
_                 -> ArrayR (Array () e) -> TupR ArrayR (Array () e)
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ArrayR (Array () e) -> TupR ArrayR (Array () e))
-> ArrayR (Array () e) -> TupR ArrayR (Array () e)
forall a b. (a -> b) -> a -> b
$ ShapeR () -> TypeR e -> ArrayR (Array () e)
forall sh e. ShapeR sh -> TypeR e -> ArrayR (Array sh e)
ArrayR ShapeR ()
ShapeRz (TypeR e -> ArrayR (Array () e)) -> TypeR e -> ArrayR (Array () e)
forall a b. (a -> b) -> a -> b
$ TypeR e
tp
    Generate ArrayR (Array sh e)
repr exp sh
_ SmartExp sh -> exp e
_         -> ArrayR (Array sh e) -> TupR ArrayR (Array sh e)
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle ArrayR (Array sh e)
repr
    Reshape ShapeR sh
shr exp sh
_ acc (Array sh' e)
a           -> let ArrayR ShapeR sh
_ TypeR e
tp = acc (Array sh' e) -> ArrayR (Array sh' e)
forall (f :: * -> *) sh e.
HasArraysR f =>
f (Array sh e) -> ArrayR (Array sh e)
arrayR acc (Array sh' e)
a
                                 in  ArrayR (Array sh e) -> TupR ArrayR (Array sh e)
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ArrayR (Array sh e) -> TupR ArrayR (Array sh e))
-> ArrayR (Array sh e) -> TupR ArrayR (Array sh e)
forall a b. (a -> b) -> a -> b
$ ShapeR sh -> TypeR e -> ArrayR (Array sh e)
forall sh e. ShapeR sh -> TypeR e -> ArrayR (Array sh e)
ArrayR ShapeR sh
shr TypeR e
tp
    Replicate SliceIndex slix sl co sh
si exp slix
_ acc (Array sl e)
a          -> let ArrayR ShapeR sh
_ TypeR e
tp = acc (Array sl e) -> ArrayR (Array sl e)
forall (f :: * -> *) sh e.
HasArraysR f =>
f (Array sh e) -> ArrayR (Array sh e)
arrayR acc (Array sl e)
a
                                 in  ArrayR (Array sh e) -> TupR ArrayR (Array sh e)
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ArrayR (Array sh e) -> TupR ArrayR (Array sh e))
-> ArrayR (Array sh e) -> TupR ArrayR (Array sh e)
forall a b. (a -> b) -> a -> b
$ ShapeR sh -> TypeR e -> ArrayR (Array sh e)
forall sh e. ShapeR sh -> TypeR e -> ArrayR (Array sh e)
ArrayR (SliceIndex slix sl co sh -> ShapeR sh
forall slix sl co dim. SliceIndex slix sl co dim -> ShapeR dim
sliceDomainR SliceIndex slix sl co sh
si) TypeR e
tp
    Slice SliceIndex slix sl co sh
si acc (Array sh e)
a exp slix
_              -> let ArrayR ShapeR sh
_ TypeR e
tp = acc (Array sh e) -> ArrayR (Array sh e)
forall (f :: * -> *) sh e.
HasArraysR f =>
f (Array sh e) -> ArrayR (Array sh e)
arrayR acc (Array sh e)
a
                                 in  ArrayR (Array sl e) -> TupR ArrayR (Array sl e)
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ArrayR (Array sl e) -> TupR ArrayR (Array sl e))
-> ArrayR (Array sl e) -> TupR ArrayR (Array sl e)
forall a b. (a -> b) -> a -> b
$ ShapeR sl -> TypeR e -> ArrayR (Array sl e)
forall sh e. ShapeR sh -> TypeR e -> ArrayR (Array sh e)
ArrayR (SliceIndex slix sl co sh -> ShapeR sl
forall slix sl co dim. SliceIndex slix sl co dim -> ShapeR sl
sliceShapeR SliceIndex slix sl co sh
si) TypeR e
tp
    Map TypeR e
_ TypeR e'
tp SmartExp e -> exp e'
_ acc (Array sh e)
a              -> let ArrayR ShapeR sh
shr TypeR e
_ = acc (Array sh e) -> ArrayR (Array sh e)
forall (f :: * -> *) sh e.
HasArraysR f =>
f (Array sh e) -> ArrayR (Array sh e)
arrayR acc (Array sh e)
a
                                 in  ArrayR (Array sh e') -> TupR ArrayR (Array sh e')
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ArrayR (Array sh e') -> TupR ArrayR (Array sh e'))
-> ArrayR (Array sh e') -> TupR ArrayR (Array sh e')
forall a b. (a -> b) -> a -> b
$ ShapeR sh -> TypeR e' -> ArrayR (Array sh e')
forall sh e. ShapeR sh -> TypeR e -> ArrayR (Array sh e)
ArrayR ShapeR sh
shr TypeR e'
tp
    ZipWith TypeR e1
_ TypeR e2
_ TypeR e3
tp SmartExp e1 -> SmartExp e2 -> exp e3
_ acc (Array sh e1)
a acc (Array sh e2)
_      -> let ArrayR ShapeR sh
shr TypeR e
_ = acc (Array sh e1) -> ArrayR (Array sh e1)
forall (f :: * -> *) sh e.
HasArraysR f =>
f (Array sh e) -> ArrayR (Array sh e)
arrayR acc (Array sh e1)
a
                                 in  ArrayR (Array sh e3) -> TupR ArrayR (Array sh e3)
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ArrayR (Array sh e3) -> TupR ArrayR (Array sh e3))
-> ArrayR (Array sh e3) -> TupR ArrayR (Array sh e3)
forall a b. (a -> b) -> a -> b
$ ShapeR sh -> TypeR e3 -> ArrayR (Array sh e3)
forall sh e. ShapeR sh -> TypeR e -> ArrayR (Array sh e)
ArrayR ShapeR sh
shr TypeR e3
tp
    Fold TypeR e
_ SmartExp e -> SmartExp e -> exp e
_ Maybe (exp e)
_ acc (Array (sh, Int) e)
a              -> let ArrayR (ShapeRsnoc ShapeR sh
shr) TypeR e
tp = acc (Array (sh, Int) e) -> ArrayR (Array (sh, Int) e)
forall (f :: * -> *) sh e.
HasArraysR f =>
f (Array sh e) -> ArrayR (Array sh e)
arrayR acc (Array (sh, Int) e)
a
                                 in  ArrayR (Array sh e) -> TupR ArrayR (Array sh e)
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ShapeR sh -> TypeR e -> ArrayR (Array sh e)
forall sh e. ShapeR sh -> TypeR e -> ArrayR (Array sh e)
ArrayR ShapeR sh
shr TypeR e
tp)
    FoldSeg IntegralType i
_ TypeR e
_ SmartExp e -> SmartExp e -> exp e
_ Maybe (exp e)
_ acc (Array (sh, Int) e)
a acc (Segments i)
_       -> acc (Array (sh, Int) e) -> ArraysR (Array (sh, Int) e)
forall (f :: * -> *) a. HasArraysR f => f a -> ArraysR a
arraysR acc (Array (sh, Int) e)
a
    Scan Direction
_ TypeR e
_ SmartExp e -> SmartExp e -> exp e
_ Maybe (exp e)
_ acc (Array (sh, Int) e)
a            -> acc (Array (sh, Int) e) -> ArraysR (Array (sh, Int) e)
forall (f :: * -> *) a. HasArraysR f => f a -> ArraysR a
arraysR acc (Array (sh, Int) e)
a
    Scan' Direction
_ TypeR e
_ SmartExp e -> SmartExp e -> exp e
_ exp e
_ acc (Array (sh, Int) e)
a           -> let repr :: ArrayR (Array (sh, Int) e)
repr@(ArrayR (ShapeRsnoc ShapeR sh
shr) TypeR e
tp) = acc (Array (sh, Int) e) -> ArrayR (Array (sh, Int) e)
forall (f :: * -> *) sh e.
HasArraysR f =>
f (Array sh e) -> ArrayR (Array sh e)
arrayR acc (Array (sh, Int) e)
a
                                 in  ArrayR (Array (sh, Int) e) -> TupR ArrayR (Array (sh, Int) e)
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle ArrayR (Array (sh, Int) e)
repr TupR ArrayR (Array (sh, Int) e)
-> TupR ArrayR (Array sh e)
-> TupR ArrayR (Array (sh, Int) e, Array sh e)
forall (s :: * -> *) a b. TupR s a -> TupR s b -> TupR s (a, b)
`TupRpair` ArrayR (Array sh e) -> TupR ArrayR (Array sh e)
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ShapeR sh -> TypeR e -> ArrayR (Array sh e)
forall sh e. ShapeR sh -> TypeR e -> ArrayR (Array sh e)
ArrayR ShapeR sh
shr TypeR e
tp)
    Permute ArrayR (Array sh e)
_ SmartExp e -> SmartExp e -> exp e
_ acc (Array sh' e)
a SmartExp sh -> exp (PrimMaybe sh')
_ acc (Array sh e)
_         -> acc (Array sh' e) -> ArraysR (Array sh' e)
forall (f :: * -> *) a. HasArraysR f => f a -> ArraysR a
arraysR acc (Array sh' e)
a
    Backpermute ShapeR sh'
shr exp sh'
_ SmartExp sh' -> exp sh
_ acc (Array sh e)
a     -> let ArrayR ShapeR sh
_ TypeR e
tp = acc (Array sh e) -> ArrayR (Array sh e)
forall (f :: * -> *) sh e.
HasArraysR f =>
f (Array sh e) -> ArrayR (Array sh e)
arrayR acc (Array sh e)
a
                                 in  ArrayR (Array sh' e) -> TupR ArrayR (Array sh' e)
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ShapeR sh' -> TypeR e -> ArrayR (Array sh' e)
forall sh e. ShapeR sh -> TypeR e -> ArrayR (Array sh e)
ArrayR ShapeR sh'
shr TypeR e
tp)
    Stencil StencilR sh a stencil
s TypeR b
tp SmartExp stencil -> exp b
_ PreBoundary acc exp (Array sh a)
_ acc (Array sh a)
_        -> ArrayR (Array sh b) -> TupR ArrayR (Array sh b)
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ArrayR (Array sh b) -> TupR ArrayR (Array sh b))
-> ArrayR (Array sh b) -> TupR ArrayR (Array sh b)
forall a b. (a -> b) -> a -> b
$ ShapeR sh -> TypeR b -> ArrayR (Array sh b)
forall sh e. ShapeR sh -> TypeR e -> ArrayR (Array sh e)
ArrayR (StencilR sh a stencil -> ShapeR sh
forall sh e pat. StencilR sh e pat -> ShapeR sh
stencilShapeR StencilR sh a stencil
s) TypeR b
tp
    Stencil2 StencilR sh a stencil1
s StencilR sh b stencil2
_ TypeR c
tp SmartExp stencil1 -> SmartExp stencil2 -> exp c
_ PreBoundary acc exp (Array sh a)
_ acc (Array sh a)
_ PreBoundary acc exp (Array sh b)
_ acc (Array sh b)
_ -> ArrayR (Array sh c) -> TupR ArrayR (Array sh c)
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ArrayR (Array sh c) -> TupR ArrayR (Array sh c))
-> ArrayR (Array sh c) -> TupR ArrayR (Array sh c)
forall a b. (a -> b) -> a -> b
$ ShapeR sh -> TypeR c -> ArrayR (Array sh c)
forall sh e. ShapeR sh -> TypeR e -> ArrayR (Array sh e)
ArrayR (StencilR sh a stencil1 -> ShapeR sh
forall sh e pat. StencilR sh e pat -> ShapeR sh
stencilShapeR StencilR sh a stencil1
s) TypeR c
tp


class HasTypeR f where
  typeR :: HasCallStack => f t -> TypeR t

instance HasTypeR SmartExp where
  typeR :: SmartExp t -> TypeR t
typeR (SmartExp PreSmartExp SmartAcc SmartExp t
e) = PreSmartExp SmartAcc SmartExp t -> TypeR t
forall (f :: * -> *) t.
(HasTypeR f, HasCallStack) =>
f t -> TypeR t
typeR PreSmartExp SmartAcc SmartExp t
e

instance HasTypeR exp => HasTypeR (PreSmartExp acc exp) where
  typeR :: PreSmartExp acc exp t -> TypeR t
typeR = \case
    Tag TypeR t
tp Int
_                        -> TypeR t
tp
    Match TagR t
_ exp t
e                       -> exp t -> TypeR t
forall (f :: * -> *) t.
(HasTypeR f, HasCallStack) =>
f t -> TypeR t
typeR exp t
e
    Const ScalarType t
tp t
_                      -> ScalarType t -> TypeR t
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle ScalarType t
tp
    PreSmartExp acc exp t
Nil                             -> TypeR t
forall (s :: * -> *). TupR s ()
TupRunit
    Pair exp t1
e1 exp t2
e2                      -> exp t1 -> TypeR t1
forall (f :: * -> *) t.
(HasTypeR f, HasCallStack) =>
f t -> TypeR t
typeR exp t1
e1 TypeR t1 -> TupR ScalarType t2 -> TupR ScalarType (t1, t2)
forall (s :: * -> *) a b. TupR s a -> TupR s b -> TupR s (a, b)
`TupRpair` exp t2 -> TupR ScalarType t2
forall (f :: * -> *) t.
(HasTypeR f, HasCallStack) =>
f t -> TypeR t
typeR exp t2
e2
    Prj PairIdx (t1, t2) t
idx exp (t1, t2)
e
      | TupRpair TupR ScalarType a
t1 TupR ScalarType b
t2 <- exp (t1, t2) -> TupR ScalarType (t1, t2)
forall (f :: * -> *) t.
(HasTypeR f, HasCallStack) =>
f t -> TypeR t
typeR exp (t1, t2)
e   -> case PairIdx (t1, t2) t
idx of
                                         PairIdx (t1, t2) t
PairIdxLeft  -> TypeR t
TupR ScalarType a
t1
                                         PairIdx (t1, t2) t
PairIdxRight -> TypeR t
TupR ScalarType b
t2
    Prj PairIdx (t1, t2) t
_ exp (t1, t2)
_                         -> [Char] -> TypeR t
forall a. HasCallStack => [Char] -> a
error [Char]
"I never joke about my work"
    VecPack   VecR n s tup
vecR exp tup
_                -> ScalarType (Vec n s) -> TupR ScalarType (Vec n s)
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ScalarType (Vec n s) -> TupR ScalarType (Vec n s))
-> ScalarType (Vec n s) -> TupR ScalarType (Vec n s)
forall a b. (a -> b) -> a -> b
$ VectorType (Vec n s) -> ScalarType (Vec n s)
forall (n :: Nat) a. VectorType (Vec n a) -> ScalarType (Vec n a)
VectorScalarType (VectorType (Vec n s) -> ScalarType (Vec n s))
-> VectorType (Vec n s) -> ScalarType (Vec n s)
forall a b. (a -> b) -> a -> b
$ VecR n s tup -> VectorType (Vec n s)
forall (n :: Nat) s tuple.
KnownNat n =>
VecR n s tuple -> VectorType (Vec n s)
vecRvector VecR n s tup
vecR
    VecUnpack VecR n s t
vecR exp (Vec n s)
_                -> VecR n s t -> TypeR t
forall (n :: Nat) s tuple. VecR n s tuple -> TypeR tuple
vecRtuple VecR n s t
vecR
    ToIndex ShapeR sh
_ exp sh
_ exp sh
_                   -> ScalarType Int -> TupR ScalarType Int
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle ScalarType Int
scalarTypeInt
    FromIndex ShapeR t
shr exp t
_ exp Int
_               -> ShapeR t -> TypeR t
forall sh. ShapeR sh -> TypeR sh
shapeType ShapeR t
shr
    Case exp a
_ ((TagR a
_,exp t
c):[(TagR a, exp t)]
_)                -> exp t -> TypeR t
forall (f :: * -> *) t.
(HasTypeR f, HasCallStack) =>
f t -> TypeR t
typeR exp t
c
    Case{}                          -> [Char] -> TypeR t
forall a. HasCallStack => [Char] -> a
internalError [Char]
"encountered empty case"
    Cond exp PrimBool
_ exp t
e exp t
_                      -> exp t -> TypeR t
forall (f :: * -> *) t.
(HasTypeR f, HasCallStack) =>
f t -> TypeR t
typeR exp t
e
    While TypeR t
t SmartExp t -> exp PrimBool
_ SmartExp t -> exp t
_ exp t
_                   -> TypeR t
t
    PrimConst PrimConst t
c                     -> ScalarType t -> TypeR t
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ScalarType t -> TypeR t) -> ScalarType t -> TypeR t
forall a b. (a -> b) -> a -> b
$ SingleType t -> ScalarType t
forall a. SingleType a -> ScalarType a
SingleScalarType (SingleType t -> ScalarType t) -> SingleType t -> ScalarType t
forall a b. (a -> b) -> a -> b
$ PrimConst t -> SingleType t
forall a. PrimConst a -> SingleType a
primConstType PrimConst t
c
    PrimApp PrimFun (a -> t)
f exp a
_                     -> (TypeR a, TypeR t) -> TypeR t
forall a b. (a, b) -> b
snd ((TypeR a, TypeR t) -> TypeR t) -> (TypeR a, TypeR t) -> TypeR t
forall a b. (a -> b) -> a -> b
$ PrimFun (a -> t) -> (TypeR a, TypeR t)
forall a b. PrimFun (a -> b) -> (TypeR a, TypeR b)
primFunType PrimFun (a -> t)
f
    Index TypeR t
tp acc (Array sh t)
_ exp sh
_                    -> TypeR t
tp
    LinearIndex TypeR t
tp acc (Array sh t)
_ exp Int
_              -> TypeR t
tp
    Shape ShapeR t
shr acc (Array t e)
_                     -> ShapeR t -> TypeR t
forall sh. ShapeR sh -> TypeR sh
shapeType ShapeR t
shr
    ShapeSize ShapeR sh
_ exp sh
_                   -> ScalarType Int -> TupR ScalarType Int
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle ScalarType Int
scalarTypeInt
    Foreign TypeR t
tp asm (x -> t)
_ SmartExp x -> SmartExp t
_ exp x
_                -> TypeR t
tp
    Undef ScalarType t
tp                        -> ScalarType t -> TypeR t
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle ScalarType t
tp
    Coerce ScalarType a
_ ScalarType t
tp exp a
_                   -> ScalarType t -> TypeR t
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle ScalarType t
tp


-- Smart constructors
-- ------------------

-- | Scalar expression inlet: make a Haskell value available for processing in
-- an Accelerate scalar expression.
--
-- Note that this embeds the value directly into the expression. Depending on
-- the backend used to execute the computation, this might not always be
-- desirable. For example, a backend that does external code generation may
-- embed this constant directly into the generated code, which means new code
-- will need to be generated and compiled every time the value changes. In such
-- cases, consider instead lifting scalar values into (singleton) arrays so that
-- they can be passed as an input to the computation and thus the value can
-- change without the need to generate fresh code.
--
constant :: forall e. (HasCallStack, Elt e) => e -> Exp e
constant :: e -> Exp e
constant = SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e)
-> (e -> SmartExp (EltR e)) -> e -> Exp e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeR (EltR e) -> EltR e -> SmartExp (EltR e)
forall t. HasCallStack => TypeR t -> t -> SmartExp t
go (Elt e => TypeR (EltR e)
forall a. Elt a => TypeR (EltR a)
eltR @e) (EltR e -> SmartExp (EltR e))
-> (e -> EltR e) -> e -> SmartExp (EltR e)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> EltR e
forall a. Elt a => a -> EltR a
fromElt
  where
    go :: HasCallStack => TypeR t -> t -> SmartExp t
    go :: TypeR t -> t -> SmartExp t
go TypeR t
TupRunit         ()       = PreSmartExp SmartAcc SmartExp () -> SmartExp ()
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp () -> SmartExp ())
-> PreSmartExp SmartAcc SmartExp () -> SmartExp ()
forall a b. (a -> b) -> a -> b
$ PreSmartExp SmartAcc SmartExp ()
forall (acc :: * -> *) (exp :: * -> *). PreSmartExp acc exp ()
Nil
    go (TupRsingle ScalarType t
tp)  t
c        = PreSmartExp SmartAcc SmartExp t -> SmartExp t
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp t -> SmartExp t)
-> PreSmartExp SmartAcc SmartExp t -> SmartExp t
forall a b. (a -> b) -> a -> b
$ ScalarType t -> t -> PreSmartExp SmartAcc SmartExp t
forall t (acc :: * -> *) (exp :: * -> *).
ScalarType t -> t -> PreSmartExp acc exp t
Const ScalarType t
tp t
c
    go (TupRpair TupR ScalarType a
t1 TupR ScalarType b
t2) (c1, c2) = PreSmartExp SmartAcc SmartExp (a, b) -> SmartExp (a, b)
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp (a, b) -> SmartExp (a, b))
-> PreSmartExp SmartAcc SmartExp (a, b) -> SmartExp (a, b)
forall a b. (a -> b) -> a -> b
$ TupR ScalarType a -> a -> SmartExp a
forall t. HasCallStack => TypeR t -> t -> SmartExp t
go TupR ScalarType a
t1 a
c1 SmartExp a -> SmartExp b -> PreSmartExp SmartAcc SmartExp (a, b)
forall (exp :: * -> *) t1 t2 (acc :: * -> *).
exp t1 -> exp t2 -> PreSmartExp acc exp (t1, t2)
`Pair` TupR ScalarType b -> b -> SmartExp b
forall t. HasCallStack => TypeR t -> t -> SmartExp t
go TupR ScalarType b
t2 b
c2

-- | 'undef' can be used anywhere a constant is expected, and indicates that the
-- consumer of the value can receive an unspecified bit pattern.
--
-- This is useful because a store of an undefined value can be assumed to not
-- have any effect; we can assume that the value is overwritten with bits that
-- happen to match what was already there. However, a store /to/ an undefined
-- location could clobber arbitrary memory, therefore, its use in such a context
-- would introduce undefined /behaviour/.
--
-- There are (at least) two cases where you may want to use this:
--
--   1. The 'Data.Array.Accelerate.Language.permute' function requires an array
--      of default values, into which the new values are combined. However, if
--      you are sure the default values are not used, and will (eventually) be
--      completely overwritten, then 'Data.Array.Accelerate.Prelude.fill'ing an
--      array with this value will give you a new uninitialised array.
--
--   2. In the definition of sum data types. See for example
--      "Data.Array.Accelerate.Data.Maybe" and
--      "Data.Array.Accelerate.Data.Either".
--
-- @since 1.2.0.0
--
undef :: forall e. Elt e => Exp e
undef :: Exp e
undef = SmartExp (EltR e) -> Exp e
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR e) -> Exp e) -> SmartExp (EltR e) -> Exp e
forall a b. (a -> b) -> a -> b
$ TypeR (EltR e) -> SmartExp (EltR e)
forall t. TypeR t -> SmartExp t
go (TypeR (EltR e) -> SmartExp (EltR e))
-> TypeR (EltR e) -> SmartExp (EltR e)
forall a b. (a -> b) -> a -> b
$ Elt e => TypeR (EltR e)
forall a. Elt a => TypeR (EltR a)
eltR @e
  where
    go :: TypeR t -> SmartExp t
    go :: TypeR t -> SmartExp t
go TypeR t
TupRunit         = PreSmartExp SmartAcc SmartExp () -> SmartExp ()
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp () -> SmartExp ())
-> PreSmartExp SmartAcc SmartExp () -> SmartExp ()
forall a b. (a -> b) -> a -> b
$ PreSmartExp SmartAcc SmartExp ()
forall (acc :: * -> *) (exp :: * -> *). PreSmartExp acc exp ()
Nil
    go (TupRsingle ScalarType t
t)   = PreSmartExp SmartAcc SmartExp t -> SmartExp t
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp t -> SmartExp t)
-> PreSmartExp SmartAcc SmartExp t -> SmartExp t
forall a b. (a -> b) -> a -> b
$ ScalarType t -> PreSmartExp SmartAcc SmartExp t
forall t (acc :: * -> *) (exp :: * -> *).
ScalarType t -> PreSmartExp acc exp t
Undef ScalarType t
t
    go (TupRpair TupR ScalarType a
t1 TupR ScalarType b
t2) = PreSmartExp SmartAcc SmartExp (a, b) -> SmartExp (a, b)
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp (a, b) -> SmartExp (a, b))
-> PreSmartExp SmartAcc SmartExp (a, b) -> SmartExp (a, b)
forall a b. (a -> b) -> a -> b
$ TupR ScalarType a -> SmartExp a
forall t. TypeR t -> SmartExp t
go TupR ScalarType a
t1 SmartExp a -> SmartExp b -> PreSmartExp SmartAcc SmartExp (a, b)
forall (exp :: * -> *) t1 t2 (acc :: * -> *).
exp t1 -> exp t2 -> PreSmartExp acc exp (t1, t2)
`Pair` TupR ScalarType b -> SmartExp b
forall t. TypeR t -> SmartExp t
go TupR ScalarType b
t2

-- | Get the innermost dimension of a shape.
--
-- The innermost dimension (right-most component of the shape) is the index of
-- the array which varies most rapidly, and corresponds to elements of the array
-- which are adjacent in memory.
--
-- Another way to think of this is, for example when writing nested loops over
-- an array in C, this index corresponds to the index iterated over by the
-- innermost nested loop.
--
indexHead :: (Elt sh, Elt a) => Exp (sh :. a) -> Exp a
indexHead :: Exp (sh :. a) -> Exp a
indexHead (Exp SmartExp (EltR (sh :. a))
x) = PreSmartExp SmartAcc SmartExp (EltR a) -> Exp a
forall t. PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp (PreSmartExp SmartAcc SmartExp (EltR a) -> Exp a)
-> PreSmartExp SmartAcc SmartExp (EltR a) -> Exp a
forall a b. (a -> b) -> a -> b
$ PairIdx (EltR sh, EltR a) (EltR a)
-> SmartExp (EltR sh, EltR a)
-> PreSmartExp SmartAcc SmartExp (EltR a)
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (EltR sh, EltR a) (EltR a)
forall a b. PairIdx (a, b) b
PairIdxRight SmartExp (EltR sh, EltR a)
SmartExp (EltR (sh :. a))
x

-- | Get all but the innermost element of a shape
--
indexTail :: (Elt sh, Elt a) => Exp (sh :. a) -> Exp sh
indexTail :: Exp (sh :. a) -> Exp sh
indexTail (Exp SmartExp (EltR (sh :. a))
x) = PreSmartExp SmartAcc SmartExp (EltR sh) -> Exp sh
forall t. PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp (PreSmartExp SmartAcc SmartExp (EltR sh) -> Exp sh)
-> PreSmartExp SmartAcc SmartExp (EltR sh) -> Exp sh
forall a b. (a -> b) -> a -> b
$ PairIdx (EltR sh, EltR a) (EltR sh)
-> SmartExp (EltR sh, EltR a)
-> PreSmartExp SmartAcc SmartExp (EltR sh)
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (EltR sh, EltR a) (EltR sh)
forall a b. PairIdx (a, b) a
PairIdxLeft SmartExp (EltR sh, EltR a)
SmartExp (EltR (sh :. a))
x


-- Smart constructor for constants
--

mkMinBound :: (Elt t, IsBounded (EltR t)) => Exp t
mkMinBound :: Exp t
mkMinBound = PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
forall t. PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp (PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t)
-> PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
forall a b. (a -> b) -> a -> b
$ PrimConst (EltR t) -> PreSmartExp SmartAcc SmartExp (EltR t)
forall t (acc :: * -> *) (exp :: * -> *).
PrimConst t -> PreSmartExp acc exp t
PrimConst (BoundedType (EltR t) -> PrimConst (EltR t)
forall a. BoundedType a -> PrimConst a
PrimMinBound BoundedType (EltR t)
forall a. IsBounded a => BoundedType a
boundedType)

mkMaxBound :: (Elt t, IsBounded (EltR t)) => Exp t
mkMaxBound :: Exp t
mkMaxBound = PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
forall t. PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp (PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t)
-> PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
forall a b. (a -> b) -> a -> b
$ PrimConst (EltR t) -> PreSmartExp SmartAcc SmartExp (EltR t)
forall t (acc :: * -> *) (exp :: * -> *).
PrimConst t -> PreSmartExp acc exp t
PrimConst (BoundedType (EltR t) -> PrimConst (EltR t)
forall a. BoundedType a -> PrimConst a
PrimMaxBound BoundedType (EltR t)
forall a. IsBounded a => BoundedType a
boundedType)

mkPi :: (Elt r, IsFloating (EltR r)) => Exp r
mkPi :: Exp r
mkPi = PreSmartExp SmartAcc SmartExp (EltR r) -> Exp r
forall t. PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp (PreSmartExp SmartAcc SmartExp (EltR r) -> Exp r)
-> PreSmartExp SmartAcc SmartExp (EltR r) -> Exp r
forall a b. (a -> b) -> a -> b
$ PrimConst (EltR r) -> PreSmartExp SmartAcc SmartExp (EltR r)
forall t (acc :: * -> *) (exp :: * -> *).
PrimConst t -> PreSmartExp acc exp t
PrimConst (FloatingType (EltR r) -> PrimConst (EltR r)
forall a. FloatingType a -> PrimConst a
PrimPi FloatingType (EltR r)
forall a. IsFloating a => FloatingType a
floatingType)


-- Smart constructors for primitive applications
--

-- Operators from Floating

mkSin :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t
mkSin :: Exp t -> Exp t
mkSin = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. FloatingType a -> PrimFun (a -> a)
PrimSin FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkCos :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t
mkCos :: Exp t -> Exp t
mkCos = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. FloatingType a -> PrimFun (a -> a)
PrimCos FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkTan :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t
mkTan :: Exp t -> Exp t
mkTan = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. FloatingType a -> PrimFun (a -> a)
PrimTan FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkAsin :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t
mkAsin :: Exp t -> Exp t
mkAsin = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. FloatingType a -> PrimFun (a -> a)
PrimAsin FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkAcos :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t
mkAcos :: Exp t -> Exp t
mkAcos = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. FloatingType a -> PrimFun (a -> a)
PrimAcos FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkAtan :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t
mkAtan :: Exp t -> Exp t
mkAtan = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. FloatingType a -> PrimFun (a -> a)
PrimAtan FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkSinh :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t
mkSinh :: Exp t -> Exp t
mkSinh = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. FloatingType a -> PrimFun (a -> a)
PrimSinh FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkCosh :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t
mkCosh :: Exp t -> Exp t
mkCosh = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. FloatingType a -> PrimFun (a -> a)
PrimCosh FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkTanh :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t
mkTanh :: Exp t -> Exp t
mkTanh = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. FloatingType a -> PrimFun (a -> a)
PrimTanh FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkAsinh :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t
mkAsinh :: Exp t -> Exp t
mkAsinh = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. FloatingType a -> PrimFun (a -> a)
PrimAsinh FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkAcosh :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t
mkAcosh :: Exp t -> Exp t
mkAcosh = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. FloatingType a -> PrimFun (a -> a)
PrimAcosh FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkAtanh :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t
mkAtanh :: Exp t -> Exp t
mkAtanh = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. FloatingType a -> PrimFun (a -> a)
PrimAtanh FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkExpFloating :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t
mkExpFloating :: Exp t -> Exp t
mkExpFloating = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. FloatingType a -> PrimFun (a -> a)
PrimExpFloating FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkSqrt :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t
mkSqrt :: Exp t -> Exp t
mkSqrt = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. FloatingType a -> PrimFun (a -> a)
PrimSqrt FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkLog :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t
mkLog :: Exp t -> Exp t
mkLog = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. FloatingType a -> PrimFun (a -> a)
PrimLog FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkFPow :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t -> Exp t
mkFPow :: Exp t -> Exp t -> Exp t
mkFPow = PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t)
-> PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun ((EltR t, EltR t) -> EltR t)
forall a. FloatingType a -> PrimFun ((a, a) -> a)
PrimFPow FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkLogBase :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t -> Exp t
mkLogBase :: Exp t -> Exp t -> Exp t
mkLogBase = PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t)
-> PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun ((EltR t, EltR t) -> EltR t)
forall a. FloatingType a -> PrimFun ((a, a) -> a)
PrimLogBase FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

-- Operators from Num

mkAdd :: (Elt t, IsNum (EltR t)) => Exp t -> Exp t -> Exp t
mkAdd :: Exp t -> Exp t -> Exp t
mkAdd = PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t)
-> PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ NumType (EltR t) -> PrimFun ((EltR t, EltR t) -> EltR t)
forall a. NumType a -> PrimFun ((a, a) -> a)
PrimAdd NumType (EltR t)
forall a. IsNum a => NumType a
numType

mkSub :: (Elt t, IsNum (EltR t)) => Exp t -> Exp t -> Exp t
mkSub :: Exp t -> Exp t -> Exp t
mkSub = PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t)
-> PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ NumType (EltR t) -> PrimFun ((EltR t, EltR t) -> EltR t)
forall a. NumType a -> PrimFun ((a, a) -> a)
PrimSub NumType (EltR t)
forall a. IsNum a => NumType a
numType

mkMul :: (Elt t, IsNum (EltR t)) => Exp t -> Exp t -> Exp t
mkMul :: Exp t -> Exp t -> Exp t
mkMul = PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t)
-> PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ NumType (EltR t) -> PrimFun ((EltR t, EltR t) -> EltR t)
forall a. NumType a -> PrimFun ((a, a) -> a)
PrimMul NumType (EltR t)
forall a. IsNum a => NumType a
numType

mkNeg :: (Elt t, IsNum (EltR t)) => Exp t -> Exp t
mkNeg :: Exp t -> Exp t
mkNeg = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ NumType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. NumType a -> PrimFun (a -> a)
PrimNeg NumType (EltR t)
forall a. IsNum a => NumType a
numType

mkAbs :: (Elt t, IsNum (EltR t)) => Exp t -> Exp t
mkAbs :: Exp t -> Exp t
mkAbs = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ NumType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. NumType a -> PrimFun (a -> a)
PrimAbs NumType (EltR t)
forall a. IsNum a => NumType a
numType

mkSig :: (Elt t, IsNum (EltR t)) => Exp t -> Exp t
mkSig :: Exp t -> Exp t
mkSig = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ NumType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. NumType a -> PrimFun (a -> a)
PrimSig NumType (EltR t)
forall a. IsNum a => NumType a
numType

-- Operators from Integral

mkQuot :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp t -> Exp t
mkQuot :: Exp t -> Exp t -> Exp t
mkQuot = PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t)
-> PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t) -> PrimFun ((EltR t, EltR t) -> EltR t)
forall a. IntegralType a -> PrimFun ((a, a) -> a)
PrimQuot IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType

mkRem :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp t -> Exp t
mkRem :: Exp t -> Exp t -> Exp t
mkRem = PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t)
-> PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t) -> PrimFun ((EltR t, EltR t) -> EltR t)
forall a. IntegralType a -> PrimFun ((a, a) -> a)
PrimRem IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType

mkQuotRem :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp t -> (Exp t, Exp t)
mkQuotRem :: Exp t -> Exp t -> (Exp t, Exp t)
mkQuotRem (Exp SmartExp (EltR t)
x) (Exp SmartExp (EltR t)
y) =
  let pair :: SmartExp (EltR t, EltR t)
pair = PreSmartExp SmartAcc SmartExp (EltR t, EltR t)
-> SmartExp (EltR t, EltR t)
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp (EltR t, EltR t)
 -> SmartExp (EltR t, EltR t))
-> PreSmartExp SmartAcc SmartExp (EltR t, EltR t)
-> SmartExp (EltR t, EltR t)
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t)
-> PrimFun ((EltR t, EltR t) -> (EltR t, EltR t))
forall a. IntegralType a -> PrimFun ((a, a) -> (a, a))
PrimQuotRem IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType PrimFun ((EltR t, EltR t) -> (EltR t, EltR t))
-> SmartExp (EltR t, EltR t)
-> PreSmartExp SmartAcc SmartExp (EltR t, EltR t)
forall a r (exp :: * -> *) (acc :: * -> *).
PrimFun (a -> r) -> exp a -> PreSmartExp acc exp r
`PrimApp` PreSmartExp SmartAcc SmartExp (EltR t, EltR t)
-> SmartExp (EltR t, EltR t)
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (SmartExp (EltR t)
-> SmartExp (EltR t)
-> PreSmartExp SmartAcc SmartExp (EltR t, EltR t)
forall (exp :: * -> *) t1 t2 (acc :: * -> *).
exp t1 -> exp t2 -> PreSmartExp acc exp (t1, t2)
Pair SmartExp (EltR t)
x SmartExp (EltR t)
y)
  in  (PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
forall t. PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp (PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t)
-> PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
forall a b. (a -> b) -> a -> b
$ PairIdx (EltR t, EltR t) (EltR t)
-> SmartExp (EltR t, EltR t)
-> PreSmartExp SmartAcc SmartExp (EltR t)
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (EltR t, EltR t) (EltR t)
forall a b. PairIdx (a, b) a
PairIdxLeft SmartExp (EltR t, EltR t)
pair, PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
forall t. PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp (PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t)
-> PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
forall a b. (a -> b) -> a -> b
$ PairIdx (EltR t, EltR t) (EltR t)
-> SmartExp (EltR t, EltR t)
-> PreSmartExp SmartAcc SmartExp (EltR t)
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (EltR t, EltR t) (EltR t)
forall a b. PairIdx (a, b) b
PairIdxRight SmartExp (EltR t, EltR t)
pair)

mkIDiv :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp t -> Exp t
mkIDiv :: Exp t -> Exp t -> Exp t
mkIDiv = PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t)
-> PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t) -> PrimFun ((EltR t, EltR t) -> EltR t)
forall a. IntegralType a -> PrimFun ((a, a) -> a)
PrimIDiv IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType

mkMod :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp t -> Exp t
mkMod :: Exp t -> Exp t -> Exp t
mkMod = PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t)
-> PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t) -> PrimFun ((EltR t, EltR t) -> EltR t)
forall a. IntegralType a -> PrimFun ((a, a) -> a)
PrimMod IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType

mkDivMod :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp t -> (Exp t, Exp t)
mkDivMod :: Exp t -> Exp t -> (Exp t, Exp t)
mkDivMod (Exp SmartExp (EltR t)
x) (Exp SmartExp (EltR t)
y) =
  let pair :: SmartExp (EltR t, EltR t)
pair = PreSmartExp SmartAcc SmartExp (EltR t, EltR t)
-> SmartExp (EltR t, EltR t)
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp (EltR t, EltR t)
 -> SmartExp (EltR t, EltR t))
-> PreSmartExp SmartAcc SmartExp (EltR t, EltR t)
-> SmartExp (EltR t, EltR t)
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t)
-> PrimFun ((EltR t, EltR t) -> (EltR t, EltR t))
forall a. IntegralType a -> PrimFun ((a, a) -> (a, a))
PrimDivMod IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType PrimFun ((EltR t, EltR t) -> (EltR t, EltR t))
-> SmartExp (EltR t, EltR t)
-> PreSmartExp SmartAcc SmartExp (EltR t, EltR t)
forall a r (exp :: * -> *) (acc :: * -> *).
PrimFun (a -> r) -> exp a -> PreSmartExp acc exp r
`PrimApp` PreSmartExp SmartAcc SmartExp (EltR t, EltR t)
-> SmartExp (EltR t, EltR t)
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (SmartExp (EltR t)
-> SmartExp (EltR t)
-> PreSmartExp SmartAcc SmartExp (EltR t, EltR t)
forall (exp :: * -> *) t1 t2 (acc :: * -> *).
exp t1 -> exp t2 -> PreSmartExp acc exp (t1, t2)
Pair SmartExp (EltR t)
x SmartExp (EltR t)
y)
  in  (PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
forall t. PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp (PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t)
-> PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
forall a b. (a -> b) -> a -> b
$ PairIdx (EltR t, EltR t) (EltR t)
-> SmartExp (EltR t, EltR t)
-> PreSmartExp SmartAcc SmartExp (EltR t)
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (EltR t, EltR t) (EltR t)
forall a b. PairIdx (a, b) a
PairIdxLeft SmartExp (EltR t, EltR t)
pair, PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
forall t. PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp (PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t)
-> PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
forall a b. (a -> b) -> a -> b
$ PairIdx (EltR t, EltR t) (EltR t)
-> SmartExp (EltR t, EltR t)
-> PreSmartExp SmartAcc SmartExp (EltR t)
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (EltR t, EltR t) (EltR t)
forall a b. PairIdx (a, b) b
PairIdxRight SmartExp (EltR t, EltR t)
pair)

-- Operators from Bits and FiniteBits

mkBAnd :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp t -> Exp t
mkBAnd :: Exp t -> Exp t -> Exp t
mkBAnd = PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t)
-> PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t) -> PrimFun ((EltR t, EltR t) -> EltR t)
forall a. IntegralType a -> PrimFun ((a, a) -> a)
PrimBAnd IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType

mkBOr :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp t -> Exp t
mkBOr :: Exp t -> Exp t -> Exp t
mkBOr = PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t)
-> PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t) -> PrimFun ((EltR t, EltR t) -> EltR t)
forall a. IntegralType a -> PrimFun ((a, a) -> a)
PrimBOr IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType

mkBXor :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp t -> Exp t
mkBXor :: Exp t -> Exp t -> Exp t
mkBXor = PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t)
-> PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t) -> PrimFun ((EltR t, EltR t) -> EltR t)
forall a. IntegralType a -> PrimFun ((a, a) -> a)
PrimBXor IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType

mkBNot :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp t
mkBNot :: Exp t -> Exp t
mkBNot = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. IntegralType a -> PrimFun (a -> a)
PrimBNot IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType

mkBShiftL :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp Int -> Exp t
mkBShiftL :: Exp t -> Exp Int -> Exp t
mkBShiftL = PrimFun ((EltR t, EltR Int) -> EltR t) -> Exp t -> Exp Int -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR Int) -> EltR t)
 -> Exp t -> Exp Int -> Exp t)
-> PrimFun ((EltR t, EltR Int) -> EltR t)
-> Exp t
-> Exp Int
-> Exp t
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t) -> PrimFun ((EltR t, Int) -> EltR t)
forall a. IntegralType a -> PrimFun ((a, Int) -> a)
PrimBShiftL IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType

mkBShiftR :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp Int -> Exp t
mkBShiftR :: Exp t -> Exp Int -> Exp t
mkBShiftR = PrimFun ((EltR t, EltR Int) -> EltR t) -> Exp t -> Exp Int -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR Int) -> EltR t)
 -> Exp t -> Exp Int -> Exp t)
-> PrimFun ((EltR t, EltR Int) -> EltR t)
-> Exp t
-> Exp Int
-> Exp t
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t) -> PrimFun ((EltR t, Int) -> EltR t)
forall a. IntegralType a -> PrimFun ((a, Int) -> a)
PrimBShiftR IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType

mkBRotateL :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp Int -> Exp t
mkBRotateL :: Exp t -> Exp Int -> Exp t
mkBRotateL = PrimFun ((EltR t, EltR Int) -> EltR t) -> Exp t -> Exp Int -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR Int) -> EltR t)
 -> Exp t -> Exp Int -> Exp t)
-> PrimFun ((EltR t, EltR Int) -> EltR t)
-> Exp t
-> Exp Int
-> Exp t
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t) -> PrimFun ((EltR t, Int) -> EltR t)
forall a. IntegralType a -> PrimFun ((a, Int) -> a)
PrimBRotateL IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType

mkBRotateR :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp Int -> Exp t
mkBRotateR :: Exp t -> Exp Int -> Exp t
mkBRotateR = PrimFun ((EltR t, EltR Int) -> EltR t) -> Exp t -> Exp Int -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR Int) -> EltR t)
 -> Exp t -> Exp Int -> Exp t)
-> PrimFun ((EltR t, EltR Int) -> EltR t)
-> Exp t
-> Exp Int
-> Exp t
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t) -> PrimFun ((EltR t, Int) -> EltR t)
forall a. IntegralType a -> PrimFun ((a, Int) -> a)
PrimBRotateR IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType

mkPopCount :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp Int
mkPopCount :: Exp t -> Exp Int
mkPopCount = PrimFun (EltR t -> EltR Int) -> Exp t -> Exp Int
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR Int) -> Exp t -> Exp Int)
-> PrimFun (EltR t -> EltR Int) -> Exp t -> Exp Int
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t) -> PrimFun (EltR t -> Int)
forall a. IntegralType a -> PrimFun (a -> Int)
PrimPopCount IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType

mkCountLeadingZeros :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp Int
mkCountLeadingZeros :: Exp t -> Exp Int
mkCountLeadingZeros = PrimFun (EltR t -> EltR Int) -> Exp t -> Exp Int
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR Int) -> Exp t -> Exp Int)
-> PrimFun (EltR t -> EltR Int) -> Exp t -> Exp Int
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t) -> PrimFun (EltR t -> Int)
forall a. IntegralType a -> PrimFun (a -> Int)
PrimCountLeadingZeros IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType

mkCountTrailingZeros :: (Elt t, IsIntegral (EltR t)) => Exp t -> Exp Int
mkCountTrailingZeros :: Exp t -> Exp Int
mkCountTrailingZeros = PrimFun (EltR t -> EltR Int) -> Exp t -> Exp Int
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR Int) -> Exp t -> Exp Int)
-> PrimFun (EltR t -> EltR Int) -> Exp t -> Exp Int
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR t) -> PrimFun (EltR t -> Int)
forall a. IntegralType a -> PrimFun (a -> Int)
PrimCountTrailingZeros IntegralType (EltR t)
forall a. IsIntegral a => IntegralType a
integralType


-- Operators from Fractional

mkFDiv :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t -> Exp t
mkFDiv :: Exp t -> Exp t -> Exp t
mkFDiv = PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t)
-> PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun ((EltR t, EltR t) -> EltR t)
forall a. FloatingType a -> PrimFun ((a, a) -> a)
PrimFDiv FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkRecip :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t
mkRecip :: Exp t -> Exp t
mkRecip = PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR t -> EltR t) -> Exp t -> Exp t)
-> PrimFun (EltR t -> EltR t) -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> EltR t)
forall a. FloatingType a -> PrimFun (a -> a)
PrimRecip FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

-- Operators from RealFrac

mkTruncate :: (Elt a, Elt b, IsFloating (EltR a), IsIntegral (EltR b)) => Exp a -> Exp b
mkTruncate :: Exp a -> Exp b
mkTruncate = PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR a -> EltR b) -> Exp a -> Exp b)
-> PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR a)
-> IntegralType (EltR b) -> PrimFun (EltR a -> EltR b)
forall a b. FloatingType a -> IntegralType b -> PrimFun (a -> b)
PrimTruncate FloatingType (EltR a)
forall a. IsFloating a => FloatingType a
floatingType IntegralType (EltR b)
forall a. IsIntegral a => IntegralType a
integralType

mkRound :: (Elt a, Elt b, IsFloating (EltR a), IsIntegral (EltR b)) => Exp a -> Exp b
mkRound :: Exp a -> Exp b
mkRound = PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR a -> EltR b) -> Exp a -> Exp b)
-> PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR a)
-> IntegralType (EltR b) -> PrimFun (EltR a -> EltR b)
forall a b. FloatingType a -> IntegralType b -> PrimFun (a -> b)
PrimRound FloatingType (EltR a)
forall a. IsFloating a => FloatingType a
floatingType IntegralType (EltR b)
forall a. IsIntegral a => IntegralType a
integralType

mkFloor :: (Elt a, Elt b, IsFloating (EltR a), IsIntegral (EltR b)) => Exp a -> Exp b
mkFloor :: Exp a -> Exp b
mkFloor = PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR a -> EltR b) -> Exp a -> Exp b)
-> PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR a)
-> IntegralType (EltR b) -> PrimFun (EltR a -> EltR b)
forall a b. FloatingType a -> IntegralType b -> PrimFun (a -> b)
PrimFloor FloatingType (EltR a)
forall a. IsFloating a => FloatingType a
floatingType IntegralType (EltR b)
forall a. IsIntegral a => IntegralType a
integralType

mkCeiling :: (Elt a, Elt b, IsFloating (EltR a), IsIntegral (EltR b)) => Exp a -> Exp b
mkCeiling :: Exp a -> Exp b
mkCeiling = PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR a -> EltR b) -> Exp a -> Exp b)
-> PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR a)
-> IntegralType (EltR b) -> PrimFun (EltR a -> EltR b)
forall a b. FloatingType a -> IntegralType b -> PrimFun (a -> b)
PrimCeiling FloatingType (EltR a)
forall a. IsFloating a => FloatingType a
floatingType IntegralType (EltR b)
forall a. IsIntegral a => IntegralType a
integralType

-- Operators from RealFloat

mkAtan2 :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp t -> Exp t
mkAtan2 :: Exp t -> Exp t -> Exp t
mkAtan2 = PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t)
-> PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun ((EltR t, EltR t) -> EltR t)
forall a. FloatingType a -> PrimFun ((a, a) -> a)
PrimAtan2 FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkIsNaN :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp Bool
mkIsNaN :: Exp t -> Exp Bool
mkIsNaN = PrimFun (EltR t -> PrimBool) -> Exp t -> Exp Bool
forall a.
Elt a =>
PrimFun (EltR a -> PrimBool) -> Exp a -> Exp Bool
mkPrimUnaryBool (PrimFun (EltR t -> PrimBool) -> Exp t -> Exp Bool)
-> PrimFun (EltR t -> PrimBool) -> Exp t -> Exp Bool
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> PrimBool)
forall a. FloatingType a -> PrimFun (a -> PrimBool)
PrimIsNaN FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

mkIsInfinite :: (Elt t, IsFloating (EltR t)) => Exp t -> Exp Bool
mkIsInfinite :: Exp t -> Exp Bool
mkIsInfinite = PrimFun (EltR t -> PrimBool) -> Exp t -> Exp Bool
forall a.
Elt a =>
PrimFun (EltR a -> PrimBool) -> Exp a -> Exp Bool
mkPrimUnaryBool (PrimFun (EltR t -> PrimBool) -> Exp t -> Exp Bool)
-> PrimFun (EltR t -> PrimBool) -> Exp t -> Exp Bool
forall a b. (a -> b) -> a -> b
$ FloatingType (EltR t) -> PrimFun (EltR t -> PrimBool)
forall a. FloatingType a -> PrimFun (a -> PrimBool)
PrimIsInfinite FloatingType (EltR t)
forall a. IsFloating a => FloatingType a
floatingType

-- FIXME: add missing operations from Floating, RealFrac & RealFloat

-- Relational and equality operators

mkLt :: (Elt t, IsSingle (EltR t)) => Exp t -> Exp t -> Exp Bool
mkLt :: Exp t -> Exp t -> Exp Bool
mkLt = PrimFun ((EltR t, EltR t) -> PrimBool)
-> Exp t -> Exp t -> Exp Bool
forall a b.
(Elt a, Elt b) =>
PrimFun ((EltR a, EltR b) -> PrimBool)
-> Exp a -> Exp b -> Exp Bool
mkPrimBinaryBool (PrimFun ((EltR t, EltR t) -> PrimBool)
 -> Exp t -> Exp t -> Exp Bool)
-> PrimFun ((EltR t, EltR t) -> PrimBool)
-> Exp t
-> Exp t
-> Exp Bool
forall a b. (a -> b) -> a -> b
$ SingleType (EltR t) -> PrimFun ((EltR t, EltR t) -> PrimBool)
forall a. SingleType a -> PrimFun ((a, a) -> PrimBool)
PrimLt SingleType (EltR t)
forall a. IsSingle a => SingleType a
singleType

mkGt :: (Elt t, IsSingle (EltR t)) => Exp t -> Exp t -> Exp Bool
mkGt :: Exp t -> Exp t -> Exp Bool
mkGt = PrimFun ((EltR t, EltR t) -> PrimBool)
-> Exp t -> Exp t -> Exp Bool
forall a b.
(Elt a, Elt b) =>
PrimFun ((EltR a, EltR b) -> PrimBool)
-> Exp a -> Exp b -> Exp Bool
mkPrimBinaryBool (PrimFun ((EltR t, EltR t) -> PrimBool)
 -> Exp t -> Exp t -> Exp Bool)
-> PrimFun ((EltR t, EltR t) -> PrimBool)
-> Exp t
-> Exp t
-> Exp Bool
forall a b. (a -> b) -> a -> b
$ SingleType (EltR t) -> PrimFun ((EltR t, EltR t) -> PrimBool)
forall a. SingleType a -> PrimFun ((a, a) -> PrimBool)
PrimGt SingleType (EltR t)
forall a. IsSingle a => SingleType a
singleType

mkLtEq :: (Elt t, IsSingle (EltR t)) => Exp t -> Exp t -> Exp Bool
mkLtEq :: Exp t -> Exp t -> Exp Bool
mkLtEq = PrimFun ((EltR t, EltR t) -> PrimBool)
-> Exp t -> Exp t -> Exp Bool
forall a b.
(Elt a, Elt b) =>
PrimFun ((EltR a, EltR b) -> PrimBool)
-> Exp a -> Exp b -> Exp Bool
mkPrimBinaryBool (PrimFun ((EltR t, EltR t) -> PrimBool)
 -> Exp t -> Exp t -> Exp Bool)
-> PrimFun ((EltR t, EltR t) -> PrimBool)
-> Exp t
-> Exp t
-> Exp Bool
forall a b. (a -> b) -> a -> b
$ SingleType (EltR t) -> PrimFun ((EltR t, EltR t) -> PrimBool)
forall a. SingleType a -> PrimFun ((a, a) -> PrimBool)
PrimLtEq SingleType (EltR t)
forall a. IsSingle a => SingleType a
singleType

mkGtEq :: (Elt t, IsSingle (EltR t)) => Exp t -> Exp t -> Exp Bool
mkGtEq :: Exp t -> Exp t -> Exp Bool
mkGtEq = PrimFun ((EltR t, EltR t) -> PrimBool)
-> Exp t -> Exp t -> Exp Bool
forall a b.
(Elt a, Elt b) =>
PrimFun ((EltR a, EltR b) -> PrimBool)
-> Exp a -> Exp b -> Exp Bool
mkPrimBinaryBool (PrimFun ((EltR t, EltR t) -> PrimBool)
 -> Exp t -> Exp t -> Exp Bool)
-> PrimFun ((EltR t, EltR t) -> PrimBool)
-> Exp t
-> Exp t
-> Exp Bool
forall a b. (a -> b) -> a -> b
$ SingleType (EltR t) -> PrimFun ((EltR t, EltR t) -> PrimBool)
forall a. SingleType a -> PrimFun ((a, a) -> PrimBool)
PrimGtEq SingleType (EltR t)
forall a. IsSingle a => SingleType a
singleType

mkEq :: (Elt t, IsSingle (EltR t)) => Exp t -> Exp t -> Exp Bool
mkEq :: Exp t -> Exp t -> Exp Bool
mkEq = PrimFun ((EltR t, EltR t) -> PrimBool)
-> Exp t -> Exp t -> Exp Bool
forall a b.
(Elt a, Elt b) =>
PrimFun ((EltR a, EltR b) -> PrimBool)
-> Exp a -> Exp b -> Exp Bool
mkPrimBinaryBool (PrimFun ((EltR t, EltR t) -> PrimBool)
 -> Exp t -> Exp t -> Exp Bool)
-> PrimFun ((EltR t, EltR t) -> PrimBool)
-> Exp t
-> Exp t
-> Exp Bool
forall a b. (a -> b) -> a -> b
$ SingleType (EltR t) -> PrimFun ((EltR t, EltR t) -> PrimBool)
forall a. SingleType a -> PrimFun ((a, a) -> PrimBool)
PrimEq SingleType (EltR t)
forall a. IsSingle a => SingleType a
singleType

mkNEq :: (Elt t, IsSingle (EltR t)) => Exp t -> Exp t -> Exp Bool
mkNEq :: Exp t -> Exp t -> Exp Bool
mkNEq = PrimFun ((EltR t, EltR t) -> PrimBool)
-> Exp t -> Exp t -> Exp Bool
forall a b.
(Elt a, Elt b) =>
PrimFun ((EltR a, EltR b) -> PrimBool)
-> Exp a -> Exp b -> Exp Bool
mkPrimBinaryBool (PrimFun ((EltR t, EltR t) -> PrimBool)
 -> Exp t -> Exp t -> Exp Bool)
-> PrimFun ((EltR t, EltR t) -> PrimBool)
-> Exp t
-> Exp t
-> Exp Bool
forall a b. (a -> b) -> a -> b
$ SingleType (EltR t) -> PrimFun ((EltR t, EltR t) -> PrimBool)
forall a. SingleType a -> PrimFun ((a, a) -> PrimBool)
PrimNEq SingleType (EltR t)
forall a. IsSingle a => SingleType a
singleType

mkMax :: (Elt t, IsSingle (EltR t)) => Exp t -> Exp t -> Exp t
mkMax :: Exp t -> Exp t -> Exp t
mkMax = PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t)
-> PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ SingleType (EltR t) -> PrimFun ((EltR t, EltR t) -> EltR t)
forall a. SingleType a -> PrimFun ((a, a) -> a)
PrimMax SingleType (EltR t)
forall a. IsSingle a => SingleType a
singleType

mkMin :: (Elt t, IsSingle (EltR t)) => Exp t -> Exp t -> Exp t
mkMin :: Exp t -> Exp t -> Exp t
mkMin = PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary (PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t)
-> PrimFun ((EltR t, EltR t) -> EltR t) -> Exp t -> Exp t -> Exp t
forall a b. (a -> b) -> a -> b
$ SingleType (EltR t) -> PrimFun ((EltR t, EltR t) -> EltR t)
forall a. SingleType a -> PrimFun ((a, a) -> a)
PrimMin SingleType (EltR t)
forall a. IsSingle a => SingleType a
singleType

-- Logical operators

mkLAnd :: Exp Bool -> Exp Bool -> Exp Bool
mkLAnd :: Exp Bool -> Exp Bool -> Exp Bool
mkLAnd (Exp SmartExp (EltR Bool)
a) (Exp SmartExp (EltR Bool)
b) = PreSmartExp SmartAcc SmartExp (EltR Bool) -> Exp Bool
forall t. PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp (PreSmartExp SmartAcc SmartExp (EltR Bool) -> Exp Bool)
-> PreSmartExp SmartAcc SmartExp (EltR Bool) -> Exp Bool
forall a b. (a -> b) -> a -> b
$ PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PrimFun ((PrimBool, PrimBool) -> PrimBool)
-> SmartExp (PrimBool, PrimBool)
-> PreSmartExp SmartAcc SmartExp PrimBool
forall a r (exp :: * -> *) (acc :: * -> *).
PrimFun (a -> r) -> exp a -> PreSmartExp acc exp r
PrimApp PrimFun ((PrimBool, PrimBool) -> PrimBool)
PrimLAnd (PreSmartExp SmartAcc SmartExp (PrimBool, PrimBool)
-> SmartExp (PrimBool, PrimBool)
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp (PrimBool, PrimBool)
 -> SmartExp (PrimBool, PrimBool))
-> PreSmartExp SmartAcc SmartExp (PrimBool, PrimBool)
-> SmartExp (PrimBool, PrimBool)
forall a b. (a -> b) -> a -> b
$ SmartExp PrimBool
-> SmartExp PrimBool
-> PreSmartExp SmartAcc SmartExp (PrimBool, PrimBool)
forall (exp :: * -> *) t1 t2 (acc :: * -> *).
exp t1 -> exp t2 -> PreSmartExp acc exp (t1, t2)
Pair SmartExp PrimBool
x SmartExp PrimBool
y)) SmartExp PrimBool
-> SmartExp () -> PreSmartExp SmartAcc SmartExp (PrimBool, ())
forall (exp :: * -> *) t1 t2 (acc :: * -> *).
exp t1 -> exp t2 -> PreSmartExp acc exp (t1, t2)
`Pair` PreSmartExp SmartAcc SmartExp () -> SmartExp ()
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp PreSmartExp SmartAcc SmartExp ()
forall (acc :: * -> *) (exp :: * -> *). PreSmartExp acc exp ()
Nil
  where
    x :: SmartExp PrimBool
x = PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool)
-> PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool
forall a b. (a -> b) -> a -> b
$ PairIdx (PrimBool, ()) PrimBool
-> SmartExp (PrimBool, ())
-> PreSmartExp SmartAcc SmartExp PrimBool
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (PrimBool, ()) PrimBool
forall a b. PairIdx (a, b) a
PairIdxLeft SmartExp (PrimBool, ())
SmartExp (EltR Bool)
a
    y :: SmartExp PrimBool
y = PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool)
-> PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool
forall a b. (a -> b) -> a -> b
$ PairIdx (PrimBool, ()) PrimBool
-> SmartExp (PrimBool, ())
-> PreSmartExp SmartAcc SmartExp PrimBool
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (PrimBool, ()) PrimBool
forall a b. PairIdx (a, b) a
PairIdxLeft SmartExp (PrimBool, ())
SmartExp (EltR Bool)
b

mkLOr :: Exp Bool -> Exp Bool -> Exp Bool
mkLOr :: Exp Bool -> Exp Bool -> Exp Bool
mkLOr (Exp SmartExp (EltR Bool)
a) (Exp SmartExp (EltR Bool)
b) = PreSmartExp SmartAcc SmartExp (EltR Bool) -> Exp Bool
forall t. PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp (PreSmartExp SmartAcc SmartExp (EltR Bool) -> Exp Bool)
-> PreSmartExp SmartAcc SmartExp (EltR Bool) -> Exp Bool
forall a b. (a -> b) -> a -> b
$ PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PrimFun ((PrimBool, PrimBool) -> PrimBool)
-> SmartExp (PrimBool, PrimBool)
-> PreSmartExp SmartAcc SmartExp PrimBool
forall a r (exp :: * -> *) (acc :: * -> *).
PrimFun (a -> r) -> exp a -> PreSmartExp acc exp r
PrimApp PrimFun ((PrimBool, PrimBool) -> PrimBool)
PrimLOr (PreSmartExp SmartAcc SmartExp (PrimBool, PrimBool)
-> SmartExp (PrimBool, PrimBool)
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp (PrimBool, PrimBool)
 -> SmartExp (PrimBool, PrimBool))
-> PreSmartExp SmartAcc SmartExp (PrimBool, PrimBool)
-> SmartExp (PrimBool, PrimBool)
forall a b. (a -> b) -> a -> b
$ SmartExp PrimBool
-> SmartExp PrimBool
-> PreSmartExp SmartAcc SmartExp (PrimBool, PrimBool)
forall (exp :: * -> *) t1 t2 (acc :: * -> *).
exp t1 -> exp t2 -> PreSmartExp acc exp (t1, t2)
Pair SmartExp PrimBool
x SmartExp PrimBool
y)) SmartExp PrimBool
-> SmartExp () -> PreSmartExp SmartAcc SmartExp (PrimBool, ())
forall (exp :: * -> *) t1 t2 (acc :: * -> *).
exp t1 -> exp t2 -> PreSmartExp acc exp (t1, t2)
`Pair` PreSmartExp SmartAcc SmartExp () -> SmartExp ()
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp PreSmartExp SmartAcc SmartExp ()
forall (acc :: * -> *) (exp :: * -> *). PreSmartExp acc exp ()
Nil
  where
    x :: SmartExp PrimBool
x = PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool)
-> PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool
forall a b. (a -> b) -> a -> b
$ PairIdx (PrimBool, ()) PrimBool
-> SmartExp (PrimBool, ())
-> PreSmartExp SmartAcc SmartExp PrimBool
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (PrimBool, ()) PrimBool
forall a b. PairIdx (a, b) a
PairIdxLeft SmartExp (PrimBool, ())
SmartExp (EltR Bool)
a
    y :: SmartExp PrimBool
y = PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool)
-> PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool
forall a b. (a -> b) -> a -> b
$ PairIdx (PrimBool, ()) PrimBool
-> SmartExp (PrimBool, ())
-> PreSmartExp SmartAcc SmartExp PrimBool
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (PrimBool, ()) PrimBool
forall a b. PairIdx (a, b) a
PairIdxLeft SmartExp (PrimBool, ())
SmartExp (EltR Bool)
b

mkLNot :: Exp Bool -> Exp Bool
mkLNot :: Exp Bool -> Exp Bool
mkLNot (Exp SmartExp (EltR Bool)
a) = PreSmartExp SmartAcc SmartExp (EltR Bool) -> Exp Bool
forall t. PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp (PreSmartExp SmartAcc SmartExp (EltR Bool) -> Exp Bool)
-> PreSmartExp SmartAcc SmartExp (EltR Bool) -> Exp Bool
forall a b. (a -> b) -> a -> b
$ PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PrimFun (PrimBool -> PrimBool)
-> SmartExp PrimBool -> PreSmartExp SmartAcc SmartExp PrimBool
forall a r (exp :: * -> *) (acc :: * -> *).
PrimFun (a -> r) -> exp a -> PreSmartExp acc exp r
PrimApp PrimFun (PrimBool -> PrimBool)
PrimLNot SmartExp PrimBool
x) SmartExp PrimBool
-> SmartExp () -> PreSmartExp SmartAcc SmartExp (PrimBool, ())
forall (exp :: * -> *) t1 t2 (acc :: * -> *).
exp t1 -> exp t2 -> PreSmartExp acc exp (t1, t2)
`Pair` PreSmartExp SmartAcc SmartExp () -> SmartExp ()
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp PreSmartExp SmartAcc SmartExp ()
forall (acc :: * -> *) (exp :: * -> *). PreSmartExp acc exp ()
Nil
  where
    x :: SmartExp PrimBool
x = PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool)
-> PreSmartExp SmartAcc SmartExp PrimBool -> SmartExp PrimBool
forall a b. (a -> b) -> a -> b
$ PairIdx (PrimBool, ()) PrimBool
-> SmartExp (PrimBool, ())
-> PreSmartExp SmartAcc SmartExp PrimBool
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (PrimBool, ()) PrimBool
forall a b. PairIdx (a, b) a
PairIdxLeft SmartExp (PrimBool, ())
SmartExp (EltR Bool)
a

-- Numeric conversions

mkFromIntegral :: (Elt a, Elt b, IsIntegral (EltR a), IsNum (EltR b)) => Exp a -> Exp b
mkFromIntegral :: Exp a -> Exp b
mkFromIntegral = PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR a -> EltR b) -> Exp a -> Exp b)
-> PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
forall a b. (a -> b) -> a -> b
$ IntegralType (EltR a)
-> NumType (EltR b) -> PrimFun (EltR a -> EltR b)
forall a a. IntegralType a -> NumType a -> PrimFun (a -> a)
PrimFromIntegral IntegralType (EltR a)
forall a. IsIntegral a => IntegralType a
integralType NumType (EltR b)
forall a. IsNum a => NumType a
numType

mkToFloating :: (Elt a, Elt b, IsNum (EltR a), IsFloating (EltR b)) => Exp a -> Exp b
mkToFloating :: Exp a -> Exp b
mkToFloating = PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary (PrimFun (EltR a -> EltR b) -> Exp a -> Exp b)
-> PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
forall a b. (a -> b) -> a -> b
$ NumType (EltR a)
-> FloatingType (EltR b) -> PrimFun (EltR a -> EltR b)
forall a b. NumType a -> FloatingType b -> PrimFun (a -> b)
PrimToFloating NumType (EltR a)
forall a. IsNum a => NumType a
numType FloatingType (EltR b)
forall a. IsFloating a => FloatingType a
floatingType

-- Other conversions

-- NOTE: Restricted to scalar types with a type-level BitSizeEq constraint to
-- make this version "safe"
mkBitcast :: forall b a. (Elt a, Elt b, IsScalar (EltR a), IsScalar (EltR b), BitSizeEq (EltR a) (EltR b)) => Exp a -> Exp b
mkBitcast :: Exp a -> Exp b
mkBitcast (Exp SmartExp (EltR a)
a) = PreSmartExp SmartAcc SmartExp (EltR b) -> Exp b
forall t. PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp (PreSmartExp SmartAcc SmartExp (EltR b) -> Exp b)
-> PreSmartExp SmartAcc SmartExp (EltR b) -> Exp b
forall a b. (a -> b) -> a -> b
$ ScalarType (EltR a)
-> ScalarType (EltR b)
-> SmartExp (EltR a)
-> PreSmartExp SmartAcc SmartExp (EltR b)
forall a b (exp :: * -> *) (acc :: * -> *).
BitSizeEq a b =>
ScalarType a -> ScalarType b -> exp a -> PreSmartExp acc exp b
Coerce (IsScalar (EltR a) => ScalarType (EltR a)
forall a. IsScalar a => ScalarType a
scalarType @(EltR a)) (IsScalar (EltR b) => ScalarType (EltR b)
forall a. IsScalar a => ScalarType a
scalarType @(EltR b)) SmartExp (EltR a)
a

mkCoerce :: Coerce (EltR a) (EltR b) => Exp a -> Exp b
mkCoerce :: Exp a -> Exp b
mkCoerce (Exp SmartExp (EltR a)
a) = SmartExp (EltR b) -> Exp b
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR b) -> Exp b) -> SmartExp (EltR b) -> Exp b
forall a b. (a -> b) -> a -> b
$ SmartExp (EltR a) -> SmartExp (EltR b)
forall a b. Coerce a b => SmartExp a -> SmartExp b
mkCoerce' SmartExp (EltR a)
a

class Coerce a b where
  mkCoerce' :: SmartExp a -> SmartExp b

instance {-# OVERLAPS #-} (IsScalar a, IsScalar b, BitSizeEq a b) => Coerce a b where
  mkCoerce' :: SmartExp a -> SmartExp b
mkCoerce' = PreSmartExp SmartAcc SmartExp b -> SmartExp b
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp b -> SmartExp b)
-> (SmartExp a -> PreSmartExp SmartAcc SmartExp b)
-> SmartExp a
-> SmartExp b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScalarType a
-> ScalarType b -> SmartExp a -> PreSmartExp SmartAcc SmartExp b
forall a b (exp :: * -> *) (acc :: * -> *).
BitSizeEq a b =>
ScalarType a -> ScalarType b -> exp a -> PreSmartExp acc exp b
Coerce (IsScalar a => ScalarType a
forall a. IsScalar a => ScalarType a
scalarType @a) (IsScalar b => ScalarType b
forall a. IsScalar a => ScalarType a
scalarType @b)

instance (Coerce a1 b1, Coerce a2 b2) => Coerce (a1, a2) (b1, b2) where
  mkCoerce' :: SmartExp (a1, a2) -> SmartExp (b1, b2)
mkCoerce' SmartExp (a1, a2)
a = PreSmartExp SmartAcc SmartExp (b1, b2) -> SmartExp (b1, b2)
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp (b1, b2) -> SmartExp (b1, b2))
-> PreSmartExp SmartAcc SmartExp (b1, b2) -> SmartExp (b1, b2)
forall a b. (a -> b) -> a -> b
$ SmartExp b1
-> SmartExp b2 -> PreSmartExp SmartAcc SmartExp (b1, b2)
forall (exp :: * -> *) t1 t2 (acc :: * -> *).
exp t1 -> exp t2 -> PreSmartExp acc exp (t1, t2)
Pair (SmartExp a1 -> SmartExp b1
forall a b. Coerce a b => SmartExp a -> SmartExp b
mkCoerce' (SmartExp a1 -> SmartExp b1) -> SmartExp a1 -> SmartExp b1
forall a b. (a -> b) -> a -> b
$ PreSmartExp SmartAcc SmartExp a1 -> SmartExp a1
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp a1 -> SmartExp a1)
-> PreSmartExp SmartAcc SmartExp a1 -> SmartExp a1
forall a b. (a -> b) -> a -> b
$ PairIdx (a1, a2) a1
-> SmartExp (a1, a2) -> PreSmartExp SmartAcc SmartExp a1
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (a1, a2) a1
forall a b. PairIdx (a, b) a
PairIdxLeft SmartExp (a1, a2)
a) (SmartExp a2 -> SmartExp b2
forall a b. Coerce a b => SmartExp a -> SmartExp b
mkCoerce' (SmartExp a2 -> SmartExp b2) -> SmartExp a2 -> SmartExp b2
forall a b. (a -> b) -> a -> b
$ PreSmartExp SmartAcc SmartExp a2 -> SmartExp a2
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp a2 -> SmartExp a2)
-> PreSmartExp SmartAcc SmartExp a2 -> SmartExp a2
forall a b. (a -> b) -> a -> b
$ PairIdx (a1, a2) a2
-> SmartExp (a1, a2) -> PreSmartExp SmartAcc SmartExp a2
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (a1, a2) a2
forall a b. PairIdx (a, b) b
PairIdxRight SmartExp (a1, a2)
a)

instance Coerce a a where
  mkCoerce' :: SmartExp a -> SmartExp a
mkCoerce' = SmartExp a -> SmartExp a
forall a. a -> a
id

instance Coerce ((), a) a where
  mkCoerce' :: SmartExp ((), a) -> SmartExp a
mkCoerce' SmartExp ((), a)
a = PreSmartExp SmartAcc SmartExp a -> SmartExp a
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp a -> SmartExp a)
-> PreSmartExp SmartAcc SmartExp a -> SmartExp a
forall a b. (a -> b) -> a -> b
$ PairIdx ((), a) a
-> SmartExp ((), a) -> PreSmartExp SmartAcc SmartExp a
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx ((), a) a
forall a b. PairIdx (a, b) b
PairIdxRight SmartExp ((), a)
a

instance Coerce a ((), a) where
  mkCoerce' :: SmartExp a -> SmartExp ((), a)
mkCoerce' = PreSmartExp SmartAcc SmartExp ((), a) -> SmartExp ((), a)
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp ((), a) -> SmartExp ((), a))
-> (SmartExp a -> PreSmartExp SmartAcc SmartExp ((), a))
-> SmartExp a
-> SmartExp ((), a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SmartExp () -> SmartExp a -> PreSmartExp SmartAcc SmartExp ((), a)
forall (exp :: * -> *) t1 t2 (acc :: * -> *).
exp t1 -> exp t2 -> PreSmartExp acc exp (t1, t2)
Pair (PreSmartExp SmartAcc SmartExp () -> SmartExp ()
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp PreSmartExp SmartAcc SmartExp ()
forall (acc :: * -> *) (exp :: * -> *). PreSmartExp acc exp ()
Nil)

instance Coerce (a, ()) a where
  mkCoerce' :: SmartExp (a, ()) -> SmartExp a
mkCoerce' SmartExp (a, ())
a = PreSmartExp SmartAcc SmartExp a -> SmartExp a
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp a -> SmartExp a)
-> PreSmartExp SmartAcc SmartExp a -> SmartExp a
forall a b. (a -> b) -> a -> b
$ PairIdx (a, ()) a
-> SmartExp (a, ()) -> PreSmartExp SmartAcc SmartExp a
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (a, ()) a
forall a b. PairIdx (a, b) a
PairIdxLeft SmartExp (a, ())
a

instance Coerce a (a, ()) where
  mkCoerce' :: SmartExp a -> SmartExp (a, ())
mkCoerce' SmartExp a
a = PreSmartExp SmartAcc SmartExp (a, ()) -> SmartExp (a, ())
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (SmartExp a -> SmartExp () -> PreSmartExp SmartAcc SmartExp (a, ())
forall (exp :: * -> *) t1 t2 (acc :: * -> *).
exp t1 -> exp t2 -> PreSmartExp acc exp (t1, t2)
Pair SmartExp a
a (PreSmartExp SmartAcc SmartExp () -> SmartExp ()
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp PreSmartExp SmartAcc SmartExp ()
forall (acc :: * -> *) (exp :: * -> *). PreSmartExp acc exp ()
Nil))



-- Auxiliary functions
-- --------------------

infixr 0 $$
($$) :: (b -> a) -> (c -> d -> b) -> c -> d -> a
(b -> a
f $$ :: (b -> a) -> (c -> d -> b) -> c -> d -> a
$$ c -> d -> b
g) c
x d
y = b -> a
f (c -> d -> b
g c
x d
y)

infixr 0 $$$
($$$) :: (b -> a) -> (c -> d -> e -> b) -> c -> d -> e -> a
(b -> a
f $$$ :: (b -> a) -> (c -> d -> e -> b) -> c -> d -> e -> a
$$$ c -> d -> e -> b
g) c
x d
y e
z = b -> a
f (c -> d -> e -> b
g c
x d
y e
z)

infixr 0 $$$$
($$$$) :: (b -> a) -> (c -> d -> e -> f -> b) -> c -> d -> e -> f -> a
(b -> a
f $$$$ :: (b -> a) -> (c -> d -> e -> f -> b) -> c -> d -> e -> f -> a
$$$$ c -> d -> e -> f -> b
g) c
x d
y e
z f
u = b -> a
f (c -> d -> e -> f -> b
g c
x d
y e
z f
u)

infixr 0 $$$$$
($$$$$) :: (b -> a) -> (c -> d -> e -> f -> g -> b) -> c -> d -> e -> f -> g-> a
(b -> a
f $$$$$ :: (b -> a)
-> (c -> d -> e -> f -> g -> b) -> c -> d -> e -> f -> g -> a
$$$$$ c -> d -> e -> f -> g -> b
g) c
x d
y e
z f
u g
v = b -> a
f (c -> d -> e -> f -> g -> b
g c
x d
y e
z f
u g
v)

unAcc :: Arrays a => Acc a -> SmartAcc (Sugar.ArraysR a)
unAcc :: Acc a -> SmartAcc (ArraysR a)
unAcc (Acc SmartAcc (ArraysR a)
a) = SmartAcc (ArraysR a)
a

unAccFunction :: (Arrays a, Arrays b) => (Acc a -> Acc b) -> SmartAcc (Sugar.ArraysR a) -> SmartAcc (Sugar.ArraysR b)
unAccFunction :: (Acc a -> Acc b) -> SmartAcc (ArraysR a) -> SmartAcc (ArraysR b)
unAccFunction Acc a -> Acc b
f = Acc b -> SmartAcc (ArraysR b)
forall a. Arrays a => Acc a -> SmartAcc (ArraysR a)
unAcc (Acc b -> SmartAcc (ArraysR b))
-> (SmartAcc (ArraysR a) -> Acc b)
-> SmartAcc (ArraysR a)
-> SmartAcc (ArraysR b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Acc a -> Acc b
f (Acc a -> Acc b)
-> (SmartAcc (ArraysR a) -> Acc a) -> SmartAcc (ArraysR a) -> Acc b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SmartAcc (ArraysR a) -> Acc a
forall a. SmartAcc (ArraysR a) -> Acc a
Acc

mkExp :: PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp :: PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp = SmartExp (EltR t) -> Exp t
forall t. SmartExp (EltR t) -> Exp t
Exp (SmartExp (EltR t) -> Exp t)
-> (PreSmartExp SmartAcc SmartExp (EltR t) -> SmartExp (EltR t))
-> PreSmartExp SmartAcc SmartExp (EltR t)
-> Exp t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PreSmartExp SmartAcc SmartExp (EltR t) -> SmartExp (EltR t)
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp

unExp :: Exp e -> SmartExp (EltR e)
unExp :: Exp e -> SmartExp (EltR e)
unExp (Exp SmartExp (EltR e)
e) = SmartExp (EltR e)
e

unExpFunction :: (Elt a, Elt b) => (Exp a -> Exp b) -> SmartExp (EltR a) -> SmartExp (EltR b)
unExpFunction :: (Exp a -> Exp b) -> SmartExp (EltR a) -> SmartExp (EltR b)
unExpFunction Exp a -> Exp b
f = Exp b -> SmartExp (EltR b)
forall e. Exp e -> SmartExp (EltR e)
unExp (Exp b -> SmartExp (EltR b))
-> (SmartExp (EltR a) -> Exp b)
-> SmartExp (EltR a)
-> SmartExp (EltR b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Exp a -> Exp b
f (Exp a -> Exp b)
-> (SmartExp (EltR a) -> Exp a) -> SmartExp (EltR a) -> Exp b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SmartExp (EltR a) -> Exp a
forall t. SmartExp (EltR t) -> Exp t
Exp

unExpBinaryFunction :: (Elt a, Elt b, Elt c) => (Exp a -> Exp b -> Exp c) -> SmartExp (EltR a) -> SmartExp (EltR b) -> SmartExp (EltR c)
unExpBinaryFunction :: (Exp a -> Exp b -> Exp c)
-> SmartExp (EltR a) -> SmartExp (EltR b) -> SmartExp (EltR c)
unExpBinaryFunction Exp a -> Exp b -> Exp c
f SmartExp (EltR a)
a SmartExp (EltR b)
b = Exp c -> SmartExp (EltR c)
forall e. Exp e -> SmartExp (EltR e)
unExp (Exp c -> SmartExp (EltR c)) -> Exp c -> SmartExp (EltR c)
forall a b. (a -> b) -> a -> b
$ Exp a -> Exp b -> Exp c
f (SmartExp (EltR a) -> Exp a
forall t. SmartExp (EltR t) -> Exp t
Exp SmartExp (EltR a)
a) (SmartExp (EltR b) -> Exp b
forall t. SmartExp (EltR t) -> Exp t
Exp SmartExp (EltR b)
b)

mkPrimUnary :: (Elt a, Elt b) => PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary :: PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary PrimFun (EltR a -> EltR b)
prim (Exp SmartExp (EltR a)
a) = PreSmartExp SmartAcc SmartExp (EltR b) -> Exp b
forall t. PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp (PreSmartExp SmartAcc SmartExp (EltR b) -> Exp b)
-> PreSmartExp SmartAcc SmartExp (EltR b) -> Exp b
forall a b. (a -> b) -> a -> b
$ PrimFun (EltR a -> EltR b)
-> SmartExp (EltR a) -> PreSmartExp SmartAcc SmartExp (EltR b)
forall a r (exp :: * -> *) (acc :: * -> *).
PrimFun (a -> r) -> exp a -> PreSmartExp acc exp r
PrimApp PrimFun (EltR a -> EltR b)
prim SmartExp (EltR a)
a

mkPrimBinary :: (Elt a, Elt b, Elt c) => PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary :: PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary PrimFun ((EltR a, EltR b) -> EltR c)
prim (Exp SmartExp (EltR a)
a) (Exp SmartExp (EltR b)
b) = PreSmartExp SmartAcc SmartExp (EltR c) -> Exp c
forall t. PreSmartExp SmartAcc SmartExp (EltR t) -> Exp t
mkExp (PreSmartExp SmartAcc SmartExp (EltR c) -> Exp c)
-> PreSmartExp SmartAcc SmartExp (EltR c) -> Exp c
forall a b. (a -> b) -> a -> b
$ PrimFun ((EltR a, EltR b) -> EltR c)
-> SmartExp (EltR a, EltR b)
-> PreSmartExp SmartAcc SmartExp (EltR c)
forall a r (exp :: * -> *) (acc :: * -> *).
PrimFun (a -> r) -> exp a -> PreSmartExp acc exp r
PrimApp PrimFun ((EltR a, EltR b) -> EltR c)
prim (PreSmartExp SmartAcc SmartExp (EltR a, EltR b)
-> SmartExp (EltR a, EltR b)
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp (EltR a, EltR b)
 -> SmartExp (EltR a, EltR b))
-> PreSmartExp SmartAcc SmartExp (EltR a, EltR b)
-> SmartExp (EltR a, EltR b)
forall a b. (a -> b) -> a -> b
$ SmartExp (EltR a)
-> SmartExp (EltR b)
-> PreSmartExp SmartAcc SmartExp (EltR a, EltR b)
forall (exp :: * -> *) t1 t2 (acc :: * -> *).
exp t1 -> exp t2 -> PreSmartExp acc exp (t1, t2)
Pair SmartExp (EltR a)
a SmartExp (EltR b)
b)

mkPrimUnaryBool :: Elt a => PrimFun (EltR a -> PrimBool) -> Exp a -> Exp Bool
mkPrimUnaryBool :: PrimFun (EltR a -> PrimBool) -> Exp a -> Exp Bool
mkPrimUnaryBool = forall b. Coerce (EltR PrimBool) (EltR b) => Exp PrimBool -> Exp b
forall a b. Coerce (EltR a) (EltR b) => Exp a -> Exp b
mkCoerce @PrimBool (Exp PrimBool -> Exp Bool)
-> (PrimFun (EltR a -> PrimBool) -> Exp a -> Exp PrimBool)
-> PrimFun (EltR a -> PrimBool)
-> Exp a
-> Exp Bool
forall b a c d. (b -> a) -> (c -> d -> b) -> c -> d -> a
$$ PrimFun (EltR a -> PrimBool) -> Exp a -> Exp PrimBool
forall a b.
(Elt a, Elt b) =>
PrimFun (EltR a -> EltR b) -> Exp a -> Exp b
mkPrimUnary

mkPrimBinaryBool :: (Elt a, Elt b) => PrimFun ((EltR a, EltR b) -> PrimBool) -> Exp a -> Exp b -> Exp Bool
mkPrimBinaryBool :: PrimFun ((EltR a, EltR b) -> PrimBool)
-> Exp a -> Exp b -> Exp Bool
mkPrimBinaryBool = forall b. Coerce (EltR PrimBool) (EltR b) => Exp PrimBool -> Exp b
forall a b. Coerce (EltR a) (EltR b) => Exp a -> Exp b
mkCoerce @PrimBool (Exp PrimBool -> Exp Bool)
-> (PrimFun ((EltR a, EltR b) -> PrimBool)
    -> Exp a -> Exp b -> Exp PrimBool)
-> PrimFun ((EltR a, EltR b) -> PrimBool)
-> Exp a
-> Exp b
-> Exp Bool
forall b a c d e.
(b -> a) -> (c -> d -> e -> b) -> c -> d -> e -> a
$$$ PrimFun ((EltR a, EltR b) -> PrimBool)
-> Exp a -> Exp b -> Exp PrimBool
forall a b c.
(Elt a, Elt b, Elt c) =>
PrimFun ((EltR a, EltR b) -> EltR c) -> Exp a -> Exp b -> Exp c
mkPrimBinary

unPair :: SmartExp (a, b) -> (SmartExp a, SmartExp b)
unPair :: SmartExp (a, b) -> (SmartExp a, SmartExp b)
unPair SmartExp (a, b)
e = (PreSmartExp SmartAcc SmartExp a -> SmartExp a
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp a -> SmartExp a)
-> PreSmartExp SmartAcc SmartExp a -> SmartExp a
forall a b. (a -> b) -> a -> b
$ PairIdx (a, b) a
-> SmartExp (a, b) -> PreSmartExp SmartAcc SmartExp a
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (a, b) a
forall a b. PairIdx (a, b) a
PairIdxLeft SmartExp (a, b)
e, PreSmartExp SmartAcc SmartExp b -> SmartExp b
forall t. PreSmartExp SmartAcc SmartExp t -> SmartExp t
SmartExp (PreSmartExp SmartAcc SmartExp b -> SmartExp b)
-> PreSmartExp SmartAcc SmartExp b -> SmartExp b
forall a b. (a -> b) -> a -> b
$ PairIdx (a, b) b
-> SmartExp (a, b) -> PreSmartExp SmartAcc SmartExp b
forall t1 t2 t (exp :: * -> *) (acc :: * -> *).
PairIdx (t1, t2) t -> exp (t1, t2) -> PreSmartExp acc exp t
Prj PairIdx (a, b) b
forall a b. PairIdx (a, b) b
PairIdxRight SmartExp (a, b)
e)

mkPairToTuple :: SmartAcc (a, b) -> SmartAcc (((), a), b)
mkPairToTuple :: SmartAcc (a, b) -> SmartAcc (((), a), b)
mkPairToTuple SmartAcc (a, b)
e = PreSmartAcc SmartAcc SmartExp () -> SmartAcc ()
forall a. PreSmartAcc SmartAcc SmartExp a -> SmartAcc a
SmartAcc PreSmartAcc SmartAcc SmartExp ()
forall (acc :: * -> *) (exp :: * -> *). PreSmartAcc acc exp ()
Anil SmartAcc () -> SmartAcc a -> SmartAcc ((), a)
forall arrs1 arrs2.
SmartAcc arrs1 -> SmartAcc arrs2 -> SmartAcc (arrs1, arrs2)
`pair` SmartAcc a
a SmartAcc ((), a) -> SmartAcc b -> SmartAcc (((), a), b)
forall arrs1 arrs2.
SmartAcc arrs1 -> SmartAcc arrs2 -> SmartAcc (arrs1, arrs2)
`pair` SmartAcc b
b
  where
    a :: SmartAcc a
a = PreSmartAcc SmartAcc SmartExp a -> SmartAcc a
forall a. PreSmartAcc SmartAcc SmartExp a -> SmartAcc a
SmartAcc (PreSmartAcc SmartAcc SmartExp a -> SmartAcc a)
-> PreSmartAcc SmartAcc SmartExp a -> SmartAcc a
forall a b. (a -> b) -> a -> b
$ PairIdx (a, b) a
-> SmartAcc (a, b) -> PreSmartAcc SmartAcc SmartExp a
forall arrs1 arrs2 arrs (acc :: * -> *) (exp :: * -> *).
PairIdx (arrs1, arrs2) arrs
-> acc (arrs1, arrs2) -> PreSmartAcc acc exp arrs
Aprj PairIdx (a, b) a
forall a b. PairIdx (a, b) a
PairIdxLeft SmartAcc (a, b)
e
    b :: SmartAcc b
b = PreSmartAcc SmartAcc SmartExp b -> SmartAcc b
forall a. PreSmartAcc SmartAcc SmartExp a -> SmartAcc a
SmartAcc (PreSmartAcc SmartAcc SmartExp b -> SmartAcc b)
-> PreSmartAcc SmartAcc SmartExp b -> SmartAcc b
forall a b. (a -> b) -> a -> b
$ PairIdx (a, b) b
-> SmartAcc (a, b) -> PreSmartAcc SmartAcc SmartExp b
forall arrs1 arrs2 arrs (acc :: * -> *) (exp :: * -> *).
PairIdx (arrs1, arrs2) arrs
-> acc (arrs1, arrs2) -> PreSmartAcc acc exp arrs
Aprj PairIdx (a, b) b
forall a b. PairIdx (a, b) b
PairIdxRight SmartAcc (a, b)
e
    pair :: SmartAcc arrs1 -> SmartAcc arrs2 -> SmartAcc (arrs1, arrs2)
pair SmartAcc arrs1
x SmartAcc arrs2
y = PreSmartAcc SmartAcc SmartExp (arrs1, arrs2)
-> SmartAcc (arrs1, arrs2)
forall a. PreSmartAcc SmartAcc SmartExp a -> SmartAcc a
SmartAcc (PreSmartAcc SmartAcc SmartExp (arrs1, arrs2)
 -> SmartAcc (arrs1, arrs2))
-> PreSmartAcc SmartAcc SmartExp (arrs1, arrs2)
-> SmartAcc (arrs1, arrs2)
forall a b. (a -> b) -> a -> b
$ SmartAcc arrs1
-> SmartAcc arrs2 -> PreSmartAcc SmartAcc SmartExp (arrs1, arrs2)
forall (acc :: * -> *) arrs1 arrs2 (exp :: * -> *).
acc arrs1 -> acc arrs2 -> PreSmartAcc acc exp (arrs1, arrs2)
Apair SmartAcc arrs1
x SmartAcc arrs2
y

class ApplyAcc a where
  type FromApplyAcc a
  applyAcc :: FromApplyAcc a -> a

instance ApplyAcc (SmartAcc a) where
  type FromApplyAcc (SmartAcc a) = PreSmartAcc SmartAcc SmartExp a
  applyAcc :: FromApplyAcc (SmartAcc a) -> SmartAcc a
applyAcc = FromApplyAcc (SmartAcc a) -> SmartAcc a
forall a. PreSmartAcc SmartAcc SmartExp a -> SmartAcc a
SmartAcc

instance (Arrays a, ApplyAcc t) => ApplyAcc (Acc a -> t) where
  type FromApplyAcc (Acc a -> t) = SmartAcc (Sugar.ArraysR a) -> FromApplyAcc t
  applyAcc :: FromApplyAcc (Acc a -> t) -> Acc a -> t
applyAcc FromApplyAcc (Acc a -> t)
f Acc a
a = FromApplyAcc t -> t
forall a. ApplyAcc a => FromApplyAcc a -> a
applyAcc (FromApplyAcc t -> t) -> FromApplyAcc t -> t
forall a b. (a -> b) -> a -> b
$ FromApplyAcc (Acc a -> t)
SmartAcc (ArraysR a) -> FromApplyAcc t
f (Acc a -> SmartAcc (ArraysR a)
forall a. Arrays a => Acc a -> SmartAcc (ArraysR a)
unAcc Acc a
a)

instance (Elt a, ApplyAcc t) => ApplyAcc (Exp a -> t) where
  type FromApplyAcc (Exp a -> t) = SmartExp (EltR a) -> FromApplyAcc t
  applyAcc :: FromApplyAcc (Exp a -> t) -> Exp a -> t
applyAcc FromApplyAcc (Exp a -> t)
f Exp a
a = FromApplyAcc t -> t
forall a. ApplyAcc a => FromApplyAcc a -> a
applyAcc (FromApplyAcc t -> t) -> FromApplyAcc t -> t
forall a b. (a -> b) -> a -> b
$ FromApplyAcc (Exp a -> t)
SmartExp (EltR a) -> FromApplyAcc t
f (Exp a -> SmartExp (EltR a)
forall e. Exp e -> SmartExp (EltR e)
unExp Exp a
a)

instance (Elt a, Elt b, ApplyAcc t) => ApplyAcc ((Exp a -> Exp b) -> t) where
  type FromApplyAcc ((Exp a -> Exp b) -> t) = (SmartExp (EltR a) -> SmartExp (EltR b)) -> FromApplyAcc t
  applyAcc :: FromApplyAcc ((Exp a -> Exp b) -> t) -> (Exp a -> Exp b) -> t
applyAcc FromApplyAcc ((Exp a -> Exp b) -> t)
f Exp a -> Exp b
a = FromApplyAcc t -> t
forall a. ApplyAcc a => FromApplyAcc a -> a
applyAcc (FromApplyAcc t -> t) -> FromApplyAcc t -> t
forall a b. (a -> b) -> a -> b
$ FromApplyAcc ((Exp a -> Exp b) -> t)
(SmartExp (EltR a) -> SmartExp (EltR b)) -> FromApplyAcc t
f ((Exp a -> Exp b) -> SmartExp (EltR a) -> SmartExp (EltR b)
forall a b.
(Elt a, Elt b) =>
(Exp a -> Exp b) -> SmartExp (EltR a) -> SmartExp (EltR b)
unExpFunction Exp a -> Exp b
a)

instance (Elt a, Elt b, Elt c, ApplyAcc t) => ApplyAcc ((Exp a -> Exp b -> Exp c) -> t) where
  type FromApplyAcc ((Exp a -> Exp b -> Exp c) -> t) = (SmartExp (EltR a) -> SmartExp (EltR b) -> SmartExp (EltR c)) -> FromApplyAcc t
  applyAcc :: FromApplyAcc ((Exp a -> Exp b -> Exp c) -> t)
-> (Exp a -> Exp b -> Exp c) -> t
applyAcc FromApplyAcc ((Exp a -> Exp b -> Exp c) -> t)
f Exp a -> Exp b -> Exp c
a = FromApplyAcc t -> t
forall a. ApplyAcc a => FromApplyAcc a -> a
applyAcc (FromApplyAcc t -> t) -> FromApplyAcc t -> t
forall a b. (a -> b) -> a -> b
$ FromApplyAcc ((Exp a -> Exp b -> Exp c) -> t)
(SmartExp (EltR a) -> SmartExp (EltR b) -> SmartExp (EltR c))
-> FromApplyAcc t
f ((Exp a -> Exp b -> Exp c)
-> SmartExp (EltR a) -> SmartExp (EltR b) -> SmartExp (EltR c)
forall a b c.
(Elt a, Elt b, Elt c) =>
(Exp a -> Exp b -> Exp c)
-> SmartExp (EltR a) -> SmartExp (EltR b) -> SmartExp (EltR c)
unExpBinaryFunction Exp a -> Exp b -> Exp c
a)

instance (Arrays a, Arrays b, ApplyAcc t) => ApplyAcc ((Acc a -> Acc b) -> t) where
  type FromApplyAcc ((Acc a -> Acc b) -> t) = (SmartAcc (Sugar.ArraysR a) -> SmartAcc (Sugar.ArraysR b)) -> FromApplyAcc t
  applyAcc :: FromApplyAcc ((Acc a -> Acc b) -> t) -> (Acc a -> Acc b) -> t
applyAcc FromApplyAcc ((Acc a -> Acc b) -> t)
f Acc a -> Acc b
a = FromApplyAcc t -> t
forall a. ApplyAcc a => FromApplyAcc a -> a
applyAcc (FromApplyAcc t -> t) -> FromApplyAcc t -> t
forall a b. (a -> b) -> a -> b
$ FromApplyAcc ((Acc a -> Acc b) -> t)
(SmartAcc (ArraysR a) -> SmartAcc (ArraysR b)) -> FromApplyAcc t
f ((Acc a -> Acc b) -> SmartAcc (ArraysR a) -> SmartAcc (ArraysR b)
forall a b.
(Arrays a, Arrays b) =>
(Acc a -> Acc b) -> SmartAcc (ArraysR a) -> SmartAcc (ArraysR b)
unAccFunction Acc a -> Acc b
a)


-- Debugging
-- ---------

showPreAccOp :: forall acc exp arrs. PreSmartAcc acc exp arrs -> String
showPreAccOp :: PreSmartAcc acc exp arrs -> [Char]
showPreAccOp (Atag ArraysR arrs
_ Int
i)            = [Char]
"Atag " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
i
showPreAccOp (Use ArrayR (Array sh e)
aR Array sh e
a)            = [Char]
"Use "  [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int
-> (e -> [Char] -> [Char])
-> ArrayR (Array sh e)
-> Array sh e
-> [Char]
forall e sh.
Int
-> (e -> [Char] -> [Char])
-> ArrayR (Array sh e)
-> Array sh e
-> [Char]
showArrayShort Int
5 (TypeR e -> e -> [Char] -> [Char]
forall e. TypeR e -> e -> [Char] -> [Char]
showsElt (ArrayR (Array sh e) -> TypeR e
forall sh e. ArrayR (Array sh e) -> TypeR e
arrayRtype ArrayR (Array sh e)
aR)) ArrayR (Array sh e)
aR Array sh e
a
showPreAccOp Pipe{}                = [Char]
"Pipe"
showPreAccOp Acond{}               = [Char]
"Acond"
showPreAccOp Awhile{}              = [Char]
"Awhile"
showPreAccOp Apair{}               = [Char]
"Apair"
showPreAccOp Anil{}                = [Char]
"Anil"
showPreAccOp Aprj{}                = [Char]
"Aprj"
showPreAccOp Unit{}                = [Char]
"Unit"
showPreAccOp Generate{}            = [Char]
"Generate"
showPreAccOp Reshape{}             = [Char]
"Reshape"
showPreAccOp Replicate{}           = [Char]
"Replicate"
showPreAccOp Slice{}               = [Char]
"Slice"
showPreAccOp Map{}                 = [Char]
"Map"
showPreAccOp ZipWith{}             = [Char]
"ZipWith"
showPreAccOp (Fold TypeR e
_ SmartExp e -> SmartExp e -> exp e
_ Maybe (exp e)
z acc (Array (sh, Int) e)
_)        = [Char]
"Fold" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> (exp e -> [Char]) -> Maybe (exp e) -> [Char]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [Char]
"1" ([Char] -> exp e -> [Char]
forall a b. a -> b -> a
const [Char]
"") Maybe (exp e)
z
showPreAccOp (FoldSeg IntegralType i
_ TypeR e
_ SmartExp e -> SmartExp e -> exp e
_ Maybe (exp e)
z acc (Array (sh, Int) e)
_ acc (Segments i)
_) = [Char]
"Fold" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> (exp e -> [Char]) -> Maybe (exp e) -> [Char]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [Char]
"1" ([Char] -> exp e -> [Char]
forall a b. a -> b -> a
const [Char]
"") Maybe (exp e)
z [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"Seg"
showPreAccOp (Scan Direction
d TypeR e
_ SmartExp e -> SmartExp e -> exp e
_ Maybe (exp e)
z acc (Array (sh, Int) e)
_)      = [Char]
"Scan" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Direction -> [Char] -> [Char]
showsDirection Direction
d ([Char] -> (exp e -> [Char]) -> Maybe (exp e) -> [Char]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [Char]
"1" ([Char] -> exp e -> [Char]
forall a b. a -> b -> a
const [Char]
"") Maybe (exp e)
z)
showPreAccOp (Scan' Direction
d TypeR e
_ SmartExp e -> SmartExp e -> exp e
_ exp e
_ acc (Array (sh, Int) e)
_)     = [Char]
"Scan" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Direction -> [Char] -> [Char]
showsDirection Direction
d [Char]
"'"
showPreAccOp Permute{}             = [Char]
"Permute"
showPreAccOp Backpermute{}         = [Char]
"Backpermute"
showPreAccOp Stencil{}             = [Char]
"Stencil"
showPreAccOp Stencil2{}            = [Char]
"Stencil2"
showPreAccOp Aforeign{}            = [Char]
"Aforeign"

showsDirection :: Direction -> ShowS
showsDirection :: Direction -> [Char] -> [Char]
showsDirection Direction
LeftToRight = (Char
'l'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:)
showsDirection Direction
RightToLeft = (Char
'r'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:)

showPreExpOp :: PreSmartExp acc exp t -> String
showPreExpOp :: PreSmartExp acc exp t -> [Char]
showPreExpOp (Tag TypeR t
_ Int
i)          = [Char]
"Tag" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
i
showPreExpOp Match{}            = [Char]
"Match"
showPreExpOp (Const ScalarType t
t t
c)        = [Char]
"Const " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ TypeR t -> t -> [Char]
forall e. TypeR e -> e -> [Char]
showElt (ScalarType t -> TypeR t
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle ScalarType t
t) t
c
showPreExpOp (Undef ScalarType t
_)          = [Char]
"Undef"
showPreExpOp Nil{}              = [Char]
"Nil"
showPreExpOp Pair{}             = [Char]
"Pair"
showPreExpOp Prj{}              = [Char]
"Prj"
showPreExpOp VecPack{}          = [Char]
"VecPack"
showPreExpOp VecUnpack{}        = [Char]
"VecUnpack"
showPreExpOp ToIndex{}          = [Char]
"ToIndex"
showPreExpOp FromIndex{}        = [Char]
"FromIndex"
showPreExpOp Case{}             = [Char]
"Case"
showPreExpOp Cond{}             = [Char]
"Cond"
showPreExpOp While{}            = [Char]
"While"
showPreExpOp PrimConst{}        = [Char]
"PrimConst"
showPreExpOp PrimApp{}          = [Char]
"PrimApp"
showPreExpOp Index{}            = [Char]
"Index"
showPreExpOp LinearIndex{}      = [Char]
"LinearIndex"
showPreExpOp Shape{}            = [Char]
"Shape"
showPreExpOp ShapeSize{}        = [Char]
"ShapeSize"
showPreExpOp Foreign{}          = [Char]
"Foreign"
showPreExpOp Coerce{}           = [Char]
"Coerce"