Rendering automata

Hi all,

I'm using GraphViz to render weighted automata. They are generalizations of the usual DFA/NFA: there are states, and transitions. In the weighted case, in addition to a label, the transitions may have a weight (denoted in angle brackets in my example below). Initial and final states also have a weight.

There are several traditions to rendering initial and final states, one being a double-circle for accepting states.

I do not belong to this tradition: there should be an incoming arrow to denote an initial state, and an outgoing arrow to denote an accepting state. Besides, these arrows will carry the weight of these initial/final states.

I could not find a means to draw incoming/outgoing arrows, have I missed something? So I am cheating, and for each initial/final state, I create a phantom pre-initial/post-final state, and a pseudo-transition. The render is OK, but not so good, as even if these phantom states are invisible, Dot tries to find them a nice place, which results in weird initial/final arrows, as in the example below.

Is there a means to get a better rendering? Does someone have a nice suggestion?

Thanks in advance!


digraph
{
vcsn_context = "lal_char(ab)_q"
rankdir = LR
{
node [style = invis, shape = none, label = "", width = 0, height = 0]
I0
F0
F1
F2
}
{
node [shape = circle]
0
1
2
}
I0 -> 0
0 -> F0 [label = "<2>"]
0 -> 1 [label = "<1/3>a"]
0 -> 2 [label = "<2/3>b"]
1 -> F1 [label = "<2>"]
1 -> 1 [label = "<4/3>a"]
1 -> 2 [label = "<2/3>b"]
2 -> F2 [label = "<2>"]
2 -> 1 [label = "<1/3>a"]
2 -> 2 [label = "<5/3>b"]
}

AttachmentSize
g.pdf8.49 KB

Really?

So there would be no way to render incoming/outgoing arrow, with labels, without requesting an invisible node that messes up the final layout?

Sorry I missed this post when

Sorry I missed this post when it first appeared.

The straightforward answer is, you are correct. If you want an arrow, meaning an edge, you need two end points. That said, you stated that the final layout is messed up but you didn't elaborate on what would be a good layout. (To me, the layout you posted looks fine.) What would you like to see? There is quite possibly a way to achieve this. And, if not, one can often employ a simple post-processing pass to tweak the diagram the way you want it.

My turn to miss your answer

Hi erg,

Sorry, I missed your answer.  What is wrong about the rendering is the two long arrows for the two "finals transitions".  They should be short and straightline, just like the arrow for the initial state.

Thanks in advance!

So you want all of the edges

So you want all of the edges labeled <2> to have roughly the same horizontal distance and be line segments, is that it?

Correct

Yes, that's what I'd like.

A simple way is to make the

A simple way is to make the ordinary edges twice as big but reducing the ranksep:

digraph
{
ranksep="0.10 equally"
vcsn_context = "lal_char(ab)_q"
rankdir = LR
{
node [shape = point, width = 0]
I0
F0
F1
F2
}
{
node [shape = circle]
0
1
2
}
I0 -> 0
0 -> F0 [label = "<2>"]
0 -> 1 [minlen=2 label = "<1/3>a"]
0 -> 2 [minlen=2 label = "<2/3>b"]
1 -> F1 [label = "<2>"]
1 -> 1 [label = "<4/3>a"]
1 -> 2 [minlen=2 label = "<2/3>b"]
2 -> F2 [label = "<2>"]
2 -> 1 [minlen=2 label = "<1/3>a"]
2 -> 2 [label = "<5/3>b"]
}

I also used 0-width points as short hand for the invisible nodes.

Now you still have the possibility that the final state edges are curved. That can be handled with a bit of post-processing:

dot g.gv | gvpr -c 'E[head.name == "F*"]{lp=pos=""}' | neato -n2 -Tpdf > g.pdf