#include #include #include #define EXIT_SUCCESS 0 #define EXIT_WRONGCOMMANDLINE 1 #define EXIT_MEMORY 2 #define EXIT_OPENFILE 3 #define EXIT_WRONGINPUTFORMAT 4 #define EXIT_TAPEEXCEEDED 5 enum _boolean {FALSE = 0, TRUE = 1}; typedef enum _boolean boolean; #define LUNGHEZZA_NOME 80 #define LUNGHEZZA_SIMBOLO 10 #define DIM_NASTRO 1000 typedef char Simbolo[LUNGHEZZA_SIMBOLO]; typedef char Stato[LUNGHEZZA_SIMBOLO]; typedef Stato* InsiemeStato; typedef Simbolo* Alfabeto; typedef Simbolo* VettoreSimboli; enum _mossa {Sinistra = 'S', Destra = 'D'}; typedef enum _mossa Mossa; typedef struct _struct_transizione Transizione; typedef Transizione* FunzioneTransizione; struct _struct_transizione { Stato StatoIn; Simbolo Input; Stato StatoFin; Simbolo Output; Mossa Spostamento; }; typedef struct _struct_TuringMachine TuringMachine; struct _struct_TuringMachine { int NumStati; InsiemeStato Q; Stato StatoIniziale; int NumStatiAccettanti; InsiemeStato A; int CardAlfabetoIngresso; Alfabeto AlfabetoIngresso; Simbolo Blank; int CardAlfabetoLavoro; Alfabeto AlfabetoLavoro; int NumTransizioni; FunzioneTransizione Delta; int DimNastro; VettoreSimboli Nastro; Stato StatoCorrente; int Pos; int NumPassi; }; void LeggeIstruzioni (int argc, char *argv[], char *TuringFile, char *InstanceFile); void CaricaMacchina (char *TuringFile, TuringMachine *TM); void CaricaIstanza (char *InstanceFile, TuringMachine *TM); void SimulaTuringMachine (TuringMachine *TM); void StampaRisultati (TuringMachine *TM); void DistruggeMacchina (TuringMachine *TM); int CercaStato (Stato S, InsiemeStato I, int CardI); int CercaSimbolo (Simbolo S, Alfabeto A, int CardA); int CercaTransizione (Stato StatoIn, Simbolo Input, FunzioneTransizione Delta, int NumTransizioni); void EsegueTransizione (int t, TuringMachine *TM); int main (int argc, char *argv[]) { char TuringFile[LUNGHEZZA_NOME+1]; char InstanceFile[LUNGHEZZA_NOME+1]; TuringMachine TM; // 1) Interpretazione della linea di comando LeggeIstruzioni(argc,argv,TuringFile,InstanceFile); // 2a) Caricamento della macchina di Turing da simulare CaricaMacchina(TuringFile,&TM); // 2b) Caricamento dell'istanza da elaborare CaricaIstanza(InstanceFile,&TM); // 4) Elaborazione SimulaTuringMachine(&TM); // 6) Stampa della risposta e del nastro di lavoro StampaRisultati(&TM); // 7) Deallocazione della macchina di Turing DistruggeMacchina(&TM); return EXIT_SUCCESS; } void LeggeIstruzioni (int argc, char *argv[], char *TuringFile, char *InstanceFile) { if (argc != 3) { printf("Formato della linea di comando errato!\n"); printf("Uso: %s [Turing machine] [Istanza]\n",argv[0]); exit(EXIT_WRONGCOMMANDLINE); } strcpy(TuringFile,argv[1]); strcpy(InstanceFile,argv[2]); } void CaricaMacchina (char *TuringFile, TuringMachine *TM) { FILE *fTuringFile; int s, t; char sp[LUNGHEZZA_SIMBOLO]; fTuringFile = fopen(TuringFile,"r"); if (fTuringFile == NULL) { printf("File %s does not exist!\n",TuringFile); exit(EXIT_OPENFILE); } if (fscanf(fTuringFile,"%*s %d\n",&TM->NumStati) != 1) { printf("Manca il numero di stati!\n"); exit(EXIT_WRONGINPUTFORMAT); } TM->Q = (InsiemeStato) calloc(TM->NumStati+1,sizeof(Stato)); if (TM->Q == NULL) { printf("Memoria insufficiente per allocare l'insieme di stato!\n"); exit(EXIT_MEMORY); } for (s = 1; s <= TM->NumStati; s++) { if (fscanf(fTuringFile,"%s",TM->Q[s]) != 1) { printf("Manca lo stato %d!\n",s); exit(EXIT_WRONGINPUTFORMAT); } if (CercaStato(TM->Q[s],TM->Q,s-1) > 0) { printf("Lo stato %s compare piu' volte!\n",TM->Q[s]); exit(EXIT_WRONGINPUTFORMAT); } } if (fscanf(fTuringFile,"%*s %s",TM->StatoIniziale) != 1) { printf("Manca lo stato iniziale!\n"); exit(EXIT_WRONGINPUTFORMAT); } // Verifica che lo stato iniziale faccia parte dell'insieme degli stati if (CercaStato(TM->StatoIniziale,TM->Q,TM->NumStati) == 0) { printf("Lo stato iniziale %s non fa parte dell'insieme degli stati!\n",TM->StatoIniziale); exit(EXIT_WRONGINPUTFORMAT); } if (fscanf(fTuringFile,"%*s %d",&TM->NumStatiAccettanti) != 1) { printf("Manca il numero di stati accettanti!\n"); exit(EXIT_WRONGINPUTFORMAT); } TM->A = (InsiemeStato) calloc(TM->NumStatiAccettanti+1,sizeof(Stato)); if (TM->A == NULL) { printf("Memoria insufficiente per allocare l'insieme degli stati accettanti!\n"); exit(EXIT_MEMORY); } for (s = 1; s <= TM->NumStatiAccettanti; s++) { if (fscanf(fTuringFile,"%s",TM->A[s]) != 1) { printf("Manca lo stato accettante %d!\n",s); exit(EXIT_WRONGINPUTFORMAT); } // Verifica che ogni stato accettante faccia parte dell'insieme degli stati if (CercaStato(TM->A[s],TM->Q,TM->NumStati) == 0) { printf("Lo stato accettante %s non fa parte dell'insieme di stato!\n",TM->A[s]); exit(EXIT_WRONGINPUTFORMAT); } // Verifica che non ci siano doppioni if (CercaStato(TM->A[s],TM->A,s-1) > 0) { printf("Lo stato %s compare piu' volte!\n",TM->A[s]); exit(EXIT_WRONGINPUTFORMAT); } } if (fscanf(fTuringFile,"%*s %d",&TM->CardAlfabetoIngresso) != 1) { printf("Manca il numero dei simboli dell'alfabeto d'ingresso!\n"); exit(EXIT_WRONGINPUTFORMAT); } TM->AlfabetoIngresso = (Alfabeto) calloc(TM->CardAlfabetoIngresso+1,sizeof(Simbolo)); if (TM->A == NULL) { printf("Memoria insufficiente per allocare l'alfabeto d'ingresso!\n"); exit(EXIT_MEMORY); } for (s = 1; s <= TM->CardAlfabetoIngresso; s++) { if (fscanf(fTuringFile,"%s",TM->AlfabetoIngresso[s]) != 1) { printf("Manca il simbolo %d dell'alfabeto d'ingresso!\n",s); exit(EXIT_WRONGINPUTFORMAT); } // Verifica che non ci siano doppioni if (CercaSimbolo(TM->AlfabetoIngresso[s],TM->AlfabetoIngresso,s-1) > 0) { printf("Lo stato %s compare piu' volte!\n",TM->AlfabetoIngresso[s]); exit(EXIT_WRONGINPUTFORMAT); } } if (fscanf(fTuringFile,"%*s %s",TM->Blank) != 1) { printf("Manca il simbolo blank!\n"); exit(EXIT_WRONGINPUTFORMAT); } // Verifica che il blank non faccia parte dell'alfabeto d'ingresso if (CercaSimbolo(TM->Blank,TM->AlfabetoIngresso,TM->CardAlfabetoIngresso) > 0) { printf("Il simbolo blank %s compare nell'alfabeto d'ingresso!\n",TM->Blank); exit(EXIT_WRONGINPUTFORMAT); } if (fscanf(fTuringFile,"%*s %d",&TM->CardAlfabetoLavoro) != 1) { printf("Manca il numero dei simboli dell'alfabeto di lavoro!\n"); exit(EXIT_WRONGINPUTFORMAT); } TM->AlfabetoLavoro = (Alfabeto) calloc(TM->CardAlfabetoLavoro+1,sizeof(Simbolo)); if (TM->A == NULL) { printf("Memoria insufficiente per allocare l'alfabeto di lavoro!\n"); exit(EXIT_MEMORY); } for (s = 1; s <= TM->CardAlfabetoLavoro; s++) { if (fscanf(fTuringFile,"%s",TM->AlfabetoLavoro[s]) != 1) { printf("Manca il simbolo %d dell'alfabeto di lavoro!\n",s); exit(EXIT_WRONGINPUTFORMAT); } // Verifica che non ci siano doppioni if (CercaSimbolo(TM->AlfabetoLavoro[s],TM->AlfabetoLavoro,s-1) > 0) { printf("Lo stato %s compare piu' volte!\n",TM->AlfabetoLavoro[s]); exit(EXIT_WRONGINPUTFORMAT); } } // Verifica che il blank faccia parte dell'alfabeto di lavoro if (CercaSimbolo(TM->Blank,TM->AlfabetoLavoro,TM->CardAlfabetoLavoro) == 0) { printf("Il simbolo blank %s non compare nell'alfabeto di lavoro!\n",TM->Blank); exit(EXIT_WRONGINPUTFORMAT); } // Verifica che ogni simbolo dell'alfabeto d'ingresso faccia parte dell'alfabeto di lavoro for (s = 1; s <= TM->CardAlfabetoIngresso; s++) if (CercaSimbolo(TM->AlfabetoIngresso[s],TM->AlfabetoLavoro,TM->CardAlfabetoLavoro) == 0) { printf("Il simbolo di ingresso %s non compare nell'alfabeto di lavoro!\n",TM->AlfabetoIngresso[s]); exit(EXIT_WRONGINPUTFORMAT); } if (fscanf(fTuringFile,"%*s %d\n",&TM->NumTransizioni) != 1) { printf("Manca il numero di transizioni!\n"); exit(EXIT_WRONGINPUTFORMAT); } TM->Delta = (FunzioneTransizione) calloc(TM->NumTransizioni+1,sizeof(Transizione)); if (TM->Delta == NULL) { printf("Memoria insufficiente per allocare la funzione di transizione!\n"); exit(EXIT_MEMORY); } for (t = 1; t <= TM->NumTransizioni; t++) { if (fscanf(fTuringFile,"%s %s %s %s %s\n",TM->Delta[t].StatoIn,TM->Delta[t].Input, TM->Delta[t].StatoFin,TM->Delta[t].Output,sp) != 5) { printf("Manca qualche dato per la transizione %d!\n",t); exit(EXIT_WRONGINPUTFORMAT); } TM->Delta[t].Spostamento = sp[0]; if (CercaStato(TM->Delta[t].StatoIn,TM->Q,TM->NumStati) == 0) { printf("Lo stato iniziale %s della transizione %d non compare nell'alfabeto di lavoro!\n",TM->Delta[t].StatoIn,t); exit(EXIT_WRONGINPUTFORMAT); } if (CercaSimbolo(TM->Delta[t].Input,TM->AlfabetoLavoro,TM->CardAlfabetoLavoro) == 0) { printf("Il simbolo d'ingresso %s della transizione %d non compare nell'alfabeto di lavoro!\n",TM->Delta[t].Input,t); exit(EXIT_WRONGINPUTFORMAT); } if (CercaStato(TM->Delta[t].StatoFin,TM->Q,TM->NumStati) == 0) { printf("Lo stato finale %s della transizione %d non compare nell'alfabeto di lavoro!\n",TM->Delta[t].StatoFin,t); exit(EXIT_WRONGINPUTFORMAT); } if (CercaSimbolo(TM->Delta[t].Output,TM->AlfabetoLavoro,TM->CardAlfabetoLavoro) == 0) { printf("Il simbolo d'uscita %s della transizione %d non compare nell'alfabeto di lavoro!\n",TM->Delta[t].Output,t); exit(EXIT_WRONGINPUTFORMAT); } if ( (TM->Delta[t].Spostamento != Sinistra) && (TM->Delta[t].Spostamento != Destra) ) { printf("Lo spostamento della transizione %d non e' valido!\n",t); exit(EXIT_WRONGINPUTFORMAT); } } TM->DimNastro = DIM_NASTRO; TM->Nastro = (VettoreSimboli) calloc(2*TM->DimNastro+1,sizeof(Simbolo)); if (TM->Nastro == NULL) { printf("Memoria insufficiente per allocare il nastro!\n"); exit(EXIT_MEMORY); } TM->Nastro += TM->DimNastro; fclose(fTuringFile); } void CaricaIstanza (char *InstanceFile, TuringMachine *TM) { } void SimulaTuringMachine (TuringMachine *TM) { } int CercaStato (Stato S, InsiemeStato I, int CardI) { int s; for (s = CardI; s > 0; s--) if (strcmp(I[s],S) == 0) break; return s; } int CercaSimbolo (Simbolo S, Alfabeto A, int CardA) { int s; for (s = CardA; s > 0; s--) if (strcmp(A[s],S) == 0) break; return s; } int CercaTransizione (Stato StatoIn, Simbolo Input, FunzioneTransizione Delta, int NumTransizioni) { return 0; } void EsegueTransizione (int t, TuringMachine *TM) { } void StampaRisultati (TuringMachine *TM) { } void DistruggeMacchina (TuringMachine *TM) { TM->NumStati = 0; free(TM->Q); TM->NumStatiAccettanti = 0; free(TM->A); TM->CardAlfabetoIngresso = 0; free(TM->AlfabetoIngresso); strcpy(TM->Blank,""); TM->CardAlfabetoLavoro = 0; free(TM->AlfabetoLavoro); TM->NumTransizioni = 0; free(TM->Delta); TM->Nastro -= TM->DimNastro; TM->DimNastro = 0; free(TM->Nastro); strcpy(TM->StatoCorrente,""); TM->Pos = 0; TM->NumPassi = 0; }