Turing_Machine/states.c

207 lines
4.6 KiB
C
Raw Normal View History

#include <stdlib.h>
#include <stdio.h>
#include "const.h"
#include "states.h"
// States of a Turing Machine that checks whether a number DOESN'T divide another number
// NTS: Check that the first number is smaller? Actually not necessary: see state 2.
/*
Initially, I defined a triplet, which was what the different states, which are functions returned.
typedef struct {
int state; // Finite list of states: initial (0), state 1, state 2, state 3, ..., state 7.
int symbol; // Finite list of symbols: 0,1,2,3,4,5,6,7,8,9
int movement; // Left = -1, Right =1;
} ssm;
But I thought that modifying pointers was easier and more elegant.
*/
void state0(int *symbol, int *state, int *movement);
void state1(int *symbol, int *state, int *movement);
void state2(int *symbol, int *state, int *movement);
void state3(int *symbol, int *state, int *movement);
void state4(int *symbol, int *state, int *movement);
void state5(int *symbol, int *state, int *movement);
void state6(int *symbol, int *state, int *movement);
void state7(int *symbol, int *state, int *movement);
// This function is the delta of which Kozen speaks of in p.210 &ss in Automata and Computability.
void carry_out_step(int *symbol, int *state, int *movement){ // I could make this a bigger if/else tree, but I don't want to.
// Initially, I thought to use https://stackoverflow.com/questions/840501/how-do-function-pointers-in-c-work, but this proved unnecessary.
if(*state==0){
state0(symbol,state, movement);
}
else if(*state==1){
// Nótese que los else ifs son necesarios, porque después de state0, *state es =1, pero queremos que se de cuenta en la siguiente vuelta
state1(symbol,state, movement);
}
else if(*state==2){
state2(symbol,state, movement);
}
else if(*state==3){
state3(symbol,state, movement);
}
else if(*state==4){
state4(symbol,state, movement);
}
else if(*state==5){
state5(symbol,state, movement);
}
else if(*state==6){
state6(symbol,state, movement);
}
else if(*state==7){
state7(symbol,state, movement);
}
}
void state0(int *symbol, int *state, int *movement){
if(*symbol ==0){
*symbol=0; // This is the left endmarker. It isn't changed. This line could be ommited.
*movement= 1; // Move to the right (0 would be to the left).
*state=1; // Change to state 1.
}
else{
fprintf(stdout,"\nEn state0, REJECT");
*state = REJECT; // This is defined as a constant in const.h
// The program ends, because it has unspecified behaviour
}
}
void state1(int *symbol, int *state, int *movement){
if(*symbol ==1){
*symbol=3; // Another symbol.
*movement= 1; // Move to the right (-1 would be to the left).
*state=2; // Change to state 2.
}
else{
fprintf(stdout,"\nEn state1, REJECT");
*state = REJECT; // This is defined as a constant in const.h
// The program ends, because it has unspecified behaviour
}
}
void state2(int *symbol, int *state, int *movement){
if(*symbol ==2){
*symbol=4; // You get the idea.
*movement= -1;
*state=3;
}
else if(*symbol ==9){
*state=ACCEPT;
fprintf(stdout,"\nIt accepts because the first number doesn't divide the second");
}
else{
*symbol=*symbol; // redundant
*movement= 1;
*state=2;
}
}
void state3(int *symbol, int *state, int *movement){
if(*symbol ==0){
*symbol=0;
*movement= 1;
*state=4;
}
else {
*symbol=*symbol;
*movement = -1;
*state= 3;
}
}
void state4(int *symbol, int *state, int *movement){
if(*symbol ==3){
*symbol=3;
*movement= 1;
*state=4;
}
else if(*symbol ==1){
*symbol=1;
*movement= -1;
*state=5;
}
else if(*symbol ==8){
*symbol=8;
*movement= 1;
*state=6;
}
else{
*state = REJECT; // This is defined as a constant in const.h
// The program ends, because it has unspecified behaviour
}
}
void state5(int *symbol, int *state, int *movement){
// This state comes to be because at the end of option symbol ==1 in state 4, I want to stay on the same place, but have to move.
*symbol =*symbol;
*movement = 1;
*state = 1;
}
void state6(int *symbol, int *state, int *movement){
if(*symbol ==2){
*symbol=4;
*movement=-1;
*state=7;
}
else if(*symbol ==9){
*symbol=9;
*movement=-1;
*state = REJECT;
fprintf(stdout,"\nIt rejects because the first number DOES divide the second\n");// The number does divide.
}
else{
*symbol = *symbol;
*movement =1;
*state=6;
}
}
void state7(int *symbol, int *state, int *movement){
if(*symbol ==3){
*symbol=1;
*movement=-1;
*state=7;
}
else if(*symbol ==0){
*symbol=0;
*movement= 1;
*state = 1;
}
else{
*symbol = *symbol;
*movement =-1;
*state=7;
}
}