Hackers News

The Hoare Cube – Wickopedia

I wrote earlier this year about my attempt to understand the repercussions of toggling \subseteq and \supseteq when giving a semantics to Hoare triples. In response to that post, Yann Herklotz helpfully pointed me to Patrick Cousot’s POPL 2024 paper [10], which does all this and a lot more besides. In particular, Cousot’s paper includes the following diagram…

…which shows how to obtain dozens of program logics just by toggling a handful of switches in the semantics.

However, that diagram is completely terrifying, and (just between you and me) I can’t get my head around much of the rest of Cousot’s paper. So, this blog post is my attempt to end up with a similar diagram to Cousot’s one, but while trying to keep things as simple as possible.


Let us assume that we have a set of states, and that a command is simply a binary relation on states. We shall write (\sigma, \sigma') \in c to mean that if command c is started in state \sigma it can produce final state \sigma'. Our commands need not always terminate: if there is no \sigma' such that (\sigma, \sigma') \in c, then that means c does not terminate when started in state \sigma. Also, our commands can be non-deterministic: if (\sigma, \sigma') \in c and (\sigma, \sigma'') \in c with \sigma' \neq \sigma'', then that means c behaves non-deterministically when started in state \sigma.

The original “partial correctness” interpretation [1] of the Hoare triple \{P\}\,c\,\{Q\} is that whenever c is started in a state satisfying the assertion P (an assertion is just a set of states), any final state it reaches must satisfy the assertion Q. That is…

\forall \sigma, \sigma'\ldotp \sigma \in P \wedge (\sigma,\sigma') \in c \longrightarrow \sigma' \in Q.

Let us define a helper function: the “strongest postcondition”. We shall write \text{sp}(P,c) for the set of all states that command c can reach if it starts executing in a P state…

\text{sp}(P, c) = \{\sigma'\ldotp \exists\sigma\ldotp (\sigma,\sigma') \in c \wedge \sigma \in P\}.

We can use \text{sp} to give a semantics to Hoare triples in a variety of different ways. For instance, the partial correctness interpretation given above can be rewritten as…

\text{sp}(P,c) \subseteq Q.

Flipping the \subseteq into a \supseteq to get Incorrectness logic…

\text{sp}(P,c) \supseteq Q

…is what led O’Hearn to remark that “program correctness and incorrectness are two sides of the same coin”. But there are other components that can be “flipped” too. I think there are three “dimensions” in total:

(NB: Cousot seems to identify four dimensions in his diagram above, but I haven’t understood what his fourth one is.)

The eight options, then, are as follows:

Note that partial correctness can also be rewritten into the more familiar P \subseteq \text{wlp}(c, Q) if we define \text{wlp} as the “weakest liberal precondition” in the usual way…

\text{wlp}(c,Q) = \{\sigma\ldotp \forall\sigma'\ldotp (\sigma,\sigma') \in c \longrightarrow \sigma' \in Q\}

…but I quite like how “systematic” the table above is: it distinguishes may from must by negating the pre and postconditions; it distinguishes forward from backward by using c or c^{-1}; and it distinguishes over from under approximate by using \subseteq or \supseteq.

Note also that I’ve labelled \text{sp}(\neg P,c) \subseteq \neg Q as the “original” formulation of necessary preconditions, as it captures the two negatives in Cousot et al.’s definition quite nicely: “under which precondition, if violated, will the program always be incorrect?” [7, my emphasis].


We can assemble all eight options in the table into a cube — a “Hoare cube”, if you will.

In the cube, I’ve drawn solid lines between vertices that represent equal semantics. For instance, may+forward+over is equal to must+backward+over because…

\text{sp}(P,c) \subseteq Q \quad\Longleftrightarrow\quad \text{sp}(\neg Q,c^{-1}) \subseteq \neg P.

Sometimes these equalities can be phrased as Galois connections. For instance…

\text{sp}(P,c) \subseteq Q \quad\Longleftrightarrow\quad P \subseteq \text{wlp}(c, Q)

…signifies a Galois connection between \text{sp}(-,c) and \text{wlp}(c, -).

I’ve also drawn dashed lines between vertices that represent equivalent semantics. By “equivalent” here, I mean that there exists a bijection f between triples such that the triple \{P\}\,c\,\{Q\} holds according to one semantics if and only if the triple f(\{P\}\,c\,\{Q\}) holds according to the other semantics. What this means is that one strategy for proving \{P\}\,c\,\{Q\} under one semantics is to prove f(\{P\}\,c\,\{Q\}) under the other semantics.

For instance, may+backward+over (necessary preconditions, \text{NC}) is equivalent to may+forward+over (partial correctness, \text{PC}) because…

