This is a computer science question, not a programming question, so it would be more appropriate on https://cs.stackexchange.com/, but I'll answer it anyway.
Consider this program to find the first index of a needle in a haystack. (The haystack might contain many needles; we want to stop at the first one.) If the haystack doesn't contain a needle, the index is equal to the size of the haystack (which is not a valid index into the haystack).
i = 0
while i < haystack.count && haystack[i] != needle {
i = i + 1
}
A “postcondition” is an assertion about the state of a program that, typically, says the program has computed something useful (at the point of the postcondition). For the example program, we can write postconditions asserting that it computed the result we want:
i = 0
while i < haystack.count && haystack[i] != needle {
i = i + 1
}
assert(i == haystack.count || haystack[i] == needle) // first postcondition
haystack[0 ..< i].forEach { assert($0 != needle) } // second postcondition
(Note: 0 ..< i
means all j
such that 0 ≤ j < i
.)
The first postcondition asserts that either i is the number of items in the haystack, or i is the index of a needle.
The second postcondition asserts that a needle doesn't appear in the haystack anywhere earlier than index i. Therefore the program found the first needle, if it found any needle.
Thus if these postconditions are true, the program did what we wanted.
A “precondition” is an assertion about the state of the program that, when combined with the program's subsequent actions, can be used to prove the postconditions. We can add preconditions to our example program:
i = 0
while i < haystack.count && haystack[i] != needle {
haystack[0 ... i].forEach { assert($0 != needle) } // precondition
i = i + 1
}
assert(i == haystack.count || haystack[i] == needle) // first postcondition
haystack[0 ..< i].forEach { assert($0 != needle) } // second postcondition
(Note: 0 ... i
means all j
such that 0 ≤ j ≤ i
.)
The precondition tells us that all of the haystack elements up to and including the element at index i
are not the needle.
You can use induction to prove that the precondition is true every time the program reaches it. The loop ends when its condition is false, which means the first postcondition is true. (The first postcondition is the contrapositive of the loop condition.) The fact that the loop precondition was true means that the second postcondition is also true.
[[ ... ]]
rather than{ ...}
). – Miocene