{-# LANGUAGE PostfixOperators #-}
module Drasil.DocumentLanguage.TraceabilityMatrix where
import Language.Drasil
import Database.Drasil hiding (cdb)
import SysInfo.Drasil
import qualified Language.Drasil.Sentence.Combinators as S
import Data.Drasil.Concepts.Documentation (purpose, component, dependency,
item, reference, traceyMatrix)
import Drasil.DocumentLanguage.Definitions (helpToRefField)
import Control.Lens ((^.), Getting)
import Data.List (nub)
import qualified Data.Map as Map
type TraceViewCat = [UID] -> ChunkDB -> [UID]
traceMIntro :: [LabelledContent] -> [Sentence] -> Contents
traceMIntro :: [LabelledContent] -> [Sentence] -> Contents
traceMIntro refs :: [LabelledContent]
refs trailings :: [Sentence]
trailings = UnlabelledContent -> Contents
UlC (UnlabelledContent -> Contents) -> UnlabelledContent -> Contents
forall a b. (a -> b) -> a -> b
$ RawContent -> UnlabelledContent
ulcc (RawContent -> UnlabelledContent)
-> RawContent -> UnlabelledContent
forall a b. (a -> b) -> a -> b
$ Sentence -> RawContent
Paragraph (Sentence -> RawContent) -> Sentence -> RawContent
forall a b. (a -> b) -> a -> b
$ [Sentence] -> Sentence
foldlSent [NamedChunk -> Sentence
forall n. (HasUID n, NamedIdea n) => n -> Sentence
phrase NamedChunk
purpose
Sentence -> Sentence -> Sentence
`S.the_ofTheC` NamedChunk -> Sentence
forall n. (HasUID n, NamedIdea n) => n -> Sentence
plural NamedChunk
traceyMatrix, String -> Sentence
S "is to provide easy", NamedChunk -> Sentence
forall n. (HasUID n, NamedIdea n) => n -> Sentence
plural NamedChunk
reference,
String -> Sentence
S "on what has to be additionally modified if a certain",
NamedChunk -> Sentence
forall n. (HasUID n, NamedIdea n) => n -> Sentence
phrase NamedChunk
component, String -> Sentence
S "is changed. Every time a", NamedChunk -> Sentence
forall n. (HasUID n, NamedIdea n) => n -> Sentence
phrase NamedChunk
component,
String -> Sentence
S "is changed, the", NamedChunk -> Sentence
forall n. (HasUID n, NamedIdea n) => n -> Sentence
plural NamedChunk
item, String -> Sentence
S "in the column of that",
NamedChunk -> Sentence
forall n. (HasUID n, NamedIdea n) => n -> Sentence
phrase NamedChunk
component, String -> Sentence
S "that are marked with an", Sentence -> Sentence
Quote (String -> Sentence
S "X"),
String -> Sentence
S "should be modified as well"] Sentence -> Sentence -> Sentence
+:+ [Sentence] -> Sentence
foldlSent_ ((LabelledContent -> Sentence -> Sentence)
-> [LabelledContent] -> [Sentence] -> [Sentence]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith LabelledContent -> Sentence -> Sentence
forall a.
(Referable a, HasShortName a) =>
a -> Sentence -> Sentence
tableShows [LabelledContent]
refs [Sentence]
trailings)
generateTraceTableView :: UID -> Sentence -> [TraceViewCat] -> [TraceViewCat] -> SystemInformation -> LabelledContent
generateTraceTableView :: UID
-> Sentence
-> [TraceViewCat]
-> [TraceViewCat]
-> SystemInformation
-> LabelledContent
generateTraceTableView u :: UID
u _ [] _ _ = String -> LabelledContent
forall a. HasCallStack => String -> a
error (String -> LabelledContent) -> String -> LabelledContent
forall a b. (a -> b) -> a -> b
$ "Expected non-empty list of column-view categories for traceability matrix " String -> String -> String
forall a. [a] -> [a] -> [a]
++ UID -> String
forall a. Show a => a -> String
show UID
u
generateTraceTableView u :: UID
u _ _ [] _ = String -> LabelledContent
forall a. HasCallStack => String -> a
error (String -> LabelledContent) -> String -> LabelledContent
forall a b. (a -> b) -> a -> b
$ "Expected non-empty list of row-view categories for traceability matrix " String -> String -> String
forall a. [a] -> [a] -> [a]
++ UID -> String
forall a. Show a => a -> String
show UID
u
generateTraceTableView u :: UID
u desc :: Sentence
desc cols :: [TraceViewCat]
cols rows :: [TraceViewCat]
rows c :: SystemInformation
c = Reference -> RawContent -> LabelledContent
llcc (UID -> Reference
makeTabRef' UID
u) (RawContent -> LabelledContent) -> RawContent -> LabelledContent
forall a b. (a -> b) -> a -> b
$ [Sentence] -> [[Sentence]] -> Sentence -> Bool -> RawContent
Table
(Sentence
EmptyS Sentence -> [Sentence] -> [Sentence]
forall a. a -> [a] -> [a]
: String -> [Sentence] -> [Sentence]
forall a. String -> [a] -> [a]
ensureItems (UID -> String
forall a. Show a => a -> String
show UID
u) (([UID] -> [UID]) -> SystemInformation -> [Sentence]
traceMColHeader [UID] -> [UID]
colf SystemInformation
c))
([Sentence] -> [[UID]] -> [UID] -> [[Sentence]]
forall a. Eq a => [Sentence] -> [[a]] -> [a] -> [[Sentence]]
makeTMatrix (String -> [Sentence] -> [Sentence]
forall a. String -> [a] -> [a]
ensureItems (UID -> String
forall a. Show a => a -> String
show UID
u) ([Sentence] -> [Sentence]) -> [Sentence] -> [Sentence]
forall a b. (a -> b) -> a -> b
$ ([UID] -> [UID]) -> SystemInformation -> [Sentence]
traceMRowHeader [UID] -> [UID]
rowf SystemInformation
c) (([UID] -> [UID]) -> ([UID] -> [UID]) -> ChunkDB -> [[UID]]
traceMColumns [UID] -> [UID]
colf [UID] -> [UID]
rowf ChunkDB
cdb) ([UID] -> [[Sentence]]) -> [UID] -> [[Sentence]]
forall a b. (a -> b) -> a -> b
$ ([UID] -> [UID]) -> ChunkDB -> [UID]
traceMReferees [UID] -> [UID]
colf ChunkDB
cdb)
(NamedChunk -> Sentence -> Sentence
forall c. NamedIdea c => c -> Sentence -> Sentence
showingCxnBw NamedChunk
traceyMatrix Sentence
desc) Bool
True where
cdb :: ChunkDB
cdb = SystemInformation -> ChunkDB
_sysinfodb SystemInformation
c
colf :: [UID] -> [UID]
colf = [TraceViewCat] -> ChunkDB -> [UID] -> [UID]
layoutUIDs [TraceViewCat]
cols ChunkDB
cdb
rowf :: [UID] -> [UID]
rowf = [TraceViewCat] -> ChunkDB -> [UID] -> [UID]
layoutUIDs [TraceViewCat]
rows ChunkDB
cdb
traceMReferees :: ([UID] -> [UID]) -> ChunkDB -> [UID]
traceMReferees :: ([UID] -> [UID]) -> ChunkDB -> [UID]
traceMReferees f :: [UID] -> [UID]
f = [UID] -> [UID]
f ([UID] -> [UID]) -> (ChunkDB -> [UID]) -> ChunkDB -> [UID]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [UID] -> [UID]
forall a. Eq a => [a] -> [a]
nub ([UID] -> [UID]) -> (ChunkDB -> [UID]) -> ChunkDB -> [UID]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map UID [UID] -> [UID]
forall k a. Map k a -> [k]
Map.keys (Map UID [UID] -> [UID])
-> (ChunkDB -> Map UID [UID]) -> ChunkDB -> [UID]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ChunkDB
-> Getting (Map UID [UID]) ChunkDB (Map UID [UID]) -> Map UID [UID]
forall s a. s -> Getting a s a -> a
^. Getting (Map UID [UID]) ChunkDB (Map UID [UID])
Lens' ChunkDB (Map UID [UID])
refbyTable)
traceMReferrers :: ([UID] -> [UID]) -> ChunkDB -> [UID]
traceMReferrers :: ([UID] -> [UID]) -> ChunkDB -> [UID]
traceMReferrers f :: [UID] -> [UID]
f = [UID] -> [UID]
f ([UID] -> [UID]) -> (ChunkDB -> [UID]) -> ChunkDB -> [UID]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [UID] -> [UID]
forall a. Eq a => [a] -> [a]
nub ([UID] -> [UID]) -> (ChunkDB -> [UID]) -> ChunkDB -> [UID]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[UID]] -> [UID]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[UID]] -> [UID]) -> (ChunkDB -> [[UID]]) -> ChunkDB -> [UID]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map UID [UID] -> [[UID]]
forall k a. Map k a -> [a]
Map.elems (Map UID [UID] -> [[UID]])
-> (ChunkDB -> Map UID [UID]) -> ChunkDB -> [[UID]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ChunkDB
-> Getting (Map UID [UID]) ChunkDB (Map UID [UID]) -> Map UID [UID]
forall s a. s -> Getting a s a -> a
^. Getting (Map UID [UID]) ChunkDB (Map UID [UID])
Lens' ChunkDB (Map UID [UID])
refbyTable)
traceMHeader :: (ChunkDB -> [UID]) -> SystemInformation -> [Sentence]
f :: ChunkDB -> [UID]
f c :: SystemInformation
c = (UID -> Sentence) -> [UID] -> [Sentence]
forall a b. (a -> b) -> [a] -> [b]
map (UID -> SystemInformation -> Sentence
`helpToRefField` SystemInformation
c) ([UID] -> [Sentence]) -> [UID] -> [Sentence]
forall a b. (a -> b) -> a -> b
$ ChunkDB -> [UID]
f (ChunkDB -> [UID]) -> ChunkDB -> [UID]
forall a b. (a -> b) -> a -> b
$ SystemInformation -> ChunkDB
_sysinfodb SystemInformation
c
traceMColHeader :: ([UID] -> [UID]) -> SystemInformation -> [Sentence]
f :: [UID] -> [UID]
f = (ChunkDB -> [UID]) -> SystemInformation -> [Sentence]
traceMHeader (([UID] -> [UID]) -> ChunkDB -> [UID]
traceMReferees [UID] -> [UID]
f)
traceMRowHeader :: ([UID] -> [UID]) -> SystemInformation -> [Sentence]
f :: [UID] -> [UID]
f = (ChunkDB -> [UID]) -> SystemInformation -> [Sentence]
traceMHeader (([UID] -> [UID]) -> ChunkDB -> [UID]
traceMReferrers [UID] -> [UID]
f)
traceMColumns :: ([UID] -> [UID]) -> ([UID] -> [UID]) -> ChunkDB -> [[UID]]
traceMColumns :: ([UID] -> [UID]) -> ([UID] -> [UID]) -> ChunkDB -> [[UID]]
traceMColumns fc :: [UID] -> [UID]
fc fr :: [UID] -> [UID]
fr c :: ChunkDB
c = (UID -> [UID]) -> [UID] -> [[UID]]
forall a b. (a -> b) -> [a] -> [b]
map ((\u :: [UID]
u -> (UID -> Bool) -> [UID] -> [UID]
forall a. (a -> Bool) -> [a] -> [a]
filter (UID -> [UID] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [UID]
u) ([UID] -> [UID]) -> [UID] -> [UID]
forall a b. (a -> b) -> a -> b
$ [UID] -> [UID]
fc [UID]
u) ([UID] -> [UID]) -> (UID -> [UID]) -> UID -> [UID]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UID -> Map UID [UID] -> [UID]) -> Map UID [UID] -> UID -> [UID]
forall a b c. (a -> b -> c) -> b -> a -> c
flip UID -> Map UID [UID] -> [UID]
traceLookup (ChunkDB
c ChunkDB
-> Getting (Map UID [UID]) ChunkDB (Map UID [UID]) -> Map UID [UID]
forall s a. s -> Getting a s a -> a
^. Getting (Map UID [UID]) ChunkDB (Map UID [UID])
Lens' ChunkDB (Map UID [UID])
traceTable)) ([UID] -> [[UID]]) -> [UID] -> [[UID]]
forall a b. (a -> b) -> a -> b
$ ([UID] -> [UID]) -> ChunkDB -> [UID]
traceMReferrers [UID] -> [UID]
fr ChunkDB
c
tableShows :: (Referable a, HasShortName a) => a -> Sentence -> Sentence
tableShows :: a -> Sentence -> Sentence
tableShows r :: a
r end :: Sentence
end = a -> Sentence
forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence
refS a
r Sentence -> Sentence -> Sentence
+:+ String -> Sentence
S "shows the" Sentence -> Sentence -> Sentence
+:+ NamedChunk -> Sentence
forall n. (HasUID n, NamedIdea n) => n -> Sentence
plural NamedChunk
dependency Sentence -> Sentence -> Sentence
`S.of_` (Sentence
end Sentence -> Sentence
!.)
ensureItems :: String -> [a] -> [a]
ensureItems :: String -> [a] -> [a]
ensureItems u :: String
u [] = String -> [a]
forall a. HasCallStack => String -> a
error (String -> [a]) -> String -> [a]
forall a b. (a -> b) -> a -> b
$ "Expected non-empty matrix dimension for traceability matrix " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
u
ensureItems _ l :: [a]
l = [a]
l
layoutUIDs :: [TraceViewCat] -> ChunkDB -> [UID] -> [UID]
layoutUIDs :: [TraceViewCat] -> ChunkDB -> [UID] -> [UID]
layoutUIDs a :: [TraceViewCat]
a c :: ChunkDB
c e :: [UID]
e = (UID -> Bool) -> [UID] -> [UID]
forall a. (a -> Bool) -> [a] -> [a]
filter (UID -> [UID] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (Map UID [UID] -> [UID]
forall k a. Map k a -> [k]
Map.keys (Map UID [UID] -> [UID]) -> Map UID [UID] -> [UID]
forall a b. (a -> b) -> a -> b
$ ChunkDB
c ChunkDB
-> Getting (Map UID [UID]) ChunkDB (Map UID [UID]) -> Map UID [UID]
forall s a. s -> Getting a s a -> a
^. Getting (Map UID [UID]) ChunkDB (Map UID [UID])
Lens' ChunkDB (Map UID [UID])
traceTable)) ([UID] -> [UID]) -> [UID] -> [UID]
forall a b. (a -> b) -> a -> b
$ (TraceViewCat -> [UID]) -> [TraceViewCat] -> [UID]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\x :: TraceViewCat
x -> TraceViewCat
x [UID]
e ChunkDB
c) [TraceViewCat]
a
traceViewFilt :: HasUID a => (a -> Bool) -> Getting (UMap a) ChunkDB (UMap a) -> TraceViewCat
traceViewFilt :: (a -> Bool) -> Getting (UMap a) ChunkDB (UMap a) -> TraceViewCat
traceViewFilt f :: a -> Bool
f table :: Getting (UMap a) ChunkDB (UMap a)
table _ = (a -> UID) -> [a] -> [UID]
forall a b. (a -> b) -> [a] -> [b]
map (a -> Getting UID a UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID a UID
forall c. HasUID c => Lens' c UID
uid) ([a] -> [UID]) -> (ChunkDB -> [a]) -> ChunkDB -> [UID]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter a -> Bool
f ([a] -> [a]) -> (ChunkDB -> [a]) -> ChunkDB -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UMap a -> [a]
forall a. UMap a -> [a]
asOrderedList (UMap a -> [a]) -> (ChunkDB -> UMap a) -> ChunkDB -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ChunkDB -> Getting (UMap a) ChunkDB (UMap a) -> UMap a
forall s a. s -> Getting a s a -> a
^. Getting (UMap a) ChunkDB (UMap a)
table)
traceView :: HasUID a => Getting (UMap a) ChunkDB (UMap a) -> TraceViewCat
traceView :: Getting (UMap a) ChunkDB (UMap a) -> TraceViewCat
traceView = (a -> Bool) -> Getting (UMap a) ChunkDB (UMap a) -> TraceViewCat
forall a.
HasUID a =>
(a -> Bool) -> Getting (UMap a) ChunkDB (UMap a) -> TraceViewCat
traceViewFilt (Bool -> a -> Bool
forall a b. a -> b -> a
const Bool
True)
traceViewCC :: Concept c => c -> TraceViewCat
traceViewCC :: c -> TraceViewCat
traceViewCC dom :: c
dom u :: [UID]
u c :: ChunkDB
c = (ConceptInstance -> Bool)
-> Getting (UMap ConceptInstance) ChunkDB (UMap ConceptInstance)
-> TraceViewCat
forall a.
HasUID a =>
(a -> Bool) -> Getting (UMap a) ChunkDB (UMap a) -> TraceViewCat
traceViewFilt (UID -> UID -> Bool
isDomUnder (c
dom c -> Getting UID c UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID c UID
forall c. HasUID c => Lens' c UID
uid) (UID -> Bool)
-> (ConceptInstance -> UID) -> ConceptInstance -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [UID] -> UID
sDom ([UID] -> UID)
-> (ConceptInstance -> [UID]) -> ConceptInstance -> UID
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConceptInstance -> [UID]
forall c. ConceptDomain c => c -> [UID]
cdom) Getting (UMap ConceptInstance) ChunkDB (UMap ConceptInstance)
Lens' ChunkDB (UMap ConceptInstance)
conceptinsTable [UID]
u ChunkDB
c
where
isDomUnder :: UID -> UID -> Bool
isDomUnder :: UID -> UID -> Bool
isDomUnder filtDom :: UID
filtDom curr :: UID
curr
| UID
filtDom UID -> UID -> Bool
forall a. Eq a => a -> a -> Bool
== UID
curr = Bool
True
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [UID] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([UID] -> Bool) -> [UID] -> Bool
forall a b. (a -> b) -> a -> b
$ UID -> [UID]
getDom UID
curr = UID -> UID -> Bool
isDomUnder UID
filtDom ([UID] -> UID
sDom ([UID] -> UID) -> [UID] -> UID
forall a b. (a -> b) -> a -> b
$ UID -> [UID]
getDom UID
curr)
| Bool
otherwise = Bool
False
getDom :: UID -> [UID]
getDom :: UID -> [UID]
getDom curr :: UID
curr = ConceptChunk -> [UID]
forall c. ConceptDomain c => c -> [UID]
cdom (ConceptChunk -> [UID]) -> ConceptChunk -> [UID]
forall a b. (a -> b) -> a -> b
$ ChunkDB -> UID -> ConceptChunk
defResolve ChunkDB
c UID
curr