* src/bin/ltlcheck.cc: Add a --no-checks option.

This commit is contained in:
Alexandre Duret-Lutz 2012-10-15 20:41:44 +02:00
parent 2977635ae5
commit 9f1d369563

View file

@ -79,11 +79,10 @@ Exit status:\n\
#define OPT_JSON 3 #define OPT_JSON 3
#define OPT_CSV 4 #define OPT_CSV 4
#define OPT_DUPS 5 #define OPT_DUPS 5
#define OPT_NOCHECKS 6
static const argp_option options[] = static const argp_option options[] =
{ {
{ "allow-dups", OPT_DUPS, 0, 0,
"translate duplicate formulas in input", 1 },
/**************************************************/ /**************************************************/
{ 0, 0, 0, 0, "Specifying translator to call:", 2 }, { 0, 0, 0, 0, "Specifying translator to call:", 2 },
{ "translator", 't', "COMMANDFMT", 0, { "translator", 't', "COMMANDFMT", 0,
@ -104,14 +103,21 @@ static const argp_option options[] =
"not use LBT-style atomic propositions (i.e. p0, p1, ...) will be " "not use LBT-style atomic propositions (i.e. p0, p1, ...) will be "
"relabeled automatically.", 0 }, "relabeled automatically.", 0 },
/**************************************************/ /**************************************************/
{ 0, 0, 0, 0, "State-space generation:", 4 }, { 0, 0, 0, 0, "ltlcheck behavior:", 4 },
{ "allow-dups", OPT_DUPS, 0, 0,
"translate duplicate formulas in input", 0 },
{ "no-checks", OPT_NOCHECKS, 0, 0,
"do not perform any sanity checks (negated formulas "
"will not be translated)", 0 },
/**************************************************/
{ 0, 0, 0, 0, "State-space generation:", 5 },
{ "states", OPT_STATES, "INT", 0, { "states", OPT_STATES, "INT", 0,
"number of the states in the state-spaces (200 by default)", 0 }, "number of the states in the state-spaces (200 by default)", 0 },
{ "density", OPT_DENSITY, "FLOAT", 0, { "density", OPT_DENSITY, "FLOAT", 0,
"probability, between 0.0 and 1.0, to add a transition between " "probability, between 0.0 and 1.0, to add a transition between "
"two states (0.1 by default)", 0 }, "two states (0.1 by default)", 0 },
/**************************************************/ /**************************************************/
{ 0, 0, 0, 0, "Statistics ouput:", 5 }, { 0, 0, 0, 0, "Statistics output:", 6 },
{ "json", OPT_JSON, "FILENAME", OPTION_ARG_OPTIONAL, { "json", OPT_JSON, "FILENAME", OPTION_ARG_OPTIONAL,
"output statistics as JSON in FILENAME or on standard output", 0 }, "output statistics as JSON in FILENAME or on standard output", 0 },
{ "csv", OPT_CSV, "FILENAME", OPTION_ARG_OPTIONAL, { "csv", OPT_CSV, "FILENAME", OPTION_ARG_OPTIONAL,
@ -135,6 +141,7 @@ const char* json_output = 0;
const char* csv_output = 0; const char* csv_output = 0;
bool want_stats = false; bool want_stats = false;
bool allow_dups = false; bool allow_dups = false;
bool no_checks = false;
typedef Sgi::hash_set<const spot::ltl::formula*, typedef Sgi::hash_set<const spot::ltl::formula*,
const spot::ptr_hash<const spot::ltl::formula> > fset_t; const spot::ptr_hash<const spot::ltl::formula> > fset_t;
@ -275,6 +282,9 @@ parse_opt(int key, char* arg, struct argp_state*)
want_stats = true; want_stats = true;
json_output = arg ? arg : "-"; json_output = arg ? arg : "-";
break; break;
case OPT_NOCHECKS:
no_checks = true;
break;
case OPT_STATES: case OPT_STATES:
states = to_pos_int(arg); states = to_pos_int(arg);
break; break;
@ -780,12 +790,10 @@ namespace
unsigned n = vstats.size(); unsigned n = vstats.size();
vstats.resize(n + 2); vstats.resize(n + (no_checks ? 1 : 2));
statistics_formula* pstats = &vstats[n]; statistics_formula* pstats = &vstats[n];
statistics_formula* nstats = &vstats[n + 1]; statistics_formula* nstats = 0;
pstats->resize(m); pstats->resize(m);
nstats->resize(m);
formulas.push_back(fstr); formulas.push_back(fstr);
for (size_t n = 0; n < m; ++n) for (size_t n = 0; n < m; ++n)
@ -793,6 +801,13 @@ namespace
// ---------- Negative Formula ---------- // ---------- Negative Formula ----------
// The negative formula is only needed when checks are
// activated.
if (!no_checks)
{
nstats = &vstats[n + 1];
nstats->resize(m);
const spot::ltl::formula* nf = const spot::ltl::formula* nf =
spot::ltl::unop::instance(spot::ltl::unop::Not, f->clone()); spot::ltl::unop::instance(spot::ltl::unop::Not, f->clone());
@ -811,13 +826,17 @@ namespace
for (size_t n = 0; n < m; ++n) for (size_t n = 0; n < m; ++n)
neg[n] = runner.translate(n, 'N', nstats); neg[n] = runner.translate(n, 'N', nstats);
nf->destroy();
}
f->destroy();
runner.round_cleanup(); runner.round_cleanup();
++round; ++round;
std::cerr << "Sanity checks..." << std::endl; if (!no_checks)
{
spot::ltl::atomic_prop_set* ap = spot::ltl::atomic_prop_collect(f); std::cerr << "Performing sanity checks and gathering statistics..."
<< std::endl;
// intersection test // intersection test
for (size_t i = 0; i < m; ++i) for (size_t i = 0; i < m; ++i)
@ -832,9 +851,16 @@ namespace
<< " is nonempty\n"; << " is nonempty\n";
delete prod; delete prod;
} }
}
else
{
std::cerr << "Gathering statistics..." << std::endl;
}
// build products with a random state-space. // build products with a random state-space.
spot::ltl::atomic_prop_set* ap = spot::ltl::atomic_prop_collect(f);
spot::tgba* statespace = spot::random_graph(states, density, ap, &dict); spot::tgba* statespace = spot::random_graph(states, density, ap, &dict);
delete ap;
std::vector<spot::tgba*> pos_prod(m); std::vector<spot::tgba*> pos_prod(m);
std::vector<spot::tgba*> neg_prod(m); std::vector<spot::tgba*> neg_prod(m);
@ -858,6 +884,7 @@ namespace
(*pstats)[i].product_transitions = s.transitions; (*pstats)[i].product_transitions = s.transitions;
} }
} }
if (!no_checks)
for (size_t i = 0; i < m; ++i) for (size_t i = 0; i < m; ++i)
if (neg[i]) if (neg[i])
{ {
@ -877,6 +904,8 @@ namespace
} }
} }
if (!no_checks)
{
// cross-comparison test // cross-comparison test
cross_check(pos_map, 'P'); cross_check(pos_map, 'P');
cross_check(neg_map, 'N'); cross_check(neg_map, 'N');
@ -887,28 +916,24 @@ namespace
!(consistency_check(pos_map[i], neg_map[i], statespace))) !(consistency_check(pos_map[i], neg_map[i], statespace)))
global_error() << "error: inconsistency between P" << i global_error() << "error: inconsistency between P" << i
<< " and N" << i << "\n"; << " and N" << i << "\n";
}
// Cleanup. // Cleanup.
delete ap;
nf->destroy();
f->destroy();
if (!no_checks)
for (size_t n = 0; n < m; ++n) for (size_t n = 0; n < m; ++n)
{ {
delete neg_map[n]; delete neg_map[n];
delete neg_prod[n]; delete neg_prod[n];
delete pos_map[n]; delete neg[n];
delete pos_prod[n];
} }
delete statespace;
for (size_t n = 0; n < m; ++n) for (size_t n = 0; n < m; ++n)
{ {
delete neg[n]; delete pos_map[n];
delete pos_prod[n];
delete pos[n]; delete pos[n];
} }
delete statespace;
std::cerr << std::endl; std::cerr << std::endl;
return 0; return 0;
} }