18

Deriving a Quine in a Lisp

 4 years ago
source link: https://bor0.wordpress.com/2020/04/24/deriving-a-quine-in-a-lisp/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

As with myprevious post, this post is another excerpt that will be included in my final Master’s thesis, but I decided it is interesting enough to post it on its own.

We start with a definition of diagonalization (or quotation), as discussed in The Gödelian Puzzle Book :

Definition 1: For an expression URNVZza.png!web in which a variable occurs, we say that its diagonalization raiUbaY.png!web is the substitution of the variable with the quoted expression 6RzeMbM.png!web .

This definition allows us to represent self-referential expressions.

For example, let qYnI7zm.png!web . Then, the diagonalization of it will be zInIjmf.png!web . In Lisp code:

> (define p (lambda (x) (list 'Boro 'is 'reading x)))
> (p 'a-book)
'(Boro is reading a-book)
> (define d (lambda (p x) (p (list 'quote (p x)))))
> (d p 'a-book)
'(Boro is reading '(Boro is reading a-book))

As another example, let niUji2v.png!web stand for “Boro is reading the diagonalization of x”, and let aiEZfy.png!web stand for `Boro is reading the diagonalization of “Boro is reading the diagonalization of x”`. That is, jEFjqqZ.png!web . But, the diagonalization of niUji2v.png!web is simply aiEZfy.png!web , i.e. jmI7Zrz.png!web . So, aiEZfy.png!web refers to itself. In Lisp:

> (define q (lambda (x) (list 'Boro 'is 'reading (d identity x))))
> (define r (lambda (x) (d q x)))
> (equal? (d q 'test) (r 'test))
#t

Based on these definitions, we will now show how to derive a Quine , which is a program that when evaluated returns its source code as an output – a metaprogram.

Note how we used (d identity x) earlier, i.e. the diagonalization of x. This simply evaluates to (list 'quote x) .

Now, let’s consider the expression (list x (list 'quote x)) which will return a list with two members: x and its diagonalization:

> (define quine-1 (lambda (x) (list x (list 'quote x))))

What if we apply it to itself?

> (quine-1 quine-1)
'(#<procedure:quine-1> '#<procedure:quine-1>)

Nothing useful. How about applying its quoted version?

> (quine-1 'quine-1)
'(quine-1 'quine-1)

This is exactly why we picked the expression that contains a list of x and its diagonalization. We wanted the evaluation of that expression to return the same expression.

It looks like we are on the right track. Finally, the Quine code that will reproduce itself is just taking the lambda and applying it to its quoted version:

((lambda (x) (list x (list 'quote x)))
  '(lambda (x) (list x (list 'quote x))))

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK