Chuangjie Xu, April 2017

We simplify T terms by removing (some) noncomputational information,
i.e. the parts of type (equivalent to) ①.  For example, a term

    t : 𝟙 → ℕ × 𝟙

will be simplified to

    pr₁ (t ⋆) : ℕ

\begin{code}

module Simp where

open import Preliminaries
open import DataTypes
open import H

\end{code}

Type equality is decidable.

\begin{code}

Ty-dec : (σ τ : Ty)  σ  τ + σ  τ
Ty-dec   = inl refl
Ty-dec   = inr  ())
Ty-dec   = inr  ())
Ty-dec  (τ *) = inr  ())
Ty-dec  (τ  τ₁) = inr  ())
Ty-dec  (τ  τ₁) = inr  ())
Ty-dec   = inr  ())
Ty-dec   = inl refl
Ty-dec   = inr  ())
Ty-dec  (τ *) = inr  ())
Ty-dec  (τ  τ₁) = inr  ())
Ty-dec  (τ  τ₁) = inr  ())
Ty-dec   = inr  ())
Ty-dec   = inr  ())
Ty-dec   = inl refl
Ty-dec  (τ *) = inr  ())
Ty-dec  (τ  τ₁) = inr  ())
Ty-dec  (τ  τ₁) = inr  ())
Ty-dec (σ *)  = inr  ())
Ty-dec (σ *)  = inr  ())
Ty-dec (σ *)  = inr  ())
Ty-dec (σ *) (τ *) = case  e  inl (*⁼ e))  f  inr  e  f (lm e))) (Ty-dec σ τ)
 where
  lm : {A B : Ty}  A *  B *  A  B
  lm refl = refl
Ty-dec (σ *) (τ  τ₁) = inr  ())
Ty-dec (σ *) (τ  τ₁) = inr  ())
Ty-dec (σ  σ₁)  = inr  ())
Ty-dec (σ  σ₁)  = inr  ())
Ty-dec (σ  σ₁)  = inr  ())
Ty-dec (σ  σ₁) (τ *) = inr  ())
Ty-dec (σ  σ₁) (τ  τ₁) = case  e  case  e₁  inl (⊠⁼ e e₁))  f  inr  e₁  f (lm₁ e₁))) (Ty-dec σ₁ τ₁))
                                 f  inr  e  f (lm₀ e)))
                                (Ty-dec σ τ)
 where
  lm₀ : {A A' B B' : Ty}  (A  A')  (B  B')  A  B
  lm₀ refl = refl
  lm₁ : {A A' B B' : Ty}  (A  A')  (B  B')  A'  B'
  lm₁ refl = refl  
Ty-dec (σ  σ₁) (τ  τ₁) = inr  ())
Ty-dec (σ  σ₁)  = inr  ())
Ty-dec (σ  σ₁)  = inr  ())
Ty-dec (σ  σ₁)  = inr  ())
Ty-dec (σ  σ₁) (τ *) = inr  ())
Ty-dec (σ  σ₁) (τ  τ₁) = inr  ())
Ty-dec (σ  σ₁) (τ  τ₁) = case  e  case  e₁  inl (⇾⁼ e e₁))  f  inr  e₁  f (lm₁ e₁))) (Ty-dec σ₁ τ₁))
                                 f  inr  e  f (lm₀ e)))
                                (Ty-dec σ τ)
 where
  lm₀ : {A A' B B' : Ty}  (A  A')  (B  B')  A  B
  lm₀ refl = refl
  lm₁ : {A A' B B' : Ty}  (A  A')  (B  B')  A'  B'
  lm₁ refl = refl

\end{code}

A special case function for defining the simpᴹ/backᴹ function.

\begin{code}

careⁱʳ : {A C : Set}  C  C  A + ¬ A  C
careⁱʳ c₀ c₁ (inl _) = c₀
careⁱʳ c₀ c₁ (inr _) = c₁

Lemma[careⁱʳ]₀ : {A C : Set} {c₀ c₁ : C}
            A    (w : A + ¬ A)  careⁱʳ c₀ c₁ w  c₀
