open import Data.Bool renaming (Bool to πΉ)
open import Data.List using (List; []; _β·_)
open import Data.Nat using (zero; suc) renaming (β to Nat)
open import Data.Product using (_Γ_; Ξ£; Ξ£-syntax; β; β-syntax; projβ; projβ)
renaming (_,_ to β¨_,_β©)
open import Data.Sum using (_β_; injβ; injβ)
open import Function using (case_of_)
open import Relation.Binary.PropositionalEquality
using (_β‘_; _β’_; refl; sym; cong; congβ)
open import Relation.Nullary using (Dec; yes; no; Β¬_)
data Type : Set where
β : Type
β
: Type
_β_ : Type β Type β Type
-- | Type equality is decidable
_ββ_ : (A B : Type) β Dec (A β‘ B)
β ββ β = yes refl
β ββ β
= no (Ξ» ())
β ββ (B β C) = no (Ξ» ())
β
ββ β = no (Ξ» ())
β
ββ β
= yes refl
β
ββ (B β C) = no (Ξ» ())
(A β B) ββ β = no (Ξ» ())
(A β B) ββ β
= no (Ξ» ())
(A β B) ββ (C β D) with A ββ C | B ββ D
... | yes refl | yes refl = yes refl
... | no Aβ’C | _ = no (Ξ» { refl β Aβ’C refl })
... | _ | no Bβ’D = no (Ξ» { refl β Bβ’D refl })
{- On paper we would just write
--------- ------------ ------------
β ~ β β
~ A A ~ β
A ~ C B ~ D
---------------------
(A β B) ~ (C β D)
This is a more elaborated version that makes it easier
to write the "coerce" function.
-}
infix 4 _~_
data _~_ : Type β Type β Set where
~-β : β ~ β
~-β
: β
~ β
β
~β : β
~ β
β~β
: β ~ β
β
~β : β{A B}
β A ~ β
β β
~ B
β β
~ (A β B)
β~β
: β{A B}
β β
~ A
β B ~ β
β (A β B) ~ β
~-β : β {A B C D}
β C ~ A
β B ~ D
β (A β B) ~ (C β D)
~-refl : β {A} β A ~ A
~-refl {A = β} = ~-β
~-refl {A = β
} = ~-β
~-refl {A = A β B} = ~-β ~-refl ~-refl
~-sym : β {A B} β A ~ B β B ~ A
~-sym ~-β = ~-β
~-sym ~-β
= ~-β
~-sym β
~β = β~β
~-sym β~β
= β
~β
~-sym (β
~β A~β
β
~B) = β~β
(~-sym A~β
) (~-sym β
~B)
~-sym (β~β
β
~A B~β
) = β
~β (~-sym β
~A) (~-sym B~β
)
~-sym (~-β C~A B~D) = ~-β (~-sym C~A) (~-sym B~D)
-- | β
is consistent with any type
β
~ : β A β β
~ A
~β
: β A β A ~ β
β
~ β = β
~β
β
~ β
= ~-β
β
~ (A β B) = β
~β (~β
A) (β
~ B)
~β
β = β~β
~β
β
= ~-β
~β
(A β B) = β~β
(β
~ A) (~β
B)
Var = Nat
Ctx = List Type
data _β_β¦_ : Ctx β Var β Type β Set where
Z : β {Ξ A}
---------------------
β (A β· Ξ) β zero β¦ A
S : β {Ξ A B x}
β Ξ β x β¦ A
------------------------
β (B β· Ξ) β suc x β¦ A
data Term : Set where
`_ : Var β Term
$_ : Nat β Term
Ζ_Λ_ : Type β Term β Term
_Β·_οΌ _ : Term β Term β Nat β Term
infix 4 _β’_β¦_
data _β’_β¦_ : Ctx β Term β Type β Set where
β’$ : β {Ξ n}
--------------- (T-Const)
β Ξ β’ $ n β¦ β
β’` : β {Ξ x A}
β Ξ β x β¦ A
--------------- (T-Var)
β Ξ β’ ` x β¦ A
β’Ζ : β {Ξ A N B}
β (A β· Ξ) β’ N β¦ B
--------------------------- (T-Abs)
β Ξ β’ Ζ A Λ N β¦ (A β B)
β’Β· : β {Ξ L M A Aβ² B β}
β Ξ β’ L β¦ A β B
β Ξ β’ M β¦ Aβ²
β Aβ² ~ A
------------------------------ (T-App)
β Ξ β’ (L Β· M οΌ β) β¦ B
β’Β·β
: β {Ξ L M A β}
β Ξ β’ L β¦ β
β Ξ β’ M β¦ A
------------------------------ (T-Appβ)
β Ξ β’ (L Β· M οΌ β) β¦ β
We can prove uniqueness of typing for GTLC.
typing-unique : β {Ξ M A B}
β Ξ β’ M β¦ A
β Ξ β’ M β¦ B
---------------
β A β‘ B
typing-unique (β’` βx) (β’` βxβ²) = β-unique βx βxβ²
where
β-unique : β {Ξ x A B} β Ξ β x β¦ A β Ξ β x β¦ B β A β‘ B
β-unique Z Z = refl
β-unique (S βx) (S βxβ²) = β-unique βx βxβ²
typing-unique β’$ β’$ = refl
typing-unique (β’Ζ β’N) (β’Ζ β’Nβ²) with typing-unique β’N β’Nβ²
... | refl = refl
typing-unique (β’Β· β’L β’M Aβ²~A) (β’Β· β’Lβ² β’Mβ² Cβ²~C)
with typing-unique β’L β’Lβ²
... | refl = refl
typing-unique (β’Β· β’L β’M Aβ²~A) (β’Β·β
β’Lβ² β’Mβ²)
with typing-unique β’L β’Lβ²
... | ()
typing-unique (β’Β·β
β’L β’M) (β’Β· β’Lβ² β’Mβ² Aβ²~A)
with typing-unique β’L β’Lβ²
... | ()
typing-unique (β’Β·β
β’L β’M) (β’Β·β
β’Lβ² β’Mβ²) = refl
Coercions are combinators that specify the conversion between two types, so β’ c : A β B.
infixr 7 _β¨_
infixr 6 _β_
data Coercion : Set where
id : Type β Coercion
-- "injection" (tagging)
_! : Type β Coercion
-- "projection" (tag checking)
_`?_ : Type β Nat β Coercion
_β_ : Coercion β Coercion β Coercion
_β¨_ : Coercion β Coercion β Coercion
-- | We restrict the source of an injection or the target
-- | of a projection to ground types
data Ground : Type β Set where
G-β : Ground β
G-β : Ground (β
β β
)
infix 4 β’_β¦_β_
data β’_β¦_β_ : Coercion β Type β Type β Set where
β’id : β {A}
--------------------- (T-Id)
β β’ id A β¦ A β A
β’! : β {G}
β Ground G
--------------------- (T-Inj)
β β’ G ! β¦ G β β
β’? : β {G β}
β Ground G
--------------------------------- (T-Proj)
β β’ G `? β β¦ β
β G
β’β : β {A B C D c d}
β β’ c β¦ C β A
β β’ d β¦ B β D
------------------------------------ (T-Fun)
β β’ c β d β¦ (A β B) β (C β D)
β’β¨ : β {A B C c d}
β β’ c β¦ A β B
β β’ d β¦ B β C
--------------------- (T-Seq)
β β’ c β¨ d β¦ A β C
data TermαΆ : Set where
`_ : Var β TermαΆ
$_ : Nat β TermαΆ
Ζ_Λ_ : Type β TermαΆ β TermαΆ
_Β·_ : TermαΆ β TermαΆ β TermαΆ
_β¨_β© : TermαΆ β Coercion β TermαΆ
blame : (β : Nat) β TermαΆ
infix 4 _β’αΆ_β¦_
data _β’αΆ_β¦_ : Ctx β TermαΆ β Type β Set where
β’$ : β {Ξ n}
--------------- (T-CC-Const)
β Ξ β’αΆ $ n β¦ β
β’` : β {Ξ x A}
β Ξ β x β¦ A
--------------- (T-CC-Var)
β Ξ β’αΆ ` x β¦ A
β’Ζ : β {Ξ A N B}
β (A β· Ξ) β’αΆ N β¦ B
--------------------------- (T-CC-Abs)
β Ξ β’αΆ Ζ A Λ N β¦ (A β B)
β’Β· : β {Ξ L M A B}
β Ξ β’αΆ L β¦ (A β B)
β Ξ β’αΆ M β¦ A
--------------------- (T-CC-App)
β Ξ β’αΆ L Β· M β¦ B
β’cast : β {Ξ M c A B}
β Ξ β’αΆ M β¦ A
β β’ c β¦ A β B
--------------------------- (T-Cast)
β Ξ β’αΆ M β¨ c β© β¦ B
β’blame : β {Ξ A β}
--------------------------- (T-Blame)
β Ξ β’αΆ blame β β¦ A
Definitions of values and evaluation contexts
data Value : TermαΆ β Set where
V-$ : β {n} β Value ($ n)
V-Ζ : β {A N} β Value (Ζ A Λ N)
V-cast! : β {V G} β Value V β Value (V β¨ G ! β©)
V-castβ : β {V c d} β Value V β Value (V β¨ c β d β©)
data Frame : Set where
β‘Β·_ : TermαΆ β Frame
_Β·β‘_ : (V : TermαΆ) β Value V β Frame
β‘β¨_β© : Coercion β Frame
plug : Frame β TermαΆ β TermαΆ
plug (β‘Β· M) L = L Β· M
plug (V Β·β‘ v) M = V Β· M
plug (β‘β¨ c β©) M = M β¨ c β©
Renaming, parallel and single substitutions
Rename : Set
Rename = Var β Var
Subst : Set
Subst = Var β TermαΆ
ext : Rename β Rename
ext Ο zero = zero
ext Ο (suc x) = suc (Ο x)
rename : Rename β TermαΆ β TermαΆ
rename Ο (` x) = ` (Ο x)
rename Ο ($ n) = $ n
rename Ο (Ζ A Λ N) = Ζ A Λ rename (ext Ο) N
rename Ο (L Β· M) = rename Ο L Β· rename Ο M
rename Ο (M β¨ c β©) = rename Ο M β¨ c β©
rename Ο (blame β) = blame β
exts : Subst β Subst
exts Ο zero = ` zero
exts Ο (suc x) = rename suc (Ο x)
subst : Subst β TermαΆ β TermαΆ
subst Ο (` x) = Ο x
subst Ο ($ n) = $ n
subst Ο (Ζ A Λ N) = Ζ A Λ subst (exts Ο) N
subst Ο (L Β· M) = subst Ο L Β· subst Ο M
subst Ο (M β¨ c β©) = subst Ο M β¨ c β©
subst Ο (blame β) = blame β
Οβ : TermαΆ β Subst
Οβ M zero = M
Οβ M (suc x) = ` x
_[_] : TermαΆ β TermαΆ β TermαΆ
N [ M ] = subst (Οβ M) N
Reduction rules
infix 4 _ββ_
data _ββ_ : TermαΆ β TermαΆ β Set where
ΞΎΞΎ : β {F M N Mβ² Nβ²}
β Mβ² β‘ plug F M
β Nβ² β‘ plug F N
β M ββ N
---------------
β Mβ² ββ Nβ²
-- blame propagation
ΞΎΞΎ-blame : β {F Mβ² β}
β Mβ² β‘ plug F (blame β)
------------------------------
β Mβ² ββ blame β
Ξ²-Ζ : β {A N V}
β Value V
---------------------------------
β (Ζ A Λ N) Β· V ββ N [ V ]
-- rules for casts
Ξ²-id : β {A V}
β Value V
---------------------------
β V β¨ id A β© ββ V
Ξ²-seq : β {V c d}
β Value V
------------------------------------------------------
β V β¨ c β¨ d β© ββ V β¨ c β© β¨ d β©
Ξ²-β : β {V W c d}
β Value V
β Value W
------------------------------------------------------------
β (V β¨ c β d β©) Β· W ββ (V Β· (W β¨ c β©)) β¨ d β©
Ξ²-proj-inj-ok : β {V G β}
β Value V
------------------------------------------------------
β V β¨ G ! β© β¨ G `? β β© ββ V
Ξ²-proj-inj-bad : β {V G H β}
β Value V
β G β’ H
------------------------------------------------------------------
β V β¨ G ! β© β¨ H `? β β© ββ blame β
pattern ΞΎ F MβN = ΞΎΞΎ {F = F} refl refl MβN
pattern ΞΎ-blame F = ΞΎΞΎ-blame {F = F} refl
Value canonical form lemmas
canonical-β
-inj : β {V}
β Value V
β [] β’αΆ V β¦ β
---------------------------------------------
β β[ G ] β[ W ] Value W Γ (V β‘ W β¨ G ! β©)
canonical-β
-inj (V-cast! {V = W} {G = G} w) (β’cast _ (β’! _)) =
β¨ G , β¨ W , β¨ w , refl β© β© β©
canonical-β : β {V A B}
β Value V
β [] β’αΆ V β¦ (A β B)
------------------------------------------------------
β β[ N ] V β‘ Ζ A Λ N β
β[ W ] β[ c ] β[ d ] Value W Γ V β‘ W β¨ c β d β©
canonical-β (V-Ζ {N = N}) (β’Ζ β’N) = injβ β¨ N , refl β©
canonical-β (V-castβ {V = W} {c = c} {d = d} w) (β’cast _ (β’β _ _)) =
injβ β¨ W , β¨ c , β¨ d , β¨ w , refl β© β© β© β©
Progress
data Progress (M : TermαΆ) : Set where
done : Value M β Progress M
step : β {N} β M ββ N β Progress M
crash : β {β} β M β‘ blame β β Progress M -- trapped errors
progress : β {M A} β [] β’αΆ M β¦ A β Progress M
progress (β’` ())
progress β’$ = done V-$
progress (β’Ζ β’M) = done V-Ζ
progress (β’Β· {L = L} {M = M} β’L β’M) =
case progress β’L of Ξ» where
(step LβLβ²) β step (ΞΎ (β‘Β· M) LβLβ²)
(crash refl) β step (ΞΎ-blame (β‘Β· M))
(done vL) β
case progress β’M of Ξ» where
(step MβMβ²) β step (ΞΎ (L Β·β‘ vL) MβMβ²)
(crash refl) β step (ΞΎ-blame (L Β·β‘ vL))
(done vM) β
case canonical-β vL β’L of Ξ» where
(injβ β¨ N , refl β©) β step (Ξ²-Ζ vM)
(injβ β¨ W , β¨ c , β¨ d , β¨ vW , refl β© β© β© β©) β step (Ξ²-β vW vM)
progress (β’cast {c = c} β’M β’c) =
case progress β’M of Ξ» where
(step MβMβ²) β step (ΞΎ (β‘β¨ c β©) MβMβ²)
(crash refl) β step (ΞΎ-blame (β‘β¨ c β©))
(done vM) β
case β’c of Ξ» where
β’id β step (Ξ²-id vM)
(β’! g) β done (V-cast! vM)
(β’β _ _) β done (V-castβ vM)
(β’β¨ _ _) β step (Ξ²-seq vM)
(β’? {G = G} {β = β} g) β
case canonical-β
-inj vM β’M of Ξ» where
β¨ H , β¨ W , β¨ vW , refl β© β© β© β
case H ββ G of Ξ» where
(yes refl) β step (Ξ²-proj-inj-ok vW)
(no Hβ’G) β step (Ξ²-proj-inj-bad {β = β} vW Hβ’G)
progress β’blame = crash refl
Preservation
_β¦_βΚ³_ : Rename β Ctx β Ctx β Set
Ο β¦ Ξ βΚ³ Ξβ² = β {x A} β Ξ β x β¦ A β Ξβ² β Ο x β¦ A
_β¦_βΛ’_ : Subst β Ctx β Ctx β Set
Ο β¦ Ξ βΛ’ Ξβ² = β {x A} β Ξ β x β¦ A β Ξβ² β’αΆ Ο x β¦ A
β’ext : β {Ξ Ξβ² A Ο}
β Ο β¦ Ξ βΚ³ Ξβ²
β ext Ο β¦ (A β· Ξ) βΚ³ (A β· Ξβ²)
β’ext β’Ο Z = Z
β’ext β’Ο (S βx) = S (β’Ο βx)
rename-preserve
: β {Ξ Ξβ² M A Ο}
β Ο β¦ Ξ βΚ³ Ξβ²
β Ξ β’αΆ M β¦ A
β Ξβ² β’αΆ rename Ο M β¦ A
rename-preserve β’Ο (β’` βx) = β’` (β’Ο βx)
rename-preserve β’Ο β’$ = β’$
rename-preserve β’Ο (β’Ζ β’N) = β’Ζ (rename-preserve (β’ext β’Ο) β’N)
rename-preserve β’Ο (β’Β· β’L β’M) = β’Β· (rename-preserve β’Ο β’L) (rename-preserve β’Ο β’M)
rename-preserve β’Ο (β’cast β’M β’c) = β’cast (rename-preserve β’Ο β’M) β’c
rename-preserve β’Ο β’blame = β’blame
β’exts : β {Ξ Ξβ² A Ο}
β Ο β¦ Ξ βΛ’ Ξβ²
β exts Ο β¦ (A β· Ξ) βΛ’ (A β· Ξβ²)
β’exts β’Ο Z = β’` Z
β’exts β’Ο (S βx) = rename-preserve S (β’Ο βx)
subst-preserve
: β {Ξ Ξβ² M A Ο}
β Ο β¦ Ξ βΛ’ Ξβ²
β Ξ β’αΆ M β¦ A
β Ξβ² β’αΆ subst Ο M β¦ A
subst-preserve β’Ο (β’` βx) = β’Ο βx
subst-preserve β’Ο β’$ = β’$
subst-preserve β’Ο (β’Ζ β’N) = β’Ζ (subst-preserve (β’exts β’Ο) β’N)
subst-preserve β’Ο (β’Β· β’L β’M) = β’Β· (subst-preserve β’Ο β’L) (subst-preserve β’Ο β’M)
subst-preserve β’Ο (β’cast β’M β’c) = β’cast (subst-preserve β’Ο β’M) β’c
subst-preserve β’Ο β’blame = β’blame
sub-preserve
: β {A B N M}
β (A β· []) β’αΆ N β¦ B
β [] β’αΆ M β¦ A
β [] β’αΆ N [ M ] β¦ B
sub-preserve β’N β’M = subst-preserve (β’Οβ β’M) β’N
where
β’Οβ : β {A M} β [] β’αΆ M β¦ A β Οβ M β¦ (A β· []) βΛ’ []
β’Οβ β’M Z = β’M
β’Οβ β’M (S ())
preserve : β {M N A}
β [] β’αΆ M β¦ A
β M ββ N
---------------------
β [] β’αΆ N β¦ A
frame-preserve : β {F M N A}
β [] β’αΆ plug F M β¦ A
β M ββ N
------------------------
β [] β’αΆ plug F N β¦ A
frame-preserve {F = β‘Β· Mβ} (β’Β· β’L β’M) LβLβ² = β’Β· (preserve β’L LβLβ²) β’M
frame-preserve {F = V Β·β‘ _} (β’Β· β’V β’M) MβMβ² = β’Β· β’V (preserve β’M MβMβ²)
frame-preserve {F = β‘β¨ c β©} (β’cast β’M β’c) MβN = β’cast (preserve β’M MβN) β’c
preserve β’M (ΞΎΞΎ refl refl MβN) = frame-preserve β’M MβN
preserve (β’Β· (β’Ζ β’N) β’V) (Ξ²-Ζ _) = sub-preserve β’N β’V
preserve (β’cast β’V β’id) (Ξ²-id _) = β’V
preserve (β’cast β’V (β’β¨ β’c β’d)) (Ξ²-seq _) = β’cast (β’cast β’V β’c) β’d
preserve (β’Β· (β’cast β’V (β’β β’c β’d)) β’W) (Ξ²-β _ _) = β’cast (β’Β· β’V (β’cast β’W β’c)) β’d
preserve (β’cast (β’cast β’V (β’! g)) (β’? _)) (Ξ²-proj-inj-ok vV) = β’V
preserve β’M (Ξ²-proj-inj-bad _ _) = β’blame
preserve β’M (ΞΎΞΎ-blame refl) = β’blame
The coercion function takes two types that are consistent and returns a coercion. We can prove that the function always well-typed coercions.
coerce : β {A B} β Nat β A ~ B β Coercion
coerce β ~-β = id β
coerce β ~-β
= id β
coerce β β
~β = β `? β
coerce β β~β
= β !
coerce β (β
~β A~β
β
~B) = ((β
β β
) `? β) β¨ (coerce β A~β
β coerce β β
~B)
coerce β (β~β
β
~A B~β
) = (coerce β β
~A β coerce β B~β
) β¨ ((β
β β
) !)
coerce β (~-β c d) = coerce β c β coerce β d
coerce-wt : β {A B} (β : Nat) (A~B : A ~ B) β β’ coerce β A~B β¦ A β B
coerce-wt β ~-β = β’id
coerce-wt β ~-β
= β’id
coerce-wt β β
~β = β’? G-β
coerce-wt β β~β
= β’! G-β
coerce-wt β (β
~β A~β
β
~B) = β’β¨ (β’? G-β) (β’β (coerce-wt β A~β
) (coerce-wt β β
~B))
coerce-wt β (β~β
β
~A B~β
) = β’β¨ (β’β (coerce-wt β β
~A) (coerce-wt β B~β
)) (β’! G-β)
coerce-wt β (~-β C~A B~D) = β’β (coerce-wt β C~A) (coerce-wt β B~D)
The semantics of GTLC is given by compilation to the cast calculus CC (for which we have already defined the reduction semantics.)
compile-β : β {Ξ x A} β Ξ β x β¦ A β Ξ β x β¦ A
compile-β Z = Z
compile-β (S βx) = S (compile-β βx)
compile : β {Ξ M A} β Ξ β’ M β¦ A β TermαΆ
compile (β’` {x = x} _) = ` x
compile (β’$ {n = n}) = $ n
compile (β’Ζ {A = A} β’N) = Ζ A Λ compile β’N
compile (β’Β· {β = β} β’L β’M Aβ²~A) = compile β’L Β· ((compile β’M) β¨ coerce β Aβ²~A β©)
compile (β’Β·β
{A = A} {β = β} β’L β’M) =
(compile β’L β¨ coerce β (β
~ (β
β β
)) β©) Β· (compile β’M β¨ coerce β (~β
A) β©)
GTLC is type safe because (1) the compilation from GTLC to CC preserves types and (2) CC is type safe.
compile-preserves : β {Ξ M A} (β’M : Ξ β’ M β¦ A) β Ξ β’αΆ compile β’M β¦ A
compile-preserves (β’` βx) = β’` (compile-β βx)
compile-preserves (β’$ {n = n}) = β’$
compile-preserves (β’Ζ {A = A} β’N) = β’Ζ (compile-preserves β’N)
compile-preserves (β’Β· {β = β} β’L β’M Aβ²~A) =
β’Β· (compile-preserves β’L)
(β’cast (compile-preserves β’M) (coerce-wt β Aβ²~A))
compile-preserves (β’Β·β
{A = A} {β = β} β’L β’M) =
β’Β· (β’cast (compile-preserves β’L) (coerce-wt β (β
~ (β
β β
))))
(β’cast (compile-preserves β’M) (coerce-wt β (~β
A)))