usesOfE :: forall acc env aenv s t. Idx env s -> PreOpenExp acc env aenv t -> Int
usesOfE idx exp =
  case exp of
    Let bnd body        -> usesOfE idx bnd + usesOfE (SuccIdx idx) body
    Var idx'
      | Just REFL <- matchIdx idx idx'  -> 1
      | otherwise                       -> 0
    Const _             -> 0
    Tuple t             -> usesOfTE idx t
    Prj _ e             -> usesOfE idx e
    IndexNil            -> 0
    IndexCons sl sz     -> usesOfE idx sl + usesOfE idx sz
    IndexHead sh        -> usesOfE idx sh
    IndexTail sh        -> usesOfE idx sh
    IndexSlice _ ix sh  -> usesOfE idx ix + usesOfE idx sh
    IndexFull _ ix sl   -> usesOfE idx ix + usesOfE idx sl
    IndexAny            -> 0
    ToIndex sh ix       -> usesOfE idx sh + usesOfE idx ix
    FromIndex sh i      -> usesOfE idx sh + usesOfE idx i
    Cond p t e          -> usesOfE idx p  + usesOfE idx t + usesOfE idx e
    Iterate n f x       -> usesOfE idx n  + usesOfE idx x + usesOfE (SuccIdx idx) f
    PrimConst _         -> 0
    PrimApp _ x         -> usesOfE idx x
    Index _ sh          -> usesOfE idx sh
    LinearIndex _ i     -> usesOfE idx i
    Shape _             -> 0
    ShapeSize sh        -> usesOfE idx sh
    Intersect sh sz     -> usesOfE idx sh + usesOfE idx sz
usesOfE :: forall acc env aenv s t. Idx env s -> PreOpenExp acc env aenv t -> Int
usesOfE idx exp =
  case exp of
    Let bnd body        -> usesOfE idx bnd + usesOfE (SuccIdx idx) body
    Var idx'
      | Just REFL <- matchIdx idx idx'  -> 1
      | otherwise                       -> 0
    Const _             -> 0
    Tuple t             -> usesOfTE idx t
    Prj _ e             -> usesOfE idx e
    IndexNil            -> 0
    IndexCons sl sz     -> usesOfE idx sl + usesOfE idx sz
    IndexHead sh        -> usesOfE idx sh
    IndexTail sh        -> usesOfE idx sh
    IndexSlice _ ix sh  -> usesOfE idx ix + usesOfE idx sh
    IndexFull _ ix sl   -> usesOfE idx ix + usesOfE idx sl
    IndexAny            -> 0
    ToIndex sh ix       -> usesOfE idx sh + usesOfE idx ix
    FromIndex sh i      -> usesOfE idx sh + usesOfE idx i
    Cond p t e          -> usesOfE idx p  + usesOfE idx t + usesOfE idx e
    Iterate n f x       -> usesOfE idx n  + usesOfE idx x + usesOfE (SuccIdx idx) f
    PrimConst _         -> 0
    PrimApp _ x         -> usesOfE idx x
    Index _ sh          -> usesOfE idx sh
    LinearIndex _ i     -> usesOfE idx i
    Shape _             -> 0
    ShapeSize sh        -> usesOfE idx sh
    Intersect sh sz     -> usesOfE idx sh + usesOfE idx sz
usesOfE idx exp =
  case exp of
    Let bnd body        -> usesOfE idx bnd + usesOfE (SuccIdx idx) body
    Var idx'
      | Just REFL <- matchIdx idx idx'  -> 1
      | otherwise                       -> 0
    Const _             -> 0
    Tuple t             -> usesOfTE idx t
    Prj _ e             -> usesOfE idx e
    IndexNil            -> 0
    IndexCons sl sz     -> usesOfE idx sl + usesOfE idx sz
    IndexHead sh        -> usesOfE idx sh
    IndexTail sh        -> usesOfE idx sh
    IndexSlice _ ix sh  -> usesOfE idx ix + usesOfE idx sh
    IndexFull _ ix sl   -> usesOfE idx ix + usesOfE idx sl
    IndexAny            -> 0
    ToIndex sh ix       -> usesOfE idx sh + usesOfE idx ix
    FromIndex sh i      -> usesOfE idx sh + usesOfE idx i
    Cond p t e          -> usesOfE idx p  + usesOfE idx t + usesOfE idx e
    Iterate n f x       -> usesOfE idx n  + usesOfE idx x + usesOfE (SuccIdx idx) f
    PrimConst _         -> 0
    PrimApp _ x         -> usesOfE idx x
    Index _ sh          -> usesOfE idx sh
    LinearIndex _ i     -> usesOfE idx i
    Shape _             -> 0
    ShapeSize sh        -> usesOfE idx sh
    Intersect sh sz     -> usesOfE idx sh + usesOfE idx sz