[lbtt] Count deterministic automata and deterministic states.

* src/BuchiAutomaton.h, src/BuchiAutomaton.cc
(BuchiState::isDeterministic, BuchiAutomaton::isDeterministic,
BuchiAutomaton::nondeterminismIndex): New methods.
* src/TestOperations.cc (generateBuchiAutomaton): Collect
nondeterminism indices, and count deterministic automata.
* src/TestStatistics.cc, src/TestStatistics.h: Add storage
for these statistics.
* src/StatDisplay.cc (printBuchiAutomatonStats,
printCollectiveStats): Display these statistics.
This commit is contained in:
Tomáš Babiak 2012-05-21 12:16:33 +02:00 committed by Alexandre Duret-Lutz
parent 31b3a22805
commit f2b188d9ec
7 changed files with 226 additions and 37 deletions

View file

@ -1,3 +1,17 @@
2012-05-21 Tomáš Babiak <xbabiak@fi.muni.cz>
Count deterministic automata and deterministic states.
* src/BuchiAutomaton.h, src/BuchiAutomaton.cc
(BuchiState::isDeterministic, BuchiAutomaton::isDeterministic,
BuchiAutomaton::nondeterminismIndex): New methods.
* src/TestOperations.cc (generateBuchiAutomaton): Collect
nondeterminism indices, and count deterministic automata.
* src/TestStatistics.cc, src/TestStatistics.h: Add storage
for these statistics.
* src/StatDisplay.cc (printBuchiAutomatonStats,
printCollectiveStats): Display these statistics.
2012-04-27 Alexandre Duret-Lutz <adl@lrde.epita.fr> 2012-04-27 Alexandre Duret-Lutz <adl@lrde.epita.fr>
* doc/gpl.texi: Fix make pdf for newer texinfo.tex. * doc/gpl.texi: Fix make pdf for newer texinfo.tex.
@ -336,7 +350,7 @@
* src/Product.h, src/SccCollection.h: New files. * src/Product.h, src/SccCollection.h: New files.
* src/BuchiProduct.h, src/BuchiProduct.cc, src/StateSpaceProduct.h: * src/BuchiProduct.h, src/BuchiProduct.cc, src/StateSpaceProduct.h:
New files for providing specializations of the general product New files for providing specializations of the general product
computation operation applicable to Büchi automata and state computation operation applicable to Büchi automata and state
spaces. spaces.
* src/Makefile.am: Add BuchiProduct.h, BuchiProduct.cc, * src/Makefile.am: Add BuchiProduct.h, BuchiProduct.cc,
@ -381,7 +395,7 @@
Product interface for constructing the product and checking Product interface for constructing the product and checking
it for emptiness. it for emptiness.
(performBuchiIntersectionCheck): Use the Product interface (performBuchiIntersectionCheck): Use the Product interface
for constructing the intersection of Büchi automata and for constructing the intersection of Büchi automata and
checking it for emptiness. checking it for emptiness.
* src/UserCommandReader.cc: Do not include the * src/UserCommandReader.cc: Do not include the
@ -412,12 +426,12 @@
analyzing a witness for the nonemptiness of a product automaton. analyzing a witness for the nonemptiness of a product automaton.
(printAutomatonAnalysisResults): Use the Product interface (printAutomatonAnalysisResults): Use the Product interface
for constructing and analyzing a witness for the nonemptiness for constructing and analyzing a witness for the nonemptiness
of the intersection of two Büchi automata. of the intersection of two Büchi automata.
(printPath): Update parameter list and documentation. Standardize (printPath): Update parameter list and documentation. Standardize
the output to resemble that produced by printAcceptingCycle. the output to resemble that produced by printAcceptingCycle.
(printAcceptingCycle): Update parameter list and documentation. (printAcceptingCycle): Update parameter list and documentation.
Display all relevant information about an accepting execution Display all relevant information about an accepting execution
of a Büchi automaton. of a Büchi automaton.
2004-05-18 Heikki Tauriainen <heikki.tauriainen@hut.fi> 2004-05-18 Heikki Tauriainen <heikki.tauriainen@hut.fi>
@ -1053,7 +1067,7 @@
2003-07-18 Heikki Tauriainen <heikki.tauriainen@hut.fi> 2003-07-18 Heikki Tauriainen <heikki.tauriainen@hut.fi>
* UserCommands.cc (printAutomatonAnalysisResults): Ensure that * UserCommands.cc (printAutomatonAnalysisResults): Ensure that
the states in a witness for the nonemptiness of two Bûchi the states in a witness for the nonemptiness of two Bûchi
automata are distinct to prevent the truth valuation for the automata are distinct to prevent the truth valuation for the
atomic propositions from being defined multiple times in any atomic propositions from being defined multiple times in any
state of the witness. state of the witness.

