Strengthening

From The Twelf Project

Strengthening lemmas prove that something which holds under assumptions also holds without them.

When proving type families total using %total, strengthening lemmas are sometimes necessary because Twelf estimates dependencies conservatively using the subordination relation. Specifically, for Twelf's output coverage check to succeed, the output variables of higher-order premises must mention all assumptions of subordinate types. If an assumption's type is subordinate to an output variable's type, but additional reasoning shows that the assumption cannot occur in the output variable in a particular case, you must prove a strengthening lemma expressing this reasoning.

In this tutorial, we'll show a proof where the need for strengthening arises. We'll define a language with locations, stores which map locations to terms in the language, and a notion of well-formedness with respect to a store (no dangling references and no loops). Then we'll define evaluation for the language, and prove that well-formed terms evaluate to well-formed terms; we will need strengthening for this proof.

This is a silly little language; it has locations but no way to use them.

(The %name declarations give a prefix which Twelf uses to name unnamed variables for display; we prefix the names with _ so that it's clear which variables Twelf named, and also because Twelf will rename your variables if they collide with the naming prefix, which can be very confusing.)

Stores are just lists of location/term pairs. The lookup relation might look a little strange, since both st-lookup/1 and st-lookup/2 apply if L = L', but for our purpose it is OK and this avoids having to define disequality of locations.

A term is well-formed with respect to a store if its locations are all defined in the store, and if the terms bound to its locations are all well-formed with respect to the store.

How to define well-formedness of the open term that appears in the lam case? We assume some term, and mark it is a variable using tm-var, then check the well-formedness of the lambda body applied to this new term. Then we give a case saying that any term marked as a variable is well-formed.

An alternative would be to directly assume tm-wf v S. This example was extracted from the AML proof, where we need to prove that if we have a store S' which extends S, and a term T is well-formed in S, then T is also well-formed in S'. That proof is difficult if we assume tm-wf v S, because we know nothing about v in S'. With the tm-var approach we can just apply the tm-wf/var rule to get tm-wf v S'.

However, as we will see, this approach forces us to prove a substitution lemma, which requires the strengthening lemma.

The preservation theorem is straightforward, but we need to appeal to a substitution lemma. Let's see why: we have Dwf1' : {v:tm}{d:tm-var v} tm-wf (T1 v) S and Dwf2 : tm-wf T2 S; we need Dwf' : tm-wf (T1 T2) S. Now, had we defined tm-wf/lam to assume d:tm-wf v S instead of d:tm-var v, then we could just write (Dwf1' T2 Dwf2) in place of Dwf'. But, as previously noted, that gets us into a different kind of trouble. So we prove an explicit substitution lemma:

The lam case is complicated only by the fact that we need to go under a binder; here v is the variable we're substituting for and v' is the bound variable. Since we call the lemma recursively under assumptions, we need to prove it in worlds where those assumptions are present.

In the var case we have found the variable we're substituting for. The bind case handles assumptions; there is no way to explicitly refer to them, but they are closed, so we can catch them with this case for closed terms.

The loc case is why we're here: Twelf determines that Dlook can depend on v and Dwf1 on v and d, even though they can't. So we need two strengthening lemmas to get the terms we need.

Why can't Dlook and Dwf1 depend on v and d? We are about to give proofs, but here is the intuition: The store S has no dependencies in the declaration of the lemma, and st-lookup just walks over the store, so Dlook has no dependencies; neither does the looked-up term. Now tm-wf just walks over the term looking up locations in the store, so it also has no dependencies.

It would be nice if we could just get rid of the v assumption on the st-lookup derivation, but we have in addition that the returned term T can depend on v, so we must invent a new non-dependent T' and return an equality. Otherwise, this is a straightforward induction that demonstrates that we never use the assumption.

Here it is a priori possible that something of type tm-wf (T v) S could depend on v and d (e.g. it could be (tm-wf/var d)), but in conjunction with the equality it cannot. In the loc case we're doing essentially the same thing that we do in the substitution lemma, and must appeal to st-lookup-strengthen and tm-wf-strengthen (but we're not inducting over the well-formed term here). The coverage checker is able to rule out the var case since T does not depend on v.