reglibcpp  1.7.0
(Naïve) C++ implementation of models for regular languages
Classes | Public Member Functions | List of all members
reg::nfa::builder Class Reference

Constructs NFAs step by step. More...

#include <nfa.h>

Classes

struct  pImpl
 Private implementation details of NFA builders. More...
 

Public Member Functions

 builder ()
 Constructs a blank builder object. More...
 
 builder (nfa const &nfa)
 Constructs a builder object with exactly the same states, symbols, transitions, initial state and accept states as a given NFA. More...
 
 builder (dfa const &dfa)
 Constructs a builder object with exactly the same states, symbols, transitions, initial state and accept states as a given DFA. More...
 
 builder (builder const &b)
 Copy-constructs a builder by copying another one's private implementation object. More...
 
 builder (builder &&b)
 Move-constructs a builder by stealing another one's private implementation object. More...
 
builderoperator= (builder const &b)
 Copy-assigns a builder by copying another one's private implementation object. More...
 
builderoperator= (builder &&b)
 Move-assigns a builder by stealing another one's private implementation object. More...
 
 operator nfa ()
 Simply calls this builder' build() method. More...
 
builderaddSymbol (char32_t symbol)
 Adds a symbol to the prospective NFA's alphabet. More...
 
builderaddSymbol (std::string const &utf8Symbol)
 Same as above for a UTF-8-encoded symbol. More...
 
buildersetAccepting (std::string const &state, bool accept)
 Sets whether or not a state will be accepting within the prospective NFA. More...
 
buildermakeInitial (std::string const &state)
 Resets the initial state for the prospective NFA. More...
 
builderaddTransition (std::string const &from, std::string const &to, char32_t symbol)
 Adds a transition for the prospective NFA. More...
 
builderaddTransition (std::string const &from, std::string const &to, std::string const &utf8Symbol)
 Same as above for a UTF-8-encoded symbol. More...
 
builderunite (nfa const &other)
 Makes the prospective NFA also accept every word of another NFA's language. More...
 
builderintersect (nfa const &other)
 Makes the prospective NFA accept only words accepted also by another NFA. More...
 
buildernormalizeStateNames (std::string const &prefix)
 Reduces the prospective NFA's state names to consecutive numbers, prefixed with a given string. More...
 
nfa build ()
 Builds the NFA, as defined by previous operations. More...
 

Detailed Description

Constructs NFAs step by step.

Any mention of a symbol or state will add them to the alphabet/set of states. The first state mentioned will be designated initial state.

Definition at line 91 of file nfa.h.

Constructor & Destructor Documentation

◆ builder() [1/5]

reg::nfa::builder::builder ( )

Constructs a blank builder object.

Definition at line 681 of file nfa.cpp.

681 : p(new pImpl) {}

◆ builder() [2/5]

reg::nfa::builder::builder ( nfa const &  nfa)

Constructs a builder object with exactly the same states, symbols, transitions, initial state and accept states as a given NFA.

Definition at line 684 of file nfa.cpp.

684  : p(new pImpl) {
685  makeInitial(nfa.getLabelOf(0));
686  for (char32_t symbol : nfa.getAlphabet()) {
687  addSymbol(symbol);
688  }
689  for (size_t qi = 0; qi < nfa.p->labels.size(); ++qi) {
690  string const& qLabel = nfa.getLabelOf(qi);
691  for (char32_t symbol : p->alphabet) {
692  valarray<bool> ps = nfa.delta(qi, symbol);
693  size_t pi(0);
694  for (bool pb : ps) {
695  if (pb) {
696  addTransition(qLabel, nfa.getLabelOf(pi), symbol);
697  }
698  pi++;
699  }
700  }
701  if (nfa.isAccepting(qi)) {
702  setAccepting(qLabel, true);
703  }
704  }
705 }
builder & addSymbol(char32_t symbol)
Adds a symbol to the prospective NFA's alphabet.
Definition: nfa.cpp:761
builder & setAccepting(std::string const &state, bool accept)
Sets whether or not a state will be accepting within the prospective NFA.
Definition: nfa.cpp:777
builder & makeInitial(std::string const &state)
Resets the initial state for the prospective NFA.
Definition: nfa.cpp:795
nfa()
Constructs an NFA accepting the empty language ∅.
Definition: nfa.cpp:68
builder & addTransition(std::string const &from, std::string const &to, char32_t symbol)
Adds a transition for the prospective NFA.
Definition: nfa.cpp:808

◆ builder() [3/5]

reg::nfa::builder::builder ( dfa const &  dfa)

