module Data.Array.Accelerate.Language (
  
  Acc, Exp,                                 
  
  
  Boundary(..), Stencil,                    
  
  Stencil3, Stencil5, Stencil7, Stencil9,
  Stencil3x3, Stencil5x3, Stencil3x5, Stencil5x5,
  Stencil3x3x3, Stencil5x3x3, Stencil3x5x3, Stencil3x3x5, Stencil5x5x3, Stencil5x3x5,
  Stencil3x5x5, Stencil5x5x5,
  
  constant,                                 
  
  use, unit, replicate, generate,
  fstA, sndA, pairA,
  
  reshape,
  
  slice, 
  
  
  map, zipWith,
  
  
  fold, fold1, foldSeg, fold1Seg,
  
  
  scanl, scanl', scanl1, scanr, scanr', scanr1,
  
  
  permute, backpermute, 
  
  
  stencil, stencil2,
  
  
  (>->),
  
  
  cond, (?|),
  
  Lift(..), Unlift(..), lift1, lift2, ilift1, ilift2,
  
  
  fst, snd, curry, uncurry,
  
  
  index0, index1, unindex1,
  
  
  (?),
  
  
  (!), the, shape, size,
  
  
  (==*), (/=*), (<*), (<=*), (>*), (>=*), max, min,
  bit, setBit, clearBit, complementBit, testBit,
  shift,  shiftL,  shiftR,
  rotate, rotateL, rotateR,
  truncate, round, floor, ceiling,
  
  (&&*), (||*), not,
  
  
  boolToInt, fromIntegral,
  
  ignore
  
  
) where
import Prelude   hiding (replicate, zip, unzip, map, scanl, scanl1, scanr, scanr1, zipWith,
                         filter, max, min, not, fst, snd, curry, uncurry,
                         truncate, round, floor, ceiling, fromIntegral)
import Data.Bits (Bits((.&.), (.|.), xor, complement))
import Data.Array.Accelerate.Type
import Data.Array.Accelerate.Tuple
import Data.Array.Accelerate.Array.Sugar hiding ((!), ignore, shape, size, index)
import qualified Data.Array.Accelerate.Array.Sugar as Sugar
import Data.Array.Accelerate.Smart
import Data.Array.Accelerate.AST (Arrays)
use :: (Shape ix, Elt e) => Array ix e -> Acc (Array ix e)
use = Acc . Use
unit :: Elt e => Exp e -> Acc (Scalar e)
unit = Acc . Unit
replicate :: (Slice slix, Elt e) 
          => Exp slix 
          -> Acc (Array (SliceShape slix) e) 
          -> Acc (Array (FullShape  slix) e)
replicate = Acc $$ Replicate
generate :: (Shape ix, Elt a)
         => Exp ix
         -> (Exp ix -> Exp a)
         -> Acc (Array ix a)
