content: {- |
  Module      :  Camfort.Specification.Stencils.Parser.Types
  Description :  Defines the representation of stencil specifications resulting from parsing.
  Copyright   :  (c) 2017, Dominic Orchard, Andrew Rice, Mistral Contrastin, Matthew Danish
  License     :  Apache-2.0
  
  Maintainer  :  dom.orchard@gmail.com
  Stability   :  experimental
  -}
  
  {-# LANGUAGE DeriveDataTypeable #-}
  
  module Camfort.Specification.Stencils.Parser.Types
    ( Specification(..)
    , Region(..)
    , SpecInner(..)
    , reqRegions
    ) where
  
  import Data.Data (Data, Typeable)
  import Data.List (nub, sort)
  
  import           Camfort.Specification.Stencils.Model
    (Approximation(..), Multiplicity(..))
  import qualified Camfort.Specification.Stencils.Syntax as Syn
  
  data Specification
    = RegionDec String Region
    | SpecDec SpecInner [String]
    deriving (Show, Eq, Typeable, Data)
  
  -- | Regions that are referenced in a specification.
  reqRegions :: Specification -> [Syn.Variable]
  reqRegions spec = nub . sort $
    case spec of
      RegionDec _ r             -> reqRegions' r
      SpecDec (SpecInner x _) _ ->
        case x of
          Once a -> reqRegionsApprox a
          Mult a -> reqRegionsApprox a
    where
      reqRegionsApprox (Exact r) = reqRegions' r
      reqRegionsApprox (Bound l u) =
        let maybeReqRegions = maybe [] reqRegions'
        in maybeReqRegions l ++ maybeReqRegions u
      reqRegions' :: Region -> [Syn.Variable]
      reqRegions' RegionConst{} = []
      reqRegions' (Or r1 r2)    = reqRegions' r1 ++ reqRegions' r2
      reqRegions' (And r1 r2)   = reqRegions' r1 ++ reqRegions' r2
      reqRegions' (Var v)       = [v]
  
  data Region
    = RegionConst Syn.Region
    | Or Region Region
    | And Region Region
    | Var String
    deriving (Show, Eq, Ord, Typeable, Data)
  
  data SpecInner = SpecInner
      (Multiplicity (Approximation Region))  -- main specification content
      Syn.IsStencil                          -- a bool: stencil or access
    deriving (Show, Eq, Typeable, Data)
  