View file

@ -641,7 +641,85 @@ void BuchiAutomaton::print
estream.flush(); estream.flush();
} }
/* ========================================================================= */
bool BuchiAutomaton::BuchiState::isDeterministic() const
/* ----------------------------------------------------------------------------
*
* Description: Checks whether there is any nondeterminism
* on the outgoing transitions.
*
* Arguments: None.
*
* Returns: True iff the state is deterministic.
*
* ------------------------------------------------------------------------- */
{
size_type size = edges().size();
if (size <= 1)
return true;
for (int i = 0; i < size - 1; i++)
{
for (int j = i + 1; j < size; j++)
{
Ltl::LtlFormula *f =
&Ltl::And::construct((static_cast<BuchiTransition*> (edges()[i]))->guard(),
(static_cast<BuchiTransition*> (edges()[j]))->guard());
if (f->satisfiable())
{
Ltl::LtlFormula::destruct(f);
return false;
}
else
{
Ltl::LtlFormula::destruct(f);
}
}
}
return true;
}
/* ========================================================================= */
bool BuchiAutomaton::isDeterministic() const
/* ----------------------------------------------------------------------------
*
* Description: Checks whether the automaton is deterministic.
*
* Arguments: None.
*
* Returns: True iff the automaton is deterministic.
*
* ------------------------------------------------------------------------- */
{
unsigned long int index = 0;
vector<Node*>::const_iterator node;
for (node = nodes.begin(); node != nodes.end(); ++node)
if (!(static_cast<BuchiState*>(*node))->isDeterministic())
return false;
return true;
}
/* ========================================================================= */
unsigned long int BuchiAutomaton::nondeterminismIndex() const
/* ----------------------------------------------------------------------------
*
* Description: Computes the nondeterminism index for the automaton.
* I.e., the number for nondeterministic states.
*
* Arguments: None.
*
* Returns: Nondeterminism index.
*
* ------------------------------------------------------------------------- */
{
unsigned long int index = 0;
vector<Node*>::const_iterator node;
for (node = nodes.begin(); node != nodes.end(); ++node)
if (!(static_cast<BuchiState*>(*node))->isDeterministic())
index++;
return index;
}
/****************************************************************************** /******************************************************************************
* *

View file

@ -86,6 +86,11 @@ public:
number_of_acceptance_sets) number_of_acceptance_sets)
const; const;
bool isDeterministic() const; /* Checks wheter there is
* any nondeterminism on
* outgoing transitions.
*/
private: private:
BuchiState(const BuchiState&); /* Prevent copying and */ BuchiState(const BuchiState&); /* Prevent copying and */
BuchiState& operator=(const BuchiState&); /* assignment of BuchiState& operator=(const BuchiState&); /* assignment of
@ -182,6 +187,13 @@ public:
* (determined by the * (determined by the
* `fmt' argument). * `fmt' argument).
*/ */
bool isDeterministic() const; /* Checks whether
* the automaton
* is deterministic.
*/
unsigned long int nondeterminismIndex() const; /* Computes the
* nondeterminism index.
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

View file

@ -26,6 +26,7 @@
#include "StatDisplay.h" #include "StatDisplay.h"
#include "StringUtil.h" #include "StringUtil.h"
#include "TestRoundInfo.h" #include "TestRoundInfo.h"
#include "Graph.h"
namespace StatDisplay namespace StatDisplay
{ {
@ -107,7 +108,7 @@ void printBuchiAutomatonStats
if (configuration.global_options.verbosity <= 2) if (configuration.global_options.verbosity <= 2)
{ {
if (!automaton_stats.buchiAutomatonComputed()) if (!automaton_stats.buchiAutomatonComputed())
estream << " N/A N/A N/A N/A"; estream << " N/A N/A N/A N/A N/A";
else else
{ {
if (automaton_stats.buchi_generation_time >= 0.0) if (automaton_stats.buchi_generation_time >= 0.0)
@ -130,6 +131,9 @@ void printBuchiAutomatonStats
changeStreamFormatting(stream, 4, 0, ios::right); changeStreamFormatting(stream, 4, 0, ios::right);
estream << automaton_stats.number_of_acceptance_sets; estream << automaton_stats.number_of_acceptance_sets;
restoreStreamFormatting(stream); restoreStreamFormatting(stream);
changeStreamFormatting(stream, 9, 0, ios::right);
estream << automaton_stats.nondeterminism_index;
restoreStreamFormatting(stream);
} }
estream << ' '; estream << ' ';
} }
@ -148,6 +152,11 @@ void printBuchiAutomatonStats
+ '\n' + string(indent, ' ') + "acceptance sets:" + '\n' + string(indent, ' ') + "acceptance sets:"
+ string(7, ' ') + string(7, ' ')
+ toString(automaton_stats.number_of_acceptance_sets) + toString(automaton_stats.number_of_acceptance_sets)
+ '\n' + string(indent, ' ') + "is deterministic:"
+ string(6, ' ')
+ (automaton_stats.is_deterministic?"Yes":"No")
+ '\n' + string(indent, ' ') + "nondeterminism index: "
+ toString(automaton_stats.nondeterminism_index)
+ '\n' + string(indent, ' ') + "computation time:" + '\n' + string(indent, ' ') + "computation time:"
+ string(6, ' '); + string(6, ' ');
@ -1089,6 +1098,8 @@ void printCollectiveStats(ostream& stream, int indent)
unsigned long int number_of_successful_instances; unsigned long int number_of_successful_instances;
BIGUINT total_number_of_states; BIGUINT total_number_of_states;
BIGUINT total_number_of_transitions; BIGUINT total_number_of_transitions;
BIGUINT total_nondeterminism_index;
int total_deterministic_count;
const TestStatistics& stats = final_statistics[algorithm]; const TestStatistics& stats = final_statistics[algorithm];
@ -1243,14 +1254,18 @@ void printCollectiveStats(ostream& stream, int indent)
double buchi_generation_time; double buchi_generation_time;
estream << '\n' + string(22 + indent, ' ') estream << '\n' + string(22 + indent, ' ')
+ "| Number of | Time consumed |\n" + "| Number of | Time consumed |"
+ " Number of | Nondeterminism |\n"
+ string(22 + indent, ' ') + string(22 + indent, ' ')
+ "| acceptance sets | (seconds) |\n" + "| acceptance sets | (seconds) |"
+ " determ. aut | index |\n"
+ string(7 + indent, ' ') + string(15, '-') + '+'; + string(7 + indent, ' ') + string(15, '-') + '+';
for (int j = 0; j < 2; j++) for (int j = 0; j < 3; j++)
estream << string(17, '-') + '+'; estream << string(17, '-') + '+';
estream << string(16, '-') + '+';
for (int j = 0; j < 3; j++) for (int j = 0; j < 3; j++)
{ {
estream << '\n' + string(8 + indent, ' '); estream << '\n' + string(8 + indent, ' ');
@ -1273,6 +1288,10 @@ void printCollectiveStats(ostream& stream, int indent)
buchi_generation_time = stats.total_buchi_generation_time[j]; buchi_generation_time = stats.total_buchi_generation_time[j];
total_number_of_acceptance_sets total_number_of_acceptance_sets
= stats.total_number_of_acceptance_sets[j]; = stats.total_number_of_acceptance_sets[j];
total_deterministic_count
= stats.total_deterministic_count[j];
total_nondeterminism_index
= stats.total_nondeterminism_index[j];
} }
else else
{ {
@ -1292,6 +1311,12 @@ void printCollectiveStats(ostream& stream, int indent)
total_number_of_acceptance_sets total_number_of_acceptance_sets
= stats.total_number_of_acceptance_sets[0] = stats.total_number_of_acceptance_sets[0]
+ stats.total_number_of_acceptance_sets[1]; + stats.total_number_of_acceptance_sets[1];
total_deterministic_count
= stats.total_deterministic_count[0]
+ stats.total_deterministic_count[1];
total_nondeterminism_index
= stats.total_nondeterminism_index[0]
+ stats.total_nondeterminism_index[1];
} }
number_of_successful_instances = number_of_successful_instances =
@ -1331,6 +1356,40 @@ void printCollectiveStats(ostream& stream, int indent)
restoreStreamFormatting(stream); restoreStreamFormatting(stream);
} }
estream << " | ";
if (number_of_successful_instances == 0)
estream << string(15, ' ');
else
{
changeStreamFormatting(stream, 15, 2,
ios::fixed | ios::right);
if (z == 0)
estream << total_deterministic_count;
else
estream << total_deterministic_count
/ static_cast<double>
(number_of_successful_instances);
restoreStreamFormatting(stream);
}
estream << " | ";
if (number_of_successful_instances == 0)
estream << string(14, ' ');
else
{
changeStreamFormatting(stream, 14, 2,
ios::fixed | ios::right);
if (z == 0)
estream << total_nondeterminism_index;
else
estream << total_nondeterminism_index
/ static_cast<double>
(number_of_successful_instances);
restoreStreamFormatting(stream);
}
estream << " |"; estream << " |";
if (z == 0) if (z == 0)
estream << '\n' + string(indent + 15, ' ') + "(avg.) | "; estream << '\n' + string(indent + 15, ' ') + "(avg.) | ";

View file

@ -1336,6 +1336,10 @@ void generateBuchiAutomaton
automaton_stats.number_of_buchi_transitions = buchi_stats.second; automaton_stats.number_of_buchi_transitions = buchi_stats.second;
automaton_stats.number_of_acceptance_sets automaton_stats.number_of_acceptance_sets
= automaton_stats.buchi_automaton->numberOfAcceptanceSets(); = automaton_stats.buchi_automaton->numberOfAcceptanceSets();
automaton_stats.nondeterminism_index
= automaton_stats.buchi_automaton->nondeterminismIndex();
automaton_stats.is_deterministic
= automaton_stats.buchi_automaton->isDeterministic();
/* /*
* Update Büchi automaton statistics for the given algorithm. * Update Büchi automaton statistics for the given algorithm.
@ -1347,6 +1351,10 @@ void generateBuchiAutomaton
+= automaton_stats.number_of_buchi_transitions; += automaton_stats.number_of_buchi_transitions;
final_statistics[algorithm_id].total_number_of_acceptance_sets[f] final_statistics[algorithm_id].total_number_of_acceptance_sets[f]
+= automaton_stats.number_of_acceptance_sets; += automaton_stats.number_of_acceptance_sets;
final_statistics[algorithm_id].total_nondeterminism_index[f]
+= automaton_stats.nondeterminism_index;
if (automaton_stats.is_deterministic)
final_statistics[algorithm_id].total_deterministic_count[f]++;
if (final_statistics[algorithm_id].total_buchi_generation_time[f] < 0.0 if (final_statistics[algorithm_id].total_buchi_generation_time[f] < 0.0
|| automaton_stats.buchi_generation_time < 0.0) || automaton_stats.buchi_generation_time < 0.0)

View file

@ -84,6 +84,7 @@ void AlgorithmTestResults::fullReset()
automaton_stats[i].number_of_buchi_transitions = 0; automaton_stats[i].number_of_buchi_transitions = 0;
automaton_stats[i].number_of_acceptance_sets = 0; automaton_stats[i].number_of_acceptance_sets = 0;
automaton_stats[i].number_of_msccs = 0; automaton_stats[i].number_of_msccs = 0;
automaton_stats[i].nondeterminism_index = 0;
automaton_stats[i].buchi_generation_time = 0.0; automaton_stats[i].buchi_generation_time = 0.0;
for (vector<int>::iterator it for (vector<int>::iterator it

View file

@ -102,6 +102,13 @@ struct AutomatonStats
* automaton. * automaton.
*/ */
unsigned long int nondeterminism_index; /* Nondeterminism index
*/
bool is_deterministic; /* True if the automaton
* is deterministic
*/
double buchi_generation_time; /* Time used to generate a double buchi_generation_time; /* Time used to generate a
* Büchi automaton. * Büchi automaton.
*/ */
@ -284,6 +291,14 @@ struct TestStatistics
* automata. * automata.
*/ */
BIGUINT total_nondeterminism_index[2]; /* Total nondetereminism
* index for all the
* generated Büchi automata.
*/
int total_deterministic_count[2]; /* Total number of
* deterministic automata
*/
double total_buchi_generation_time[2]; /* Total time used when double total_buchi_generation_time[2]; /* Total time used when
* generating Büchi * generating Büchi
* automata. * automata.
@ -349,10 +364,10 @@ struct TestStatistics
inline AutomatonStats::AutomatonStats inline AutomatonStats::AutomatonStats
(vector<Configuration::AlgorithmInformation>::size_type number_of_algorithms, (vector<Configuration::AlgorithmInformation>::size_type number_of_algorithms,
StateSpace::size_type max_statespace_size) : StateSpace::size_type max_statespace_size) :
buchi_automaton(0), number_of_buchi_states(0), buchi_automaton(0), number_of_buchi_states(0), nondeterminism_index(0),
number_of_buchi_transitions(0), number_of_acceptance_sets(0), number_of_buchi_transitions(0), number_of_acceptance_sets(0),
number_of_msccs(0), buchi_generation_time(0.0), number_of_product_states(0), number_of_msccs(0), buchi_generation_time(0.0), number_of_product_states(0),
number_of_product_transitions(1), number_of_product_transitions(1), is_deterministic(false),
emptiness_check_result(max_statespace_size), emptiness_check_result(max_statespace_size),
emptiness_check_performed(false), emptiness_check_performed(false),
cross_comparison_stats(number_of_algorithms, make_pair(false, 0)), cross_comparison_stats(number_of_algorithms, make_pair(false, 0)),
@ -541,6 +556,8 @@ inline TestStatistics::TestStatistics
total_number_of_buchi_states[i] = 0; total_number_of_buchi_states[i] = 0;
total_number_of_buchi_transitions[i] = 0; total_number_of_buchi_transitions[i] = 0;
total_number_of_acceptance_sets[i] = 0; total_number_of_acceptance_sets[i] = 0;
total_nondeterminism_index[i] = 0;
total_deterministic_count[i] = 0;
total_number_of_product_states[i] = 0; total_number_of_product_states[i] = 0;
total_number_of_product_transitions[i] = 0; total_number_of_product_transitions[i] = 0;
total_buchi_generation_time[i] = 0.0; total_buchi_generation_time[i] = 0.0;