0% found this document useful (0 votes)
75 views38 pages

Understanding Hoare's Logic for Program Correctness

Hoare's Logic is a technique for proving the correctness of computer programs using assertions and logic rules. It involves writing preconditions and postconditions for code segments in Hoare triples of the form {P} S {Q}, where P is the precondition, S is the statement, and Q is the postcondition. A Hoare triple is partially correct if the postcondition Q holds whenever the statement S terminates in a state where the precondition P was initially true. Total correctness requires the statement S to also always terminate. Hoare's Logic provides a way to formally reason about program correctness through the use of assertions and logical rules to manipulate triples.

Uploaded by

Zahra Qamar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
75 views38 pages

Understanding Hoare's Logic for Program Correctness

Hoare's Logic is a technique for proving the correctness of computer programs using assertions and logic rules. It involves writing preconditions and postconditions for code segments in Hoare triples of the form {P} S {Q}, where P is the precondition, S is the statement, and Q is the postcondition. A Hoare triple is partially correct if the postcondition Q holds whenever the statement S terminates in a state where the precondition P was initially true. Total correctness requires the statement S to also always terminate. Hoare's Logic provides a way to formally reason about program correctness through the use of assertions and logical rules to manipulate triples.

Uploaded by

Zahra Qamar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 38

Hoare’s Logic

Dr. Yawar
• [We were] building a missile that must be
trusted, that must work every time, and is a
single shot device, and people’s lives depend
on
When failure it.
Jim McDowell, Managing Director, BAE
is not an Systems
option
• But how do we ensure that a system lives up
to this standard and literally never fails?
• Imagine it’s your first internship, and you are
asked to write a max() method for an IntList
class. You write this code and bring it to your
boss. She says, “Prove to me that it works.”
OK… how do you do that? You could (and
surely would) run some tests on sample
Code is OK? input, but there’s effectively an infinite
number of possible IntLists.
• Tests are useful, but they can’t prove that
your code works in all possible scenarios.
This is where reasoning about code comes
in. Instead of running your code, you step
back and read it.
• You ask: “What is guaranteed to be true at
this point in the program, based on the
statements before it?” Or, going in the other
direction: “If I want to guarantee that some
fact Q is true at this point in the program,
Code is OK? what must be true earlier to provide that
guarantee?” You’ve surely done some of this
naturally. Now you’ll learn to do it in a more
structured way with techniques to help.
Let’s start with a simple code example:
x = 17;
y = 42;
z = x+y;
At each point before/after/in between
statements, what do we know about the state of
the program, specifically the values of variables?
Simple Code Since we’re looking at this chunk of code in
isolation, we don’t know anything before it
executes. After the first line executes, we know
that x = 17. After the second line executes, we still
know that x = 17, and we know that y = 42 too.
After the third line executes, we also know that z
= 17 + 42 = 59.
{ true }
x = 17;
{ x = 17 }
y = 42;
{ x = 17 Λ y = 42 }
How to z = x+y;
{ x = 17 Λ y = 42 Λ z = 59 }
reason Each logical formula shows what must be true
at that point in the program. Since we don’t
know anything at the beginning, only “true”
itself must be true, so we simply write {true}.
Each of the lines with curly braces is an assertion.

An assertion is a logical formula inserted at some


point in a program.

Some
terminologies It is presumed to hold true at that point in the
program.

There are two special assertions:

the precondition and the postcondition.


Assertion: invariant at specific program point

Using Predicate placed in a program to indicate that the


Assertions in developer thinks that the predicate is always true at that
place, point.

