# RelProperties of Relations

*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.

# Relations

*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.

Definition relation (X: Type) := X → X → Prop.

An example relation on nat is le, the less-than-or-equal-to
relation, which we usually write n

_{1}≤ n_{2}.
Print le.

(* ====> Inductive le (n : nat) : nat -> Prop :=

le_n : n <= n

| le_S : forall m : nat, n <= m -> n <= S m *)

Check le : nat → nat → Prop.

Check le : relation nat.

(* ====> Inductive le (n : nat) : nat -> Prop :=

le_n : n <= n

| le_S : forall m : nat, n <= m -> n <= S m *)

Check le : nat → nat → Prop.

Check le : relation nat.

(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 ≤.)

# Basic Properties

### Partial Functions

*partial function*if, for every x, there is at most one y such that R x y — i.e., R x y

_{1}and R x y

_{2}together imply y

_{1}= y

_{2}.

Definition partial_function {X: Type} (R: relation X) :=

∀x y

∀x y

_{1}y_{2}: X, R x y_{1}→ R x y_{2}→ y_{1}= y_{2}.
For example, the next_nat relation defined earlier is a partial
function.

Print next_nat.

(* ====> Inductive next_nat (n : nat) : nat -> Prop :=

nn : next_nat n (S n) *)

Check next_nat : relation nat.

Theorem next_nat_partial_function :

partial_function next_nat.

(* ====> Inductive next_nat (n : nat) : nat -> Prop :=

nn : next_nat n (S n) *)

Check next_nat : relation nat.

Theorem next_nat_partial_function :

partial_function next_nat.

Proof.

unfold partial_function.

intros x y

inversion H

reflexivity. Qed.

unfold partial_function.

intros x y

_{1}y_{2}H_{1}H_{2}.inversion H

_{1}. inversion H_{2}.reflexivity. Qed.

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.)

Theorem le_not_a_partial_function :

¬(partial_function le).

¬(partial_function le).

Proof.

unfold not. unfold partial_function. intros Hc.

assert (0 = 1) as Nonsense. {

apply Hc with (x := 0).

- apply le_n.

- apply le_S. apply le_n. }

discriminate Nonsense. Qed.

unfold not. unfold partial_function. intros Hc.

assert (0 = 1) as Nonsense. {

apply Hc with (x := 0).

- apply le_n.

- apply le_S. apply le_n. }

discriminate Nonsense. Qed.

### Reflexive Relations

*reflexive*relation on a set X is one for which every element of X is related to itself.

Definition reflexive {X: Type} (R: relation X) :=

∀a : X, R a a.

Theorem le_reflexive :

reflexive le.

∀a : X, R a a.

Theorem le_reflexive :

reflexive le.

Proof.

unfold reflexive. intros n. apply le_n. Qed.

unfold reflexive. intros n. apply le_n. Qed.

Definition transitive {X: Type} (R: relation X) :=

∀a b c : X, (R a b) → (R b c) → (R a c).

Theorem le_trans :

transitive le.

∀a b c : X, (R a b) → (R b c) → (R a c).

Theorem le_trans :

transitive le.

Proof.

intros n m o Hnm Hmo.

induction Hmo.

- (* le_n *) apply Hnm.

- (* le_S *) apply le_S. apply IHHmo. Qed.

intros n m o Hnm Hmo.

induction Hmo.

- (* le_n *) apply Hnm.

- (* le_S *) apply le_S. apply IHHmo. Qed.

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 and Antisymmetric Relations

*symmetric*if R a b implies R b a.
Definition symmetric {X: Type} (R: relation X) :=

∀a b : X, (R a b) → (R b a).

∀a b : X, (R a b) → (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.
Definition antisymmetric {X: Type} (R: relation X) :=

∀a b : X, (R a b) → (R b a) → a = b.

∀a b : X, (R a b) → (R b a) → a = b.

Definition equivalence {X:Type} (R: relation X) :=

(reflexive R) ∧ (symmetric R) ∧ (transitive R).

(reflexive R) ∧ (symmetric R) ∧ (transitive R).

### Partial Orders and Preorders

*partial order*when it's reflexive,

*anti*-symmetric, and transitive. In the Coq standard library it's called just "order" for short.

Definition order {X:Type} (R: relation X) :=

(reflexive R) ∧ (antisymmetric R) ∧ (transitive R).

(reflexive R) ∧ (antisymmetric R) ∧ (transitive R).

A preorder is almost like a partial order, but doesn't have to be
antisymmetric.

Definition preorder {X:Type} (R: relation X) :=

(reflexive R) ∧ (transitive R).

(reflexive R) ∧ (transitive R).

# Reflexive, Transitive Closure

*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:

Inductive clos_refl_trans {A: Type} (R: relation A) : relation A :=

| rt_step x y (H : R x y) : clos_refl_trans R x y

| rt_refl x : clos_refl_trans R x x

| rt_trans x y z

(Hxy : clos_refl_trans R x y)

(Hyz : clos_refl_trans R y z) :

clos_refl_trans R x z.

| rt_step x y (H : R x y) : clos_refl_trans R x y

| rt_refl x : clos_refl_trans R x x

| rt_trans x y z

(Hxy : clos_refl_trans R x y)

(Hyz : clos_refl_trans R y z) :

clos_refl_trans R x z.

For example, the reflexive and transitive closure of the
next_nat relation coincides with the le relation.

Theorem next_nat_closure_is_le : ∀n m,

(n ≤ m) ↔ ((clos_refl_trans next_nat) n m).

(n ≤ m) ↔ ((clos_refl_trans next_nat) n m).

Proof.

intros n m. split.

- (* -> *)

intro H. induction H.

+ (* le_n *) apply rt_refl.

+ (* le_S *)

apply rt_trans with m. apply IHle. apply rt_step.

apply nn.

- (* <- *)

intro H. induction H.

+ (* rt_step *) inversion H. apply le_S. apply le_n.

+ (* rt_refl *) apply le_n.

+ (* rt_trans *)

apply le_trans with y.

apply IHclos_refl_trans1.

apply IHclos_refl_trans2. Qed.

intros n m. split.

- (* -> *)

intro H. induction H.

+ (* le_n *) apply rt_refl.

+ (* le_S *)

apply rt_trans with m. apply IHle. apply rt_step.

apply nn.

- (* <- *)

intro H. induction H.

+ (* rt_step *) inversion H. apply le_S. apply le_n.

+ (* rt_refl *) apply le_n.

+ (* rt_trans *)

apply le_trans with y.

apply IHclos_refl_trans1.

apply IHclos_refl_trans2. Qed.

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:

Inductive clos_refl_trans_1n {A : Type}

(R : relation A) (x : A)

: A → Prop :=

| rt1n_refl : clos_refl_trans_1n R x x

| rt1n_trans (y z : A)

(Hxy : R x y) (Hrest : clos_refl_trans_1n R y z) :

clos_refl_trans_1n R x z.

(R : relation A) (x : A)

: A → Prop :=

| rt1n_refl : clos_refl_trans_1n R x x

| rt1n_trans (y z : A)

(Hxy : R x y) (Hrest : clos_refl_trans_1n R y z) :

clos_refl_trans_1n R x z.

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.

Lemma rsc_R : ∀(X:Type) (R:relation X) (x y : X),

R x y → clos_refl_trans_1n R x y.

R x y → clos_refl_trans_1n R x y.

Proof.

intros X R x y H.

apply rt1n_trans with y. apply H. apply rt1n_refl. Qed.

intros X R x y H.

apply rt1n_trans with y. apply H. apply rt1n_refl. Qed.

Lemma rsc_trans :

∀(X:Type) (R: relation X) (x y z : X),

clos_refl_trans_1n R x y →

clos_refl_trans_1n R y z →

clos_refl_trans_1n R x z.

Proof.

(* FILL IN HERE *) Admitted.

☐
∀(X:Type) (R: relation X) (x y z : X),

clos_refl_trans_1n R x y →

clos_refl_trans_1n R y z →

clos_refl_trans_1n R x z.

Proof.

(* FILL IN HERE *) Admitted.

#### Exercise: 3 stars, standard, optional (rtc_rsc_coincide)

Theorem rtc_rsc_coincide :

∀(X:Type) (R: relation X) (x y : X),

clos_refl_trans R x y ↔ clos_refl_trans_1n R x y.

Proof.

(* FILL IN HERE *) Admitted.

☐
∀(X:Type) (R: relation X) (x y : X),

clos_refl_trans R x y ↔ clos_refl_trans_1n R x y.

Proof.

(* FILL IN HERE *) Admitted.