From 302a4980e6935c28025cd13890ce1b61df88a2aa Mon Sep 17 00:00:00 2001 From: Jan Travnicek <jan.travnicek@.fit.cvut.cz> Date: Wed, 2 Oct 2019 15:56:05 +0200 Subject: [PATCH] backward bisimulation and forward bisimulation by definition --- .../properties/BackwardBisimulation.cpp | 25 ++++ .../properties/BackwardBisimulation.h | 133 ++++++++++++++++++ .../properties/ForwardBisimulation.cpp | 25 ++++ .../properties/ForwardBisimulation.h | 125 ++++++++++++++++ examples2/automaton/NFTA_fab_faa.xml | 95 +++++++++++++ 5 files changed, 403 insertions(+) create mode 100644 alib2algo/src/automaton/properties/BackwardBisimulation.cpp create mode 100644 alib2algo/src/automaton/properties/BackwardBisimulation.h create mode 100644 alib2algo/src/automaton/properties/ForwardBisimulation.cpp create mode 100644 alib2algo/src/automaton/properties/ForwardBisimulation.h create mode 100644 examples2/automaton/NFTA_fab_faa.xml diff --git a/alib2algo/src/automaton/properties/BackwardBisimulation.cpp b/alib2algo/src/automaton/properties/BackwardBisimulation.cpp new file mode 100644 index 0000000000..5f82105558 --- /dev/null +++ b/alib2algo/src/automaton/properties/BackwardBisimulation.cpp @@ -0,0 +1,25 @@ +/* +* BackwardBisimulation.cpp + * + * Created on: 27. 3. 2019 + * Author: Tomas Pecka + */ + +#include "BackwardBisimulation.h" +#include <registration/AlgoRegistration.hpp> + +namespace { + +auto BackwardBisimulationDFTA = registration::AbstractRegister < automaton::properties::BackwardBisimulation, ext::set < ext::pair < DefaultStateType, DefaultStateType > >, const automaton::DFTA < > & > ( automaton::properties::BackwardBisimulation::backwardBisimulation, "fta" ).setDocumentation ( +"Computes a relation on states of the DFTA 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 BackwardBisimulationNFTA = registration::AbstractRegister < automaton::properties::BackwardBisimulation, ext::set < ext::pair < DefaultStateType, DefaultStateType > >, const automaton::NFTA < > & > ( automaton::properties::BackwardBisimulation::backwardBisimulation, "fta" ).setDocumentation ( +"Computes a relation on states of the NFTA 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 new file mode 100644 index 0000000000..1fdca25c6f --- /dev/null +++ b/alib2algo/src/automaton/properties/BackwardBisimulation.h @@ -0,0 +1,133 @@ +/* + * BackwardBisimulation.h + * + * This file is part of Algorithms library toolkit. + * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz) + + * Algorithms library toolkit 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. + + * Algorithms library toolkit 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 Algorithms library toolkit. If not, see <http://www.gnu.org/licenses/>. + * + * Created on: 27. 3. 2019 + * Author: Tomas Pecka + */ + +#ifndef BACKWARD_BISIMULATION_H_ +#define BACKWARD_BISIMULATION_H_ + +#include <alib/set> +#include <alib/map> + +#include <automaton/TA/DFTA.h> +#include <automaton/TA/NFTA.h> + +namespace automaton { + +namespace properties { + +/** + * Find all backwardBisimulation pairs of states of DFA. + * Implements table-filling algorithm, Hopcroft 2nd edition, 4.4.1 + */ +class BackwardBisimulation { + template < class StateType > + static ext::set < ext::pair < StateType, StateType > > initial ( const ext::set < StateType > & states ) { + ext::set < ext::pair < StateType, StateType > > init; + + for ( const StateType & a : states ) { + for ( const StateType & b : states ) { + init.insert ( ext::make_pair ( a, b ) ); + init.insert ( ext::make_pair ( b, a ) ); + } + } + + return init; + } + +public: + /** + * 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::DFTA < 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::NFTA < SymbolType, StateType > & fta ); +}; + +template < class SymbolType, class StateType > +ext::set < ext::pair < StateType, StateType > > BackwardBisimulation::backwardBisimulation ( const automaton::DFTA < SymbolType, StateType > & fta ) { + return backwardBisimulation ( NFTA < SymbolType, StateType > ( fta ) ); +} + +template < class SymbolType, class StateType > +ext::set < ext::pair < StateType, StateType > > BackwardBisimulation::backwardBisimulation ( const automaton::NFTA < 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::vector < StateType > >, StateType > & pTransition : fta.getTransitionsToState ( p ) ) { + + bool exists = false; + for ( const std::pair < const ext::pair < common::ranked_symbol < SymbolType >, ext::vector < StateType > >, StateType > & qTransition : fta.getTransitionsToState ( q ) ) { + if ( qTransition.first.first != pTransition.first.first ) + continue; + + size_t inRelation = 0; + for ( size_t i = 0; i < pTransition.first.second.size ( ); ++ i ) { + if ( backwardBisimulation.contains ( ext::make_pair ( pTransition.first.second [ i ], qTransition.first.second [ i ] ) ) ) + ++ inRelation; + } + + if ( inRelation == pTransition.first.second.size ( ) ) { + 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 */ + +#endif /* BACKWARD_BISIMULATION_H_ */ diff --git a/alib2algo/src/automaton/properties/ForwardBisimulation.cpp b/alib2algo/src/automaton/properties/ForwardBisimulation.cpp new file mode 100644 index 0000000000..b800f32a10 --- /dev/null +++ b/alib2algo/src/automaton/properties/ForwardBisimulation.cpp @@ -0,0 +1,25 @@ +/* +* ForwardBisimulation.cpp + * + * Created on: 27. 3. 2019 + * Author: Tomas Pecka + */ + +#include "ForwardBisimulation.h" +#include <registration/AlgoRegistration.hpp> + +namespace { + +auto ForwardBisimulationNFTA = registration::AbstractRegister < automaton::properties::ForwardBisimulation, ext::set < ext::pair < DefaultStateType, DefaultStateType > >, const automaton::NFTA < > & > ( automaton::properties::ForwardBisimulation::forwardBisimulation, "fta" ).setDocumentation ( +"Computes a relation on states of the 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 ForwardBisimulationDFTA = registration::AbstractRegister < automaton::properties::ForwardBisimulation, ext::set < ext::pair < DefaultStateType, DefaultStateType > >, const automaton::DFTA < > & > ( automaton::properties::ForwardBisimulation::forwardBisimulation, "fta" ).setDocumentation ( +"Computes a relation on states of the 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 new file mode 100644 index 0000000000..e16cd7b224 --- /dev/null +++ b/alib2algo/src/automaton/properties/ForwardBisimulation.h @@ -0,0 +1,125 @@ +/* + * ForwardBisimulation.h + * + * This file is part of Algorithms library toolkit. + * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz) + + * Algorithms library toolkit 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. + + * Algorithms library toolkit 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 Algorithms library toolkit. If not, see <http://www.gnu.org/licenses/>. + * + * Created on: 27. 3. 2019 + * Author: Tomas Pecka + */ + +#ifndef FORWARD_BISIMULATION_H_ +#define FORWARD_BISIMULATION_H_ + +#include <alib/set> +#include <alib/map> + +#include <automaton/TA/DFTA.h> +#include <automaton/TA/NFTA.h> + +namespace automaton { + +namespace properties { + +/** + * Find all forwardBisimulation pairs of states of DFA. + * Implements table-filling algorithm, Hopcroft 2nd edition, 4.4.1 + */ +class ForwardBisimulation { + template < class StateType > + static ext::set < ext::pair < StateType, StateType > > initial ( const ext::set < StateType > & states, const ext::set < StateType > & finals ) { + ext::set < ext::pair < StateType, StateType > > init; + + for ( const StateType & a : states ) { + for ( const StateType & b : states ) { + if ( finals.count ( a ) == finals.count ( b ) ) { + init.insert ( ext::make_pair ( a, b ) ); + init.insert ( ext::make_pair ( b, a ) ); + } + } + } + + return init; + } + +public: + /** + * 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::DFTA < 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::NFTA < SymbolType, StateType > & fta ); +}; + +template < class SymbolType, class StateType > +ext::set < ext::pair < StateType, StateType > > ForwardBisimulation::forwardBisimulation ( const automaton::DFTA < SymbolType, StateType > & fta ) { + return forwardBisimulation ( automaton::NFTA < SymbolType, StateType > ( fta ) ); +} + +template < class SymbolType, class StateType > +ext::set < ext::pair < StateType, StateType > > ForwardBisimulation::forwardBisimulation ( const automaton::NFTA < 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::vector < StateType > >, StateType > & transition : fta.getTransitions ( ) ) { + for ( size_t i = 0; i < transition.first.second.size ( ); ++ i ) { + if ( transition.first.second [ i ] == p ) { + ext::vector < StateType > copy = transition.first.second; + copy [ i ] = q; + + const auto & transition2 = fta.getTransitions ( ).find ( std::make_pair ( transition.first.first, std::move ( copy ) ) ); + + if ( transition2 == fta.getTransitions ( ).end ( ) || ! forwardBisimulation.contains ( ext::make_pair ( transition.second, transition2->second ) ) ) { + forwardBisimulation.erase ( ext::make_pair ( p, q ) ); + forwardBisimulation.erase ( ext::make_pair ( q, p ) ); + changed = true; + } + } + } + } + } + } + } while ( changed ); + + return forwardBisimulation; +} + +} /* namespace properties */ + +} /* namespace automaton */ + +#endif /* FORWARD_BISIMULATION_H_ */ diff --git a/examples2/automaton/NFTA_fab_faa.xml b/examples2/automaton/NFTA_fab_faa.xml new file mode 100644 index 0000000000..8ecae02e1b --- /dev/null +++ b/examples2/automaton/NFTA_fab_faa.xml @@ -0,0 +1,95 @@ +<?xml version="1.0"?> +<NFTA> + <states> + <String>1</String> + <String>2</String> + <String>3</String> + <String>4</String> + <String>5</String> + <String>6</String> + </states> + <rankedInputAlphabet> + <RankedSymbol> + <String>f</String> + <UnsignedLong>2</UnsignedLong> + </RankedSymbol> + <RankedSymbol> + <String>a</String> + <UnsignedLong>0</UnsignedLong> + </RankedSymbol> + <RankedSymbol> + <String>b</String> + <UnsignedLong>0</UnsignedLong> + </RankedSymbol> + </rankedInputAlphabet> + <finalStates> + <String>3</String> + <String>6</String> + </finalStates> + <transitions> + <transition> + <input> + <RankedSymbol><String>a</String><UnsignedLong>0</UnsignedLong></RankedSymbol> + </input> + <from> + </from> + <to> + <String>1</String> + </to> + </transition> + <transition> + <input> + <RankedSymbol><String>a</String><UnsignedLong>0</UnsignedLong></RankedSymbol> + </input> + <from> + </from> + <to> + <String>4</String> + </to> + </transition> + <transition> + <input> + <RankedSymbol><String>a</String><UnsignedLong>0</UnsignedLong></RankedSymbol> + </input> + <from> + </from> + <to> + <String>5</String> + </to> + </transition> + <transition> + <input> + <RankedSymbol><String>b</String><UnsignedLong>0</UnsignedLong></RankedSymbol> + </input> + <from> + </from> + <to> + <String>2</String> + </to> + </transition> + <transition> + <input> + <RankedSymbol><String>f</String><UnsignedLong>2</UnsignedLong></RankedSymbol> + </input> + <from> + <String>1</String> + <String>2</String> + </from> + <to> + <String>3</String> + </to> + </transition> + <transition> + <input> + <RankedSymbol><String>f</String><UnsignedLong>2</UnsignedLong></RankedSymbol> + </input> + <from> + <String>4</String> + <String>5</String> + </from> + <to> + <String>6</String> + </to> + </transition> + </transitions> +</NFTA> -- GitLab