The Invariant Principle is a proof technique used to verify properties of State Machines or iterative processes. It is a specific application of Mathematical Induction.
A State Machine consists of:
- States: A set of possible configurations.
- Transitions: Rules for moving from one state to another ().
- Start State: The initial configuration ().
Definition: Preserved Invariant
A predicate is a preserved invariant of a state machine if:
- If is true for a state , and there is a transition , then is also true.
- Formally:
- Base Case: is true (Given).
- Inductive Step: If state is reachable and is true, any transition leads to . Since is preserved, is true.
Example: The Die Hard Water Jugs
Problem: You have a 3-gallon jug and a 5-gallon jug. Can you measure exactly 4 gallons? Transitions:
- Fill a jug completely.
- Empty a jug completely.
- Pour from one jug to another until the first is empty or the second is full.
Invariant Analysis:
- Let the state be , the amount of water in the 3-gal and 5-gal jugs.
- Start state: .
- Invariant: and are always linear combinations of 3 and 5. Specifically, is a multiple of .
- Since , we can reach any integer amount between 0 and 8.
- this shows we CAN do it.
Counter-Example: The 3 and 6 Gallon Jugs
- Can you measure 4 gallons with a 3-gal and 6-gal jug?
- Invariant: The amount of water is always a linear combination of 3 and 6.
- .
- Therefore, any amount of water must be a multiple of 3.
- Conclusion: Since 4 is not a multiple of 3, it is impossible to reach 4 gallons. The state is unreachable.
Application in Systems
- Loop Invariants: Used to prove correctness of algorithms (e.g., sorting).
- Rust’s Memory Safety: The Rust compiler enforces specific invariants (like “Every value has exactly one owner”) at compile time. If the code compiles, the invariant holds for all executions.