Lemma[careⁱʳ]₀ a (inl _) = refl
Lemma[careⁱʳ]₀ a (inr f) = 𝟘-elim (f a)

Lemma[careⁱʳ]₁ : {A C : Set} {c₀ c₁ : C}
            ¬ A  (w : A + ¬ A)  careⁱʳ c₀ c₁ w  c₁
Lemma[careⁱʳ]₁ f (inl a) = 𝟘-elim (f a)
Lemma[careⁱʳ]₁ f (inr _) = refl

\end{code}

Simplcareⁱʳy types

\begin{code}

simpᵀ : Ty  Ty
simpᵀ  = 
simpᵀ  = 
simpᵀ  = 
simpᵀ (σ *) = careⁱʳ  (σᵀ *) (Ty-dec σᵀ )
 where
  σᵀ : Ty
  σᵀ = simpᵀ σ
simpᵀ (σ  τ) = careⁱʳ τᵀ (careⁱʳ σᵀ (σᵀ  τᵀ) (Ty-dec τᵀ )) (Ty-dec σᵀ )
 where
  σᵀ τᵀ : Ty
  σᵀ = simpᵀ σ
  τᵀ = simpᵀ τ
simpᵀ (σ  τ) = careⁱʳ τᵀ (careⁱʳ  (σᵀ  τᵀ) (Ty-dec τᵀ )) (Ty-dec σᵀ )
 where
  σᵀ τᵀ : Ty
  σᵀ = simpᵀ σ
  τᵀ = simpᵀ τ

\end{code}

Simplcareⁱʳy terms

\begin{code}

simpᴹ : (σ : Ty)   σ ⟧ʸ   simpᵀ σ ⟧ʸ
backᴹ : (σ : Ty)   simpᵀ σ ⟧ʸ   σ ⟧ʸ
simpᴹ  t = 
simpᴹ  t = t
simpᴹ  t = t
simpᴹ (σ *) t = case c₀ c₁ (Ty-dec σᵀ )
 where
  σᵀ : Ty
  σᵀ = simpᵀ σ
  c₀ : σᵀ     simpᵀ (σ *) ⟧ʸ
  c₀ e = transport ⟦_⟧ʸ (sym claim) 
   where
    claim : simpᵀ (σ *)  
    claim = Lemma[careⁱʳ]₀ e (Ty-dec σᵀ )
  c₁ : σᵀ     simpᵀ (σ *) ⟧ʸ
  c₁ f = transport ⟦_⟧ʸ (sym claim) tᴹ
   where
    claim : simpᵀ (σ *)  σᵀ *
    claim = Lemma[careⁱʳ]₁ f (Ty-dec σᵀ )
    tᴹ :  σᵀ * ⟧ʸ
    tᴹ = recᴸ ε  x ys  ys  simpᴹ σ x) t
simpᴹ (σ  τ) (t₀ , t₁) = case c₀ c₁ (Ty-dec σᵀ )
 where
  σᵀ τᵀ : Ty
  σᵀ = simpᵀ σ
  τᵀ = simpᵀ τ
  c₀ : σᵀ     simpᵀ (σ  τ) ⟧ʸ
  c₀ e = transport ⟦_⟧ʸ (sym claim) tᴹ
   where
    claim : simpᵀ (σ  τ)  τᵀ
    claim = Lemma[careⁱʳ]₀ e (Ty-dec σᵀ )
    tᴹ :  τᵀ ⟧ʸ
    tᴹ = simpᴹ τ t₁
  c₁ : σᵀ     simpᵀ (σ  τ) ⟧ʸ
  c₁ f = case d₀ d₁ (Ty-dec τᵀ )
   where
    claim₀ : simpᵀ (σ  τ)  careⁱʳ σᵀ (σᵀ  τᵀ) (Ty-dec τᵀ )
    claim₀ = Lemma[careⁱʳ]₁ f (Ty-dec σᵀ )
    d₀ : τᵀ     simpᵀ (σ  τ) ⟧ʸ
    d₀ e' = transport ⟦_⟧ʸ (sym claim₂) tᴹ
     where
      claim₁ : careⁱʳ σᵀ (σᵀ  τᵀ) (Ty-dec τᵀ )  σᵀ
      claim₁ = Lemma[careⁱʳ]₀ e' (Ty-dec τᵀ )
      claim₂ : simpᵀ (σ  τ)  σᵀ
      claim₂ = trans claim₀ claim₁
      tᴹ :  σᵀ ⟧ʸ
      tᴹ = simpᴹ σ t₀
    d₁ : τᵀ     simpᵀ (σ  τ) ⟧ʸ
    d₁ f' = transport ⟦_⟧ʸ (sym claim₂) tᴹ
     where
      claim₁ : careⁱʳ σᵀ (σᵀ  τᵀ) (Ty-dec τᵀ )  σᵀ  τᵀ
      claim₁ = Lemma[careⁱʳ]₁ f' (Ty-dec τᵀ )
      claim₂ : simpᵀ (σ  τ)  σᵀ  τᵀ
      claim₂ = trans claim₀ claim₁
      tᴹ :  σᵀ  τᵀ ⟧ʸ
      tᴹ = simpᴹ σ t₀ , simpᴹ τ t₁
