Counting constrained integers up to N requires a prefix position, a tight flag, and the property state. I want the notation, the mechanism, and the failure mode visible at the same time.
Objects and notation
A full dynamic-programming state \(dp[i][s]\) states exactly which prefix \(i\) and mathematical state \(s\) have been processed. The recurrence is a theorem about transitions between these states.
There are two layers here: the object \(\mathsf D\) and the law \(\mathsf C\). Writing them separately makes the direction of \(\Longrightarrow\) visible and keeps an accidental converse from slipping in.
Push the symbols
Here is a concrete symbolic test. Reading it from left to right reveals which transformation is reversible and which is only an implication.
Structural reading
The invariant statement is the one that does not depend on a convenient choice of coordinates, representatives, basis, or enumeration.
A hypothesis worth keeping
State compression is an implementation change, not the definition. Loop order is safe only after the uncompressed dependency graph is understood.
The important habit is to remember what was fixed before the calculation began and what was proved only afterward. The final display preserves that order.