Aligning nodes in dot with group does not give the desired result - graph

I tried to create graph from here Improving graphviz layout and want to get the exact picture
like in post, but can't vertically align nodes and get nice curve in q3->q3. My question is about how fix this:
digraph {
layout=dot
rankdir = LR
node [shape=circle]
Start [shape=plaintext group=g1]
q0 [shape = doublecircle label=<<I>q</I><SUB>0</SUB>> group=g1]
q1 [label=<<I>q</I><SUB>1</SUB>> group=g1]
q2 [label=<<I>q</I><SUB>2</SUB>> group=g2]
q3 [label=<<I>q</I><SUB>3</SUB>> group=g2]
Start -> q0
q0 -> q1 [label="1"]
q1 -> q0 [label="0"]
q1 -> q3 [label="0"]
q3:s -> q3:e [label="0,1"]
q0 -> q2 [label="1"]
q2 -> q0 [label="0"]
q2 -> q3 [label="1"]
{rank = same; q2;q0;}
{rank = same; q1;q3;}
}
Online editor
P.S. I came up with another variant, it's better than the first one, but not yet what I visually expected:
digraph {
layout=dot
ranksep=0.2;
node [shape=circle]
Start [shape=plaintext group=g1]
q0 [shape = doublecircle label=<<I>q</I><SUB>0</SUB>> group=g1]
q1 [label=<<I>q</I><SUB>1</SUB>> group=g1]
q2 [label=<<I>q</I><SUB>2</SUB>> group=g2]
q3 [label=<<I>q</I><SUB>3</SUB>> group=g2]
Start -> q0
q0:ne -> q1:nw [label="1"]
q1:sw -> q0:se [label="0"]
q1 -> q3 [label="0"]
q3:se -> q3:e [label="0,1";]
q0 -> q2 [label="1"]
q2 -> q0 [label="0"]
q2 -> q3 [label="1"; constraint=false]
{rank=same; Start; q0; q1}
{rank=same; q2; q3}
//hack starting
//invisnode [shape=point, width=0]
edge [style=invis]
q0 -> q2
//q0 -> invisnode -> q1
}
Result:

Image:
Script:
digraph {
ranksep=1;
nodesep=0.5;
node [shape=circle]
Start [margin=0 width=0 shape=plaintext]
q0 [shape = doublecircle label=<<I>q</I><SUB>0</SUB>>]
q1 [label=<<I>q</I><SUB>1</SUB>>]
q2 [label=<<I>q</I><SUB>2</SUB>>]
q3 [label=<<I>q</I><SUB>3</SUB>>]
Start -> q0
q1 -> q0 [xlabel="1"]
q0 -> q1 [xlabel="0"]
q1 -> q3 [label=" 0"]
q3:se -> q3:e [label=" 0,1"]
q2 -> q0 [xlabel="0 "]
q0 -> q2 [xlabel="1 "]
q2 -> q3 [label="1"]
{rank=same; Start; q0; q1}
{rank=same; q2; q3}
}
Answer's sources: how group attribute works, solution
P.S. I think I can get a nice curve q3->q3 using the neato engine with pos node attribute for positioning nodes and pos edge attribute for spline control points. Solution still in work.

Related

Splitting a premise with conjunction conclusion in Coq

