Definition ty_lam (tau1 tau2 : pred world) : pred world :=
EX e:expr, EX H:closed' 1 e, just (v_Lam e H) &&
|>%(ALL v':value, with_val v' (%tau1) --> expr_type (subst 0 v' e) tau2).
Definition etype : Type := list (pred world).
Fixpoint etype_valid (e : env) (G : etype) : pred world :=
match (e,G) with
| (v :: es, tau :: Gs) => with_val v (%tau) && etype_valid es Gs
| (nil, nil) => TT
| _ => FF
end.
(* Not in paper, but should add.  Taken from VMM. *)
Definition Typ (G : etype) (exp : expr) (tau : pred world) : Prop :=
closed' (length G) exp  /\
forall env, etype_valid env G |-- expr_type (subst_env env exp) tau.

(* Specifications: *)
Lemma expr_type_sub2 :
forall X e P Q,
P >=> Q |-- expr_typeF P X e >=> expr_typeF Q X e.
Lemma subp_expr_type : forall G P P',
G |-- P >=> P' ->
G |-- ALL e:expr, expr_type e P >=> expr_type e P'.
Lemma ty_lam_sub : forall G P P' Q Q',
G |-- |>(P' >=> P) ->
G |-- |>(Q >=> Q') ->
G |-- (ty_lam P Q) >=> (ty_lam P' Q').
Lemma subp_type_at : forall G P Q l,
G |-- |>(P <=> Q) ->
G |-- type_at l P >=> type_at l Q.
Lemma ty_ref_sub : forall G P Q,
G |-- |>(P <=> Q) ->
G |-- ty_ref P >=> ty_ref Q.
Lemma extend_nonexpansive : forall F,
nonexpansive F ->
nonexpansive (fun X => %(F X)).
Lemma with_val_nonexpansive : forall F v,
nonexpansive F ->
nonexpansive (fun X => with_val v (F X)).
Lemma expr_type_nonexpansive : forall F e,
nonexpansive F ->
nonexpansive (fun X => (expr_type e (F X))).
Lemma ty_lam_contractive : forall F G,
nonexpansive F ->
nonexpansive G ->
contractive (fun X => ty_lam (F X) (G X)).
Lemma type_at_contractive : forall l F,
nonexpansive F ->
contractive (fun X => type_at l (F X)).
Lemma ty_ref_contractive : forall F,
nonexpansive F ->
contractive (fun X => ty_ref (F X)).
Lemma just_extends : forall v,
%just v = just v.
Lemma ty_ref_extends : forall tau,
%(ty_ref tau) = ty_ref tau.