Skip to content

Instantly share code, notes, and snippets.

@Mr-Slippery
Created February 11, 2021 23:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Mr-Slippery/81705ec02204831998c24d1e26b4dc17 to your computer and use it in GitHub Desktop.
Save Mr-Slippery/81705ec02204831998c24d1e26b4dc17 to your computer and use it in GitHub Desktop.
Find the Turing machine that will produce a desired string.
#ifdef KLEE
#include <klee/klee.h>
#include <assert.h>
#endif
#ifndef KLEE
#include <string.h>
#include <stdio.h>
#endif
#include <stdint.h>
#include <stdbool.h>
#define TRANS_SIZE ((uint8_t)5u)
#define MACHINE_MAX_TRANS ((uint32_t)6u)
#define MACHINE_MAX_DESC ((uint32_t)(MACHINE_MAX_TRANS * TRANS_SIZE))
char machine[MACHINE_MAX_DESC] =
#ifdef KLEE
{0}
#else
{
1, 0, 'H', 'R', 2,
6, 0, '.', 'R', 0,
5, 0, 'o', 'R', 6,
3, 0, 'l', 'R', 4,
4, 0, 'l', 'R', 5,
2, 0, 'e', 'R', 3,
}
#endif
;
#define TAPE_MAX ((uint32_t)32)
char tape[TAPE_MAX] = {0};
bool same(const char * a, const char * b, uint32_t size)
{
uint32_t i;
for (i = 0u; i < size; ++i) {
if (a[i] != b[i]) {
return false;
}
}
return true;
}
int main(int argc, char *argv[])
{
uint32_t i, j;
uint8_t state;
int32_t head = 0;
#ifdef KLEE
klee_make_symbolic(machine, MACHINE_MAX_DESC, "machine");
#endif
state = machine[0];
while (true) {
#ifndef KLEE
printf("State: %2x Head: %u Symbol: %2x Tape: %s\n", state, head, tape[head], tape);
#endif
if (head < 0 || head >= TAPE_MAX ) {
#ifndef KLEE
printf("Exit: head %d out of bounds.\n", head);
#endif
break;
}
for(i = 0u; i <= MACHINE_MAX_DESC - 5 && machine[i]; i += TRANS_SIZE) {
if (state == machine[i]
&& tape[head] == machine[i + 1u])
{
break;
}
}
if (i > MACHINE_MAX_DESC - 5 || !machine[i]) {
#ifndef KLEE
printf("Exit: no applicable transitions.\n");
#endif
break;
}
tape[head] =
machine[i + 2u];
if ('L' == machine[i + 3u]) {
--head;
} else if ('R' == machine[i + 3u]) {
++head;
} else {
#ifndef KLEE
printf("Exit: no applicable transitions.\n");
#endif
return 1;
}
state = machine[i + 4u];
if (!state) {
#ifndef KLEE
printf("Exit: final state.\n");
#endif
break;
}
}
#ifndef KLEE
printf("Tape: %s\n", tape);
#endif
#ifdef KLEE
klee_assert(!same(tape, "Forty-two", 10));
#endif
return 0;
}
@PeterHahlweg
Copy link

Hi, I have done some changes to improve the performance on a KLEE run.
You will find it on my fork https://gist.github.com/PeterHahlweg/d2009f1c48f90dc037614772b09916e7
Let me know what you think about it. 🙂

@Mr-Slippery
Copy link
Author

Mr-Slippery commented Feb 15, 2021

Hey @PeterHahlweg, will check it ASAP, thanks a lot! 👍

@Mr-Slippery
Copy link
Author

Thanks @PeterHahlweg, looks very good, I would create a repo as discussed and then maybe you can make a PR to it when you have time? I'll put in the code as I have it... which is already a bit improved by having seen your code, but I don't have everything in. Cheers again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment