Instead, contracts are largely used to constrain inputs and outputs in ways that the type system is not rich enough to describe, such as by requiring that numbers are within a certain range, or that references are non-null.To match programmer expectations, preconditions and postconditions are designed to satisfy the Liskov substitution principle.