我正在尝试使用Agda中的isorecursive类型对按值调用lambda演算进行编码。所以我用最多n个自由值类型变量(我只需要替换isorecursive类型的值类型)相互定义值类型和计算类型,如下所示(这只是一个片段)。
data VType (n : ℕ) : Set where
vunit : VType n -- unit type
var : Fin n → VType n -- type variable
u : CType n → VType n -- thunk
μ : VType (1 + n) → VType n -- isorecursive type
data CType (n : ℕ) : Set where
_⇒_ : VType n → CType n → CType n -- lambda abstraction
f : VType n → CType n -- a value-producer
在样式here中,我希望能够进行像
这样的替换example : CType 0
example = f (var (# 0)) C[/ vunit ]
,其中
_C[/_] : ∀ {n} → CType (1 + n) → VType n → CType n
ct [/ vt ] = ?
将替代vt
替换为ct
。注意我想将值类型替换为计算类型。我能够使用标准库将VType
替换为VType
s,而不是VType
s替换为CType
s,如上所述。我是这样做的,使用Data.Fin.Substitution
(请参阅here):
module TypeSubst where
-- Following Data.Substitutions.Example
module TypeApp {T} (l : Lift T VType) where
open Lift l hiding (var)
-- Applies a substitution to a type
infixl 8 _/v_
_/v_ : ∀ {m n} → VType m → Sub T m n → VType n
_/c_ : ∀ {m n} → CType m → Sub T m n → CType n
vunit /v ρ = vunit
(var x) /v ρ = lift (lookup x ρ)
(u σ) /v ρ = u (σ /c ρ)
(μ τ) /v ρ = μ (τ /v ρ ↑)
(σ ⇒ τ) /c ρ = σ /v ρ ⇒ τ /c ρ
f x /c ρ = f (x /v ρ)
open Application (record { _/_ = _/v_ }) using (_/✶_)
typeSubst : TermSubst VType
typeSubst = record { var = var; app = TypeApp._/v_ }
open TermSubst typeSubst public hiding (var)
weaken↑ : ∀ {n} → VType (1 + n) → VType (2 + n)
weaken↑ τ = τ / wk ↑
infix 8 _[/_]
-- single type substitution
_[/_] : ∀ {n} → VType (1 + n) → VType n → VType n
τ [/ σ ] = τ / sub σ
我尝试使用新的数据类型Type
:
data VorC : Set where
v : VorC
c : VorC
data Type : VorC → ℕ → Set where
vtype : ∀ {n} → VType n → Type v n
ctype : ∀ {n} → CType n → Type c n
我尝试使用自然展开功能从Type
转到VType
或CType
,但这似乎不起作用或导致终止检查问题如果我尝试模仿标准库的模块。
有谁知道是否可以使用标准库中的Data.Fin.Substitution
来完成这样的事情?有人可以向我解释这个模块吗?没有关于此的文档...如果无法使用标准库,那么也欢迎任何有关如何解决此问题的指示。谢谢!
答案 0 :(得分:4)
您可以在Application
案例中打开CType
,而不是打开看似不合适的TermSubst
(我不知道它有什么问题)。以下是相关部分:
typeSubst : TermSubst VType
typeSubst = record { var = var; app = TypeApp._/v_ }
open TermSubst typeSubst public hiding (var)
module TypeSubst where
_[/v_] : ∀ {n} → VType (1 + n) → VType n → VType n
τ [/v σ ] = τ / sub σ
open Application (record { _/_ = TypeApp._/c_ termLift }) renaming (_/_ to _/c_) using ()
_[/c_] : ∀ {n} → CType (1 + n) → VType n → CType n
τ [/c σ ] = τ /c sub σ
整个code。
要了解标准库中的内容,您需要阅读Type-Preserving Renaming and Substitution论文。但是,stdlib中的代码更加抽象。
顺便说一下,您可以使用order preserving embeddings来定义重命名和重命名以定义替换。填补空洞here。