Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions brat/Brat/Compiler.hs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ writeDot :: [FilePath] -> String -> String -> IO ()
writeDot libDirs file out = do
env <- runExceptT $ loadFilename root libDirs file
-- Discard captureSets; perhaps we could incorporate into the graph
(_, _, _, graph, _) <- eitherIO env
writeFile out (toDotString graph)
(_, _, _, graph, cs) <- eitherIO env
writeFile out (toDotString graph cs)
{-
where
isMain (PrefixName [] "main", _) = True
Expand Down
54 changes: 35 additions & 19 deletions brat/Brat/Dot.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module Brat.Dot (toDotString) where

import Brat.Checker.Monad (CaptureSets)
import Brat.Naming
import Brat.Graph
import Brat.Syntax.Common
Expand All @@ -11,7 +12,9 @@ import qualified Data.GraphViz.Printing as GV
import qualified Data.GraphViz.Attributes.Complete as GV

import qualified Data.Map as M
import qualified Data.Set as S
import Data.Text.Lazy (pack, unpack)
import Data.Maybe (fromMaybe)
import Data.Bifunctor (first)
import Data.Graph (reachable, transposeG)
import Data.Maybe (fromJust)
Expand All @@ -34,9 +37,10 @@ instance Show EdgeType where
show (GraphEdge ty) = show ty


toDotString :: Graph -> String
toDotString (ns,ws) = unpack . GV.printDotGraph $ GV.graphElemsToDot params verts edges
toDotString :: Graph -> CaptureSets -> String
toDotString (ns,ws) cs = unpack . GV.printDotGraph $ GV.graphElemsToDot params verts edges
where
_ = cs
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤣 now defunct but it was temporarily to silence some error messages. Thanks for spotting :) now removed!

verts :: [(Name', Node)]
verts = first Name' <$> M.toList ns

Expand All @@ -50,26 +54,31 @@ toDotString (ns,ws) = unpack . GV.printDotGraph $ GV.graphElemsToDot params vert
getRefEdge :: Name' -> Node -> [(Name', Name', EdgeType)]
getRefEdge x (BratNode (Eval (Ex y _)) _ _) = [(Name' y, x, EvalEdge)]
getRefEdge x (KernelNode (Splice (Ex y _)) _ _) = [(Name' y, x, EvalEdge)]
getRefEdge x (BratNode (Box src _) _ _) = [(x, Name' src, SrcEdge)]
getRefEdge x (BratNode (Box src tgt) _ _) = [(x, Name' src, SrcEdge), (x, Name' tgt, SrcEdge)]
getRefEdge _ _ = []

-- Map all nodes in a box to the src node
clusterMap :: M.Map Name' Name'
-- Map from node to cluster. Clusters are identified by their containing Box node.
clusterMap :: M.Map Name' Name
clusterMap = foldr f M.empty verts
where
(g, toNode, toVert) = toGraph (ns, ws)
f (_, node) m = case node of
BratNode (Box src tgt) _ _ ->
-- Find all nodes in the box spanned by src and tgt, i.e. all nodes
-- reachable from src that can reach tgt
let srcReaches = reachable g (fromJust (toVert src))
reachesTgt = reachable (transposeG g) (fromJust (toVert tgt))
box = Name' . snd3 . toNode <$> (srcReaches ++ reachesTgt) in
foldr (`M.insert` Name' src) m box
_ -> m
f (Name' boxNode, BratNode (Box src tgt) _ _) m =
-- Find all nodes in the box spanned by src and tgt, i.e. all nodes
-- reachable from src that can reach tgt
let srcReaches = reachable g (fromJust (toVert src))
reachesTgt = reachable (transposeG g) (fromJust (toVert tgt))
nodesUsedInBox = snd3 . toNode <$> (srcReaches ++ reachesTgt)
-- exclude nodes that are captured by the box - these are not in the box
-- (TODO: we might consider adding extra edges from these to the box itself,
-- but for now they'll just have "normal" value edges *entering* the box)
captures = fromMaybe M.empty (M.lookup boxNode cs)
captureNodes = S.fromList [n | vs <- M.elems captures, (NamedPort (Ex n _) _, _) <- vs]
nodesInBox = [Name' n | n <- nodesUsedInBox, S.notMember n captureNodes]
in foldr (`M.insert` boxNode) m nodesInBox
f _ m = m

-- GV.GraphVisParams vertexType vertexLabelType edgeLabelType clusterType clusterLabelType
params :: GV.GraphvizParams Name' Node EdgeType Name' Node
params :: GV.GraphvizParams Name' Node EdgeType Name Node
params = GV.defaultParams {
GV.fmtNode = \(Name' name, node) -> [
GV.textLabel (pack $ show name ++ ":\\n" ++ showNodeType node),
Expand All @@ -83,13 +92,20 @@ toDotString (ns,ws) = unpack . GV.printDotGraph $ GV.graphElemsToDot params vert
GV.Style [style label],
GV.arrowTo (arrow label)
],
GV.clusterBy = \n@(name, _) -> case clusterMap M.!? name of
Just parent -> GV.C parent $ GV.N n
Nothing -> GV.N n,
GV.clusterID = \(Name' name) -> GV.Str (pack $ show name)
GV.clusterBy = \n@(name, _) -> nestClusters name (GV.N n),
GV.clusterID = GV.Str . pack . show
}

nestClusters :: Name' -> GV.NodeCluster Name (Name', Node) -> GV.NodeCluster Name (Name', Node)
nestClusters name n = case clusterMap M.!? name of
Nothing -> n
-- put n in clust, which may itself be in another cluster
Just clust -> nestClusters (Name' clust) (GV.C clust n)

showNodeType :: Node -> String
-- Do not repeat the internal links that have been turned into edges
showNodeType (BratNode (Box _ _) _ _) = "Box"
showNodeType (BratNode (Eval _) _ _) = "Eval"
showNodeType (BratNode thing _ _) = show thing
showNodeType (KernelNode thing _ _) = show thing

Expand Down
15 changes: 0 additions & 15 deletions brat/test/compilation/closures.brat
Original file line number Diff line number Diff line change
@@ -1,17 +1,2 @@
f(Nat) -> { Nat -> Nat }
f(x) = { y => x + y }

g(Nat) -> { Nat -> { Nat -> Nat } }
g(x) = { y => { z => x + y + z } }


h(Nat) -> { Nat -> Nat }
h(x) = let y = x in { z => x + y + z }

ff(Vec(Nat,2)) -> { Nat -> Nat }
ff([a,b]) = { y => a + b*y }

ext "to_float" i2f :: {Int -> Float}

fi(Float) -> { Int -> Float }
fi(x) = { y => x + i2f(y) }
Loading