A good specification is concerned only with the net effect of a design and not how it is constructed. Thus specifications should be entirely mathematical in nature. Sometimes designs are subject to certain constraints. A typical constraint might be that two inputs are related, say one is the always inverse of the other. In which case the theorem to be proved will have the form which states that the implementation meets the specification provided that the constraints hold.
Constraints help to simplify a proof obligation by removing certain cases from consideration.
Relaxing the correctness criterion from equivalence to implication allows the specification to stipulate only selected properties of an implementation's behaviour. The devices we prove now will be used later as building blocks in the construction of larger systems. Their correctness statements enable us to replace the detail and volume of the implementation by the distilled and mathematical specification wherever a verified device is used as a building block. Once a piece of hardware has been specified and verified, the specification, implementation and correctness proof can be saved in a verification library. When that hardware is used later in a more complex design, we don't need to know how it was constructed, we can just work with its specification in the new verification.