2016-03-30 3 views
2

Dans un previous question, j'avais types pour un langage de jouetApprendre à termes avec ascenseur et Setω et occurrences variables dans les expressions

data Type : Set where 
    Nat : Type 
    Prp : Type 

Je pensais à les interpréter à l'aide d'une union disjointe Type → Set ⊎ Set₁, mais je pensais niveau lifiting serait mieux et a aidé à obtenir

⟦_⟧ₜ : Type → Set₁ 
⟦ Nat ⟧ₜ = Lift ℕ 
⟦ Prp ⟧ₜ = Set 

supposons maintenant que ma langue de jouet a des variables et des expressions

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 

Puis la sémantique des expressions,

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₁ ⟧ₑ σ)) 

Je me genre de qu'en général lift (lower x) ≠ x en raison de « niveau rafraîchissant » en raison de lift, mais pourquoi ne peut pas la dernière ligne simplement ⟦ e ⟧ₑ σ ≡ ⟦ e₁ ⟧ₑ σ?

Je dois admettre que c'est la première fois que j'utilise Lift et je n'ai malheureusement pas trouvé de tutoriel/explication dessus --- à part l'idée qu'il incorpore des petits types en grands types, comme indiqué par sa définition.


Depuis que je suis tout aménagé, laissez-moi faire une requête assez particulière.

Avec les égalités standard/dérivés,

-- no quick `deriving Eq' mechanism, yet. 
postulate _≟ₜ_ : Decidable {A = Type} _≡_ 
postulate _≟ᵥ_ : ∀ {t s} → Variable t → Variable s → Bool 

Je définis la substitution textuelle sur les expressions,

_[_/_] : ∀ {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 ] 

maintenant est la question des occurrences variables dans les expressions.

_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 ⟧ₑ σ 

J'ai rencontré des problèmes lors de l'utilisation de l'une ou l'autre définition. En particulier, je ne pouvais même pas définir l'un par rapport à l'autre. Toute aide à ce sujet serait appréciée!


Après some digging around, j'ai essayé

levelOf : Type → Level 
levelOf Nat = zero 
levelOf Prp = suc zero 

New⟦_⟧ₜ : (t : Type) → Set (levelOf t) 
New⟦ Nat ⟧ₜ = ℕ 
New⟦ Prp ⟧ₜ = Set  

Cependant, maintenant je Setω erreurs pour la définition de State ci-dessus! C'est,

-- works fine if i use the risky {-# OPTIONS --type-in-type #-} 
NState = {t : Type} → Variable t → New⟦ {!t!} ⟧ₜ 

As far as I know, une telle erreur se produit, à peu près, quand on a une mission de niveaux aux univers.

Quelles sont les manigances que je fais inconsciemment pour avoir ce problème?

Répondre

0

Rappelons que Set₁ ∋ Lift ℕ ∋ ⟦ e ⟧ₑ σ et Set α ∋ (Set α ∋ A ∋ x) ≡ (Set α ∋ A ∋ y), où _∋_ est à partir du module Function:

infixl 0 _∋_ 
_∋_ : ∀ {a} (A : Set a) → A → A 
A ∋ x = x 

D'où l'expression ⟦ e ⟧ₑ σ ≡ ⟦ e₁ ⟧ₑ σ réside dans Set₁ (parce que les types de ⟦ e ⟧ₑ σ et ⟦ e₁ ⟧ₑ σ se trouvent dans Set₁), alors que vous en avez besoin être au Set. Vous pouvez écrire

⟦_⟧ₑ (e ≈ e₁) σ = lower (⟦ e ⟧ₑ σ) ≡ lower (⟦ e₁ ⟧ₑ σ) 

ou redéfinir _≡_ utilisant une nouvelle fonctionnalité qui permet à des niveaux « force out » qui apparaissent uniquement dans les types de paramètres et les indices d'un type de données:

data _≡′_ {a} {A : Set a} (x : A) : A → Set where 
    refl′ : x ≡′ x 

Notez le Set au lieu de Set a. Alors c'est

⟦_⟧ₑ (e ≈ e₁) σ = ⟦ e ⟧ₑ σ ≡′ ⟦ e₁ ⟧ₑ σ 

Je choisirai la première option.


Votre _not-occurs-inₙ_ ne sont pas tout à fait sans se produit, puisque e peut être Var v et E [ v/Var v ] ≡ E indépendamment du fait que v se produit dans E ou non. Pourquoi ne pas définir _not-occurs-in_ comme type de données? BTW, je pense qu'il serait plus standard de prononcer des substitutions soit E [ v ≔ e ] ou [ e/v ] E.

Vous pouvez aller de _not-occurs-in₀_ à _not-occurs-in₁_ comme ceci:

+-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))) 

Il est impossible de donner un nom à un type comme ∀ α -> Set (f α) parce que ce type ne dispose pas d'un type dans Agda comme expliqué dans le lien que vous avez mentionné. Mais vous pouvez transformer l'expression un peu pour obtenir une fonction:

F : ∀ α -> Set (suc (f α)) 
F α = Set (f α) 

En utilisant la même transformation que vous pouvez définir NState et ⟦_⟧ₑ:

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₁ ⟧ₑ σ 

Essayez de passer du NState courant à votre origine NState à voir le problème avec ce dernier: quel est le type de ∀ {t} -> NState t? Set appliqué à quoi? Le type de NState t dépend de t, mais lorsque t est quantifié universellement, cette dépendance ne peut pas être reflétée au niveau du type.

Ce serait bien d'écrire

syntax (∀ {t} -> NState t) = State 

mais Agda ne le permet pas. En théorie, il existe un univers d'univers (c'est-à-dire Setω): il s'agit d'un super universe. Bien que, Setω est un nom malheureux pour lui, parce qu'un tel univers n'est pas un Set - c'est plus grand que tout Set, parce qu'il les contient tous. Vous pouvez trouver ces idées exprimées dans Agda here.

The code.