10

Those typing rules are present on the "On the expressivity of elementary linear logic: characterizing Ptime and an exponential time hierarchy" paper:

typing rules

From the “What part of Milner-Hindley do you not understand?” Stack Overflow question, I can read some of those in English, but it is still difficult to figure out how to make a type checker out of that. This is my attempt at reading the first 4 rules:

  • Ax: as an axiom, if x has type A, then x has type A. (Isn't that obvious?)

  • Cut: If a context Γ proves t has type A, and another context , extended with the assertion x has type A, proves u has type B, then those two contexts together prove the substitution of all occurrences of x by t in u has type B. (What does that mean, though? Why there are two contexts, where the extra one comes from? Also, that seems like a rule for substitution, but how, if substitution isn't a term, but an operation? The classical Milner-Hindley has nothing like that; it has just a very simple rule for App.)

  • Weak: If a context proves t has type A, then that context extended with the statement x has type B still proves t has type A. (Again, isn't that obvious?)

  • Contr: if a context extended with x1 has type !A and x2 has type !A proves t has type B, then that context, extended with x has type !A proves substituting all occurrences of x1 and x2 by x in t has type B. (Another rule for substitution, it seems? But why there are two terms above, one term below? Also, why those !s? Where would that all show up on the type checker?)

I quite get what those rules want to say, but I am missing something before it truly clicks and I'm able to implement the corresponding type checker. How can I approach understanding those rules?

Community
  • 1
  • 1
MaiaVictor
  • 51,090
  • 44
  • 144
  • 286
  • 1
    Some of these are indeed obvious, and I don't know why "Axiom" is required, but many "obvious" things need to be included to set up a type system or logic. – dfeuer Oct 14 '16 at 20:10
  • In case this question is not fit, if someone could link me to a practical tutorial on how to write a type-checker out of those formulas (perhaps using the STLC or something simple) it would advance a lot my understanding. I'm reading [this](http://typesafety.net/thesis/chapter-2.pdf) guide on light logics on the meanwhile, trying to compare its formulas to those I posted, I'm finding it very instructive. – MaiaVictor Oct 14 '16 at 20:28
  • The title of the question is a bit misleading: are you asking about the judgements in this particular case, or understanding judgements in general? – Alec Oct 14 '16 at 20:37
  • @Alec if I understand how to do it in general then it would be easy to do it on this particular case, right? But I think the question evolved more for this particular case so I edited the title... – MaiaVictor Oct 14 '16 at 20:42
  • 5
    In general, to implement a typechecker, you need your type system in syntax-directed form—I don’t know if this is. Then each rule corresponds to a case branch on the syntax. E.g., **Ax** could be `typecheck gamma (Var x) = case Map.lookup x gamma of { Just a -> return a; Nothing -> fail "unbound variable" }`, like the Var rule in HM, x : A ∈ Γ / Γ ⊢ x : A. – Jon Purdy Oct 14 '16 at 21:22
  • 2
    @dfeuer Axiom is the only rule without a premise -- if we didn't have that we could not type anything. Think of it as the base case for the induction. – chi Oct 14 '16 at 22:13
  • @dfeuer, `Axiom` says that if you have some `x : A` in a context, you can reference this `x : A`. It's like in normal STLC where you can construct `\(x : A) -> x` — here the lambda binds a variable (i.e. adds it to the context) and `Axiom` allows to mention it later (i.e. take it from a (possibly empty) extension of the context where it was bound). – effectfully Oct 15 '16 at 09:11

1 Answers1

8

This is a bit too broad, but from your comments I guess that you lack some basics of linear type systems. This system has weakening (not usually allowed in linear logic), so it actually corresponds to affine intuitionistic logic.

The key idea is: you can use every value you have (e.g. variables) at most once.

The type A (x) B (tensor product) roughly stands for the type of pair values, from which you can project out both a A value and a B value.

The type A -o B stands for a linear function which consumes a value A (remember: at most one use!) and produces a single B.

You can have e.g. \x.x : A -o A but you can not have any term : A -o (A (x) A) since that would require you to use the argument twice.

The type !A ("of course A!") stands for values of type A which can be duplicated as will -- as you can do normally in non-linear lambda calculi. This is done by the Contraction rule.

For instance, !A -o !B represents a plain function: it requires a value (in an unbounded amount of copies) and produce a value (in an unbounded amount of copies). You can write a function !A -o (!A (x) !A) as follows:

\a. (a (x) a)

Note that every linear typing rule with multiple premises has to split the environment variables between the premises (e.g. one gets Gamma, the other Delta), without overlap. Otherwise, you could duplicate linear variables. Cut has two contexts because of this. The non-linear cut would be:

G |- t: A        G, x:A |- u: B
--------------------------------
  G |- u[t/x]: B

but here both terms t and u can use the variables in G, hence u[t/x] can use variables twice -- not good. Instead, the linear cut

G1 |- t: A        G2, x:A |- u: B
--------------------------------
  G1,G2 |- u[t/x]: B

forces you to split variables between the two premises: what you use in t is unavailable for u.

Benjamin Hodgson
  • 42,952
  • 15
  • 108
  • 157
chi
  • 111,837
  • 3
  • 133
  • 218