1

In System F, the kind of a polymorphic type is * (as that's the only kind in System F anyway...), so e.g. for the following closed type:

[] ⊢ (forall α : *. α → α) : *

I would like to represent System F in Agda, and because everything is in *, I thought I'd interpret types (like the above) as Agda Sets; so something like

evalTy : RepresentationOfAWellKindedClosedType → Set

However, Agda doesn't have polymorphic types, so the above type, in Agda, would need to be a (large!) Π type:

idType = (α : Set) → α → α

which means it is not in Set₀:

idType : Set
idType = (α : Set) → α → α

poly-level.agda:4,12-29
Set₁ != Set
when checking that the expression (α : Set) → α → α has type Set

Is there a way out of this, or is System F not embeddable in this sense into Agda?

Cactus
  • 27,075
  • 9
  • 69
  • 149
  • 2
    As I understand it: System F being impredicative and Agda not, it is impossible to define an interpretation where [[*]] = Set. This was taught to us by Reynolds: http://link.springer.com/chapter/10.1007/3-540-13346-1_7. Note: that paper is not the easiest to read. – Dominique Devriese Nov 23 '15 at 08:22
  • 1
    I think you could try alternatives though, e.g. interpreting [[*]] not as sets, but as subsets of a predefined universe or something similar. Perhaps someone else has a good reference for this... I'm not sure this is what you're looking for though... – Dominique Devriese Nov 23 '15 at 08:29
  • Also note: the Reynolds paper is really about interpreting System F in set theory with [[*]] = Set, not about doing the same in a dependent type theory like Agda, but I do have the intuition that the result holds here too... – Dominique Devriese Nov 23 '15 at 08:31
  • Could [this paper](https://www.fing.edu.uy/~amiquel/publis/lics00.pdf) be useful? – Cactus Nov 23 '15 at 08:46
  • 1
    @Dominique Devriese, these are good points, but the OP's question as well arises for the predicative fragment of System F, which is embeddable. – effectfully Nov 23 '15 at 09:04
  • 1
    @Cactus, their impredicativity is Prop-impredicativity, only `Prop` (`x ≡ y -: A : Prop, x y : A`) is impredicative, while in System F the whole `*` is impredicative. There is also `Set` in the paper, but it's basically a synonym for `Prop` and not `Type₀` like in Coq. – effectfully Nov 23 '15 at 09:43
  • 1
    I [wrote](https://github.com/effectfully/random-stuff/blob/master/System-F/TypeEval.agda) an evaluator for System F types. – effectfully Dec 16 '15 at 17:01
  • 1
    @DominiqueDevriese A few notes: Reynolds's does not apply to intuitionistic metatheories (as taught by Pitts: https://dl.acm.org/citation.cfm?id=755423), and System F can indeed be embedded in Coq with impredicative Set: https://bentnib.org/f-in-coq.html. Impredicative Prop is instead enough for logical relations for F (including strong normalization proofs). But Agda is predicative, so apparently it's too weak to prove F consistent/normalizing (you'd need meta-level impredicativity to model the object-level one, and no other way can work: https://cstheory.stackexchange.com/a/32862/989). – Blaisorblade Jul 10 '18 at 11:39

1 Answers1

4

Instead of

evalTy : Type → Set

you can write

evalTy : (σ : Type) -> Set (levelOf σ)

(András Kovács, care to add an answer with references to your embedding of predicative System F?)

This is enough for embedding, but I've seen a lot of Setω errors and they have traumatised me, so now I'm trying to avoid dependent universes as much as possible.

You can embed polymorphic types into Set₁ and monomorphic types into Set, so you can embed any type into Set₁ using the ugly lifting mechanism. I tried this several times and it always was awful.

The thing I would try is to define evalTy as

evalTy : Type -> Set ⊎ Set₁

and then eliminate it at the type level like this:

data [_,_]ᵀ {α β γ δ} {A : Set α} {B : Set β} (C : A -> Set γ) (D : B -> Set δ)
            : A ⊎ B -> Set (γ ⊔ δ) where
  inj¹ : ∀ {x} -> C x -> [ C , D ]ᵀ (inj₁ x)
  inj² : ∀ {y} -> D y -> [ C , D ]ᵀ (inj₂ y)

You can run this elimination:

Runᴸ : ∀ {α β γ δ} {A : Set α} {B : Set β} {C : A -> Set γ} {D : B -> Set δ} {s}
     -> [ C , D ]ᵀ s -> Level
Runᴸ {γ = γ} (inj¹ _) = γ
Runᴸ {δ = δ} (inj² _) = δ

Runᵀ : ∀ {α β γ δ} {A : Set α} {B : Set β} {C : A -> Set γ} {D : B -> Set δ} {s}
     -> (sᵀ : [ C , D ]ᵀ s) -> Set (Runᴸ sᵀ) 
Runᵀ {C = C} (inj¹ {x} _) = C x
Runᵀ {D = D} (inj² {y} _) = D y

runᵀ : ∀ {α β γ δ} {A : Set α} {B : Set β} {C : A -> Set γ} {D : B -> Set δ} {s}
     -> (sᵀ : [ C , D ]ᵀ s) -> Runᵀ sᵀ
runᵀ (inj¹ z) = z
runᵀ (inj² w) = w

Thus you introduce a universe dependency only at the end, when you actually need to compute something.

E.g.

SomeSet : ℕ -> Set ⊎ Set₁
SomeSet 0 = inj₁ ℕ
SomeSet n = inj₂ Set

ofSomeSet : ∀ n -> [ (λ A -> A × A) , id ]ᵀ (SomeSet n)
ofSomeSet  zero   = inj¹ (0 , 5)
ofSomeSet (suc n) = inj² ℕ

-- 0 , 5
test₁ : ℕ × ℕ
test₁ = runᵀ (ofSomeSet 0)

-- ℕ
test₂ : Set
test₂ = runᵀ (ofSomeSet 1)

ofSomeSet is a dependent function, but not a "universally dependent", you can write e.g. f = ofSomeSet ∘ suc and it's a perfectly typeable expression. This doesn't work with universes dependencies:

fun : ∀ α -> Set (Level.suc α)
fun α = Set α

oops = fun ∘ Level.suc

-- ((α : Level) → Set (Level.suc α)) !=< ((y : _B_160 .x) → _C_161 y)
-- because this would result in an invalid use of Setω

You can also enhance [_,_]ᵀ to make it mappable like I did here, but this all is probably overkill and you should just use

evalTy : (σ : Type) -> Set (levelOf σ)

Note that I'm talking only about the predicative fragment of System F. Full System F is not embeddable as Dominique Devriese explains in his comments to the question.

However I feel like we can embed more than the predicative fragment, if we first normalize a System F term. E.g. id [∀ α : *. α → α] id is not directly embeddable, but after normalization it becomes just id, which is embeddable.

However it should be possible to embed id [∀ α : *. α → α] id even without normalization by transforming it into Λ α. id [α → α] (id [α]), which is what Agda does with implicit arguments (right?). So it's not clear to me what exactly we can't embed.

Community
  • 1
  • 1
effectfully
  • 12,325
  • 2
  • 17
  • 40
  • 1
    My old [System F](https://gist.github.com/AndrasKovacs/83e7dcbb4bd0a4dc11f3) is awful and I was rather clueless when I wrote it, and I think it would be better to start out with the scheme in the answer above. In my System F the main issue was that I couldn't prove equality of `Set` -s with non-obviously same levels, so instead I proved their logical equivalence, with lots of code bloat. – András Kovács Nov 23 '15 at 12:46
  • I also handled substitution in an ugly way. Now I would rather borrow stuff from [this](http://www.cs.nott.ac.uk/~psztxa/publ/msfp10.pdf). – András Kovács Nov 23 '15 at 12:50
  • @András Kovács, I have no idea whether this scheme really can make things nicer. Every time I use such type-level eliminators, I eventually find a simpler ad hoc solution. – effectfully Nov 23 '15 at 14:45
  • 2
    Interesting answer, but it's worth making (more) clear that this will only allow you to embed *the predicative fragment of* System F, not full System F... – Dominique Devriese Nov 24 '15 at 10:09
  • @Dominique Devriese, thanks, I updated the answer and made myself confused. – effectfully Nov 24 '15 at 10:47
  • The transformation you mentioned in your last paragraph -- won't that only work for rank-1 types? – Cactus Nov 25 '15 at 01:32
  • @Cactus, I don't understand the question, could you expand it? – effectfully Nov 25 '15 at 04:36
  • I mean what if you have a rank-2 type like `∀ α : ⋆. ∀ β : ⋆. α → (∀ γ : ⋆. α → γ) → β`? How do you "lift out" the binding of `γ`? – Cactus Nov 25 '15 at 06:32
  • 1
    @Cactus, ah, see now. But even for such terms we can embed them into universe polymorphic Agda terms (that's what I'm doing [here](https://github.com/effectfully/STLC-in-Agda) for STLC) and "lift-out" `Level`s rather than `Set`s. [A short illustration](http://lpaste.net/145926). – effectfully Nov 25 '15 at 06:51