usesOfA :: UsesOfAcc acc -> Idx aenv s -> PreOpenAcc acc aenv t -> Int
usesOfA u idx acc =
  case acc of
    Alet bnd body       -> u idx bnd + u (SuccIdx idx) body
    Avar idx'
      | Just REFL <- matchIdx idx idx'  -> 1
      | otherwise                       -> 0
    Atuple tup          -> usesOfATA u idx tup
    Aprj _ a            -> u idx a
    Apply _ a           -> u idx a
    Acond p t e         -> usesOfEA u idx p + u idx t + u idx e
    Use _               -> 0
    Unit e              -> usesOfEA u idx e
    Reshape e a         -> usesOfEA u idx e + u idx a
    Generate e f        -> usesOfEA u idx e + usesOfFA u idx f
    Transform sh ix f a -> usesOfEA u idx sh + usesOfFA u idx ix + usesOfFA u idx f + u idx a
    Replicate _ slix a  -> usesOfEA u idx slix + u idx a
    Slice _ a slix      -> usesOfEA u idx slix + u idx a
    Map f a             -> usesOfFA u idx f + u idx a
    ZipWith f a1 a2     -> usesOfFA u idx f + u idx a1 + u idx a2
    Fold f z a          -> usesOfFA u idx f + usesOfEA u idx z + u idx a
    Fold1 f a           -> usesOfFA u idx f + u idx a
    FoldSeg f z a s     -> usesOfFA u idx f + usesOfEA u idx z + u idx a + u idx s
    Fold1Seg f a s      -> usesOfFA u idx f + u idx a + u idx s
    Scanl f z a         -> usesOfFA u idx f + usesOfEA u idx z + u idx a
    Scanl' f z a        -> usesOfFA u idx f + usesOfEA u idx z + u idx a
    Scanl1 f a          -> usesOfFA u idx f + u idx a
    Scanr f z a         -> usesOfFA u idx f + usesOfEA u idx z + u idx a
    Scanr' f z a        -> usesOfFA u idx f + usesOfEA u idx z + u idx a
    Scanr1 f a          -> usesOfFA u idx f + u idx a
    Permute f1 a1 f2 a2 -> usesOfFA u idx f1 + u idx a1 + usesOfFA u idx f2 + u idx a2
    Backpermute sh f a  -> usesOfEA u idx sh + usesOfFA u idx f + u idx a
    Stencil f _ a       -> usesOfFA u idx f + u idx a
    Stencil2 f _ a1 _ a2-> usesOfFA u idx f + u idx a1 + u idx a2
    Foreign _ _ a       -> u idx a
usesOfA :: UsesOfAcc acc -> Idx aenv s -> PreOpenAcc acc aenv t -> Int
usesOfA u idx acc =
  case acc of
    Alet bnd body       -> u idx bnd + u (SuccIdx idx) body
    Avar idx'
      | Just REFL <- matchIdx idx idx'  -> 1
      | otherwise                       -> 0
    Atuple tup          -> usesOfATA u idx tup
    Aprj _ a            -> u idx a
    Apply _ a           -> u idx a
    Acond p t e         -> usesOfEA u idx p + u idx t + u idx e
    Use _               -> 0
    Unit e              -> usesOfEA u idx e
    Reshape e a         -> usesOfEA u idx e + u idx a
    Generate e f        -> usesOfEA u idx e + usesOfFA u idx f
    Transform sh ix f a -> usesOfEA u idx sh + usesOfFA u idx ix + usesOfFA u idx f + u idx a
    Replicate _ slix a  -> usesOfEA u idx slix + u idx a
    Slice _ a slix      -> usesOfEA u idx slix + u idx a
    Map f a             -> usesOfFA u idx f + u idx a
    ZipWith f a1 a2     -> usesOfFA u idx f + u idx a1 + u idx a2
    Fold f z a          -> usesOfFA u idx f + usesOfEA u idx z + u idx a
    Fold1 f a           -> usesOfFA u idx f + u idx a
    FoldSeg f z a s     -> usesOfFA u idx f + usesOfEA u idx z + u idx a + u idx s
    Fold1Seg f a s      -> usesOfFA u idx f + u idx a + u idx s
    Scanl f z a         -> usesOfFA u idx f + usesOfEA u idx z + u idx a
    Scanl' f z a        -> usesOfFA u idx f + usesOfEA u idx z + u idx a
    Scanl1 f a          -> usesOfFA u idx f + u idx a
    Scanr f z a         -> usesOfFA u idx f + usesOfEA u idx z + u idx a
    Scanr' f z a        -> usesOfFA u idx f + usesOfEA u idx z + u idx a
    Scanr1 f a          -> usesOfFA u idx f + u idx a
    Permute f1 a1 f2 a2 -> usesOfFA u idx f1 + u idx a1 + usesOfFA u idx f2 + u idx a2
    Backpermute sh f a  -> usesOfEA u idx sh + usesOfFA u idx f + u idx a
    Stencil f _ a       -> usesOfFA u idx f + u idx a
    Stencil2 f _ a1 _ a2-> usesOfFA u idx f + u idx a1 + u idx a2
    Foreign _ _ a       -> u idx a
usesOfA u idx acc =
  case acc of
    Alet bnd body       -> u idx bnd + u (SuccIdx idx) body
    Avar idx'
      | Just REFL <- matchIdx idx idx'  -> 1
      | otherwise                       -> 0
    Atuple tup          -> usesOfATA u idx tup
    Aprj _ a            -> u idx a
    Apply _ a           -> u idx a
    Acond p t e         -> usesOfEA u idx p + u idx t + u idx e
    Use _               -> 0
    Unit e              -> usesOfEA u idx e
    Reshape e a         -> usesOfEA u idx e + u idx a
    Generate e f        -> usesOfEA u idx e + usesOfFA u idx f
    Transform sh ix f a -> usesOfEA u idx sh + usesOfFA u idx ix + usesOfFA u idx f + u idx a
    Replicate _ slix a  -> usesOfEA u idx slix + u idx a
    Slice _ a slix      -> usesOfEA u idx slix + u idx a
    Map f a             -> usesOfFA u idx f + u idx a
    ZipWith f a1 a2     -> usesOfFA u idx f + u idx a1 + u idx a2
    Fold f z a          -> usesOfFA u idx f + usesOfEA u idx z + u idx a
    Fold1 f a           -> usesOfFA u idx f + u idx a
    FoldSeg f z a s     -> usesOfFA u idx f + usesOfEA u idx z + u idx a + u idx s
    Fold1Seg f a s      -> usesOfFA u idx f + u idx a + u idx s
    Scanl f z a         -> usesOfFA u idx f + usesOfEA u idx z + u idx a
    Scanl' f z a        -> usesOfFA u idx f + usesOfEA u idx z + u idx a
    Scanl1 f a          -> usesOfFA u idx f + u idx a
    Scanr f z a         -> usesOfFA u idx f + usesOfEA u idx z + u idx a
    Scanr' f z a        -> usesOfFA u idx f + usesOfEA u idx z + u idx a
    Scanr1 f a          -> usesOfFA u idx f + u idx a
    Permute f1 a1 f2 a2 -> usesOfFA u idx f1 + u idx a1 + usesOfFA u idx f2 + u idx a2
    Backpermute sh f a  -> usesOfEA u idx sh + usesOfFA u idx f + u idx a
    Stencil f _ a       -> usesOfFA u idx f + u idx a
    Stencil2 f _ a1 _ a2-> usesOfFA u idx f + u idx a1 + u idx a2
    Foreign _ _ a       -> u idx a