{-# LANGUAGE TemplateHaskell #-}
module Database.Drasil.ChunkDB (
ChunkDB(CDB, symbolTable, termTable, defTable),
RefbyMap, TraceMap, UMap,
cdb, idMap, termMap, conceptMap, traceMap, generateRefbyMap,
asOrderedList, collectUnits,
termResolve, defResolve, symbResolve,
traceLookup, refbyLookup,
datadefnLookup, insmodelLookup, gendefLookup, theoryModelLookup,
conceptinsLookup, refResolve,
unitTable, traceTable, refbyTable, citationTable,
dataDefnTable, insmodelTable, gendefTable, theoryModelTable,
conceptinsTable, labelledcontentTable, refTable
) where
import Language.Drasil
import Theory.Drasil (DataDefinition, GenDefn, InstanceModel, TheoryModel)
import Control.Lens ((^.), makeLenses)
import Data.List (sortOn)
import Data.Maybe (fromMaybe, mapMaybe)
import qualified Data.Map as Map
import Utils.Drasil (invert)
type UMap a = Map.Map UID (a, Int)
type SymbolMap = UMap QuantityDict
type ConceptMap = UMap ConceptChunk
type UnitMap = UMap UnitDefn
type TermMap = UMap IdeaDict
type TraceMap = Map.Map UID [UID]
type RefbyMap = Map.Map UID [UID]
type DatadefnMap = UMap DataDefinition
type InsModelMap = UMap InstanceModel
type GendefMap = UMap GenDefn
type TheoryModelMap = UMap TheoryModel
type ConceptInstanceMap = UMap ConceptInstance
type LabelledContentMap = UMap LabelledContent
type ReferenceMap = UMap Reference
type CitationMap = UMap Citation
cdbMap :: HasUID a => (a -> b) -> [a] -> Map.Map UID (b, Int)
cdbMap :: forall a b. HasUID a => (a -> b) -> [a] -> Map UID (b, Int)
cdbMap a -> b
fn = [(UID, (b, Int))] -> Map UID (b, Int)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(UID, (b, Int))] -> Map UID (b, Int))
-> ([a] -> [(UID, (b, Int))]) -> [a] -> Map UID (b, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a, Int) -> (UID, (b, Int))) -> [(a, Int)] -> [(UID, (b, Int))]
forall a b. (a -> b) -> [a] -> [b]
map (\(a
x,Int
y) -> (a
x a -> Getting UID a UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID a UID
forall c. HasUID c => Getter c UID
Getter a UID
uid, (a -> b
fn a
x, Int
y))) ([(a, Int)] -> [(UID, (b, Int))])
-> ([a] -> [(a, Int)]) -> [a] -> [(UID, (b, Int))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a] -> [Int] -> [(a, Int)]) -> [Int] -> [a] -> [(a, Int)]
forall a b c. (a -> b -> c) -> b -> a -> c
flip [a] -> [Int] -> [(a, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
1..]
symbolMap :: (Quantity c, MayHaveUnit c) => [c] -> SymbolMap
symbolMap :: forall c. (Quantity c, MayHaveUnit c) => [c] -> SymbolMap
symbolMap = (c -> QuantityDict) -> [c] -> SymbolMap
forall a b. HasUID a => (a -> b) -> [a] -> Map UID (b, Int)
cdbMap c -> QuantityDict
forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw
termMap :: (Idea c) => [c] -> TermMap
termMap :: forall c. Idea c => [c] -> TermMap
termMap = (c -> IdeaDict) -> [c] -> TermMap
forall a b. HasUID a => (a -> b) -> [a] -> Map UID (b, Int)
cdbMap c -> IdeaDict
forall c. Idea c => c -> IdeaDict
nw
conceptMap :: (Concept c) => [c] -> ConceptMap
conceptMap :: forall c. Concept c => [c] -> ConceptMap
conceptMap = (c -> ConceptChunk) -> [c] -> ConceptMap
forall a b. HasUID a => (a -> b) -> [a] -> Map UID (b, Int)
cdbMap c -> ConceptChunk
forall c. Concept c => c -> ConceptChunk
cw
unitMap :: (IsUnit u) => [u] -> UnitMap
unitMap :: forall u. IsUnit u => [u] -> UnitMap
unitMap = (u -> UnitDefn) -> [u] -> UnitMap
forall a b. HasUID a => (a -> b) -> [a] -> Map UID (b, Int)
cdbMap u -> UnitDefn
forall u. IsUnit u => u -> UnitDefn
unitWrapper
idMap :: HasUID a => [a] -> Map.Map UID (a, Int)
idMap :: forall a. HasUID a => [a] -> Map UID (a, Int)
idMap = (a -> a) -> [a] -> Map UID (a, Int)
forall a b. HasUID a => (a -> b) -> [a] -> Map UID (b, Int)
cdbMap a -> a
forall a. a -> a
id
traceMap :: [(UID, [UID])] -> TraceMap
traceMap :: [(UID, [UID])] -> TraceMap
traceMap = [(UID, [UID])] -> TraceMap
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
getUnitLup :: HasUID c => ChunkDB -> c -> Maybe UnitDefn
getUnitLup :: forall c. HasUID c => ChunkDB -> c -> Maybe UnitDefn
getUnitLup ChunkDB
m c
c = QuantityDict -> Maybe UnitDefn
forall u. MayHaveUnit u => u -> Maybe UnitDefn
getUnit (QuantityDict -> Maybe UnitDefn) -> QuantityDict -> Maybe UnitDefn
forall a b. (a -> b) -> a -> b
$ ChunkDB -> UID -> QuantityDict
symbResolve ChunkDB
m (c
c c -> Getting UID c UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID c UID
forall c. HasUID c => Getter c UID
Getter c UID
uid)
uMapLookup :: String -> String -> UID -> UMap a -> a
uMapLookup :: forall a. String -> String -> UID -> UMap a -> a
uMapLookup String
tys String
ms UID
u UMap a
t = Maybe (a, Int) -> a
forall {b} {b}. Maybe (b, b) -> b
getFM (Maybe (a, Int) -> a) -> Maybe (a, Int) -> a
forall a b. (a -> b) -> a -> b
$ UID -> UMap a -> Maybe (a, Int)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup UID
u UMap a
t
where getFM :: Maybe (b, b) -> b
getFM = b -> ((b, b) -> b) -> Maybe (b, b) -> b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> b
forall a. HasCallStack => String -> a
error (String -> b) -> String -> b
forall a b. (a -> b) -> a -> b
$ String
tys String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ UID -> String
forall a. Show a => a -> String
show UID
u String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" not found in " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
ms) (b, b) -> b
forall a b. (a, b) -> a
fst
symbResolve :: ChunkDB -> UID -> QuantityDict
symbResolve :: ChunkDB -> UID -> QuantityDict
symbResolve ChunkDB
m UID
x = String -> String -> UID -> SymbolMap -> QuantityDict
forall a. String -> String -> UID -> UMap a -> a
uMapLookup String
"Symbol" String
"SymbolMap" UID
x (SymbolMap -> QuantityDict) -> SymbolMap -> QuantityDict
forall a b. (a -> b) -> a -> b
$ ChunkDB -> SymbolMap
symbolTable ChunkDB
m
termResolve :: ChunkDB -> UID -> IdeaDict
termResolve :: ChunkDB -> UID -> IdeaDict
termResolve ChunkDB
m UID
x = String -> String -> UID -> TermMap -> IdeaDict
forall a. String -> String -> UID -> UMap a -> a
uMapLookup String
"Term" String
"TermMap" UID
x (TermMap -> IdeaDict) -> TermMap -> IdeaDict
forall a b. (a -> b) -> a -> b
$ ChunkDB -> TermMap
termTable ChunkDB
m
refResolve :: UID -> ReferenceMap -> Reference
refResolve :: UID -> ReferenceMap -> Reference
refResolve = String -> String -> UID -> ReferenceMap -> Reference
forall a. String -> String -> UID -> UMap a -> a
uMapLookup String
"Reference" String
"ReferenceMap"
unitLookup :: UID -> UnitMap -> UnitDefn
unitLookup :: UID -> UnitMap -> UnitDefn
unitLookup = String -> String -> UID -> UnitMap -> UnitDefn
forall a. String -> String -> UID -> UMap a -> a
uMapLookup String
"Unit" String
"UnitMap"
defResolve :: ChunkDB -> UID -> ConceptChunk
defResolve :: ChunkDB -> UID -> ConceptChunk
defResolve ChunkDB
m UID
x = String -> String -> UID -> ConceptMap -> ConceptChunk
forall a. String -> String -> UID -> UMap a -> a
uMapLookup String
"Concept" String
"ConceptMap" UID
x (ConceptMap -> ConceptChunk) -> ConceptMap -> ConceptChunk
forall a b. (a -> b) -> a -> b
$ ChunkDB -> ConceptMap
defTable ChunkDB
m
datadefnLookup :: UID -> DatadefnMap -> DataDefinition
datadefnLookup :: UID -> DatadefnMap -> DataDefinition
datadefnLookup = String -> String -> UID -> DatadefnMap -> DataDefinition
forall a. String -> String -> UID -> UMap a -> a
uMapLookup String
"DataDefinition" String
"DatadefnMap"
insmodelLookup :: UID -> InsModelMap -> InstanceModel
insmodelLookup :: UID -> InsModelMap -> InstanceModel
insmodelLookup = String -> String -> UID -> InsModelMap -> InstanceModel
forall a. String -> String -> UID -> UMap a -> a
uMapLookup String
"InstanceModel" String
"InsModelMap"
gendefLookup :: UID -> GendefMap -> GenDefn
gendefLookup :: UID -> GendefMap -> GenDefn
gendefLookup = String -> String -> UID -> GendefMap -> GenDefn
forall a. String -> String -> UID -> UMap a -> a
uMapLookup String
"GenDefn" String
"GenDefnMap"
theoryModelLookup :: UID -> TheoryModelMap -> TheoryModel
theoryModelLookup :: UID -> TheoryModelMap -> TheoryModel
theoryModelLookup = String -> String -> UID -> TheoryModelMap -> TheoryModel
forall a. String -> String -> UID -> UMap a -> a
uMapLookup String
"TheoryModel" String
"TheoryModelMap"
conceptinsLookup :: UID -> ConceptInstanceMap -> ConceptInstance
conceptinsLookup :: UID -> ConceptInstanceMap -> ConceptInstance
conceptinsLookup = String -> String -> UID -> ConceptInstanceMap -> ConceptInstance
forall a. String -> String -> UID -> UMap a -> a
uMapLookup String
"ConceptInstance" String
"ConceptInstanceMap"
asOrderedList :: UMap a -> [a]
asOrderedList :: forall a. UMap a -> [a]
asOrderedList = ((a, Int) -> a) -> [(a, Int)] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (a, Int) -> a
forall a b. (a, b) -> a
fst ([(a, Int)] -> [a]) -> (UMap a -> [(a, Int)]) -> UMap a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a, Int) -> Int) -> [(a, Int)] -> [(a, Int)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (a, Int) -> Int
forall a b. (a, b) -> b
snd ([(a, Int)] -> [(a, Int)])
-> (UMap a -> [(a, Int)]) -> UMap a -> [(a, Int)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((UID, (a, Int)) -> (a, Int)) -> [(UID, (a, Int))] -> [(a, Int)]
forall a b. (a -> b) -> [a] -> [b]
map (UID, (a, Int)) -> (a, Int)
forall a b. (a, b) -> b
snd ([(UID, (a, Int))] -> [(a, Int)])
-> (UMap a -> [(UID, (a, Int))]) -> UMap a -> [(a, Int)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UMap a -> [(UID, (a, Int))]
forall k a. Map k a -> [(k, a)]
Map.toList
data ChunkDB = CDB {
ChunkDB -> SymbolMap
symbolTable :: SymbolMap
, ChunkDB -> TermMap
termTable :: TermMap
, ChunkDB -> ConceptMap
defTable :: ConceptMap
, ChunkDB -> UnitMap
_unitTable :: UnitMap
, ChunkDB -> DatadefnMap
_dataDefnTable :: DatadefnMap
, ChunkDB -> InsModelMap
_insmodelTable :: InsModelMap
, ChunkDB -> GendefMap
_gendefTable :: GendefMap
, ChunkDB -> TheoryModelMap
_theoryModelTable :: TheoryModelMap
, ChunkDB -> ConceptInstanceMap
_conceptinsTable :: ConceptInstanceMap
, ChunkDB -> CitationMap
_citationTable :: CitationMap
, ChunkDB -> LabelledContentMap
_labelledcontentTable :: LabelledContentMap
, ChunkDB -> ReferenceMap
_refTable :: ReferenceMap
, ChunkDB -> TraceMap
_traceTable :: TraceMap
, ChunkDB -> TraceMap
_refbyTable :: RefbyMap
}
makeLenses ''ChunkDB
cdb :: (Quantity q, MayHaveUnit q, Concept c, IsUnit u) =>
[q] -> [IdeaDict] -> [c] -> [u] -> [DataDefinition] -> [InstanceModel] ->
[GenDefn] -> [TheoryModel] -> [ConceptInstance] ->
[LabelledContent] -> [Reference] -> [Citation] -> ChunkDB
cdb :: forall q c u.
(Quantity q, MayHaveUnit q, Concept c, IsUnit u) =>
[q]
-> [IdeaDict]
-> [c]
-> [u]
-> [DataDefinition]
-> [InstanceModel]
-> [GenDefn]
-> [TheoryModel]
-> [ConceptInstance]
-> [LabelledContent]
-> [Reference]
-> [Citation]
-> ChunkDB
cdb [q]
s [IdeaDict]
t [c]
c [u]
u [DataDefinition]
d [InstanceModel]
ins [GenDefn]
gd [TheoryModel]
tm [ConceptInstance]
ci [LabelledContent]
lc [Reference]
r [Citation]
cits =
CDB {
symbolTable :: SymbolMap
symbolTable = [q] -> SymbolMap
forall c. (Quantity c, MayHaveUnit c) => [c] -> SymbolMap
symbolMap [q]
s,
termTable :: TermMap
termTable = [IdeaDict] -> TermMap
forall c. Idea c => [c] -> TermMap
termMap ([IdeaDict] -> TermMap) -> [IdeaDict] -> TermMap
forall a b. (a -> b) -> a -> b
$ [IdeaDict]
t [IdeaDict] -> [IdeaDict] -> [IdeaDict]
forall a. [a] -> [a] -> [a]
++ [IdeaDict]
termsHACK,
defTable :: ConceptMap
defTable = [c] -> ConceptMap
forall c. Concept c => [c] -> ConceptMap
conceptMap [c]
c,
_unitTable :: UnitMap
_unitTable = [u] -> UnitMap
forall u. IsUnit u => [u] -> UnitMap
unitMap [u]
u,
_dataDefnTable :: DatadefnMap
_dataDefnTable = [DataDefinition] -> DatadefnMap
forall a. HasUID a => [a] -> Map UID (a, Int)
idMap [DataDefinition]
d,
_insmodelTable :: InsModelMap
_insmodelTable = [InstanceModel] -> InsModelMap
forall a. HasUID a => [a] -> Map UID (a, Int)
idMap [InstanceModel]
ins,
_gendefTable :: GendefMap
_gendefTable = [GenDefn] -> GendefMap
forall a. HasUID a => [a] -> Map UID (a, Int)
idMap [GenDefn]
gd,
_theoryModelTable :: TheoryModelMap
_theoryModelTable = [TheoryModel] -> TheoryModelMap
forall a. HasUID a => [a] -> Map UID (a, Int)
idMap [TheoryModel]
tm,
_conceptinsTable :: ConceptInstanceMap
_conceptinsTable = [ConceptInstance] -> ConceptInstanceMap
forall a. HasUID a => [a] -> Map UID (a, Int)
idMap [ConceptInstance]
ci,
_citationTable :: CitationMap
_citationTable = [Citation] -> CitationMap
forall a. HasUID a => [a] -> Map UID (a, Int)
idMap [Citation]
cits,
_labelledcontentTable :: LabelledContentMap
_labelledcontentTable = [LabelledContent] -> LabelledContentMap
forall a. HasUID a => [a] -> Map UID (a, Int)
idMap [LabelledContent]
lc,
_traceTable :: TraceMap
_traceTable = TraceMap
forall k a. Map k a
Map.empty,
_refbyTable :: TraceMap
_refbyTable = TraceMap
forall k a. Map k a
Map.empty,
_refTable :: ReferenceMap
_refTable = [Reference] -> ReferenceMap
forall a. HasUID a => [a] -> Map UID (a, Int)
idMap [Reference]
r
}
where
termsHACK :: [IdeaDict]
termsHACK = (DataDefinition -> IdeaDict) -> [DataDefinition] -> [IdeaDict]
forall a b. (a -> b) -> [a] -> [b]
map DataDefinition -> IdeaDict
forall c. Idea c => c -> IdeaDict
nw [DataDefinition]
d
collectUnits :: Quantity c => ChunkDB -> [c] -> [UnitDefn]
collectUnits :: forall c. Quantity c => ChunkDB -> [c] -> [UnitDefn]
collectUnits ChunkDB
m = (UID -> UnitDefn) -> [UID] -> [UnitDefn]
forall a b. (a -> b) -> [a] -> [b]
map (UnitDefn -> UnitDefn
forall u. IsUnit u => u -> UnitDefn
unitWrapper (UnitDefn -> UnitDefn) -> (UID -> UnitDefn) -> UID -> UnitDefn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UID -> UnitMap -> UnitDefn) -> UnitMap -> UID -> UnitDefn
forall a b c. (a -> b -> c) -> b -> a -> c
flip UID -> UnitMap -> UnitDefn
unitLookup (ChunkDB
m ChunkDB -> Getting UnitMap ChunkDB UnitMap -> UnitMap
forall s a. s -> Getting a s a -> a
^. Getting UnitMap ChunkDB UnitMap
Lens' ChunkDB UnitMap
unitTable))
([UID] -> [UnitDefn]) -> ([c] -> [UID]) -> [c] -> [UnitDefn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UnitDefn -> [UID]) -> [UnitDefn] -> [UID]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap UnitDefn -> [UID]
forall u. IsUnit u => u -> [UID]
getUnits ([UnitDefn] -> [UID]) -> ([c] -> [UnitDefn]) -> [c] -> [UID]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (c -> Maybe UnitDefn) -> [c] -> [UnitDefn]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (ChunkDB -> c -> Maybe UnitDefn
forall c. HasUID c => ChunkDB -> c -> Maybe UnitDefn
getUnitLup ChunkDB
m)
traceLookup :: UID -> TraceMap -> [UID]
traceLookup :: UID -> TraceMap -> [UID]
traceLookup UID
c = [UID] -> Maybe [UID] -> [UID]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [UID] -> [UID])
-> (TraceMap -> Maybe [UID]) -> TraceMap -> [UID]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UID -> TraceMap -> Maybe [UID]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup UID
c
generateRefbyMap :: TraceMap -> RefbyMap
generateRefbyMap :: TraceMap -> TraceMap
generateRefbyMap = TraceMap -> TraceMap
forall v k. Ord v => Map k [v] -> Map v [k]
invert
refbyLookup :: UID -> RefbyMap -> [UID]
refbyLookup :: UID -> TraceMap -> [UID]
refbyLookup UID
c = [UID] -> Maybe [UID] -> [UID]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [UID] -> [UID])
-> (TraceMap -> Maybe [UID]) -> TraceMap -> [UID]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UID -> TraceMap -> Maybe [UID]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup UID
c