Constructs a builder object with exactly the same states, symbols, transitions, initial state and accept states as a given DFA.

Transition destinations will be converted to singleton sets of the respective reached states.

Definition at line 709 of file nfa.cpp.

709  {
710  string initial(dfa.getLabelOf(0));
711  unordered_set<string> acceptingStates;
712  unordered_set<char32_t> alphabet(dfa.getAlphabet().begin(), dfa.getAlphabet().end());
713  Ntransitionmap transitions;
714  transitions[initial];
715  for (size_t q(0); q < dfa.getNumberOfStates(); q++) {
716  for (char32_t symbol : alphabet) {
717  transitions[dfa.getLabelOf(q)][symbol].insert(dfa.getLabelOf(dfa.delta(q, symbol)));
718  }
719  if (dfa.isAccepting(q)) {
720  acceptingStates.insert(dfa.getLabelOf(q));
721  }
722  }
723  p = make_unique<pImpl>(initial, acceptingStates, alphabet, transitions);
724 }
unordered_map< string, unordered_map< char32_t, unordered_set< string > >> Ntransitionmap
Shorthand for the map from state name and transition symbol to set of target states.
Definition: nfa.cpp:653

◆ builder() [4/5]

reg::nfa::builder::builder ( builder const &  b)

Copy-constructs a builder by copying another one's private implementation object.

Definition at line 727 of file nfa.cpp.

727 : p(new pImpl(*(b.p))) {}

◆ builder() [5/5]

reg::nfa::builder::builder ( builder &&  b)

Move-constructs a builder by stealing another one's private implementation object.

The other builder will be blank afterwards.

Definition at line 731 of file nfa.cpp.

731 : p(new pImpl) {p.swap(b.p);}

Member Function Documentation

◆ addSymbol() [1/2]

nfa::builder & reg::nfa::builder::addSymbol ( char32_t  symbol)

Adds a symbol to the prospective NFA's alphabet.

Parameters
symbolthe symbol to add
Returns
reference to this object, for chaining operations

Definition at line 761 of file nfa.cpp.

761  {
762  p->alphabet.insert(symbol);
763  return *this;
764 }

◆ addSymbol() [2/2]

nfa::builder & reg::nfa::builder::addSymbol ( std::string const &  utf8Symbol)

Same as above for a UTF-8-encoded symbol.

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Definition at line 767 of file nfa.cpp.

767  {
768  return addSymbol(converter.from_bytes(utf8Symbol)[0]);
769 }
std::wstring_convert< std::codecvt_utf8< char32_t >, char32_t > converter
Converts between UTF-8-encoded and UTF-32-encoded strings.
Definition: utils.cpp:4
builder & addSymbol(char32_t symbol)
Adds a symbol to the prospective NFA's alphabet.
Definition: nfa.cpp:761

◆ addTransition() [1/2]

nfa::builder & reg::nfa::builder::addTransition ( std::string const &  from,
std::string const &  to,
char32_t  symbol 
)

Adds a transition for the prospective NFA.

Parameters
fromthe starting state for the transition
tothe destination state for the transition
symbolthe symbol triggering the transition or \0 for an ε-transition
Returns
reference to this object, for chaining operations

Definition at line 808 of file nfa.cpp.

808  {
809  if (p->transitions.empty()) {
810  p->initial = from;
811  }
812  p->transitions[to];
813  p->transitions[from][symbol].insert(to);
814  addSymbol(symbol);
815  return *this;
816 }
builder & addSymbol(char32_t symbol)
Adds a symbol to the prospective NFA's alphabet.
Definition: nfa.cpp:761

◆ addTransition() [2/2]

nfa::builder & reg::nfa::builder::addTransition ( std::string const &  from,
std::string const &  to,
std::string const &  utf8Symbol 
)

Same as above for a UTF-8-encoded symbol.

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Definition at line 819 of file nfa.cpp.

819  {
820  return addTransition(from, to, converter.from_bytes(utf8Symbol)[0]);
821 }
std::wstring_convert< std::codecvt_utf8< char32_t >, char32_t > converter
Converts between UTF-8-encoded and UTF-32-encoded strings.
Definition: utils.cpp:4
builder & addTransition(std::string const &from, std::string const &to, char32_t symbol)
Adds a transition for the prospective NFA.
Definition: nfa.cpp:808

◆ build()

nfa reg::nfa::builder::build ( )

Builds the NFA, as defined by previous operations.

Returns
an NFA object with exactly the states, alphabet and transitions that were defined

Definition at line 1003 of file nfa.cpp.

