Some techniques for proving correctness of programs which alter data structures