김표 계산 및 ZFC에서 종료되지 않은 알고리즘


12

김 테이블은 수학의 표준 공리 시스템에 종료 표시되지 않은 프로그램의 예를 제공 ZFC 하나가 매우 큰 추기경 공리를 가정 할 때 종료 않지만.

소개

고전 김 테이블 세트를 기본으로 고유의 유한 대수 있습니다 및 작업 만족 신원 과 에 와 .An{1,...,2n}*x * (y * z)=(x * y) * (x * z)x*1=x+1x<2n2n*1=1

클래식 김 테이블에 대한 자세한 정보는 Patrick Dehornoy의 Braids and Self-Distributivity 책에서 찾을 수 있습니다.

도전

1*32고전적인 Laver 테이블에서 계산 하고 nwith를 찾으면 정확하게 종료 되는 가장 짧은 코드 (바이트)는 무엇입니까 ? 다시 말해, 프로그램은 with를 찾은 경우에만 종료되고 그렇지 않으면 영원히 실행됩니다.1*32<2nn1*32<2n

자극

순위에 랭크 추기경 (또한 I3-추기경라고는) 매우 큰 무한대의 수준 과 하나가 순위에 랭크 추기경의 존재를 가정하면, 다음 하나 하나를하지 않는 경우보다 더 많은 정리를 증명할 수있다 순위 대 추기경의 존재를 가정합니다. 랭크 랭킹 추기경이 있으면 클래식 Laver 테이블 이 있습니다. 그러나 ZFC 에는 알려진 증거가 없습니다 . 또한, 가장 작은 곳 은 Ackermann 함수 가 빠르게 증가하는 함수이므로 매우 큰 숫자 인 것으로 알려져 있습니다. 따라서 그러한 프로그램은 매우 오랫동안 지속됩니다.An1*32<2n1*32<2nn1*32<2nAck(9,Ack(8,Ack(8,254)))Ack

프로그램이 표준 axiomatic 시스템 ZFC를 사용하여 종료되는지 알지 못하지만 프로그램이 결국 더 강한 axiomatic 시스템, 즉 ZFC + I3에서 종료된다는 것을 알 수 있도록 프로그램을 얼마나 짧게 작성할 수 있는지 알고 싶습니다. 이 질문은 Scott Aaronson의 최근 게시물 에서 Aaronson과 Adam Yedidia가 8000 개 이하의 상태로 튜링 머신을 구성하여 ZFC가 튜링 머신이 종료되지 않는다는 것을 증명할 수는 없지만 큰 기본 가설을 가정 할 때 종료되지 않는 것으로 알려져 있습니다.

클래식 김 테이블을 계산하는 방법

김 테이블을 계산할 때 대수에 있다는 사실 사용하는 것이 편리하다 , 우리가 모든 의를 .An2n * x=xxAn

다음 코드는 클래식 Laver 테이블을 계산합니다 An

# table (n, x, y)는 A n 에서 x * y를 반환합니다.
테이블 : = 함수 (n, x, y)
x = 2 ^ n이면 y를 반환합니다.
elif y = 1은 x + 1을 반환합니다.
그렇지 않으면 반환 테이블 (n, table (n, x, y-1), x + 1); fi; 종료;

예를 들어 입력 table(4,1,2)은을 반환 12합니다.

에 대한 코드 table(n,x,y)는 다소 비효율적이며 합리적인 시간 내에 Laver 테이블에서만 계산할 수 있습니다 . 운 좋게도, 기존의 Laver 테이블을 계산하는 알고리즘은 위에 주어진 것보다 훨씬 빠릅니다.A4


2
PPCG에 오신 것을 환영합니다! 좋은 포스트!
NoOneIsHere 여기

1
Wikipedia에 따르면 Ack (9, Ack (8, Ack (8,254)))는 n이 16을 초과하는 하한입니다.이를 위해 1 * 32가 아닌 1 * 16을 확인할 수 있습니다. 이에 따라 프로그램을 수정하겠습니다.
존 트롬 프

1
이 작업을 수행하기 위해 튜링 머신을 작성하기 시작했으며, 요인 별 오류를 발견했다고 생각합니다. Dougherty Ack(9,Ack(8,Ack(8,254)))가 첫 번째 행에 기간이 32 인 첫 번째 테이블의 하한 임을 증명하지 않았습니까 1*16 < 2^n?
피터 테일러

1
Ackermann을위한 20 개 상태의 2 기호 기계를 가지고 있다면, 그 아이디어를 훔칠 수 있기 때문에 링크를주세요. 44 개의 계산 table(n,x,y)상태가 있으며 상수와 외부 루프를 설정하는 데 25 ~ 30 개의 상태가 필요하다고 생각합니다. esolangs.org에서 찾을 수있는 유일한 직접 TM 표현은 esolangs.org/wiki/ScripTur 이며 실제로 그렇게 골프가 아닙니다.
피터 테일러

