Reputation: 385
I'm an Agda beginner! I have read both Programming language foundations in Agda and Verified functional programming in Agda, and now I want to try to formalize a small language by myself. As I am interested in Algebraic Effects and Handlers, I started with Pretnar's tutorial "An Introduction to Algebraic Effects and Handlers". Pretnar's language has 2 type judgements (Γ ⊢ values and Γ ⊢ computations) as it is usual to follow an approach close to CBPV. Also, as it is suggested in PLPA, I'm trying to use de Bruijn representation.
Some of the code I have:
mutual
data ValueType : Set where
~ℕ : ValueType
~𝔹 : ValueType
~⊤ : ValueType
_⟶_ : ValueType → CompType → ValueType
_⇒_ : CompType → CompType → ValueType
data CompType : Set where
_!_ : ValueType → Δ → CompType
data Type : Set where
⋆ : ValueType → Type
✪ : CompType → Type
data Context : Set where
∅ : Context
_,_ : Context → Type → Context
data _∋_ : Context → Type → Set where
Z : ∀ {Γ A} → Γ , A ∋ A
S_ : ∀ {Γ A B} → Γ ∋ B → Γ , A ∋ B
mutual
data _⊢ₖ_ : Context → CompType → Set where
-- computation defs go here
data _⊢ₑ_ : Context → ValueType → Set where
-- values defs go here
data _⊢_ : Context → Type → Set where
~_ : ∀ {Γ A}
→ Γ ∋ A
-----
→ Γ ⊢ A
⋆ : ∀ {Γ} {A : ValueType}
→ Γ ⊢ₑ A
------
→ Γ ⊢ ⋆ A
✪ : ∀ {Γ} {C : CompType}
→ Γ ⊢ₖ C
-------
→ Γ ⊢ ✪ C
Then I proceed to prove renaming and substitution, which is where my problem arises: how can I prove them?
mutual
renameₑ : ∀ {Γ Δ} → (∀ {A} → Γ ∋ A → Δ ∋ A)
→ (∀ {A} → Γ ⊢ₑ A → Δ ⊢ₑ A)
renameₖ : ∀ {Γ Δ} → (∀ {A} → Γ ∋ A → Δ ∋ A)
→ (∀ {A} → Γ ⊢ₖ A → Δ ⊢ₖ A)
rename : ∀ {Γ Δ} → (∀ {A} → Γ ∋ A → Δ ∋ A)
→ (∀ {A} → Γ ⊢ A → Δ ⊢ A)
rename ρ (~ x) = ~ (ρ x)
rename ρ (⋆ A) = {!!} (renameₑ ρ (⋆ A))
rename ρ (✪ A) = {!!} (renameₖ ρ (✪ A))
I can prove a rename
for each of the judgements, but I can seem to find a way to prove the "main" rename function that unifies them. I wonder if this is a correct way to proceed, and I will just need to make my proofs come along (and if so, how?)... or is there another, better way to formalise the language I'm interested in in Agda?
Upvotes: 1
Views: 117
Reputation: 12715
If you write
rename ρ (⋆ E) = {!!}
and look at the context in the hole, you'll see that E
is of type .Γ ⊢ₑ .A
. This can be readily renamed using renameₑ
:
renameₑ ρ E
which is of type .Δ ⊢ₑ .A
and it only remains to apply ⋆
to the result to get an .Δ ⊢ .A
.
The basic idea is that you pattern match on a term, figure out whether it's a value or a computation, apply the corresponding renaming function and wrap the result using the same constructor. I.e. rename
maps values to values and computations to computations, but uses different renaming functions for these judgements under the hood.
The code:
rename : ∀ {Γ Δ} → (∀ {A} → Γ ∋ A → Δ ∋ A)
→ (∀ {A} → Γ ⊢ A → Δ ⊢ A)
rename ρ (~ x) = ~ (ρ x)
rename ρ (⋆ E) = ⋆ (renameₑ ρ E)
rename ρ (✪ E) = ✪ (renameₖ ρ E)
Upvotes: 1