{-# OPTIONS --without-K #-}
module function.extensionality.computation where

open import equality
open import function.isomorphism.core
open import function.core
open import function.extensionality.core
open import function.extensionality.proof
open import function.extensionality.strong

funext-inv-hom :  {i j}{X : Set i}{Y : X  Set j}
                {f₁ f₂ f₃ : (x : X)  Y x}
                (p₁ : f₁  f₂)
                (p₂ : f₂  f₃)
                funext-inv (p₁ · p₂)
                 x  funext-inv p₁ x · funext-inv p₂ x)
funext-inv-hom refl p₂ = refl

funext-hom :  {i j}{X : Set i}{Y : X  Set j}
            {f₁ f₂ f₃ : (x : X)  Y x}
            (h₁ : (x : X)  f₁ x  f₂ x)
            (h₂ : (x : X)  f₂ x  f₃ x)
            funext  x  h₁ x · h₂ x)
            funext h₁ · funext h₂
funext-hom h₁ h₂ = begin
    funext  x  h₁ x · h₂ x)
  ≡⟨ sym (ap funext (ap₂  u v x  u x · v x)
                         (_≅_.iso₁ strong-funext-iso h₁)
                         (_≅_.iso₁ strong-funext-iso h₂))) 
    funext  x  funext-inv (funext h₁) x · funext-inv (funext h₂) x)
  ≡⟨ sym (ap funext (funext-inv-hom (funext h₁) (funext h₂))) 
    funext (funext-inv (funext h₁ · funext h₂))
  ≡⟨ _≅_.iso₂ strong-funext-iso (funext h₁ · funext h₂) 
    funext h₁ · funext h₂
  
  where open ≡-Reasoning

funext-inv-ap :  {i j k}{X : Set i}{Y : X  Set j}{Z : X  Set k}
               (g : {x : X}  Y x  Z x)
               {f₁ f₂ : (x : X)  Y x}
               (p : f₁  f₂)
               funext-inv (ap (_∘'_ g) p)
               ((λ x  ap g (funext-inv p x)))
funext-inv-ap g refl = refl

funext-ap :  {i j k}{X : Set i}{Y : X  Set j}{Z : X  Set k}
           (g : {x : X}  Y x  Z x)
           {f₁ f₂ : (x : X)  Y x}
           (h : (x : X)  f₁ x  f₂ x)
           funext  x  ap g (h x))
           ap (_∘'_ g) (funext h)
funext-ap g h = begin
    funext  x  ap g (h x))
  ≡⟨ sym (ap funext (ap  h x  ap g (h x))
                    (_≅_.iso₁ strong-funext-iso h))) 
    funext  x  ap g (funext-inv (funext h) x))
  ≡⟨ ap funext (sym (funext-inv-ap g (funext h))) 
    funext (funext-inv (ap (_∘'_ g) (funext h)))
  ≡⟨ _≅_.iso₂ strong-funext-iso _ 
    ap (_∘'_ g) (funext h)
  
  where open ≡-Reasoning