I often have to do "induction loading" to prove goals in Coq, where I prove multiple things simultaneously by induction.
The problem is, I often end up with Inductive Hypotheses of the following form:
forall a1 ... an,
Premise1 -> Premise2 -> ... Premisek ->
Conclusion1 /\ Conclusion2 /\ ... Conclusion_m
This is fine, but tactics like eauto really don't know how to handle things like this, so it kills automation most of the time.
What I'm wondering is, is there a way to automatically break such a premise into m different premises, i.e.
forall a1 ... an,
Premise1 -> Premise2 -> ... Premisek ->
Conclusion1
...
forall a1 ... an,
Premise1 -> Premise2 -> ... Premise_k ->
Conclusion_m
The main problem I'm running into is that I don't know how to match with an arbitrary length chain of arrows in LTac. I could hard-code up to a certain length, but I'm hoping there's a better way.
Additionally, if it were possible to do the dual (i.e. split on all combinations of disjunctions in Premise1 .. Premise_k) that would also be useful.
I am not an expert of Ltac, but I gave it a try and came up with the following tactic.
Ltac decomp H :=
try match type of H with
context c [?A /\ ?B] =>
let H' := fresh H in
let Pa := context c[A] in
assert (H' : Pa) by (apply H);
let H'' := fresh H in
let Pb := context c[B] in
assert (H'' : Pb) by (apply H);
clear H;
rename H' into H;
rename H'' into H';
decomp H'
end.
Tactic Notation "decomp_hyp" hyp(H) := decomp H.
decomp H searches occurrences of conjunctions in H, then decomposes it into H' and H'', clean the state and calls itself recursively.
On a trivial example, this seems to work.
Perhaps something like this (minus the debug printouts)?
Ltac foo :=
match goal with
| |- forall q, ?X =>
let x := fresh in intros x; idtac x q ; (try foo); generalize x as q; clear x
| |- ?X -> _ =>
let x := fresh in intros x; idtac x ; (try foo); generalize x; clear x
| |- _ /\ _ => repeat split
end; idtac "done".
Goal forall {T} (a1 a2 a3:T) P1 P2 P3 Q1 Q2 Q3, P1 a1 -> P2 a2 -> P3 a3 -> Q1 /\ Q2 /\ Q3.
foo.
This leaves you with the goals
3 subgoals (ID 253)
============================
forall (T : Type) (a1 a2 a3 : T) (P1 P2 P3 : T -> Type) (Q1 : Prop),
Prop -> Prop -> P1 a1 -> P2 a2 -> P3 a3 -> Q1
subgoal 2 (ID 254) is:
forall (T : Type) (a1 a2 a3 : T) (P1 P2 P3 : T -> Type),
Prop -> forall Q2 : Prop, Prop -> P1 a1 -> P2 a2 -> P3 a3 -> Q2
subgoal 3 (ID 255) is:
forall (T : Type) (a1 a2 a3 : T) (P1 P2 P3 : T -> Type),
Prop -> Prop -> forall Q3 : Prop, P1 a1 -> P2 a2 -> P3 a3 -> Q3

Remove line-crossing in Graphviz; layout different in jupyter and webgraphviz

I'm looking for a way to remove an unacceptable line crossing in a simple dot script. There is no line-crossing when the code is executed in http://www.webgraphviz.com/, but there is a line-crossing when the exact same code is executed in a Jupyter notebook. I'd be grateful for a suggestion of how to remove the line-crossing in Jupyter, that is, to make the layout in Jupyter look like the layout in webgraphviz.
Here is the dot code:
Digraph X {
rankdir=LR;
{rank=same; a b}
{rank=same; d c}
z -> a
a -> b
b -> c
c -> d
d -> a
}
In http://www.webgraphviz.com/, it displays as follows:
But, in Jupyter, it displays as follows, with an unacceptable line-crossing:
The jupyter code is the following:
import graphviz
graphviz.Source('''Digraph X {
rankdir=LR;
{rank=same; a b}
{rank=same; d c}
z -> a
a -> b
b -> c
c -> d
d -> a
}''')
This took some trial and error and piecing together clues from https://graphviz.gitlab.io/_pages/doc/info/attrs.html
import graphviz
graphviz.Source('''Digraph X {
rankdir=RL;
{rank=sink; z}
{rank=same; c d}
{rank=same; a b}
z -> a
a -> b
b -> c [constraint=false]
c -> d [constraint=false]
d -> a
}''')

Graphviz Draw graph nodes using BFS order

I've a graph file (.dot) with nodes that has depth and size "properties". I want to use graphviz to draw this graph considering "depth" as the depth of a Breadth First Search and the size property as a relative size of the node.
I've tried using twopi and setting all nodes that have the same depth on the same rank, but with no success. Any suggestion on how I can accomplish this?
Sample graph:
strict digraph {
root = 0;
ranksep = 5;
{rank=same;
0
14754221888142813049
}
{rank=same;
17110173155996056797
8860119836345733269
12488214955576990298
5164430016200693425
6534280015544966791
16035081712171710670
7728255721346380016
3065692608114503807
15537038826989012875
15464545769657918305
7964210557574239786
17237485240931079100
9667703542183627069
9063621412962345275
4956992700610885217
703599774521196210
}
0 [label="A"];
14754221888142813049 [label="B"];
17110173155996056797 [label="C"];
8860119836345733269 [label="D"];
12488214955576990298 [label="E"];
5164430016200693425 [label="F"];
6534280015544966791 [label="G"];
16035081712171710670 [label="H"];
7728255721346380016 [label="I"];
3065692608114503807 [label="J"];
15537038826989012875 [label="K"];
15464545769657918305 [label="L"];
7964210557574239786 [label="M"];
17237485240931079100 [label="N"];
9667703542183627069 [label="O"];
9063621412962345275 [label="P"];
4956992700610885217 [label="Q"];
703599774521196210 [label="R"];
0 -> 14754221888142813049
0 -> 12488214955576990298
0 -> 5164430016200693425 [weight=0, constraint=false];
0 -> 15537038826989012875
0 -> 7964210557574239786
0 -> 9667703542183627069
0 -> 17237485240931079100
5164430016200693425 -> 8860119836345733269 [weight=0, constraint=false];
8860119836345733269 -> 4956992700610885217
8860119836345733269 -> 9063621412962345275
8860119836345733269 -> 703599774521196210
8860119836345733269 -> 17110173155996056797
8860119836345733269 -> 6534280015544966791
8860119836345733269 -> 16035081712171710670
8860119836345733269 -> 7728255721346380016
8860119836345733269 -> 3065692608114503807
8860119836345733269 -> 15464545769657918305
}
You are trying to capture hierarchical structure so you want to use the dot layout. By default, if you have an edge a->b, node b will be 1 level below node a. If you have a tree, and make sure the node of depth 0 appears first, you'll get the layout you want by default. If your graph is more complex, the edge criteria mentioned, or cycle breaking, may interfere with what you want. In that case, you need to make the depth constraints more explicit and turn off other edge constraints. There are several ways to do this.
Suppose you have the following graph where the numbers in the node names indicate the depth.
digraph {
0 -> a1
0 -> b1
a1 -> a2
a1 -> b2
b1 -> c2
b1 -> d2
a2 -> d2
a2 -> b1
}
A simple way to get what you want is to do a BFS, and set any edge not part of the BFS tree to have constraint=false.
digraph {
0 -> a1
0 -> b1
a1 -> a2
a1 -> b2
b1 -> c2
b1 -> d2
a2 -> d2 [constraint=false]
a2 -> b1 [constraint=false]
}
Or you can use rank=same to make sure nodes are placed on ranks corresponding to their depths, again turning off edges that conflict. (This assumes you have at least one chain of edges going from depth 0 to the bottom. If not, you can introduce an invisible chain of dummy nodes and edges satisfying this, and adding each dummy node to its rank=same subgraph.}
digraph {
0 -> a1
0 -> b1
a1 -> a2
a1 -> b2
b1 -> c2
b1 -> d2
a2 -> d2 [constraint=false]
a2 -> b1 [constraint=false]
{rank=same a1 b1}
{rank=same a2 b2 c2 d2}
}
This allows the depth function to not be actually tied to a BFS tree.
By the way, twopi should have worked, but with the layout center out instead of top down, as its levels are based on a BFS from a root node. This assumes you set the root attribute and, as you have an explicit BFS in mind, turning off non-tree edges by setting weight=0.
digraph {
root=0
0 -> a1
0 -> b1
a1 -> a2
a1 -> b2
b1 -> c2
b1 -> d2
a2 -> d2 [weight=0]
a2 -> b1 [weight=0]
}

Creating an Exclusive Or from two Deterministic Finite Automatons (Deterministic Finite-State Machines)

Two DFAs (Deterministic Finite Automaton or Deterministic Fininte-State Machines - Which will be called DFAs from here on)
Defined over the set
DFA 1: L1 = {Q1, E, D1, s1, F}
DFA 2: L2 = {Q2, E, D2, s2, F}
Q is the list of states. Ex 1, 2, 3, 4 or a, b, c, d
E is the the language Ex. 0, 1
D is the transition set Ex. {(a,0,b)} state a goes to b on a 0
s is the starting state
F is the final state
How would you take and exclusive-or of two DFAs L1 and L2
Here are a few broad hints to get you started...
You'll probably want to build another DFA whose states Q3 are identified with
elements of the Cartesian product of Q1 and Q2. From s1 and s2, it should be
pretty obvious which element of Q3 should be designated as the start state.
Then, given any node (n1 in Q1, n2 in Q2) in Q3, it should be pretty easy to
figure out where the edges need to go for each input. And F3 will a set of states
(n1, n2) where (n1 in F1 XOR n2 in F2) holds.
Q = Q1 X Q2;
E = E;
D is all transitions that agree from both systems;
s = S1 intersect S2;
F = F1 XOR F2

Drawing reflexive edges in State Machines

I have to draw a small finite state machine that has some reflexive transitions (meaning the start and the end state of the transition are equal.
The problem is that rendering that in Graphviz has ugly results.
digraph finite_state_machine {
edge [fontsize=11];
S0 -> S0 [label = "td=1\n-/e2"];
S0 -> S1 [label = "td=3 \n-/e3" ];
S1 -> S0 [label = "td=3\n-/-\nt=0"];
S0 -> S2 [label = "P:i1/e4"];
S2 -> S0 [label = "td=0\n-/-" ];
S0 -> S0 [label = "i1/e1\ntd+=1"];
}
Is there a way to make this look a little better?
BTW: I tried head/tailport but they don't work on my version of Graphviz (1.13 on Mac OS X)
I am not limited to the dot engine, I only want a nice looking graph and don't care about the renderer/language.
Thanks a lot
So, if found a workaround, but not really an answer to my problem.
The trick is to have an invisible node that connections to the starting state. the starting state is then not the top of the hierarchy and one has a little bit more freedom in placing the nodes. Also then the head/tailport attributes work as they should.
The result is - if not a pretty as I would like it to be - ok to look at.
digraph finite_state_machine {
edge [fontsize=7];
fontsize = 11;
rankdir=LR;
{rank = same;null}
{rank = same; S0}
{rank = same; S1 S2}
nodesep = 1;
ranksep = 1;
null [shape = plaintext label=""];
null -> S0;
S0 -> S0 [label = "td=1\n-/e2", tailport = n, headport = n];
S0 -> S1 [label = "td=3 \n-/e3" ];
S1 -> S0 [label = "td=3\n-/-\nt=0"];
S0 -> S2 [label = "P:i1/e4"];
S2 -> S0 [label = "td=0\n-/-" ];
S0 -> S0 [label = "i1/e1\ntd+=1" headport = s tailport = s];
}
a rendering of the state machine http://img532.imageshack.us/img532/4083/previewd.png
While this works (for this particular example) I would still very much like some advice on dot/Graphviz or an alternative for rendering finite state machines in a pleasing way.

Resources