Hoare-Logic
- Hoare-Logic
- Motivation
- Hoare Triples
- Application
- Assignment
- Composition
- Branching
- Looping
- Weakest Precondition
- Further Resources
Hoare-Logic
Motivation
A formal system for verification of a program’s correctness.
Hoare Triples
The central feature of Hoare logic is the Hoare triple. It describes how the execution of a piece of code changes the state of the computation. It is of the form
where and are assertions and is a command/piece of code. is called the precondition and the postcondition. and are formulae in predicate logic. When the precondition is met, executing the command establishes the postcondition.
The understanding of a Hoare triple is straightforward: Whenever holds of the state before execution of , then either will not terminate or will hold afterwards, i.e.,
Application
Forward Conclusion
- Defines what can be concluded from original assumptions
- Very useful when an invariante is to hold
- Simulates the execution of the program
- Easy to understand, however many details must be stored
- Problem: changing the value of a variable can influence other assumptions/assertions. We need to change the name of the variable whose value is changed in the postcondition to be able to reference such a variable correctly.
Backward Conclusion
- Identifies sufficient conditions to guarantee a given outcome
- If the outcome is desirable, then program correctness follows from those conditions
- If the outcome is undesirable, then the conditions suffice to generate a bug
- Often times of high practical use. One must understand what each and every command contributes to reaching a certain state
Assignment
A variable is substituted by another variable. is valid if and only if
Composition
A triple is valid if there exists assertion such that
- is valid and
- is valid
Branching
A triple is valid if there exist assertions such that
- is valid and
- is valid and
Looping
A triple is valid if there exists an invariant such that
- Invariant is valid before entering the loop, i.e.,
- Invariant is valid after executing the loop body, i.e., is a valid triple
- Invariant implies postcondition, i.e.,
Note that this only holds if there are no non-local control transfers in the loop body (i.e., no continue; or break; statements). Invariants must be neither too strong nor too weak.
Methodology for finding Invariants
- Define an invariant first and let the other steps guide you. What brings us closer to the goal every iteration? What needs to hold after every iteration?
- Write a body for the loop that makes the invariant valid
- Write the loop condition such that it implies the postcondition if it is false
- Write the initialisation such that the code ensures the invariant
Partial Correctness vs. Total Correctness
Without proving that terminates we can only prove partial correctness of a Hoare triple . could run into system faults (out of memory, OS killing the process etc.) or enter an infinite loop. We can prove the latter. Idea: map the state after execution of the loop to a natural number such that that number decreases after every execution of the loop body. Then we can find proof that the loop test was if that number goes to zero in a finite amount of steps. Therefore we would have shown termination. Example: summation of 1 through . Map to: . Positive at the start (), decreases in every iteration ( unchanged, ), when then and the loop terminates.
Weakest Precondition
For preconditions , if we say that is weaker than . When concluding in the backwards direction one should always find the weakest preconditions as one can then also conclude the stronger ones. Without loops and methods there exists a unique weakest precondition for every program segment , denoted . The weakest precondition is .