-- | This function checks multiplicity consistency and then delegates the
-- spatial consistency to |consistent'| function.
consistent :: forall n .
              Specification
           -> Multiplicity (UnionNF n Offsets)
           -> ConsistencyResult
consistent (Specification mult) observedIxs =
    -- First do the linearity check
    case (specModel, observedIxs) of
      (Mult a, Mult b) -> a `consistent'` b
      (Once a, Once b) -> a `consistent'` b
      (Once _, Mult _) ->Inconsistent
        "Specification is readOnce, but there are repeated indices."
      (Mult _, Once _) -> Inconsistent
        "Specification lacks readOnce, but the indices are inuque."
  where
    specModel :: Multiplicity (Approximation (UnionNF n (Interval Standard)))
    specModel =
      case sequence $ (sequence . fmap (regionsToIntervals nOfDims)) <$> mult of
        Right model -> model
        Left msg -> error msg

    nOfDims :: V.Natural n
    nOfDims = vecLength . peel $ observedIxs

-- | This is the actual consistency check using set comparison supplied in
-- the model.
consistent :: forall n .
              Specification
           -> Multiplicity (UnionNF n Offsets)
           -> ConsistencyResult
consistent (Specification mult) observedIxs =
    -- First do the linearity check
    case (specModel, observedIxs) of
      (Mult a, Mult b) -> a `consistent'` b
      (Once a, Once b) -> a `consistent'` b
      (Once _, Mult _) ->Inconsistent
        "Specification is readOnce, but there are repeated indices."
      (Mult _, Once _) -> Inconsistent
        "Specification lacks readOnce, but the indices are inuque."
  where
    specModel :: Multiplicity (Approximation (UnionNF n (Interval Standard)))
    specModel =
      case sequence $ (sequence . fmap (regionsToIntervals nOfDims)) <$> mult of
        Right model -> model
        Left msg -> error msg

    nOfDims :: V.Natural n
    nOfDims = vecLength . peel $ observedIxs

-- | This is the actual consistency check using set comparison supplied in
-- the model.
consistent (Specification mult) observedIxs =
    -- First do the linearity check
    case (specModel, observedIxs) of
      (Mult a, Mult b) -> a `consistent'` b
      (Once a, Once b) -> a `consistent'` b
      (Once _, Mult _) ->Inconsistent
        "Specification is readOnce, but there are repeated indices."
      (Mult _, Once _) -> Inconsistent
        "Specification lacks readOnce, but the indices are inuque."
  where
    specModel :: Multiplicity (Approximation (UnionNF n (Interval Standard)))
    specModel =
      case sequence $ (sequence . fmap (regionsToIntervals nOfDims)) <$> mult of
        Right model -> model
        Left msg -> error msg

    nOfDims :: V.Natural n
    nOfDims = vecLength . peel $ observedIxs

-- | This is the actual consistency check using set comparison supplied in
-- the model.