module Drasil.SSP.Requirements (funcReqs, funcReqTables, nonFuncReqs) where

import Language.Drasil
import Language.Drasil.Chunk.Concept.NamedCombinators
import qualified Language.Drasil.Sentence.Combinators as S

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

import Data.Drasil.Concepts.Computation (inDatum)
import Data.Drasil.Concepts.Documentation (code,
  datum, funcReqDom, input_, mg, mis, name_, nonFuncReqDom,
  output_, physicalConstraint, property, symbol_, user, value, propOfCorSol)
import Data.Drasil.Concepts.Physics (twoD)

import Drasil.SSP.Defs (crtSlpSrf, slope, slpSrf)
import Drasil.SSP.IMods (fctSfty, nrmShrFor, intsliceFs, crtSlpId)
import Drasil.SSP.Unitals (constF, coords, fs, fsMin, intNormForce, 
  intShrForce, inputs, xMaxExtSlip, xMaxEtrSlip, xMinExtSlip, xMinEtrSlip, 
  yMaxSlip, yMinSlip)

{-Functional Requirements-}

funcReqs :: [ConceptInstance]
funcReqs :: [ConceptInstance]
funcReqs = [ConceptInstance
readAndStore, ConceptInstance
verifyInput, ConceptInstance
determineCritSlip, ConceptInstance
verifyOutput, 
  ConceptInstance
displayInput, ConceptInstance
displayGraph, ConceptInstance
displayFS, ConceptInstance
displayNormal, ConceptInstance
displayShear, 
  ConceptInstance
writeToFile]

funcReqTables :: [LabelledContent]
funcReqTables :: [LabelledContent]
funcReqTables = [LabelledContent
inputDataTable, LabelledContent
inputsToOutputTable]

readAndStore, verifyInput, determineCritSlip, verifyOutput, displayInput, 
  displayGraph, displayFS, displayNormal, displayShear, 
  writeToFile :: ConceptInstance

readAndStore :: ConceptInstance
readAndStore = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"readAndStore" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Read the", forall n. NamedIdea n => n -> Sentence
plural IdeaDict
input_ Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"shown in the table", 
  forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence -> Sentence
namedRef LabelledContent
inputDataTable (String -> Sentence
S String
"Required Inputs") Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"and store the", forall n. NamedIdea n => n -> Sentence
plural IdeaDict
datum]) 
  String
"Read-and-Store" ConceptChunk
funcReqDom

verifyInput :: ConceptInstance
verifyInput = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"verifyInput" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Verify that the", forall n. NamedIdea n => n -> Sentence
plural IdeaDict
inDatum, String -> Sentence
S String
"lie within the",
  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
"Verify-Input" ConceptChunk
funcReqDom

determineCritSlip :: ConceptInstance
determineCritSlip = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"determineCritSlip" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Determine the", forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
crtSlpSrf, String -> Sentence
S String
"for the", forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
input_, 
  forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
slope Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"corresponding to the minimum", forall n. NamedIdea n => n -> Sentence
phrase ConstrConcept
fs Sentence -> Sentence -> Sentence
`sC` 
  String -> Sentence
S String
"by using", Sentence
usingIMs, String -> Sentence
S String
"to calculate the", forall n. NamedIdea n => n -> Sentence
phrase ConstrConcept
fs, String -> Sentence
S String
"for a", 
  forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
slpSrf Sentence -> Sentence -> Sentence
`S.and_` String -> Sentence
S String
"using", forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence
refS InstanceModel
crtSlpId, String -> Sentence
S String
"to find the", 
  forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
slpSrf, String -> Sentence
S String
"that minimizes it"]) 
  String
"Determine-Critical-Slip-Surface" ConceptChunk
funcReqDom

verifyOutput :: ConceptInstance
verifyOutput = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"verifyOutput" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Verify that the", forall n. NamedIdea n => n -> Sentence
phrase DefinedQuantityDict
fsMin Sentence -> Sentence -> Sentence
`S.and_` forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
crtSlpSrf, String -> Sentence
S String
"satisfy the",
  forall n. NamedIdea n => n -> Sentence
plural IdeaDict
physicalConstraint, String -> Sentence
S String
"shown 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
"Verify-Output" ConceptChunk
funcReqDom

displayInput :: ConceptInstance
displayInput = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"displayInput" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Display as", forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
output_, forall n. NounPhrase n => n -> Sentence
phraseNP (forall t. NamedIdea t => t -> NP
the IdeaDict
user) Sentence -> Sentence -> Sentence
:+: String -> Sentence
S String
"-supplied",
  forall n. NamedIdea n => n -> Sentence
plural IdeaDict
input_, String -> Sentence
S String
"listed in", forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence
refS LabelledContent
inputsToOutputTable])
  String
"Display-Input" ConceptChunk
funcReqDom

