(* The current set of constraints is represented by a record with two components:
- [te_typ]: a partial map from variables to types
- [te_equ]: a list of pairs [(x,y)] of variables, indicating that
  the type of [x] must be equal to the type of [y].
*)

Definition constraint : Type := (positive * positive)%type.Record typenv : Type := Typenv {
  te_typ: PTree.t T.t;       (**r mapping var -> typ *)
  te_equ: list constraint    (**r additional equality constraints *)
}.Record typenv : Type := Typenv {
  te_typ: PTree.t T.t;       (**r mapping var -> typ *)
  te_equ: list constraint    (**r additional equality constraints *)
}.Record typenv : Type := Typenv {
  te_typ: PTree.t T.t;       (**r mapping var -> typ *)
  te_equ: list constraint    (**r additional equality constraints *)
}.Record typenv : Type := Typenv {
  te_typ: PTree.t T.t;       (**r mapping var -> typ *)
  te_equ: list constraint    (**r additional equality constraints *)
}.Definition initial : typenv := {| te_typ := PTree.empty _; te_equ := nil |}.

Lemma move_shape: forall e r1 r2 changed e', move e r1 r2 = OK (changed, e') -> (e'.(te_equ) = e.(te_equ) \/ e'.(te_equ) = (r1, r2) :: e.(te_equ)) /\ (changed = true -> e'.(te_equ) = e.(te_equ)).