chriswarbo-net: 8a4bc36d3c3dad23e084e6f1fcf93c8308202e05
1: ---
2: title: Boltzmann RAM
3: packages: [ 'mathml' ]
4: ---
5:
6: Simulating every computable universe (the constructivist/intuitionistic version
7: of Tegmark's level 4) is actually remarkably easy. Each of those universes can
8: be simulated by running some computer program (by definition of constrictivism),
9: so we can simulate all of them by "just" running every possible computer
10: program!
11:
12: ## A simple existence proof ##
13:
14: There's actually a *single*, very simple, program which will simulate all
15: others, by [diagonalising](https://en.wikipedia.org/wiki/Diagonal_argument) over
16: the program lengths and running times:
17:
18: - Run all programs of length `1`{.unwrap pipe="num | math"} (i.e. programs
19: `0` and `1`) for `1`{.unwrap pipe="num | math"} step each.
20: - Re-run all programs of length `1`{.unwrap pipe="num | math"}, this time for
21: `2`{.unwrap pipe="num | math"} steps. Then run programs of length
22: `2`{.unwrap pipe="num | math"} (`00`, `01`, `10` and `11`) for
23: `1`{.unwrap pipe="num | math"} step each.
24: - Re-run programs of length `1`{.unwrap pipe="num | math"} for
25: `3`{.unwrap pipe="num | math"} steps; programs of length
26: `2`{.unwrap pipe="num | math"} for `2`{.unwrap pipe="num | math"} steps; and
27: run all programs of length `3`{.unwrap pipe="num | math"} (`000`, `001`,
28: `010`, etc.) for `1`{.unwrap pipe="num | math"} step each.
29: - Keep going in this manner forever: each time re-running all previous programs
30: for an extra step, then running all one-bit-longer programs for
31: `1`{.unwrap pipe="num | math"} step.
32:
33: If we wait long enough, this loop will eventually run *any* program for *any*
34: number of steps: including simulations of our universe being run for long enough
35: to reach the present day!
36:
37: ## A remarkable linear-time solution ##
38:
39: The above algorithm is exponentially slow: each iteration runs twice as many
40: programs as the last (since there are
41: `num '2'; var 'l';`{.unwrap pipe="sh | mapply power | math"} programs of length
42: `l`{.unwrap pipe="var | math"}), so reaching step
43: `var 'n'; num '1'`{.unwrap pipe="sh | add | math"} of any program will take at
44: least twice as long as reaching step `n`{.unwrap pipe="var | math"}. That's
45: *a lot* of overhead, which will soon grind everything to a crawl, and makes this
46: whole endeavour seem far-fetched.
47:
48: However,
49: [Schmidhuber suggests](http://people.idsia.ch/~juergen/computeruniverse.html) we
50: can avoid this in two ways:
51:
52: - Firstly we can 'spread out' the programs by writing them in a
53: [prefix-free code](https://en.wikipedia.org/wiki/Prefix_code). This requires
54: more bits to encode our programs, reducing the number of programs of each
55: length; i.e. there are *fewer than*
56: `num '2'; var 'l';`{.unwrap pipe="sh | mapply power | math"} programs of
57: length `l`{.unwrap pipe="var | math"} when encoded in a prefix-free way.
58: - Then, instead of re-running with an extra step each time, we instead re-run
59: with *double* the number of steps, i.e. running for
60: `1`{.unwrap pipe="num | math"} step, then `2`{.unwrap pipe="num | math"}
61: steps, then `4`{.unwrap pipe="num | math"} steps, then
62: `8`{.unwrap pipe="num | math"} steps, etc.
63:
64: This doubling has an interesting effect: the original algorithm took twice as
65: long to reach step `var 'n'; num '1'`{.unwrap pipe="sh | add | math"} as to
66: reach step `n`{.unwrap pipe="var | math"}; yet this algorithm can reach step
67: `num '2'; var 'n'`{.unwrap pipe="sh | mult | math"}: that's *linear time*! In
68: other words, nothing will slow down over time: it's as if we were running each
69: program on a dedicated computer, yet we're actually running *all* programs on a
70: *single* machine!
71:
72: ```{pipe="sh > runtime.mml"}
73: {
74: num '1'
75: { num '2'; var 'l'; } | mapply 'power'
76: } | mapply 'divide'
77: ```
78:
79: The reason this works is that our changes (prefix-free encoding and
80: exponentially-distributed running times) cause the allocation of runtime between
81: programs to obey the [Kraft
82: inequality](https://en.wikipedia.org/wiki/Kraft%E2%80%93McMillan_inequality).
83: Each program gets a *constant fraction* of our runtime (equivalent to running
84: on a dedicated, albeit slower, machine). The downside is those fractions get
85: *very* small for larger programs: those of length `1`{.unwrap pipe="num | math"}
86: will get `num '1'; num '2';`{.unwrap pipe="sh | mapply divide | math"} the
87: runtime, programs of length `2`{.unwrap pipe="num | math"} will get
88: `num '1'; num '4';`{.unwrap pipe="sh | mapply divide | math"} of the runtime,
89: and in general programs of length `l`{.unwrap pipe="var | math"} will get
90: `cat runtime.mml`{.unwrap pipe="sh | math"} of the runtime. The use of a
91: prefix-free code ensures that there are few-enough programs of each length to
92: avoid these fractions adding up to more than `1`{.unwrap pipe="num | math"}.
93:
94: ```{pipe="sh > 10.mml"}
95: {
96: {
97: num '1'
98: { num '2'; num '10'; } | mapply 'power'
99: } | mapply 'divide'
100: { num '1'; num '1024'; } | mapply 'divide'
101: } | mapply 'eq'
102: ```
103:
104: ```{pipe="sh > sum.mml"}
105: {
106: {
107: num '1'
108: num '2'
109: num '4'
110: num '8'
111: num '16'
112: num '32'
113: num '64'
114: } | add
115: num '127'
116: } | mapply 'eq'
117: ```
118:
119: Finally, the *overall speed* of each program is only half of its allocated
120: runtime, so a program of (prefix-free encoded) length
121: `10`{.unwrap pipe="num | math"} will get
122: `cat 10.mml`{.unwrap pipe="sh | math"} of the runtime, but only run at
123: `num '1'; num '2048';`{.unwrap pipe="sh | mapply divide | math"} of its normal
124: speed. The reason is that we keep restarting everything. As an example, for a
125: program to reach step `100`{.unwrap pipe="num | math"} of its execution it must
126: be restarted many times, which wastes some of its allocated runtime: first it
127: wastes `1`{.unwrap pipe="num | math"} step, then is later restarted and run for
128: `2`{.unwrap pipe="num | math"} steps (making `3`{.unwrap pipe="num | math"}
129: wasted steps so far); then `4`{.unwrap pipe="num | math"} steps
130: (`7`{.unwrap pipe="num | math"} wasted so far); and so on. *Eventually* it will
131: be run for `128`{.unwrap pipe="num | math"} steps, which is enough for it to
132: reach step `100`{.unwrap pipe="num | math"} that we wanted. At that point it's
133: wasted `cat sum.mml`{.unwrap pipe="sh | math"} steps; and in general, when we
134: re-run a program for `S`{.unwrap pipe="var | math"} steps, it means we've
135: already wasted (one fewer than) `S`{.unwrap pipe="var | math"} steps on it so
136: far. Since we're thus spending (just less than) twice as many steps to reach
137: each point of a program's execution, this restarting is hence causing every
138: program to run at around half the speed it otherwise would.
139:
140: Whilst these linear slowdowns of each program are exponential in their length;
141: they are nevertheless *constant over time*. Hence if we start this program
142: running, it will (gradually) spin-up a simulation of every possible universe
143: simultaneously (albeit most will be running at an extremely slow rate).
144:
145: ## Implications ##
146:
147: The "simulation hypothesis" has recently entered popular culture as a serious
148: idea (building on previous, more fanciful incarnations like The Matrix). It asks
149: whether our Universe was *purposefully created* as a simulation, inside and of
150: some other "host" Universe (perhaps to investigate historical or counterfactual
151: scenarios). That's a nice philosophical idea, akin to thought experiments like
152: the classic [brain in a jar](https://en.wikipedia.org/wiki/Brain_in_a_vat), but
153: hence just as self-defeating: they are predicated on our inability to discern
154: the difference between their postulated worlds, so they therefore make no
155: discernable difference to anything either way!
156:
157: In contrast, any simulations run by the above algorithms are *not* purposeful:
158: if run for long enough, they *will* simulate our Universe, and countless others;
159: not because we were specially chosen, but precisely because we are *not*
160: fundamentally different from any other computer program! Since there's no
161: postulated "host", to [select and manipulate the
162: rules](https://en.wikipedia.org/wiki/Omphalos_hypothesis), we can treat this
163: setup in a scientific way; more akin to a
164: [Boltzmann brain](https://en.wikipedia.org/wiki/Boltzmann_brain).
165:
166: The idea of a Boltzmann brain is that random movements in some collection of
167: matter, like a gas cloud, may *occasionally* bring their constituent parts
168: together in a way which is
169: [capable of thought](https://en.wikipedia.org/wiki/Cogito,_ergo_sum). The usual
170: argument against this as an explanation for our observations is that
171: smaller arrangements of matter are exponentially more likely to occur by chance
172: than larger arrangements. Hence, if we were such a Boltzmann brain, we would
173: expect to see very little structure or order around us; yet we observe a vast
174: Universe filled with structure.
175:
176: (Of course, such "observations" might have simply appeared, by pure coincidence,
177: as "memories" inside a randomly assembled Boltzmann brain which *thinks* it's
178: observed a structured Universe; and this line of reasoning can never be
179: completely disproved. However, the further we travel down that road, the closer
180: we get to those unfalsifiable-by-definition ideas like the simulation hypothesis
181: and the brain in a jar; and hence the easier it becomes to dismiss that whole
182: direction as empirically irrelevant!)
183:
184: ### Boltzmann RAM ###
185:
186: Rather than applying the Boltzmann brain idea to the structure that
187: *constitutes* us, we can instead apply it to a structure that *computes* us; for
188: example, by flipping random bits on a Turing machine tape. Again, it's unlikely
189: that an algorithm will arise by chance for simulating precisely us, or our
190: Universe, due to how complex it is to describe: it's exponentially more likely
191: for smaller, simpler programs to arise.
192:
193: However, we've seen above that there are small, simple programs that *do*
194: simulate our Universe (albeit not *precisely*, since they also run *every other*
195: Universe alongside). Such programs may well arise by chance, given a
196: reasonable number of bit flips. In that case, we need to ask how likely our
197: observations about the Universe would be, if there were so many simulations
198: running at once. Since "disorder" takes more bits to encode, and the above
199: algorithms allocate less runtime to longer programs, we would expect most minds
200: to observe an ordered, structured Universe (so long as there's *enough*
201: complexity for such minds to arise at all)!
202:
203: ## Conclusion ##
204:
205: Note that this hypothesis does not postulate some 'higher level' Universe that
206: runs the computation of ours; it could instead be the case that such computation
207: is just the underlying nature of reality. As an analogy, General Relativity
208: assumes curved spacetime is the underlying nature of reality, that's why Earth
209: orbits the Sun, and the motion can be calculated using tensor algebra. Yet that
210: *does not* imply there must be some intelligent beings performing those
211: calculations in order for the motion to occur: it just happens, all on its own.
212: Likewise, it may be the case that computations "just happen", and we can use
213: complexity arguments to make falsifiable predictions about what's more or less
214: likely to happen.
215:
216: To his credit, Schmidhuber followed this line of reasoning to arrive at a
217: prediction that large-scale quantum computation will not be possible: precisely
218: because the computational effort required to describe that behaviour would make
219: Universes containing them very unlikely, compared to Universes which constrain
220: quantum effects to more easily-calculated realms (perhaps taking shortcuts to
221: arrive at classical solutions on the macro-scale). Whilst I doubt that will be
222: the case, it's certainly a novel perspective on cosmology; and yet another
223: justification for trying to scale up our quantum computers!
Generated by git2html.