module Drasil.SWHS.Requirements where --all of this file is exported

import Language.Drasil
import Language.Drasil.Chunk.Concept.NamedCombinators
import qualified Language.Drasil.NounPhrase.Combinators as NP
import qualified Language.Drasil.Sentence.Combinators as S
import Theory.Drasil (InstanceModel, HasOutput(output))

import Drasil.DocLang (inReq, mkMaintainableNFR)
import Drasil.DocLang.SRS (datCon, propCorSol) 

import Data.Drasil.Concepts.Computation (inValue)
import Data.Drasil.Concepts.Documentation (code, condition,
  funcReqDom, input_, mg, mis, nonFuncReqDom, output_,
  physicalConstraint, property, propOfCorSol, value, vavPlan)
import Data.Drasil.Concepts.Math (parameter)
import Data.Drasil.Concepts.PhysicalProperties (materialProprty)
import Data.Drasil.Concepts.Thermodynamics as CT (lawConsEnergy, melting)

import Data.Drasil.Quantities.PhysicalProperties (mass)
import Data.Drasil.Quantities.Physics (energy, time)

import Drasil.SWHS.DataDefs (waterMass, waterVolume, tankVolume, 
  balanceDecayRate, balanceDecayTime, balanceSolidPCM, balanceLiquidPCM)
import Drasil.SWHS.Concepts (phsChgMtrl, tank)
import Drasil.SWHS.IMods (eBalanceOnWtr, eBalanceOnPCM, heatEInWtr, heatEInPCM, 
  iMods)
import Drasil.SWHS.Unitals (consTol, pcmE, tFinalMelt, tInitMelt, watE)

import Control.Lens ((^.))

------------------------------
-- Data Constraint: Table 1 --
------------------------------

------------------------------
-- Section 5 : REQUIREMENTS --
------------------------------
-----------------------------------
-- 5.1 : Functional Requirements --
-----------------------------------

inReqDesc :: Sentence
inReqDesc :: Sentence
inReqDesc = SepType -> FoldType -> [Sentence] -> Sentence
foldlList SepType
Comma FoldType
List [forall n. NounPhrase n => n -> Sentence
pluralNP (NP -> NP
NP.the (forall c d. (NamedIdea c, NamedIdea d) => c -> d -> NP
combineNINI ConceptChunk
tank ConceptChunk
parameter)),
  forall n. NamedIdea n => n -> Sentence
plural IdeaDict
materialProprty, String -> Sentence
S String
"initial" Sentence -> Sentence -> Sentence
+:+ forall n. NamedIdea n => n -> Sentence
plural IdeaDict
condition]

funcReqs :: [ConceptInstance]
funcReqs :: [ConceptInstance]
funcReqs = [ConceptInstance
findMass, ConceptInstance
checkWithPhysConsts, ConceptInstance
outputInputDerivVals,
  [InstanceModel] -> ConceptInstance
calcValues [InstanceModel]
swhsOutputs, ConceptInstance
verifyEnergyOutput, ConceptInstance
calcPCMMeltBegin, ConceptInstance
calcPCMMeltEnd,
  [InstanceModel] -> ConceptInstance
outputValues [InstanceModel]
swhsOutputs]

findMass, checkWithPhysConsts, outputInputDerivVals, verifyEnergyOutput,
  calcPCMMeltBegin, calcPCMMeltEnd :: ConceptInstance

calcValues, outputValues :: [InstanceModel] -> ConceptInstance

--
findMass :: ConceptInstance
findMass = forall r s t.
(Referable r, HasShortName r, Referable s, HasShortName s,
 Referable t, HasShortName t) =>
r -> Sentence -> [s] -> [t] -> ConceptInstance
findMassConstruct (Sentence -> ConceptInstance
inReq Sentence
EmptyS) (forall n. NamedIdea n => n -> Sentence
plural UnitalChunk
mass) [InstanceModel]
iMods 
  [DataDefinition
waterMass, DataDefinition
waterVolume, DataDefinition
tankVolume]

findMassConstruct :: (Referable r, HasShortName r, Referable s, HasShortName s,
  Referable t, HasShortName t) => r -> Sentence -> [s] -> [t] -> ConceptInstance