1003  {
1004  p->transitions[p->initial];
1005  p->alphabet.insert(U'\0');
1006  vector<char32_t> alphabetV(p->alphabet.begin(), p->alphabet.end());
1007  std::sort(alphabetV.begin(), alphabetV.end());
1008  vector<string> labelV(p->transitions.size());
1009  labelV[0] = p->initial;
1010  valarray<bool> acceptingV(p->transitions.size());
1011  acceptingV[0] = (p->acceptingStates.find(p->initial) != p->acceptingStates.end());
1012  size_t i(1);
1013  for (auto entry : p->transitions) {
1014  if (entry.first == p->initial) {
1015  continue;
1016  }
1017  labelV[i] = entry.first;
1018  acceptingV[i++] = (
1019  p->acceptingStates.find(entry.first) != p->acceptingStates.end()
1020  );
1021  }
1022  vector<vector<valarray<bool>>> transitionV(
1023  p->transitions.size(),
1025  p->alphabet.size()+1,
1026  valarray<bool>(labelV.size())
1027  )
1028  );
1029  unordered_set<string> emptySet;
1030  size_t qi(0);
1031  for (auto const& q : labelV) {
1032  unordered_map<char32_t,unordered_set<string>> const& fromQ = p->transitions[q];
1033  size_t si(0);
1034  for (char32_t symbol : alphabetV) {
1035  auto to = fromQ.find(symbol);
1036  unordered_set<string> const& viaSymbol(to != fromQ.end() ? to->second : emptySet);
1037  i = 0;
1038  for (auto const& p : labelV) {
1039  transitionV[qi][si][i++] = (viaSymbol.count(p) != 0);
1040  }
1041  si++;
1042  }
1043  qi++;
1044  }
1045  return {alphabetV, transitionV, labelV, acceptingV};
1046 }

◆ intersect()

nfa::builder & reg::nfa::builder::intersect ( nfa const &  other)

Makes the prospective NFA accept only words accepted also by another NFA.

Concatenates the names of states defined so far with the other NFA's state names and resolves conflicts by appending _.

Parameters
otherthe NFA whose language should also be accepted
Returns
reference to this object, for chaining operations

Definition at line 926 of file nfa.cpp.

926  {
927  if (!p->transitions.empty()) {
928  vector<string> stateNames;
929  stateNames.reserve(p->transitions.size());
930  stateNames.push_back(p->initial);
931  for (auto const& fromTo : p->transitions) {
932  if (fromTo.first != p->initial) {
933  stateNames.push_back(fromTo.first);
934  }
935  }
936  auto const& oAlph = other.getAlphabet();
937  size_t commonSymbols = 0;
938  for (char32_t symbol : p->alphabet) {
939  if (index_of(oAlph, symbol) < oAlph.size()) {
940  commonSymbols++;
941  } else {
942  for (auto & fromVia : p->transitions) {
943  fromVia.second.erase(symbol);
944  }
945  }
946  }
947  p->alphabet.insert(oAlph.begin(), oAlph.end());
948  Ntransitionmap newTr(stateNames.size() * other.getNumberOfStates());
949  unordered_set<string> newAcc(stateNames.size() * other.getNumberOfStates());
950  unordered_map<size_t, unordered_map<size_t, string const*>> pairToName(stateNames.size() * other.getNumberOfStates());
951  for (size_t q = 0; q < stateNames.size(); q++) {
952  for (size_t qq = 0; qq < other.getNumberOfStates(); qq++) {
953  string potentialName = stateNames[q] + other.getLabelOf(qq);
954  for (auto nameIt = newTr.find(potentialName); nameIt != newTr.end(); nameIt = newTr.find(potentialName)) {
955  potentialName.append("_");
956  }
957  auto nameIt = newTr.emplace(potentialName, commonSymbols);
958  pairToName.emplace(q, 1).first->second.emplace(qq, &(nameIt.first->first));
959  if (p->acceptingStates.find(stateNames[q]) != p->acceptingStates.end() && other.isAccepting(qq)) {
960  newAcc.insert(potentialName);
961  }
962  }
963  p->transitions[stateNames[q]][U'\0'].insert(stateNames[q]);
964  // Needed due to the equivalence of standing still to “taking” an ε-transition.
965  }
966  for (size_t q = 0; q < stateNames.size(); q++) {
967  auto const& qLabel = stateNames[q];
968  auto const& viaTos = p->transitions[qLabel];
969  for (auto const& viaTo : viaTos) {
970  for (size_t qq = 0; qq < other.getNumberOfStates(); qq++) {
971  valarray<bool> const& reached = other.delta(qq, viaTo.first);
972  for (auto const& to : viaTo.second) {
973  size_t p = index_of(stateNames, to);
974  for (size_t pp = 0; pp < reached.size(); pp++) {
975  if (reached[pp] || (pp == qq && viaTo.first == U'\0')) {
976  // Needed due to the equivalence of standing still to “taking” an ε-transition.
977  newTr[*(pairToName[q][qq])][viaTo.first].insert(*(pairToName[p][pp]));
978  }
979  }
980  }
981  }
982  }
983  }
984  for (auto & fromVia : newTr) {
985  auto const& from = fromVia.first;
986  auto to = fromVia.second.find(U'\0');
987  to->second.erase(from);
988  if (to->second.empty()) {
989  fromVia.second.erase(to);
990  }
991  }
992  p->transitions = newTr;
993  p->acceptingStates = newAcc;
994  p->initial = *(pairToName[0][0]);
995  }
996  return *this;
997 }
size_t index_of(C const &container, T const &element)
Basically Java&#39;s List interface&#39;s indexOf, but as a non-member function and returning the container&#39;s...
Definition: utils.h:19
unordered_map< string, unordered_map< char32_t, unordered_set< string > >> Ntransitionmap
Shorthand for the map from state name and transition symbol to set of target states.
Definition: nfa.cpp:653

