Знакомство с Lift и Setω, а также с появлением переменных в выражениях
В предыдущем вопросе у меня были типы для игрушечного языка
data Type : Set where
Nat : Type
Prp : Type
Я думал о том, чтобы интерпретировать их, используя несвязанный союзType → Set ⊎ Set₁
, но подъем уровня мышления был бы лучшим и помог получить
⟦_⟧ₜ : Type → Set₁
⟦ Nat ⟧ₜ = Lift ℕ
⟦ Prp ⟧ₜ = Set
Теперь предположим, что мой игрушечный язык имеет переменные и выражения
data Variable : Type → Set where
x y : ∀ {t} → Variable t
data Expr : Type → Set₁ where
Var : ∀ {t} (v : Variable t) → Expr t -- varaible symbols
: ℕ → Expr Nat -- constant symbols
: Set → Expr Prp
_+_ : (m n : Expr Nat) → Expr Nat -- binary function symbol
_≈_ : (e f : Expr Nat) → Expr Prp -- binary relation symbol
Тогда семантика выражений,
State = ∀ {t} → Variable t → ⟦ t ⟧ₜ
⟦_⟧ₑ : ∀ {t} → Expr t → State → ⟦ t ⟧ₜ
⟦_⟧ₑ (Var v) σ = σ v
⟦_⟧ₑ ( q) σ = lift q
⟦_⟧ₑ ( p) σ = p
⟦_⟧ₑ (e + e₁) σ = lift $ lower (⟦ e ⟧ₑ σ) +ℕ lower (⟦ e₁ ⟧ₑ σ)
⟦_⟧ₑ (e ≈ e₁) σ = lift (lower (⟦ e ⟧ₑ σ)) ≡ lift (lower (⟦ e₁ ⟧ₑ σ))
Я вроде понимаю, что в целом lift (lower x) ≠ x
из-за "обновления уровня" из-за lift
, но все же почему последняя строка просто не может быть ⟦ e ⟧ₑ σ ≡ ⟦ e₁ ⟧ₑ σ
?
Я должен признать, что это мой первый раз, используя Lift
и, к сожалению, не нашел учебника / объяснения по этому поводу - кроме идеи, что он встраивает мелкие типы в большие типы, как указано в его определении.
Поскольку я все изложил, позвольте мне сделать довольно конкретный запрос.
Со стандартными / производными равенствами,
-- no quick `deriving Eq' mechanism, yet.
postulate _≟ₜ_ : Decidable {A = Type} _≡_
postulate _≟ᵥ_ : ∀ {t s} → Variable t → Variable s → Bool
Я могу определить текстовую подстановку над выражениями,
_[_/_] : ∀ {s t} → Expr t → Variable s → Expr s → Expr t
_[_/_] {s} {t} (Var v) u e with s ≟ₜ t
Var v [ u / e ] | yes refl = if v ≟ᵥ u then e else Var v
Var v [ u / e ] | no ¬p = Var v
n [ v / e ] = n
p [ v / e ] = p
(E + F) [ v / e ] = E [ v / e ] + F [ v / e ]
(E ≈ F) [ v / e ] = E [ v / e ] ≈ F [ v / e ]
Теперь проблема вхождений переменных в выражениях.
_not-occurs-in₀_ : ∀ {t} → Variable t → Expr t → Set₁
v not-occurs-in₀ E = ∀ {e} → E [ v / e ] ≡ E
_not-occurs-in₁_ : ∀ {t} → Variable t → Expr t → Set₁
v not-occurs-in₁ E = ∀ {e} {σ : State} → ⟦ E [ v / e ] ⟧ₑ σ ≡ ⟦ E ⟧ₑ σ
У меня были проблемы с использованием любого определения. В частности, я не мог даже определить одно в терминах другого. Любая помощь в этом будет оценена!
После некоторого копания я попытался
levelOf : Type → Level
levelOf Nat = zero
levelOf Prp = suc zero
New⟦_⟧ₜ : (t : Type) → Set (levelOf t)
New⟦ Nat ⟧ₜ = ℕ
New⟦ Prp ⟧ₜ = Set
Тем не менее, теперь я получаю Setω
ошибки в определении State
выше! То есть,
-- works fine if i use the risky {-# OPTIONS --type-in-type #-}
NState = {t : Type} → Variable t → New⟦ {!t!} ⟧ₜ
Насколько я знаю, такая ошибка возникает, примерно, при назначении уровней вселенным.
Какие махинации я неосознанно делаю, чтобы получить эту проблему?
1 ответ
Напомним, что Set₁ ∋ Lift ℕ ∋ ⟦ e ⟧ₑ σ
а также Set α ∋ (Set α ∋ A ∋ x) ≡ (Set α ∋ A ∋ y)
, где _∋_
от Function
модуль:
infixl 0 _∋_
_∋_ : ∀ {a} (A : Set a) → A → A
A ∋ x = x
Отсюда и выражение ⟦ e ⟧ₑ σ ≡ ⟦ e₁ ⟧ₑ σ
заключается в Set₁
(потому что типы ⟦ e ⟧ₑ σ
а также ⟦ e₁ ⟧ₑ σ
роды Set₁
), пока вам нужно, чтобы он был в Set
, Вы можете написать
⟦_⟧ₑ (e ≈ e₁) σ = lower (⟦ e ⟧ₑ σ) ≡ lower (⟦ e₁ ⟧ₑ σ)
или переопределить _≡_
использование новой функции, которая позволяет "вытеснять" уровни, которые появляются только в типах параметров и индексов типа данных:
data _≡′_ {a} {A : Set a} (x : A) : A → Set where
refl′ : x ≡′ x
Обратите внимание Set
вместо Set a
, Тогда это
⟦_⟧ₑ (e ≈ e₁) σ = ⟦ e ⟧ₑ σ ≡′ ⟦ e₁ ⟧ₑ σ
Я выберу первый вариант.
Ваш _not-occurs-inₙ_
не совсем не происходит, так как e
может быть Var v
а также E [ v / Var v ] ≡ E
несмотря на погоду v
происходит в E
или нет. Почему бы не определить _not-occurs-in_
как тип данных? Кстати, я думаю, что было бы более стандартным произносить замены либо как E [ v ≔ e ]
или же [ e / v ] E
,
Вы можете перейти от _not-occurs-in₀_
в _not-occurs-in₁_
как это:
+-inj : ∀ {E₁ E₂ E₃ E₄} -> E₁ + E₂ ≡ E₃ + E₄ -> E₁ ≡ E₃ × E₂ ≡ E₄
+-inj refl = refl , refl
≈-inj : ∀ {E₁ E₂ E₃ E₄} -> E₁ ≈ E₂ ≡ E₃ ≈ E₄ -> E₁ ≡ E₃ × E₂ ≡ E₄
≈-inj refl = refl , refl
coe : ∀ {t s} {v : Variable t} → (E : Expr s) → v not-occurs-in₀ E → v not-occurs-in₁ E
coe {t} {v} (Var w) q {e} rewrite q {e} = refl
coe ( n) q = refl
coe ( p) q = refl
coe (E + E₁) q =
cong₂ (λ n m → lift $ lower n +ℕ lower m) (coe E (proj₁ (+-inj q))) (coe E₁ (proj₂ (+-inj q)))
coe (E ≈ E₁) q =
cong₂ (λ p₁ p₂ → lower p₁ ≡ lower p₂) (coe E (proj₁ (≈-inj q))) (coe E₁ (proj₂ (≈-inj q)))
Невозможно дать имя типу ∀ α -> Set (f α)
потому что этот тип не имеет типа в Agda, как объяснено в ссылке, которую вы упомянули. Но вы можете немного преобразовать выражение, чтобы получить функцию:
F : ∀ α -> Set (suc (f α))
F α = Set (f α)
Используя то же преобразование, вы можете определить NState
а также ⟦_⟧ₑ
:
NState : ∀ t → Set (levelOf t)
NState t = Variable t → New⟦ t ⟧ₜ
⟦_⟧ₑ : ∀ {t} → Expr t → (∀ {t} -> NState t) → New⟦ t ⟧ₜ
⟦_⟧ₑ (Var v) σ = σ v
⟦_⟧ₑ ( q) σ = q
⟦_⟧ₑ ( p) σ = p
⟦_⟧ₑ (e + e₁) σ = ⟦ e ⟧ₑ σ +ℕ ⟦ e₁ ⟧ₑ σ
⟦_⟧ₑ (e ≈ e₁) σ = ⟦ e ⟧ₑ σ ≡ ⟦ e₁ ⟧ₑ σ
Попробуй уйти от текущего NState
к вашему оригиналу NState
чтобы увидеть проблему с последним: какой тип ∀ {t} -> NState t
? Set
применяется к чему? Тип NState t
зависит от t
, но когда t
повсеместно количественно эта зависимость не может быть отражена на уровне типа.
Было бы неплохо написать
syntax (∀ {t} -> NState t) = State
но Агда не позволяет этого.
Кстати, в теории вселенная вселенных (т.е. Setω
) существует: это супер вселенная. Хоть, Setω
это неудачное название, потому что такая вселенная не Set
- это больше, чем любой Set
потому что он содержит их всех. Вы можете найти эти идеи, выраженные в Агде здесь.
Код.