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