GenI-0.17.3: src/NLP/GenI/GraphvizShowPolarity.lhs
% GenI surface realiser
% Copyright (C) 2005 Carlos Areces and Eric Kow
%
% This program is free software; you can redistribute it and/or
% modify it under the terms of the GNU General Public License
% as published by the Free Software Foundation; either version 2
% of the License, or (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\begin{code}
{-# LANGUAGE TypeSynonymInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module NLP.GenI.GraphvizShowPolarity
where
import Data.List (intersperse)
import qualified Data.Map as Map
import NLP.GenI.Btypes(showSem)
import NLP.GenI.General(showInterval, isEmptyIntersect)
import NLP.GenI.Polarity(PolAut, PolState(PolSt), NFA(states, transitions), finalSt)
import NLP.GenI.Graphviz(GraphvizShow(..), gvUnlines, gvNewline, gvNode, gvEdge)
import NLP.GenI.Tags(idname)
\end{code}
\begin{code}
instance GraphvizShow () PolAut where
-- we want a directed graph (arrows)
graphvizShowGraph f aut =
"digraph aut {\n"
++ "rankdir=LR\n"
++ "ranksep = 0.02\n"
++ "pack=1\n"
++ "edge [ fontsize=10 ]\n"
++ "node [ fontsize=10 ]\n"
++ graphvizShowAsSubgraph f "aut" aut
++ "}"
--
graphvizShowAsSubgraph _ prefix aut =
let st = (concat.states) aut
ids = map (\x -> prefix ++ show x) ([0..] :: [Int])
-- map which permits us to assign an id to a state
stmap = Map.fromList $ zip st ids
in --
gvShowFinal aut stmap
-- any other state should be an ellipse
++ "node [ shape = ellipse, peripheries = 1 ]\n"
-- draw the states and transitions
++ (concat $ zipWith gvShowState ids st)
++ (concat $ zipWith (gvShowTrans aut stmap) ids st )
\end{code}
\begin{code}
gvShowState :: String -> PolState -> String
gvShowState stId st =
-- note that we pass the label param explicitly to allow for null label
gvNode stId "" [ ("label", showSt st) ]
where showSt (PolSt pr ex po) = showPr pr ++ showEx ex ++ showPo po
showPr _ = "" -- (_,pr,_) = pr ++ gvNewline
showPo po = concat $ intersperse "," $ map showInterval po
showEx ex = if null ex then "" else showSem ex ++ gvNewline
\end{code}
Specify that the final states are drawn with a double circle
\begin{code}
gvShowFinal :: PolAut -> Map.Map PolState String -> String
gvShowFinal aut stmap =
if isEmptyIntersect (concat $ states aut) fin
then ""
else "node [ peripheries = 2 ]; "
++ concatMap (\x -> " " ++ lookupId x) fin
++ "\n"
where fin = finalSt aut
lookupId x = Map.findWithDefault "error_final" x stmap
\end{code}
Each transition is displayed with the name of the tree. If there is more
than one transition to the same state, they are displayed on a single
label.
\begin{code}
gvShowTrans :: PolAut -> Map.Map PolState String
-> String -> PolState -> String
gvShowTrans aut stmap idFrom st =
let -- outgoing transition labels from st
trans = Map.findWithDefault Map.empty st $ transitions aut
-- returns the graphviz dot command to draw a labeled transition
drawTrans (stTo,x) = case Map.lookup stTo stmap of
Nothing -> drawTrans' ("id_error_" ++ (sem_ stTo)) x
Just idTo -> drawTrans' idTo x
where sem_ (PolSt i _ _) = show i
--showSem (PolSt (_,pred,_) _ _) = pred
drawTrans' idTo x = gvEdge idFrom idTo (drawLabel x) []
drawLabel labels = gvUnlines labs
where
lablen = length labels
maxlabs = 6
excess = "...and " ++ (show $ lablen - maxlabs) ++ " more"
--
labstrs = map fn labels
fn Nothing = "EMPTY"
fn (Just x) = idname x
--
labs = if lablen > maxlabs
then take maxlabs labstrs ++ [ excess ]
else labstrs
in unlines $ map drawTrans $ Map.toList trans
\end{code}
%gvShowTransPred te =
% let p = tpredictors te
% charge fv = case () of _ | c == -1 -> "-"
% | c == 1 -> "+"
% | c > 0 -> "+" ++ (show c)
% | otherwise -> (show c)
% where c = lookupWithDefaultFM p 0 fv
% showfv (f,v) = charge (f,v) ++ f
% ++ (if (null v) then "" else ":" ++ v)
% in map showfv $ Map.keys p