Commit b77f7e24 authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz

revamp the formula hierarchy (montro-patch)

Flatten the formula ltl::formula hiearchy into a single ltl::vnode that
has an enumerator to distinguish the types of node, and a common
interface to access children, update reference counts, etc.  The
ltl::formula class is now a thin wrapper around an ltl::vnode pointer to
keep track of reference counts automatically.  Visitor are not used
anymore; we now have map() and traversor() methods that are more
concise.

This basically fixes #43, but should be followed by some fine tuning
that should now be localized to the formula.hh and formula.cc files.

Some statistics about this patch.  I started working on it on Sep 9, had
a first compiling version two weeks later on Sep 22, and it then took 5
days to fixes the ~70 distincts bugs that were introduced during the
conversion.  About 13200 lines were modified, and one third of those
were removed.

* src/ltlast/formula.cc, src/ltlast/formula.hh: Complete rewrite,
including what was in separate nearby files.
* src/ltlast/allnodes.hh, src/ltlast/atomic_prop.cc,
src/ltlast/atomic_prop.hh, src/ltlast/binop.cc, src/ltlast/binop.hh,
src/ltlast/bunop.cc, src/ltlast/bunop.hh, src/ltlast/constant.cc,
src/ltlast/constant.hh, src/ltlast/multop.cc, src/ltlast/multop.hh,
src/ltlast/unop.cc, src/ltlast/unop.hh, src/ltlvisit/dump.cc,
src/ltlvisit/dump.hh, src/ltlast/predecl.hh: Delete these files.  Their
feature have been merged in formula.hh and formula.cc.
* src/ltlast/visitor.hh, src/ltlvisit/clone.cc, src/ltlvisit/clone.hh,
src/ltlvisit/dump.hh, src/ltlvisit/postfix.cc, src/ltlvisit/postfix.hh:
Delete these files, as we do not use visitors anymore.
* bench/stutter/stutter_invariance_formulas.cc,
bench/stutter/stutter_invariance_randomgraph.cc, doc/org/tut01.org,
doc/org/tut02.org, doc/org/tut10.org, doc/org/tut22.org,
iface/ltsmin/ltsmin.cc, iface/ltsmin/ltsmin.hh,
iface/ltsmin/modelcheck.cc, src/bin/autfilt.cc,
src/bin/common_aoutput.cc, src/bin/common_aoutput.hh,
src/bin/common_finput.cc, src/bin/common_finput.hh,
src/bin/common_output.cc, src/bin/common_output.hh,
src/bin/common_trans.cc, src/bin/common_trans.hh, src/bin/dstar2tgba.cc,
src/bin/genltl.cc, src/bin/ltl2tgba.cc, src/bin/ltl2tgta.cc,
src/bin/ltlcross.cc, src/bin/ltldo.cc, src/bin/ltlfilt.cc,
src/bin/ltlgrind.cc, src/bin/randaut.cc, src/bin/randltl.cc,
src/kripke/kripkeexplicit.cc, src/kripke/kripkeexplicit.hh,
src/kripkeparse/kripkeparse.yy, src/ltlast/Makefile.am,
src/ltlenv/declenv.cc, src/ltlenv/declenv.hh, src/ltlenv/defaultenv.cc,
src/ltlenv/defaultenv.hh, src/ltlenv/environment.hh,
src/ltlparse/ltlparse.yy, src/ltlparse/public.hh,
src/ltlvisit/Makefile.am, src/ltlvisit/apcollect.cc,
src/ltlvisit/apcollect.hh, src/ltlvisit/contain.cc,
src/ltlvisit/contain.hh, src/ltlvisit/dot.cc, src/ltlvisit/dot.hh,
src/ltlvisit/exclusive.cc, src/ltlvisit/exclusive.hh,
src/ltlvisit/length.cc, src/ltlvisit/length.hh, src/ltlvisit/mark.cc,
src/ltlvisit/mark.hh, src/ltlvisit/mutation.cc,
src/ltlvisit/mutation.hh, src/ltlvisit/nenoform.cc,
src/ltlvisit/nenoform.hh, src/ltlvisit/print.cc, src/ltlvisit/print.hh,
src/ltlvisit/randomltl.cc, src/ltlvisit/randomltl.hh,
src/ltlvisit/relabel.cc, src/ltlvisit/relabel.hh,
src/ltlvisit/remove_x.cc, src/ltlvisit/remove_x.hh,
src/ltlvisit/simpfg.cc, src/ltlvisit/simpfg.hh,
src/ltlvisit/simplify.cc, src/ltlvisit/simplify.hh, src/ltlvisit/snf.cc,
src/ltlvisit/snf.hh, src/ltlvisit/unabbrev.cc, src/ltlvisit/unabbrev.hh,
src/parseaut/parseaut.yy, src/ta/taexplicit.cc, src/ta/tgtaexplicit.cc,
src/taalgos/minimize.cc, src/taalgos/tgba2ta.cc, src/tests/bare.test,
src/tests/checkpsl.cc, src/tests/checkta.cc,
src/tests/complementation.cc, src/tests/consterm.cc,
src/tests/emptchk.cc, src/tests/equalsf.cc, src/tests/ikwiad.cc,
src/tests/isop.test, src/tests/kind.cc, src/tests/length.cc,
src/tests/ltldo.test, src/tests/ltlfilt.test, src/tests/ltlgrind.test,
src/tests/ltlprod.cc, src/tests/ltlrel.cc,
src/tests/parse_print_test.cc, src/tests/parseaut.test,
src/tests/parseerr.test, src/tests/randtgba.cc, src/tests/readltl.cc,
src/tests/reduc.cc, src/tests/syntimpl.cc, src/tests/taatgba.cc,
src/tests/tostring.cc, src/tests/twagraph.cc, src/tests/utf8.test,
src/twa/acc.cc, src/twa/bdddict.cc, src/twa/bdddict.hh,
src/twa/bddprint.cc, src/twa/formula2bdd.cc, src/twa/formula2bdd.hh,
src/twa/taatgba.cc, src/twa/taatgba.hh, src/twa/twa.cc, src/twa/twa.hh
src/twa/twagraph.cc, src/twa/twagraph.hh, src/twa/twasafracomplement.cc,
src/twaalgos/compsusp.cc, src/twaalgos/compsusp.hh,
src/twaalgos/dtgbasat.cc, src/twaalgos/hoa.cc, src/twaalgos/lbtt.cc,
src/twaalgos/ltl2taa.cc, src/twaalgos/ltl2taa.hh,
src/twaalgos/ltl2tgba_fm.cc, src/twaalgos/ltl2tgba_fm.hh,
src/twaalgos/minimize.cc, src/twaalgos/minimize.hh,
src/twaalgos/neverclaim.cc, src/twaalgos/postproc.cc,
src/twaalgos/postproc.hh, src/twaalgos/powerset.cc,
src/twaalgos/powerset.hh, src/twaalgos/randomgraph.cc,
src/twaalgos/remprop.cc, src/twaalgos/remprop.hh, src/twaalgos/stats.cc,
src/twaalgos/stats.hh, src/twaalgos/stutter.cc, src/twaalgos/stutter.hh,
src/twaalgos/translate.cc, src/twaalgos/translate.hh,
wrap/python/ajax/spotcgi.in, wrap/python/spot.py,
wrap/python/spot_impl.i, wrap/python/Makefile.am,
wrap/python/tests/automata-io.ipynb, wrap/python/tests/formulas.ipynb,
wrap/python/tests/ltl2tgba.py, wrap/python/tests/ltlparse.py,
wrap/python/tests/ltlsimple.py, wrap/python/tests/randltl.ipynb: Adjust
to use the new interface.
* src/sanity/style.test: Accept more C++11 patterns.
* NEWS: Mention the change.
parent 1628b188
......@@ -15,6 +15,24 @@ New in spot 1.99.3a (not yet released)
(But dstar2tgba does not offer all the filtering and
transformations options of autfilt.)
* The class hierarchy for temporal formulas has been entirely
rewritten. This change is actually quite massive (~13200 lines
removed, ~8200 lines added), and brings some nice benefits:
- LTL/PSL formulas are now represented by lightweight
ltl::formula objects (instead of ltl::formula* pointers)
that perform reference counting automatically.
- There is no hierachy anymore: all operators are represented
by a single type of node in the syntax tree, and an
enumerator is used to distinguish between operators.
- Visitors have been replaced by member functions such
as map() or traverse(), that take a function (usually
written as a lambda function) and apply it to the
nodes of the tree.
- As a consequence, writing algorithms that manipulate
formula is more friendly, and several functions
algorithms that spanned a few pages have been
reduced to a few lines.
New in spot 1.99.3 (2015-08-26)
* The CGI script for LTL translation offers a HOA download link
......
......@@ -25,7 +25,6 @@
#include "twaalgos/stutter.hh"
#include "twaalgos/dupexp.hh"
#include "twaalgos/stats.hh"
#include "ltlast/allnodes.hh"
#include "ltlvisit/apcollect.hh"
#include "ltlvisit/length.hh"
#include "misc/timer.hh"
......@@ -64,14 +63,10 @@ namespace
}
int
process_formula(const spot::ltl::formula* f,
const char*, int)
process_formula(spot::ltl::formula f, const char*, int)
{
const spot::ltl::formula* nf =
spot::ltl::unop::instance(spot::ltl::unop::Not,
f->clone());
spot::twa_graph_ptr a = trans.run(f);
spot::twa_graph_ptr na = trans.run(nf);
spot::twa_graph_ptr na = trans.run(spot::ltl::formula::Not(f));
spot::ltl::atomic_prop_set* ap = spot::ltl::atomic_prop_collect(f);
bdd apdict = spot::ltl::atomic_prop_collect_as_bdd(f, a);
......@@ -103,9 +98,6 @@ namespace
prev = res;
}
std::cout << prev << '\n';
f->destroy();
nf->destroy();
delete ap;
return 0;
}
......
......@@ -127,6 +127,5 @@ main(int argc, char** argv)
break;
}
dict->unregister_all_my_variables(&ap);
spot::ltl::destroy_atomic_prop_set(ap);
return 0;
}
......@@ -72,10 +72,9 @@ exceptions.
int main()
{
print_latex_psl(std::cout, spot::ltl::parse_formula("[]<>p0 || <>[]p1")) << '\n';
const spot::ltl::formula* f = spot::ltl::parse_formula("& & G p0 p1 p2");
spot::ltl::formula f = spot::ltl::parse_formula("& & G p0 p1 p2");
print_lbt_ltl(std::cout, f) << '\n';
print_spin_ltl(std::cout, f, true) << '\n';
f->destroy();
return 0;
}
#+END_SRC
......@@ -90,12 +89,6 @@ syntax the output, and the type of formula they can output. Here we
are only using LTL formulas for demonstration, so those three
functions are OK with that.
Did you notice the calls to =f->destroy()= at the end? The LTL
formula objects are implemented as DAG with sharing of subformulas.
Each (sub)formula is therefore reference counted, and currently this
is done manually by calling =f->clone()= and =f->destroy()= (do not
ever =delete= a formula, always call =f->destroy()=).
We do not recommend using this =parse_formula()= interface because of
the potential formulas (like =f= or =t=) that have different meanings
in the two parsers that are tried.
......@@ -118,15 +111,10 @@ Here is how to call the infix parser explicitly,:
{
std::string input = "[]<>p0 || <>[]p1";
spot::ltl::parse_error_list pel;
const spot::ltl::formula* f = spot::ltl::parse_infix_psl(input, pel);
spot::ltl::formula f = spot::ltl::parse_infix_psl(input, pel);
if (spot::ltl::format_parse_errors(std::cerr, input, pel))
{
if (f)
f->destroy();
return 1;
}
return 1;
print_latex_psl(std::cout, f) << '\n';
f->destroy();
return 0;
}
#+END_SRC
......@@ -165,14 +153,14 @@ with the "fixed" formula if you wish. Here is an example:
{
std::string input = "(a U b))";
spot::ltl::parse_error_list pel;
const spot::ltl::formula* f = spot::ltl::parse_infix_psl(input, pel);
spot::ltl::formula f = spot::ltl::parse_infix_psl(input, pel);
// Use std::cout instead of std::cerr because we can only
// show the output of std::cout in this documentation.
(void) spot::ltl::format_parse_errors(std::cout, input, pel);
if (f == nullptr)
return 1;
print_latex_psl(std::cout, f) << '\n';
f->destroy();
std::cout << "Parsed formula: ";
print_psl(std::cout, f) << '\n';
return 0;
}
#+END_SRC
......@@ -186,7 +174,7 @@ with the "fixed" formula if you wish. Here is an example:
: ^
: ignoring trailing garbage
:
: a \U b
: Parsed formula: a U b
The formula =f= is only returned as null when the parser really cannot
......@@ -207,16 +195,11 @@ of =parse_infix_psl()=.
{
std::string input = "& & G p0 p1 p2";
spot::ltl::parse_error_list pel;
const spot::ltl::formula* f = spot::ltl::parse_prefix_ltl(input, pel);
spot::ltl::formula f = spot::ltl::parse_prefix_ltl(input, pel);
if (spot::ltl::format_parse_errors(std::cerr, input, pel))
{
if (f)
f->destroy();
return 1;
}
return 1;
print_lbt_ltl(std::cout, f) << '\n';
print_spin_ltl(std::cout, f, true) << '\n';
f->destroy();
return 0;
}
#+END_SRC
......@@ -254,15 +237,10 @@ For instance, let's see what happens if a PSL formulas is passed to
{
std::string input = "{a*;b}<>->(a U (b & GF c))";
spot::ltl::parse_error_list pel;
const spot::ltl::formula* f = spot::ltl::parse_infix_psl(input, pel);
spot::ltl::formula f = spot::ltl::parse_infix_psl(input, pel);
if (spot::ltl::format_parse_errors(std::cerr, input, pel))
{
if (f)
f->destroy();
return 1;
}
return 1;
print_spin_ltl(std::cout, f) << '\n';
f->destroy();
return 0;
}
#+END_SRC
......@@ -289,21 +267,15 @@ The first is to simply diagnose non-LTL formulas.
{
std::string input = "{a*;b}<>->(a U (b & GF c))";
spot::ltl::parse_error_list pel;
const spot::ltl::formula* f = spot::ltl::parse_infix_psl(input, pel);
spot::ltl::formula f = spot::ltl::parse_infix_psl(input, pel);
if (spot::ltl::format_parse_errors(std::cerr, input, pel))
return 1;
if (!f.is_ltl_formula())
{
if (f)
f->destroy();
return 1;
}
if (!f->is_ltl_formula())
{
f->destroy();
std::cerr << "Only LTL formulas are supported.\n";
return 1;
}
print_spin_ltl(std::cout, f) << '\n';
f->destroy();
return 0;
}
#+END_SRC
......@@ -314,7 +286,7 @@ equivalent LTL formula. This does not always work, so you need to be
prepared to reject the formula any way. In our example, we are lucky
(maybe because it was carefully chosen...):
#+BEGIN_SRC C++ :results verbatim :exports code
#+BEGIN_SRC C++ :results verbatim :exports both
#include <string>
#include <iostream>
#include "ltlparse/public.hh"
......@@ -325,28 +297,20 @@ prepared to reject the formula any way. In our example, we are lucky
{
std::string input = "{a*;b}<>->(a U (b & GF c))";
spot::ltl::parse_error_list pel;
const spot::ltl::formula* f = spot::ltl::parse_infix_psl(input, pel);
spot::ltl::formula f = spot::ltl::parse_infix_psl(input, pel);
if (spot::ltl::format_parse_errors(std::cerr, input, pel))
{
if (f)
f->destroy();
return 1;
}
if (!f->is_ltl_formula())
return 1;
if (!f.is_ltl_formula())
{
spot::ltl::ltl_simplifier simp;
const formula* g = simp.simplify(f);
f->destroy();
f = g;
f = simp.simplify(f);
}
if (!f->is_ltl_formula())
if (!f.is_ltl_formula())
{
f->destroy();
std::cerr << "Only LTL formulas are supported.\n";
return 1;
}
print_spin_ltl(std::cout, f) << '\n';
f->destroy();
return 0;
}
#+END_SRC
......
......@@ -15,9 +15,9 @@ ltlfilt -ps --relabel=pnn --define -f '"Proc@Here" U ("var > 10" | "var < 4")'
#+END_SRC
#+RESULTS:
: #define p0 ((Proc@Here))
: #define p1 ((var < 4))
: #define p2 ((var > 10))
: #define p0 (Proc@Here)
: #define p1 (var < 4)
: #define p2 (var > 10)
: (p0) U ((p1) || (p2))
When is this output interesting, you may ask? It is useful for
......@@ -34,9 +34,9 @@ rm tmp.defs tmp.ltl
#+RESULTS:
#+begin_example
#define p0 ((Proc@Here))
#define p1 ((var < 4))
#define p2 ((var > 10))
#define p0 (Proc@Here)
#define p1 (var < 4)
#define p2 (var > 10)
never { /* (p0) U ((p1) || (p2))
*/
T0_init:
......@@ -88,32 +88,26 @@ destructor.
{
std::string input = "\"Proc@Here\" U (\"var > 10\" | \"var < 4\")";
spot::ltl::parse_error_list pel;
const spot::ltl::formula* f = spot::ltl::parse_infix_psl(input, pel);
spot::ltl::formula f = spot::ltl::parse_infix_psl(input, pel);
if (spot::ltl::format_parse_errors(std::cerr, input, pel))
{
if (f)
f->destroy();
return 1;
}
return 1;
spot::ltl::relabeling_map m;
const spot::ltl::formula* g = spot::ltl::relabel(f, spot::ltl::Pnn, &m);
f = spot::ltl::relabel(f, spot::ltl::Pnn, &m);
for (auto& i: m)
{
std::cout << "#define ";
print_psl(std::cout, i.first) << " (";
print_spin_ltl(std::cout, i.second, true) << ")\n";
}
print_spin_ltl(std::cout, g, true) << '\n';
g->destroy();
f->destroy();
print_spin_ltl(std::cout, f, true) << '\n';
return 0;
}
#+END_SRC
#+RESULTS:
: #define p0 ((Proc@Here))
: #define p1 ((var < 4))
: #define p2 ((var > 10))
: #define p0 (Proc@Here)
: #define p1 (var < 4)
: #define p2 (var > 10)
: (p0) U ((p1) || (p2))
......@@ -135,7 +129,7 @@ ltlfilt -ps --relabel-bool=pnn --define -f '"Proc@Here" U ("var > 10" | "var < 4
#+END_SRC
#+RESULTS:
: #define p0 ((Proc@Here))
: #define p0 (Proc@Here)
: #define p1 ((var < 4) || (var > 10))
: (p0) U (p1)
......@@ -151,8 +145,8 @@ ltlfilt -ps --relabel-bool=pnn --define -f 'a U (a & b)'
#+END_SRC
#+RESULTS:
: #define p0 ((a))
: #define p1 ((b))
: #define p0 (a)
: #define p1 (b)
: (p0) U ((p0) && (p1))
This "Boolean sub-expression" relabeling is available in Python and
......
......@@ -138,18 +138,13 @@ never claim is done via the =print_never_claim= function.
{
std::string input = "[]<>p0 || <>[]p1";
spot::ltl::parse_error_list pel;
const spot::ltl::formula* f = spot::ltl::parse_infix_psl(input, pel);
spot::ltl::formula f = spot::ltl::parse_infix_psl(input, pel);
if (spot::ltl::format_parse_errors(std::cerr, input, pel))
{
if (f)
f->destroy();
return 1;
}
return 1;
spot::translator trans;
trans.set_type(spot::postprocessor::BA);
spot::twa_graph_ptr aut = trans.run(f);
print_never_claim(std::cout, aut) << '\n';
f->destroy();
return 0;
}
#+END_SRC
......
......@@ -4,7 +4,6 @@
#+HTML_LINK_UP: tut.html
This example demonstrates how to create an automaton in C++, and then print it.
The interface
#+BEGIN_SRC C++ :results verbatim :exports both
#include <iostream>
......
// -*- coding: utf-8 -*-
// Copyright (C) 2011, 2012, 2014 Laboratoire de Recherche et Développement
// de l'Epita (LRDE)
// Copyright (C) 2011, 2012, 2014, 2015 Laboratoire de Recherche et
// Développement de l'Epita (LRDE)
//
// This file is part of Spot, a model checking library.
//
......@@ -326,7 +326,7 @@ namespace spot
convert_aps(const ltl::atomic_prop_set* aps,
const spins_interface* d,
bdd_dict_ptr dict,
const ltl::formula* dead,
ltl::formula dead,
prop_set& out)
{
int errors = 0;
......@@ -359,7 +359,7 @@ namespace spot
if (*ap == dead)
continue;
std::string str = (*ap)->name();
const std::string& str = ap->ap_name();
const char* s = str.c_str();
// Skip any leading blank.
......@@ -602,7 +602,7 @@ namespace spot
public:
spins_kripke(const spins_interface* d, const bdd_dict_ptr& dict,
const spot::prop_set* ps, const ltl::formula* dead,
const spot::prop_set* ps, ltl::formula dead,
int compress)
: kripke(dict),
d_(d),
......@@ -646,12 +646,12 @@ namespace spot
// appropriately. ALIVE_PROP is the bdd that should be ANDed
// to all transitions leaving a live state, while DEAD_PROP should
// be ANDed to all transitions leaving a dead state.
if (dead == ltl::constant::false_instance())
if (dead.is_false())
{
alive_prop = bddtrue;
dead_prop = bddfalse;
}
else if (dead == ltl::constant::true_instance())
else if (dead.is_true())
{
alive_prop = bddtrue;
dead_prop = bddtrue;
......@@ -1016,7 +1016,7 @@ namespace spot
kripke_ptr
load_ltsmin(const std::string& file_arg, const bdd_dict_ptr& dict,
const ltl::atomic_prop_set* to_observe,
const ltl::formula* dead, int compress, bool verbose)
const ltl::formula dead, int compress, bool verbose)
{
std::string file;
if (file_arg.find_first_of("/\\") != std::string::npos)
......
// -*- coding: utf-8 -*-
// Copyright (C) 2011, 2013, 2014 Laboratoire de Recherche et
// Copyright (C) 2011, 2013, 2014, 2015 Laboratoire de Recherche et
// Developpement de l'Epita (LRDE)
//
// This file is part of Spot, a model checking library.
......@@ -21,7 +21,6 @@
#include "kripke/kripke.hh"
#include "ltlvisit/apcollect.hh"
#include "ltlast/constant.hh"
namespace spot
{
......@@ -59,6 +58,6 @@ namespace spot
SPOT_API kripke_ptr
load_ltsmin(const std::string& file, const bdd_dict_ptr& dict,
const ltl::atomic_prop_set* to_observe,
const ltl::formula* dead = ltl::constant::true_instance(),
ltl::formula dead = ltl::formula::tt(),
int compress = 0, bool verbose = true);
}
......@@ -20,7 +20,6 @@
#include "ltsmin.hh"
#include "twaalgos/dot.hh"
#include "ltlenv/defaultenv.hh"
#include "ltlast/allnodes.hh"
#include "ltlparse/public.hh"
#include "twaalgos/translate.hh"
#include "twaalgos/emptiness.hh"
......@@ -163,16 +162,16 @@ checked_main(int argc, char **argv)
spot::emptiness_check_instantiator_ptr echeck_inst = nullptr;
int exit_code = 0;
spot::postprocessor post;
const spot::ltl::formula* deadf = nullptr;
const spot::ltl::formula* f = nullptr;
spot::ltl::formula deadf = nullptr;
spot::ltl::formula f = nullptr;
if (!dead || !strcasecmp(dead, "true"))
{
deadf = spot::ltl::constant::true_instance();
deadf = spot::ltl::formula::tt();
}
else if (!strcasecmp(dead, "false"))
{
deadf = spot::ltl::constant::false_instance();
deadf = spot::ltl::formula::ff();
}
else
{
......@@ -355,11 +354,6 @@ checked_main(int argc, char **argv)
}
safe_exit:
if (f)
f->destroy();
deadf->destroy();
if (use_timer)
tm.print(std::cout);
tm.reset_all(); // This helps valgrind.
......@@ -372,15 +366,6 @@ main(int argc, char **argv)
auto exit_code = checked_main(argc, argv);
// Additional checks to debug reference counts in formulas.
spot::ltl::atomic_prop::dump_instances(std::cerr);
spot::ltl::unop::dump_instances(std::cerr);
spot::ltl::binop::dump_instances(std::cerr);
spot::ltl::multop::dump_instances(std::cerr);
spot::ltl::bunop::dump_instances(std::cerr);
assert(spot::ltl::atomic_prop::instance_count() == 0);
assert(spot::ltl::unop::instance_count() == 0);
assert(spot::ltl::binop::instance_count() == 0);
assert(spot::ltl::multop::instance_count() == 0);
assert(spot::ltl::bunop::instance_count() == 0);
assert(spot::ltl::fnode::instances_check());
exit(exit_code);
}
......@@ -487,7 +487,7 @@ namespace
}
int
process_formula(const spot::ltl::formula*, const char*, int)
process_formula(spot::ltl::formula, const char*, int)
{
SPOT_UNREACHABLE();
}
......
......@@ -272,7 +272,7 @@ automaton_printer::automaton_printer(stat_style input)
void
automaton_printer::print(const spot::twa_graph_ptr& aut,
const spot::ltl::formula* f,
spot::ltl::formula f,
// Input location for errors and statistics.
const char* filename,
int loc,
......
......@@ -107,7 +107,7 @@ public:
std::ostream&
print(const spot::const_parsed_aut_ptr& haut,
const spot::const_twa_graph_ptr& aut,
const spot::ltl::formula* f,
spot::ltl::formula f,
const char* filename, int loc, double run_time)
{
filename_ = filename ? filename : "";
......@@ -225,7 +225,7 @@ public:
void
print(const spot::twa_graph_ptr& aut,
const spot::ltl::formula* f = nullptr,
spot::ltl::formula f = nullptr,
// Input location for errors and statistics.
const char* filename = nullptr,
int loc = -1,
......
......@@ -75,7 +75,7 @@ parse_opt_finput(int key, char* arg, struct argp_state*)
return 0;
}
const spot::ltl::formula*
spot::ltl::formula
parse_formula(const std::string& s, spot::ltl::parse_error_list& pel)
{
if (lbt_input)
......@@ -108,15 +108,13 @@ job_processor::process_string(const std::string& input,
int linenum)
{
spot::ltl::parse_error_list pel;
const spot::ltl::formula* f = parse_formula(input, pel);
auto f = parse_formula(input, pel);
if (!f || !pel.empty())
{
if (filename)
error_at_line(0, 0, filename, linenum, "parse error:");
spot::ltl::format_parse_errors(std::cerr, input, pel);
if (f)
f->destroy();
return 1;
}
return process_formula(f, filename, linenum);
......
// -*- coding: utf-8 -*-
// Copyright (C) 2012, 2013 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2012, 2013, 2015 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
......@@ -44,7 +44,7 @@ extern const struct argp finput_argp;
int parse_opt_finput(int key, char* arg, struct argp_state* state);
const spot::ltl::formula*
spot::ltl::formula
parse_formula(const std::string& s, spot::ltl::parse_error_list& error_list);
......@@ -58,7 +58,7 @@ public:
virtual ~job_processor();
virtual int
process_formula(const spot::ltl::formula* f,
process_formula(spot::ltl::formula f,
const char* filename = 0, int linenum = 0) = 0;
virtual int
......
......@@ -68,7 +68,7 @@ const struct argp output_argp = { options, parse_opt_output, 0, 0, 0, 0, 0 };
static
void
report_not_ltl(const spot::ltl::formula* f,
report_not_ltl(spot::ltl::formula f,
const char* filename, int linenum, const char* syn)
{
std::string s = spot::ltl::str_psl(f);
......@@ -82,12 +82,12 @@ report_not_ltl(const spot::ltl::formula* f,
std::ostream&