-- Author: Floris van Doorn open eq is_trunc variables {I : Type} [is_set I] {P : I → Type} {i j k : I} {x x₁ x₂ : P i} {y y₁ y₂ : P j} {z : P k} {Q : Π⦃i⦄, P i → Type} structure heq (x : P i) (y : P j) : Type := (p : i = j) (q : x =[p] y) namespace eq notation x ` ==[`:50 P:0 `] `:0 y:50 := @heq _ _ P _ _ x y infix ` == `:50 := heq -- mostly for printing, since it will be almost always ambiguous what P is definition pathover_of_heq {p : i = j} (q : x ==[P] y) : x =[p] y := change_path !is_set.elim (heq.q q) definition eq_of_heq (p : x₁ ==[P] x₂) : x₁ = x₂ := eq_of_pathover_idp (pathover_of_heq p) definition heq.elim (p : x ==[P] y) (q : Q x) : Q y := begin induction p with p r, induction r, exact q end definition heq.refl [refl] (x : P i) : x ==[P] x := heq.mk idp idpo definition heq.rfl : x ==[P] x := heq.refl x definition heq.symm [symm] (p : x ==[P] y) : y ==[P] x := begin induction p with p q, constructor, exact q⁻¹ᵒ end definition heq_of_eq (p : x₁ = x₂) : x₁ ==[P] x₂ := heq.mk idp (pathover_idp_of_eq p) definition heq.trans [trans] (p : x ==[P] y) (p₂ : y ==[P] z) : x ==[P] z := begin induction p with p q, induction p₂ with p₂ q₂, constructor, exact q ⬝o q₂ end infix ` ⬝he `:72 := heq.trans postfix `⁻¹ʰᵉ`:(max+10) := heq.symm definition heq_of_heq_of_eq (p : x ==[P] y) (p₂ : y = y₂) : x ==[P] y₂ := p ⬝he heq_of_eq p₂ definition heq_of_eq_of_heq (p : x = x₂) (p₂ : x₂ ==[P] y) : x ==[P] y := heq_of_eq p ⬝he p₂ infix ` ⬝hep `:73 := concato_eq infix ` ⬝phe `:74 := eq_concato definition heq_tr (p : i = j) (x : P i) : x ==[P] transport P p x := heq.mk p !pathover_tr definition tr_heq (p : i = j) (x : P i) : transport P p x ==[P] x := (heq_tr p x)⁻¹ʰᵉ end eq