stats: fix slow %s and inappropriate %S output

Fixes #269.

* spot/twaalgos/stats.cc: Use twa_statistics instead of
twa_sub_statistics when %t is not used.
* bin/common_aoutput.cc: Likewise, also fix %S to use twa_statistics
instead of num_states(), and document that %s,%t,%e all return
statistics about the reachable part of the automaton.
* tests/core/format.test: Add more tests.
* NEWS: Document the issue.
This commit is contained in:
Alexandre Duret-Lutz 2017-06-19 17:06:56 +02:00
parent 97e903b13d
commit 20a4959ff6
4 changed files with 81 additions and 11 deletions

6
NEWS
View file

@ -11,6 +11,12 @@ New in spot 2.3.4.dev (not yet released)
SCC) or 'y' (split universal destination by colors) universal SCC) or 'y' (split universal destination by colors) universal
edges could be connected to undefined states. edges could be connected to undefined states.
- Using --stats=%s or --stats=%s or --stats=%t could take an
unnecessary long time on automata with many atomic propositions,
due to a typo. Furthermore, %s/%e/%t/%E/%T were printing
a number of reachable states/edges/transitions, but %S was
incorrectly counting all states even unreachable.
New in spot 2.3.4 (2017-05-11) New in spot 2.3.4 (2017-05-11)
Bugs fixed: Bugs fixed:

View file

