1 Proving Properties of Recursive List Functions CS 270 Math Foundations of CS Jeremy Johnson
2 Objective To provide simple semantics for a purely functional subset of racket and to use this semantics to prove properties of racket programs. To use structural induction to prove properties of recursive list functions (append, reverse)
Outline Substitution semantics Basic axioms Definitional axiom Equational reasoning Structural induction Proving properties of recursive functions of lists
4 Substitution Model of Computation function application corresponds to substituting the argument expressions into the formal parameters of the function body Order of evaluation Applicative vs. normal order Termination Church-Rosser
5 Substitution Example (define (sqr x) (* x x)) (define (sum-of-squares x y) (+ (sqr x) (sqr y))) (define (f a) (sum-of-squares (+ a 1) (* a 2))) [applicative order] (f 5) (sum-of-squares (+ 5 1) (* 5 2)) (+ (square 6) (square 10)) (+ (* 6 6) (* 10 10)) ( ) 136 [normal order] (f 5) (sum-of-squares (+ 5 1) (* 5 2)) (+ (square (+ 5 1)) (square (* 5 2)) ) (+ (* (+ 5 1) (+ 5 1)) (* (* 5 2) (* 5 2))) (+ (* 6 6) (* 10 10)) ( )
6 Order Matters (define (p) (p)) (define (test x y) (if (= x 0) 0 y)) (test 0 (p))
7 Equational Reasoning Prove equivalence of racket expressions by repeatedly replacing subexpressions by equivalent subexpressions until the two expressions are equal Axioms for built-in functions Definitional axiom Properties of equality
Equality x = y ⇒ (equal? x y) = #t x y ⇒ (equal? x y) = #f = 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 null (cons? (cons x y)) = #t Otherwise #f (null? null) = #t Otherwise #f x = #f ⇒ (if x y z) = z x #f ⇒ (if x y z) = y
Contracts ; input-contract ic ; output-contract oc (define (f x 1... x n ) body) Input contract – input assumptions Output contract – guarantees provided by outputs Body contracts – input contracts must be satisfied for all function calls
Definitional Axiom ; input-contract ic ; output-contract oc (define (f x 1... x n ) body) If the function f is admissible Add definitional axiom for f: ic [(f x 1... x n ) = body] Add contract theorem for f: ic oc
Definitional Principle ; input-contract ic ; output-contract oc (define (f x 1... x n ) body) The function f is admissible f is a new function (no other axioms about f) x i ’s are distinct body is a term, possibly using f, but with no free variables other than x i ’s f is terminating ic oc is a theorem body contracts hold under assumption of ic
Soundness and Termination (define (f x) ;input-contract (natural? x) ;output-contract (natural? (f x)) (+ 1 (f x))) The definitional axiom for f leads to unsound logic (natural? x) x x+1 [property of natural numbers] (natural? (f x)) (f x) (+ 1 (f x)) [instantiate above] (natural? x) (f x) (+ 1 (f x)) [from ic oc] (natural x) (f x) = (+ 1 (f x)) [from def axiom] (natural x) #f [from p p = #f]
Structural Induction When using induction on recursively defined data structures like lists you can induct on the size of the data structure = to the number of calls to the constructors. When trying to show a property for a data structure of a given size, you can assume that the property holds when making a recursive call on a smaller data structure. You must make sure that the property holds for all constructors including base cases. With lists (rest …) will return a smaller data structure (at least one fewer cons) Structural induction allows you to induct on the recursive data structure without being explicit about the size provided the IH is applied to smaller objects.
Length ; Input: l is a list ; Output: a non-negative integer = length of l (define (length l) (if (null? l) 0 (+ 1 (length (rest l))) )) Properties 1.(length null) = 0 2.(length (cons x y)) = (+ 1 (length y)) 15
Proof of Properties of Length Proof (length null) = (if (null? null) 0 (+ 1 (length (rest null)))) (if #t 0 (+ (length (rest null)))) 0 (length (cons x y)) (if (null? (cons x y)) 0 (+ 1 (length (rest (cons x y))))) (if #f 0 (+ 1 (length (rest (cons x y))))) (+ 1 (length (rest (cons x y)))) (+ 1 (length y)) 16
Output Contract (define (natural? x) (if (integer? x) (or (> x 0) (= x 0)) #f)) (list? x) (natural? (length x)) Proof by induction. Base case x = null. (length x) = 0 Assume (list? (rest x)) (natural? (length (rest x))) (natural? (length x)) (natural? (+ 1 (length (rest x)))) (and (natural? 1) (natural? (length (rest x)))) [(rest x) is a list since x is a list, hence, by IH and sum of two natural numbers is natural] 17
Append ; inputs: x, y are lists ; output: a list whose elements are those of x followed by y (define (append x y) (if (null? x) y (cons (first x) (append (rest x) y)))) Properties 1.(and (list? x) (list? y)) (list? (append x y)) 2.(append null y) = y 3.x null (first (append x y)) = (first x) 4.(append x null) = x 5.(length (append x y)) = (+ (length x) (length y)) 6.(append x (append y z)) = (append (append x y) z) 18
Proof of Property 2 (append null y) (if (null? null) y (cons (first x) (append (rest x) y)))) (if #t y (cons (first x) (append (rest x) y)))) y
Proof of Property 3 (null? x) (first (append x y)) = (first x) (first (append x y)) (first (if (null? x) y (cons (first x) (append (rest x) y)))) (first (if #f y (cons (first x) (append (rest x) y)))) (first (cons (first x) (append (rest x) y))) (first x)
Proof of Property 4 Show (append x null) = x using structural induction Base case. x = null. In this case, (append null null) returns null = x. By induction assume recursive call satisfies the property [note (rest x) is smaller than x] I.E. (append (rest x) null) = (rest x) Thus (append x null) returns (cons (first x) (rest x)) = x
Proof of Property 5 Show (length (append x y) = (+ (length x) (length y)) using structural induction on x Base case. x = null. (append null y) = y and (length y) = (+ (length null) (length y)) By induction assume recursive call satisfies the property (length (append (rest x) y) = (+ (length (rest x)) (length y)) Thus (length (append x y)) = (length (cons (first x) (append (rest x) y)) = (+ 1 (length (rest x)) + (length y)) = (+ (length x) (length y))
Proof of Property 6 Show (append x (append y z)) = (append (append x y) z) Base case. x = null. (append null (append y z)) = (append y z) = (append (append null y) z) Assume property holds for (rest x) (append (append x y) z) (append (cons (first x) (append (rest x) y)) z) [by def] (cons (first x) (append (append (rest x) y) z)) [by def] (cons (first x) (append (rest x) (append y z))) [by IH] (append (cons (first x) (rest x)) (append y z)) [by def] (append x (append y z)) [by property of cons]
Reverse (define (reverse l) (if (null? l) null (append (reverse (rest l)) (cons (first l) null)))) Properties 1.(list? l) (list? (reverse l)) 2.(length (reverse x)) = (length x) 3.(reverse (append x y)) = (append (reverse y) (reverse x)) 4.(reverse (reverse x)) = x 24
Proof of Property 2 Show (length (rev x)) = (length x) Base case. x = null. (length (rev null)) (length null) Assume property holds for (rest x) (length (rev x)) (length (append (rev (rest x)) (cons (first x) null))) [def rev] (length (rev (rest x)) + (length (cons (first x) null)) [prop 5 of app] (length (rest x)) + (length (cons (first x) null)) [IH] (length (rest x)) + 1 [evaluation] (length (cons (first x) (rest x)) [prop 2 of length] (length x) [axiom for cons]
Proof of Property 3 Show (rev (append x y)) = (append (rev y) (rev x)) Base case. x = null. (rev (append null y)) = (rev y) = (append (rev y) null) = (append (rev y) (rev null)) Assume property holds for (rest x) (rev (append x y)) (rev (cons (first x) (append (rest x) y)) [def apppend] (append (rev (append (rest x) y)) (cons (first x) null)) [def rev] (append (append (rev y) (rev (rest x))) (cons (first x) null)) [IH] (append (rev y) (append (rev (rest x)) (cons (first x) null))) [prop app] (append (rev y) (rev x)) [def of rev]
Proof of Property 4 Show (rev (rev x)) = x Base case. x = null. (rev (rev null)) = (rev null) = null Assume property holds for (rest x) (rev (rev x)) (rev (append (rev (rest x)) (cons (first x) null))) [def rev] (append (rev (cons (first x) null)) (rev (rev (rest x)))) [property 2 of rev] (append (cons (first x) null) (rev (rev (rest x)))) [def of rev] (append (cons (first x) null) (rest x)) [IH] (cons (first x) (append null (rest x))) [def of app] (cons (first x) (rest x)) = x [def of app and prop of cons]