Programming
– use assertions as foundation for static correctness proofs
– specify assertions at every program point
– correctness reduced to reasoning about individual
statements
In this lecture all our variables will store numbers
only.
So all our assertions about the state will be built
Assertions – out of variables, numbers, and basic arithmetic
relations:
Preconditions • x = 3;
• x = y;
and • x- 6= y;
Postconditions • x > 0;
• x ≤ (y2 + 1 3 4);
• etc
We may want to make complicated claims
about several different variables, so we will
Assertions – use propositional logic to combine the simple
Preconditions assertions, e.g.
• x = 4 ^ y = 2;
and • x < 0 ^ y < 0;
Postconditions • x > y ^ x= 2 ∗ y;
ctd • True;
• False.
• A precondition is an assertion inserted prior to
execution,
• A postcondition is an assertion inserted after
execution.
• In the example above, {true} is the precondition
and { x = 17 Λ y = 42 Λ z = 59 } is the postcondition.
Precondition,
• All other assertions are called intermediate
postcondition assertions.
• They serve as steps as you reason between
precondition and postcondition,
• kind of like the intermediate steps in a math
problem that show how you get from problem to
solution.
• let’s look at this two-line block of code:
x = y;
x = x + 1;
{x>0}
• The postcondition is x > 0. We want to know
what must be true beforehand for the
Another postcondition to be satisfied. We start with the
last statement: x = x + 1. If x > 0 afterward, then
Example the value assigned to x (namely, x+1) must be >
0 beforehand. We add this assertion:
x = y;
{x+1>0}
x = x + 1;
{x>0}
Now we look at the second-to-last statement:
x = y. If x + 1 > 0 after this statement, then [the
value assigned to x] + 1 > 0 beforehand. That
is, y + 1 > 0. We add this assertion:
{y+1>0}
x = y;
{x+1>0}
Continue x = x + 1;
{x>0}
Since there are no more statements, we’re
done. We have proven that if y + 1 > 0 before
this block of code executes, then x > 0
afterward
To prove things about programs, we first need to
fix a programming language. For this we’ll define
a little language with four different kinds of
statement.
Assignment – x := e
A Very where x is a variable, and e is an expression with
Simple variables and arithmetic that returns a number,
e.g. 2+ 3, x ∗ y+ 1...
Imperative Sequencing – S1; S2
Conditional – if b then S1 else S2
Language where b is an expression with variables,
arithmetic and logic that returns a boolean (true
or false), e.g. y < 0, x 6= y ^ z = 0...
While – while b do S
• Imperative languages are built around a program state (data stored in
memory).
• A state is a valuation of all program variables.
• Imperative programs are sequences of commands that modify that
state
• A program statement defines transitions between
Imperative program states.

language
and
program
Specifications of
imperative
programs
• To prove properties of imperative programs, we
need
• A way of expressing assertions about program
states.
• Rules for manipulating and proving those
assertions.
• Predicate, standard mathematical notation
Continue together with logical operators.
• A precondition, statement, and postcondition
together form a Hoare triple.
• Preconditions and postconditions are typically
written inside curly braces to distinguish them
from program code
These will be provided by Hoare Logic
C. A. R. (Tony) Hoare
• The inventor of this week’s logic is also famous for
inventing the Quicksort algorithm in 1960 - when he was
just 26!
• A quote: Computer programming is an exact science in
that all the properties of a program and all the
consequences of executing it in any given environment
can, in principle, be found out from the text of the
program itself by means of purely deductive reasoning.
• The goal of Hoare logic is to provide a formal system
for reasoning about program correctness.
• Proving that program will work correctly!
• Hoare’s Triple
• {P} S {Q}
• S= program statement, P= precondition, Q=
post-condition
• partial correctness: if S is executed in a
Hoare, 1969 state initially satisfying P and it terminates,
then the final state satisfies Q
• total correctness: as partial, but also
requires termination
• The implementation of a function/program is
partially correct with respect to its specification if,
assuming the precondition is true just before the
function executes, then if the function terminates,
the post-condition is true.
• The implementation is totally correct if, again
Partial and assuming the precondition is true before function
Total executes, the function is guaranteed to terminate
and when it does, the post-condition is true.
correctness • The (total correctness) meaning of a triple {P } S {Q}
is that if we start in a state where P is true and
execute S, then S will terminate in a state where Q is
true.
• Thus total correctness is partial correctness plus
termination
• A partial correctness specification {p}c{q} is valid, iff
• if c is executed in a state initially satisfying p
• and if the execution of c terminates
• then the final state satisfies q
 
• A total correctness specification [p]c[q] is valid, iff
• if c is executed in a state initially satisfying p
Continue • then the execution of c terminates
• and the final state satisfies q
• Partial correctness  termination assumed
• Total correctness  termination demanded

• Informally: Total correctness = Termination + Partial


correctness
Hoare logic expresses partial correctness.

We say a program is partially correct if it gives the


right answer whenever it terminates.
Partial It never gives a wrong answer, but it may give no
Correctness answer at all.

{P } S {Q } does NOT imply that S terminates, even if


P holds initially. For example

{x = 1} while x=1 do y:=2 {x = 3}

is true in Hoare logic.


• For a program c,
• partial correctness specification:
• {p}c{q}
• total correctness specification:
• [p]c[q]
• Here p and q are assertions, i.e., conditions on
Continue the program variables used in c.
• p is called precondition, and q is called post-
condition
• P is a predicate describes the precondition of C
• Q is a predicate describes the postcondition of C
• {true}c{q}
This says that whenever c terminates, then
How to q holds
differentiate • [true]c[q]
• This says that c always terminates and ends
in a state where q holds
• Hoare logic uses Hoare Triples to reason
about program correctness. A Hoare Triple is
of the form {P } S {Q}, where P is the
Reasoning precondition, Q is the post-condition, and S
is the statement(s) that implement the
about our function.
program • A logic for reasoning about programs and
assertions
Floyd-Hoare Logic also known as Hoare logic

