fix status of lbtt's subtree. Apparently it was messed up during the cvsimport
This commit is contained in:
parent
17f76e371f
commit
91df6cab77
77 changed files with 16272 additions and 6019 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -17,10 +17,6 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <deque>
|
||||
#include <stack>
|
||||
|
|
@ -96,7 +92,9 @@ BuchiAutomaton::BuchiAutomaton(const BuchiAutomaton& automaton) :
|
|||
++transition)
|
||||
connect(state,
|
||||
static_cast<const BuchiTransition*>(*transition)->targetNode(),
|
||||
static_cast<const BuchiTransition*>(*transition)->guard());
|
||||
static_cast<const BuchiTransition*>(*transition)->guard(),
|
||||
static_cast<const BuchiTransition*>(*transition)
|
||||
->acceptanceSets());
|
||||
|
||||
operator[](state).acceptanceSets().copy(automaton[state].acceptanceSets(),
|
||||
number_of_acceptance_sets);
|
||||
|
|
@ -133,7 +131,9 @@ BuchiAutomaton& BuchiAutomaton::operator=(const BuchiAutomaton& automaton)
|
|||
++transition)
|
||||
connect(state,
|
||||
static_cast<const BuchiTransition*>(*transition)->targetNode(),
|
||||
static_cast<const BuchiTransition*>(*transition)->guard());
|
||||
static_cast<const BuchiTransition*>(*transition)->guard(),
|
||||
static_cast<const BuchiTransition*>(*transition)
|
||||
->acceptanceSets());
|
||||
|
||||
operator[](state).acceptanceSets().copy
|
||||
(automaton[state].acceptanceSets(), number_of_acceptance_sets);
|
||||
|
|
@ -194,113 +194,13 @@ BuchiAutomaton::size_type BuchiAutomaton::expand(size_type node_count)
|
|||
return nodes.size() - 1;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
BuchiAutomaton* BuchiAutomaton::regularize() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Converts a generalized Büchi automaton (i.e., an automaton
|
||||
* with any number of accepting state sets) into an automaton
|
||||
* with only one set of accepting states.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A pointer to an equivalent BuchiAutomaton with exactly one
|
||||
* set of accepting states.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
/*
|
||||
* If `this' automaton already has exactly one set of accepting states,
|
||||
* return a copy of `this' automaton.
|
||||
*/
|
||||
|
||||
if (number_of_acceptance_sets == 1)
|
||||
return new BuchiAutomaton(*this);
|
||||
|
||||
/*
|
||||
* Otherwise construct the result using a depth-first search in `this'
|
||||
* automaton.
|
||||
*/
|
||||
|
||||
typedef pair<size_type, unsigned long int> ExpandedState;
|
||||
|
||||
BuchiAutomaton* result_automaton = new BuchiAutomaton(0, 0, 1);
|
||||
|
||||
if (empty())
|
||||
return result_automaton;
|
||||
|
||||
stack<ExpandedState, deque<ExpandedState, ALLOC(ExpandedState) > >
|
||||
states_to_process;
|
||||
|
||||
map<ExpandedState, size_type, less<ExpandedState>, ALLOC(size_type) >
|
||||
state_mapping;
|
||||
|
||||
const GraphEdgeContainer* transitions;
|
||||
|
||||
size_type result_source_state, result_target_state;
|
||||
map<ExpandedState, size_type, less<ExpandedState>, ALLOC(size_type) >
|
||||
::const_iterator check_state;
|
||||
|
||||
ExpandedState state = make_pair(initial_state, 0);
|
||||
|
||||
states_to_process.push(state);
|
||||
state_mapping[state] = result_automaton->expand();
|
||||
|
||||
while (!states_to_process.empty())
|
||||
{
|
||||
state = states_to_process.top();
|
||||
states_to_process.pop();
|
||||
|
||||
result_source_state = state_mapping[state];
|
||||
transitions = &operator[](state.first).edges();
|
||||
|
||||
if (number_of_acceptance_sets == 0
|
||||
|| operator[](state.first).acceptanceSets().test(state.second))
|
||||
{
|
||||
if (state.second == 0)
|
||||
(*result_automaton)[result_source_state].acceptanceSets().setBit(0);
|
||||
|
||||
if (number_of_acceptance_sets > 0)
|
||||
{
|
||||
++state.second;
|
||||
state.second %= number_of_acceptance_sets;
|
||||
}
|
||||
}
|
||||
|
||||
for (GraphEdgeContainer::const_iterator transition = transitions->begin();
|
||||
transition != transitions->end();
|
||||
++transition)
|
||||
{
|
||||
state.first = (*transition)->targetNode();
|
||||
|
||||
check_state = state_mapping.find(state);
|
||||
|
||||
if (check_state == state_mapping.end())
|
||||
{
|
||||
result_target_state = result_automaton->expand();
|
||||
state_mapping[state] = result_target_state;
|
||||
states_to_process.push(state);
|
||||
}
|
||||
else
|
||||
result_target_state = check_state->second;
|
||||
|
||||
result_automaton->connect(result_source_state, result_target_state,
|
||||
static_cast<const BuchiTransition*>
|
||||
(*transition)->guard());
|
||||
}
|
||||
}
|
||||
|
||||
return result_automaton;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void BuchiAutomaton::read(istream& input_stream)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Reads an automaton description (which may represent a
|
||||
* generalized Büchi automaton) from a stream and stores it
|
||||
* into the automaton object, converting it to a regular
|
||||
* Büchi automaton if necessary.
|
||||
* into the automaton object.
|
||||
*
|
||||
* Argument: input_stream -- A reference to an input stream.
|
||||
*
|
||||
|
|
@ -316,20 +216,63 @@ void BuchiAutomaton::read(istream& input_stream)
|
|||
|
||||
try
|
||||
{
|
||||
/*
|
||||
* Read in the number of states in the generalized Büchi automaton.
|
||||
*/
|
||||
/* Read the number of states in the generalized Büchi automaton. */
|
||||
|
||||
einput_stream >> number_of_states;
|
||||
|
||||
/*
|
||||
* If the automaton is empty, do nothing.
|
||||
*/
|
||||
/* If the automaton is empty, do nothing. */
|
||||
|
||||
if (number_of_states == 0)
|
||||
return;
|
||||
|
||||
einput_stream >> number_of_acceptance_sets;
|
||||
/*
|
||||
* Determine the number and placement of acceptance sets.
|
||||
* (Acceptance sets are described using strings described by the regular
|
||||
* expression [0-9]+(s|S|t|T)*, where the [0-9]+ part corresponds to the
|
||||
* number of the sets, and the (s|S|t|T)* part corresponds to the
|
||||
* placement of the sets -- s or S for states, t or T for transitions.
|
||||
* To retain compatibility with lbtt 1.0.x, the acceptance set placement
|
||||
* defaults to acceptance sets on states if is not given explicitly.)
|
||||
*/
|
||||
|
||||
bool acceptance_sets_on_states = false;
|
||||
bool acceptance_sets_on_transitions = false;
|
||||
|
||||
string tok;
|
||||
einput_stream >> tok;
|
||||
|
||||
string::size_type s_pos = string::npos;
|
||||
string::size_type t_pos = string::npos;
|
||||
string::size_type pos = tok.find_first_not_of("0123456789");
|
||||
if (pos == 0)
|
||||
throw AutomatonParseException
|
||||
("invalid specification for acceptance sets");
|
||||
|
||||
number_of_acceptance_sets = strtoul(tok.substr(0, pos).c_str(), 0, 10);
|
||||
|
||||
for ( ; pos < tok.length(); ++pos)
|
||||
{
|
||||
if (tok[pos] == 's' || tok[pos] == 'S')
|
||||
{
|
||||
s_pos = pos;
|
||||
acceptance_sets_on_states = true;
|
||||
}
|
||||
else if (tok[pos] == 't' || tok[pos] == 'T')
|
||||
{
|
||||
t_pos = pos;
|
||||
acceptance_sets_on_transitions = true;
|
||||
}
|
||||
else
|
||||
throw AutomatonParseException
|
||||
("invalid specification for acceptance sets");
|
||||
}
|
||||
if (s_pos == string::npos && t_pos == string::npos)
|
||||
{
|
||||
acceptance_sets_on_states = true;
|
||||
acceptance_sets_on_transitions = false;
|
||||
}
|
||||
|
||||
BitArray acc_sets(number_of_acceptance_sets);
|
||||
|
||||
/*
|
||||
* Allocate space for the regular Büchi automaton that will be constructed
|
||||
|
|
@ -345,27 +288,20 @@ void BuchiAutomaton::read(istream& input_stream)
|
|||
* to the interval [0...(number of states - 1)].
|
||||
*/
|
||||
|
||||
map<long int, size_type, less<long int>, ALLOC(size_type) >
|
||||
state_number_map;
|
||||
map<long int, size_type> state_number_map;
|
||||
pair<long int, size_type> state_mapping(0, 0);
|
||||
|
||||
pair<map<long int, size_type, less<long int>, ALLOC(size_type) >
|
||||
::const_iterator,
|
||||
bool>
|
||||
state_finder;
|
||||
pair<map<long int, size_type>::const_iterator, bool> state_finder;
|
||||
|
||||
/*
|
||||
* Also the acceptance set numbers will be mapped to the interval
|
||||
* [0...(number of acceptance sets - 1)].
|
||||
*/
|
||||
|
||||
map<long int, unsigned long int, less<long int>, ALLOC(unsigned long int) >
|
||||
acceptance_set_map;
|
||||
map<long int, unsigned long int> acceptance_set_map;
|
||||
pair<long int, unsigned long int> acceptance_set_mapping(0, 0);
|
||||
|
||||
pair<map<long int, unsigned long int, less<long int>,
|
||||
ALLOC(unsigned long int) >::const_iterator,
|
||||
bool>
|
||||
pair<map<long int, unsigned long int>::const_iterator, bool>
|
||||
acceptance_set_finder;
|
||||
|
||||
/*
|
||||
|
|
@ -450,36 +386,41 @@ void BuchiAutomaton::read(istream& input_stream)
|
|||
operator[](current_state).acceptanceSets().clear
|
||||
(number_of_acceptance_sets);
|
||||
|
||||
while (1)
|
||||
if (acceptance_sets_on_states)
|
||||
{
|
||||
einput_stream >> acceptance_set_mapping.first;
|
||||
|
||||
if (acceptance_set_mapping.first == -1)
|
||||
break;
|
||||
|
||||
acceptance_set_finder =
|
||||
acceptance_set_map.insert(acceptance_set_mapping);
|
||||
|
||||
if (!acceptance_set_finder.second)
|
||||
acceptance_set = (acceptance_set_finder.first)->second;
|
||||
else
|
||||
while (1)
|
||||
{
|
||||
if (acceptance_set_mapping.second >= number_of_acceptance_sets)
|
||||
throw AutomatonParseException("number of acceptance sets "
|
||||
"does not match automaton state "
|
||||
"definitions");
|
||||
einput_stream >> acceptance_set_mapping.first;
|
||||
|
||||
acceptance_set = acceptance_set_mapping.second;
|
||||
++acceptance_set_mapping.second;
|
||||
}
|
||||
if (acceptance_set_mapping.first == -1)
|
||||
break;
|
||||
|
||||
operator[](current_state).acceptanceSets().setBit(acceptance_set);
|
||||
acceptance_set_finder =
|
||||
acceptance_set_map.insert(acceptance_set_mapping);
|
||||
|
||||
if (!acceptance_set_finder.second)
|
||||
acceptance_set = (acceptance_set_finder.first)->second;
|
||||
else
|
||||
{
|
||||
if (acceptance_set_mapping.second >= number_of_acceptance_sets)
|
||||
throw AutomatonParseException("number of acceptance sets "
|
||||
"does not match automaton state "
|
||||
"definitions");
|
||||
|
||||
acceptance_set = acceptance_set_mapping.second;
|
||||
++acceptance_set_mapping.second;
|
||||
}
|
||||
|
||||
operator[](current_state).acceptanceSets().setBit(acceptance_set);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Process the transitions from the state to other states. Read a
|
||||
* target state id and add a mapping for it in the translation table if
|
||||
* necessary. Then, read the propositional formula guarding the
|
||||
* necessary. If the automaton is allowed to have acceptance sets
|
||||
* associated with transitions, read an additional list of acceptance
|
||||
* sets. Finally, read the propositional formula guarding the
|
||||
* transition and connect the current state to the target using the
|
||||
* guard formula.
|
||||
*/
|
||||
|
|
@ -505,6 +446,42 @@ void BuchiAutomaton::read(istream& input_stream)
|
|||
state_mapping.second++;
|
||||
}
|
||||
|
||||
acc_sets.clear(number_of_acceptance_sets);
|
||||
|
||||
/*
|
||||
* If automata with acceptance sets on transitions are accepted, read
|
||||
* the acceptance sets associated with the transition.
|
||||
*/
|
||||
|
||||
if (acceptance_sets_on_transitions)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
einput_stream >> acceptance_set_mapping.first;
|
||||
|
||||
if (acceptance_set_mapping.first == -1)
|
||||
break;
|
||||
|
||||
acceptance_set_finder =
|
||||
acceptance_set_map.insert(acceptance_set_mapping);
|
||||
|
||||
if (!acceptance_set_finder.second)
|
||||
acceptance_set = (acceptance_set_finder.first)->second;
|
||||
else
|
||||
{
|
||||
if (acceptance_set_mapping.second >= number_of_acceptance_sets)
|
||||
throw AutomatonParseException("number of acceptance sets "
|
||||
"does not match automaton state "
|
||||
"definitions");
|
||||
|
||||
acceptance_set = acceptance_set_mapping.second;
|
||||
++acceptance_set_mapping.second;
|
||||
}
|
||||
|
||||
acc_sets.setBit(acceptance_set);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
guard = ::Ltl::LtlFormula::read(input_stream);
|
||||
|
|
@ -520,7 +497,7 @@ void BuchiAutomaton::read(istream& input_stream)
|
|||
throw AutomatonParseException("illegal operators in guard formula");
|
||||
}
|
||||
|
||||
connect(current_state, neighbor_state, guard);
|
||||
connect(current_state, neighbor_state, guard, acc_sets);
|
||||
}
|
||||
|
||||
processed_states.setBit(current_state);
|
||||
|
|
@ -548,297 +525,6 @@ void BuchiAutomaton::read(istream& input_stream)
|
|||
}
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
BuchiAutomaton* BuchiAutomaton::intersect
|
||||
(const BuchiAutomaton& a1, const BuchiAutomaton& a2,
|
||||
map<size_type, StateIdPair, less<size_type>, ALLOC(StateIdPair) >*
|
||||
intersection_state_mapping)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Computes the intersection of two Büchi automata and returns
|
||||
* a pointer to the intersection of the two automata.
|
||||
*
|
||||
* Arguments: a1, a2 -- References to two constant
|
||||
* Büchi automata.
|
||||
* intersection_state_mapping -- An (optional) pointer to a
|
||||
* map which can be used to find
|
||||
* out the state identifiers of
|
||||
* the original automata to
|
||||
* which a particular state in
|
||||
* the intersection corresponds.
|
||||
*
|
||||
* Returns: A newly allocated BuchiAutomaton representing the
|
||||
* intersection of the two automata.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (intersection_state_mapping != 0)
|
||||
intersection_state_mapping->clear();
|
||||
|
||||
/*
|
||||
* If either of the original automata is empty, the intersection is also
|
||||
* empty.
|
||||
*/
|
||||
|
||||
if (a1.empty() || a2.empty())
|
||||
return new BuchiAutomaton(0, 0, 0);
|
||||
|
||||
BuchiAutomaton* automaton;
|
||||
|
||||
/*
|
||||
* Determine the number of acceptance sets in the intersection.
|
||||
*/
|
||||
|
||||
const bool a1_has_no_acceptance_sets = (a1.number_of_acceptance_sets == 0);
|
||||
const bool a2_has_no_acceptance_sets = (a2.number_of_acceptance_sets == 0);
|
||||
|
||||
unsigned long int number_of_intersection_acceptance_sets;
|
||||
|
||||
if (a1_has_no_acceptance_sets && a2_has_no_acceptance_sets)
|
||||
number_of_intersection_acceptance_sets = 0;
|
||||
else
|
||||
number_of_intersection_acceptance_sets = a1.number_of_acceptance_sets
|
||||
+ a2.number_of_acceptance_sets;
|
||||
|
||||
automaton = new BuchiAutomaton(1, 0, number_of_intersection_acceptance_sets);
|
||||
|
||||
/*
|
||||
* A stack for processing pairs of states of the original automata.
|
||||
*/
|
||||
|
||||
stack<const StateIdPair*, deque<const StateIdPair*,
|
||||
ALLOC(const StateIdPair*) > >
|
||||
unprocessed_states;
|
||||
|
||||
/*
|
||||
* `state_mapping' maps pairs of states of the original automata to the
|
||||
* states of the new automaton.
|
||||
*/
|
||||
|
||||
map<StateIdPair, size_type, less<StateIdPair>, ALLOC(size_type) >
|
||||
state_mapping;
|
||||
|
||||
size_type first_free_id = 1; /* First free identifier for a
|
||||
* new state in the intersection
|
||||
* automaton.
|
||||
*/
|
||||
|
||||
const StateIdPair* state_pair; /* Pointer to pair of two state
|
||||
* identifiers of the original
|
||||
* automata.
|
||||
*/
|
||||
|
||||
size_type intersect_state; /* `Current' state in the
|
||||
* intersection automaton.
|
||||
*/
|
||||
|
||||
bool intersect_state_valid; /* True if the current state has
|
||||
* been determined by using the
|
||||
* mapping.
|
||||
*/
|
||||
|
||||
BitArray* intersect_acceptance_sets; /* Pointers for accessing the */
|
||||
const BitArray* acceptance_sets; /* acceptance sets of the new
|
||||
* and the original automata.
|
||||
*/
|
||||
|
||||
const GraphEdgeContainer* transitions1; /* Pointers for accessing the */
|
||||
const GraphEdgeContainer* transitions2; /* transitions of the two
|
||||
* original automata.
|
||||
*/
|
||||
|
||||
::Ltl::LtlFormula* guard1; /* Pointers for accessing the */
|
||||
::Ltl::LtlFormula* guard2; /* guard formulas of the */
|
||||
::Ltl::LtlFormula* new_guard; /* transitions of the
|
||||
* automata.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Insert the initial state into the state mapping.
|
||||
*/
|
||||
|
||||
state_mapping.insert(make_pair(make_pair(a1.initial_state, a2.initial_state),
|
||||
0));
|
||||
unprocessed_states.push(&(state_mapping.begin()->first));
|
||||
|
||||
/*
|
||||
* Adjust the acceptance sets of the initial state of the intersection.
|
||||
*/
|
||||
|
||||
intersect_acceptance_sets = &((*automaton)[0].acceptanceSets());
|
||||
|
||||
if (!a1_has_no_acceptance_sets)
|
||||
{
|
||||
acceptance_sets = &(a1[a1.initial_state].acceptanceSets());
|
||||
|
||||
for (unsigned long int accept_set = 0;
|
||||
accept_set < a1.number_of_acceptance_sets;
|
||||
accept_set++)
|
||||
{
|
||||
if (acceptance_sets->test(accept_set))
|
||||
intersect_acceptance_sets->setBit(accept_set);
|
||||
}
|
||||
}
|
||||
|
||||
if (!a2_has_no_acceptance_sets)
|
||||
{
|
||||
acceptance_sets = &(a2[a2.initial_state].acceptanceSets());
|
||||
|
||||
for (unsigned long int accept_set = 0;
|
||||
accept_set < a2.number_of_acceptance_sets;
|
||||
accept_set++)
|
||||
{
|
||||
if (acceptance_sets->test(accept_set))
|
||||
intersect_acceptance_sets->setBit(a1.number_of_acceptance_sets
|
||||
+ accept_set);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Pop pairs of states of the two original automata until all states have
|
||||
* been processed.
|
||||
*/
|
||||
|
||||
try
|
||||
{
|
||||
while (!unprocessed_states.empty())
|
||||
{
|
||||
if (::user_break)
|
||||
throw UserBreakException();
|
||||
|
||||
intersect_state_valid = false;
|
||||
state_pair = unprocessed_states.top();
|
||||
unprocessed_states.pop();
|
||||
|
||||
/*
|
||||
* Loop through the transitions of the two original automata. If the
|
||||
* conjunction of the guard formulae of any two transitions is
|
||||
* satisfiable, insert a new transition into the intersection automaton.
|
||||
* Create new states in the intersection automaton if necessary.
|
||||
*/
|
||||
|
||||
transitions1 = &a1[state_pair->first].edges();
|
||||
transitions2 = &a2[state_pair->second].edges();
|
||||
|
||||
for (GraphEdgeContainer::const_iterator tr1 = transitions1->begin();
|
||||
tr1 != transitions1->end();
|
||||
++tr1)
|
||||
{
|
||||
guard1 = &(static_cast<BuchiTransition*>(*tr1)->guard());
|
||||
|
||||
for (GraphEdgeContainer::const_iterator tr2 = transitions2->begin();
|
||||
tr2 != transitions2->end();
|
||||
++tr2)
|
||||
{
|
||||
guard2 = &(static_cast<BuchiTransition*>(*tr2)->guard());
|
||||
|
||||
new_guard = &Ltl::And::construct(*guard1, *guard2);
|
||||
|
||||
if (new_guard->satisfiable())
|
||||
{
|
||||
/*
|
||||
* Determine the `current' state of the intersection automaton.
|
||||
*/
|
||||
|
||||
if (!intersect_state_valid)
|
||||
{
|
||||
intersect_state = state_mapping[*state_pair];
|
||||
intersect_state_valid = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test whether the state pair pointed to by the two transitions
|
||||
* is already in the intersection.
|
||||
*/
|
||||
|
||||
pair<map<StateIdPair, size_type, less<StateIdPair>,
|
||||
ALLOC(size_type) >::iterator, bool>
|
||||
check_state;
|
||||
|
||||
check_state
|
||||
= state_mapping.insert(make_pair(make_pair((*tr1)->targetNode(),
|
||||
(*tr2)->targetNode()),
|
||||
first_free_id));
|
||||
|
||||
if (check_state.second) /* insertion occurred? */
|
||||
{
|
||||
automaton->expand();
|
||||
|
||||
/*
|
||||
* Determine the acceptance sets to which the new state in the
|
||||
* intersection automaton belongs.
|
||||
*/
|
||||
|
||||
intersect_acceptance_sets
|
||||
= &((*automaton)[first_free_id].acceptanceSets());
|
||||
|
||||
if (!a1_has_no_acceptance_sets)
|
||||
{
|
||||
acceptance_sets = &(a1[check_state.first->first.first].
|
||||
acceptanceSets());
|
||||
|
||||
for (unsigned long int accept_set = 0;
|
||||
accept_set < a1.number_of_acceptance_sets;
|
||||
accept_set++)
|
||||
{
|
||||
if (acceptance_sets->test(accept_set))
|
||||
intersect_acceptance_sets->setBit(accept_set);
|
||||
}
|
||||
}
|
||||
|
||||
if (!a2_has_no_acceptance_sets)
|
||||
{
|
||||
acceptance_sets = &(a2[check_state.first->first.second].
|
||||
acceptanceSets());
|
||||
|
||||
for (unsigned long int accept_set = 0;
|
||||
accept_set < a2.number_of_acceptance_sets;
|
||||
accept_set++)
|
||||
{
|
||||
if (acceptance_sets->test(accept_set))
|
||||
intersect_acceptance_sets->setBit
|
||||
(a1.number_of_acceptance_sets + accept_set);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect the `current' state of the intersection automaton to
|
||||
* the new state.
|
||||
*/
|
||||
|
||||
automaton->connect(intersect_state, first_free_id, new_guard);
|
||||
first_free_id++;
|
||||
unprocessed_states.push(&(check_state.first->first));
|
||||
}
|
||||
else
|
||||
automaton->connect(intersect_state, check_state.first->second,
|
||||
new_guard);
|
||||
}
|
||||
else
|
||||
::Ltl::LtlFormula::destruct(new_guard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (intersection_state_mapping != 0)
|
||||
{
|
||||
for (map<StateIdPair, size_type, less<StateIdPair>, ALLOC(size_type) >
|
||||
::const_iterator mapping = state_mapping.begin();
|
||||
mapping != state_mapping.end();
|
||||
++mapping)
|
||||
intersection_state_mapping->insert(make_pair(mapping->second,
|
||||
mapping->first));
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete automaton;
|
||||
throw;
|
||||
}
|
||||
|
||||
return automaton;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void BuchiAutomaton::print
|
||||
(ostream& stream, const int indent, const GraphOutputFormat fmt) const
|
||||
|
|
@ -880,7 +566,7 @@ void BuchiAutomaton::print
|
|||
<< " transitions.\n" + string(indent, ' ')
|
||||
+ "The automaton has "
|
||||
<< number_of_acceptance_sets
|
||||
<< " sets of accepting states.\n" + string(indent, ' ')
|
||||
<< " acceptance sets.\n" + string(indent, ' ')
|
||||
+ "The reachable part of the automaton contains\n"
|
||||
+ string(indent + 4, ' ')
|
||||
<< reachable_part_statistics.first
|
||||
|
|
@ -941,7 +627,8 @@ void BuchiAutomaton::print
|
|||
++transition)
|
||||
{
|
||||
estream << string(indent + 2, ' ') + 'n' << state;
|
||||
(*transition)->print(stream, indent, fmt);
|
||||
static_cast<const BuchiTransition*>(*transition)
|
||||
->print(stream, indent, fmt, number_of_acceptance_sets);
|
||||
estream << ";\n";
|
||||
}
|
||||
}
|
||||
|
|
@ -964,16 +651,23 @@ void BuchiAutomaton::print
|
|||
|
||||
/* ========================================================================= */
|
||||
void BuchiAutomaton::BuchiTransition::print
|
||||
(ostream& stream, const int indent, const GraphOutputFormat fmt) const
|
||||
(ostream& stream, const int indent, const GraphOutputFormat fmt,
|
||||
const unsigned long int number_of_acceptance_sets) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Writes information about a transition between two states of
|
||||
* a Büchi automaton.
|
||||
*
|
||||
* Arguments: stream -- A reference to an output stream.
|
||||
* indent -- Number of spaces to leave to the left of output.
|
||||
* fmt -- Determines the format of output.
|
||||
*
|
||||
* Arguments: stream -- A reference to an output
|
||||
* stream.
|
||||
* indent -- Number of spaces to leave to
|
||||
* the left of output.
|
||||
* fmt -- Determines the format of
|
||||
* output.
|
||||
* number_of_acceptance_sets -- Number of acceptance sets in
|
||||
* the automaton to which the
|
||||
* transition belongs.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
|
@ -981,11 +675,9 @@ void BuchiAutomaton::BuchiTransition::print
|
|||
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
|
||||
|
||||
if (fmt == NORMAL)
|
||||
{
|
||||
estream << string(indent, ' ') + "Transition to state "
|
||||
<< targetNode()
|
||||
<< " [ guard: " << *guard_formula << " ]\n";
|
||||
}
|
||||
<< " [ acc.: ";
|
||||
else if (fmt == DOT)
|
||||
{
|
||||
string formula(StringUtil::toString(*guard_formula));
|
||||
|
|
@ -1006,9 +698,33 @@ void BuchiAutomaton::BuchiTransition::print
|
|||
else
|
||||
estream << formula[i];
|
||||
}
|
||||
estream << "\",fontsize=10,fontname=\"Courier-Bold\"]";
|
||||
|
||||
estream << "\\n";
|
||||
}
|
||||
|
||||
estream << '{';
|
||||
bool first_printed = false;
|
||||
for (unsigned long int accept_set = 0;
|
||||
accept_set < number_of_acceptance_sets;
|
||||
++accept_set)
|
||||
{
|
||||
if (acceptance_sets[accept_set])
|
||||
{
|
||||
if (first_printed)
|
||||
estream << ", ";
|
||||
else
|
||||
first_printed = true;
|
||||
|
||||
estream << accept_set;
|
||||
}
|
||||
}
|
||||
estream << '}';
|
||||
|
||||
if (fmt == NORMAL)
|
||||
estream << ", guard: " << *guard_formula << " ]\n";
|
||||
else if (fmt == DOT)
|
||||
estream << "\",fontsize=10,fontname=\"Courier-Bold\"]";
|
||||
|
||||
estream.flush();
|
||||
}
|
||||
|
||||
|
|
@ -1073,7 +789,8 @@ void BuchiAutomaton::BuchiState::print
|
|||
GraphEdgeContainer::const_iterator edge;
|
||||
|
||||
for (edge = edges().begin(); edge != edges().end(); ++edge)
|
||||
(*edge)->print(stream, indent);
|
||||
static_cast<const BuchiAutomaton::BuchiTransition*>(*edge)
|
||||
->print(stream, indent, fmt, number_of_acceptance_sets);
|
||||
|
||||
} else
|
||||
estream << string(indent, ' ') + "No transitions to other states.\n";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue