Spec == /\ Init /\ [][Next]_vars
/\ WF_vars(Next)
/\ SF_vars(ssd)
/\ SF_vars(sData)
/\ SF_vars(rData)
/\ SF_vars(wire)
/\ SF_vars(ackWire)
/\ SF_vars(sender)
Spec == /\ Init /\ [][Next]_vars /\ WF_vars(Next) /\ SF_vars(ackWire) /\ SF_vars(sData \/ ssd) /\ SF_vars(receiver)It is interesting that fairness in TLA+ is defined on the behaviour with regard to a single step. Where as in a world with concurrent components, say your phone and my phone, a step my phone might take could act unfairly in as much as it prevented the execution of another step on my phone. But, the steps on my phone are fair with respect to steps on your phone as my phone can never prevent your phone from performing its steps. So it would seem that fairness might be better viewed as a function of more than one step. Then steps on distinct processes by default behave fairly with respect to each other and it is only hard to implement fairness between steps on the same process.
I have to admit that, when I place fairness conditions every where, I am being influenced by my past experiences formalising concurrent systems. In process algebras it is decided that every thing is fair or every thing is not fair (largely no distinction is made between strong and weak fairness). In either case, fair or unfair, liveness conditions can be preserved by selecting the appropriate semantics. Consequently I am unfamiliar with using a fairness condition to establish a liveness property.