Raw File
From HoTT Require Import Basics Types Truncations.

(** The "fiber" of a map with respect to a relation. *)
Definition rfiber {X Y : Type} (R : Relation Y) (f : X -> Y) (y : Y) : Type
  := exists x, R (f x) y.

Definition lfiber {X Y : Type} (R : Relation Y) (f : X -> Y) (y : Y) : Type
  := exists x, R y (f x).

(** * The equivalence relation generated by a relation. *)

(** We model the equivalence relation generated by a relation using alternating zig-zags, and by throwing in reflexivity relations. It's easy to show that the resulting relation is an equivalence relation. *)

(** The 'zig' goes forward, and the 'zag' goes backward *)
Fixpoint zig_or_zag {X : Type} (R : Relation X) (n : nat) (x0 x1 : X) : Type
  := match n with
     | 0%nat => x0 = x1
     | S n => exists x, zig_or_zag R n x0 x * (R x x1 + R x1 x)
     end.

(** The equivalence relation generated by a relation [R]. *) 
Definition EqRel {X : Type} (R : Relation X) (x0 x1 : X) : Type
  := exists n, zig_or_zag R n x0 x1.

(** We can add ("cons") a zig or a zag at the end of a chain of such. *)

Definition zig_cons {X : Type} (R : Relation X) {x0 x1 x2 : X}
  (rho : EqRel R x0 x1) (zig : R x1 x2)
  : EqRel R x0 x2
  := (S rho.1; (x1; (rho.2, inl zig))).
                       
Definition zag_cons {X : Type} (R : Relation X) {x0 x1 x2 : X}
  (rho : EqRel R x0 x1) (zag : R x2 x1)
  : EqRel R x0 x2
  := (S rho.1; (x1; (rho.2, inr zag))).

Global Instance reflexive_eqrel {X : Type} (R : Relation X)
  : Reflexive (EqRel R) := fun _ => (0%nat; idpath).

Definition zig_to_eqrel {X : Type} (R : Relation X)
  {x0 x1 : X} (zig : R x0 x1) : EqRel R x0 x1
  := zig_cons R (reflexivity _) zig.

Definition zag_to_eqrel {X : Type} (R : Relation X)
  {x0 x1 : X} (zag : R x1 x0) : EqRel R x0 x1
  := zag_cons R (reflexivity _) zag.

(** ** [EqRel R] is an equivalence relation. We saw reflexivity above. *)

Global Instance transitive_eqrel {X : Type} (R : Relation X)
  : Transitive (EqRel R).
Proof.
  intros x0 x1 x2 rho01 [m zzs].
  revert x1 x2 rho01 zzs.
  induction m as [|m IH]; intros.
  - by induction zzs.
  - destruct zzs as [x [zzs [zig|zag]]].
    + exact (zig_cons R (IH _ _ rho01 zzs) zig).
    + exact (zag_cons R (IH _ _ rho01 zzs) zag).
Defined.

Global Instance symmetric_eqrel {X : Type} (R : Relation X)
  : Symmetric (EqRel R).
Proof.
  intros x0 x1 [n zzs]; revert x0 x1 zzs.
  induction n as [|n IH].
  - intros ? ? p; exact (0%nat; p^).
  - intros ? ? [x [zzs zorz]].
    transitivity x.
    2: by apply IH.
    destruct zorz as [zig|zag].
    + exact (zag_to_eqrel R zig).
    + exact (zig_to_eqrel R zag).
Defined.

(** To check whether a map respects [EqRel R], we just need to check that it respects [R]. *)
Definition eqrel_generator {X Y : Type}
  (R : Relation X) (Q : Relation Y) (f : X -> Y)
  : (forall x0 x1, R x0 x1 -> Q (f x0) (f x1))
    -> (forall x0 x1, EqRel R x0 x1 -> EqRel Q (f x0) (f x1)).
Proof.
  intros f_resp x0 x1 [n zz].
  (* we need a free endpoint before inducting on [n] *)
  revert dependent x1.
  induction n as [|n IH].
  1: intros; by induction zz.
  intros x1 [x [zz [zig|zag]]].
  - exact (zig_cons _ (IH _ zz) (f_resp _ _ zig)).
  - exact (zag_cons _ (IH _ zz) (f_resp _ _ zag)).
Defined.

Definition MEqRel {X : Type} (R : Relation X) (x0 x1 : X) : Type
  := merely (EqRel R x0 x1).

Definition zig_to_meqrel {X : Type} (R : Relation X)
  : forall x0 x1, R x0 x1 -> MEqRel R x0 x1
  := fun _ _ rho => tr (zig_to_eqrel R rho).

Definition zag_to_meqrel {X : Type} (R : Relation X) {x0 x1 : X}
  (zag : R x1 x0) : MEqRel R x0 x1
  := tr (zag_to_eqrel R zag).

Global Instance reflexive_meqrel {X : Type} (R : Relation X)
  : Reflexive (MEqRel R) := fun _ => tr (0%nat; idpath).

Global Instance transitive_meqrel {X : Type} (R : Relation X)
  : Transitive (MEqRel R).
Proof.
Proof.
  intros x0 x1 x2 rho01 rho12; strip_truncations.
  destruct rho12 as [m zzs].
  revert x1 x2 rho01 zzs.
  induction m as [|m IH]; intros.
  - induction zzs.
    exact (tr rho01).
  - destruct zzs as [x [zzs [zig|zag]]];
      pose proof (IHz := IH _ _ rho01 zzs); strip_truncations.
    + exact (tr (zig_cons R IHz zig)).
    + exact (tr (zag_cons R IHz zag)).
Defined.

Global Instance symmetric_meqrel {X : Type} (R : Relation X)
  : Symmetric (MEqRel R).
Proof.
  intros x0 x1; apply Trunc_rec; intros [n zzs].
  revert x0 x1 zzs.
  induction n as [|n IH].
  - intros ? ? p; exact (tr (0%nat; p^)).
  - intros ? ? [x [zzs zorz]].
    transitivity x.
    2: by apply IH.
    destruct zorz as [zig|zag].
    + exact (tr (zag_to_eqrel R zig)).
    + exact (tr (zig_to_eqrel R zag)).
Defined.
back to top