simpᴹ (σ  τ) t = case c₀ c₁ (Ty-dec σᵀ )
 where
  σᵀ τᵀ : Ty
  σᵀ = simpᵀ σ
  τᵀ = simpᵀ τ
  c₀ : σᵀ     simpᵀ (σ  τ) ⟧ʸ
  c₀ e = transport ⟦_⟧ʸ (sym claim) tᴹ
   where
    claim : simpᵀ (σ  τ)  τᵀ
    claim = Lemma[careⁱʳ]₀ e (Ty-dec σᵀ )
    tᴹ :  τᵀ ⟧ʸ
    tᴹ = simpᴹ τ (t (⟦𝒄⟧ σ))
  c₁ : σᵀ     simpᵀ (σ  τ) ⟧ʸ
  c₁ f = case d₀ d₁ (Ty-dec τᵀ )
   where
    claim₀ : simpᵀ (σ  τ)  careⁱʳ  (σᵀ  τᵀ) (Ty-dec τᵀ )
    claim₀ = Lemma[careⁱʳ]₁ f (Ty-dec σᵀ )
    d₀ : τᵀ     simpᵀ (σ  τ) ⟧ʸ
    d₀ e' = transport ⟦_⟧ʸ (sym claim₂) 
     where
      claim₁ : careⁱʳ  (σᵀ  τᵀ) (Ty-dec τᵀ )  
      claim₁ = Lemma[careⁱʳ]₀ e' (Ty-dec τᵀ )
      claim₂ : simpᵀ (σ  τ)  
      claim₂ = trans claim₀ claim₁
    d₁ : τᵀ     simpᵀ (σ  τ) ⟧ʸ
    d₁ f' = transport ⟦_⟧ʸ (sym claim₂) tᴹ
     where
      claim₁ : careⁱʳ  (σᵀ  τᵀ) (Ty-dec τᵀ )  σᵀ  τᵀ
      claim₁ = Lemma[careⁱʳ]₁ f' (Ty-dec τᵀ )
      claim₂ : simpᵀ (σ  τ)  σᵀ  τᵀ
      claim₂ = trans claim₀ claim₁
      tᴹ :  σᵀ  τᵀ ⟧ʸ
      tᴹ x = simpᴹ τ (t (backᴹ σ x))

backᴹ  t = 
backᴹ  t = t
backᴹ  t = t
backᴹ (σ *) t = case c₀ c₁ (Ty-dec σᵀ )
 where
  σᵀ : Ty
  σᵀ = simpᵀ σ
  c₀ : σᵀ     σ * ⟧ʸ
  c₀ e = ε
  c₁ : σᵀ     σ * ⟧ʸ
  c₁ f = recᴸ ε  x ys  ys  backᴹ σ x) u
   where
    claim : simpᵀ (σ *)  σᵀ *
    claim = Lemma[careⁱʳ]₁ f (Ty-dec σᵀ )
    u :  σᵀ * ⟧ʸ
    u = transport ⟦_⟧ʸ claim t
