imperative programming languages christine rizkallah
play

Imperative Programming Languages Christine Rizkallah CSE, UNSW (and - PowerPoint PPT Presentation

History TinyImp Hoare Logic Imperative Programming Languages Christine Rizkallah CSE, UNSW (and data61) Term 3 2019 1 History TinyImp Hoare Logic Imperative Programming imper o Definition Imperative programming is where programs are


  1. History TinyImp Hoare Logic Imperative Programming Languages Christine Rizkallah CSE, UNSW (and data61) Term 3 2019 1

  2. History TinyImp Hoare Logic Imperative Programming imper ¯ o Definition Imperative programming is where programs are described as a series of statements or commands to manipulate mutable state or cause externally observable effects . States may take the form of a mapping from variable names to their values, or even a model of a CPU state with a memory model (for example, in an assembly language ). 2

  3. History TinyImp Hoare Logic The Old Days Early microcomputer languages used a line numbering system with GO TO statements used to arrange control flow. 3

  4. History TinyImp Hoare Logic Factorial Example in BASIC (1964) 4

  5. History TinyImp Hoare Logic Dijkstra (1968) The structured programming movement brought in control structures to mainstream use, such as conditionals and loops. 5

  6. History TinyImp Hoare Logic Factorial Example in Pascal (1970) 6

  7. History TinyImp Hoare Logic Syntax We’re going to specify a language TinyImp , based on structured programming. The syntax consists of statements and expressions. Grammar Stmt ::= Do nothing skip | x := Expr Assignment | var y · Stmt Declaration | if Expr then Stmt else Stmt fi Conditional | while Expr do Stmt od Loop | Stmt ; Stmt Sequencing Expr ::= � Arithmetic expressions � We already know how to make unambiguous abstract syntax, so we will use concrete syntax in the rules for readability. 7

  8. History TinyImp Hoare Logic Examples Example (Factorial and Fibonacci) var m · var n · var i · var i · m := 1; n := 1; var m · i := 1; i := 0; while i < N do m := 1; var t · t := m ; while i < N do m := n ; i := i + 1; n := m + t ; m := m × i i := i + 1 od od 8

  9. History TinyImp Hoare Logic Static Semantics Types? We only have one type ( int ), so type checking is a wash. Scopes? We have to check that variables are declared before use. Anything Else? We have to check that variables are initialized before they are used! Indicates that no unsafe reads occur Set of initialized variables U ; V ⊢ s ok � W Set of initially uninitialized variables Set of definitely written to variables 9

  10. History TinyImp Hoare Logic Static Semantics Rules x ∈ U ∪ V FV ( e ) ⊆ V U ; V ⊢ skip ok � ∅ U ; V ⊢ x := e ok � { x } U ∪ { y } ; V ⊢ s ok � W U ; V ⊢ var y · s ok � W \ { y } FV ( e ) ⊆ V U ; V ⊢ s 1 ok � W 1 U ; V ⊢ s 2 ok � W 2 U ; V ⊢ if e then s 1 else s 2 fi ok � W 1 ∩ W 2 FV ( e ) ⊆ V U ; V ⊢ s ok � W U ; V ⊢ while e do s od ok � ∅ U ; V ⊢ s 1 ok � W 1 ( U \ W 1 ); ( V ∪ W 1 ) ⊢ s 2 ok � W 2 U ; V ⊢ s 1 ; s 2 ok � W 1 ∪ W 2 10

  11. History TinyImp Hoare Logic Dynamic Semantics We will use big-step operational semantics. What are the sets of evaluable expressions and values here? Evaluable Expressions : A pair containing a statement to execute and a state σ . Values : The final state that results from executing the statement. States A state is a mutable mapping from variables to their values. We use the following notation: To read a variable x from the state σ , we write σ ( x ). To update an existing variable x to have value v inside the state σ , we write ( σ : x �→ v ). To extend a state σ with a new, previously undeclared variable x , we write σ · x . In such a state, x has undefined value. 11

  12. History TinyImp Hoare Logic Evaluation Rules We will assume we have defined a relation σ ⊢ e ⇓ v for arithmetic expressions, much like in the previous lecture. ( σ 1 , s 1 ) ⇓ σ 2 ( σ 2 , s 2 ) ⇓ σ 3 ( σ, skip ) ⇓ σ ( σ 1 , s 1 ; s 2 ) ⇓ σ 3 σ ⊢ e ⇓ v ( σ 1 · x , s ) ⇓ ( σ 2 · x ) ( σ, x := e ) ⇓ ( σ : x �→ v ) ( σ 1 , var x · s ) ⇓ σ 2 σ 1 ⊢ e ⇓ v v � = 0 ( σ 1 , s 1 ) ⇓ σ 2 ( σ 1 , if e then s 1 else s 2 fi ) ⇓ σ 2 σ 1 ⊢ e ⇓ 0 ( σ 1 , s 2 ) ⇓ σ 2 ( σ 1 , if e then s 1 else s 2 fi ) ⇓ σ 2 σ 1 ⊢ e ⇓ v v � = 0 σ 1 ⊢ e ⇓ 0 ( σ 1 , s ) ⇓ σ 2 ( σ 2 , while e do s od ) ⇓ σ 3 ( σ 1 , while e do s od ) ⇓ σ 1 ( σ 1 , while e do s od ) ⇓ σ 3 12

  13. History TinyImp Hoare Logic Hoare Logic To give you a taste of axiomatic semantics , and also how formal verification works, we are going to define what’s called a Hoare Logic for TinyImp to allow us to prove properties of our program. We write a Hoare triple judgement as: { ϕ } s { ψ } Where ϕ and ψ are logical formulae about state variables, called assertions , and s is a statement. This triple states that if the statement s successfully evaluates from a starting state satisfying the precondition ϕ , then the result state will satisfy the postcondition ψ : ϕ ( σ ) ∧ ( σ, s ) ⇓ σ ′ ⇒ ψ ( σ ′ ) 13

  14. History TinyImp Hoare Logic Proving Hoare Triples To prove a Hoare triple like: { True } var i · var m · i := 0; m := 1; while i < N do i := i + 1; m := m × i od { m = N ! } It is undesirable to look at the operational semantics derivations of this whole program to compute what the possible final states are for a given input state. Instead we shall define a set of rules to prove Hoare triples directly (called a proof calculus ). 14

  15. History TinyImp Hoare Logic Hoare Rules ( σ, skip ) ⇓ σ { ϕ } skip { ϕ } ( σ 1 , s 1 ) ⇓ σ 2 ( σ 2 , s 2 ) ⇓ σ 3 { ϕ } s 1 { α } { α } s 2 { ψ } ( σ 1 , s 1 ; s 2 ) ⇓ σ 3 { ϕ } s 1 ; s 2 { ψ } σ ⊢ e ⇓ v ( σ, x := e ) ⇓ ( σ : x �→ v ) { ϕ [ x := e ] } x := e { ϕ } Continuing on, we can get rules for if , and while with a loop invariant : { ϕ ∧ e } s 1 { ψ } { ϕ ∧ ¬ e } s 2 { ψ } { ϕ ∧ e } s { ϕ } { ϕ } if e then s 1 else s 2 fi { ψ } { ϕ } while e do s od { ϕ ∧ ¬ e } 15

  16. History TinyImp Hoare Logic Consequence There is one more rule, called the rule of consequence , that we need to insert ordinary logical reasoning into our Hoare logic proofs: ϕ ⇒ α { α } s { β } β ⇒ ψ { ϕ } s { ψ } This is the only rule that is not directed entirely by syntax. This means a Hoare logic proof need not look like a derivation tree. Instead we can sprinkle assertions through our program and specially note uses of the consequence rule. 16

  17. History TinyImp Hoare Logic Factorial Example Let’s verify the Factorial program using our Hoare rules: { ϕ ∧ e } s 1 { ψ } { ϕ ∧ ¬ e } s 2 { ψ } { True } { ϕ } if e then s 1 else s 2 fi { ψ } var i · var m · { 1 = 0! } i := 0; { 1 = i ! } { 1 = i ! } m := 1; { m = i ! } { ϕ [ x := e ] } x := e { ϕ } { m = i ! } while i < N do { m = i ! ∧ i < N } { ϕ ∧ e } s { ϕ } { m × ( i + 1) = ( i + 1)! } { ϕ } while e do s od { ϕ ∧ ¬ e } i := i + 1; { m × i = i ! } { ϕ } s 1 { α } { α } s 2 { ψ } m := m × i { ϕ } s 1 ; s 2 { ψ } { m = i ! } od { m = i ! ∧ i = N } ϕ ⇒ α { α } s { β } β ⇒ ψ { m = N ! } { ϕ } s { ψ } note: ( i + 1)! = i ! × ( i + 1) 17

Recommend


More recommend