findMassConstruct :: forall r s t.
(Referable r, HasShortName r, Referable s, HasShortName s,
 Referable t, HasShortName t) =>
r -> Sentence -> [s] -> [t] -> ConceptInstance
findMassConstruct r
fr Sentence
m [s]
ims [t]
ddefs = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"findMass" ([Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Use the", forall n. NamedIdea n => n -> Sentence
plural IdeaDict
input_ Sentence -> Sentence -> Sentence
`S.in_` forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence
refS r
fr, String -> Sentence
S String
"to find the", 
  Sentence
m, String -> Sentence
S String
"needed for", SepType -> FoldType -> [Sentence] -> Sentence
foldlList SepType
Comma FoldType
List (forall a b. (a -> b) -> [a] -> [b]
map forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence
refS [s]
ims) Sentence -> Sentence -> Sentence
`sC`
  String -> Sentence
S String
"using", SepType -> FoldType -> [Sentence] -> Sentence
foldlList SepType
Comma FoldType
List (forall a b. (a -> b) -> [a] -> [b]
map forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence
refS [t]
ddefs)])
  String
"Find-Mass" ConceptChunk
funcReqDom
--
checkWithPhysConsts :: ConceptInstance
checkWithPhysConsts = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"checkWithPhysConsts" ([Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Verify that", forall n. NounPhrase n => n -> Sentence
pluralNP (forall t. NamedIdea t => t -> NP
the IdeaDict
input_), String -> Sentence
S String
"satisfy the required",
  forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence -> Sentence
namedRef ([Contents] -> [Section] -> Section
datCon [] []) (forall n. NamedIdea n => n -> Sentence
plural IdeaDict
physicalConstraint)])
  String
"Check-Input-with-Physical_Constraints" ConceptChunk
funcReqDom
--
outputInputDerivVals :: ConceptInstance
outputInputDerivVals = [Sentence] -> ConceptInstance
oIDQConstruct [Sentence]
oIDQVals

oIDQConstruct :: [Sentence] -> ConceptInstance
oIDQConstruct :: [Sentence] -> ConceptInstance
oIDQConstruct [Sentence]
x = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"outputInputDerivVals" ([Sentence] -> Sentence
foldlSentCol [
  forall n. NamedIdea n => n -> Sentence
titleize IdeaDict
output_, forall n. NounPhrase n => n -> Sentence
pluralNP (forall t. NamedIdea t => t -> NP
the IdeaDict
inValue) Sentence -> Sentence -> Sentence
`S.and_`
  String -> Sentence
S String
"derived", forall n. NamedIdea n => n -> Sentence
plural IdeaDict
value Sentence -> Sentence -> Sentence
`S.inThe` String -> Sentence
S String
"following list"] Sentence -> Sentence -> Sentence
+:+.
  SepType -> FoldType -> [Sentence] -> Sentence
foldlList SepType
Comma FoldType
List [Sentence]
x) String
"Output-Input-Derived-Values" ConceptChunk
funcReqDom

oIDQVals :: [Sentence]
oIDQVals :: [Sentence]
oIDQVals = forall a b. (a -> b) -> [a] -> [b]
map [Sentence] -> Sentence
foldlSent_ [
  [forall n. NounPhrase n => n -> Sentence
pluralNP (forall t. NamedIdea t => t -> NP
the IdeaDict
value), forall r. (Referable r, HasShortName r) => r -> Sentence
fromSource (Sentence -> ConceptInstance
inReq Sentence
EmptyS)],
  [forall n. NounPhrase n => n -> Sentence
pluralNP (forall t. NamedIdea t => t -> NP
the UnitalChunk
mass), forall r. (Referable r, HasShortName r) => r -> Sentence
fromSource ConceptInstance
findMass],
  [forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch (DataDefinition
balanceDecayRate forall s a. s -> Getting a s a -> a
^. forall d. DefinesQuantity d => Getter d QuantityDict
defLhs), forall r. (Referable r, HasShortName r) => r -> Sentence
fromSource DataDefinition
balanceDecayRate],
  [forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch (DataDefinition
balanceDecayTime forall s a. s -> Getting a s a -> a
^. forall d. DefinesQuantity d => Getter d QuantityDict
defLhs), forall r. (Referable r, HasShortName r) => r -> Sentence
fromSource DataDefinition
balanceDecayTime],
  [forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch (DataDefinition
balanceSolidPCM forall s a. s -> Getting a s a -> a
^. forall d. DefinesQuantity d => Getter d QuantityDict
defLhs),  forall r. (Referable r, HasShortName r) => r -> Sentence
fromSource DataDefinition
balanceSolidPCM],
  [forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch (DataDefinition
balanceLiquidPCM forall s a. s -> Getting a s a -> a
^. forall d. DefinesQuantity d => Getter d QuantityDict
defLhs), forall r. (Referable r, HasShortName r) => r -> Sentence
fromSource DataDefinition
balanceLiquidPCM]
  ]

