Equational Reasoning Math Foundations of Computer Science
Topics Review of propositional calculus Decision procedure Finite number of test cases Generating counter examples Deduction Reasoning about programs Properties of equals Definitional axioms and input contracts Input contracts Testing conjectures Formal proofs
Objective To provide a formal system for reasoning about programs using logical deduction and equational reasoning
Propositional Calculus There is a decision procedure for determining the validity/satisfiability of a formula from the propositional calculus Truth table Only need to check a finite number of cases! Can find counter example if not valid Can also use deduction to derive formulas from other formulas Soundness and Completeness
Example with Truth Table A (B C) (A B) C A B C B C A B A (B C) (A B) C
Counterexample with Truth Table A (B C) (A B) C A B C B C A B A (B C) (A B) C
Counterexample with Tree C A BCAB 1 0
C A BCAB
C A BCAB
C A BCAB
Example with Deduction A (B C) (A B) C A (B C) A (B C) A ( B C) ( A B) C (A B) C (A B) C
Proof in ACL2 ACL2 >QUERY (thm (implies (and (booleanp A) (booleanp B) (booleanp C)) (iff (implies A (implies B C)) (implies (and A B) C)))) > Q.E.D. Summary Form: ( THM...) Rules: NIL Time: 0.00 seconds (prove: 0.00, print: 0.00, proof tree: 0.00, other: 0.00) Proof succeeded.
Counterexample in ACL2 ACL2 >QUERY (thm (implies (and (booleanp A) (booleanp B) (booleanp C)) (iff (implies A (implies B C)) (implies (implies A B) C)))) > Goal' Goal'' Goal''' Goal'4' **Summary of testing** We tested 500 examples across 1 subgoals, of which 2 (2 unique) satisfied the hypotheses, and found 2 counterexamples and 0 witnesses.
Counterexample in ACL2 We falsified the conjecture. Here are counterexamples: [found in : "Goal'4'"] (NOT (BOOLEANP B)) -- (C NIL), (B T) and (A NIL) -- (C NIL), (B NIL) and (A NIL)
Counterexample in ACL2 Summary Form: ( THM...) Rules: ((:COMPOUND-RECOGNIZER BOOLEANP-COMPOUND-RECOGNIZER) (:DEFINITION IFF) (:DEFINITION NOT) (:EXECUTABLE-COUNTERPART BOOLEANP) (:EXECUTABLE-COUNTERPART NOT)) Time: 0.19 seconds (prove: 0.05, print: 0.00, proof tree: 0.02, other: 0.12) Prover steps counted: 281 *** Note: No checkpoints to print. *** ACL2 Error in ( THM...): See :DOC failure. ******** FAILED ********
Reasoning about Numbers Conjecture: a+b = a*b [a,b ] Is this valid? Satisfiable? b = a/(a-1) (0,0), (2,2), (3,3/2) …
Counterexample in ACL2 ACL2 >EVENT (test? (implies (and (rationalp a) (rationalp b)) (equal (+ a b) (* a b)))) **Summary of testing** We tested 291 examples across 1 subgoals, of which 276 (276 unique) satisfied the hypotheses, and found 273 counterexamples and 3 witnesses. We falsified the conjecture. Here are counterexamples: [found in : "top"] -- (A 0) and (B 1/5) -- (A -1/4) and (B -2) -- (A 1) and (B -2/11) Cases in which the conjecture is true include: [found in : "top"] -- (A 1/4) and (B -1/3) -- (A -1/3) and (B 1/4) -- (A 0) and (B 0) Test? found a counterexample.
Reasoning about Numbers Conjecture: a+b = b+a [a,b ] Is this valid? Satisfiable? Must test infinitely many examples
Proof in ACL2 ACL2 >QUERY (thm (implies (and (rationalp a) (rationalp b)) (equal (+ a b) (+ b a)))) > Q.E.D. Summary Form: ( THM...) Rules: ((:EXECUTABLE-COUNTERPART TAU-SYSTEM)) Time: 0.00 seconds (prove: 0.00, print: 0.00, proof tree: 0.00, other: 0.00) Prover steps counted: 18 Proof succeeded.
How was ACL2 able to do this? Arithmetic defined through functions and ACL2 can reason about functions. Also axioms provided for built-in functions. Equational Reasoning Repeatedly replace ACL expressions by equal expressions to either compute the value of an expression of check to see if two expressions are equal
Proof Proofs use formal reasoning Axioms for built-in functions (consp, if, equal) Every time we define a function that ACL2s admits, we also get a definitional axiom an axiom stating that the function is equal to its body. I.E. Replace a function call by its body substituting the formal parameters with the actual arguments Reason using properties of equality and first order logic
Equality x = y ⇒ (equal x y) = t x y ⇒ (equal x y) = nil = is an equivalence relation Reflexive x = x Symmetric x = y y = x Transitive x = y y = z x = z (chain together a sequence of equations) Equality Axiom Schema for Functions (x 1 = y 1 ∧ ∧ x n = y n ) ⇒ (f x 1 x n ) = (f y 1 y n ) To reason about constants, we can use evaluation
Axioms (first (cons x y)) = x (rest (cons x y)) = y Otherwise nil (consp (cons x y)) = t Otherwise nil x = nil ⇒ (if x y z) = z x nil ⇒ (if x y z) = y
Example Reason about the following functions (defunc len (x) :input-contract t :output-contract (natp (len x)) (if (atom x) 0 (+ 1 (len (rest x)))))
Example (defunc atom (x) :input-contract t :output-contract (booleanp (atom x)) (not (consp x))) (defunc not (a) :input-contract (booleanp a) :output-contract (booleanp (not a)) (if a nil t))
Example Theorem: (equal (len (cons x (list z))) 2) (len (cons x (list z))) (if (atom (cons x (list z))) 0 (+ 1 (len (rest (cons x (list z)))))) {def of len} (if (atom (cons x (list z))) 0 (+ 1 (len (list z)))) {first-rest axiom} (if (not (consp (cons x (list z)))) 0 (+ 1 (len (list z)))) {def of atom}
Example Continued (if (if (consp (cons x (list z))) nil t) 0 (+ 1 (len (list z)))) {def of not} (if (if t nil t) 0 (+ 1 (len (list z)))) {consp axiom} (if nil 0 (+ 1 (len (list z)))) {if axiom} (+ 1 (len (list z))) {if axiom} (+ 1 (len (cons z nil))) {expand list macro} … (+ 1 1) = 2
Fill in … (+ 1 (len (cons z nil))) {expand list macro} (+ 1 (if (atom (cons z nil)) 0 (+ 1 (len (rest (cons z nil)))))) {def of len} (+ 1 (if (atom (cons z nil)) 0 (+ 1 (len nil)))) {rest axiom} (+ 1 (if (not (consp (cons z nil))) 0 (+ 1 (len nil)))) {def of atom} (+ 1 (if (if (consp (cons z nil)) nil t) 0 (+ 1 (len nil)))) {def of not} (+ 1 (if (if t nil t) 0 (+ 1 (len nil)))) {consp axiom}
Fill in … (+ 1 (if nil 0 (+ 1 (len nil)))) {if axiom} (+ 1 (+ 1 (len nil))) {if axiom} (+ 1 (+ 1 (if (atom nil) 0 (+ 1 (len (rest nil)))))) {def of len} (+ 1 (+ 1 (if (not (consp nil)) 0 (+ 1 (len (rest nil)))))) {def of atom} (+ 1 (+ 1 (if (if (consp nil) nil t) 0 (+ 1 (len (rest nil)))))) {def of not} (+ 1 (+ 1 (if (if nil nil t) 0 (+ 1 (len (rest nil)))))) {consp axiom}
Fill in … (+ 1 (+ 1 (if (if nil nil t) 0 (+ 1 (len (rest nil)))))) {consp axiom} (+ 1 (+ 1 (if t 0 (+ 1 (len (rest nil)))))) {if axiom} (+ 1 (+ 1 0)) {if axiom} 2 {arithmetic}
Example Proof Conjecture: (equal (len (cons x (list z))) (len (cons y (list z)))) The previous theorem showed (len (cons x (list z))) = 2 Similar reasoning shows (len (cons y (list z))) = 2 Alternatively we can substitute x=y in the theorem to obtain (len (cons y (list z))) = 2
Instantiation Derive | from . That is, if is a theorem and is a substitution, then by instantiation, | is a theorem. Substitution ((var 1 term 1 )... (var n term n )) Example. From the theorem (equal (first (cons x y)) x) We can derive (equal (first (cons (foo x) (bar z))) (foo x))
Counter Example Same type of reasoning can be use to prove conjectures false Conjecture: (equal (len (list x)) (len x)) (equal (len (list nil)) (len nil)) Compute (len nil) and (len (list nil)) and compare
Counter Example (len nil) (if (atom nil) 0 (+ 1 (len (rest nil))))) [def of len] (if t 0 (+ 1 (len (rest nil))))) [def of atom] 0 [if axiom] (len (list nil)) (if (atom (list nil)) 0 (+ 1 (len (rest (list nil)))))) [def of len] (if nil 0 (+ 1 (len (rest nil))))) [def of atom] (+ 1 (len (rest nil)))) [if axiom]
Counter Example (len (list nil)) (if (atom (list nil)) 0 (+ 1 (len (rest (list nil)))))) [def of len] (if nil 0 (+ 1 (len (rest (list nil))))) [def of atom] (+ 1 (len (rest (list nil))))) [if axiom] (+ 1 (len nil)) [first-rest axiom] (+ 1 0) [previous calculation] 1 0
Definition of Append (defunc app (a b) :input-contract (and (listp a) (listp b)) :output-contract (and (listp (app a b)) (equal (len (app a b)) (+ (len a) (len b)))) (if (endp a) b (cons (first a) (app (rest a) b))))
Necessary Functions (defunc listp (l) :input-contract t :output-contract (booleanp (listp l)) (if (consp l) (listp (rest l)) (equal l ()))) (defunc endp (a) :input-contract (listp a) :output-contract (booleanp (endp a)) (equal a nil))
Proving Properties Associativity of app (app x (app y z)) = (app (app x y) z) Definitional axiom Input contracts and context Formal reasoning needed for induction Base Case when x = nil (endp x) (listp x) (listp y) (listp z) ⇒ (app (app x y) z) = (app x (app y z)) General case assuming inductive hypothesis (listp (rest x)) ∧ (listp y) ∧ (listp z) ⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))
Definitional Axiom (listp a) ∧ (listp b) ⇒ (app a b) = (if (endp a) b (cons (first a) (app (rest a) b))) Can’t expand body unless (listp a) and (listp b) In general every time we “successfully admit a function” we get an axiom: ic ⇒ (f x 1... x n ) = body Can’t expand body unless ic is satisfied.
Application of Append Theorem [CA]: (listp y) (listp z) (app (cons x y) z) = (cons x (app y z)) (app (cons x y) z) (if (endp (cons x y)) z (cons (first (cons x y)) (app (rest (cons x y)) z))) [def of app and inst] (if nil z (cons (first (cons x y)) (app (rest (cons x y)) z))) [def of endp and consp axiom] (cons (first (cons x y)) (app (rest (cons x y)) z)) [if axiom] (cons x (app y z)) [axioms for first and rest]
Base Case Theorem: (endp x) (listp x) (listp y) (listp z) ⇒ (app (app x y) z) = (app x (app y z))
Conjecture Contract Checking Make sure all hypotheses are present in your conjectures Conjecture: (endp x) ⇒ (app (app x y) z) = (app x (app y z)) Taking into account all input contracts Conjecture: (endp x) (listp x) (listp y) (listp z) ⇒ (app (app x y) z) = (app x (app y z))
Context Conjecture: (endp x) (listp x) (listp y) (listp z) ⇒ (app (app x y) z) = (app x (app y z)) (implies (and (endp x) (listp x) (listp y) (listp z)) (iff (app (app x y) z) (app x (app y z)) hyp 1 ∧ hyp 2 ∧ ∧ hyp n ⇒ conc Context = {hyp 1, hyp 2,…, hyp n } Context of conjecture = {(endp x), (listp x), (listp y), (listp z)}
Implications of Context Conjecture: (endp x) (listp x) (listp y) (listp z) ⇒ (app (app x y) z) = (app x (app y z)) C1. (endp x) C2. (listp x) C3. (listp y) C4. (listp z) C5. x = nil {C1, C2}
Testing Conjecture (let ((x nil) (y nil) (z nil)) (implies (and (endp x) (listp x) (listp y) (listp z)) (equal (app (app x y) z) (app x (app y z)))))
Testing Conjecture (test? (implies (and (endp x) (listp x) (listp y) (listp z)) (equal (app (app x y) z) (app x (app y z)))))
Proof of Conjecture Theorem: (endp x) (listp x) (listp y) (listp z) ⇒ (app (app x y) z) = (app x (app y z)) C1. (endp x) C2. (listp x) C3. (listp y) C4. (listp z) C5. x = nil {C1, C2} (app (app x y) z) (app y z) [def of app, def of endp, C5, if axiom] (app x (app y z) ) [def of app, def of endp, C5, if axiom]
General Case Theorem. [(consp x) (listp x) ∧ (listp y) ∧ (listp z) [(listp (rest x)) ∧ (listp y) ∧ (listp z) ⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))]] ⇒ (app (app x y) z) = (app x (app y z))
Rearranging Contexts (consp x) ⇒ [[(listp (rest x)) ∧ (listp y) ∧ (listp z) ⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))] ⇒ [(listp x) ∧ (listp y) ∧ (listp z) ⇒ (app (app x y) z) = (app x (app y z))]] [(consp x) [(listp (rest x)) ∧ (listp y) ∧ (listp z) ⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))] ⇒ [(listp x) ∧ (listp y) ∧ (listp z) ⇒ (app (app x y) z) = (app x (app y z))]]
Rearranging Contexts [(consp x) [(listp (rest x)) ∧ (listp y) ∧ (listp z) ⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))] ⇒ [(listp x) ∧ (listp y) ∧ (listp z) ⇒ (app (app x y) z) = (app x (app y z))]] [(consp x) (listp x) ∧ (listp y) ∧ (listp z) [(listp (rest x)) ∧ (listp y) ∧ (listp z) ⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))]] ⇒ (app (app x y) z) = (app x (app y z))
Context of Conjecture Conjecture: (app (app x y) z) = (app x (app y z)) C1. (consp x) C2. (listp x) C3. (listp y) C4. (listp z) C5. [(listp (rest x)) ∧ (listp y) ∧ (listp z) ⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))]
Modus Ponens (A B A) B A A B B
Extending Context C1. (consp x) C2. (listp x) C3. (listp y) C4. (listp z) C5. [(listp (rest x)) ∧ (listp y) ∧ (listp z) ⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))] C6. (listp (rest x)) [C1, C2, def of listp] C7. (app (app (rest x) y) z) = (app (rest x) (app y z)) [C6, C3, C4, C5, MP]
Proof of Theorem Theorem. [(consp x) (listp x) ∧ (listp y) ∧ (listp z) [(listp (rest x)) ∧ (listp y) ∧ (listp z) ⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))]] ⇒ (app (app x y) z) = (app x (app y z)) Proof (app (app x y) z) (app (cons (first x) (app (rest x) y)) z) [def app, C1, C2, C3] (cons (first x) (app (app (rest x) y) z)) [Thm CA,C3,C4,C6] (cons (first x) (app (rest x) (app y z))) [C7] (app x (app y z))) [def app, C1, C2, C3, C4]
Induction Scheme Base Case (endp x) (listp x) (listp y) (listp z) ⇒ (app (app x y) z) = (app x (app y z)) Induction Step [(consp x) (listp x) ∧ (listp y) ∧ (listp z) [(listp (rest x)) ∧ (listp y) ∧ (listp z) ⇒ (app (app (rest x) y) z) = (app (rest x) (app y z))]] ⇒ (app (app x y) z) = (app x (app y z)) Conclude (assuming termination) (app (app x y) z) = (app x (app y z))
Induction in ACL2 ACL2 >QUERY (thm (implies (and (true-listp x) (true-listp y) (true-listp z)) (equal (app (app x y) z) (app x (app y z))))) > ^^^ Checkpoint Goal ^^^ *1 (the initial Goal, a key checkpoint) is pushed for proof by induction. Perhaps we can prove *1 by induction. Five induction schemes are suggested by this conjecture. These merge into three derived induction schemes. However, two of these are flawed and so we are left with one viable candidate. We will induct according to a scheme suggested by (APP X Y). This suggestion was produced using the :induction rules APP-INDUCTION- SCHEME, APP-INDUCTION-SCHEME-FROM-DEFINITION and TRUE-LISTP. If we let (:P X Y Z) denote *1 above then the induction scheme we'll use is (AND (IMPLIES (NOT (AND (TRUE-LISTP X) (TRUE-LISTP Y))) (:P X Y Z)) (IMPLIES (AND (AND (TRUE-LISTP X) (TRUE-LISTP Y)) (NOT (ENDP X)) (:P (CDR X) Y Z)) (:P X Y Z)) (IMPLIES (AND (AND (TRUE-LISTP X) (TRUE-LISTP Y)) (ENDP X)) (:P X Y Z))). This induction is justified by the same argument used to admit APP. When applied to the goal at hand the above induction scheme produces three nontautological subgoals. ^^^ Checkpoint *1 ^^^ Subgoal *1/3 Subgoal *1/3' Subgoal *1/2 Subgoal *1/1 Subgoal *1/1' *1 is COMPLETED! Thus key checkpoint Goal is COMPLETED! Q.E.D. Summary Form: ( THM...) Rules: ((:DEFINITION APP-DEFINITION-RULE) (:DEFINITION ENDP) (:DEFINITION NOT) (:DEFINITION TRUE-LISTP) (:EXECUTABLE-COUNTERPART CONSP) (:FAKE-RUNE-FOR-TYPE-SET NIL) (:INDUCTION APP-INDUCTION-SCHEME) (:INDUCTION APP-INDUCTION-SCHEME-FROM-DEFINITION) (:INDUCTION TRUE-LISTP) (:REWRITE APP-CONTRACT) (:REWRITE CAR-CONS) (:REWRITE CDR-CONS) (:REWRITE LIST::TRUE-LISTP-OF-CONS) (:REWRITE LIST::TRUE-LISTP-OF-NON-CONSP)) Time: 0.37 seconds (prove: 0.19, print: 0.00, proof tree: 0.03, other: 0.16) Prover steps counted: Proof succeeded.
Induction in ACL2 We will induct according to a scheme suggested by (APP X Y). This suggestion was produced using the :induction rules APP-INDUCTION- SCHEME, APP-INDUCTION-SCHEME-FROM-DEFINITION and TRUE-LISTP. If we let (:P X Y Z) denote *1 above then the induction scheme we'll use is (AND (IMPLIES (NOT (AND (TRUE-LISTP X) (TRUE-LISTP Y))) (:P X Y Z)) (IMPLIES (AND (AND (TRUE-LISTP X) (TRUE-LISTP Y)) (NOT (ENDP X)) (:P (CDR X) Y Z)) (:P X Y Z)) (IMPLIES (AND (AND (TRUE-LISTP X) (TRUE-LISTP Y)) (ENDP X)) (:P X Y Z))).
Induction in ACL2 This induction is justified by the same argument used to admit APP. When applied to the goal at hand the above induction scheme produces three nontautological subgoals. ^^^ Checkpoint *1 ^^^ Subgoal *1/3 Subgoal *1/3' Subgoal *1/2 Subgoal *1/1 Subgoal *1/1' *1 is COMPLETED! Thus key checkpoint Goal is COMPLETED! Q.E.D.
Induction in ACL2 Summary Form: ( THM...) Rules: ((:DEFINITION APP-DEFINITION-RULE) (:DEFINITION ENDP) (:DEFINITION NOT) (:DEFINITION TRUE-LISTP) (:EXECUTABLE-COUNTERPART CONSP) (:FAKE-RUNE-FOR-TYPE-SET NIL) (:INDUCTION APP-INDUCTION-SCHEME) (:INDUCTION APP-INDUCTION-SCHEME-FROM-DEFINITION) (:INDUCTION TRUE-LISTP) (:REWRITE APP-CONTRACT) (:REWRITE CAR-CONS) (:REWRITE CDR-CONS) (:REWRITE LIST::TRUE-LISTP-OF-CONS) (:REWRITE LIST::TRUE-LISTP-OF-NON-CONSP)) Time: 0.37 seconds (prove: 0.19, print: 0.00, proof tree: 0.03, other: 0.16) Prover steps counted: Proof succeeded.