On Mon, 05 Jul 2010 19:26:34 -0700, Ivan Miljenovic <ivan.miljeno...@gmail.com> 
wrote:

Graphviz (http://graphviz.org/) has the option to convert provided Dot
code for visualising a graph into a canonical form.  For example, take
the sample Dot code:
[snip]
I've recently thought up a way that I can duplicate this functionality
(in terms of what it does, not necessarily the actual output) in my
graphviz library (http://hackage.haskell.org/package/graphviz),
however I'm not sure how closely to follow what Graphviz does.

There doesn't seem to be a clear definition of "canon" output is, and the implication in the 
documentation is that this mode might better have been named "pprint" (thus my hesitance to refer 
to it as "canonical form").  Based on this, I'd suggest that you don't need strict adherence to 
graphviz.

It generally appears that "canon" output follows the two guidelines of "Atomic" and 
"Minimal":

* "Atomic" meaning specify all attributes that apply to an element instead of 
relying on inheritance
* "Minimal" meaning don't specify too much
   - No default attributes
   - Each element (edge or node) on its own, no combining (see also "Atomic")
   - Elements only in necessary scope (thus move edges/nodes that only appear 
in a subgraph context into that subgraph)

Based on this I would anticipate your options (1), (2), and (4) below.  The advantages of 
"canon" form would seem to be that removing, or adding elements to the graph is as 
"safe" as possible because the impact to the graph is only as explicitly stated.  For 
example, removal of a node requires only removing that node statement and any edge statement 
specifying that node---no concern about removing it from multi-node or multi-edge elements---and 
that the locality of the removal is fairly evident (i.e. which subgraph the element is part of).  
Likewise adding an element means that the element will appear pretty much as-specified without 
inheriting attributes.

Interestingly you could envision providing a dual of this mode named "compact".  The 
compact mode would attempt to specify the graph as compactly as possible, using inheritance for 
attributes and multi-element statements (interestingly it's an attribute-oriented approach to the 
graph as opposed to the element-oriented approach of "canon" form).

-KQ

 What
would the community prefer out of the following (including a mixture,
such as options 2 and 3):

1) Match Graphviz's output as much as possible (note that the ordering
of the attributes won't happen this way, since I'll be sorting them
alphabetically rather than working out Graphviz's arcane rules).

1a) As with 1), but don't worry about defining extra attributes such
as "node [label="\N"]".

2) Explicitly define nodes that are only mentioned in edges (e.g.
actually define a `c' node, even if it doesn't have any extra
attributes).  Note that this already happens if such an edge is
specified inside a different cluster than the already known node is
in; in that case then the stand-alone node is defined in the cluster
its edge is defined in, and the actual edge is moved into the outer
context that combines the two clusters.

2a) As with 2), but define all edges in the overall graph rather than
grouping them internally inside clusters, etc.

3) Group common attributes together as much as possible (e.g. inside
the bar cluster, define another subgroup which has a top-level
attribute "node [color=blue]" and define the `a' and `b' nodes in
there).  Not sure how well this will work with edges though, and is
probably not possible in conjunction with option 2a).  This is a bit
tricky and subtle: if `a' and `b' are already in such a subgraph, but
an edge specifying one of them is defined _before_ the subgraph is
defined, then that node will have an explicit color attribute defined
of "" (i.e. empty string), though I would classify this as a bug.

4) As an alternate to option 3), remove all explicit top-level node
and edge attributes and move them all to the affected node and edge
definitions themselves; this may require option 2).

I'm also willing to hear and consider other possible variants;
however, I'm only going to code (at most) one.


--
-KQ
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to