--
calcValues :: [InstanceModel] -> ConceptInstance
calcValues [InstanceModel]
l = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"calcValues" (String -> Sentence
S String
"Calculate the following" Sentence -> Sentence -> Sentence
+: forall n. NamedIdea n => n -> Sentence
plural IdeaDict
value Sentence -> Sentence -> Sentence
+:+.
  [InstanceModel] -> Sentence
outputList [InstanceModel]
l) String
"Calculate-Values" ConceptChunk
funcReqDom
--
verifyEnergyOutput :: ConceptInstance
verifyEnergyOutput = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"verifyEnergyOutput" ([Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Verify that the", forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
energy, forall n. NamedIdea n => n -> Sentence
plural IdeaDict
output_,
  Sentence -> Sentence
sParen (forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch ConstrConcept
watE Sentence -> Sentence -> Sentence
:+: Sentence -> Sentence
sParen (forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch UnitalChunk
time) Sentence -> Sentence -> Sentence
`S.and_` forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch ConstrConcept
pcmE Sentence -> Sentence -> Sentence
:+:
  Sentence -> Sentence
sParen (forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch UnitalChunk
time)), String -> Sentence
S String
"follow the", forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
CT.lawConsEnergy Sentence -> Sentence -> Sentence
`sC`
  String -> Sentence
S String
"as outlined in", forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence -> Sentence
namedRef ([Contents] -> [Section] -> Section
propCorSol [] []) (forall n. NamedIdea n => n -> Sentence
titleize' IdeaDict
propOfCorSol) Sentence -> Sentence -> Sentence
`sC`
  String -> Sentence
S String
"with relative error no greater than", forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch DefinedQuantityDict
consTol])
  String
"Verify-Energy-Output-Follow-Conservation-of-Energy" ConceptChunk
funcReqDom
--
calcPCMMeltBegin :: ConceptInstance
calcPCMMeltBegin = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"calcPCMMeltBegin" ([Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Calculate and", forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
output_, forall n. NounPhrase n => n -> Sentence
phraseNP (forall t. NamedIdea t => t -> NP
the UnitalChunk
time),
  String -> Sentence
S String
"at which the", forall c. Idea c => c -> Sentence
short CI
phsChgMtrl, String -> Sentence
S String
"begins to melt",
  forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch UnitalChunk
tInitMelt, forall r. (Referable r, HasShortName r) => r -> Sentence
fromSource InstanceModel
eBalanceOnPCM])
  String
"Calculate-PCM-Melt-Begin-Time" ConceptChunk
funcReqDom
--
calcPCMMeltEnd :: ConceptInstance
calcPCMMeltEnd = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"calcPCMMeltEnd" ([Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Calculate and", forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
output_, forall n. NounPhrase n => n -> Sentence
phraseNP (forall t. NamedIdea t => t -> NP
the UnitalChunk
time),
  String -> Sentence
S String
"at which the", forall c. Idea c => c -> Sentence
short CI
phsChgMtrl, String -> Sentence
S String
"stops", forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
CT.melting,
  forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch UnitalChunk
tFinalMelt, forall r. (Referable r, HasShortName r) => r -> Sentence
fromSource InstanceModel
eBalanceOnPCM])
  String
"Calculate-PCM-Melt-End-Time" ConceptChunk
funcReqDom
--
outputValues :: [InstanceModel] -> ConceptInstance
outputValues [InstanceModel]
l = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"outputValues" (forall n. NamedIdea n => n -> Sentence
titleize IdeaDict
output_ Sentence -> Sentence -> Sentence
+:+. [InstanceModel] -> Sentence
outputList [InstanceModel]
l)
  String
