* src/ltlvisit/dotty.cc: Rewrite to display formulae as

graphs rather than trees, to show how nodes are shared.
This commit is contained in:
Alexandre Duret-Lutz 2003-05-16 09:35:21 +00:00
parent e9b734f936
commit 38f7ae9a46
3 changed files with 59 additions and 49 deletions

View file

@ -1,5 +1,8 @@
2003-05-16 Alexandre Duret-Lutz <aduret@src.lip6.fr> 2003-05-16 Alexandre Duret-Lutz <aduret@src.lip6.fr>
* src/ltlvisit/dotty.cc: Rewrite to display formulae as
graphs rather than trees, to show how nodes are shared.
* src/ltlvisit/dump.hh (dump): Return the passed ostream. * src/ltlvisit/dump.hh (dump): Return the passed ostream.
* src/ltlvisit/dump.cc (dump): Likewise. * src/ltlvisit/dump.cc (dump): Likewise.
* src/ltlvisit/dotty.hh (dotty): Likewise. * src/ltlvisit/dotty.hh (dotty): Likewise.

View file

@ -2,17 +2,17 @@
#include "ltlast/visitor.hh" #include "ltlast/visitor.hh"
#include "ltlast/allnodes.hh" #include "ltlast/allnodes.hh"
namespace spot namespace spot
{ {
namespace ltl namespace ltl
{ {
class dotty_visitor : public spot::ltl::const_visitor class dotty_visitor : public const_visitor
{ {
public: public:
dotty_visitor(std::ostream& os = std::cout) typedef std::map<const formula*, int> map;
: os_(os), label_("i") dotty_visitor(std::ostream& os, map& m)
: os_(os), father_(-1), node_(m)
{ {
} }
@ -22,82 +22,89 @@ namespace spot
} }
void void
visit(const spot::ltl::atomic_prop* ap) visit(const atomic_prop* ap)
{ {
draw_node_(ap->name()); draw_node_(ap, ap->name());
} }
void void
visit(const spot::ltl::constant* c) visit(const constant* c)
{ {
draw_node_(c->val_name()); draw_node_(c, c->val_name());
} }
void void
visit(const spot::ltl::binop* bo) visit(const binop* bo)
{ {
draw_rec_node_(bo->op_name()); if (draw_node_(bo, bo->op_name(), true))
std::string label = label_; {
dotty_visitor v(*this);
label_ += "l"; bo->first()->accept(v);
draw_link_(label, label_); bo->second()->accept(*this);
bo->first()->accept(*this); }
label_ = draw_link_(label, label + "r");
bo->second()->accept(*this);
} }
void void
visit(const spot::ltl::unop* uo) visit(const unop* uo)
{ {
draw_rec_node_(uo->op_name()); if (draw_node_(uo, uo->op_name(), true))
label_ = draw_link_(label_, label_ + "c"); uo->child()->accept(*this);
uo->child()->accept(*this);
} }
void void
visit(const spot::ltl::multop* mo) visit(const multop* mo)
{ {
draw_rec_node_(mo->op_name()); if (!draw_node_(mo, mo->op_name(), true))
return;
unsigned max = mo->size(); unsigned max = mo->size();
std::string label = label_;
for (unsigned n = 0; n < max; ++n) for (unsigned n = 0; n < max; ++n)
{ {
// FIXME: use `n' as a string for label names. dotty_visitor v(*this);
label_ = draw_link_(label, label_ + "m"); mo->nth(n)->accept(v);
mo->nth(n)->accept(*this);
} }
} }
private: private:
std::ostream& os_; std::ostream& os_;
std::string label_; int father_;
map& node_;
const std::string& bool
draw_link_(const std::string& in, const std::string& out) draw_node_(const formula* f, const std::string& str, bool rec = false)
{ {
os_ << " " << in << " -> " << out << ";" << std::endl; map::iterator i = node_.find(f);
return out; int node;
bool node_exists = false;
if (i != node_.end())
{
node = i->second;
node_exists = true;
}
else
{
node = node_.size();
node_[f] = node;
}
// the link
if (father_ >= 0)
os_ << " " << father_ << " -> " << node << ";" << std::endl;
father_ = node;
// the node
if (node_exists)
return false;
os_ << " " << node
<< " [label=\"" << str << "\"";
if (rec)
os_ << ", shabe=box";
os_ << "];" << std::endl;
return true;
} }
void
draw_rec_node_(const char* str) const
{
os_ << " " << label_ << " [label=\"" << str << "\", shabe=box];"
<< std::endl;
}
void
draw_node_(const std::string& str) const
{
os_ << " " << label_ << " [label=\"" << str << "\"];" << std::endl;
}
}; };
std::ostream& std::ostream&
dotty(const formula* f, std::ostream& os) dotty(const formula* f, std::ostream& os)
{ {
dotty_visitor v(os); dotty_visitor::map m;
dotty_visitor v(os, m);
os << "digraph G {" << std::endl; os << "digraph G {" << std::endl;
f->accept(v); f->accept(v);
os << "}" << std::endl; os << "}" << std::endl;