generate = Acc $$ Generate
reshape :: (Shape ix, Shape ix', Elt e) 
        => Exp ix 
        -> Acc (Array ix' e) 
        -> Acc (Array ix e)
reshape = Acc $$ Reshape
slice :: (Slice slix, Elt e) 
      => Acc (Array (FullShape slix) e) 
      -> Exp slix 
      -> Acc (Array (SliceShape slix) e)
slice = Acc $$ Index
map :: (Shape ix, Elt a, Elt b) 
    => (Exp a -> Exp b) 
    -> Acc (Array ix a)
    -> Acc (Array ix b)
map = Acc $$ Map
zipWith :: (Shape ix, Elt a, Elt b, Elt c)
        => (Exp a -> Exp b -> Exp c) 
        -> Acc (Array ix a)
        -> Acc (Array ix b)
        -> Acc (Array ix c)
zipWith = Acc $$$ ZipWith
fold :: (Shape ix, Elt a)
     => (Exp a -> Exp a -> Exp a) 
     -> Exp a 
     -> Acc (Array (ix:.Int) a)
     -> Acc (Array ix a)
fold = Acc $$$ Fold
fold1 :: (Shape ix, Elt a)
      => (Exp a -> Exp a -> Exp a) 
      -> Acc (Array (ix:.Int) a)
      -> Acc (Array ix a)
fold1 = Acc $$ Fold1
foldSeg :: (Shape ix, Elt a)
        => (Exp a -> Exp a -> Exp a) 
        -> Exp a 
        -> Acc (Array (ix:.Int) a)
        -> Acc Segments
        -> Acc (Array (ix:.Int) a)
foldSeg = Acc $$$$ FoldSeg
fold1Seg :: (Shape ix, Elt a)
         => (Exp a -> Exp a -> Exp a) 
         -> Acc (Array (ix:.Int) a)
         -> Acc Segments
         -> Acc (Array (ix:.Int) a)
fold1Seg = Acc $$$ Fold1Seg
scanl :: Elt a
      => (Exp a -> Exp a -> Exp a)
      -> Exp a
      -> Acc (Vector a)
      -> Acc (Vector a)
scanl = Acc $$$ Scanl
scanl' :: Elt a
       => (Exp a -> Exp a -> Exp a)
       -> Exp a
       -> Acc (Vector a)
       -> (Acc (Vector a), Acc (Scalar a))
scanl' = unpair . Acc $$$ Scanl'
scanl1 :: Elt a
       => (Exp a -> Exp a -> Exp a)
       -> Acc (Vector a)
       -> Acc (Vector a)
scanl1 = Acc $$ Scanl1
scanr :: Elt a
      => (Exp a -> Exp a -> Exp a)
      -> Exp a
      -> Acc (Vector a)
      -> Acc (Vector a)
scanr = Acc $$$ Scanr
scanr' :: Elt a
       => (Exp a -> Exp a -> Exp a)
       -> Exp a
       -> Acc (Vector a)
       -> (Acc (Vector a), Acc (Scalar a))
scanr' = unpair . Acc $$$ Scanr'
scanr1 :: Elt a
       => (Exp a -> Exp a -> Exp a)
       -> Acc (Vector a)
       -> Acc (Vector a)
scanr1 = Acc $$ Scanr1
permute :: (Shape ix, Shape ix', Elt a)
        => (Exp a -> Exp a -> Exp a)    
        -> Acc (Array ix' a)            
        -> (Exp ix -> Exp ix')          
        -> Acc (Array ix  a)            
        -> Acc (Array ix' a)
permute = Acc $$$$ Permute
backpermute :: (Shape ix, Shape ix', Elt a)
            => Exp ix'                  
            -> (Exp ix' -> Exp ix)      
            -> Acc (Array ix  a)        
            -> Acc (Array ix' a)
backpermute = Acc $$$ Backpermute
type Stencil3 a = (Exp a, Exp a, Exp a)
type Stencil5 a = (Exp a, Exp a, Exp a, Exp a, Exp a)
type Stencil7 a = (Exp a, Exp a, Exp a, Exp a, Exp a, Exp a, Exp a)
type Stencil9 a = (Exp a, Exp a, Exp a, Exp a, Exp a, Exp a, Exp a, Exp a, Exp a)
type Stencil3x3 a = (Stencil3 a, Stencil3 a, Stencil3 a)
type Stencil5x3 a = (Stencil5 a, Stencil5 a, Stencil5 a)
type Stencil3x5 a = (Stencil3 a, Stencil3 a, Stencil3 a, Stencil3 a, Stencil3 a)
type Stencil5x5 a = (Stencil5 a, Stencil5 a, Stencil5 a, Stencil5 a, Stencil5 a)
type Stencil3x3x3 a = (Stencil3x3 a, Stencil3x3 a, Stencil3x3 a)
type Stencil5x3x3 a = (Stencil5x3 a, Stencil5x3 a, Stencil5x3 a)
type Stencil3x5x3 a = (Stencil3x5 a, Stencil3x5 a, Stencil3x5 a)
type Stencil3x3x5 a = (Stencil3x3 a, Stencil3x3 a, Stencil3x3 a, Stencil3x3 a, Stencil3x3 a)
type Stencil5x5x3 a = (Stencil5x5 a, Stencil5x5 a, Stencil5x5 a)
type Stencil5x3x5 a = (Stencil5x3 a, Stencil5x3 a, Stencil5x3 a, Stencil5x3 a, Stencil5x3 a)
type Stencil3x5x5 a = (Stencil3x5 a, Stencil3x5 a, Stencil3x5 a, Stencil3x5 a, Stencil3x5 a)
type Stencil5x5x5 a = (Stencil5x5 a, Stencil5x5 a, Stencil5x5 a, Stencil5x5 a, Stencil5x5 a)
stencil :: (Shape ix, Elt a, Elt b, Stencil ix a stencil)
        => (stencil -> Exp b)                 
        -> Boundary a                         
        -> Acc (Array ix a)                   
        -> Acc (Array ix b)                   
stencil = Acc $$$ Stencil
stencil2 :: (Shape ix, Elt a, Elt b, Elt c, 
             Stencil ix a stencil1, 
             Stencil ix b stencil2)
        => (stencil1 -> stencil2 -> Exp c)    
        -> Boundary a                         
        -> Acc (Array ix a)                   
        -> Boundary b                         
        -> Acc (Array ix b)                   
        -> Acc (Array ix c)                   
stencil2 = Acc $$$$$ Stencil2
infixl 1 >->
(>->) :: (Arrays a, Arrays b, Arrays c) => (Acc a -> Acc b) -> (Acc b -> Acc c) -> (Acc a -> Acc c)
(>->) = Acc $$$ Pipe
cond :: (Arrays a)
     => Exp Bool          
     -> Acc a             
     -> Acc a             
     -> Acc a
cond = Acc $$$ Acond
infix 0 ?|
(?|) :: (Arrays a) => Exp Bool -> (Acc a, Acc a) -> Acc a
c ?| (t, e) = cond c t e
fstA :: (Shape sh1, Shape sh2, Elt e1, Elt e2)
     => Acc (Array sh1 e1, Array sh2 e2)
     -> Acc (Array sh1 e1)
fstA = Acc . FstArray
sndA :: (Shape sh1, Shape sh2, Elt e1, Elt e2)
     => Acc (Array sh1 e1, Array sh2 e2)
     -> Acc (Array sh2 e2)
sndA = Acc . SndArray
pairA :: (Shape sh1, Shape sh2, Elt e1, Elt e2)
      => Acc (Array sh1 e1)
      -> Acc (Array sh2 e2)
      -> Acc (Array sh1 e1, Array sh2 e2)
pairA = Acc $$ PairArrays
class Lift e where
  type Plain e
  
  
  lift :: e -> Exp (Plain e)
  
class Lift e => Unlift e where
  
  
  
  unlift :: Exp (Plain e) -> e
instance Lift () where
  type Plain () = ()
  lift _ = Tuple NilTup
instance Unlift () where
  unlift _ = ()
instance Lift Z where
  type Plain Z = Z
  lift _ = IndexNil
instance Unlift Z where
  unlift _ = Z
instance (Slice (Plain ix), Lift ix) => Lift (ix :. Int) where
  type Plain (ix :. Int) = Plain ix :. Int
  lift (ix:.i) = IndexCons (lift ix) (Const i)
instance (Slice (Plain ix), Lift ix) => Lift (ix :. All) where
  type Plain (ix :. All) = Plain ix :. All
  lift (ix:.i) = IndexCons (lift ix) (Const i)
instance (Elt e, Slice (Plain ix), Lift ix) => Lift (ix :. Exp e) where
  type Plain (ix :. Exp e) = Plain ix :. e
  lift (ix:.i) = IndexCons (lift ix) i
instance (Elt e, Slice (Plain ix), Unlift ix) => Unlift (ix :. Exp e) where
  unlift e = unlift (IndexTail e) :. IndexHead e
instance Shape sh => Lift (Any sh) where
 type Plain (Any sh) = Any sh
 lift Any = IndexAny
instance Lift Int where
  type Plain Int = Int
  lift = Const
  
instance Lift Int8 where
  type Plain Int8 = Int8
  lift = Const
  
instance Lift Int16 where
  type Plain Int16 = Int16
  lift = Const
  
instance Lift Int32 where
  type Plain Int32 = Int32
  lift = Const
  
instance Lift Int64 where
  type Plain Int64 = Int64
  lift = Const
  
instance Lift Word where
  type Plain Word = Word
  lift = Const
  
instance Lift Word8 where
  type Plain Word8 = Word8
  lift = Const
  
instance Lift Word16 where
  type Plain Word16 = Word16
  lift = Const
  
instance Lift Word32 where
  type Plain Word32 = Word32
  lift = Const
  
instance Lift Word64 where
  type Plain Word64 = Word64
  lift = Const
 
instance Lift Float where
  type Plain Float = Float
  lift = Const
instance Lift Double where
  type Plain Double = Double
  lift = Const
instance Lift Bool where
  type Plain Bool = Bool
  lift = Const
instance Lift Char where
  type Plain Char = Char
  lift = Const
instance (Lift a, Lift b, Elt (Plain a), Elt (Plain b)) => Lift (a, b) where
  type Plain (a, b) = (Plain a, Plain b)
  lift (x, y) = tup2 (lift x, lift y)
instance (Elt a, Elt b) => Unlift (Exp a, Exp b) where
  unlift = untup2
instance (Lift a, Lift b, Lift c, Elt (Plain a), Elt (Plain b), Elt (Plain c)) => Lift (a, b, c) where
  type Plain (a, b, c) = (Plain a, Plain b, Plain c)
  lift (x, y, z) = tup3 (lift x, lift y, lift z)
instance (Elt a, Elt b, Elt c) => Unlift (Exp a, Exp b, Exp c) where
  unlift = untup3
instance (Lift a, Lift b, Lift c, Lift d,
          Elt (Plain a), Elt (Plain b), Elt (Plain c), Elt (Plain d)) 
  => Lift (a, b, c, d) where
  type Plain (a, b, c, d) = (Plain a, Plain b, Plain c, Plain d)
  lift (x, y, z, u) = tup4 (lift x, lift y, lift z, lift u)
instance (Elt a, Elt b, Elt c, Elt d) => Unlift (Exp a, Exp b, Exp c, Exp d) where
  unlift = untup4
instance (Lift a, Lift b, Lift c, Lift d, Lift e,
          Elt (Plain a), Elt (Plain b), Elt (Plain c), Elt (Plain d), Elt (Plain e)) 
  => Lift (a, b, c, d, e) where
  type Plain (a, b, c, d, e) = (Plain a, Plain b, Plain c, Plain d, Plain e)
  lift (x, y, z, u, v) = tup5 (lift x, lift y, lift z, lift u, lift v)
instance (Elt a, Elt b, Elt c, Elt d, Elt e) => Unlift (Exp a, Exp b, Exp c, Exp d, Exp e) where
  unlift = untup5
instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f,
          Elt (Plain a), Elt (Plain b), Elt (Plain c), Elt (Plain d), Elt (Plain e), Elt (Plain f)) 
  => Lift (a, b, c, d, e, f) where
  type Plain (a, b, c, d, e, f) = (Plain a, Plain b, Plain c, Plain d, Plain e, Plain f)
  lift (x, y, z, u, v, w) = tup6 (lift x, lift y, lift z, lift u, lift v, lift w)
instance (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f) 
  => Unlift (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f) where
  unlift = untup6
instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g,
          Elt (Plain a), Elt (Plain b), Elt (Plain c), Elt (Plain d), Elt (Plain e), Elt (Plain f),
          Elt (Plain g)) 
  => Lift (a, b, c, d, e, f, g) where
  type Plain (a, b, c, d, e, f, g) = (Plain a, Plain b, Plain c, Plain d, Plain e, Plain f, Plain g)
  lift (x, y, z, u, v, w, r) = tup7 (lift x, lift y, lift z, lift u, lift v, lift w, lift r)
instance (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g) 
  => Unlift (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g) where
  unlift = untup7
instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g, Lift h,
          Elt (Plain a), Elt (Plain b), Elt (Plain c), Elt (Plain d), Elt (Plain e), Elt (Plain f),
          Elt (Plain g), Elt (Plain h)) 
  => Lift (a, b, c, d, e, f, g, h) where
  type Plain (a, b, c, d, e, f, g, h) 
    = (Plain a, Plain b, Plain c, Plain d, Plain e, Plain f, Plain g, Plain h)
  lift (x, y, z, u, v, w, r, s) 
    = tup8 (lift x, lift y, lift z, lift u, lift v, lift w, lift r, lift s)
instance (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h) 
  => Unlift (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h) where
  unlift = untup8
instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g, Lift h, Lift i,
          Elt (Plain a), Elt (Plain b), Elt (Plain c), Elt (Plain d), Elt (Plain e), Elt (Plain f),
          Elt (Plain g), Elt (Plain h), Elt (Plain i)) 
  => Lift (a, b, c, d, e, f, g, h, i) where
  type Plain (a, b, c, d, e, f, g, h, i) 
    = (Plain a, Plain b, Plain c, Plain d, Plain e, Plain f, Plain g, Plain h, Plain i)
  lift (x, y, z, u, v, w, r, s, t) 
    = tup9 (lift x, lift y, lift z, lift u, lift v, lift w, lift r, lift s, lift t)
instance (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i) 
  => Unlift (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i) where
  unlift = untup9
instance Lift (Exp e) where
  type Plain (Exp e) = e
  lift = id
lift1 :: (Unlift e1, Lift e2) 
      => (e1 -> e2) -> Exp (Plain e1) -> Exp (Plain e2)
lift1 f = lift . f . unlift
lift2 :: (Unlift e1, Unlift e2, Lift e3) 
      => (e1 -> e2 -> e3) -> Exp (Plain e1) -> Exp (Plain e2) -> Exp (Plain e3)
lift2 f x y = lift $ f (unlift x) (unlift y)
ilift1 :: (Exp Int -> Exp Int) -> Exp (Z :. Int) -> Exp (Z :. Int)
ilift1 f = lift1 (\(Z:.i) -> Z :. f i)
ilift2 :: (Exp Int -> Exp Int -> Exp Int) -> Exp (Z :. Int) -> Exp (Z :. Int) -> Exp (Z :. Int)
ilift2 f = lift2 (\(Z:.i) (Z:.j) -> Z :. f i j)
fst :: forall a b. (Elt a, Elt b) => Exp (a, b) -> Exp a
fst e = let (x, _:: Exp b) = unlift e in x
snd :: forall a b. (Elt a, Elt b) => Exp (a, b) -> Exp b
snd e = let (_ :: Exp a, y) = unlift e in y
curry :: (Elt a, Elt b) => (Exp (a, b) -> Exp c) -> Exp a -> Exp b -> Exp c
curry f x y = f (lift (x, y))
uncurry :: (Elt a, Elt b) => (Exp a -> Exp b -> Exp c) -> Exp (a, b) -> Exp c
uncurry f t = let (x, y) = unlift t in f x y
index0 :: Exp Z
index0 = lift Z
index1 :: Exp Int -> Exp (Z:. Int)
index1 = lift . (Z:.)
unindex1 :: Exp (Z:. Int) -> Exp Int
unindex1 ix = let Z:.i = unlift ix in i
  
infix 0 ?
(?) :: Elt t => Exp Bool -> (Exp t, Exp t) -> Exp t
c ? (t, e) = Cond c t e
infixl 9 !
(!) :: (Shape ix, Elt e) => Acc (Array ix e) -> Exp ix -> Exp e
(!) = IndexScalar
the :: Elt e => Acc (Scalar e) -> Exp e
the = (!index0)
shape :: (Shape ix, Elt e) => Acc (Array ix e) -> Exp ix
shape = Shape
size :: (Shape ix, Elt e) => Acc (Array ix e) -> Exp Int
size = Size
instance (Elt t, IsBounded t) => Bounded (Exp t) where
  minBound = mkMinBound
  maxBound = mkMaxBound
instance (Elt t, IsScalar t) => Enum (Exp t)
  
instance (Elt t, IsScalar t) => Prelude.Eq (Exp t) where
  
  (==)        = error "Prelude.Eq.== applied to EDSL types"
instance (Elt t, IsScalar t) => Prelude.Ord (Exp t) where
  
  compare     = error "Prelude.Ord.compare applied to EDSL types"
instance (Elt t, IsNum t, IsIntegral t) => Bits (Exp t) where
  (.&.)      = mkBAnd
  (.|.)      = mkBOr
  xor        = mkBXor
  complement = mkBNot
  
shift, shiftL, shiftR :: (Elt t, IsIntegral t) => Exp t -> Exp Int -> Exp t
shift  x i = i ==* 0 ? (x, i <* 0 ? (x `shiftR` (i), x `shiftL` i))
shiftL     = mkBShiftL
shiftR     = mkBShiftR
rotate, rotateL, rotateR :: (Elt t, IsIntegral t) => Exp t -> Exp Int -> Exp t
rotate  x i = i ==* 0 ? (x, i <* 0 ? (x `rotateR` (i), x `rotateL` i))
rotateL     = mkBRotateL
rotateR     = mkBRotateR
bit :: (Elt t, IsIntegral t) => Exp Int -> Exp t
bit x = 1 `shiftL` x
setBit, clearBit, complementBit :: (Elt t, IsIntegral t) => Exp t -> Exp Int -> Exp t
x `setBit` i        = x .|. bit i
x `clearBit` i      = x .&. complement (bit i)
x `complementBit` i = x `xor` bit i
testBit :: (Elt t, IsIntegral t) => Exp t -> Exp Int -> Exp Bool
x `testBit` i       = (x .&. bit i) /=* 0
instance (Elt t, IsNum t) => Num (Exp t) where
  (+)         = mkAdd
  ()         = mkSub
  (*)         = mkMul
  negate      = mkNeg
  abs         = mkAbs
  signum      = mkSig
  fromInteger = constant . fromInteger
instance (Elt t, IsNum t) => Real (Exp t)
  
  
instance (Elt t, IsIntegral t) => Integral (Exp t) where
  quot = mkQuot
  rem  = mkRem
  div  = mkIDiv
  mod  = mkMod
instance (Elt t, IsFloating t) => Floating (Exp t) where
  pi      = mkPi
  sin     = mkSin
  cos     = mkCos
  tan     = mkTan
  asin    = mkAsin
  acos    = mkAcos
  atan    = mkAtan
  asinh   = mkAsinh
  acosh   = mkAcosh
  atanh   = mkAtanh
  exp     = mkExpFloating
  sqrt    = mkSqrt
  log     = mkLog
  (**)    = mkFPow
  logBase = mkLogBase
instance (Elt t, IsFloating t) => Fractional (Exp t) where
  (/)          = mkFDiv
  recip        = mkRecip
  fromRational = constant . fromRational
instance (Elt t, IsFloating t) => RealFrac (Exp t)
  
instance (Elt t, IsFloating t) => RealFloat (Exp t) where
  atan2 = mkAtan2
  
infix 4 ==*, /=*, <*, <=*, >*, >=*
(==*) :: (Elt t, IsScalar t) => Exp t -> Exp t -> Exp Bool
(==*) = mkEq
(/=*) :: (Elt t, IsScalar t) => Exp t -> Exp t -> Exp Bool
(/=*) = mkNEq
(<*) :: (Elt t, IsScalar t) => Exp t -> Exp t -> Exp Bool
(<*)  = mkLt
(>=*) :: (Elt t, IsScalar t) => Exp t -> Exp t -> Exp Bool
(>=*) = mkGtEq
(>*) :: (Elt t, IsScalar t) => Exp t -> Exp t -> Exp Bool
(>*)  = mkGt
(<=*) :: (Elt t, IsScalar t) => Exp t -> Exp t -> Exp Bool
(<=*) = mkLtEq
max :: (Elt t, IsScalar t) => Exp t -> Exp t -> Exp t
max = mkMax
min :: (Elt t, IsScalar t) => Exp t -> Exp t -> Exp t
min = mkMin
truncate :: (Elt a, Elt b, IsFloating a, IsIntegral b) => Exp a -> Exp b
truncate = mkTruncate
round :: (Elt a, Elt b, IsFloating a, IsIntegral b) => Exp a -> Exp b
round = mkRound
floor :: (Elt a, Elt b, IsFloating a, IsIntegral b) => Exp a -> Exp b
floor = mkFloor
ceiling :: (Elt a, Elt b, IsFloating a, IsIntegral b) => Exp a -> Exp b
ceiling = mkCeiling
infixr 3 &&*
(&&*) :: Exp Bool -> Exp Bool -> Exp Bool
(&&*) = mkLAnd
infixr 2 ||*
(||*) :: Exp Bool -> Exp Bool -> Exp Bool
(||*) = mkLOr
not :: Exp Bool -> Exp Bool
not = mkLNot
boolToInt :: Exp Bool -> Exp Int
boolToInt = mkBoolToInt
fromIntegral :: (Elt a, Elt b, IsIntegral a, IsNum b) => Exp a -> Exp b
fromIntegral = mkFromIntegral
ignore :: Shape ix => Exp ix
ignore = constant Sugar.ignore