1/12/2025 at 2:05:28 PM
I’m not sure that I agree with the article.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”.
by efitz
1/12/2025 at 4:01:57 PM
CLRS defines loop invariants pretty clearly: 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.
by ryandv
1/12/2025 at 2:37:30 PM
> 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.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.
by JadeNB
1/12/2025 at 2:58:28 PM
Indeed, but the author works through a deeply idiosyncratic train of thought before getting to that, and then quickly continues with some creative analogizing about how the idea of an invariant might be applied at other scales.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.
by swatcoder
1/12/2025 at 3:27:11 PM
It's just the inductive reasoning version of the essay rather than the deductive version.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.
by hansvm
1/12/2025 at 2:45:58 PM
For data structures, an invariant is something that must hold true at the end of all its public APIs. For example a doubly-linked list may have to break invariants around its pointers while in the middle of a splice or insert. But at the end of those public routines they must all be valid and conformant to the type’s requirements.by MontagFTB
1/12/2025 at 2:55:52 PM
Right. A "system" is the observable parts.If you have a good wall of abstraction, you have freedom in the internals and security in the observables.
by lupire
1/13/2025 at 8:03:58 PM
"Maybe a good analogy would be “a runtime assert”."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
by UltraSane