알 수없는 완성도의 프로그래밍 언어 작성


91

언어가 튜링 완료 인지 확인하는 것은 언어를 디자인 할 때 매우 중요합니다. 많은 난해한 프로그래밍 언어가 시작하기에는 꽤 어려운 작업이지만 한 단계 더 발전시킬 수 있습니다. 튜링 컴플리트를 증명하기 어려운 프로그래밍 언어를 만들면 세계 최고의 수학자조차도 어느 쪽이든 증명할 수 없습니다. 당신의 임무는 Turing Completeness 가 수학주요 미해결 문제에 의존하는 언어를 고안하고 구현하는 것 입니다.

규칙

  • 선택한 문제는 적어도 10 년 전에 제기되었고이 질문을 게시 할 때 해결되지 않았어야합니다. 그것은 위키피디아 페이지 에 열거 된 것 중 하나만이 아니라 수학에서 가능한 추측 일 수 있습니다 .

  • 언어 사양과 기존 언어로 구현을 제공해야합니다.

  • 추측이있는 경우에만 프로그래밍 언어가 튜링을 완료해야합니다. (또는 추측이 보류되지 않은 경우에만)

  • 선택한 추측에 따라 튜링이 완료되었거나 불완전한 이유에 대한 증거를 포함해야합니다. 인터프리터 또는 컴파일 된 프로그램을 실행할 때 무한 메모리에 액세스한다고 가정 할 수 있습니다.

  • 우리는 튜링 완전성 I / O가 필요하지 않기 때문에 목표는 가장 흥미로운 언어를 만들어 도움을 줄 것입니다.

  • 이것은 이므로 가장 많은 표를 얻은 답이 이길 것입니다.

목표 기준

좋은 대답은 무엇을해야합니까? 투표 할 때주의해야 할 사항이 있지만 기술적으로 필요하지는 않습니다.


이 대화는 채팅 으로 이동 되었습니다 .
Dennis

13
전체적으로, 나는 여기서 실망스러운 답을 찾고 있습니다. "튜링 완성 언어로 시작한 다음 추측 X가 참 / 거짓인지 테스트하고, 그렇다면 핵심 기능을 종료하거나 비활성화하십시오."
xnor

1
@ xnor 나는 당신에게 동의합니다, 나는이 현상금이 좀 더 흥미로운 답변을 유발하기를 바라고 있었지만 그것은 일어나지 않을 것 같습니다.
밀 마법사

2
문제 중 하나는 대부분의 추측이 무한한 수의 값에 대해서는 사실이지만 그 반대의 예도 무한한 수의 값에 대해서는 사실이라고 생각합니다. 결과적으로 튜링의 완전성을 증명하는 것이 거의 불가능합니다.
fəˈnɛtɪk

1
튜링 완성도가 주어진 추측과 일대일로 연결되어야한다는 요구 사항은 매우 강력한 요구 사항이라고 생각합니다. Turing 완전성이 두 가지 다른 열린 문제를 각각 결정하거나 반증한다면 쉽게 될 것이라고 생각합니다. (즉, 튜링 완전성을 증명하는 것은 열린 문제 A를 결정하고 반박하는 것은 열린 문제 B를 결정합니다).
PyRulez 2016 년

답변:


48

레전드 르

이 언어는 Legendre의 추측 이 거짓 인 경우에만 Turing-complete 입니다. 즉, n ^ 2와 (n + 1) ^ 2 사이에 소수가없는 정수 n> 0이 있습니다. 이 언어는 Underload에서 영감을 얻지 만, 어떤면에서는 그 언어와는 매우 다릅니다.

Legendre의 프로그램은 일련의 양의 정수로 구성됩니다 (0은 특히 언어의 전체 목적을 무효화하기 때문에 금지됩니다). 각 정수는 Legendre의 기본 명령 또는 잠재적 인 사용자 정의 명령에 해당합니다. 할당 된 명령은 제곱과 다음 정수 사이의 소수 ( OEIS 시퀀스 A014085 와 동일)를 기반으로합니다 .

언어 명령은 스택을 수정하여 임의로 큰 양의 정수를 보유 할 수 있습니다. 스택에 0이 있으면 0이 즉시 제거됩니다. 세부적으로 명령은 다음과 같습니다.

  • 2 (이 명령을 생성하는 가장 작은 정수 : 1) : 프로그램에서 다음 정수를 스택에 넣습니다.

  • 3 (최소 생산 정수 : 4) : 스택에서 최상위 정수를 팝하고 이와 관련된 명령을 실행합니다.

  • 4 (최소 : 6) : 상단 정수를 팝합니다. 1이면 스택에서 최상위 정수를 증가시킵니다.

  • 5 (10) : 상단 두 스택 항목을 교환합니다.

  • 6 (15) : 스택에서 최상위 정수를 줄입니다. 결과가 0이면 0을 팝하고 버립니다.

  • 7 (16) : 스택의 최상위 정수를 복제합니다.

  • 8 (25) : 실행을 중지하고 스택 내용을 인쇄합니다.

이것은 기본 명령 세트이며 루프는 물론 흥미로운 것을 할 수 없습니다. 그러나 Legendre의 추측이 거짓으로 판명 된 경우에만 액세스 할 수있는 다른 명령이 있습니다.

  • 0 (알 수 없음) : 스택에서 모든 항목을 제거하고 새로운 기능으로 결합하여 스택의 원래 하단에서 시작하여 상단에서 끝나는 모든 명령을 실행합니다. "명령 번호"와 같은 명령으로 액세스 할 수 있습니다. 프로그램 소스의 다음 정수에 해당하는 것

이 명령에 접근 할 수있는 언어는 Minsky 기계를 시뮬레이션 할 수 있으므로 언어가 Turing-complete가됩니다.

명령 8이 실행되거나 프로그램의 끝에 도달하면 프로그램이 종료되고 스택의 각 정수에 해당하는 (유니 코드) 문자가 인쇄됩니다.

예제 프로그램

1 2 1 3 1 10 4

이 간단한 프로그램은 4 (명령 : 3)를 실행하기 전에 숫자 2, 3, 마지막으로 10을 푸시합니다. 이로 인해 10 (명령 : 5)이 팝업되고 실행되어 2와 3이 바뀝니다.

