Return to the C++ Demos Home Page

Finite Automata
Borland Turbo C++ was used

This code emulates a simple Turing machine.  

The Header

#include <iostream.h>
#include <conio.h>

class TuringMachine
{
    protected:
        char* Tape;
        char* HeadString;
    // The Quad Variables
        int* Starts;
        char* Readins;
        char* Actions;
        int* Finis;
    // Other Fun Stuff
        int Head,TapeMax,StartingPoint,NumQuads;

    public:
        TuringMachine(int InitTapeMax);
        void SetInput(int Input1,int Input2=0);
        void ShowTape(int InX, int InY);
        void InitTape();
        void MoveRight();
        void MoveLeft();
        void WriteSymbol(char Sym);
        void InitHead();
        void ShowHead();
        int GetStart() { return StartingPoint; }
        void SetHead(int InitHead) { Head = InitHead; }
        int GetHead() { return Head; }
        void EnterQuads(int InitNumQuads);
        int ActionForQuad(int InitStart, char InitReadin);
        void ShowQuads(int InX, int InY);
        void ApplyQuads();
};

The Splash Screen Data File.

	  Hello.  This is a small program, written in C++, that acts as
	a very limited Turing Machine tester.  Restricted to an alphabet
	of a single character (I) and inputs of one or two strings only, it
	still allows a large range of machines to be built and applied to
	input.
	  Due to an 18 credit load and a complete lack of ample time, the
	code has NO error traps or nicities.  What occurs if a machine is
	entered incorrectly or is just wrong is anyone's guess.  Also, when
	entering a machine DO NOT add the Q in front of states.  Just enter
	a number, then the Read Symbol, then the Action, then just a number
	for the final state.  For example, enter a f(x) = x+1 machine as :

	1 B R 2 <enter>
	2 I R 2 <enter>
	2 B I 3 <enter>
	3 I L 3 <enter>

	  That's about all.  You'll catch on to the rest.  Future features
	will include proper error traps, unlimited tape (Now only 40), and
	a "step-through" feature to watch the effect of each individual quad
	as the machine runs on the input.  Hope you like.

						               Lars Sorensen 

The Driver

// Shell for Turing Machine Program
// AUTHOR   : Lars Sorensen

#include <iostream.h>
#include <conio.h>
#include <fstream.h>
#include <stdlib.h>
#include <graphics.h>
#include "Turing.h"

void main(void)
{
 int Choice;

 TuringMachine M(60);

 gotoxy(1,1);
 textcolor(WHITE);
 textbackground(BLUE);
 clrscr();

  while (1)
    { //while
      clrscr();
      cout << "  The Turing Machine Processing Program\n\n";
      cout << " 1. Instructions and Excuses.\n";
      cout << " 2. Create (or change) an Input Tape.\n";
      cout << " 3. Build a Turing Machine (Enter Quadruples) \n";
      cout << " 4. Inspect your Tape.\n";
      cout << " 5. Inspect your Turing Machine Quadruples.\n";
      cout << " 6. Apply the Machine's Quads to the Input Tape.\n";
      cout << " 7. Exit the Program.\n\n";
      cout << "   Enter The Choice : ";

      cin >> (Choice);

      switch (Choice) {
	case 1 :
	  {
	   char ch;

	   ifstream infile("a:turing.doc");

	   clrscr();
	   cout << '\n';
	   while(infile)
	    {
	     infile.get(ch);
	     cout << ch;
	    }
	   cout << "\n                       Press a Key to Return to Menu";
	   getch();
	   break;
	  }
	case 2 :
	  {
	   int NumPuts, In1, In2=0;

	   clrscr();
	   gotoxy(1,3);
	   cout << "           OK.. Now it's time to enter the Input tape that your \n"
		<< "           machine will work on.  As you've been told, this program\n"
		<< "           works on very, very, limited versions of the machines.\n"
		<< "             You're input is limited to an alphabet of one symbol, I.\n"
		<< "           Because the tape has been initialized with B's all this\n"
		<< "           program needs is the number of I's to place on the tape.\n"
		<< "           The program also allows tapes with two input strings.\n\n"
		<< "           Now, Enter how many Inputs you'll need (1 or 2): ";
		cin >> NumPuts;

		 if( NumPuts != 1 )
		  {
		   cout << "\n           Enter the Number of I's you need for Input 1 : ";
		   cin >> In1;
		   cout <<"\n           Enter the Number of I's you need for Input 2 : ";
		   cin >> In2;
		  }
		 else
		  {
		   cout <<"\n           Enter the Number of I's you need : ";
		   cin >> In1;
		  }

		  M.SetInput(In1,In2);
		  cout << "\n\nThanks.... Press a Key to Inspect the Tape.";
		  clrscr();
		  M.ShowTape(10,12);
		  getch();
	   break;
	  }
	case 3 :
	  {
	   int NumQ;

	   clrscr();
	   gotoxy(1,3);
		cout << "           \n";
		cout << "           \n";
		cout << "           \n";
		cout << "           \n";
		cout << "           \n";
		cout << "           \n";
		cout << "           \n";
		cout << "           \n\n";
		cout << "           Enter the Number of Quadruples for your Machine : ";

		cin >> NumQ;
		clrscr();
		gotoxy(2,2);
		cout << "Now Enter Your Turing Machine\n\n";
		M.EnterQuads(NumQ);
	   break;
	  }
	case 4 :
	  {
	   clrscr();
	   M.ShowTape(10,12);
	   getch();
	   break;
	  }
	case 5 :
	  {
	   clrscr();
	   M.ShowQuads(20,3);
	   break;
	  }
	case 6 :
	  {
	   clrscr();
	   gotoxy(2,2);
	   cout << "Here is your Input Tape.";
	   M.ShowTape(2,4);
	   gotoxy(2,7);
	   cout << "Press a Key and Your Machine will be run on the Tape.\n";
	   getch();
	   M.ApplyQuads();
	   gotoxy(2,11);
	   cout << "Here is the Output Tape.";
	   M.ShowTape(2,13);
	   gotoxy(2,16);
	   cout << "Press a Key to return to the Menu.";
	   getch();
	   break;
	  }
	case 7 :
	   {
	      textcolor(WHITE);
	      textbackground(BLACK);
	      clrscr();
	      exit(0);
	   }
      } //switch
    } //while

// That's All Folks.....

}

