{-# Language TemplateHaskell #-}
-- | Define concept-related chunks. A concept is usually something that has
-- a term, definition, and comes from some domain of knowledge.
module Language.Drasil.Chunk.Concept.Core(
  -- * Concept-related Datatypes
  ConceptChunk(ConDict)
  , sDom
) where

import Control.Lens (makeLenses, (^.),)

import Drasil.Database (UID, HasUID(..), declareHasChunkRefs, Generically(..))

import Language.Drasil.Classes (NamedIdea(term), Idea(getA),
  Definition(defn), ConceptDomain(cdom))
import Language.Drasil.NaturalLanguage.English.NounPhrase.Core (NP)
import Language.Drasil.Sentence (Sentence)

-- | Check if something has one domain. Throws an error if there is more than one.
sDom :: [UID] -> UID
sDom :: [UID] -> UID
sDom [UID
d] = UID
d
sDom [UID]
d = [Char] -> UID
forall a. HasCallStack => [Char] -> a
error ([Char] -> UID) -> [Char] -> UID
forall a b. (a -> b) -> a -> b
$ [Char]
"Expected ConceptDomain to have a single domain, found " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
  Int -> [Char]
forall a. Show a => a -> [Char]
show ([UID] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [UID]
d) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" instead."

-- | The 'ConceptChunk' datatype records a concept that contains a unique id ('UID'),
-- a term ('NP'), a definition ('Sentence'), an optional abbreviation ('Maybe String'),
-- and an associated domain of knowledge (['UID']).
--
-- Ex. The concept of "Accuracy" may be defined as the quality or state of being correct or precise.
data ConceptChunk = ConDict { ConceptChunk -> UID
_uu :: UID -- ^ The 'UID' of the concept.
                            , ConceptChunk -> NP
_np :: NP -- ^ The term for the concept.
                            , ConceptChunk -> Maybe [Char]
mabbr :: Maybe String -- ^ The optional abbreviation for the concept.
                            , ConceptChunk -> Sentence
_defn' :: Sentence -- ^ The definition of the concept.
                            , ConceptChunk -> [UID]
cdom' :: [UID] -- ^ Domain of the concept.
                            }
makeLenses ''ConceptChunk
declareHasChunkRefs ''ConceptChunk

-- | Equal if 'UID's are equal.
instance Eq            ConceptChunk where ConceptChunk
c1 == :: ConceptChunk -> ConceptChunk -> Bool
== ConceptChunk
c2 = (ConceptChunk
c1 ConceptChunk -> Getting UID ConceptChunk UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID ConceptChunk UID
forall c. HasUID c => Getter c UID
Getter ConceptChunk UID
uid) UID -> UID -> Bool
forall a. Eq a => a -> a -> Bool
== (ConceptChunk
c2 ConceptChunk -> Getting UID ConceptChunk UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID ConceptChunk UID
forall c. HasUID c => Getter c UID
Getter ConceptChunk UID
uid)
-- | Finds 'UID' of the 'ConceptChunk'.
instance HasUID        ConceptChunk where uid :: Getter ConceptChunk UID
uid = (UID -> f UID) -> ConceptChunk -> f ConceptChunk
Lens' ConceptChunk UID
uu
-- | Finds term ('NP') of the 'ConceptChunk'.
instance NamedIdea     ConceptChunk where term :: Lens' ConceptChunk NP
term = (NP -> f NP) -> ConceptChunk -> f ConceptChunk
Lens' ConceptChunk NP
np
-- | Finds the abbreviation of the 'ConceptChunk'.
instance Idea          ConceptChunk where getA :: ConceptChunk -> Maybe [Char]
getA = ConceptChunk -> Maybe [Char]
mabbr
-- | Finds definition of a 'ConceptChunk'.
instance Definition    ConceptChunk where defn :: Lens' ConceptChunk Sentence
defn = (Sentence -> f Sentence) -> ConceptChunk -> f ConceptChunk
Lens' ConceptChunk Sentence
defn'
-- | Finds the domain of 'UID's of a 'ConceptChunk'.
instance ConceptDomain ConceptChunk where cdom :: ConceptChunk -> [UID]
cdom = ConceptChunk -> [UID]
cdom'