71 points by SchwKatze 2 weeks ago | 14 comments
efitz 1 week ago
In the course of my work, I think of an invariant as a state that must hold true at all points during the software’s execution.
For example, “port xxx must never accept inbound traffic”.
I don’t think of invariants as mindsets; I think of them as runtime requirements that are observable and testable at any point during execution, and whose violation is an indication that some assumption about state that the proper execution of the software depends on, no longer holds.
Maybe a good analogy would be “a runtime assert”.
ryandv 1 week ago
We must show three things about a loop invariant:
Initialization: It is true prior to the first iteration of the loop.
Maintenance: If it is true before an iteration of the loop, it remains true before the next iteration.
Termination: When the loop terminates, the invariant gives us a useful property that helps show that the algorithm is correct.
Which is very much what the article says: lo <= insertion_point <= hi
should hold on every iteration. It clearly holds before we enter the loop.
[...] The invariant, the condition binding lo and hi, holds on every iteration.
They are indeed observable and testable during runtime, but beyond just being dependencies on certain subsets of your state space, or "runtime asserts," they are properties that must hold as a necessary consequence of the operation of the algorithm. One proves that an invariant is necessarily true in the process of demonstrating the correctness of an algorithm.In terms of concrete implementations of an algorithm, this in some way makes the "runtime assert" redundant, for, at least in principle, one can statically analyze the code and then prove, before runtime, that the expressions being asserted must necessarily be true (subject to certain preconditions), and even optimize them out.
Of course, this presumes that you have indeed implemented the algorithm correctly - and one way to determine this is to see whether or not your implementation satisfies those same properties and invariants that the abstract description of the algorithm depends upon, and the article also discusses this point.
JadeNB 1 week ago
That seems quite close to the author's answer:
> Perhaps it’s time to answer the title question: invariant is some property which holds at all times during dynamic evolution of the system.
swatcoder 1 week ago
For an essay titled "What is an invariant?", it doesn't really focus on answering the question at all and so the GP's failure to spot the traditional answer is pretty reasonable. A more fitting title may have been something more like "Invariants in software system design" -- better framing that it'll be a survey of examples and their rationales rather than an analysis of invariants.
hansvm 1 week ago
A lot of software exposition fails on that front. If you're familiar with invariants as a crucial tool for reasoning about software systems, then the essay will be a bit fluffy. It looks decent for a newcomer to the topic to rapidly build up intuition though.
MontagFTB 1 week ago
lupire 1 week ago
If you have a good wall of abstraction, you have freedom in the internals and security in the observables.
UltraSane 6 days ago
The first example if found when googling "python invariants" was a BankAccount class that did exactly this
class BankAccount:
"""
A bank account class with a representation invariant: balance is always non-negative.
"""
def __init__(self, initial_balance):
self.balance = initial_balance
assert self.balance >= 0, "Balance cannot be negative"
def deposit(self, amount):
assert amount > 0, "Deposit amount must be positive"
self.balance += amount
def withdraw(self, amount):
assert amount > 0, "Withdrawal amount must be positive"
assert self.balance >= amount, "Insufficient funds"
self.balance -= amount
driggs 1 week ago
https://learn.adacore.com/courses/intro-to-ada/chapters/cont...
UltraSane 6 days ago
renox 6 days ago
MarkLowenstein 1 week ago
fishstock25 1 week ago
The pre-condition is a special case, then the invariant provides the "guard rails" along which the computation proceeds, and then the post-condition is again a special case which ultimately is the result of the computation.
In the search example of the computation, the pre-condition is "the position is somewhere in the allowed indices", the post-condition is "the return value is the position". The stated invariant is "the value is between current min and max bounds". These bounds become tighter and tighter, so that eventually the pre-condition is transformed into the post-condition.