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

Represents nondeterministic finite automata with ε-moves. More...

#include <nfa.h>

Classes

class  builder
 Constructs NFAs step by step. More...
 
struct  pImpl
 Private implementation details of NFAs. More...
 

Public Member Functions

 nfa ()
 Constructs an NFA accepting the empty language ∅. More...
 
 nfa (nfa const &n)
 Copy-constructs an NFA by copying another one's private implementation object. More...
 
 nfa (nfa &&n)
 Move-constructs an NFA by stealing another one's private implementation object. More...
 
 nfa (dfa const &d)
 Constructs an NFA from a DFA. More...
 
 nfa (builder &b)
 Constructs an NFA from a builder. More...
 
nfaoperator= (nfa const &n)
 Copy-assigns this NFA by copying another one's private implementation object. More...
 
nfaoperator= (nfa &&n)
 Move-assigns this NFA by stealing another one's private implementation object. More...
 
bool operator== (nfa const &n) const
 Tests whether this NFA accepts exactly the same language as another one. More...
 
bool operator!= (nfa const &n) const
 Tests whether this NFA doesn't accept the same language as another one. More...
 
std::valarray< bool > const & delta (size_t q, char32_t symbol) const
 Computes this NFA's transition function for a state and a symbol. More...
 
std::valarray< bool > const & delta (size_t q, std::string const &utf8Symbol) const
 Same as above for a UTF-8-encoded symbol. More...
 
std::valarray< bool > deltaHat (size_t q, std::u32string const &word) const
 Computes this NFA's transition function recursively for a string of symbols, starting in a specified state. More...
 
std::valarray< bool > deltaHat (size_t q, std::string const &utf8Word) const
 Same as above for a UTF-8-encoded string of symbols. More...
 
std::valarray< bool > deltaHat (std::valarray< bool > const &qs, std::u32string const &word) const
 Computes this NFA's transition function recursively for a string of symbols, starting in multiple specified states. More...
 
std::valarray< bool > deltaHat (std::valarray< bool > const &qs, std::string const &utf8Word) const
 Same as above for a UTF-8-encoded string of symbols. More...
 
std::valarray< bool > const & epsilonClosure (size_t q) const
 Computes a state's ε-closure. More...
 
std::valarray< bool > epsilonClosure (std::valarray< bool > const &qs) const
 Computes the union of multiple states' ε-closures. More...
 
std::u32string getShortestWord () const
 Searches the shortest UTF-32-encoded word accepted by this NFA. More...
 
std::string getShortestUtf8Word () const
 Same as above for a UTF-8-encoded word, INCLUDING POTENTIAL INFINITE LOOP. More...
 
std::string const & getLabelOf (size_t q) const
 Puts a name to an index. More...
 
std::string getLabelOf (std::valarray< bool > const &qs) const
 Puts a name to a set of indices. More...
 
std::vector< char32_t > const & getAlphabet () const
 Fetches this NFA's set of processable symbols. More...
 
std::vector< std::string > const & getUtf8Alphabet () const
 Fetches this NFA's set of processable symbols as UTF-8-encoded strings. More...
 
size_t getNumberOfStates () const
 Counts this NFA's states. More...
 
bool isAccepting (size_t q) const
 Tests whether a state is an accept state within this NFA. More...
 
bool hasAccepting (std::valarray< bool > const &qs) const
 Tests whether a set of states contains an accept state within this NFA. More...
 

Static Public Member Functions

static nfa::builder unite (nfa const &n1, nfa const &n2)
 Creates a builder for an NFA accepting the union of the languages of two NFAs. More...
 
static nfa::builder intersect (nfa const &n1, nfa const &n2)
 Creates a builder for an NFA accepting the intersection of the languages of two NFAs. More...
 
static nfa::builder subtract (nfa const &n1, nfa const &n2)
 Creates a builder for an NFA accepting the set difference of the languages of two NFAs. More...
 
static nfa::builder complement (nfa const &n)
 Creates a builder for an NFA accepting the complement of the language of an NFA. More...
 

Detailed Description

Represents nondeterministic finite automata with ε-moves.

Instances of this class are completely immutable. The builder class is the preferred way of constructing NFAs.

By convention, the state with index 0 is the initial state.

Definition at line 22 of file nfa.h.

Constructor & Destructor Documentation

◆ nfa() [1/5]

reg::nfa::nfa ( )

Constructs an NFA accepting the empty language ∅.

Definition at line 79 of file nfa.cpp.

79 : p(new pImpl) {}

◆ nfa() [2/5]

reg::nfa::nfa ( nfa const &  n)

Copy-constructs an NFA by copying another one's private implementation object.

Definition at line 395 of file nfa.cpp.

395 : p(new pImpl(*(n.p))) {}

◆ nfa() [3/5]

reg::nfa::nfa ( nfa &&  n)

Move-constructs an NFA by stealing another one's private implementation object.

The other NFA will be accepting the empty language ∅ afterwards.

Definition at line 399 of file nfa.cpp.

399 : p(new pImpl) {p.swap(n.p);}

◆ nfa() [4/5]

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

Constructs an NFA from a DFA.

Definition at line 405 of file nfa.cpp.

405 : nfa(builder(n).build()) {}
nfa()
Constructs an NFA accepting the empty language ∅.
Definition: nfa.cpp:79

◆ nfa() [5/5]

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

Constructs an NFA from a builder.

Definition at line 402 of file nfa.cpp.

402 : nfa(b.build()) {}
nfa()
Constructs an NFA accepting the empty language ∅.
Definition: nfa.cpp:79

Member Function Documentation

◆ complement()

nfa::builder reg::nfa::complement ( nfa const &  n)
static

Creates a builder for an NFA accepting the complement of the language of an NFA.

The input NFAs' state names will probably be mangled in the created NFA.

