{-# OPTIONS --without-K --rewriting #-}

open import lib.Base
open import lib.Equivalence
open import lib.NType
open import lib.Function
open import lib.Funext
open import lib.types.Sigma
open import lib.types.Pi

-- function extensionality for functions of higher arity

module lib.Funext2 {i} {A : Type i} where

  module _ {j} where

    Π-iter : (n : ℕ-ₚ) (P : ×⦅ n  A  Type j)  Type (lmax i j)
    Π-iter I P = Π A P
    Π-iter (S n) P = Π A  a  Π-iter n (curry P a))

    infixr 80 _∼^_
    _∼^_ : {n : ℕ-ₚ} {P : ×⦅ n  A  Type j}  Π-iter n P  Π-iter n P  Type (lmax i j)
    _∼^_ {n = I} f g = f  g
    _∼^_ {n = S n} f g = (a : A)  _∼^_ {n = n} (f a) (g a)

    app=-equiv-iter : {n : ℕ-ₚ} {P : ×⦅ n  A  Type j} {f g : Π-iter n P}  (f == g)  (f ∼^ g)
    app=-equiv-iter {I} {f = f} {g = g} = app=-equiv
    app=-equiv-iter {S n} {f = f} {g = g} = lemma ∘e app=-equiv
      where
        lemma : (f  g)  Π A  a  f a ∼^ g a)
        lemma = Π-emap-r  a  app=-equiv-iter {n} {f = f a} {g = g a})        

    funhom-iter-contr : (n : ℕ-ₚ) {P : ×⦅ n  A  Type j} (f : Π-iter n P)  is-contr (Σ (Π-iter n P)  g  f ∼^ g))
    funhom-iter-contr _ f = equiv-preserves-level (Σ-emap-r  g  app=-equiv-iter)) {{pathfrom-is-contr f}}

    funhom-iter-contr-to : (n : ℕ-ₚ) {P : ×⦅ n  A  Type j} (f : Π-iter n P)  is-contr (Σ (Π-iter n P)  g  g ∼^ f))
    funhom-iter-contr-to _ f = equiv-preserves-level (Σ-emap-r  g  app=-equiv-iter)) {{pathto-is-contr f}}