Laver table computations and an algorithm that is not known to terminate in ZFC

12

5

The Laver tables provide examples of programs which have not been shown to terminate in the standard axiomatic system of mathematics ZFC but which do terminate when one assumes very large cardinal axioms.

Introduction

The classical Laver tables An are the unique finite algebras with underlying set {1,...,2n} and an operation * that satisfies the identity x * (y * z)=(x * y) * (x * z) and where x*1=x+1 for x<2n and where 2n*1=1.

More information about the classical Laver tables can be found in the book Braids and Self-Distributivity by Patrick Dehornoy.

Challenge

What is the shortest code (in bytes) that calculates 1*32 in the classical Laver tables and terminates precisely when it finds an n with 1*32<2n? In other words, the program terminates if and only if it finds an n with 1*32<2n but otherwise it runs forever.

Motivation

A rank-into-rank cardinal (also called an I3-cardinal) is an extremely large level of infinity and if one assumes the existence of a rank-into-rank cardinal, then one is able to prove more theorems than if one does not assume the existence of a rank-into-rank cardinal. If there exists a rank-into-rank cardinal, then there is some classical Laver table An where 1*32<2n. However, there is no known proof that 1*32<2n in ZFC. Furthermore, it is known that the least n where 1*32<2n is greater than Ack(9,Ack(8,Ack(8,254)))(which is an extremely large number since the Ackermann function Ack is a fast growing function). Therefore, any such program will last for an extremely long amount of time.

I want to see how short of a program can be written so that we do not know if the program terminates using the standard axiomatic system ZFC but where we do know that the program eventually terminates in a much stronger axiomatic system, namely ZFC+I3. This question was inspired by Scott Aaronson's recent post in which Aaronson and Adam Yedidia have constructed a Turing machine with under 8000 states such that ZFC cannot prove that the Turing machine does not terminate but is known not to terminate when one assumes large cardinal hypotheses.

How the classical Laver tables are computed

When computing Laver tables it is usually convenient to use the fact that in the algebra An, we have 2n * x=x for all x in An.

The following code calculates the classical Laver table An

# table(n,x,y) returns x*y in An
table:=function(n,x,y)
if x=2^n then return y;
elif y=1 then return x+1;
else return table(n,table(n,x,y-1),x+1); fi; end;

For example, the input table(4,1,2) will return 12.

The code for table(n,x,y) is rather inefficient and it can only compute in the Laver table A4 in a reasonable amount of time. Fortunately, there are much faster algorithms for computing the classical Laver tables than the ones given above.

Joseph Van Name

Posted 2016-05-08T23:36:50.657

Reputation: 1

2Welcome to PPCG! Great post! – NoOneIsHere – 2016-05-09T02:56:59.150

1According to Wikipedia, Ack(9,Ack(8,Ack(8,254))) is a lower bound on n for which the period exceeds 16. For that, we can check 116 rather than 132. I will amend my program accordingly. – John Tromp – 2016-05-10T20:59:32.060

John Tromp. Thanks for pointing that out. I now realize that I made that typo and wrote 132<2^n instead of 116<2^n in the question . Nevertheless, the question still makes sense whether one uses 16 or 32 (or even 64), and an answer where one uses 32 would be just as theoretically interesting for me as an answer where one uses 16. – Joseph Van Name – 2016-05-11T06:02:13.260

Is this question inspired by http://www.scottaaronson.com/blog/?p=2741 ?

– None – 2016-05-11T09:48:12.570

Lembik. Yes. The question was inspired by Scott Aaronson's blog post p=2725. – Joseph Van Name – 2016-05-11T16:59:51.763

1I've started writing up a Turing machine to do this, and I think I've spotted an out-by-factor-of-two error. Didn't Dougherty prove that Ack(9,Ack(8,Ack(8,254))) is a lower bound for the first table in which the first row has period 32, i.e. where 1*16 < 2^n? – Peter Taylor – 2016-05-26T22:36:32.650

Peter Taylor. Yes. You are correct. I made a typo, and I should have written 116<2^n instead of 132<2^n. Such a Turing machine sounds very interesting. I conjecture that such a Turing machine will be about as easy to describe as a Turing machine for the Ackermann function, so I conjecture that one could use around 20-something states and two symbols to construct a Turing machine that terminates if and only if 1*32<2^n in the n-th classical Laver table for some n. – Joseph Van Name – 2016-05-27T21:44:01.437

@Peter Taylor. Also, is there known golfing language for Turing machines? If so, then a Turing machine could be compared with the answers given here already (and such a golfing language should be easy to describe). Let me know when you have constructed such a Turing machine. – Joseph Van Name – 2016-05-27T21:57:31.347

