University of Virginia, Department of Computer Science CS200: Computer Science, Spring 2002

 Problem Set 7: Quantum Computing The Quist for Shor Out: 27 March 2002 Due: 5 April 2002, before class

 Turn-in Checklist: On Friday, 5 April, bring to class a stapled turn in containing: Your written answers to questions 1, 2a, and 4a. All the code you wrote or modified for this problem set. Be sure to clearly mark the code for each question.

Collaboration Policy - Read Carefully

This problem set is intended to help you prepare for Exam 2. You may work on it by yourself or with other students, but you will need to do the exam on your own.

Regardless of whether you work alone or with a partner, you are encouraged to discuss this assignment with other students in the class and ask and provide help in useful ways. You may consult any outside resources you wish including books, papers, web sites and people. If you use resources other than the class materials, indicate what you used along with your answer.

Purpose
• Learn about evaluators
• Understand deeply how a Scheme evaluator works
• Extend an evaluator to define a new language
Downloads:
• meval.ss — metacircular evaluator for Mini-Scheme.
• listprocs.ss — list procedures (same as for PS6)

### A Mini-Scheme Evaluator

In problem sets 1-4 we solved problems by dividing them into procedures; in problem set 5, we solved a problem by dividing it into procedures and state; in problem set 6, we solved a problem by dividing it into objects that could be used to build a model. In this problem set, we will explore how languages can be used to solve problems. If the languages we have are not well-suited to the problem, we can invent a new language, build an evaluator for that language, and solve the problem by defining a procedure in the new language.

 Reading: Before going further, you should have finished reading Structure and Interpretation of Computer Programs, Chapter 4 (you may skip 4.1.6 and 4.1.7 and 4.4-end). You should see many similarities between the Scheme variation explained in Section 4.3, and what you need to do for this problem set.

The evaluator in meval.ss defines a Scheme-like language we will call Mini-Scheme. The language it defines is described by this BNF grammar:

Expression ::= Compound-Expression
Expression ::= Lambda-Expression
Expression ::= Define-Expression
Expression ::= Self-Evaluating
Expression ::= Name

Compound-Expression ::= (Expression Expressions)
Lambda-Expression ::= (lambda (Names) Expressions)
Define-Expression ::= (define Name Expression)

Expressions ::= Expression Expressions
Expressions ::=

Names ::= Name Names
Names ::=

Self-Evaluating ::= Number
Self-Evaluating ::= Primitive-Procedure
Self-Evaluating ::= String

The language is defined by its evaluation procedure, meval. Below are some sample interactions using meval. Note how we us ' (quote) to prevent the underlying Scheme interpreter from attempting to evaluate the Mini-Scheme expression we pass to meval.

> (meval '3 the-global-environment)

3

> (meval '(+ 3 3) the-global-environment)

6

> (meval '(+ 3 3) the-empty-environment)

No binding for +

> (meval '(define x 3) the-global-environment)

ok

> (meval 'x the-global-environment)

3

> (meval '(define square (lambda (x) (* x x))) the-global-environment)

ok

> (meval '(square x) the-global-environment)

9

> the-global-environment

#1=(((+ primitive-procedure #)
(* primitive-procedure #)
(- primitive-procedure #)
(x . 3)
(square procedure (x) ((* x x)) #1#)))

 Question 1: Draw an environment diagram showing the Mini-Scheme environment the-global-environment at the end of the interactions above.

In meval.ss, we have provided a procedure (driver-loop) that runs a read-eval-print loop for Mini-Scheme. Try running (driver-loop) and evaluating some Mini-Scheme expressions. For example:

> (driver-loop)

;;; Mini-Scheme input:
(define square (lambda (x) (* x x)))
;;; Mini-Scheme value:
ok

;;; Mini-Scheme input:
(square (square x))
;;; Mini-Scheme value:
81

;;; Mini-Scheme input:
quit
Done.

Play around with Mini-Scheme a little to get a feel for how it works, and what's different from the actual Scheme interpreter.

### Extending Mini-Scheme

Our Mini-Scheme language is missing some important things. For example, it does not provide if.

Eva Lu Ator claims she can define if herself using Mini-Scheme:

(meval '(define true (lambda (x y) x)) the-global-environment)

(meval '(define false (lambda (x y) y)) the-global-environment)

(meval '(define if (lambda (pred tbranch fbranch)
(pred tbranch fbranch)))
the-global-environment)

And demonstrates her definitions as follows:

(meval '(if true 3 5) the-global-environment)

3

(meval '(if false (+ 3 5) (+ 7 12)) the-global-environment)

19

 Question 2:a. Convince Eva Lu Ator that her if is inadequate by showing an expression which it would not evaluate correctly. Explain why it is impossible to define a procedure in Mini-Scheme that behaves like the Scheme if (that is, why if must be a special form). b. Extend the provided Mini-Scheme implementation to support the special form if, that does the same thing that Scheme's if special form does. You will need to add a new evaluation rule to the meval procedure.

### Quantum Computing

Normal computers are based on classical mechanics — computation is done using electricty and magnetism, more or less as understood since Maxwell (1873). Quantum computers are based on quantum mechanics, laws of physics that apply at the lowest levels of matter. GEB Chapter 5 (p. 142-146) discussed quantum mechanics. At the lowest level, particles are actually in several states at once. Quantum particles have the very strange property of being in more than one state at the same time.

In the eary 1980s, Richard Feynman and others suggested that this property may be useful for performing computations. The first important algorithm for a quantum computer was invented by Peter Shor in 1994 (Polynomial-time algorithms for prime factorization and discrete logarithms on a quantum computer, SIAM Journal of Computing). He demonstrated that if you had a quantum computer you could take advantage of the multiple states property to solve the problem of factoring large numbers. With normal computers, there is no known polynomial time solution to factoring. With Shor's quantum algorithm, it is possible to factor in polynomial time with a quantum computer. Factoring is a very important problem since many cryptosystems depend on factoring being hard for their security. (You can think of the box in the movie Sneakers as a quantum computer that can factor quickly.)

When Shor published his paper no one had yet built a quantum computer (at least as far as the general public knows — the National Security Agency does lots of secret work in quantum computing, but doesn't tell many people about it!). Recently, people have built real quantum computers. IBM recently used Shor's algorithm on a quantum computer to factor 15 (into 3 x 5). (Big Blue Takes Quantum Step, Wired, December 2001)

The smallest unit of quantum information is known as a qubit. A standard bit is the smallest unit of information in a normal computer. A bit can be in one of two states — 0 or 1. A qubit, however, is in two states at the same time. In other words, a qubit can represent both 0 and 1 at the same time. With two normal bits, we can represent four different values. We can think of two qubits as representing four different values at once. The quantum computer that factored 15 had 7-qubits, enough to be in 27 (= 128) states at once. If we could build a thousand qubit quantum computer, we could use it to quickly factor large numbers. Making an extra qubit, though, is extremely hard. Most physicists believe it is practically impossible to build a many-qubit quantum computer. There may be potential side effects to the surrounding area with a quantum computer that has more than 10 or 12 qubits. See http://www.qubit.org/intros/comp/comp.html for more information on quantum computing (but it is not necessary to understand quantum physics to do this problem set).

For this problem set, you will be extending our Mini-Scheme evaluator to support a model of computation inspired by quantum computing. We'll call the new language Quantum-Mini-Scheme.

To model quantum computers, we will extend our Mini-Scheme evaluator with quists, short for quantum list. A quist is a list of values, but unlike a normal list it represents all of the values at the same time. For example, (quist 0 1) would represent a single qubit, storing both 0 and 1 at the same time. To represent (quist 0 1 2 3) we would need two qubits since it represents four possible values.

Expressions involving quists evaluate to a quist of the value of the expression for all possible values in each of the quists. Some examples:

> (+ (quist 0 1) 3)

(quist 3 4)

> (+ (quist 0 1) (quist 0 1))

(quist 0 1 1 2)

>((quist + -) (quist 2 3) (quist 1 2))

(quist 3 4 5 1 0 2)

or equivalently:

(quist 0 1 2 3 4 5)

Note that the order of the values in a quist does not matter. For example, (quist 3 4) means exactly the same thing as (quist 4 3).

 Question 3: Extend your Mini-Scheme evaluator to support quist. Your evaluator should be able to perform all the interaction examples shown above correctly. You may assume that quist's cannot be nested — that is the possible values of a quist cannot contain other quists. It is okay to have the same value in a quist more than once (like (quist 0 1 1 2) above. Your evaluator may display quists as (list 'quist 3 4) instead of (quist 3 4).

To do useful computations with quists we need to convert them back into normal values. Potentially (again, this may not actually be possible in our universe), one can "observe" a quantum particle, which would force it into one of its possible states, at which point we could examine some of its properties. We will model this using an observe special form that takes a quist, a function and produces a normal value.

The observe form takes a function that evaluates to a boolean when it is applied to a value of any type and a quist. The value of an observe is any value in the quist for which the function evaluates to true, if there is one. If there are no such values, it should return an error stating that the quist is unobservable. (On the real quantum computer, an unobservable quist might lead to a chain-reaction explosion that engulfs the Universe. For the purposes of this assignment, it is not necessary for your simulator to produce the same effect.)

Here are some examples:

(observe (lambda (x) #t) (quist 0 1))
0 or 1
(observe (lambda (x) #f) (quist 0 1))
Error: unobservable quist.
(observe (lambda (x) (> x 10) (quist 3 17 8 23 -4))
17 or 23
(observe list? (quist 3 (list 0 1) (list) 17 (list 2 3)))
(0 1) or () or (2 3)

 Question 4:a. Explain why observe must be a special form. b. Extend your implementation to support observe. (We will provide you a good way to test your function in the next question.)

### Quantum Factoring

One way to see why factoring large numbers is so hard is to compare it with multiplication. If you were asked to factor 15 by hand, it would (hopefully) take you no more than a few seconds to respond with 3 * 5. If you were asked to factor 629 by hand, it would probably take you a bit longer, maybe five or ten minutes, but it wouldn't be terribly long. If, however, you were asked to factor 29083 by hand, it could take you upwards of an hour or more. Compare this with multiplication. If you were asked to compute 3 * 5, 17 * 27, and 127 * 229, it would take you less than 5 minutes to do them all by hand.

This is a key point. We have an algorithm for multiplication that is easy to scale to larger numbers, so each of those problems is not much more difficult than the one before. However, the best known algorithms for factoring increase exponentially in difficulty with the number of digits of the number to be factored. Think about the difference just between trying to factor 629 and 29083, and then imagine trying to factor a number with 10 or 20 digits! The security of the RSA cryptosystem depends on it being hard to factor numbers with a few hundred digits. Factoring numbers with over 160 digits is beyond today's technology. RSA runs a factoring challenge that offers prizes to people who find factors of large numbers (a 155 digit number was factored, using 35 years of processing time distributed over thousands of computers).

Informally, this should make you think factoring is in NP — it is easy to check if the factors are correct, but we have to guess to find the right factors. Note that is it important to be clear about how we measure the problem size when we say a problem is hard. For factoring, we consider the number of digits in the input number the problem size, instead of the input number itself. Factoring would be polynomial in the input number, since we can just try dividing by every number up to n (actually the square root of n would be enough). But, that would be exponential in the number of digits (which is log n).

What quantum computers potentially offer is the ability to try all the guesses at once. Of course, we are simulating our quantum computer on a traditional computer, so we can't actually do that. But we can define a procedure so that if we had a real quantum computer, it would be able to do everything at once.

So, we can factor by trying all possible factorings at once, and keeping the one whose product matches the number we are factoring. For example, we could factor 15 by creating a list of all the prime numbers less than (/ 15 2): (2 3 5 7) (note that we don't need to worry about prime numbers bigger than (/ n 2), since they couldn't possibly be prime factors). Then, we create a list with each prime repeated the maximum number of times before the produce of all the repetitions would exceed n. So to factor 15, we need to include three 2s since (* 2 2 2) is 8, but four 2s would exceed 15. The possible factors list now is: (2 2 2 3 3 5 7). The powerset of this list will contain the factorization of 15. Recall from http://www.cs.virginia.edu/~evans/cs200/notes/0222.html the powerset procedure (which is included in meval.ss.) For this example, it would have 128 elements.

In meval.ss we have provided a procedure factor that uses this approach to factor a number. This is a really inefficient way of factoring on a normal computer.

 Question 5: Rewrite the factor procedure in Quantum-Mini-Scheme. Your procedure should take advantage of the quist and observe forms you defined in questions 3 and 4. Demonstrate that your factor procedure works by factoring 9, 15, 16 and 37. Your factoring procedure should run in polynomial time on a mythical quantum computer that could perform operations on quists in constant time. Since you don't have a real quantum computer, though, its very slow and you won't be able to factor big numbers.

 Credits: This problem set was created by Stephen Liang and David Evans,based on a problem set create for CS655 Spring 2001.