Commit 08c77318 authored by Thomas Badie's avatar Thomas Badie Committed by Alexandre Duret-Lutz
Browse files

Add the "don't care" simulation

* src/tgba/bddprint.cc, src/tgba/bddprint.hh: Add bdd_print_isop
that prints the bdd into a Irreductible Sum Of Product.
* src/tgbaalgos/dupexp.cc, src/tgbaalgos/dupexp.hh: Add a way to
know which states (in the input) is which (in the result).
* src/tgbaalgos/simulation.cc, src/tgbaalgos/simulation.hh: Add
the Don't Care Simulation and the Don't Care Iterated Simulation.
* src/tgbatest/ltl2tgba.cc, src/tgbatest/spotlbtt.test,
src/tgbatest/Makefile.am, src/tgbatest/sim.test: Test them.
* bench/ltl2tgba/algorithms, bench/ltl2tgba/README,
bench/ltl2tgba/algorithms: Add a way to bench the don't care
simulation.
parent 5796114e
...@@ -38,6 +38,13 @@ this benchmark. ...@@ -38,6 +38,13 @@ this benchmark.
The timeout value, common to the three benchmarks, is also set here. The timeout value, common to the three benchmarks, is also set here.
You can also benchmark some simulations algorithms by setting the
variable "BENCH_SIMULATION". For example by running:
BENCH_SIMULATION=t make -j3 run
You run the simulation benchmark on the three kind of formulae.
* small * small
* big * big
* known * known
......
...@@ -4,18 +4,35 @@ ...@@ -4,18 +4,35 @@
# the tools starts with "-". # the tools starts with "-".
set dummy set dummy
if test -n "$BENCH_SIMULATION"; then
translator="../../src/tgbatest/ltl2tgba"
set "$@" "$translator -R3 -Rm -r7 -t %s >%T" \
"$translator -t -RDS -Rm -r7 -R3 %s >%T" \
"$translator -t -RDCS -r7 -Rm -R3 %s >%T" \
"$translator -t -RRS -r7 -R3 -Rm %s >%T" \
"$translator -t -RIS -r7 -R3 -Rm %s >%T" \
"$translator -t -RDCIS -r7 -Rm -R3 %s >%T" \
"$translator -t -R3 -Rm -r7 -DS %s >%T" \
"$translator -t -r7 -R3 -Rm -RDS -DS %s >%T" \
"$translator -t -RDCS -r7 -Rm -R3 -DS %s >%T" \
"$translator -t -RRS -r7 -R3 -Rm -DS %s >%T" \
"$translator -t -RIS -r7 -R3 -Rm -DS %s >%T" \
"$translator -t -RDCIS -r7 -R3 -Rm -DS %s >%T"
else
# Add third-party tools if they are available # Add third-party tools if they are available
test -n "$SPIN" && set "$@" "$SPIN -f %s >%N" test -n "$SPIN" && set "$@" "$SPIN -f %s >%N"
test -n "$LTL2BA" && set "$@" "$LTL2BA -f %s >%N" test -n "$LTL2BA" && set "$@" "$LTL2BA -f %s >%N"
test -n "$LTL3BA" && set "$@" "$LTL3BA -f %s >%N" \ test -n "$LTL3BA" && set "$@" "$LTL3BA -f %s >%N" \
"$LTL3BA -M -f %s >%N" \ "$LTL3BA -M -f %s >%N" \
"$LTL3BA -S -f %s >%N" \ "$LTL3BA -S -f %s >%N" \
"$LTL3BA -S -M -f %s >%N" "$LTL3BA -S -M -f %s >%N"
# Use -s to output a neverclaim, like the other tools. # Use -s to output a neverclaim, like the other tools.
set "$@" "$LTL2TGBA --det -s %s >%N" \ set "$@" "$LTL2TGBA --det -s %s >%N" \
"$LTL2TGBA --small -s %s >%N" "$LTL2TGBA --small -s %s >%N"
fi;
# If you want to add your own tool, you can add it here. # If you want to add your own tool, you can add it here.
# See 'man ltlcross' for the list of %-escape you may use # See 'man ltlcross' for the list of %-escape you may use
# to specify input formula and output automaton. # to specify input formula and output automaton.
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "bddprint.hh" #include "bddprint.hh"
#include "ltlvisit/tostring.hh" #include "ltlvisit/tostring.hh"
#include "formula2bdd.hh" #include "formula2bdd.hh"
#include "misc/minato.hh"
namespace spot namespace spot
{ {
...@@ -242,4 +243,28 @@ namespace spot ...@@ -242,4 +243,28 @@ namespace spot
{ {
utf8 = true; utf8 = true;
} }
std::ostream&
bdd_print_isop(std::ostream& os, const bdd_dict* d, bdd b)
{
dict = d;
want_acc = true;
minato_isop isop(b);
bdd p;
while ((p = isop.next()) != bddfalse)
{
os << bdd_format_set(d, p);
}
return os;
}
std::string
bdd_format_isop(const bdd_dict* d, bdd b)
{
std::ostringstream os;
bdd_print_isop(os, d, b);
return os.str();
}
} }
...@@ -113,6 +113,23 @@ namespace spot ...@@ -113,6 +113,23 @@ namespace spot
/// \brief Enable UTF-8 output for bdd printers. /// \brief Enable UTF-8 output for bdd printers.
void enable_utf8(); void enable_utf8();
/// \brief Format a BDD as an irredundant sum of product.
/// \param dict The dictionary to use, to lookup variables.
/// \param b The BDD to print.
/// \return The BDD formated as a string.
std::string
bdd_format_isop(const bdd_dict* d, bdd b);
/// \brief Print a BDD as an irredundant sum of product.
/// \param os The output stream.
/// \param dict The dictionary to use, to lookup variables.
/// \param b The BDD to print.
std::ostream&
bdd_print_isop(std::ostream& os, const bdd_dict* d, bdd b);
} }
#endif // SPOT_TGBA_BDDPRINT_HH #endif // SPOT_TGBA_BDDPRINT_HH
...@@ -56,10 +56,31 @@ namespace spot ...@@ -56,10 +56,31 @@ namespace spot
out_->add_acceptance_conditions(t, si->current_acceptance_conditions()); out_->add_acceptance_conditions(t, si->current_acceptance_conditions());
} }
private: protected:
tgba_explicit_number* out_; tgba_explicit_number* out_;
}; };
template <typename T>
class dupexp_iter_save: public dupexp_iter<T>
{
public:
dupexp_iter_save(const tgba* a,
std::map<const state*,
const state*,
state_ptr_less_than>& relation)
: dupexp_iter<T>(a),
relation_(relation)
{
}
void process_state(const state* s, int n, tgba_succ_iterator*)
{
relation_[this->out_->add_state(n)] = const_cast<state*>(s);
}
std::map<const state*, const state*, state_ptr_less_than>& relation_;
};
} // anonymous } // anonymous
tgba_explicit_number* tgba_explicit_number*
...@@ -78,4 +99,25 @@ namespace spot ...@@ -78,4 +99,25 @@ namespace spot
return di.result(); return di.result();
} }
tgba_explicit_number*
tgba_dupexp_bfs(const tgba* aut,
std::map<const state*,
const state*, state_ptr_less_than>& rel)
{
dupexp_iter_save<tgba_reachable_iterator_breadth_first> di(aut,
rel);
di.run();
return di.result();
}
tgba_explicit_number*
tgba_dupexp_dfs(const tgba* aut,
std::map<const state*,
const state*, state_ptr_less_than>& rel)
{
dupexp_iter_save<tgba_reachable_iterator_depth_first> di(aut,
rel);
di.run();
return di.result();
}
} }
...@@ -35,6 +35,21 @@ namespace spot ...@@ -35,6 +35,21 @@ namespace spot
/// numbering states in depth first order as they are processed. /// numbering states in depth first order as they are processed.
/// \ingroup tgba_misc /// \ingroup tgba_misc
tgba_explicit_number* tgba_dupexp_dfs(const tgba* aut); tgba_explicit_number* tgba_dupexp_dfs(const tgba* aut);
/// \brief Build an explicit automata from all states of \a aut,
/// numbering states in bread first order as they are processed.
/// \ingroup tgba_misc
tgba_explicit_number*
tgba_dupexp_bfs(const tgba* aut,
std::map<const state*, const state*,
state_ptr_less_than>& relation);
/// \brief Build an explicit automata from all states of \a aut,
/// numbering states in depth first order as they are processed.
/// \ingroup tgba_misc
tgba_explicit_number*
tgba_dupexp_dfs(const tgba* aut,
std::map<const state*, const state*,
state_ptr_less_than>& relation);
} }
#endif // SPOT_TGBAALGOS_DUPEXP_HH #endif // SPOT_TGBAALGOS_DUPEXP_HH
This diff is collapsed.
...@@ -133,6 +133,13 @@ namespace spot ...@@ -133,6 +133,13 @@ namespace spot
/// one /// one
tgba* iterated_simulations(const tgba* automaton); tgba* iterated_simulations(const tgba* automaton);
tgba* dont_care_simulation(const tgba* t, int limit = -1);
tgba*
dont_care_iterated_simulations(const tgba* t, int limit = -1);
/// @} /// @}
} // End namespace spot. } // End namespace spot.
......
...@@ -69,7 +69,6 @@ tripprod_SOURCES = tripprod.cc ...@@ -69,7 +69,6 @@ tripprod_SOURCES = tripprod.cc
# because such failures will be easier to diagnose and fix. # because such failures will be easier to diagnose and fix.
TESTS = \ TESTS = \
intvcomp.test \ intvcomp.test \
simdet.test \
eltl2tgba.test \ eltl2tgba.test \
explicit.test \ explicit.test \
explicit2.test \ explicit2.test \
...@@ -79,6 +78,8 @@ TESTS = \ ...@@ -79,6 +78,8 @@ TESTS = \
nondet.test \ nondet.test \
neverclaimread.test \ neverclaimread.test \
readsave.test \ readsave.test \
simdet.test \
sim.test \
ltl2tgba.test \ ltl2tgba.test \
ltl2neverclaim.test \ ltl2neverclaim.test \
ltl2neverclaim-lbtt.test \ ltl2neverclaim-lbtt.test \
......
...@@ -216,6 +216,8 @@ syntax(char* prog) ...@@ -216,6 +216,8 @@ syntax(char* prog)
<< std::endl << std::endl
<< " -RIS iterate both direct and reverse simulations" << " -RIS iterate both direct and reverse simulations"
<< std::endl << std::endl
<< " -RDCS reduce the automaton with direct simulation"
<< std::endl
<< " -Rm attempt to WDBA-minimize the automaton" << std::endl << " -Rm attempt to WDBA-minimize the automaton" << std::endl
<< std::endl << std::endl
<< " -RM attempt to WDBA-minimize the automaton unless the " << " -RM attempt to WDBA-minimize the automaton unless the "
...@@ -314,6 +316,17 @@ syntax(char* prog) ...@@ -314,6 +316,17 @@ syntax(char* prog)
exit(2); exit(2);
} }
static int
to_int(const char* s)
{
char* endptr;
int res = strtol(s, &endptr, 10);
if (*endptr)
return -1;
return res;
}
int int
main(int argc, char** argv) main(int argc, char** argv)
{ {
...@@ -374,6 +387,9 @@ main(int argc, char** argv) ...@@ -374,6 +387,9 @@ main(int argc, char** argv)
bool reduction_dir_sim = false; bool reduction_dir_sim = false;
bool reduction_rev_sim = false; bool reduction_rev_sim = false;
bool reduction_iterated_sim = false; bool reduction_iterated_sim = false;
bool reduction_dont_care_sim = false;
int limit_dont_care_sim = 0;
bool reduction_iterated_dont_care_sim = false;
spot::tgba* temp_dir_sim = 0; spot::tgba* temp_dir_sim = 0;
bool ta_opt = false; bool ta_opt = false;
bool tgta_opt = false; bool tgta_opt = false;
...@@ -382,7 +398,8 @@ main(int argc, char** argv) ...@@ -382,7 +398,8 @@ main(int argc, char** argv)
bool opt_with_artificial_livelock = false; bool opt_with_artificial_livelock = false;
spot::tgba* temp_rev_sim = 0; spot::tgba* temp_rev_sim = 0;
spot::tgba* temp_iterated_sim = 0; spot::tgba* temp_iterated_sim = 0;
spot::tgba* temp_dont_care_sim = 0;
spot::tgba* temp_dont_care_iterated_sim = 0;
for (;;) for (;;)
{ {
...@@ -721,6 +738,18 @@ main(int argc, char** argv) ...@@ -721,6 +738,18 @@ main(int argc, char** argv)
{ {
reduction_iterated_sim = true; reduction_iterated_sim = true;
} }
else if (!strncmp(argv[formula_index], "-RDCS", 5))
{
reduction_dont_care_sim = true;
if (argv[formula_index][5] == '=')
limit_dont_care_sim = to_int(argv[formula_index] + 6);
}
else if (!strncmp(argv[formula_index], "-RDCIS", 6))
{
reduction_iterated_dont_care_sim = true;
if (argv[formula_index][6] == '=')
limit_dont_care_sim = to_int(argv[formula_index] + 7);
}
else if (!strcmp(argv[formula_index], "-rL")) else if (!strcmp(argv[formula_index], "-rL"))
{ {
simpltl = true; simpltl = true;
...@@ -1131,6 +1160,9 @@ main(int argc, char** argv) ...@@ -1131,6 +1160,9 @@ main(int argc, char** argv)
// When the minimization succeed, simulation is useless. // When the minimization succeed, simulation is useless.
reduction_dir_sim = false; reduction_dir_sim = false;
reduction_rev_sim = false; reduction_rev_sim = false;
reduction_iterated_dont_care_sim = false;
reduction_dont_care_sim = false;
reduction_iterated_sim = false;
assume_sba = true; assume_sba = true;
} }
} }
...@@ -1153,6 +1185,17 @@ main(int argc, char** argv) ...@@ -1153,6 +1185,17 @@ main(int argc, char** argv)
assume_sba = false; assume_sba = false;
} }
if (reduction_iterated_dont_care_sim)
{
tm.start("don't care iterated simulation");
temp_dont_care_iterated_sim
= spot::dont_care_iterated_simulations(a, limit_dont_care_sim);
a = temp_dont_care_iterated_sim;
tm.stop("don't care iterated simulation");
assume_sba = false;
}
if (reduction_iterated_sim) if (reduction_iterated_sim)
{ {
tm.start("Reduction w/ iterated simulations"); tm.start("Reduction w/ iterated simulations");
...@@ -1170,6 +1213,25 @@ main(int argc, char** argv) ...@@ -1170,6 +1213,25 @@ main(int argc, char** argv)
tm.stop("SCC-filter post-sim"); tm.stop("SCC-filter post-sim");
} }
if (reduction_dont_care_sim)
{
tm.start("don't care simulation");
temp_dont_care_sim
= spot::dont_care_simulation(a, limit_dont_care_sim);
a = temp_dont_care_sim;
tm.stop("don't care simulation");
if (scc_filter)
{
tm.start("SCC-filter on don't care");
a = spot::scc_filter(a, true);
delete temp_dont_care_sim;
temp_dont_care_sim = a;
tm.stop("SCC-filter on don't care");
}
assume_sba = false;
}
unsigned int n_acc = a->number_of_acceptance_conditions(); unsigned int n_acc = a->number_of_acceptance_conditions();
if (echeck_inst if (echeck_inst
&& degeneralize_opt == NoDegen && degeneralize_opt == NoDegen
...@@ -1673,6 +1735,8 @@ main(int argc, char** argv) ...@@ -1673,6 +1735,8 @@ main(int argc, char** argv)
delete temp_dir_sim; delete temp_dir_sim;
delete temp_rev_sim; delete temp_rev_sim;
delete temp_iterated_sim; delete temp_iterated_sim;
delete temp_dont_care_sim;
delete temp_dont_care_iterated_sim;
} }
else else
{ {
......
#! /bin/sh
# -*- coding: utf-8 -*-
# Copyright (C) 2013 Laboratoire de Recherche et Développement
# de l'Epita (LRDE).
#
# 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 3 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 this program. If not, see <http://www.gnu.org/licenses/>.
. ./defs
set -e
cat >in.tgba <<EOF
acc = "1";
"i", "x", "b",;
"i", "d2", "b",;
"x", "ed", "a", "1";
"ed", "ed", "a & b", "1";
"d2", "d", "a",;
"d", "d", "a", "1";
EOF
run 0 ../ltl2tgba -X -RDCS -b in.tgba > out.tgba
cat >expected.tgba <<EOF
acc = "1";
"1", "2", "b",;
"2", "2", "a", "1";
EOF
diff out.tgba expected.tgba
run 0 ../ltl2tgba -RDCIS -b XXXXGFa > out.tgba
cat >expected.tgba <<EOF
acc = "a";
"1", "1", "a", "a";
"1", "1", "!a",;
EOF
diff out.tgba expected.tgba
run 0 ../ltl2tgba -RDCIS -kt 'Fp U Gq' > out.tgba
cat >expected.tgba <<EOF
sub trans.: 12
transitions: 6
states: 3
nondeterministic states: 1
EOF
diff out.tgba expected.tgba
...@@ -182,6 +182,23 @@ Algorithm ...@@ -182,6 +182,23 @@ Algorithm
Enabled = yes Enabled = yes
} }
Algorithm
{
Name = "Spot (Couvreur -- FM), don't care simulation"
Path = "${LBTT_TRANSLATE}"
Parameters = "--spot '../ltl2tgba -F -f -t -RDCS -r4 -R3f'"
Enabled = yes
}
Algorithm
{
Name = "Spot (Couvreur -- FM), don't care iterated simulation"
Path = "${LBTT_TRANSLATE}"
Parameters = "--spot '../ltl2tgba -F -f -t -RDCIS -r4 -R3f'"
Enabled = yes
}
Algorithm Algorithm
{ {
Name = "Spot (Couvreur -- FM), cosimulated" Name = "Spot (Couvreur -- FM), cosimulated"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment