TuringSim
C++ framework to simulate abstract computing models
turingMachineSymbolPattern.h
1 #pragma once
2 
3 #include <utils/visitor.h>
4 #include <state/mConfiguration/mConfiguration.h>
5 #include <symbol/symbolPattern.h>
6 
7 namespace TuringSim::Symbol {
8 
16  template <typename T>
18  {
19  public:
25  constexpr explicit TuringStyleConstantSymbolPattern(bool neg) : neg(neg) {}
33  constexpr TuringStyleConstantSymbolPattern(const T& e) : symbols({e}) {}
41  constexpr TuringStyleConstantSymbolPattern(const std::set<T>& v) : symbols(v) {}
50  constexpr TuringStyleConstantSymbolPattern(const std::set<T>& v, bool b) : symbols(v), neg(b) {}
57  virtual bool match(const T& e) const override { return (symbols.find(e) == symbols.end()) == neg; }
58 
63  constexpr bool operator==(const TuringStyleConstantSymbolPattern<T>& other) const { return neg == other.neg && symbols == other.symbols; }
64 
69  constexpr bool operator!=(const TuringStyleConstantSymbolPattern<T>& other) const { return neg != other.neg || symbols != other.symbols; }
70 
75  constexpr bool operator<(const TuringStyleConstantSymbolPattern<T>& other) const {
76  if(neg < other.neg) {
77  return true;
78  }
79  if(neg > other.neg) {
80  return false;
81  }
82  return symbols < other.symbols;
83  }
84 
92  template <typename CharT = char, typename Traits = std::char_traits<CharT>>
93  friend std::basic_ostream<CharT, Traits> &operator<<(std::basic_ostream<CharT, Traits>& os, const TuringStyleConstantSymbolPattern& pattern) {
94  bool first = true;
95  if(pattern.neg) {
96  os << "non";
97  }
98  os << "(";
99  for (const T &symbol: pattern.symbols) {
100  if (!first) {
101  os << ", ";
102  }
103  else {
104  first = false;
105  }
106  os << "{" << symbol << "}";
107  }
108  os << ")";
109  return os;
110  }
111 
112  private:
113  std::set<T> symbols{};
114  bool neg = false;
115  };
116 
123  template <typename KeyType, typename ValueType, typename SymbolType>
124  class DynamicSymbolPattern : public SymbolPattern<SymbolType, std::map<KeyType, ValueType>> {
125  public:
129  constexpr explicit DynamicSymbolPattern(bool neg) : neg(neg) {}
130 
134  constexpr DynamicSymbolPattern(const KeyType& key) : keys({key}) {}
135 
139  constexpr DynamicSymbolPattern(const std::set<KeyType>& keys) : keys(keys) {}
140 
145  constexpr DynamicSymbolPattern(const std::set<KeyType>& keys, bool neg) : keys(keys), neg(neg) {}
146 
157  constexpr bool matchAccordingToPredicate(const std::map<KeyType, ValueType>& context, const std::function<bool(const ValueType&)>& predicate) const {
158  for(const KeyType& key : keys) {
159  typename std::map<KeyType, ValueType>::const_iterator it = context.find(key);
160  if(it != context.end()) {
161  if(predicate(it->second)) {
162  return !neg;
163  }
164  }
165  }
166  return neg;
167  }
168 
173  constexpr bool operator==(const DynamicSymbolPattern<KeyType, ValueType, SymbolType>& other) const { return neg == other.neg && keys == other.keys; }
174 
179  constexpr bool operator!=(const DynamicSymbolPattern<KeyType, ValueType, SymbolType>& other) const { return neg != other.neg || keys != other.keys; }
180 
186  if(neg < other.neg) {
187  return true;
188  }
189  if(neg > other.neg) {
190  return false;
191  }
192  return keys < other.keys;
193  }
194 
200  constexpr bool isAlphaEquivalent(const DynamicSymbolPattern<KeyType, ValueType, SymbolType>& other, const std::map<KeyType, KeyType>& rewriting) const {
201  if(neg != other.neg) {
202  return false;
203  }
204  if(keys.size() != other.keys.size()) {
205  return false;
206  }
207  for(const KeyType& key : keys) {
208  typename std::map<KeyType, KeyType>::const_iterator it = rewriting.find(key);
209  if(it == rewriting.end()) {
210  return false;
211  }
212  if(other.keys.find(it->second) == other.keys.end()) {
213  return false;
214  }
215  }
216  return true;
217  }
218 
226  template <typename CharT = char, typename Traits = std::char_traits<CharT>>
227  friend std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const DynamicSymbolPattern<KeyType, ValueType, SymbolType>& pattern) {
228  using Utils::Debug::operator<<;
229  os << "dyn";
230  if(pattern.neg) {
231  os << "_non";
232  }
233  os << "(" << Utils::Debug::debug(pattern.keys) << ")";
234  return os;
235  }
236 
237  private:
238  std::set<KeyType> keys{};
239  bool neg = false;
240  };
241 
246  template <typename SymbolType>
247  class TuringStyleDynamicSymbolPattern : public DynamicSymbolPattern<SymbolType, State::MConfiguration::MConfiguration<SymbolType>, SymbolType> {
249  public:
253  constexpr explicit TuringStyleDynamicSymbolPattern(bool neg) : DynamicSymbolPattern_(neg) {}
254 
259 
263  constexpr TuringStyleDynamicSymbolPattern(const std::set<SymbolType>& keys) : DynamicSymbolPattern_(keys) {}
264 
269  constexpr TuringStyleDynamicSymbolPattern(const std::set<SymbolType>& keys, bool neg) : DynamicSymbolPattern_(keys, neg) {}
270 
276  virtual bool match(const SymbolType& symbol, const std::map<SymbolType, State::MConfiguration::MConfiguration<SymbolType>>& context) const override {
277  std::function<bool(const State::MConfiguration::MConfiguration<SymbolType>&)> predicate =
278  [&symbol](const State::MConfiguration::MConfiguration<SymbolType>& m_conf) -> bool {
279  return m_conf.isLeaf() && m_conf.getNode() == symbol;
280  };
281  return DynamicSymbolPattern_::matchAccordingToPredicate(context, predicate);
282  }
283 
289 
295 
300  constexpr bool operator<(const TuringStyleDynamicSymbolPattern<SymbolType>& other) const { return DynamicSymbolPattern_::operator<(other); }
301  };
302 
310  template <typename KeyType, typename ValueType, typename SymbolType>
311  class MixedSymbolPattern : public SymbolPattern<SymbolType, std::map<KeyType, ValueType>> {
312  public:
318  constexpr MixedSymbolPattern(const std::set<KeyType>& symbols, const std::set<KeyType>& keys, bool neg) : symbols(symbols), keys(keys), neg(neg) {}
319 
333  constexpr bool matchAccordingToPredicate(const SymbolType& symbol, const std::map<KeyType, ValueType>& context, const std::function<bool(const ValueType&)>& predicate) const {
334  if(!neg && symbols.find(symbol) != symbols.end()) {
335  return true;
336  }
337  if(neg && symbols.find(symbol) != symbols.end()) {
338  return false;
339  }
340  for(const KeyType& key : keys) {
341  typename std::map<KeyType, ValueType>::const_iterator it = context.find(key);
342  if(it != context.end()) {
343  if(predicate(it->second)) {
344  return !neg;
345  }
346  }
347  }
348  return neg;
349  }
350 
355  constexpr bool operator==(const MixedSymbolPattern<KeyType, ValueType, SymbolType>& other) const { return neg == other.neg && symbols == other.symbols && keys == other.keys; }
360  constexpr bool operator!=(const MixedSymbolPattern<KeyType, ValueType, SymbolType>& other) const { return neg != other.neg || symbols != other.symbols || keys != other.keys; }
366  if(neg < other.neg) {
367  return true;
368  }
369  if(neg > other.neg) {
370  return false;
371  }
372  if(symbols < other.symbols) {
373  return true;
374  }
375  if(symbols > other.symbols) {
376  return false;
377  }
378  return keys < other.keys;
379  }
380 
386  constexpr bool isAlphaEquivalent(const MixedSymbolPattern<KeyType, ValueType, SymbolType>& other, const std::map<KeyType, KeyType>& rewriting) const {
387  if(neg != other.neg) {
388  return false;
389  }
390  if(symbols != other.symbols) {
391  return false;
392  }
393  if(keys.size() != other.keys.size()) {
394  return false;
395  }
396  for(const KeyType& key : keys) {
397  typename std::map<KeyType, KeyType>::const_iterator it = rewriting.find(key);
398  if(it == rewriting.end()) {
399  return false;
400  }
401  if(other.keys.find(it->second) == other.keys.end()) {
402  return false;
403  }
404  }
405  return true;
406  }
407 
415  template <typename CharT = char, typename Traits = std::char_traits<CharT>>
416  friend std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const MixedSymbolPattern<KeyType, ValueType, SymbolType>& pattern) {
417  using Utils::Debug::operator<<;
418  os << "mixed";
419  if(pattern.neg) {
420  os << "_non";
421  }
422  os << "(" << Utils::Debug::debug(pattern.symbols) << ", " << Utils::Debug::debug(pattern.keys) << ")";
423  return os;
424  }
425 
426  private:
427  std::set<SymbolType> symbols{};
428  std::set<KeyType> keys{};
429  bool neg = false;
430  };
431 
436  template <typename SymbolType>
437  class TuringStyleMixedSymbolPattern : public MixedSymbolPattern<SymbolType, std::shared_ptr<const State::MConfiguration::MConfiguration<SymbolType>>, SymbolType> {
439  public:
445  constexpr TuringStyleMixedSymbolPattern(const std::set<SymbolType>& symbols, const std::set<SymbolType>& keys, bool neg) :
446  MixedSymbolPattern_(symbols, keys, neg)
447  {}
448 
454  virtual bool match(const SymbolType& symbol, const std::map<SymbolType, std::shared_ptr<const State::MConfiguration::MConfiguration<SymbolType>>>& context) const noexcept override {
455  std::function<bool(const std::shared_ptr<const State::MConfiguration::MConfiguration<SymbolType>>&)> predicate =
456  [&symbol](const std::shared_ptr<const State::MConfiguration::MConfiguration<SymbolType>>& m_conf) -> bool {
457  return m_conf->isLeaf() && m_conf->getNode() == symbol;
458  };
459  return MixedSymbolPattern_::matchAccordingToPredicate(symbol, context, predicate);
460  }
461 
466  constexpr bool operator==(const TuringStyleMixedSymbolPattern<SymbolType>& other) const { return MixedSymbolPattern_::operator==(other); }
467 
472  constexpr bool operator!=(const TuringStyleMixedSymbolPattern<SymbolType>& other) const { return MixedSymbolPattern_::operator!=(other); }
473 
478  constexpr bool operator<(const TuringStyleMixedSymbolPattern<SymbolType>& other) const { return MixedSymbolPattern_::operator<(other); }
479  };
480 
487  template<typename T>
488  using TuringStyleSymbolPattern = std::variant<TuringStyleConstantSymbolPattern<T>, TuringStyleDynamicSymbolPattern<T>>;
489 
498  template<typename T, typename CharT = char, typename Traits = std::char_traits<CharT>>
499  std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits> &os, const TuringStyleSymbolPattern<T>& pattern) {
500  using Utils::Visitor;
501  std::visit(
502  Visitor{
503  [&os](const TuringStyleConstantSymbolPattern<T> &p) { os << p; },
504  [&os](const TuringStyleDynamicSymbolPattern<T> &p) { os << p; },
505  },
506  pattern);
507  return os;
508  }
509 }
TuringSim::Symbol::TuringStyleDynamicSymbolPattern::TuringStyleDynamicSymbolPattern
constexpr TuringStyleDynamicSymbolPattern(const std::set< SymbolType > &keys)
Make a dynamic pattern that accepts a set of keys.
Definition: turingMachineSymbolPattern.h:263
TuringSim::Symbol::MixedSymbolPattern::operator<
constexpr bool operator<(const MixedSymbolPattern< KeyType, ValueType, SymbolType > &other) const
Less than operator, total order.
Definition: turingMachineSymbolPattern.h:365
TuringSim::Symbol::DynamicSymbolPattern::DynamicSymbolPattern
constexpr DynamicSymbolPattern(const std::set< KeyType > &keys)
Make a dynamic pattern that accepts a set of keys.
Definition: turingMachineSymbolPattern.h:139
TuringSim::Utils::Visitor
Visitor(Ts...) -> Visitor< Ts... >
The deduction guide for Visitor, useless since C++20.
TuringSim::Symbol::SymbolPattern< SymbolType, std::map< SymbolType, State::MConfiguration::MConfiguration< SymbolType > > >::SymbolType
SymbolType SymbolType
The type of symbols.
Definition: symbolPattern.h:18
TuringSim::Symbol::TuringStyleMixedSymbolPattern::operator<
constexpr bool operator<(const TuringStyleMixedSymbolPattern< SymbolType > &other) const
Less than.
Definition: turingMachineSymbolPattern.h:478
TuringSim::State::MConfiguration::MConfiguration
The base class for m-configurations.
Definition: mConfiguration.h:25
TuringSim::Symbol::TuringStyleConstantSymbolPattern
A symbol pattern as used by Turing. Such a pattern accept or reject a finite explicit set of symbols.
Definition: turingMachineSymbolPattern.h:18
TuringSim::Symbol::TuringStyleDynamicSymbolPattern::match
virtual bool match(const SymbolType &symbol, const std::map< SymbolType, State::MConfiguration::MConfiguration< SymbolType >> &context) const override
Check is a symbol is accepted.
Definition: turingMachineSymbolPattern.h:276
TuringSim::Symbol::TuringStyleMixedSymbolPattern::operator!=
constexpr bool operator!=(const TuringStyleMixedSymbolPattern< SymbolType > &other) const
Non-equality operator.
Definition: turingMachineSymbolPattern.h:472
TuringSim::Symbol::TuringStyleMixedSymbolPattern::match
virtual bool match(const SymbolType &symbol, const std::map< SymbolType, std::shared_ptr< const State::MConfiguration::MConfiguration< SymbolType >>> &context) const noexcept override
Check is a symbol is accepted.
Definition: turingMachineSymbolPattern.h:454
TuringSim::Symbol::DynamicSymbolPattern::operator<
constexpr bool operator<(const DynamicSymbolPattern< KeyType, ValueType, SymbolType > &other) const
Less than operator.
Definition: turingMachineSymbolPattern.h:185
TuringSim::Symbol
The namespace for symbol patterns.
Definition: simpleSymbolPattern.h:5
TuringSim::Symbol::MixedSymbolPattern::matchAccordingToPredicate
constexpr bool matchAccordingToPredicate(const SymbolType &symbol, const std::map< KeyType, ValueType > &context, const std::function< bool(const ValueType &)> &predicate) const
Test if a key match a given predicate in a given context.
Definition: turingMachineSymbolPattern.h:333
TuringSim::Symbol::TuringStyleConstantSymbolPattern::operator<<
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const TuringStyleConstantSymbolPattern &pattern)
Debug printer.
Definition: turingMachineSymbolPattern.h:93
TuringSim::Symbol::DynamicSymbolPattern::matchAccordingToPredicate
constexpr bool matchAccordingToPredicate(const std::map< KeyType, ValueType > &context, const std::function< bool(const ValueType &)> &predicate) const
Test if a key match a given predicate in a given context.
Definition: turingMachineSymbolPattern.h:157
TuringSim::Symbol::MixedSymbolPattern::operator!=
constexpr bool operator!=(const MixedSymbolPattern< KeyType, ValueType, SymbolType > &other) const
Non-equality operator.
Definition: turingMachineSymbolPattern.h:360
TuringSim::Symbol::DynamicSymbolPattern::DynamicSymbolPattern
constexpr DynamicSymbolPattern(const std::set< KeyType > &keys, bool neg)
Make a dynamic pattern that accepts or rejects a set of keys.
Definition: turingMachineSymbolPattern.h:145
TuringSim::Symbol::MixedSymbolPattern::operator<<
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const MixedSymbolPattern< KeyType, ValueType, SymbolType > &pattern)
Debug printer for MixedSymbolPattern.
Definition: turingMachineSymbolPattern.h:416
TuringSim::Symbol::DynamicSymbolPattern::DynamicSymbolPattern
constexpr DynamicSymbolPattern(bool neg)
Produce a trivial pattern.
Definition: turingMachineSymbolPattern.h:129
TuringSim::Symbol::DynamicSymbolPattern
A dynamic symbol pattern where accepted/rejected letters are identified by keys, and interpreted in a...
Definition: turingMachineSymbolPattern.h:124
TuringSim::Symbol::DynamicSymbolPattern::operator!=
constexpr bool operator!=(const DynamicSymbolPattern< KeyType, ValueType, SymbolType > &other) const
Non-equality operator.
Definition: turingMachineSymbolPattern.h:179
TuringSim::Symbol::MixedSymbolPattern::operator==
constexpr bool operator==(const MixedSymbolPattern< KeyType, ValueType, SymbolType > &other) const
Equality operator.
Definition: turingMachineSymbolPattern.h:355
TuringSim::Symbol::DynamicSymbolPattern::DynamicSymbolPattern
constexpr DynamicSymbolPattern(const KeyType &key)
Make a dynamic pattern that accepts a single key.
Definition: turingMachineSymbolPattern.h:134
TuringSim::Symbol::MixedSymbolPattern::isAlphaEquivalent
constexpr bool isAlphaEquivalent(const MixedSymbolPattern< KeyType, ValueType, SymbolType > &other, const std::map< KeyType, KeyType > &rewriting) const
Test if, given a renaming of keys, *this is alpha-equivalent to another DynamicSymbolPattern.
Definition: turingMachineSymbolPattern.h:386
TuringSim::Symbol::TuringStyleMixedSymbolPattern
A MixedSymbolPattern with a predicate adapted to m-configuration.
Definition: turingMachineSymbolPattern.h:437
TuringSim::Symbol::TuringStyleConstantSymbolPattern::TuringStyleConstantSymbolPattern
constexpr TuringStyleConstantSymbolPattern(const T &e)
Construct a pattern which accept only one symbol.
Definition: turingMachineSymbolPattern.h:33
TuringSim::Symbol::TuringStyleDynamicSymbolPattern::TuringStyleDynamicSymbolPattern
constexpr TuringStyleDynamicSymbolPattern(bool neg)
Produce a trivial pattern.
Definition: turingMachineSymbolPattern.h:253
TuringSim::Symbol::DynamicSymbolPattern::isAlphaEquivalent
constexpr bool isAlphaEquivalent(const DynamicSymbolPattern< KeyType, ValueType, SymbolType > &other, const std::map< KeyType, KeyType > &rewriting) const
Test if, given a renaming of keys, *this is alpha-equivalent to another DynamicSymbolPattern.
Definition: turingMachineSymbolPattern.h:200
TuringSim::Symbol::TuringStyleConstantSymbolPattern::TuringStyleConstantSymbolPattern
constexpr TuringStyleConstantSymbolPattern(bool neg)
Constructs a trivial pattern: a pattern that accepts everything or nothing.
Definition: turingMachineSymbolPattern.h:25
TuringSim::Symbol::SymbolPattern
Base class to store any symbol pattern on one letter.
Definition: symbolPattern.h:13
TuringSim::Symbol::operator<<
std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const TuringStyleSymbolPattern< T > &pattern)
a printer for TuringStyleConstantSymbolPattern
Definition: turingMachineSymbolPattern.h:499
TuringSim::Symbol::DynamicSymbolPattern::operator<<
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const DynamicSymbolPattern< KeyType, ValueType, SymbolType > &pattern)
Debug printer for DynamicSymbolPattern.
Definition: turingMachineSymbolPattern.h:227
TuringSim::Symbol::TuringStyleDynamicSymbolPattern::operator!=
constexpr bool operator!=(const TuringStyleDynamicSymbolPattern< SymbolType > &other) const
Non-equality operator.
Definition: turingMachineSymbolPattern.h:294
TuringSim::Symbol::TuringStyleDynamicSymbolPattern::TuringStyleDynamicSymbolPattern
constexpr TuringStyleDynamicSymbolPattern(const std::set< SymbolType > &keys, bool neg)
Make a dynamic pattern that accepts or rejects a set of keys.
Definition: turingMachineSymbolPattern.h:269
TuringSim::Symbol::TuringStyleMixedSymbolPattern::operator==
constexpr bool operator==(const TuringStyleMixedSymbolPattern< SymbolType > &other) const
Equality operator.
Definition: turingMachineSymbolPattern.h:466
TuringSim::Symbol::TuringStyleConstantSymbolPattern::match
virtual bool match(const T &e) const override
Test if a letter matches the pattern.
Definition: turingMachineSymbolPattern.h:57
TuringSim::Symbol::TuringStyleConstantSymbolPattern::operator<
constexpr bool operator<(const TuringStyleConstantSymbolPattern< T > &other) const
Less than operator. Total order.
Definition: turingMachineSymbolPattern.h:75
TuringSim::Symbol::TuringStyleDynamicSymbolPattern::operator<
constexpr bool operator<(const TuringStyleDynamicSymbolPattern< SymbolType > &other) const
Less than operator. Total order.
Definition: turingMachineSymbolPattern.h:300
TuringSim::Symbol::TuringStyleDynamicSymbolPattern::operator==
constexpr bool operator==(const TuringStyleDynamicSymbolPattern< SymbolType > &other) const
Equality operator.
Definition: turingMachineSymbolPattern.h:288
TuringSim::Symbol::TuringStyleDynamicSymbolPattern
A DynamicSymbolPattern with a predicate adapted to m-configuration.
Definition: turingMachineSymbolPattern.h:247
TuringSim::Symbol::TuringStyleConstantSymbolPattern::operator==
constexpr bool operator==(const TuringStyleConstantSymbolPattern< T > &other) const
Equality operator.
Definition: turingMachineSymbolPattern.h:63
TuringSim::Symbol::DynamicSymbolPattern::operator==
constexpr bool operator==(const DynamicSymbolPattern< KeyType, ValueType, SymbolType > &other) const
Equality operator.
Definition: turingMachineSymbolPattern.h:173
TuringSim::Symbol::TuringStyleMixedSymbolPattern::TuringStyleMixedSymbolPattern
constexpr TuringStyleMixedSymbolPattern(const std::set< SymbolType > &symbols, const std::set< SymbolType > &keys, bool neg)
Build a TuringStyleMixedSymbolPattern from components.
Definition: turingMachineSymbolPattern.h:445
TuringSim::Symbol::MixedSymbolPattern::MixedSymbolPattern
constexpr MixedSymbolPattern(const std::set< KeyType > &symbols, const std::set< KeyType > &keys, bool neg)
Builds a new MixedSymbolPattern.
Definition: turingMachineSymbolPattern.h:318
TuringSim::Symbol::TuringStyleConstantSymbolPattern::TuringStyleConstantSymbolPattern
constexpr TuringStyleConstantSymbolPattern(const std::set< T > &v, bool b)
Construct a pattern which accept or reject a sequence of symbols.
Definition: turingMachineSymbolPattern.h:50
TuringSim::Symbol::TuringStyleSymbolPattern
std::variant< TuringStyleConstantSymbolPattern< T >, TuringStyleDynamicSymbolPattern< T > > TuringStyleSymbolPattern
a TuringStyleConstantSymbolPattern or a TuringStyleDynamicSymbolPattern.
Definition: turingMachineSymbolPattern.h:488
TuringSim::Utils::Debug::debug
std::function< std::basic_ostream< CharT, Traits > &(std::basic_ostream< CharT, Traits > &)> debug(const T &s)
Generic debug printing function.
Definition: printer.h:34
TuringSim::Symbol::MixedSymbolPattern
A dynamic symbol pattern where some accepted/rejected symbols are explicit and constant,...
Definition: turingMachineSymbolPattern.h:311
TuringSim::Symbol::TuringStyleConstantSymbolPattern::operator!=
constexpr bool operator!=(const TuringStyleConstantSymbolPattern< T > &other) const
Non-equality operator.
Definition: turingMachineSymbolPattern.h:69
TuringSim::Symbol::TuringStyleConstantSymbolPattern::TuringStyleConstantSymbolPattern
constexpr TuringStyleConstantSymbolPattern(const std::set< T > &v)
Construct a pattern which accept a sequence of symbols.
Definition: turingMachineSymbolPattern.h:41
TuringSim::Symbol::TuringStyleDynamicSymbolPattern::TuringStyleDynamicSymbolPattern
constexpr TuringStyleDynamicSymbolPattern(const SymbolType &key)
Make a dynamic pattern that accepts a single key.
Definition: turingMachineSymbolPattern.h:258