Module ESD := FSetDecide.Decide(EqSet).
Definition sel_val (k: equation_kind) (v: val) : val :=
match k with
| Full => v
| Low => Val.loword v
| High => Val.hiword v
end.
(** A set of equations [e] is satisfied in a RTL pseudoreg state [rs] and an LTL location state [ls] if, for every equation [r = l [k]] in [e], [sel_val k (rs#r)] (the [k] fragment of [r]'s value in the RTL code) is less defined than [ls l] (the value of [l] in the LTL code). *)
Definition satisf (rs: regset) (ls: locset) (e: eqs) : Prop :=
forall q, EqSet.In q e -> Val.lessdef (sel_val (ekind q) rs#(ereg q)) (ls (eloc q)).
Remark select_reg_l_monotone:
forall r q1 q2,
OrderedEquation.eq q1 q2 \/ OrderedEquation.lt q1 q2 ->
select_reg_l r q1 = true -> select_reg_l r q2 = true.
Remark select_reg_h_monotone:
forall r q1 q2,
OrderedEquation.eq q1 q2 \/ OrderedEquation.lt q2 q1 ->
select_reg_h r q1 = true -> select_reg_h r q2 = true.
Remark select_reg_charact:
forall r q, select_reg_l r q = true /\ select_reg_h r q = true <-> ereg q = r.
Remark select_loc_l_monotone:
forall l q1 q2,
OrderedEquation'.eq q1 q2 \/ OrderedEquation'.lt q1 q2 ->
select_loc_l l q1 = true -> select_loc_l l q2 = true.
Remark select_loc_h_monotone:
forall l q1 q2,
OrderedEquation'.eq q1 q2 \/ OrderedEquation'.lt q2 q1 ->
select_loc_h l q1 = true -> select_loc_h l q2 = true.
Remark select_loc_charact:
forall l q,
select_loc_l l q = false \/ select_loc_h l q = false <-> Loc.diff l (eloc q).
Remark in_elements_between_1:
forall r1 s q,
EqSet.In q (EqSet.elements_between (select_reg_l r1) (select_reg_h r1) s) <-> EqSet.In q s /\ ereg q = r1.

Lemma subst_reg_kind_satisf_makelong:
forall src1 src2 dst rs ls e,
let e1 := subst_reg_kind dst High src1 Full e in
let e2 := subst_reg_kind dst Low src2 Full e1 in
reg_unconstrained dst e2 = true ->
satisf rs ls e2 ->
satisf (rs#dst <- (Val.longofwords rs#src1 rs#src2)) ls e.