@ -166,11 +166,11 @@ static const argp_option io_options[] =
{ "%M, %m", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, { "%M, %m", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"name of the automaton", 0 }, "name of the automaton", 0 },
{ "%S, %s", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, { "%S, %s", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of states", 0 }, "number of reachable states", 0 },
{ "%E, %e", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, { "%E, %e", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of edges", 0 }, "number of reachable edges", 0 },
{ "%T, %t", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, { "%T, %t", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of transitions", 0 }, "number of reachable transitions", 0 },
{ "%A, %a", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, { "%A, %a", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of acceptance sets", 0 }, "number of acceptance sets", 0 },
{ "%G, %g", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, { "%G, %g", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
@ -227,11 +227,11 @@ static const argp_option o_options[] =
{ "%m", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, { "%m", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"name of the automaton", 0 }, "name of the automaton", 0 },
{ "%s", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, { "%s", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of states", 0 }, "number of reachable states", 0 },
{ "%e", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, { "%e", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of edges", 0 }, "number of reachable edges", 0 },
{ "%t", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, { "%t", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of transitions", 0 }, "number of reachable transitions", 0 },
{ "%a", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, { "%a", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
"number of acceptance sets", 0 }, "number of acceptance sets", 0 },
{ "%g", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, { "%g", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
@ -422,9 +422,9 @@ hoa_stat_printer::print(const spot::const_parsed_aut_ptr& haut,
haut_edges_ = s.edges; haut_edges_ = s.edges;
haut_trans_ = s.transitions; haut_trans_ = s.transitions;
} }
else if (has('E')) else if (has('E') || has('S'))
{ {
spot::twa_sub_statistics s = sub_stats_reachable(haut->aut); spot::twa_statistics s = stats_reachable(haut->aut);
haut_states_ = s.states; haut_states_ = s.states;
haut_edges_ = s.edges; haut_edges_ = s.edges;
} }
@ -436,8 +436,6 @@ hoa_stat_printer::print(const spot::const_parsed_aut_ptr& haut,
else else
haut_name_.val().clear(); haut_name_.val().clear();
} }
if (has('S'))
haut_states_ = haut->aut->num_states();
if (has('A')) if (has('A'))
haut_acc_ = haut->aut->acc().num_sets(); haut_acc_ = haut->aut->acc().num_sets();

View file

@ -346,7 +346,7 @@ namespace spot
} }
else if (has('s') || has('e')) else if (has('s') || has('e'))
{ {
twa_sub_statistics s = sub_stats_reachable(aut); twa_statistics s = stats_reachable(aut);
states_ = s.states; states_ = s.states;
edges_ = s.edges; edges_ = s.edges;
} }

View file

@ -74,3 +74,69 @@ test "1,3,1,3,2,1,0" = "$out"
ltl2tgba 'a' --stats='%[z]c' 2>stderr && exit 1 ltl2tgba 'a' --stats='%[z]c' 2>stderr && exit 1
cat stderr cat stderr
grep -F "ltl2tgba: unknown option 'z' in '%[z]c'" stderr grep -F "ltl2tgba: unknown option 'z' in '%[z]c'" stderr
# From issue #269.
f='!X(FG((a & b) | (a & c) | (a & d) | (a & e) | (a & f) | (g & h) |
(g & i) | (g & j) | (g & k) | (g & l) | (m & n) | (m & o) | (m & p) |
(m & q) | (m & r) | (s & t) | (s & u) | (s & v) | (s & w) | (s & x) |
(y & z) | (ab & y) | (bb & y) | (cb & y) | (db & y) | (eb & g) | (c &
eb) | (d & eb) | (e & eb) | (eb & f) | (b & m) | (b & i) | (b & j) |
(b & k) | (b & l) | (h & s) | (h & o) | (h & p) | (h & q) | (h & r) |
(n & y) | (n & u) | (n & v) | (n & w) | (n & x) | (fb & t) | (ab & t)
| (bb & t) | (cb & t) | (db & t) | (g & gb) | (b & gb) | (d & gb) |
(e & gb) | (f & gb) | (c & m) | (c & h) | (c & j) | (c & k) | (c & l) |
(i & s) | (i & n) | (i & p) | (i & q) | (i & r) | (o & y) | (o & t) |
(o & v) | (o & w) | (o & x) | (fb & u) | (u & z) | (bb & u) | (cb &
u) | (db & u) | (g & hb) | (b & hb) | (c & hb) | (e & hb) | (f & hb) |
(d & m) | (d & h) | (d & i) | (d & k) | (d & l) | (j & s) | (j & n) |
(j & o) | (j & q) | (j & r) | (p & y) | (p & t) | (p & u) | (p & w) |
(p & x) | (fb & v) | (v & z) | (ab & v) | (cb & v) | (db & v) | (g &
ib) | (b & ib) | (c & ib) | (d & ib) | (f & ib) | (e & m) | (e & h) |
(e & i) | (e & j) | (e & l) | (k & s) | (k & n) | (k & o) | (k & p) |
(k & r) | (q & y) | (q & t) | (q & u) | (q & v) | (q & x) | (fb & w) |
(w & z) | (ab & w) | (bb & w) | (db & w) | (g & jb) | (b & jb) | (c &
jb) | (d & jb) | (e & jb) | (f & m) | (f & h) | (f & i) | (f & j) |
(f & k) | (l & s) | (l & n) | (l & o) | (l & p) | (l & q) | (r & y) |
(r & t) | (r & u) | (r & v) | (r & w) | (fb & x) | (x & z) | (ab & x) |
(bb & x) | (cb & x)) U ((a & b) | (a & c) | (a & d) | (a & e) | (a & f) |
(g & h) | (g & i) | (g & j) | (g & k) | (g & l) | (m & n) | (m & o) |
(m & p) | (m & q) | (m & r) | (s & t) | (s & u) | (s & v) | (s & w) |
(s & x) | (y & z) | (ab & y) | (bb & y) | (cb & y) | (db & y) | (eb &
g) | (c & eb) | (d & eb) | (e & eb) | (eb & f) | (b & m) | (b & i) |
(b & j) | (b & k) | (b & l) | (h & s) | (h & o) | (h & p) | (h & q) |
(h & r) | (n & y) | (n & u) | (n & v) | (n & w) | (n & x) | (fb & t) |
(ab & t) | (bb & t) | (cb & t) | (db & t) | (g & gb) | (b & gb) | (d &
gb) | (e & gb) | (f & gb) | (c & m) | (c & h) | (c & j) | (c & k) |
(c & l) | (i & s) | (i & n) | (i & p) | (i & q) | (i & r) | (o & y) |
(o & t) | (o & v) | (o & w) | (o & x) | (fb & u) | (u & z) | (bb & u)
| (cb & u) | (db & u) | (g & hb) | (b & hb) | (c & hb) | (e & hb) |
(f & hb) | (d & m) | (d & h) | (d & i) | (d & k) | (d & l) | (j & s) |
(j & n) | (j & o) | (j & q) | (j & r) | (p & y) | (p & t) | (p & u) |
(p & w) | (p & x) | (fb & v) | (v & z) | (ab & v) | (cb & v) | (db &
v) | (g & ib) | (b & ib) | (c & ib) | (d & ib) | (f & ib) | (e & m) |
(e & h) | (e & i) | (e & j) | (e & l) | (k & s) | (k & n) | (k & o) |
(k & p) | (k & r) | (q & y) | (q & t) | (q & u) | (q & v) | (q & x) |
(fb & w) | (w & z) | (ab & w) | (bb & w) | (db & w) | (g & jb) | (b &
jb) | (c & jb) | (d & jb) | (e & jb) | (f & m) | (f & h) | (f & i) |
(f & j) | (f & k) | (l & s) | (l & n) | (l & o) | (l & p) | (l & q) |
(r & y) | (r & t) | (r & u) | (r & v) | (r & w) | (fb & x) | (x & z) |
(ab & x) | (bb & x) | (cb & x)))'
test 3,5 = `ltl2tgba --low --any --stats=%s,%e "$f"`
cat >foo <<EOF
HOA: v1
States: 3
Start: 0
AP: 0
Acceptance: 0 t
--BODY--
State: 0
[t] 1
State: 1
[t] 0
State: 2
[t] 2
--END--
EOF
test 2,2 = `autfilt --stats=%S,%s foo`