"Output-Values" ConceptChunk
funcReqDom

outputList :: [InstanceModel] -> Sentence
outputList :: [InstanceModel] -> Sentence
outputList [InstanceModel]
l = SepType -> FoldType -> [Sentence] -> Sentence
foldlList SepType
Comma FoldType
List forall a b. (a -> b) -> a -> b
$
  forall a b. (a -> b) -> [a] -> [b]
map (\InstanceModel
x -> forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch (InstanceModel
x forall s a. s -> Getting a s a -> a
^. forall c. HasOutput c => Getter c QuantityDict
output) Sentence -> Sentence -> Sentence
:+: Sentence -> Sentence
sParen (forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch UnitalChunk
time) Sentence -> Sentence -> Sentence
+:+ forall r. (Referable r, HasShortName r) => r -> Sentence
fromSource InstanceModel
x) [InstanceModel]
l

swhsOutputs :: [InstanceModel]
swhsOutputs :: [InstanceModel]
swhsOutputs = [InstanceModel
eBalanceOnWtr, InstanceModel
eBalanceOnPCM, InstanceModel
heatEInWtr, InstanceModel
heatEInPCM]

-- List structure same between all examples

--How to include pi?
--How to add exponents?

---------------------------------------
-- 5.2 : Non-functional Requirements --
---------------------------------------

nfRequirements :: [ConceptInstance]
nfRequirements :: [ConceptInstance]
nfRequirements = [ConceptInstance
correct, ConceptInstance
verifiable, ConceptInstance
understandable, ConceptInstance
reusable, ConceptInstance
maintainable]

correct :: ConceptInstance
correct :: ConceptInstance
correct = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"correct" ([Sentence] -> Sentence
foldlSent [forall n. NounPhrase n => n -> Sentence
atStartNP'
  (IdeaDict
output_ forall c d. (NamedIdea c, NamedIdea d) => c -> d -> NP
`the_ofThePS` IdeaDict
code), String -> Sentence
S String
"have the",
  forall n. NamedIdea n => n -> Sentence
plural IdeaDict
property, String -> Sentence
S String
"described in", forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence -> Sentence
namedRef ([Contents] -> [Section] -> Section
propCorSol [] []) (forall n. NamedIdea n => n -> Sentence
titleize' IdeaDict
propOfCorSol)
  ]) String
"Correct" ConceptChunk
nonFuncReqDom
 
verifiable :: ConceptInstance
verifiable :: ConceptInstance
verifiable = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"verifiable" ([Sentence] -> Sentence
foldlSent [
  forall n. NounPhrase n => n -> Sentence
atStartNP (forall t. NamedIdea t => t -> NP
the IdeaDict
code), String -> Sentence
S String
"is tested with complete",
  forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
vavPlan]) String
"Verifiable" ConceptChunk
nonFuncReqDom

understandable :: ConceptInstance
understandable :: ConceptInstance
understandable = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"understandable" ([Sentence] -> Sentence
foldlSent [
  forall n. NounPhrase n => n -> Sentence
atStartNP (forall t. NamedIdea t => t -> NP
the IdeaDict
code), String -> Sentence
S String
"is modularized with complete",
  forall n. NamedIdea n => n -> Sentence
phrase CI
mg Sentence -> Sentence -> Sentence
`S.and_` forall n. NamedIdea n => n -> Sentence
phrase CI
mis]) String
"Understandable" ConceptChunk
nonFuncReqDom

reusable :: ConceptInstance
reusable :: ConceptInstance
reusable = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"reusable" ([Sentence] -> Sentence
foldlSent [
  forall n. NounPhrase n => n -> Sentence
atStartNP (forall t. NamedIdea t => t -> NP
the IdeaDict
code), String -> Sentence
S String
"is modularized"]) String
"Reusable" ConceptChunk
nonFuncReqDom

maintainable :: ConceptInstance
maintainable :: ConceptInstance
maintainable = String -> Integer -> String -> ConceptInstance
mkMaintainableNFR String
"maintainable" Integer
10 String
"Maintainable"