6133N/ACopyright : Heng Jiang, Uni Bremen 2004-2006
6133N/Aimport qualified List as List
6147N/A-- | call for owl parser (env. variable $HETS_OWL_PARSER muss be defined)
6147N/AparseOWL :: FilePath -- ^ local filepath or uri
6147N/A -> IO OntologyMap -- ^ map: uri -> Ontology
6133N/A else if checkUri $ filename
else if (head filename) == '/'
++ pwd ++ "/" ++ filename)
-- ++ pwd ++ "/" ++ filename)
where run :: ExitCode -> IO OntologyMap
| exitCode == ExitSuccess =
| otherwise = error ("process stop! " ++ (show exitCode))
parseProc :: FilePath -> IO OntologyMap
do d <- readFile filename
let aterm = getATermFull $ readATerm d
_ -> error ("false file: " ++ show filename ++ ".")
-- | parse an ontology with all imported ontologies
parsingAll :: [ATerm] -> [(String, Ontology)]
(ontologyParse aterm):(parsingAll res)
-- | ontology parser, this version ignore validation, massages of java-parser.
ontologyParse :: ATerm -> (String, Ontology)
AAppl "OWLParserOutput" [_, _, _, onto] _] _)
Ontology _ _ namespace ->
(if head uri == '"' then read uri::String else uri,
propagateNspaces namespace $ createAndReduceClassAxiom ontology)
where ontology = fromATerm onto::Ontology
ontologyParse _ = error "false ontology file."
-- | remove equivalent disjoint class axiom, create equivalentClasses,
-- | subClassOf axioms, and sort directives (definitions of classes and
-- | properties muss be moved to begin of directives)
createAndReduceClassAxiom :: Ontology -> Ontology
createAndReduceClassAxiom (Ontology oid directives ns) =
let (definition, axiom, other) =
findAndCreate (
List.nub directives) ([], [], [])
directives' = reverse definition ++ reverse axiom ++ reverse other
in Ontology oid directives' ns
where -- search directives list, sort the define concept and role,
findAndCreate :: [Directive]
-> ([Directive], [Directive], [Directive])
-> ([Directive], [Directive], [Directive])
findAndCreate [] res = res
findAndCreate (h:r) (def, axiom, rest) =
Ax (Class cid _ Complete _ desps) ->
-- the original directive must also be saved.
(h:def,(Ax (EquivalentClasses (DC cid) desps)):axiom,rest)
Ax (Class cid _ Partial _ desps) ->
findAndCreate r (h:def, axiom, rest)
(appendSubClassAxiom cid desps) ++ axiom,
Ax (EnumeratedClass _ _ _ _) ->
findAndCreate r (h:def, axiom, rest)
Ax (DisjointClasses _ _ _) ->
if any (eqClass h) r then
findAndCreate r (def, axiom, rest)
else findAndCreate r (def,h:axiom, rest)
Ax (DatatypeProperty _ _ _ _ _ _ _) ->
findAndCreate r (h:def, axiom, rest)
Ax (ObjectProperty _ _ _ _ _ _ _ _ _) ->
findAndCreate r (h:def, axiom, rest)
_ -> findAndCreate r (def, axiom, h:rest)
-- append single subClassOf axioms from an derective of ontology
appendSubClassAxiom :: ClassID -> [Description] -> [Directive]
appendSubClassAxiom _ [] = []
appendSubClassAxiom cid (hd:rd) =
(Ax (SubClassOf (DC cid) hd)):(appendSubClassAxiom cid rd)
-- check if two disjointClasses axiom are equivalent
-- (a disjointOf b == b disjointOf a)
eqClass :: Directive -> Directive -> Bool
Ax (DisjointClasses c1 c2 _) ->
Ax (DisjointClasses c3 c4 _) ->
if (c1 == c4 && c2 == c3)
-- | structure analysis bases of ontologyMap from owl parser
-> IO (Maybe (LIB_NAME, -- filename
LibEnv -- DGraphs for imported modules
structureAna file opt ontoMap =
let (newOntoMap, dg) = buildDevGraph ontoMap
Structured -> do -- only structure analysis
return (Just (simpleLibName file,
simpleLibEnv file $ reverseGraph dg))
Skip -> return $ fail "" -- Nothing is ambiguous
_ -> staticAna file opt (newOntoMap, dg)
where -- output Analyzing messages for structured anaylsis
printMsg :: [LNode DGNodeLab] -> IO()
printMsg [] = putStrLn ""
printMsg ((_, node):rest) =
do putStrLn ("Analyzing ontology " ++
(showName $ dgn_name node))
-- simpleLibEnv and simpleLibName builded two simple lib-entities for
simpleLibEnv :: FilePath -> DGraph -> LibEnv
simpleLibEnv filename dg =
(SpecEntry ((JustNode nodeSig), [], g_sign, nodeSig))
where nodeSig = NodeSig 0 g_sign
g_sign = G_sign OWL_DL emptySign 0
simpleLibName :: FilePath -> LIB_NAME
simpleLibName s = Lib_id (Direct_link ("library_" ++ s) (Range []))
-- | static analysis if the HetcatesOpts is not only Structured.
-- | sequence call for nodesStaticAna on the basis of topologically
-> IO (Maybe (LIB_NAME, -- filename
LibEnv -- DGraphs for imported modules
staticAna file opt (ontoMap, dg) =
do let topNodes = topsort dg
let dg'' = insEdges (reverseLinks $ labEdges dg')
(delEdges (edges dg') dg')
return (Just (simpleLibName file,
_ -> error "no devGraph..."
-- | a map to save which node has been analysed.
type SignMap =
Map.Map Node (Sign, [Named Sentence])
-- | call to static analyse of all nodes
nodesStaticAna :: [Node] -- ^ topologically sort of graph
-> SignMap -- ^ an map of analyzed nodes
-> OntologyMap -- ^ an map of parsed ontology
-> Namespace -- ^ global namespaces
-> DGraph -- ^ current graph
-> [Diagnosis] -- ^ diagnosis of result
-> IO (Result (SignMap, DGraph, Namespace))
-- ^ result is tuple of new map of signs and sentences,
-- ^ new grpah, and new global namespace map.
nodesStaticAna [] signMap _ ns dg diag =
return $ Result diag (Just (signMap, dg, ns))
nodesStaticAna (h:r) signMap ontoMap globalNs dg diag = do
-- Each node must be analyzed with the associated imported nodes.
-- Those search for imported nodes is by bfs accomplished.
nodeStaticAna (reverse $ map (matchNode dg) (bfs h dg))
signMap ontoMap globalNs dg
Just (newSignMap, newDg, newGlobalNs) ->
nodesStaticAna r newSignMap ontoMap newGlobalNs newDg (diag++digs)
-- Warning or Error message
nodesStaticAna r signMap ontoMap globalNs dg (diag++digs)
-- | call to static analyse of single nodes
nodeStaticAna :: [LNode DGNodeLab] -- ^ imported nodes of one node
-> (Sign, [Diagnosis]) -- ^ here saved incoming sign, diagnoses
-> SignMap -- ^ an map of analyzed nodes
-> OntologyMap -- ^ an map of parsed ontology
-> Namespace -- ^ global namespaces
-> DGraph -- ^ current graph
-> IO (Result (SignMap, DGraph, Namespace))
nodeStaticAna [] _ _ _ _ _ =
do return initResult -- remove warning
-- the last node in list is current top node.
((n,topNode):[]) (inSig, oldDiags) signMap ontoMap globalNs dg =
let nn@(nodeName, _, _) = dgn_name topNode
putStrLn ("Analyzing ontology " ++ (show nodeName))
return $ Result oldDiags (Just (signMap, dg, globalNs))
let ontology@(Ontology mid _ _) = fromJust $
-- static analysis of current ontology with all sign of
basicOWL_DLAnalysis (ontology, inSig, emptyGlobalAnnos)
Just (_, accSig, sent) ->
let (newGlobalNs, tMap) =
integrateNamespaces globalNs (namespaceMap accSig)
newSent = map (renameNamespace tMap) sent
difSig = diffSig accSig inSig
newDifSig = renameNamespace tMap difSig
newSig = renameNamespace tMap accSig
-- the new node (with sign and sentence) has the sign of
-- accumulated sign with imported signs, but the sentences
-- is only of current ontology, because all sentences of
-- imported ontoloies can be automatically outputed by
(n, topNode {dgn_theory =
G_theory OWL_DL newSig 0 (toThSens newSent)
-- by remove of an node all associated edges are also deleted
-- so the deges must be saved before remove the node, then
-- The out edges (after reverse are inn edges) must
-- also with new signature be changed.
ledges = (inn dg n) ++ (map (changeGMorOfEdges newSig) (out dg n))
newG = insEdges ledges (insNode newLNode (delNode n dg))
return $ Result (oldDiags ++ diag)
(Just ((
Map.insert n (newDifSig, newSent) signMap),
_ -> do let actDiag = mkDiag Error
("error by analysing of " ++ (show mid)) ()
-- The GMorphism of edge should also with new Signature be changed,
-- since with "show theory" the edges also with Sign one links
where changeGMorOfEdges :: Sign -> LEdge DGLinkLab -> LEdge DGLinkLab
changeGMorOfEdges newSign (n1, n2, edge) =
let newCMor = idComorphism (Logic OWL_DL)
Result _ newGMor = gEmbedComorphism newCMor
(G_sign OWL_DL newSign 0)
in (n1, n2, edge {dgl_morphism = fromJust newGMor})
-- The other nodes in list are examined whether they were already analyzed.
-- if yes then signs of it for further analysis are taken out; otherwise they
-- are first analyzed (with complete part tree of this node).
nodeStaticAna ((n, _):r) (inSig, oldDiags) signMap ontoMap globalNs dg
nodeStaticAna r ((integSign sig inSig), oldDiags)
signMap ontoMap globalNs dg
nodeStaticAna (reverse $ map (matchNode dg) (bfs n dg))
signMap ontoMap globalNs dg
Just (signMap', dg', globalNs') ->
((integSign sig' inSig), (oldDiags ++ digs'))
signMap' ontoMap globalNs' dg'
_ -> do error "Error by analysis : nodeStaticAna"
nodeStaticAna r (inSig, oldDiags)
signMap ontoMap globalNs dg
integSign :: Sign -> Sign -> Sign
integSign inSig totalSig =
let (newNamespace, transMap) =
integrateNamespaces (namespaceMap totalSig) (namespaceMap inSig)
in addSign (renameNamespace transMap inSig)
(totalSig {namespaceMap = newNamespace})
reverseLinks :: [LEdge DGLinkLab] -> [LEdge DGLinkLab]
reverseLinks ((source, target, edge):r) =
(target, source, edge):(reverseLinks r)
-- | turn all edges over of graph
reverseGraph :: DGraph -> DGraph
let newLinks = reverseLinks $ labEdges dg
in insEdges newLinks (delEdges (edges dg) dg)
-- | find a node in DevGraph
matchNode :: DGraph -> Node -> LNode DGNodeLab
let (mcontext, _ ) = match node dgraph
(_, _, dgNode, _) = fromJust mcontext