dot: heuristic to switch between circles and ellipses
* src/twaalgos/dotty.cc: Add an option (e) to force elliptic shape, and a heuristic to choose between circle and ellipse by default. * src/bin/common_aoutput.cc, src/bin/dstar2tgba.cc: Document 'e'. * src/taalgos/dotty.cc: Ignore 'e'. * wrap/python/spot.py (setup): Do not force circular states. The default should be fine. * src/tests/det.test, src/tests/dstar.test, src/tests/monitor.test, src/tests/neverclaimread.test, src/tests/readsave.test, src/tests/sccdot.test, src/tests/tgbagraph.test: Adjust expected results. * NEWS: Adjust.
This commit is contained in:
parent
8aa88c2951
commit
a4b63e8e7f
13 changed files with 65 additions and 22 deletions
10
NEWS
10
NEWS
|
|
@ -187,10 +187,12 @@ New in spot 1.99b (not yet released)
|
||||||
sugar for [:*1..], and corresponds to the operator ⊕ introduced
|
sugar for [:*1..], and corresponds to the operator ⊕ introduced
|
||||||
by Dax et al. (ATVA'09).
|
by Dax et al. (ATVA'09).
|
||||||
|
|
||||||
- GraphViz output now uses an horizontal layout by default. The
|
- GraphViz output now uses an horizontal layout by default, and
|
||||||
--dot option of the various command-line tools takes an optional
|
also use circular states (unless the automaton has more than 100
|
||||||
parameter to fine-tune the GraphViz output (including vertical
|
states, or uses named-states). The --dot option of the various
|
||||||
layout, round states, named automata, SCC informations, ordered
|
command-line tools takes an optional parameter to fine-tune the
|
||||||
|
GraphViz output (including vertical layout, forced circular or
|
||||||
|
elliptic states, named automata, SCC information, ordered
|
||||||
transitions, and different ways to colorize the acceptance
|
transitions, and different ways to colorize the acceptance
|
||||||
sets). The environment variables SPOT_DOTDEFAULT and
|
sets). The environment variables SPOT_DOTDEFAULT and
|
||||||
SPOT_DOTEXTRA can also be used to respectively provide a default
|
SPOT_DOTEXTRA can also be used to respectively provide a default
|
||||||
|
|
|
||||||
|
|
@ -51,13 +51,14 @@ static const argp_option options[] =
|
||||||
{
|
{
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
{ 0, 0, 0, 0, "Output format:", 3 },
|
{ 0, 0, 0, 0, "Output format:", 3 },
|
||||||
{ "dot", OPT_DOT, "1|a|b|B|c|f(FONT)|h|n|N|o|r|R|s|t|v",
|
{ "dot", OPT_DOT, "1|a|b|B|c|e|f(FONT)|h|n|N|o|r|R|s|t|v",
|
||||||
OPTION_ARG_OPTIONAL,
|
OPTION_ARG_OPTIONAL,
|
||||||
"GraphViz's format (default). Add letters for "
|
"GraphViz's format (default). Add letters for "
|
||||||
"(1) force numbered states, "
|
"(1) force numbered states, "
|
||||||
"(a) acceptance display, (b) acceptance sets as bullets, "
|
"(a) acceptance display, (b) acceptance sets as bullets, "
|
||||||
"(B) bullets except for Büchi/co-Büchi automata, "
|
"(B) bullets except for Büchi/co-Büchi automata, "
|
||||||
"(c) circular nodes, (f(FONT)) use FONT, (h) horizontal layout, "
|
"(c) force circular nodes, (e) force elliptic nodes, "
|
||||||
|
"(f(FONT)) use FONT, (h) horizontal layout, "
|
||||||
"(v) vertical layout, (n) with name, (N) without name, "
|
"(v) vertical layout, (n) with name, (N) without name, "
|
||||||
"(o) ordered transitions, "
|
"(o) ordered transitions, "
|
||||||
"(r) rainbow colors for acceptance sets, "
|
"(r) rainbow colors for acceptance sets, "
|
||||||
|
|
|
||||||
|
|
@ -73,13 +73,14 @@ static const argp_option options[] =
|
||||||
"of the given property)", 0 },
|
"of the given property)", 0 },
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
{ 0, 0, 0, 0, "Output format:", 3 },
|
{ 0, 0, 0, 0, "Output format:", 3 },
|
||||||
{ "dot", OPT_DOT, "1|a|b|B|c|f(FONT)|h|n|N|o|r|R|s|t|v",
|
{ "dot", OPT_DOT, "1|a|b|B|c|e|f(FONT)|h|n|N|o|r|R|s|t|v",
|
||||||
OPTION_ARG_OPTIONAL,
|
OPTION_ARG_OPTIONAL,
|
||||||
"GraphViz's format (default). Add letters for "
|
"GraphViz's format (default). Add letters for "
|
||||||
"(1) force numbered states, "
|
"(1) force numbered states, "
|
||||||
"(a) acceptance display, (b) acceptance sets as bullets, "
|
"(a) acceptance display, (b) acceptance sets as bullets, "
|
||||||
"(B) bullets except for Büchi automata, "
|
"(B) bullets except for Büchi/co-Büchi automata, "
|
||||||
"(c) circular nodes, (f(FONT)) use FONT, (h) horizontal layout, "
|
"(c) force circular nodes, (e) force elliptic nodes, "
|
||||||
|
"(f(FONT)) use FONT, (h) horizontal layout, "
|
||||||
"(v) vertical layout, (n) with name, (N) without name, "
|
"(v) vertical layout, (n) with name, (N) without name, "
|
||||||
"(o) ordered transitions, "
|
"(o) ordered transitions, "
|
||||||
"(r) rainbow colors for acceptance sets, "
|
"(r) rainbow colors for acceptance sets, "
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ namespace spot
|
||||||
case 'a':
|
case 'a':
|
||||||
case 'b':
|
case 'b':
|
||||||
case 'B':
|
case 'B':
|
||||||
|
case 'e':
|
||||||
case 'n':
|
case 'n':
|
||||||
case 'N':
|
case 'N':
|
||||||
case 'o':
|
case 'o':
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,7 @@ run 0 ../ltl2tgba -x -DC 'GFa & XGFb' > out.tgba
|
||||||
cat >ex.tgba <<EOF
|
cat >ex.tgba <<EOF
|
||||||
digraph G {
|
digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
I -> 0
|
I -> 0
|
||||||
0 [label="0"]
|
0 [label="0"]
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ run 0 ../ltl2tgba -XD dra.dstar | tee stdout
|
||||||
cat >expected <<EOF
|
cat >expected <<EOF
|
||||||
digraph G {
|
digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
I -> 0
|
I -> 0
|
||||||
0 [label="0"]
|
0 [label="0"]
|
||||||
|
|
@ -82,6 +83,7 @@ run 0 ../ltl2tgba -XDD dra.dstar | tee stdout
|
||||||
cat >expected <<EOF
|
cat >expected <<EOF
|
||||||
digraph G {
|
digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
I -> 0
|
I -> 0
|
||||||
0 [label="0"]
|
0 [label="0"]
|
||||||
|
|
@ -126,6 +128,7 @@ run 0 ../ltl2tgba -XDB dsa.dstar | tee stdout
|
||||||
cat >expected <<EOF
|
cat >expected <<EOF
|
||||||
digraph G {
|
digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
I -> 0
|
I -> 0
|
||||||
0 [label="0"]
|
0 [label="0"]
|
||||||
|
|
@ -215,6 +218,7 @@ run 0 ../ltl2tgba -XDD dra.dstar | tee stdout
|
||||||
cat >expected <<EOF
|
cat >expected <<EOF
|
||||||
digraph G {
|
digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
I -> 0
|
I -> 0
|
||||||
0 [label="0"]
|
0 [label="0"]
|
||||||
|
|
@ -264,6 +268,7 @@ digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
label="aut.dsa"
|
label="aut.dsa"
|
||||||
labelloc="t"
|
labelloc="t"
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
I -> 0
|
I -> 0
|
||||||
0 [label="0"]
|
0 [label="0"]
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ expect()
|
||||||
expect ../../bin/ltl2tgba --monitor a <<EOF
|
expect ../../bin/ltl2tgba --monitor a <<EOF
|
||||||
digraph G {
|
digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
I -> 1
|
I -> 1
|
||||||
0 [label="0"]
|
0 [label="0"]
|
||||||
|
|
|
||||||
|
|
@ -134,6 +134,7 @@ run 0 ../ltl2tgba -XN input > stdout
|
||||||
cat >expected <<EOF
|
cat >expected <<EOF
|
||||||
digraph G {
|
digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
I -> 0
|
I -> 0
|
||||||
0 [label="0", peripheries=2]
|
0 [label="0", peripheries=2]
|
||||||
|
|
|
||||||
|
|
@ -349,6 +349,7 @@ digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
label="Inf(0)&Inf(1)"
|
label="Inf(0)&Inf(1)"
|
||||||
labelloc="t"
|
labelloc="t"
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
I -> 0
|
I -> 0
|
||||||
0 [label="0"]
|
0 [label="0"]
|
||||||
|
|
@ -367,6 +368,7 @@ digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
label="G(Fa & Fb)\nInf(⓿)&Inf(❶)"
|
label="G(Fa & Fb)\nInf(⓿)&Inf(❶)"
|
||||||
labelloc="t"
|
labelloc="t"
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
I -> 0
|
I -> 0
|
||||||
0 [label="0"]
|
0 [label="0"]
|
||||||
|
|
@ -379,7 +381,7 @@ EOF
|
||||||
diff output expected
|
diff output expected
|
||||||
|
|
||||||
|
|
||||||
SPOT_DOTDEFAULT=bra $ltl2tgba --dot='c.f(Lato)' 'GFa & GFb' >output
|
SPOT_DOTDEFAULT=bra $ltl2tgba --dot='e.f(Lato)' 'GFa & GFb' >output
|
||||||
cat output
|
cat output
|
||||||
|
|
||||||
zero='<font color="#5DA5DA">⓿</font>'
|
zero='<font color="#5DA5DA">⓿</font>'
|
||||||
|
|
@ -389,7 +391,6 @@ digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
label=<Inf($zero)&Inf($one)>
|
label=<Inf($zero)&Inf($one)>
|
||||||
labelloc="t"
|
labelloc="t"
|
||||||
node [shape="circle"]
|
|
||||||
fontname="Lato"
|
fontname="Lato"
|
||||||
node [fontname="Lato"]
|
node [fontname="Lato"]
|
||||||
edge [fontname="Lato"]
|
edge [fontname="Lato"]
|
||||||
|
|
@ -515,6 +516,7 @@ digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
label="Fin(⓿) | (Fin(❶) & Inf(❷)) | Fin(❸)"
|
label="Fin(⓿) | (Fin(❶) & Inf(❷)) | Fin(❸)"
|
||||||
labelloc="t"
|
labelloc="t"
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
0 [label="0"]
|
0 [label="0"]
|
||||||
1 [label="1\n⓿❸"]
|
1 [label="1\n⓿❸"]
|
||||||
|
|
@ -529,7 +531,8 @@ digraph G {
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# This should remove the state names
|
# This should remove the state names, and automatically use circled
|
||||||
|
# states.
|
||||||
$autfilt --dot=bao1 in | grep -v '>' >out
|
$autfilt --dot=bao1 in | grep -v '>' >out
|
||||||
diff out expected2
|
diff out expected2
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
label="Fin(2) & (Inf(0)&Inf(1))"
|
label="Fin(2) & (Inf(0)&Inf(1))"
|
||||||
labelloc="t"
|
labelloc="t"
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
I -> 1
|
I -> 1
|
||||||
subgraph cluster_0 {
|
subgraph cluster_0 {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright (C) 2014 Laboratoire de Recherche et Développement de
|
# Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement
|
||||||
# l'Epita (LRDE).
|
# de l'Epita (LRDE).
|
||||||
#
|
#
|
||||||
# This file is part of Spot, a model checking library.
|
# This file is part of Spot, a model checking library.
|
||||||
#
|
#
|
||||||
|
|
@ -35,6 +35,7 @@ run 0 ../tgbagraph | tee stdout
|
||||||
cat >expected <<EOF
|
cat >expected <<EOF
|
||||||
digraph G {
|
digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
I -> 0
|
I -> 0
|
||||||
0 [label="0"]
|
0 [label="0"]
|
||||||
|
|
@ -50,6 +51,7 @@ digraph G {
|
||||||
}
|
}
|
||||||
digraph G {
|
digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
I -> 0
|
I -> 0
|
||||||
0 [label="0"]
|
0 [label="0"]
|
||||||
|
|
@ -63,6 +65,7 @@ digraph G {
|
||||||
}
|
}
|
||||||
digraph G {
|
digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
I -> 0
|
I -> 0
|
||||||
0 [label="0"]
|
0 [label="0"]
|
||||||
|
|
@ -75,6 +78,7 @@ digraph G {
|
||||||
}
|
}
|
||||||
digraph G {
|
digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
I -> 0
|
I -> 0
|
||||||
0 [label="0"]
|
0 [label="0"]
|
||||||
|
|
@ -90,6 +94,7 @@ digraph G {
|
||||||
}
|
}
|
||||||
digraph G {
|
digraph G {
|
||||||
rankdir=LR
|
rankdir=LR
|
||||||
|
node [shape="circle"]
|
||||||
I [label="", style=invis, width=0]
|
I [label="", style=invis, width=0]
|
||||||
I -> 0
|
I -> 0
|
||||||
0 [label="0"]
|
0 [label="0"]
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,8 @@ namespace spot
|
||||||
bool opt_force_acc_trans_ = false;
|
bool opt_force_acc_trans_ = false;
|
||||||
bool opt_horizontal_ = true;
|
bool opt_horizontal_ = true;
|
||||||
bool opt_name_ = false;
|
bool opt_name_ = false;
|
||||||
bool opt_circles_ = false;
|
enum { ShapeAuto = 0, ShapeCircle, ShapeEllipse }
|
||||||
|
opt_shape_ = ShapeAuto;
|
||||||
bool opt_show_acc_ = false;
|
bool opt_show_acc_ = false;
|
||||||
bool mark_states_ = false;
|
bool mark_states_ = false;
|
||||||
bool opt_scc_ = false;
|
bool opt_scc_ = false;
|
||||||
|
|
@ -123,10 +124,10 @@ namespace spot
|
||||||
opt_bullet_but_buchi = true;
|
opt_bullet_but_buchi = true;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
opt_circles_ = true;
|
opt_shape_ = ShapeCircle;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'e':
|
||||||
opt_horizontal_ = true;
|
opt_shape_ = ShapeEllipse;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
if (*options != '(')
|
if (*options != '(')
|
||||||
|
|
@ -141,6 +142,9 @@ namespace spot
|
||||||
options = end + 1;
|
options = end + 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'h':
|
||||||
|
opt_horizontal_ = true;
|
||||||
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
opt_name_ = true;
|
opt_name_ = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -275,7 +279,6 @@ namespace spot
|
||||||
aut_->get_acceptance().used_inf_fin_sets();
|
aut_->get_acceptance().used_inf_fin_sets();
|
||||||
if (opt_bullet && aut_->acc().num_sets() <= MAX_BULLET)
|
if (opt_bullet && aut_->acc().num_sets() <= MAX_BULLET)
|
||||||
opt_all_bullets = true;
|
opt_all_bullets = true;
|
||||||
|
|
||||||
os_ << "digraph G {\n";
|
os_ << "digraph G {\n";
|
||||||
if (opt_horizontal_)
|
if (opt_horizontal_)
|
||||||
os_ << " rankdir=LR\n";
|
os_ << " rankdir=LR\n";
|
||||||
|
|
@ -317,8 +320,18 @@ namespace spot
|
||||||
}
|
}
|
||||||
os_ << " labelloc=\"t\"\n";
|
os_ << " labelloc=\"t\"\n";
|
||||||
}
|
}
|
||||||
if (opt_circles_)
|
switch (opt_shape_)
|
||||||
os_ << " node [shape=\"circle\"]\n";
|
{
|
||||||
|
case ShapeCircle:
|
||||||
|
os_ << " node [shape=\"circle\"]\n";
|
||||||
|
break;
|
||||||
|
case ShapeEllipse:
|
||||||
|
// Do not print anything. Ellipse is
|
||||||
|
// the default shape used by GraphViz.
|
||||||
|
break;
|
||||||
|
case ShapeAuto:
|
||||||
|
SPOT_UNREACHABLE();
|
||||||
|
}
|
||||||
if (!opt_font_.empty())
|
if (!opt_font_.empty())
|
||||||
os_ << " fontname=\"" << opt_font_
|
os_ << " fontname=\"" << opt_font_
|
||||||
<< "\"\n node [fontname=\"" << opt_font_
|
<< "\"\n node [fontname=\"" << opt_font_
|
||||||
|
|
@ -452,8 +465,16 @@ namespace spot
|
||||||
if (opt_name_)
|
if (opt_name_)
|
||||||
name_ = aut_->get_named_prop<std::string>("automaton-name");
|
name_ = aut_->get_named_prop<std::string>("automaton-name");
|
||||||
mark_states_ = !opt_force_acc_trans_ && aut_->has_state_based_acc();
|
mark_states_ = !opt_force_acc_trans_ && aut_->has_state_based_acc();
|
||||||
|
if (opt_shape_ == ShapeAuto)
|
||||||
|
{
|
||||||
|
if (sn_ || aut->num_states() > 100)
|
||||||
|
opt_shape_ = ShapeEllipse;
|
||||||
|
else
|
||||||
|
opt_shape_ = ShapeCircle;
|
||||||
|
}
|
||||||
auto si =
|
auto si =
|
||||||
std::unique_ptr<scc_info>(opt_scc_ ? new scc_info(aut) : nullptr);
|
std::unique_ptr<scc_info>(opt_scc_ ? new scc_info(aut) : nullptr);
|
||||||
|
|
||||||
start();
|
start();
|
||||||
if (si)
|
if (si)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ def setup(**kwargs):
|
||||||
kwargs.get('fillcolor', '#ffffaa'))
|
kwargs.get('fillcolor', '#ffffaa'))
|
||||||
|
|
||||||
bullets = 'B' if kwargs.get('bullets', True) else ''
|
bullets = 'B' if kwargs.get('bullets', True) else ''
|
||||||
d = 'rcf({})'.format(kwargs.get('font', 'Lato')) + bullets
|
d = 'rf({})'.format(kwargs.get('font', 'Lato')) + bullets
|
||||||
os.environ['SPOT_DOTDEFAULT'] = d
|
os.environ['SPOT_DOTDEFAULT'] = d
|
||||||
|
|
||||||
# Global BDD dict so that we do not have to create one in user code.
|
# Global BDD dict so that we do not have to create one in user code.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue