(* 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 |}.

(* Specifications: *)
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)).
Lemma length_move: forall e r1 r2 changed e', move e r1 r2 = OK (changed, e') -> length e'.(te_equ) + (if changed then 1 else 0) <= S(length e.(te_equ)).
Lemma length_solve_rec: forall q e ch e' ch', solve_rec e ch q = OK (e', ch') -> length e'.(te_equ) + (if ch' && negb ch then 1 else 0) <= length e.(te_equ) + length q.