◆ makeInitial()

nfa::builder & reg::nfa::builder::makeInitial ( std::string const &  state)

Resets the initial state for the prospective NFA.

Parameters
statethe new initial state
Returns
reference to this object, for chaining operations

Definition at line 795 of file nfa.cpp.

795  {
796  p->initial = state;
797  p->transitions[state];
798  return *this;
799 }

◆ normalizeStateNames()

nfa::builder & reg::nfa::builder::normalizeStateNames ( std::string const &  prefix)

Reduces the prospective NFA's state names to consecutive numbers, prefixed with a given string.

Definition at line 824 of file nfa.cpp.

824  {
825  if (!p->transitions.empty()) {
826  vector<string> stateNames;
827  stateNames.reserve(p->transitions.size());
828  stateNames.push_back(p->initial);
829  for (auto const& fromTo : p->transitions) {
830  if (fromTo.first != p->initial) {
831  stateNames.push_back(fromTo.first);
832  }
833  }
834  Ntransitionmap newTr(p->transitions.size());
835  unordered_set<string> newAcc(p->acceptingStates.size());
836  for (size_t q = 0; q < stateNames.size(); q++) {
837  auto const& vias = p->transitions[stateNames[q]];
838  unordered_map<char32_t,unordered_set<string>> newVias(vias.size());
839  for (auto const& viaTo : vias) {
840  unordered_set<string> newTos(viaTo.second.size());
841  for (size_t p = 0; p < stateNames.size(); p++) {
842  if (viaTo.second.find(stateNames[p]) != viaTo.second.cend()) {
843  newTos.insert(prefix + std::to_string(p));
844  }
845  }
846  newVias.insert(make_pair(viaTo.first, newTos));
847  }
848  newTr.insert(make_pair(prefix + std::to_string(q), newVias));
849  if (p->acceptingStates.find(stateNames[q]) != p->acceptingStates.end()) {
850  newAcc.insert(prefix + std::to_string(q));
851  }
852  }
853  p->initial = string(string(prefix).append("0"));
854  p->transitions = newTr;
855  p->acceptingStates = newAcc;
856  }
857  return *this;
858 }
T make_pair(T... args)
unordered_map< string, unordered_map< char32_t, unordered_set< string > >> Ntransitionmap
Shorthand for the map from state name and transition symbol to set of target states.
Definition: nfa.cpp:653

◆ operator nfa()

reg::nfa::builder::operator nfa ( )

Simply calls this builder' build() method.

Definition at line 752 of file nfa.cpp.

752  {
753  return build();
754 }
nfa build()
Builds the NFA, as defined by previous operations.
Definition: nfa.cpp:1003

◆ operator=() [1/2]

nfa::builder & reg::nfa::builder::operator= ( builder const &  b)

Copy-assigns a builder by copying another one's private implementation object.

Definition at line 734 of file nfa.cpp.

734  {
735  if (this != &b) {
736  p.reset(new pImpl(*(b.p)));
737  }
738  return *this;
739 }

◆ operator=() [2/2]

nfa::builder & reg::nfa::builder::operator= ( nfa::builder &&  b)

