//Printing all the states and transitions in the Turing Machine public void printTuringMachine() { StateNode nodeList = nodes; //We have a list of states TransitionNode transitions = null; //We use this variable to get through all the transitions of one state if (nodeList != null) //If nodeList it not null, we print them. Otherwise there aren't states to print { Console.WriteLine("Number of states in the Turing Machine: {0}", nStates);//Printing the total number of states in the Turing Machine while (nodeList != null) { Console.Write("{0} :[", nodeList.getStateId()); //Printing the ID of the states transitions = nodeList.getTransition(); //Get the first transition of the current state while (transitions != null) //Each iteration is a transition { Console.Write("{0} ", transitions.getDestNode().getStateId()); //Printing the destination node after the transition is completed transitions = transitions.getNextTNode(); //We pass to the next transition of the SAME state. } Console.WriteLine("]"); nodeList = nodeList.getNextSNode();//We pass to the next state } } else { Console.WriteLine("There is nothing to print."); } }
private char movement; //Movement of the tape //Constructor of the TransitionNode //We need a StateNode type variable which will be the destination node to the next state in the Turing Machine //String array named t contains the conditions for the transition in order to move to the next state and/or finish the Turing Machine public TransitionNode(StateNode destinationNode, string[] t) { destNode = destinationNode;//State destination node //Index on the array. What the number, character or letter represents. //2. What it is on the tape //3. What it will put on the tape //4. Movement of the tape charInTape = char.Parse(t[2]); repInTape = char.Parse(t[3]); movement = char.Parse(t[4]); //Reference to the next transition node, in case there is. This is asigned later nextTNode = null; }
//Create a transition and associate it with the state's number private void createTransitions(string[] t) { StateNode sAux = null, sAux2 = null; //States nodes auxiliars to search if the current state and the destination state exists TransitionNode trans = null; //New transition node to create if (nodes != null) //If nodes is not null, we can add transitions for those states //fetchNode returns a state node. { sAux = fetchNode(short.Parse(t[0]));//Search for a initial state with the Id given //If the node returned is null, it doesn't exist in the Turing Machine if (sAux == null) { Console.WriteLine("The starting node with the ID does not exist."); } else { //Return the destination node sAux2 = fetchNode(short.Parse(t[1]));//Search for the destination state with the Id given if (sAux2 == null) { Console.WriteLine("The destination node with the ID does not exist."); } else { trans = new TransitionNode(sAux2, t); //Create the transition node with the destination node of the current state trans.setNextTNode(sAux.getTransition()); //Create a list of transitions in the current state of sAux sAux.setTransition(trans); //Associating the transition to the state } } } else { Console.WriteLine("There aren't states in the Turing Machine"); } }
public void setNextTNode(TransitionNode nextTNode) { this.nextTNode = nextTNode; }
public void setTransition(TransitionNode transition) { this.transition = transition; }
private short stateId; //State's Id //Constructor of the class StateNode public StateNode(short stateId) { this.nextSNode = null; //Set the next node to null this.transition = null; //Set the transitions to null this.stateId = stateId; //Set the state's id }
//Recursive function to validate the string. //Here we use the transitions and we move throughout all the tape. //Disclaimer: after this, only god knows how it works. /s private static void validateTuringMachine(StateNode q0, string tape, short movement, string pointer, string fileName) { Console.Clear(); TransitionNode transition = q0.getTransition();//Getting the first transition of the current node //Write in console the tape and the pointer Console.WriteLine(tape); Console.WriteLine(pointer); //Sleep function System.Threading.Thread.Sleep(TimeSpan.FromSeconds(.5)); //If the first transition of the current node is null, it only means that either we came to a final state or there isn't transition on that node. if (transition != null) { while (transition != null) { // Add spaces at the end of the tape where the new characters will be written, as well as the pointer that should point them out. if (tape.Length == movement) { tape += ' '; } if (pointer.Length == movement) { pointer += ' '; } //Try-catch block to determinate whether the index of the string called "movement" is lower than 0. //Applies only in the subtraction. try { if (movement < 0) { throw new Exception(); } } catch (Exception E) {//Catch an exception when movement is lower than 0 //When this happends in the subtraction it means that either the result is 0 or a negative number, //which is represented with the number of dashes left in the tape using (StreamWriter file = new StreamWriter(fileName, true)) { file.WriteLine("Done"); } //Since the operation is finished we exit the application Console.WriteLine("Done\nPress any key to continue."); Console.ReadKey(); Environment.Exit(1); } //Compare the current character in the tape on all the transitions of the state //Tape is a string that contains the operation we introduce, movement is the index of that string //We look in the transitions if the character is equal to what we have in the string in determinated index if (tape[movement] == transition.getCharInTape()) { //Write in the file the tape and the pointer using (StreamWriter file = new StreamWriter(fileName, true)) { file.WriteLine(tape); file.WriteLine(pointer); file.WriteLine("Q: {0}\n" + "Next Q: {1}\n" + "Char in tape: {2}\tRep in tape: {3}\n" + "Movement: {4}\n", q0.getStateId(), transition.getDestNode().getStateId(), transition.getCharInTape(), transition.getRepInTape(), transition.getMovement()); } //Removing the current character in the tape and use the "aux" variable to store the string without the character removed string aux = tape.Remove(movement, 1); //Using the "aux" variable, get the character to replace from the transition node and put them in the current index determinated for "movement" aux = aux.Insert(movement, transition.getRepInTape().ToString()); //Same with the head pointer, but instead of getting the character from the transition node, use a space to replace it string auxP = pointer.Replace("^", " "); auxP = auxP.Insert(movement, "^"); //Conditions for the tape to know where to move next //Determinate where will the tape will move next. //R == right. So increase "movement" variable to move to the right in the string //L == left. Decrease "movement" to move to the left in the string if (transition.getMovement() == 'R') { movement++; } if (transition.getMovement() == 'L') { movement--; } //Recursive call function, this time with //destination state, //the new tape modified, //movement increased or decreased, //head pointer modified and //name file to keep writing on it validateTuringMachine(transition.getDestNode(), aux, movement, auxP, fileName); } else { transition = transition.getNextTNode(); //If the current character isn't in the current transition, move to next transition of the same state } } } else //There aren't transitions left, so the operation must been finished { using (StreamWriter file = new StreamWriter(fileName, true)) { file.WriteLine("Done"); } //Since the operation is finished we exit the application Console.WriteLine("Done\nPress any key to continue."); Console.ReadKey(); Environment.Exit(1); } }