Here we define the proper GADT Seq of sequences. It will be used several times in the examples.
module seq where open import map open import Data.List using ([] ; _∷_ ; [_]) open import Data.Vec renaming ([] to [||] ; _∷_ to _¦_ ; [_] to [|_|] ) open import Data.Unit renaming (tt to ∗) open import Data.Product using (_,_)
We introduce variables and contexts for the declaration of Seq’s data constructors.
α β γ : mix-var
α = tvar 0
β = tvar 1
γ = tvar 2
Γα : type-context {mix-var}
Γα = ⟦ [| α |] ⟧
Γβγ : type-context {mix-var}
Γβγ = ⟦ β ¦ γ ¦ [||] ⟧
We then define Seq as usual, with a constructor const producing a sequence from a piece of raw data, and a constructor pair making a sequence of pairs from sequences of the pair’s constituent types.
Seq-id : id-TC-var
Seq-id = 4
Seq-name : TC-var 1
Seq-name = TC Seq-id 1
const-id pair-id : id-data-constructor
const-id = 40
pair-id = 41
const pair : data-constructor 1
const = const-id ∷ [ varᵀ α ] ⇒ᵀ [| (varᵀ α) |]
pair = pair-id ∷ (appᵀ Seq-name [ [| varᵀ β |] ] ∷ appᵀ Seq-name [ [| varᵀ γ |] ] ∷ []) ⇒ᵀ [| ((varᵀ β) ×ᵀ (varᵀ γ)) |]
Seq : user-defined {mix-var} 1
Seq = dataᵀ Seq-name whereᵀ (const ∷ pair ∷ [])
Seq[_] = λ x → data-typeᵀ Seq [ [| x |] ]
const[_] = λ x → dc const [| x |]
pair[_,_] = λ x y → dc pair (x ¦ y ¦ [||] )
Finally, we justify the application of Seq to a type expression.
⊢const : Γα ∥ ∅ ⊢ᶜ const
⊢const = dcᵀ-intro {G = Seq-name} (var-intro ∋-last , ∗) (var-intro ∋-last , ∗)
⊢pair : Γβγ ∥ (∅ , (1 , Seq-name)) ⊢ᶜ pair
⊢pair = dcᵀ-intro {G = Seq-name} (app-intro (var-intro (∋-rec ∋-last) , ∗) ∋-last , (app-intro (var-intro ∋-last , ∗) ∋-last , ∗)) (×-intro (var-intro (∋-rec ∋-last) ) (var-intro ∋-last) , ∗)
⊢Seq : ∀ {Γ χ φ} → _ → Γ ∥ χ ⊢ Seq[ φ ]
⊢Seq ⊢φ =
data-intro {k = 1} {G = Seq-name}
{Γcs = Γα ∷ Γβγ ∷ []}
{χcs = ∅ ∷ (∅ , (1 , Seq-name)) ∷ []}
(⊢const , (⊢pair , ∗))
(⊢φ , ∗)