rebuildA
    :: SyntacticAcc f
    => RebuildAcc acc
    -> (forall t'. Arrays t' => Idx aenv t' -> f acc aenv' t')
    -> PreOpenAcc acc aenv  t
    -> PreOpenAcc acc aenv' t
rebuildA rebuild v acc =
  case acc of
    Alet a b            -> Alet (rebuild v a) (rebuild (shiftA rebuild v) b)
    Avar ix             -> accOut (v ix)
    Atuple tup          -> Atuple (rebuildATA rebuild v tup)
    Aprj tup a          -> Aprj tup (rebuild v a)
    Apply f a           -> Apply f (rebuild v a)
    Acond p t e         -> Acond (rebuildEA rebuild v p) (rebuild v t) (rebuild v e)
    Use a               -> Use a
    Unit e              -> Unit (rebuildEA rebuild v e)
    Reshape e a         -> Reshape (rebuildEA rebuild v e) (rebuild v a)
    Generate e f        -> Generate (rebuildEA rebuild v e) (rebuildFA rebuild v f)
    Transform sh ix f a -> Transform (rebuildEA rebuild v sh) (rebuildFA rebuild v ix) (rebuildFA rebuild v f) (rebuild v a)
    Replicate sl slix a -> Replicate sl (rebuildEA rebuild v slix) (rebuild v a)
    Slice sl a slix     -> Slice sl (rebuild v a) (rebuildEA rebuild v slix)
    Map f a             -> Map (rebuildFA rebuild v f) (rebuild v a)
    ZipWith f a1 a2     -> ZipWith (rebuildFA rebuild v f) (rebuild v a1) (rebuild v a2)
    Fold f z a          -> Fold (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a)
    Fold1 f a           -> Fold1 (rebuildFA rebuild v f) (rebuild v a)
    FoldSeg f z a s     -> FoldSeg (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a) (rebuild v s)
    Fold1Seg f a s      -> Fold1Seg (rebuildFA rebuild v f) (rebuild v a) (rebuild v s)
    Scanl f z a         -> Scanl (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a)
    Scanl' f z a        -> Scanl' (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a)
    Scanl1 f a          -> Scanl1 (rebuildFA rebuild v f) (rebuild v a)
    Scanr f z a         -> Scanr (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a)
    Scanr' f z a        -> Scanr' (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a)
    Scanr1 f a          -> Scanr1 (rebuildFA rebuild v f) (rebuild v a)
    Permute f1 a1 f2 a2 -> Permute (rebuildFA rebuild v f1) (rebuild v a1) (rebuildFA rebuild v f2) (rebuild v a2)
    Backpermute sh f a  -> Backpermute (rebuildEA rebuild v sh) (rebuildFA rebuild v f) (rebuild v a)
    Stencil f b a       -> Stencil (rebuildFA rebuild v f) b (rebuild v a)
    Stencil2 f b1 a1 b2 a2
                        -> Stencil2 (rebuildFA rebuild v f) b1 (rebuild v a1) b2 (rebuild v a2)
    Foreign ff afun as  -> Foreign ff afun (rebuild v as)


-- Rebuilding array computations
--
rebuildA
    :: SyntacticAcc f
    => RebuildAcc acc
    -> (forall t'. Arrays t' => Idx aenv t' -> f acc aenv' t')
    -> PreOpenAcc acc aenv  t
    -> PreOpenAcc acc aenv' t
rebuildA rebuild v acc =
  case acc of
    Alet a b            -> Alet (rebuild v a) (rebuild (shiftA rebuild v) b)
    Avar ix             -> accOut (v ix)
    Atuple tup          -> Atuple (rebuildATA rebuild v tup)
    Aprj tup a          -> Aprj tup (rebuild v a)
    Apply f a           -> Apply f (rebuild v a)
    Acond p t e         -> Acond (rebuildEA rebuild v p) (rebuild v t) (rebuild v e)
    Use a               -> Use a
    Unit e              -> Unit (rebuildEA rebuild v e)
    Reshape e a         -> Reshape (rebuildEA rebuild v e) (rebuild v a)
    Generate e f        -> Generate (rebuildEA rebuild v e) (rebuildFA rebuild v f)
    Transform sh ix f a -> Transform (rebuildEA rebuild v sh) (rebuildFA rebuild v ix) (rebuildFA rebuild v f) (rebuild v a)
    Replicate sl slix a -> Replicate sl (rebuildEA rebuild v slix) (rebuild v a)
    Slice sl a slix     -> Slice sl (rebuild v a) (rebuildEA rebuild v slix)
    Map f a             -> Map (rebuildFA rebuild v f) (rebuild v a)
    ZipWith f a1 a2     -> ZipWith (rebuildFA rebuild v f) (rebuild v a1) (rebuild v a2)
    Fold f z a          -> Fold (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a)
    Fold1 f a           -> Fold1 (rebuildFA rebuild v f) (rebuild v a)
    FoldSeg f z a s     -> FoldSeg (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a) (rebuild v s)
    Fold1Seg f a s      -> Fold1Seg (rebuildFA rebuild v f) (rebuild v a) (rebuild v s)
    Scanl f z a         -> Scanl (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a)
    Scanl' f z a        -> Scanl' (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a)
    Scanl1 f a          -> Scanl1 (rebuildFA rebuild v f) (rebuild v a)
    Scanr f z a         -> Scanr (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a)
    Scanr' f z a        -> Scanr' (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a)
    Scanr1 f a          -> Scanr1 (rebuildFA rebuild v f) (rebuild v a)
    Permute f1 a1 f2 a2 -> Permute (rebuildFA rebuild v f1) (rebuild v a1) (rebuildFA rebuild v f2) (rebuild v a2)
    Backpermute sh f a  -> Backpermute (rebuildEA rebuild v sh) (rebuildFA rebuild v f) (rebuild v a)
    Stencil f b a       -> Stencil (rebuildFA rebuild v f) b (rebuild v a)
    Stencil2 f b1 a1 b2 a2
                        -> Stencil2 (rebuildFA rebuild v f) b1 (rebuild v a1) b2 (rebuild v a2)
    Foreign ff afun as  -> Foreign ff afun (rebuild v as)


-- Rebuilding array computations
--
rebuildA rebuild v acc =
  case acc of
    Alet a b            -> Alet (rebuild v a) (rebuild (shiftA rebuild v) b)
    Avar ix             -> accOut (v ix)
    Atuple tup          -> Atuple (rebuildATA rebuild v tup)
    Aprj tup a          -> Aprj tup (rebuild v a)
    Apply f a           -> Apply f (rebuild v a)
    Acond p t e         -> Acond (rebuildEA rebuild v p) (rebuild v t) (rebuild v e)
    Use a               -> Use a
    Unit e              -> Unit (rebuildEA rebuild v e)
    Reshape e a         -> Reshape (rebuildEA rebuild v e) (rebuild v a)
    Generate e f        -> Generate (rebuildEA rebuild v e) (rebuildFA rebuild v f)
    Transform sh ix f a -> Transform (rebuildEA rebuild v sh) (rebuildFA rebuild v ix) (rebuildFA rebuild v f) (rebuild v a)
    Replicate sl slix a -> Replicate sl (rebuildEA rebuild v slix) (rebuild v a)
    Slice sl a slix     -> Slice sl (rebuild v a) (rebuildEA rebuild v slix)
    Map f a             -> Map (rebuildFA rebuild v f) (rebuild v a)
    ZipWith f a1 a2     -> ZipWith (rebuildFA rebuild v f) (rebuild v a1) (rebuild v a2)
    Fold f z a          -> Fold (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a)
    Fold1 f a           -> Fold1 (rebuildFA rebuild v f) (rebuild v a)
    FoldSeg f z a s     -> FoldSeg (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a) (rebuild v s)
    Fold1Seg f a s      -> Fold1Seg (rebuildFA rebuild v f) (rebuild v a) (rebuild v s)
    Scanl f z a         -> Scanl (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a)
    Scanl' f z a        -> Scanl' (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a)
    Scanl1 f a          -> Scanl1 (rebuildFA rebuild v f) (rebuild v a)
    Scanr f z a         -> Scanr (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a)
    Scanr' f z a        -> Scanr' (rebuildFA rebuild v f) (rebuildEA rebuild v z) (rebuild v a)
    Scanr1 f a          -> Scanr1 (rebuildFA rebuild v f) (rebuild v a)
    Permute f1 a1 f2 a2 -> Permute (rebuildFA rebuild v f1) (rebuild v a1) (rebuildFA rebuild v f2) (rebuild v a2)
    Backpermute sh f a  -> Backpermute (rebuildEA rebuild v sh) (rebuildFA rebuild v f) (rebuild v a)
    Stencil f b a       -> Stencil (rebuildFA rebuild v f) b (rebuild v a)
    Stencil2 f b1 a1 b2 a2
                        -> Stencil2 (rebuildFA rebuild v f) b1 (rebuild v a1) b2 (rebuild v a2)
    Foreign ff afun as  -> Foreign ff afun (rebuild v as)


-- Rebuilding array computations
--