import
GUI.Taxonomy (displayConceptGraph,displaySubsortGraph)
createInfoDisplayWithTwoButtons)
import TextDisplay(createTextDisplay)
import InfoBus(encapsulateWaitTermAct)
import DialogWin (useHTk)
import Messages(errorMess)
import Configuration(size)
import FileDialog(newFileDialogStr)
-- | Locks the global lock and runs function
runAndLock :: GInfo -> IO () -> IO ()
runAndLock (GInfo { functionLock = lock
, gi_GraphInfo = actGraphInfo
locked <- tryPutMVar lock ()
$ "an other function is still working ... please wait ..."
negateChange :: DGChange -> DGChange
negateChange change = case change of
InsertNode x -> DeleteNode x
DeleteNode x -> InsertNode x
InsertEdge x -> DeleteEdge x
DeleteEdge x -> InsertEdge x
SetNodeLab old (node, new) -> SetNodeLab new (node, old)
-- | Undo one step of the History
undo :: GInfo -> Bool -> IO ()
undo gInfo@(GInfo { globalHist = gHist
, gi_GraphInfo = actGraph
(guHist, grHist) <- takeMVar gHist
case if isUndo then guHist else grHist of
putMVar gHist (guHist, grHist)
undoDGraphs gInfo isUndo lns
putMVar gHist $ if isUndo then (gHist', reverse lns : grHist)
else (reverse lns : guHist, gHist')
undoDGraphs :: GInfo -> Bool -> [LIB_NAME] -> IO ()
undoDGraphs _ _ [] = return ()
undoDGraphs g u (ln:r) = do
undoDGraph :: GInfo -> Bool -> LIB_NAME -> IO ()
undoDGraph gInfo@(GInfo { libEnvIORef = ioRefProofStatus
, gi_GraphInfo = actGraph
le <- readIORef ioRefProofStatus
hist = (proofHistory dg, redoHistory dg)
(phist, rhist) = (if isUndo then id else swap) hist
(cl@(rs, cs), newHist) = case phist of
hd : tl -> (hd, (tl, hd : rhist))
(newPHist, newRHist) = (if isUndo then id else swap) newHist
change = if isUndo then (reverse rs, reverse $ map negateChange cs)
dg' = (changesDG dg $ snd change)
{ proofHistory = newPHist
, redoHistory = newRHist }
writeIORef ioRefProofStatus $
Map.insert ln dg' le
-- | reloads the Library of the DevGraph
reload gInfo@(GInfo { libEnvIORef = ioRefProofStatus
oldle <- readIORef ioRefProofStatus
ioruplibs <- newIORef ([] :: [LIB_NAME])
reloadLibs ioRefProofStatus opts libdeps ioruplibs ln
-- | Creates a list of all LIB_NAME pairs, which have a dependency
getLibDeps :: LibEnv -> [(LIB_NAME, LIB_NAME)]
concat $ map (\ ln -> getDep ln le) $
Map.keys le
-- | Creates a list of LIB_NAME pairs for the fist argument
getDep :: LIB_NAME -> LibEnv -> [(LIB_NAME, LIB_NAME)]
getDep ln le = map (\ (_, x) -> (ln, dgn_libname x)) $
filter (isDGRef . snd) $ labNodesDG $ lookupDGraph ln le
reloadLib :: IORef LibEnv -> HetcatsOpts -> IORef [LIB_NAME] -> LIB_NAME
reloadLib iorle opts ioruplibs ln = do
mfile <- existsAnSource opts {intype = GuessIn}
$ rmSuffix $ libNameToFile opts ln
mres <- anaLibExt opts file le'
uplibs <- readIORef ioruplibs
writeIORef ioruplibs $ ln:uplibs
errorMess $ "Could not read original development graph from '"++ file
-- | Reloads libraries if nessesary
reloadLibs :: IORef LibEnv -> HetcatsOpts -> [(LIB_NAME, LIB_NAME)]
-> IORef [LIB_NAME] -> LIB_NAME -> IO Bool
reloadLibs iorle opts deps ioruplibs ln = do
uplibs <- readIORef ioruplibs
deps' = map (snd) $ filter (\ (ln',_) -> ln == ln') deps
res <- mapM (reloadLibs iorle opts deps ioruplibs) deps'
libupdate = foldl (\ u r -> if r then True else u) False res
reloadLib iorle opts ioruplibs ln
mfile <- existsAnSource opts $ rmSuffix $ libNameToFile opts ln
newmt <- getModificationTime file
libupdate' = (getModTime $ getLIB_ID newln) < newmt
reloadLib iorle opts ioruplibs ln
-- | Deletes the old edges and nodes of the Graph and makes new ones
remakeGraph :: GInfo -> IO ()
remakeGraph (GInfo { libEnvIORef = ioRefProofStatus
, gi_GraphInfo = actGraphInfo
le <- readIORef ioRefProofStatus
dgraph = lookupDGraph ln le
convert actGraphInfo dgraph
-- | Toggles to display internal node names
hideShowNames :: GInfo -> Bool -> IO ()
hideShowNames (GInfo { internalNamesIORef = showInternalNames
(intrn::InternalNames) <- readIORef showInternalNames
let showThem = if toggle then not $ showNames intrn else showNames intrn
showItrn s = if showThem then s else ""
mapM_ (\(s,upd) -> upd (\_ -> showItrn s)) $ updater intrn
writeIORef showInternalNames $ intrn {showNames = showThem}
-- | shows all hidden nodes and edges
showNodes :: GInfo -> IO ()
showNodes gInfo@(GInfo { gi_GraphInfo = actGraphInfo
hideShowNames gInfo False
-- | hides all unnamed internal nodes that are proven
hideNodes :: GInfo -> IO ()
hideNodes (GInfo { libEnvIORef = ioRefProofStatus
, gi_GraphInfo = actGraphInfo
le <- readIORef ioRefProofStatus
let dg = lookupDGraph ln le
nodes = selectNodesByType dg [LocallyEmptyProvenConsInternal]
edges = getCompressedEdges dg nodes
-- | selects all nodes of a type with outgoing edges
selectNodesByType :: DGraph -> [DGNodeType] -> [Node]
selectNodesByType dg types =
filter (\ n -> outDG dg n /= []) $ map fst
$ filter (\ (_, n) -> elem (getRealDGNodeType n) types) $ labNodesDG dg
-- | compresses a list of types to the highest one
compressTypes :: [DGEdgeType] -> DGEdgeType
compressTypes [] = error "compressTypes: wrong usage"
compressTypes (t1:t2:r) = case t1 > t2 of
True -> compressTypes (t1:r)
False -> compressTypes (t2:r)
-- | returns a list of compressed edges
getCompressedEdges :: DGraph -> [Node] -> [(Node,Node,DGEdgeType)]
getCompressedEdges dg hidden =
filterDuplicates $ getShortPaths $ concat
$ map (\ e@(_,t,_) -> map (e:) $ getPaths dg t hidden [])
inEdges = filter (\ (_,t,_) -> elem t hidden)
$ concat $ map (outDG dg)
$ foldr (\ n i -> if elem n hidden
|| elem n i then i else n:i) []
$ map (\ (s,_,_) -> s) $ concat $ map (innDG dg) hidden
-- | filter duplicate paths
filterDuplicates :: [(Node,Node,DGEdgeType)]
-> [(Node,Node,DGEdgeType)]
filterDuplicates ((s,t,et):r) = edge:filterDuplicates others
(same,others) = partition (\ (s',t',_) -> s == s' && t == t') r
edge = (s,t,compressTypes $ et:map (\ (_,_,et') -> et') same)
-- | returns the pahts of a given node through hidden nodes
getPaths :: DGraph -> Node -> [Node] -> [Node] -> [[LEdge DGLinkLab]]
getPaths dg node hidden seen' = case elem node hidden of
True -> case edges /= [] of
True -> concat $ map (\ e@(_,t,_) -> map (e:) $ getPaths dg t hidden seen)
edges = filter (\ (_,t,_) -> notElem t seen) $ outDG dg node
-- | returns source and target node of a path with the compressed type
getShortPaths :: [[LEdge DGLinkLab]]
-> [(Node,Node,DGEdgeType)]
((s,t,compressTypes $ map (\ (_,_,e) -> getRealDGLinkType e) p))
-- | Let the user select a Node to focus
focusNode :: GInfo -> IO ()
focusNode (GInfo { libEnvIORef = ioRefProofStatus
le <- readIORef ioRefProofStatus
$ labNodesDG $ lookupDGraph ln le
let (ids,nodes) = unzip idsnodes
let nodes' = map (getDGNodeName) nodes
selection <- listBox "Select a node to focus" nodes'
translateGraph :: GInfo -> ConvFunc -> LibFunc -> IO ()
translateGraph (GInfo {libEnvIORef = ioRefProofStatus,
}) convGraph showLib = do
le <- readIORef ioRefProofStatus
openTranslateGraph le ln opts (getDGLogic le) convGraph showLib
showLibGraph :: GInfo -> LibFunc -> IO ()
showLibGraph gInfo showLib = do
{- | it tries to perform the given action to the given graph.
If part of the given graph is not hidden, then the action can
be performed directly; otherwise the graph will be shown completely
firstly, and then the action will be performed, and after that the graph
performProofAction :: GInfo -> IO () -> IO ()
performProofAction gInfo@(GInfo { gi_GraphInfo = actGraphInfo
let actionWithMessage = do
"Applying development graph calculus proof rule..."
False -> actionWithMessage
"Development graph calculus proof rule finished."
saveProofStatus :: GInfo -> FilePath -> IO ()
saveProofStatus (GInfo { libEnvIORef = ioRefProofStatus
}) file = encapsulateWaitTermAct $ do
proofStatus <- readIORef ioRefProofStatus
writeShATermFile file (ln, lookupHistory ln proofStatus)
putIfVerbose opts 2 $ "Wrote " ++ file
-- | implementation of open menu, read in a proof status
openProofStatus :: GInfo -> FilePath -> ConvFunc -> LibFunc
openProofStatus gInfo@(GInfo { libEnvIORef = ioRefProofStatus
}) file convGraph showLib = do
mh <- readVerbose opts ln file
Nothing -> errorMess $ "Could not read proof status from file '"
let libfile = libNameToFile opts ln
m <- anaLib opts { outtypes = [] } libfile
Nothing -> errorMess $ "Could not read original development graph"
++ " from '" ++ libfile ++ "'"
Nothing -> errorMess $ "Could not get original development"
++ " graph for '" ++ showDoc ln "'"
oldEnv <- readIORef ioRefProofStatus
(applyProofHistory h dg) oldEnv
writeIORef ioRefProofStatus proofStatus
gInfo' <- copyGInfo gInfo ln
convGraph gInfo' "Proof Status " showLib
let actGraphInfo = gi_GraphInfo gInfo
-- | apply a rule of the development graph calculus
proofMenu gInfo@(GInfo { libEnvIORef = ioRefProofStatus
, gi_GraphInfo = actGraphInfo
filled <- tryPutMVar guiMVar Nothing
then readMVar guiMVar >>=
(maybe (putIfVerbose hOpts 0 "proofMenu: ignored Nothing")
"proofMenu: Ignored Proof command; " ++
"maybe a proof window is still open?"
proofStatus <- readIORef ioRefProofStatus
putIfVerbose hOpts 4 "Proof started via \"Proofs\" menu"
putIfVerbose hOpts 4 "Analyzing result of proof"
mapM_ (putStrLn . show) ds
Just newProofStatus -> do
let newGr = lookupDGraph ln newProofStatus
history = proofHistory newGr
(guHist, grHist) <- takeMVar gHist
doDump hOpts "PrintHistory" $ do
print $ prettyHistory history
(calcGlobalHistory proofStatus newProofStatus : guHist, grHist)
applyChanges actGraphInfo history
applyTypeChanges actGraphInfo newGr
writeIORef ioRefProofStatus newProofStatus
hideShowNames gInfo False
mGUIMVar <- tryTakeMVar guiMVar
maybe (fail $ "should be filled with Nothing after proof attempt")
calcGlobalHistory :: LibEnv -> LibEnv -> [LIB_NAME]
calcGlobalHistory old new = let
pHist = (\ ln le -> proofHistory $ lookupDGraph ln le)
length' = (\ ln le -> length $ pHist ln le)
changes = filter (\ ln -> pHist ln old /= pHist ln new) $
Map.keys old
in concatMap (\ ln -> replicate (length' ln new - length' ln old) ln) changes
nodeErr descr = error $ "node with descriptor " ++ show descr
++ " has no corresponding node in the development graph"
showSpec :: Int -> DGraph -> IO ()
showSpec descr dgraph = do
let sp = dgToSpec dgraph descr
Res.Result ds Nothing -> show $ vcat $ map pretty ds
createTextDisplay "Show spec" sp' [size(80,25)]
showNodeInfo :: Int -> DGraph -> IO ()
showNodeInfo descr dgraph = do
let dgnode = labDG dgraph descr
title = (if isDGRef dgnode then ("reference " ++) else
if isInternalNode dgnode then ("internal " ++) else id)
"node " ++ getDGNodeName dgnode ++ " " ++ show descr
createTextDisplay title (title ++ "\n" ++ showDoc dgnode "")
fetches the theory from a node inside the IO Monad
(added by KL based on code in getTheoryOfNode) -}
lookupTheoryOfNode :: IORef LibEnv -> LIB_NAME -> Int
lookupTheoryOfNode proofStatusRef ln descr = do
libEnv <- readIORef proofStatusRef
case (do gth <- computeTheory libEnv ln descr
{- | outputs the theory of a node in a window;
used by the node menu defined in initializeGraph-}
getTheoryOfNode :: GInfo -> Int -> DGraph -> IO ()
getTheoryOfNode gInfo@(GInfo { gi_LIB_NAME = ln
, libEnvIORef = le }) descr dgraph = do
r <- lookupTheoryOfNode le ln descr
showDiags (gi_hetcatsOpts gInfo) ds
"Theory" (getNameOfNode n dgraph)
(addHasInHidingWarning dgraph n)
{- | translate the theory of a node in a window;
used by the node menu defined in initializeGraph-}
translateTheoryOfNode :: GInfo -> Int -> DGraph -> IO ()
translateTheoryOfNode gInfo@(GInfo {gi_hetcatsOpts = opts})
libEnv <- readIORef $ libEnvIORef gInfo
th <- computeTheory libEnv (gi_LIB_NAME gInfo) descr
do G_theory lid sign _ sens _ <- return th
-- find all comorphism paths starting from lid
let paths = findComorphismPaths logicGraph (sublogicOfTh th)
-- let the user choose one
sel <- lift $ listBox "Choose a logic translation"
_ -> liftR $ fail "no logic translation chosen"
Comorphism cid <- return (paths!!i)
let lidS = sourceLogic cid
sign' <- coerceSign lid lidS "" sign
sens' <- coerceThSens lid lidS "" sens
-- translate theory along chosen comorphism
liftR $ wrapMapTheory cid (plainSign sign', toNamedList sens')
"Translated Theory" (getNameOfNode node dgraph)
(addHasInHidingWarning dgraph node)
(G_theory lidT (mkExtSign sign'') startSigId
(toThSens sens1) startThId)
-- | Show proof status of a node
showProofStatusOfNode :: GInfo -> Int -> DGraph -> IO ()
showProofStatusOfNode _ descr dgraph = do
let dgnode = labDG dgraph descr
stat = showStatusAux dgnode
title = "Proof status of node "++showName (dgn_name dgnode)
createTextDisplay title stat [
HTk.size(105,55)]
showStatusAux :: DGNodeLab -> String
case dgn_theory dgnode of
consGoal = "\nconservativity of this node"
in "Proven proof goals:\n"
++ if not $ hasOpenConsStatus True dgnode
++ "\nOpen proof goals:\n"
++ if hasOpenConsStatus False dgnode
-- | start local theorem proving or consistency checking at a node
proveAtNode :: Bool -> GInfo -> Int -> DGraph -> IO ()
proveAtNode checkCons gInfo@(GInfo { libEnvIORef = ioRefProofStatus
, gi_LIB_NAME = ln }) descr dgraph = do
let dgn = labDG dgraph descr
(dgraph',dgn') <- case hasLock dgn of
True -> return (dgraph, dgn)
le <- readIORef ioRefProofStatus
(dgraph',dgn') <- initLocking (lookupDGraph ln le) (descr, dgn)
writeIORef ioRefProofStatus $
Map.insert ln dgraph' le
locked <- tryLockLocal dgn'
createTextDisplay "Error" "Proofwindow already open" [
HTk.size(30,10)]
let action = (do le <- readIORef ioRefProofStatus
guiMVar <- newMVar Nothing
res <- basicInferenceNode checkCons logicGraph libNode ln
runProveAtNode gInfo (descr, dgn') res)
case checkCons || not (hasIncomingHidingEdge dgraph' $ snd libNode) of
"This node has incoming hiding links!!!" "Prove anyway"
runProveAtNode :: GInfo -> LNode DGNodeLab ->
Res.Result LibEnv -> IO ()
runProveAtNode gInfo@(GInfo {gi_LIB_NAME = ln}) (v,_)
proofMenu gInfo $ mergeDGNodeLab gInfo (v, labDG (lookupDGraph ln le) v)
mergeDGNodeLab :: GInfo -> LNode DGNodeLab -> LibEnv -> IO (
Res.Result LibEnv)
mergeDGNodeLab (GInfo{gi_LIB_NAME = ln}) (v, new_dgn) le = do
let dg = lookupDGraph ln le
theory <- joinG_sentences (dgn_theory old_dgn) $ dgn_theory new_dgn
let new_dgn' = old_dgn { dgn_theory = theory }
(dg', _) = labelNodeDG (v, new_dgn') dg
dg'' = addToProofHistoryDG ([], [SetNodeLab old_dgn (v, new_dgn')]) dg'
-- | print the id, origin, type, proof-status and morphism of the edge
showEdgeInfo :: Int -> Maybe (LEdge DGLinkLab) -> IO ()
showEdgeInfo descr me = case me of
Just e@(_, _, l) -> let estr = showLEdge e in
createTextDisplay ("Info of " ++ estr)
(estr ++ "\n" ++ showDoc l "") [
HTk.size(70,30)]
Nothing -> createTextDisplay "Error"
("edge " ++ show descr ++ " has no corresponding edge"
++ "in the development graph") [
HTk.size(50,10)]
-- | check conservativity of the edge
checkconservativityOfEdge :: Int -> GInfo -> Maybe (LEdge DGLinkLab) -> IO ()
checkconservativityOfEdge _ gInfo
(Just (source,target,linklab)) = do
libEnv <- readIORef $ libEnvIORef gInfo
let dgraph = lookupDGraph (gi_LIB_NAME gInfo) libEnv
dgtar = labDG dgraph target
if isDGRef dgtar then error "checkconservativityOfEdge: no DGNode" else do
G_theory lid _ _ sens _ <- return $ dgn_theory dgtar
GMorphism cid _ _ morphism2 _ <- return $ dgl_morphism linklab
morphism2' <- coerceMorphism (targetLogic cid) lid
"checkconservativityOfEdge" morphism2
let th = case computeTheory libEnv (gi_LIB_NAME gInfo) source of
_ -> error "checkconservativityOfEdge: computeTheory"
G_theory lid1 sign1 _ sens1 _ <- return th
sens2 <- coerceThSens lid1 lid "" sens1
(plainSign sign2, toNamedList sens2)
morphism2' $ toNamedList sens
Just(Just True) -> "The link is conservative"
Just(Just False) -> "The link is not conservative"
_ -> "Could not determine whether link is conservative"
myDiags = unlines (map show ds)
createTextDisplay "Result of conservativity check"
(showRes ++ "\n" ++ myDiags) [
HTk.size(50,50)]
checkconservativityOfEdge descr _ Nothing =
createTextDisplay "Error"
("edge " ++ show descr ++ " has no corresponding edge "
++ "in the development graph") [
HTk.size(30,10)]
convert ginfo dgraph = do
convertNodes ginfo dgraph
convertEdges ginfo dgraph
{- | converts the nodes of the development graph, if it has any,
and returns the resulting conversion maps
if the graph is empty the conversion maps are returned unchanged-}
convertNodes ginfo = mapM_ (convertNodesAux ginfo) .labNodesDG
{- | auxiliary function for convertNodes if the given list of nodes is
emtpy, it returns the conversion maps unchanged otherwise it adds the
converted first node to the abstract graph and to the affected
conversion maps and afterwards calls itself with the remaining node
convertNodesAux ginfo (node, dgnode) =
GA.addNode ginfo node (getRealDGNodeType dgnode) $ getDGNodeName dgnode
{- | converts the edges of the development graph
works the same way as convertNods does-}
convertEdges ginfo = mapM_ (convertEdgesAux ginfo) . labEdgesDG
-- | auxiliary function for convertEges
convertEdgesAux ginfo e@(src, tar, lbl) =
GA.addEdge ginfo (dgl_id lbl) (getRealDGLinkType lbl) src tar "" $ Just e
-- | show library referened by a DGRef node (=node drawn as a box)
showReferencedLibrary :: Int -> GInfo -> ConvFunc -> LibFunc -> IO ()
showReferencedLibrary descr gInfo@(GInfo { libEnvIORef = ioRefProofStatus
le <- readIORef ioRefProofStatus
let refNode = labDG (lookupDGraph ln le) descr
refLibname = if isDGRef refNode then dgn_libname refNode
else error "showReferencedLibrary"
gInfo' <- copyGInfo gInfo refLibname
convGraph gInfo' "development graph" showLib
let gv = gi_GraphInfo gInfo'
Nothing -> error $ "The referenced library (" ++ show refLibname
-- | apply type changes of edges
applyTypeChanges gi dgraph = do
mapM_ (\ (node, dgnode) ->
-- | apply the changes of first history item (computed by proof rules,
-- see folder Proofs) to the displayed development graph
applyChanges _ [] = return ()
applyChanges ginfo ((_, hElem) : _) = mapM_ (applyChangesAux ginfo)
$ removeContraryChanges hElem
-- | auxiliary function for applyChanges
applyChangesAux ginfo change =
SetNodeLab _ (node, newLab) ->
InsertNode (node, nodelab) ->
GA.addNode ginfo node (getRealDGNodeType nodelab) $ getDGNodeName nodelab
InsertEdge e@(src, tgt, lbl) ->
GA.addEdge ginfo (dgl_id lbl) (getRealDGLinkType lbl) src tgt "" $ Just e
DeleteEdge (_, _, lbl) ->
-- | display a window of translated graph with maximal sublogic.
openTranslateGraph :: LibEnv -> LIB_NAME -> HetcatsOpts
->
Res.Result G_sublogics -> ConvFunc -> LibFunc -> IO ()
openTranslateGraph libEnv ln opts (
Res.Result diagsSl mSublogic) convGraph
-- if an error existed by the search of maximal sublogicn
if hasErrors diagsSl then
errorMess $ unlines $ map show
$ filter (relevantDiagKind . diagKind) diagsSl
let paths = findComorphismPaths logicGraph sublogic
errorMess "This graph has no comorphism to translation."
sel <- lift $ listBox "Choose a logic translation"
_ -> liftR $ fail "no logic translation chosen")
let aComor = paths !! fromJust i
case libEnv_translation libEnv aComor of
showDiags opts (diagsSl ++ diagsR ++ diagsTrans)
if hasErrors (diagsR ++ diagsTrans) then
errorMess $ unlines $ map show
$ filter (relevantDiagKind . diagKind)
(\gI@(GInfo{libEnvIORef = iorLE}) -> do
writeIORef iorLE newLibEnv
convGraph (gI{ gi_LIB_NAME = ln
, gi_hetcatsOpts = opts})
"translation Graph" showLib)
errorMess $ unlines $ map show
$ filter (relevantDiagKind . diagKind)
$ diagsSl ++ diagsR ++ diagsTrans
Nothing -> errorMess "the maximal sublogic is not found."
where relevantDiagKind Error = True
relevantDiagKind Warning = verbose opts >= 2
relevantDiagKind Hint = verbose opts >= 4
relevantDiagKind Debug = verbose opts >= 5
relevantDiagKind MessageW = False
dg_showGraphAux :: (GInfo -> IO ()) -> IO ()
dg_showGraphAux convFct = do
useHTk -- All messages are displayed in TK dialog windows
let actGraphInfo = gi_GraphInfo gInfo
-- DaVinciGraph to String
-- Functions to convert a DaVinciGraph to a String to store as a .udg file
-- | saves the uDrawGraph graph to a file
saveUDGraph :: GInfo ->
Map.Map DGNodeType (Shape value, String)
saveUDGraph gInfo@(GInfo { gi_GraphInfo = graphInfo
evnt <- newFileDialogStr "Save as..."
$ (rmSuffix $ libNameToFile opts ln) ++ ".udg"
nstring <- nodes2String gInfo nodemap linkmap
writeFile filepath nstring
-- | Converts the nodes of the graph to String representation
nodes2String :: GInfo ->
Map.Map DGNodeType (Shape value, String)
nodes2String gInfo@(GInfo { gi_GraphInfo = graphInfo
, libEnvIORef = ioRefProofStatus
le <- readIORef ioRefProofStatus
$ labNodesDG $ lookupDGraph ln le
nstring <- foldM (\s node -> do
s' <- (node2String gInfo nodemap linkmap node)
return $ s ++ (if s /= "" then ",\n " else "") ++ s')
return $ "[" ++ nstring ++ "]"
-- | Converts a node to String representation
node2String :: GInfo ->
Map.Map DGNodeType (Shape value, String)
-> LNode DGNodeLab -> IO String
node2String gInfo nodemap linkmap (nid, dgnode) = do
label <- getNodeLabel gInfo dgnode
let ntype = getRealDGNodeType dgnode
(shape, color) <- case
Map.lookup ntype nodemap of
Nothing -> error $ "SaveGraph: can't lookup nodetype: " ++ show ntype
Just (s, c) -> return (s, c)
object = "a(\"OBJECT\",\"" ++ label ++ "\"),"
color' = "a(\"COLOR\",\"" ++ color ++ "\"),"
shape' = "a(\"_GO\",\"" ++ (map toLower $ show shape) ++ "\")"
links <- links2String gInfo linkmap nid
return $ "l(\"" ++ (show nid) ++ "\",n(\"" ++ show ntype ++ "\","
++ "[" ++ object ++ color' ++ shape' ++ "],"
++ "\n [" ++ links ++ "]))"
-- | Converts all links of a node to String representation
links2String (GInfo { gi_GraphInfo = graphInfo
, libEnvIORef = ioRefProofStatus
le <- readIORef ioRefProofStatus
edges <- filterM (\(src,_,edge) -> do
return $ (not b) && src == nodeid)
$ labEdgesDG $ lookupDGraph ln le
s' <- link2String linkmap edge
return $ s ++ (if s /= "" then ",\n " else "") ++ s') "" edges
-- | Converts a link to String representation
-> LEdge DGLinkLab -> IO String
link2String linkmap (nodeid1, nodeid2, edge) = do
let (EdgeId linkid) = dgl_id edge
ltype = getRealDGLinkType edge
Nothing -> error $ "SaveGraph: can't lookup linktype: " ++ show ltype
Just (l, c) -> return (l, c)
name = "\"" ++ (show linkid) ++ ":" ++ (show nodeid1) ++ "->"
++ (show nodeid2) ++ "\""
color' = "a(\"EDGECOLOR\",\"" ++ color ++ "\"),"
line' = "a(\"EDGEPATTERN\",\"" ++ (map toLower $ show line) ++ "\")"
return $ "l(" ++ name ++ ",e(\"" ++ show ltype ++ "\","
++ "[" ++ color' ++ line' ++"],"
++ "r(\"" ++ (show nodeid2) ++ "\")))"
-- | Returns the name of the Node
getNodeLabel :: GInfo -> DGNodeLab -> IO String
getNodeLabel (GInfo {internalNamesIORef = ioRefInternal}) dgnode = do
internal <- readIORef ioRefInternal
let ntype = getDGNodeType dgnode
case (not $ showNames internal) &&
elem ntype ["open_cons__internal"
, "proven_cons__internal"
, "locallyEmpty__open_cons__internal"
, "locallyEmpty__proven_cons__internal"] of
False -> return $ getDGNodeName dgnode