Foundations of Program Verification: Theory and Practice