The Guts

#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#include "Turing.h"

TuringMachine::TuringMachine(int InitTapeMax)
{
    Tape = new char[InitTapeMax-1];
    for (int i=0; i < TapeMax; i++ ) Tape[i] = 'B';
    TapeMax = InitTapeMax;
    StartingPoint = (TapeMax/2)-1;    
    Head = StartingPoint;
    InitTape();
}

void TuringMachine::SetInput(int Input1,int Input2)
{
    Head = StartingPoint;
    InitTape();

        if ( Input2 == 0 )
        {
            MoveRight();
            for (int j=(StartingPoint+1); j < (Input1+StartingPoint+1); j++)
                {
                WriteSymbol('I');
                MoveRight();
                }
        }
        else
        {
        MoveRight();
            for (int j=(StartingPoint+1); j < (Input1+StartingPoint+1); j++)
                {
                WriteSymbol('I');
                MoveRight();
                }
        MoveRight();
         for (int k=(StartingPoint+Input1+2); k < (Input2+StartingPoint+Input1+2); k++)
            {
            WriteSymbol('I');
            MoveRight();
            }
        }
    Head = StartingPoint;
  } 

void TuringMachine::ShowTape(int InX, int InY)
{
    // The Actual Tape
        gotoxy(InX,InY);
        for (int i=0; i < TapeMax; i++) cout << Tape[i];
    // The Head Position
        gotoxy(InX,InY+1);
        HeadString = new char[TapeMax-1];
        for (int k=0; k < TapeMax; k++) HeadString[k]=' ';
        HeadString[Head] = '^';
        for (int j=0; j < TapeMax; j++) cout << HeadString[j];
}

void TuringMachine::InitTape()
{
    for (int i=0; i < TapeMax; i++) Tape[i]='B';
}

void TuringMachine::InitHead()
{
    Head = (TapeMax/2)-1;
}

void TuringMachine::MoveRight()
{
    if ( Head == (TapeMax-1) )
        {
        cout << "Cannot Move Tape Any Further to the Right";
        }
    else
        {
        Head++;     // I know you don't need the brackets...Readability people!!
        }
}

void TuringMachine::MoveLeft()
{
    if ( Head == 0 )
        {
         cout << "Cannot Move Tape Any Further to the Left";
        }
    else
        {
        Head--;
        }
}

void TuringMachine::WriteSymbol(char Sym)
{
    Tape[Head] = Sym;
}

void TuringMachine::EnterQuads(int InitNumQuads)
{
    NumQuads = InitNumQuads;

    Starts = new int[NumQuads];
    Readins = new char[NumQuads];
    Actions = new char[NumQuads];
    Finis = new int[NumQuads];

    cout << "\nPlease Enter, in order, the Start State, "
            << "the Reading Symbol ( B or I ),\n"
            << "the Action to take ( R,L,I ), and "
            << "the Finish State ... \n";

    for ( int i=0; i < NumQuads; i++)
        {
        cin >> Starts[i] >> Readins[i] >> Actions[i] >> Finis[i];
        }
        cout << "Thank You...Press a Key to Continue.\n";
        getch();  // old C cheatin...where's stdio.h when you need it?
}

void TuringMachine::ShowQuads(int InX, int InY)
{
    for ( int j=0; j < NumQuads; j++)
        {
        gotoxy(InX,InY+j);
            cout << 'Q' << Starts[j] << ' ' 
                    << Readins[j] << ' '
                    << Actions[j] << ' '
                    << 'Q' << Finis[j];
        }
getch();
}


int TuringMachine::ActionForQuad(int InitStart, char InitReadin)
{    
        for(int i=0; i < NumQuads; i++ )
            {
                if ((InitStart==Starts[i]) && (InitReadin==Readins[i])) return i;
            }
return -1;
}

void TuringMachine::ApplyQuads()
{
    int CurrentState=1,NextState;
    char CurrentSymbol,NextAction;
    int NextIndex;

    while(1)
        {
            CurrentSymbol = Tape[Head];

            NextIndex = ActionForQuad(CurrentState,CurrentSymbol);
            if ( NextIndex == -1 ) break;

            NextAction = Actions[NextIndex];
            NextState = Finis[NextIndex];

            if ( NextAction == 'B' ) WriteSymbol('B');
            if ( NextAction == 'I' ) WriteSymbol('I');
            if ( NextAction == 'R' ) MoveRight();
            if ( NextAction == 'L' ) MoveLeft();

            CurrentState = NextState;

        }

        cout << "\n Machine has halted reading a " << CurrentSymbol
                << " in state " << CurrentState << '\n';
} // end of source
 

Return to the C++ Demos Home Page