Reasoning about concurrent programs : refining rely-guarantee thinking