Skip to content

Precondition-Postcondition Framing

Why It Matters

Most confusion about "broken" systems comes from unstated preconditions. A function isn't "buggy" if you violate its preconditions - you broke the contract. This framing forces you to be explicit about assumptions, preventing the common error of expecting behavior outside the guaranteed domain. It distinguishes "this operation failed" from "you used it wrong."

The Key Move

For any operation, procedure, or claim, explicitly state: "This works when [precondition] and guarantees [postcondition]." When something fails, check which failed: did the precondition not hold, or did the postcondition not follow? Never say "this should work" - say "this works when X, guaranteeing Y."

Classic Application

Programming language semantics. Hoare logic formalizes this as {P} C {Q} - if precondition P holds before executing command C, then postcondition Q holds after. A simple example: {x ≥ 0} y := sqrt(x) {y² = x} - square root requires non-negative input and guarantees the result squared equals the input.

Surprising Application

Relationship advice. "Be yourself" is terrible advice without preconditions. Better: "If you've already established basic compatibility and trust [precondition], then authentic self-expression strengthens the relationship [postcondition]." The advice isn't wrong; it was missing its precondition, making it sound universally applicable when it only works in specific contexts.

Failure Modes

Over-specification creates preconditions so restrictive the operation becomes useless. Under-specification leaves implicit assumptions that cause failures. False precision - treating approximate postconditions as exact guarantees. Confusing necessary with sufficient conditions in preconditions.

Go Deeper

Hoare, "An Axiomatic Basis for Computer Programming" (1969); Gries, The Science of Programming, Chapter 2