I’m trying to understand why the notation R ==> S has the same definition as R ++> S.
I would naively expect it to have a definition like (fun x y => R x y \/ R y x) ++> S, since according to the documentation:
The special arrow
==>is used in signatures for morphisms that are both covariant and contravariant.
I understand that for symmetric relations the distinction doesn’t matter. But for relations that are not symmetric, I believe it does.
When/why would one use ==> over ++>?
Here’s a development to illustrate what my question:
From Stdlib Require Import Setoid Morphisms.
(* Simple pre-order (implication on truth values). *)
Inductive P : Set := F | T.
Inductive R : P -> P -> Prop :=
| RFF : R F F
| RFT : R F T
| RTT : R T T
.
Lemma R_refl : reflexive P R.
Proof. intros [|]; auto using R. Qed.
Lemma R_not_sym : ~ (symmetric P R).
Proof. intro H; specialize (H F T RFT); inversion H. Qed.
Lemma R_trans : transitive P R.
Proof. intros [|] [|] [|]; auto using R. Qed.
(* Register the relation. *)
Add Relation P R
reflexivity proved by R_refl
transitivity proved by R_trans
as pr.
(* Simple co- and contra-variant morphism (constant function). *)
Definition f (_ : P) : P := F.
Section fails.
(* Register the morphism as co- and contra-variant. *)
Add Morphism f with signature R ==> R as fm.
(* But somehow only prove the co-variant part. *)
Proof. intros; exact RFF. Qed.
(* Co-variance works as expected. *)
Goal forall x y, R x y -> R (f x) (f y).
Proof. intros x y H; rewrite H; reflexivity. Qed.
(* Contra-variance does not work (as expected?). *)
Goal forall x y, R y x -> R (f x) (f y).
Proof.
intros x y H.
(* Not sure how to read the error (if it expects symmetry or a missing morphism). *)
Fail rewrite H.
Abort.
End fails.
Section works.
(* Register the morphism as co- and then contra-variant. *)
Add Morphism f with signature R ++> R as fmp.
Proof. intros; exact RFF. Qed.
Add Morphism f with signature R --> R as fmn.
Proof. intros; exact RFF. Qed.
(* Co-variance still works as expected. *)
Goal forall x y, R x y -> R (f x) (f y).
Proof. intros x y H; rewrite H; reflexivity. Qed.
(* Contra-variance now also works as expected. *)
Goal forall x y, R y x -> R (f x) (f y).
Proof. intros x y H; rewrite H; reflexivity. Qed.
End works.
Section naive.
(* Define ==> as being both co- and contra-variant. *)
Definition or_flip {T} (R : relation T) : relation T := fun x y => R x y \/ R y x.
Notation "R ==> S" := (respectful (or_flip R) S) : signature_scope.
(* Prove the morphism is both co- and contra-variant. *)
Lemma m : Proper (R ==> R) f.
Proof. intros x y _; exact RFF. Qed.
(* Co-variance works using the left side of [or_flip]. *)
Goal forall x y, R x y -> R (f x) (f y).
Proof. intros x y H; apply m; left; exact H. Qed.
(* Contra-variance works using the right side of [or_flip]. *)
Goal forall x y, R y x -> R (f x) (f y).
Proof. intros x y H; apply m; right; exact H. Qed.
End naive.