하나의 명령 세트 컴퓨터를 설계하십시오!


31

주의 사항 : 흥미로운 답변에 대해 현상금을 기꺼이 제공합니다.

도전 과제는 Turing-complete one instruction set computer (OISC) 를 설계하는 것입니다 .

OISC는 하나의 명령 만 사용하는 추상 시스템으로 기계 언어 opcode가 필요하지 않습니다. 단일 명령과 무한한 리소스를 신중하게 선택하면 OISC는 여러 명령이있는 기존 컴퓨터와 동일한 방식으로 범용 컴퓨터가 될 수 있습니다.

Turing-complete OISC를 만드는 단일 명령의 예는 다음과 같습니다 .

규칙 :

해석 또는 증거를 제공해야합니다

귀하의 언어에 대한 통역사를 제공해야합니다. 이 인터프리터는 메모리 / 시간에 의해서만 제한되어야합니다 (예 : 사용자가 부과 한 제한이 없어야 함). 언어에 대한 통역사를 제공하지 않으면 (게으름 이외의 다른 이유로) 언어를 작성할 수 있음을 증명해야합니다. 통역 이 가능해야합니다 .

튜링 완성도를 증명해야합니다

귀하의 언어가 튜링 완료라는 공식적인 증거를 포함해야합니다. 이를 수행하는 간단한 방법은 다른 Turing-complete 언어와 동일한 동작을 해석하거나 해석 할 수 있음을 증명하는 것입니다. 해석하는 가장 기본적인 언어는 Brainf ** k 입니다.

예를 들어, Brainf ** k와 동일한 명령 (및 사용자가 부과 한 메모리 제한이 동일하지 않음)이 모두있는 일반 언어는 튜링 완료입니다. Brainf ** k에서 구현할 수있는 모든 언어로 구현할 수 있기 때문입니다 .

다음 은 구현이 매우 간단한 튜링 완료 언어 목록입니다.

추가 OISC 요구 사항

  • 이 OISC에는 명령이 하나만 있어야합니다. 명령 중 하나에 여러 명령이 있으면 Turing-complete로 만들 수 없습니다.

  • OISC는 원하는 구문을 사용할 수 있습니다. 당신은 답에서 지시가 무엇인지, 데이터가 무엇인지, 그리고 빈칸이없는 것이 무엇인지 정의해야합니다 (예 : 공백). 창의력을 발휘하십시오!

  • 인수는 정수일 필요는 없습니다. 예를 들어 /// 는 Turing-complete OISC의 아름다운 예입니다.

  • 입력과 출력이 어떻게 이루어지고 제공되는지는 당신에게 달려 있습니다. 대부분의 OISC는 특정 메모리 위치를 통해 I / O를 구현하지만 다른 방법이있을 수 있으므로 찾아야합니다.

  • 유효한 답변은 게시물에 포함 시키거나 언어로 해결 된 간단한 도전에 연결하여 OISC에 예제 코드를 제공해야합니다.

투표

유권자 여러분, 지루한 제출물을지지하지 마십시오. 예 :

  • 언어 -동등한
  • 기존 OISC 구현 (응답자, 직접 작성하십시오!)
  • 첫 번째 인수가 호출 할 명령을 지정하는 "OISC"( example )

그러나 다음과 같은 흥미롭고 창의적인 제출물을지지해야합니다.

  • 수학 방정식에 기반한 OISC
  • 신경망을 기반으로 한 튜링 완료 ZISC
  • 출력 I / O가 특정 메모리 위치와 다른 방식으로 발생하는 OISC

승리

와 마찬가지로 , 가장 많은 표를 얻은 답변이 승리합니다! 행운을 빕니다!


10
"지시"는 무엇입니까? 그리고 우리는 어떻게 그들을 계산합니까?
밀 마법사

1
@NoOneIsHere는 난 그냥 투표의 xD 충분히 알고 싶어
브라이언 H.

2
나는 이것을 하향 투표했다. 나는 이것이 매우 흥미로운 아이디어라고 생각하지만, 당신은 OISC가 무엇인지, 무언가를 확인하는 방법이 정확히 무엇인지 설명하지 않습니다. 나는 BF를 OISC로 만들었지 만, 그것은 분명히 문제의 정신에 위배되지만 기술적으로 유효합니다.
NoOneIsHere 여기

