This repository has been archived by the owner on Sep 30, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcore.c
73 lines (69 loc) · 2.08 KB
/
core.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*
* core.c: Turing machine core
*
* Author: Giorgio Pristia
*/
#include <stdlib.h>
#include "core.h"
int tm_run(struct tm *tm, struct tmconf *c){
rule_dest *d;
struct tmconf *c_;
int o = 0;
struct queue *q = new_queue();
if(!q){
delete_tmconf(c);
return -1;
}
enqueue(q, c);
/* Loop until reache accept state or queue is empty */
while(!(o & 1) && (c = dequeue(q))){
/* Outgoing transitions from the current configuration */
d = rule_dict_find(tm->rules, c->st, tape_read(c->t));
if(!d) /* No outgoing transitions: dead branch */
delete_tmconf(c);
else if(!c->ttl){ /* There are outgoing transitions but time */
delete_tmconf(c); /* to live is zero: non terminating branch */
o = 2;
}
else for(; d; d = d->next){
if(set_get(tm->accept, d->st)){
delete_tmconf(c); /* As soon as an accepting state is */
o = 1; /* reached, TM stops and returns 1 */
break;
}
if(d->next){
if(!(c_ = calloc(1, sizeof(*c_)))){
delete_tmconf(c);
o = -1;
break;
}
c_->t = tape_branch(c->t); /* Branch current configuration */
}
else /* Last transition is applied inplace without branching */
c_ = c;
/* Apply transition and enqueue the configuration reached */
c_->st = d->st;
c_->ttl = c->ttl - 1;
tape_write(c_->t, d->ch, d->mv);
enqueue(q, c_);
};
}
/* Clear all remaining enqueued configurations and return */
delete_queue(q);
return o;
}
int tm_init(struct tm *tm){
tm->rules = new_rule_dict();
if(!tm->rules)
return -1;
tm->accept = new_set();
if(!tm->accept){
free(tm->rules);
return -1;
}
return 0;
}
void tm_destroy(struct tm *tm){
delete_rule_dict(tm->rules);
delete_set(tm->accept);
}