------------------------------------------------------
-- Recalculating indices
------------------------------------------------------


-- | Recalculate the `from` and `to` values of the individual labels to reflect
-- the distance from the beginning of the sentence to the given position (with
-- the goal to simplify merging several DAGs).
-- The way distance is calculated depends on the first argument, which
-- computes the length of the token (typical values: the actual length
-- or 1).
recalcIxs :: (Token t -> Int) -> DAG (Token t) -> DAG (Token t)
recalcIxs tokLen dag =
  [ edge
    { from = dist (from edge)
    , to = dist (to edge) }
  | edge <- dag ]
  where
    dist = Memo.integral dist'
    dist' i = maximumDef 0
      [ dist from + tokLen label
      | Edge{..} <- findEdgeTo i dag ]
    maximumDef x xs = case xs of
      [] -> x
      _ -> maximum xs


-- | Run `recalcIxs` with the length of token set to the number of non-space
-- characters inside.
recalcIxs :: (Token t -> Int) -> DAG (Token t) -> DAG (Token t)
recalcIxs tokLen dag =
  [ edge
    { from = dist (from edge)
    , to = dist (to edge) }
  | edge <- dag ]
  where
    dist = Memo.integral dist'
    dist' i = maximumDef 0
      [ dist from + tokLen label
      | Edge{..} <- findEdgeTo i dag ]
    maximumDef x xs = case xs of
      [] -> x
      _ -> maximum xs


-- | Run `recalcIxs` with the length of token set to the number of non-space
-- characters inside.
recalcIxs tokLen dag =
  [ edge
    { from = dist (from edge)
    , to = dist (to edge) }
  | edge <- dag ]
  where
    dist = Memo.integral dist'
    dist' i = maximumDef 0
      [ dist from + tokLen label
      | Edge{..} <- findEdgeTo i dag ]
    maximumDef x xs = case xs of
      [] -> x
      _ -> maximum xs


-- | Run `recalcIxs` with the length of token set to the number of non-space
-- characters inside.