Add 2 benchmarks directories.
Add an algorithm to split an automaton in several automata. * bench/scc-stats: New directory. Contains input files and test program for computing statistics. * bench/split-product: New directory. Contains test program for synchronised product on splitted automata. * bench/split-product/models: New directory. Contains Promela files and LTL formulae that should be verified by the models. * src/tgba/tgbafromfile.cc, src/tgba/tgbafromfile.hh: New files. Small class to avoid long initializations with numerous constants when translating to TGBA many LTL formulae from a given file. * src/tgbaalgos/cutscc.cc, src/tgbaalgos/cutscc.hh: New file. From a single automaton, create, at most, X sub automata. * src/tgbaalgos/scc.cc, src/tgbaalgos/scc.hh: Adjust to compute self-loops count.
This commit is contained in:
parent
a160b3504b
commit
414956c51e
35 changed files with 2989 additions and 5 deletions
32
bench/scc-stats/Makefile.am
Normal file
32
bench/scc-stats/Makefile.am
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
## Copyright (C) 2009 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||
## département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||
## et Marie Curie.
|
||||
##
|
||||
## This file is part of Spot, a model checking library.
|
||||
##
|
||||
## Spot is free software; you can redistribute it and/or modify it
|
||||
## under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation; either version 2 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
## License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with Spot; see the file COPYING. If not, write to the Free
|
||||
## Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
## 02111-1307, USA.
|
||||
|
||||
AM_CPPFLAGS = -I$(srcdir)/../../src $(BUDDY_CPPFLAGS)
|
||||
AM_CXXFLAGS = $(WARNING_CXXFLAGS)
|
||||
LDADD = ../../src/libspot.la
|
||||
|
||||
noinst_PROGRAMS = \
|
||||
stats
|
||||
|
||||
stats_SOURCES = stats.cc
|
||||
|
||||
bench: $(noinst_PROGRAMS)
|
||||
./stats $(srcdir)/formulae.ltl
|
||||
103
bench/scc-stats/README
Normal file
103
bench/scc-stats/README
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
This directory contains the input files and test program used to compute basic
|
||||
statistics on TGBA.
|
||||
|
||||
==========
|
||||
CONTENTS
|
||||
==========
|
||||
|
||||
This directory contains:
|
||||
|
||||
* formulae.ltl
|
||||
|
||||
A list of 96 handwritten formulae with their negations. They come
|
||||
from three sources:
|
||||
|
||||
@InProceedings{ dwyer.98.fmsp,
|
||||
author = {Matthew B. Dwyer and George S. Avrunin and James C.
|
||||
Corbett},
|
||||
title = {Property Specification Patterns for Finite-state
|
||||
Verification},
|
||||
booktitle = {Proceedings of the 2nd Workshop on Formal Methods in
|
||||
Software Practice (FMSP'98)},
|
||||
publisher = {ACM Press},
|
||||
address = {New York},
|
||||
editor = {Mark Ardis},
|
||||
month = mar,
|
||||
year = {1998},
|
||||
pages = {7--15}
|
||||
}
|
||||
|
||||
@InProceedings{ etessami.00.concur,
|
||||
author = {Kousha Etessami and Gerard J. Holzmann},
|
||||
title = {Optimizing {B\"u}chi Automata},
|
||||
booktitle = {Proceedings of the 11th International Conference on
|
||||
Concurrency Theory (Concur'00)},
|
||||
pages = {153--167},
|
||||
year = {2000},
|
||||
editor = {C. Palamidessi},
|
||||
volume = {1877},
|
||||
series = {Lecture Notes in Computer Science},
|
||||
address = {Pennsylvania, USA},
|
||||
publisher = {Springer-Verlag}
|
||||
}
|
||||
|
||||
@InProceedings{ somenzi.00.cav,
|
||||
author = {Fabio Somenzi and Roderick Bloem},
|
||||
title = {Efficient {B\"u}chi Automata for {LTL} Formul{\ae}},
|
||||
booktitle = {Proceedings of the 12th International Conference on
|
||||
Computer Aided Verification (CAV'00)},
|
||||
pages = {247--263},
|
||||
year = {2000},
|
||||
volume = {1855},
|
||||
series = {Lecture Notes in Computer Science},
|
||||
address = {Chicago, Illinois, USA},
|
||||
publisher = {Springer-Verlag}
|
||||
}
|
||||
|
||||
* full.ltl
|
||||
|
||||
A list of 1000 large randomly generated LTL formulae with ./randtgba.
|
||||
|
||||
=======
|
||||
USAGE
|
||||
=======
|
||||
|
||||
Use the stats program.
|
||||
Usage : ./stats ltl_file
|
||||
Where ltl_file is a file with a single LTL formula per line.
|
||||
|
||||
==========================
|
||||
INTERPRETING THE RESULTS
|
||||
==========================
|
||||
|
||||
Results can be found in file 'results'.
|
||||
Here is the list of the measured values:
|
||||
- Accepting Strongly Connected Components.
|
||||
Total number of accepting SCC.
|
||||
- Dead Strongly Connected Components.
|
||||
Total number of dead SCC.
|
||||
An SCC is dead if no accepting SCC is reachable from it.
|
||||
- Accepting Paths.
|
||||
Number of maximal accepting paths.
|
||||
An path is maximal and accepting if it ends in an accepting
|
||||
SCC that is only dead (i.e. non accepting) successors, or no
|
||||
successors at all.
|
||||
- Dead Paths.
|
||||
Number of paths to a terminal dead SCC.
|
||||
A terminal dead SCC is a dead SCC without successors.
|
||||
- Max Effective Splitting.
|
||||
A clue to measure the potential effectiveness of splitting the formula.
|
||||
This is the maximum number of possible sub automata with unique states.
|
||||
Beyond this threshold, more sub automata can be generated, but all their
|
||||
states will be included in some of the previous automata.
|
||||
- Self Loops per State.
|
||||
Number of self loops.
|
||||
A self loop is a transition from a state to itself.
|
||||
|
||||
For each of these measured value, we provide the following statistics
|
||||
computed on all the formulae in ltl_file:\
|
||||
- Min
|
||||
- Max
|
||||
- Mean
|
||||
- Median
|
||||
- Standard Deviation
|
||||
55
bench/scc-stats/formulae.ltl
Normal file
55
bench/scc-stats/formulae.ltl
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
[](!p0)
|
||||
<>p1 -> (!p0 U p1)
|
||||
[](p2 -> [](!p0))
|
||||
[]((p2 & !p1 & <>p1) -> (!p0 U p1))
|
||||
[](p2 & !p1 -> (!p0 U (p1 | []!p0)))
|
||||
<>(p0)
|
||||
!p1 U ((p0 & !p1) | []!p1)
|
||||
[](!p2) | <>(p2 & <>p0)
|
||||
[](p2 & !p1 -> (!p1 U ((p0 & !p1) | []!p1)))
|
||||
[](p2 & !p1 -> (!p1 U (p0 & !p1)))
|
||||
<>p1 -> ((!p0 & !p1) U (p1 | ((p0 & !p1) U (p1 | ((!p0 & !p1) U (p1 | ((p0 & !p1) U (p1 | (!p0 U p1)))))))))
|
||||
[]((p2 & <>p1) -> ((!p0 & !p1) U (p1 | ((p0 & !p1) U (p1 | ((!p0 & !p1) U (p1 | ((p0 & !p1) U (p1 | (!p0 U p1))))))))))
|
||||
[](p2 -> ((!p0 & !p1) U (p1 | ((p0 & !p1) U (p1 | ((!p0 & !p1) U (p1 | ((p0 & !p1) U (p1 | (!p0 U (p1 | []!p0)) | []p0)))))))))
|
||||
[](p0)
|
||||
<>p1 -> (p0 U p1)
|
||||
[](p2 -> [](p0))
|
||||
[]((p2 & !p1 & <>p1) -> (p0 U p1))
|
||||
[](p2 & !p1 -> (p0 U (p1 | [] p0)))
|
||||
!p0 U (p3 | []!p0)
|
||||
<>p1 -> (!p0 U (p3 | p1))
|
||||
[]!p2 | <>(p2 & (!p0 U (p3 | []!p0)))
|
||||
[]((p2 & !p1 & <>p1) -> (!p0 U (p3 | p1)))
|
||||
[](p2 & !p1 -> (!p0 U ((p3 | p1) | []!p0)))
|
||||
[](p0 -> <>p3)
|
||||
<>p1 -> (p0 -> (!p1 U (p3 & !p1))) U p1
|
||||
[](p2 -> [](p0 -> <>p3))
|
||||
[]((p2 & !p1 & <>p1) -> (p0 -> (!p1 U (p3 & !p1))) U p1)
|
||||
[](p2 & !p1 -> ((p0 -> (!p1 U (p3 & !p1))) U (p1 | [](p0 -> (!p1 U (p3 & !p1))))))
|
||||
<>p0 -> (!p0 U (p3 & !p0 & X(!p0 U p4)))
|
||||
<>p1 -> (!p0 U (p1 | (p3 & !p0 & X(!p0 U p4))))
|
||||
([]!p2) | (!p2 U (p2 & <>p0 -> (!p0 U (p3 & !p0 & X(!p0 U p4)))))
|
||||
[]((p2 & <>p1) -> (!p0 U (p1 | (p3 & !p0 & X(!p0 U p4)))))
|
||||
[](p2 -> (<>p0 -> (!p0 U (p1 | (p3 & !p0 & X(!p0 U p4))))))
|
||||
(<>(p3 & X<>p4)) -> ((!p3) U p0)
|
||||
<>p1 -> ((!(p3 & (!p1) & X(!p1 U (p4 & !p1)))) U (p1 | p0))
|
||||
([]!p2) | ((!p2) U (p2 & ((<>(p3 & X<>p4)) -> ((!p3) U p0))))
|
||||
[]((p2 & <>p1) -> ((!(p3 & (!p1) & X(!p1 U (p4 & !p1)))) U (p1 | p0)))
|
||||
[](p2 -> (!(p3 & (!p1) & X(!p1 U (p4 & !p1))) U (p1 | p0) | [](!(p3 & X<>p4))))
|
||||
[] (p3 & X<> p4 -> X(<>(p4 & <> p0)))
|
||||
<>p1 -> (p3 & X(!p1 U p4) -> X(!p1 U (p4 & <> p0))) U p1
|
||||
[] (p2 -> [] (p3 & X<> p4 -> X(!p4 U (p4 & <> p0))))
|
||||
[] ((p2 & <>p1) -> (p3 & X(!p1 U p4) -> X(!p1 U (p4 & <> p0))) U p1)
|
||||
[] (p2 -> (p3 & X(!p1 U p4) -> X(!p1 U (p4 & <> p0))) U (p1 | [] (p3 & X(!p1 U p4) -> X(!p1 U (p4 & <> p0)))))
|
||||
[] (p0 -> <>(p3 & X<>p4))
|
||||
<>p1 -> (p0 -> (!p1 U (p3 & !p1 & X(!p1 U p4)))) U p1
|
||||
[] (p2 -> [] (p0 -> (p3 & X<> p4)))
|
||||
[] ((p2 & <>p1) -> (p0 -> (!p1 U (p3 & !p1 & X(!p1 U p4)))) U p1)
|
||||
[] (p2 -> (p0 -> (!p1 U (p3 & !p1 & X(!p1 U p4)))) U (p1 | [] (p0 -> (p3 & X<> p4))))
|
||||
[] (p0 -> <>(p3 & !p5 & X(!p5 U p4)))
|
||||
<>p1 -> (p0 -> (!p1 U (p3 & !p1 & !p5 & X((!p1 & !p5) U p4)))) U p1
|
||||
[] (p2 -> [] (p0 -> (p3 & !p5 & X(!p5 U p4))))
|
||||
[] ((p2 & <>p1) -> (p0 -> (!p1 U (p3 & !p1 & !p5 & X((!p1 & !p5) U p4)))) U p1)
|
||||
[] (p2 -> (p0 -> (!p1 U (p3 & !p1 & !p5 & X((!p1 & !p5) U p4)))) U (p1 | [] (p0 -> (p3 & !p5 & X(!p5 U p4)))))
|
||||
!p0 U ((p0 U ((!p0 U ((p0 U ([]!p0 | []p0)) | []!p0)) | []!p0)) | []!p0)
|
||||
<>p2 -> (!p2 U (p2 & (!p0 U ((p0 U ((!p0 U ((p0 U ([]!p0 | []p0)) | []!p0)) | []!p0)) | []!p0))))
|
||||
204
bench/scc-stats/stats.cc
Normal file
204
bench/scc-stats/stats.cc
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Laboratoire
|
||||
// d'Informatique de Paris 6 (LIP6), département Systèmes Répartis
|
||||
// Coopératifs (SRC), Université Pierre et Marie Curie.
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Spot; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
// 02111-1307, USA.
|
||||
|
||||
#include <queue>
|
||||
#include <math.h>
|
||||
#include "tgbaalgos/scc.hh"
|
||||
#include "tgbaalgos/cutscc.hh"
|
||||
#include "tgba/tgbafromfile.hh"
|
||||
|
||||
namespace spot
|
||||
{
|
||||
unsigned tgba_size(const tgba* a)
|
||||
{
|
||||
typedef Sgi::hash_set<const state*,
|
||||
state_ptr_hash, state_ptr_equal> hash_type;
|
||||
hash_type seen;
|
||||
std::queue<state*> tovisit;
|
||||
// Perform breadth-first search.
|
||||
state* init = a->get_init_state();
|
||||
tovisit.push(init);
|
||||
seen.insert(init);
|
||||
unsigned count = 0;
|
||||
// While there are still states to visit.
|
||||
while (!tovisit.empty())
|
||||
{
|
||||
++count;
|
||||
state* cur = tovisit.front();
|
||||
tovisit.pop();
|
||||
tgba_succ_iterator* sit = a->succ_iter(cur);
|
||||
for (sit->first(); !sit->done(); sit->next())
|
||||
{
|
||||
state* dst = sit->current_state();
|
||||
// Is it a new state ?
|
||||
if (seen.find(dst) == seen.end())
|
||||
{
|
||||
// Yes, register the successor for later processing.
|
||||
tovisit.push(dst);
|
||||
seen.insert(dst);
|
||||
}
|
||||
else
|
||||
// No, free dst.
|
||||
delete dst;
|
||||
}
|
||||
delete sit;
|
||||
}
|
||||
hash_type::iterator it2;
|
||||
// Free visited states.
|
||||
for (it2 = seen.begin(); it2 != seen.end(); it2++)
|
||||
{
|
||||
delete *it2;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
void compute_and_print(std::vector<double>& v,
|
||||
int count, std::ofstream& output)
|
||||
{
|
||||
int i;
|
||||
double sum = 0.;
|
||||
double mean;
|
||||
double median;
|
||||
double variance = 0.;
|
||||
sum = 0;
|
||||
// Compute mean: sigma(Xi)/n for i=0..n-1.
|
||||
for (i = 0; i < count; i++)
|
||||
sum += v[i];
|
||||
mean = sum / count;
|
||||
// Compute variance: sigma((Xi - mean)*(Xi - mean))/n for i=0..n-1.
|
||||
for (i = 0; i < count; i++)
|
||||
variance += (v[i] - mean)*(v[i] - mean);
|
||||
variance = variance / count;
|
||||
// Compute median: mean of (n-th/2) value and ((n-th/2)+1) value if n even
|
||||
// else (n-th+1) value if n odd.
|
||||
if (count % 2 == 0)
|
||||
median = float(v[count/2] + v[(count/2)+1])/2;
|
||||
else
|
||||
median = v[(count+1)/2];
|
||||
output << "\tMin = " << v[0] << std::endl;
|
||||
output << "\tMax = " << v[count-1] << std::endl;
|
||||
output << "\tMean = " << mean << std::endl;
|
||||
output << "\tMedian = " << median << std::endl;
|
||||
output << "\tStandard Deviation = " << sqrt(variance) << std::endl;
|
||||
output << std::endl;
|
||||
}
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
std::cout << "Usage : ./stats file_name" << std::endl;
|
||||
std::cout << "There must be one LTL formula per line." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::ofstream output;
|
||||
output.open("results");
|
||||
spot::bdd_dict* dict = new spot::bdd_dict();
|
||||
unsigned count = 0;
|
||||
bool count_even;
|
||||
std::vector<double> acc_scc;
|
||||
std::vector<double> dead_scc;
|
||||
std::vector<double> acc_paths;
|
||||
std::vector<double> dead_paths;
|
||||
std::vector<double> spanning_paths;
|
||||
std::vector<double> self_loops;
|
||||
// Get each LTL formula.
|
||||
spot::ltl_file* formulae = new spot::ltl_file (argv[1], dict);
|
||||
formulae->begin();
|
||||
unsigned k = 0;
|
||||
do
|
||||
{
|
||||
++k;
|
||||
spot::tgba* a = formulae->current_automaton();
|
||||
// Get number of spanning paths.
|
||||
spot::scc_map m (a);
|
||||
m.build_map();
|
||||
spot::state* initial_state = a->get_init_state();
|
||||
unsigned init = m.scc_of_state(initial_state);
|
||||
delete initial_state;
|
||||
std::vector<std::vector<spot::sccs_set* > >* paths = find_paths(a, m);
|
||||
unsigned spanning_count =spot::max_spanning_paths(&(*paths)[init], m);
|
||||
spanning_paths.push_back(double(spanning_count));
|
||||
// Get characteristics from automaton.
|
||||
spot::scc_stats stat;
|
||||
stat = build_scc_stats(a);
|
||||
|
||||
// Add those characteristics to our arrays.
|
||||
acc_scc.push_back(double(stat.acc_scc));
|
||||
dead_scc.push_back(double(stat.dead_scc));
|
||||
acc_paths.push_back(double(stat.acc_paths));
|
||||
dead_paths.push_back(double(stat.dead_paths));
|
||||
self_loops.push_back(double(stat.self_loops)/tgba_size(a));
|
||||
++count;
|
||||
delete a;
|
||||
unsigned i;
|
||||
unsigned j;
|
||||
for (i = 0; i < paths->size(); ++i)
|
||||
for (j = 0; j < (*paths)[i].size(); ++j)
|
||||
delete (*paths)[i][j];
|
||||
delete paths;
|
||||
formulae->next();
|
||||
} while (!formulae->done());
|
||||
delete formulae;
|
||||
|
||||
// We could have inserted at the right place instead of
|
||||
// sorting at the end.
|
||||
// Sorting allows us to find the extrema and
|
||||
// the median of the distribution.
|
||||
sort(acc_scc.begin(), acc_scc.end());
|
||||
sort(dead_scc.begin(), dead_scc.end());
|
||||
sort(acc_paths.begin(), acc_paths.end());
|
||||
sort(spanning_paths.begin(), spanning_paths.end());
|
||||
sort(dead_paths.begin(), dead_paths.end());
|
||||
sort(self_loops.begin(), self_loops.end());
|
||||
count_even = (count % 2 == 0);
|
||||
output << "Parsed Formulae : " << count << std::endl << std::endl;
|
||||
|
||||
// Accepting SCCs
|
||||
output << "Accepting SCCs:" << std::endl;
|
||||
compute_and_print(acc_scc, count, output);
|
||||
|
||||
// Dead SCCs
|
||||
output << "Dead SCCs:" << std::endl;
|
||||
compute_and_print(dead_scc, count, output);
|
||||
|
||||
// Accepting Paths
|
||||
output << "Accepting Paths:" << std::endl;
|
||||
compute_and_print(acc_paths, count, output);
|
||||
|
||||
// Dead Paths
|
||||
output << "Dead Paths:" << std::endl;
|
||||
compute_and_print(dead_paths, count, output);
|
||||
|
||||
// Max Effective Splitting
|
||||
output << "Max effective splitting:" << std::endl;
|
||||
compute_and_print(spanning_paths, count, output);
|
||||
|
||||
// Self loops
|
||||
output << "Self loops per State:" << std::endl;
|
||||
compute_and_print(self_loops, count, output);
|
||||
|
||||
std::cout << "Statistics generated in file results." << std::endl;
|
||||
output.close();
|
||||
delete dict;
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue