TuringSim
C++ framework to simulate abstract computing models
deterministicMachineRunner.h
1 #pragma once
2 
3 #include <runner/machineRunner.h>
4 
5 namespace TuringSim::Runner {
14  template<
15  typename MachineType,
16  typename ListenerType,
17  typename ListenerConstructorArgs = typename MachineRunnerArgs<MachineType, ListenerType>::ListenerConstructorArgs
18  >
20 
28  template<
29  typename MachineType_,
30  typename ListenerType_,
31  typename... Args
32  >
34  MachineType_,
35  ListenerType_,
36  std::tuple<Args...>
37  >
38  : public MachineRunner<MachineType_, ListenerType_> {
40  public:
41  using typename MachineRunner_::StateType;
42  using typename MachineRunner_::MachineType;
43  using typename MachineRunner_::StorageType;
44  using typename MachineRunner_::ListenerType;
45  using typename MachineRunner_::ListenerIdType;
46  using typename MachineRunner_::TransitionType;
47  using typename MachineRunner_::ApplyHelperType;
48 
52  typedef std::integral_constant<bool, !std::is_same_v<ListenerType, void>> IsListened;
55  static constexpr bool IsListened_v = IsListened::value;
56 
60  typedef typename MachineType::IsAccepting IsAccepting;
63  static constexpr bool IsAccepting_v = IsAccepting::value;
64 
68  typedef typename MachineType::IsAlternating IsAlternating;
71  static constexpr bool IsAlternating_v = IsAlternating::value;
72 
76  typedef std::conditional_t<IsListened_v, std::tuple<StateType, ListenerIdType>, StateType> StateAndIdType;
77 
78  static_assert(std::is_same_v<std::tuple<Args...>, typename MachineRunnerArgs<MachineType, ListenerType>::ListenerConstructorArgs>,
79  "The only valid value of template parameter ListenerConstructorArgs is the default one.");
80 
87  DeterministicMachineRunner(const MachineType& machine, Args ...listener) :
88  MachineRunner_(machine, listener...),
89  currentStateAndId(getInitialStateAndId()),
90  memory(),
91  running(true) {
92  }
93 
98  MachineRunner_(other),
99  currentStateAndId(other.currentStateAndId),
100  memory(other.memory),
101  running(other.running)
102  {}
103 
108  MachineRunner_(std::move(other)),
109  currentStateAndId(std::move(other.currentStateAndId)),
110  memory(std::move(other.memory)),
111  running(std::move(other.running))
112  {}
113 
119  if(this != &other) {
120  MachineRunner_::operator=(other);
121  currentStateAndId = other.currentStateAndId;
122  memory = other.memory;
123  running = other.running;
124  }
125  return *this;
126  }
127 
133  if(this != &other) {
134  MachineRunner_::operator=(std::move(other));
135  currentStateAndId = std::move(other.currentStateAndId);
136  memory = std::move(other.memory);
137  running = std::move(other.running);
138  }
139  return *this;
140  }
141 
144  virtual ~DeterministicMachineRunner() override {}
145 
149  const StorageType& getStorage() const noexcept {
150  return memory;
151  }
152 
156  StorageType& getStorage() noexcept {
157  return memory;
158  }
159 
163  const StateType& getCurrentState() const noexcept {
164  if constexpr (IsListened_v) {
165  return std::get<StateType>(currentStateAndId);
166  } else {
167  return currentStateAndId;
168  }
169  }
170 
174  bool isRunning() const noexcept {
175  return running;
176  }
177 
178  virtual void step(size_t nbIter = 1) override {
179  for(size_t i = 0; i < nbIter && running; ++i) {
180  this->oneStep();
181  }
182  }
183 
184  virtual void exec() override {
185  while(running) {
186  this->oneStep();
187  }
188  }
189 
190 #pragma clang diagnostic push
191 #pragma clang diagnostic ignored "-Winconsistent-missing-override"
192 
197  virtual bool accept() {
198  this->exec();
199 
200  if constexpr (!IsAccepting_v) {
201  return true;
202  }
203  else if constexpr (IsAccepting_v && !IsAlternating_v) {
204  return this->machine.isAcceptingConfiguration(getCurrentState(), this->getStorage());
205  } else {
206  switch (this->machine.isAcceptingConfiguration(getCurrentState(), memory)) {
207  case Machine::Acceptance::Accept:
208  case Machine::Acceptance::Universal:
209  return true;
210  case Machine::Acceptance::Reject:
211  case Machine::Acceptance::Existential:
212  return false;
213  }
214  }
215  }
216 #pragma clang diagnostic pop
217 
218  protected:
223  if constexpr (IsListened_v) {
224  return {MachineRunner_::machine.getInitialState(), MachineRunner_::listener.getInitialId()};
225  } else {
226  return MachineRunner_::machine.getInitialState();
227  }
228  }
229 
236  virtual void oneStep() override {
237  if (!this->running) {
238  return;
239  }
240 
241  if constexpr (IsListened_v) {
242  auto& [currentState, currentId] = currentStateAndId;
243  std::optional<std::pair<const TransitionType &, ApplyHelperType>> matchingTransition =
244  MachineRunner_::machine.getMatchingTransition(currentState, memory);
245 
246  if (matchingTransition) {
247  ListenerIdType id = this->listener.registerPreTransition(currentState, memory, currentId);
248  auto&[transition, helper] = *matchingTransition;
249  currentState = transition.apply(
250  currentState,
251  memory,
252  std::move(helper),
253  this->running);
254  this->running = this->running && !this->machine.isHaltingConfiguration(currentState, memory);
255  this->listener.registerPostTransition(id, currentState, memory, transition, helper, this->running);
256  currentId = id;
257  } else {
258  this->running = false;
259  this->listener.registerNoTransition(currentId, currentState, memory);
260  }
261  } else {
262  auto& currentState = currentStateAndId;
263  std::optional<std::pair<const TransitionType &, ApplyHelperType>> matchingTransition =
264  MachineRunner_::machine.getMatchingTransition(currentState, memory);
265 
266  if (matchingTransition) {
267  auto&[transition, helper] = *matchingTransition;
268  currentState = transition.apply(
269  currentState,
270  memory,
271  std::move(helper),
272  this->running);
273  this->running = this->running && !this->machine.isHaltingConfiguration(currentState, memory);
274  } else {
275  this->running = false;
276  }
277  }
278  }
279 
284 
289 
293  bool running;
294  };
295 }
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::DeterministicMachineRunner
constexpr DeterministicMachineRunner(DeterministicMachineRunner &&other)
Move a runner.
Definition: deterministicMachineRunner.h:107
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::getStorage
const StorageType & getStorage() const noexcept
Get a const reference to the memory of the machine.
Definition: deterministicMachineRunner.h:149
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::accept
virtual bool accept()
Test acceptance.
Definition: deterministicMachineRunner.h:197
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::operator=
constexpr DeterministicMachineRunner & operator=(const DeterministicMachineRunner &other)
Copy a runner.
Definition: deterministicMachineRunner.h:118
TuringSim::Runner::MachineRunner::ApplyHelperType
MachineType::ApplyHelperType ApplyHelperType
The type of transitions apply helpers of the machine.
Definition: machineRunner.h:163
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::getStorage
StorageType & getStorage() noexcept
Get a reference to the memory of the machine.
Definition: deterministicMachineRunner.h:156
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::StateAndIdType
std::conditional_t< IsListened_v, std::tuple< StateType, ListenerIdType >, StateType > StateAndIdType
the current state, and the corresponding id if any.
Definition: deterministicMachineRunner.h:76
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::memory
StorageType memory
The memories of the Machine.
Definition: deterministicMachineRunner.h:288
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::DeterministicMachineRunner
DeterministicMachineRunner(const MachineType &machine, Args ...listener)
Construct a MachineRunner from a Machine.
Definition: deterministicMachineRunner.h:87
TuringSim::Runner::MachineRunner::TransitionType
MachineType::TransitionType TransitionType
The type of transitions of the machine.
Definition: machineRunner.h:158
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::~DeterministicMachineRunner
virtual ~DeterministicMachineRunner() override
Destroy the runner.
Definition: deterministicMachineRunner.h:144
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::running
bool running
Whether the machine is sill running.
Definition: deterministicMachineRunner.h:293
TuringSim::Runner
The namespace of machine runners.
Definition: deterministicMachineRunner.h:5
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::IsAccepting
MachineType::IsAccepting IsAccepting
std::true_type if the machine is accepting or alternating, std::false_type otherwise.
Definition: deterministicMachineRunner.h:60
TuringSim::Runner::MachineRunner::StateType
MachineType::StateType StateType
The type of states of the machine.
Definition: machineRunner.h:148
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::getCurrentState
const StateType & getCurrentState() const noexcept
Get a const reference to the current state.
Definition: deterministicMachineRunner.h:163
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::step
virtual void step(size_t nbIter=1) override
Execute a given number of steps of the machine, one step by default.
Definition: deterministicMachineRunner.h:178
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::exec
virtual void exec() override
Run the machine until it halts.
Definition: deterministicMachineRunner.h:184
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::isRunning
bool isRunning() const noexcept
Test if the machine is still running.
Definition: deterministicMachineRunner.h:174
TuringSim::Runner::MachineRunner::ListenerType
ListenerType_ ListenerType
The type of the listener.
Definition: machineRunner.h:142
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::getInitialStateAndId
StateAndIdType getInitialStateAndId()
Return the initial state along with the initial listener id if any.
Definition: deterministicMachineRunner.h:222
TuringSim::Runner::MachineRunnerArgs::ListenerConstructorArgs
std::tuple< ListenerType & > ListenerConstructorArgs
The tuple of parameters of a runner, excluding the machine parameter.
Definition: machineRunner.h:101
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::currentStateAndId
StateAndIdType currentStateAndId
Store the configuration during the execution, with the id leading to it.
Definition: deterministicMachineRunner.h:283
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::IsListened
std::integral_constant< bool, !std::is_same_v< ListenerType, void > > IsListened
std::true_type if the runner has a listener, std::false_type otherwise.
Definition: deterministicMachineRunner.h:52
TuringSim::Runner::MachineRunner::ListenerIdType
ListenerType::IdType ListenerIdType
The type of identifiers used by the listener.
Definition: machineRunner.h:169
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::oneStep
virtual void oneStep() override
Execute one step of the machine.
Definition: deterministicMachineRunner.h:236
TuringSim::Runner::DeterministicMachineRunner
A class to run a simulate the execution of a deterministic Machine.
Definition: deterministicMachineRunner.h:19
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::IsAlternating
MachineType::IsAlternating IsAlternating
std::true_type if the machine is alternating, std::false_type otherwise.
Definition: deterministicMachineRunner.h:68
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::operator=
constexpr DeterministicMachineRunner & operator=(DeterministicMachineRunner &&other)
Move a runner.
Definition: deterministicMachineRunner.h:132
TuringSim::Runner::MachineRunner::StorageType
MachineType::StorageType StorageType
The type of the memory of the machine.
Definition: machineRunner.h:153
TuringSim::Runner::MachineRunner
A class to run a simulate the execution of a Machine.
Definition: machineRunner.h:132
TuringSim::Runner::DeterministicMachineRunner< MachineType_, ListenerType_, std::tuple< Args... > >::DeterministicMachineRunner
constexpr DeterministicMachineRunner(const DeterministicMachineRunner &other)
Copy a runner.
Definition: deterministicMachineRunner.h:97
TuringSim::Runner::MachineRunner::MachineType
MachineType_ MachineType
The type of the simulated machine.
Definition: machineRunner.h:137