; Solutions to the Exercises for: ; An Exercise in Graph Theory ; by J Strother Moore ; This is an ACL2 file but it is not a book. It contains expressions ; that are not allowed in certified books. ; I provide solutions to the exercises in my chapter. To find the ; solution for exercise n, search for ``; Exercise n''. Some of the ; exercises just call for explanations. But others call for ACL2 ; commands to lead the system to some proof. So the explanations are ; all comments here and the commands are not. Every exercise that ; contains commands starts with a command to configure the ACL2 ; database appropriately. The most common such command here is ; (ubt! 1), which means ``undo back through command 1 (without ; asking any questions). The other common such context-setting ; command here is to use LD to load one of the support files mentioned ; in the chapter. I use the :ld-pre-eval-filter option of LD to ; load the file up through a given event. By starting every command ; sequence with a context-setting command, each solution can be executed ; independently. But it does mean that processing them all is a lot slower ; than it could be, since each command sets the context from scratch. ; Before you try to execute any of these solutions, you should install ; in some directory the supporting books ; find-path1.lisp ; find-path2.lisp ; find-path3.lisp ; helpers.lisp ; linear-find-path.lisp ; then select that directory as the connected directory and start ; ACL2. ; You may be tempted to load this file into ACL2, with ld, rather than ; to execute individual commands from within this file. I recommend ; against just loading the whole file. Most of the pedagogical material ; here is in comments that won't show up when you load the file. ; You should consider this file the explanation of my solutions and you ; should execute the individual commands in it as necessary to explore ; my solutions. ; Also, remember that if you have proved different lemmas than I ; prove, then my solution to any given exercise will not necessarily ; work in your context. ; ----------------------------------------------------------------- ; Exercise 1 ; (defthm member-append ; (equal (member x (append a b)) ; (or (member x a) ; (member x b)))) ; is not a theorem because member is not Boolean-valued. Instead of ; returning T it returns a tail of its second argument, indicating where ; the first argument occurs as an element. ; For example, (member 1 '(0 1 2 3)) is (1 2 3). Hence, here is a counter- ; example to the conjecture above. (let ((x 1) (a '(0 1 2)) (b '(3 4 5))) (equal (member x (append a b)) (or (member x a) (member x b)))) ; The expression above evaluates to nil, because the member-expression ; on the left-hand side evaluates to (1 2 3 4 5) but the or-expression ; on the right-hand side evaluates to (1 2). ; When looking for counterexamples, I sometimes type expressions like ; this, (let ((x 1) (a '(0 1 2)) (b '(3 4 5))) (list (member x (append a b)) (or (member x a) (member x b)))) ; where I've replaced the EQUAL with LIST. This way I get to see the ; values of the two allegedly equal terms. ; Here is a corrected version of the conjecture. (ubt! 1) (defthm member-append (iff (member x (append a b)) (or (member x a) (member x b)))) ; This theorem is proved automatically by ACL2 in its initial state. It ; is just a simple induction on a. As a rewrite rule, it replaces ; instances of (member x (append a b)) by the corresponding instances of ; the or-expression, in contexts in which we are just concerned about ; propositional equivalence. ; ----------------------------------------------------------------- ; Exercise 2 (ubt! 1) (defun rev (x) (if (endp x) nil (append (rev (cdr x)) (list (car x))))) (defthm car-last-rev (equal (car (last (rev x))) (car x))) ; ACL2 proves car-last-rev without help, from its initial state. ; However, The Method suggests a lemma about last and append. So let me ; undo the last theorem, (u) ; and prove the following lemma first. (defthm last-append (implies (consp b) (equal (last (append a b)) (last b)))) ; Now the proof of car-last-rev is more direct: no induction is required. (defthm car-last-rev (equal (car (last (rev x))) (car x))) ; Note that a stronger theorem about last and append is possible: (defthm strong-last-append (equal (last (append a b)) (if (consp b) (last b) (if (consp a) (cons (car (last a)) b) b)))) ; ----------------------------------------------------------------- ; Exercise 3 ; The rewrite rule suggested to me is shown below. To prove it ; I first have to prove the previously mentioned member-append. (ubt! 1) (defthm member-append (iff (member x (append a b)) (or (member x a) (member x b)))) (defthm no-duplicatesp-append-cons (equal (no-duplicatesp (append a (cons e b))) (and (not (member e a)) (not (member e b)) (no-duplicatesp (append a b))))) ; ----------------------------------------------------------------- ; Exercise 4 ; Find-next-step terminates because on each recursion either the number ; of unvisited nodes decreases or else the number of unvisted nodes ; stays fixed but the number of neighbors (of the current node) to be ; tried decreases. Here, by ``unvisited nodes'' we mean ``nodes of g ; that are not listed in stack.'' Notice that we have just described a ; measure containing two components and we are using a lexicographic ; comparison. ; Here is the definition. You will not be able to execute this because ; we haven't defined the necessary graph functions (e.g., neighbors). ; But I need to talk about its parts. I've enclosed this definition in ; the expression comment delimiters, #| ... |#, so it is really just a ; comment here. #| (defun find-next-step (c stack b g) (cond ((endp c) 'failure) ((member (car c) stack) (find-next-step (cdr c) stack b g)) ; Call 1 ((equal (car c) b) (rev (cons b stack))) (t (let ((temp (find-next-step ; Call 2 (neighbors (car c) g) (cons (car c) stack) b g))) (if (equal temp 'failure) (find-next-step (cdr c) stack b g) ; Call 3 temp))))) |# ; In Calls 1 and 3, the first component of the measure stays fixed ; (because stack and g stay fixed) but the second component decreases ; (because c is replaced by (cdr c), where c is known to be a consp). ; In Call 2, the first component appears to decrease -- because an ; element is added to stack and, by hypothesis, that element is not ; already in stack. That is, the number of unvisited nodes seems to ; decrease. But, as pointed out in the paper, we have to think about ; what happens if the element added to the stack is not a node. This ; is discussed in Exercise 7, below. ; ----------------------------------------------------------------- ; Exercise 5 ; The formal version of the measure is shown below. ; (defun measure (c stack g) ; (cons (+ 1 (count-non-members (all-nodes g) stack)) ; (len c))) ; Observe that count-non-members, defined below, computes the first ; component and len computes the second. We add one to the first and ; cons it onto the second to produce an ordinal. As discussed in ; the book, the pair is lexicographically below iff either ; i(f 3) ; 3 ; ACL2 !>(f 10) ; 10 ; It seems to terminate and to return its argument (for natural numbers, ; at least). ; We could try to admit the function in :logic mode, using the measure ; (acl2-count x), just by typing: ; (verify-termination f) ; That will generate the measure conjectures for acl2-count. The first ; two are trivial and are not printed by ACL2. The third is not proved ; and the admission attempt fails. ; But that doesn't mean it is impossible. Suppose we imagine a new ; measure, m. Here are the conjectures required by the definitional ; principle. ; (e0-ordinalp (m x)) ; (implies (not (zp x)) ; (e0-ord-< (m (- x 1)) (m x))) ; (implies (not (zp x)) ; (e0-ord-< (m (f (- x 1))) (m x))) ; If the last could be proved BEFORE f IS DEFINED, then we could prove ; anything! ; Why? Because if we could prove the last measure conjecture without ; using the definition of f, then we could define (g x) = (+ 1 x) and ; prove ; (implies (not (zp x)) ; (e0-ord-< (m (g (- x 1))) (m x))) ; using exactly the same proof. But once we prove the formula above, about ; g, we can get ; (implies (not (zp x)) ; (e0-ord-< (m x) (m x))) ; by expanding the definition of g and using arithmetic. ; Clearly we are in trouble. To put a bow on it: if the formula above ; is a theorem, then so is nil. We know (not (e0-ord-< z z)). So the ; theorem above reduces to the theorem (zp x), which allows us to prove ; (zp 1), which reduces to nil. ; Hence, there is just no measure m for which you can prove the third ; measure conjecture without a definition of f! ; The definition of f is therefore inadmissible. ; ----------------------------------------------------------------- ; Exercise 19 ; Exercise 20 ; Exercise 21 ; I will do all three of these sequentially so I don't have to keep ; repeating myself to rebuild the database constructed by the previous ; exercise. ; Here is a suitable m. (ubt! 1) (defun m (x) (acl2-count x)) (defun f (x) (declare (xargs :measure (m x))) (if (zp x) 0 (if (e0-ord-< (m (f (- x 1))) (m x)) (+ 1 (f (f (- x 1)))) 'impossible))) ; The measure conjectures are as shown in Exercise 18, except in ; addition to the test (not (zp x)) we get the test ; (e0-ord-< (m (f (- x 1))) (m x)). ; This makes the third measure conjecture trivial. This is the answer ; to exercise 19. ; Having admitted f we prove the following two interesting facts. ; First, f is actually the identity function (on naturals). (defthm f-is-identity (equal (f x) (nfix x))) ; And hence, it is the case that the e0-ord-< test is always t (defthm test-is-always-t (implies (not (zp x)) (e0-ord-< (m (f (- x 1))) (m x)))) ; Thus the f defined above actually satisfies the originally desired ; equation. (defthm f-satisfies-original-equation (equal (f x) (if (zp x) 0 (+ 1 (f (f (- x 1)))))) :rule-classes ((:definition :controller-alist ((f t))))) ; The :rule-classes above tells ACL2 to use this equation as though it ; were a recursive definition ``measured'' by the first (only) ; argument of f. That is, ACL2 uses its definitional heuristics to ; apply this equality, rather than its standard rewrite heuristics. ; So we have now given the answer to exercise 20. ; We now turn to exercise 21, proving uniqueness. ; Here we constrain g to satisfy the original f equation. Obviously, ; we use f as our witness. (encapsulate ((g (x) t)) (local (defun g (x) (f x))) (defthm g-constraint (equal (g x) (if (zp x) 0 (+ 1 (g (g (- x 1)))))) :rule-classes ((:definition :controller-alist ((g t)))))) ; And then here is an inductive proof that g is f! (defthm g-must-be-f (equal (g x) (f x)) :hints (("Goal" :induct (f x)))) ; ----------------------------------------------------------------- ; Exercise 22 ; Exercise 23 ; The solutions to these two exercises are found in the book ; linear-find-path.lisp. In that book I admit a linear-time find-path ; following the strategy used above for f in exercises 19-21. Then I ; prove that it is equivalent to find-path. (ubt! 1) (include-book "linear-find-path") ; But for the record, here is the definition: (defun linear-find-next-step (c stack b g mt) (declare (xargs :measure (measure c mt g))) (cond ((endp c) (mv 'failure mt)) ((markedp (car c) mt) (linear-find-next-step (cdr c) stack b g mt)) ((equal (car c) b) (mv (rev (cons b stack)) mt)) (t (mv-let (temp new-mt) (linear-find-next-step (neighbors (car c) g) (cons (car c) stack) b g (mark (car c) mt)) (cond ((e0-ord-< (measure (cdr c) new-mt g) (measure c mt g)) (if (eq temp 'failure) (linear-find-next-step (cdr c) stack b g new-mt) (mv temp mt))) (t (mv 'impossible 'impossible))))))) (defun linear-find-path (a b g) (cond ((equal a b) (list a)) (t (mv-let (temp mt) (linear-find-next-step (neighbors a g) (list a) b g (mark a nil)) (declare (ignore mt)) temp)))) ; Note the e0-ord-< test in linear-find-next-step. I prove that this ; test is always t. Then I show that linear-find-next-step satisfies ; the original equation and that the solution is unique. ; Finally, I prove that (defthm linear-find-path-is-find-path (equal (linear-find-path a b g) (find-path a b g))) ; ----------------------------------------------------------------- ; Now return to the initial state. (ubt! 1)