Why I Don't Love Gödel, Escher, Bach
311–320 of 348 posts
Re: Why I Don't Love Gödel, Escher, Bach
#312Earlier quoted context omitted.
How would you even express that as a piece of code? I'm not talking about magic blackbox functions.
Seriously? You don't know how to write a function that tests if a number is a prime?
Re: Why I Don't Love Gödel, Escher, Bach
#313Earlier quoted context omitted.
you're right, my phrasing wasn't ideal there. I'll try to clarify: what I want to do is to create a static analyser based on a set of axioms/deductions that can determine which of the "always halts/does not always halt/don't know" categories a program fits into. (I'm rephrasing the categories because a program like "(x: int) => x == 1 ? halt : loop" fits into the second category). What I'm wanting to figure out is th…
> you could clearly change "x is even" to any "x is wholly divisible by " The tricky thing is that it's not clear, since it depends entirely upon the formal system you're using! As a simple example, let's say I have the following Java program: if (2 This program will halt, but what if we change it? We "could clearly change" the `3` to a `1` and the resulting program would not halt. What if we changed the `3` to `"hel…
- collatz(x: 1) => halt
- collatz(x: int where x > 0 && x % 2 = 0) => collatz(x / 2)
- collatz(x: int where x > 0 && x % 2 = 1) => collatz(x * 3 + 1)
I figure that if I extract out recursion like this (as recursion seems to be the only thing that makes a computation potentially undecidable) and bubble the branching up to the signature as a form of pattern matching, then the signature becomes something you could potentially use to figure out if it is decidable. The issue I'm stuck on is what approach to take to build a deduction system for calculating whether continuing such a sequence from any value in the allowed input space would halt - obviously at this point in time the collatz conjecture is an open question but we can also construct functions using the same notation that we can intuitively determine will either always halt or only sometimes halt, so there is surely room for the existence of such a deductive system. I just don't want to spend a year learning about e.g. category theory or natural deductive logic just to find out that this problem cannot be effectively expressed in such a system.
Re: Why I Don't Love Gödel, Escher, Bach
#314Earlier quoted context omitted.
I find the latter to be too tedious usually. If they don't at least start out as the former then the latter will never be finished by me. I think that those two kinds are poles of a spectrum and I believe there is a falloff point not too far past the middle that I find acceptable. I think it is interesting you say the one end is incredible but the other end is "still great". Does that mean you enjoy them less?
> Does that mean you enjoy them less? Enjoyment is not the point. I am a different person because of reading GEB, and my coding style changed because of reading On Lisp. With internalisation and comprehension, the first kind of book will change the way that you think forever. This kind of book is going to be a boring if you are unable understand the concepts that it is trying to communicate. If these concepts are goi…
Re: Why I Don't Love Gödel, Escher, Bach
#315Earlier quoted context omitted.
If you think I'm trying to discover something then you've completely missed my point. I was never looking to discover some new concept, but to find an existing model of looking at computability and implement it as software. I know its possible to decide computability for at least some subset of programs because we can do it by eye, I'm just looking to do the same thing programmatically in a way that is theoretically…
Yes, I understand that. And what I'm trying to tell you is that this problem you have set for yourself is formally equivalent to the problem proving mathematical theorems. They are the same problem . Any substantial progress on one is necessarily also substantial progress on the other.
Re: Why I Don't Love Gödel, Escher, Bach
#316Earlier quoted context omitted.
The internet says Hofstadter was born in 1945 and GED was published in 1979. ~34 years later?
Sounds about right? What's your point? If you're trying to extrapolate his age from the publishing, someone below corrected me. He was 27 when he wrote it. A few years between writing and publishing the first edition lines up.
Re: Why I Don't Love Gödel, Escher, Bach
#317Earlier quoted context omitted.
Yes, I understand that. And what I'm trying to tell you is that this problem you have set for yourself is formally equivalent to the problem proving mathematical theorems. They are the same problem . Any substantial progress on one is necessarily also substantial progress on the other.
not quite - I'm trying to implement existing proofs into an axiomatic system. All unproven theorems can be classified as the "don't know" outcome. But I don't know what approach to use to implement a system that can look at "f(x: int) => x is cleanly divisible by 2 ? f(x + 1) : halt" and tell me that this recursive function all halt under all valid inputs. Because that would require that it be able to derive such a f…
Yes, and that's the part that's not possible in general, only for specific cases. For example, you can prove that:
f(P: int -> boolean, x: int) => P(x) ? f(x + 1) : halt
will halt for any x IFF there are an infinite number of integers that have the property P, so f will halt if P is "is an even integer" because there are an infinite number of even integers (which, obviously, you can also prove).
And with that in mind, you might want to go take another look at:
Re: Why I Don't Love Gödel, Escher, Bach
#318Earlier quoted context omitted.
> you could clearly change "x is even" to any "x is wholly divisible by " The tricky thing is that it's not clear, since it depends entirely upon the formal system you're using! As a simple example, let's say I have the following Java program: if (2 This program will halt, but what if we change it? We "could clearly change" the `3` to a `1` and the resulting program would not halt. What if we changed the `3` to `"hel…
a dependent typing engine is exactly how I was thinking of representing this - i.e "x: int => x + 1" would have a type signature of "x: int => x + 1". Further compositions would stack. If I e.g. converted the Collatz conjecture to a function I would get the following signatures: - collatz(x: 1) => halt - collatz(x: int where x > 0 && x % 2 = 0) => collatz(x / 2) - collatz(x: int where x > 0 && x % 2 = 1) => collatz(x…
loop = loop
What is the type of `loop`? We can infer it by starting with a completely generic type variable, e.g. `forall t. t`: loop : forall t. t
loop = loop
Then we can look at the type of the body to see which constraints it must satisfy, and perform unification with that and the `t` we have so far. In this case the body is `loop` which has type `forall t. t` (i.e. which is completely unconstrained). Unifying `forall t. t` with `forall t. t` gives (unsurprisingly) `forall t. t`. Hence that is the type of `loop`. Yet this claims to hold for all types `t`, which must include empty types like `Empty`, which should have no values! data Empty where
-- This page intentionally left blank
loop : forall t. t
loop = loop
myEmptyValue : Empty
myEmptyValue = loop
In particular, this lets us "prove" (in an invalid way) things like the Collatz conjecture. Here's a quick definition of the Collatz sequence, in Agda/Idris notation (untested): -- Peano arithmetic
data Natural where
Zero : Natural
Succ : Natural -> Natural
one = Succ Zero
halve : Natural -> Natural
halve Zero = Zero
halve (Succ Zero) = Succ Zero -- Should never reach this; included for completeness
halve (Succ (Succ n)) = Succ (halve n)
threeTimes : Natural -> Natural
threeTimes Zero = Zero
threeTimes (Succ n) = Succ (Succ (Succ (threeTimes n)))
data Boolean where
True : Boolean
False : Boolean
not : Boolean -> Boolean
not True = False
not False = True
ifThenElseNat : Boolean -> Natural -> Natural -> Natural
ifThenElseNat True x y = x
ifThenElseNat False x y = y
isEven : Natural -> Boolean
isEven Zero = True
isEven (Succ n) = not (isEven n)
collatzStep : Natural -> Natural
collatzStep Zero = one -- Again, only for completeness
collatzStep (Succ n) = ifThenElseNat (isEven (Succ n))
(halve (Succ n))
(Succ (threeTimes (Succ n)))
-- This won't be allowed by Agda/Idris since it may or may not halt ;)
collatzLoop : Natual -> Natural
collatzLoop Zero = collatzLoop (collatzStep Zero) -- For completeness
collatzLoop (Succ Zero) = Succ Zero -- Halt
collatzLoop (Succ (Succ n)) = collatzLoop (collatzStep (Succ (Succ n)))
We can then define the Collatz conjecture, using a standard encoding of equality: data Equal : Natural -> Natural -> Type where
reflexivity : (n : Natural) -> Equal n n
CollatzConjecture : Type
CollatzConjecture = (n : Natural) -> Equal (collatzLoop n) one
proofOfCollatzConjecture : CollatzConjecture
proofOfCollatzConjecture = ?
disproofOfCollatzConjecture : CollatzConjecture -> Empty
disproofOfCollatzConjecture purportedProof = ?
The disproof basicallys says "if you give me a proof of `CollatzConjecture`, I can give you a value which doesn't exist"; since that's absurd, the only way it can hold is if there are no proofs of `CollatzConjecture` to give it (this is a form of proof by contradiction: give me a supposed proof, and I'll show you why it must be wrong).The problem with allowing non-terminating recursion is that we can use `loop` to fill in either of these proofs, or even both of them!
proofOfCollatzConjecture : CollatzConjecture
proofOfCollatzConjecture = loop
disproofOfCollatzConjecture : CollatzConjecture -> Empty
disproofOfCollatzConjecture purportedProof = loop
The type of `loop` is `forall t. t`, which can unify with either of these types, so the language/logic will allow us to use it in these definitions (or anywhere else, for that matter).For this reason, we have to make sure our language isn't Turing-complete, which we can do using a "totality checker" (a static analyser which checks if our definitions halt: if they definitely do, they're permitted; if they don't or we can't tell, they're forbidden). That stops us from writing things like `loop`, but unfortunately it stops us from writing `collatzLoop` as well.
One way to get around this is to use "corecursion". This lets an infinite loop pass the totality checker, as long as it's definitely producing output data as it goes (e.g. like a stream which is forbidden from getting "stuck"). We can use this to make a `Delayed` type, which is just a stream of dummy data which might or might not end (a polymorphic version of this is described in more detail at http://chriswarbo.net/blog/2014-12-04-Nat_like_types.html ):
data Delayed : Type where
Now : Natural -> Delayed
Later : Delayed -> Delayed
collatzLoop : Natural -> Delayed
collatzLoop Zero = Later (collatzLoop (collatzStep Zero)) -- For completeness
collatzLoop (Succ Zero) = Now (Succ Zero) -- Halt
collatzLoop (Succ (Succ n)) = Later (collatzLoop (collatzStep (Succ (Succ n))))
This will pass the totality checker since each step is guaranteed to produce some data (either the `Now` symbol or the `Later` symbol); even though the contents of a `Later` value may be infinite! If we run this version of `collatzLoop` on, say, 6 (ignoring the `Zero`/`Succ` notation for brevity), we get: collatzLoop 6
Later (collatzLoop 3)
Later (Later (collatzLoop 10))
Later (Later (Later (collatzLoop 5)))
Later (Later (Later (Later (collatzLoop 16))))
Later (Later (Later (Later (Later (collatzLoop 8)))))
Later (Later (Later (Later (Later (Later (collatzLoop 4))))))
Later (Later (Later (Later (Later (Later (Later (collatzLoop 2)))))))
Later (Later (Later (Later (Later (Later (Later (Later (collatzLoop 1))))))))
Later (Later (Later (Later (Later (Later (Later (Later (Now 1))))))))
We can rephrase the Collatz conjecture as saying that the return value of `collatzLoop` will always, eventually, end with `Now one`. This is an existence proof: there exists an `n : Natural` such that after `n` layers of `Later` wrappers there will be a `Now one` value. Since we're dealing with constructive logic, to prove this existence we must construct the number `n` (e.g. using some function, which I'll call `boundFinder`): unwrap : Natural -> Delayed -> Delayed
wrap Zero x = x
wrap (Succ n) (Now y) = Now y
wrap (Succ n) (Later y) = unwrap n y
data DelayEqual : Delayed -> Delayed -> Type where
delayedReflexivity : (d : Delayed) -> DelayEqual d d
-- The notation `(x : y *** z)` is a dependent pair, where the first element has
-- type `y` and the second element has type `z` which may refer to the first
-- value as `x`
CollatzConjecture : Type
CollatzConjecture = (boundFinder : Natural -> Natural ***
(n : Natural) -> DelayEqual (unwrap (boundFinder n) (collatzLoop n)) (Now one))
proofOfCollatzConjecture : CollatzConjecture
proofOfCollatzConjecture = ?
disproofOfCollatzConjecture : CollatzConjecture -> Empty
disproofOfCollatzConjecture (boundFinder, purportedProof) = ?
With this definition, a value of type `CollatzConjecture` will be a proof of the Collatz conjecture. Since we can't use tricks like `loop`, we're forced to actually construct a value of the required type. This value will be a pair: the first element of the pair is a function of type `Natural -> Natural`, which we call `boundFinder`. The second element of the pair is also a function, but it has type: (n : Natural) -> DelayEqual (unwrap (boundFinder n) (collatzLoop n)) (Now one))
This says that given any `n : Natural`, we can return a proof that: DelayEqual (unwrap (boundFinder n) (collatzLoop n)) (Now one))
This says that `unwrap (boundFinder n) (collatzLoop n)`, i.e. removing `boundFinder n` layers of `Later` wrappers from `collatzLoop n`, is equal to the value `Now one`.To disprove this form of the Collatz conjecture, we're given a supposed proof: i.e. we're given some `boundFinder` function and a value supposedly proving the equation described above. We need to find a contradiction to that supposed proof, which might be an `n : Natural` which reduces to `Now x` where `x` is not 1; or which we can show doesn't reduce at all. Either way this would contradict the claim made by `purportedProof`, and we could use that contradiction to prove anything ("ex falso quodlibet") including the `Empty` return value we need (just as if we had `loop`!).
The thing is, even if we set up all of this machinery, there is an unfortunate fact staring us in the face: compare the definition of `Natural` to the definition of `Delayed`. They're almost identical! The only difference is that `Now` takes an argument but `Zero` doesn't. If we think about what `Succ` is doing, it's just adding a wrapper around a `Natural` to represent "one more than" (e.g. `Succ Zero` is 1, `Succ (Succ Zero)` is 2, etc.). If we think about what `Later` is doing, it's just adding a wrapper around a `Delayed` to represent "one more step". In essence we've just traded one form of counting for another! It doesn't actually get us any closer to solving the Collatz conjecture, other than giving us something to plug a proof attempt into, such that it will be verified automatically. It's like setting up a Wordpress blog: it lets us say anything we like to the world, but doesn't help us figure what we want to say ;)
Re: Why I Don't Love Gödel, Escher, Bach
#319Though interestingly the beginning of the discussion of 'Zen': > This might seem unfair, so I’ll give a very specific but pervasive instance of this sort of meaningless flavor. Many parts of the book invoke Zen, which is a school of Buddhism that originated in China and has spread to several other Asian countries but, in the Western mind, is usually associated with Japan. (We do, after all, know this school by its Ja…
> seems to miss the fact that Buddhism originated in India and that not only the Japanese word Zen but also Chinese Chán are adaptations of the Sanskrit dhān(a) (meaning originally something like 'concentration' or 'contemplation'). Etymologically this is true, but in the sense of tradition, India doesn't really have a Zen tradition, it really did originate in China. Dhyāna is much more broad and not only part of Bud…
India certainly has meditative/yogic practices and it seems unlikely to me that some bits of these wouldn't have travelled from India to China along with Buddhism and Sanskritic vocabulary.
Re: Why I Don't Love Gödel, Escher, Bach
#320Earlier quoted context omitted.
> Metamagical Themes It's Metamagica Themas, I think - an anagram of 'Mathematical Games'; the Martin Gardner's column in Scientific American which proceeded it. A lovely book.
> Metamagica Themas Metamagical Themas (You left out the L.)