diff --git a/dataflow.cabal b/dataflow.cabal
--- a/dataflow.cabal
+++ b/dataflow.cabal
@@ -1,5 +1,5 @@
 name:                dataflow
-version:             0.5.0.0
+version:             0.5.1.0
 synopsis:            Generate Graphviz documents from a Haskell representation.
 description:         Outputs .dot files that can be processed by the dot
                      command. Currently it only supports the DFD output format
@@ -32,6 +32,7 @@
   exposed-modules:
     DataFlow.Core,
     DataFlow.Graphviz,
+    DataFlow.Graphviz.EdgeNormalization,
     DataFlow.Graphviz.Renderer,
     DataFlow.DFD
   build-depends:
diff --git a/src/DataFlow/Graphviz/EdgeNormalization.hs b/src/DataFlow/Graphviz/EdgeNormalization.hs
new file mode 100644
--- /dev/null
+++ b/src/DataFlow/Graphviz/EdgeNormalization.hs
@@ -0,0 +1,50 @@
+module DataFlow.Graphviz.EdgeNormalization (normalize) where
+
+import DataFlow.Graphviz
+
+import Control.Monad.State
+import Data.Set (Set)
+import qualified Data.Set as Set
+
+type Normalizer v = State (Set (NodeID, NodeID)) v
+
+exists :: (NodeID, NodeID) -> Normalizer Bool
+exists k = do
+  s <- get
+  return $ Set.member k s
+
+register :: (NodeID, NodeID) -> Normalizer ()
+register p = modify $ \s -> Set.insert p s
+
+shouldInvert :: (NodeID, NodeID) -> Normalizer Bool
+shouldInvert k@(i1, i2) = do
+  e <- exists k
+  if e
+    then return False
+    else do
+      ie <- exists (i2, i1)
+      if ie
+        then return True
+        else do
+          register k
+          return False
+
+normalizeStmt :: Stmt -> Normalizer Stmt
+normalizeStmt e@(EdgeStmt (EdgeExpr (IDOperand i1) op (IDOperand i2)) attrs) = do
+  i <- shouldInvert (i1, i2)
+  return $ if i then EdgeStmt (EdgeExpr (IDOperand i2) op (IDOperand i1))
+                              (Attr (ID "dir") (ID "back") : attrs)
+           else e
+
+normalizeStmt (SubgraphStmt (Subgraph id' stmts)) = do
+  s <- mapM normalizeStmt stmts
+  return $ SubgraphStmt $ Subgraph id' s
+normalizeStmt s = return s
+
+normalize' :: Graph -> Normalizer Graph
+normalize' (Digraph id' stmts) = do
+  s <- mapM normalizeStmt stmts
+  return $ Digraph id' s
+
+normalize :: Graph -> Graph
+normalize g = evalState (normalize' g) Set.empty
