(* * Copyright (c) 2009 Robert Dockins and Aquinas Hobor. * *)
(* Coq development: using indirection theory to model types in l-calculus *)
(* lam_ref_type_defs.v: the definition of the type system; this is the main event. *)
Module TFP <: TY_FUNCTOR_PROP.
(* From section 4.1 *)
Definition F : Type -> Type := fun K => addr -> option K.
Definition f_F := f_fun addr (f_option f_identity).
Definition other : Type := value.
End TFP.
Export TFP.
Module K := KnotHered(TFP). (* Wow, that was easy... *)
Module KL := KnotHered_Lemmas(K).
Export K.
Export KL.
(* Let's define our typing system on values *)
Definition mtype : Type := knot.
Definition world : Type := (mtype * value)%type.
Definition world_ag : ageable world :=
ag_prod mtype value ag_knot.
Existing Instance world_ag.
Definition knot_extends (k1 k2 : knot) : Prop :=
match (unsquash k1, unsquash k2) with
((n, psi), (n', psi')) => n = n' /\ forall a, (psi a = None) \/ (psi' a = psi a)
end.
Definition R_extends (w1 w2 : world) : Prop :=
match (w1, w2) with
((k1, v1), (k2, v2)) => knot_extends k1 k2 /\ v1 = v2
end.

Lemma knot_extends_age_commute2 : forall x y z,
knot_extends x y /\ age y z -> exists y',
age x y' /\ knot_extends y' z.