This file implements the GADT G presented in Example 2.2 in the paper.
module G where open import map open import nat using (Nat[] ; ⊢Nat) open import list using (List[_] ; ⊢List ; nil[] ; cons[_,_]) open import Data.Unit renaming (tt to ∗) open import Data.List using ([] ; _∷_ ; [_]) open import Data.Vec renaming ([] to [||] ; _∷_ to _¦_ ; [_] to [|_|] ) open import Data.Product using (_,_)
If we want to use different variables for each data constructors of G, we need six type variables and the corresponding contexts.
α β γ δ γ' δ' : mix-var α = tvar 0 β = tvar 1 γ = tvar 2 δ = tvar 3 γ' = tvar 4 δ' = tvar 5 Γα Γβ Γγδ Γγ'δ' : type-context {mix-var} Γα = ⟦ [| α |] ⟧ Γβ = ⟦ [| β |] ⟧ Γγδ = ⟦ γ ¦ δ ¦ [||] ⟧ Γγ'δ' = ⟦ γ' ¦ δ' ¦ [||] ⟧
Now we define G following the definition given in Example 2.2.
G-id : id-TC-var G-id = 5 G-name : TC-var 1 G-name = TC G-id 1 const-id flat-id inj-id pairing-id projpair-id : id-data-constructor const-id = 50 flat-id = 51 inj-id = 52 pairing-id = 53 projpair-id = 54 const flat inj pairing projpair : data-constructor 1 const = const-id ∷ [] ⇒ᵀ [| Nat[] |] flat = flat-id ∷ [ List[ appᵀ G-name [ [| varᵀ α |] ] ] ] ⇒ᵀ [| List[ varᵀ α ] |] inj = inj-id ∷ [ varᵀ β ] ⇒ᵀ [| varᵀ β |] pairing = pairing-id ∷ (appᵀ G-name [ [| varᵀ γ |] ] ∷ appᵀ G-name [ [| varᵀ δ |] ] ∷ []) ⇒ᵀ [| varᵀ γ ×ᵀ varᵀ δ |] projpair = projpair-id ∷ [ appᵀ G-name [ [| (appᵀ G-name [ [| varᵀ γ' |] ]) ×ᵀ (appᵀ G-name [ [| varᵀ δ' ×ᵀ varᵀ δ' |] ]) |] ] ] ⇒ᵀ [| varᵀ γ' ×ᵀ varᵀ δ' |] G : user-defined {mix-var} 1 G = dataᵀ G-name whereᵀ (const ∷ flat ∷ inj ∷ pairing ∷ projpair ∷ []) G[_] = λ x → data-typeᵀ G [ [| x |] ] const[] = dc const [||] flat[_] = λ x → dc flat [| x |] inj[_] = λ x → dc inj [| x |] pairing[_,_] = λ x y → dc pairing (x ¦ y ¦ [||]) projpair[_] = λ x → dc projpair [| x |]
Finally, we justify the application of G to a type expression, by first justifying each of its constructors.
⊢const : ∅ ∥ ∅ ⊢ᶜ const ⊢const = dcᵀ-intro {G = G-name} ∗ (⊢Nat , ∗) ⊢flat : Γα ∥ ∅ ⊢ᶜ flat ⊢flat = dcᵀ-intro {G = G-name} (⊢List (app-intro (var-intro ∋-last , ∗) ∋-last) , ∗) (⊢List (var-intro ∋-last) , ∗) ⊢inj : Γβ ∥ ∅ ⊢ᶜ inj ⊢inj = dcᵀ-intro {G = G-name} (var-intro ∋-last , ∗) (var-intro ∋-last , ∗) ⊢pairing : Γγδ ∥ ∅ ⊢ᶜ pairing ⊢pairing = dcᵀ-intro {G = G-name} ( app-intro (var-intro (∋-rec ∋-last) , ∗) ∋-last , app-intro (var-intro ∋-last , ∗) ∋-last , ∗ ) ( ×-intro (var-intro (∋-rec ∋-last)) (var-intro ∋-last) , ∗ ) ⊢projpair : Γγ'δ' ∥ ∅ ⊢ᶜ projpair ⊢projpair = dcᵀ-intro {G = G-name} ( app-intro ( ×-intro (app-intro (var-intro (∋-rec ∋-last) , ∗) ∋-last) (app-intro (×-intro (var-intro ∋-last) (var-intro ∋-last) , ∗) ∋-last) , ∗ ) ∋-last , ∗ ) ( ×-intro (var-intro (∋-rec ∋-last)) (var-intro ∋-last) , ∗ ) ⊢G : ∀ {Γ χ φ} → _ → Γ ∥ χ ⊢ G[ φ ] ⊢G ⊢φ = data-intro {k = 1} {G = G-name} {Γcs = ∅ ∷ Γα ∷ Γβ ∷ Γγδ ∷ Γγ'δ' ∷ []} {χcs = ∅ ∷ ∅ ∷ ∅ ∷ ∅ ∷ ∅ ∷ []} (⊢const , ⊢flat , ⊢inj , ⊢pairing , ⊢projpair , ∗) (⊢φ , ∗)