CS 227 Lecture -*- Outline -*- * Reasoning about assignment ** Terms --------------------- TERMINOLOGY def: the state of a variable, x, is the value of x at a given time. --------------------- note that set! changes the state Can think of the state as the computer's memory an implicit argument to every procedure. --------------------- FUNCTION vs. PROCEDURE Function -- Mathematical mapping Procedure -- Scheme implementation May have side effects --------------------------- ** reasoning without assignment (can omit if pressed for time) ------------------- REASONING ABOUT EXPRESSIONS (car (cons x l)) = x (list ) = '() (list x ...) = (cons x (list ...)) (car (list 1)) = (car (cons 1 '())) = 1 ((lambda (x) (+ x x)) 3) = (+ 3 3) = 6 -------------------- We have done this in the past, and found it very useful Implicitly, we used the following axioms -------------------- AXIOMS OF EQUALITY reflexive: E = E symmetric: E1 = E2 iff E2 = E1 transitive: if E1 = E2 and E2 = E3 then E1 = E3 congruence: if E1 = E2 then (f E1) = (f E2) Example: (count-calls! 1) = (count-calls! 1) ------------------- Of course when we state the reflexive law, we mean for any expression E, in congruence we mean any procedure ** how set! breaks equational reasoning ------------------- HOW set! BREAKS THE AXIOMS (define count-calls! (let ((count 0)) (lambda (ignored) (set! count (add1 count)) count))) (= (count-calls! 1) (count-calls! 1)) ==> #f (define count-calls! (let ((count (make-vector 1 0))) (lambda (ignored) (vector-set! count 0 (add1 count)) count))) ------------------- Can also break the axioms with aliasing... but won't go into that ** how to reason with assignments So how to reason if can't use equality like this? Have to explicitly think about the state ------------------- REASONING WITH STATE PREDICATES def: a state predicate is a mapping from program variables to the booleans Examples: In mathematical notation: 0 < i 0 <= j < i In a Scheme-like notation: (< 0 i) (and (<= 0 j) (< j i)) Statements characterized by how they affect state predicates Examples: ; 0 <= i (set! i (add1 i)) ; 0 < i General rule: ; (and (defined x) (Pred (f x))) (set! x (f x)) ; (Pred x) --------------------- How does this relate to pre- and post-conditions? REQUIRES and ENSURES --------------------- RULE FOR PROCEDURE CALLS (define f (lambda (arg) ; REQUIRES: (PreCond arg) ; EFFECT: (PostCond arg result) ...)) General rule (omitting details): ; (and (defined x) (Precond E)) (set! x (f E)) ; (PostCond E x) ----------------------- It is possible to do this using equations (using Dijkstra's wp, dynamic logic, Boehm TOPLAS Oct. 1985) but always have to talk about programs in assertions (wp and Boehm) or talk about state explicitly (dynamic logic) ** Some conclusions State and Mutation are convenient many times, especially for efficiency. -- In applications like memoizing, they are indispensable -- In many other programming languages, you are forced to use them; and you will see much of them in the next few years. -- But it may be wise to use them sparingly to make reasoning easier. this is the "mostly functional" style.