Three
Parts
Components
of Hoare
Logic A precondition
2. A code fragment
3. A post-condition
Assertions
The precondition is an assertion saying something of
interest about the state before the code is executed.
The post-condition is a assertion saying something of
interest about the state after the code is executed.
{P}S{Q} means
  Whenever S is executed in a state satisfying P
and if the execution of S terminates Then the
state in which S terminates satisfies Q.
Meaning of   Example: {X = 1} X:= X+1 {X = 2}
  P: the value of X is 1
Hoare’s   Q: the value of X is 2
Notation   S: an assignment X:= X + 1
  X becomes X + 1
  {X = 1} X := X + 1 {X = 2} is true
  {X = 1} X := X + 1 {X = 2} is false
1. {X = 1} Y:=X {Y = 1}
This says that if the command Y:=X is executed
in a state satisfying the condition X = 1 (i.e. a
state in which the value of X is 1), then, if the
execution terminates (which it does), then the
condition Y = 1 will hold. Clearly this
Continue specification is true.
2. {X = 1} Y:=X {Y = 2}
This says that if the execution of Y:=X
terminates when started in a state satisfying X
= 1, then Y = 2 will hold. This is clearly false
• { true } x := 5 {x=5 }
A Hoare’s • {x=y } x := x + 3 { x = y + 3 }
TRIPLE
• a Hoare triple is invalid if there can be
a scenario where P is true, S is executed, and Q
is false afterwards.
• To give a subtler example of an invalid Hoare
triple:
• { x >= 0 } Invalid Hoare triple
Invalid Triple • y = 2*x;
• {y>x}
• Suppose x = 0 in the initial state. P is satisfied
initially, but afterward y = 0 = x and Q is not
satisfied. If we change Q from y > x to y >= x,
then the Hoare triple becomes valid.
• Now we look at the second-to-last statement: x = y. If x + 1 > 0 after
this statement, then [the value assigned to x] + 1 > 0 beforehand. That
is, y + 1 > 0. We add this assertion:
{y+1>0}
x = y;
{x+1>0}
x = x + 1;
{x>0}
Since there are no more statements, we’re done. We have proven
that if y + 1 > 0 before this block of code executes, then x > 0
afterward
• In the example above, y + 1 > 0 is not the
only valid precondition.
• How about the precondition y = 117? Or y >
100?
Weakest • These, too, guarantee the postcondition.
precondition • Technically they’re correct, but intuitively
they’re not as useful.
• They are more restrictive about the values of
y for which the program is guaranteed to be
correct.
• We usually want to use the precondition that
guarantees correctness for the broadest set of
inputs.
• Stated differently, we want the weakest
precondition:
• the most general precondition needed to establish
the postcondition. The terms “weak” and “strong”
Continue refer to how general or specific an assertion is.
• The weaker an assertion is, the more general it is;
the stronger it is, the more specific it is.
• We write P = wp(S,Q) to indicate that P is the
weakest precondition for statement S and
postcondition Q
• (x = 6) ⇒ (x > 0), so (x = 6) is stronger than (x
> 0)
• The statement:{x = 5} x := x + 1 {x = 6}
• says more about the code than:
Strong post- • {x = 5} x := x + 1 {x > 0}
condition • If a postcondition Q1 is stronger than Q2,
• then {P }S {Q1} is a stronger statement than
{P }S {Q2}.
• Consider the Hoare triple {x = 5} x := x ∗2 {x >
0}. This triple is clearly correct, because if x = 5
and we multiply x by 2, we get x = 10 which
clearly implies that x > 0.
• However, although correct, this Hoare triple is
Another not a precise as we might like. Specifically, we
could write a stronger post-condition, i.e. one
Example that implies x > 0. For example, x > 5 && x < 20
is stronger because it is more informative
• It pins down the value of x more precisely than
x > 0. The strongest post-condition possible is x
= 10; this is the most useful post-condition.
• Here are a number of valid Hoare Triples:
• {x = 5} x := x * 2 { true }
Strongest • {x = 5} x := x * 2 { x > 0 }
• {x = 5} x := x * 2 { x = 10 || x = 5 }
Post
• {x = 5} x := x * 2 { x = 10 }
condition • All are true, but this one is the most useful
• x=10 is the strongest postcondition
• (Usually we are interested in strong
Weak postconditions and weak preconditions,
because they say more about the code.)
precondition
• We can use pre- and post-conditions to specify the
effect of a code fragment on the state, but how do
we prove or disprove a Hoare Triple specification?
• Is {P } S {Q } true?
• We need a logic or a calculus:
• a collection of rules and procedures for (formally)
How to manipulating the (language of) triples. 
• (Just like algebra, just like logic . . . ) 
prove
• We will now turn to developing and applying a basic
version of Hoare Logic.
• A proof in Floyd-Hoare logic is a sequence of lines,
each of which is either an axiom of the logic or
follows from earlier lines by a rule of inference of
the logic

You might also like