튜링 완성을 위해 do-while 루프가 충분합니까?


22

필자는 명령형 프로그래밍 언어에서 언어 튜링을 완벽하게하기위한 제어 흐름 구조로 while-do 루프가 충분하다는 것을 알고 있습니다 (제어 흐름이 진행되는 한-물론 우리는 무제한 메모리와 특정 연산자가 필요합니다 ...) . 내 질문의 요지는 : do-while 루프가 while-do 루프와 동일한 계산 능력을 가지고 있습니까? 다시 말해, 명령어를 완전히 건너 뛸 수없는 경우 언어가 튜링 완료 상태가 될 수 있습니다.

여기서 의미의 일부가 모호 할 수 있다는 것을 알고 있으므로 실제 질문을 구체적인 예를 들어 설명하겠습니다.

Brainfuck (BF)은 유일한 제어 흐름이 while-do 루프 인 Turing tarpit [...]입니다 (Brainfuck에 익숙하지 않은 경우 질문 하단에 완전한 언어 사양이 있음). 하자의 새로운 언어 BF의 * 정의 ,.+-<>BF의 경우와 동일한 의미를 갖는다를하지만, 대신에 []우리가 {}할 - while 루프를 의미한다. 즉, BF와의 유일한 차이점은 추가 반복을 건너 뛸 수 있기 전에 모든 루프가 적어도 한 번 실행된다는 것입니다.

BF * 튜링이 완료 되었습니까? 그렇다면 BF를 BF *로 변환하는 방법에 관심이 있습니다. 그렇지 않은 경우 어떻게 증명합니까?

내 자신의 일부 관찰 :

  • 모든 BF 프로그램을 BF *로 번역 할 수있는 것은 아닙니다. 예를 들어, 값을 읽거나 인쇄하지 않을 수있는 BF *로 프로그램을 작성하는 것은 불가능합니다. 프로그램이 하나 이상의 값을 인쇄 할 수있는 경우 항상 하나 이상의 값을 인쇄합니다. 그러나 BF *로 변환 될 수있는 BF의 Turing-complete 하위 집합이있을 수 있습니다.
  • 우리는 간단하게 변환 할 수 없습니다 [f](여기서 f몇 가지 임의 만 구성된 브레인 퍽 프로그램 +-[]<>)에 A) 때문에, (첫 번째 반복의 효과를 취소하기위한 시도) 하지 모든 계산 가능한 함수는 계산 가능한 역이 그것을 한 경우에도와 B), 이 단계를 재귀 적으로 적용한다고해서 반드시 루프 수가 적을 필요 는 없습니다.f-1{f}f-1f

다음은 Brainfuck 언어에 대한 간략한 개요입니다. Brainfuck은 각 셀에 바이트 값이 포함 된 무한 테이프에서 작동하며 처음에는 0입니다. 오버플로가 줄 바꿈되므로 255를 증가 시키면 0이되고 그 반대도 마찬가지입니다. 이 언어는 8 가지 명령으로 구성됩니다.

+   Increment the current cell.
-   Decrement the current cell.
>   Move tape head to the right.
<   Move tape head to the left.
,   Input a character from STDIN into the current cell.
.   Output the current cell as a character to STDOUT.
[   If the current cell is zero, jump past the matching ].
]   If the current cell is non-zero, jump back to just behind the matching [.


흥미롭지 만 완전히 신중하게 구성되지 않았다고 생각하십시오. []BF에서 "while"루프를 정확하게 정의하지는 않습니다. 표에서와 같이 왼쪽 및 오른쪽 대괄호는 현재 셀 0/0이 아닌 값을 평가합니다. 그렇다면 해당 {}중괄호 평가 논리에 대한 정확한 설명은 무엇 입니까? Computer Science Chat 에서 추가 대화 / 토론을 제안하십시오 . 또한 귀하의 "관측"은 증거가없는 "가정"또는 "제안"과 유사합니다.
vzn

@vzn 좋은 지적입니다. 나는 명백한 정의가 와 같은 것을 전혀하지 않는 {}것이라고 생각했다 . 다음 며칠 동안 시간이 많지 않지만 시간이 있으면 채팅에 참여할 것입니다. {}]
Martin Ender

슬프게도 이것은 다소 미묘한 질문이며 여기에는 완전히 다른 두 가지 질문이있는 것 같습니다. (1) while-do 루프 (및 "기타 항목")가있는 Turing 완성 언어를 사용하면 do-while 루프만으로 Turing 완성 언어로 변환 할 수 있습니다. 그러나 "다른 것들"에 대해 더 자세히 알고 대답해야합니다. (2) 주어진 BF와 소정의 정의에 새로운 BF의 * {}및 데려가는 [], BF * 튜링 완료된다. BF []는 Turing 완전한 언어에서 while-do 루프와 유사하거나 유사한 구조 라는 것을 이해합니다 .
vzn