1 5 3 15 2 1 6 7

이 프로그램은 간접 정수 대 명령 대응을 사용하는 방법을 보여줍니다. 먼저 2 명령을 인코딩하는 세 가지 다른 방법을 사용하여 5를 누른 다음 15와 1을 누릅니다. 그런 다음 1이 팝업되고 결과적으로 15가 16으로 증가하여 최종적으로 실행됩니다. 프로그램은 스택에서 숫자 5의 두 인스턴스로 끝납니다.

1 1 1 5 ? 24 1 15 1 31 ? 31 24 31

이 프로그램은? 명령을 사용하여 0 명령을 사용하는 방법을 보여줍니다. 자리 표시 자 번호로 프로그램은 먼저 함수 9에 '1 5'를 저장하고 함수 9를 실행하기 전에 (24를 사용하여) 10에 '15 31 '을 저장합니다.이 함수는 스택에 5를 푸시하고 0에 도달하여 제거 될 때까지 반복적으로 감소시킵니다. . 그런 다음 프로그램이 중지됩니다.

민스키 기계

Minsky 컴퓨터를 Legendre 코드로 변환하려면 0 명령을 사용해야 합니다. Legendre의 추측이 거짓이 아니면이 명령에 액세스 할 수 없으므로 자리 표시자를 사용 했습니까? 대신에.

모든 Minsky 기계 명령어 라인 이름은 서로 다른 A014085 대응 및 기본 명령어뿐만 아니라 24 (9) 및 31 (10)의 정수를 가져야합니다.

초기화 :
1 1 1 1 ? 24
x INC (A / B) y :

에이:

1 y 1 24 1 ? 1 6 1 1 16 1 24 ? x

비:

1 y 1 24 1 ? 1 10 1 6 1 1 16 1 10 1 24 ? x
x DEC (A / B) yz :

에이:

1 4 1 10 1 15 1 10 1 31 1 1 1 10 1 z 1 1 1 16 1 24 1 31 1 ? 1 24 1 15 1 y 1 6 16 1 24 16 1 ? 1 1 16 1 10 1 1 16 1 24 ? x

비:

1 4 1 10 1 15 1 10 1 31 1 1 1 10 1 z 1 1 1 16 1 24 1 31 1 ? 1 24 1 15 1 10 1 y 1 6 16 1 24 16 1 ? 1 1 16 1 10 1 1 16 1 10 1 24 ? x
x 정지 :
1 25 ? x

최종 프로그램을 만들려면 모든 부품을 추가하고 (x, y, z를 해당 부품으로 대체) 단일 정수를 추가하여 체인의 첫 번째 명령을 시작하십시오. 이것은 Legendre의 추측이 반례에 의해 거짓으로 판명 된 경우에 언어의 튜링 완성도를 증명해야합니다.

통역사

이 인터프리터는 Python (3)으로 작성되었으며 위의 세 가지 예 모두에서 테스트되었습니다. -a /-allowZero 플래그를 사용하여? -f /-file을 사용하여 파일에서 직접 코드를 실행하고 -s /-stackOut을 사용하여 스택을 Python 목록으로 출력합니다. 파일이 제공되지 않으면 인터프리터는 일종의 REPL 모드로 들어가며 --stackOut에 가장 적합합니다.

import sys
import argparse
import io

class I_need_missing(dict): #used to avoid try/except statements. Essentially a dict
    def __missing__(self,key):
        return None 

def appropriate(integer,prev): #returns number of primes between the square of the integer given and the next

    return_value = 0

    if prev[integer]:
        return prev[integer],prev
    if integer == "?":
        return 0,prev
    for i in range(integer ** 2, (integer + 1) ** 2):
        t = False
        if i > 1:
            t = True
            for j in range(2,int(i ** 0.5)+1):
                t = i/j != round(i/j)
                if not t:
                    break
        return_value += t

    prev[integer] = return_value
    return return_value,prev

def run_command(commandseries,stack,functions,prev): #Runs the appropriate action for each command.

    command,prev = appropriate(commandseries.pop(0),prev)

    halt = False

    if command == 0: #store in given number
        functions[appropriate(commandseries.pop(0),prev)[0]] = stack
        stack = []

    elif command == 2:#push
        stack.append(commandseries.pop(0))

    elif command == 3:#execute top instruction
        commandseries.insert(0,stack.pop())

    elif command == 4:#pop, add 1 to new top if popped value was 1
        if stack.pop() == 1:
            stack[-1] += 1

    elif command == 5:#swap top two integers/?
        stack[-1],stack[-2] = stack[-2],stack[-1]

    elif command == 6:#subtract 1 from top of stack
        stack[-1] -= 1
        if stack[-1] == 0:
            stack.pop()

    elif command == 7:#duplicate top of stack
        stack.append(stack[-1])

    elif command == 8:#halt
        halt = True

    else:#run custom
        try:
            commandseries[0:0] = functions[command]
        except TypeError:
            print("Warning: unassigned function " + str(command) + " is unassigned", file = sys.stderr)

    return commandseries,stack,functions,prev,halt

def main(stack,functions,prev):
    #Parser for command line options
    parser = argparse.ArgumentParser(description = "Interpreter for the Legendre esoteric programming language.")
    parser.add_argument("-a","--allowZero", action = "store_true")
    parser.add_argument("-f","--file")
    parser.add_argument("-s","--stackOut", action = "store_true")

    args = parser.parse_args()
    allow_zero = bool(args.allowZero)

    #Program decoding starts
    pre = ""

    if not args.file:
        pre = input()
        if pre == "":
            return
    else:
        pre = open(args.file).read()

    mid = pre.split()
    final = []

    for i in mid:
        if i == "?" and allow_zero:
            final.append("?")
        elif i != 0 or allow_zero: #and allow_zero)
            final.append(int(i))

    halt = False

    #Functional programming at its best
    while final and not halt:
        final,stack,functions,prev,halt = run_command(final,stack,functions,prev)

    #Halting and output
    else:
        if args.stackOut:
            print(stack)
        else:
            for i in stack:
                print(i == "?" and "?" or chr(i),end = "")
            print("")
        if args.file or halt:
            return
        else:
            main(stack,functions,prev)


