Remove more unneccessary nodes in SLF networks.

This commit is contained in:
bringert
2006-01-05 16:48:55 +00:00
parent 0603e75a14
commit 6958b7bb7b
2 changed files with 25 additions and 15 deletions

View File

@@ -128,34 +128,37 @@ moveLabelsToNodes = onGraph f
-- | Remove empty nodes which are not start or final, and have -- | Remove empty nodes which are not start or final, and have
-- exactly one outgoing edge. -- exactly one outgoing edge or exactly one incoming edge.
removeTrivialEmptyNodes :: Ord n => FA n (Maybe a) () -> FA n (Maybe a) () removeTrivialEmptyNodes :: Ord n => FA n (Maybe a) () -> FA n (Maybe a) ()
removeTrivialEmptyNodes = pruneUnreachable . skipEmptyNodes removeTrivialEmptyNodes = pruneUnusable . skipSimpleEmptyNodes
-- | Move edges to empty nodes with one outgoing edge to the next edge. -- | Move edges to empty nodes with exactly one outgoing edge
skipEmptyNodes :: Ord n => FA n (Maybe a) () -> FA n (Maybe a) () -- or exactly one incoming edge to point to the next node(s).
skipEmptyNodes = onGraph og skipSimpleEmptyNodes :: Ord n => FA n (Maybe a) () -> FA n (Maybe a) ()
skipSimpleEmptyNodes = onGraph og
where where
og g@(Graph c ns es) = Graph c ns (map changeEdge es) og g@(Graph c ns es) = Graph c ns (concatMap changeEdge es)
where where
info = nodeInfo g info = nodeInfo g
changeEdge e@(f,t,()) changeEdge e@(f,t,())
| isNothing (getNodeLabel info t) | isNothing (getNodeLabel info t)
= case getOutgoing info t of && (inDegree info t == 1 || outDegree info t == 1)
[(_,t',())] -> (f,t',()) = [ (f,t',()) | (_,t',()) <- getOutgoing info t]
_ -> e | otherwise = [e]
| otherwise = e
isInternal :: Eq n => FA n a b -> n -> Bool isInternal :: Eq n => FA n a b -> n -> Bool
isInternal (FA _ start final) n = n /= start && n `notElem` final isInternal (FA _ start final) n = n /= start && n `notElem` final
-- | Remove all internal nodes with no incoming edges. -- | Remove all internal nodes with no incoming edges
pruneUnreachable :: Ord n => FA n (Maybe a) () -> FA n (Maybe a) () -- or no outgoing edges.
pruneUnreachable fa = onGraph f fa pruneUnusable :: Ord n => FA n (Maybe a) () -> FA n (Maybe a) ()
pruneUnusable fa = onGraph f fa
where where
f g = removeNodes (Set.fromList [ n | (n,_) <- nodes g, f g = removeNodes (Set.fromList [ n | (n,_) <- nodes g,
isInternal fa n, isInternal fa n,
null (getIncoming info n)]) g inDegree info n == 0
|| outDegree info n == 0]) g
where info = nodeInfo g where info = nodeInfo g
fixIncoming :: (Ord n, Eq a) => [n] fixIncoming :: (Ord n, Eq a) => [n]

View File

@@ -17,6 +17,7 @@ module GF.Speech.Graph ( Graph(..), Node, Edge, NodeInfo
, removeNodes , removeNodes
, nodeInfo , nodeInfo
, getIncoming, getOutgoing, getNodeLabel , getIncoming, getOutgoing, getNodeLabel
, inDegree, outDegree
, edgeFrom, edgeTo, edgeLabel , edgeFrom, edgeTo, edgeLabel
, reverseGraph, renameNodes , reverseGraph, renameNodes
) where ) where
@@ -109,6 +110,12 @@ getIncoming i n = let (_,inc,_) = lookupNode i n in inc
getOutgoing :: Ord n => NodeInfo n a b -> n -> [Edge n b] getOutgoing :: Ord n => NodeInfo n a b -> n -> [Edge n b]
getOutgoing i n = let (_,_,out) = lookupNode i n in out getOutgoing i n = let (_,_,out) = lookupNode i n in out
inDegree :: Ord n => NodeInfo n a b -> n -> Int
inDegree i n = length $ getIncoming i n
outDegree :: Ord n => NodeInfo n a b -> n -> Int
outDegree i n = length $ getOutgoing i n
getNodeLabel :: Ord n => NodeInfo n a b -> n -> a getNodeLabel :: Ord n => NodeInfo n a b -> n -> a
getNodeLabel i n = let (l,_,_) = lookupNode i n in l getNodeLabel i n = let (l,_,_) = lookupNode i n in l