uniformly reversed — this one is going to be more difficult.
Say we are in the prep phase of a recipe, and we have bowls on the counter with various ingredients. Our slice of the universe considers only what bowls are on the counter, and what ingredients are in these bowls. Amount of ingredients and number of dishes in the sink are ignored.
Now let
add(milk) denote the action of adding a bowl of milk to the counter. We can reverse this action by removing a bowl of milk from the counter. Call this
remove(milk). Then performing
remove(milk) right after
add(milk) completely undoes the
add(milk), just as we want.
But recall that actions are required to be
unconditional: the action
remove(milk) must
also have instructions for what to do if there is no milk to remove. We can resolve this simply by asking that
remove(milk) do nothing in the cases where there is no milk to remove.
Perhaps this feels a little unsatisfactory, though: amending
remove(milk) this way feels like something we shouldn’t even have to think about.
To that end, we want reversals to be
uniform, which is to say, they don’t have to worry about these edge cases. In particular, we ask that an action’s reversal can be done either before
or after the action and either way it will negate the action. In the case of the recipe, we can do this by expanding our universe to also allow us to place sticky notes on the counter which say “if you are going to add a milk, please don’t”. Then
remove(milk) will remove a milk if one is present, or add a sticky note otherwise.
Mathematically we say that an action and its reversal must
commute.
(alt. justification — we want actions and their removals to be ‘disjoint’ in that they don’t interact with each other. that is, they commute)