1
@vzn 부분 (1)은 내 질문의 TL; DR 부분이었습니다. 나는 이것이 "일부 언어"에 대해 대답하는 것이 불가능하다는 것을 완전히 알고 있습니다. 정말 아주 간단한 장난감 언어 (BF)의 측면에서 실제 질문을 표현한 내가 생각하기 때문에 (루프의 행동 범위를 좁힐 한 이유입니다 경우 BF *이 그것을 간단하게 것이라고 TC를로 표시 할 수 있습니다 반복되는 루프 만있는 다른 언어에 대해서는 표시하십시오. BF 루프가 다른 언어의 while-do 루프와 어떻게 다른지 잘 모르겠습니다.
Martin Ender

답변:


10

나는 Brainfuck을 모른다. 그래서 당신은 내 의사 코드로부터 약간의 번역을해야 할 것이다. 그러나 Brainfuck이 현명하게 작동한다고 가정하면 (아래!) 모든 것이 적용되어야합니다.

do-while은 while-do와 같습니다. do X while Y에 해당 X; while Y do X당신이 조건문을 가정하고, while Y do X동일합니다 if Y then (do X while Y).

조건이 없으면 인생이 좀 더 어려워집니다. 수행하는 동안 if Y then X다음과 같은 것을 사용하여 시뮬레이션 할 수 있습니다 .

B := true
while (Y and B) do
    X
    B := false
endwhile

그러나 당신이 할 일이 없다면 어떨까요? 변수의 현재 값이 주어지면 종료 if Y then X한다고 가정하면 다음과 같이 시뮬레이트 한다고 주장 X합니다. (이것은 보장되지 않습니다 : 변수 값을 루프 하더라도 프로그램 if y=0 then loopforever은 if를 종료 합니다). 하자 , ..., 에 의해 수정 변수 수 와 할 수 가 사용하도록 수정 하는 대신 해당 변수 각각에 대해. 변수 스왑 명백한 나타낸다 코드 와 .y != 0XV1VnXX'XVi'Viswap(A,B)AB

V1' := V1; ...; Vn' := Vn
V1'' := V1; ...; Vn'' := Vn
C := 0
do
    X'
    swap (V1',V1''); ...; swap (Vn',Vn'')
    C := C+1
while Y and C<2
V1 := V1'; ...; Vn := Vn'

아이디어는 다음과 같습니다. 먼저, 그것이 틀렸다고 가정하십시오 Y. X한 번 수행하는 것을 시뮬레이션하고 결과를 V1'', ..., Vn''; V1', ..., Vn'의 원래 값을 유지 V1, ..., Vn. 그런 다음 V1 := V1'; ...; Vn := Vn'아무것도 할당 하지 않습니다. 따라서 Y거짓 인 경우 , 우리는 아무것도하지 않았습니다. 자, 그것이 Y사실 이라고 가정하십시오 . 이제 "primed"및 "double-primed"변수에 결과를 저장하여 X 두 번 시뮬레이션 합니다. 이제 루프 끝의 할당은 X한 번 계산 된 효과를 갖습니다 . 참고 Y값이 반복 루프를 실행하여 영향을받지 않도록에만 "초회"변수에 따라 달라집니다.

그렇다면 X변수의 현재 값으로 종료되지 않으면 어떻게 될까요? (이 가능성을 지적 해준 Martin Ender에게 감사합니다.)이 경우 X위와 유사한 아이디어를 사용하여 명령 별 명령 을 시뮬레이션해야합니다 . 각 명령은 확실히 종료되므로 if"opcode가 foo 인 경우이 작업을 수행하십시오. 실행중인 경우에는 수행하십시오. ..."의 행을 따라 명령 시뮬레이션을 수행 할 수 있습니다 . 이제 루프를 X사용하여 명령어 포인터 등을 사용하여의 명령어 를 반복 하여 다음에 실행할 명령어를 알 수 있습니다. 루프가 반복 될 때마다 정지 Y했는지 확인하십시오 X. 경우 Y거짓, 스와핑 기술의 효과를 취소 할 수있게 해준다X의 첫 번째 교육.


1
이것은 깔끔한 아이디어이지만 여기에 한 가지 문제가 있다고 생각합니다. Y거짓이지만 X현재 변수 값 집합에서 끝나지 않는 경우를 고려하십시오 . if Y then X종료하지만 번역은 항상 X'한 번 이상 실행해야하므로 번역이 종료되지 않습니다 .
Martin Ender

1
@ MartinBüttner Urgh. 네가 옳아. 따라서 X명령별로 명령 을 시뮬레이션 하고 Y각 명령을 확인 하려면 루프를 사용해야합니다 . 각 명령은 모든 것이 작동하도록 종료되도록 보장됩니다. 그러나 적어 두는 것은 고통입니다.
David Richerby

1
Xwhile 루프 / 조건 자체로 시작하면 그렇게 해체 할 수 있는지 확실하지 않습니다 . 나는 이것에 대해 좀 더 생각해야 할 것이다.
Martin Ender

또한 "이제 루프를 사용하여 X 명령을 반복하고 명령 포인터 등을 사용하여 다음에 실행할 명령을 알 수 있습니다." 나는 이것 자체가 어떤 종류의 조건을 요구할 수 있다고 생각합니다.
Martin Ender

1
X'비선형 인 경우 "각 명령"을 어떻게 정의하는지 여전히 확실하지 않습니다 . 간단하지만 사소한 장난감에 대한 자세한 내용을 포함시켜 주시겠습니까 X? 예를 들어 do (while A do B) while C? (외부는 do while외부에서 오는 while do우리가 현재 번역하고 있음)
마틴 청산
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.