We assume a type X and represent binary relations
on X as functions X -> X -> Prop.
Parameter X : Type.
Definition relation := X -> X -> Prop.
We define some properties for relations.
Definition reflexive (r: relation) := forall x, r x x.
Definition transitive (r: relation) := forall x y z, r x y -> r y z -> r x z.
Definition left_trans (r p: relation) := forall x y z, r x y -> p y z -> p x z.
Definition contained (r p: relation) := forall x y, r x y -> p x y.
Definition equivalent (r p: relation) := contained r p /\ contained p r.
Proposition P1 r p :
reflexive p -> left_trans r p -> contained r p.
Proof.
unfold contained. eauto.
Qed.
Proposition P2 r p :
reflexive p -> transitive p -> contained r p -> left_trans r p.
Proof.
unfold left_trans. eauto.
Qed.
Here are possible definitions of the reflexive
transitive closure r* of a relation r.
- r is the reachability relation of the directed graph (X,r). That is, r*xy if and only if there is a path from node x to node y in the graph (X,r).
- r* is the union of all relations r^n.
- r* is the intersection of all relations that are reflexive and left transitive for r.
- r* is the intersection of all relations that are reflexive, transitive, and contain r.
- r* is the least relation that is reflexive and left transitive for r.
- r* is the least relation that is reflexive, transitive, and contains r.
- r* is the relation inductively obtained with the
inference rules
rxy r*yz === ========== rxx r*xz
- r* is the relation inductively obtained with the
inference rules
r*xy r*yz rxy === ========== ==== rxx r*xz r*xy
Inductive stari (r: relation): relation :=
| stari_R : reflexive (stari r)
| stari_LT : left_trans r (stari r).
This definition gives us a function stari that
maps relations to relations. Given a relation r, the
relation stari r can be taken as the reflexive
transitive closure of r.
Next we define r* as the union of all relations r^n. Note that this definition of the rflexive transitive closure is very close to the graph-based definition.
Next we define r* as the union of all relations r^n. Note that this definition of the rflexive transitive closure is very close to the graph-based definition.
Definition id: relation := fun x y => x=y.
Definition comp (r p: relation) : relation :=
fun x y => exists z, r x z /\ p z y.
Fixpoint iter (X:Type) n x (f: X->X) :=
match n with 0 => x | S n' => f(iter X n' x f) end.
Definition starn (r: relation) : relation :=
fun x y => exists n, iter relation n id (comp r) x y.
Finally, we define r* as the intersection of all
reflexive relations that are left transitive for
r.
Definition stard (r: relation): relation :=
fun x y => forall p, reflexive p -> left_trans r p -> p x y.
This definition of the reflexive transitive closure
is mathematically the most lightweight in that it is
neither inductive nor does it use natural numbers.
We now turn to the task of showing that the three definitions are equivalent. We first define two predicates weak and faithful.
We now turn to the task of showing that the three definitions are equivalent. We first define two predicates weak and faithful.
Definition weak r p := forall q, reflexive q -> left_trans r q -> contained p q.
Definition faithful r p := reflexive p /\ left_trans r p /\ weak r p.
Note that a relation p is faithful for a relation
r if p is the least reflexive relation that is left
transitive for r. Hence we expect that all relations
that a faithful for a given relation r are
equivalent, and that the relations stari r, starn
r, and stard r are all faithful. The proofs are not
difficult.
Proposition faithful_canonical r p q:
faithful r p -> faithful r q -> equivalent p q.
Proof.
unfold faithful. unfold equivalent. intuition.
Qed.
Proposition stari_faithful r: faithful r (stari r).
Proof.
unfold faithful. intuition.
(* R *) apply stari_R.
(* LT *) apply stari_LT.
(* W *) unfold weak. unfold contained. intros. induction H1.
apply H.
eapply H0; eauto.
Qed.
Ltac sinv h := (inversion h; clear h; subst).
Proposition starn_faithful r: faithful r (starn r).
Proof.
unfold faithful. unfold starn. intuition.
(* R *) unfold reflexive. intros.
exists 0. simpl. unfold id. reflexivity.
(* LT *) unfold left_trans. intros. sinv H0.
exists (S x0). simpl. unfold comp at 1. eauto.
(* W *) unfold weak. unfold contained. intros. sinv H1.
rename x0 into n. generalize dependent x. induction n; intros.
simpl in H2. unfold id in H2. subst. apply H.
simpl in H2. unfold comp at 1 in H2. sinv H2. sinv H1. eapply H0; eauto.
Qed.
Proposition stard_faithful r: faithful r (stard r).
Proof.
unfold faithful. unfold stard. intuition.
(* R *) unfold reflexive. auto.
(* LT *) unfold left_trans at 1. intros.
eapply H2; eauto. eapply H0; eauto.
(* W *) unfold weak. unfold contained. intros.
eapply H1; eauto.
Qed.
It is easy to prove that faithful relations are
transitive. Note that this implies that our operators
stari, starn, and stard all yield transitive
relations.
Proposition faithful_transitive r p: faithful r p -> transitive p.
Proof.
unfold faithful. unfold transitive. intuition.
cut (contained p (fun x y: X => p y z -> p x z)).
unfold contained. eauto.
apply H2.
unfold reflexive. auto.
unfold left_trans. eauto.
Qed.
All faithful relations are weak, and weakness can
be used like an induction principle. If we check the
induction principle stari_ind for stari, we see
that it is somewhat stronger than weakness. It is not
difficult to prove a stronger induction principle for
faithful relations that corresponds exactly to the
induction principle that is automatically generated for
the inductively defined stari.
Proposition faithful_induction r p q: faithful r p ->
reflexive q ->
(forall x y z, r x y -> p y z -> q y z -> q x z) ->
contained p q.
Proof.
unfold faithful. intuition.
cut (contained p (fun x y => p x y /\ q x y)).
unfold contained. intuition. apply H3 in H5. intuition.
apply H4.
unfold reflexive. auto.
unfold left_trans. intuition.
eapply H; eauto.
eapply H1; eauto.
Qed.
So there is no need to define the reflexive
transitive closure inductively. In fact, every
inductive definition of a relation can be turned into a
non-inductive definition in the style of stard. This
is nice to know, but in practice it is advantageous to
use inductive definitions since then the induction
principle comes for free. Moreover, given the inductive
definition, we can use the induction tactic (i.e.,
induction H), which automatically synthesizes the
predicate p to be used for the induction.
This page has been generated by coqdoc