-- | Contains functions related to the choice of concept matches.
module Language.Drasil.Code.Imperative.ConceptMatch (
  chooseConcept, conceptToGOOL
) where

import Language.Drasil (UID, Sentence(S), (+:+), (+:+.))

import Language.Drasil.Choices (Choices(..), CodeConcept(..),
    MatchedConceptMap, showChs, Maps(..))

import GOOL.Drasil (SValue, OOProg, MathConstant(..))

import Prelude hiding (pi)
import qualified Data.Map as Map (mapWithKey)
import Control.Monad.State (State, modify)

-- | Concretizes the ConceptMatchMap in Choices to a 'MatchedConceptMap'.
-- Currently we don't have any Choices that would prevent a 'CodeConcept' from
-- being mapped, so we just take the head of the list of 'CodeConcept's
-- The ConceptMatchMap from choices is passed to chooseConcept' internally, this way
-- any 'CodeConcept' list can be matched to its appropiate 'UID'.
chooseConcept :: Choices -> State [Sentence] MatchedConceptMap
chooseConcept :: Choices -> State [Sentence] MatchedConceptMap
chooseConcept Choices
chs = forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence forall a b. (a -> b) -> a -> b
$ forall k a b. (k -> a -> b) -> Map k a -> Map k b
Map.mapWithKey UID -> [CodeConcept] -> State [Sentence] CodeConcept
chooseConcept' (Maps -> ConceptMatchMap
conceptMatch forall a b. (a -> b) -> a -> b
$ Choices -> Maps
maps Choices
chs)
  where chooseConcept' :: UID -> [CodeConcept] -> State [Sentence] CodeConcept
        chooseConcept' :: UID -> [CodeConcept] -> State [Sentence] CodeConcept
chooseConcept' UID
_ [] = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"Empty list of CodeConcepts in the " forall a. [a] -> [a] -> [a]
++
          [Char]
"ConceptMatchMap"
        chooseConcept' UID
uid (CodeConcept
c:[CodeConcept]
_) = do
            forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (forall a. [a] -> [a] -> [a]
++ [[Char] -> Sentence
S [Char]
"Code Concept" Sentence -> Sentence -> Sentence
+:+ [Char] -> Sentence
S (forall a. Show a => a -> [Char]
show UID
uid) Sentence -> Sentence -> Sentence
+:+ [Char] -> Sentence
S [Char]
"selected as" Sentence -> Sentence -> Sentence
+:+. forall a. RenderChoices a => a -> Sentence
showChs CodeConcept
c])
            forall (m :: * -> *) a. Monad m => a -> m a
return CodeConcept
c

-- | Translates a 'CodeConcept' into GOOL.
conceptToGOOL :: (OOProg r) => CodeConcept -> SValue r
conceptToGOOL :: forall (r :: * -> *). OOProg r => CodeConcept -> SValue r
conceptToGOOL CodeConcept
Pi = forall (r :: * -> *). MathConstant r => SValue r
pi