if __name__ == '__main__':
    main([],I_need_missing(),I_need_missing())

14

유니온 휴무

이 프로그래밍 언어는 Union-closed Sets 추측 이 올바르지 않은 경우 튜링 완료 입니다.

통제 수단

명령 목록 :
x ++ 증가 x (INC)
x-- 감소 x (DEC)
j (x, y) y가 0이면 명령 대기열의 끝까지 명령 세트 x 추가

모든 변수는 0으로 초기화됩니다

통사론

프로그램은 일련의 명령으로 작성됩니다.
Command1 Command2 Command3 ...
Command1 Command2 ...
...

프로그램이 공용 닫힘인지 판별하기 위해 각 세트는 세트
j (x, y)! = j (a, b)
+ (x)! = + (y) 에있는 다른 명령 목록 만 설명합니다.

명령 유형 (+,-, j)이 세트의 적어도 절반에 나타나면 아무 것도 수행하지 않습니다.

명령 대기열 끝에 명령이 없으면 프로그램이 종료 될 수 있습니다

빈 루프를 포함한 무한 루프는 j (x, y)를 사용하여 달성 할 수 있습니다.

통역사

튜링 완성도

j (x, y) 명령이 모두 증가하면 명령이 모두 사용 가능하므로 Minsky 머신을 시뮬레이션 할 수 있습니다.

j (x, y)를 사용하여 도달 한 j (x, y) 만있는 모든 세트는 HALT입니다.
x ++는 INC x
입니다. DEC입니다.
j (x, y)는 JZ입니다.

조합 폐쇄 집합 추측이 올바른 경우, 세 가지 명령 중 하나 이상이 항상 비활성화되어이 언어가 튜링을 완료 할 수 없습니다.


내가하는 것은 3 개의 연산자를 갖는 대신 무한한 수의 값을 가지며 각각의 모듈로 4를 사용하여 세 가지 연산 중 하나에 no-op를 얻는 것입니다. 프로그램이 시작되면 세트의 결합이 닫혀 있는지 확인한 다음 세트의 절반 이상에있는 요소를 제거합니다. 그런 다음 해당 요소가 없을 때까지이를 반복합니다. 추측이 참이면 모든 프로그램이 빈 프로그램과 동일하지만 거짓이면 가능한 모든 프로그램을 표현할 수 있습니다 (그래서 no-op가 포함되는 이유).
밀 마법사

@WheatWizard 인터프리터가 닫은 공용체 결정은 다른 변수의 동일한 연산자가 다른 것으로 간주합니다. x ++는 y ++와 다른 것으로 간주됩니다. 결과적으로, 생성 될 수있는 다른 세트의 무한대가 있습니다. 무한한 개수의 세트를 사용하면 세 가지 주요 유형 중 하나도 세트의 절반 이상에 해당되지 않으면 튜링이 완료된 것입니다.
fəˈnɛtɪk

조합 폐쇄 세트 추측에 대한 증거는 프로그램에 다른 모든 연산자를 남겨 둘 수 있기 때문에 튜링이 완료된 것처럼 세 연산자 중 하나에 대한 변환을 남길 수 있습니다. 남을 가치.
fəˈnɛtɪk

13

페르마 프라임

이 언어는 테이프의 각 위치가 임의의 정수를 저장할 수있는 두 개의 잠재적으로 무한한 테이프에서 작동합니다. 두 테이프 모두 -1시작시 채워집니다 . 두 테이프에서 위치 0에서 시작하는 두 개의 테이프 헤드도 있습니다.

인터프리터는 먼저 입력을 읽고 위치 0에서 시작하여 첫 번째 (데이터) 테이프에 값을 저장합니다.

그런 다음 제공된 프로그램을 읽습니다. 발생하는 모든 숫자에 대해 먼저 값이 Fermat 소수인지 여부를 확인합니다. 그렇다면, Fermat가 프라임 인 두 번째 (지시) 테이프에 기록 -1하고 그렇지 않으면 지시 테이프에 기록 합니다.

그런 다음 명령 포인터에서 값을 확인하고 다음 중 하나를 수행하십시오.

  • -1 이하 : 프로그램 종료
  • 0: 데이터 테이프 위치를 왼쪽으로 이동합니다. 지시 테이프 위치를 오른쪽으로 이동
  • 1: 데이터 테이프 위치를 오른쪽으로 이동합니다. 지시 테이프 위치를 오른쪽으로 이동
  • 2: 데이터 테이프 위치에서 값을 증가시킵니다. 지시 테이프 위치를 오른쪽으로 이동
  • 3: 데이터 테이프 위치의 값을 줄입니다. 지시 테이프 위치를 오른쪽으로 이동
  • 4: 현재 데이터 테이프 위치의 값이 0이면 명령 테이프에서 일치하는 5(또는 더 큰) 값에 도달 하거나보다 작은 값에 도달 할 때까지 명령 테이프를 오른쪽으로 이동하십시오 0. 그것은 경우 5(또는 그 이상)가보다 작은 있다면, 다시 한번 명령 포인터를 오른쪽으로 이동 0한 후 프로그램을 종료합니다. 현재 데이터 테이프 위치 값이 0이 아닌 경우 명령 테이프를 오른쪽으로 간단히 이동하십시오.
  • 5또는 그 이상 : 해당 4값에 도달 하거나보다 작은 것을 찾을 때까지 명령 포인터를 왼쪽으로 이동하십시오 0. 후자의 경우 프로그램을 종료하십시오.

( 5또는 더 많은 4값 과 값 을 일치시킴으로써 ) 명령 테이프에서 올바른 값을 검색하는 동안 초기 명령과 동일한 값이 발생할 때마다 5(또는 이상) 또는 4적절한 숫자를 건너 뛰어야 함을 의미합니다. 검색에서 다른 값 ( 4또는 5각각 또는 그 이상)

명령에서 프로그램을 종료해야 할 때까지 반복하십시오.

프로그램이 종료되면 데이터 테이프의 값을 0위치에서 -1값 을 포함하는 첫 번째 테이프 위치까지 출력하십시오 .

증명

이 언어는 본질적으로 IO가없는 Brainfuck 인터프리터에 매핑되며 F_5모든 종류의 적절한 루프를 수행 할 수 있어야합니다.

그러나 Fermat 프라임 추측을 기반으로 5 개의 Fermat 프라임 ( F_0- F_4) 만 있습니다. F_5존재하는 경우 Brainfuck이 Turing-complete라는 것을 알기 때문에 언어가 Turing-complete입니다. 그러나, F_5당신이 없으면 브랜칭이나 루핑을 할 수 없으므로 본질적으로 매우 간단한 프로그램에 고정됩니다.

이행

(루비 2.3.1로 테스트)

#!/usr/bin/env ruby
require 'prime'

CHEAT_MODE = false
DEBUG_MODE = false
NUM_CACHE = {}

def determine_number(n)
  return n.to_i if CHEAT_MODE
  n = n.to_i
  -1 if n<3

  return NUM_CACHE[n] if NUM_CACHE[n]

  i = 0

  loop do
    num = 2**(2**i) + 1
    if num == n && Prime.prime?(n)
      NUM_CACHE[n] = i
      break
    end
    if num > n
      NUM_CACHE[n] = -1
      break
    end
    i += 1
  end

  NUM_CACHE[n]
end

data_tape = Hash.new(-1)
instruction_tape = Hash.new(-1)

STDIN.read.each_char.with_index { |c,i| data_tape[i] = c.ord }
File.read(ARGV[0]).split.each.with_index do |n,i|
  instruction_tape[i] = determine_number(n)
end

data_pos = 0
instruction_pos = 0

while instruction_tape[instruction_pos] >= 0
  p data_tape, data_pos, instruction_tape, instruction_pos,'------------' if DEBUG_MODE

  case instruction_tape[instruction_pos]
  when 0 then data_pos -= 1; instruction_pos += 1
  when 1 then data_pos += 1; instruction_pos += 1
  when 2 then data_tape[data_pos] += 1; instruction_pos += 1
  when 3 then data_tape[data_pos] -= 1; instruction_pos += 1
  when 4 then
    if data_tape[data_pos] == 0
      count = 1
      instruction_pos += 1
      while count>0 && instruction_tape[instruction_pos] >= 0
        count += 1 if instruction_tape[instruction_pos] == 4
        count -= 1 if instruction_tape[instruction_pos] >= 5
        instruction_pos += 1
      end
      break if count != 0
    else
      instruction_pos += 1
    end
  else
    count = 1
    instruction_pos -= 1
    while count>0 && instruction_tape[instruction_pos] >= 0
      count += 1 if instruction_tape[instruction_pos] >= 5
      count -= 1 if instruction_tape[instruction_pos] == 4
      instruction_pos -= 1 if count>0
    end
    break if count != 0
  end
end

data_pos = 0

while data_tape[data_pos] >= 0
  print data_tape[data_pos].chr
  data_pos += 1
end

예 :

이 줄 바꿈과 함께 화면에 씁니다 H( Hello World!).

17 17 17 17 17 17 17 17 17 17
17 17 17 17 17 17 17 17 17 17
17 17 17 17 17 17 17 17 17 17
17 17 17 17 17 17 17 17 17 17
17 17 17 17 17 17 17 17 17 17
17 17 17 17 17 17 17 17 17 17
17 17 17 17 17 17 17 17 17 17
17 17 17
5
17 17 17 17 17 17 17 17 17 17
17

다른 이름으로 저장하고 다음 example.fermat과 같이 실행하십시오 (참고 : 항상 입력이 필요합니다).

$ echo -n '' | ./fermat.rb example.fermat

다음 예제는 입력의 각 값을 1 씩 증가시켜 간단한 시저 스타일 사이퍼를 수행합니다. 분명히 ?다섯 번째 Fermat 프라임 으로 교체 해야합니다.

17 65537 5 17 ? 257

치트 모드를 활성화 2 4 1 2 5 3하고 소스 코드로 사용하여 작동하는지 확인할 수 있습니다 .

$ echo 'Hello' | ./fermat.rb example2_cheat.fermat

2
에 해당하는 소수를 입력 해야하는 가난한 코더에게 죄송합니다 5. 나는 그들이 좋은 키보드를 가지고 있기를 바랍니다.
AdmBorkBork

2
@AdmBorkBork 걱정하지 마십시오. 우주에는 원소 입자보다 많은 비트가 있습니다.
fəˈnɛtɪk

@LliwTelracs 실제로 우주에서 원소 입자의 양이 Aleph-null (omega)이고 오메가에서 오므로 실제 숫자의 크기를 의미하지 않기 때문에 의미가 없습니다. (알레프가 아닌 한 : P)
Matthew Roh

1
@MatthewRoh 나는 실수했다. 나는 관측 가능한 우주를 의미했다.
fəˈnɛtɪk

