400 likes | 757 Views
Hoare Logic. Dr. Edgar Lederer University of Basel. Valid Hoare Triples for Commands. For each command of our Imperative Mini-Language (IML) we need valid Hoare triples for the basic commands skip and assignment they can be given directly
E N D
Hoare Logic Dr. Edgar Lederer University of Basel
Valid Hoare Triples for Commands • For each command of our Imperative Mini-Language (IML) we need valid Hoare triples • for the basic commands skip and assignment they can be given directly • for the composite commands composition, conditional and loop they can be given in terms of valid Hoare triples for their constituent commands • In addition, we need a possibility to construct valid Hoare triples from other valid Hoare triples and valid assertions. Engineering of Reliable Software
Rules ofInference • letf, f1, …, fnbebooleanformulas (hereassertionsor Hoare triples), n≥ 0 • an inferenceruleis a syntacticconstructofthefollowing form: • theinferenceruleiscorrect, ifthevalidityoff (theconclusion) followsfromthevalidityoff1, …, fn (thepremisesorhypotheses) • Note: iftherearenopremises (n = 0), theruleiscalled an axiom Engineering of Reliable Software
Hoare triple for skip • for all assertions P the following Hoare triple is valid: • { P } skip { P } Engineering of Reliable Software
Textual Substitution • Let E and R be expressions and let x be a variable. • E[x:=R] denotes the expression that is the same as E but with all (free) occurrences of xtextually replaced by (R). • Examples • x[x:=z+2] yields (z + 2) or z + 2 • (x + y)[x:=z+2] yields ((z + 2) + y) or z + 2 + y • (x * y)[x:=z+2] yields ((z + 2) * y) or (z + 2) * y • (x < y)[x:=z+2] yields ((z + 2) < y) or z + 2 < y Engineering of Reliable Software
Hoare Triple for Assignment • for all postconditions P, variables x and expressions E, the following Hoare triple is valid: • { P[x:=E] } x := E { P } • Example • postcondition: x = 5 • assignment command: x := x + 1 • precondition: (x = 5)[x:=x+1], which is (x+1) = 5 • thus ⊨{ (x+1) = 5 } x := x + 1 { x = 5 } Engineering of Reliable Software
Hoare Triple for Assignment • Note: one tends to think first that the situation should be vice versa: • { P } x := E { P[x:=E] }. • However, that would yield • { x = 4 } x := x + 1 { (x = 4)[x:=x+1] } and hence • { x = 4 } x := x + 1 { x = 3 } which would not be valid • Fortunately, going from the postcondition to the precondition is consistent with the design process, since the postcondition is the condition one wants to achieve. Engineering of Reliable Software
Hoare Triple for Assignment Why is { P[x:=E] } x := E { P } valid? • let s be the initial state, s' the final state • let v be the value of E in state s • execution of x := E begun in state s stores v into x • thus v is the value of x in state s' • thus the value of E in state s (2) is the same as the value of x in s' (4), that is, v • thus P[x:=E] has the same truth value in s as P has in s' • thus if P[x:=E] is true in s then P is true in s' Engineering of Reliable Software
Hoare Triple for Assignment Further examples • ⊨{ x= 5[x:=5] } x := 5 { x= 5 } or ⊨{ 5 = 5 } x := 5 { x= 5 } • ⊨{ 5 ≠ 5 } x := 5 { x≠ 5 } • ⊨{ (x> x * y)[x:=x*x] } x := x*x { x> x * y } or ⊨{ (x*x) > (x*x) * y } x := x*x { x> x * y } Engineering of Reliable Software
Hoare Triple for Assignment Note: • In fact, application of rule ⊨{ P[x:=E] } x := E { P } yields, for example • ⊨{ (x = 5)[x:=x+1] } x := x + 1 { x = 5 }, that is • ⊨{ (x + 1) = 5 } x := x + 1 { x = 5 }, but not • ⊨{ x = 4 } x := x + 1 { x = 5 } • For this, further knowledge is required, and a further rule, the Rule of Consequence. Engineering of Reliable Software
Valid Assertions • An assertion P is called valid, written ⊨P if it evaluates to true in all possible states. • Examples • ⊨ 0 + x = x + 0 • ⊨P P Q • ⊭x + 1 = y (not valid) Engineering of Reliable Software
RuleofConsequence Theorem LetP, Q, R, Sbeassertions, andC a command. The inferencerule iscorrect. Example: • premises: ⊨ x > 6 ⇒ x > 5, ⊨ { x > 5 } skip { x > 5 } • conclusion: ⊨ { x > 6 } skip { x > 5 } Engineering of Reliable Software
Rule of Consequence Example 1 • ⊨ x = 4 x + 1 = 5 • ⊨{ x + 1 = 5 } x := x + 1 { x = 5 } Therefore • ⊨{ x = 4 } x := x + 1 { x = 5 } Example 2 • ⊨x = 4 y > 9 x = 4 • ⊨{ x = 4 } x := x + 1 { x = 5 } Therefore • ⊨{ x = 4 y > 9 } x := x + 1 { x = 5 } Engineering of Reliable Software
Rule of Consequence as Interface • Hoare logic itself just describes properties of imperative programming language constructs, not of integers, strings, predicates, etc. • For these, additional logics are required. • The Rule of Consequence is an interface between Hoare logic and these other logics. Engineering of Reliable Software
Composition Rule Theorem LetC1, …, Cnbecommands, n≥ 2, P0, P1, …, Pn-1, Pnbeassertions. The inferencerule iscorrect. Example: • ⊨ { y = A x = B } h := x{ y = A h = B } • ⊨ { y = A h = B } x := y{ x = A h = B } • ⊨ { x = A h = B } y := h{ x = A y = B } • ⊨ { y = A x = B } h := x; x := y; y := h{ x = A y = B } Engineering of Reliable Software
(1) { y = X & x = Y } begin (2) { y = X & x = Y } t := x; (3) { y = X & t = Y } begin (4) { y = X & t = Y } x := y; (5) { x = X & t = Y } y := t (6) { x = X & y = Y } end (7) { x = X & y = Y } end (8) { x = X & y = Y } (6) with assignment rule yields (5) (5) with assignment rule yields (4) (4), (5) and (5), (6) with composition rule yields (3), (7) (3) with assignment rule yields (2) (2), (3) and (3), (7) with composition rule yields (1), (8) Note: the program uses three program variables, but any assertion considers only two of them Proof Outline Engineering of Reliable Software
Proof Outline, Annotated Program • Proof outline: a program annotated with assertions (as comments) between each pair of commands • Annotated program: a program annotated with assertions (as comments (or assert-commands)) for purposes of documentation • In practice, annotating a program with assertions that are relevant for understanding the program (but with no others) provides an excellent way of documentation • "Enough assertions should be inserted to make the program understandable, but not so many that the program is hidden from view. In general, a good practice is to insert those assertions that are not so easily determined by the reader, and to omit those that are." • cited from David Gries, The Science of Programming, Springer-Verlag, 1981; page 105. Engineering of Reliable Software
(1) { y = X & x = Y } (2) { y = X & y = Y } begin (3) { y = X & y = Y } x := y; (4) { x = X & x = Y } y := x (5) { x = X & y = Y } end (6) { x = X & y = Y } (5) with assignment rule yields (4) (4) with assignment rule yields (3) (3), (4) and (4), (5) with composition rule yields (2), (6) (1) should imply (2), but that only works if X = Y Note: in a proof outline, two successive assertions (like 1 and 2 here) mean that the second is an implication of the first, thus symbolizing the Rule of Consequence Beginner's "Swap" Engineering of Reliable Software
Exercise 5.1: Swap Program Exercise • Write a proof outline for the swap program starting with the postcondition • { x = X & y = Y & t = Y } where each assertion gives a condition for all three program variables. Engineering of Reliable Software
Exercise 5.2: Strange Swap Exercise • Write a proof outline for the following swap program: • begin x := x-y ; begin y := x+y ; x := y-x end end for postcondition • { x = A y = B } • Note: use the Rule of Consequence twice. Engineering of Reliable Software
Conditional Rule Theorem LetCtandCebecommands, B a booleanexpression, andPandQassertions. The inferencerule iscorrect. Engineering of Reliable Software
Exercise 5.3: Hoare Triple for Conditional Exercise • command C: if x <= y then skip else begin t := x ; begin x := y ; y := t end end endif • Prove ⊨ { true }C { x≤y }. Engineering of Reliable Software
Chess + Dominoes • mutilatedchessboardproblem • given a chessboardwherethetwofieldsoftheoppositecornersaremissing • a dominoematchesexactlytwofieldsofthechessboard • Question: • Is itpossibletoexactly cover themutilatedchessboardwith non-mutilateddominoes? Engineering of Reliable Software
Invariants • a booleanexpressionIiscalled an invariantof a commandCif ⊨ { I } C { I } • Example: { x – y = } // 4. {(x – 1) – (y – 1) = } // 3. x := x – 1; { x – (y – 1) = } // 2.: here, invariant Idoes not hold !!! y := y – 1 { x – y = } // 1. thus: "x – y = "is an invariant of "x := x – 1; y := y – 1" Engineering of Reliable Software
InvariantswithRespectto a Condition • Usuallyweneedinvariantsforloops • an invariant of a loopbodyis also an invariant ofthecompleteloop • but atthebeginningoftheloopbodywecanassumemorethanthe invariant only: wecan also assumetheloopcondition • Example: whilei > 0do { i 0 i > 0} // invariant condition { (i – 1) 0 } i := i – 1 { i 0} // invariant endwhile Engineering of Reliable Software
InvariantswithRespectto a Condition • a booleanexpressionIiscalled an invariant of a commandCwithrespectto a conditionBif ⊨{ I B } C { I } • Example: { i 0 i > 0 } { (i – 1) 0 } i := i – 1 { i 0} thus: "i 0"is an invariant of "i := i – 1" withrespectto "i > 0" Engineering of Reliable Software
Invariantsof a Loop • an invariant IofthebodyC relative totheconditionBof a loopindeedis an invariant ofthecompleteloop: { I } whileBdo { I B} C { I } endwhile { I } • since: • ifIistrueatthebeginningoftheloop, andthebody will notbeexecuted, Iistriviallytrueatthe end • ifIistrueatthebeginningoftheloop, andthebody will beexecutedat least once, then … • … IandBaretrueatthebeginningofthebody, thusIatthe end ofthebody, thus … • … IandBaretrueatthebeginningofthebody, thusIatthe end ofthebody, thus … • … • … thusIis also true after the last executionofthebody — providedthereexists a last execution, thatis, wedon‘thaveand infinite loop • we still giveawaysomeinformation: after the last executionBis also true (sinceotherwisetheloopbodywouldagainbeexecuted) Engineering of Reliable Software
Invariantsof a Loop • withthe last remark, we not onlyhave an invariant ofthecompleteloop, but also a strengthenedpostcondition: { I } whileBdo { I B} C { I } endwhile { I B} • orexpressed in Hoare logic: theinferencerule iscorrect Engineering of Reliable Software
Invariantsof a Loop • asinvariant of a loopwedescribethe invariant oftheloopbodywithrespecttotheloopcondition Engineering of Reliable Software
Correctness of a Loop • usuallywewanttoprovethat a loopiscorrectwithrespectto a preconditionand a postcondition: ⊨ { P } whileBdoCendwhile { Q } • ifweknow a suitable invariant IofC relative toB, thenwecan do this in threesteps: • prove⊨P I • prove⊨{ I B } C { I } • prove⊨I B Q Engineering of Reliable Software
Recipe „Correctness of Loop" summarized: • toprove: ⊨ { P } whileBdoCendwhile { Q} • find a suitable invariant I • prove: • ⊨P I // preconditionPimpliesI • ⊨ { I B } C { I } // Iis indeed an invariant of the loop • ⊨I B Q // Iand negation of loop condition // Bimplies postconditionQ Engineering of Reliable Software
Loop withInitialization • often, loopsare not considered in isolation, but with a suitableinitializationcommandCini in front ofit • Cini ; whileBdoCrependwhile • then one has to prove • ⊨ { P } Cini ; whileBdoCrependwhile{ Q } Engineering of Reliable Software
Exercise: Division Exercise • Command C (our division program): q := 0 ; r := m ; while r >= n do q := q + 1 ; r := r – n endwhile • Prove ⊨{ P} C{ Q } with: • P : m = Mn = NM ≥ 0 N > 0 • Q : m = Mn = Nm = q * n + r 0 ≤r < n • Given: loop invariant: • m = M n = Nm = q * n + r 0 ≤r Engineering of Reliable Software
Importance of Invariants • Loop invariants are the key to understanding loops, and consequently to understanding any non-trivial program. • In general, there are not only loop invariants, but also class invariants, consistency constraints in data bases, etc. • Thinking in terms of invariants is extreeemely useful. • To develop a loop (or class, etc.), one should first think about the invariant, and then about the loop (or class, etc.) itself. • Invariants correspond to the inductive steps in inductive proofs. Engineering of Reliable Software
Finding Invariants and Guards • Note: not all invariantsaresuitedforourtask • Examplesofinvariants: • true, since⊨ { true B }C { true} • but tells nothing, since post-state is completely unrestricted • thus true B areusuallytooweaktoimplythepostcondition • false, since ⊨ { false B }C { false } • but tells nothing, since it makes claims for no states at all • thus falseis too strong to be implied by any precondition ≠ false • B, since ⊨ {B B }C {B} • thus, we need "smart" invariants that allow us to establish a given postcondition • to find them is a topic of its own Engineering of Reliable Software
Finding Invariants and Guards • Programming is a goal-oriented activity: • given is a specification, find a program that fulfills the specification • the most important part of the specification is the postcondition, since it describes what has to be achieved: the postcondition describes our goal • Can we look at the postcondition and find invariant and guard of a loop? • Heuristics have been developed for finding invariants and guards; see for example David Gries, The Science of Programming, Springer-Verlag, 1981; Chapter 16: "Developing Invariants". • The basic idea of these heuristics is some kind of weakening of the postcondition. Engineering of Reliable Software
Finding Invariants and Guards Example (our division example) • the postcondition • { m = Mn = Nm = q * n + r 0 ≤r r< n } can be weakened by removing the last conjunct r < n • this already yields our invariant • the missing conjunct can be obtained as negation of the guard • thus the guard must ber ≥ n (and not r > n, asonemightguesswhenprogrammingbytrialanderror) Engineering of Reliable Software