\text{NC} \models \{P\}\,c\,\{Q\} \quad\Longleftrightarrow\quad \text{PC} \models \{\neg P\}\,c\,\{\neg Q\}

…as Ascari et al. have observed [4, Proposition 5.4]. Here we use the bijection f_1 that maps \{P\}\,c\,\{Q\} to \{\neg P\}\,c\,\{\neg Q\}.

For another instance, may+forward+under (incorrectness logic, \text{IL}) is equivalent to may+backward+under (sufficient incorrectness logic, \text{SIL}) because, using another bijection f_2 that maps \{P\}\,c\,\{Q\} to \{Q\}\,c^{-1}\,\{P\}, we have…

\text{IL} \models \{P\}\,c\,\{Q\} \quad\Longleftrightarrow\quad \text{SIL} \models \{Q\}\,c^{-1}\,\{P\}.

For this reason, I’ve deemed all of the over nodes equivalent (and coloured them green) and all of the under nodes equivalent (and coloured them blue).

But is it a bit of a stretch to consider all those same-coloured nodes “equivalent”? I mean, if the point of these bijections is to suggest how a proof in one logic can be transformed into a proof in another logic, then are these transformations reasonable? The bijection f_2, for instance, requires the ability to invert an arbitrary command (turning c into c^{-1}). That’s straightforward enough for simple programs, thanks to properties like (c; d)^{-1} = (d^{-1} ; c^{-1}) and (c + d)^{-1} = (c^{-1} + d^{-1}) and (c^*)^{-1} = (c^{-1})^*, but it could become infeasible in more complicated settings. Likewise, the bijection f_1 requires the ability to negate an arbitrary assertion (turning P into \neg P), which is fine in ordinary predicate logic but doesn’t work very nicely in a substructural logic like separation logic.

Still, it does give a pretty handy way to generate proof rules for one logic from the proof rules for another logic. For instance, Ascari et al. [4] present this proof rule from incorrectness logic…

…and if we apply our bijection f_2 to all the triples in this rule, then we obtain “for free” the corresponding proof rule from their sufficient incorrectness logic…

…without having to prove anything about its soundness.

To conclude: perhaps program correctness and incorrectness are not simply two sides of the same coin, but two opposite faces of the same cube!

Related work

Möller et al. [2, Section 5] define and briefly study “backward under-approximate Hoare triples”. Zilberstein et al. [3] refer to those triples also as “Lisbon triples”. Ascari et al. [4] define sufficient incorrectness logic as a proof system for those “backward under-approximate Hoare triples”, and I’m grateful to Ike Mulder who referred me to Ascari et al.’s paper in a comment on my earlier blog post.

Zilberstein et al. [3] defines and studies “Outcome logic”, but I haven’t included it in my “cube” because I don’t think it quite fits with the other logics – its postconditions are not simply “sets of states”, but have a more complicated monoidal structure. I also haven’t included “Exact separation logic” [11], which unifies over-approximate and under-approximate reasoning in the context of separation logic.

Zhang and Benjamin Kaminsky [8, Section 6.3] also studied the eight options in my table above, similarly obtained by toggling three binary switches (albeit with slightly different names), and I’m grateful to Benjamin for pointing me to his work in a comment on my earlier blog post. I’ve reproduced their table here:

The two blue rows in their table are equal, and they correspond to the two “partial correctness” vertices in my cube. The two orange lines are also equal, and they correspond to the two “necessary preconditions” vertices in my cube. I also haven’t got names for the ??? and ¿¿¿ logics, but I note that ??? can be straightforwardly obtained from sufficient incorrectness logic via the f_1 bijection I defined above, and ¿¿¿ can be obtained from incorrectness logic in the same way, so I think this makes it unlikely that those logics will offer anything particularly new.

For the record: one potential point of confusion in Zhang and Kaminsky’s table is that what they call “wp” is actually what O’Hearn [6, Section 6.3] calls the “weakest possible precondition”: the sets of states from which c can reach a final state satisfying the postcondition (but due to non-determinism, might not). Thus, I think “total correctness” should probably be read as “possible correctness”, following Hoare’s terminology [9, Section 5.3].

Bibliography

admin

The realistic wildlife fine art paintings and prints of Jacquie Vaux begin with a deep appreciation of wildlife and the environment. Jacquie Vaux grew up in the Pacific Northwest, soon developed an appreciation for nature by observing the native wildlife of the area. Encouraged by her grandmother, she began painting the creatures she loves and has continued for the past four decades. Now a resident of Ft. Collins, CO she is an avid hiker, but always carries her camera, and is ready to capture a nature or wildlife image, to use as a reference for her fine art paintings.

Related Articles

Leave a Reply