1 Interactive Computer Theorem Proving CS294-9 October 19, 2006 Adam Chlipala UC Berkeley Lecture 9: Beyond Primitive Recursion.

Slides:



Advertisements
Similar presentations
Completeness and Expressiveness
Advertisements

22C:19 Discrete Structures Induction and Recursion Spring 2014 Sukumar Ghosh.
22C:19 Discrete Structures Induction and Recursion Fall 2014 Sukumar Ghosh.
Reasoning About Code; Hoare Logic, continued
1 How to transform an analyzer into a verifier. 2 OUTLINE OF THE LECTURE a verification technique which combines abstract interpretation and Park’s fixpoint.
Recursion. Recursion is a powerful technique for thinking about a process It can be used to simulate a loop, or for many other kinds of applications In.
ISBN Chapter 3 Describing Syntax and Semantics.
Termination Analysis Math Foundations of Computer Science.
Comp 205: Comparative Programming Languages Semantics of Imperative Programming Languages denotational semantics operational semantics logical semantics.
CSC212 Data Structure - Section FG Lecture 14 Reasoning about Recursion Instructor: Zhigang Zhu Department of Computer Science City College of New York.
Katz Formal Specifications Larch 1 Algebraic Specification and Larch Formal Specifications of Complex Systems Shmuel Katz The Technion.
CS5371 Theory of Computation
Describing Syntax and Semantics
1 Module 10 Recursive and r.e. language classes –representing solvable and half-solvable problems Proofs of closure properties –for the set of recursive.
November 3, 2009Theory of Computation Lecture 14: A Universal Program VI 1 Recursively Enumerable Sets Definition: We write: W n = {x  N |  (x, n) 
22C:19 Discrete Math Induction and Recursion Fall 2011 Sukumar Ghosh.
MATH 224 – Discrete Mathematics
NummSquared Coercion make it so! Samuel Howse poohbist.com November 29, 2006 Copyright © 2006 Samuel Howse. All rights reserved.
Section 3.1: Proof Strategy Now that we have a fair amount of experience with proofs, we will start to prove more difficult theorems. Our experience so.
Formal Semantics Chapter Twenty-ThreeModern Programming Languages, 2nd ed.1.
Reading and Writing Mathematical Proofs Spring 2015 Lecture 4: Beyond Basic Induction.
Introduction to ACL2 CS 680 Formal Methods for Computer Verification Jeremy Johnson Drexel University.
Great Theoretical Ideas in Computer Science.
Coq and Nuprl Wojciech Moczydłowski History World, type system Inductive types in Coq Extraction in Coq Other features of Coq.
CSE 311: Foundations of Computing Fall 2014 Lecture 27: Cardinality.
1 Proving Properties of Recursive List Functions CS 270 Math Foundations of CS Jeremy Johnson.
1 Interactive Computer Theorem Proving CS294-9 October 5, 2006 Adam Chlipala UC Berkeley Lecture 7: Programming with Proofs.
1 Interactive Computer Theorem Proving CS294-9 November 30, 2006 Adam Chlipala UC Berkeley Lecture 14: Twelf.
1 Interactive Computer Theorem Proving CS294-9 September 7, 2006 Adam Chlipala UC Berkeley Lecture 3: Data structures and Induction.
1 Interactive Computer Theorem Proving CS294-9 September 14, 2006 Adam Chlipala UC Berkeley Lecture 4: Inductively- Defined Predicates.
Thoughts on Programming with Proof Assistants Adam Chlipala University of California, Berkeley PLPV Workshop.
Lecture 4 CS140 Dick Steflik. Reading Keyboard Input Import java.util.Scanner – A simple text scanner which can parse primitive types and strings using.
Lecture 2: Proofs and Recursion. Lecture 2-1: Proof Techniques Proof methods : –Inductive reasoning Lecture 2-2 –Deductive reasoning Using counterexample.
Lecture 11: Proof by Reflection
Chapter 2: Lambda Calculus
User-Written Functions
Gödel's Legacy: The Limits Of Logics
CPSC 121: Models of Computation 2008/9 Winter Term 2
Sparkle a functional theorem prover
The Propositional Calculus
CS2210:0001Discrete Structures Induction and Recursion
Reasoning About Code.
Reasoning about code CSE 331 University of Washington.
Chapter 3 The Real Numbers.
Theory of Computation Lecture 14: A Universal Program V
Great Theoretical Ideas in Computer Science
Chapter 5. Optimal Matchings
Proving Properties of Recursive List Functions
Copyright © Cengage Learning. All rights reserved.
Lecture 5 Floyd-Hoare Style Verification
3.5 Minimum Cuts in Undirected Graphs
CPSC 121: Models of Computation 2013W2
Data Structures Review Session
This Lecture Substitution model
CSE373: Data Structures & Algorithms Lecture 5: AVL Trees
Semantics In Text: Chapter 3.
Halting Problem.
MA/CSSE 474 More Math Review Theory of Computation
Searching, Sorting, and Asymptotic Complexity
Computer Security: Art and Science, 2nd Edition
Class 33: Making Recursion M.C. Escher, Ascending and Descending
Department of Computer Science
Recursion Taken from notes by Dr. Neil Moore
This Lecture Substitution model
Instructor: Aaron Roth
This Lecture Substitution model
Programming Languages and Compilers (CS 421)
Instructor: Aaron Roth
Lecture 23: Computability CS200: Computer Science
Presentation transcript:

1 Interactive Computer Theorem Proving CS294-9 October 19, 2006 Adam Chlipala UC Berkeley Lecture 9: Beyond Primitive Recursion

2 Recap: Termination Matters Proof of A Proof of B Proof of (A -> B) Compute a proof of B from a proof of A. If proof functions could run forever, everything would be “true”! So guaranteeing termination is critical to soundness.... Fixpoint f (x : A) : B := f x. “Proof by procrastination”!

3 Primitive Recursion Fixpoint fib (n : nat) : nat := match n with | 0 => 1 | S n' => match n' with | O => 1 | S n'' => fib n'' + fib n' end end. Every recursive call must have an argument that has a syntactic path from the original.

4 General Recursion let rec nat_to_int = function O -> 0 | S O -> 1 | S (S n) -> let i = nat_to_int (n / 2) in if isEven n then 2 * i else * i let rec mergeSort = function [] -> [] | [x] -> [x] | ls -> let (ls1, ls2) = split ls in merge (mergeSort ls1) (mergeSort ls2) let rec looper = function true -> () | false -> looper false Recursion Principle: When defining f(n), you may use f(n') for all n' < n. Alternative Principle: When defining f(n) with n > 1, you may use f(n / 2). Recursion Principle: When defining f(L), you may use f(L') for all L' with length(L') < length(L). This really is non-terminating, but we want to reason about the terminating cases!

5 Outline of Techniques ● Relations instead of functions ● Bounded recursion ● Recursion on ad-hoc predicates ● Well-founded recursion ● Constructive domain theory

6 Using Relations Inductive plusR : nat -> nat -> nat -> Set := | plusR_O : forall n, plusR O n n | plusR_Sn : forall n m sum, plusR n m sum -> plusR (S n) m (S sum). Extraction plusR. type plusR = | PlusR_O of nat | PlusR_Sn of nat * nat * nat * plusR

7 Bounded Recursion Fixpoint nat_to_int (bound : nat) (n : nat) {struct bound} : int := match bound with | O => 0 | S bound' => match n with | O -> 0 | S O -> 1 | S (S n') -> let i := nat_to_int bound' (n / 2) in if isEven n then 2 * i else * i end end. Pros ● We can prove that nat_to_int (S n) n satisfies the spec, for any n. Cons ●...but nat_to_int gives the wrong answer if we pass it too low a bound! – Alternatively, we could have it return an error code, but that isn't much better. ● Threading a nat around is a pain. ● The extraction of this function retains the extra argument, though we'd probably rather it didn't.

8 The Big Problem: Compositional Reasoning Variable f : nat -> A -> option B. Variable g : nat -> C -> option D. Variable h : B -> D -> E. Definition foo (n : nat) (x : A) (y : C) := match f n x, g n y with | Some r1, Some r2 => Some (h r1 r2) | _, _ => None end. Proposal: For any F : nat -> T1 -> option T2, say that “F(x) = y” if there exists n such that F n x = Some y. If we know f(u) = v and g(w) = x, we want to conclude foo(u)(w) = h(v)(x). This requires looking inside the definitions of f and g!

9 Recursion on an Ad-Hoc Predicate Fixpoint nat_to_int (n : nat) : int := match n with | O -> 0 | S O -> 1 | S (S n') -> let i := nat_to_int (n / 2) in if isEven n then 2 * i else * i end. This may not be primitive recursive, but the recursive structure is still very predictable and “obviously” well-founded! Key Property: There exists a P n for any n! Inductive P : nat -> Set := | P_0 : P 0 | P_1 : P 1 | P_div2 : forall n, P (n / 2) -> P n.

10 Recursion on an Ad-Hoc Predicate Fixpoint nat_to_int (n : nat) (p : P n) {struct p} : int := match n with | O -> 0 | S O -> 1 | S (S n') -> match p with | P_div2 _ p' => let i := nat_to_int (n / 2) p' in if isEven n then 2 * i else * i | _ => (* show a contradiction *) end end. Inductive P : nat -> Set := | P_0 : P 0 | P_1 : P 1 | P_div2 : forall n, P (n / 2) -> P n. Pros ● nat_to_int always returns a correct answer! Cons ● To call nat_to_int, we have to come up with a P n value through some ad-hoc mechanism. ● The P n values survive extraction and add even more runtime complexity than the nats from bounded recursion. This one turns out to be easy to solve! Just put P in Prop.

11 Recursion on an Ad-Hoc Predicate Fixpoint nat_to_int (n : nat) (p : P n) {struct p} : int := match n with | O -> 0 | S O -> 1 | S (S n') -> match p with | P_div2 _ p' => let i := nat_to_int (n / 2) p' in if isEven n then 2 * i else * i | _ => (* show a contradiction *) end end. Inductive P : nat -> Prop := | P_0 : P 0 | P_1 : P 1 | P_div2 : forall n, P (n / 2) -> P n. You can't eliminate a Prop to form a Set!

12 Recursion on an Ad-Hoc Predicate Fixpoint nat_to_int (n : nat) (p : P n) {struct p} : int := match n with | O -> 0 | S O -> 1 | S (S n') -> let i := nat_to_int (n / 2) (match p with | P_div2 _ p' => p' | _ => (* show a contradiction *) end) in if isEven n then 2 * i else * i end. Inductive P : nat -> Prop := | P_0 : P 0 | P_1 : P 1 | P_div2 : forall n, P (n / 2) -> P n. Pros ● Finally nat_to_int extracts to exactly the OCaml program we want, since any P n values are erased. Cons ● Manipulating these witnesses is still a bookkeeping hassle.

13 Well-Founded Recursion A well-founded relation on set X is a binary relation R on such that there are no infinite descending chains. That is, there exists no sequence x1 R x2 R x3 R x4 R.... u v Accessibility graph: Connect x to y if x R y. Say x is accessible if it has no outgoing edges or all of its successors are accessible. Alternate definition: R is well-founded iff every element of X is accessible. v R uv R u

14 Back to Our Example Fixpoint nat_to_int (n : nat) {well_founded R} : int := match n with | O -> 0 | S O -> 1 | S (S n') -> let i := nat_to_int (n / 2) in if isEven n then 2 * i else * i end. pf R n (n / 2) R x y = x > y or even R x y = y = x / 2 Not quite legal Coq syntax in 8.0, but something similar added in 8.1 beta. Prove your relation is well-founded by showing that every nat is accessible for it.

15 One catch.... We have to show that our function is extensional. Definition f (self : nat -> int) (n : nat) : int := match n with | O -> 0 | S O -> 1 | S (S n') -> let i := self pf (n / 2) in if isEven n then 2 * i else * i end. For any self1 and self2 that return equal values on equal inputs, f behaves the same. Waaait a minute. Coq doesn't allow you to “look inside of functions,” so every function must be extensional! That may be true, but the logic isn't strong enough to prove it! Universal extensionality can be expressed as an axiom, and the result is a new sound formal system....

16 Real General Recursion let rec looper = function true -> () | false -> looper false A Turing-complete programming language must allow general recursion, which implies allowing non-termination. How can we “add Turing completeness” to Coq in a way that: ● Preserves logical soundness? ● Allows us to reason about programs? ● Allows extraction of executable programs? My answer: A principled version of bounded recursion...inspired by domain theory

17 Solving The Big Problem Variable f : nat -> A -> option B. Variable g : nat -> C -> option D. Variable h : B -> D -> E. Definition foo (n : nat) (x : A) (y : C) := match f n x, g n y with | Some r1, Some r2 => Some (h r1 r2) | _, _ => None end. Proposal: For any F : nat -> T1 -> option T2, say that “F(x) = y” if there exists n such that F n x = Some y. If we know f(u) = v and g(w) = x, we want to conclude foo(u)(w) = h(v)(x). This requires looking inside the definitions of f and g! What very general condition can we impose on f and g to avoid this problem? Whenever f n x = Some y, for any n' > n, f n' x = Some y.

18 Solving the Little Problem Threading bounds throughout a program is a pain. We want to build up a library of combinators that let us program naturally. Return e Theorem: Return e ) e x <- e1; e2 Theorem: If e1 => v1, And e2[x := v1] => v2, Then x v2 Implementation: ¸n. Some e Implementation: ¸n. match e1 n with | None => None | Some v => (e2 v) n end. Fix f Theorem: If f (Fix f) x => v, Then Fix f x => v Implementation: ¸n. ¸x. f n n x For f : (A -> B) -> (A -> B): where f 0 = ¸x. ¸n. None and f n+1 = f (f n )