Move-assigns a builder by stealing another one's private implementation object.

The other builder will be blank afterwards.

Definition at line 743 of file nfa.cpp.

743  {
744  if (this != &b) {
745  p.reset(new pImpl);
746  p.swap(b.p);
747  }
748  return *this;
749 }

◆ setAccepting()

nfa::builder & reg::nfa::builder::setAccepting ( std::string const &  state,
bool  accept 
)

Sets whether or not a state will be accepting within the prospective NFA.

Parameters
statethe state's name
accepttrue if the state should be an accept state afterwards, false else
Returns
reference to this object, for chaining operations

Definition at line 777 of file nfa.cpp.

777  {
778  if (p->transitions.empty()) {
779  p->initial = state;
780  }
781  p->transitions[state];
782  if (accept) {
783  p->acceptingStates.insert(state);
784  } else {
785  p->acceptingStates.erase(state);
786  }
787  return *this;
788 }

◆ unite()

nfa::builder & reg::nfa::builder::unite ( nfa const &  other)

Makes the prospective NFA also accept every word of another NFA's language.

Prepends the names of states defined so far with a single 1 and the other NFA's state names with a single 2 and adds a new initial state with an ε transition to each of the other initial states.

Parameters
otherthe NFA whose language should also be accepted
Returns
reference to this object, for chaining operations

Definition at line 868 of file nfa.cpp.

868  {
869  string newInitial("q0");
870  if (!p->transitions.empty()) {
871  Ntransitionmap tempTr(p->transitions.size());
872  for (auto const& fromVia : p->transitions) {
873  unordered_map<char32_t,unordered_set<string>> tempVia(fromVia.second.size());
874  for (auto const& viaTo : fromVia.second) {
875  unordered_set<string> tempTo(viaTo.second.size());
876  for (auto const& to : viaTo.second) {
877  tempTo.insert(string(to.length() + 1, '1').replace(1, string::npos, to));
878  }
879  tempVia.insert(make_pair(viaTo.first, tempTo));
880  }
881  tempTr.insert(make_pair(string(fromVia.first.length() + 1, '1').replace(1, string::npos, fromVia.first), tempVia));
882  }
883  p->transitions = tempTr;
884  unordered_set<string> tempAcc(p->acceptingStates.size());
885  for (auto const& acc : p->acceptingStates) {
886  tempAcc.insert(string(acc.length() + 1, '1').replace(1, string::npos, acc));
887  }
888  p->acceptingStates = tempAcc;
889  p->initial = string(p->initial.length() + 1, '1').replace(1, string::npos, p->initial);
890  addTransition(newInitial, p->initial, U'\0');
891  }
892  makeInitial(newInitial);
893  auto & oAlphabet = other.getAlphabet();
894  p->alphabet.insert(oAlphabet.cbegin(), oAlphabet.cend());
895  for (size_t q = 0; q < other.getNumberOfStates(); q++) {
896  auto & qLabel = other.getLabelOf(q);
897  string newQLabel = string(qLabel.length() + 1, '2').replace(1, string::npos, qLabel);
898  unordered_map<char32_t,unordered_set<string>> tempVia(oAlphabet.size() + 1);
899  for (char32_t symbol : oAlphabet) {
900  valarray<bool> const& to = other.delta(q, symbol);
901  unordered_set<string> tempTo(other.getNumberOfStates());
902  for (size_t p = 0; p < other.getNumberOfStates(); p++) { if (to[p]) {
903  auto & pLabel = other.getLabelOf(p);
904  tempTo.insert(string(pLabel.length() + 1, '2').replace(1, string::npos, pLabel));
905  }}
906  tempVia.insert(make_pair(symbol, tempTo));
907  }
908  p->transitions.insert(make_pair(newQLabel, tempVia));
909  if (other.isAccepting(q)) {
910  p->acceptingStates.insert(newQLabel);
911  }
912  if (q == 0) {
913  addTransition(newInitial, newQLabel, U'\0');
914  }
915  }
916  return *this;
917 }
T replace(T... args)
T make_pair(T... args)
builder & makeInitial(std::string const &state)
Resets the initial state for the prospective NFA.
Definition: nfa.cpp:795
unordered_map< string, unordered_map< char32_t, unordered_set< string > >> Ntransitionmap
Shorthand for the map from state name and transition symbol to set of target states.
Definition: nfa.cpp:653
builder & addTransition(std::string const &from, std::string const &to, char32_t symbol)
Adds a transition for the prospective NFA.
Definition: nfa.cpp:808

The documentation for this class was generated from the following files: