Create the cosimulation.
* src/tgbaalgos/simulation.cc: Add the cosimulation: (acc_compl_automaton) Add a template parameter. (acc_compl_automaton::process_link) Add a swap source destination. (direct_simulation) Add a template parameter. (direct_simulation::compute_sig) Add a flag in the signature to know if the state is initial. (direct_simulation::build_result) Remove the flag before reading the signature. Swap source and destination when building the new automaton. * src/tgbaalgos/simulation.hh: Declare and document the Cosimulation. * src/tgbatest/ltl2tgba.cc: Associate the cosimulation with the -RRS option. * src/tgbatest/spotlbtt.test: Add a test on the cosimulation.
This commit is contained in:
parent
aa230d1f8b
commit
387bace98b
4 changed files with 137 additions and 38 deletions
|
|
@ -78,6 +78,13 @@
|
||||||
// bdd_support(sig(X)) - allacc - allclassvar
|
// bdd_support(sig(X)) - allacc - allclassvar
|
||||||
|
|
||||||
|
|
||||||
|
// We have had the Cosimulation by changing the acc_compl_automaton by
|
||||||
|
// adding a template parameter. If this parameter is set to true, we
|
||||||
|
// record the transition in the opposite direction (we just swap
|
||||||
|
// sources and destination). In the build result we are making the
|
||||||
|
// same thing to rebuild the automaton.
|
||||||
|
// In the signature,
|
||||||
|
|
||||||
namespace spot
|
namespace spot
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
|
|
@ -93,7 +100,6 @@ namespace spot
|
||||||
state_ptr_hash,
|
state_ptr_hash,
|
||||||
state_ptr_equal> map_state_unsigned;
|
state_ptr_equal> map_state_unsigned;
|
||||||
|
|
||||||
|
|
||||||
// Get the list of state for each class.
|
// Get the list of state for each class.
|
||||||
typedef std::map<bdd, std::list<const state*>,
|
typedef std::map<bdd, std::list<const state*>,
|
||||||
bdd_less_than> map_bdd_lstate;
|
bdd_less_than> map_bdd_lstate;
|
||||||
|
|
@ -101,6 +107,7 @@ namespace spot
|
||||||
|
|
||||||
// This class takes an automaton and creates a copy with all
|
// This class takes an automaton and creates a copy with all
|
||||||
// acceptance conditions complemented.
|
// acceptance conditions complemented.
|
||||||
|
template <bool Cosimulation>
|
||||||
class acc_compl_automaton:
|
class acc_compl_automaton:
|
||||||
public tgba_reachable_iterator_depth_first
|
public tgba_reachable_iterator_depth_first
|
||||||
{
|
{
|
||||||
|
|
@ -139,6 +146,15 @@ namespace spot
|
||||||
int src = get_state(in_s);
|
int src = get_state(in_s);
|
||||||
int dst = get_state(out_s);
|
int dst = get_state(out_s);
|
||||||
|
|
||||||
|
|
||||||
|
// In the case of the cosimulation, we want to have all the
|
||||||
|
// ingoing transition, and to keep the rest of the code
|
||||||
|
// similar, we just create equivalent transition in the other
|
||||||
|
// direction. Since we do not have to run through the
|
||||||
|
// automaton to get the signature, this is correct.
|
||||||
|
if (Cosimulation)
|
||||||
|
std::swap(src, dst);
|
||||||
|
|
||||||
bdd acc = ac_.complement(si->current_acceptance_conditions());
|
bdd acc = ac_.complement(si->current_acceptance_conditions());
|
||||||
|
|
||||||
tgba_explicit_number::transition* t
|
tgba_explicit_number::transition* t
|
||||||
|
|
@ -170,7 +186,7 @@ namespace spot
|
||||||
state* init_;
|
state* init_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <bool Cosimulation>
|
||||||
class direct_simulation
|
class direct_simulation
|
||||||
{
|
{
|
||||||
// Shortcut used in update_po and go_to_next_it.
|
// Shortcut used in update_po and go_to_next_it.
|
||||||
|
|
@ -181,7 +197,7 @@ namespace spot
|
||||||
po_size_(0),
|
po_size_(0),
|
||||||
all_class_var_(bddtrue)
|
all_class_var_(bddtrue)
|
||||||
{
|
{
|
||||||
acc_compl_automaton
|
acc_compl_automaton<Cosimulation>
|
||||||
acc_compl(t);
|
acc_compl(t);
|
||||||
|
|
||||||
// We'll start our work by replacing all the acceptance
|
// We'll start our work by replacing all the acceptance
|
||||||
|
|
@ -190,6 +206,8 @@ namespace spot
|
||||||
|
|
||||||
a_ = acc_compl.out_;
|
a_ = acc_compl.out_;
|
||||||
|
|
||||||
|
initial_state = a_->get_init_state();
|
||||||
|
|
||||||
// We use the previous run to know the size of the
|
// We use the previous run to know the size of the
|
||||||
// automaton, and to class all the reachable states in the
|
// automaton, and to class all the reachable states in the
|
||||||
// map previous_class_.
|
// map previous_class_.
|
||||||
|
|
@ -199,11 +217,10 @@ namespace spot
|
||||||
// class. We register one bdd by state, because in the worst
|
// class. We register one bdd by state, because in the worst
|
||||||
// case, |Class| == |State|.
|
// case, |Class| == |State|.
|
||||||
unsigned set_num = a_->get_dict()
|
unsigned set_num = a_->get_dict()
|
||||||
->register_anonymous_variables(size_a_, a_);
|
->register_anonymous_variables(size_a_ + 1, a_);
|
||||||
bdd init = bdd_ithvar(set_num);
|
|
||||||
|
|
||||||
// Because we have already take the first element which is init.
|
bdd_initial = bdd_ithvar(set_num++);
|
||||||
++set_num;
|
bdd init = bdd_ithvar(set_num++);
|
||||||
|
|
||||||
used_var_.push_back(init);
|
used_var_.push_back(init);
|
||||||
all_class_var_ = init;
|
all_class_var_ = init;
|
||||||
|
|
@ -258,12 +275,12 @@ namespace spot
|
||||||
it_s != it->second.end();
|
it_s != it->second.end();
|
||||||
++it_s)
|
++it_s)
|
||||||
{
|
{
|
||||||
// If the signature of a state is bddfalse (which is
|
// If the signature of a state is bddfalse (no
|
||||||
// roughly equivalent to no transition) the class of
|
// transitions) the class of this state is bddfalse
|
||||||
// this state is bddfalse instead of an anonymous
|
// instead of an anonymous variable. It allows
|
||||||
// variable. It allows simplifications in the signature
|
// simplifications in the signature by removing a
|
||||||
// by removing a transition which has as a destination a
|
// transition which has as a destination a state with
|
||||||
// state with no outgoing transition.
|
// no outgoing transition.
|
||||||
if (it->first == bddfalse)
|
if (it->first == bddfalse)
|
||||||
previous_class_[*it_s] = bddfalse;
|
previous_class_[*it_s] = bddfalse;
|
||||||
else
|
else
|
||||||
|
|
@ -315,10 +332,16 @@ namespace spot
|
||||||
dst->destroy();
|
dst->destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When we Cosimulate, we add a special flag to differentiate
|
||||||
|
// initial state.
|
||||||
|
if (Cosimulation && initial_state == src)
|
||||||
|
res |= bdd_initial;
|
||||||
|
|
||||||
delete sit;
|
delete sit;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void update_sig()
|
void update_sig()
|
||||||
{
|
{
|
||||||
// At this time, current_class_ must be empty. It implies
|
// At this time, current_class_ must be empty. It implies
|
||||||
|
|
@ -402,7 +425,6 @@ namespace spot
|
||||||
++it1)
|
++it1)
|
||||||
{
|
{
|
||||||
bdd accu = it1->second;
|
bdd accu = it1->second;
|
||||||
|
|
||||||
for (map_bdd_bdd::const_iterator it2 = now_to_next.begin();
|
for (map_bdd_bdd::const_iterator it2 = now_to_next.begin();
|
||||||
it2 != now_to_next.end();
|
it2 != now_to_next.end();
|
||||||
++it2)
|
++it2)
|
||||||
|
|
@ -476,6 +498,9 @@ namespace spot
|
||||||
// Get the signature.
|
// Get the signature.
|
||||||
bdd sig = compute_sig(*(it->second.begin()));
|
bdd sig = compute_sig(*(it->second.begin()));
|
||||||
|
|
||||||
|
if (Cosimulation)
|
||||||
|
sig = bdd_compose(sig, bddfalse, bdd_var(bdd_initial));
|
||||||
|
|
||||||
// Get all the variable in the signature.
|
// Get all the variable in the signature.
|
||||||
bdd sup_sig = bdd_support(sig);
|
bdd sup_sig = bdd_support(sig);
|
||||||
|
|
||||||
|
|
@ -495,7 +520,6 @@ namespace spot
|
||||||
bddtrue);
|
bddtrue);
|
||||||
all_atomic_prop -= one;
|
all_atomic_prop -= one;
|
||||||
|
|
||||||
|
|
||||||
// For each possible valuation, iterator over all possible
|
// For each possible valuation, iterator over all possible
|
||||||
// destination classes. We use minato_isop here, because
|
// destination classes. We use minato_isop here, because
|
||||||
// if the same valuation of atomic properties can go
|
// if the same valuation of atomic properties can go
|
||||||
|
|
@ -533,6 +557,9 @@ namespace spot
|
||||||
int src = bdd2state[previous_class_[*it->second.begin()]];
|
int src = bdd2state[previous_class_[*it->second.begin()]];
|
||||||
int dst = bdd2state[dest];
|
int dst = bdd2state[dest];
|
||||||
|
|
||||||
|
if (Cosimulation)
|
||||||
|
std::swap(src, dst);
|
||||||
|
|
||||||
// src or dst == 0 means "dest" or "prev..." isn't
|
// src or dst == 0 means "dest" or "prev..." isn't
|
||||||
// in the map. so it is a bug.
|
// in the map. so it is a bug.
|
||||||
assert(src != 0);
|
assert(src != 0);
|
||||||
|
|
@ -550,7 +577,9 @@ namespace spot
|
||||||
|
|
||||||
res->set_init_state(bdd2state[previous_class_
|
res->set_init_state(bdd2state[previous_class_
|
||||||
[a_->get_init_state()]]);
|
[a_->get_init_state()]]);
|
||||||
|
|
||||||
res->merge_transitions();
|
res->merge_transitions();
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -629,13 +658,29 @@ namespace spot
|
||||||
|
|
||||||
// All the class variable:
|
// All the class variable:
|
||||||
bdd all_class_var_;
|
bdd all_class_var_;
|
||||||
|
|
||||||
|
// The flag to say if the outgoing state is initial or not
|
||||||
|
bdd bdd_initial;
|
||||||
|
|
||||||
|
// Initial state of the automaton we are working on
|
||||||
|
state* initial_state;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End namespace anonymous.
|
} // End namespace anonymous.
|
||||||
|
|
||||||
tgba*
|
tgba*
|
||||||
simulation(const tgba* t)
|
simulation(const tgba* t)
|
||||||
{
|
{
|
||||||
direct_simulation simul(t);
|
direct_simulation<false> simul(t);
|
||||||
|
|
||||||
|
return simul.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
tgba*
|
||||||
|
cosimulation(const tgba* t)
|
||||||
|
{
|
||||||
|
direct_simulation<true> simul(t);
|
||||||
|
|
||||||
return simul.run();
|
return simul.run();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,11 @@ namespace spot
|
||||||
/// \addtogroup tgba_reduction
|
/// \addtogroup tgba_reduction
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// \brief Attempt to reduce the automaton by direct simulation
|
/// \brief Attempt to reduce the automaton by direct simulation When
|
||||||
///
|
/// the suffixes (letter and acceptance conditions) seen by one
|
||||||
/// When the language recognized by one state is included in the
|
/// state is included in the suffixes seen by another one, the first
|
||||||
/// language recognized by an another one, the first one is merged
|
/// one is merged with the second. The algorithm is based on the
|
||||||
/// with the second. The algorithm is based on the following
|
/// following paper, but generalized to handle TGBA directly.
|
||||||
/// paper, but generalized to handle TGBA directly.
|
|
||||||
///
|
///
|
||||||
/// \verbatim
|
/// \verbatim
|
||||||
/// @InProceedings{ etessami.00.concur,
|
/// @InProceedings{ etessami.00.concur,
|
||||||
|
|
@ -58,6 +57,34 @@ namespace spot
|
||||||
/// one
|
/// one
|
||||||
tgba* simulation(const tgba* automaton);
|
tgba* simulation(const tgba* automaton);
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Attempt to reduce the automaton by direct cosimulation.
|
||||||
|
/// When the prefixes (letter and acceptance conditions) seen by one
|
||||||
|
/// state is included in the prefixes seen by another one, the first
|
||||||
|
/// one is merged with the second. The algorithm is based on the
|
||||||
|
/// following paper, but generalized to handle TGBA directly.
|
||||||
|
/// \verbatim
|
||||||
|
/// @InProceedings{Somenzi:2000:EBA:647769.734097,
|
||||||
|
/// author = {Somenzi, Fabio and Bloem, Roderick},
|
||||||
|
/// title = {Efficient {B\"u}chi Automata from LTL Formulae},
|
||||||
|
/// booktitle = {Proceedings of the 12th International
|
||||||
|
/// Conference on Computer Aided Verification},
|
||||||
|
/// series = {CAV '00},
|
||||||
|
/// year = {2000},
|
||||||
|
/// isbn = {3-540-67770-4},
|
||||||
|
/// pages = {248--263},
|
||||||
|
/// numpages = {16},
|
||||||
|
/// url = {http://dl.acm.org/citation.cfm?id=647769.734097},
|
||||||
|
/// acmid = {734097},
|
||||||
|
/// publisher = {Springer-Verlag},
|
||||||
|
/// address = {London, UK, UK},
|
||||||
|
/// }
|
||||||
|
/// \endverbatim
|
||||||
|
/// \param automaton the automaton to simulate.
|
||||||
|
/// \return a new automaton which is at worst a copy of the received
|
||||||
|
/// one
|
||||||
|
tgba* cosimulation(const tgba* automaton);
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
} // End namespace spot.
|
} // End namespace spot.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -204,6 +204,8 @@ syntax(char* prog)
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< " -RDS minimize the automaton with direct simulation"
|
<< " -RDS minimize the automaton with direct simulation"
|
||||||
<< std::endl
|
<< std::endl
|
||||||
|
<< " -RRS minimize the automaton with reverse simulation"
|
||||||
|
<< std::endl
|
||||||
<< " -Rm attempt to WDBA-minimize the automata" << std::endl
|
<< " -Rm attempt to WDBA-minimize the automata" << std::endl
|
||||||
<< std::endl
|
<< std::endl
|
||||||
|
|
||||||
|
|
@ -352,13 +354,14 @@ main(int argc, char** argv)
|
||||||
bool use_timer = false;
|
bool use_timer = false;
|
||||||
bool assume_sba = false;
|
bool assume_sba = false;
|
||||||
bool reduction_dir_sim = false;
|
bool reduction_dir_sim = false;
|
||||||
|
bool reduction_rev_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;
|
||||||
bool opt_with_artificial_initial_state = true;
|
bool opt_with_artificial_initial_state = true;
|
||||||
bool opt_single_pass_emptiness_check = false;
|
bool opt_single_pass_emptiness_check = false;
|
||||||
bool opt_with_artificial_livelock = false;
|
bool opt_with_artificial_livelock = false;
|
||||||
|
spot::tgba* temp_rev_sim = 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
|
@ -631,6 +634,10 @@ main(int argc, char** argv)
|
||||||
// equal to -RDS.
|
// equal to -RDS.
|
||||||
reduction_dir_sim = true;
|
reduction_dir_sim = true;
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(argv[formula_index], "-RRS"))
|
||||||
|
{
|
||||||
|
reduction_rev_sim = true;
|
||||||
|
}
|
||||||
else if (!strcmp(argv[formula_index], "-R3"))
|
else if (!strcmp(argv[formula_index], "-R3"))
|
||||||
{
|
{
|
||||||
scc_filter = true;
|
scc_filter = true;
|
||||||
|
|
@ -1031,11 +1038,21 @@ main(int argc, char** argv)
|
||||||
a = minimized;
|
a = minimized;
|
||||||
// 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;
|
||||||
assume_sba = true;
|
assume_sba = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (reduction_rev_sim)
|
||||||
|
{
|
||||||
|
tm.start("Reduction w/ reverse simulation");
|
||||||
|
temp_rev_sim = spot::cosimulation(a);
|
||||||
|
a = temp_rev_sim;
|
||||||
|
tm.stop("Reduction w/ reverse simulation");
|
||||||
|
assume_sba = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (reduction_dir_sim)
|
if (reduction_dir_sim)
|
||||||
{
|
{
|
||||||
tm.start("Reduction w/ direct simulation");
|
tm.start("Reduction w/ direct simulation");
|
||||||
|
|
@ -1505,6 +1522,7 @@ main(int argc, char** argv)
|
||||||
delete to_free;
|
delete to_free;
|
||||||
delete echeck_inst;
|
delete echeck_inst;
|
||||||
delete temp_dir_sim;
|
delete temp_dir_sim;
|
||||||
|
delete temp_rev_sim;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,15 @@ Algorithm
|
||||||
Enabled = yes
|
Enabled = yes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Algorithm
|
||||||
|
{
|
||||||
|
Name = "Spot (Couvreur -- FM), cosimulated"
|
||||||
|
Path = "${LBTT_TRANSLATE}"
|
||||||
|
Parameters = "--spot '../ltl2tgba -F -f -t -RRS -r4 -R3'"
|
||||||
|
Enabled = yes
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Algorithm
|
Algorithm
|
||||||
{
|
{
|
||||||
Name = "Spot (Couvreur -- LaCim), simulated"
|
Name = "Spot (Couvreur -- LaCim), simulated"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue