Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

Notes on A Little Greek - First Year Interest Group Seminar | N 1, Study notes of Health sciences

Material Type: Notes; Class: FIRST-YEAR INTEREST GROUP SMNR; Subject: Nursing; University: University of Texas - Austin; Term: Spring 2008;

Typology: Study notes

Pre 2010

Uploaded on 08/30/2009

koofers-user-q3r
koofers-user-q3r 🇺🇸

10 documents

1 / 202

Toggle sidebar

Related documents


Partial preview of the text

Download Notes on A Little Greek - First Year Interest Group Seminar | N 1 and more Study notes Health sciences in PDF only on Docsity! i CS313K Notes – Spring, 2009 J Strother Moore The University of Texas at Austin December 4, 2008 Copyright c©2008 by Moore All rights reserved. I hereby grant permission for this publication to be photo-copied for personal or classroom use. No part of this publication may be stored in a retrieval system or transmitted in any form or by any means other than paper copies without the prior written permission of the authors. Please contact the author for details. Contents Preface xi 1 A Little Greek 1 2 The ACL2 Programming Language 3 2.1 Syntax 3 2.2 Data Types 7 2.3 Writing Pairs 8 2.4 Practice Recognizing ACL2 Objects 11 2.5 Writing Terms 12 2.6 Primitive Functions 13 2.7 Some Simple Definitions 15 2.8 Abbreviations 19 2.9 Defining New Functions 21 2.10 Practice, Practice, Practice 23 2.11 Talking about ACL2 with ACL2 26 3 The Need for Logic 33 3.1 An Informal Proof 33 3.2 Implication 35 3.3 Proving Another Simple Property 36 3.4 A Typical Question 38 3.5 What’s Going On Here? 39 3.6 Rearranging Your Programs 39 3.7 Some Useful “Identities” 43 4 Logic 47 4.1 Preliminaries 47 4.2 Syntax 50 viii 4.3 Axioms 53 4.4 Rules of Inference 55 4.5 Tautologies 58 4.6 About the Rules of Inference 61 4.7 Writing Proofs Down 67 4.8 Practice Proofs 77 5 Structural Induction 83 5.1 New Rule of Inference 84 5.2 Advice About Induction 85 5.3 Practice Proofs 87 5.4 Arithmetic in This Course 92 6 Induction and Recursion 95 6.1 The Definitional Principle 95 6.2 A General Induction Principle 98 6.3 Practice Definitions and Proofs 101 7 Quantifiers 103 7.1 The Universal Quantifier 103 7.2 The Existential Quantifier 108 7.3 Talking About Quantifiers Precisely 109 7.4 Imprecise Talk about the Rules of Inference 115 7.5 Rules of Inference 120 7.6 Practice Proofs 123 8 Set Theory 129 8.1 Basic Set Notation 131 8.2 Set Operations 133 8.3 Extensions to Quantifier and Set Builder Notation 135 8.4 Cons versus Traditional Notation 137 8.5 Generalized Union and Intersection 138 8.6 Cross Product 139 8.7 Relations 139 8.8 Orders 143 8.9 Equivalence Relations 144 8.10 Uniqueness Notation 147 8.11 Partitions 148 ix 8.12 The Characterization Theorem for Equivalence Relations 149 8.13 Functions 150 8.14 Cardinality 154 Appendices 154 A A Potted History of Logic in CS 155 B Example Recursive Definitions 157 C On The Difference Between Terms and Formulas 163 D On Resolution Theorem Proving 165 D.1 Conjunctive Normal Form 165 D.2 Ground Resolution 170 D.3 General Resolution 177 E On Ordinals 179 F On Peano Arithmetic 183 G On Entailment 187 Index 189 xii programs to search a list for an element, count the number of times an element occurs, etc. While the ACL2 system supports much more than just defining and running programs, that’s all you have to learn. But if you don’t learn how to write simple ACL2 programs, you probably won’t pass the course! Why am I making you learn another programming language? To learn to use logic to talk about computer science applications we need some simple applications. You’re going to write those simple applications in ACL2 because programs in it are much simpler to analyze than those of other programming languages you might know. Here’s an analogy. When you learn to use calculus to model the physical world, you start by using it to model objects falling in a vacuum, not helicopters in hurricanes. I should add that no computer science student should be anxious about learning another programming language! You will learn a dozen before you graduate and you will continue to learn new ones throughout your careers. Get used to it! Once you’ve learned how to write simple applications in ACL2, we’ll start talking and reasoning about them with logic. 1 A Little Greek You will see a lot of Greek symbols in computer science. You should know their names. name symbol alternative uppercase name symbol alternative uppercase symbol version symbol version alpha α A nu ν N beta β B xi ξ Ξ gamma γ Γ omicron o O delta δ ∆ pi π ̟ Π epsilon ǫ ε E rho ρ ̺ P zeta ζ Z sigma σ ς Σ eta η H tau τ T theta θ ϑ Θ upsilon υ Υ iota ι I phi φ ϕ Φ kappa κ K chi χ X lambda λ Λ psi ψ Ψ mu µ M • Question 1: What is the name of this symbol: φ? • • Question 2: What is the name of this symbol: ψ? • • Question 3: What is the name of this symbol: γ? • • Question 4: What is the name of this symbol: α? • • Question 5: What is the name of this symbol: ω? • • Question 6: What is the name of this symbol: δ? • • Question 7: What is the name of this symbol: π? • • Question 8: What is the name of this symbol: σ? • • Question 9: What is the name of this symbol: β? • • Question 10: What English word is written this way in Greek: λoγικη? • In computer science we spend a lot of time talking about strings of symbols representing text in some language. For example, we might talk about the Java program: public static int fact(int n){ int a = 1; while (n>0) {a=a*n; n=n-1;}; return a; } But what if we want to talk about a while statement where we don’t want to specify what the test and body are? The natural inclination is to use variables in those positions. But 2 A Little Logic if we write “while (test) {body};” the reader might think we really mean to test the variable test or call the method body. We need some symbols that can’t be mistaken for text in the language we’re talking about. Such variables are called meta-variables. Computer scientists tend to use Greek letters to solve this notational problem. We might write “while (τ) {β};” to talk about a general pattern in Java text and now it is clear that τ and β aren’t meant to be part of the Java text but stand for for some arbitrary pieces of text that we might put there. The Java text “while (n>0) {a=a*n; n=n-1;};” is an instance of the pattern “while (τ) {β};”, letting τ stand for “n>0” and letting β stand for “a=a*n; n=n-1;”. But “while (n<0) {n++};” is another instance of the same pattern. • Question 11: What is the name of this symbol: τ? • Sometimes we use italized variables for the same purpose. For example, we might write the pattern as “while (test) {body};.” The ACL2 Programming Language 5 (fact 3) = {by definition} (if (zp 3) 1 (* 3 (fact (- 3 1)))) = {since (zp 3) is nil (3 is not 0)} (if nil 1 (* 3 (fact (- 3 1)))) = {by the rules about if} (* 3 (fact (- 3 1))) = {by arithmetic} (* 3 (fact 2)) = {by definition} (* 3 (if (zp 2) 1 (* 2 (fact (- 2 1))))) = {since (zp 2) is nil (2 is not 0)} (* 3 (if nil 1 (* 2 (fact (- 2 1))))) = {by the rules about if} (* 3 (* 2 (fact (- 2 1)))) = {by arithmetic} (* 3 (* 2 (fact 1))) = {by definition} (* 3 (* 2 (if (zp 1) 1 (* 1 (fact (- 1 1)))))) = {since (zp 1) is nil (1 is not 0)} (* 3 (* 2 (if nil 1 (* 1 (fact (- 1 1)))))) = {by the rules about if} (* 3 (* 2 (* 1 (fact (- 1 1))))) = {by arithmetic} (* 3 (* 2 (* 1 (fact 0)))) = {by definition} (* 3 (* 2 (* 1 (if (zp 0) 1 (* 0 (fact (- 0 1))))))) = {since (zp 0) is t} (* 3 (* 2 (* 1 (if t 1 (* 0 (fact (- 0 1))))))) = {by the rules about if} (* 3 (* 2 (* 1 1))) = {by arithmetic} 6 To compute with ACL2, all you have to understand is substitution of equals for equals and the rules for the primitive functions symbols, like if, zp, and *. Expressions in the ACL2 programming language are called “terms.” (* n (fact (- n 1))) is a term. So is the whole if-expression used as the body of fact. When you type a term to ACL2, it is read, evaluated, and its value is printed, and then the system waits for 6 A Little Logic another input. This is called a read-eval-print loop. When you define a program in ACL2 you write: (defun f (v1 . . . vn) term) The f is the name of the program, the vi are the formal parameters or variables of the program, and the term is a term that is the body of the definition. After you’ve defined f , you can write (f a1 . . . an), where the ai are terms. This is called calling f or applying f . What happens when you call f? The ai are evaluated, producing some values xi. These values are called the actuals. You are applying f to those actual values. To compute the answer, the formal parameters of f , the vi, are temporarily bound to the corresponding actuals xi and in that environment where the formals are bound to the actuals the body term is evaluated. Whatever it computes is the value of (f a1 . . . an). So what is a term? A term is a variable, a quoted constant, or a function symbol, f , applied to the correct number of argument terms, a1, . . . , an, written (f a1 . . . an). The number of arguments a function symbol “expects” is called its arity. If c is an ACL2 constant, then (quote c) is a quoted constant. By convention, (quote c) is printed ’c. Furthermore, by conventon, we do not require the quote (or ’) on certain constants, including t, nil, numbers, and strings. Warning: If you play with ACL2 or Lisp, never write a comma! The program that reads your type-in does something very special on commas and you don’t want to go there! There are a few other “bad characters,” among them hash mark “#” and dot “.” but they are occasionally used in certain situations. Also, when writing strings, "Hello, World!", the rules are relaxed. But naked commas, hash marks, and dots can cause trouble. So don’t type them unless you know what you’re doing! • Question 12: Assume the following function symbols have the arities given. Pretend there are no other function symbols. You may assume that any contiguous sequence of alphabetic characters, e.g., x and temp, is a legal variable symbol. Mark with a check the legal terms below. Note that this doesn’t require that you know what the terms mean! The ACL2 Programming Language 7 All Known Functions symbol arity symbol arity if 3 + 2 cons 2 * 2 car 1 zp 1 cdr 1 nth 2 consp 1 prime-factors 1 filter 2 Alleged Terms 1. (if x y z) 2. nth(3,filter(u,temp)) 3. (if p (if q t nil) t) 4. (cons (car x) (cdr x)) 5. (cons 1 2 3) 6. 3 + 4 7. (if (zp n) (car x) (nth (+ n -1) (cdr x))) 8. (nth 3 (filter u v)) 9. (filter (prime-factors x 7)) 10. (filter (prime-factors x) 7) 11. (+ (* x x) (* -1 (* y y))) 12. (if (x 7) (y 8) (t 9)) 13. (car car) 14. (x cons y) 15. (if 1 2 3) 16. (car 17) 17. (if x y) 18. (cons x (confabulate x y)) • 2.2 Data Types ACL2 supports only five data types. It doesn’t allow you to introduce new ones. Every value you can construct in ACL2 is one of these five types.  numbers: ACL2 provides naturals (0, 1, 2, . . .), integers, rationals, and complex ra- tionals. We’ll probably only use the naturals. They’re written in the usual way.  characters: There are 256 character objects, e.g., #\A, #\a, and #\Space. To each character there corresponds an ASCII code, i.e., a natural between 0 and 255. We probably won’t use character objects in this course.  strings: A string is a finite sequence of character objects, e.g., "Hello World!". You may see a few strings but we won’t do much with them.  symbols: A symbol may be thought of as an object representing a name, e.g., of a func- tion, variable, opcode, or theorem. For example, fact, n, STORE, and associativity-- of-append are all symbols. For our purposes, case is unimportant: fact, Fact, and FACT all denote the same symbol. Symbols containing “unusual” characters like spaces, 10 A Little Logic All of these are legal ways to write the original object. We can apply the rules in any order and as often or as seldom as we wish to the various dots in the transcription. For example, (x . (y . (z . nil))) could be written in any of these ways: (x . (y . (z . nil))) (x . (y z . nil )) (x y . (z . nil) ) (x y z . nil ) (x . (y . (z ))) (x . (y z )) (x y . (z ) ) (x y z ) This is called dot notation for ordered pairs. As we do with numbers, we typically choose the transcription that makes most clear some aspect of the object, e.g., that it is a nil- terminated list, that it is a balanced binary tree, etc. Dot notation is surprisingly hard for students to master. I will not intentionally test you on it. But you should learn to read it because I will write it to communicate to you! The vast majority of our lists will not require any dots to transcribe. The rest of this section attempts to help you master dot notation. Every legal object can be written in full dot notation. Take any transcription in full dot notation, e.g., (x . (y . (z . nil))), and pick any dot in it. Immediately in front of the dot you’ll see an object. Immediately behind the dot you’ll see an object. Perhaps these objects are written with parentheses but if so those parentheses are part of the transcriptions of those objects. Immediately after the trailing object there will be a close parenthesis. In the picture below, the close parenthesis we are talking about is number 5. 6 This is the object in front of the dot. This is the trailing object. our dot 21 3 4 5 No matter which dot we choose, we can always find a leading object, a trailing object, and the close parenthesis after the trailing object. The first mistake students make in dot dropping is to erase the dot and the parentheses that “belong to it.” In our example, this would be parentheses 2 and 5. But read rule 2 carefully. Those are not the parentheses erased by dropping our dot! If we were to erase our dot, we’d erase parentheses 3 and 4. The second important thing to realize is that the properties just discussed – every dot has an object before it, a trailing object, and a close parenthesis after that – are preserved by the dot dropping rules. Look at the table of ways we can write (x . (y . (z . nil))) The ACL2 Programming Language 11 and confirm that whenever you see a dot there is an object in front of it within the currently open left parenthesis, there is an object after it within that open parenthesis, and there is a close parenthesis immediately after the trailing object. Always! The parenthesis in front of the leading object, parenthesis 2 above, may eventually disappear. That would happen if we used rule 2 to erase the first dot above. Note that if we deleted the first dot, our dot would survive the erasure but parentheses 2 and 5 would be erased. Since parenthesis 5 is the one we identified in checking the property for our dot, we’d better check the property would still hold after these erasures! Imagine erasing the first dot and parentheses 2 and 5. There’s still an object in front of our dot, namely y. There’s still an object after our dot, namely (z . nil). And there is still a parenthesis immediately after that trailing object, only now it would be parenthesis 6. Any time you see an alleged transcription of an object in which a dot is not preceded by an object, e.g., (A (. 3) 4) or one where there is no trailing object, e.g., (A (B .) C), or one where the trailing object is not immediately followed by a close parethesis, e.g., (A . B C), then you know it couldn’t have come from full dot notation because the dot dropping rules preserve those properties. So you would know the alleged transcription doesn’t denote an object! When writing in dot notation, a good convention to follow is to never write a dot unless it is followed by an atom and that atom is followed by a close parenthesis. When in doubt, write an object in full dot notation and then apply the rules. 2.4 Practice Recognizing ACL2 Objects • Question 13: For each of the “objects” below, classify it according to the types shown. If the “object” is not an ACL2 object, place a mark in the “none” column. These notes are incomplete. You may have to guess on some of these. Use your common sense and let’s see what happens. 12 A Little Logic object num char str sym pair none A B C D E 1 346 2 2.167 3 Hello 4 Mary Ann 5 (Hello Mary Ann) 6 ((A . 1) (B . 2)) 7 "Error: Bad PC!" 8 #\Newline 9 #\M 10 #\π 11 360. 12 (A . B C) 13 (A B . C) 14 (A B C) 15 ((A .)) 16 UNDEF 17 1/2 18 (A B C . 0) 19 (NIL) 20 NIL 21 () 22 1/0 • • Question 14: Some of the transcriptions below denote objects and the others are illegal. Put an “X” beside the illegal ones. 1 (A . (B C . (D))) 2 (A . B C . D) 3 ((A . B) . (C . D)) 4 (A B . (C . (D . NIL))) 5 (A B (C . D) . NIL) 6 (A B . (C . D) . NIL) 7 ((A B) (C D)) 8 (A B (C . D)) 9 ((A B C D)) 10 (A (B) (C . D)) 11 ((A . (B)) (C D . NIL)) • • Question 15: Some of the legal transcriptions in the previous question denote the same object as other transcriptions in that question. Indicate which ones are transcriptions of the same object. • 2.5 Writing Terms Earlier we said: The ACL2 Programming Language 15 results are naturals. For example (- 5 7) is -2 and (/ 15 6) is the rational 5/2, which is a number between 2 and 3. The following three functions play crucial behind-the-scenes roles in the mathematical foun- dations of ACL2. We’ll talk about them later but for completeness we’ll mention them now. They deal with the “ordinals below ǫ0.” To learn what that means, see Appendix E. But you can think of the ordinals as a “well-ordered extension of the natural numbers.” (o-p x) t or nil according to whether x is an ordinal below ǫ0. (o< x1 x2) t or nil according to whether x1 a smaller ordinal than x2 (pro- vided both are ordinals below ǫ0). (acl2-count x) a natural number measure of the “size” of object x; for objects composed entirely of pairs and natural numbers it, for example, the sum of the number of pairs plus the sum of all the natural numbers. 2.7 Some Simple Definitions Here are some functions we’ll use often. 2.7.1 Defined Propositional Functions (defun and (p q) (if p q nil)) (defun or (p q) (if p p q)) (defun not (p) (if p nil t)) (defun implies (p q) (if p (if q t nil) t)) (defun iff (p q) (and (implies p q) (implies q p))) These are called the propositional functions because they’re used to form “propositions” like “x is a natural and less than y.” Like all ACL2 functions, they can take any arguments you give them, but they’re meant to be applied to Booleans. (And p q) is the conjunction of p and q. It is true if both p and q are true and it is false otherwise. Think in terms of people making statements about what they think is true. John says “(and p q).” If p and q are both true, then John’s statement is true. If p is false, or q is false, or both are false, John’s statement is false. What does it mean if John says “(and 1 3)?” You might have several reactions: Maybe you think John has uttered nonsense. No! ACL2 is untyped! Functions in ACL2 can be applied to anything so (and 1 3) means something. You might think (and 1 3) is “true” because both 1 and 3 are “true” in the sense that they are non-nil. You would be right in the Lisp-colloquial where we say something “is true” to mean it “is non-nil.” (And 1 3) is non-nil. 16 A Little Logic • Question 17: What is the value of (and 1 3)? • It might be hard to work that out from the informal description of (and p q) as the conjunction of p and q. But it is trivial to work it out from the definition of and. Given (defun and (p q) (if p q nil)) we know (and 1 3) = {by definition} (if 1 3 nil) = {since 1 is different from nil} 3 • Question 18: What is (and nil 7)? • • Question 19: What is (and ’Monday "Hi")? • When you are not sure what something means, go back to the definition! The fact that and is not Boolean is very unconventional. We will not exploit that fact of and or the similiar one about or. (Or p q) is the disjunction of p and q. It is true if either (or both) of them is true and false otherwise. (Not p) is the Boolean negation of p: (not t) is nil and (not nil) is t. (Implies p q) can be read “if p is true, then q is true.” We call p the hypothesis or antecedent and we call q the conclusion or consequent. So (implies t t) is true and (implies t nil) is false. Why is (implies t nil) false? If John says “(implies t nil)” is he saying true or something false? He’s saying “if t is true then nil is true.” That’s clearly false because t is true but nil certainly is not. But if you have a hard time seeing it, just go to the definition. (defun implies (p q) (if p (if q t nil) t)) If John says “(implies nil t)” is he saying something true or false? He’s saying “if nil is true, then t is true.” That’s clearly true, because t is true no matter what. What about “(implies nil nil)”? He’s saying “if nil is true, then nil is true.” That’s clearly true too. If nil is true then, sure, nil is true. Of course, nil isn’t true, but if it were, it would be. A valuable lesson is that if somebody says (implies p q) it doesn’t mean q is true. It just means q is true if p is true! Finally (iff p q) means the truth values of p and q are the same. Either they’re both true or they’re both false. So (iff t t) and (iff nil nil) are both true and (iff t nil) and (iff nil t) are both false. • Question 20: Define the function xor so that (xor p q) means either p or q is true but not both. In your solution, let if be the only function you apply (i.e., define it using p, q, t, nil, and the function if). • In all the questions below, don’t use if in your answers, use the propositional functions instead. The ACL2 Programming Language 17 • Question 21: Define the function xor again. Note if you’re doing these exercises in an ACL2 system, you will have to undo your earlier definition of xor. ACL2 won’t let you redefine a function (but see the ACL2 documentation topic redef). • • Question 22: Write a term that checks whether exactly one of p, q, and r is true. By checks I mean the term returns true if the condition is true and false otherwise. • • Question 23: We say x is a singleton if x is pair whose cdr is nil. Define singletonp to recognize singletons. Often in Lisp, functions that indicate whether some condition is true or false have names ending in p, for “predicate.” • • Question 24: We say x is a doublet if it is of the form (u v). So (1 2) is a doublet, but (1 . 2) is not. Define the recognizer for doublets, doubletp. • • Question 25: We say x is text-like if x is a symbol or a string. However, we don’t consider the symbols t and nil text-like. Define text-likep. • • Question 26: If x is a pair, then it is equal to the result of pairing its own car and cdr. Say that in ACL2. • Because your answer to the last question will contain the variable x, you won’t be able to test your answer in ACL2, except by trying it out on different constant values of x. Suppose your answer is some expression (. . . x . . .) involving x. You can run it on a concrete value of x, say ’(1 . 2), by typing (let ((x ’(1 . 2))) (. . . x . . .)) We’ll explain let later. You don’t have to test your answers. Furthermore, I do not claim that all these “sayings” are true! I just want you to get used to expressing ideas in ACL2. • Question 27: If x is not a pair then its car is nil. Say that. • • Question 28: If 0 is less than x, then so is the symbol Monday. Say that. • • Question 29: X is equal to 0 or 1. Say that. • • Question 30: Exactly one of the following is true: x is a cons, a symbol, or a string. Say that. • • Question 31: If you have three naturals, i, j, and k and they are all different, then adding them up never produces 0. Say that. • • Question 32: If you have three naturals i, j, and k and they are all different, then one is between the other two. Say that. • • Question 33: If x is a pair whose car is y and z is a string, then if the car of x is z, then y is a string. Say that. • • Question 34: Pairs and strings are disjoint. A way to say this is that if x is a pair then it isn’t a string, and vice versa. Say that. • • Question 35: If one of y and z is a pair and the other is a natural, and if x is either y or z then x is not text-like. Say that. • • Question 36: The product of the sum and difference of x and y is positive, provided x and y are naturals. • People are really good at inventing new ways to say the same old things. I guess we get bored with repetition of patterns of speech. So we might say “if p then q,” but we might 20 A Little Logic Thus, (list 1 2 3) evaluates to (1 2 3). Abbreviation: (and p1 p2 . . . pk−1 pk) is an abbreviation for a “right-associated” and- nest: (and p1 (and p2 . . . (and pk−1 pk). . .)) Abbreviation: (or p1 p2 . . . pk−1 pk) is an abbreviation for a right-associated or-nest: (or p1 (or p2 . . . (or pk−1 pk). . .)) Abbreviation: (+ x1 x2 . . . xk−1 xk) is an abbreviation for a right-associated +-nest: (+ x1 (+ x2 . . . (+ xk−1 xk). . .)) Abbreviation: (* x1 x2 . . . xk−1 xk) is an abbreviation for a right-associated *-nest: (* x1 (* x2 . . . (* xk−1 xk). . .)) Abbreviation: (cond (p1 x1) (p2 x2) . . . (pk xk) (t xk+1)) is an abbreviation for an if-nest: (if p1 x1 (if p2 x2 . . . (if pk xk xk+1). . .)) Abbreviation: (let ((v1 a1) . . . (vk ak)) body), where the vi are distinct variable symbols and the ai and body are terms, is an abbreviation for the term obtained from body by simultaneously replacing all the vi by the corresponding ai. • Question 42: What is the value of (list ’mon ’tue ’wed ’thu ’fri)? • • Question 43: What is the car of (list x y z)? • • Question 44: Can (list x y z) be the same as (cons u v)? If so, what must be the values of u and v? If not, why not? • • Question 45: Can (list x y) and (list u v w) be the same? If so, what must be the values of x and y? f not, why not? • • Question 46: What is (list (list ’name "Susan") (list ’income 65000) (list ’city ’austin))? • The ACL2 Programming Language 21 • Question 47: What term does (and p q r) abbreviate? • • Question 48: What term does (and (or p q r) u v) abbreviate? • • Question 49: What term does this abbreviate? (cond ((consp x) ’pair) ((text-likep x) ’text) (t ’other)) If you want to run this, see Question 25 for the definition of text-likep. • • Question 50: If x is "Hello, World!" what is the value returned by the expression in the previous question? • • Question 51: What term does this abbreviate? (let ((x (+ a b)) (y (f 23))) (+ (* x x) y)) • Most of the conventions above are implemented with “macros.” The ACL2 user can intro- duce new macros but we don’t discuss them here. 2.9 Defining New Functions To define new functions we use the ACL2 command defun. It supports two modes. In program mode the requirements on definitions are less stringent but all you can do is run your functions like normal programs. In logic mode ACL2 supports the ability to reason about your functions. In this course, we’ll mainly use program mode. You can tell which mode ACL2 is in by the prompt. If the prompt is ACL2 !> then you are in logic mode and you should get into program mode by typing this to the prompt: ACL2 !>:program Then it will be in program mode and the prompt will look like this: ACL2 > Get used to noticing which mode you’re in. To introduce a new function f of arity n, do (defun f (v1 . . . vn) β) where 1. f is a symbol that has never been defined before, 22 A Little Logic 2. the vi are variable symbols and no two are the same, and 3. β is an ACL2 term and (a) every function called by β has already been defined (except for f itself), and (b) there are no free variables in β except the vi. Here are some example bad definitions – ones that violate the rules. (defun car (x y) (+ x y)) ; Note 1 (defun f (x x) (+ x x)) ; Note 2 (defun even (n) ; Note 3(a) (if (zp n) t (odd (- n 1)))) (defun odd (n) (if (zp n) nil (even (- n 1)))) (defun f (x) y) ; Note 3(b) It should be clear that “definitions” 1 and 2 are “bad.” The first redefines an existing function (however, see the ACL2 documentation topic u (for undoing a definition) or redef). The second doesn’t tell us how to evaluate (f 1 2). The reason 3(a) is “bad” is that even calls odd before odd is defined. But since odd calls even, we can’t introduce odd first either. This is mutual recursion and ACL2 permits such definitions, provided they are wrapped in a mutual-recursion form: (mutual-recursion (defun even (n) (if (zp n) t (odd (- n 1)))) (defun odd (n) (if (zp n) nil (even (- n 1)))) ) Finally, 3(b) is “bad” because the value of (f 3) might be 5 in one execution and 7 in another, depending on the value of y. When in logic mode, ACL2 must be able to prove that your recursive definitions terminate on all arguments. The essence of recursion is this: to solve a “big” problem, think of a smaller problem of the same kind, solve it (by calling the new function recursively, even though you don’t know yet how it solves the smaller problem!), and then convert the solution of the smaller problem into a solution of the bigger one. Eventually, you reduce the problem to one you just inherently know how to solve (the base case) and you return the answer. This is one of the most powerful ideas in computing, both theoretically and practically. It is also one of the most confusing things for new students to grasp. How can you solve the smaller problem if you still haven’t written a method to solve the bigger one? Recursion sort of takes a leap of faith: Suppose I want to write a function f that can solve a problem of size n. Here I really don’t need to be specific about how n is determined. If n is 0, this is the smallest problem of this The ACL2 Programming Language 25 Our lists are like finite sets, if we take care not to allow duplications and our answers are not affected by order. So define setp to recognize duplication-free true lists. • • Question 73: The cardinality of a set is the number of elements in it. Define card so that (card x) is the cardinality of the setp x. • • Question 74: One set is said to be a subset of another if every element of the first set is an element of the second. define sub so that (sub x y) checks whether x is a subset of y, provided both are setps. By the way, in normal mathematics, this relation is written x ⊆ y. • • Question 75: If x, y, and z are setps, then subset is transitive. That is, if x is a subset of y and y is a subset of z, then x is a subset of z. Say that in ACL2. • • Question 76: In set theory, two sets are equal precisely when they have the same elements. Define seteq so that (seteqp x y) checks whether setps x and y represent equal sets. In normal mathematics, set equality is written x = y, but we cannot use that symbol because in ACL2 it is a synnonym for equal. But our equal can tell the difference between (1 2 3) and (2 3 1), both of which represent the same set in set theory. So we content ourselves with defining a new symbol, seteq. • • Question 77: The union of two sets is the set that contains all the elements of each and no other elements. Define unn so that (unn x y) is a setp that represents the union of setps x and y. By the way, in normal mathematics, this operation is written x ∪ y. • • Question 78: The intersection of two sets is the set that contains just the objects that are in both sets. Define int so that (int x y) is a setp representing the intersection of setps x and y. By the way, in normal mathematics, this operation is written x ∩ y. • •Question 79: The difference between two sets is the set that contains the elements of the first that are not in the second. Define diff so that (diff x y) is a setp representing the difference of setps x and y. By the way, in normal mathematics, this operation is written x \ y. • • Question 80: The power set of a set x is the set that contains all the subsets of x. Note that the elements of the power set of x are the subsets of x. Define power so that (power x) is a setp representing the power set of setp x. For example, (power ’(a b c)) is a setp that contains the following other setps (in some order): nil, (a), (b), (c), (a b) (a c) (b c) and (a b c). Which representatives you use for the subsets is irrelevant, i.e., you can include (a b) or (b a). But your function should include a setp for each of the subsets. In normal mathematics, the power set of x is written ℘(x) • • Question 81: What is the cardinality of the power set of a finite set x? • • Question 82: Define the function how-many so that (how-many e x) counts the number of times e occurs as an element of the list x. For example, (how-many ’a ’(a b a c a d)) returns 3. • • Question 83: Define the function perm so that (perm x y) is t if the lists x and y are permutations of each other, i.e., they contain the same elements (including the same duplications) but just list them in different orders. For example, (a b a c) is a permutation of (c a a b) but not a permutation of (a b c) or (a b a c a). • • Question 84: How many permutations are there of the list (a b c)? • • Question 85: Suppose list x contains no duplications. How many permutations of x are there? • In the following questions, you need to know about an ACL2 function we won’t use elsewhere. 26 A Little Logic Lexorder is like “less than or equal” except instead of just being able to determine if one number is smaller than (or equal to) another, lexorder can consider any two ACL2 objects and determine whether the first is smaller than (or equal to) the second. Lexorder imposes what is called a “total ordering” on all ACL2 objects. We discuss orderings later. But an important property of lexorder is that if (lexorder x y) and (lexorder y x), then (equal x y). That is, if x “≤” y and y “≤” x, then x is y. Lexorder considers numbers smaller than characters, characters smaller than strings, strings smaller than symbols, and symbols smaller than lists; within those categories, lexorder uses an alphabetic-like ordering. So 1 comes before ALPHA, which comes before Monday, which comes before (APPLE). That is (lexorder 1 ’alpha) is t, as are (lexorder ’alpha ’monday) and (lexorder ’monday ’(APPLE)). (Lexorder ’BRAVO ’ALPHA) is nil. • Question 86: Define ordp so that (ordp x) determines whether the list x is in weakly ascending order, where the order is determined by lexorder. Thus (1 2 ALPHA ALPHA BRAVO (APPLE)) is ordered but (ALPHA BRAVO DOG CHARLIE) is not. • • Question 87: How many ordered (in the sense of ordp) permutations of x are there? • Question 88: Define insert so that (insert e x) returns the list x with e added as a new element. In addition, if x is ordered (by ordp from Question 86) then so is (insert e x). Thus, (insert ’CHARLIE ’(ALPHA BRAVO DOG)) is (ALPHA BRAVO CHARLIE DOG). • • Question 89: Define isort so that (isort x) takes an arbitrary true-list and returns a rearrangement of it that is ordered according to ordp (Question 86). Thus, (isort ’(DOG 3 BRAVO 2 CHARLIE 0 ALPHA)) is (0 2 3 ALPHA BRAVO CHARLIE DOG). • • Question 90: A combination of n objects from the list x is a list of length n, each element of which is an element of x. Thus, a combination of 3 objects taken from (A B C D) is (A A A A), but another combination is (A B D D). Note that there are only a finite number of combinations of n objects taken from a finite list. Define combinations so that (combinations n x) returns a list of all of the combinations of n objects taken from x. • • Question 91: A propositional literal is either a symbol other than nil or it is a true list of length 2 whose first element is the symbol NOT and whose second element is a symbol other than nil. Define litp to recognize when its argument is a propositional literal. • • Question 92: Let x be some propositional literal (see above). If x is of the form (NOT a), then the negation of x is a; otherwise, the negation of x is (NOT x). Define negate. • • Question 93: The pointwise negation of a list of propositional literals is obtained by collecting the negation of each literal in the list. Define map-negate to return the pointwise negation of its argument. • • Question 94: A propositional clause is a true list of propositional literals. Define clausep to recognize when its argument is a clause. • • Question 95: Define clausesp to recognize when its argument is a list of clauses. • 2.11 Talking about ACL2 with ACL2 In this section I give more programming exercises. These are harder than the ones above because they deal with trees rather than lists. But the trees have a peculiar property: they look like terms. The ACL2 Programming Language 27 If you put a quote mark (’) in front of an ACL2 term, you get an ACL2 object. For example, this is a term whose top-level function symbol is if: (if (zp n) 1 (* n (fact (- n 1)))) The term above evaluates to some number, depending on the value of the variable n. But if we put a quote mark in front of it we get ’(if (zp n) 1 (* n (fact (- n 1)))) which is a constant. In fact, the term above evaluates to a list of length 4 whose car is the symbol if. Let x be that list of length 4. Then (nth 1 x) evaluates to the list (zp n), (nth 2 x) evaluates to 1, and (nth 3 x) evaluates to the list (* n (fact (- n 1))). The exercises in this section have you write functions that walk over trees representing ACL2 terms. As strange as this may see to you, you should get used to it. Computer scientists frequently define new languages and often represent them as objects in some existing language. That is what we’re doing and you’ll do this many times in your CS career. Below is a pair of functions, wff and wff*, that describe the well-formed terms of our language. “Wff” stands for “well-formed formula.” We tend to use the words “term” and “formula” interchangeably ACL2. But in presentations of more conventional mathematical logics, terms and formulas are different syntatic classes. For more on the difference between “term” and “formula” see Appendix C. In the definition below, we assume arity-table is a table (see Question 62 and the next few questions after it) that gives the arities of all known function symbols. Note that to define a term we have to be able to check whether something is a list of terms (because a function call is a symbol followed by a list of terms). And to test whether something is a list of terms we have to be able to check whether each element is a term. So we need mutual recursion. Wff checks whether its argument is a term (formula) and wff* checks whether its argument is a list of terms. The definition of wff is mutually recursive with another function, wff*, which checks whether its argument is a list of wffs. Wff uses wff* to check the argument list of an alleged function call, wff* uses wff to check that each element of a list is well-formed. (mutual-recursion (defun wff (x arity-table) (cond ((atom x) (legal-varp x)) ((equal (car x) ’quote) (and (true-listp (cdr x)) (equal (len (cdr x)) 1))) (t (and (legal-fnp (car x)) (in-tablep (car x) arity-table) (true-listp (cdr x)) (equal (len (cdr x)) 30 A Little Logic • Question 102: Is (2 1 1) a legal address into the term above? If so, what does it point to? • • Question 103: What is the address of ’stop in the term above? Note that ’stop is just another way to write (quote stop). • • Question 104: What is the address of w in the term above? • • Question 105: Define legal-address so that if x is a well-formed term for some arity table then (legal-address a x) returns t iff a is a legal address in x. • • Question 106: Define get-addr so that if a is a legal address in the well-formed term x, then (get-addr a x) is the subterm to which a points. • • Question 107: Define peval so that it takes a propositional formula, p, and a table tbl (see Question 62 and nearby questions) in which the domain is the set of variables of p and the range is the set (T NIL), and returns t if p evaluates to true when the variables have the values indicated by tbl, and nil otherwise. For example, (peval ’(implies (and p q) (not r)) ’((p t) (q t) (r nil))) is t. (Note: I have not specified that tables have to have the structure used above; that’s just my version of a table associating key p with value t, key q with value t, etc. Your tables may be of a different shape.) • A table of the form just mentioned is called an interpretation of the variables of the formula. • Question 108: The conjuncts list of a term γ is defined as follows. If γ is of the form (and p q), its conjuncts list is the concatentation of the conjuncts list of p with the conjuncts list of q. The conjuncts list of t is the empty list. The conjuncts list of any other γ is the singleton list containing just γ. Thus, the conjuncts list of (and (and p q) (and r (or a b))) is (p q r (or a b)). The conjuncts list of (equal x y) is ((equal x y)). Define conjuncts to take a well-formed term and return its conjuncts lists. • • Question 109: The disjuncts list of a term γ is defined as follows. If γ is of the form (or p q), its disjuncts list is the concatentation of the disjuncts list of p with the disjuncts list of q. If γ is of the form (implies p q), its disjuncts list is the pointwise negation (see Question 93) of the conjuncts list of p concatenated with the disjuncts list of q. Otherwise, the disjuncts list of γ is the singleton list containing γ. Define disjuncts to return the disjuncts list of a term. • • Question 110: The conjunction of a list of terms x is the right-associated AND-nest whose conjuncts list is x. Define conjoin to return the conjunction of its argument. For example, (conjoin ’(A B C D)) is (AND A (AND B (AND C D))). • • Question 111: What is the conjunction of the empty list? • • Question 112: The disjunction of a list of terms x is the right-associated OR-nest whose disjuncts list is x. Define disjoin to return the disjunction of its argument. • A substitution is a table that associates keys and values. The keys must be symbols that are legal variables (legal-varp). The values must be well-formed terms with respect to some given arity table. •Question 113: Define (legal-substitutionp sigma arity-table) to recognize when sigma is a substitution. • Substitutions are written an a variety of way by different authors. We will use the following notation: {v1 ← α1, . . . , vk ← αk} to denote a subsitution that associates the keys vi to the The ACL2 Programming Language 31 terms αi. The idea of the “←” is that it suggests that vi is to be replaced by αi when the substitution is “applied.” The result of applying a legal substitution, σ, to a term, α, is the term produced by replacing each occurrence of each variable symbol in α by its image under σ. This is also called the image of α under σ and often written α/σ. For example, let σ be {x ← (car a), a ← (cdr a)}. Then α: (f (g x a) (h x y)) α/σ: (f (g (car a) (cdr a)) (h (car a) y)) • Question 114: Define apply-subst so that (apply-subst alpha sigma) is the result of applying substitution sigma to term alpha, provided both are legal. Note the order of the arguments. Even though we say “apply σ to α” the formal way of writing it is (apply-subst α σ). The order of the arguments stems from the “α/σ” notation. • • Question 115: What is γ/σ if: γ: (append (append a b) c) σ: {a ← (f b), b ← (f b), c ← (f b)} • • Question 116: What is γ/σ if: γ: (cons ’a a) σ: {a ← (f b)} • • Question 117: Is there a substitution σ such that (f x (h y z))/σ is (f (g a) (h b 33))? If so, what is it? If not, why? • • Question 118: Is there a substitution σ such that (f x (h y y))/σ is (f (g a) (h b 33))? If so, what is it? If not, why? • Need for Logic 35 So γ1 = γ2. Next, every programmer knows that (if (not x) y z) is the same as (if x z y). So apply that transformation to the first if in γ2 and get: γ3: (equal (car (if (consp a) (cons (car a) (app (cdr a) b)) b)) (if (consp a) (car a) (car b))) Also, you probably realize that (car (if x y z)) is the same as (if x (car y) (car z)). That is, you can either let the if return its value and then feed it to car, or you can move the car into both branches of the if and compute it before leaving the if. I think of this as “pushing” the car down into the if. So if we push the car down into the if we get γ4: (equal (if (consp a) (car (cons (car a) (app (cdr a) b))) (car b)) (if (consp a) (car a) (car b))) Finally, we know that (car (cons x y)) is just x, so we can simplify γ4 to get: γ5: (equal (if (consp a) (car a) (car b)) (if (consp a) (car a) (car b))) And look! Now the equal is being applied to two identical expressions. So of course it returns t. Since γ = γ1 = γ2 = γ3 = γ4 = γ5 = t, we know γ = t. This is a symbolic proof. We didn’t execute the code for app on examples. We manipulated the formula without knowing anything at all about a and b. So γ holds for all possible values of a and b. 3.2 Implication Another property of app is that if a is not a consp, then (app a b) is b. 36 A Little Logic • Question 119: Write an ACL2 term to capture the claim that “if a is not a consp, (app a b) is b.” That is, we want an ACL2 term that is t if the claim is true and nil if the claim is false. A more common way to say this is “formalize (in ACL2) the claim that if a is not a consp, then (app a b) is b.” This is a rhetorical question because I want to answer it and discuss the answer! In general, this question has the form “formalize the claim that if α is true, then β is true.” Clearly, the hypothesis α, “a is not a consp,” is formalized as (not (consp a)). The conclusion, β, “(app a b) is b” is captured by (equal (app a b) b). But how do we glue them together? It’s pretty obvious we write something like (if α β ???), but we need to decide what to write in the “else” branch of the if. Suppose I tell you “if α then β” is true. Clearly, if α is true, then the truth of my statement guarantees that β is true. But what have I told you about the case where α is false? Absolutely nothing. So “???” above has to be an ACL2 term whose truth tells you nothing. What term is that? What can we put in for “???” so that the statement “??? is true” tells you absolutely nothing? The answer is that “???” should be t. If I tell you “t is true” you’ve learned nothing. So to say “if α then β” formally we write (if α β t). If we want our statement to be Boolean, we could wrap “β” in another if to force the answer to be t or nil: (if α (if β t nil) t). But this is just the same as (implies α β). That is, (implies α β) is a Boolean-valued term that formalizes the claim “if α is true, then β is true.” It tells you absolutely nothing when α is false. 3.3 Proving Another Simple Property Let’s prove that if a is not a consp, then (app a b) is b. Formally, we want to prove that γ: (implies (not (consp a)) (equal (app a b) b)) is always true. Again, we can expand the call of (app a b): γ1: (implies (not (consp a)) (equal (if (endp a) b (cons (car a) (app (cdr a) b))) b)) Now expand the call of endp, Need for Logic 37 γ2: (implies (not (consp a)) (equal (if (not (consp a)) b (cons (car a) (app (cdr a) b))) b)) Now comes something tricky! We have a hypothesis that tells us that (not (consp a)) is true. We have an if expression that tests (not (consp a)). In the display below, I’ve underlined the hypothesis and I’ve printed the the test in italics. Now expand the call of endp, γ2: (implies (not (consp a)) (equal (if (not (consp a)) b (cons (car a) (app (cdr a) b))) b)) Since we’re assuming the hypothesis, every time we see it in the conclusion of the implication we know it is true. We see it in the test. So we “use” the hypothesis by replacing the test by t. γ3: (implies (not (consp a)) (equal (if t b (cons (car a) (app (cdr a) b))) b)) But we know that if returns its second argument when the first argument is t. So we can reduce this to: γ4: (implies (not (consp a)) (equal b b)). And we know that (equal b b) is t, so we get: γ5: (implies (not (consp a)) t). If you have thought about implies, you’ll know that (implies α t) is always t, no matter what α is. But let’s prove it, by continuing to replace equals by equals. What can we use? The definition of implies. This is an important insight: use the definitions of things! Remember the definition of implies? It is 40 A Little Logic But now recall the function findpos (Question 70) that sometimes returns nil and other times returns a natural number. Suppose we want to simplify this expression: (if (findpos e x) ; (1) (if (and (findpos e x) (natp b)) ; (2) (+ (findpos e x) b) ; (3) nil) . . .). Note that (findpos e x) appears three times above: (1) as the test of an if, (2) in the true-branch of that if, tested in an and, and (3) again in the true-branch of that if, used as a number in a + expression. When we are in the true-branch, we know (findpos e x) is “true” because of the test at (1). But we do not know it is t! It would be wrong to replace all the (findpos e x) terms in the true-branch by t! The test at (1) just tells us that (findpos e x) is propositionally equivalent to t, not equal to t. In the true-branch, we know (iff (findpos e x) t), not (equal (findpos e x) t). We’d like to use this fact to replace the (findpos e x) at (2) by t but not be able to use it to replace the (findpos e x) at (3) by t. You know you can replace equals by equals. But sometimes you can replace propositional equivalents by propositional equivalents, without changing the value of the expression. In this section we discuss how to use iff as though it were equal in certain situations. In particular, suppose you know α is propositionally equivalent to β and you want to use that fact by replacing some occurrence of α in γ by β – and you do want to maintain the value of γ. That is, you want the value of γ to be unchanged after the replacement. You will often analyze a program’s source text and rearrange it while maintaining the pro- gram’s value (or some other property). You may never do the exact analysis we discuss here because few high-level programming languages allow non-Booleans to be used as Booleans the way Lisp does. But the kind of thinking we need is roughly “If I do this, could it change the value of the program?” and that kind of thinking is absolutely fundamental to code maintenance, efficiency, and addition of new features. It is useful to practice this thinking in a setting as simple as this one. Suppose that after we do the replacement in γ we get γ′. There are two senses of “maintain- ing” the value of γ. One sense is that the value of γ is equal to the value of γ′. The other sense is that the value of γ is iff the value of γ′. The latter sense is called propositional equivalence. Two terms, γ and γ′, are propositionally equivalent if either they both return nil or they both return non-nil. But when they return non-nil, they may return different things, e.g., one might return "Error" and the other might return 23, but those two things are indistinguishable to the basic “Boolean” test functions like if, and, etc. Note: Throughout this booklet, we use the phrase “propositionally equivalent” to mean the sense of equivalence tested by iff. We will use the word “equal” when we mean strict identity as tested by equal. Pay attention because they’re different! We saw an example of maintaining equal in the example above when, we contemplated replacing occurrence (2) of (findpos e x) by t, even though we know its value is a natural number. Furthermore, if we replaced occurrence (3) of (findpos e x) by t, γ′ might not have the same value as γ. So this notion of replacement of propositional equivalents by propositional equivalents has something to do with where the terms appear in γ. That’s why we need addresses into terms (see Question 105). Reconsider the term: (if (findpos e x) Need for Logic 41 (if (and (findpos e x) (natp b)) (+ (findpos e x) b) nil) . . .) • Question 121: What is the address of the first (findpos e x)? What is the address of the second? What is the address of the third? • Suppose we replace an occurrence of α at address π in some formula γ by β to get γ′. If the values of γ and γ′ are equal then we say the replacement maintains equal. If γ and γ′ are propositionally equivalent, then we say the replacement maintains iff. If α and β are equal, then of course γ and γ′ are equal and also propositionally equivalent. But if α and β are only propositionally equivalent, then we need to know something about π to be sure that γ and γ′ are equivalent in whatever sense we mean. Here’s an example. I’ll be really concrete. Think of (and a b) as α and (and b a) as β. They are propositionally equivalent but not equal. • Question 122: Show values for a and b so that (and a b) evaluates to something different than (and b a). • Let γ: (if (and a b) (and a b) (f (and a b))) γ1: γ2: γ3: (if (and b a) (if (and a b) (if (and a b) (and a b) (and b a) (and a b) (f (and a b))) (f (and a b))) (f (and b a))) Notice α occurs at three addresses in γ: (1), (2), and (3 1). We produce γ1 by replacing the first occurrence of α in γ by β, we produce γ2 by replacing the second occurrence, and we produce γ3 by replacing the third occurrence. Note that the first replacement maintains equality. That is, no matter what values we choose for a and b and no matter what the function f does, γ and γ1 always return the same value. The second replacement maintains propositional equivalence: no matter what values we choose for a and b and no matter what f does, the value returned by γ is propositionally equivalent to that returned by γ2, even though they may not be equal. • Question 123: Show values of a and b such that (equal γ γ2) evaluates to nil but (iff γ γ2) evaluates to t. • Finally, note that we can’t be sure the third maintains either equal or iff! • Question 124: Define an f and give values for a and b so that γ and γ3 evaluate to propositionally different constants, e.g., one evaluates to t and the other evaluates to nil. • So there are two questions: What do we have to know about address π in γ to insure that the replacement of α by a propositionally equivalent β maintains equality? What do we have to know to insure that it maintains propositional equivalence? Some observations may help you see how to answer this question. 42 A Little Logic Observation 1: If π points to the argument of some arbitrary function, e.g., f above, then the only way we can guarantee the maintenance of either equality or propositional equivalence is to insist that α is equal to β. Observation 2: If π points to the test of an if, then we can allow α to be merely proposi- tionally equivalent to β and still guarantee that γ is equal to γ′. Observation 3: If π points to the output branch of an if, then γ is equivalent to γ′ in whatever sense that α is equivalent to β. That is, (if x α z) is propositionally equivalent to (if x β z) provided α is propositionally equivalent to β. Of course, if α is equal to β then the two if expressions are equal. Observation 4: When π points to the arguments of not, implies, and iff, then the propo- sitional equivalence of α and β insures the equality of γ and γ′. That is, if (iff α β) is true, then the following are also all true: (equal (not α) (not β)) (equal (implies α y) (implies β y)) (equal (implies x α) (implies x β)) (equal (iff α y) (iff β y)) (equal (iff x α) (iff x β)) Observation 5: If π points to the first argument of an and, then (iff α β) insures that (equal (and α y) (and β y)). But the most we can say about the second argument of an and is that (iff α β) insures that (iff (and x α) (and x β)). Observation 6: If π points to the first or second argument of an or, then the most we can say is that (iff α β) insures that (iff (or α y) (or β y)) and (iff (or x α) (or x β)). • Question 125: Show an a and b that are propositionally equivalent but such that (or a y) is unequal to (or b y). • • Question 126: Show an a and b that are propositionally equivalent but such that (or x a) is unequal to (or x b). • Putting all these observations together we can define a new concept: Let π be a legal address in γ, let α and β be two terms, let α be at address π in γ, let γ′ be obtained by replacing α at π in γ by β, and finally, let eqv be some sense of equivalence (either equal or iff). What sense of equivalence (iff or equal) must hold between α and β in order for us to know that γ is eqv to γ′? We call this the equivalence admitted by π to maintain eqv in γ. It can be computed with (eqv@ π γ eqv), where (defun eqv@ (a x eqv) (cond ((endp a) eqv) ((equal (car x) ’IF) (eqv@ (cdr a) (nth (car a) x) (if (equal (car a) 1) ’iff eqv))) ((equal (car x) ’AND) (eqv@ (cdr a) (nth (car a) x) (if (equal (car a) 1) ’iff eqv))) ((equal (car x) ’OR) (eqv@ (cdr a) (nth (car a) x) Need for Logic 45 • Question 133: Write an ACL2 expression that tests Distributivity of and over or (the first Distributivity formula). • A tautology is a propositional formula that evaluates to t for all combinations of Boolean values for its variables. All of the identities given above are tautologies. • Question 134: Define the function tautp that takes a propositional formula p and eval- uates it on all possible interpretations of its variables. Hint: See Question 98 for a function to collect all the variables in a propositional formula, see Question 90 for a function to make all combinations of n objects taken from the list (nil t), see Question 69 for a function to produce an interpretation from a list of variables and a list of corresponding values, and see Question 107 for a function to evaluate a propositional formula on an interpretation. • • Question 135: Write an expression to test all of the familiar identities. You may define functions to help you if you wish. • Furthermore, since they hold for all possible objects, we can replace the variables above by arbitrary expressions and still have true identities. For example, not only is (not (not p)) propositionally equivalent to p, but (not (not (mem e x))) is propositionally equivalent to (mem e x) and (not (not (and a b))) is propositionally equivalent to (and a b). •Question 136: Below are two columns of expressions labeled A and B. For each expression in column A, find an expression in column B that is propositionally equivalent to it or else note that no expression in column B is equivalent. When an equivalent expression is found, write down the number of the equivalent expression and the name of the familiar identity that establishes their equivalence. A1: (not (not (consp a))) B1: (and (consp x) (not (equal x y))) A2: (or (not (mem e a)) (mem e (append a b))) B2: (consp a) A3: (not (and (or a b) c)) B3: (and (and (or a b) c) d) A4: (or (and x y) (and x z)) B4: (or (not (or a b)) (not c)) A5: (not (or (cons x) (natp x))) B5: (implies (consp x) (natp x)) A6: (implies (consp x) B6: (or (mem e (append a b)) (not (natp x))) (mem e a)) A7: (and (or a b) (and c d)) B7: (and x (or y z)) A8: (not (implies (consp x) B8: (implies (mem e a) (equal x y))) (mem e (append a b))) A9: (and (or (consp x) (and p q)) B9: (implies (not (not (natp x))) (or (consp x) r)) (not (consp x))) B10: (or (consp x) (and (and p q) r)) B11: (or (and a b) (consp x)) • 4 Logic Earlier we said “So it remains to show you the axioms of Lisp and the rules of inference. But to do that we have to be able to speak very precisely about terms and formulas.” So now we review the terminology (and introduce a few new ideas), then we present the axioms and the rules of inference of Lisp. 4.1 Preliminaries We have already introduced several very important concepts for stating the rules of inference: the concept of a legal address into a term or formula and the concept that an address admits propositional replacement. We now describe some others. Recall from Questions 113 and 114 the notions of a substitution and how to apply a substi- tution σ to a term α, written α/σ. We say a substitution instantiates the variables in its domain. Also recall the notation of substitutions, {v1 ← α1, . . . , vk ← αk} to indicate that when applied the vi are replaced by the αi. If there is a substitution σ such that γ/σ is δ then we say that δ is an instance of γ. When we say α′ is a σ instance of α we mean that σ is the substitution that shows that α′ is an instance of α, i.e., α′ is α/σ. • Question 137: Is (rev1 (cdr x) (cons a b)) an instance of (rev1 x a)? • • Question 138: Is (rev1 (cdr x) (cons a b)) an instance of (rev1 x (cdr a))? • • Question 139: (mem (car a) (unn (int a b) (diff c d))) is a σ instance of (mem e (unn x y)). What is σ? • Recall from Questions 108 and 109 the conjuncts and disjuncts lists of a term. Now suppose you’re simplifying some “target” term and you know that (equal lhs rhs) is true. How might you know (equal lhs rhs) is true? One way is that you have it as a hypothesis that governs the term you’re simplifying. Another is that it is a theorem you’ve already proved. Another is that it is an instance of a theorem you’ve already proved. In any case, suppose you know that (equal lhs rhs) is true. Given that you know it, how can you use it to simplify the target? Intuitively, you could use it to replace lhs by rhs. Or you could replace rhs by lhs. Suppose that instead of (equal lhs rhs) you know (iff lhs rhs). How could you use it? You could replace lhs by rhs (or vice versa) in any context that admits propositional replacement. Similarly, you can use (not lhs) to rewrite lhs to nil in any context where we know (not 50 A Little Logic For example, one of our rules of inference allows us to use a hypothesis to rewrite the conclusion of a goal. But what do we do if we want to use a hypothesis to rewrite another hypothesis? In formula (1) below, suppose we want to use a to change c to c’. (Suppose such a thing is logically possible.) Our rule allows this by permitting a factoring at the beginning and a refactoring at the end. The idea is to factor (1) to move c into the conclusion, use the rule to change it to c’, and then use refactoring to “put c’ back.” Here is the whole sequence: (implies (and (and a (not b)) c) d) (1) Factor (1) to move c into the conclusion: (implies (and a (and (not b) (not d))) (not c)) (2) Use hypothesis a to reduce c to c’: (implies (and a (and (not b) (not d))) (not c’)) (3) Refactor (3) to get: (implies (and (and a (not b)) c’) d) (4) Our rule of inference for using a hypothesis allows us to transform (1) into (4) in one step. You will find CS life a lot easier if you can look at formula and see it in whatever guise you need to to use it as your intuitions tell you it can be used. 4.2 Syntax Now for a shocking revelation: most computer scientists do not use ACL2 notation! We’ve stuck to ACL2 notation so far because it makes it easier (I think) for you to understand such ideas as how to do substitution, address a subterm, factor a formula into a certain forms, etc. But now it is time to learn the traditional notation. Most computer scientists write in “infix” notation, writing x+y instead of (+ x y). You’re familiar with infix notation for addition (+), subtraction (−), multiplication (×), and divi- sion (/), as well as equality (=) and dis-equality (6=) and the standard inequalities (<, ≤, ≥, and >). You are free to use them on your homeworks. Please understand that the ACL2 system does not accept them! The familiar notation, e.g., “x+ y”, is an example of what computer scientists call concrete syntax. It is the syntax of the “source language.” The ACL2 notation, e.g., “(+ x y)”, is an example of abstract syntax. It is the deep, underlying syntactic structure of the utterance. Typically, the concrete syntax provides all sorts of conveniences while the abstract syntax is very regular and uniform. For example, in traditional concrete syntax one might write “x+y”, “xy”, and “mod(x, y)” where the corresponding abstract syntactic structures would be “(+ x y)”, “(expt x y)”, and “(mod x y).” Note that the concrete syntax varies wildly: the operator (the function symbol) is written between the operands, the operator is not written at all (!), or the operator is written before the operands, depending on what the operator is. But regardless of the concrete syntax, the abstract syntax is very similar: a operator followed by its arguments, enclosed in a pair of parentheses. Logic 51 In ACL2 the concrete and abstract syntax are the same! Even though ACL2 doesn’t accept infix notation, I will use it interchangeably with ACL2 notation in this course. I may well write, (x+ (6× y)) 6= j to mean (not (equal (+ x (* 6 y)) j)). Note how “ 6=” turns into an equal expression embedded in a not. We will always give our terms the meaning that ACL2 gives them. So you should not be surprised if I say nil+ 6 = 6. We hope such weird expressions don’t arise! But if they do, don’t argue with me about what they mean! Infix notation is just shorthand for ACL2 and infix expressions mean whatever ACL2 says their ACL2-translations mean! Computer scientists use a lot more symbols than the arithmetic ones you’ve seen before. We will also start to use those symbols and infix notation. Sometimes people will use other symbols for these connectives and we show common alternatives below. If someone uses a symbol you don’t recognize, ask them what it means! In this booklet, we’ll either write in ACL2 or we will use the infix column of symbols and write in infix. name ACL2 infix other alternatives truth t True 1 falsity nil False 0 conjunction (and p q) (p ∧ q) (p * q) (p & q) (p && q) disjunction (or p q) (p ∨ q) (p | q) (p || q) negation (not p) (¬p) (∼ p) p (- p) (! p) implication (implies p q) (p→ q) (p ⊃ q) (p⇒ q) (p --> q) (p ==> q) if-and-only-if (iff p q) (p↔ q) (p ≡ q) (p <--> q) (equivalence) exclusive-or (xor p q) (p⊕ q) Note Well: We do not use the other alternatives in these notes. It would be really ambiguous to sometimes write t as 1 because they’re different objects! But you may well have professors that write 1 and 0 as True and False or use (p && q) instead of (p ∧ q), etc. We either use the ACL2 syntax or the infix syntax, or a mixture of both. In the rest of these notes, we may well write the propositional formula (implies (and p (or q (not r))) (iff u v)) as (p ∧ (q ∨ ¬r)) → (u ↔ v). We tend to use parentheses only as necessary to indicate structure. The negation sign “binds” most closely. That is, ¬A∧B means (¬A)∧B rather than ¬(A ∧ B). If you have doubts about how to parse an infix formula in these notes, please ask. You should just get used to the idea that “(p∧ q)→ r” is an often-used concrete syntax for the abstract syntax “(implies (and p q) r).” I think of the former as merely a way to display the latter. The truth values (more commonly called Booleans) are True and False. In these notes when I write infix formulas, I’ll use True and False as synonymous with t and nil, respectively.1 • Question 140: Write the infix form of the propositional formula. 1In ACL2, t is a different symbol from True. But note the font difference between ACL2’s symbol True and True, my abbreviation for the symbol t in infix formulas. 52 A Little Logic (iff (not (and p q)) (or (not p) (not q))) • • Question 141: Write the infix form of the propositional formula. (implies (and (not c) (implies (implies b (not c)) a)) (implies (implies a c) nil)) • • Question 142: Write the ACL2 form of the following propositional formula. ((p→ q) ∧ (q → r))→ (p→ r) • • Question 143: Write the ACL2 form of the following propositional formula. ((B → ¬C)→ A)↔ ((¬A→ B) ∧ (¬A→ C)) • • Question 144: Write the ACL2 form of (p ∨ ¬p)↔ True. • • Question 145: What is the conjuncts list of a ∧ ((b ∨ c) ∧ ¬d)? • • Question 146: Is (a∧ (b∨ c))→ (a→ b) a σ instance of (p∧ q)→ r? If so, what is σ. If not, why? • • Question 147: Let σ be the substitution {x ← (a + b), y ← c, z ← (i × j)}. Let α be x+ 2× y ≤ 25× z. What is α/σ? • • Question 148: If σ is the substitution {p ← (CONSP A), q ← (CONSP (APPEND X Y))} what is (p→ q)/σ? • • Question 149: Factor (a ∧ b)→ c so that the conclusion is ¬a. What is the hypothesis? • • Question 150: Factor ((a ∧ b) ∧ (¬(p ↔ q)))→ c so the conclusion is (p ↔ q). What is the hypothesis? • • Question 151: Factor (rev (append a b)) = (append (rev b) (rev a)) so that the pattern is (append (rev b) (rev a)). What is the replacement? What is the maintained relation? • • Question 152: Factor (ordp (isort x)) so that the pattern is (ordp (isort x)). What is the replacement? What is the maintained equivalence? • •Question 153: Factor (evenp (+ x y))↔ ((evenp x)∧(evenp y)) so that the pattern is (evenp (+ x y)). What is the replacement? What is the maintained equivalence? • • Question 154: Factor ¬(clausep x) so the pattern is (clausep x). What is the replacement? What is the maintained equivalence? • • Question 155: Factor (rev (rev x)) = x so that the pattern is (rev (rev x)) = x. What is the replacement? What is the maintained equivalence? • Technically, in the next section, we ought to include axioms for the symbol = (equal). But we assume you know about equality. The key facts about equality (that aren’t written elsewhere here) are:  The function symbol equal is Boolean, it returns t or nil. Logic 55 Axiom Schema type: (symbolp ’sym) = t for every symbol object sym. Axiom Schema type: (consp ’x) = t for every ordered pair object x. Second, we give ourselves axioms asserting that distinct constants are unequal. We refer to all these axioms by the name distinct-constants. Axiom Schema distinct-constants: ’c 6= ’d, where c and d are constants that print differently when using standard notation for numbers and full dot notation for ordered pairs. Thus, for example, distinct-constants tells us that ’t 6=’nil and ’17 6=’23 as well as ’17 6=’(A B). Of course, these are just abbreviations for t 6=nil, 17 6=23, and 17 6=’(A B). Because of the schema’s requirement on the standard (canonical) notations, we are not “fooled” into thinking that 017 6=17 or ’(0 1) 6=’(0 . (1 . nil)). Finally, every defun introduces an axiom. Definitional Axiom Schema: Any admissible definition of the form (defun f (v1 . . . vn) β) introduces the definitional axiom: Def Ax f : (f v1 . . . vn) = β. Recall that the definitional principle has four conditions for admissibility. Only three have been presented so far. We present the fourth one later. But all of the functions definable with the definition patterns are admissible and you should think of us as having an axiom for every such definition we’ve made so far. We may add additional axioms later. 4.4 Rules of Inference I wrote this section succinctly – no cluttering examples – so you could come back to it again and again as a reference manual. I recommend you put a bookmark here and refer back every time we use an inference rule until you know them cold! Each Rule of Inference tells you how to reduce a goal, ψ, to a new goal, ψ′, while preserving propositional equivalence. Thus, if a rule is applied correctly, ψ ↔ ψ′ is true. We will see that “↔” (iff) is transitive. So if you can get a chain of reductions: ψ ↔ (by Rule1) ψ1 ↔ (by Rule2) . . . . . . ↔ (by Rulek) ψk 56 A Little Logic in which each step is justified by one of the Rules of Inference below, then you have reduced the formula ψ to ψk. It is also the case that the sequence of steps above is a proof of the formula ψ ↔ ψk. A proof of ψ is a reduction of ψ to True by a finite number of applications of the Rules of Inference below. Proofs may take many forms, but the one above is common. A Theorem is any axiom, definitional axiom, tautology, or formula that can be proved. Sometimes theorems are called by other names, including Lemma (a theorem proved in order to use it as a stepping-stone in another proof) and Corollary (a theorem whose proof follows easily from a theorem just proved). Rule of Inference Tautology (or Theorem) (“Taut” or “Thm”): Summary: This rule allows you to prove your goal ψ if it is an instance of a theorem φ. When φ is actually a tautology (a propositional formula that is true under all combinations of Boolean values for its variables, recall Question 134), we call this the Tautology rule. Otherwise, it is the Theorem rule. Description: If you can carry out all of the following steps: 1. find a theorem φ 2. find a substitution σ such that goal ψ is φ/σ then you may reduce ψ to True. End of Rule Rule of Inference Rewrite (“Re”): Summary: This rule allows you to rewrite part of the goal ψ using a previously established theorem (including an axiom or definition) φ. Description: If you can carry out all of the following steps: 1. factor the goal ψ into a hypothesis ψh and a conclusion ψc so that the term you wish to replace is in the goal’s conclusion ψc 2. let π be the address in ψc pointing to the subterm you want to replace 3. factor the previously proved theorem φ into a hypothesis φh and conclusion φc 4. factor φc into pattern α, replacement β, and maintained equivalvence eqv such that the term you want to replace (at π in ψc) is an instance of α under some substitution σ 5. if eqv is iff, confirm that address π admits a propositional replacement in ψc 6. prove ψh → (φh/σ) 7. obtain ψc′ by replacing the term at π in ψc by β/σ then you may reduce ψ to any refactoring of ψh → ψc′. End of Rule Note: Step 6 is called relieving the hypotheses of the theorem φ. Rule of Inference Hypothesis (or “Hyp”): Logic 57 Summary: This rule allows you to use one of the hypotheses of the goal ψ by replacing some term in its conclusion with an equivalent term. Description: If you can carry out all of the following steps: 1. factor the goal ψ into a hypothesis ψh and a conclusion ψc 2. let δ be one of the conjuncts of ψh (a hypothesis of goal ψ) 3. factor hypothesis δ into pattern α, replacement β, and maintained equivalence eqv 4. let π be an address in ψc at which you find α 5. if eqv is iff, confirm that address π admits a propositional replacement in ψc 6. obtain ψc′ by replacing the term at π in ψc by β then you may reduce ψ to any refactoring of ψh → ψc′. Warning: Unlike Rewrite, the Hypothesis rule does not allow you to instantiate α! There is no substitution σ in this rule! End of Rule Rule of Inference Cases (“Cases”): Summary: This rule allows you to prove ψ by splitting the proof into several cases. The case-split is justified by some theorem φ which establishes that all possibilities have been considered. Description: If you can carry out all of the following steps: 1. choose some theorem φ 2. let σ be a substitution that instantiates the variables of theorem φ 3. let φ′1, φ ′ 2, . . . φ ′ k be the disjuncts of φ/σ 4. prove φ′i → ψ, for each 1 ≤ i ≤ k then you may reduce ψ to True End of Rule Rule of Inference Constant Expansion (“Const”): Summary: This rule allows you to replace certain constants by function calls, or vice versa. There are several variants. Description of Variant 1: If you can carry out both of the following steps: 1. let π be a legal address in ψ that points to the list constant term ’(c1.c2) 2. let ψ′ be the result of replacing the term at address π in ψ by (cons ’c1 ’c2) then you may reduce ψ to ψ′ (and vice versa). Description of Variant 2: If you can carry out both of the following steps: 60 A Little Logic miliar tautologies! But ok, because others will expect it of you, I’m going to show you a few truth tables and expect you to be able to do more. To make a truth table, set up a column for each variable and each subformula, building up to the formula you want to check. That formula is in the far right-hand column. Then make a row for every combination of values of the variables. Then calculate and write into the cells the values of the respective subformulas in the corresponding cells. For brevity it is conventional to use T and F instead of True and False. Here is the truth table for one of the Basic tautologies, “(p ∧ q)→ p.” p q (p ∧ q) (p ∧ q) → p T T T T T F F T F T F T F F F T Notice how the first two columns show all combinations of truth values for p and q. Notice how the last column shows the truth value “(p∧q)→ p. And notice how the value in the last column is always T . The formula is True under all combinations of values for its variables. It is a tautology. Here is a non-tautology. p q (p ∨ q) (p ∧ q) (p ∨ q) → (p ∧ q) T T T T T T F T F F F T T F F F F F F T Note that the last column contains some Falses. This formula is not a tautology. • Question 156: The formula checked above is the converse of one of our well-known tautologies. Which one? • Here is the last one of these boring things I’m going to do! Below is a truth table to show that the transitivity of implication is really a tautology. P Q R (P → Q) (Q → R) ((P → Q) ∧ (Q → R)) (P → R) (((P → Q) ∧ (Q → R)) → (P → R)) T T T T T T T T T T F T F F F T T F T F T F T T T F F F T F F T F T T T T T T T F T F T F F T T F F T T T T T T F F F T T T T T • Question 157: If you have a formula with n different variables in it, how many rows do you need in its truth table? • • Question 158: A femtosecond is 10−15 seconds. In order to perform one operation per femtosecond a sequential processor would have to operate at one million gigahertz – so a femtosecond is a very fast cycle length! Suppose you could fill in all the cells in one row of a given truth table in 1 femtosecond. Suppose the truth table was for a formula containing 1,000 propositional variables. About how long would it take to fill in the entire truth table? • Today we have industrial-strength tools that can easily check formulas containing hundreds of thousands of variables. Sometimes they can check formulas containing many millions of variables. Use of such tools is standard practice in the hardware industry: microprocessors are essentially just big propositional formulas connected by memory devices. I’ll explain Logic 61 that if you’re interested. How do people check propositional formulas with millions of variables? They do not do it with truth tables! 4.6 About the Rules of Inference In this section, I discuss the informal proof from section 3.1 again. I mimic the informal proof, but I’ll use the rules to carry out several of the “big steps” in that proof and I explain what I’m doing. I also do a couple of other proofs to illustrate the rules. Before reading this section, re-read the Rewrite rule of inference. We’re going to use it over and over again. You must know every part of these rules cold. The only reason I tediously explain how I use the rules is so you can see how they’re used. You will not be expected to explain your proofs in such tedious detail. But you ought to be able to, because if you don’t know every detail of the rules, you’ll probably use them incorrectly. Bad things can happen if you use an inference rule incorrectly. • Question 159: What “bad thing” can happen if you mis-use a rule of inference? • In the next section I present proofs in the succinct notation you’ll use most often. 4.6.1 An Exploration of Rewrite We want to prove: Theorem car-app: (equal (car (app a b)) (if (consp a) (car a) (car b))). We have the definitional axiom Def Ax app: (app x y) = (if (endp x) y (cons (car x) (app (cdr x) y))). Big Step 1: We’ll use the Rewrite rule to replace (app a b) by the body of app. The rule requires that we carry out seven steps. In this application of the rule, ψ is our main goal and π is an address that points to the subterm we want to replace. π ↓ (equal (car (app a b)) (if (consp a) (car a) 62 A Little Logic (car b))) We factor goal ψ into the True hypothesis (ψh) and the conclusion (ψc) shown above as ψ. Note that the term we want to rewrite is in the conclusion. The “previously proved theorem” φ we will use is the definitional axiom of app. We factor it into a hypothesis True (φh) and the equality conclusion shown in Def Ax app (φc). We further factor φc into the pattern (app x y), the replacement β: (if (endp x) y (cons (car x) (app (cdr x) y))) and the maintained equivalence equal. Note that the term at π in ψc is (app a b) and that is a σ instance of the pattern, with σ being {x← a; y← b}. Since the maintained equivalence is equal, we are not required to check that π admits a propositional replacement: we’re doing a replacement of equals by equals and we can do that anywhere. We have to prove that the hypothesis of our goal implies the hypothesis of the axiom we’re using. In this case, ψh → φh/σ is just True→ True. Can we prove that? Yes! Think of it in its ACL2 form: (implies t t). We can compute that it is equal to t. So the proof of this required theorem is just an application of the Computation rule of inference. So we obtain ψc′ by replacing the term at π in ψc by β/σ, which produces: ψc′: (equal (car (if (endp a) b (cons (car a) (app (cdr a) b)))) (if (consp a) (car a) (car b))) Having carried out all seven steps required by the Rewrite rule, we create True→ ψc′ and refactor it any way we want to obtain our new goal ψ′. In our case, ψ′ is just ψc′. That completes Big Step 1. Big Step 2 is to replace the (endp a) above by its definition. • Question 160: Explain how to take Big Step 2. • The result of Big Step 2 is ψc′: (equal (car (if (not (consp a)) b (cons (car a) (app (cdr a) b)))) (if (consp a) (car a) (car b))) Logic 65 Case 1′: a → (if (not t) b c) = (if a c b). By the Computation rule, (not t) is nil and we can reduce this to Case 1′′: a → (if nil b c) = (if a c b). We can then use Rewrite, with Axiom if-ax2: x = nil → (if x y z) = z. to reduce Case 1′′ to: Case 1′′′: a → c = (if a c b). This application of Rewrite is actually a little interesting, because it is the first time we’ve applied Rewrite on a theorem with a hypothesis. To make a long story short, step 6 of the statement of the Rewrite rule says we have to prove that True→ nil = nil. We’ve already seen how to prove that. To complete the proof of Case 1′′′ we have to simplify the other side of the equality, (if a c b). That is very similar: use the Hypothesis rule to replace the a by t and then rewrite with Axiom if-ax1. This time, the proof obligation incurred in step 6 of Rewrite is True→ t 6= nil. We could prove that by Computation. Now, I don’t write this stuff for my own entertainment. • Question 168: Prove Case 2 at a similar level of detail. • 4.6.3 Another Exploration of Rewrite Before moving on, let me show a non-trivial use of Rewrite. It is undoubtedly the most frequently used rule of inference in our collection. Suppose we know this is a theorem: φ: (true-listp x) → (rev (rev x)) = x. Suppose we’re trying to prove: ψ: ((true-listp a) ∧ (mem e (rev (rev (copy a))))) → (mem e a). We want to use φ to simplify the (rev (rev (copy a))) to (copy a). How do we do it? First, we factor ψ so the hypothesis ψh is ((true-listp a) ∧ ¬ (mem e a)) and the conclusion, ψc is ¬ (mem e (rev (rev (copy a)))). We do this because we must rewrite something in the conclusion. We’ll see why in a moment. The π we choose points to (rev (rev (copy a))) in ψc. We factor theorem φ into hypothesis, φh, (true-listp x) and conclusion φc (rev (rev x))=x. We further factor φc into pattern (rev (rev x)), replacement x, and maintained 66 A Little Logic equivalence equal. If we let σ be {x ← (copy a)}, then we see that φc/σ is (rev (rev (copy a))), which is indeed the term pointed to by π in ψc. Since the maintained equivalence is equal, we don’t have to check that π admits proposi- tional replacement. This brings us to step 6 of the use of Rewrite, the step in which we “relieve the hypotheses” of φ. We must prove ψh → (φh/σ): ((true-listp a) ∧ ¬ (mem e a)) → (true-listp (copy a)). We’re not in a position to prove this right now, but I wanted to write it down so you can get a feel for what step 6 is all about. The theorem φ, does not tell us (rev (rev x)) is equal to x! It tells us that (rev (rev x)) is equal to x provided (true-listp x). To use it to rewrite (rev (rev (copy a))) to (copy a), we must prove that (copy a) is a true-list. When we prove that, we get to use as hypotheses all the hypotheses that are known to be true at address π. That is why we factored ψ to put the target term in the conclusion!. If we could prove the theorem required by step 6, then we could rewrite the term at π to x/σ, which is (copy a). That would give us ψc′: ¬ (mem e (copy a)) But we’re not done yet! According to the Rewrite rule, we can return any refactoring of ψh → ψc′: ((true-listp a) ∧ ¬ (mem e a)) → ¬ (mem e (copy a)). We could return that very formula. But since we started with ψ: ((true-listp a) ∧ (mem e (rev (rev (copy a))))) → (mem e a) it would be nice to put things back where they were, by refactoring to ψ′: ((true-listp a) ∧ (mem e (copy a))) → (mem e a). Note that it looks like we used the Rewrite rule to rewrite one of our hypotheses. And we did! But we temporarily moved it into the conclusion so we could know what hypotheses we could use while relieving the hypotheses of φ in step 6. Then we put it back with the final refactoring. Of course, we haven’t finished the proof of ψ. To finish it, we’d have to prove ψ′ above. But I don’t do that here because I just wanted to illustrate the Rewrite rule of inference. 4.6.4 An Exploration of Constant Expansion Let’s prove that (car (cdr ’(A B C))) returns B. Of course, that’s easy by the Computa- tion rule. But I want to show you that we don’t need the Computation rule to work with list constants. We can use the Constant Expansion (“Const”) rule and axioms. Logic 67 Theorem (car (cdr ’(A B C))) = ’B. Proof: lhs = (car (cdr ’(A B C))) = {Const)} (car (cdr (cons ’A ’(B C)))) = {Const} (car (cdr (cons ’A (cons ’B ’(C))))) = {Re cdr-cons} (car (cons ’B ’(C))) = {Re car-cons} ’B = rhs 2 • Question 169: “Compute” the value of (app ’(A B) ’(C D)) by doing a proof, without using the Computation rule. • Computation is just the disciplined use of symbolic rewriting using the axioms and defini- tions. I included the Computation rule of inference for two reasons. First, I have revealed that list and natural number constants may be thought of as “constructed” by cons and + and I have provided axioms for how to manipulate expressions involving the constructor cons and its “destructors” car and cdr and its recognizer consp. But I have provided no axioms, yet, about how to manipulate expressions involving the constructor +, its “destructor” - (difference) or its “recognizer” zp. In the absence of such axioms, you have no way to prove that (+ 2 2) is 4 except by the Computation rule. And I’ve given no hint as to how the strings, symbols, rationals, etc., are “constructed”. The second reason I included the Computation rule is that while it is nice to know that computation is really just a particularly trivial kind of proof, it’s very convenient in proofs to just compute when you can. 4.7 Writing Proofs Down Computer scientists give proofs in many different notations. If a professor asks you to give a proof, let’s hope you’ve seen an example of his or her proof style! When writing a proof your goal is to make it clear to the reader that the formula is always true. Your goal is not to shoehorn your argument into some fixed format or to make the proof look like a secret language! You want the reader to understand your steps. Here are several proofs of car-app. They’re all identical in my opinion and I don’t care which style you adopt. Let’s prove: Theorem: (equal (car (app a b)) (if (consp a) (car a) (car b))). 70 A Little Logic Sometimes your proofs are clearer if you skip over some steps! Some professors would actually prefer a “proof sketch” like this: Theorem: (equal (car (app a b)) (if (consp a) (car a) (car b))). Proof 3: Use the definitions of app and endp to rewrite the left-hand side to (car (if (not (consp a)) b (cons (car a) (app (cdr a) b)))) Then rewrite with if-swap, car-if, and Axiom car-cons to get (if (consp a) (car a) (car b)) which is the right-hand side. 2 When you give a proof sketch like Proof 3, it is up to you to decide how big the steps can be. I’ve seen proof sketches like: Proof 4: Rewrite with the definitions of app and endp, the lemmas if-swap, and car-if, and Axiom car-cons to get an instance of x = x. 2 The trouble with such succinct sketches is that if you don’t explicitly name a lemma you used then the reader can’t follow it. But if you write some of the intermediate formulas, the reader might be able to figure out what you really did. This is important if your proofs are being graded! Here is a succinct but detailed proof of if-swap to illustrate Cases and Hyp steps. Theorem if-swap: (if (not a) b c) = (if a c b). Proof 5: Case 1: a → (if (not a) b c) = (if a c b). ↔ {Hyp (twice)} a → (if (not t) b c) = (if t c b). ↔ {Comp} a → (if nil b c) = (if t c b). ↔ {Re with Axiom if-ax2} a → c = (if t c b). ↔ {Re with Axiom if-ax1} Logic 71 a → c = c. ↔ {Re with Axiom equal-reflexive} a → True. ↔ {Re with Taut Short-Circuit} True Case 2: ¬ a → (if (not a) b c) = (if a c b). ↔ {Hyp (twice)} ¬ a → (if (not nil) b c) = (if nil c b). ↔ {Comp} ¬ a → (if t b c) = (if nil c b). ↔ {Re with Axiom if-ax1} ¬ a → b = (if nil c b). ↔ {Re with Axiom if-ax2} ¬ a → b = b. ↔ {Re with Axiom equal-reflexive} ¬ a → True. ↔ {Re with Taut Short-Circuit} True 2 This proof, as detailed as it is, omits certain simple steps, like relieving the hypothesis of Axiom if-ax1, which requires that we prove True → t 6= nil. I’m content to ignore the omission of such simple steps – computation on constants and uses of such things as the Basic and Short-Circuit tautologies. Eventually in this course, a proof like Proof 5 will be written really succinctly: “Case split on a and simplify.” But not yet! Another common notation for proof by cases is to write the hypotheses just once, when you say “Case” and then work on the original formula inside the case: Theorem if-swap: (if (not a) b c) = (if a c b). Proof 6: Case 1: a (if (not a) b c) = (if a c b). ↔ {Hyp (twice)} (if (not t) b c) = (if t c b). ↔ {Comp} (if nil b c) = (if t c b). ↔ {Re with Axiom if-ax2} c = (if t c b). ↔ {Re with Axiom if-ax1} c = c. ↔ {Re with Axiom equal-reflexive} True. Case 2: ¬ a (if (not a) b c) = (if a c b). ↔ {Hyp (twice)} 72 A Little Logic (if (not nil) b c) = (if nil c b). ↔ {Comp} (if t b c) = (if nil c b). ↔ {Re with Axiom if-ax1} b = (if nil c b). ↔ {Re with Axiom if-ax2} b = b. ↔ {Re with Axiom equal-reflexive} True. 2 Note that we didn’t keep writing “a→ . . .” or “¬ a → . . .” the way we did in Proof 5. This can save a lot of writing if you split on a big formula instead of a variable like a. Warning: There is a danger many students fall into when writing proofs this way. Suppose you want to prove φ and your plan is to case split on α and then manipulate φ by some series of justified steps to show it is true. Case 1 α φ ↔ { justification } . . . ↔ . . . T rue Case 2 ¬ α φ ↔ { justification } . . . ↔ . . . T rue 2 If you do this, remember that α (or ¬α in Case 2) is just another hypothesis of the formula. You can use α with the Hyp rule but not the Rewrite rule. In particular, you cannot instantiate α! We often take this notation even further. Suppose you’re trying to prove: (α1∧(α2∧α3))→ φ and you want to prove it by working just on φ. Often you’ll see such proofs written as below. Proof: Given H1: α1 H2: α2 H3: α3 Now I transform the conclusion to True. φ ↔ { justification } . . . ↔ . . . T rue 2 Logic 75 That is, in the future I’m going to use Associativity and Commutativity of “∧” and “∨” freely and implicitly. But I assume you can fill in the gaps! I’ll also use Double Negation freely and implicitly. Let’s prove the following tautology, without using a truth table. Theorem. (¬ C ∧ ((B → ¬ C) → A)) → ((A → C) → False) I don’t like thinking about implications involving implications, i.e., things of the form (p→ (q → r)) or of the form ((p→ q)→ r). The theorem above has subformulas of each of these two forms in it! I know that I can transform subformulas of the first form (p → (q → r)) to (p ∧ q) → r. This is called Promotion and is justified by a tautology of that name on page 58. This tranformation is good because it gets rid of an implication and gives me another hypothesis, q, to work with as I work on r. As for the other form, ((p→ q)→ r), there’s not a tautology in our list to handle it. But I can prove one. I’ll prove this as a lemma and then return to theorem. Lemma double-implies: ((p → q) → r) ↔ ((¬ r → p) ∧ (¬ r → ¬ q)) Proof: I will transform the left-hand side into the right-hand side. lhs = ((p → q) → r) ↔ {Re Implicative Disjunction} ((¬ p ∨ q) → r) ↔ {Re Implicative Disjunction} (¬ (¬ p ∨ q) ∨ r) ↔ {Re De Morgan} ((p ∧ ¬ q) ∨ r) ↔ {Re Distributivity} ((p ∨ r) ∧ (¬ q ∨ r)) ↔ {Implicative Disjunction (twice)} ((¬ r → p) ∧ (¬ r → ¬ q)) = rhs 2 • Question 173: Show a step in the proof above in which Commutativity was used implic- itly. • • Question 174: Show a step in the proof above in which Double Negation was used implicitly. • Now let’s return to the theorem we were working on. Theorem. (¬ C ∧ ((B → ¬ C) → A)) → ((A → C) → False) Proof: (¬ C ∧ ((B → ¬ C) → A)) → ((A → C) → False) ↔ {Re double-implies} (¬ C ∧ (¬ A → B) ∧ (¬ A → C)) → ((A → C) → False) 76 A Little Logic ↔ {Re Promotion} (¬ C ∧ (¬ A → B) ∧ (¬ A → C) ∧ (A → C)) → False ↔ {Re Contraposition} (¬ C ∧ (¬ A → B) ∧ (¬ C → A) ∧ (A → C)) → False ↔ {Re Forward Chaining} (¬ C ∧ (¬ A → B) ∧ A ∧ (A → C)) → False ↔ {Re Forward Chaining} (¬ C ∧ (¬ A → B) ∧ A ∧ C) → False ↔ {Re Contraposition } ((¬ A → B) ∧ A ∧ C) → C ↔ {Taut Basic} True 2 • Question 175: Explain what really happened on the first Forward Chaining step in the proof above. • You will be expected to be able to explain any step in a proof. Now we will prove our theorem again, only this time we will use case analysis too. Theorem. (¬ C ∧ ((B → ¬ C) → A)) → ((A → C) → False) Proof: Case 1 C: (¬ C ∧ ((B → ¬ C) → A)) → ((A → C) → False) ↔ {Hyp Case 1} (¬ True ∧ ((B → ¬ True) → A)) → ((A → True) → False) ↔ {Comp} (False ∧ ((B → ¬ True) → A)) → ((A → True) → False) ↔ {Re Short-Circuits} True Case 2 ¬ C: (¬ C ∧ ((B → ¬ C) → A)) → ((A → C) → False) ↔ {Hyp Case 2} (¬ False ∧ ((B → ¬ False) → A)) → ((A → False) → False) ↔ {Comp} (True ∧ ((B → True) → A)) → ((A → False) → False) ↔ {Re Short-Circuits} (True ∧ (True → A)) → ¬ A → False ↔ {Re Short-Circuits} A → A ↔ {Re Basic} True 2 Note that when I used the Hyp rule I cited “Case 1” or “Case 2” meaning I used the hypothesis introduced by that case. The repeated uses of Short-Circuit and Computation are so monotonous that I’ll frequently abbreviate them as “Prop Simp” meaning propositional simplification. I show intermediate steps only so you can follow along. I recommend that you show intermediate steps when you do it too. Here’s that same proof, somewhat more succinctly. Logic 77 Theorem. (¬ C ∧ ((B → ¬ C) → A)) → ((A → C) → False) Proof: Case 1 C: (¬ C ∧ ((B → ¬ C) → A)) → ((A → C) → False) ↔ {Hyp Case 1} (¬ True ∧ ((B → ¬ True) → A)) → ((A → True) → False) ↔ {Prop Simp} True Case 2 ¬ C: (¬ C ∧ ((B → ¬ C) → A)) → ((A → C) → False) ↔ {Hyp Case 2} (¬ False ∧ ((B → ¬ False) → A)) → ((A → False) → False) ↔ {Prop Simp} (True ∧ (True → A)) → (¬ A → False) ↔ {Prop Simp} A → A ↔ {Re Basic} True 2 By doing a case analysis on the “right” variable you can sometimes drastically simplify the two formulas you have to prove. Doing it on the “wrong” variable can help very little. •Question 176: Prove the theorem just proved again, by doing a case analysis on A instead of C. • Software systems designed to recognize tautologies containing thousands or millions of vari- ables use a combination of case splitting and rewriting. 4.8 Practice Proofs When I state a question as a formula, I mean for you to prove it or exhibit a falsifying assignment: concrete values for the variables that make the formula evaluate to false. When I follow a question’s number with a symbol, that symbol is the name I’ll use for that formula later. I find the names easier to remember than the numbers. In this section, please write your proofs at the level of detail shown in Proofs 1, 2, 5, and 6 of the previous section. In your proofs you may use any of the previously mentioned theorems by name (or number). You may wish to state and prove lemmas to help simplify your proofs. But do not use truth tables below. If you want to prove a tautology, do it symbolically, by using other tautologies to rearrange formulas. The unfamiliar function symbols, f, g, etc., may be assumed to be legitimate functions of the appropriate arity; you just don’t know their definitions. For your convenience, at the end of the section I’ve included the definitions of the defined functions mentioned below. • Question 177: (if-t) (if t x y) = x • • Question 178: (if-nil) (if nil x y) = y • 80 A Little Logic • Question 204: ((A → (B ∨ C)) ∧ (D → A)) → (B ∨ (D → C)) • • Question 205: ¬ (consp a) → (app (app a b) c) = (app a (app b c)) • • Question 206: ((consp a) ∧ (app (app (cdr a) b) c) = (app (cdr a) (app b c))) → (app (app a b) c) = (app a (app b c)) • • Question 207: ((a = b) ∧ ((p a) → (f a) = (g a))) → ((p b) → (h (f b)) = (h (g b))) • • Question 208: ¬ (consp a) → ((true-listp a) → (rev (rev a)) = a) • • Question 209: ((consp a) ∧ ((true-listp a) → (rev (rev a)) = a)) → ((true-listp a) → (rev (rev a)) = a) • Here are the relevant definitions. (defun endp (x) (not (consp x))) (defun app (x y) (if (endp x) y (cons (car x) (app (cdr x) y)))) (defun mem (x y) (if (endp y) nil (if (equal x (car y)) Logic 81 t (mem e (cdr y))))) (defun true-listp (x) (if (consp x) (true-listp (cdr x)) (equal x nil))) (defun rev (x) (if (endp x) nil (app (rev (cdr x)) (cons (car x) nil)))) Structural Induction 85 lhs = (f x) = {Def Ax f} (if (consp x) (f (cdr x)) t) = {Hyp Step and Re if-t} (f (cdr x)) = {Hyp IH1} t = rhs. 2 Note that you get one induction hypothesis for each σi and you can assume as many as you’d like, as long as they’re all car/cdr substitutions on your chosen variable. 5.2 Advice About Induction When you write a proof by induction, always name the variable you’re inducting on and always write down all of the induction hypotheses in full! Let me illustrate the most common mistake students make when they do induction. Suppose you want to prove: ψ: (app x nil) = x Informally, this is the statement that “nil is a right identity for app.” We’ll induct on x to “unwind” the recursive function app, which is defined as (defun app (x y) (if (endp x) y (cons (car x) (app (cdr x) y)))) That means we let σ be {x← (cdr x)}. The Base Case is: (endp x) → (app x nil) = x since (endp x) is ¬(consp x). Simplifying (app x nil) we get (endp x) → nil = x Can we prove this? Clearly not! A counterexample to this goal is x = 7, because (endp 7) is true but nil 6= 7. In fact, x = 7 is a counterexample to our proposed theorem, (app x nil) = x. So much for that attempt! 86 A Little Logic Learning from this failed proof attempt, we think to ourselves: “Ok, nil is not a right identity for app when x is empty!” and then decide to prove instead “nil is a right identity for app provided x is non-empty.” ψ: (consp x) → (app x nil) = x. We’ll induct on x again with the same σ. Now the Base Case, (endp x) → ψ, is trivial: (endp x) → ((consp x) → (app x nil) = x), because it becomes (¬(consp x) ∧ (consp x)) → (app x nil) = x, which is a tautology because the hypotheses contradict one another. So onto the Induction Step and the fatal mistake many students make. The correct induction step is to prove ((consp x) ∧ ψ/σ)→ ψ. But many students set it up incorrectly, this way: Bogus Induction Step: (consp x) ∧ (app (cdr x) nil) = (cdr x) {IH} → (app x nil) = x. We can prove this by expanding the (app x nil) in the conclusion and rewriting the x on the right-hand side of the conclusion to express it as a cons. The result is Bogus Induction Step: (consp x) ∧ (app (cdr x) nil) = (cdr x) {IH} → (cons (car x) (app (cdr x) nil)) = (cons (car x) (cdr x)). Then, because we know two conses are equal iff their cars and cdrs are equal, we can reduce this to Bogus Induction Step: (consp x) ∧ (app (cdr x) nil) = (cdr x) {IH} → (app (cdr x) nil) = (cdr x), which is a tautology because the simplified conclusion is the Induction Hypothesis IH. So it seems we proved ψ: (consp x) → (app x nil) = x. Structural Induction 87 But surprise! This ψ is not a theorem either! Test it for x = ’(1 . 7). The hypothesis is true and the conclusion becomes ’(1 . nil) = ’(1 . 7), which is false. So how did we prove a non-theorem? We screwed up the Induction Step. Here is the correct setup for the induction step: Correct Induction Step: (consp x) ∧ ((consp (cdr x)) → (app (cdr x) nil) = (cdr x)) {IH} → ((consp x) → (app x nil) = x). The key observation is that ψ is the formula ψ: (consp x) → (app x nil) = x. But in the bogus setup, we acted like ψ was (app x nil) = x. • Question 212: Can you prove the Correct Induction Step? If so, do it. If not, why not? • This mistake can be avoided if you follow the advice I gave at the beginning of the section: “When you write a proof by induction, always name the variable you’re inducting on and always write down all of the induction hypotheses in full!” The induction step is always (consp x) ∧ ψ/σ1 . . . ψ/σk → ψ. Don’t forget that. Remember, each Induction Hypothesis is an instance of the entire formula ψ, not some part of it! If you forget this you can “prove” non-theorems. Here is some heuristic advice about inductions. When doing an inductive proof, identify some function in ψ that you want to “unwind.” We picked app above, because it was the only function. The function you choose should be “controlled” by the variable, v, that you choose. We picked x. Then provide as many induction hypotheses as there are recursive calls of that function in its definition. Make your substitutions map your variable v to the exact car/cdr nests in the definition. And we provided one substitution, σ, mapping x to (cdr x) because (app x nil) recurs to (app (cdr x) nil). By doing this, you will provide yourself with an induction hypothesis about every recursive call of the function you’re unwinding. Then, in the Base Case and the Induction Step, unwind your function, use the hypotheses controlling the function to simplify what you get, and then use your induction hypotheses. 5.3 Practice Proofs Below are some recursive definitions. Some are very interesting programs and the theorems below state some very important properties of these programs. You might learn some valuable lessons about programming by studing these definitions and playing with them with ACL2. Prove each of the theorems stated in the questions. Some relevant definitions are shown at the end of this section. You might have to prove some lemmas to prove some of these.
Docsity logo



Copyright © 2024 Ladybird Srl - Via Leonardo da Vinci 16, 10126, Torino, Italy - VAT 10816460017 - All rights reserved