From ebde3b29bad65253801426b6713c33a60c19292b Mon Sep 17 00:00:00 2001 From: Jan Travnicek <jan.travnicek@.fit.cvut.cz> Date: Mon, 3 Feb 2020 15:49:23 +0100 Subject: [PATCH] unranked tree automata bisimulation --- .../properties/BackwardBisimulation.cpp | 12 +++ .../properties/BackwardBisimulation.h | 80 +++++++++++++++++++ .../properties/DistinguishableStates.cpp | 6 ++ .../properties/DistinguishableStates.h | 44 ++++++++++ .../properties/ForwardBisimulation.cpp | 12 +++ .../properties/ForwardBisimulation.h | 69 ++++++++++++++++ 6 files changed, 223 insertions(+) diff --git a/alib2algo/src/automaton/properties/BackwardBisimulation.cpp b/alib2algo/src/automaton/properties/BackwardBisimulation.cpp index 0139fe58d0..51d1385a4a 100644 --- a/alib2algo/src/automaton/properties/BackwardBisimulation.cpp +++ b/alib2algo/src/automaton/properties/BackwardBisimulation.cpp @@ -34,4 +34,16 @@ auto BackwardBisimulationNFTA = registration::AbstractRegister < automaton::prop @param fta the examined automaton.\n\ @return set of pairs of states of the @p fta that are the backward bisimulation." ); +auto BackwardBisimulationUnorderedDFTA = registration::AbstractRegister < automaton::properties::BackwardBisimulation, ext::set < ext::pair < DefaultStateType, DefaultStateType > >, const automaton::UnorderedDFTA < > & > ( automaton::properties::BackwardBisimulation::backwardBisimulation, "fta" ).setDocumentation ( +"Computes a relation on states of the UnorderedDFTA satisfying the backward bisimulation definition.\n\ +\n\ +@param fta the examined automaton.\n\ +@return set of pairs of states of the @p fta that are the backward bisimulation." ); + +auto BackwardBisimulationUnorderedNFTA = registration::AbstractRegister < automaton::properties::BackwardBisimulation, ext::set < ext::pair < DefaultStateType, DefaultStateType > >, const automaton::UnorderedNFTA < > & > ( automaton::properties::BackwardBisimulation::backwardBisimulation, "fta" ).setDocumentation ( +"Computes a relation on states of the UnorderedNFTA satisfying the backward bisimulation definition.\n\ +\n\ +@param fta the examined automaton.\n\ +@return set of pairs of states of the @p fta that are the backward bisimulation." ); + } /* namespace */ diff --git a/alib2algo/src/automaton/properties/BackwardBisimulation.h b/alib2algo/src/automaton/properties/BackwardBisimulation.h index 9215c55e07..c8c1745384 100644 --- a/alib2algo/src/automaton/properties/BackwardBisimulation.h +++ b/alib2algo/src/automaton/properties/BackwardBisimulation.h @@ -30,6 +30,9 @@ #include <automaton/TA/DFTA.h> #include <automaton/TA/NFTA.h> +#include <automaton/TA/UnorderedDFTA.h> +#include <automaton/TA/UnorderedNFTA.h> + #include <automaton/FSM/DFA.h> #include <automaton/FSM/NFA.h> @@ -98,6 +101,26 @@ public: */ template < class SymbolType, class StateType > static ext::set < ext::pair < StateType, StateType > > backwardBisimulation ( const automaton::NFTA < SymbolType, StateType > & fta ); + + /** + * Computes a relation on states of the DFTA satisfying the backward bisimulation definition. + * + * @param fta the examined automaton + * + * @return set of pairs of states of the @p fta that are the backward bisimulation. + */ + template < class SymbolType, class StateType > + static ext::set < ext::pair < StateType, StateType > > backwardBisimulation ( const automaton::UnorderedDFTA < SymbolType, StateType > & fta ); + + /** + * Computes a relation on states of the NFTA satisfying the backward bisimulation definition. + * + * @param fta the examined automaton + * + * @return set of pairs of states of the @p fta that are the backward bisimulation. + */ + template < class SymbolType, class StateType > + static ext::set < ext::pair < StateType, StateType > > backwardBisimulation ( const automaton::UnorderedNFTA < SymbolType, StateType > & fta ); }; template < class SymbolType, class StateType > @@ -196,6 +219,63 @@ ext::set < ext::pair < StateType, StateType > > BackwardBisimulation::backwardBi return backwardBisimulation; } +template < class SymbolType, class StateType > +ext::set < ext::pair < StateType, StateType > > BackwardBisimulation::backwardBisimulation ( const automaton::UnorderedDFTA < SymbolType, StateType > & fta ) { + return backwardBisimulation ( UnorderedNFTA < SymbolType, StateType > ( fta ) ); +} + +template < class SymbolType, class StateType > +ext::set < ext::pair < StateType, StateType > > BackwardBisimulation::backwardBisimulation ( const automaton::UnorderedNFTA < SymbolType, StateType > & fta ) { + ext::set < ext::pair < StateType, StateType > > backwardBisimulation = initial ( fta.getStates ( ), { } ); + + bool changed; + do { + changed = false; + + for ( const StateType & p : fta.getStates ( ) ) { + for ( const StateType & q : fta.getStates ( ) ) { + if ( ! backwardBisimulation.contains ( ext::make_pair ( p, q ) ) ) + continue; + + for ( const std::pair < const ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > & pTransition : fta.getTransitionsToState ( p ) ) { + + ext::multiset < StateType > pSource; + for ( const StateType & state : pTransition.first.second ) { + auto lower = backwardBisimulation.lower_bound ( ext::slice_comp ( state ) ); + pSource.insert ( lower->second ); + } + + bool exists = false; + for ( const std::pair < const ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > & qTransition : fta.getTransitionsToState ( q ) ) { + if ( qTransition.first.first != pTransition.first.first ) + continue; + + ext::multiset < StateType > qSource; + for ( const StateType & state : qTransition.first.second ) { + auto lower = backwardBisimulation.lower_bound ( ext::slice_comp ( state ) ); + qSource.insert ( lower->second ); + } + + if ( pSource == qSource ) { + exists = true; + break; + } + } + + if ( ! exists ) { + backwardBisimulation.erase ( ext::make_pair ( p, q ) ); + backwardBisimulation.erase ( ext::make_pair ( q, p ) ); + changed = true; + break; + } + } + } + } + } while ( changed ); + + return backwardBisimulation; +} + } /* namespace properties */ } /* namespace automaton */ diff --git a/alib2algo/src/automaton/properties/DistinguishableStates.cpp b/alib2algo/src/automaton/properties/DistinguishableStates.cpp index e161aaf38c..43910bd8d2 100644 --- a/alib2algo/src/automaton/properties/DistinguishableStates.cpp +++ b/alib2algo/src/automaton/properties/DistinguishableStates.cpp @@ -22,4 +22,10 @@ auto DistinguishableStatesDFTA = registration::AbstractRegister < automaton::pro @param dfta finite tree automaton.\n\ @return set of pairs of distinguishable states" ); +auto DistinguishableStatesUnorderedDFTA = registration::AbstractRegister < automaton::properties::DistinguishableStates, ext::set < ext::pair < DefaultStateType, DefaultStateType > >, const automaton::UnorderedDFTA < > & > ( automaton::properties::DistinguishableStates::distinguishable, "fta" ).setDocumentation ( +"Computes the pairs of distinguishable states in given UnorderedDFTA.\n\ +\n\ +@param unordered dfta finite tree automaton.\n\ +@return set of pairs of distinguishable states" ); + } /* namespace */ diff --git a/alib2algo/src/automaton/properties/DistinguishableStates.h b/alib2algo/src/automaton/properties/DistinguishableStates.h index 0de068158c..fc01074ae0 100644 --- a/alib2algo/src/automaton/properties/DistinguishableStates.h +++ b/alib2algo/src/automaton/properties/DistinguishableStates.h @@ -30,6 +30,8 @@ #include <automaton/FSM/DFA.h> #include <automaton/TA/DFTA.h> +#include <automaton/TA/UnorderedDFTA.h> + namespace automaton { namespace properties { @@ -69,6 +71,9 @@ public: template < class SymbolType, class StateType > static ext::set < ext::pair < StateType, StateType > > distinguishable ( const automaton::DFTA < SymbolType, StateType > & fta ); + + template < class SymbolType, class StateType > + static ext::set < ext::pair < StateType, StateType > > distinguishable ( const automaton::UnorderedDFTA < SymbolType, StateType > & fta ); }; template < class SymbolType, class StateType > @@ -144,6 +149,45 @@ ext::set < ext::pair < StateType, StateType > > DistinguishableStates::distingui return distinguishable; } +template < class SymbolType, class StateType > +ext::set < ext::pair < StateType, StateType > > DistinguishableStates::distinguishable ( const automaton::UnorderedDFTA < SymbolType, StateType > & fta ) { + ext::set < ext::pair < StateType, StateType > > distinguishable = initial ( fta.getStates ( ), fta.getFinalStates ( ) ); + + bool changed; + do { + changed = false; + + for ( const StateType & a : fta.getStates ( ) ) { + for ( const StateType & b : fta.getStates ( ) ) { + if ( distinguishable.count ( ext::make_pair ( a, b ) ) ) + continue; + + for ( const std::pair < const ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > & transition : fta.getTransitions ( ) ) { + for ( const StateType & state : transition.first.second ) { + if ( state == a ) { + ext::multiset < StateType > copy = transition.first.second; + copy.erase ( copy.find ( state ) ); + copy.insert ( b ); + + const auto & transition2 = fta.getTransitions ( ).find ( std::make_pair ( transition.first.first, std::move ( copy ) ) ); + + if ( transition2 == fta.getTransitions ( ).end ( ) || distinguishable.count ( ext::make_pair ( transition.second, transition2->second ) ) ) { + // end up in dead state - dead state is be distinguishable from every other state OR + // end up in distinguishable states + distinguishable.insert ( ext::make_pair ( a, b ) ); + distinguishable.insert ( ext::make_pair ( b, a ) ); + changed = true; + } + } + } + } + } + } + } while ( changed ); + + return distinguishable; +} + } /* namespace properties */ } /* namespace automaton */ diff --git a/alib2algo/src/automaton/properties/ForwardBisimulation.cpp b/alib2algo/src/automaton/properties/ForwardBisimulation.cpp index 2ac86db876..de0566955c 100644 --- a/alib2algo/src/automaton/properties/ForwardBisimulation.cpp +++ b/alib2algo/src/automaton/properties/ForwardBisimulation.cpp @@ -34,4 +34,16 @@ auto ForwardBisimulationDFTA = registration::AbstractRegister < automaton::prope @param fta the examined automaton.\n\ @return set of pairs of states of the @p fta that are the forward bisimulation." ); +auto ForwardBisimulationUnorderedNFTA = registration::AbstractRegister < automaton::properties::ForwardBisimulation, ext::set < ext::pair < DefaultStateType, DefaultStateType > >, const automaton::UnorderedNFTA < > & > ( automaton::properties::ForwardBisimulation::forwardBisimulation, "fta" ).setDocumentation ( +"Computes a relation on states of the Unordered NFTA satisfying the forward bisimulation definition.\n\ +\n\ +@param fta the examined automaton.\n\ +@return set of pairs of states of the @p fta that are the forward bisimulation." ); + +auto ForwardBisimulationUnorderedDFTA = registration::AbstractRegister < automaton::properties::ForwardBisimulation, ext::set < ext::pair < DefaultStateType, DefaultStateType > >, const automaton::UnorderedDFTA < > & > ( automaton::properties::ForwardBisimulation::forwardBisimulation, "fta" ).setDocumentation ( +"Computes a relation on states of the Unordered DFTA satisfying the forward bisimulation definition.\n\ +\n\ +@param fta the examined automaton.\n\ +@return set of pairs of states of the @p fta that are the forward bisimulation." ); + } /* namespace */ diff --git a/alib2algo/src/automaton/properties/ForwardBisimulation.h b/alib2algo/src/automaton/properties/ForwardBisimulation.h index 963b37081d..74a4523041 100644 --- a/alib2algo/src/automaton/properties/ForwardBisimulation.h +++ b/alib2algo/src/automaton/properties/ForwardBisimulation.h @@ -29,6 +29,7 @@ #include <automaton/TA/DFTA.h> #include <automaton/TA/NFTA.h> +#include <automaton/TA/UnorderedNFTA.h> #include <automaton/FSM/DFA.h> #include <automaton/FSM/NFA.h> @@ -99,6 +100,26 @@ public: */ template < class SymbolType, class StateType > static ext::set < ext::pair < StateType, StateType > > forwardBisimulation ( const automaton::NFTA < SymbolType, StateType > & fta ); + + /** + * Computes a relation on states of the DFTA satisfying the forward bisimulation definition. + * + * @param fta the examined automaton + * + * @return set of pairs of states of the @p fta that are the forward bisimulation. + */ + template < class SymbolType, class StateType > + static ext::set < ext::pair < StateType, StateType > > forwardBisimulation ( const automaton::UnorderedDFTA < SymbolType, StateType > & fta ); + + /** + * Computes a relation on states of the NFTA satisfying the forward bisimulation definition. + * + * @param fta the examined automaton + * + * @return set of pairs of states of the @p fta that are the forward bisimulation. + */ + template < class SymbolType, class StateType > + static ext::set < ext::pair < StateType, StateType > > forwardBisimulation ( const automaton::UnorderedNFTA < SymbolType, StateType > & fta ); }; template < class SymbolType, class StateType > @@ -190,6 +211,54 @@ ext::set < ext::pair < StateType, StateType > > ForwardBisimulation::forwardBisi return forwardBisimulation; } +template < class SymbolType, class StateType > +ext::set < ext::pair < StateType, StateType > > ForwardBisimulation::forwardBisimulation ( const automaton::UnorderedDFTA < SymbolType, StateType > & fta ) { + return forwardBisimulation ( automaton::UnorderedNFTA < SymbolType, StateType > ( fta ) ); +} + +template < class SymbolType, class StateType > +ext::set < ext::pair < StateType, StateType > > ForwardBisimulation::forwardBisimulation ( const automaton::UnorderedNFTA < SymbolType, StateType > & fta ) { + ext::set < ext::pair < StateType, StateType > > forwardBisimulation = initial ( fta.getStates ( ), fta.getFinalStates ( ) ); + + bool changed; + do { + changed = false; + + for ( const StateType & p : fta.getStates ( ) ) { + for ( const StateType & q : fta.getStates ( ) ) { + if ( ! forwardBisimulation.contains ( ext::make_pair ( p, q ) ) ) + continue; + + for ( const std::pair < const ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > & pTransition : fta.getTransitions ( ) ) { + for ( const StateType & state : pTransition.first.second ) { + if ( state == p ) { + ext::multiset < StateType > copy = pTransition.first.second; + copy.erase ( copy.find ( state ) ); + copy.insert ( q ); + + bool exists = false; + for ( const std::pair < const ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > & qTransition : fta.getTransitions ( ).equal_range ( std::make_pair ( pTransition.first.first, std::move ( copy ) ) ) ) { + if ( forwardBisimulation.contains ( ext::make_pair ( pTransition.second, qTransition.second ) ) ) { + exists = true; + break; + } + } + + if ( ! exists ) { + forwardBisimulation.erase ( ext::make_pair ( p, q ) ); + forwardBisimulation.erase ( ext::make_pair ( q, p ) ); + changed = true; + } + } + } + } + } + } + } while ( changed ); + + return forwardBisimulation; +} + } /* namespace properties */ } /* namespace automaton */ -- GitLab