Definition weight_constraints (b: PTree.t bounds) (cstr: list constraint) : nat :=
List.fold_right (fun xy n => n + weight_bounds b!(fst xy) + weight_bounds b!(snd xy)) 0 cstr.
Remark weight_constraints_tighter:
forall b1 b2, (forall r, weight_bounds b1!r <= weight_bounds b2!r) ->
forall q, weight_constraints b1 q <= weight_constraints b2 q.

(* Specifications: *)
Lemma weight_solve_rec:
forall q e changed e' changed',
solve_rec e changed q = OK(e', changed') ->
(forall r, weight_bounds e'.(te_typ)!r <= weight_bounds e.(te_typ)!r) /\
weight_constraints e'.(te_typ) e'.(te_sub) + (if changed' && negb changed then 1 else 0)
<= weight_constraints e.(te_typ) e.(te_sub) + weight_constraints e.(te_typ) q.
Lemma weight_solve_rec:
forall q e changed e' changed',
solve_rec e changed q = OK(e', changed') ->
(forall r, weight_bounds e'.(te_typ)!r <= weight_bounds e.(te_typ)!r) /\
weight_constraints e'.(te_typ) e'.(te_sub) + (if changed' && negb changed then 1 else 0)
<= weight_constraints e.(te_typ) e.(te_sub) + weight_constraints e.(te_typ) q.