Constraint-based Program Reasoning with Heaps and Separation