displayGraph :: ConceptInstance
displayGraph = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"displayGraph" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Display", forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
crtSlpSrf Sentence -> Sentence -> Sentence
`S.the_ofThe` forall c. Idea c => c -> Sentence
short CI
twoD, forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
slope Sentence -> Sentence -> Sentence
`sC` 
  String -> Sentence
S String
"as determined from", forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence
refS InstanceModel
crtSlpId Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"graphically"]) 
  String
"Display-Graph" ConceptChunk
funcReqDom

displayFS :: ConceptInstance
displayFS = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"displayFS" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Display", forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
value Sentence -> Sentence -> Sentence
`S.the_ofThe` forall n. NamedIdea n => n -> Sentence
phrase ConstrConcept
fs, String -> Sentence
S String
"for the", 
  forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
crtSlpSrf Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"as determined from", Sentence
usingIMs]) 
  String
"Display-Factor-of-Safety" ConceptChunk
funcReqDom

displayNormal :: ConceptInstance
displayNormal = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"displayNormal" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Using", Sentence
usingIMs Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"calculate and graphically display the",
  forall n. NamedIdea n => n -> Sentence
plural UnitalChunk
intNormForce]) String
"Display-Interslice-Normal-Forces" ConceptChunk
funcReqDom

displayShear :: ConceptInstance
displayShear = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"displayShear" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Using", Sentence
usingIMs Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"calculate and graphically display the",
  forall n. NamedIdea n => n -> Sentence
plural UnitalChunk
intShrForce]) String
"Display-Interslice-Shear-Forces" ConceptChunk
funcReqDom

writeToFile :: ConceptInstance
writeToFile = forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"writeToFile" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Provide the option of writing the output result data, as given in", 
  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 [ConceptInstance
displayInput, ConceptInstance
displayGraph, ConceptInstance
displayFS, 
  ConceptInstance
displayNormal, ConceptInstance
displayShear]) Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"to a file"]) String
"Write-Results-To-File" 
  ConceptChunk
funcReqDom

usingIMs :: Sentence
usingIMs :: Sentence
usingIMs = SepType -> FoldType -> [Sentence] -> Sentence
foldlList SepType
Comma FoldType
List forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence
refS [InstanceModel
fctSfty, InstanceModel
nrmShrFor, InstanceModel
intsliceFs]

------------------
inputDataTable :: LabelledContent
inputDataTable :: LabelledContent
inputDataTable = forall i r.
(Quantity i, MayHaveUnit i, HasShortName r, Referable r) =>
[i] -> r -> LabelledContent
mkInputPropsTable (forall c.
(Quantity c, Concept c, MayHaveUnit c) =>
c -> DefinedQuantityDict
dqdWr ConstrConcept
coords forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map forall c.
(Quantity c, Concept c, MayHaveUnit c) =>
c -> DefinedQuantityDict
dqdWr [DefinedQuantityDict]
inputs) ConceptInstance
readAndStore
  --FIXME: this has to be seperate since coords is a different type

inputsToOutput :: [DefinedQuantityDict]
inputsToOutput :: [DefinedQuantityDict]
inputsToOutput = DefinedQuantityDict
constF forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map forall c.
(Quantity c, Concept c, MayHaveUnit c) =>
c -> DefinedQuantityDict
dqdWr [UncertQ
xMaxExtSlip, UncertQ
xMaxEtrSlip, UncertQ
xMinExtSlip, 
  UncertQ
xMinEtrSlip, UncertQ
yMaxSlip, UncertQ
yMinSlip]

inputsToOutputTable :: LabelledContent
inputsToOutputTable :: LabelledContent
inputsToOutputTable = Reference -> RawContent -> LabelledContent
llcc (String -> Reference
makeTabRef String
"inputsToOutputTable") forall a b. (a -> b) -> a -> b
$
  [Sentence] -> [[Sentence]] -> Sentence -> Bool -> RawContent
Table [forall n. NamedIdea n => n -> Sentence
titleize IdeaDict
symbol_, forall n. NamedIdea n => n -> Sentence
titleize IdeaDict
name_] (forall a b. [a -> b] -> [a] -> [[b]]
mkTable [forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch, forall n. NamedIdea n => n -> Sentence
phrase] [DefinedQuantityDict]
inputsToOutput)
  (forall n. NamedIdea n => n -> Sentence
atStart' IdeaDict
input_ Sentence -> Sentence -> Sentence
+:+ String -> Sentence
S String
"to be Returned as" Sentence -> Sentence -> Sentence
+:+ forall n. NamedIdea n => n -> Sentence
titleize IdeaDict
output_ forall r.
(Referable r, HasShortName r) =>
Sentence -> r -> Sentence
`follows`
    ConceptInstance
displayInput) Bool
True

{-Nonfunctional Requirements-}
nonFuncReqs :: [ConceptInstance]
nonFuncReqs :: [ConceptInstance]
nonFuncReqs = [ConceptInstance
correct, 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
refS ([Contents] -> [Section] -> Section
propCorSol [] [])
  ]) String
"Correct" 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"