1 / 18

CSE 3341.03 Winter 2008 Introduction to Program Verification

CSE 3341.03 Winter 2008 Introduction to Program Verification. implementing ADTs. verifying ADT implementations (ch. 6). example: if we implement stacks with arrays, we need to verify that the stack axioms are still valid.

carl
Download Presentation

CSE 3341.03 Winter 2008 Introduction to Program Verification

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CSE 3341.03 Winter 2008Introduction to Program Verification implementing ADTs

  2. verifying ADT implementations (ch. 6) • example: if we implement stacks with arrays, we need to verify that the stack axioms are still valid. • need a description of arrays which allows us to prove equations involving array expressions

  3. motivation • why implement stacks (and queues and lists?) using arrays?

  4. array axiom • unbounded arrays, array index ≥ 0. • what axioms do we need? just one! • 2 functions: array and change • array(A, I) returns the value of the array A at location I corresponds to A[I] • change(A, I, V) returns an array which has the value V at I. • corresponds to A[I] = V • combine into an axiom? array(change(Array(I, Value), J) = if(J=I, Value, array(Array, J))

  5. general strategy • translate ADT functions into implemented (non-abstract) functions -- for clarity & convenience e. g. pop(S) ->> popA(S) • delete original ADT axioms, add axioms for the ADT used in implementation (e. g. array axiom) • what happens to rules for dup, over, etc.?

  6. implementation in terms of the target ADT • e. g., a stack = array and # of values on the stack (= index) = [Array, Index] nil = [nilA, 0] nilA is the array component (with no elements) of the implementation of the empty stack)

  7. array axiom • unbounded arrays, array index ≥ 0. • what axioms do we need? just one! • 2 functions: array and change • array(I) returns the value of the array at I • change(A, I, V) returns an array which has the value V at I. • combine into an axiom? • array(change(Array(I, Value), J) = if(J=I, Value, array(Array, J))

  8. general strategy • translate ADT functions to implemented (non-abstract) functions -- for clarity & convenience • e. g., pop(S) ->> popA(S) • delete original ADT axioms • add axioms for ADT used in implementation (e. g. array axiom)

  9. implementation in terms of the target ADT • e. g. a stack = array & # of values on the stack (= index) • define getter functions to access the parts of the implementation e. g. a([A, I]) ->> A, i([A, I]) ->> I. • define ADT functions in terms of new ADT topA(Stack) ->> array([a(S), i(S)]). popA(Stack) ->> [a(Stack), i(Stack) - 1] pushA(X, Stack) ->> [change(a(Stack), i(Stack)+1, X), i(Stack)+1]? • in English?

  10. verification using prover • use prover with trace on and theory files try to verify the original ADT axioms • e. g. pop(push(x,s)) = s |: theory('stackA.simp'). % what goes in here? |: theory('array.simp'). % what goes in here?

  11. tracing . . . pop(push(x,s))=s popA(push(x,s))=s [a(push(x,s)),i([change(a(s),i(s)+1,x),i(s)+1])-1]=s . . . [change(a(s),i(s)+1,x),i(s)]=s * Cannot prove [change(a(s),i(s)+1,x),i(s)]=s. easy to add a simplification rule to prove the identity what's the general case? how would you prove it?

  12. exercise 6.6: implementing queues • a key line: firstA(Q) = array(a(Q), 1) mathematically (abstractly), first needs a recursive definition, if defined in terms of the ADT functions but can be implemented efficiently (without recursion), using arrays. • that's the purpose of translating queues into something built from arrays.

  13. verifying a logic circuit: Section 6.3 • a different kind of implementation: • objects (gates) connected to form a (storage-free) logic circuit • each kind of gate has a definition: e.g. or_gate(V, W, X) ->> X iff (V or W). • this is not the only way to do it • chosen to make the “wiring” easier, but the logic is more complicated

  14. how else might we represent the circuit? • try just using functions: e. g., Z = or(or( . . ), and(. . . )) the nesting makes it harder to translate without error from the diagram to a Boolean expression

  15. vote circuit: p. 55 • what’s the purpose of the function int(X) ->> if(X, 1, 0) ? • what’s the purpose of the implementation term? to specify the gates and connections of a circuit in the equality to be verified: implementation(a, b, c, z) implies z = majority(a, b, c).

  16. Skolem constants • the implementation predicate implicitly introduces existentially quantified variables: • e. g., for all A, B, there exists a d such that d(A, B) = and_gate(A, B) or more simply: and_gate(A, B, d).

  17. exercise 6.9: • what’s “half” mean in the context of a “half-adder” ? • anyone not sure of what the gate symbols mean? • what are the outputs supposed to be (arithmetically)? • what portion of the exercise is more or less mechanical?

  18. what is being verified? • what part of the exercise requires some understanding & insight? • identifying the intended goal as a function of the inputs to the circuit: 2*Carry + Sum = A + B

More Related