rebuildEA
    :: SyntacticAcc f
    => RebuildAcc acc
    -> (forall t'. Arrays t' => Idx aenv t' -> f acc aenv' t')
    -> PreOpenExp acc env aenv  t
    -> PreOpenExp acc env aenv' t
rebuildEA k v exp =
  case exp of
    Let a b             -> Let (rebuildEA k v a) (rebuildEA k v b)
    Var ix              -> Var ix
    Const c             -> Const c
    Tuple tup           -> Tuple (rebuildTA k v tup)
    Prj tup e           -> Prj tup (rebuildEA k v e)
    IndexNil            -> IndexNil
    IndexCons sh sz     -> IndexCons (rebuildEA k v sh) (rebuildEA k v sz)
    IndexHead sh        -> IndexHead (rebuildEA k v sh)
    IndexTail sh        -> IndexTail (rebuildEA k v sh)
    IndexAny            -> IndexAny
    IndexSlice x ix sh  -> IndexSlice x (rebuildEA k v ix) (rebuildEA k v sh)
    IndexFull x ix sl   -> IndexFull x (rebuildEA k v ix) (rebuildEA k v sl)
    ToIndex sh ix       -> ToIndex (rebuildEA k v sh) (rebuildEA k v ix)
    FromIndex sh ix     -> FromIndex (rebuildEA k v sh) (rebuildEA k v ix)
    Cond p t e          -> Cond (rebuildEA k v p) (rebuildEA k v t) (rebuildEA k v e)
    Iterate n f x       -> Iterate (rebuildEA k v n) (rebuildEA k v f) (rebuildEA k v x)
    PrimConst c         -> PrimConst c
    PrimApp f x         -> PrimApp f (rebuildEA k v x)
    Index a sh          -> Index (k v a) (rebuildEA k v sh)
    LinearIndex a i     -> LinearIndex (k v a) (rebuildEA k v i)
    Shape a             -> Shape (k v a)
    ShapeSize sh        -> ShapeSize (rebuildEA k v sh)
    Intersect s t       -> Intersect (rebuildEA k v s) (rebuildEA k v t)
rebuildEA
    :: SyntacticAcc f
    => RebuildAcc acc
    -> (forall t'. Arrays t' => Idx aenv t' -> f acc aenv' t')
    -> PreOpenExp acc env aenv  t
    -> PreOpenExp acc env aenv' t
rebuildEA k v exp =
  case exp of
    Let a b             -> Let (rebuildEA k v a) (rebuildEA k v b)
    Var ix              -> Var ix
    Const c             -> Const c
    Tuple tup           -> Tuple (rebuildTA k v tup)
    Prj tup e           -> Prj tup (rebuildEA k v e)
    IndexNil            -> IndexNil
    IndexCons sh sz     -> IndexCons (rebuildEA k v sh) (rebuildEA k v sz)
    IndexHead sh        -> IndexHead (rebuildEA k v sh)
    IndexTail sh        -> IndexTail (rebuildEA k v sh)
    IndexAny            -> IndexAny
    IndexSlice x ix sh  -> IndexSlice x (rebuildEA k v ix) (rebuildEA k v sh)
    IndexFull x ix sl   -> IndexFull x (rebuildEA k v ix) (rebuildEA k v sl)
    ToIndex sh ix       -> ToIndex (rebuildEA k v sh) (rebuildEA k v ix)
    FromIndex sh ix     -> FromIndex (rebuildEA k v sh) (rebuildEA k v ix)
    Cond p t e          -> Cond (rebuildEA k v p) (rebuildEA k v t) (rebuildEA k v e)
    Iterate n f x       -> Iterate (rebuildEA k v n) (rebuildEA k v f) (rebuildEA k v x)
    PrimConst c         -> PrimConst c
    PrimApp f x         -> PrimApp f (rebuildEA k v x)
    Index a sh          -> Index (k v a) (rebuildEA k v sh)
    LinearIndex a i     -> LinearIndex (k v a) (rebuildEA k v i)
    Shape a             -> Shape (k v a)
    ShapeSize sh        -> ShapeSize (rebuildEA k v sh)
    Intersect s t       -> Intersect (rebuildEA k v s) (rebuildEA k v t)
rebuildEA k v exp =
  case exp of
    Let a b             -> Let (rebuildEA k v a) (rebuildEA k v b)
    Var ix              -> Var ix
    Const c             -> Const c
    Tuple tup           -> Tuple (rebuildTA k v tup)
    Prj tup e           -> Prj tup (rebuildEA k v e)
    IndexNil            -> IndexNil
    IndexCons sh sz     -> IndexCons (rebuildEA k v sh) (rebuildEA k v sz)
    IndexHead sh        -> IndexHead (rebuildEA k v sh)
    IndexTail sh        -> IndexTail (rebuildEA k v sh)
    IndexAny            -> IndexAny
    IndexSlice x ix sh  -> IndexSlice x (rebuildEA k v ix) (rebuildEA k v sh)
    IndexFull x ix sl   -> IndexFull x (rebuildEA k v ix) (rebuildEA k v sl)
    ToIndex sh ix       -> ToIndex (rebuildEA k v sh) (rebuildEA k v ix)
    FromIndex sh ix     -> FromIndex (rebuildEA k v sh) (rebuildEA k v ix)
    Cond p t e          -> Cond (rebuildEA k v p) (rebuildEA k v t) (rebuildEA k v e)
    Iterate n f x       -> Iterate (rebuildEA k v n) (rebuildEA k v f) (rebuildEA k v x)
    PrimConst c         -> PrimConst c
    PrimApp f x         -> PrimApp f (rebuildEA k v x)
    Index a sh          -> Index (k v a) (rebuildEA k v sh)
    LinearIndex a i     -> LinearIndex (k v a) (rebuildEA k v i)
    Shape a             -> Shape (k v a)
    ShapeSize sh        -> ShapeSize (rebuildEA k v sh)
    Intersect s t       -> Intersect (rebuildEA k v s) (rebuildEA k v t)