1
@MDXF /// : 당신이 /// :를 얻는다고 생각하지 않습니다 : 그것은 대체 명령을 가지고 있으며, 그것은 대체 명령의 부작용이 아니라 인쇄 명령을 가지고 있습니다
Destructible Lemon

1
@NoOneIsHere 인기 대회 이기 때문에 . 예, 유효하지만 점수가 좋지 않습니다 (투표).
user202729

답변:


20

XOISC

이 OISC는 다음과 같이 정의 된 Fokker의 X- 콤비 네이터를 기반 으로합니다.

엑스=λ에프 .에프 (λ h 엑스 . 엑스 (h 엑스)) (λ에이  기음 .에이)

SKI 미적분 이 튜링 이라는 사실을 인정하면 위의 콤비 네이터도 튜링 완료입니다. 이것은 S , KI 를 다음 과 같이 X 로 작성할 수 있기 때문입니다 .엑스에스케이나는엑스

에스=엑스 (엑스 엑스)케이=엑스 엑스나는=에스 케이 케이=엑스 (엑스 엑스) (엑스 엑스) (엑스 엑스)

XOISC 작동 방식

내부적으로 XOISC에는 (처음에는 비어있는) 스택이 있으며, 을 인수로 사용하는 명령 은 다음을 수행합니다.

  • 스택에서 요소 (기능 f 1f N )를 팝 하고 f 1 ( f 2 ( ( f N에프1에프에프1 (에프2 ((에프 엑스)))

명령이 더 이상 남아 있지 않으면 XOISC는 모든 명령 줄 인수 (있는 경우)를 스택으로 푸시합니다. 예를 들면 다음과 같습니다.

[에스1,, 에스전에 스택, 에이1,, 에이인수]

최종 계산은 .((((에스1 에스2)) 에스) 에이1))에이


XOISC의 하나의 명령어는 하나의 인수 (메모리 오프셋) 만 취하므로 해당 명령어의 이름을 사용할 이유도 없습니다. 따라서 유효한 소스 파일은 다음과 같이 개행 또는 공백으로 구분 된 정수로만 구성됩니다.

0 0 2 0 1 0 1

온라인으로 사용해보십시오!

위 예제를 보자 (오른쪽으로 자라는 스택).

0팝 0 및 적용 (즉, 단일 푸시 엑스):[엑스]0다시 간단히 엑스:[엑스, 엑스]2팝 2 (에이,) 및 푸시 에이 ( 엑스):[엑스 (엑스 엑스)]0단순히 밀어 엑스:[엑스 (엑스 엑스), 엑스]1팝 1 (에이) 및 푸시 에이 엑스:[엑스 (엑스 엑스), 엑스 엑스]0단순히 밀어 엑스:[엑스 (엑스 엑스), 엑스 엑스, 엑스]1팝 1 (에이) 및 푸시 에이 엑스:[엑스 (엑스 엑스), 엑스 엑스, 엑스 엑스]

마지막으로 스택을 평가 : 또는 덜 괄호 X ( X X ) ( X X ) ( X X ) 우리는 좋은 오래된로 인식하는 S K K의 정체성 기능.((엑스 (엑스 엑스)) (엑스 엑스)) (엑스 엑스)엑스 (엑스 엑스) (엑스 엑스) (엑스 엑스)에스 케이 케이

튜링 완성도

증거 아이디어

XOISC가 튜링을 완료하려면 괄호와 조합 의 (올바른) 인터리빙을 번역 할 수 있어야합니다 . 이것은 팝업, 적용 및 푸시가 올바른 연관 방식으로 수행되기 때문에 가능합니다 (함수 적용은 왼쪽 연관 임).엑스

이러한 표현식 을 번역하려면 다음과 같이 쉬운 방법이 있습니다. 항상 현재 괄호 레벨의 처음부터 하나의 요소 만 남도록 많은 요소를 팝하십시오.엑스

예를 들어, 이전에 사용한 표현식 : ((엑스 (엑스 엑스)) (엑스 엑스)) (엑스 엑스)

  • 를 얻으려면 간단히엑스0
  • 다음으로 우리는 새로운 수준의 괄호 안에 있습니다. 0
  • 이제 두 개의 괄호가 닫히므로 2 개의 요소를 표시해야합니다. 2
  • 다시 우리는 새로운 수준의 괄호 안에 있습니다. 0
  • 두 괄호, 다시 닫습니다 2
  • 그리고 다시

그래서 우리는 다른 의미 론적으로 XOISC 프로그램으로 끝납니다.

0 0 2 0 2 0 2 온라인으로 사용해보십시오!

엑스

공식적인 증거

SKI 미적분이 튜링을 완료 한 것을 감안할 때 다음 두 가지를 보여줘야합니다.

  1. 엑스
  2. 엑스

소개에서 세 가지 평등을 증명하는 첫 번째 부분은 매우 지루하고 공간 소모적이며 흥미롭지 않습니다. 따라서이 게시물에 넣는 대신 여기에서 찾을 수 있습니다 * .

엑스

엑스엑스에프 에프

0엑스에프1에프1케이에프에프 

에프1에프 1케이1 (케이+1)에프에프에프 

통역사

입력

타입이 지정되지 않은 람다 미적분은 우리가 원하는 모든 것에 대해 우리 자신의 데이터 타입을 정의해야하기 때문에 통역사가 교회 숫자를 인식하는 것은 번거 롭습니다. 이것은 입력을 제공 할 때 자동으로 숫자를 해당하는 교회 숫자로 변환합니다.

예를 들어 두 개의 숫자를 곱하는 프로그램이 있습니다. 온라인으로 사용해보십시오!

또한 De Bruijn 인덱스 ( 예 : S결합 자 \\\(3 1 (2 1))(또는 λλλ(3 1 (2 1)))) 를 사용하여 함수를 인수로 제공 할 수도 있습니다 . 그러나 그것은 또한 인식 S, K, I물론 X콤비를.

산출

기본적으로 인터프리터는 출력이 정수를 인코딩하는지 확인하고, 그렇지 않으면 결과와 함께 해당 숫자를 출력합니다. 편의상 -b인터프리터가 부울을 대신 일치 시키도록 지시 하는 플래그가 있습니다 (마지막 예 참조).

어셈블러

물론 어떤 저수준 언어라도 고수준 언어를 그 언어로 변환하는 어셈블러가 필요합니다. 간단히 모든 입력 (위 참조)을 사용하여 -a플래그 를 사용하여 XOISC 프로그램으로 변환 하고 온라인으로 사용해보십시오! **


* 링크가 다운 된 경우이 게시물에 HTML 주석으로 된 사본이 있습니다.

** 이로 인해 우선 순위를 테스트하는 프로그램이 만들어집니다. 온라인으로 사용해보십시오!


1
Iota 콤비 네이터 대신 X 콤비 네이터를 선택한 이유가 있습니까?
Esolanging Fruit

1
@ EsolangingFruit : 예, 다른 옵션도 있습니다. 결국 SK를 만들기 위해 가장 적은 응용 프로그램을 사용하기 때문에 그 옵션을 선택했습니다. 그것은 최고의 성능을 발휘하는 것처럼 보였습니다 (tbh 내가 직접 비교하지 않았습니다).
ბიმო

1
Btw. 당신이 관심이 있다면 연결된 종이에 여러 조합기를 비교 한 것이 있습니다.
ბიმო

19

무승부

Draw 는 Wang B-machine과 유사한 방식으로 사각형을 표시하는 2D 그리드에서 작동하는 OISC입니다. 그러나 언어를 가능한 한 단순하고 OISC-y로 유지하기 위해 모든 명령 (총합이 1 개)은 방금 밟은 사각형을 표시하고 정지 할 수 있도록 표시된 사각형을 밟습니다. 프로그램을 종료합니다.

이 프로그램은 라인 식별자 (# 또는 공백을 포함하지 않는 임의의 문자열), 두 개의 정수 ( xy) 및 두 개의 추가 라인 식별자 ( ab)를 포함하는 일련의 라인으로 구성됩니다 .

프로그램 실행은 다음과 같이
식별 라인에서 시작 start위치 (0, 0)을 가리키는 포인터에 의해 주어진 양만큼 포인터를 이동 x하고 y, 포인터가 (사각형이 이미 표시되지 않은 경우에 지금 사각형을 표시 이 경우 실행이 종료됩니다). 그런 다음 a직접 인접한 사각형 중 하나 이상이 표시되어 있으면 줄로 이동하고 b그렇지 않으면 줄로 이동 합니다.

통역사는 그리드의 최종 결과를 일종의 이미지, 캔버스 등으로 출력하도록 권장됩니다.

튜링 완성

Minsky 기계의 수정 된 버전 (Alternate라고 함)을 언어로 컴파일 할 수 있으므로 Draw는 Turing-complete입니다.

대체는 2 카운터 Minsky 시스템과 유사하게 작동하지만 명령에는 큰 제한이 있습니다. 명령은 첫 번째 카운터와 두 번째 카운터를 대상으로 번갈아 가야합니다. 이 수정 사항을 해결하기 위해 추가 명령이 추가되었습니다.nop . 이 명령은 대상 카운터를 전혀 변경하지 않으므로, 위에서 설명한 제한 사항을 만족시키면서 연속 변경 사항을 하나의 카운터에 "채우는"것이 가능합니다. 이것은 또한 수정 될 레지스터가 주어질 필요가 없으며, 주어진 명령에 대해 실행이 점프 할 수있는 명령에서 직접 추론 될 수 있음을 의미합니다.

예 :이 Minsky 머신

1 inc A 2
2 inc A 3
3 dec A 3 4
4 halt

이 대체 프로그램으로 바뀝니다.

1 inc 2
2 nop 3
3 inc 4
4 nop 5
5 dec 6 8
6 nop 5
7 halt
8 halt

이 제한은 최종 Draw 프로그램이 레지스터를 처리하는 방식으로 인해 필요합니다. 즉, 레지스터를 전혀 구분하지 않습니다. 대신, Draw 프로그램은 단순히 이전 명령에 의해 변경되지 않은 레지스터를 복사하여 실행중인 명령에 따라 수정합니다.

그런 다음 대체 프로그램은 다음과 같이 Draw로 직접 변환됩니다.

프로그램은이 블록으로 시작합니다.

start 0 0 a a
a 3 0 b b
b -3 1 c c
c 3 0 d d
d -3 2 e e
e 3 0 f f
f 3 -3 i1_a i1_a

inc, dec그리고 nop서로 거의 같은 방법으로 번역되어진다. 모든 경우에, (위에서 설명 된 바와 같이) 제 1 레지스터 또는 제 2 레지스터를 변경하는 것 사이에는 차이가 없다. 다음과 같은 증분이 있습니다 inc 2.

i1_y 0 -2 i1_z i1_y
i1_z 3 -1 i1_a i1_a
i1_a -5 1 i1_b i1_b
i1_b 0 2 i1_c i1_c
i1_c 0 2 i1_d i1_e
i1_d 0 2 i1_d i1_f

i1_e 5 0 i2_z i2_y
i1_f 5 0 i2_z i2_y

i1_x부품 의 숫자를 현재 명령어의 색인으로 변경 하고i2_x 다음에 실행할 명령의 색인으로 변경하십시오.

nop명령 등으로 번역 될 수있다 :

i1_y 0 -2 i1_z i1_y
i1_z 3 -1 i1_a i1_a
i1_a -5 1 i1_b i1_b
i1_b 0 2 i1_c i1_c
i1_c 0 2 i1_d i1_e
i1_d 0 2 i1_d i1_f

i1_e 5 -2 i2_z i2_y
i1_f 5 -2 i2_z i2_y

이것은 감소입니다 :

i1_y 0 -2 i1_z i1_y
i1_z 3 -1 i1_a i1_a
i1_a -5 1 i1_b i1_b
i1_b 0 2 i1_c i1_c
i1_c 0 2 i1_d i1_e
i1_d 0 2 i1_d i1_f

i1_e 5 -2 i3_z i3_y
i1_f 5 -4 i2_z i2_y

i3_x 카운터가 이미 1 인 경우 호출 할 명령을 나타냅니다.

정지:

i1_y 0 0 0 0
i1_z 0 0 0 0

라벨을 적절하게 변경하고 모든 것을 함께 연결하십시오. 위의 예제에서이를 수행하면 위의 저장소에 Draw 프로그램이 제공됩니다.

통역사

현재 파이썬으로 작성된 두 개의 통역사가 있습니다. Draw의 GitHub 리포지토리 에서 찾을 수 있습니다 .

  1. draw.py :이 인터프리터는 명령 행을위한 것이며 프로그램 소스를 인수로 사용합니다. 모든 단계 후에 실행 된 명령과 명령 포인터의 위치를 ​​출력합니다. 프로그램이 중단 된 후 표시된 셀 수를 인쇄합니다.
  2. draw_golly.py :이 버전은 스크립트를 시작할 때 팝업 상자를 통해 소스를 가져와 잘못된 목적으로 쉽게 그래픽을 출력하기 위해 Golly 를 사용합니다 . Golly는 Python에서 약간 까다로울 수 있으므로 Python 2가 설치되어 있는지 확인하십시오 (32 비트 Golly와 64 비트 Python을 혼합하지 마십시오). 출력은 Golly의 내장 셀 그리드를 통해 제공됩니다.

다음 이미지는 두 번째 인터프리터의 출력 예입니다. 저장소에서 예제 프로그램을 실행하면 다음과 같은 결과가 나타납니다.


1
놀랄 만한! 도전을 수행하는 매우 독특한 방법을 찾은 것을 축하합니다.
MD XF

튜링을 완료하기 위해 언어를 전혀 멈출 필요는 없습니다. 규칙 110은 종료되지 않지만 그럼에도 불구하고 완전히 끝나고 있습니다.
Akangka

최고의 셀룰러 오토마타 시뮬레이터 Golly에게 +1.
HighRadioactive

14

-삼

요점은 다음과 같습니다.

기억

메모리는 테이프 맵이며 키는 문자열이고 값은 임의 크기의 정수입니다.

또한 프로그램으로 이동할 수있는 레이블 세트가 있습니다.

문자열 인 피연산자가 포함 된 스택이 있습니다.

메모리 테이프에서 액세스 할 수있는 위치를 제어하는 ​​offest가 있습니다.

하나의 명령

-. 먼저 LABEL스택 에서 문자열을 팝합니다 . LABEL레이블로 정의되지 않은 경우 레이블을 정의하고 해당 레이블의 소스 (예 : 푸시 된 위치)와 현재 명령어를 지 웁니다. 그렇지 않으면, 상위 두 개의 값을 사용하여 다음의 계산을 수행 A하고 B:

if mem[A] < mem[B]:
    jump to LABEL
if mem[A] != mem[B]:
    mem[A]--
else:
    mem[B]++

인수가 너무 많거나 인수가 충분하지 않으면 프로그램의 오류가 발생하여 프로그램 상태가 표시됩니다.

의 값에 액세스하여 오프셋을 수정할 수 있습니다 ..

예제 코드

X-

i i X-
i i X-
i i X-
i i X-
i i X-
i i X-
i i X-

시간이 증가 i함에 7따라 변수가 로 설정 됩니다 7.

X-

i i X-
i i X-
i i X-
LOOP-
    a a X-
    a a X-
    j i LOOP-

i+1상수에 곱 합니다 2.

튜링 완성도 증명

C ++의 int 크기를 무시하면 (즉, 무한하다고 가정) -3은 3 셀 brainfuck 로 축소하여 Turing Complete 입니다. 임의 크기의 셀이있는 무한 메모리를 가진 컴퓨터에서 -3에 대한 인터프리터를 작성할 수 있기 때문에이 크기를 무시할 수 있습니다.

또한 모든 BCT 를 -3 프로그램으로 작성할 수 있다고 생각합니다 .


내 콘텐츠를 개선하고 싶을 때 다운 투표에 대한 설명을 부탁드립니다.
Conor O'Brien
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.