backᴹ (σ  τ) t = case c₀ c₁ (Ty-dec σᵀ )
 where
  σᵀ τᵀ : Ty
  σᵀ = simpᵀ σ
  τᵀ = simpᵀ τ
  c₀ : σᵀ     σ  τ ⟧ʸ
  c₀ e = ⟦𝒄⟧ σ , backᴹ τ u
   where
    claim : simpᵀ (σ  τ)  τᵀ
    claim = Lemma[careⁱʳ]₀ e (Ty-dec σᵀ )
    u :  τᵀ ⟧ʸ
    u = transport ⟦_⟧ʸ claim t
  c₁ : σᵀ     σ  τ ⟧ʸ
  c₁ f = case d₀ d₁ (Ty-dec τᵀ )
   where
    claim₀ : simpᵀ (σ  τ)  careⁱʳ σᵀ (σᵀ  τᵀ) (Ty-dec τᵀ )
    claim₀ = Lemma[careⁱʳ]₁ f (Ty-dec σᵀ )
    d₀ : τᵀ     σ  τ ⟧ʸ
    d₀ e' = backᴹ σ u , ⟦𝒄⟧ τ
     where
      claim₁ : careⁱʳ σᵀ (σᵀ  τᵀ) (Ty-dec τᵀ )  σᵀ
      claim₁ = Lemma[careⁱʳ]₀ e' (Ty-dec τᵀ )
      claim₂ : simpᵀ (σ  τ)  σᵀ
      claim₂ = trans claim₀ claim₁
      u :  σᵀ ⟧ʸ
      u = transport ⟦_⟧ʸ claim₂ t
    d₁ : τᵀ     σ  τ ⟧ʸ
    d₁ f' = backᴹ σ (pr₁ u) , backᴹ τ (pr₂ u)
     where
      claim₁ : careⁱʳ σᵀ (σᵀ  τᵀ) (Ty-dec τᵀ )  σᵀ  τᵀ
      claim₁ = Lemma[careⁱʳ]₁ f' (Ty-dec τᵀ )
      claim₂ : simpᵀ (σ  τ)  σᵀ  τᵀ
      claim₂ = trans claim₀ claim₁
      u :  σᵀ  τᵀ ⟧ʸ
      u = transport ⟦_⟧ʸ claim₂ t
backᴹ (σ  τ) t = case c₀ c₁ (Ty-dec σᵀ )
 where
  σᵀ τᵀ : Ty
  σᵀ = simpᵀ σ
  τᵀ = simpᵀ τ
  c₀ : σᵀ     σ  τ ⟧ʸ
  c₀ e = λ _  backᴹ τ u
   where
    claim : simpᵀ (σ  τ)  τᵀ
    claim = Lemma[careⁱʳ]₀ e (Ty-dec σᵀ )
    u :  τᵀ ⟧ʸ
    u = transport ⟦_⟧ʸ claim t
  c₁ : σᵀ     σ  τ ⟧ʸ
  c₁ f = case d₀ d₁ (Ty-dec τᵀ )
   where
    claim₀ : simpᵀ (σ  τ)  careⁱʳ  (σᵀ  τᵀ) (Ty-dec τᵀ )
    claim₀ = Lemma[careⁱʳ]₁ f (Ty-dec σᵀ )
    d₀ : τᵀ     σ  τ ⟧ʸ
    d₀ _ = ⟦𝒄⟧ (σ  τ)
    d₁ : τᵀ     σ  τ ⟧ʸ
    d₁ f' = λ x  backᴹ τ (u (simpᴹ σ x))
     where
      claim₁ : careⁱʳ  (σᵀ  τᵀ) (Ty-dec τᵀ )  σᵀ  τᵀ
      claim₁ = Lemma[careⁱʳ]₁ f' (Ty-dec τᵀ )
      claim₂ : simpᵀ (σ  τ)  σᵀ  τᵀ
      claim₂ = trans claim₀ claim₁
      u :  σᵀ  τᵀ ⟧ʸ
      u = transport ⟦_⟧ʸ claim₂ t

\end{code}