{-# LANGUAGE GADTs, TemplateHaskell, RankNTypes #-}
module SysInfo.Drasil.SystemInformation (
SystemInformation(..), Block(..),
instModels, datadefs, configFiles, inputs,
defSequence, constraints, constants, sysinfodb, usedinfodb,
citeDB, citationsFromBibMap,
ReferenceDB, RefMap,
rdb, simpleMap,
citationDB, conceptDB,
) where
import Language.Drasil
import Theory.Drasil
import Database.Drasil (ChunkDB)
import Control.Lens ((^.), makeLenses)
import Data.Function (on)
import Data.List (find, groupBy, sortBy)
import qualified Data.Map as Map
data SystemInformation where
SI :: (CommonIdea a, Idea a, Idea b, HasName c,
Quantity e, Eq e, MayHaveUnit e, Quantity f, MayHaveUnit f, Concept f, Eq f,
Quantity h, MayHaveUnit h, Quantity i, MayHaveUnit i,
HasUID j, Constrained j) =>
{ ()
_sys :: a
, ()
_kind :: b
, ()
_authors :: [c]
, ()
_purpose :: d
, ()
_quants :: [e]
, ()
_concepts :: [f]
, SystemInformation -> [InstanceModel]
_instModels :: [InstanceModel]
, SystemInformation -> [DataDefinition]
_datadefs :: [DataDefinition]
, SystemInformation -> [String]
_configFiles :: [String]
, ()
_inputs :: [h]
, ()
_outputs :: [i]
, SystemInformation -> [Block SimpleQDef]
_defSequence :: [Block SimpleQDef]
, ()
_constraints :: [j]
, SystemInformation -> [ConstQDef]
_constants :: [ConstQDef]
, SystemInformation -> ChunkDB
_sysinfodb :: ChunkDB
, SystemInformation -> ChunkDB
_usedinfodb :: ChunkDB
, SystemInformation -> ReferenceDB
refdb :: ReferenceDB
} -> SystemInformation
data Block a = Coupled a a [a] | Parallel a [a]
citeDB :: SystemInformation -> BibRef
citeDB :: SystemInformation -> BibRef
citeDB si :: SystemInformation
si = BibMap -> BibRef
citationsFromBibMap (ReferenceDB -> BibMap
_citationDB (SystemInformation -> ReferenceDB
refdb SystemInformation
si))
citationsFromBibMap :: BibMap -> [Citation]
citationsFromBibMap :: BibMap -> BibRef
citationsFromBibMap bm :: BibMap
bm = (Citation -> Citation -> Ordering) -> BibRef -> BibRef
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy Citation -> Citation -> Ordering
forall c. HasFields c => c -> c -> Ordering
compareAuthYearTitle BibRef
citations
where citations :: [Citation]
citations :: BibRef
citations = ((Citation, Int) -> Citation) -> [(Citation, Int)] -> BibRef
forall a b. (a -> b) -> [a] -> [b]
map (Citation, Int) -> Citation
forall a b. (a, b) -> a
fst (BibMap -> [(Citation, Int)]
forall k a. Map k a -> [a]
Map.elems BibMap
bm)
compareAuthYearTitle :: (HasFields c) => c -> c -> Ordering
compareAuthYearTitle :: c -> c -> Ordering
compareAuthYearTitle c1 :: c
c1 c2 :: c
c2
| Ordering
cp Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
/= Ordering
EQ = Ordering
cp
| Int
y1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
y2 = Int
y1 Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Int
y2
| String
t1 String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
t2 = String
t1 String -> String -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` String
t2
| Bool
otherwise = String -> Ordering
forall a. HasCallStack => String -> a
error "Couldn't sort authors"
where
cp :: Ordering
cp = [Person] -> [Person] -> Ordering
comparePeople (c -> [Person]
forall c. HasFields c => c -> [Person]
getAuthor c
c1) (c -> [Person]
forall c. HasFields c => c -> [Person]
getAuthor c
c2)
y1 :: Int
y1 = c -> Int
forall c. HasFields c => c -> Int
getYear c
c1
y2 :: Int
y2 = c -> Int
forall c. HasFields c => c -> Int
getYear c
c2
t1 :: String
t1 = c -> String
forall c. HasFields c => c -> String
getTitle c
c1
t2 :: String
t2 = c -> String
forall c. HasFields c => c -> String
getTitle c
c2
getAuthor :: (HasFields c) => c -> People
getAuthor :: c -> [Person]
getAuthor c :: c
c = [Person] -> (CiteField -> [Person]) -> Maybe CiteField -> [Person]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> [Person]
forall a. HasCallStack => String -> a
error "No author found") (\(Author x :: [Person]
x) -> [Person]
x) ((CiteField -> Bool) -> [CiteField] -> Maybe CiteField
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find CiteField -> Bool
isAuthor (c
c c -> Getting [CiteField] c [CiteField] -> [CiteField]
forall s a. s -> Getting a s a -> a
^. Getting [CiteField] c [CiteField]
forall c. HasFields c => Lens' c [CiteField]
getFields))
where isAuthor :: CiteField -> Bool
isAuthor :: CiteField -> Bool
isAuthor (Author _) = Bool
True
isAuthor _ = Bool
False
getYear :: (HasFields c) => c -> Int
getYear :: c -> Int
getYear c :: c
c = Int -> (CiteField -> Int) -> Maybe CiteField -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> Int
forall a. HasCallStack => String -> a
error "No year found") (\(Year x :: Int
x) -> Int
x) ((CiteField -> Bool) -> [CiteField] -> Maybe CiteField
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find CiteField -> Bool
isYear (c
c c -> Getting [CiteField] c [CiteField] -> [CiteField]
forall s a. s -> Getting a s a -> a
^. Getting [CiteField] c [CiteField]
forall c. HasFields c => Lens' c [CiteField]
getFields))
where isYear :: CiteField -> Bool
isYear :: CiteField -> Bool
isYear (Year _) = Bool
True
isYear _ = Bool
False
getTitle :: (HasFields c) => c -> String
getTitle :: c -> String
getTitle c :: c
c = String -> (CiteField -> String) -> Maybe CiteField -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> String
forall a. HasCallStack => String -> a
error "No title found") (\(Title x :: String
x) -> String
x) ((CiteField -> Bool) -> [CiteField] -> Maybe CiteField
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find CiteField -> Bool
isTitle (c
c c -> Getting [CiteField] c [CiteField] -> [CiteField]
forall s a. s -> Getting a s a -> a
^. Getting [CiteField] c [CiteField]
forall c. HasFields c => Lens' c [CiteField]
getFields))
where isTitle :: CiteField -> Bool
isTitle :: CiteField -> Bool
isTitle (Title _) = Bool
True
isTitle _ = Bool
False
type RefMap a = Map.Map UID (a, Int)
type BibMap = RefMap Citation
type ConceptMap = RefMap ConceptInstance
data ReferenceDB = RDB
{ ReferenceDB -> BibMap
_citationDB :: BibMap
, ReferenceDB -> ConceptMap
_conceptDB :: ConceptMap
}
makeLenses ''ReferenceDB
rdb :: BibRef -> [ConceptInstance] -> ReferenceDB
rdb :: BibRef -> [ConceptInstance] -> ReferenceDB
rdb citations :: BibRef
citations con :: [ConceptInstance]
con = BibMap -> ConceptMap -> ReferenceDB
RDB (BibRef -> BibMap
bibMap BibRef
citations) ([ConceptInstance] -> ConceptMap
conceptMap [ConceptInstance]
con)
simpleMap :: HasUID a => [a] -> RefMap a
simpleMap :: [a] -> RefMap a
simpleMap xs :: [a]
xs = [(UID, (a, Int))] -> RefMap a
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(UID, (a, Int))] -> RefMap a) -> [(UID, (a, Int))] -> RefMap a
forall a b. (a -> b) -> a -> b
$ [UID] -> [(a, Int)] -> [(UID, (a, Int))]
forall a b. [a] -> [b] -> [(a, b)]
zip ((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]
xs) ([a] -> [Int] -> [(a, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [a]
xs [1..])
bibMap :: [Citation] -> BibMap
bibMap :: BibRef -> BibMap
bibMap cs :: BibRef
cs = [(UID, (Citation, Int))] -> BibMap
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(UID, (Citation, Int))] -> BibMap)
-> [(UID, (Citation, Int))] -> BibMap
forall a b. (a -> b) -> a -> b
$ [UID] -> [(Citation, Int)] -> [(UID, (Citation, Int))]
forall a b. [a] -> [b] -> [(a, b)]
zip ((Citation -> UID) -> BibRef -> [UID]
forall a b. (a -> b) -> [a] -> [b]
map (Citation -> Getting UID Citation UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID Citation UID
forall c. HasUID c => Lens' c UID
uid) BibRef
scs) (BibRef -> [Int] -> [(Citation, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip BibRef
scs [1..])
where scs :: [Citation]
scs :: BibRef
scs = (Citation -> Citation -> Ordering) -> BibRef -> BibRef
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy Citation -> Citation -> Ordering
forall c. HasFields c => c -> c -> Ordering
compareAuthYearTitle BibRef
cs
conGrp :: ConceptInstance -> ConceptInstance -> Bool
conGrp :: ConceptInstance -> ConceptInstance -> Bool
conGrp a :: ConceptInstance
a b :: ConceptInstance
b = ConceptInstance -> UID
cdl ConceptInstance
a UID -> UID -> Bool
forall a. Eq a => a -> a -> Bool
== ConceptInstance -> UID
cdl ConceptInstance
b where
cdl :: ConceptInstance -> UID
cdl :: ConceptInstance -> UID
cdl = [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
conceptMap :: [ConceptInstance] -> ConceptMap
conceptMap :: [ConceptInstance] -> ConceptMap
conceptMap cs :: [ConceptInstance]
cs = [(UID, (ConceptInstance, Int))] -> ConceptMap
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(UID, (ConceptInstance, Int))] -> ConceptMap)
-> [(UID, (ConceptInstance, Int))] -> ConceptMap
forall a b. (a -> b) -> a -> b
$ [UID]
-> [(ConceptInstance, Int)] -> [(UID, (ConceptInstance, Int))]
forall a b. [a] -> [b] -> [(a, b)]
zip ((ConceptInstance -> UID) -> [ConceptInstance] -> [UID]
forall a b. (a -> b) -> [a] -> [b]
map (ConceptInstance -> Getting UID ConceptInstance UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID ConceptInstance UID
forall c. HasUID c => Lens' c UID
uid) ([[ConceptInstance]] -> [ConceptInstance]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[ConceptInstance]]
grp)) ([(ConceptInstance, Int)] -> [(UID, (ConceptInstance, Int))])
-> [(ConceptInstance, Int)] -> [(UID, (ConceptInstance, Int))]
forall a b. (a -> b) -> a -> b
$ ([ConceptInstance] -> [(ConceptInstance, Int)])
-> [[ConceptInstance]] -> [(ConceptInstance, Int)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap
(\x :: [ConceptInstance]
x -> [ConceptInstance] -> [Int] -> [(ConceptInstance, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [ConceptInstance]
x [1..]) [[ConceptInstance]]
grp
where grp :: [[ConceptInstance]]
grp :: [[ConceptInstance]]
grp = (ConceptInstance -> ConceptInstance -> Bool)
-> [ConceptInstance] -> [[ConceptInstance]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy ConceptInstance -> ConceptInstance -> Bool
conGrp ([ConceptInstance] -> [[ConceptInstance]])
-> [ConceptInstance] -> [[ConceptInstance]]
forall a b. (a -> b) -> a -> b
$ (ConceptInstance -> ConceptInstance -> Ordering)
-> [ConceptInstance] -> [ConceptInstance]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ConceptInstance -> ConceptInstance -> Ordering
forall c. HasUID c => c -> c -> Ordering
uidSort [ConceptInstance]
cs
uidSort :: HasUID c => c -> c -> Ordering
uidSort :: c -> c -> Ordering
uidSort = UID -> UID -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (UID -> UID -> Ordering) -> (c -> UID) -> c -> c -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (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)
makeLenses ''SystemInformation