Reasoning About Programs - Lecture 1 Notes
Course Introduction: Reasoning About Programs
Introduction
- Course focuses on systematically reasoning about code to ensure correctness.
- Moves beyond testing and debugging to treat code as a mathematical object.
- Aims to enhance code understanding and improve programming skills.
The Difficulty of Achieving Program Correctness
- Quote from Carol Morgan (UNSW) highlights the common experience of initial programming success followed by persistent errors.
- The challenge of creating programs that are fully correct and fail-proof is emphasized.
Binary Search Experiment
- John Bentley's experiment: Programmers at Bell Labs and IBM were asked to write binary search.
- Binary search algorithm: Efficiently searches a sorted array by repeatedly dividing the search interval in half.
- time complexity compared to linear search.
- Experiment result: 90% of programmers had bugs in their binary search code.
- Carol Morgan's experiment with fourth-year computer science students at UNSW yielded similar results.
- These experiment underscores the difficulty of writing correct code, even for well-known algorithms.
Zoom MP3 Player Bug
In 2006, Microsoft released the Zoom MP3 player to compete with Apple's iPod.
On New Year's Eve 2008, all Zoom players froze due to a software bug.
The bug was in the code responsible for calculating the current year, based on the number of days since 1980.
The incorrect code:
while (days > 365) { if (isLeapYear(year)) { if (days > 366) { days -= 366; } } else { days -= 365; } year++; }The issue: An infinite loop occurred on leap years when the day was 366.
The root cause was the
ifstatement without anelsewithin the leap year check resulting in being unable to decrement days.Microsoft's failure to catch the leap year bug highlights the challenges of thorough testing.
Incorrect fixes for the bug:
- The initial fixes posted online were also incorrect, demonstrating the subtlety of the problem.
- It took three attempts to produce a correct fix, highlighting the difficulty of ensuring correctness even in simple programs.
Timsort Bug
- Timsort: A sorting algorithm used in Java's
Collections.sortandArrays.sortmethods, and formerly in Python. - Developed in 2002 by Tim Peters, Timsort adapts to runs of already sorted data within the input.
- Combines merge sort and insertion sort techniques for efficiency.
- In 2015, a Dutch computer scientist discovered a bug in Timsort that could lead to an "ArrayIndexOutOfBoundsException".
- The bug's existence despite extensive testing highlights the limitations of relying solely on testing for correctness.
- The bug was identified through formal methods.
Formal Methods
- Formal methods: Mathematical techniques for reasoning about programs and software.
- Edsger Dijkstra's quote: "Program testing can be used to show the presence of bugs, but never to show their absence."
- Formal methods aim to prove the absence of bugs by treating programs as mathematical objects.
- Involves formal specification and formal proof to verify program correctness.
- Formal methods are typically applied to critical or complex parts of code rather than entire large programs.
- Early work in formal methods:
- Robert Floyd (1967): Assigned meanings to programs using predicate logic.
- Tony Hoare (1969): Developed an axiomatic basis for computer programming.
- Edsger Dijkstra: Weakest precondition calculus.
- Adoption by Industry:
- Initially limited to safety-critical software (aerospace, railway).
- Increased adoption in recent years by companies like Amazon and Meta.
- Key factors driving adoption include:
- Increased importance of verifying programs.
- Development of powerful automated tools.
- Examples of tools: Key, Verifast, Viper, Dafny.
- Languages designed for verification: Y3, Whiley, Dafny.
Course Overview
- Focuses on formal verification of program correctness.
- Covers deriving correct programs from formal specifications.
- Uses the Daphne tool for formal verification.
Daphne: A Verification-Aware Programming Language
- Supports formal specifications and static program verification.
- Object-based (classes and objects) but without inheritance.
- Supports functional programming (not covered in this course).
- Can be compiled to C, C++, Go, Java, JavaScript, and Python.
- Daphne can detect runtime errors like division by zero and array index out of bounds.
Daphne Syntax Overview
- Classes, functions, predicates, and methods.
- Assignment (
:=) including simultaneous assignments. - Variable introduction (
var). - If-then-else statements and while loops.
Daphne Types
- Native basic types: Booleans, characters, integers, naturals, reals.
- Collection types: Sequences, sets, multisets, maps.
- Arrays for efficient programming.
Zoom Bug Revisited using Daphne
- The Zoom bug code rewritten in Daphne. Daphne immediately flags the non-termination issue.
- Daphne indicates "cannot prove termination"
- Daphne can detect possible division by zero errors with the message "possible division by zero"
- Daphne can detect index out of range errors with the message "index out of range"