Algorithmic.Signature

module Algorithmic.Signature where

Imports

open import Data.Nat using (suc)

open import Relation.Binary.PropositionalEquality using (_≡_;refl;cong;sym;trans)
open Relation.Binary.PropositionalEquality.≡-Reasoning

open import Function using (_∘_)

open import Utils using (*;♯;_∔_≣_)
open import Type using (Ctx⋆;∅;_,⋆_;_⊢⋆_;Φ)
open _⊢⋆_

open import Type.BetaNormal using (_⊢Nf⋆_;_⊢Ne⋆_;renNf;embNf)
open _⊢Nf⋆_
open _⊢Ne⋆_

import Type.RenamingSubstitution as ⋆
open import Type.BetaNBE.Completeness using (reifyCR;idext;exte-lem)
open import Type.BetaNBE.RenamingSubstitution
                         using (subNf;SubNf;renNf-subNf;subNf-cong;subNf-comp;subNf-cons;extsNf;subNf-lemma;subNf∅;subNf∅≡subNf;subNf∅-subNf;subNf∅-renNf)
                         renaming (_[_]Nf to _[_])
open import Builtin using (Builtin;signature)
open import Type.BetaNBE using (nf;reify;eval;idEnv;exte)
open import Builtin.Signature using ()
open Builtin.Signature.FromSig _⊢Nf⋆_ _⊢Ne⋆_ ne ` _·_ ^ con _⇒_   Π
     using (sig2type;SigTy;sigTy2type;convSigTy;sig2typeΠ;sig2type⇒;⊢♯2TyNe♯;mkTy) public
open SigTy
btype : Builtin → Φ ⊢Nf⋆ *
btype b = subNf∅ (sig2type (signature b))

btype-ren : ∀{Φ Ψ} b (ρ : ⋆.Ren Φ Ψ) → btype b ≡ renNf ρ (btype b)
btype-ren b ρ = sym (subNf∅-renNf ρ (sig2type (signature b)))

btype-sub : ∀{Φ Ψ} b (ρ : SubNf Φ Ψ) → btype b ≡ subNf ρ (btype b)
btype-sub b ρ = sym (subNf∅-subNf ρ (sig2type (signature b)))

Substitution in Signature types

subNf-Π : ∀{Φ Ψ J}(ρ : SubNf Φ Ψ)(B : Φ ,⋆ J ⊢Nf⋆ *) →  subNf ρ (Π B) ≡ Π (subNf (extsNf ρ) B)
subNf-Π {Φ}{Ψ}{J} ρ B = begin
    subNf ρ (Π B)
  ≡⟨ refl ⟩
    Π (reify (eval (⋆.sub (⋆.exts (embNf ∘ ρ)) (embNf B)) (exte (idEnv _))))
  ≡⟨ cong nf (cong Π (subNf-lemma ρ (embNf B)) ) ⟩
    Π (reify (eval (⋆.sub (embNf ∘ extsNf ρ) (embNf B)) (exte (idEnv _))))
  ≡⟨ cong Π (reifyCR (idext exte-lem ((⋆.sub (embNf ∘ extsNf ρ) (embNf B))))) ⟩
   Π (reify (eval (⋆.sub (embNf ∘ extsNf ρ) (embNf B)) (idEnv _)))
  ≡⟨ refl ⟩   -- nf def
    Π (nf (⋆.sub (embNf ∘ extsNf ρ) (embNf B)))
  ≡⟨ refl ⟩
    Π (subNf (extsNf ρ) B)
  ∎

subSigTy : ∀ {Φ Ψ}
   -- {n⋆ n♯}
  → (σ : SubNf Φ Ψ)
  → ∀{tn tm tt} {pt : tn ∔ tm ≣ tt}
  → ∀{am an at} {pa : an ∔ am ≣ at}
  → {A : Φ ⊢Nf⋆ *} → SigTy pt pa A
  -------------------------
  → SigTy pt pa (subNf σ A)
subSigTy σ (bresult _) = bresult _
subSigTy σ (A B⇒ bt) = (subNf σ A) B⇒ (subSigTy σ bt)
subSigTy σ (sucΠ bt) rewrite (subNf-Π σ (sigTy2type bt)) = sucΠ (subSigTy (extsNf σ) bt)

_[_]SigTy : ∀{Φ K}
          → ∀{tn tm tt} {pt : tn ∔ tm ≣ tt}
          → ∀{am an at} {pa : an ∔ am ≣ at}
          → {B : Φ ,⋆ K ⊢Nf⋆ *}
          → SigTy pt pa B
          → (A : Φ ⊢Nf⋆ K)
          → SigTy pt pa (B [ A ])
_[_]SigTy bt A  = subSigTy (subNf-cons (ne ∘ `) A) bt

uniqueSigTy :
      ∀{tn tm tt} → {pt : tn ∔ tm ≣ tt}
    → ∀{an am at} → {pa : an ∔ am ≣ at}
    → ∀{Φ} → {A : Φ ⊢Nf⋆ *}
    → (s s' : SigTy pt pa A)
    → s ≡ s'
uniqueSigTy (bresult _) (bresult _) = refl
uniqueSigTy (A B⇒ s) (.A B⇒ s') = cong (A B⇒_) (uniqueSigTy s s')
uniqueSigTy (sucΠ s) (sucΠ s') = cong sucΠ (uniqueSigTy s s')