1

If you have a 20-state 2-symbol machine for Ackermann then please give me a link, because I can probably steal some ideas from it. I have 44 states to compute table(n,x,y), and I think it'll take between 25 and 30 states to set up the constants and the outer loop. The only direct TM representation I can find on esolangs.org is http://esolangs.org/wiki/ScripTur and it's not really that golfy.

– Peter Taylor – 2016-05-27T22:09:15.757

At googology, a 23 state 2-symbol Turing machine that runs for longer than Graham's number steps before terminating has been constructed. In fact, there they have a 13 state Turing machine that exhibits Ackermann growth.

– Joseph Van Name – 2016-05-27T23:16:03.857

Should I ask another question asking for a Turing machine that runs as long as 1*16=2^n but halts otherwise (I am new to this site) or are both questions too similar? – Joseph Van Name – 2016-05-27T23:21:40.123

Also, if anyone is interested, a Turing machine for computing the classical Laver tables can probably be slightly modified to a Turing machine that computes certain generalized Laver tables simply by adding more symbols to the Turing machine.

– Joseph Van Name – 2016-05-27T23:38:29.223

If A is a set, then the underlying set of the generalized Laver table (A^(2^n))^+ is the set of non-empty strings over the alphabet A of length at most 2^n and is given a unique self-distributive operation such that x*y=y whenever |x|=2^n and where y*a=ya whenever |y|<2^n and |a|=1. In other words, the generalized Laver table (A^(2^n))^+ is like the classical Laver table A_n but where we work with non-empty strings of length less than 2^n instead of natural numbers at most 2^n. – Joseph Van Name – 2016-05-27T23:41:04.473

1http://cheddarmonk.org/papers/laver.pdf is as much as I expect to get done this week, because I'm going to be travelling. – Peter Taylor – 2016-05-31T21:51:17.023

Answers

4

Binary Lambda Calculus, 215 bits (27 bytes)

\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

compiles to (using software at https://github.com/tromp/AIT)

000101000110100000010101010100011010000000010110000101111110011110010111
110111100000010101111100000011001110111100011000100000101100100010110101
00000011100111010100011001011101100000010111101100101111011001110100010

This solution is mostly due to https://github.com/int-e

John Tromp

Posted 2016-05-08T23:36:50.657

Reputation: 957

2

I'm not sure how you got your score but by default submissions should be scored according to the number of bytes in the code. I count 375 bytes for this submission. You should also include the language name and optionally a link to an interpreter for the language.

– Alex A. – 2016-05-09T02:42:05.590

You should probably include the exact code of length 234 bits in your post. – CalculatorFeline – 2016-05-09T04:32:03.990

2

The encoding can be found on Wikipedia. There's also a link to this interpreter (not tested). These should be checked, though, and the binary encoding should also be in the post.

– PurkkaKoodari – 2016-05-09T05:46:12.857

1For compiled languages, we score the code written by the user--not the number of bytes in the generated binary. – Alex A. – 2016-05-09T20:31:55.350

5@AlexA. That's not necessary... any form of the code that can be understood by a compiler or interpreter is fine. – feersum – 2016-05-10T03:57:59.193

4

CJam (36 32 bytes)

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

In practice, this errors out quite quickly because it overflows the call stack, but on a theoretical unlimited machine it is correct, and I understand that to be the assumption of this question.

The code for table(n,x,y) is rather inefficient and it can only compute in the Laver table A4 in a reasonable amount of time.

is not actually correct if we cache computed values to avoid recomputing them. That's the approach I've taken, using the j (memoisation) operator. It tests A6 in milliseconds and overflows the stack testing A7 - and I've actually deoptimised table in the interests of golfing.

Dissection

If we assume that n is understood from the context, instead of

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

we can remove the first special case, giving

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

and it still works because

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

and for any other y,

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

so by induction we get f(2^n, y) = y.

For CJam it turns out to be more convenient to reverse the order of the parameters. And rather than using the range 1 .. 2^n I'm using the range 0 .. 2^n - 1 by decrementing each value, so the recursive function I'm implementing is

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

Peter Taylor

Posted 2016-05-08T23:36:50.657

Reputation: 41 901

1

Pyth, 33 bytes

.N?qT^2NY?tY:N:NTtYhThT<:T1 32^2T

Try it online! (Obviously the testing part is not included here.)

Leaky Nun

Posted 2016-05-08T23:36:50.657

Reputation: 45 011

What loop? Also, what does fi in the code mean? – Leaky Nun – 2016-05-10T02:57:09.637