using System;
using System.Collections.Generic;
using System.Linq;
namespace TuringMachine
{
public class Head
{
public const char Blank = '_';
public Head(IEnumerable<char> tape, int headPosition)
{
if (tape == null) throw new ArgumentNullException(nameof(tape));
var safeData = tape as char[] ?? tape.ToArray();
if (headPosition > safeData.Count() - 1 || headPosition < 0)
throw new IndexOutOfRangeException("Invalid head position");
Tape = safeData;
HeadPosition = headPosition;
}
public IEnumerable<char> Tape { get; }
public int HeadPosition { get; }
public Head Write(char head) =>
new Head(new List<char>(Tape) { [HeadPosition] = head }, HeadPosition);
public Head MoveLeft() => HeadPosition == 0
? new Head(new[] { Blank }.Concat(Tape), 0)
: new Head(Tape, HeadPosition - 1);
public Head MoveRight() => HeadPosition == Tape.Count() - 1
? new Head(Tape.Concat(new[] { Blank }), HeadPosition + 1)
: new Head(Tape, HeadPosition + 1);
public Head Move(HeadDirection direction)
{
switch (direction)
{
case HeadDirection.Left:
return MoveLeft();
case HeadDirection.NoMove:
return this;
case HeadDirection.Right:
return MoveRight();
default:
throw new ArgumentOutOfRangeException(nameof(direction), direction, null);
}
}
public char Read() => Tape.ElementAt(HeadPosition);
public override string ToString() => $@"Tape:
{Tape.Select(GetChar).Aggregate((agg, next) => agg + next)}";
private string GetChar(char c, int index) =>
index == HeadPosition ? $"({c})" : c.ToString();
}
}
namespace TuringMachine
{
public class Transition
{
public Transition(int initialState, char read, char write, HeadDirection headDirection, int nextState)
{
InitialState = initialState;
Read = read;
Write = write;
HeadDirection = headDirection;
NextState = nextState;
}
public int InitialState { get; }
public char Read { get; }
public char Write { get; }
public HeadDirection HeadDirection { get; }
public int NextState { get; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace TuringMachine
{
public class Machine
{
public Machine(int state, Head head, IEnumerable<transition> transitionTable)
{
if (head == null) throw new ArgumentNullException(nameof(head));
if (transitionTable == null) throw new ArgumentNullException(nameof(transitionTable));
State = state;
Head = head;
TransitionTable = transitionTable;
}
public int State { get; }
public Head Head { get; }
public IEnumerable<transition> TransitionTable { get; }
public Machine Step()
{
if (State < 0) return this;
return
TransitionTable
.Where(t => t.InitialState == State && t.Read == Head.Read())
.DefaultIfEmpty(new Transition(0, Head.Blank, Head.Read(), HeadDirection.NoMove,
TuringMachine.State.Error))
.Select(
t => new Machine(t.NextState, Head.Write(t.Write).Move(t.HeadDirection), TransitionTable))
.First();
}
public Machine Run()
{
var m = this;
while (m.State >= 0)
m = m.Step();
return m;
}
}
}
using System.Collections.Generic;
using System.Resources;
namespace TuringMachine
{
public static class TransitionTableGenerator
{
public static IEnumerable<transition> Addition() => new[]
{
new Transition(0, Tape.Blank, Tape.Blank, HeadDirection.Right, 0),
new Transition(0, '1', '1', HeadDirection.Right, 1),
new Transition(1, Tape.Blank, '1', HeadDirection.Right, 2),
new Transition(1, '1', '1', HeadDirection.Right, 1),
new Transition(2, Tape.Blank, Tape.Blank, HeadDirection.Left, 3),
new Transition(2, '1', '1', HeadDirection.Right, 2),
new Transition(3, Tape.Blank, Tape.Blank, HeadDirection.Left, 3),
new Transition(3, '1', Tape.Blank, HeadDirection.Left, 4),
new Transition(4, Tape.Blank, Tape.Blank, HeadDirection.NoMove, State.Halt),
new Transition(4, '1', '1', HeadDirection.Left, 4)
};
}
}
using System.Collections.Generic;
using System.Resources;
namespace TuringMachine
{
public static class TransitionTableGenerator
{
public static IEnumerable<transition> Multiplication() => new[]
{
new Transition(0, Tape.Blank, Tape.Blank, HeadDirection.Right, 1),
new Transition(0, '1', Tape.Blank, HeadDirection.Right, 2),
new Transition(1, Tape.Blank, Tape.Blank, HeadDirection.Right, 14),
new Transition(1, '1', Tape.Blank, HeadDirection.Right, 2),
new Transition(2, Tape.Blank, Tape.Blank, HeadDirection.Right, 3),
new Transition(2, '1', '1', HeadDirection.Right, 2),
new Transition(3, Tape.Blank, Tape.Blank, HeadDirection.Left, 15),
new Transition(3, '1', Tape.Blank, HeadDirection.Right, 4),
new Transition(4, Tape.Blank, Tape.Blank, HeadDirection.Right, 5),
new Transition(4, '1', '1', HeadDirection.Right, 4),
new Transition(5, Tape.Blank, '1', HeadDirection.Left, 6),
new Transition(5, '1', '1', HeadDirection.Right, 5),
new Transition(6, Tape.Blank, Tape.Blank, HeadDirection.Left, 7),
new Transition(6, '1', '1', HeadDirection.Left, 6),
new Transition(7, Tape.Blank, '1', HeadDirection.Left, 9),
new Transition(7, '1', '1', HeadDirection.Left, 8),
new Transition(8, Tape.Blank, '1', HeadDirection.Right, 3),
new Transition(8, '1', '1', HeadDirection.Left, 8),
new Transition(9, Tape.Blank, Tape.Blank, HeadDirection.Left, 10),
new Transition(9, '1', '1', HeadDirection.Left, 9),
new Transition(10, Tape.Blank, Tape.Blank, HeadDirection.Right, 12),
new Transition(10, '1', '1', HeadDirection.Left, 11),
new Transition(11, Tape.Blank, Tape.Blank, HeadDirection.Right, 0),
new Transition(11, '1', '1', HeadDirection.Left, 11),
new Transition(12, Tape.Blank, Tape.Blank, HeadDirection.Right, 12),
new Transition(12, '1', Tape.Blank, HeadDirection.Right, 13),
new Transition(13, Tape.Blank, Tape.Blank, HeadDirection.NoMove, State.Halt),
new Transition(13, '1', Tape.Blank, HeadDirection.Right, 13),
new Transition(14, Tape.Blank, Tape.Blank, HeadDirection.NoMove, State.Halt),
new Transition(14, '1', Tape.Blank, HeadDirection.Right, 14),
new Transition(15, Tape.Blank, Tape.Blank, HeadDirection.Left, 16),
new Transition(15, '1', Tape.Blank, HeadDirection.Left, 15),
new Transition(16, Tape.Blank, Tape.Blank, HeadDirection.NoMove, State.Halt),
new Transition(16, '1', Tape.Blank, HeadDirection.Left, 16)
};
}
}
using System.Collections.Generic;
using System.Linq;
namespace TuringMachine
{
public class Head
{
public const char Blank = '_';
public Head(IEnumerable<char> tape, int headPosition)
{
if (tape == null) throw new ArgumentNullException(nameof(tape));
var safeData = tape as char[] ?? tape.ToArray();
if (headPosition > safeData.Count() - 1 || headPosition < 0)
throw new IndexOutOfRangeException("Invalid head position");
Tape = safeData;
HeadPosition = headPosition;
}
public IEnumerable<char> Tape { get; }
public int HeadPosition { get; }
public Head Write(char head) =>
new Head(new List<char>(Tape) { [HeadPosition] = head }, HeadPosition);
public Head MoveLeft() => HeadPosition == 0
? new Head(new[] { Blank }.Concat(Tape), 0)
: new Head(Tape, HeadPosition - 1);
public Head MoveRight() => HeadPosition == Tape.Count() - 1
? new Head(Tape.Concat(new[] { Blank }), HeadPosition + 1)
: new Head(Tape, HeadPosition + 1);
public Head Move(HeadDirection direction)
{
switch (direction)
{
case HeadDirection.Left:
return MoveLeft();
case HeadDirection.NoMove:
return this;
case HeadDirection.Right:
return MoveRight();
default:
throw new ArgumentOutOfRangeException(nameof(direction), direction, null);
}
}
public char Read() => Tape.ElementAt(HeadPosition);
public override string ToString() => $@"Tape:
{Tape.Select(GetChar).Aggregate((agg, next) => agg + next)}";
private string GetChar(char c, int index) =>
index == HeadPosition ? $"({c})" : c.ToString();
}
}
namespace TuringMachine
{
public class Transition
{
public Transition(int initialState, char read, char write, HeadDirection headDirection, int nextState)
{
InitialState = initialState;
Read = read;
Write = write;
HeadDirection = headDirection;
NextState = nextState;
}
public int InitialState { get; }
public char Read { get; }
public char Write { get; }
public HeadDirection HeadDirection { get; }
public int NextState { get; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace TuringMachine
{
public class Machine
{
public Machine(int state, Head head, IEnumerable<transition> transitionTable)
{
if (head == null) throw new ArgumentNullException(nameof(head));
if (transitionTable == null) throw new ArgumentNullException(nameof(transitionTable));
State = state;
Head = head;
TransitionTable = transitionTable;
}
public int State { get; }
public Head Head { get; }
public IEnumerable<transition> TransitionTable { get; }
public Machine Step()
{
if (State < 0) return this;
return
TransitionTable
.Where(t => t.InitialState == State && t.Read == Head.Read())
.DefaultIfEmpty(new Transition(0, Head.Blank, Head.Read(), HeadDirection.NoMove,
TuringMachine.State.Error))
.Select(
t => new Machine(t.NextState, Head.Write(t.Write).Move(t.HeadDirection), TransitionTable))
.First();
}
public Machine Run()
{
var m = this;
while (m.State >= 0)
m = m.Step();
return m;
}
}
}
using System.Collections.Generic;
using System.Resources;
namespace TuringMachine
{
public static class TransitionTableGenerator
{
public static IEnumerable<transition> Addition() => new[]
{
new Transition(0, Tape.Blank, Tape.Blank, HeadDirection.Right, 0),
new Transition(0, '1', '1', HeadDirection.Right, 1),
new Transition(1, Tape.Blank, '1', HeadDirection.Right, 2),
new Transition(1, '1', '1', HeadDirection.Right, 1),
new Transition(2, Tape.Blank, Tape.Blank, HeadDirection.Left, 3),
new Transition(2, '1', '1', HeadDirection.Right, 2),
new Transition(3, Tape.Blank, Tape.Blank, HeadDirection.Left, 3),
new Transition(3, '1', Tape.Blank, HeadDirection.Left, 4),
new Transition(4, Tape.Blank, Tape.Blank, HeadDirection.NoMove, State.Halt),
new Transition(4, '1', '1', HeadDirection.Left, 4)
};
}
}
using System.Collections.Generic;
using System.Resources;
namespace TuringMachine
{
public static class TransitionTableGenerator
{
public static IEnumerable<transition> Multiplication() => new[]
{
new Transition(0, Tape.Blank, Tape.Blank, HeadDirection.Right, 1),
new Transition(0, '1', Tape.Blank, HeadDirection.Right, 2),
new Transition(1, Tape.Blank, Tape.Blank, HeadDirection.Right, 14),
new Transition(1, '1', Tape.Blank, HeadDirection.Right, 2),
new Transition(2, Tape.Blank, Tape.Blank, HeadDirection.Right, 3),
new Transition(2, '1', '1', HeadDirection.Right, 2),
new Transition(3, Tape.Blank, Tape.Blank, HeadDirection.Left, 15),
new Transition(3, '1', Tape.Blank, HeadDirection.Right, 4),
new Transition(4, Tape.Blank, Tape.Blank, HeadDirection.Right, 5),
new Transition(4, '1', '1', HeadDirection.Right, 4),
new Transition(5, Tape.Blank, '1', HeadDirection.Left, 6),
new Transition(5, '1', '1', HeadDirection.Right, 5),
new Transition(6, Tape.Blank, Tape.Blank, HeadDirection.Left, 7),
new Transition(6, '1', '1', HeadDirection.Left, 6),
new Transition(7, Tape.Blank, '1', HeadDirection.Left, 9),
new Transition(7, '1', '1', HeadDirection.Left, 8),
new Transition(8, Tape.Blank, '1', HeadDirection.Right, 3),
new Transition(8, '1', '1', HeadDirection.Left, 8),
new Transition(9, Tape.Blank, Tape.Blank, HeadDirection.Left, 10),
new Transition(9, '1', '1', HeadDirection.Left, 9),
new Transition(10, Tape.Blank, Tape.Blank, HeadDirection.Right, 12),
new Transition(10, '1', '1', HeadDirection.Left, 11),
new Transition(11, Tape.Blank, Tape.Blank, HeadDirection.Right, 0),
new Transition(11, '1', '1', HeadDirection.Left, 11),
new Transition(12, Tape.Blank, Tape.Blank, HeadDirection.Right, 12),
new Transition(12, '1', Tape.Blank, HeadDirection.Right, 13),
new Transition(13, Tape.Blank, Tape.Blank, HeadDirection.NoMove, State.Halt),
new Transition(13, '1', Tape.Blank, HeadDirection.Right, 13),
new Transition(14, Tape.Blank, Tape.Blank, HeadDirection.NoMove, State.Halt),
new Transition(14, '1', Tape.Blank, HeadDirection.Right, 14),
new Transition(15, Tape.Blank, Tape.Blank, HeadDirection.Left, 16),
new Transition(15, '1', Tape.Blank, HeadDirection.Left, 15),
new Transition(16, Tape.Blank, Tape.Blank, HeadDirection.NoMove, State.Halt),
new Transition(16, '1', Tape.Blank, HeadDirection.Left, 16)
};
}
}
No comments:
Post a Comment