Проектирование таблицы состояний машины Тьюринга - PullRequest
3 голосов
/ 20 января 2010

Являются ли они полезными руководящими принципами для описания того, что делает машина Тьюринга, если у вас уже есть псевдокод для алгоритма?

Я изучаю теорию сложности, и мне требуется некоторое время, чтобы описатьМашина Тьюринга, которая решает или принимает какой-то язык (состояния, переходы и т. Д.), Хотя я знаю, как я могу кодировать его в нечто вроде C или даже сборки.Думаю, мне просто не хватило практики с машинами Тьюринга (работаю над этим), но я ценю любые предложения.

edit

Я не хочусоздать симулятор машины Тьюринга, я хочу описать машину Тьюринга на бумаге (алфавит, состояния, переходы) для выбора языка.

Вот тривиальный пример того, что я имею в виду, скажем, мне нужно написать машину Тьюрингаон перебирает строку 0 и 1 и заменяет все 0 на 1.Например, если вы начинаете с 11010 на ленте (вход), он останавливается с 11111 на ленте (выход).Теперь на языке высокого уровня вы знаете, что это что-то вроде:

Go over every character on tape
    If character is 0 change it to 1

Неформально описание машины Тьюринга выглядит примерно так:

У вас есть два состояния, q и halt.Когда вы находитесь в состоянии q и видите 1, идите направо, не меняя его.Если вы видите 0, измените его на 1 и идите направо.Если вы видите пустой символ (конец ленты), то переходите в состояние остановки.

Формально у вас будет что-то вроде {q, halt} для состояний.{((q, 1) -> (q, 1, R)), ((q, 0) -> (q, 1, R)), ((q, #) -> (останов, 0, L))} для переходов.

Теперь эта проблема тривиальна, но есть и другие, которые более интересны (добавьте унарные числа или узнайте язык с равным числом a, b и c).Я мог бы легко написать для них псевдокод, но написание машины Тьюринга гораздо сложнее (у меня уходит много времени), и мне было интересно, есть ли какие-нибудь советы, ресурсы или рекомендации, которые помогут мне лучше справляться с такими проблемами.

Ответы [ 2 ]

10 голосов
/ 20 января 2010

Отказ от ответственности: Ваш вопрос очень общий, следовательно, и ответ такой. Обратите внимание, что я не эксперт по ТМ, а этот подход обычно не будет очень эффективным (я даже не могу обещать, что он всегда будет эффективным). Я просто записываю здесь некоторые мысли.

Я бы предложил попробовать такой подход: возьмите свой псевдокод и уменьшите его так, чтобы он состоит только из а) логических переменных и б) if -статементов. Например:

if THIS_LETTER_IS("A"):
    found_an_even_number_of_A = not found_an_even_number_of_A

if THIS_LETTER_IS("Q") and previous_letter_was_X and found_an_even_number_of_A
        and not checking_for_alternative_2:
    # can't be a word of alternative 1, so check for alternative 2
    going_back_to_start_to_check_for_alternative_2 = True

if going_back_to_start_to_check_for_alternative_2:
    MOVE_TO_PREVIOUS
else:
    MOVE_TO_NEXT

if going_back_to_start_to_check_for_alternative_2 and THIS_LETTER_IS(EMPTY):
    # reached the beginning, so let's check for alternative 2
    going_back_to_start_to_check_for_alternative_2 = False
    checking_for_alternative_2 = True

Если вы вложили if s, замените их на and s; удалить блоки else с помощью not:

if something:
    if something_else:
        do_a
    else:
        do_b

становится

if something and something_else:
    do_a

if something and not something_else:
    do_b

Каждый блок if должен содержать только одну MOVE_TO_PREVIOUS или MOVE_TO_NEXT, возможно, команду WRITE и любое число. переменных назначений.

Заполните все if предложения, чтобы каждый ваших логических значений И текущая буква всегда проверялись, дублируя блоки, где необходимо. Пример: * +1028 *

if something and something_else:
    do_a

становится

if THIS_LETTER_IS("A") and something and something_else and something_i_dont_care_about_here:
    do_a

if THIS_LETTER_IS("A") and something and something_else and not something_i_dont_care_about_here:
    do_a

if THIS_LETTER_IS("Q") and something and something_else and something_i_dont_care_about_here:
    do_a

if THIS_LETTER_IS("Q") and something and something_else and not something_i_dont_care_about_here:
    do_a

Теперь, если у вас есть n логических и m букв, у вас должно быть m * 2 n if с. Представьте, что вы сохранили логические значения в битовом поле, поэтому каждая возможная комбинация логических значений представляет собой целое число. Следовательно, вышесказанное становится

if THIS_LETTER_IS("A") and bitfield[0] and bitfield[1] and bitfield[2]:
    do_a

if THIS_LETTER_IS("A") and bitfield[0] and bitfield[1] and not bitfield[2]:
    do_a

# ...

, который затем становится

if THIS_LETTER_IS("A") and bitfield == 7:
    do_a

if THIS_LETTER_IS("A") and bitfield == 3:
    do_a

# ...

Это целочисленное значение для битового поля является состоянием машины Тьюринга. Часть do_a - это просто присвоение логическим значениям (т. Е. Битовое поле, так что это ваше новое состояние), команда записи (если ее нет, просто напишите письмо, которое уже было там) и команда перемещения, отсюда явный переход машины Тьюринга.

Надеюсь, все вышеперечисленное имеет смысл.

1 голос
/ 20 января 2010

Вам нужен готовый инструмент, симулятор Turing Machine? Есть довольно много доступных . Или на самом деле вы хотите сделать свой собственный? Кажется, это правильная реализация в JavaScript: http://klickfamily.com/david/school/cis119/TuringSim.html вы можете легко проанализировать код и перевести его на C или C ++.

...