2
@MatthewRoh 실제로, 그것은 유한하거나, 무한하거나, 셀 수 없거나, 이론에 맞지 않을 수도 있습니다! 그러나 우리는 결코 알지 못할 것입니다 :(
CalculatorFeline

10

코코넛 v2가있는 제비

이전 버전에서이 컨테스트에 사용할 수없는 오류가 발생하여이 버전에 대해 이전 버전의 지지율이 크게 다른 것을 원하지 않기 때문에이 버전은 새 게시물로 제출되고 있습니다.

Collatz Conjecture 가 모든 양의 정수에 대해 입증 될 수있는 경우이 언어는 완전하지 않습니다 . 그렇지 않으면 언어가 튜링 완료입니다.

이 언어는 추기경 을 기반으로합니다 .

먼저, 프로그램의 contVal은
contVal = sum (sum (ASCII values ​​of row) * 2 ^ (row number-1)) 공식을 사용하여 계산됩니다.

다음으로, 각각의 A 또는 E에서 반대 방향으로 향하는 2 개의 제비가 생성되고 모든 조건부 회전문이 초기화를 기다리도록 설정됩니다.
E에서 만든 제비는 왼쪽 / 오른쪽으로 향하고 A에서 만든 제비는 위 / 아래로 향합니다.

마지막으로 코드는 모든 포인터가 제거되거나 contVal이 하나로 떨어질 때까지 단계를 수행합니다.

각 단계에서 contVal % 2 == 0이면 2로 나누고 그렇지 않으면 3을 곱하고 1 씩 증가시킵니다.

명령 :

0 : 값을 0으로 설정
+ : 1을 기준으로 증분 값
> : 방향을 오른쪽으로 변경
v : 방향을 아래로
변경 <: 방향을 왼쪽
으로 변경 ^ : 방향을 위쪽으로 변경
R : 첫 번째 포인터 이후의 후속 포인터는 첫 번째 포인터. 같으면 똑바로 가십시오. 그렇지 않으면 우회전하십시오.
L : 첫 번째 포인터 이후의 후속 포인터는 첫 번째 포인터의 값과 비교됩니다. 같으면 직진하고 좌회전하십시오.
E : 포인터를 복제하지만 왼쪽과 오른쪽 방향으로 향함
A : 포인터를 복제하지만 위와 아래 방향으로 향하고
있습니까? : 값이 0이면 포인터를 제거하십시오.

설명:

Collatz Conjecture가 모든 양의 정수에 대해 입증 될 수있는 경우, contVal이 항상 1로 수렴되어 프로그램을 종료하므로이 언어로 실행되는 모든 프로그램의 기간은 유한합니다.

그렇지 않으면이 언어가 다음 기능을 구현할 수 있음을 증명해야 합니다.

증분 : +로
표시됨 상수 0 : 0으로 표시
변수 액세스 : 변수가 이동함에 따라 포인터로 저장됩니다
. 명령문 연결 : 작업으로 이동 한 거리를 변경하여 작업 수행 순서를 변경할 수 있습니다.
For 루프 : 이 언어로

E   > V
    ^+R
      +
      A

for 루프 역할을하며 최대 1 개까지 카운트합니다 (추가 코드를 루프에 추가 할 수 있음)

마찬가지로 코드

Rv
^<

R 루프에 설정된 조건 값과 같아 질 때까지 수행합니다.


당신도 날 이겼어요 흥미로운 일 이네요.
Rohan Jhunjhunwala

혼란 스러워요. Collatz 기능은 어디에 있습니까? 두 번째 판독에서 함수가 contVal모든 단계에 적용된다고 말하고 (따라서 추측이 참이면 무한 루프가 없음) 대답하지만 대답의 어느 부분에도 명시 적으로 언급되어 있지는 않습니다. ??
DLosc

미안하지만, 내가 실수로 내 설명에서 어떤 점을 잘라낸 것 같아요
fəˈnɛtɪk

10

완벽 / 불완전

휴, 그것은 재미 있었다.

완벽 / 불완전은 무한 완벽 숫자가있는 경우에만 완료됩니다. 있으면 완벽이라고하고,없는 경우에는 불완전이라고합니다. 이 수수께끼가 풀릴 때까지 두 이름이 있습니다.

완전 숫자는 제수가 그 수에 해당하는 숫자이므로 6은 완벽한 숫자입니다 1+2+3=6.

완벽 / 불완전에는 다음과 같은 기능이 있습니다.

완벽 / 영향은 스택 기반이며 인덱스가 0 인 스택입니다.

명령 :

p(x, y): x를 y 번째 위치의 스택으로 푸시합니다.

z(x, y): x를 y 번째 위치의 스택으로 밀고 이전의 y 번째 위치에 있던 것을 제거합니다.

r(x): 스택에서 x 번째 항목을 제거합니다

k(x): 스택의 x 번째 항목을 반환

a(x, y): x와 y를 더합니다. 문자열과 함께 사용하면 xy 순서로 묶습니다.

s(x, y): x에서 y를 뺍니다. 문자열로 x에서 마지막 len (y)을 제거합니다.

m(x, y): x와 y를 곱합니다. 문자열과 함께 사용하면 x에 len y를 곱합니다.

d(x, y): x를 y로 나눕니다.

o(x): x를 인쇄합니다

i(x, y): x가 true로 평가되면 함수 y를 실행합니다.

n(): 코드 블록이 호출되는 카운터를 반환합니다.

q(): 스택의 길이를 반환

t(): 사용자 입력

e(x, y): x가 정수이면 x와 y의 값이 같으면 1을 반환합니다. y가 문자열이면 y의 길이를 얻습니다. x가 문자열 인 경우 y를 문자열로 변환하여 동일한 지 확인하고 동일한 경우 1을 반환하고 그렇지 않으면 0을 반환합니다.

l(x, y): x가 y보다 크면 1을 반환합니다. 문자열이 있으면 문자열의 길이를 사용합니다.

b(): 프로그램을 중지합니다.

c(x, y): x를 실행 한 다음 y를 실행합니다.

Python과 동등한 것을 얻으려면 and두 값을 곱하십시오. 내용은 or, 값 추가에 대한 not값은 그 자체로 수를 분할함으로써 달성 될 수있다 1 또는 0이면 1이에만 작동에서 값을 뺀다.

데이터 유형 : 정수 및 문자열 문자열은로 표시되며 ''정수가 아닌 모든 숫자는 반올림됩니다.

통사론:

코드는 10 {}초 안에 중첩 함수로 구성됩니다 . 예를 들어, 입력을 받고 추가하여 인쇄하는 프로그램은 다음과 같습니다 {o(a(t(), t()))}. 프로그램의 배경에는 0에서 시작하여 코드 블록을 실행할 때마다 1 씩 증가하는 카운터가 있습니다. 첫 번째 코드 블록은에서 실행 0됩니다. 10 개의 코드 블록이 실행되면 카운터가 완벽한 숫자에 도달 할 때마다 6 번째 코드 블록이 실행됩니다. 프로그램이 작동하기 위해 10 개의 코드 블록을 모두 가질 필요는 없지만 루프를 만들려면 7이 필요합니다. 이 언어의 작동 방식을보다 잘 이해하려면 다음 프로그램을 실행하십시오. 카운터는 완벽한 숫자에 도달 할 때마다 카운터를 인쇄합니다 {}{}{}{}{}{}{o(n())}.

인터프리터는 repl.it/GL7S/37 에서 찾을 수 있습니다 . 1을 선택하고 터미널에 코드를 입력하거나 code.perfect탭에 코드를 붙여넣고 실행할 때 2를 선택하십시오. 당신이 그것을 시도 할 때 의미가 있습니다.

튜링 완전성 증명 / 튜링 완전성 부족.

이 소프트웨어 엔지니어링 스택 교환 기사 에 따르면 튜링 컴플리트는 점프 조건부 반복 형식을 가질 수 있어야하며 메모리를 읽거나 쓰는 방법이 있어야합니다. 스택 형태로 메모리를 읽고 쓸 수 있으며 카운터가 완벽한 숫자에 도달 할 때마다 6 번째 코드 블록이 실행되기 때문에 반복 될 수 있습니다. 완벽한 수의 무한 수가있는 경우 무한 반복 될 수 있으며 튜링 완료입니다. 그렇지 않으면 그렇지 않습니다.

5 비트 (1 또는 0)를 입력으로 사용하는 자체 비트 순환 태그 인터프리터 :

{p(t(),0)}{(p(t(),0)}{p(t(),0)}{p(t(),0)}{p(t(),0)}{p(0,0)}{c(i(e(k(s(q(),k(0))),0),c(r(q()),i(l(k(0),0),z(s(k(0),1),0)))),i(e(k(s(q(),k(0))),1),c(z(a(k(0),1),0),i(e(k(q()),1),p(k(s(q(),k(0))),1)))))}

여러 문자를 입력으로 사용하도록 확장 할 수 있습니다. 무한 입력이 필요할 수 있지만 무한 완벽 숫자가있는 경우에만 가능합니다!


1
나는 함수와 공유되지 않기 때문에 로컬로 루핑하기 위해 새로운 값을 만들고 있다고 생각합니다.
fəˈnɛtɪk

3
TC에 대한 증거는 없습니다. 링크 된 소프트웨어 엔지니어링 기사는 대략적인 요구 사항을 제공하지만 TC는 체크 박스로만 사용되는 것은 아닙니다. TC 자동 장치 (예 : Minsky Machine)를 구현하거나 언어를 결정할 수 없음을 보여 주어야합니다.
밀 마법사

2
@WheatWizard 거기서 Bitwise Cyclic Tag 인터프리터를 추가했습니다. 임의의 양의 문자를 입력으로 사용하도록 수정할 수 있습니다. 무한 문자를 입력으로 사용할 수는 있지만 무한 완벽 숫자가있는 경우에만 가능합니다!
스파클 포니 동지

2
"10 개의 코드 블록이 실행되면 카운터의 숫자가 완벽한 숫자에 도달 할 때마다 6 번째 코드 블록이 실행됩니다."따라서 통역사는 완벽한 숫자를 직접 계산합니까? 나는 이것이 도전 정신에 위배되는 것처럼 느낍니다. 실제 언어 사양은 그다지 중요하지 않습니다. Turing-complete와 "완벽한 숫자에 도달했을 때만 한 단계 만 실행"이 될 수 있습니다.
xnor

10

발바닥

이 프로그래밍 언어는 Scholz 추측맞으면 튜링 완료 입니다.

@SztupY는 튜링이 완벽하다고 추측하기에 추측에 의존하는 결과가 없을 것이라고 말했기 때문에이 언어를 썼습니다.

명령 목록

+(x)      Increment x (INC)   
-(x)      Decrement x (DEC)  
j(x,y)    Jump to instruction x if y is 0 (JZ)  
x         End program (HALT) 

이 명령으로이 언어는 Minsky 머신을 시뮬레이션 할 수 있습니다

통역사

이것을 실행하지 않는 것이 좋습니다. 추가 체인을 확인하는 매우 느린 방법을 사용합니다.

튜링 완성도

이 언어는 Scholz 추측과 대조하여 언어의 완전한 완성도를 수정하는 명령 실행 횟수에 대한 카운터를 사용합니다.

Scholz 추측이 참인 경우,이 프로그램은 Zero Halt 인 경우
증가
감소
점프가 있는 일반 Minsky 시스템과 동일하게 작동합니다.

그러나 Scholz 추측이 거짓이면 카운터는 결국 Scholz 추측이 맞지 않는 값에 도달합니다. Scholz 추측이 틀린 수에 도달하면 언어가 종료되도록 설계되었으므로 프로그램은 많은 명령을 실행 한 후 매번 종료됩니다. 따라서 모든 프로그램의 길이가 제한됩니다. 튜링이 완료되는 언어에 대한 요구 사항에 동의하지 않으면

"테이프는 주어진 정의에 해당하지 않고 기계가 수행 할 수있는 계산 범위를 선형 경계 오토 마톤의 계산 범위로 심각하게 제한 할 수 있기 때문에 길이를 고정 할 수 없습니다.",

숄츠 추측이 틀린 경우 언어는 튜링 완료되지 않을 것입니다


1
+1, 이것은 실제로 추측 요구 사항을 언어에 하드 베이크 (hard-baking)하기 때문에 추측이 참 / 거짓 일 경우 언어를 죽이기 위해 불필요한 것을 추가하는 것
Gryphon

나는 그것을 얻지 못한다. 제공하는 명령은 Minsky 기계를 시뮬레이션하는 데 필요한 명령 일 뿐이므로 Scholz 추측에 관계없이 언어가 튜링입니다. 당신은 당신의 설명에서 무언가를 놓치고 있어야합니다.
Nathaniel

@Nathaniel 튜링 완전 언어의 요구 사항 중 하나는 언어가 무한 루프로 끝날 수 있다는 것입니다 (정지 문제). 내 코드는 명령을 실행할 때 계산되며 Scholz 추측이 거짓이면 프로그램은 설정된 수의 명령 후에 항상 중지됩니다.
fəˈnɛtɪk

그렇습니다. 그러나 당신은 숄츠 추측이 거짓이라면 그것이 멈추는 원인을 설명하는 것을 잊었습니다. 답을 다시 한 번보십시오. 전혀 없습니다.
Nathaniel

@Nathaniel이 프로그램은 문자 그대로 scholz 추측에서 작동하는지 모든 단일 숫자를 검사하여 작동합니다. 추측에 동의하지 않는 숫자를 찾으면 자동으로 종료됩니다.
fəˈnɛtɪk

9

약혼자

약자 Github .

readme 및 사양은 github의 "README.txt"에 있습니다.

일반적으로, Betrothed 프로그램은 한 쌍의 라인으로 구성되며, 길이는 별개의 쌍 소수 쌍 또는 약자 쌍입니다 (중복이 발생하지 않음). 프로그램은 두 번째 라인 내에서 첫 번째 라인의 "유연한 서브셋"을 찾아서 실행됩니다. 유연한 서브 세트가없는 원래의 두 번째 라인과 두 번째 라인 사이의 레 벤슈 테인 거리와 결합 된 이러한 서브 세트의 수는 실행할 명령을 결정합니다.

이 게시물에 대한 증거를 발췌합니다.

V. PROOF OF TURING COMPLETENESS

Now, no language can be Turing Complete with bounded program size. Therefore, if Betrothed
is Turing Complete, it must have unbounded program size. Since the lengths of the lines of
a Betrothed program must be twin prime pairs or betrothed pairs, and since both sequences
are unproven to be infinite or finite, Betrothed has unbounded program size if and only if
there are infintie betrothed pairs, there are infinite twin prime pairs, or both.

    Next: to prove that if Betrothed has an unbounded program size, then it is Turing
Complete. I will use the op-codes from the above table to demonstrate key factors of a
Turing Complete language; they are of the form  [index]<[ld]> .

  1. Conditional goto: 6<> 5<>, or if-popjump. This can be used to form a loop.
  2. Inequality to a constant K: 10<K> 
  3. Arbitrarily large variable space: you can use some separator constant C.

    With this, I have sufficient reason to believe that Betrothed is Turing Complete.

4
"이제 제한된 프로그램 크기로 언어를 튜링 완성 할 수는 없습니다." 나는이 진술에 대해 혼란 스럽습니다 ... 한편으로는 제한된 프로그램 크기를 사용하면 유한 수의 다른 프로그램 만 작성할 수 있지만 Turing Completeness에 대한 일반적인 증거는 다른 해석기를 작성하는 것입니다 무한한 프로그램 규모를 필요로하지 않는 튜링 완전한 언어 ...
Leo

1
통역사에게 전달 된 프로그램은 통역사 코드에 입력 할 필요가 없으며, 입력으로 통역사에게 제공되어야합니다
Leo

7
@사자 별자리. 언어가 TC가 되려면 프로그램이 인터프리터로 전달되도록 인코딩 할 수 있어야합니다 (즉,이 언어에 입력 명령이 없다고 상상해보십시오). 하나의 명령으로 언어를 상상해보십시오 b. 이것은 다음과 같은 BF 프로그램을 해석합니다 b+++++.. 그러나 프로그램의 크기는 10 자로 제한됩니다. BF를 해석 할 수는 있지만 튜링 머신이 할 수있는 모든 프로그램을 계산할 수는 없습니다.
코너 오브라이언

3
@EriktheOutgolfer 문제의 주요 문제는 "입력에서 얻은 BF 프로그램을 넣을 수 있습니다 ..."입니다.이를 위해, 이전 주석, 특히이 첫 문장을 읽거나 다시 읽어 보시기 바랍니다. 입력에 따라 언어가 Turing 만 완료된 경우 입력없이 언어가 어떻게 Turing 완료 될 수 있습니까? 즉, 언어가 튜링을 완료하기 위해서는 프로그램을 인코딩해야하는 것이 언어의 프로그램 자체입니다. 그렇지 않으면 입력에서 프로그램을 인코딩하는 것으로 나타 났는데 이는 유효한 프로그래밍 방법이 아닙니다.
Conor O'Brien

1
나는 이것이 확정 된 지점이라고 생각하지 않습니다. 이 Esolang 기사 는이 문제에 대해 설명합니다. ( 가능한 모든 종료 프로그램을 출력과 함께 Turing-complete 언어로 출력하는 프로그램이 Turing-completeness 데모 인지 여부에 대한 질문도 있습니다 . 입력이 필요없고 유한하게 긴 프로그램으로 수행 할 수 있습니다 .)

5

원만한 패리티

이 언어는 반대 패리티를 가진 원만한 숫자 가 있는지 여부를 기반으로합니다 .

명령

x : End program if not on top line  
+ : increment stored value  
- : decrement stored value  
{ : set next goto x value to current x value
} : goto previous x value set by {  
j : Go down one line if the special value is an amicable number and the
    parity is opposite to the matching number (loops back to top). If the
    special value is not an amicable number and not on the top line, go up
    one line.  

제어 흐름

프로그램은 왼쪽에서 오른쪽으로 반복해서 순환하며 시작으로 되돌아갑니다. "j"가 발생하면 값을 확인하여 행을 변경해야하는지 여부를 결정합니다. 숫자가 일치하는 패리티가있는 원만한 숫자이면 한 행 아래로 내려 가고 (루프 맨 위로), 그렇지 않으면 숫자가 원만한 숫자이면 맨 위 행에 있지 않으면 한 행 위로 올라갑니다.

프로그램은 맨 위 행 외부의 행에서 x에 도달 한 경우에만 종료 할 수 있습니다.

튜링 완성도

이 프로그램은 반대 패리티를 가진 원만한 숫자 쌍이 있다고 가정하여 Minsky 기계를 시뮬레이션하는 데 사용할 수 있습니다.

j, {및}를 사용하여 JZ (r, x)를 시뮬레이션 할 수 있지만 0이 아닌 원만한 숫자를 확인합니다.
+는 INC (r)
-DEC (r)
x는 HALT

첫 번째 행을 떠날 수 없으면 x 및} 명령은 아무 작업도 수행하지 않습니다. 이로 인해 프로그램이 비어 있지 않으면 프로그램이 HALT 상태로 들어갈 수 없습니다. 따라서 Turing 완성도 에는 HALT state가 필요 하다는 설명 하에서 언어는 Turing 불완전합니다.

통역사


2

줄 바꿈

면책 조항 : 그것은 약간 혼란스럽고 매우 간단합니다. 이것은 내가 쓴 첫 번째 언어이며 추측은 내가 이해 한 유일한 언어입니다. 다른 사용자가 동일한 사용자로 더 긴 답변을 받았음을 알고 있지만 어쨌든 작성하기로 결정했습니다.

줄 바꿈으로 쓰려면 많은 시간과 줄 바꿈이 있어야합니다 ( \n). 이것은 Legendre 추측에서 사실로 작동합니다. 모든 연산자는 우리가 n = 1로 시작하는 Legendre 추측의 숫자에 속해야합니다. 연산자가있을 때마다 \ n을 가져 와서 Legendre 추측에 꽂고 다음 소수가 \ 인 범위를 얻습니다. n은 반드시 들어가야합니다. 따라서 시작 \n\n하려면 연산자로 이동 한 \n다음 다른 연산자를 3 개의 줄 바꿈에 놓습니다. 이제 다음은 5입니다. 그래서 \n\n마지막 연산자 라인에 우리가 시작한 Legendre 추측에 해당하는 소수의 줄 바꿈이 올바른지 확인하십시오.

숫자 (배열)는 변수와 같습니다. 연산자가 숫자를 사용하여 실행될 때마다 증가합니다.

+ adds
- subtracts
/ divide
* multiply 
s sqrt
% mod
a push to vars
g sets stack to numbers
q pushes value of stack to numbers
i increment 
d decrement
r stops subtraction at 0
w turns back on subtraction past 0
[ starts loop
] ends loop runs until stack is 0
{ starts loop
} ends loop and loops until loops[ln] is 0
k increment loops

규칙을 따르는 무제한 소수가있는 한이 언어에는 유한 테이프가 없습니다.

민스키 기계

\n\ng\nr\n\n[\n\nd\n\n\n\n]

작동 방식 :

\n\ng     # the first two newlines are to get to a prime number of newlines (2) then sets the value of stack to the first variable in the array numbers (see code in link)

\nr       # gets to the next number and makes it so subtraction stops at 0

\n\n[     # starts the loop

\n\nd     # decrements stack 

\n\n\n\n] # ends loop

KhanAcademy 에서 사용해보십시오 .


@wheat 그것은 무한 메모리가 아닌 루프로 루프 할 필요가 없습니다
Christopher

사실 인 경우에만 작동합니다. 나는 모바일에 있지만 지금은 오늘 밤 글을 마칠 수 없습니다
Christopher

무한 메모리가 있어도 무한 루프를 계속할 수 있어야합니다.
Pavel

루프가 있습니다. 그들을 무한으로 만들려고
Christopher

지금 그들은 충돌합니다
Christopher

2

타기 스

Taggis는 태그 시스템을 기반으로하는 언어입니다 .

Taggis의 튜링 완성도는 Collatz 추측을 기반으로합니다.

통사론

Taggis 프로그램의 구문은 단순히 공백으로 구분 된 문자 a, b 및 c로 구성된 세 개의 문자열 (생산 규칙)입니다.

실행

Taggis의 유일한 프로그램 상태는 동일한 세 문자로 구성된 문자열입니다.

Taggis는 TS (3, 2) 태그 시스템을 구현합니다. 여기서 모든 단계에서 현재 "태그"의 처음 두 글자가 제거되고 제거 된 부분에 있던 첫 번째 글자가 해당 생산 규칙의 끝에 추가됩니다. 문자열

예를 들어 Taggis 프로그램 bc a aaa은 3n + 1 문제를 구현합니다. 여기서 반복은 해당 개수의 as로 표시되고 3n + 1 단계는 (3n + 1) / 2 [1]로 대체되어 프로그램 출력으로 이어집니다.

aaa // 3
  abc
    cbc
      caaa
        aaaaa // 5
          aaabc
            abcbc
              cbcbc
                cbcaaa
                  caaaaaa
                    aaaaaaaa // 8
                      aaaaaabc
                        aaaabcbc
                          aabcbcbc
                            bcbcbcbc
                              bcbcbca
                                bcbcaa
                                  bcaaa
                                    aaaa // 4
                                      aabc
                                        bcbc
                                          bca
                                            aa // 2
                                              bc
                                                a // 1 and halt because we then begin an infinite loop
                                                 HALT

튜링 완성도

물론,이 간단한 시스템은 튜링 완성도를 모방하기에는 너무 단순 해 보일 수 있지만, 2 개의 심볼 (유니버설 머신을 포함하는 클래스)을 가진 모든 튜링 머신은 헤드에서 2 개의 제거 된 문자를 가진 태그 시스템으로 변환 될 수 있습니다. 32 * m 생산 규칙, 여기서 mTuring 기계의 상태 수입니다.

2 개의 기호 만있는 가장 작은 알려진 범용 튜링 기계는 18 개의 상태를 사용하므로 해당 태그 시스템에는 무려 576 개의 생산 규칙이 포함됩니다 [2].

그러나 3 개의 프로덕션과 2 개의 제거 된 심볼을 가진 모든 태그 시스템 세트의 계산 클래스는 Collatz Conjecture [2]와 연결되어 있습니다. Collatz 추측이 틀린 것으로 판명되면 Taggis는 Turing-complete입니다. 그렇지 않으면 수학에서 해결되지 않은 또 다른 문제를 기반으로해서보다 작은 튜링 머신을 찾습니다.

def taggis(inp, a, b, c):
    current = inp
    seen = set()
    while True:
        seen.add(tuple(current))

        yield current

        head = current[0]

        current = current[2:]

        current.extend([a, b, c][head])

        if tuple(current) in seen:
            return

def parse():
    program = input().split(" ")

    assert len(program) == 3, "There has to be exactly 3 production rules!" 

    productions = []

    for production in program:

        production = [{"a": 0, "b": 1, "c": 2}[x] for x in production]
        productions.append(production)  

    program_input = [{"a": 0, "b": 1, "c": 2}[x] for x in input()]

    k = 0   

    for step in taggis(program_input, *productions):
        print(' ' * k +''.join(['abc'[x] for x in step]))

        k += 2
    print(' ' * (k - 1) + 'HALT')

parse()
  1. 홀수의 3n + 1 n은 항상 짝수 이므로 나눗셈이 자동으로 적용될 수 있으므로 원래 Collatz 함수와 같습니다.

  2. 태그 시스템과 Collatz 같은 기능, 리스 베스 드 몰 ,

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.