1
cheddarmonk.org/papers/laver.pdf 는 이번 주에 여행을 계획하기 때문에 이번 주에 예상되는 것입니다.
피터 테일러

답변:


4

이진 람다 미적분, 215 비트 (27 바이트)

\io. let
  zero = \f\x. x;
  one = \x. x;
  two = \f\x. f (f x);
  sixteen = (\x. x x x) two;
  pred = \n\f\x. n (\g\h. h (g f)) (\h. x) (\x. x);
  laver = \mx.
    let laver = \b\a. a (\_. mx (b (laver (pred a))) zero) b
    in laver;
  sweet = sixteen;
  dblp1 = \n\f\x. n f (n f (f x)); -- map n to 2*n+1
  go2 = \mx. laver mx sweet mx (\_. mx) (go2 (dblp1 mx));
in go2 one

컴파일 ( https://github.com/tromp/AIT의 소프트웨어 사용 )

000101000110100000010101010100011010000000010110000101111110011110010111
110111100000010101111100000011001110111100011000100000101100100010110101
00000011100111010100011001011101100000010111101100101111011001110100010

이 솔루션은 주로 https://github.com/int-e 때문입니다.


2
점수를 어떻게 얻었는지 잘 모르겠지만 기본적으로 제출은 코드의 바이트 수에 따라 점수가 매겨 져야합니다. 이 제출물에 대해 375 바이트 를 계산 합니다. 또한 언어 이름과 선택적으로 언어 통역사에 대한 링크를 포함시켜야합니다.
Alex A.

게시물에 길이가 234 비트 인 정확한 코드를 포함해야합니다.
CalculatorFeline

2
인코딩은 Wikipedia 에서 찾을 수 있습니다 . 이 인터프리터에 대한 링크도 있습니다 (테스트되지 않음). 그러나 이것들을 확인하고 바이너리 인코딩도 포스트에 있어야합니다.
PurkkaKoodari

1
컴파일 된 언어의 경우 생성 된 이진의 바이트 수가 아닌 사용자가 작성한 코드의 점수를 매 깁니다.
Alex A.

5
@AlexA. 그것은 필요하지 않습니다 ... 컴파일러 나 인터프리터가 이해할 수있는 모든 형태의 코드는 괜찮습니다.
feersum

4

CJam ( 36 32 바이트)

1{2*31TW$,(+a{0X$j@(@jj}2j)W$=}g

실제로 이것은 호출 스택을 오버플로하기 때문에 매우 빠르게 오류가 발생하지만 이론적으로 무제한 시스템에서는 정확 하며이 질문의 가정임을 이해합니다.

에 대한 코드 table(n,x,y)는 다소 비효율적이며 합리적인 시간에 Laver 테이블 A 4 에서만 계산할 수 있습니다 .

다시 계산하지 않도록 계산 된 값을 캐시하면 실제로 정확하지 않습니다. 그것이 j(memoisation) 연산자를 사용하여 내가 취한 접근법 입니다. 밀리 초 단위로 A 6 을 테스트하고 스택 테스트 A 7을 오버플로합니다. 실제로 골프와 관련하여 최적화되지 않았습니다 table .

해부

n문맥에서 이해 한다고 가정하면

f(x,y) =
    x==2^n ? y :
    y==1 ? x+1 :
    f(f(x,y-1),x+1)

첫 번째 특별한 경우를 제거하고

f(x,y) =
    y==1 ? x+1 :
    f(f(x,y-1),x+1)

그리고 여전히 작동하기 때문에

f(2^n, 1) = 2^n + 1 = 1

및 기타에 대한 y,

f(2^n, y) = f(f(2^n, y-1), 1) = f(2^n, y-1) + 1

유도에 의해 우리는 얻는다 f(2^n, y) = y.

CJam의 경우 매개 변수의 순서를 반대로하는 것이 더 편리합니다. 그리고 범위를 사용하는 대신 각 값을 감소 1 .. 2^n시켜 범위 0 .. 2^n - 1를 사용하고 있으므로 구현하는 재귀 함수는

g(y,x) =
    y==0 ? x+1
         : g(x+1, g(y-1, x))

1           e# Initial value of 2^n
{           e# do-while loop
  2*        e#   Double 2^n (i.e. increment n)
  31T       e#   table(n,1,32) is g(31,0) so push 31 0
  W$,(+a    e#   Set up a lookup table for g(0,x) = x+1 % 2^n
  {         e#   Memoisation function body: stack is 2^n ... y x
    0X$j    e#     Compute g(0,x) = x+1 % 2^n
            e#     Stack is 2^n ... y x (x+1%2^n)
    @(      e#     Bring y to top, decrement (guaranteed not to underflow)
            e#     Stack is 2^n ... x (x+1%2^n) (y-1%2^n)
    @jj     e#     Rotate and apply memoised function twice: g(x+1,g(y-1,x))
  }
  2j        e#   Memoise two-parameter function
            e#   Stack: 2^n g(31,0)
  )W$=      e#   Test whether g(31,0)+1 is 2^n
}g          e# Loop while true

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