This problem set includes several problems that test your understanding of the proofs that ACL2 does. You are expected to do these proofs by hand, not use the theorem prover. Your exam may contain problems like this. These problems are for your practice. You do not need to submit your solutions. But we urge you to do them, to get a sense of what it takes to do formal proofs. We will post our solutions on the Web in a couple of weeks. But we do urge you to not look at the posted solutions unless you are irrepairably stuck and do not find a way to make progress. Looking at our solutions will not help you do the reasoning --- the best way to understand how to do formal proofs is to *do* it. However, we do hope that the experience will teach you the need for mechanized tools like ACL2 to help you in doing proofs. In doing the hand proofs, you can make use of (1) substitution of equals by equals, (2) propositional reasoning, and (3) induction. You can also prove a lemma and use any instance of that proven lemma in a subsequent theorem. When you do propositional reasoning, remember that the functions and, or, etc. in ACL2, are not exactly Boolean. For instance, the ACL2 definition of AND is: (and x y) = (if x y NIL). You can also use any standard arithmetic facts when reasoning about numbers, but remember that the arithmetic operators (+, *, etc.) have completion axioms that state what their values will be for non-numeric inputs. If you are unsure what the relevant axioms about a function are, consult the paper "M. Kaufmann and J S. Moore: A Precise Description of the ACL2 Logic". Feel free to ask the instructors in case you get stuck. The problems specifications below are often provided as informal English text. In such cases, the first job is to formalize them, convert them into a term that you can start proving. Note that it is *not* sufficient to just argue the correctness of the statement informally, --- you will need to produce a formula that you believe is a reflection of the statement in the logic. We understand that there may be several ways to formalize a problem. In some cases, the problem descriptions may even be (deliberately) ambiguous. A key skill that you need to learn in applying formal methods is to translate informal English statements to a formal form, and this skill can be learnt only out of practice. If for some English statement, it is not clear what the intended formalization is, please feel free to ask the instructors. Problem 1: This is a warm-up, and asks you to reason about factorial. (a) Recall the definition of factorial shown in class (defun fact (n) (if (zp n) 1 (* n (fact (- n 1))))) Prove that this function always returns a natural number greater than 0. (b) Consider the following definition: (defun trfact (n a) (if (zp n) a (trfact (- n 1) (* n a)))) (defun trfact1 (n) (trfact n 1)) Prove that trfact1 returns the factorial of a number. Problem 2: This problem asks you to think about reversing lists. Prove the statement that reversing a list twice returns the original list. (Hint: You can use the rev function shown in class.) Problem 3: This problem considers list sorting. (a) Consider the functions orderedp and insert below. (defun orderedp (x) (if (endp x) t (if (endp (cdr x)) t (if (<= (car x) (car (cdr x))) (orderedp (cdr x)) nil)))) (defun insert (e x) (if (endp x) (list e) (if (< e (car x)) (cons e x) (cons (car x) (insert e (cdr x)))))) Prove the following statement: Suppose we insert an element e into a ordered list x of natural numbers. Then the result is ordered. (b) Consider the following definition of the insertion-sort function. (defun isort (x) (if (endp x) nil (insert (car x) (isort (cdr x))))) Prove that isort produces an ordered list. Problem 4: This problem deals with trees. (a) Consider the following definition, which swaps the elements in a tree. (defun swap-tree (x) (if (atom x) x (cons (swap-tree (cdr x)) (swap-tree (car x))))) Prove that doing swap-tree and then doing it again returns the original tree. (b) Consider the following function fringe that creates a list out of the leaves of a tree. Here app is the function we showed in class. (defun fringe (x) (if (atom x) (cons x nil) (app (fringe (car x)) (fringe (cdr x))))) Prove that the fringe of the tree obtained after the swap-tree operation is the reverse of the fringe of the original tree. Problem 5: This problem deals with bit vectors, and is a bit more elaborate. You should try this problem only after you have done all the previous ones. Also, it may be worth-while to first do this proof in ACL2 before embarking on a proof by hand. We will consider modeling bit vectors as lists of Booleans (that is, T and NIL). Thus, '(T NIL) is a bit vector which you might have conventionally written as the binary string 10. The decimal value of this bit vector is 3. (a) Define a function bit-vectorp that returns T if its argument is a bit vector. (b) Define a function bv-add which takes two bit vectors and returns the bit-vector which represents their sum. (Note: the lengths of the bit vectors may vary, and the length of the sum can be at most one more than the length of the larger bit-vector. (c) Define functions bv-to-nat and nat-to-bv to convert a bit vector to a natural number and back. Function bv-to-nat takes a bit-vector b and returns a natural number. Function nat-to-bv takes a natural number n and length l and returns a bit vector of length l whose value is the same n. If l is too small nat-to-bv you can decide yourself what to do, for example throw an error or truncate the result, or something else. Do whatever you feel is natural. (d) Formalize and state the following theorem. "Suppose we have two bit vectors x and y, and we add them to get the bit vector z. Convert z to a natural number. The result is the same as first converting x and y to natural numbers and then computing their sum. (e) Prove the theorem above. (f) State the other side of the theorem. That is, suppose you want to take two arbitrary natural numbers a and b, convert them to appropriate bit vectors and compute bit-vector sum. Then the result should be the same as first summing a and b and then converting the result to a bit vector. Can you state this theorem? (Note: This statement is a bit more subtle, since you need to produce bit vectors of appropriate lengths.)