geni-gui-0.24: src/NLP/GenI/GraphvizShowPolarity.hs
-- 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.
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module NLP.GenI.GraphvizShowPolarity
where
import Data.List (intercalate)
import qualified Data.Map as Map
import Data.Maybe (catMaybes)
import qualified Data.Text.Lazy as TL
import Data.GraphViz
import Data.GraphViz.Attributes.Complete
import NLP.GenI.General (showInterval)
import NLP.GenI.Graphviz (GraphvizShow (..),
gvUnlines)
import NLP.GenI.Polarity (NFA (states, transitions),
PolAut, PolState (PolSt),
finalSt)
import NLP.GenI.Pretty
import NLP.GenI.Tag (idname)
instance GraphvizShow PolAut where
-- we want a directed graph (arrows)
graphvizShowGraph aut =
DotGraph False True Nothing $ DotStmts
atts
(graphvizShowAsSubgraph "aut" aut)
[] -- all nodes are in the subgraph
[]
where
atts =
[ GraphAttrs [RankDir FromLeft, RankSep [0.02], Pack (PackMargin 1)]
, NodeAttrs [FontSize 10]
, EdgeAttrs [FontSize 10]
]
graphvizShowAsSubgraph prefix aut =
[ DotSG False Nothing
$ DotStmts [ NodeAttrs [ Shape Ellipse, Peripheries 1 ] ]
[]
(zipWith (gvShowState fin) ids st)
(concat $ zipWith (gvShowTrans aut stmap) ids st)
]
where
st = (concat.states) aut
fin = finalSt aut
ids = map (\x -> prefix <> TL.pack (show x)) ([0..] :: [Int])
-- map which permits us to assign an id to a state
stmap = Map.fromList $ zip st ids
gvShowState :: [PolState] -> TL.Text -> PolState -> DotNode TL.Text
gvShowState fin stId st =
DotNode stId $ decorate [ Label . StrLabel . showSt $ st ]
where
showSt (PolSt _ ex po) = gvUnlines . catMaybes $
[ Nothing -- Just (snd3 pr)
, if null ex then Nothing else Just (TL.fromChunks [pretty ex])
, Just . TL.pack . intercalate "," $ map showInterval po
]
decorate =
if st `elem` fin then (Peripheries 2 :) else id
gvShowTrans :: PolAut -> Map.Map PolState TL.Text
-> TL.Text -> PolState -> [DotEdge TL.Text]
gvShowTrans aut stmap idFrom st =
map drawTrans (Map.toList trans)
where
-- 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_" `TL.append` (TL.pack (sem_ stTo))) x
Just idTo -> drawTrans' idTo x
where
sem_ (PolSt i _ _) = show i
--showSem (PolSt (_,pred,_) _ _) = pred
drawTrans' idTo x = DotEdge idFrom idTo [Label (drawLabel x)]
drawLabel labels =
StrLabel . gvUnlines $ labs
where
lablen = length labels
maxlabs = 6
excess = TL.pack $ "...and " ++ show (lablen - maxlabs) ++ " more"
--
name t = TL.fromChunks [ idname t ]
labstrs = map (maybe "EMPTY" name) labels
labs = if lablen > maxlabs
then take maxlabs labstrs ++ [ excess ]
else labstrs