    -- Copyright 2024 United States Government as represented by the Administrator
    -- of the National Aeronautics and Space Administration. All Rights Reserved.
    --
    -- Disclaimers
    --
    -- Licensed under the Apache License, Version 2.0 (the "License"); you may
    -- not use this file except in compliance with the License. You may obtain a
    -- copy of the License at
    --
    --      https://www.apache.org/licenses/LICENSE-2.0
    --
    -- Unless required by applicable law or agreed to in writing, software
    -- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    -- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    -- License for the specific language governing permissions and limitations
    -- under the License.
    --
    -- | Abstract representation of an Ogma specification.
    module Data.OgmaSpec where

    -- | Abstract representation of an Ogma specification.
    data Spec a = Spec
        { forall a. Spec a -> [InternalVariableDef]
    internalVariables :: [ InternalVariableDef ]
        , forall a. Spec a -> [ExternalVariableDef]
    externalVariables :: [ ExternalVariableDef ]
        , forall a. Spec a -> [Requirement a]
    requirements      :: [ Requirement a ]
        }
      deriving (Int -> Spec a -> ShowS
    [Spec a] -> ShowS
    Spec a -> String
    (Int -> Spec a -> ShowS)
    -> (Spec a -> String) -> ([Spec a] -> ShowS) -> Show (Spec a)
    forall a. Show a => Int -> Spec a -> ShowS
    forall a. Show a => [Spec a] -> ShowS
    forall a. Show a => Spec a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Show a => Int -> Spec a -> ShowS
    showsPrec :: Int -> Spec a -> ShowS
    $cshow :: forall a. Show a => Spec a -> String
    show :: Spec a -> String
    $cshowList :: forall a. Show a => [Spec a] -> ShowS
    showList :: [Spec a] -> ShowS
    Show)

    -- | Internal variable definition, with a given name, its type and definining
    -- expression.
    data InternalVariableDef = InternalVariableDef
        { InternalVariableDef -> String
    internalVariableName    :: String
        , InternalVariableDef -> String
    internalVariableType    :: String
        , InternalVariableDef -> String
    internalVariableExpr    :: String
        }
      deriving (Int -> InternalVariableDef -> ShowS
    [InternalVariableDef] -> ShowS
    InternalVariableDef -> String
    (Int -> InternalVariableDef -> ShowS)
    -> (InternalVariableDef -> String)
    -> ([InternalVariableDef] -> ShowS)
    -> Show InternalVariableDef
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> InternalVariableDef -> ShowS
    showsPrec :: Int -> InternalVariableDef -> ShowS
    $cshow :: InternalVariableDef -> String
    show :: InternalVariableDef -> String
    $cshowList :: [InternalVariableDef] -> ShowS
    showList :: [InternalVariableDef] -> ShowS
    Show)

    -- | External variable definition, with a given name and type.
    --
    -- The value of external variables is assigned outside Copilot, so they have no
    -- defining expression in this type.
    data ExternalVariableDef = ExternalVariableDef
        { ExternalVariableDef -> String
    externalVariableName :: String
        , ExternalVariableDef -> String
    externalVariableType :: String
        }
      deriving (Int -> ExternalVariableDef -> ShowS
    [ExternalVariableDef] -> ShowS
    ExternalVariableDef -> String
    (Int -> ExternalVariableDef -> ShowS)
    -> (ExternalVariableDef -> String)
    -> ([ExternalVariableDef] -> ShowS)
    -> Show ExternalVariableDef
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ExternalVariableDef -> ShowS
    showsPrec :: Int -> ExternalVariableDef -> ShowS
    $cshow :: ExternalVariableDef -> String
    show :: ExternalVariableDef -> String
    $cshowList :: [ExternalVariableDef] -> ShowS
    showList :: [ExternalVariableDef] -> ShowS
    Show)

    -- | Requirement with a given name and a boolean expression.
    data Requirement a = Requirement
        { forall a. Requirement a -> String
    requirementName        :: String
        , forall a. Requirement a -> a
    requirementExpr        :: a
        , forall a. Requirement a -> String
    requirementDescription :: String
        , forall a. Requirement a -> Maybe String
    requirementResultType  :: Maybe String
        , forall a. Requirement a -> Maybe a
    requirementResultExpr  :: Maybe a
        }
      deriving (Int -> Requirement a -> ShowS
    [Requirement a] -> ShowS
    Requirement a -> String
    (Int -> Requirement a -> ShowS)
    -> (Requirement a -> String)
    -> ([Requirement a] -> ShowS)
    -> Show (Requirement a)
    forall a. Show a => Int -> Requirement a -> ShowS
    forall a. Show a => [Requirement a] -> ShowS
    forall a. Show a => Requirement a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Show a => Int -> Requirement a -> ShowS
    showsPrec :: Int -> Requirement a -> ShowS
    $cshow :: forall a. Show a => Requirement a -> String
    show :: Requirement a -> String
    $cshowList :: forall a. Show a => [Requirement a] -> ShowS
    showList :: [Requirement a] -> ShowS
    Show)