How to resolve the algorithm Universal Turing machine step by step in the UNIX Shell programming language
How to resolve the algorithm Universal Turing machine step by step in the UNIX Shell programming language
Table of Contents
Problem Statement
One of the foundational mathematical constructs behind computer science is the universal Turing Machine.
(Alan Turing introduced the idea of such a machine in 1936–1937.) Indeed one way to definitively prove that a language is turing-complete is to implement a universal Turing machine in it.
Simulate such a machine capable
of taking the definition of any other Turing machine and executing it.
Of course, you will not have an infinite tape,
but you should emulate this as much as is possible.
The three permissible actions on the tape are "left", "right" and "stay".
To test your universal Turing machine (and prove your programming language
is Turing complete!), you should execute the following two Turing machines
based on the following definitions.
Simple incrementer
The input for this machine should be a tape of 1 1 1
Three-state busy beaver
The input for this machine should be an empty tape.
Bonus: 5-state, 2-symbol probable Busy Beaver machine from Wikipedia
The input for this machine should be an empty tape. This machine runs for more than 47 millions steps.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Universal Turing machine step by step in the UNIX Shell programming language
Source code in the unix programming language
#!/usr/bin/env bash
main() {
printf 'Simple Incrementer\n'
printf '1 1 1' | run_utm q0 qf B q0,1,1,R,q0 q0,B,1,S,qf
printf '\nThree-state busy beaver\n'
run_utm a halt 0 \
a,0,1,R,b a,1,1,L,c b,0,1,L,a b,1,1,R,b c,0,1,L,b c,1,1,S,halt \
}
run_utm() {
local initial=$1 final=$2 blank=$3
shift 3
local rules=("$@") tape
mapfile -t -d' ' tape
if (( ! ${#tape[@]} )); then
tape=( "$blank" )
fi
local state=$initial
local head=0
while [[ $state != $final ]]; do
print_state "$state" "$head" "${tape[@]}"
local symbol=${tape[head]}
local found=0 rule from input output move to
for rule in "${rules[@]}"; do
IFS=, read from input output move to <<<"$rule"
if [[ $state == $from && $symbol == $input ]]; then
found=1
break
fi
done
if (( ! found )); then
printf >&2 "Configuration error: no match for state=$state input=$sym\n"
return 1
fi
tape[head]=$output
state=$to
case "$move" in
L) if (( ! head-- )); then
head=0
tape=("$blank" "${tape[@]}")
fi
;;
R) if (( ++head >= ${#tape[@]} )); then
tape+=("$blank")
fi
;;
esac
done
print_state "$state" "$head" "${tape[@]}"
}
print_state() {
local state=$1 head=$2
shift 2
local tape=("$@")
printf '%s' "$state"
printf ' %s' "${tape[@]}"
printf '\r'
(( t = ${#state} + 1 + 3 * head ))
printf '\e['"$t"'C<\e[C>\n'
}
main "$@"
You may also check:How to resolve the algorithm Fraction reduction step by step in the Julia programming language
You may also check:How to resolve the algorithm Arithmetic/Integer step by step in the HicEst programming language
You may also check:How to resolve the algorithm Jewels and stones step by step in the Euphoria programming language
You may also check:How to resolve the algorithm Greatest common divisor step by step in the Rust programming language
You may also check:How to resolve the algorithm Averages/Mode step by step in the Factor programming language