turingsim
This commit is contained in:
parent
6b31568e50
commit
339e12eea0
|
@ -8,12 +8,23 @@ writing code closer to the machine(s)
|
|||
|
||||
# software
|
||||
|
||||
=> ./forth.gmi {forth}
|
||||
## in C
|
||||
|
||||
=> ./turingsim.gmi {turingsim}
|
||||
|
||||
## uxn
|
||||
=> ./uxnería.gmi {uxnería}
|
||||
=> ./nibble_dice_tracker.gmi {nibble dice tracker}
|
||||
=> ./darena.gmi {darena}
|
||||
|
||||
## other assembly languages
|
||||
|
||||
=> ./avr-asm.gmi {avr-asm}
|
||||
|
||||
## forth
|
||||
|
||||
=> ./forth.gmi {forth}
|
||||
|
||||
# command-line interface notes
|
||||
|
||||
=> ./apuntes.gmi {apuntes}
|
||||
|
|
|
@ -168,6 +168,30 @@ dado un símbolo encontrado en la cinta, y un estado actual: ¿por cuál símbol
|
|||
|
||||
=> ./img/dibujo_tabla_d-turing_parentesis.png dibujo que representa la tabla de arriba, pero con símbolos estilizados
|
||||
|
||||
## archivo para turingsim
|
||||
|
||||
el siguiente archivo se puede usar con {turingsim} para ver los pasos de la máquina. nota la correspondencia entre la tabla y la lista de reglas.
|
||||
|
||||
```
|
||||
a
|
||||
A((()())())A
|
||||
1
|
||||
11
|
||||
a)bX1
|
||||
a(a(0
|
||||
aAcA1
|
||||
aXaX0
|
||||
b)b)1
|
||||
b(aX0
|
||||
bAH00
|
||||
bXbX1
|
||||
c(H00
|
||||
cAH10
|
||||
cXcX1
|
||||
80
|
||||
|
||||
```
|
||||
|
||||
# contador
|
||||
|
||||
esta máquina escribe "1"s en la cinta en una dirección, hasta encontrar un "1" en la cinta (o por siempre, si no es así)
|
||||
|
|
|
@ -0,0 +1,292 @@
|
|||
# turingsim
|
||||
|
||||
a quick and dirty turing machine simulator, written in C89.
|
||||
|
||||
# the code
|
||||
|
||||
```
|
||||
#include <stdio.h>
|
||||
|
||||
#define TAPE_SIZE 80
|
||||
#define RULES_SIZE 256
|
||||
|
||||
typedef struct {
|
||||
char state; /* current state */
|
||||
char symbol; /* current symbol */
|
||||
int head; /* index of head */
|
||||
char tape[TAPE_SIZE]; /* tape of characters */
|
||||
int nrules; /* number of rules */
|
||||
/* state, symbol, new state, new symbol, direction (even right, odd left ) */
|
||||
char rules[RULES_SIZE][5];
|
||||
} Machine;
|
||||
|
||||
Machine m;
|
||||
int nsteps;
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
int i,n=0;
|
||||
FILE *f;
|
||||
|
||||
if(!(f = fopen(argv[1], "r"))){
|
||||
fprintf(stderr, "failed to load file\n");
|
||||
return 1;
|
||||
}
|
||||
printf("%s\n\n", argv[1]);
|
||||
|
||||
/* read machine description */
|
||||
printf("initial state: ");
|
||||
fscanf(f,"%c",&m.state);
|
||||
printf("%c\n",m.state);
|
||||
|
||||
printf("initial tape: ");
|
||||
fscanf(f,"%s",m.tape);
|
||||
printf("%s\n",m.tape);
|
||||
|
||||
printf("initial position of head: ");
|
||||
fscanf(f,"%d",&m.head);
|
||||
m.head = (m.head+TAPE_SIZE)%TAPE_SIZE;
|
||||
printf("%d\n",m.head);
|
||||
|
||||
printf("number of rules: ");
|
||||
fscanf(f,"%d",&m.nrules);
|
||||
printf("%d\n",m.nrules);
|
||||
|
||||
for(i=0; i<m.nrules; i++){
|
||||
printf("rule number %d: ",i);
|
||||
fscanf(f,"%s",m.rules[i]);
|
||||
printf("%s\n",m.rules[i]);
|
||||
|
||||
}
|
||||
printf("max number of simulation steps: ");
|
||||
fscanf(f,"%d",&nsteps);
|
||||
printf("%d\n\n",nsteps);
|
||||
|
||||
/* simulate */
|
||||
int irules; /* rules index */
|
||||
do{
|
||||
printf("step %d\n",n);
|
||||
/* print head and state */
|
||||
for(i=0; i<m.head; i++)
|
||||
printf(" ");
|
||||
printf("%c\n",m.state);
|
||||
/* print tape: */
|
||||
printf("%s\n",m.tape);
|
||||
|
||||
/* get symbol at head position */
|
||||
m.symbol = m.tape[ m.head ];
|
||||
|
||||
/* search for corresponding rule */
|
||||
irules = -1;
|
||||
for(i=0; i<m.nrules && irules<0; i++)
|
||||
if(m.rules[i][0] == m.state && m.rules[i][1] == m.symbol)
|
||||
irules = i;
|
||||
|
||||
if( irules == -1) /* halt if not found */
|
||||
printf("halted\n");
|
||||
else{ /* update machine otherwise */
|
||||
m.state = m.rules[irules][2]; /* new state */
|
||||
m.tape[ m.head ] = m.rules[irules][3]; /* new symbol */
|
||||
/* move head */
|
||||
if( m.rules[irules][4]%2 ) /* if odd, move to left */
|
||||
m.head = (m.head-1+TAPE_SIZE)%TAPE_SIZE;
|
||||
else /* if even, move to right */
|
||||
m.head = (m.head+1)%TAPE_SIZE;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}while( ++n<nsteps && irules != -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
# build and run
|
||||
|
||||
to build:
|
||||
|
||||
```
|
||||
cc -std=c89 -Wall turingsim.c -o turingsim
|
||||
```
|
||||
|
||||
to run with an input file:
|
||||
|
||||
```
|
||||
./turingsim parentesis.txt | less
|
||||
```
|
||||
|
||||
# input file fields
|
||||
|
||||
the line-based fields are:
|
||||
|
||||
* initial state
|
||||
* inital tape
|
||||
* initial position of head on tape (starting at 0)
|
||||
* number of rules
|
||||
* list of rules, in the form: state, symbol, new state, new symbol, direction (even is right, odd is left)
|
||||
* maximum number of simulation steps
|
||||
|
||||
# example input file
|
||||
|
||||
this input file corresponds to the "comprobador de paréntesis" machine described in {máquinas de turing}
|
||||
|
||||
```
|
||||
a
|
||||
A(()())A
|
||||
1
|
||||
11
|
||||
a)bX1
|
||||
a(a(0
|
||||
aAcA1
|
||||
aXaX0
|
||||
b)b)1
|
||||
b(aX0
|
||||
bAH00
|
||||
bXbX1
|
||||
c(H00
|
||||
cAH10
|
||||
cXcX1
|
||||
80
|
||||
```
|
||||
|
||||
## example output
|
||||
|
||||
the output for this example file looks as follows:
|
||||
|
||||
```
|
||||
parentesis.txt
|
||||
initial state: a
|
||||
initial tape: A(()())A
|
||||
initial position of head: 1
|
||||
number of rules: 11
|
||||
rule number 0: a)bX1
|
||||
rule number 1: a(a(0
|
||||
rule number 2: aAcA1
|
||||
rule number 3: aXaX0
|
||||
rule number 4: b)b)1
|
||||
rule number 5: b(aX0
|
||||
rule number 6: bAH00
|
||||
rule number 7: bXbX1
|
||||
rule number 8: c(H00
|
||||
rule number 9: cAH10
|
||||
rule number 10: cXcX1
|
||||
max number of simulation steps: 80
|
||||
|
||||
step 0
|
||||
a
|
||||
A(()())A
|
||||
|
||||
step 1
|
||||
a
|
||||
A(()())A
|
||||
|
||||
step 2
|
||||
a
|
||||
A(()())A
|
||||
|
||||
step 3
|
||||
b
|
||||
A((X())A
|
||||
|
||||
step 4
|
||||
a
|
||||
A(XX())A
|
||||
|
||||
step 5
|
||||
a
|
||||
A(XX())A
|
||||
|
||||
step 6
|
||||
a
|
||||
A(XX())A
|
||||
|
||||
step 7
|
||||
b
|
||||
A(XX(X)A
|
||||
|
||||
step 8
|
||||
a
|
||||
A(XXXX)A
|
||||
|
||||
step 9
|
||||
a
|
||||
A(XXXX)A
|
||||
|
||||
step 10
|
||||
b
|
||||
A(XXXXXA
|
||||
|
||||
step 11
|
||||
b
|
||||
A(XXXXXA
|
||||
|
||||
step 12
|
||||
b
|
||||
A(XXXXXA
|
||||
|
||||
step 13
|
||||
b
|
||||
A(XXXXXA
|
||||
|
||||
step 14
|
||||
b
|
||||
A(XXXXXA
|
||||
|
||||
step 15
|
||||
a
|
||||
AXXXXXXA
|
||||
|
||||
step 16
|
||||
a
|
||||
AXXXXXXA
|
||||
|
||||
step 17
|
||||
a
|
||||
AXXXXXXA
|
||||
|
||||
step 18
|
||||
a
|
||||
AXXXXXXA
|
||||
|
||||
step 19
|
||||
a
|
||||
AXXXXXXA
|
||||
|
||||
step 20
|
||||
a
|
||||
AXXXXXXA
|
||||
|
||||
step 21
|
||||
c
|
||||
AXXXXXXA
|
||||
|
||||
step 22
|
||||
c
|
||||
AXXXXXXA
|
||||
|
||||
step 23
|
||||
c
|
||||
AXXXXXXA
|
||||
|
||||
step 24
|
||||
c
|
||||
AXXXXXXA
|
||||
|
||||
step 25
|
||||
c
|
||||
AXXXXXXA
|
||||
|
||||
step 26
|
||||
c
|
||||
AXXXXXXA
|
||||
|
||||
step 27
|
||||
c
|
||||
AXXXXXXA
|
||||
|
||||
step 28
|
||||
H
|
||||
1XXXXXXA
|
||||
halted
|
||||
```
|
||||
|
||||
the 1 written at the end indicates that the parenthesis sequence was well-formed. if there was a parenthesis without its pair, the machine would have written 0 instead.
|
Loading…
Reference in New Issue