This short (and optional) chapter develops some basic definitions and a few theorems about binary relations in Coq. The key definitions are repeated where they are actually used (in the Smallstep chapter of Programming Language Foundations), so readers who are already comfortable with these ideas can safely skim or skip this chapter. However, relations are also a good source of exercises for developing facility with Coq's basic reasoning facilities, so it may be useful to look at this material just after the IndProp chapter.
A binary relation on a set X is a family of propositions parameterized by two elements of X -- i.e., a proposition about pairs of elements of X.
Confusingly, the Coq standard library hijacks the generic term
relation
for this specific instance of the idea. To maintain
consistency with the library, we will do the same. So, henceforth
the Coq identifier relation will always refer to a binary
relation between some set and itself, whereas the English word
relation
can refer either to the specific Coq concept or the
more general concept of a relation between any number of possibly
different sets. The context of the discussion should always make
clear which is meant.
An example relation on nat is le, the less-than-or-equal-to relation, which we usually write n1 <= n2.
(Why did we write it this way instead of starting with Inductive le : relation nat...? Because we wanted to put the first nat to the left of the :, which makes Coq generate a somewhat nicer induction principle for reasoning about <=.)
As anyone knows who has taken an undergraduate discrete math course, there is a lot to be said about relations in general, including ways of classifying relations (as reflexive, transitive, etc.), theorems that can be proved generically about certain sorts of relations, constructions that build one relation from another, etc. For example...
A relation R on a set X is a partial function if, for every x, there is at most one y such that R x y -- i.e., R x y1 and R x y2 together imply y1 = y2.
For example, the next_nat relation defined earlier is a partial function.
However, the <= relation on numbers is not a partial function. (Assume, for a contradiction, that <= is a partial function. But then, since 0 <= 0 and 0 <= 1, it follows that 0 = 1. This is nonsense, so our assumption was contradictory.)
Show that the total_relation defined in (an exercise in) IndProp is not a partial function.
Show that the empty_relation defined in (an exercise in) IndProp is a partial function.
A reflexive relation on a set X is one for which every element of X is related to itself.
A relation R is transitive if R a c holds whenever R a b and R b c do.
We can also prove lt_trans more laboriously by induction, without using le_trans. Do this.
Prove the same thing again by induction on o.
The transitivity of le, in turn, can be used to prove some facts that will be useful later (e.g., for the proof of antisymmetry below)...
Provide an informal proof of the following theorem:
Theorem: For every n, ~ (S n <= n)
A formal proof of this is an optional exercise below, but try writing an informal proof without doing the formal proof first.
Proof:
Reflexivity and transitivity are the main concepts we'll need for later chapters, but, for a bit of additional practice working with relations in Coq, let's look at a few other common ones...
A relation R is symmetric if R a b implies R b a.
A relation R is antisymmetric if R a b and R b a together
imply a = b -- that is, if the only cycles
in R are trivial
ones.
A relation is an equivalence if it's reflexive, symmetric, and transitive.
A relation is a partial order when it's reflexive,
anti-symmetric, and transitive. In the Coq standard library
it's called just order
for short.
A preorder is almost like a partial order, but doesn't have to be antisymmetric.
The reflexive, transitive closure of a relation R is the smallest relation that contains R and that is both reflexive and transitive. Formally, it is defined like this in the Relations module of the Coq standard library:
For example, the reflexive and transitive closure of the next_nat relation coincides with the le relation.
The above definition of reflexive, transitive closure is natural:
it says, explicitly, that the reflexive and transitive closure of
R is the least relation that includes R and that is closed
under rules of reflexivity and transitivity. But it turns out
that this definition is not very convenient for doing proofs,
since the nondeterminism
of the rt_trans rule can sometimes
lead to tricky inductions. Here is a more useful definition:
Our new definition of reflexive, transitive closure bundles
the rt_step and rt_trans rules into the single rule step.
The left-hand premise of this step is a single use of R,
leading to a much simpler induction principle.
Before we go on, we should check that the two definitions do indeed define the same relation...
First, we prove two lemmas showing that clos_refl_trans_1n mimics
the behavior of the two missing
clos_refl_trans
constructors.
Then we use these facts to prove that the two definitions of reflexive, transitive closure do indeed define the same relation.