Turing 머신이 일반적인 계산 모델이라는 것을 스스로 확신시키는 방법에 대해 지금 생각하고 있습니다. 나는 Sipser와 같은 일부 표준 교과서에서 Church-Turing 논문의 표준 처리가 완벽하지 않다는 것에 동의합니다. 다음은 Turing 머신에서 더 잘 알려진 프로그래밍 언어로 어떻게 전환 할 수 있는지에 대한 스케치입니다.
블록 구조의 프로그래밍과 언어 고려 if
와 while
함께 문 비 재귀 라는 정의 기능 및 서브 루틴 부울 확률 변수 일반적인 부울 표현을 단일 바운드 부울 배열 tape[n]
정수 배열 포인터를 n
증가 또는 감소 될 수 n++
또는 n--
. 포인터 n
는 처음에는 0이고 배열 tape
은 처음에는 모두 0입니다. 따라서이 컴퓨터 언어는 C와 비슷하거나 Python과 유사 할 수 있지만 데이터 형식에는 매우 제한적입니다. 사실, 그것들은 너무 제한되어 있으므로 n
부울 식에 포인터를 사용할 수있는 방법조차 없습니다 . 그것을 가정tape
오른쪽에만 무한대 n
입니다. 음수 이면 포인터 언더 플로 "시스템 오류"를 선언 할 수 있습니다 . 또한, 우리 언어에는 exit
부울 답변을 출력하기위한 하나의 인수가 있는 문장이 있습니다.
그런 다음 첫 번째 요점은이 프로그래밍 언어가 튜링 머신에 적합한 사양 언어라는 것입니다. 테이프 배열을 제외하고는 코드에 선언 된 모든 변수의 상태, 현재 실행 라인 및 서브 루틴 스택의 상태 만 한정되어 있음을 쉽게 알 수 있습니다. 후자는 재귀 함수가 허용되지 않기 때문에 유한 한 양의 상태 만 있습니다. 이 유형의 코드에서 "실제"튜링 머신을 생성하는 "컴파일러"를 상상할 수 있지만 그 세부 사항은 중요하지 않습니다. 요점은 우리는 꽤 좋은 구문을 가지고 있지만 매우 원시적 인 데이터 유형을 가진 프로그래밍 언어를 가지고 있다는 것입니다.
구성의 나머지 부분은 유한 한 라이브러리 함수 목록과 사전 컴파일 단계를 사용하여이를보다 실용적인 프로그래밍 언어로 변환하는 것입니다. 다음과 같이 진행할 수 있습니다.
프리 컴파일러를 사용하면 부울 데이터 유형을 ASCII와 같이 더 크지 만 유한 한 기호 알파벳으로 확장 할 수 있습니다. 우리는 tape
이 더 큰 알파벳으로 값을받는 다고 가정 할 수 있습니다 . 포인터의 언더 플로를 방지하기 위해 테이프의 시작 부분에 마커를두고 테이프의 끝 부분에 움직일 수있는 마커를 두어 TM이 테이프에서 무한대로 스케이팅되는 것을 방지 할 수 있습니다. 심볼 사이의 임의의 이진 연산과 부울 for if
및 while
명령문으로의 변환을 구현할 수 있습니다 . (실제로 if
사용할 수 while
없는 경우에도 구현할 수 있습니다.)
kkiik
우리는 하나의 테이프를 기호 값 "메모리"로 지정하고 다른 테이프는 부호없는 정수 값 "레지스터"또는 "변수"로 지정합니다. 정수는 종료 표시와 함께 리틀 엔디안 바이너리에 저장합니다. 먼저 레지스터의 사본과 레지스터의 이진 감소를 구현합니다. 이를 메모리 포인터의 증가 및 감소와 결합하여 심볼 메모리의 랜덤 액세스 탐색을 구현할 수 있습니다. 정수의 이진 가산 및 곱셈을 계산하는 함수를 작성할 수도 있습니다. 비트 단위 연산으로 이진 덧셈 함수를 작성하는 것은 어렵지 않고 왼쪽 시프트로 2를 곱하는 함수입니다. (또는 리틀 엔디안이기 때문에 실제로 올바른 시프트입니다.) 이러한 프리미티브를 사용하면 긴 곱셈 알고리즘을 사용하여 두 개의 레지스터를 곱하는 함수를 작성할 수 있습니다.
공식을 사용하여 메모리 테이프를 1 차원 기호 배열 symbol[n]
에서 2 차원 기호 배열 로 재구성 할 수 있습니다 . 이제 메모리의 각 행을 사용하여 부호없는 정수를 종료 기호로 이진수로 표현하여 1 차원 랜덤 액세스 정수 값 메모리를 얻을 수 있습니다. 메모리에서 정수 레지스터로 읽고 레지스터에서 메모리로 쓰는 것을 구현할 수 있습니다. 부호있는 부동 소수점 산술, 기호 문자열 등의 기능을 사용하여 많은 기능을 구현할 수 있습니다.symbol[x,y]
n = (x+y)*(x+y) + y
memory[x]
하나의 기본 기능 만 사전 컴파일러, 즉 재귀 함수를 엄격하게 요구합니다. 이것은 해석 된 언어를 구현하는 데 널리 사용되는 기술로 수행 할 수 있습니다. 각각의 상위 수준의 재귀 함수에 이름 문자열을 할당하고 하위 수준 코드를 while
일반적인 매개 변수 (호출 지점, 호출 된 함수 및 인수 목록)를 사용하여 호출 스택을 유지하는 하나의 큰 루프 로 구성합니다 .
이 시점에서이 구성에는 고급 프로그래밍 언어의 기능이 충분하므로 CS 이론보다는 프로그래밍 언어 및 컴파일러의 주제보다 더 많은 기능이 추가됩니다. 이 개발 된 언어로 Turing-machine 시뮬레이터를 작성하는 것도 이미 쉽습니다. 언어에 대한 자체 컴파일러를 작성하는 것은 쉽지 않지만 확실하게 표준입니다. 물론이 C와 같은 언어 나 Python과 같은 언어로 된 코드에서 외부 TM을 만들려면 외부 컴파일러가 필요하지만 모든 컴퓨터 언어로 수행 할 수 있습니다.
이 스케치 된 구현은 재귀 함수 클래스에 대한 논리학 자의 Church-Turing 논문뿐만 아니라 결정 론적 계산에 적용되는 확장 된 (다항식) Church-Turing 논문을 지원합니다. 다시 말해, 다항식 오버 헤드가 있습니다. 실제로, 우리가 RAM 머신 또는 (나의 개인적으로 좋아하는) 트리 테이프 TM를 받았다면, 이것은 RAM 메모리를 사용한 직렬 계산을 위해 다항 오버 헤드로 줄일 수 있습니다.