92 lines
2.6 KiB
C#
92 lines
2.6 KiB
C#
using System;
|
|
|
|
namespace TuringMachine.Core
|
|
{
|
|
public class Machine
|
|
{
|
|
public Tape Tape { get; }
|
|
public TransitionTable Transitions { get; }
|
|
|
|
public int HeadPosition { get; private set; }
|
|
public string CurrentState { get; private set; }
|
|
public bool IsHalted { get; private set; }
|
|
public string InitialState { get; set; } = "q0";
|
|
|
|
public event Action? OnStep;
|
|
public event Action? OnHalt;
|
|
|
|
public Machine()
|
|
{
|
|
Tape = new Tape();
|
|
Transitions = new TransitionTable();
|
|
CurrentState = InitialState;
|
|
}
|
|
|
|
public void ForceHeadPosition(int position)
|
|
{
|
|
HeadPosition = position;
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
Tape.Clear();
|
|
HeadPosition = 0;
|
|
CurrentState = InitialState;
|
|
IsHalted = false;
|
|
OnStep?.Invoke();
|
|
}
|
|
|
|
public void LoadProgram(string initialState, IEnumerable<(string state, char read, string newState, char write, MoveDirection move, string comment)> transitions)
|
|
{
|
|
InitialState = initialState;
|
|
Transitions.Clear();
|
|
foreach (var t in transitions)
|
|
{
|
|
Transitions.Add(t.state, t.read, t.newState, t.write, t.move, t.comment);
|
|
}
|
|
Reset();
|
|
}
|
|
|
|
public bool Step()
|
|
{
|
|
if (IsHalted) return false;
|
|
|
|
char readSymbol = Tape[HeadPosition];
|
|
|
|
if (Transitions.TryGetTransition(CurrentState, readSymbol, out var result))
|
|
{
|
|
if (result == null)
|
|
{
|
|
// Should not simplify happen due to TryGetTransition semantics, but for safety
|
|
IsHalted = true;
|
|
OnHalt?.Invoke();
|
|
return false;
|
|
}
|
|
|
|
Tape[HeadPosition] = result.WriteSymbol;
|
|
CurrentState = result.NewState;
|
|
|
|
switch (result.MoveDirection)
|
|
{
|
|
case MoveDirection.Left:
|
|
HeadPosition--;
|
|
break;
|
|
case MoveDirection.Right:
|
|
HeadPosition++;
|
|
break;
|
|
}
|
|
|
|
OnStep?.Invoke();
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// No transition defined = Halt
|
|
IsHalted = true;
|
|
OnHalt?.Invoke();
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|