Gödel Numbering
January 16, 2015
We begin by hard-coding a list of prime numbers:
(define primes (list 2 3 5 7 11 13 17 19 23 29
31 37 41 43 47 53 59 61 67 71 73 79 83 89 97))
Then the function that converts a string to a Gödel number iterates over the characters of the string, accumulating the product as it goes:
(define (godel str)
(let loop ((cs (string->list str)) (ps primes) (g 1))
(if (null? cs) g
(loop (cdr cs) (cdr ps)
(* g (expt (car ps) (- (char->integer
(char-upcase (car cs))) 64)))))))
> (godel "praxis")
83838469305478699942290773046821079668485703984645720358854000640
Reversing the process is only a little bit more complicated; there are three legs to the conditional, instead of two, and a new variable to count the number of factors in the exponent:
(define (ungodel num)
(let loop ((cs (list)) (ps primes) (g num) (cnt 64))
(cond ((= g 1)
(list->string (reverse (cons (integer->char cnt) cs))))
((zero? (modulo g (car ps)))
(loop cs ps (/ g (car ps)) (+ cnt 1)))
(else (loop (cons (integer->char cnt) cs) (cdr ps) g 64)))))
> (ungodel (godel "praxis"))
"PRAXIS"
You can run the program at http://programmingpraxis.codepad.org/jakEOZPF. There’s more to Gödel numbering that we have shown here; Wikipedia is a good place to start further study.
Haskell:
Python:
Factor:
: >gödel ( str — n )
[ length nprimes ] keep [ 64 – ^ ] 2map product ;
: gödel> ( n — str )
group-factors values [ 64 + ] "" map-as ;
Implemented as a Python class that takes a sequence of symbols as a configuration parameter.
Example:
Also in Haskell, and similar to Francesco’s solution. This one uses the arithmoi package for the list of primes and the factorization function. I don’t shift the powers, so the resulting numbers are even larger.