Parameters
nthe NFA
Returns
builder fo an NFA accepting all words not accepted by the input NFA (provided they can be built from symbols of that NFA's alphabet)

Definition at line 390 of file nfa.cpp.

390  {
391  return nfa::builder(dfa::builder(n).complement().minimize().build());
392 }
static nfa::builder complement(nfa const &n)
Creates a builder for an NFA accepting the complement of the language of an NFA.
Definition: nfa.cpp:390

◆ delta() [1/2]

valarray< bool > const & reg::nfa::delta ( size_t  q,
char32_t  symbol 
) const

Computes this NFA's transition function for a state and a symbol.

Parameters
qthe state's index (< getNumberOfStates)
symbolthe symbol to process (∈ getAlphabet)
Returns
valarray with true at reached states' indices

Definition at line 102 of file nfa.cpp.

102  {
103  size_t i = index_of(p->alphabet, symbol);
104  if (i >= p->alphabet.size()) {
105  #ifdef __EXCEPTIONS
106  throw std::domain_error(
107  string(u8"δ is not defined for symbol ") + converter.to_bytes(symbol)
108  );
109  #endif
110  }
111  if (q >= p->labels.size()) {
112  #ifdef __EXCEPTIONS
113  throw std::out_of_range(
114  string("There is no state with index ").append(std::to_string(q))
115  );
116  #endif
117  }
118  return p->transitions[q][i];
119 }
size_t index_of(vector< T > const &vec, 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: dfa.cpp:995
std::wstring_convert< std::codecvt_utf8< char32_t >, char32_t > converter
Converts between UTF-8-encoded and UTF-32-encoded strings.
Definition: dfa.cpp:1001

◆ delta() [2/2]

valarray< bool > const & reg::nfa::delta ( size_t  q,
std::string const &  utf8Symbol 
) const

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 122 of file nfa.cpp.

122  {
123  return delta(q, converter.from_bytes(utf8Symbol)[0]);
124 }
std::valarray< bool > const & delta(size_t q, char32_t symbol) const
Computes this NFA's transition function for a state and a symbol.
Definition: nfa.cpp:102
std::wstring_convert< std::codecvt_utf8< char32_t >, char32_t > converter
Converts between UTF-8-encoded and UTF-32-encoded strings.
Definition: dfa.cpp:1001

◆ deltaHat() [1/4]

valarray< bool > reg::nfa::deltaHat ( size_t  q,
std::u32string const &  word 
) const

Computes this NFA's transition function recursively for a string of symbols, starting in a specified state.

Parameters
qthe starting state's index (< getNumberOfStates)
wordthe string of symbols to process (all of which ∈ getAlphabet)
Returns
valarray with true at reached states' indices

Definition at line 132 of file nfa.cpp.

132  {
133  valarray<bool> qs(p->labels.size());
134  qs[q] = true;
135  return deltaHat(qs, word);
136 }
std::valarray< bool > deltaHat(size_t q, std::u32string const &word) const
Computes this NFA's transition function recursively for a string of symbols, starting in a specified ...
Definition: nfa.cpp:132

◆ deltaHat() [2/4]

valarray< bool > reg::nfa::deltaHat ( size_t  q,
std::string const &  utf8Word 
) const

Same as above for a UTF-8-encoded string of symbols.

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 139 of file nfa.cpp.

139  {
140  return deltaHat(q, converter.from_bytes(utf8Word));
141 }
std::valarray< bool > deltaHat(size_t q, std::u32string const &word) const
Computes this NFA's transition function recursively for a string of symbols, starting in a specified ...
Definition: nfa.cpp:132
std::wstring_convert< std::codecvt_utf8< char32_t >, char32_t > converter
Converts between UTF-8-encoded and UTF-32-encoded strings.
Definition: dfa.cpp:1001

◆ deltaHat() [3/4]

valarray< bool > reg::nfa::deltaHat ( std::valarray< bool > const &  qs,
std::u32string const &  word 
) const

Computes this NFA's transition function recursively for a string of symbols, starting in multiple specified states.

Parameters
qsvalarray with true at starting states' indices (the size of which == getNumberOfStates)
wordthe string of symbols to process (all of which ∈ getAlphabet)
Returns
valarray with true at reached states' indices

Definition at line 149 of file nfa.cpp.

149  {
150  valarray<bool> ps = epsilonClosure(qs);
151  for (char32_t symbol : word) {
152  valarray<bool> reached(p->labels.size());
153  size_t qi(0);
154  for (bool qb : ps) {
155  if (qb) {
156  reached |= epsilonClosure(delta(qi, symbol));
157  }
158  qi++;
159  }
160  ps = move(reached);
161  }
162  return ps;
163 }
std::valarray< bool > const & delta(size_t q, char32_t symbol) const
Computes this NFA's transition function for a state and a symbol.
Definition: nfa.cpp:102
std::valarray< bool > const & epsilonClosure(size_t q) const
Computes a state's ε-closure.
Definition: nfa.cpp:217

◆ deltaHat() [4/4]

valarray< bool > reg::nfa::deltaHat ( std::valarray< bool > const &  qs,
std::string const &  utf8Word 
) const

Same as above for a UTF-8-encoded string of symbols.

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 166 of file nfa.cpp.

166  {
167  return deltaHat(qs, converter.from_bytes(utf8Word));
168 }
std::valarray< bool > deltaHat(size_t q, std::u32string const &word) const
Computes this NFA's transition function recursively for a string of symbols, starting in a specified ...
Definition: nfa.cpp:132
std::wstring_convert< std::codecvt_utf8< char32_t >, char32_t > converter
Converts between UTF-8-encoded and UTF-32-encoded strings.
Definition: dfa.cpp:1001

◆ epsilonClosure() [1/2]

valarray< bool > const & reg::nfa::epsilonClosure ( size_t  q) const

Computes a state's ε-closure.

Parameters
qthe state's index (< getNumberOfStates)
Returns
valarray with true at indices of states reachable without actual inputs

Definition at line 217 of file nfa.cpp.

217  {
218  if (p->epsClosures[q].size() == 0) {
219  p->epsClosures[q].resize(p->labels.size());
220  p->epsClosures[q][q] = true;
221  int growth(1);
222  while (growth > 0) {
223  growth = 0;
224  valarray<bool> old(p->epsClosures[q]);
225  size_t qi(0);
226  for (bool qb : old) {
227  if (qb) {
228  size_t pi(0);
229  for (bool pb : p->transitions[qi][0]) {
230  if (pb) {
231  if (!p->epsClosures[q][pi]) {
232  growth++;
233  p->epsClosures[q][pi] = true;
234  }
235  }
236  pi++;
237  } // going through the true bools in transitions[qi][0]
238  }
239  qi++;
240  } // going through the true bools in old
241  }
242  }
243  return p->epsClosures[q];
244 }

◆ epsilonClosure() [2/2]

valarray< bool > reg::nfa::epsilonClosure ( std::valarray< bool > const &  qs) const

Computes the union of multiple states' ε-closures.

Parameters
qsvalarray with true at indices of states in question (the size of which == getNumberOfStates)
Returns
valarray with true at indices of states reachable without actual inputs

Definition at line 251 of file nfa.cpp.

251  {
252  valarray<bool> closure(p->labels.size());
253  size_t qi(0);
254  for (bool qb : qs) {
255  if (qb) {
256  closure |= epsilonClosure(qi);
257  }
258  qi++;
259  } // going through the true bools in qs
260  return closure;
261 }
std::valarray< bool > const & epsilonClosure(size_t q) const
Computes a state's ε-closure.
Definition: nfa.cpp:217

◆ getAlphabet()

vector< char32_t > const & reg::nfa::getAlphabet ( ) const

Fetches this NFA's set of processable symbols.

Returns
a vector containing all the valid symbol inputs for delta and deltaHat

Definition at line 298 of file nfa.cpp.

298  {
299  return p->alphabet;
300 }

◆ getLabelOf() [1/2]

string const & reg::nfa::getLabelOf ( size_t  q) const

Puts a name to an index.

Parameters
qthe state's index (< getNumberOfStates)
Returns
the state's name

Definition at line 268 of file nfa.cpp.

268  {
269  return p->labels[q];
270 }

◆ getLabelOf() [2/2]

string reg::nfa::getLabelOf ( std::valarray< bool > const &  qs) const

Puts a name to a set of indices.

Parameters
qsvalarray with true at indices of states in question (the size of which == getNumberOfStates)
Returns
a comma-separated list of the states' names, surrounded by curly brackets

Definition at line 277 of file nfa.cpp.

277  {
278  string label;
279  size_t qi(0);
280  for (bool qb : qs) {
281  if (qb) {
282  label = label.append(1, label.length() == 0 ? '{' : ',');
283  label = label.append(p->labels[qi]);
284  }
285  qi++;
286  }
287  if (label.length() == 0) {
288  return string("{}");
289  } else {
290  return label.append(1, '}');
291  }
292 }

◆ getNumberOfStates()

size_t reg::nfa::getNumberOfStates ( ) const

Counts this NFA's states.

Returns
the number of states this NFA has

Definition at line 314 of file nfa.cpp.

314  {
315  return p->labels.size();
316 }

◆ getShortestUtf8Word()

string reg::nfa::getShortestUtf8Word ( ) const

Same as above for a UTF-8-encoded word, INCLUDING POTENTIAL INFINITE LOOP.

Definition at line 208 of file nfa.cpp.

208  {
209  return converter.to_bytes(getShortestWord());
210 }
std::u32string getShortestWord() const
Searches the shortest UTF-32-encoded word accepted by this NFA.
Definition: nfa.cpp:183
std::wstring_convert< std::codecvt_utf8< char32_t >, char32_t > converter
Converts between UTF-8-encoded and UTF-32-encoded strings.
Definition: dfa.cpp:1001

◆ getShortestWord()

u32string reg::nfa::getShortestWord ( ) const

Searches the shortest UTF-32-encoded word accepted by this NFA.

LOOPS INFINITELY FOR NFA WITH AN EMPTY LANGUAGE!

Hint: Compare with the empty-language nfa() before using this method:

nfa empty();
if (myNfa != empty) {
  myNfa.getShortestWord();
}
Returns
the shortest word leading to one of this NFA's accept states

Definition at line 183 of file nfa.cpp.

183  {
184  if (p->accepting[0]) {
185  return U"";
186  }
187  unordered_map<size_t, u32string> shortestWords(p->labels.size());
188  shortestWords.emplace(0, U"");
189  while (true) {
190  for (auto const& stateWord : shortestWords) {
191  for (auto symbol : p->alphabet) {
192  valarray<bool> reached = deltaHat(stateWord.first, u32string(!!symbol, symbol));
193  u32string shWord = stateWord.second + u32string(!!symbol, symbol);
194  for (size_t q = 0; q < reached.size(); q++) { if (reached[q]) {
195  if (p->accepting[q]) {
196  return shWord;
197  }
198  if (shortestWords.find(q) == shortestWords.end()) {
199  shortestWords.emplace(q, shWord);
200  }
201  }}
202  }
203  }
204  }
205 }
std::valarray< bool > deltaHat(size_t q, std::u32string const &word) const
Computes this NFA's transition function recursively for a string of symbols, starting in a specified ...
Definition: nfa.cpp:132

◆ getUtf8Alphabet()

vector< string > const & reg::nfa::getUtf8Alphabet ( ) const

Fetches this NFA's set of processable symbols as UTF-8-encoded strings.

Returns
a vector containing all the valid symbol inputs for delta and deltaHat

Definition at line 306 of file nfa.cpp.

306  {
307  return p->utf8Alphabet;
308 }

◆ hasAccepting()

bool reg::nfa::hasAccepting ( std::valarray< bool > const &  qs) const

Tests whether a set of states contains an accept state within this NFA.

Parameters
qsvalarray with true at indices of states in question (the size of which == getNumberOfStates)
Returns
true if the set of states contains an accept states, false else

Definition at line 332 of file nfa.cpp.

332  {
333  for (size_t q = 0; q < getNumberOfStates(); q++) {
334  if (qs[q] && p->accepting[q]) {
335  return true;
336  }
337  }
338  return false;
339 }
size_t getNumberOfStates() const
Counts this NFA's states.
Definition: nfa.cpp:314

◆ intersect()

nfa::builder reg::nfa::intersect ( nfa const &  n1,
nfa const &  n2 
)
static

Creates a builder for an NFA accepting the intersection of the languages of two NFAs.

The input NFAs' state names will be concatenated and collisions resolved by appending _ in the created NFA.

Parameters
n1the first NFA
n2the other NFA
Returns
builder for an NFA accepting all the words accepted by both of the input NFAs

Definition at line 361 of file nfa.cpp.

361  {
362  return builder(n1).intersect(n2);
363 }

◆ isAccepting()

bool reg::nfa::isAccepting ( size_t  q) const

Tests whether a state is an accept state within this NFA.

Parameters
qthe state's index (< getNumberOfStates)
Returns
true if the state is in the set of accept states, false else

Definition at line 323 of file nfa.cpp.

323  {
324  return p->accepting[q];
325 }

◆ operator!=()

bool reg::nfa::operator!= ( nfa const &  n) const

Tests whether this NFA doesn't accept the same language as another one.

Definition at line 92 of file nfa.cpp.

92  {
93  return p->getEquivalentDfa(this) != n.p->getEquivalentDfa(&n);
94 }

◆ operator=() [1/2]

nfa & reg::nfa::operator= ( nfa const &  n)

Copy-assigns this NFA by copying another one's private implementation object.

Definition at line 408 of file nfa.cpp.

408  {
409  if (this != &n) {
410  p.reset(new pImpl(*(n.p)));
411  }
412  return *this;
413 }

◆ operator=() [2/2]

nfa & reg::nfa::operator= ( nfa &&  n)

Move-assigns this NFA by stealing another one's private implementation object.

The other NFA will be accepting the empty language ∅ afterwards.

Definition at line 417 of file nfa.cpp.

417  {
418  if (this != &n) {
419  p.reset(new pImpl);
420  p.swap(n.p);
421  }
422  return *this;
423 }

◆ operator==()

bool reg::nfa::operator== ( nfa const &  n) const

Tests whether this NFA accepts exactly the same language as another one.

Definition at line 87 of file nfa.cpp.

87  {
88  return p->getEquivalentDfa(this) == n.p->getEquivalentDfa(&n);
89 }

◆ subtract()

nfa::builder reg::nfa::subtract ( nfa const &  n1,
nfa const &  n2 
)
static

Creates a builder for an NFA accepting the set difference of the languages of two NFAs.

The input NFAs' state names will probably be mangled in the created NFA.

Parameters
n1the first NFA
n2the other NFA
Returns
builder for an NFA accepting all the words accepted by the first but not the other input NFA

Definition at line 373 of file nfa.cpp.

373  {
374  dfa::builder b2(n2);
375  for (auto symbol : n1.getAlphabet()) {
376  b2.addSymbol(symbol);
377  }
378  b2.complement().minimize();
379  return builder(n1).intersect(builder(b2.build()).build());
380 }

◆ unite()

nfa::builder reg::nfa::unite ( nfa const &  n1,
nfa const &  n2 
)
static

Creates a builder for an NFA accepting the union of the languages of two NFAs.

The input NFAs' state names will be prepended with either 1 or 2 in the created NFA.

Parameters
n1the first NFA
n2the other NFA
Returns
builder for an NFA accepting all the words accepted by any of the input NFAs

Definition at line 349 of file nfa.cpp.

349  {
350  return builder(n1).unite(n2);
351 }

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