dot: add x option for dot2tex
* spot/twa/acc.cc, spot/twa/acc.hh: Add a LaTeX output for acceptance conditions. * spot/twaalgos/dot.cc: Implement the 'x' option and refactor the code a bit to limit duplication. * tests/core/dot2tex.test: New test case (requires dot2tex). * tests/Makefile.am: Add dot2tex.test. * tests/core/alternating.test, tests/core/readsave.test, tests/python/automata-io.ipynb: Adjust expected output. * NEWS, doc/org/oaut.org: Mention the new option.
This commit is contained in:
parent
b242122ce8
commit
fbb9e4374e
10 changed files with 365 additions and 182 deletions
101
spot/twa/acc.cc
101
spot/twa/acc.cc
|
|
@ -63,20 +63,45 @@ namespace spot
|
|||
os << v;
|
||||
}
|
||||
|
||||
template<bool html>
|
||||
enum code_output {HTML, TEXT, LATEX};
|
||||
|
||||
template<enum code_output style>
|
||||
static void
|
||||
print_code(std::ostream& os,
|
||||
const acc_cond::acc_code& code, unsigned pos,
|
||||
std::function<void(std::ostream&, int)> set_printer)
|
||||
{
|
||||
const char* op = " | ";
|
||||
const char* op_ = style == LATEX ? " \\lor " : " | ";
|
||||
auto& w = code[pos];
|
||||
const char* negated = "";
|
||||
const char* negated_pre = "";
|
||||
const char* negated_post = "";
|
||||
auto set_neg = [&]() {
|
||||
if (style == LATEX)
|
||||
{
|
||||
negated_pre = "\\overline{";
|
||||
negated_post = "}";
|
||||
}
|
||||
else
|
||||
{
|
||||
negated_pre = "!";
|
||||
}
|
||||
};
|
||||
bool top = pos == code.size() - 1;
|
||||
switch (w.sub.op)
|
||||
{
|
||||
case acc_cond::acc_op::And:
|
||||
op = html ? " & " : " & ";
|
||||
switch (style)
|
||||
{
|
||||
case HTML:
|
||||
op_ = " & ";
|
||||
break;
|
||||
case TEXT:
|
||||
op_ = " & ";
|
||||
break;
|
||||
case LATEX:
|
||||
op_ = " \\land ";
|
||||
break;
|
||||
}
|
||||
SPOT_FALLTHROUGH;
|
||||
case acc_cond::acc_op::Or:
|
||||
{
|
||||
|
|
@ -90,8 +115,8 @@ namespace spot
|
|||
if (first)
|
||||
first = false;
|
||||
else
|
||||
os << op;
|
||||
print_code<html>(os, code, pos, set_printer);
|
||||
os << op_;
|
||||
print_code<style>(os, code, pos, set_printer);
|
||||
pos -= code[pos].sub.size;
|
||||
}
|
||||
if (!top)
|
||||
|
|
@ -99,14 +124,17 @@ namespace spot
|
|||
}
|
||||
break;
|
||||
case acc_cond::acc_op::InfNeg:
|
||||
negated = "!";
|
||||
set_neg();
|
||||
SPOT_FALLTHROUGH;
|
||||
case acc_cond::acc_op::Inf:
|
||||
{
|
||||
auto a = code[pos - 1].mark.id;
|
||||
if (a == 0U)
|
||||
{
|
||||
os << 't';
|
||||
if (style == LATEX)
|
||||
os << "\\mathsf{t}";
|
||||
else
|
||||
os << 't';
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -115,16 +143,32 @@ namespace spot
|
|||
top = code[pos - 1].mark.count() == 1;
|
||||
unsigned level = 0;
|
||||
const char* and_ = "";
|
||||
const char* and_next_ = []() {
|
||||
// The lack of surrounding space in HTML and
|
||||
// TEXT is on purpose: we want to
|
||||
// distinguish those grouped "Inf"s from
|
||||
// other terms that are ANDed together.
|
||||
switch (style)
|
||||
{
|
||||
case HTML:
|
||||
return "&";
|
||||
case TEXT:
|
||||
return "&";
|
||||
case LATEX:
|
||||
return " \\land ";
|
||||
}
|
||||
}();
|
||||
if (!top)
|
||||
os << '(';
|
||||
const char* inf_ = (style == LATEX) ? "\\mathsf{Inf}(" : "Inf(";
|
||||
while (a)
|
||||
{
|
||||
if (a & 1)
|
||||
{
|
||||
os << and_ << "Inf(" << negated;
|
||||
os << and_ << inf_ << negated_pre;
|
||||
set_printer(os, level);
|
||||
os << ')';
|
||||
and_ = html ? "&" : "&";
|
||||
os << negated_post << ')';
|
||||
and_ = and_next_;
|
||||
}
|
||||
a >>= 1;
|
||||
++level;
|
||||
|
|
@ -135,14 +179,17 @@ namespace spot
|
|||
}
|
||||
break;
|
||||
case acc_cond::acc_op::FinNeg:
|
||||
negated = "!";
|
||||
set_neg();
|
||||
SPOT_FALLTHROUGH;
|
||||
case acc_cond::acc_op::Fin:
|
||||
{
|
||||
auto a = code[pos - 1].mark.id;
|
||||
if (a == 0U)
|
||||
{
|
||||
os << 'f';
|
||||
if (style == LATEX)
|
||||
os << "\\mathsf{f}";
|
||||
else
|
||||
os << 'f';
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -153,14 +200,19 @@ namespace spot
|
|||
const char* or_ = "";
|
||||
if (!top)
|
||||
os << '(';
|
||||
const char* fin_ = (style == LATEX) ? "\\mathsf{Fin}(" : "Fin(";
|
||||
while (a)
|
||||
{
|
||||
if (a & 1)
|
||||
{
|
||||
os << or_ << "Fin(" << negated;
|
||||
os << or_ << fin_ << negated_pre;
|
||||
set_printer(os, level);
|
||||
os << ')';
|
||||
or_ = "|";
|
||||
os << negated_post << ')';
|
||||
// The lack of surrounding space in HTML and
|
||||
// TEXT is on purpose: we want to distinguish
|
||||
// those grouped "Fin"s from other terms that
|
||||
// are ORed together.
|
||||
or_ = style == LATEX ? " \\lor " : "|";
|
||||
}
|
||||
a >>= 1;
|
||||
++level;
|
||||
|
|
@ -1407,7 +1459,7 @@ namespace spot
|
|||
if (empty())
|
||||
os << 't';
|
||||
else
|
||||
print_code<true>(os, *this, size() - 1,
|
||||
print_code<HTML>(os, *this, size() - 1,
|
||||
set_printer ? set_printer : default_set_printer);
|
||||
return os;
|
||||
}
|
||||
|
|
@ -1420,7 +1472,20 @@ namespace spot
|
|||
if (empty())
|
||||
os << 't';
|
||||
else
|
||||
print_code<false>(os, *this, size() - 1,
|
||||
print_code<TEXT>(os, *this, size() - 1,
|
||||
set_printer ? set_printer : default_set_printer);
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
acc_cond::acc_code::to_latex(std::ostream& os,
|
||||
std::function<void(std::ostream&, int)>
|
||||
set_printer) const
|
||||
{
|
||||
if (empty())
|
||||
os << "\\mathsf{t}";
|
||||
else
|
||||
print_code<LATEX>(os, *this, size() - 1,
|
||||
set_printer ? set_printer : default_set_printer);
|
||||
return os;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -892,6 +892,13 @@ namespace spot
|
|||
std::function<void(std::ostream&, int)>
|
||||
set_printer = nullptr) const;
|
||||
|
||||
// Print the acceptance as Latex. The set_printer function can
|
||||
// be used to implement customized output for set numbers.
|
||||
std::ostream&
|
||||
to_latex(std::ostream& os,
|
||||
std::function<void(std::ostream&, int)>
|
||||
set_printer = nullptr) const;
|
||||
|
||||
|
||||
/// \brief Construct an acc_code from a string.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <spot/tl/print.hh>
|
||||
#include <spot/twa/twagraph.hh>
|
||||
#include <spot/twaalgos/dot.hh>
|
||||
#include <spot/twa/bddprint.hh>
|
||||
|
|
@ -100,6 +101,10 @@ namespace spot
|
|||
bool opt_numbered_edges_ = false;
|
||||
bool opt_orig_show_ = false;
|
||||
bool max_states_given_ = false; // related to max_states_
|
||||
bool opt_latex_ = false;
|
||||
const char* nl_ = "\\n";
|
||||
const char* label_pre_ = "label=\"";
|
||||
char label_post_ = '"';
|
||||
|
||||
const_twa_graph_ptr aut_;
|
||||
std::string opt_font_;
|
||||
|
|
@ -265,6 +270,9 @@ namespace spot
|
|||
case 't':
|
||||
opt_force_acc_trans_ = true;
|
||||
break;
|
||||
case 'x':
|
||||
opt_latex_ = true;
|
||||
break;
|
||||
case 'y':
|
||||
opt_shared_univ_dest_ = false;
|
||||
break;
|
||||
|
|
@ -272,6 +280,23 @@ namespace spot
|
|||
throw std::runtime_error
|
||||
(std::string("unknown option for print_dot(): ") + c);
|
||||
}
|
||||
if (opt_html_labels_)
|
||||
{
|
||||
nl_ = "<br/>";
|
||||
label_pre_ = "label=<";
|
||||
label_post_ = '>';
|
||||
}
|
||||
if (opt_latex_)
|
||||
{
|
||||
if (opt_latex_ && opt_html_labels_)
|
||||
throw std::runtime_error
|
||||
(std::string("print_dot(): options 'r' and 'R' "
|
||||
"are incompatible with 'x'"));
|
||||
nl_ = "\\\\{}";
|
||||
label_pre_ = "texlbl=\"";
|
||||
label_post_ = '"';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dotty_output(std::ostream& os, const char* options)
|
||||
|
|
@ -306,7 +331,12 @@ namespace spot
|
|||
output_set(acc_cond::mark_t a) const
|
||||
{
|
||||
if (!opt_all_bullets)
|
||||
os_ << '{';
|
||||
{
|
||||
if (opt_latex_)
|
||||
os_ << "\\{";
|
||||
else
|
||||
os_ << '{';
|
||||
}
|
||||
const char* space = "";
|
||||
for (auto v: a.sets())
|
||||
{
|
||||
|
|
@ -316,7 +346,12 @@ namespace spot
|
|||
space = ",";
|
||||
}
|
||||
if (!opt_all_bullets)
|
||||
os_ << '}';
|
||||
{
|
||||
if (opt_latex_)
|
||||
os_ << "\\}";
|
||||
else
|
||||
os_ << '}';
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
|
|
@ -369,8 +404,30 @@ namespace spot
|
|||
os_ << '}';
|
||||
}
|
||||
|
||||
std::string
|
||||
state_label(unsigned s) const
|
||||
std::ostream&
|
||||
escape_for_output(std::ostream& os, const std::string& s) const
|
||||
{
|
||||
if (opt_html_labels_)
|
||||
return escape_html(os, s);
|
||||
if (opt_latex_)
|
||||
return escape_latex(os, s);
|
||||
return escape_str(os, s);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
format_label(std::ostream& os, bdd label) const
|
||||
{
|
||||
formula f = bdd_to_formula(label, aut_->get_dict());
|
||||
if (opt_latex_)
|
||||
{
|
||||
print_sclatex_psl(os << '$', f) << '$';
|
||||
return os;
|
||||
}
|
||||
return escape_for_output(os, str_psl(f));
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
format_state_label(std::ostream& os, unsigned s) const
|
||||
{
|
||||
bdd label = bddfalse;
|
||||
for (auto& t: aut_->out(s))
|
||||
|
|
@ -380,8 +437,8 @@ namespace spot
|
|||
}
|
||||
if (label == bddfalse
|
||||
&& incomplete_ && incomplete_->find(s) != incomplete_->end())
|
||||
return "...";
|
||||
return bdd_format_formula(aut_->get_dict(), label);
|
||||
return os << "...";
|
||||
return format_label(os, label);
|
||||
}
|
||||
|
||||
std::string string_dst(int dst, int color_num = -1)
|
||||
|
|
@ -420,26 +477,27 @@ namespace spot
|
|||
}
|
||||
}
|
||||
|
||||
void print_acceptance_for_human()
|
||||
std::string get_acceptance_for_human()
|
||||
{
|
||||
const char* nl = opt_html_labels_ ? "<br/>" : "\\n";
|
||||
std::ostringstream os;
|
||||
|
||||
if (aut_->acc().is_generalized_buchi())
|
||||
{
|
||||
if (aut_->acc().is_all())
|
||||
os_ << nl << "[all]";
|
||||
os << "all";
|
||||
else if (aut_->acc().is_buchi())
|
||||
os_ << nl << "[Büchi]";
|
||||
os << "Büchi";
|
||||
else
|
||||
os_ << nl << "[gen. Büchi " << aut_->num_sets() << ']';
|
||||
os << "gen. Büchi " << aut_->num_sets();
|
||||
}
|
||||
else if (aut_->acc().is_generalized_co_buchi())
|
||||
{
|
||||
if (aut_->acc().is_none())
|
||||
os_ << nl << "[none]";
|
||||
os << "none";
|
||||
else if (aut_->acc().is_co_buchi())
|
||||
os_ << nl << "[co-Büchi]";
|
||||
os << "co-Büchi";
|
||||
else
|
||||
os_ << nl << "[gen. co-Büchi " << aut_->num_sets() << ']';
|
||||
os << "gen. co-Büchi " << aut_->num_sets();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -447,7 +505,7 @@ namespace spot
|
|||
assert(r != 0);
|
||||
if (r > 0)
|
||||
{
|
||||
os_ << nl << "[Rabin " << r << ']';
|
||||
os << "Rabin " << r;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -455,14 +513,14 @@ namespace spot
|
|||
assert(r != 0);
|
||||
if (r > 0)
|
||||
{
|
||||
os_ << nl << "[Streett " << r << ']';
|
||||
os << "Streett " << r;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<unsigned> pairs;
|
||||
if (aut_->acc().is_generalized_rabin(pairs))
|
||||
{
|
||||
os_ << nl << "[gen. Rabin " << pairs.size() << ']';
|
||||
os << "gen. Rabin " << pairs.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -470,10 +528,10 @@ namespace spot
|
|||
bool odd = false;
|
||||
if (aut_->acc().is_parity(max, odd))
|
||||
{
|
||||
os_ << nl << "[parity "
|
||||
<< (max ? "max " : "min ")
|
||||
<< (odd ? "odd " : "even ")
|
||||
<< aut_->num_sets() << ']';
|
||||
os << "parity "
|
||||
<< (max ? "max " : "min ")
|
||||
<< (odd ? "odd " : "even ")
|
||||
<< aut_->num_sets();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -484,14 +542,23 @@ namespace spot
|
|||
bool s_like = aut_->acc().is_streett_like(s_pairs);
|
||||
unsigned ssz = s_pairs.size();
|
||||
if (r_like && (!s_like || (rsz <= ssz)))
|
||||
os_ << nl << "[Rabin-like " << rsz << ']';
|
||||
else if (s_like && (!r_like || (ssz < rsz)))
|
||||
os_ << nl << "[Streett-like " << ssz << ']';
|
||||
os << "Rabin-like " << rsz;
|
||||
else if (s_like && (!r_like || (ssz < rsz)))
|
||||
os << "Streett-like " << ssz;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
void print_acceptance_for_human()
|
||||
{
|
||||
std::string accstr = get_acceptance_for_human();
|
||||
if (accstr.empty())
|
||||
return;
|
||||
os_ << nl_ << '[' << accstr << ']';
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -503,56 +570,39 @@ namespace spot
|
|||
if (opt_bullet && aut_->num_sets() <= MAX_BULLET)
|
||||
opt_all_bullets = true;
|
||||
os_ << "digraph G {\n";
|
||||
if (opt_latex_)
|
||||
os_ << " d2tgraphstyle=\"every node/.style={align=center}\"\n";
|
||||
if (!opt_vertical_)
|
||||
os_ << " rankdir=LR\n";
|
||||
if (name_ || opt_show_acc_)
|
||||
{
|
||||
if (!opt_html_labels_)
|
||||
os_ << " " << label_pre_;
|
||||
if (name_)
|
||||
escape_for_output(os_, *name_);
|
||||
if (opt_show_acc_)
|
||||
{
|
||||
os_ << " label=\"";
|
||||
if (name_)
|
||||
if (!dcircles_)
|
||||
{
|
||||
escape_str(os_, *name_);
|
||||
if (opt_show_acc_)
|
||||
os_ << "\\n";
|
||||
if (name_)
|
||||
os_ << nl_;
|
||||
auto& acc = aut_->get_acceptance();
|
||||
if (opt_html_labels_)
|
||||
acc.to_html(os_, [this](std::ostream& os, int v)
|
||||
{
|
||||
this->output_html_set_aux(os, v);
|
||||
});
|
||||
else if (opt_latex_)
|
||||
acc.to_latex(os_ << '$') << '$';
|
||||
else
|
||||
acc.to_text(os_, [this](std::ostream& os, int v)
|
||||
{
|
||||
this->output_set(os, v);
|
||||
});
|
||||
|
||||
}
|
||||
if (opt_show_acc_)
|
||||
{
|
||||
if (!dcircles_)
|
||||
{
|
||||
aut_->get_acceptance().to_text
|
||||
(os_, [this](std::ostream& os, int v)
|
||||
{
|
||||
this->output_set(os, v);
|
||||
});
|
||||
}
|
||||
print_acceptance_for_human();
|
||||
}
|
||||
os_ << "\"\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
os_ << " label=<";
|
||||
if (name_)
|
||||
{
|
||||
escape_html(os_, *name_);
|
||||
if (opt_show_acc_)
|
||||
os_ << "<br/>";
|
||||
}
|
||||
if (opt_show_acc_)
|
||||
{
|
||||
if (!dcircles_)
|
||||
{
|
||||
aut_->get_acceptance().to_html
|
||||
(os_, [this](std::ostream& os, int v)
|
||||
{
|
||||
this->output_html_set_aux(os, v);
|
||||
});
|
||||
}
|
||||
print_acceptance_for_human();
|
||||
}
|
||||
os_ << ">\n";
|
||||
print_acceptance_for_human();
|
||||
}
|
||||
os_ << label_post_ << '\n';
|
||||
os_ << " labelloc=\"t\"\n";
|
||||
}
|
||||
switch (opt_shape_)
|
||||
|
|
@ -607,6 +657,16 @@ namespace spot
|
|||
void
|
||||
process_state(unsigned s)
|
||||
{
|
||||
os_ << " " << s << " [" << label_pre_;
|
||||
if (sn_ && s < sn_->size() && !(*sn_)[s].empty())
|
||||
escape_for_output(os_, (*sn_)[s]);
|
||||
else if (sprod_)
|
||||
os_ << (*sprod_)[s].first << ',' << (*sprod_)[s].second;
|
||||
else
|
||||
os_ << s;
|
||||
if (orig_ && s < orig_->size())
|
||||
os_ << " (" << (*orig_)[s] << ')';
|
||||
|
||||
if (mark_states_ && !dcircles_)
|
||||
{
|
||||
acc_cond::mark_t acc = 0U;
|
||||
|
|
@ -616,64 +676,23 @@ namespace spot
|
|||
break;
|
||||
}
|
||||
|
||||
bool has_name = sn_ && s < sn_->size() && !(*sn_)[s].empty();
|
||||
|
||||
os_ << " " << s << " [label=";
|
||||
if (!opt_html_labels_)
|
||||
if (acc)
|
||||
{
|
||||
os_ << '"';
|
||||
if (has_name)
|
||||
escape_str(os_, (*sn_)[s]);
|
||||
else if (sprod_)
|
||||
os_ << (*sprod_)[s].first << ',' << (*sprod_)[s].second;
|
||||
os_ << nl_;
|
||||
if (opt_html_labels_)
|
||||
output_html_set(acc);
|
||||
else
|
||||
os_ << s;
|
||||
if (orig_ && s < orig_->size())
|
||||
os_ << " (" << (*orig_)[s] << ')';
|
||||
if (acc)
|
||||
{
|
||||
os_ << "\\n";
|
||||
output_set(acc);
|
||||
}
|
||||
if (opt_state_labels_)
|
||||
escape_str(os_ << "\\n", state_label(s));
|
||||
os_ << '"';
|
||||
}
|
||||
else
|
||||
{
|
||||
os_ << '<';
|
||||
if (has_name)
|
||||
escape_html(os_, (*sn_)[s]);
|
||||
else if (sprod_)
|
||||
os_ << (*sprod_)[s].first << ',' << (*sprod_)[s].second;
|
||||
else
|
||||
os_ << s;
|
||||
if (orig_ && s < orig_->size())
|
||||
os_ << " (" << (*orig_)[s] << ')';
|
||||
if (acc)
|
||||
{
|
||||
os_ << "<br/>";
|
||||
output_html_set(acc);
|
||||
}
|
||||
if (opt_state_labels_)
|
||||
escape_html(os_ << "<br/>", state_label(s));
|
||||
os_ << '>';
|
||||
output_set(acc);
|
||||
}
|
||||
if (opt_state_labels_)
|
||||
format_state_label(os_ << nl_, s);
|
||||
os_ << label_post_;
|
||||
}
|
||||
else
|
||||
{
|
||||
os_ << " " << s << " [label=\"";
|
||||
if (sn_ && s < sn_->size() && !(*sn_)[s].empty())
|
||||
escape_str(os_, (*sn_)[s]);
|
||||
else if (sprod_)
|
||||
os_ << (*sprod_)[s].first << ',' << (*sprod_)[s].second;
|
||||
else
|
||||
os_ << s;
|
||||
if (orig_ && s < orig_->size())
|
||||
os_ << " (" << (*orig_)[s] << ')';
|
||||
if (opt_state_labels_)
|
||||
escape_str(os_ << "\\n", state_label(s));
|
||||
os_ << '"';
|
||||
format_state_label(os_ << nl_, s);
|
||||
os_ << label_post_;
|
||||
// Use state_acc_sets(), not state_is_accepting() because
|
||||
// on co-Büchi automata we want to mark the rejecting
|
||||
// states.
|
||||
|
|
@ -713,35 +732,20 @@ namespace spot
|
|||
if (iter != highlight_edges_->end())
|
||||
os_ << '.' << iter->second % palette_mod;
|
||||
}
|
||||
std::string label;
|
||||
os_ << " [" << label_pre_;
|
||||
if (!opt_state_labels_)
|
||||
label = bdd_format_formula(aut_->get_dict(), t.cond);
|
||||
if (!opt_html_labels_)
|
||||
{
|
||||
os_ << " [label=\"";
|
||||
escape_str(os_, label);
|
||||
if (!mark_states_)
|
||||
if (auto a = t.acc)
|
||||
{
|
||||
if (!opt_state_labels_)
|
||||
os_ << "\\n";
|
||||
output_set(a);
|
||||
}
|
||||
os_ << '"';
|
||||
}
|
||||
else
|
||||
{
|
||||
os_ << " [label=<";
|
||||
escape_html(os_, label);
|
||||
if (!mark_states_)
|
||||
if (auto a = t.acc)
|
||||
{
|
||||
if (!opt_state_labels_)
|
||||
os_ << "<br/>";
|
||||
output_html_set(a);
|
||||
}
|
||||
os_ << '>';
|
||||
}
|
||||
format_label(os_, t.cond);
|
||||
if (!mark_states_)
|
||||
if (auto a = t.acc)
|
||||
{
|
||||
if (!opt_state_labels_)
|
||||
os_ << nl_;
|
||||
if (opt_html_labels_)
|
||||
output_html_set(a);
|
||||
else
|
||||
output_set(a);
|
||||
}
|
||||
os_ << label_post_;
|
||||
if (opt_ordered_edges_ || opt_numbered_edges_)
|
||||
{
|
||||
os_ << ", taillabel=\"";
|
||||
|
|
@ -886,7 +890,7 @@ namespace spot
|
|||
{
|
||||
// Reset the label, otherwise the graph label would
|
||||
// be inherited by the cluster.
|
||||
os_ << " label=\"\"\n";
|
||||
os_ << (opt_latex_ ? " texlbl=\"\"\n" : " label=\"\"\n");
|
||||
}
|
||||
for (auto s: si->states_of(i))
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue