Computer science literature abounds with descriptions of program verifiers, systems which analyse a software program and attempt to prove automatically that the program satisfies behavioural specifications. Techniques used include predicate abstraction, three-valued heaps graphs and classes of polyhedra. Yet while these systems have had some encouraging successes, each deals only with particular patterns of program behaviour: e.g. predicate abstraction can infer arithmetical relationships but does not capture the 'shape' of linked data structures; for three-valued shape graphs the reverse is true. Thus typical programs, in which different patterns of behaviour are mixed up together, still cannot be verified automatically. This thesis explor...