Explain the rely-guarantee approach to concurrency verification and how it enables compositional reasoning about threads.
Think about your answer, then reveal below.
Model answer: Each thread is specified with four conditions: a precondition (P), postcondition (Q), rely (R) — what the thread assumes other threads will do to shared state, and guarantee (G) — what this thread promises about its own modifications to shared state. A thread is correct if, assuming its environment adheres to R, the thread's execution from P establishes Q while adhering to G. Compositionality comes from checking that each thread's guarantee implies the other threads' rely conditions — the guarantees of one thread justify the assumptions of the others.
Rely-guarantee, introduced by Jones (1983), was the first compositional approach to concurrent verification. Without it, you must reason about all interleavings globally. With rely-guarantee, each thread is verified independently under assumptions about its environment, and a compatibility check ensures the assumptions are justified. This is analogous to assume-guarantee reasoning in model checking and to interface contracts in modular software design. The approach complements concurrent separation logic: separation logic handles spatial (heap) decomposition, while rely-guarantee handles temporal (interference) decomposition.