Verification of Concurrent Programs: Temporal Proof Principles